@cldmv/slothlet 3.15.3 → 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/README.md +7 -5
  2. package/dist/lib/builders/api-assignment.mjs +1 -1
  3. package/dist/lib/builders/api_builder.mjs +1 -1
  4. package/dist/lib/builders/builder.mjs +1 -1
  5. package/dist/lib/builders/modes-processor.mjs +1 -1
  6. package/dist/lib/handlers/api-cache-manager.mjs +1 -1
  7. package/dist/lib/handlers/api-manager.mjs +1 -1
  8. package/dist/lib/handlers/module-manager.mjs +1 -1
  9. package/dist/lib/handlers/ownership.mjs +1 -1
  10. package/dist/lib/handlers/routine-manager.mjs +17 -0
  11. package/dist/lib/handlers/unified-wrapper.mjs +1 -1
  12. package/dist/lib/helpers/config.mjs +1 -1
  13. package/dist/lib/helpers/defaults.mjs +1 -1
  14. package/dist/lib/helpers/eventtarget-property-context.mjs +17 -0
  15. package/dist/lib/helpers/observer-context.mjs +17 -0
  16. package/dist/lib/helpers/scheduler-context.mjs +1 -1
  17. package/dist/lib/i18n/languages/en-us.json +2 -0
  18. package/dist/lib/modes/eager.mjs +1 -1
  19. package/dist/lib/processors/flatten.mjs +1 -1
  20. package/dist/slothlet.mjs +1 -1
  21. package/index.cjs +20 -0
  22. package/index.mjs +14 -0
  23. package/package.json +8 -7
  24. package/types/stub/devcheck.d.mts +1 -1
  25. package/types/stub/lib/builders/api-assignment.d.mts +130 -2
  26. package/types/stub/lib/builders/api_builder.d.mts +109 -2
  27. package/types/stub/lib/builders/builder.d.mts +87 -2
  28. package/types/stub/lib/builders/modes-processor.d.mts +71 -2
  29. package/types/stub/lib/factories/component-base.d.mts +177 -0
  30. package/types/stub/lib/helpers/caller-pinning.d.mts +22 -2
  31. package/types/stub/lib/helpers/class-instance-wrapper.d.mts +58 -2
  32. package/types/stub/lib/helpers/config.d.mts +321 -2
  33. package/types/stub/lib/helpers/defaults.d.mts +41 -2
  34. package/types/stub/lib/helpers/eventemitter-context.d.mts +31 -2
  35. package/types/stub/lib/helpers/eventtarget-context.d.mts +21 -2
  36. package/types/stub/lib/helpers/eventtarget-property-context.d.mts +23 -0
  37. package/types/stub/lib/helpers/generate-manifest.d.mts +180 -2
  38. package/types/stub/lib/helpers/hint-detector.d.mts +27 -2
  39. package/types/stub/lib/helpers/manifest-resolver.d.mts +101 -2
  40. package/types/stub/lib/helpers/modes-utils.d.mts +35 -2
  41. package/types/stub/lib/helpers/module-discovery.d.mts +81 -2
  42. package/types/stub/lib/helpers/module-manifest-validator.d.mts +37 -2
  43. package/types/stub/lib/helpers/module-sort.d.mts +65 -2
  44. package/types/stub/lib/helpers/observer-context.d.mts +23 -0
  45. package/types/stub/lib/helpers/pattern-matcher.d.mts +44 -2
  46. package/types/stub/lib/helpers/platform.d.mts +111 -2
  47. package/types/stub/lib/helpers/resolve-from-caller.d.mts +33 -2
  48. package/types/stub/lib/helpers/scheduler-context.d.mts +23 -2
  49. package/types/stub/lib/helpers/utilities.d.mts +57 -2
  50. package/types/stub/lib/i18n/translations.d.mts +52 -2
  51. package/types/stub/lib/modes/eager.d.mts +56 -2
  52. package/types/stub/lib/modes/lazy.d.mts +67 -2
  53. package/types/stub/lib/processors/flatten.d.mts +123 -2
  54. package/types/stub/lib/processors/loader.d.mts +83 -2
  55. package/types/stub/lib/processors/type-generator.d.mts +19 -2
  56. package/types/stub/lib/processors/typescript.d.mts +174 -2
  57. package/types/stub/lib/runtime/runtime-asynclocalstorage.d.mts +72 -2
  58. package/types/stub/lib/runtime/runtime-livebindings.d.mts +38 -2
@@ -1,3 +1,322 @@
1
1
  // AUTO-GENERATED by tools/build/build-typestubs.mjs — do not edit.
