@cldmv/slothlet-types 3.15.2 → 3.16.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.
Files changed (58) hide show
  1. package/lib/builders/api-assignment.d.mts +125 -4
  2. package/lib/builders/api_builder.d.mts +104 -7
  3. package/lib/builders/builder.d.mts +82 -1
  4. package/lib/builders/modes-processor.d.mts +66 -3
  5. package/lib/errors.d.mts +114 -19
  6. package/lib/factories/component-base.d.mts +171 -8
  7. package/lib/factories/context.d.mts +22 -4
  8. package/lib/handlers/api-cache-manager.d.mts +209 -20
  9. package/lib/handlers/api-manager.d.mts +539 -38
  10. package/lib/handlers/context-async.d.mts +92 -25
  11. package/lib/handlers/context-live.d.mts +117 -30
  12. package/lib/handlers/framework-internals.d.mts +33 -2
  13. package/lib/handlers/hook-manager.d.mts +306 -73
  14. package/lib/handlers/lifecycle-token.d.mts +48 -3
  15. package/lib/handlers/lifecycle.d.mts +86 -5
  16. package/lib/handlers/materialize-manager.d.mts +76 -8
  17. package/lib/handlers/metadata.d.mts +238 -18
  18. package/lib/handlers/module-manager.d.mts +169 -21
  19. package/lib/handlers/ownership.d.mts +376 -45
  20. package/lib/handlers/permission-manager.d.mts +283 -46
  21. package/lib/handlers/routine-manager.d.mts +425 -0
  22. package/lib/handlers/trusted-root.d.mts +45 -4
  23. package/lib/handlers/unified-wrapper.d.mts +287 -26
  24. package/lib/handlers/version-manager.d.mts +236 -29
  25. package/lib/helpers/caller-pinning.d.mts +21 -2
  26. package/lib/helpers/class-instance-wrapper.d.mts +56 -2
  27. package/lib/helpers/config.d.mts +311 -161
  28. package/lib/helpers/defaults.d.mts +40 -0
  29. package/lib/helpers/eventemitter-context.d.mts +29 -3
  30. package/lib/helpers/eventtarget-context.d.mts +19 -1
  31. package/lib/helpers/eventtarget-property-context.d.mts +21 -0
  32. package/lib/helpers/generate-manifest.d.mts +174 -7
  33. package/lib/helpers/hint-detector.d.mts +22 -2
  34. package/lib/helpers/manifest-resolver.d.mts +100 -1
  35. package/lib/helpers/modes-utils.d.mts +30 -3
  36. package/lib/helpers/module-discovery.d.mts +80 -7
  37. package/lib/helpers/module-manifest-validator.d.mts +36 -13
  38. package/lib/helpers/module-sort.d.mts +64 -1
  39. package/lib/helpers/observer-context.d.mts +21 -0
  40. package/lib/helpers/pattern-matcher.d.mts +43 -3
  41. package/lib/helpers/platform.d.mts +109 -10
  42. package/lib/helpers/resolve-from-caller.d.mts +27 -3
  43. package/lib/helpers/sanitize.d.mts +92 -4
  44. package/lib/helpers/scheduler-context.d.mts +21 -1
  45. package/lib/helpers/utilities.d.mts +52 -4
  46. package/lib/i18n/translations.d.mts +50 -5
  47. package/lib/modes/eager.d.mts +46 -8
  48. package/lib/modes/lazy.d.mts +57 -10
  49. package/lib/processors/flatten.d.mts +116 -56
  50. package/lib/processors/loader.d.mts +77 -10
  51. package/lib/processors/type-generator.d.mts +16 -2
  52. package/lib/processors/typescript.d.mts +169 -13
  53. package/lib/runtime/runtime-asynclocalstorage.d.mts +71 -3
  54. package/lib/runtime/runtime-livebindings.d.mts +37 -2
  55. package/lib/runtime/runtime.d.mts +39 -3
  56. package/lib/typegen/typegen.d.mts +34 -2
  57. package/package.json +5 -23
  58. package/slothlet.d.mts +428 -3
