{"id":18045613,"url":"https://github.com/piroor/webextensions-lib-configs","last_synced_at":"2025-10-15T17:34:48.374Z","repository":{"id":54586367,"uuid":"55588711","full_name":"piroor/webextensions-lib-configs","owner":"piroor","description":"Configuration library for Firefox addons based on WebExtensions","archived":false,"fork":false,"pushed_at":"2025-09-16T08:47:47.000Z","size":160,"stargazers_count":12,"open_issues_count":1,"forks_count":6,"subscribers_count":2,"default_branch":"trunk","last_synced_at":"2025-09-16T10:30:45.021Z","etag":null,"topics":["firefox-addon","hacktoberfest","webextensions"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/piroor.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2016-04-06T08:28:14.000Z","updated_at":"2025-09-16T08:47:54.000Z","dependencies_parsed_at":"2023-12-13T11:31:44.548Z","dependency_job_id":"e44fee53-0395-4e69-9dab-724aa95d0793","html_url":"https://github.com/piroor/webextensions-lib-configs","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/piroor/webextensions-lib-configs","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/piroor%2Fwebextensions-lib-configs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/piroor%2Fwebextensions-lib-configs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/piroor%2Fwebextensions-lib-configs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/piroor%2Fwebextensions-lib-configs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/piroor","download_url":"https://codeload.github.com/piroor/webextensions-lib-configs/tar.gz/refs/heads/trunk","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/piroor%2Fwebextensions-lib-configs/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279096297,"owners_count":26102537,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-15T02:00:07.814Z","response_time":56,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["firefox-addon","hacktoberfest","webextensions"],"created_at":"2024-10-30T18:13:46.912Z","updated_at":"2025-10-15T17:34:48.331Z","avatar_url":"https://github.com/piroor.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# webextensions-lib-configs\n\n![Build Status](https://github.com/piroor/webextensions-lib-configs/actions/workflows/main.yml/badge.svg?branch=trunk)\n\nProvides ability to store/load configurations, on Firefox 52 and later.\n\nBy the [bug 1197346](https://bugzilla.mozilla.org/show_bug.cgi?id=1197346), now we don't have to do inter-sandboxes comunication to read/write configuration values.\nAfter the bug, this library is still effective to provide easy access for configuration values.\n\n## Required permissions\n\n * `storage`\n\n## Usage\n\nIn `manifest.json`, load the file `Configs.js` from both the background page and others, like:\n\n```json\n{\n  \"background\": {\n    \"scripts\": [\n      \"path/to/Configs.js\",\n      \"path/to/common.js\"\n    ]\n  },\n  \"content_scripts\": [\n    {\n      \"all_frames\": true,\n      \"matches\": [\n        \"\u003call_urls\u003e\"\n      ],\n      \"js\": [\n        \"path/to/Configs.js\",\n        \"path/to/common.js\",\n        \"...\"\n      ],\n      \"run_at\": \"document_start\"\n    }\n  ],\n  \"options_ui\": {\n    \"page\": \"path/to/options.html\",\n    \"chrome_style\": true\n  },\n  \"permissions\": [\n    \"storage\"\n  ]\n}\n```\n\n`options.html` is:\n\n```html\n\u003c!DOCTYPE html\u003e\n\u003cscript type=\"application/javascript\" src=\"./Configs.js\"\u003e\u003c/script\u003e\n\u003cscript type=\"application/javascript\" src=\"./common.js\"\u003e\u003c/script\u003e\n...\n```\n\nAnd, define an instance with default values on each namespace like:\n\n```javascript\n// common.js\n\nvar configs = new Configs({\n  enabled: true,\n  advanced: false,\n  attributes: 'alt|title',\n  entries: [],\n  cache: {}\n});\n```\n\nThe instance has a built-in property `$loaded`. It is a `Promise`, so you can do something after all stored user values are loaded:\n\n```javascript\nconfigs.$loaded.then(function() {\n  MyService.start();\n});\n```\n\nAfter all values are loaded, you can access loaded values via its own properties same to the given default values:\n\n```javascript\nconsole.log(configs.enabled); // =\u003e true (default value)\nconsole.log(configs.advanced); // =\u003e false (default value)\nconsole.log(configs.attributes); // =\u003e \"alt|title\" (default value)\nconsole.log(configs.cache); // =\u003e {} (default value)\n```\n\nIf you set a new value, it will be notified to the background page, then stored to the local storage as the user value and dispatched to all other namespaces.\n\n```javascript\n// in the options.html\nconfigs.enabled = false;\n```\n\n```javascript\n// in content script\nconsole.log(configs.enabled); // =\u003e false (user value)\n```\n\nYou still can get default values easily, with a prefix `$default.`:\n\n```javascript\nconsole.log(configs.$default.enabled); // =\u003e true (default value)\nconfigs.enabled = configs.$default.enabled; // reset to default\n\nconfigs.$reset(); // reset all to default\n```\n\n### Important note around object or array values\n\nWhen you hope to update a non-primitive configuration values, note that you must replace the object itself.\nFor example, deep clone based on `JSON.parse()` and `JSON.stringify()` will be effective:\n\n```javascript\nvar newEntries = JSON.parse(JSON.stringify(configs.entries)); // deep clone\nentries.push('added item');\nconfigs.entries = newEntries;\n\nvar newCache = JSON.parse(JSON.stringify(configs.cache)); // deep clone\nnewCache.addedItem = true;\nconfigs.cache = newCache;\n```\n\nIn other words, following codes don't work as expected:\n\n```javascript\n// Directly modified object won't be saved.\nconfigs.entries.push('added item');\nconfigs.cache.addedItems = true;\n\n// Simple assignment also uses the object itself,\n// so this example is same to the previous.\n{\n   let newEntries = configs.entries;\n   newEntries.push('added item');\n   configs.entries = newEntries;\n\n   let newCache = configs.cache;\n   newCache.addedItems = true;\n   configs.cache = newCache;\n}\n\n// Shallow clone is better than above, and it works as expected\n// only when all values are primitive.\n{\n   let newEntries = configs.entries.slice(0);\n   newEntries.push('added item');\n   configs.entries = newEntries;\n\n   let newCache = { ...configs.cache }; // shallow clone\n   newCache.addedItems = true;\n   configs.cache = newCache;\n}\n```\n\n## Managed Storage\n\nThis library supports `storage.managed`. Configuration items which have any value in `storage.managed` are  treated as locked configuration and they become unchangable. For more details, see the [API documentation](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/storage/managed).\n\nFor providing default configs instead of completely managed locked configs, please use `:unlock` suffix for each key.\nIf you define `:unlocked`-suffixed key with `false` value, the corresponding config will become unlocked, for example:\n\n```json\n{\n  \"name\": \"...\",\n  \"description\": \"...\",\n  \"type\": \"storage\",\n  \"data\":\n  {\n    \"color\": \"#FF0000\",\n    \"color:locked\", false // \u003c= HERE! This makes \"color\" unlocked.\n  }\n}\n```\n\n\n## Sync Storage\n\nThis library supports [storage.sync](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/storage/sync). To use it, set `syncKeys` in the optional second parameter of the `Configs` constructor to an array of the key names that should be synced:\n\n```javascript\nvar configs = new Configs({\n  enabled: true,\n  advanced: false,\n  attributes: 'alt|title'\n}, {\n  syncKeys: ['enabled', 'attributes']\n});\n```\n\nAlternately, specify (possibly empty) array of keys which should _not_ be synced in `localKeys`:\n\n```javascript\nvar configs = new Configs({\n  enabled: true,\n  advanced: false,\n  attributes: 'alt|title'\n}, {\n  localKeys: ['advanced']\n});\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpiroor%2Fwebextensions-lib-configs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpiroor%2Fwebextensions-lib-configs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpiroor%2Fwebextensions-lib-configs/lists"}