2
- // Re-exports the real declarations from @cldmv/slothlet-types (install it for TypeScript support).
3
- export * from "@cldmv/slothlet-types/helpers/config";
2
+ // Self-contained copy: this subpath is internal and not published by @cldmv/slothlet-types.
3
+ /**
4
+ * Normalize the `hook` config (V2-style support) into a canonical
5
+ * `{ enabled, pattern, suppressErrors }` object.
6
+ *
7
+ * Accepts the boolean form (enable/disable with the catch-all pattern), the string form
8
+ * (enable, restricting hooks to a global path pattern — e.g. `"database.*"`), or the full
9
+ * object form. Idempotent: an already-normalized object normalizes to an equivalent object,
10
+ * so `reload()` can re-feed it.
11
+ *
12
+ * Exported as a standalone function (not just a {@link Config} method) because the HookManager
13
+ * is constructed during `_initializeComponents` — BEFORE `transformConfig` runs — so it cannot
14
+ * rely on the normalized config being in place yet, and must normalize the raw `config.hook`
15
+ * itself from the same source of truth.
16
+ *
17
+ * @param {boolean|string|Object} [hook] - Raw hook config in any supported form.
18
+ * @returns {{enabled: boolean, pattern: (string|null), suppressErrors: boolean, pin: boolean}} Normalized hook config.
19
+ * @public
20
+ */
21
+ export function normalizeHookConfig(hook?: boolean | string | Object): {
22
+ enabled: boolean;
23
+ pattern: (string | null);
24
+ suppressErrors: boolean;
25
+ pin: boolean;
26
+ };
27
+ /**
28
+ * Configuration normalization utilities
29
+ * @class Config
30
+ * @extends ComponentBase
31
+ * @public
32
+ */
33
+ export class Config extends ComponentBase {
34
+ static slothletProperty: string;
35
+ /**
36
+ * Normalize collision configuration for handling property collisions
37
+ * @param {string|Object} collision - Collision mode or object with per-context modes
38
+ * @returns {Object} Normalized collision configuration with initial and api.slothlet.api.add modes
39
+ * @public
40
+ *
41
+ * @description
42
+ * Normalizes collision handling configuration for both initial load (buildAPI)
43
+ * and hot reload (api.add) contexts. Supports six collision modes:
44
+ * - "skip": Silently ignore collision, keep existing value
45
+ * - "warn": Warn about collision, keep existing value
46
+ * - "replace": Replace existing value completely
47
+ * - "merge": Merge properties (preserve original + add new)
48
+ * - "merge-replace": Merge properties (add new + overwrite existing with new values)
49
+ * - "error": Throw error on collision
50
+ *
51
+ * @example
52
+ * // String shorthand applies to both contexts
53
+ * normalizeCollision("merge")
54
+ * // => { initial: "merge", api: "merge" }
55
+ *
56
+ * @example
57
+ * // Object allows per-context control
58
+ * normalizeCollision({ initial: "warn", api: "error" })
59
+ * // => { initial: "warn", api: "error" }
60
+ */
61
+ public normalizeCollision(collision: string | Object): Object;
62
+ /**
63
+ * Normalize runtime input to internal standard format
64
+ * @param {string} runtime - Input runtime type (various formats accepted)
65
+ * @returns {string} Normalized runtime type ("async" or "live")
66
+ * @public
67
+ */
68
+ public normalizeRuntime(runtime: string): string;
69
+ /**
70
+ * Normalize mode input to internal standard format
71
+ * @param {string} mode - Input mode type (various formats accepted)
72
+ * @returns {string} Normalized mode type ("eager" or "lazy")
73
+ * @public
74
+ */
75
+ public normalizeMode(mode: string): string;
76
+ /**
77
+ * Normalize mutations configuration for API modification control
78
+ * @param {Object} mutations - Mutations config object with add/remove/reload properties
79
+ * @returns {Object} Normalized mutations configuration
80
+ * @public
81
+ *
82
+ * @description
83
+ * Normalizes mutation control configuration for API runtime modifications.
84
+ * Controls whether api.slothlet.api.add(), api.slothlet.api.remove(), and
85
+ * api.slothlet.reload() operations are allowed.
86
+ *
87
+ * @example
88
+ * // Allow all mutations (default)
89
+ * normalizeMutations({ add: true, remove: true, reload: true })
90
+ * // => { add: true, remove: true, reload: true }
91
+ *
92
+ * @example
93
+ * // Disable all mutations
94
+ * normalizeMutations({ add: false, remove: false, reload: false })
95
+ * // => { add: false, remove: false, reload: false }
96
+ */
97
+ public normalizeMutations(mutations: Object): Object;
98
+ /**
99
+ * Normalize debug configuration
100
+ * @param {boolean|Object} debug - Debug flag or object with targeted flags
101
+ * @returns {Object} Normalized debug object with all flags
102
+ * @public
103
+ */
104
+ public normalizeDebug(debug: boolean | Object): Object;
105
+ /**
106
+ * Normalize execution-environment target from the raw `platform` config value.
107
+ *
108
+ * @description
109
+ * Distinct from `normalizeEnv()` which handles the `process.env` snapshot
110
+ * allowlist (`config.env`). This method determines *where* slothlet is executing
111
+ * so that filesystem-dependent code paths can be bypassed in browser/worker builds.
112
+ *
113
+ * When `platform` is omitted the method auto-detects by checking whether
114
+ * `process.versions.node` is available (true in Node.js; absent or undefined
115
+ * in browsers, web workers, and Electron renderers without nodeIntegration).
116
+ * Pass `"browser"` or `"node"` to override auto-detection for edge cases
117
+ * (e.g. Deno, Electron with custom process polyfills).
118
+ *
119
+ * @param {*} platform - Raw value of `config.platform` before normalisation.
120
+ * @returns {"browser"|"node"} Execution-environment target.
121
+ * @public
122
+ *
123
+ * @example
124
+ * normalizeEnvTarget("browser"); // => "browser" (explicit override)
125
+ * normalizeEnvTarget("node"); // => "node" (explicit override)
126
+ * normalizeEnvTarget(undefined); // => "browser" or "node" (auto-detected)
127
+ */
128
+ public normalizeEnvTarget(platform: any, hasManifest?: boolean): "browser" | "node";
129
+ /**
130
+ * Normalize the `hook` config (V2-style support) into a canonical
131
+ * `{ enabled, pattern, suppressErrors }` object.
132
+ *
133
+ * Accepts the boolean form (enable/disable with the catch-all pattern), the string form
134
+ * (enable, restricting hooks to a global path pattern — e.g. `"database.*"`), or the full
135
+ * object form. Idempotent: an already-normalized object normalizes to an equivalent object,
136
+ * so `reload()` can re-feed it. Shared by {@link transformConfig} and the HookManager so both
137
+ * derive the same values regardless of construction order (the manager is built before
138
+ * transformConfig runs, so it cannot rely on the normalized config being in place yet).
139
+ *
140
+ * @param {boolean|string|Object} [hook] - Raw hook config in any supported form.
141
+ * @returns {{enabled: boolean, pattern: (string|null), suppressErrors: boolean, pin: boolean}} Normalized hook config.
142
+ * @public
143
+ */
144
+ public normalizeHook(hook?: boolean | string | Object): {
145
+ enabled: boolean;
146
+ pattern: (string | null);
147
+ suppressErrors: boolean;
148
+ pin: boolean;
149
+ };
150
+ /**
151
+ * Transform and validate configuration
152
+ * @param {Object} config - Raw configuration options
153
+ * @returns {Object} Normalized configuration
154
+ * @throws {SlothletError} If configuration is invalid
155
+ * @public
156
+ */
157
+ public transformConfig(config?: Object): Object;
158
+ /**
159
+ * Normalize and validate the suppressFixes option. Emits a deprecation warning for each
160
+ * rule ID present. Invalid entries (non-strings, unknown rule IDs) are silently dropped.
161
+ *
162
+ * @param {string[]|undefined} suppressFixes - Raw suppressFixes value from user config.
163
+ * @param {boolean} silent - If true, suppress warnings.
164
+ * @returns {Set<string>} Normalized set of suppressed rule IDs.
165
+ * @example
166
+ * // Rule IDs use the <rule>_<PR> form. The C03 fix landed in PR #116.
167
+ * normalizeSuppressFixes(["C03_116"], false); // emits WARN_SUPPRESS_FIX_ACTIVE for C03_116
168
+ * @public
169
+ */
170
+ public normalizeSuppressFixes(suppressFixes: string[] | undefined, silent: boolean): Set<string>;
171
+ /**
172
+ * Normalize TypeScript configuration
173
+ * @param {boolean|string|Object} typescript - TypeScript config (true, "fast", or { mode: "fast"|"strict", ... })
174
+ * @returns {Object|null} Normalized TypeScript configuration or null if disabled
175
+ * @public
176
+ */
177
+ public normalizeTypeScript(typescript: boolean | string | Object): Object | null;
178
+ /**
179
+ * Normalize env snapshot configuration.
180
+ *
181
+ * @description
182
+ * Validates the `env` option from user config. When `include` is a non-empty
183
+ * string array, returns `{ include }` (the allowlist used by `_captureEnvSnapshot`).
184
+ * Any other value — including `undefined`, `null`, `{}`, or an empty `include`
185
+ * array — is normalised to `null`, meaning the full `process.env` snapshot is used.
186
+ *
187
+ * @param {Object|null|undefined} env - Raw env option from user config.
188
+ * @param {string[]} [env.include] - Allowlist of env variable names to capture.
189
+ * @returns {{ include: string[] }|null} Normalized env config, or `null` for full snapshot.
190
+ * @public
191
+ *
192
+ * @example
193
+ * // No restriction — full snapshot
194
+ * normalizeEnv(undefined); // => null
195
+ * normalizeEnv(null); // => null
196
+ * normalizeEnv({}); // => null
197
+ *
198
+ * @example
199
+ * // Include allowlist
200
+ * normalizeEnv({ include: ["NODE_ENV", "PORT"] });
201
+ * // => { include: ["NODE_ENV", "PORT"] }
202
+ *
203
+ * @example
204
+ * // Non-string keys in the include array are filtered out
205
+ * normalizeEnv({ include: ["NODE_ENV", 42, null] });
206
+ * // => { include: ["NODE_ENV"] }
207
+ */
208
+ public normalizeEnv(env: Object | null | undefined): {
209
+ include: string[];
210
+ } | null;
211
+ /**
212
+ * Normalize + validate the construction-time `lifecycle` subscription map (#148).
213
+ *
214
+ * @description
215
+ * The `lifecycle` option registers event handlers on the Lifecycle emitter BEFORE the api builds,
216
+ * so events emitted during cold-start `buildAPI` (init-time `impl:warning` / `impl:created` / …)
217
+ * are observable. It is a plain object mapping an event name to a handler function or an array of
218
+ * handler functions. Any event name is accepted — registration is just early `subscribe()` calls,
219
+ * so these handlers also receive runtime events afterward.
220
+ *
221
+ * Idempotent: an already-normalized map (values already functions / arrays of functions) passes
222
+ * through unchanged, so `reload()` can re-feed it.
223
+ *
224
+ * @param {object|null|undefined} lifecycle - Raw `lifecycle` option from user config.
225
+ * @returns {object|null} The validated map, or `null` when absent.
226
+ * @throws {SlothletError} INVALID_CONFIG when the shape is not a plain object of functions / function arrays.
227
+ * @public
228
+ *
229
+ * @example
230
+ * normalizeLifecycle({ "impl:warning": (data) => log(data) });
231
+ * // => { "impl:warning": (data) => log(data) }
232
+ *
233
+ * @example
234
+ * normalizeLifecycle({ "impl:error": [onError, auditError] });
235
+ * // => { "impl:error": [onError, auditError] }
236
+ */
237
+ public normalizeLifecycle(lifecycle: object | null | undefined): object | null;
238
+ /**
239
+ * Normalize + validate the `routines` config option (#341).
240
+ *
241
+ * @description
242
+ * A routine is a named cross-module runnable: every mounted module that exports a function
243
+ * matching a configured routine name gets stacked into one chain at its resolved api path, and
244
+ * a root cascade runs every matching contribution anywhere, ordered per the entry's `order`.
245
+ * See `docs/LIFECYCLE.md` ("Routines") for the full contract.
246
+ *
247
+ * Each entry normalizes to `{ name, mode, recursive, order }` — `recursive` and `order` are
248
+ * always present on the normalized output, even when the raw entry omitted them:
249
+ * - `"name"` (string, no `:`) → `{ name, mode: "manual", recursive: false, order: "mount" }`.
250
+ * - `"name:mode"` (string, split once on the first `:`) → `{ name, mode, recursive: false, order: <mode-defaulted> }`.
251
+ * - `{ name, mode?, recursive?, order? }` (object) → `mode` defaults to `"manual"`, `recursive` to
252
+ * `false`, and `order` to {@link DEFAULT_ROUTINE_ORDER_BY_MODE}`[mode]` when each is omitted.
253
+ *
254
+ * Providing `routines` at all REPLACES {@link DEFAULT_ROUTINES} — that is the off-switch
255
+ * (`routines: []` disables every routine). Omitting the option keeps the built-in defaults.
256
+ * `slothlet.defaults.routines` is the frozen source of those defaults, exported for a consumer
257
+ * to spread (extend) or filter (drop one) rather than replace wholesale.
258
+ *
259
+ * Idempotent: an already-normalized list (every entry already `{ name, mode, recursive, order }`)
260
+ * normalizes to an equivalent list — same values, always freshly-built objects (never the same
261
+ * references) — so `reload()` can safely re-feed it.
262
+ *
263
+ * @param {undefined|null|Array<string|{name: string, mode?: string, recursive?: boolean, order?: string}>} routines - Raw `routines` option.
264
+ * @returns {Array<{name: string, mode: "manual"|"startup"|"shutdown"|"destroy", recursive: boolean, order: "mount"|"depth"}>} Normalized routines list.
265
+ * @throws {SlothletError} INVALID_CONFIG when the shape is invalid, a name is empty/reserved/an invalid glob, or a mode/order is unrecognized.
266
+ * @public
267
+ *
268
+ * @example
269
+ * normalizeRoutines(undefined);
270
+ * // => [{ name: "initialize", mode: "startup", recursive: false, order: "mount" },
271
+ * // { name: "shutdown", mode: "shutdown", recursive: false, order: "depth" }]
272
+ *
273
+ * @example
274
+ * normalizeRoutines(["launch", "prefetch:startup", { name: "warmup" }]);
275
+ * // => [{ name: "launch", mode: "manual", recursive: false, order: "mount" },
276
+ * // { name: "prefetch", mode: "startup", recursive: false, order: "mount" },
277
+ * // { name: "warmup", mode: "manual", recursive: false, order: "mount" }]
278
+ *
279
+ * @example
280
+ * normalizeRoutines([]);
281
+ * // => [] — disables every routine
282
+ */
283
+ public normalizeRoutines(routines: undefined | null | Array<string | {
284
+ name: string;
285
+ mode?: string;
286
+ recursive?: boolean;
287
+ order?: string;
288
+ }>): Array<{
289
+ name: string;
290
+ mode: "manual" | "startup" | "shutdown" | "destroy";
291
+ recursive: boolean;
292
+ order: "mount" | "depth";
293
+ }>;
294
+ /**
295
+ * Normalize permissions configuration.
296
+ *
297
+ * @param {object|null} [permissions] - Raw permissions config from user.
298
+ * @param {string} [permissions.defaultPolicy="allow"] - Fallback policy: "allow" or "deny".
299
+ * @param {boolean} [permissions.enabled=true] - Global toggle.
300
+ * @param {string|boolean} [permissions.audit="default"] - Audit level: `"default"` (denied + self-bypass only),
301
+ * `"verbose"` (all decisions). `true` and `false` are accepted and both normalize to `"default"`.
302
+ * @param {object} [permissions.references] - Options governing api functions held as references.
303
+ * @param {boolean} [permissions.references.capture=true] - When `true` (the default), a function read
304
+ * out of the api carries the identity of the module that read it, so it stays enforced as that module
305
+ * wherever it is later invoked. Set `false` to restore the older host-initiated treatment.
306
+ * @param {boolean} [permissions.failOpenOnAbsentCaller=false] - When `false` (the default), calls
307
+ * and reads occurring inside an active context with no resolvable (or forged) caller identity
308
+ * fail closed (denied); only genuinely host-initiated calls are exempt via the trusted-root
309
+ * marker. Set `true` to restore the legacy fail-open behaviour.
310
+ * @param {boolean} [permissions.readGating=true] - When `true` (the default), reading a terminal
311
+ * data value (primitive, Buffer, TypedArray, Date, Map, etc.) off a module API path is
312
+ * permission-checked, the same way calls are. Set `false` to opt out and gate calls only.
313
+ * @param {Array<object>} [permissions.rules=[]] - Initial permission rules.
314
+ * @returns {object|null} Normalized permissions config, or null when permissions is absent or not an object.
315
+ *
316
+ * @example
317
+ * normalizePermissions({ defaultPolicy: "deny", rules: [{ caller: "**", target: "admin.**", effect: "deny" }] });
318
+ * // => { defaultPolicy: "deny", enabled: true, audit: "default", readGating: true, rules: [...] }
319
+ */
320
+ normalizePermissions(permissions?: object | null): object | null;
321
+ }
322
+ import { ComponentBase } from "#factories/component-base";
@@ -1,3 +1,42 @@
1
1
  // AUTO-GENERATED by tools/build/build-typestubs.mjs — do not edit.
