@vacantthinker/firefox-addon-framework-easy 2026.613.1110 → 2026.613.1536

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/BaseORM.d.ts CHANGED
@@ -4,37 +4,32 @@
4
4
  * Uses Generics (T) to ensure type safety for the stored object structure.
5
5
  */
6
6
  export declare abstract class BaseORM<T extends Record<string, any>> {
7
- #private;
8
- /**
9
- * @param prefix The prefix for the storage key.
10
- * @param id The unique identifier for this instance.
11
- * @param defaultValue The initial value to use if the key does not exist.
12
- */
7
+ protected readonly id: string;
8
+ protected readonly storageKey: string;
9
+ private readonly defaultValue;
10
+ private initPromise;
13
11
  protected constructor(prefix: string, id: string, defaultValue?: T);
14
- get id(): string;
15
- get storageKey(): string;
16
12
  /**
17
13
  * Retrieve the value associated with the bound key.
18
14
  * @returns {Promise<T>}
19
15
  */
20
- get(): Promise<T>;
16
+ protected get(): Promise<T>;
17
+ /**
18
+ * Safely initialize the default object. Prevents multiple concurrent
19
+ * requests from writing the default value simultaneously.
20
+ */
21
+ private safeInit;
21
22
  /**
22
23
  * Overwrite the value of the bound key completely.
23
24
  * @param {T} value
24
25
  * @returns {Promise<void>}
25
26
  */
26
- set(value: T): Promise<void>;
27
+ protected set(value: T): Promise<void>;
27
28
  /**
28
29
  * Wipe the bound key from storage.
29
30
  * @returns {Promise<T>}
30
31
  */
31
- delete(): Promise<T>;
32
- /**
33
- * Modify a single targeted key-value pair nested deep within the stored object.
34
- * @param {K} key The internal key path inside the main value object.
35
- * @param {T[K]} value The new value to map to that key.
36
- */
37
- updateValueKeyValue<K extends keyof T>(key: K, value: T[K]): Promise<void>;
32
+ protected delete(): Promise<T>;
38
33
  private exists;
39
34
  private initDefaultObject;
40
35
  }
@@ -1 +1 @@
1
- {"version":3,"file":"BaseORM.d.ts","sourceRoot":"","sources":["../src/BaseORM.ts"],"names":[],"mappings":"AAOA;;;;GAIG;AACH,8BAAsB,OAAO,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;;IAKzD;;;;OAIG;IACH,SAAS,aACP,MAAM,EAAE,MAAM,EACd,EAAE,EAAE,MAAM,EACV,YAAY,GAAE,CAAW;IAe3B,IAAI,EAAE,IAAI,MAAM,CAEf;IAED,IAAI,UAAU,IAAI,MAAM,CAEvB;IAED;;;OAGG;IACG,GAAG,IAAI,OAAO,CAAC,CAAC,CAAC;IAOvB;;;;OAIG;IACG,GAAG,CAAC,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAOlC;;;OAGG;IACG,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC;IAM1B;;;;OAIG;IACG,mBAAmB,CAAC,CAAC,SAAS,MAAM,CAAC,EACzC,GAAG,EAAE,CAAC,EACN,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,GACV,OAAO,CAAC,IAAI,CAAC;YAMF,MAAM;YAIN,iBAAiB;CAMhC"}
1
+ {"version":3,"file":"BaseORM.d.ts","sourceRoot":"","sources":["../src/BaseORM.ts"],"names":[],"mappings":"AAOA;;;;GAIG;AACH,8BAAsB,OAAO,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IACzD,SAAS,CAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAC9B,SAAS,CAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IACtC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAI;IAGjC,OAAO,CAAC,WAAW,CAA8B;IAEjD,SAAS,aACP,MAAM,EAAE,MAAM,EACd,EAAE,EAAE,MAAM,EACV,YAAY,GAAE,CAAW;IAkB3B;;;OAGG;cACa,GAAG,IAAI,OAAO,CAAC,CAAC,CAAC;IAQjC;;;OAGG;YACW,QAAQ;IAgBtB;;;;OAIG;cACa,GAAG,CAAC,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAO5C;;;OAGG;cACa,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC;YAMtB,MAAM;YAIN,iBAAiB;CAMhC"}
package/dist/BaseORM.js CHANGED
@@ -5,14 +5,11 @@ import { stoOpCheck, stoOpGet, stoOpRem, stoOpSet } from './opStorage';
5
5
  * Uses Generics (T) to ensure type safety for the stored object structure.
