@cldmv/slothlet 3.3.0 → 3.3.2
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/README.md +6 -8
- package/REFERENCE.md +23 -0
- package/dist/lib/builders/api-assignment.mjs +1 -589
- package/dist/lib/builders/api_builder.mjs +1 -1385
- package/dist/lib/builders/builder.mjs +1 -78
- package/dist/lib/builders/modes-processor.mjs +1 -1800
- package/dist/lib/errors.mjs +9 -211
- package/dist/lib/factories/component-base.mjs +1 -80
- package/dist/lib/factories/context.mjs +1 -22
- package/dist/lib/handlers/api-cache-manager.mjs +1 -200
- package/dist/lib/handlers/api-manager.mjs +1 -2536
- package/dist/lib/handlers/context-async.mjs +1 -172
- package/dist/lib/handlers/context-live.mjs +1 -173
- package/dist/lib/handlers/hook-manager.mjs +1 -667
- package/dist/lib/handlers/lifecycle-token.mjs +1 -28
- package/dist/lib/handlers/lifecycle.mjs +1 -115
- package/dist/lib/handlers/materialize-manager.mjs +1 -48
- package/dist/lib/handlers/metadata.mjs +1 -501
- package/dist/lib/handlers/ownership.mjs +1 -322
- package/dist/lib/handlers/permission-manager.mjs +1 -392
- package/dist/lib/handlers/unified-wrapper.mjs +1 -3110
- package/dist/lib/handlers/version-manager.mjs +1 -885
- package/dist/lib/helpers/class-instance-wrapper.mjs +1 -109
- package/dist/lib/helpers/config.mjs +1 -439
- package/dist/lib/helpers/eventemitter-context.mjs +1 -349
- package/dist/lib/helpers/hint-detector.mjs +1 -47
- package/dist/lib/helpers/modes-utils.mjs +1 -37
- package/dist/lib/helpers/pattern-matcher.mjs +1 -125
- package/dist/lib/helpers/resolve-from-caller.mjs +1 -169
- package/dist/lib/helpers/sanitize.mjs +1 -340
- package/dist/lib/helpers/utilities.mjs +1 -70
- package/dist/lib/i18n/translations.mjs +1 -126
- package/dist/lib/modes/eager.mjs +1 -59
- package/dist/lib/modes/lazy.mjs +1 -81
- package/dist/lib/processors/flatten.mjs +1 -437
- package/dist/lib/processors/loader.mjs +1 -339
- package/dist/lib/processors/type-generator.mjs +1 -275
- package/dist/lib/processors/typescript.mjs +1 -172
- package/dist/lib/runtime/runtime-asynclocalstorage.mjs +1 -113
- package/dist/lib/runtime/runtime-livebindings.mjs +1 -78
- package/dist/lib/runtime/runtime.mjs +1 -102
- package/dist/slothlet.mjs +1 -817
- package/package.json +34 -31
- package/types/dist/lib/builders/api-assignment.d.mts +3 -92
- package/types/dist/lib/builders/api-assignment.d.mts.map +1 -1
- package/types/dist/lib/builders/api_builder.d.mts +102 -91
- package/types/dist/lib/builders/api_builder.d.mts.map +1 -1
- package/types/dist/lib/builders/builder.d.mts +1 -55
- package/types/dist/lib/builders/builder.d.mts.map +1 -1
- package/types/dist/lib/builders/modes-processor.d.mts +3 -27
- package/types/dist/lib/builders/modes-processor.d.mts.map +1 -1
- package/types/dist/lib/errors.d.mts +19 -109
- package/types/dist/lib/errors.d.mts.map +1 -1
- package/types/dist/lib/factories/component-base.d.mts +7 -177
- package/types/dist/lib/factories/component-base.d.mts.map +1 -1
- package/types/dist/lib/factories/context.d.mts +4 -22
- package/types/dist/lib/factories/context.d.mts.map +1 -1
- package/types/dist/lib/handlers/api-cache-manager.d.mts +20 -203
- package/types/dist/lib/handlers/api-cache-manager.d.mts.map +1 -1
- package/types/dist/lib/handlers/api-manager.d.mts +33 -408
- package/types/dist/lib/handlers/api-manager.d.mts.map +1 -1
- package/types/dist/lib/handlers/context-async.d.mts +23 -61
- package/types/dist/lib/handlers/context-async.d.mts.map +1 -1
- package/types/dist/lib/handlers/context-live.d.mts +22 -59
- package/types/dist/lib/handlers/context-live.d.mts.map +1 -1
- package/types/dist/lib/handlers/hook-manager.d.mts +46 -185
- package/types/dist/lib/handlers/hook-manager.d.mts.map +1 -1
- package/types/dist/lib/handlers/lifecycle-token.d.mts +3 -48
- package/types/dist/lib/handlers/lifecycle-token.d.mts.map +1 -1
- package/types/dist/lib/handlers/lifecycle.d.mts +5 -82
- package/types/dist/lib/handlers/lifecycle.d.mts.map +1 -1
- package/types/dist/lib/handlers/materialize-manager.d.mts +8 -70
- package/types/dist/lib/handlers/materialize-manager.d.mts.map +1 -1
- package/types/dist/lib/handlers/metadata.d.mts +17 -221
- package/types/dist/lib/handlers/metadata.d.mts.map +1 -1
- package/types/dist/lib/handlers/ownership.d.mts +44 -160
- package/types/dist/lib/handlers/ownership.d.mts.map +1 -1
- package/types/dist/lib/handlers/permission-manager.d.mts +37 -141
- package/types/dist/lib/handlers/permission-manager.d.mts.map +1 -1
- package/types/dist/lib/handlers/unified-wrapper.d.mts +26 -239
- package/types/dist/lib/handlers/unified-wrapper.d.mts.map +1 -1
- package/types/dist/lib/handlers/version-manager.d.mts +28 -225
- package/types/dist/lib/handlers/version-manager.d.mts.map +1 -1
- package/types/dist/lib/helpers/class-instance-wrapper.d.mts +2 -52
- package/types/dist/lib/helpers/class-instance-wrapper.d.mts.map +1 -1
- package/types/dist/lib/helpers/config.d.mts +125 -139
- package/types/dist/lib/helpers/config.d.mts.map +1 -1
- package/types/dist/lib/helpers/eventemitter-context.d.mts +3 -29
- package/types/dist/lib/helpers/eventemitter-context.d.mts.map +1 -1
- package/types/dist/lib/helpers/hint-detector.d.mts +2 -15
- package/types/dist/lib/helpers/hint-detector.d.mts.map +1 -1
- package/types/dist/lib/helpers/modes-utils.d.mts +3 -30
- package/types/dist/lib/helpers/modes-utils.d.mts.map +1 -1
- package/types/dist/lib/helpers/pattern-matcher.d.mts +3 -43
- package/types/dist/lib/helpers/pattern-matcher.d.mts.map +1 -1
- package/types/dist/lib/helpers/resolve-from-caller.d.mts +3 -27
- package/types/dist/lib/helpers/resolve-from-caller.d.mts.map +1 -1
- package/types/dist/lib/helpers/sanitize.d.mts +4 -92
- package/types/dist/lib/helpers/sanitize.d.mts.map +1 -1
- package/types/dist/lib/helpers/utilities.d.mts +4 -52
- package/types/dist/lib/helpers/utilities.d.mts.map +1 -1
- package/types/dist/lib/i18n/translations.d.mts +4 -37
- package/types/dist/lib/i18n/translations.d.mts.map +1 -1
- package/types/dist/lib/modes/eager.d.mts +8 -30
- package/types/dist/lib/modes/eager.d.mts.map +1 -1
- package/types/dist/lib/modes/lazy.d.mts +10 -43
- package/types/dist/lib/modes/lazy.d.mts.map +1 -1
- package/types/dist/lib/processors/flatten.d.mts +56 -107
- package/types/dist/lib/processors/flatten.d.mts.map +1 -1
- package/types/dist/lib/processors/loader.d.mts +6 -41
- package/types/dist/lib/processors/loader.d.mts.map +1 -1
- package/types/dist/lib/processors/type-generator.d.mts +2 -16
- package/types/dist/lib/processors/type-generator.d.mts.map +1 -1
- package/types/dist/lib/processors/typescript.d.mts +6 -53
- package/types/dist/lib/processors/typescript.d.mts.map +1 -1
- package/types/dist/lib/runtime/runtime-asynclocalstorage.d.mts +3 -71
- package/types/dist/lib/runtime/runtime-asynclocalstorage.d.mts.map +1 -1
- package/types/dist/lib/runtime/runtime-livebindings.d.mts +2 -37
- package/types/dist/lib/runtime/runtime-livebindings.d.mts.map +1 -1
- package/types/dist/lib/runtime/runtime.d.mts +3 -39
- package/types/dist/lib/runtime/runtime.d.mts.map +1 -1
- package/types/dist/slothlet.d.mts +3 -249
- package/types/dist/slothlet.d.mts.map +1 -1
- package/types/index.d.mts +36 -16
- package/types/index.d.mts.map +1 -0
- package/AGENT-USAGE.md +0 -736
- package/docs/API-RULES.md +0 -712
|
@@ -14,670 +14,4 @@
|
|
|
14
14
|
limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
import { ComponentBase } from "@cldmv/slothlet/factories/component-base";
|
|
22
|
-
import { compilePattern } from "@cldmv/slothlet/helpers/pattern-matcher";
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
const ERROR_HOOK_PROCESSED = Symbol.for("@cldmv/slothlet/hook-error-processed");
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
export class HookManager extends ComponentBase {
|
|
31
|
-
|
|
32
|
-
static slothletProperty = "hookManager";
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
#hooks = {
|
|
36
|
-
before: { before: {}, primary: {}, after: {} },
|
|
37
|
-
after: { before: {}, primary: {}, after: {} },
|
|
38
|
-
always: { before: {}, primary: {}, after: {} },
|
|
39
|
-
error: { before: {}, primary: {}, after: {} }
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
#byId = new Map();
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
#idCounter = 0;
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
#validTypes = new Set(["before", "after", "always", "error"]);
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
#validSubsets = new Set(["before", "primary", "after"]);
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
constructor(slothlet) {
|
|
56
|
-
super(slothlet);
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
const hookConfig = slothlet.config?.hook || { enabled: false, pattern: "**", suppressErrors: false };
|
|
60
|
-
|
|
61
|
-
this.enabled = hookConfig.enabled;
|
|
62
|
-
this.defaultPattern = hookConfig.pattern || "**";
|
|
63
|
-
this.suppressErrors = hookConfig.suppressErrors || false;
|
|
64
|
-
this.enabledPatterns = new Set();
|
|
65
|
-
this.patternFilterActive = false;
|
|
66
|
-
|
|
67
|
-
this.hooks = new Map();
|
|
68
|
-
this.registrationOrder = 0;
|
|
69
|
-
this.reportedErrors = new WeakSet();
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
on(typePattern, handler, options = {}) {
|
|
74
|
-
|
|
75
|
-
let { type, pattern } = this.#parseTypePattern(typePattern);
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
if (options.pattern !== undefined) {
|
|
79
|
-
pattern = options.pattern;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
if (!this.#validTypes.has(type)) {
|
|
84
|
-
throw new this.slothlet.SlothletError("INVALID_HOOK_TYPE", {
|
|
85
|
-
type,
|
|
86
|
-
validTypes: Array.from(this.#validTypes)
|
|
87
|
-
});
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
if (typeof handler !== "function") {
|
|
92
|
-
throw new this.slothlet.SlothletError("INVALID_HOOK_HANDLER", {
|
|
93
|
-
receivedType: typeof handler,
|
|
94
|
-
validationError: true
|
|
95
|
-
});
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
const id = options.id || this.#generateId();
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
if (this.#byId.has(id)) {
|
|
103
|
-
throw new this.slothlet.SlothletError("DUPLICATE_HOOK_ID", { id, validationError: true });
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
const subset = options.subset || "primary";
|
|
108
|
-
if (!this.#validSubsets.has(subset)) {
|
|
109
|
-
throw new this.slothlet.SlothletError("INVALID_HOOK_SUBSET", {
|
|
110
|
-
subset,
|
|
111
|
-
validSubsets: Array.from(this.#validSubsets)
|
|
112
|
-
});
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
this.#compilePattern(pattern);
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
const hook = {
|
|
120
|
-
id,
|
|
121
|
-
type,
|
|
122
|
-
pattern,
|
|
123
|
-
handler,
|
|
124
|
-
priority: options.priority || 0,
|
|
125
|
-
subset,
|
|
126
|
-
enabled: true,
|
|
127
|
-
_compiled: null
|
|
128
|
-
};
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
const typeIndex = this.#hooks[type];
|
|
132
|
-
const subsetIndex = typeIndex[subset];
|
|
133
|
-
|
|
134
|
-
if (!subsetIndex[pattern]) {
|
|
135
|
-
subsetIndex[pattern] = [];
|
|
136
|
-
}
|
|
137
|
-
subsetIndex[pattern].push(hook);
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
this.#byId.set(id, hook);
|
|
141
|
-
|
|
142
|
-
return id;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
remove(filter = {}) {
|
|
147
|
-
let removed = 0;
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
if (filter.id) {
|
|
151
|
-
const hook = this.#byId.get(filter.id);
|
|
152
|
-
if (hook) {
|
|
153
|
-
this.#removeHook(hook);
|
|
154
|
-
removed = 1;
|
|
155
|
-
}
|
|
156
|
-
return removed;
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
const types = filter.type ? [filter.type] : Array.from(this.#validTypes);
|
|
161
|
-
|
|
162
|
-
for (const type of types) {
|
|
163
|
-
const typeIndex = this.#hooks[type];
|
|
164
|
-
|
|
165
|
-
for (const subset of ["before", "primary", "after"]) {
|
|
166
|
-
const subsetIndex = typeIndex[subset];
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
if (filter.pattern) {
|
|
170
|
-
const patternHooks = subsetIndex[filter.pattern];
|
|
171
|
-
if (patternHooks) {
|
|
172
|
-
removed += patternHooks.length;
|
|
173
|
-
patternHooks.forEach((hook) => this.#byId.delete(hook.id));
|
|
174
|
-
delete subsetIndex[filter.pattern];
|
|
175
|
-
}
|
|
176
|
-
} else {
|
|
177
|
-
|
|
178
|
-
for (const pattern in subsetIndex) {
|
|
179
|
-
const patternHooks = subsetIndex[pattern];
|
|
180
|
-
removed += patternHooks.length;
|
|
181
|
-
patternHooks.forEach((hook) => this.#byId.delete(hook.id));
|
|
182
|
-
delete subsetIndex[pattern];
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
return removed;
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
enable(filter = {}) {
|
|
193
|
-
|
|
194
|
-
if (typeof filter === "string") {
|
|
195
|
-
filter = { pattern: filter };
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
this.enabled = true;
|
|
200
|
-
|
|
201
|
-
return this.#setEnabledState(filter, true);
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
disable(filter = {}) {
|
|
206
|
-
|
|
207
|
-
if (typeof filter === "string") {
|
|
208
|
-
filter = { pattern: filter };
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
if (Object.keys(filter).length === 0) {
|
|
213
|
-
this.enabled = false;
|
|
214
|
-
}
|
|
215
|
-
return this.#setEnabledState(filter, false);
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
list(filter = {}) {
|
|
220
|
-
|
|
221
|
-
if (typeof filter === "string") {
|
|
222
|
-
|
|
223
|
-
if (this.#validTypes.has(filter)) {
|
|
224
|
-
filter = { type: filter };
|
|
225
|
-
} else {
|
|
226
|
-
|
|
227
|
-
filter = { pattern: filter };
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
const hooks = [];
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
if (filter.id) {
|
|
235
|
-
const hook = this.#byId.get(filter.id);
|
|
236
|
-
if (hook && (filter.enabled === undefined || hook.enabled === filter.enabled)) {
|
|
237
|
-
hooks.push(this.#serializeHook(hook));
|
|
238
|
-
}
|
|
239
|
-
return { registeredHooks: hooks };
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
const types = filter.type ? [filter.type] : Array.from(this.#validTypes);
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
let patternMatcher = null;
|
|
247
|
-
if (filter.pattern) {
|
|
248
|
-
patternMatcher = this.#compilePattern(filter.pattern);
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
for (const type of types) {
|
|
252
|
-
const typeIndex = this.#hooks[type];
|
|
253
|
-
|
|
254
|
-
for (const subset of ["before", "primary", "after"]) {
|
|
255
|
-
const subsetIndex = typeIndex[subset];
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
for (const pattern in subsetIndex) {
|
|
259
|
-
const patternHooks = subsetIndex[pattern];
|
|
260
|
-
for (const hook of patternHooks) {
|
|
261
|
-
|
|
262
|
-
if (filter.enabled !== undefined && hook.enabled !== filter.enabled) {
|
|
263
|
-
continue;
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
if (patternMatcher && !patternMatcher(hook.pattern)) {
|
|
268
|
-
continue;
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
hooks.push(this.#serializeHook(hook));
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
return { registeredHooks: hooks };
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
getHooksForPath(type, apiPath) {
|
|
282
|
-
|
|
283
|
-
if (this.enabled === false) {
|
|
284
|
-
return [];
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
const typeIndex = this.#hooks[type];
|
|
288
|
-
if (!typeIndex) {
|
|
289
|
-
return [];
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
const hooks = [];
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
for (const subset of ["before", "primary", "after"]) {
|
|
296
|
-
const subsetIndex = typeIndex[subset];
|
|
297
|
-
const subsetHooks = [];
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
for (const pattern in subsetIndex) {
|
|
301
|
-
const patternHooks = subsetIndex[pattern];
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
if (pattern === apiPath) {
|
|
305
|
-
subsetHooks.push(...patternHooks.filter((h) => h.enabled));
|
|
306
|
-
continue;
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
for (const hook of patternHooks) {
|
|
311
|
-
if (!hook.enabled) continue;
|
|
312
|
-
|
|
313
|
-
if (!hook._compiled) {
|
|
314
|
-
hook._compiled = this.#compilePattern(hook.pattern);
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
if (hook._compiled(apiPath)) {
|
|
318
|
-
subsetHooks.push(hook);
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
subsetHooks.sort((a, b) => b.priority - a.priority);
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
hooks.push(...subsetHooks);
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
return hooks;
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
executeBeforeHooks(path, args, api, ctx) {
|
|
335
|
-
const hooks = this.getHooksForPath("before", path);
|
|
336
|
-
|
|
337
|
-
for (const hook of hooks) {
|
|
338
|
-
try {
|
|
339
|
-
const result = hook.handler({ path, args, api, ctx });
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
if (result && typeof result === "object" && typeof result.then === "function") {
|
|
343
|
-
throw new this.SlothletError("HOOK_BEFORE_RETURNED_PROMISE", { id: hook.id, path }, null, { validationError: true });
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
if (result !== undefined && !Array.isArray(result)) {
|
|
348
|
-
return { args, shortCircuit: true, value: result };
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
if (Array.isArray(result)) {
|
|
353
|
-
args = result;
|
|
354
|
-
}
|
|
355
|
-
} catch (error) {
|
|
356
|
-
|
|
357
|
-
const sourceInfo = {
|
|
358
|
-
type: "before",
|
|
359
|
-
subset: hook.subset,
|
|
360
|
-
hookTag: hook.id,
|
|
361
|
-
hookId: hook.id,
|
|
362
|
-
timestamp: Date.now(),
|
|
363
|
-
stack: error.stack
|
|
364
|
-
};
|
|
365
|
-
this.executeErrorHooks(path, error, sourceInfo, args, api, ctx);
|
|
366
|
-
|
|
367
|
-
if (!this.suppressErrors) {
|
|
368
|
-
throw error;
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
return { args, shortCircuit: true, value: undefined };
|
|
372
|
-
}
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
return { args, shortCircuit: false };
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
executeAfterHooks(path, result, args, api, ctx) {
|
|
380
|
-
const hooks = this.getHooksForPath("after", path);
|
|
381
|
-
const originalResult = result;
|
|
382
|
-
let currentResult = result;
|
|
383
|
-
|
|
384
|
-
for (const hook of hooks) {
|
|
385
|
-
try {
|
|
386
|
-
const hookContext = {
|
|
387
|
-
path,
|
|
388
|
-
args,
|
|
389
|
-
result: currentResult,
|
|
390
|
-
api,
|
|
391
|
-
ctx
|
|
392
|
-
};
|
|
393
|
-
const transformed = hook.handler(hookContext);
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
if (transformed !== undefined) {
|
|
397
|
-
currentResult = transformed;
|
|
398
|
-
}
|
|
399
|
-
} catch (error) {
|
|
400
|
-
|
|
401
|
-
const sourceInfo = {
|
|
402
|
-
type: "after",
|
|
403
|
-
subset: hook.subset,
|
|
404
|
-
hookTag: hook.id,
|
|
405
|
-
hookId: hook.id,
|
|
406
|
-
timestamp: Date.now(),
|
|
407
|
-
stack: error.stack
|
|
408
|
-
};
|
|
409
|
-
this.executeErrorHooks(path, error, sourceInfo, args, api, ctx);
|
|
410
|
-
|
|
411
|
-
if (!this.suppressErrors) {
|
|
412
|
-
throw error;
|
|
413
|
-
}
|
|
414
|
-
}
|
|
415
|
-
}
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
if (currentResult === originalResult) {
|
|
419
|
-
return { modified: false };
|
|
420
|
-
} else {
|
|
421
|
-
return { modified: true, result: currentResult };
|
|
422
|
-
}
|
|
423
|
-
}
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
executeAlwaysHooks(path, args, resultOrError, hasError = false, errors = [], api, ctx) {
|
|
427
|
-
const hooks = this.getHooksForPath("always", path);
|
|
428
|
-
|
|
429
|
-
for (const hook of hooks) {
|
|
430
|
-
try {
|
|
431
|
-
hook.handler({
|
|
432
|
-
path,
|
|
433
|
-
args,
|
|
434
|
-
result: hasError ? undefined : resultOrError,
|
|
435
|
-
hasError,
|
|
436
|
-
errors: errors,
|
|
437
|
-
api,
|
|
438
|
-
ctx
|
|
439
|
-
});
|
|
440
|
-
} catch (error) {
|
|
441
|
-
|
|
442
|
-
const sourceInfo = {
|
|
443
|
-
type: "always",
|
|
444
|
-
subset: hook.subset,
|
|
445
|
-
hookTag: hook.id,
|
|
446
|
-
hookId: hook.id,
|
|
447
|
-
timestamp: Date.now(),
|
|
448
|
-
stack: error.stack
|
|
449
|
-
};
|
|
450
|
-
this.executeErrorHooks(path, error, sourceInfo, args, api, ctx);
|
|
451
|
-
}
|
|
452
|
-
}
|
|
453
|
-
}
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
executeErrorHooks(path, error, source, args, api, ctx) {
|
|
457
|
-
|
|
458
|
-
if (error && typeof error === "object") {
|
|
459
|
-
error[ERROR_HOOK_PROCESSED] = true;
|
|
460
|
-
}
|
|
461
|
-
|
|
462
|
-
const hooks = this.getHooksForPath("error", path);
|
|
463
|
-
|
|
464
|
-
for (const hook of hooks) {
|
|
465
|
-
try {
|
|
466
|
-
hook.handler({
|
|
467
|
-
path,
|
|
468
|
-
args,
|
|
469
|
-
error,
|
|
470
|
-
errorType: error?.constructor?.name || "Error",
|
|
471
|
-
source,
|
|
472
|
-
timestamp: new Date(),
|
|
473
|
-
api,
|
|
474
|
-
ctx
|
|
475
|
-
});
|
|
476
|
-
} catch (hookError) {
|
|
477
|
-
|
|
478
|
-
this.slothlet.debug("hooks", `Error hook failed for ${path}:`, hookError);
|
|
479
|
-
}
|
|
480
|
-
}
|
|
481
|
-
}
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
#parseTypePattern(typePattern) {
|
|
485
|
-
if (typeof typePattern !== "string") {
|
|
486
|
-
throw new this.slothlet.SlothletError("INVALID_TYPE_PATTERN", {
|
|
487
|
-
typePattern,
|
|
488
|
-
expected: "string in format 'type:pattern'"
|
|
489
|
-
});
|
|
490
|
-
}
|
|
491
|
-
|
|
492
|
-
const colonIndex = typePattern.indexOf(":");
|
|
493
|
-
if (colonIndex === -1) {
|
|
494
|
-
throw new this.slothlet.SlothletError("INVALID_TYPE_PATTERN", {
|
|
495
|
-
typePattern,
|
|
496
|
-
expected: "string in format 'type:pattern' with at least one colon"
|
|
497
|
-
});
|
|
498
|
-
}
|
|
499
|
-
|
|
500
|
-
const type = typePattern.substring(0, colonIndex);
|
|
501
|
-
const pattern = typePattern.substring(colonIndex + 1);
|
|
502
|
-
|
|
503
|
-
if (!type || !pattern) {
|
|
504
|
-
throw new this.slothlet.SlothletError("INVALID_TYPE_PATTERN", {
|
|
505
|
-
typePattern,
|
|
506
|
-
expected: "non-empty type and pattern"
|
|
507
|
-
});
|
|
508
|
-
}
|
|
509
|
-
|
|
510
|
-
return { type, pattern };
|
|
511
|
-
}
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
#compilePattern(pattern) {
|
|
515
|
-
return compilePattern(pattern, {
|
|
516
|
-
onMaxDepth: (maxDepth) => {
|
|
517
|
-
throw new this.SlothletError("HOOK_BRACE_EXPANSION_MAX_DEPTH", { maxDepth }, null, { validationError: true });
|
|
518
|
-
}
|
|
519
|
-
});
|
|
520
|
-
}
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
getCompilePatternForDiagnostics() {
|
|
524
|
-
return this.#compilePattern.bind(this);
|
|
525
|
-
}
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
#generateId() {
|
|
529
|
-
return `hook-${++this.#idCounter}`;
|
|
530
|
-
}
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
#removeHook(hook) {
|
|
534
|
-
const typeIndex = this.#hooks[hook.type];
|
|
535
|
-
const subsetIndex = typeIndex[hook.subset];
|
|
536
|
-
const patternHooks = subsetIndex[hook.pattern];
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
if (!patternHooks) {
|
|
546
|
-
throw new this.slothlet.SlothletError("INTERNAL_HOOK_STATE_CORRUPT", {
|
|
547
|
-
hookId: hook.id,
|
|
548
|
-
type: hook.type,
|
|
549
|
-
subset: hook.subset,
|
|
550
|
-
pattern: hook.pattern,
|
|
551
|
-
detail: "patternHooks array missing from subsetIndex — #byId and #hooks are desynced"
|
|
552
|
-
});
|
|
553
|
-
}
|
|
554
|
-
|
|
555
|
-
const index = patternHooks.indexOf(hook);
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
if (index === -1) {
|
|
564
|
-
throw new this.slothlet.SlothletError("INTERNAL_HOOK_STATE_CORRUPT", {
|
|
565
|
-
hookId: hook.id,
|
|
566
|
-
type: hook.type,
|
|
567
|
-
subset: hook.subset,
|
|
568
|
-
pattern: hook.pattern,
|
|
569
|
-
detail: "hook object not found in patternHooks array — #byId and #hooks are desynced"
|
|
570
|
-
});
|
|
571
|
-
}
|
|
572
|
-
|
|
573
|
-
patternHooks.splice(index, 1);
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
if (patternHooks.length === 0) {
|
|
577
|
-
delete subsetIndex[hook.pattern];
|
|
578
|
-
}
|
|
579
|
-
|
|
580
|
-
this.#byId.delete(hook.id);
|
|
581
|
-
}
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
#setEnabledState(filter, enabled) {
|
|
585
|
-
let affected = 0;
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
if (filter.id) {
|
|
589
|
-
const hook = this.#byId.get(filter.id);
|
|
590
|
-
if (hook) {
|
|
591
|
-
hook.enabled = enabled;
|
|
592
|
-
affected = 1;
|
|
593
|
-
}
|
|
594
|
-
return affected;
|
|
595
|
-
}
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
const types = filter.type ? [filter.type] : Array.from(this.#validTypes);
|
|
599
|
-
|
|
600
|
-
for (const type of types) {
|
|
601
|
-
const typeIndex = this.#hooks[type];
|
|
602
|
-
|
|
603
|
-
for (const subset of ["before", "primary", "after"]) {
|
|
604
|
-
const subsetIndex = typeIndex[subset];
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
if (filter.pattern) {
|
|
608
|
-
const patternHooks = subsetIndex[filter.pattern] || [];
|
|
609
|
-
for (const hook of patternHooks) {
|
|
610
|
-
hook.enabled = enabled;
|
|
611
|
-
affected++;
|
|
612
|
-
}
|
|
613
|
-
} else {
|
|
614
|
-
|
|
615
|
-
for (const pattern in subsetIndex) {
|
|
616
|
-
const patternHooks = subsetIndex[pattern];
|
|
617
|
-
for (const hook of patternHooks) {
|
|
618
|
-
hook.enabled = enabled;
|
|
619
|
-
affected++;
|
|
620
|
-
}
|
|
621
|
-
}
|
|
622
|
-
}
|
|
623
|
-
}
|
|
624
|
-
}
|
|
625
|
-
|
|
626
|
-
return affected;
|
|
627
|
-
}
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
#serializeHook(hook) {
|
|
631
|
-
return {
|
|
632
|
-
id: hook.id,
|
|
633
|
-
type: hook.type,
|
|
634
|
-
pattern: hook.pattern,
|
|
635
|
-
priority: hook.priority,
|
|
636
|
-
subset: hook.subset,
|
|
637
|
-
enabled: hook.enabled
|
|
638
|
-
|
|
639
|
-
};
|
|
640
|
-
}
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
exportHooks() {
|
|
644
|
-
const registrations = [];
|
|
645
|
-
for (const hook of this.#byId.values()) {
|
|
646
|
-
registrations.push({
|
|
647
|
-
typePattern: `${hook.type}:${hook.pattern}`,
|
|
648
|
-
handler: hook.handler,
|
|
649
|
-
options: {
|
|
650
|
-
id: hook.id,
|
|
651
|
-
priority: hook.priority,
|
|
652
|
-
subset: hook.subset
|
|
653
|
-
},
|
|
654
|
-
enabled: hook.enabled
|
|
655
|
-
});
|
|
656
|
-
}
|
|
657
|
-
return registrations;
|
|
658
|
-
}
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
importHooks(registrations) {
|
|
662
|
-
if (!Array.isArray(registrations)) return;
|
|
663
|
-
for (const reg of registrations) {
|
|
664
|
-
this.on(reg.typePattern, reg.handler, reg.options);
|
|
665
|
-
if (!reg.enabled) {
|
|
666
|
-
this.disable({ id: reg.options.id });
|
|
667
|
-
}
|
|
668
|
-
}
|
|
669
|
-
}
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
async shutdown() {
|
|
673
|
-
|
|
674
|
-
this.#hooks = {
|
|
675
|
-
before: { before: {}, primary: {}, after: {} },
|
|
676
|
-
after: { before: {}, primary: {}, after: {} },
|
|
677
|
-
always: { before: {}, primary: {}, after: {} },
|
|
678
|
-
error: { before: {}, primary: {}, after: {} }
|
|
679
|
-
};
|
|
680
|
-
this.#byId.clear();
|
|
681
|
-
this.#idCounter = 0;
|
|
682
|
-
}
|
|
683
|
-
}
|
|
17
|
+
import{ComponentBase}from"@cldmv/slothlet/factories/component-base";import{compilePattern}from"@cldmv/slothlet/helpers/pattern-matcher";const ERROR_HOOK_PROCESSED=Symbol.for("@cldmv/slothlet/hook-error-processed");class HookManager extends ComponentBase{static slothletProperty="hookManager";#hooks={before:{before:{},primary:{},after:{}},after:{before:{},primary:{},after:{}},always:{before:{},primary:{},after:{}},error:{before:{},primary:{},after:{}}};#byId=new Map;#idCounter=0;#validTypes=new Set(["before","after","always","error"]);#validSubsets=new Set(["before","primary","after"]);constructor(slothlet){super(slothlet);const hookConfig=slothlet.config?.hook||{enabled:false,pattern:"**",suppressErrors:false};this.enabled=hookConfig.enabled;this.defaultPattern=hookConfig.pattern||"**";this.suppressErrors=hookConfig.suppressErrors||false;this.enabledPatterns=new Set;this.patternFilterActive=false;this.hooks=new Map;this.registrationOrder=0;this.reportedErrors=new WeakSet}on(typePattern,handler,options={}){let{type,pattern}=this.#parseTypePattern(typePattern);if(options.pattern!==void 0){pattern=options.pattern}if(!this.#validTypes.has(type)){throw new this.slothlet.SlothletError("INVALID_HOOK_TYPE",{type,validTypes:Array.from(this.#validTypes)})}if(typeof handler!=="function"){throw new this.slothlet.SlothletError("INVALID_HOOK_HANDLER",{receivedType:typeof handler,validationError:true})}const id=options.id||this.#generateId();if(this.#byId.has(id)){throw new this.slothlet.SlothletError("DUPLICATE_HOOK_ID",{id,validationError:true})}const subset=options.subset||"primary";if(!this.#validSubsets.has(subset)){throw new this.slothlet.SlothletError("INVALID_HOOK_SUBSET",{subset,validSubsets:Array.from(this.#validSubsets)})}this.#compilePattern(pattern);const hook={id,type,pattern,handler,priority:options.priority||0,subset,enabled:true,_compiled:null};const typeIndex=this.#hooks[type];const subsetIndex=typeIndex[subset];if(!subsetIndex[pattern]){subsetIndex[pattern]=[]}subsetIndex[pattern].push(hook);this.#byId.set(id,hook);return id}remove(filter={}){let removed=0;if(filter.id){const hook=this.#byId.get(filter.id);if(hook){this.#removeHook(hook);removed=1}return removed}const types=filter.type?[filter.type]:Array.from(this.#validTypes);for(const type of types){const typeIndex=this.#hooks[type];for(const subset of["before","primary","after"]){const subsetIndex=typeIndex[subset];if(filter.pattern){const patternHooks=subsetIndex[filter.pattern];if(patternHooks){removed+=patternHooks.length;patternHooks.forEach(hook=>this.#byId.delete(hook.id));delete subsetIndex[filter.pattern]}}else{for(const pattern in subsetIndex){const patternHooks=subsetIndex[pattern];removed+=patternHooks.length;patternHooks.forEach(hook=>this.#byId.delete(hook.id));delete subsetIndex[pattern]}}}}return removed}enable(filter={}){if(typeof filter==="string"){filter={pattern:filter}}this.enabled=true;return this.#setEnabledState(filter,true)}disable(filter={}){if(typeof filter==="string"){filter={pattern:filter}}if(Object.keys(filter).length===0){this.enabled=false}return this.#setEnabledState(filter,false)}list(filter={}){if(typeof filter==="string"){if(this.#validTypes.has(filter)){filter={type:filter}}else{filter={pattern:filter}}}const hooks=[];if(filter.id){const hook=this.#byId.get(filter.id);if(hook&&(filter.enabled===void 0||hook.enabled===filter.enabled)){hooks.push(this.#serializeHook(hook))}return{registeredHooks:hooks}}const types=filter.type?[filter.type]:Array.from(this.#validTypes);let patternMatcher=null;if(filter.pattern){patternMatcher=this.#compilePattern(filter.pattern)}for(const type of types){const typeIndex=this.#hooks[type];for(const subset of["before","primary","after"]){const subsetIndex=typeIndex[subset];for(const pattern in subsetIndex){const patternHooks=subsetIndex[pattern];for(const hook of patternHooks){if(filter.enabled!==void 0&&hook.enabled!==filter.enabled){continue}if(patternMatcher&&!patternMatcher(hook.pattern)){continue}hooks.push(this.#serializeHook(hook))}}}}return{registeredHooks:hooks}}getHooksForPath(type,apiPath){if(this.enabled===false){return[]}const typeIndex=this.#hooks[type];if(!typeIndex){return[]}const hooks=[];for(const subset of["before","primary","after"]){const subsetIndex=typeIndex[subset];const subsetHooks=[];for(const pattern in subsetIndex){const patternHooks=subsetIndex[pattern];if(pattern===apiPath){subsetHooks.push(...patternHooks.filter(h=>h.enabled));continue}for(const hook of patternHooks){if(!hook.enabled)continue;if(!hook._compiled){hook._compiled=this.#compilePattern(hook.pattern)}if(hook._compiled(apiPath)){subsetHooks.push(hook)}}}subsetHooks.sort((a,b)=>b.priority-a.priority);hooks.push(...subsetHooks)}return hooks}executeBeforeHooks(path,args,api,ctx){const hooks=this.getHooksForPath("before",path);for(const hook of hooks){try{const result=hook.handler({path,args,api,ctx});if(result&&typeof result==="object"&&typeof result.then==="function"){throw new this.SlothletError("HOOK_BEFORE_RETURNED_PROMISE",{id:hook.id,path},null,{validationError:true})}if(result!==void 0&&!Array.isArray(result)){return{args,shortCircuit:true,value:result}}if(Array.isArray(result)){args=result}}catch(error){const sourceInfo={type:"before",subset:hook.subset,hookTag:hook.id,hookId:hook.id,timestamp:Date.now(),stack:error.stack};this.executeErrorHooks(path,error,sourceInfo,args,api,ctx);if(!this.suppressErrors){throw error}return{args,shortCircuit:true,value:void 0}}}return{args,shortCircuit:false}}executeAfterHooks(path,result,args,api,ctx){const hooks=this.getHooksForPath("after",path);const originalResult=result;let currentResult=result;for(const hook of hooks){try{const hookContext={path,args,result:currentResult,api,ctx};const transformed=hook.handler(hookContext);if(transformed!==void 0){currentResult=transformed}}catch(error){const sourceInfo={type:"after",subset:hook.subset,hookTag:hook.id,hookId:hook.id,timestamp:Date.now(),stack:error.stack};this.executeErrorHooks(path,error,sourceInfo,args,api,ctx);if(!this.suppressErrors){throw error}}}if(currentResult===originalResult){return{modified:false}}else{return{modified:true,result:currentResult}}}executeAlwaysHooks(path,args,resultOrError,hasError=false,errors=[],api,ctx){const hooks=this.getHooksForPath("always",path);for(const hook of hooks){try{hook.handler({path,args,result:hasError?void 0:resultOrError,hasError,errors,api,ctx})}catch(error){const sourceInfo={type:"always",subset:hook.subset,hookTag:hook.id,hookId:hook.id,timestamp:Date.now(),stack:error.stack};this.executeErrorHooks(path,error,sourceInfo,args,api,ctx)}}}executeErrorHooks(path,error,source,args,api,ctx){if(error&&typeof error==="object"){error[ERROR_HOOK_PROCESSED]=true}const hooks=this.getHooksForPath("error",path);for(const hook of hooks){try{hook.handler({path,args,error,errorType:error?.constructor?.name||"Error",source,timestamp:new Date,api,ctx})}catch(hookError){this.slothlet.debug("hooks",`Error hook failed for ${path}:`,hookError)}}}#parseTypePattern(typePattern){if(typeof typePattern!=="string"){throw new this.slothlet.SlothletError("INVALID_TYPE_PATTERN",{typePattern,expected:"string in format 'type:pattern'"})}const colonIndex=typePattern.indexOf(":");if(colonIndex===-1){throw new this.slothlet.SlothletError("INVALID_TYPE_PATTERN",{typePattern,expected:"string in format 'type:pattern' with at least one colon"})}const type=typePattern.substring(0,colonIndex);const pattern=typePattern.substring(colonIndex+1);if(!type||!pattern){throw new this.slothlet.SlothletError("INVALID_TYPE_PATTERN",{typePattern,expected:"non-empty type and pattern"})}return{type,pattern}}#compilePattern(pattern){return compilePattern(pattern,{onMaxDepth:maxDepth=>{throw new this.SlothletError("HOOK_BRACE_EXPANSION_MAX_DEPTH",{maxDepth},null,{validationError:true})}})}getCompilePatternForDiagnostics(){return this.#compilePattern.bind(this)}#generateId(){return`hook-${++this.#idCounter}`}#removeHook(hook){const typeIndex=this.#hooks[hook.type];const subsetIndex=typeIndex[hook.subset];const patternHooks=subsetIndex[hook.pattern];if(!patternHooks){throw new this.slothlet.SlothletError("INTERNAL_HOOK_STATE_CORRUPT",{hookId:hook.id,type:hook.type,subset:hook.subset,pattern:hook.pattern,detail:"patternHooks array missing from subsetIndex \u2014 #byId and #hooks are desynced"})}const index=patternHooks.indexOf(hook);if(index===-1){throw new this.slothlet.SlothletError("INTERNAL_HOOK_STATE_CORRUPT",{hookId:hook.id,type:hook.type,subset:hook.subset,pattern:hook.pattern,detail:"hook object not found in patternHooks array \u2014 #byId and #hooks are desynced"})}patternHooks.splice(index,1);if(patternHooks.length===0){delete subsetIndex[hook.pattern]}this.#byId.delete(hook.id)}#setEnabledState(filter,enabled){let affected=0;if(filter.id){const hook=this.#byId.get(filter.id);if(hook){hook.enabled=enabled;affected=1}return affected}const types=filter.type?[filter.type]:Array.from(this.#validTypes);for(const type of types){const typeIndex=this.#hooks[type];for(const subset of["before","primary","after"]){const subsetIndex=typeIndex[subset];if(filter.pattern){const patternHooks=subsetIndex[filter.pattern]||[];for(const hook of patternHooks){hook.enabled=enabled;affected++}}else{for(const pattern in subsetIndex){const patternHooks=subsetIndex[pattern];for(const hook of patternHooks){hook.enabled=enabled;affected++}}}}}return affected}#serializeHook(hook){return{id:hook.id,type:hook.type,pattern:hook.pattern,priority:hook.priority,subset:hook.subset,enabled:hook.enabled}}exportHooks(){const registrations=[];for(const hook of this.#byId.values()){registrations.push({typePattern:`${hook.type}:${hook.pattern}`,handler:hook.handler,options:{id:hook.id,priority:hook.priority,subset:hook.subset},enabled:hook.enabled})}return registrations}importHooks(registrations){if(!Array.isArray(registrations))return;for(const reg of registrations){this.on(reg.typePattern,reg.handler,reg.options);if(!reg.enabled){this.disable({id:reg.options.id})}}}async shutdown(){this.#hooks={before:{before:{},primary:{},after:{}},after:{before:{},primary:{},after:{}},always:{before:{},primary:{},after:{}},error:{before:{},primary:{},after:{}}};this.#byId.clear();this.#idCounter=0}}export{HookManager};
|
|
@@ -14,31 +14,4 @@
|
|
|
14
14
|
limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
const instanceTokens = new WeakMap();
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
function registerInstance(slothlet) {
|
|
26
|
-
if (instanceTokens.has(slothlet)) {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
return;
|
|
30
|
-
}
|
|
31
|
-
instanceTokens.set(slothlet, Symbol("@cldmv/slothlet/lifecycle.tagToken"));
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
function getInstanceToken(slothlet) {
|
|
36
|
-
return instanceTokens.get(slothlet);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
function verifyToken(slothlet, token) {
|
|
41
|
-
return token === instanceTokens.get(slothlet);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export { registerInstance, getInstanceToken, verifyToken };
|
|
17
|
+
const instanceTokens=new WeakMap;function registerInstance(slothlet){if(instanceTokens.has(slothlet)){return}instanceTokens.set(slothlet,Symbol("@cldmv/slothlet/lifecycle.tagToken"))}function getInstanceToken(slothlet){return instanceTokens.get(slothlet)}function verifyToken(slothlet,token){return token===instanceTokens.get(slothlet)}export{getInstanceToken,registerInstance,verifyToken};
|