2
- // Re-exports the real declarations from @cldmv/slothlet-types (install it for TypeScript support).
3
- export * from "@cldmv/slothlet-types/helpers/defaults";
2
+ // Self-contained copy: this subpath is internal and not published by @cldmv/slothlet-types.
3
+ /**
4
+ * The default `apiDepth` (directory-traversal depth) applied when a caller does not specify one.
5
+ * Unbounded by default. The config normalizer ({@link module:@cldmv/slothlet/helpers/config}) is
6
+ * what every real compose path reads — it resolves `config.apiDepth` once and the mode processors
7
+ * receive that already-normalized value. The mode processors' and the loader's own parameter
8
+ * defaults exist only for the case where they are invoked directly, bypassing normalization (a
9
+ * standalone call, a future direct consumer); they read this same constant so that case can never
10
+ * silently disagree with the normalized default.
11
+ * @type {number}
12
+ */
13
+ export const DEFAULT_API_DEPTH: number;
14
+ /**
15
+ * The built-in `routines` list applied when a caller omits the `routines` config option entirely.
16
+ * Each entry is `{ name, mode }` (bare mount-relative names, non-recursive, mode-defaulted `order`)
17
+ * — see `docs/LIFECYCLE.md` ("Routines") for the full contract, including the `recursive`/`order`/
18
+ * `destroy`-mode fields a caller-supplied entry may also set. Passing `routines` at all REPLACES
19
+ * this list (it is the off-switch); a consumer that wants to extend rather than replace it spreads
20
+ * this array: `slothlet.defaults.routines`.
21
+ *
22
+ * Frozen at every level (the array, and each entry object) so a consumer's spread copies the
23
+ * entries by reference safely without risking a mutation here leaking across consumers.
24
+ * @type {ReadonlyArray<{name: string, mode: "manual"|"startup"|"shutdown"|"destroy"}>}
25
+ */
26
+ export const DEFAULT_ROUTINES: ReadonlyArray<{
27
+ name: string;
28
+ mode: "manual" | "startup" | "shutdown" | "destroy";
29
+ }>;
30
+ /**
31
+ * The complete set of framework-reserved export names — names a module export can never
32
+ * meaningfully claim because the framework's own wrapper machinery already owns them.
33
+ *
34
+ * Derived as the union of {@link ComponentBase.INTERNAL_KEYS} (wrapper state/control properties)
35
+ * and `IMPL_METADATA_KEYS` (child-adoption metadata) — the same two Sets `isFrameworkReservedKey()`
36
+ * (`#handlers/unified-wrapper`) checks against, combined here into one Set for convenient
37
+ * introspection. Wrapped via {@link freezeSet} — `Object.freeze()` alone would leave `add`/
38
+ * `delete`/`clear` callable, letting a consumer mutate this shared singleton (and corrupt what
39
+ * every other consumer in the same process sees) despite it claiming to be frozen.
40
+ * @type {ReadonlySet<string>}
41
+ */
42
+ export const RESERVED_EXPORTS: ReadonlySet<string>;
@@ -1,3 +1,32 @@
1
1
  // AUTO-GENERATED by tools/build/build-typestubs.mjs — do not edit.
