@twin.org/context 0.9.1-next.1 → 0.9.1-next.3

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.
@@ -1,4 +1,4 @@
1
- import { BaseError, GeneralError, Is, SharedStore } from "@twin.org/core";
1
+ import { BaseError, GeneralError, SharedStore } from "@twin.org/core";
2
2
  /**
3
3
  * Class to maintain context ids and execute an async method.
4
4
  */
@@ -30,21 +30,21 @@ export class ContextIdStore {
30
30
  * @returns The storage.
31
31
  */
32
32
  static async getStorage() {
33
- let asyncHooksStore = SharedStore.get("asyncHooks");
34
- if (Is.empty(asyncHooksStore?.contextIds)) {
33
+ // get with the factory is invoked synchronously and stores the returned
34
+ // Promise before yielding, so concurrent callers always await the same
35
+ // AsyncLocalStorage instance regardless of how many module versions are loaded.
36
+ return SharedStore.get("asyncHooks", async () => {
35
37
  try {
36
38
  const hooks = await import("node:async_hooks");
37
- asyncHooksStore = asyncHooksStore ?? {};
38
- asyncHooksStore.contextIds = new hooks.AsyncLocalStorage({
39
+ return new hooks.AsyncLocalStorage({
39
40
  name: "AsyncContextIdsStorage"
40
41
  });
41
42
  }
42
43
  catch (err) {
44
+ SharedStore.remove("asyncHooks");
43
45
  throw new GeneralError(ContextIdStore.CLASS_NAME, "asyncHooksNotAvailable", undefined, BaseError.fromError(err));
44
46
  }
45
- SharedStore.set("asyncHooks", asyncHooksStore);
46
- }
47
- return asyncHooksStore.contextIds;
47
+ });
48
48
  }
49
49
  }
50
50
  //# sourceMappingURL=contextIdStore.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"contextIdStore.js","sourceRoot":"","sources":["../../../src/utils/contextIdStore.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,EAAE,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAI1E;;GAEG;AACH,MAAM,OAAO,cAAc;IAC1B;;OAEG;IACI,MAAM,CAAU,UAAU,oBAAoC;IAErE;;;;;OAKG;IACI,MAAM,CAAC,KAAK,CAAC,GAAG,CAAc,UAAuB,EAAE,WAAoB;QACjF,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,UAAU,EAAE,CAAC;QAClD,OAAO,OAAO,CAAC,GAAG,CAAI,UAAU,EAAE,WAAW,CAAC,CAAC;IAChD,CAAC;IAED;;;OAGG;IACI,MAAM,CAAC,KAAK,CAAC,aAAa;QAChC,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,UAAU,EAAE,CAAC;QAClD,OAAO,OAAO,CAAC,QAAQ,EAAE,CAAC;IAC3B,CAAC;IAED;;;OAGG;IACI,MAAM,CAAC,KAAK,CAAC,UAAU;QAC7B,IAAI,eAAe,GAAG,WAAW,CAAC,GAAG,CACpC,YAAY,CACZ,CAAC;QAEF,IAAI,EAAE,CAAC,KAAK,CAAC,eAAe,EAAE,UAAU,CAAC,EAAE,CAAC;YAC3C,IAAI,CAAC;gBACJ,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAC;gBAC/C,eAAe,GAAG,eAAe,IAAI,EAAE,CAAC;gBACxC,eAAe,CAAC,UAAU,GAAG,IAAI,KAAK,CAAC,iBAAiB,CAAc;oBACrE,IAAI,EAAE,wBAAwB;iBAC9B,CAAC,CAAC;YACJ,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACd,MAAM,IAAI,YAAY,CACrB,cAAc,CAAC,UAAU,EACzB,wBAAwB,EACxB,SAAS,EACT,SAAS,CAAC,SAAS,CAAC,GAAG,CAAC,CACxB,CAAC;YACH,CAAC;YACD,WAAW,CAAC,GAAG,CAAC,YAAY,EAAE,eAAe,CAAC,CAAC;QAChD,CAAC;QACD,OAAO,eAAe,CAAC,UAAU,CAAC;IACnC,CAAC","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport type { AsyncLocalStorage } from \"node:async_hooks\";\nimport { BaseError, GeneralError, Is, SharedStore } from \"@twin.org/core\";\nimport { nameof } from \"@twin.org/nameof\";\nimport type { IContextIds } from \"../models/IContextIds.js\";\n\n/**\n * Class to maintain context ids and execute an async method.\n */\nexport class ContextIdStore {\n\t/**\n\t * Runtime name for the class.\n\t */\n\tpublic static readonly CLASS_NAME: string = nameof<ContextIdStore>();\n\n\t/**\n\t * Execute the method wrapped in the context.\n\t * @param contextIds The context IDs.\n\t * @param asyncMethod The async method to run.\n\t * @returns A promise that resolves with the result of the async method.\n\t */\n\tpublic static async run<T = unknown>(contextIds: IContextIds, asyncMethod: () => T): Promise<T> {\n\t\tconst storage = await ContextIdStore.getStorage();\n\t\treturn storage.run<T>(contextIds, asyncMethod);\n\t}\n\n\t/**\n\t * Get the context IDs.\n\t * @returns The context IDs.\n\t */\n\tpublic static async getContextIds(): Promise<IContextIds | undefined> {\n\t\tconst storage = await ContextIdStore.getStorage();\n\t\treturn storage.getStore();\n\t}\n\n\t/**\n\t * Get the storage and create it if it doesn't exist.\n\t * @returns The storage.\n\t */\n\tpublic static async getStorage(): Promise<AsyncLocalStorage<IContextIds>> {\n\t\tlet asyncHooksStore = SharedStore.get<{ contextIds?: AsyncLocalStorage<IContextIds> }>(\n\t\t\t\"asyncHooks\"\n\t\t);\n\n\t\tif (Is.empty(asyncHooksStore?.contextIds)) {\n\t\t\ttry {\n\t\t\t\tconst hooks = await import(\"node:async_hooks\");\n\t\t\t\tasyncHooksStore = asyncHooksStore ?? {};\n\t\t\t\tasyncHooksStore.contextIds = new hooks.AsyncLocalStorage<IContextIds>({\n\t\t\t\t\tname: \"AsyncContextIdsStorage\"\n\t\t\t\t});\n\t\t\t} catch (err) {\n\t\t\t\tthrow new GeneralError(\n\t\t\t\t\tContextIdStore.CLASS_NAME,\n\t\t\t\t\t\"asyncHooksNotAvailable\",\n\t\t\t\t\tundefined,\n\t\t\t\t\tBaseError.fromError(err)\n\t\t\t\t);\n\t\t\t}\n\t\t\tSharedStore.set(\"asyncHooks\", asyncHooksStore);\n\t\t}\n\t\treturn asyncHooksStore.contextIds;\n\t}\n}\n"]}
1
+ {"version":3,"file":"contextIdStore.js","sourceRoot":"","sources":["../../../src/utils/contextIdStore.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAItE;;GAEG;AACH,MAAM,OAAO,cAAc;IAC1B;;OAEG;IACI,MAAM,CAAU,UAAU,oBAAoC;IAErE;;;;;OAKG;IACI,MAAM,CAAC,KAAK,CAAC,GAAG,CAAc,UAAuB,EAAE,WAAoB;QACjF,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,UAAU,EAAE,CAAC;QAClD,OAAO,OAAO,CAAC,GAAG,CAAI,UAAU,EAAE,WAAW,CAAC,CAAC;IAChD,CAAC;IAED;;;OAGG;IACI,MAAM,CAAC,KAAK,CAAC,aAAa;QAChC,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,UAAU,EAAE,CAAC;QAClD,OAAO,OAAO,CAAC,QAAQ,EAAE,CAAC;IAC3B,CAAC;IAED;;;OAGG;IACI,MAAM,CAAC,KAAK,CAAC,UAAU;QAC7B,wEAAwE;QACxE,uEAAuE;QACvE,gFAAgF;QAChF,OAAO,WAAW,CAAC,GAAG,CAA0C,YAAY,EAAE,KAAK,IAAI,EAAE;YACxF,IAAI,CAAC;gBACJ,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAC;gBAC/C,OAAO,IAAI,KAAK,CAAC,iBAAiB,CAAc;oBAC/C,IAAI,EAAE,wBAAwB;iBAC9B,CAAC,CAAC;YACJ,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACd,WAAW,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;gBACjC,MAAM,IAAI,YAAY,CACrB,cAAc,CAAC,UAAU,EACzB,wBAAwB,EACxB,SAAS,EACT,SAAS,CAAC,SAAS,CAAC,GAAG,CAAC,CACxB,CAAC;YACH,CAAC;QACF,CAAC,CAAC,CAAC;IACJ,CAAC","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport type { AsyncLocalStorage } from \"node:async_hooks\";\nimport { BaseError, GeneralError, SharedStore } from \"@twin.org/core\";\nimport { nameof } from \"@twin.org/nameof\";\nimport type { IContextIds } from \"../models/IContextIds.js\";\n\n/**\n * Class to maintain context ids and execute an async method.\n */\nexport class ContextIdStore {\n\t/**\n\t * Runtime name for the class.\n\t */\n\tpublic static readonly CLASS_NAME: string = nameof<ContextIdStore>();\n\n\t/**\n\t * Execute the method wrapped in the context.\n\t * @param contextIds The context IDs.\n\t * @param asyncMethod The async method to run.\n\t * @returns A promise that resolves with the result of the async method.\n\t */\n\tpublic static async run<T = unknown>(contextIds: IContextIds, asyncMethod: () => T): Promise<T> {\n\t\tconst storage = await ContextIdStore.getStorage();\n\t\treturn storage.run<T>(contextIds, asyncMethod);\n\t}\n\n\t/**\n\t * Get the context IDs.\n\t * @returns The context IDs.\n\t */\n\tpublic static async getContextIds(): Promise<IContextIds | undefined> {\n\t\tconst storage = await ContextIdStore.getStorage();\n\t\treturn storage.getStore();\n\t}\n\n\t/**\n\t * Get the storage and create it if it doesn't exist.\n\t * @returns The storage.\n\t */\n\tpublic static async getStorage(): Promise<AsyncLocalStorage<IContextIds>> {\n\t\t// get with the factory is invoked synchronously and stores the returned\n\t\t// Promise before yielding, so concurrent callers always await the same\n\t\t// AsyncLocalStorage instance regardless of how many module versions are loaded.\n\t\treturn SharedStore.get<Promise<AsyncLocalStorage<IContextIds>>>(\"asyncHooks\", async () => {\n\t\t\ttry {\n\t\t\t\tconst hooks = await import(\"node:async_hooks\");\n\t\t\t\treturn new hooks.AsyncLocalStorage<IContextIds>({\n\t\t\t\t\tname: \"AsyncContextIdsStorage\"\n\t\t\t\t});\n\t\t\t} catch (err) {\n\t\t\t\tSharedStore.remove(\"asyncHooks\");\n\t\t\t\tthrow new GeneralError(\n\t\t\t\t\tContextIdStore.CLASS_NAME,\n\t\t\t\t\t\"asyncHooksNotAvailable\",\n\t\t\t\t\tundefined,\n\t\t\t\t\tBaseError.fromError(err)\n\t\t\t\t);\n\t\t\t}\n\t\t});\n\t}\n}\n"]}
package/docs/changelog.md CHANGED
@@ -1,5 +1,55 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.9.1-next.3](https://github.com/iotaledger/twin-framework/compare/context-v0.9.1-next.2...context-v0.9.1-next.3) (2026-06-26)
4
+
5
+
6
+ ### Features
7
+
8
+ * add context id features ([#206](https://github.com/iotaledger/twin-framework/issues/206)) ([ef0d4ee](https://github.com/iotaledger/twin-framework/commit/ef0d4ee11a4f5fc6cc6f52a4958ce905c04ee13b))
9
+ * add user organization context key ([a3da436](https://github.com/iotaledger/twin-framework/commit/a3da4360451860052a508bdc147255a0b9ca8410))
10
+ * concurrency in SharedStore ([#388](https://github.com/iotaledger/twin-framework/issues/388)) ([0610198](https://github.com/iotaledger/twin-framework/commit/0610198ba482273c3f6ba918e34f5875a3659571))
11
+ * context id handler derives from component ([c868ec2](https://github.com/iotaledger/twin-framework/commit/c868ec21d3a576d4faa222bf130270a21936e50e))
12
+ * typescript 6 update ([1d10f31](https://github.com/iotaledger/twin-framework/commit/1d10f31e6516ec622773f45e88af82fe749b384a))
13
+ * update dependencies ([4da77ab](https://github.com/iotaledger/twin-framework/commit/4da77ab30f499e52825ac5a76f51436ceb59c26e))
14
+
15
+
16
+ ### Bug Fixes
17
+
18
+ * ensure __decorate is defined for decorators ([103a563](https://github.com/iotaledger/twin-framework/commit/103a563ce01ebdef6240d2e590e7b026e8692684))
19
+ * use singleton pattern for context storage ([c69f358](https://github.com/iotaledger/twin-framework/commit/c69f358e45361b45d4e46f19846cd5b8c99b0ccd))
20
+ * use singleton pattern for context storage ([5cc706a](https://github.com/iotaledger/twin-framework/commit/5cc706a2bbfc601fa3d00f3efd8b764052e9f91d))
21
+
22
+
23
+ ### Dependencies
24
+
25
+ * The following workspace dependencies were updated
26
+ * dependencies
27
+ * @twin.org/core bumped from 0.9.1-next.2 to 0.9.1-next.3
28
+ * @twin.org/nameof bumped from 0.9.1-next.2 to 0.9.1-next.3
29
+ * devDependencies
30
+ * @twin.org/nameof-transformer bumped from 0.9.1-next.2 to 0.9.1-next.3
31
+ * @twin.org/nameof-vitest-plugin bumped from 0.9.1-next.2 to 0.9.1-next.3
32
+ * @twin.org/validate-locales bumped from 0.9.1-next.2 to 0.9.1-next.3
33
+
34
+ ## [0.9.1-next.2](https://github.com/iotaledger/twin-framework/compare/context-v0.9.1-next.1...context-v0.9.1-next.2) (2026-06-26)
35
+
36
+
37
+ ### Features
38
+
39
+ * concurrency in SharedStore ([#388](https://github.com/iotaledger/twin-framework/issues/388)) ([0610198](https://github.com/iotaledger/twin-framework/commit/0610198ba482273c3f6ba918e34f5875a3659571))
40
+
41
+
42
+ ### Dependencies
43
+
44
+ * The following workspace dependencies were updated
45
+ * dependencies
46
+ * @twin.org/core bumped from 0.9.1-next.1 to 0.9.1-next.2
47
+ * @twin.org/nameof bumped from 0.9.1-next.1 to 0.9.1-next.2
48
+ * devDependencies
49
+ * @twin.org/nameof-transformer bumped from 0.9.1-next.1 to 0.9.1-next.2
50
+ * @twin.org/nameof-vitest-plugin bumped from 0.9.1-next.1 to 0.9.1-next.2
51
+ * @twin.org/validate-locales bumped from 0.9.1-next.1 to 0.9.1-next.2
52
+
3
53
  ## [0.9.1-next.1](https://github.com/iotaledger/twin-framework/compare/context-v0.9.1-next.0...context-v0.9.1-next.1) (2026-06-25)
4
54
 
5
55
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@twin.org/context",
3
- "version": "0.9.1-next.1",
3
+ "version": "0.9.1-next.3",
4
4
  "description": "Helper methods/classes for context handling",
5
5
  "repository": {
6
6
  "type": "git",
@@ -14,8 +14,8 @@
14
14
  "node": ">=20.0.0"
15
15
  },
16
16
  "dependencies": {
17
- "@twin.org/core": "0.9.1-next.1",
18
- "@twin.org/nameof": "0.9.1-next.1"
17
+ "@twin.org/core": "0.9.1-next.3",
18
+ "@twin.org/nameof": "0.9.1-next.3"
19
19
  },
20
20
  "main": "./dist/es/index.js",
21
21
  "types": "./dist/types/index.d.ts",