@yongdall/context 0.1.0

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/index.d.mts ADDED
@@ -0,0 +1,122 @@
1
+ //#region packages/context/index.d.mts
2
+ /**
3
+ * 创建一个存储单元
4
+ * @template T
5
+ * @overload
6
+ * @param {T} def
7
+ * @returns {[() => T, (v: T) => boolean]}
8
+ */
9
+ declare function createStore<T>(def: T): [() => T, (v: T) => boolean];
10
+ /**
11
+ * 创建一个存储单元
12
+ * @template T
13
+ * @overload
14
+ * @param {T} [def]
15
+ * @returns {[() => T | undefined, (v: T) => boolean]}
16
+ */
17
+ declare function createStore<T>(def?: T | undefined): [() => T | undefined, (v: T) => boolean];
18
+ /**
19
+ * @template T
20
+ * @param {() => T} fn
21
+ * @returns {() => T}
22
+ */
23
+ declare function createComputed<T>(fn: () => T): () => T;
24
+ /**
25
+ * 创建一个存储单元
26
+ * @template T
27
+ * @template TS
28
+ * @overload
29
+ * @param {string} name
30
+ * @param {(data: T) => TS | PromiseLike<TS>} serialize
31
+ * @param {(data: TS) => T | PromiseLike<T>} deserialize
32
+ * @param {T} def
33
+ * @returns {[() => T, (v: T) => boolean]}
34
+ */
35
+ declare function createStoreSerializable<T, TS>(name: string, serialize: (data: T) => TS | PromiseLike<TS>, deserialize: (data: TS) => T | PromiseLike<T>, def: T): [() => T, (v: T) => boolean];
36
+ /**
37
+ * 创建一个存储单元
38
+ * @template T
39
+ * @template TS
40
+ * @overload
41
+ * @param {string} name
42
+ * @param {(data: T) => TS | PromiseLike<TS>} serialize
43
+ * @param {(data: TS) => T | PromiseLike<T>} deserialize
44
+ * @param {T} [def]
45
+ * @returns {[() => T | undefined, (v: T) => boolean]}
46
+ */
47
+ declare function createStoreSerializable<T, TS>(name: string, serialize: (data: T) => TS | PromiseLike<TS>, deserialize: (data: TS) => T | PromiseLike<T>, def?: T | undefined): [() => T | undefined, (v: T) => boolean];
48
+ declare function serialize(): Promise<Record<string, any> | null>;
49
+ /**
50
+ *
51
+ * @param {Record<string, any>} data
52
+ */
53
+ declare function deserialize(data: Record<string, any>): Promise<void>;
54
+ /**
55
+ * @template {object} T
56
+ * @param {() => T} fn
57
+ */
58
+ declare function createOnceStore<T extends object>(fn: () => T): () => T;
59
+ /**
60
+ * @template {(...args: any) => any} T
61
+ * @param {T} fn
62
+ * @param {(...p: Parameters<T>) => string} getKey
63
+ * @param {(...p: Parameters<T>) => boolean} [isForce]
64
+ * @returns {T}
65
+ */
66
+ declare function createKeyStore<T extends (...args: any) => any>(fn: T, getKey: (...p: Parameters<T>) => string, isForce?: (...p: Parameters<T>) => boolean): T;
67
+ /**
68
+ * 是否存在上下文
69
+ * @param {boolean} [must]
70
+ * @returns {boolean}
71
+ */
72
+ declare function has(must?: boolean): boolean;
73
+ /**
74
+ * 创建一个上下文函数列表
75
+ * @template {*[]} T
76
+ * @returns {[(fn: (...v: T) => Promise<void> | void) => (() => void) | undefined, (...v: T) => void | Promise<void>]}
77
+ */
78
+ declare function createFnList<T extends any[]>(): [(fn: (...v: T) => Promise<void> | void) => (() => void) | undefined, (...v: T) => void | Promise<void>];
79
+ /**
80
+ * @template T
81
+ * @template {*[]} TArgs
82
+ * @param {Env} env
83
+ * @param {(...args: TArgs) => PromiseLike<T> | T} fn
84
+ * @param {TArgs} args
85
+ * @returns {Promise<T>}
86
+ */
87
+ declare function _run<T, TArgs extends any[]>(env: Env, fn: (...args: TArgs) => PromiseLike<T> | T, ...args: TArgs): Promise<T>;
88
+ /**
89
+ *
90
+ * @returns {Env}
91
+ */
92
+ declare function getEnv(): Env;
93
+ declare function getDomain(): string;
94
+ /**
95
+ * @template T
96
+ * @template {*[]} TArgs
97
+ * @param {(...args: TArgs) => T} fn
98
+ * @param {TArgs} args
99
+ * @returns {T}
100
+ */
101
+ declare function parentRun<T, TArgs extends any[]>(fn: (...args: TArgs) => T, ...args: TArgs): T;
102
+ /**
103
+ *
104
+ * @param {string} key
105
+ * @param {any} [value]
106
+ * @returns
107
+ */
108
+ declare function setState(key: string, value?: any): void;
109
+ /**
110
+ *
111
+ * @param {string} key
112
+ * @returns
113
+ */
114
+ declare function getState(key: string): any;
115
+ type Env = {
116
+ domain: string;
117
+ };
118
+ declare const addDone: (fn: (...v: any[]) => Promise<void> | void) => (() => void) | undefined;
119
+ declare const addCatch: (fn: (...v: any[]) => Promise<void> | void) => (() => void) | undefined;
120
+ declare const addFinally: (fn: (...v: any[]) => Promise<void> | void) => (() => void) | undefined;
121
+ //#endregion
122
+ export { Env, _run, addCatch, addDone, addFinally, createComputed, createFnList, createKeyStore, createOnceStore, createStore, createStoreSerializable, deserialize, getDomain, getEnv, getState, has, parentRun, serialize, setState };
package/index.mjs ADDED
@@ -0,0 +1,329 @@
1
+ import { AsyncLocalStorage } from "node:async_hooks";
2
+
3
+ //#region packages/context/index.mjs
4
+ const asyncLocalStorage = new AsyncLocalStorage();
5
+ const parentKey = Symbol();
6
+ const envKey = Symbol();
7
+ /**
8
+ * 创建一个存储单元
9
+ * @template T
10
+ * @overload
11
+ * @param {T} def
12
+ * @returns {[() => T, (v: T) => boolean]}
13
+ */
14
+ /**
15
+ * 创建一个存储单元
16
+ * @template T
17
+ * @overload
18
+ * @param {T} [def]
19
+ * @returns {[() => T | undefined, (v: T) => boolean]}
20
+ */
21
+ /**
22
+ * 创建一个存储单元
23
+ * @template T
24
+ * @param {T} [def]
25
+ * @returns {[() => T | undefined, (v: T) => boolean]}
26
+ */
27
+ function createStore(def) {
28
+ const symbol = Symbol();
29
+ function get() {
30
+ const state = asyncLocalStorage.getStore();
31
+ if (state && symbol in state) return state[symbol];
32
+ return def;
33
+ }
34
+ /**
35
+ *
36
+ * @param {T} v
37
+ * @returns
38
+ */
39
+ function set(v) {
40
+ const state = asyncLocalStorage.getStore();
41
+ if (!state) return false;
42
+ state[symbol] = v;
43
+ return true;
44
+ }
45
+ return [get, set];
46
+ }
47
+ /**
48
+ * @template T
49
+ * @param {() => T} fn
50
+ * @returns {() => T}
51
+ */
52
+ function createComputed(fn) {
53
+ const symbol = Symbol();
54
+ return () => {
55
+ const state = asyncLocalStorage.getStore();
56
+ if (!state) return fn();
57
+ if (symbol in state) return state[symbol];
58
+ const v = fn();
59
+ state[symbol] = v;
60
+ return v;
61
+ };
62
+ }
63
+ /** @type {Record<symbol, [string, (data: any) => any]>} */
64
+ const allSerialize = Object.create(null);
65
+ /** @type {Record<string, [symbol, (data: any) => any]>} */
66
+ const allDeserialize = Object.create(null);
67
+ /**
68
+ * 创建一个存储单元
69
+ * @template T
70
+ * @template TS
71
+ * @overload
72
+ * @param {string} name
73
+ * @param {(data: T) => TS | PromiseLike<TS>} serialize
74
+ * @param {(data: TS) => T | PromiseLike<T>} deserialize
75
+ * @param {T} def
76
+ * @returns {[() => T, (v: T) => boolean]}
77
+ */
78
+ /**
79
+ * 创建一个存储单元
80
+ * @template T
81
+ * @template TS
82
+ * @overload
83
+ * @param {string} name
84
+ * @param {(data: T) => TS | PromiseLike<TS>} serialize
85
+ * @param {(data: TS) => T | PromiseLike<T>} deserialize
86
+ * @param {T} [def]
87
+ * @returns {[() => T | undefined, (v: T) => boolean]}
88
+ */
89
+ /**
90
+ * 创建一个存储单元
91
+ * @template T
92
+ * @template TS
93
+ * @param {string} name
94
+ * @param {(data: T) => TS | PromiseLike<TS>} serialize
95
+ * @param {(data: TS) => T | PromiseLike<T>} deserialize
96
+ * @param {T} [def]
97
+ * @returns {[() => T | undefined, (v: T) => boolean]}
98
+ */
99
+ function createStoreSerializable(name, serialize, deserialize, def) {
100
+ const symbol = Symbol();
101
+ allSerialize[symbol] = [name, serialize];
102
+ allDeserialize[name] = [symbol, deserialize];
103
+ function get() {
104
+ const state = asyncLocalStorage.getStore();
105
+ if (state && symbol in state) return state[symbol];
106
+ return def;
107
+ }
108
+ /**
109
+ *
110
+ * @param {T} v
111
+ * @returns
112
+ */
113
+ function set(v) {
114
+ const state = asyncLocalStorage.getStore();
115
+ if (!state) return false;
116
+ state[symbol] = v;
117
+ return true;
118
+ }
119
+ return [get, set];
120
+ }
121
+ async function serialize() {
122
+ const state = asyncLocalStorage.getStore();
123
+ if (!state) return null;
124
+ /** @type {Record<string, any>} */
125
+ const data = {};
126
+ for (const [symbol, [name, serialize]] of Object.entries(allSerialize)) {
127
+ const value = state[symbol];
128
+ if (value === void 0) continue;
129
+ data[name] = await serialize(value);
130
+ }
131
+ return data;
132
+ }
133
+ /**
134
+ *
135
+ * @param {Record<string, any>} data
136
+ */
137
+ async function deserialize(data) {
138
+ const state = asyncLocalStorage.getStore();
139
+ if (!state) return;
140
+ for (const [name, value] of Object.entries(data)) {
141
+ if (data === void 0) continue;
142
+ const f = allDeserialize[name];
143
+ if (!f) continue;
144
+ const [symbol, deserialize] = f;
145
+ state[symbol] = await deserialize(value);
146
+ }
147
+ }
148
+ /**
149
+ * @template {object} T
150
+ * @param {() => T} fn
151
+ */
152
+ function createOnceStore(fn) {
153
+ const [getter, setter] = createStore(null);
154
+ /**
155
+ * @returns {T}
156
+ */
157
+ return function() {
158
+ const p = getter();
159
+ if (p) return p;
160
+ const result = fn();
161
+ setter(result);
162
+ return result;
163
+ };
164
+ }
165
+ /**
166
+ * @template {(...args: any) => any} T
167
+ * @param {T} fn
168
+ * @param {(...p: Parameters<T>) => string} getKey
169
+ * @param {(...p: Parameters<T>) => boolean} [isForce]
170
+ * @returns {T}
171
+ */
172
+ function createKeyStore(fn, getKey, isForce) {
173
+ const [getter, setter] = createStore(null);
174
+ /**
175
+ * @param {Parameters<T>} params
176
+ * @returns {ReturnType<T>}
177
+ */
178
+ function run(...params) {
179
+ let p = getter();
180
+ if (!p) {
181
+ p = {};
182
+ setter(p);
183
+ }
184
+ const key = getKey(...params);
185
+ if (Object.hasOwn(p, key) && !isForce?.(...params)) return p[key];
186
+ const result = fn(...params);
187
+ p[key] = result;
188
+ return result;
189
+ }
190
+ return run;
191
+ }
192
+ /**
193
+ * 是否存在上下文
194
+ * @param {boolean} [must]
195
+ * @returns {boolean}
196
+ */
197
+ function has(must) {
198
+ if (asyncLocalStorage.getStore()) return true;
199
+ if (must) throw new Error("不在上下文中");
200
+ return false;
201
+ }
202
+ /**
203
+ * 创建一个上下文函数列表
204
+ * @template {*[]} T
205
+ * @returns {[(fn: (...v: T) => Promise<void> | void) => (() => void) | undefined, (...v: T) => void | Promise<void>]}
206
+ */
207
+ function createFnList() {
208
+ const symbol = Symbol();
209
+ /**
210
+ * @param {(...v: T) => Promise<void> | void} fn
211
+ * @returns {(() => void) | undefined}
212
+ */
213
+ function add(fn) {
214
+ const state = asyncLocalStorage.getStore();
215
+ if (!state) return;
216
+ /**
217
+ * @param {T} v
218
+ * @returns
219
+ */
220
+ const f = async (...v) => {
221
+ try {
222
+ return await fn(...v);
223
+ } catch (e) {
224
+ console.error(e);
225
+ }
226
+ };
227
+ /** @type {Set<any>} */
228
+ let list = state[symbol];
229
+ if (!list) list = state[symbol] = /* @__PURE__ */ new Set();
230
+ list.add(f);
231
+ return () => {
232
+ list.delete(f);
233
+ };
234
+ }
235
+ /**
236
+ * @param {T} v
237
+ * @returns {void | Promise<void>}
238
+ */
239
+ function run(...v) {
240
+ const list = asyncLocalStorage.getStore()?.[symbol];
241
+ if (!list) return;
242
+ return Promise.all([...list].map((f) => f(...v))).then(() => {});
243
+ }
244
+ return [add, run];
245
+ }
246
+ /**
247
+ * @typedef {object} Env
248
+ * @property {string} domain
249
+ */
250
+ const [addDone, runDone] = createFnList();
251
+ const [addCatch, runCatch] = createFnList();
252
+ const [addFinally, runFinally] = createFnList();
253
+ /**
254
+ * @template T
255
+ * @template {*[]} TArgs
256
+ * @param {Env} env
257
+ * @param {(...args: TArgs) => PromiseLike<T> | T} fn
258
+ * @param {TArgs} args
259
+ * @returns {Promise<T>}
260
+ */
261
+ async function _run(env, fn, ...args) {
262
+ const state = {
263
+ [parentKey]: asyncLocalStorage.getStore(),
264
+ [envKey]: env
265
+ };
266
+ try {
267
+ const r = await asyncLocalStorage.run(state, fn, ...args);
268
+ await asyncLocalStorage.run(state, () => runDone(r));
269
+ return r;
270
+ } catch (e) {
271
+ await asyncLocalStorage.run(state, () => runCatch(e));
272
+ throw e;
273
+ } finally {
274
+ await asyncLocalStorage.run(state, () => runFinally());
275
+ }
276
+ }
277
+ /**
278
+ *
279
+ * @returns {Env}
280
+ */
281
+ function getEnv() {
282
+ return asyncLocalStorage.getStore()?.[envKey] || { domain: "" };
283
+ }
284
+ function getDomain() {
285
+ return getEnv().domain;
286
+ }
287
+ /**
288
+ * @template T
289
+ * @template {*[]} TArgs
290
+ * @param {(...args: TArgs) => T} fn
291
+ * @param {TArgs} args
292
+ * @returns {T}
293
+ */
294
+ function parentRun(fn, ...args) {
295
+ const state = asyncLocalStorage.getStore();
296
+ if (!state) throw new Error("不再上下文中");
297
+ const p = state?.[parentKey];
298
+ if (!p) throw new Error("不存在父级上下文");
299
+ return asyncLocalStorage.run(p || state, fn, ...args);
300
+ }
301
+ const stateSymbol = Symbol();
302
+ /**
303
+ *
304
+ * @param {string} key
305
+ * @param {any} [value]
306
+ * @returns
307
+ */
308
+ function setState(key, value = true) {
309
+ const store = asyncLocalStorage.getStore();
310
+ if (!store) return;
311
+ (store[stateSymbol] ||= /* @__PURE__ */ new Map()).set(key, value);
312
+ }
313
+ /**
314
+ *
315
+ * @param {string} key
316
+ * @returns
317
+ */
318
+ function getState(key) {
319
+ const store = asyncLocalStorage.getStore();
320
+ if (!store) return;
321
+ /** @type {Map<string, any>} */
322
+ const state = store[stateSymbol];
323
+ if (!state) return;
324
+ return state.get(key);
325
+ }
326
+
327
+ //#endregion
328
+ export { _run, addCatch, addDone, addFinally, createComputed, createFnList, createKeyStore, createOnceStore, createStore, createStoreSerializable, deserialize, getDomain, getEnv, getState, has, parentRun, serialize, setState };
329
+ //# sourceMappingURL=index.mjs.map
package/index.mjs.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../packages/context/index.mjs"],"sourcesContent":["import { AsyncLocalStorage } from 'node:async_hooks';\n\nconst asyncLocalStorage = new AsyncLocalStorage();\nconst parentKey = Symbol();\nconst envKey = Symbol();\n\n/**\n * 创建一个存储单元\n * @template T\n * @overload\n * @param {T} def\n * @returns {[() => T, (v: T) => boolean]}\n */\n/**\n * 创建一个存储单元\n * @template T\n * @overload\n * @param {T} [def]\n * @returns {[() => T | undefined, (v: T) => boolean]}\n */\n/**\n * 创建一个存储单元\n * @template T\n * @param {T} [def]\n * @returns {[() => T | undefined, (v: T) => boolean]}\n */\nexport function createStore(def) {\n\tconst symbol = Symbol();\n\tfunction get() {\n\t\tconst state = asyncLocalStorage.getStore();\n\t\tif (state && symbol in state) {\n\t\t\treturn state[symbol];\n\t\t}\n\t\treturn def;\n\t}\n\t/**\n\t * \n\t * @param {T} v \n\t * @returns \n\t */\n\tfunction set(v) {\n\t\tconst state = asyncLocalStorage.getStore();\n\t\tif (!state) { return false; }\n\n\t\tstate[symbol] = v;\n\t\treturn true;\n\t}\n\treturn [get, set];\n}\n\n/**\n * @template T\n * @param {() => T} fn \n * @returns {() => T}\n */\nexport function createComputed(fn) {\n\tconst symbol = Symbol();\n\treturn () => {\n\t\tconst state = asyncLocalStorage.getStore();\n\t\tif (!state) { return fn(); }\n\t\tif (symbol in state) {\n\t\t\treturn state[symbol];\n\t\t}\n\t\tconst v = fn();\n\t\tstate[symbol] = v;\n\t\treturn v;\n\t}\n}\n/** @type {Record<symbol, [string, (data: any) => any]>} */\nconst allSerialize = Object.create(null);\n/** @type {Record<string, [symbol, (data: any) => any]>} */\nconst allDeserialize = Object.create(null);\n\n/**\n * 创建一个存储单元\n * @template T\n * @template TS\n * @overload\n * @param {string} name\n * @param {(data: T) => TS | PromiseLike<TS>} serialize \n * @param {(data: TS) => T | PromiseLike<T>} deserialize\n * @param {T} def\n * @returns {[() => T, (v: T) => boolean]}\n */\n/**\n * 创建一个存储单元\n * @template T\n * @template TS\n * @overload\n * @param {string} name\n * @param {(data: T) => TS | PromiseLike<TS>} serialize \n * @param {(data: TS) => T | PromiseLike<T>} deserialize\n * @param {T} [def]\n * @returns {[() => T | undefined, (v: T) => boolean]}\n */\n/**\n * 创建一个存储单元\n * @template T\n * @template TS\n * @param {string} name\n * @param {(data: T) => TS | PromiseLike<TS>} serialize \n * @param {(data: TS) => T | PromiseLike<T>} deserialize\n * @param {T} [def]\n * @returns {[() => T | undefined, (v: T) => boolean]}\n */\nexport function createStoreSerializable(name, serialize, deserialize, def) {\n\tconst symbol = Symbol();\n\tallSerialize[symbol] = [name, serialize];\n\tallDeserialize[name] = [symbol, deserialize];\n\tfunction get() {\n\t\tconst state = asyncLocalStorage.getStore();\n\t\tif (state && symbol in state) {\n\t\t\treturn state[symbol];\n\t\t}\n\t\treturn def;\n\t}\n\t/**\n\t * \n\t * @param {T} v \n\t * @returns \n\t */\n\tfunction set(v) {\n\t\tconst state = asyncLocalStorage.getStore();\n\t\tif (!state) { return false; }\n\n\t\tstate[symbol] = v;\n\t\treturn true;\n\t}\n\treturn [get, set];\n}\nexport async function serialize() {\n\tconst state = asyncLocalStorage.getStore();\n\tif (!state) { return null; }\n\t/** @type {Record<string, any>} */\n\tconst data = {};\n\tfor (const [symbol, [name, serialize]] of Object.entries(allSerialize)) {\n\t\tconst value = state[symbol];\n\t\tif (value === void 0) { continue; }\n\t\tdata[name] = await serialize(value);\n\t}\n\treturn data;\n}\n\n/**\n * \n * @param {Record<string, any>} data \n */\nexport async function deserialize(data) {\n\tconst state = asyncLocalStorage.getStore();\n\tif (!state) { return; }\n\tfor (const [name, value] of Object.entries(data)) {\n\t\tif (data === void 0) { continue; }\n\t\tconst f = allDeserialize[name];\n\t\tif (!f) { continue; }\n\t\tconst [symbol, deserialize] = f;\n\t\tstate[symbol] = await deserialize(value);\n\t}\n\n}\n\n\n/**\n * @template {object} T\n * @param {() => T} fn \n */\nexport function createOnceStore(fn) {\n\tconst [getter, setter] = createStore(/** @type {T?} */(null));\n\t/**\n\t * @returns {T}\n\t */\n\treturn function () {\n\t\tconst p = getter();\n\t\tif (p) { return p; }\n\t\tconst result = fn();\n\t\tsetter(result);\n\t\treturn result;\n\t};\n}\n\n/**\n * @template {(...args: any) => any} T\n * @param {T} fn \n * @param {(...p: Parameters<T>) => string} getKey \n * @param {(...p: Parameters<T>) => boolean} [isForce] \n * @returns {T}\n */\nexport function createKeyStore(fn, getKey, isForce) {\n\tconst [getter, setter] = createStore(/** @type {Record<string, ReturnType<T>>?} */(null));\n\t/**\n\t * @param {Parameters<T>} params\n\t * @returns {ReturnType<T>}\n\t */\n\t function run(...params) {\n\t\tlet p = getter();\n\t\tif (!p) {\n\t\t\tp = {};\n\t\t\tsetter(p);\n\t\t}\n\t\tconst key = getKey(...params);\n\t\tif (Object.hasOwn(p, key) && !isForce?.(...params)) {\n\t\t\treturn p[key];\n\t\t}\n\t\tconst result = fn(...params);\n\t\tp[key] = result;\n\t\treturn result;\n\t};\n\treturn /** @type {T} */(run);\n}\n\n/**\n * 是否存在上下文\n * @param {boolean} [must] \n * @returns {boolean}\n */\nexport function has(must) {\n\tif (asyncLocalStorage.getStore()) { return true; }\n\tif (must) { throw new Error('不在上下文中'); }\n\treturn false;\n}\n/**\n * 创建一个上下文函数列表\n * @template {*[]} T\n * @returns {[(fn: (...v: T) => Promise<void> | void) => (() => void) | undefined, (...v: T) => void | Promise<void>]}\n*/\nexport function createFnList() {\n\tconst symbol = Symbol();\n\t/**\n\t * @param {(...v: T) => Promise<void> | void} fn\n\t * @returns {(() => void) | undefined}\n\t */\n\tfunction add(fn) {\n\t\tconst state = asyncLocalStorage.getStore();\n\t\tif (!state) { return; }\n\t\t/**\n\t\t * @param {T} v \n\t\t * @returns \n\t\t */\n\t\tconst f = async (...v) => {\n\t\t\ttry {\n\t\t\t\treturn await fn(...v);\n\t\t\t} catch (e) {\n\t\t\t\tconsole.error(e);\n\t\t\t}\n\t\t};\n\t\t/** @type {Set<any>} */\n\t\tlet list = state[symbol];\n\t\tif (!list) {\n\t\t\tlist = state[symbol] = new Set();\n\t\t}\n\t\tlist.add(f);\n\t\treturn () => { list.delete(f); };\n\t}\n\t/**\n\t * @param {T} v \n\t * @returns {void | Promise<void>}\n\t */\n\tfunction run(...v) {\n\t\tconst list = asyncLocalStorage.getStore()?.[symbol];\n\t\tif (!list) { return; }\n\t\treturn Promise.all([...list].map(f => f(...v))).then(() => { });\n\n\t}\n\treturn [add, run];\n}\n\n/**\n * @typedef {object} Env\n * @property {string} domain\n */\n\nconst [addDone, runDone] = createFnList();\nconst [addCatch, runCatch] = createFnList();\nconst [addFinally, runFinally] = createFnList();\n/**\n * @template T\n * @template {*[]} TArgs\n * @param {Env} env \n * @param {(...args: TArgs) => PromiseLike<T> | T} fn \n * @param {TArgs} args \n * @returns {Promise<T>}\n */\nexport async function _run(env, fn, ...args) {\n\tconst state = { [parentKey]: asyncLocalStorage.getStore(), [envKey]: env };\n\ttry {\n\t\tconst r = await asyncLocalStorage.run(state, fn, ...args);\n\t\tawait asyncLocalStorage.run(state, () => runDone(r));\n\t\treturn r;\n\t} catch (e) {\n\t\tawait asyncLocalStorage.run(state, () => runCatch(e));\n\t\tthrow e;\n\t} finally {\n\t\tawait asyncLocalStorage.run(state, () => runFinally());\n\t}\n}\n/**\n * \n * @returns {Env}\n */\nexport function getEnv() {\n\t\tconst state = asyncLocalStorage.getStore();\n\t\treturn state?.[envKey] || {domain: ''};\n\t\n\n}\nexport function getDomain() {\n\t\treturn getEnv().domain;\n}\n\n\n/**\n * @template T\n * @template {*[]} TArgs\n * @param {(...args: TArgs) => T} fn \n * @param {TArgs} args \n * @returns {T}\n */\nexport function parentRun(fn, ...args) {\n\tconst state = asyncLocalStorage.getStore();\n\tif (!state) {\n\t\tthrow new Error('不再上下文中');\n\t}\n\tconst p = state?.[parentKey];\n\tif (!p) {\n\t\tthrow new Error('不存在父级上下文');\n\t}\n\treturn asyncLocalStorage.run(p || state, fn, ...args);\n}\n\nexport { addDone, addCatch, addFinally };\n\n\nconst stateSymbol = Symbol();\n/**\n * \n * @param {string} key \n * @param {any} [value] \n * @returns \n */\nexport function setState(key, value = true) {\n\tconst store = asyncLocalStorage.getStore();\n\tif (!store) { return; }\n\t/** @type {Map<string, any>} */\n\tconst state = store[stateSymbol] ||= new Map();\n\tstate.set(key, value);\n}\n/**\n * \n * @param {string} key \n * @returns \n */\nexport function getState(key) {\n\tconst store = asyncLocalStorage.getStore();\n\tif (!store) { return; }\n\t/** @type {Map<string, any>} */\n\tconst state = store[stateSymbol];\n\tif (!state) { return; }\n\treturn state.get(key);\n}\n"],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,15 @@
1
+ {
2
+ "name": "@yongdall/context",
3
+ "type": "module",
4
+ "main": "./index.mjs",
5
+ "exports": {
6
+ ".": "./index.mjs"
7
+ },
8
+ "version": "0.1.0",
9
+ "description": "",
10
+ "keywords": [],
11
+ "author": "",
12
+ "license": "ISC",
13
+ "dependencies": {},
14
+ "devDependencies": {}
15
+ }