2
- // Re-exports the real declarations from @cldmv/slothlet-types (install it for TypeScript support).
3
- export * from "@cldmv/slothlet-types/helpers/eventemitter-context";
2
+ // Self-contained copy: this subpath is internal and not published by @cldmv/slothlet-types.
3
+ /**
4
+ * Set the context checker callback
5
+ * Called by the runtime to register a way to detect API context
6
+ * @param {Function} checker - Function that returns true if in API context
7
+ * @public
8
+ */
9
+ export function setApiContextChecker(checker: Function): void;
10
+ /**
11
+ * Enable EventEmitter context propagation by patching EventEmitter.prototype.
12
+ * This should be called ONCE globally when the first slothlet instance is created.
13
+ * Subsequent calls will be ignored (patching is global).
14
+ *
15
+ * @public
16
+ */
17
+ export function enableEventEmitterPatching(): void;
18
+ /**
19
+ * Disable EventEmitter context propagation and restore original methods.
20
+ * This should only be called when ALL slothlet instances have been shut down.
21
+ *
22
+ * @public
23
+ */
24
+ export function disableEventEmitterPatching(): void;
25
+ /**
26
+ * Cleanup all tracked EventEmitters created within slothlet API context.
27
+ * This removes all listeners from tracked emitters and clears tracking structures.
28
+ * Should be called during shutdown to prevent memory leaks and hanging processes.
29
+ *
30
+ * @public
31
+ */
32
+ export function cleanupEventEmitterResources(): void;
@@ -1,3 +1,22 @@
1
1
  // AUTO-GENERATED by tools/build/build-typestubs.mjs — do not edit.
