@warlock.js/context 4.0.41 → 4.0.46

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/cjs/index.js CHANGED
@@ -1,194 +1,21 @@
1
1
  'use strict';
2
2
 
3
- var async_hooks = require('async_hooks');
3
+ var baseContext = require('./base-context');
4
+ var contextManager = require('./context-manager');
4
5
 
5
- // ../../warlock.js/context/src/base-context.ts
6
- var Context = class {
7
- storage = new async_hooks.AsyncLocalStorage();
8
- /**
9
- * Run a callback within a new context
10
- *
11
- * Creates a new async context with the provided store data.
12
- * All operations within the callback will have access to this context.
13
- *
14
- * @param store - Initial context data
15
- * @param callback - Async function to execute
16
- * @returns Result of the callback
17
- */
18
- run(store, callback) {
19
- return this.storage.run(store, callback);
20
- }
21
- /**
22
- * Enter a new context without a callback
23
- *
24
- * Useful for middleware where you want to set context for the rest of the request.
25
- * Unlike `run()`, this doesn't require a callback.
26
- *
27
- * @param store - Context data to set
28
- */
29
- enter(store) {
30
- this.storage.enterWith(store);
31
- }
32
- /**
33
- * Update the current context
34
- *
35
- * Merges new data into existing context, or enters new context if none exists.
36
- *
37
- * @param updates - Partial context data to merge
38
- */
39
- update(updates) {
40
- const current = this.storage.getStore();
41
- if (current) {
42
- Object.assign(current, updates);
43
- } else {
44
- this.enter(updates);
45
- }
46
- }
47
- /**
48
- * Get the current context store
49
- *
50
- * @returns Current context or undefined if not in context
51
- */
52
- getStore() {
53
- return this.storage.getStore();
54
- }
55
- /**
56
- * Get a specific value from context
57
- *
58
- * @param key - Key to retrieve
59
- * @returns Value or undefined
60
- */
61
- get(key) {
62
- return this.storage.getStore()?.[key];
63
- }
64
- /**
65
- * Set a specific value in context
66
- *
67
- * @param key - Key to set
68
- * @param value - Value to store
69
- */
70
- set(key, value) {
71
- this.update({ [key]: value });
72
- }
73
- /**
74
- * Clear the context
75
- */
76
- clear() {
77
- this.storage.enterWith({});
78
- }
79
- /**
80
- * Check if currently in a context
81
- */
82
- hasContext() {
83
- return this.storage.getStore() !== void 0;
84
- }
85
- };
86
6
 
87
- // ../../warlock.js/context/src/context-manager.ts
88
- var ContextManager = class {
89
- contexts = /* @__PURE__ */ new Map();
90
- /**
91
- * Register a context
92
- *
93
- * @param name - Unique context name
94
- * @param context - Context instance
95
- * @returns This instance for chaining
96
- */
97
- register(name, context) {
98
- this.contexts.set(name, context);
99
- return this;
100
- }
101
- /**
102
- * Run all registered contexts together
103
- *
104
- * Nests all context.run() calls, ensuring all contexts are active
105
- * for the duration of the callback.
106
- *
107
- * @param stores - Context stores keyed by context name
108
- * @param callback - Async function to execute
109
- * @returns Result of the callback
110
- */
111
- async runAll(stores, callback) {
112
- const entries = Array.from(this.contexts.entries());
113
- const runner = entries.reduceRight((next, [name, context]) => {
114
- return () => context.run(stores[name] || {}, next);
115
- }, callback);
116
- return runner();
117
- }
118
- /**
119
- * Enter all contexts at once (for middleware)
120
- *
121
- * @param stores - Context stores keyed by context name
122
- */
123
- enterAll(stores) {
124
- for (const [name, context] of this.contexts.entries()) {
125
- if (stores[name]) {
126
- context.enter(stores[name]);
127
- }
128
- }
129
- }
130
- /**
131
- * Clear all contexts
132
- */
133
- clearAll() {
134
- for (const context of this.contexts.values()) {
135
- context.clear();
136
- }
137
- }
138
- /**
139
- * Get a specific registered context
140
- *
141
- * @param name - Context name
142
- * @returns Context instance or undefined
143
- */
144
- getContext(name) {
145
- return this.contexts.get(name);
146
- }
147
- /**
148
- * Check if a context is registered
149
- *
150
- * @param name - Context name
151
- * @returns True if context is registered
152
- */
153
- hasContext(name) {
154
- return this.contexts.has(name);
155
- }
156
- /**
157
- * Build all context stores by calling each context's buildStore() method
158
- *
159
- * This is the immutable pattern - returns a new record of stores.
160
- * Each context defines its own initialization logic.
161
- *
162
- * @param payload - Payload passed to each buildStore() (e.g., { request, response })
163
- * @returns Record of context name -> store data
164
- *
165
- * @example
166
- * ```typescript
167
- * const httpContextStore = contextManager.buildStores({ request, response });
168
- * await contextManager.runAll(httpContextStore, async () => { ... });
169
- * ```
170
- */
171
- buildStores(payload) {
172
- const stores = {};
173
- for (const [name, context] of this.contexts.entries()) {
174
- stores[name] = context.buildStore(payload) ?? {};
175
- }
176
- return stores;
177
- }
178
- /**
179
- * Unregister a context
180
- *
181
- * @param name - Context name to remove
182
- * @returns True if context was removed
183
- */
184
- unregister(name) {
185
- return this.contexts.delete(name);
186
- }
187
- };
188
- var contextManager = new ContextManager();
189
7
 