@@ -1,5 +1,22 @@
1
+ /**
2
+ * Manages hooks for API function interception.
3
+ * Supports before/after/always/error hooks with pattern matching and priority ordering.
4
+ *
5
+ * @class HookManager
6
+ * @extends ComponentBase
7
+ */
1
8
  export class HookManager extends ComponentBase {
9
+ /**
10
+ * Property name for auto-discovery
11
+ * @type {string}
12
+ * @static
13
+ */
2
14
  static slothletProperty: string;
15
+ /**
16
+ * Creates a new HookManager instance.
17
+ * @param {object} slothlet - Parent slothlet instance
18
+ */
19
+ constructor(slothlet: object);
3
20
  enabled: boolean;
4
21
  defaultPattern: string;
5
22
  suppressErrors: boolean;
@@ -9,80 +26,296 @@ export class HookManager extends ComponentBase {
9
26
  hooks: Map<any, any>;
10
27
  registrationOrder: number;
11
28
  reportedErrors: WeakSet<object>;
12
- on(typePattern: any, handler: any, options?: {}): any;
13
- remove(filter?: {}): number;
14
- enable(filter?: {}): number;
15
- disable(filter?: {}): number;
16
- enablePattern(pattern: any): number;
17
- disablePattern(pattern: any): number;
18
- resetPatternFilter(): void;
19
- setPinEnforced(value: any): boolean;
20
- list(filter?: {}): {
21
- registeredHooks: {
22
- id: any;
23
- type: any;
24
- pattern: any;
25
- priority: any;
26
- subset: any;
27
- enabled: any;
28
- lockCaller: any;
29
- }[];
29
+ /**
30
+ * Register a hook for API functions.
31
+ *
32
+ * @param {string} typePattern - Path pattern then hook type, `"pattern:type"` (e.g. `"math.*:before"`).
33
+ * The legacy `"type:pattern"` form (e.g. `"before:math.*"`) is still accepted but deprecated.
34
+ * @param {function} handler - Hook handler function
35
+ * @param {object} [options={}] - Hook options
36
+ * @param {string} [options.id] - Unique identifier (auto-generated if not provided)
37
+ * @param {number} [options.priority=0] - Higher = earlier execution
38
+ * @param {string} [options.subset=DEFAULT_HOOK_SUBSET] - Phase: "before", "primary", or "after" ({@link HOOK_SUBSETS})
39
+ * @param {boolean} [options.lockCaller=true] - Pin the registering module's caller
40
+ * identity onto the handler so its `self.*` calls and permission checks are
41
+ * attributed to the module that registered the hook, not the caller whose API
42
+ * call triggered it. On by default; pass `false` to opt out — the handler then
43
+ * runs un-pinned, with whatever async context is ambient when it fires (for a
44
+ * `before` hook, typically none, so a `self.*` call inside it has no context).
45
+ * No effect when the hook is registered outside a module (no caller identity to
46
+ * capture) or when `handler` is already a `lockCaller`-wrapped function.
47
+ * @returns {string} Hook ID
48
+ * @public
49
+ *
50
+ * @example
51
+ * hookManager.on("math.*:before", ({ args }) => {
52
+ * console.log("Args:", args);
53
+ * return args;
54
+ * }, { priority: 100 });
55
+ */
56
+ public on(typePattern: string, handler: Function, options?: {
57
+ id?: string | undefined;
58
+ priority?: number | undefined;
59
+ subset?: string | undefined;
60
+ lockCaller?: boolean | undefined;
61
+ }): string;
62
+ /**
63
+ * Remove hooks matching filter criteria.
64
+ *
65
+ * @param {object} [filter={}] - Filter criteria
66
+ * @param {string} [filter.id] - Remove hook by ID
67
+ * @param {string} [filter.type] - Remove hooks by type
68
+ * @param {string} [filter.pattern] - Remove hooks matching pattern
69
+ * @returns {number} Number of hooks removed
70
+ * @public
71
+ */
72
+ public remove(filter?: {
73
+ id?: string | undefined;
74
+ type?: string | undefined;
75
+ pattern?: string | undefined;
76
+ }): number;
77
+ /**
78
+ * Enable hooks matching filter criteria.
79
+ *
80
+ * @param {object|string} [filter={}] - Filter criteria (empty = enable all, string = pattern)
81
+ * @param {string} [filter.id] - Enable hook by ID
82
+ * @param {string} [filter.type] - Enable hooks by type
83
+ * @param {string} [filter.pattern] - Enable hooks matching pattern
84
+ * @returns {number} Number of hooks enabled
85
+ * @public
86
+ */
87
+ public enable(filter?: object | string): number;
88
+ /**
89
+ * Disable hooks matching filter criteria.
90
+ *
91
+ * @param {object|string} [filter={}] - Filter criteria (empty = disable all, string = pattern)
92
+ * @param {string} [filter.id] - Disable hook by ID
93
+ * @param {string} [filter.type] - Disable hooks by type
94
+ * @param {string} [filter.pattern] - Disable hooks matching pattern
95
+ * @returns {number} Number of hooks disabled
96
+ * @public
97
+ */
98
+ public disable(filter?: object | string): number;
99
+ /**
100
+ * Restrict hook execution to a path pattern at runtime (the global path filter).
101
+ *
102
+ * Distinct from {@link enable}/{@link disable}, which toggle the `enabled` flag of
103
+ * individual registered hooks by their registration pattern. This narrows *which API
104
+ * paths* the hook system applies to at all — the runtime counterpart of the `hook.pattern`
105
+ * config. Once any pattern is enabled the filter is active, and a hook fires only when the
106
+ * called path matches at least one enabled pattern. Adding `"**"` matches every path.
107
+ *
108
+ * @param {string} pattern - Glob path pattern to restrict execution to (e.g. "math.*").
109
+ * @returns {number} The number of patterns now in the active filter.
110
+ * @public
111
+ *
112
+ * @example
113
+ * api.slothlet.hook.enablePattern("database.*"); // only intercept database.* paths
114
+ */
115
+ public enablePattern(pattern: string): number;
116
+ /**
117
+ * Remove a path pattern from the runtime global path filter.
118
+ *
119
+ * When the last enabled pattern is removed the filter deactivates, so hooks once again
120
+ * apply to every path (an unrestricted state, matching a `"**"` default).
121
+ *
122
+ * @param {string} pattern - The previously-enabled path pattern to remove.
123
+ * @returns {number} The number of patterns remaining in the filter.
124
+ * @public
125
+ *
126
+ * @example
127
+ * api.slothlet.hook.disablePattern("database.*"); // stop restricting to database.*
128
+ */
129
+ public disablePattern(pattern: string): number;
130
+ /**
131
+ * Reset the runtime global path filter back to the configured `hook.pattern` default.
132
+ *
133
+ * Clears any runtime {@link enablePattern}/{@link disablePattern} changes. If the configured
134
+ * default is the catch-all `"**"` the filter ends up inactive (unrestricted); otherwise it is
135
+ * re-seeded with the configured pattern.
136
+ *
137
+ * @returns {void}
138
+ * @public
139
+ */
140
+ public resetPatternFilter(): void;
141
+ /**
142
+ * Set the pin-enforcement policy at runtime (backs `api.slothlet.hook.pin.enable`/`disable`).
143
+ * When true (the default) module hooks are force-pinned to their owner; false permits a
144
+ * per-registration `lockCaller: false`. The public wrapper is host-only when permissions are
145
+ * enabled — `slothlet.hook.pin.*` falls under the `slothlet.hook.**` deny baseline.
146
+ *
147
+ * @param {boolean} value - True to enforce pinning (force-pin module hooks), false to permit unpinned.
148
+ * @returns {boolean} The policy value now in effect.
149
+ * @public
150
+ */
151
+ public setPinEnforced(value: boolean): boolean;
152
+ /**
153
+ * List registered hooks matching filter criteria.
154
+ *
155
+ * @param {object|string} [filter={}] - Filter criteria (empty = list all), type string, or pattern string
156
+ * @param {string} [filter.id] - List hook by ID
157
+ * @param {string} [filter.type] - List hooks by type
158
+ * @param {string} [filter.pattern] - List hooks matching pattern
159
+ * @param {boolean} [filter.enabled] - Filter by enabled state
160
+ * @returns {object} Object with registeredHooks array property
161
+ * @public
162
+ */
163
+ public list(filter?: object | string): object;
164
+ /**
165
+ * Get hooks for a specific API path and type.
166
+ * Used internally by UnifiedWrapper.
167
+ *
168
+ * @param {string} type - Hook type (before/after/always/error)
169
+ * @param {string} apiPath - API path (e.g., "math.add")
170
+ * @returns {Array<object>} Sorted array of matching hooks
171
+ * @public
172
+ */
173
+ public getHooksForPath(type: string, apiPath: string): Array<object>;
174
+ /**
175
+ * Derive the dispatch strategy for a path from the current hook set.
176
+ *
177
+ * @param {string} path - API path about to be called
178
+ * @returns {{asyncBefore: boolean, asyncAfter: boolean}} Whether any matching transforming
179
+ * hook is asynchronous.
180
+ * @public
181
+ *
182
+ * @description
183
+ * The strategy is a property of the CALL, derived per invocation from the registration state —
184
+ * never baked onto the leaf, so removing an async hook returns the path to synchronous
185
+ * dispatch. Only TRANSFORMING hooks (before/after) are consulted: `always` and `error` are
186
+ * observers whose return values are never consumed, so they never force promotion. Cached per
187
+ * path behind the registry epoch; the hot-path cost is one integer compare.
188
+ */
189
+ public getDispatchStrategy(path: string): {
190
+ asyncBefore: boolean;
191
+ asyncAfter: boolean;
30
192
  };
31
- getHooksForPath(type: any, apiPath: any): any[];
32
- getDispatchStrategy(path: any): any;
33
- executeBeforeHooks(path: any, args: any, api: any, ctx: any): {
34
- args: any;
35
- shortCircuit: boolean;
36
- value: any;
37
- } | {
38
- args: any;
39
- shortCircuit: boolean;
40
- value?: undefined;
41
- };
42
- executeAfterHooks(path: any, result: any, args: any, api: any, ctx: any): {
43
- modified: boolean;
44
- result?: undefined;
45
- } | {
46
- modified: boolean;
47
- result: any;
48
- };
49
- executeBeforeHooksAsync(path: any, args: any, api: any, ctx: any): Promise<{
50
- args: any;
51
- shortCircuit: boolean;
52
- value: any;
53
- } | {
54
- args: any;
55
- shortCircuit: boolean;
56
- value?: undefined;
57
- }>;
58
- executeAfterHooksAsync(path: any, result: any, args: any, api: any, ctx: any): Promise<{
59
- modified: boolean;
60
- result?: undefined;
61
- } | {
62
- modified: boolean;
63
- result: any;
64
- }>;
65
- executeAlwaysHooks(path: any, args: any, resultOrError: any, hasError: boolean | undefined, errors: any[] | undefined, api: any, ctx: any): void;
66
- executeErrorHooks(path: any, error: any, source: any, args: any, api: any, ctx: any): void;
67
- getCompilePatternForDiagnostics(): (pattern: any) => any;
68
- exportHooks(): {
69
- typePattern: string;
70
- handler: any;
71
- options: {
72
- id: any;
73
- priority: any;
74
- subset: any;
75
- lockCaller: any;
76
- async: any;
77
- };
78
- ownerPath: any;
79
- version: any;
80
- groupId: any;
81
- ownerFilePath: any;
82
- enabled: any;
83
- }[];
84
- importHooks(registrations: any): void;
85
- shutdown(): Promise<void>;
193
+ /**
194
+ * Execute before hooks for an API path.
195
+ *
196
+ * @param {string} path - API path being called
197
+ * @param {Array} args - Function arguments
198
+ * @param {object} api - Bound API object
199
+ * @param {object} ctx - User context object
200
+ * @returns {object} Result object: { args, shortCircuit, value }
201
+ * @public
202
+ */
203
+ public executeBeforeHooks(path: string, args: any[], api: object, ctx: object): object;
204
+ /**
205
+ * Execute after hooks for an API path.
206
+ *
207
+ * @param {string} path - API path being called
208
+ * @param {*} result - Function return value
209
+ * @param {Array} args - Original function arguments
210
+ * @param {object} api - Bound API object
211
+ * @param {object} ctx - User context object
212
+ * @returns {HookExecutionResult} Object indicating if result was modified and the final result
213
+ * @public
214
+ */
215
+ public executeAfterHooks(path: string, result: any, args: any[], api: object, ctx: object): HookExecutionResult;
216
+ /**
217
+ * Execute before hooks asynchronously — the promoted-pipeline twin of
218
+ * {@link executeBeforeHooks}.
219
+ *
220
+ * @param {string} path - API path being called
221
+ * @param {Array} args - Function arguments
222
+ * @param {object} api - Bound API object
223
+ * @param {object} ctx - User context object
224
+ * @returns {Promise<object>} Result object: { args, shortCircuit, value }
225
+ * @public
226
+ *
227
+ * @description
228
+ * Same protocol and strict registration order as the sync variant, with one difference: a
229
+ * handler's thenable return is AWAITED rather than refused — the caller of a promoted path
230
+ * already receives a Promise, so awaiting the chain changes nothing observable. A synchronous
231
+ * handler's return is used as-is (no microtask tick is inserted for it).
232
+ */
233
+ public executeBeforeHooksAsync(path: string, args: any[], api: object, ctx: object): Promise<object>;
234
+ /**
235
+ * Execute after hooks asynchronously — the promoted-pipeline twin of
236
+ * {@link executeAfterHooks}.
237
+ *
238
+ * @param {string} path - API path being called
239
+ * @param {*} result - Function return value (already settled)
240
+ * @param {Array} args - Original function arguments
241
+ * @param {object} api - Bound API object
242
+ * @param {object} ctx - User context object
243
+ * @returns {Promise<HookExecutionResult>} Object indicating if result was modified and the final result
244
+ * @public
245
+ *
246
+ * @description
247
+ * Same protocol and ordering as the sync variant; a thenable transform is awaited (that is the
248
+ * cell this pipeline exists for) and a synchronous transform costs no microtask tick.
249
+ */
250
+ public executeAfterHooksAsync(path: string, result: any, args: any[], api: object, ctx: object): Promise<HookExecutionResult>;
251
+ /**
252
+ * Execute always hooks for an API path.
253
+ *
254
+ * @param {string} path - API path being called
255
+ * @param {Array} args - Function arguments
256
+ * @param {*} resultOrError - Function result or error
257
+ * @param {boolean} hasError - Whether an error occurred
258
+ * @param {Array<Error>} errors - Array of errors that occurred
259
+ * @param {object} api - Bound API object
260
+ * @param {object} ctx - User context object
261
+ * @public
262
+ */
263
+ public executeAlwaysHooks(path: string, args: any[], resultOrError: any, hasError: boolean | undefined, errors: Array<Error> | undefined, api: object, ctx: object): void;
264
+ /**
265
+ * Execute error hooks for an API path.
266
+ *
267
+ * @param {string} path - API path being called
268
+ * @param {Error} error - The error that occurred
269
+ * @param {object} source - Error source info with type, hookTag, hookId, timestamp, stack
270
+ * @param {Array} args - Function arguments
271
+ * @param {object} api - Bound API object
272
+ * @param {object} ctx - User context object
273
+ * @public
274
+ */
275
+ public executeErrorHooks(path: string, error: Error, source: object, args: any[], api: object, ctx: object): void;
276
+ /**
277
+ * Get the pattern compilation function for diagnostic purposes.
278
+ * Only exposed when diagnostics mode is enabled.
279
+ *
280
+ * @returns {function} The pattern compilation function
281
+ * @internal
282
+ */
283
+ getCompilePatternForDiagnostics(): Function;
284
+ /**
285
+ * Export all registered hooks (including handler closures) so they can be
286
+ * re-registered on a fresh HookManager instance after a full reload.
287
+ *
288
+ * @returns {Array<object>} Snapshot of all current hook registrations.
289
+ * @public
290
+ */
291
+ public exportHooks(): Array<object>;
292
+ /**
293
+ * Re-register hooks exported by {@link exportHooks} into this (new) instance.
294
+ * Called after a full `api.slothlet.reload()` to restore user-registered hooks.
295
+ *
296
+ * @param {Array<object>} registrations - Snapshot returned by exportHooks().
297
+ * @returns {void}
298
+ * @public
299
+ */
300
+ public importHooks(registrations: Array<object>): void;
301
+ /**
302
+ * Cleanup hook manager on shutdown.
303
+ * @public
304
+ */
305
+ public shutdown(): Promise<void>;
86
306
  #private;
87
307
  }
308
+ /**
309
+ * Result returned by hook execution methods.
310
+ */
311
+ export type HookExecutionResult = {
312
+ /**
313
+ * - Whether any hook modified the result value.
314
+ */
315
+ modified: boolean;
316
+ /**
317
+ * - The final (possibly hook-modified) return value.
318
+ */
319
+ result?: any;
320
+ };
88
321
  import { ComponentBase } from "#factories/component-base";
@@ -1,3 +1,48 @@
1
- export function getInstanceToken(slothlet: any): any;
2
- export function registerInstance(slothlet: any): void;
3
- export function verifyToken(slothlet: any, token: any): boolean;
1
+ /**
2
+ * Registers a Slothlet instance and creates its per-instance lifecycle capability token.
3
+ *
4
+ * Safe to call multiple times on the same instance (idempotent) — subsequent calls are
5
+ * silently ignored, preserving the original token. This handles the reload code path where
6
+ * `load()` is called again on the same Slothlet object.
7
+ *
8
+ * @param {object} slothlet - The Slothlet instance to register.
9
+ * @returns {void}
10
+ * @package
11
+ *
12
+ * @example
13
+ * // Called once (or on reload) in Slothlet.load():
14
+ * registerInstance(this);
15
+ */
16
+ export function registerInstance(slothlet: object): void;
17
+ /**
18
+ * Returns the per-instance capability token for the given Slothlet instance.
19
+ *
20
+ * Used internally by `lifecycle.mjs` (emit dispatch) and `modes-processor.mjs`
21
+ * (direct tagSystemMetadata call for folder wrappers). Requires a live registered
22
+ * Slothlet instance — cannot be exploited without one.
23
+ *
24
+ * @param {object} slothlet - A registered Slothlet instance.
25
+ * @returns {symbol|undefined} The instance token, or undefined if not registered.
26
+ * @package
27
+ *
28
+ * @example
29
+ * handler(data, getInstanceToken(this.slothlet));
30
+ */
31
+ export function getInstanceToken(slothlet: object): symbol | undefined;
32
+ /**
33
+ * Verifies that `token` is the registered capability token for the given Slothlet instance.
34
+ *
35
+ * Used by `metadata.mjs` inside `tagSystemMetadata()` to reject calls that did not
36
+ * originate from the internal lifecycle dispatch path.
37
+ *
38
+ * @param {object} slothlet - A registered Slothlet instance.
39
+ * @param {*} token - The token value to verify.
40
+ * @returns {boolean} `true` only if `token` is the exact Symbol registered for `slothlet`.
41
+ * @package
42
+ *
43
+ * @example
44
+ * if (!verifyToken(this.slothlet, token)) {
45
+ * throw new this.SlothletError("METADATA_LIFECYCLE_BYPASS", ...);
46
+ * }
47
+ */
48
+ export function verifyToken(slothlet: object, token: any): boolean;
@@ -1,12 +1,93 @@
1
+ /**
2
+ * Lifecycle event manager for impl changes
3
+ * @extends ComponentBase
4
+ * @public
5
+ */
1
6
  export class Lifecycle extends ComponentBase {
7
+ /**
8
+ * Where this component should be mounted on the Slothlet instance
9
+ * @type {string}
10
+ */
2
11
  static slothletProperty: string;
12
+ /**
13
+ * @param {object} slothlet - Slothlet instance
14
+ */
15
+ constructor(slothlet: object);
3
16
  subscribers: Map<any, any>;
4
17
  eventLog: any[];
5
18
  maxLogSize: number;
6
- subscribe(event: any, handler: any): () => void;
7
- on(event: any, handler: any): () => void;
8
- off(event: any, handler: any): void;
9
- unsubscribe(event: any, handler: any): void;
10
- emit(event: any, data: any): Promise<void>;
19
+ /**
20
+ * Subscribe to lifecycle event
21
+ * @param {string} event - Event name (impl:created, impl:changed, impl:removed, materialized:complete, path:collision)
22
+ * @param {Function} handler - Event handler function(eventData)
23
+ * @returns {Function} Unsubscribe function
24
+ * @public
25
+ *
26
+ * @description
27
+ * Subscribe to lifecycle events to react to impl changes.
28
+ *
29
+ * @example
30
+ * const unsubscribe = lifecycle.subscribe("impl:changed", (data) => {
31
+ * console.log("Impl changed:", data.apiPath, data.source);
32
+ * });
33
+ */
34
+ public subscribe(event: string, handler: Function): Function;
35
+ /**
36
+ * Alias for subscribe() - standard EventEmitter pattern
37
+ * @param {string} event - Event name
38
+ * @param {Function} handler - Event handler function
39
+ * @returns {Function} Unsubscribe function
40
+ * @public
41
+ *
42
+ * @example
43
+ * lifecycle.on('materialized:complete', (data) => {
44
+ * console.log(`${data.total} modules materialized`);
45
+ * });
46
+ */
47
+ public on(event: string, handler: Function): Function;
48
+ /**
49
+ * Unsubscribe from lifecycle event - standard EventEmitter pattern
50
+ * @param {string} event - Event name
51
+ * @param {Function} handler - Event handler function to remove
52
+ * @public
53
+ *
54
+ * @example
55
+ * const handler = (data) => console.log(data);
56
+ * lifecycle.on('impl:changed', handler);
57
+ * lifecycle.off('impl:changed', handler);
58
+ */
59
+ public off(event: string, handler: Function): void;
60
+ /**
61
+ * Alias for off() - standard EventEmitter pattern
62
+ * @param {string} event - Event name
63
+ * @param {Function} handler - Event handler function to remove
64
+ * @public
65
+ */
66
+ public unsubscribe(event: string, handler: Function): void;
67
+ /**
68
+ * Emit lifecycle event
69
+ * @param {string} event - Event name
70
+ * @param {object} data - Event data
71
+ * @private
72
+ *
73
+ * @description
74
+ * Emit event to all subscribers. Event data should include:
75
+ * - apiPath: API path where impl exists
76
+ * - impl: The implementation object
77
+ * - source: Source of event (initial, hot-reload, materialization, etc)
78
+ * - moduleID: Module identifier (if applicable)
79
+ * - filePath: File path (if applicable)
80
+ * - metadata: Additional metadata
81
+ *
82
+ * @example
83
+ * lifecycle.emit("impl:created", {
84
+ * apiPath: "math.add",
85
+ * impl: addFunction,
86
+ * source: "initial",
87
+ * moduleID: "base_abc123",
88
+ * filePath: "/path/to/math.mjs"
89
+ * });
90
+ */
91
+ private emit;
11
92
  }
12
93
  import { ComponentBase } from "#factories/component-base";
@@ -1,12 +1,80 @@
1
+ /**
2
+ * Manager for tracking lazy folder materialization state
3
+ * @class MaterializeManager
4
+ * @extends ComponentBase
5
+ * @package
6
+ *
7
+ * @description
8
+ * Provides access to lazy materialization state via `api.slothlet.materialize`.
9
+ * Tracks count of unmaterialized lazy folders and provides boolean state, statistics,
10
+ * and wait functionality for synchronization.
11
+ *
12
+ * @example
13
+ * const api = await slothlet({ base: "./api", mode: "lazy" });
14
+ *
15
+ * // Check if fully materialized
16
+ * if (api.slothlet.materialize.materialized) {
17
+ * console.log("All lazy folders loaded!");
18
+ * }
19
+ *
20
+ * // Get statistics
21
+ * const stats = api.slothlet.materialize.get();
22
+ * console.log(`${stats.percentage}% loaded (${stats.remaining}/${stats.total} remaining)`);
23
+ *
24
+ * // Wait for full materialization
25
+ * await api.slothlet.materialize.wait();
26
+ */
1
27
  export class MaterializeManager extends ComponentBase {
2
28
  static slothletProperty: string;
3
- get materialized(): boolean;
4
- get(): {
5
- total: any;
6
- materialized: number;
7
- remaining: any;
8
- percentage: number;
9
- };
10
- wait(): Promise<any>;
29
+ /**
30
+ * Create MaterializeManager instance
31
+ * @param {object} slothlet - Slothlet orchestrator instance
32
+ * @package
33
+ */
34
+ constructor(slothlet: object);
35
+ /**
36
+ * Get materialization state as a boolean
37
+ * Returns true when all lazy wrappers have been materialized
38
+ * @returns {boolean} True if fully materialized, false if any lazy folders remain
39
+ * @public
40
+ *
41
+ * @example
42
+ * if (api.slothlet.materialize.materialized) {
43
+ * console.log("API is fully loaded");
44
+ * }
45
+ */
46
+ public get materialized(): boolean;
47
+ /**
48
+ * Get detailed materialization statistics
49
+ * @returns {Object} Statistics object with total, materialized, remaining, percentage
50
+ * @public
51
+ *
52
+ * @example
53
+ * const stats = api.slothlet.materialize.get();
54
+ * // { total: 5, materialized: 3, remaining: 2, percentage: 60 }
55
+ */
56
+ public get(): Object;
57
+ /**
58
+ * Wait for full materialization (all lazy folders loaded)
59
+ * Returns immediately if already fully materialized
60
+ * @returns {Promise<void>} Resolves when all lazy wrappers have materialized
61
+ * @public
62
+ *
63
+ * @example
64
+ * // Wait for API to fully load
65
+ * await api.slothlet.materialize.wait();
66
+ * console.log("All modules loaded!");
67
+ *
68
+ * @example
69
+ * // Wait with timeout
70
+ * const timeoutPromise = new Promise((_, reject) =>
71
+ * setTimeout(() => reject(new Error("Timeout")), 5000)
72
+ * );
73
+ * await Promise.race([
74
+ * api.slothlet.materialize.wait(),
75
+ * timeoutPromise
76
+ * ]);
77
+ */
78
+ public wait(): Promise<void>;
11
79
  }
12
80
  import { ComponentBase } from "#factories/component-base";