2
- // Re-exports the real declarations from @cldmv/slothlet-types (install it for TypeScript support).
3
- export * from "@cldmv/slothlet-types/helpers/eventtarget-context";
2
+ // Self-contained copy: this subpath is internal and not published by @cldmv/slothlet-types.
3
+ /**
4
+ * Enable context propagation through `EventTarget` listeners.
5
+ *
6
+ * Called once globally when the first instance is created; later calls are ignored, matching how
7
+ * EventEmitter patching behaves.
8
+ *
9
+ * @returns {void}
10
+ * @public
11
+ */
12
+ export function enableEventTargetPatching(): void;
13
+ /**
14
+ * Restore the original `EventTarget` methods.
15
+ *
16
+ * Restores a method only when the patch installed here is still in place, so anything that replaced
17
+ * it afterwards keeps ownership of its own restore.
18
+ *
19
+ * @returns {void}
20
+ * @public
21
+ */
22
+ export function disableEventTargetPatching(): void;
@@ -0,0 +1,23 @@
1
+ // AUTO-GENERATED by tools/build/build-typestubs.mjs — do not edit.
2
+ // Self-contained copy: this subpath is internal and not published by @cldmv/slothlet-types.
3
+ /**
4
+ * Pin `on*` handler assignments to the module that makes them.
5
+ *
6
+ * Called once globally when the first instance is created; later calls are ignored, matching how the
7
+ * other boundary patches behave. Costs nothing when no runtime registered a pinning strategy — the
8
+ * wrapper hands the callback straight through.
9
+ *
10
+ * @returns {void}
11
+ * @public
12
+ */
13
+ export function enableEventTargetPropertyPatching(): void;
14
+ /**
15
+ * Restore the original `on*` handler accessors.
16
+ *
17
+ * Restores an accessor only when the patch installed here is still in place, so anything that replaced
18
+ * it afterwards keeps ownership of its own restore.
19
+ *
20
+ * @returns {void}
21
+ * @public
22
+ */
23
+ export function disableEventTargetPropertyPatching(): void;
@@ -1,3 +1,181 @@
1
1
  // AUTO-GENERATED by tools/build/build-typestubs.mjs — do not edit.