190
- exports.Context = Context;
191
- exports.ContextManager = ContextManager;
192
- exports.contextManager = contextManager;
8
+ Object.keys(baseContext).forEach(function (k) {
9
+ if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
10
+ enumerable: true,
11
+ get: function () { return baseContext[k]; }
12
+ });
13
+ });
14
+ Object.keys(contextManager).forEach(function (k) {
15
+ if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
16
+ enumerable: true,
17
+ get: function () { return contextManager[k]; }
18
+ });
19
+ });
193
20
  //# sourceMappingURL=index.js.map
194
21
  //# sourceMappingURL=index.js.map
package/cjs/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../../warlock.js/context/src/base-context.ts","../../../../../../../warlock.js/context/src/context-manager.ts"],"names":["AsyncLocalStorage"],"mappings":"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","file":"index.js","sourcesContent":["import { AsyncLocalStorage } from \"async_hooks\";\n\n/**\n * Base class for all AsyncLocalStorage-based contexts\n *\n * Provides a consistent API for managing context across async operations.\n * All framework contexts (request, storage, database) extend this class.\n *\n * @template TStore - The type of data stored in context\n *\n * @example\n * ```typescript\n * interface MyContextStore {\n * userId: string;\n * tenant: string;\n * }\n *\n * class MyContext extends Context<MyContextStore> {}\n * const myContext = new MyContext();\n *\n * // Use it\n * await myContext.run({ userId: '123', tenant: 'acme' }, async () => {\n * const userId = myContext.get('userId'); // '123'\n * });\n * ```\n */\nexport abstract class Context<TStore extends Record<string, any>> {\n protected readonly storage: AsyncLocalStorage<TStore> = new AsyncLocalStorage<TStore>();\n\n /**\n * Run a callback within a new context\n *\n * Creates a new async context with the provided store data.\n * All operations within the callback will have access to this context.\n *\n * @param store - Initial context data\n * @param callback - Async function to execute\n * @returns Result of the callback\n */\n public run<T>(store: TStore, callback: () => Promise<T>): Promise<T> {\n return this.storage.run(store, callback);\n }\n\n /**\n * Enter a new context without a callback\n *\n * Useful for middleware where you want to set context for the rest of the request.\n * Unlike `run()`, this doesn't require a callback.\n *\n * @param store - Context data to set\n */\n public enter(store: TStore): void {\n this.storage.enterWith(store);\n }\n\n /**\n * Update the current context\n *\n * Merges new data into existing context, or enters new context if none exists.\n *\n * @param updates - Partial context data to merge\n */\n public update(updates: Partial<TStore>): void {\n const current = this.storage.getStore();\n\n if (current) {\n Object.assign(current, updates);\n } else {\n this.enter(updates as TStore);\n }\n }\n\n /**\n * Get the current context store\n *\n * @returns Current context or undefined if not in context\n */\n public getStore(): TStore | undefined {\n return this.storage.getStore();\n }\n\n /**\n * Get a specific value from context\n *\n * @param key - Key to retrieve\n * @returns Value or undefined\n */\n public get<K extends keyof TStore>(key: K): TStore[K] | undefined {\n return this.storage.getStore()?.[key];\n }\n\n /**\n * Set a specific value in context\n *\n * @param key - Key to set\n * @param value - Value to store\n */\n public set<K extends keyof TStore>(key: K, value: TStore[K]): void {\n this.update({ [key]: value } as any);\n }\n\n /**\n * Clear the context\n */\n public clear(): void {\n this.storage.enterWith({} as TStore);\n }\n\n /**\n * Check if currently in a context\n */\n public hasContext(): boolean {\n return this.storage.getStore() !== undefined;\n }\n\n /**\n * Build the initial store for this context\n *\n * Override this method to provide custom initialization logic.\n * Called by ContextManager.buildStores() for each registered context.\n *\n * @param payload - Generic payload (e.g., { request, response } for HTTP contexts)\n * @returns Initial store data\n */\n public abstract buildStore(payload?: Record<string, any>): TStore;\n}\n","import type { Context } from \"./base-context\";\n\n/**\n * Context Manager - Orchestrates multiple contexts together\n *\n * Allows running multiple AsyncLocalStorage contexts in a single operation,\n * making it easy to link request, storage, database, and other contexts.\n *\n * @example\n * ```typescript\n * // Register contexts\n * contextManager\n * .register('request', requestContext)\n * .register('storage', storageDriverContext)\n * .register('database', databaseDataSourceContext);\n *\n * // Run all contexts together\n * await contextManager.runAll({\n * request: { request, response, user },\n * storage: { driver, metadata: { tenantId: '123' } },\n * database: { dataSource: 'primary' },\n * }, async () => {\n * // All contexts active!\n * await handleRequest();\n * });\n * ```\n */\nexport class ContextManager {\n private contexts = new Map<string, Context<any>>();\n\n /**\n * Register a context\n *\n * @param name - Unique context name\n * @param context - Context instance\n * @returns This instance for chaining\n */\n public register(name: string, context: Context<any>): this {\n this.contexts.set(name, context);\n return this;\n }\n\n /**\n * Run all registered contexts together\n *\n * Nests all context.run() calls, ensuring all contexts are active\n * for the duration of the callback.\n *\n * @param stores - Context stores keyed by context name\n * @param callback - Async function to execute\n * @returns Result of the callback\n */\n public async runAll<T>(stores: Record<string, any>, callback: () => Promise<T>): Promise<T> {\n const entries = Array.from(this.contexts.entries());\n\n // Build nested context runners\n const runner = entries.reduceRight((next, [name, context]) => {\n return () => context.run(stores[name] || {}, next);\n }, callback);\n\n return runner();\n }\n\n /**\n * Enter all contexts at once (for middleware)\n *\n * @param stores - Context stores keyed by context name\n */\n public enterAll(stores: Record<string, any>): void {\n for (const [name, context] of this.contexts.entries()) {\n if (stores[name]) {\n context.enter(stores[name]);\n }\n }\n }\n\n /**\n * Clear all contexts\n */\n public clearAll(): void {\n for (const context of this.contexts.values()) {\n context.clear();\n }\n }\n\n /**\n * Get a specific registered context\n *\n * @param name - Context name\n * @returns Context instance or undefined\n */\n public getContext<T extends Context<any>>(name: string): T | undefined {\n return this.contexts.get(name) as T | undefined;\n }\n\n /**\n * Check if a context is registered\n *\n * @param name - Context name\n * @returns True if context is registered\n */\n public hasContext(name: string): boolean {\n return this.contexts.has(name);\n }\n\n /**\n * Build all context stores by calling each context's buildStore() method\n *\n * This is the immutable pattern - returns a new record of stores.\n * Each context defines its own initialization logic.\n *\n * @param payload - Payload passed to each buildStore() (e.g., { request, response })\n * @returns Record of context name -> store data\n *\n * @example\n * ```typescript\n * const httpContextStore = contextManager.buildStores({ request, response });\n * await contextManager.runAll(httpContextStore, async () => { ... });\n * ```\n */\n public buildStores(payload?: Record<string, any>): Record<string, any> {\n const stores: Record<string, any> = {};\n\n for (const [name, context] of this.contexts.entries()) {\n stores[name] = context.buildStore(payload) ?? {};\n }\n\n return stores;\n }\n\n /**\n * Unregister a context\n *\n * @param name - Context name to remove\n * @returns True if context was removed\n */\n public unregister(name: string): boolean {\n return this.contexts.delete(name);\n }\n}\n\n/**\n * Global context manager instance\n *\n * Use this singleton to register and manage all framework contexts.\n */\nexport const contextManager = new ContextManager();\n"]}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"index.js","sourcesContent":[]}
package/esm/index.js CHANGED
@@ -1,190 +1,4 @@
1
- import { AsyncLocalStorage } from 'async_hooks';
2
-
3
- // ../../warlock.js/context/src/base-context.ts
4
- var Context = class {
5
- storage = new AsyncLocalStorage();
6
- /**
7
- * Run a callback within a new context
8
- *
9
- * Creates a new async context with the provided store data.
10
- * All operations within the callback will have access to this context.
11
- *
12
- * @param store - Initial context data
13
- * @param callback - Async function to execute
14
- * @returns Result of the callback
15
- */
16
- run(store, callback) {
17
- return this.storage.run(store, callback);
18
- }
19
- /**
20
- * Enter a new context without a callback
21
- *
22
- * Useful for middleware where you want to set context for the rest of the request.
23
- * Unlike `run()`, this doesn't require a callback.
24
- *
25
- * @param store - Context data to set
26
- */
27
- enter(store) {
28
- this.storage.enterWith(store);
29
- }
30
- /**
31
- * Update the current context
32
- *
33
- * Merges new data into existing context, or enters new context if none exists.
34
- *
35
- * @param updates - Partial context data to merge
36
- */
37
- update(updates) {
38
- const current = this.storage.getStore();
39
- if (current) {
40
- Object.assign(current, updates);
41
- } else {
42
- this.enter(updates);
43
- }
44
- }
45
- /**
46
- * Get the current context store
47
- *
48
- * @returns Current context or undefined if not in context
49
- */
50
- getStore() {
51
- return this.storage.getStore();
52
- }
53
- /**
54
- * Get a specific value from context
55
- *
56
- * @param key - Key to retrieve
57
- * @returns Value or undefined
58
- */
59
- get(key) {
60
- return this.storage.getStore()?.[key];
61
- }
62
- /**
63
- * Set a specific value in context
64
- *
65
- * @param key - Key to set
66
- * @param value - Value to store
67
- */
68
- set(key, value) {
69
- this.update({ [key]: value });
70
- }
71
- /**
72
- * Clear the context
73
- */
74
- clear() {
75
- this.storage.enterWith({});
76
- }
77
- /**
78
- * Check if currently in a context
79
- */
80
- hasContext() {
81
- return this.storage.getStore() !== void 0;
82
- }
83
- };
84
-
85
- // ../../warlock.js/context/src/context-manager.ts
86
- var ContextManager = class {
87
- contexts = /* @__PURE__ */ new Map();
88
- /**
89
- * Register a context
90
- *
91
- * @param name - Unique context name
92
- * @param context - Context instance
93
- * @returns This instance for chaining
94
- */
95
- register(name, context) {
96
- this.contexts.set(name, context);
97
- return this;
98
- }
99
- /**
100
- * Run all registered contexts together
101
- *
102
- * Nests all context.run() calls, ensuring all contexts are active
103
- * for the duration of the callback.
104
- *
105
- * @param stores - Context stores keyed by context name
106
- * @param callback - Async function to execute
107
- * @returns Result of the callback
108
- */
109
- async runAll(stores, callback) {
110
- const entries = Array.from(this.contexts.entries());
111
- const runner = entries.reduceRight((next, [name, context]) => {
112
- return () => context.run(stores[name] || {}, next);
113
- }, callback);
114
- return runner();
115
- }
116
- /**
117
- * Enter all contexts at once (for middleware)
118
- *
119
- * @param stores - Context stores keyed by context name
120
- */
121
- enterAll(stores) {
122
- for (const [name, context] of this.contexts.entries()) {
123
- if (stores[name]) {
124
- context.enter(stores[name]);
125
- }
126
- }
127
- }
128
- /**
129
- * Clear all contexts
130
- */
131
- clearAll() {
132
- for (const context of this.contexts.values()) {
133
- context.clear();
134
- }
135
- }
136
- /**
137
- * Get a specific registered context
138
- *
139
- * @param name - Context name
140
- * @returns Context instance or undefined
141
- */
142
- getContext(name) {
143
- return this.contexts.get(name);
144
- }
145
- /**
146
- * Check if a context is registered
147
- *
148
- * @param name - Context name
149
- * @returns True if context is registered
150
- */
151
- hasContext(name) {
152
- return this.contexts.has(name);
153
- }
154
- /**
155
- * Build all context stores by calling each context's buildStore() method
156
- *
157
- * This is the immutable pattern - returns a new record of stores.
158
- * Each context defines its own initialization logic.
159
- *
160
- * @param payload - Payload passed to each buildStore() (e.g., { request, response })
161
- * @returns Record of context name -> store data
162
- *
163
- * @example
164
- * ```typescript
165
- * const httpContextStore = contextManager.buildStores({ request, response });
166
- * await contextManager.runAll(httpContextStore, async () => { ... });
167
- * ```
168
- */
169
- buildStores(payload) {
170
- const stores = {};
171
- for (const [name, context] of this.contexts.entries()) {
172
- stores[name] = context.buildStore(payload) ?? {};
173
- }
174
- return stores;
175
- }
176
- /**
177
- * Unregister a context
178
- *
179
- * @param name - Context name to remove
180
- * @returns True if context was removed
181
- */
182
- unregister(name) {
183
- return this.contexts.delete(name);
184
- }
185
- };
186
- var contextManager = new ContextManager();
187
-
188
- export { Context, ContextManager, contextManager };
1
+ export * from './base-context';
2
+ export * from './context-manager';
189
3
  //# sourceMappingURL=index.js.map