6
6
  */
7
7
  export class BaseORM {
8
- #id;
9
- #fullStorageKey;
10
- #defaultValue;
11
- /**
12
- * @param prefix The prefix for the storage key.
13
- * @param id The unique identifier for this instance.
14
- * @param defaultValue The initial value to use if the key does not exist.
15
- */
8
+ id;
9
+ storageKey;
10
+ defaultValue;
11
+ // The Mutex "Lock" for preventing race conditions during initialization
12
+ initPromise = null;
16
13
  constructor(prefix, id, defaultValue = {}) {
17
14
  if (new.target === BaseORM) {
18
15
  throw new TypeError('Cannot construct BaseORM instances directly (Abstract Class).');
@@ -20,16 +17,12 @@ export class BaseORM {
20
17
  if (!prefix || !id) {
21
18
  throw new Error('Both prefix and id must be specified.');
22
19
  }
23
- this.#id = id;
24
- const formattedPrefix = prefix.endsWith(' ') ? prefix : `${prefix} `;
25
- this.#fullStorageKey = `${formattedPrefix}${id}`;
26
- this.#defaultValue = JSON.parse(JSON.stringify(defaultValue));
27
- }
28
- get id() {
29
- return this.#id;
30
- }
31
- get storageKey() {
32
- return this.#fullStorageKey;
20
+ this.id = id;
21
+ const formattedPrefix = prefix.endsWith(' ') ?
22
+ prefix :
23
+ `${prefix} `;
24
+ this.storageKey = `${formattedPrefix}${id}`;
25
+ this.defaultValue = structuredClone(defaultValue);
33
26
  }
34
27
  /**
35
28
  * Retrieve the value associated with the bound key.
@@ -37,9 +30,27 @@ export class BaseORM {
37
30
  */
38
31
  async get() {
39
32
  if (!(await this.exists())) {
40
- await this.initDefaultObject();
33
+ // Calls the lock-protected initialization instead of initDefaultObject directly
34
+ await this.safeInit();
41
35
  }
42
- return (await stoOpGet(this.#fullStorageKey));
36
+ return (await stoOpGet(this.storageKey));
37
+ }
38
+ /**
39
+ * Safely initialize the default object. Prevents multiple concurrent
40
+ * requests from writing the default value simultaneously.
41
+ */
42
+ async safeInit() {
43
+ // If an initialization is already in progress, wait for it
44
+ if (this.initPromise) {
45
+ return this.initPromise;
46
+ }
47
+ // Start initialization and store the Promise as the lock
48
+ this.initPromise = this.initDefaultObject()
49
+ .finally(() => {
50
+ // Clear the lock whether the initialization succeeds or fails
51
+ this.initPromise = null;
52
+ });
53
+ return this.initPromise;
43
54
  }
44
55
  /**
45
56
  * Overwrite the value of the bound key completely.
@@ -47,7 +58,7 @@ export class BaseORM {
47
58
  * @returns {Promise<void>}
48
59
  */
49
60
  async set(value) {
50
- await stoOpSet(this.#fullStorageKey, value || this.#defaultValue);
61
+ await stoOpSet(this.storageKey, value ?? this.defaultValue);
51
62
  }
52
63
  /**
53
64
  * Wipe the bound key from storage.
@@ -55,23 +66,13 @@ export class BaseORM {
55
66
  */
56
67
  async delete() {
57
68
  const previousValue = await this.get();
58
- await stoOpRem(this.#fullStorageKey);
69
+ await stoOpRem(this.storageKey);
59
70
  return previousValue;
60
71
  }
61
- /**
62
- * Modify a single targeted key-value pair nested deep within the stored object.
63
- * @param {K} key The internal key path inside the main value object.
64
- * @param {T[K]} value The new value to map to that key.
65
- */
66
- async updateValueKeyValue(key, value) {
67
- const data = await this.get();
68
- data[key] = value;
69
- await this.set(data);
70
- }
71
72
  async exists() {
72
- return await stoOpCheck(this.#fullStorageKey);
73
+ return await stoOpCheck(this.storageKey);
73
74
  }
74
75
  async initDefaultObject() {
75
- await stoOpSet(this.#fullStorageKey, this.#defaultValue);
76
+ await stoOpSet(this.storageKey, this.defaultValue);
76
77
  }
77
78
  }
@@ -2,17 +2,17 @@
2
2
  * Sends a message to a specific tab.
3
3
  */
4
4
  export declare function browserTabSendMessage(tabId: number, message: any): Promise<void>;
5
- export declare function browserTabExecuteScriptDocumentStart(tabId: number, code: string): Promise<any[]>;
6
- export declare function browserTabExecuteScript(tabId: number, code: string, runAt?: browser.extensionTypes.RunAt): Promise<any[]>;
5
+ export declare function browserTabExecuteScriptCodeDocumentStart(tabId: number, code: string): Promise<any[]>;
6
+ export declare function browserTabExecuteScriptDocumentStart(tabId: number, updateDetails: browser.extensionTypes.InjectDetails): Promise<any[]>;
7
+ export declare function browserTabExecuteScript(tabId: number, details: browser.extensionTypes.InjectDetails): Promise<any[]>;
7
8
  export declare function browserTabSetZoom(tabId: number, zoomFactor: number): Promise<void>;
8
9
  export declare function browserTabGetZoom(tabId: number): Promise<number>;
9
- export declare function browserTabInsertCSSDocumentStart(tabId: number, code: string): Promise<void>;
10
+ export declare function browserTabInsertCSSCodeDocumentStart(tabId: number, code: string): Promise<void>;
11
+ export declare function browserTabInsertCSSDocumentStart(tabId: number, details: browser.extensionTypes.InjectDetails): Promise<void>;
10
12
  /**
11
13
  * Injects CSS code into a page.
12
14
  */
13
- export declare function browserTabInsertCSS(tabId: number, code: string, runAt: browser.extensionTypes.RunAt): Promise<void>;
14
- /**
15
- * Removes CSS code that was previously injected into a page.
16
- */
17
- export declare function browserTabRemoveCSS(tabId: number, code: string): Promise<void>;
15
+ export declare function browserTabInsertCSS(tabId: number, details: browser.extensionTypes.InjectDetails): Promise<void>;
16
+ export declare function browserTabRemoveCSSCode(tabId: number, code: string): Promise<void>;
17
+ export declare function browserTabRemoveCSS(tabId: number, details: browser.extensionTypes.InjectDetails): Promise<void>;
18
18
  //# sourceMappingURL=browserTab.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"browserTab.d.ts","sourceRoot":"","sources":["../src/browserTab.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,wBAAsB,qBAAqB,CACzC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,GAAG,GACX,OAAO,CAAC,IAAI,CAAC,CAKf;AAED,wBAAsB,oCAAoC,CACxD,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,kBAOb;AAED,wBAAsB,uBAAuB,CAC3C,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,KAAK,GAAE,OAAO,CAAC,cAAc,CAAC,KAAsB,kBAMrD;AAED,wBAAsB,iBAAiB,CACrC,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,MAAM,iBAMnB;AAED,wBAAsB,iBAAiB,CACrC,KAAK,EAAE,MAAM,mBAGd;AAGD,wBAAsB,gCAAgC,CACpD,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,IAAI,CAAC,CAMf;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,OAAO,CAAC,cAAc,CAAC,KAAK,GAClC,OAAO,CAAC,IAAI,CAAC,CAKf;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,IAAI,CAAC,CAKf"}
1
+ {"version":3,"file":"browserTab.d.ts","sourceRoot":"","sources":["../src/browserTab.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,wBAAsB,qBAAqB,CACzC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,GAAG,GACX,OAAO,CAAC,IAAI,CAAC,CAKf;AAED,wBAAsB,wCAAwC,CAC5D,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,kBAMb;AAED,wBAAsB,oCAAoC,CACxD,KAAK,EAAE,MAAM,EACb,aAAa,EAAE,OAAO,CAAC,cAAc,CAAC,aAAa,kBAQpD;AAED,wBAAsB,uBAAuB,CAC3C,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,OAAO,CAAC,cAAc,CAAC,aAAa,kBAM9C;AAED,wBAAsB,iBAAiB,CACrC,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,MAAM,iBAMnB;AAED,wBAAsB,iBAAiB,CACrC,KAAK,EAAE,MAAM,mBAGd;AAED,wBAAsB,oCAAoC,CACxD,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,IAAI,CAAC,CAOf;AAED,wBAAsB,gCAAgC,CACpD,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,OAAO,CAAC,cAAc,CAAC,aAAa,GAC5C,OAAO,CAAC,IAAI,CAAC,CAOf;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,OAAO,CAAC,cAAc,CAAC,aAAa,GAC5C,OAAO,CAAC,IAAI,CAAC,CAKf;AAED,wBAAsB,uBAAuB,CAC3C,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,IAAI,CAAC,CAKf;AAED,wBAAsB,mBAAmB,CACvC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,OAAO,CAAC,cAAc,CAAC,aAAa,GAC5C,OAAO,CAAC,IAAI,CAAC,CAKf"}
@@ -4,11 +4,15 @@
4
4
  export async function browserTabSendMessage(tabId, message) {
5
5
  await browser.tabs.sendMessage(tabId, message);
6
6
  }
7
- export async function browserTabExecuteScriptDocumentStart(tabId, code) {
8
- return await browserTabExecuteScript(tabId, code, "document_start");
7
+ export async function browserTabExecuteScriptCodeDocumentStart(tabId, code) {
8
+ return browserTabExecuteScriptDocumentStart(tabId, { code });
9
9
  }
10
- export async function browserTabExecuteScript(tabId, code, runAt = "document_end") {
11
- return await browser.tabs.executeScript(tabId, { code, runAt });
10
+ export async function browserTabExecuteScriptDocumentStart(tabId, updateDetails) {
11
+ const details = { ...updateDetails, runAt: "document_start" };
12
+ return await browserTabExecuteScript(tabId, details);
13
+ }
14
+ export async function browserTabExecuteScript(tabId, details) {
15
+ return await browser.tabs.executeScript(tabId, details);
12
16
  }
13
17
  export async function browserTabSetZoom(tabId, zoomFactor) {
14
18
  return await browser.tabs.setZoom(tabId, zoomFactor);
@@ -16,18 +20,23 @@ export async function browserTabSetZoom(tabId, zoomFactor) {
16
20
  export async function browserTabGetZoom(tabId) {
17
21
  return await browser.tabs.getZoom(tabId);
18
22
  }
19
- export async function browserTabInsertCSSDocumentStart(tabId, code) {
20
- await browserTabInsertCSS(tabId, code, "document_start");
23
+ export async function browserTabInsertCSSCodeDocumentStart(tabId, code) {
24
+ const mergedDetails = { code };
25
+ await browserTabInsertCSSDocumentStart(tabId, mergedDetails);
26
+ }
27
+ export async function browserTabInsertCSSDocumentStart(tabId, details) {
28
+ const mergedDetails = { ...details, runAt: 'document_start' };
29
+ await browserTabInsertCSS(tabId, mergedDetails);
21
30
  }
22
31
  /**
23
32
  * Injects CSS code into a page.
24
33
  */
25
- export async function browserTabInsertCSS(tabId, code, runAt) {
26
- await browser.tabs.insertCSS(tabId, { code, runAt });
34
+ export async function browserTabInsertCSS(tabId, details) {
35
+ await browser.tabs.insertCSS(tabId, details);
27
36
  }
28
- /**
29
- * Removes CSS code that was previously injected into a page.
30
- */
31
- export async function browserTabRemoveCSS(tabId, code) {
32
- await browser.tabs.removeCSS(tabId, { code });
37
+ export async function browserTabRemoveCSSCode(tabId, code) {
38
+ await browserTabRemoveCSS(tabId, { code });
39
+ }
40
+ export async function browserTabRemoveCSS(tabId, details) {
41
+ await browser.tabs.removeCSS(tabId, details);
33
42
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vacantthinker/firefox-addon-framework-easy",
3
- "version": "2026.0613.1110",
3
+ "version": "2026.0613.1536",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",