2
- // Re-exports the real declarations from @cldmv/slothlet-types (install it for TypeScript support).
3
- export * from "@cldmv/slothlet-types/helpers/generate-manifest";
2
+ // Self-contained copy: this subpath is internal and not published by @cldmv/slothlet-types.
3
+ /**
4
+ * Generate a slothlet browser manifest by scanning a directory at build time.
5
+ *
6
+ * This is the primary entry point for producing the `manifest` object required by
7
+ * `slothlet({ manifest, resolveModuleSpecifier })`. Call this once during your build
8
+ * step and embed the result in your browser bundle.
9
+ *
10
+ * @param {string} dir - Absolute or relative path to the API root directory.
11
+ * @returns {Promise<{ files: Array<{path:string,name:string,fullName:string}>, directories: Array }>}
12
+ * Manifest object ready to pass to `slothlet()`.
13
+ *
14
+ * @throws {SlothletError} `GENERATE_MANIFEST_DIR_INVALID` if `dir` is not a non-empty string.
15
+ * @throws {SlothletError} `GENERATE_MANIFEST_DIR_UNREADABLE` if `dir` cannot be read (missing path, permission denied); the underlying reason is surfaced in the message.
16
+ * @throws {SlothletError} `GENERATE_MANIFEST_NOT_DIRECTORY` if `dir` exists but is not a directory.
17
+ *
18
+ * @example
19
+ * // Build script — produces a manifest and writes it to disk
20
+ * import { generateManifest } from "@cldmv/slothlet/helpers/generate-manifest";
21
+ * import { writeFileSync } from "node:fs";
22
+ *
23
+ * const manifest = await generateManifest("./src/api");
24
+ * writeFileSync("./dist/api-manifest.json", JSON.stringify(manifest, null, 2));
25
+ *
26
+ * @example
27
+ * // Vite plugin — inline manifest into the browser bundle
28
+ * import { generateManifest } from "@cldmv/slothlet/helpers/generate-manifest";
29
+ *
30
+ * export function slothletManifestPlugin(apiDir) {
31
+ * return {
32
+ * name: "slothlet-manifest",
33
+ * async buildStart() {
34
+ * const manifest = await generateManifest(apiDir);
35
+ * this.emitFile({
36
+ * type: "asset",
37
+ * fileName: "slothlet-manifest.json",
38
+ * source: JSON.stringify(manifest)
39
+ * });
40
+ * }
41
+ * };
42
+ * }
43
+ */
44
+ export function generateManifest(dir: string): Promise<{
45
+ files: Array<{
46
+ path: string;
47
+ name: string;
48
+ fullName: string;
49
+ }>;
50
+ directories: any[];
51
+ }>;
52
+ /**
53
+ * Generate everything the browser needs to run slothlet, in one build-time call.
54
+ *
55
+ * Returns both halves of a browser-mode setup:
56
+ * - `manifest` — the API-directory listing passed to `slothlet({ manifest })` (replaces the
57
+ * filesystem `readdir` slothlet uses in Node).
58
+ * - `importmap` — the `<script type="importmap">` content that lets the browser resolve slothlet's
59
+ * own module graph AND the third-party packages the registered API leaves import.
60
+ *
61
+ * Run this in your build step (or, for Electron, in the main process) and send both to the
62
+ * renderer: inline `importmap` into the page's importmap script tag, and pass `manifest` (plus a
63
+ * `resolveModuleSpecifier` for your API base) to `slothlet()`.
64
+ *
65
+ * The importmap covers two surfaces. First, slothlet's own modules (rebased onto `slothletBase`).
66
+ * Second — and this is what the registered API leaves need — the **exact `exports` subpaths** of the
67
+ * other packages in the browser graph: the generator scans the `apiDir` leaves for the packages they
68
+ * import, reads each package's `package.json` `exports`, and emits the redirected subpath keys a
69
+ * plain prefix map can't produce (`@scope/ext/errors` → `…/@scope/ext/src/lib/errors.mjs`). Without
70
+ * these, a subpath the `exports` map redirects resolves to a literal URL and 404s in the browser, so
71
+ * consumers previously hand-maintained allowlists. Those sibling packages are served next to
72
+ * `@cldmv/slothlet` under a base **derived** from `slothletBase` (its node_modules/CDN parent). (#297)
73
+ *
74
+ * @param {string} apiDir - Absolute or relative path to the API root directory.
75
+ * @param {object} [options] - Options.
76
+ * @param {string} [options.slothletBase="/node_modules/@cldmv/slothlet/"] - URL/path prefix where
77
+ * the `@cldmv/slothlet` package is served in the browser. Defaults to the conventional
78
+ * node_modules location (slothlet installed as a dependency, node_modules served at the web
79
+ * root). Override with a CDN URL, an Electron protocol path, or `"/"` when the package is served
80
+ * at the web root.
81
+ * @returns {Promise<{ manifest: { files: Array, directories: Array }, importmap: { imports: Object<string,string> } }>}
82
+ * The API manifest and slothlet's own browser importmap.
83
+ *
84
+ * @throws {SlothletError} `GENERATE_BROWSER_ASSETS_SLOTHLET_BASE_INVALID` if `options.slothletBase` is provided but is not a string.
85
+ *
86
+ * @example
87
+ * // Build step — slothlet installed in node_modules (default base), ship both to the renderer.
88
+ * import { generateBrowserAssets } from "@cldmv/slothlet/helpers/generate-manifest";
89
+ * const { manifest, importmap } = await generateBrowserAssets("./src/api");
90
+ * // → inline importmap: `<script type="importmap">${JSON.stringify(importmap)}</script>`
91
+ * // → pass manifest to slothlet({ manifest, resolveModuleSpecifier })
92
+ *
93
+ * @example
94
+ * // Override the base for a CDN (or "/" when the package is served at the web root).
95
+ * const { manifest, importmap } = await generateBrowserAssets("./src/api", {
96
+ * slothletBase: "https://cdn.example.com/@cldmv/slothlet@3/"
97
+ * });
98
+ */
99
+ export function generateBrowserAssets(apiDir: string, options?: {
100
+ slothletBase?: string | undefined;
101
+ }): Promise<{
102
+ manifest: {
103
+ files: any[];
104
+ directories: any[];
105
+ };
106
+ importmap: {
107
+ imports: {
108
+ [x: string]: string;
109
+ };
110
+ };
111
+ }>;
112
+ /**
113
+ * Generate the browser importmap for slothlet's OWN modules.
114
+ *
115
+ * In a browser, slothlet's internal imports (`@cldmv/slothlet`, `@cldmv/slothlet/helpers/*`, …)
116
+ * are static and resolved by the page's importmap **before slothlet runs** — they cannot route
117
+ * through `resolveModuleSpecifier` (which only governs API-leaf loads). This produces that
118
+ * importmap from slothlet's public export surface so consumers never hand-roll it.
119
+ *
120
+ * Each specifier is resolved via `import.meta.resolve`, which automatically picks the dev
121
+ * (`slothlet-dev` → `src/`) or published (`default` → `dist/`) files based on the conditions of
122
+ * the build process — then rebased onto `slothletBase` (where the package is served).
123
+ *
124
+ * @param {string} [slothletBase="/node_modules/@cldmv/slothlet/"] - URL/path prefix where the
125
+ * `@cldmv/slothlet` package is served in the browser. Defaults to the conventional node_modules
126
+ * location; override with a CDN URL, an Electron protocol path, or `"/"` when the package is
127
+ * served at the web root.
128
+ * @returns {Promise<{ imports: Object<string,string> }>} An importmap object ready to inline as
129
+ * `<script type="importmap">`.
130
+ */
131
+ export function generateImportMap(slothletBase?: string): Promise<{
132
+ imports: {
133
+ [x: string]: string;
134
+ };
135
+ }>;
136
+ /**
137
+ * Collect the full set of `@cldmv/slothlet[/sub]` specifiers the browser importmap must cover.
138
+ *
139
+ * Three sources, unioned so the map mirrors slothlet's public export surface: (1) declared flat entry points from package.json `exports` — so
140
+ * every flat (non-wildcard) public module specifier a consumer can import resolves via the importmap, including public aggregators that
141
+ * slothlet's own internals never import directly (notably the bare `@cldmv/slothlet/runtime`, whose
142
+ * `/runtime/async` + `/runtime/live` variants are the only ones internally referenced); (2) a per-file
143
+ * enumeration of every wildcard `exports` directory (`./helpers/*`, `./handlers/*`, …) so EVERY exported
144
+ * subpath gets an entry by construction — not just the modules slothlet itself imports, so a browser can
145
+ * never hit a wildcard endpoint the map lacks; and (3) a recursive source scan as a backstop for any
146
+ * imported specifier the first two miss. i18n locales are handled separately — they are dynamic-template imports the
147
+ * static scan can't see, and are enumerated separately from the languages directory. Inclusion here is about
148
+ * specifier resolution, not runtime compatibility — some public exports (e.g. `typegen`, `devcheck`) are
149
+ * Node-only and won't execute in a browser even though their specifier resolves. JSON exports (the
150
+ * module-manifest schema) are tooling-only and excluded too — they aren't browser module imports. (#137)
151
+ *
152
+ * @param {string} root - The slothlet package root (holds package.json and the shipped source).
153
+ * @returns {Promise<Set<string>>} The set of bare specifiers, always including `@cldmv/slothlet` and
154
+ * its flat (non-wildcard) public exports.
155
+ */
156
+ export function collectSlothletSpecifiers(root: string): Promise<Set<string>>;
157
+ /**
158
+ * Collect the exact importmap subpath keys for ANY package from its `package.json` `exports`.
159
+ *
160
+ * The package-agnostic counterpart to {@link collectSlothletSpecifiers}: given a package's root
161
+ * directory, read its `exports` map and return the bare specifier → relative-target pairs a browser
162
+ * importmap needs. Import maps do plain prefix substitution and never consult a package's `exports`,
163
+ * so a subpath the `exports` map *redirects* (`@scope/pkg/errors` → `./src/lib/errors.mjs`) 404s
164
+ * unless the importmap carries that exact key. This produces those keys.
165
+ *
166
+ * Handles the same shapes the self-collector does, generalized: the package root (`.`), flat
167
+ * (non-wildcard) subpaths, wildcard directories (`./x/*` → every module file under the declared
168
+ * target dir), conditional `exports` (via {@link pickBrowserTarget} — browser/import/default, never
169
+ * node/require), and the string-exports and conditions-only (`.` sugar) forms. Only ES-module
170
+ * targets are emitted (see {@link isBrowserModuleTarget}); a package with no `exports` (or an
171
+ * unreadable `package.json`) yields an empty map — the prefix map already covers those.
172
+ *
173
+ * The returned targets are the paths the `exports` map itself declares, so the caller rebases them
174
+ * onto wherever the package is served — no `import.meta.resolve` (which resolves from slothlet's own
175
+ * scope, not the consumer's) is involved.
176
+ *
177
+ * @param {string} packageRoot - Absolute path to the package's root (the dir holding its package.json).
178
+ * @returns {Promise<Map<string,string>>} Map of bare specifier → target path relative to `packageRoot`.
179
+ * @public
180
+ */
181
+ export function collectPackageSpecifiers(packageRoot: string): Promise<Map<string, string>>;