190
4
  //# sourceMappingURL=index.js.map
package/esm/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../../warlock.js/context/src/base-context.ts","../../../../../../../warlock.js/context/src/context-manager.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import { AsyncLocalStorage } from \"async_hooks\";\n\n/**\n * Base class for all AsyncLocalStorage-based contexts\n *\n * Provides a consistent API for managing context across async operations.\n * All framework contexts (request, storage, database) extend this class.\n *\n * @template TStore - The type of data stored in context\n *\n * @example\n * ```typescript\n * interface MyContextStore {\n * userId: string;\n * tenant: string;\n * }\n *\n * class MyContext extends Context<MyContextStore> {}\n * const myContext = new MyContext();\n *\n * // Use it\n * await myContext.run({ userId: '123', tenant: 'acme' }, async () => {\n * const userId = myContext.get('userId'); // '123'\n * });\n * ```\n */\nexport abstract class Context<TStore extends Record<string, any>> {\n protected readonly storage: AsyncLocalStorage<TStore> = new AsyncLocalStorage<TStore>();\n\n /**\n * Run a callback within a new context\n *\n * Creates a new async context with the provided store data.\n * All operations within the callback will have access to this context.\n *\n * @param store - Initial context data\n * @param callback - Async function to execute\n * @returns Result of the callback\n */\n public run<T>(store: TStore, callback: () => Promise<T>): Promise<T> {\n return this.storage.run(store, callback);\n }\n\n /**\n * Enter a new context without a callback\n *\n * Useful for middleware where you want to set context for the rest of the request.\n * Unlike `run()`, this doesn't require a callback.\n *\n * @param store - Context data to set\n */\n public enter(store: TStore): void {\n this.storage.enterWith(store);\n }\n\n /**\n * Update the current context\n *\n * Merges new data into existing context, or enters new context if none exists.\n *\n * @param updates - Partial context data to merge\n */\n public update(updates: Partial<TStore>): void {\n const current = this.storage.getStore();\n\n if (current) {\n Object.assign(current, updates);\n } else {\n this.enter(updates as TStore);\n }\n }\n\n /**\n * Get the current context store\n *\n * @returns Current context or undefined if not in context\n */\n public getStore(): TStore | undefined {\n return this.storage.getStore();\n }\n\n /**\n * Get a specific value from context\n *\n * @param key - Key to retrieve\n * @returns Value or undefined\n */\n public get<K extends keyof TStore>(key: K): TStore[K] | undefined {\n return this.storage.getStore()?.[key];\n }\n\n /**\n * Set a specific value in context\n *\n * @param key - Key to set\n * @param value - Value to store\n */\n public set<K extends keyof TStore>(key: K, value: TStore[K]): void {\n this.update({ [key]: value } as any);\n }\n\n /**\n * Clear the context\n */\n public clear(): void {\n this.storage.enterWith({} as TStore);\n }\n\n /**\n * Check if currently in a context\n */\n public hasContext(): boolean {\n return this.storage.getStore() !== undefined;\n }\n\n /**\n * Build the initial store for this context\n *\n * Override this method to provide custom initialization logic.\n * Called by ContextManager.buildStores() for each registered context.\n *\n * @param payload - Generic payload (e.g., { request, response } for HTTP contexts)\n * @returns Initial store data\n */\n public abstract buildStore(payload?: Record<string, any>): TStore;\n}\n","import type { Context } from \"./base-context\";\n\n/**\n * Context Manager - Orchestrates multiple contexts together\n *\n * Allows running multiple AsyncLocalStorage contexts in a single operation,\n * making it easy to link request, storage, database, and other contexts.\n *\n * @example\n * ```typescript\n * // Register contexts\n * contextManager\n * .register('request', requestContext)\n * .register('storage', storageDriverContext)\n * .register('database', databaseDataSourceContext);\n *\n * // Run all contexts together\n * await contextManager.runAll({\n * request: { request, response, user },\n * storage: { driver, metadata: { tenantId: '123' } },\n * database: { dataSource: 'primary' },\n * }, async () => {\n * // All contexts active!\n * await handleRequest();\n * });\n * ```\n */\nexport class ContextManager {\n private contexts = new Map<string, Context<any>>();\n\n /**\n * Register a context\n *\n * @param name - Unique context name\n * @param context - Context instance\n * @returns This instance for chaining\n */\n public register(name: string, context: Context<any>): this {\n this.contexts.set(name, context);\n return this;\n }\n\n /**\n * Run all registered contexts together\n *\n * Nests all context.run() calls, ensuring all contexts are active\n * for the duration of the callback.\n *\n * @param stores - Context stores keyed by context name\n * @param callback - Async function to execute\n * @returns Result of the callback\n */\n public async runAll<T>(stores: Record<string, any>, callback: () => Promise<T>): Promise<T> {\n const entries = Array.from(this.contexts.entries());\n\n // Build nested context runners\n const runner = entries.reduceRight((next, [name, context]) => {\n return () => context.run(stores[name] || {}, next);\n }, callback);\n\n return runner();\n }\n\n /**\n * Enter all contexts at once (for middleware)\n *\n * @param stores - Context stores keyed by context name\n */\n public enterAll(stores: Record<string, any>): void {\n for (const [name, context] of this.contexts.entries()) {\n if (stores[name]) {\n context.enter(stores[name]);\n }\n }\n }\n\n /**\n * Clear all contexts\n */\n public clearAll(): void {\n for (const context of this.contexts.values()) {\n context.clear();\n }\n }\n\n /**\n * Get a specific registered context\n *\n * @param name - Context name\n * @returns Context instance or undefined\n */\n public getContext<T extends Context<any>>(name: string): T | undefined {\n return this.contexts.get(name) as T | undefined;\n }\n\n /**\n * Check if a context is registered\n *\n * @param name - Context name\n * @returns True if context is registered\n */\n public hasContext(name: string): boolean {\n return this.contexts.has(name);\n }\n\n /**\n * Build all context stores by calling each context's buildStore() method\n *\n * This is the immutable pattern - returns a new record of stores.\n * Each context defines its own initialization logic.\n *\n * @param payload - Payload passed to each buildStore() (e.g., { request, response })\n * @returns Record of context name -> store data\n *\n * @example\n * ```typescript\n * const httpContextStore = contextManager.buildStores({ request, response });\n * await contextManager.runAll(httpContextStore, async () => { ... });\n * ```\n */\n public buildStores(payload?: Record<string, any>): Record<string, any> {\n const stores: Record<string, any> = {};\n\n for (const [name, context] of this.contexts.entries()) {\n stores[name] = context.buildStore(payload) ?? {};\n }\n\n return stores;\n }\n\n /**\n * Unregister a context\n *\n * @param name - Context name to remove\n * @returns True if context was removed\n */\n public unregister(name: string): boolean {\n return this.contexts.delete(name);\n }\n}\n\n/**\n * Global context manager instance\n *\n * Use this singleton to register and manage all framework contexts.\n */\nexport const contextManager = new ContextManager();\n"]}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"index.js","sourcesContent":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@warlock.js/context",
3
- "version": "4.0.41",
3
+ "version": "4.0.46",
4
4
  "description": "A simple and unified way to share context using AsyncLocalStorage for the Warlock.js framework",
5
5
  "keywords": [
6
6
  "warlock",