@vacantthinker/firefox-addon-framework-easy 2026.613.1125 → 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
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vacantthinker/firefox-addon-framework-easy",
3
- "version": "2026.0613.1125",
3
+ "version": "2026.0613.1536",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",