@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.
- package/lib/builders/api-assignment.d.mts +125 -4
- package/lib/builders/api_builder.d.mts +104 -7
- package/lib/builders/builder.d.mts +82 -1
- package/lib/builders/modes-processor.d.mts +66 -3
- package/lib/errors.d.mts +114 -19
- package/lib/factories/component-base.d.mts +171 -8
- package/lib/factories/context.d.mts +22 -4
- package/lib/handlers/api-cache-manager.d.mts +209 -20
- package/lib/handlers/api-manager.d.mts +539 -38
- package/lib/handlers/context-async.d.mts +92 -25
- package/lib/handlers/context-live.d.mts +117 -30
- package/lib/handlers/framework-internals.d.mts +33 -2
- package/lib/handlers/hook-manager.d.mts +306 -73
- package/lib/handlers/lifecycle-token.d.mts +48 -3
- package/lib/handlers/lifecycle.d.mts +86 -5
- package/lib/handlers/materialize-manager.d.mts +76 -8
- package/lib/handlers/metadata.d.mts +238 -18
- package/lib/handlers/module-manager.d.mts +169 -21
- package/lib/handlers/ownership.d.mts +376 -45
- package/lib/handlers/permission-manager.d.mts +283 -46
- package/lib/handlers/routine-manager.d.mts +425 -0
- package/lib/handlers/trusted-root.d.mts +45 -4
- package/lib/handlers/unified-wrapper.d.mts +287 -26
- package/lib/handlers/version-manager.d.mts +236 -29
- package/lib/helpers/caller-pinning.d.mts +21 -2
- package/lib/helpers/class-instance-wrapper.d.mts +56 -2
- package/lib/helpers/config.d.mts +311 -161
- package/lib/helpers/defaults.d.mts +40 -0
- package/lib/helpers/eventemitter-context.d.mts +29 -3
- package/lib/helpers/eventtarget-context.d.mts +19 -1
- package/lib/helpers/eventtarget-property-context.d.mts +21 -0
- package/lib/helpers/generate-manifest.d.mts +174 -7
- package/lib/helpers/hint-detector.d.mts +22 -2
- package/lib/helpers/manifest-resolver.d.mts +100 -1
- package/lib/helpers/modes-utils.d.mts +30 -3
- package/lib/helpers/module-discovery.d.mts +80 -7
- package/lib/helpers/module-manifest-validator.d.mts +36 -13
- package/lib/helpers/module-sort.d.mts +64 -1
- package/lib/helpers/observer-context.d.mts +21 -0
- package/lib/helpers/pattern-matcher.d.mts +43 -3
- package/lib/helpers/platform.d.mts +109 -10
- package/lib/helpers/resolve-from-caller.d.mts +27 -3
- package/lib/helpers/sanitize.d.mts +92 -4
- package/lib/helpers/scheduler-context.d.mts +21 -1
- package/lib/helpers/utilities.d.mts +52 -4
- package/lib/i18n/translations.d.mts +50 -5
- package/lib/modes/eager.d.mts +46 -8
- package/lib/modes/lazy.d.mts +57 -10
- package/lib/processors/flatten.d.mts +116 -56
- package/lib/processors/loader.d.mts +77 -10
- package/lib/processors/type-generator.d.mts +16 -2
- package/lib/processors/typescript.d.mts +169 -13
- package/lib/runtime/runtime-asynclocalstorage.d.mts +71 -3
- package/lib/runtime/runtime-livebindings.d.mts +37 -2
- package/lib/runtime/runtime.d.mts +39 -3
- package/lib/typegen/typegen.d.mts +34 -2
- package/package.json +5 -23
- package/slothlet.d.mts +428 -3
|
@@ -1,4 +1,36 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Generate a TypeScript declaration file (`.d.ts`) for a Slothlet API directory.
|
|
3
|
+
*
|
|
4
|
+
* Loads the API in eager + fast TypeScript mode (no type-checking pass needed —
|
|
5
|
+
* the structure walk uses the loaded API and source files), writes the `.d.ts`,
|
|
6
|
+
* and shuts the loaded instance down before returning.
|
|
7
|
+
*
|
|
8
|
+
* @param {object} options
|
|
9
|
+
* @param {string} options.dir - Path to the API directory to scan (relative or absolute).
|
|
10
|
+
* @param {string} options.output - Path to write the `.d.ts` file to (relative or absolute).
|
|
11
|
+
* @param {string} options.interfaceName - Name of the generated TypeScript interface (e.g. `"MyApi"`).
|
|
12
|
+
* @param {boolean|string|object} [options.typescript] - Override TypeScript loader config. Same union accepted by `slothlet({ typescript })`: pass `true` (default mode), `"fast"` / `"strict"`, or an object like `{ mode: "fast" }`. Defaults to `{ mode: "fast" }` when omitted.
|
|
13
|
+
* @param {boolean} [options.includeDocumentation=true] - Include JSDoc comments in the generated declaration.
|
|
14
|
+
* @returns {Promise<{filePath: string, content: string}>} Absolute path written and the declaration content.
|
|
15
|
+
* @throws {SlothletError} `INVALID_CONFIG` when `dir`, `output`, or `interfaceName` is missing or not a string.
|
|
16
|
+
* @public
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* import { generateTypes } from "@cldmv/slothlet/typegen";
|
|
20
|
+
*
|
|
21
|
+
* await generateTypes({
|
|
22
|
+
* dir: "./api",
|
|
23
|
+
* output: "./types/api.d.ts",
|
|
24
|
+
* interfaceName: "MyApi"
|
|
25
|
+
* });
|
|
26
|
+
*/
|
|
27
|
+
export function generateTypes(options?: {
|
|
28
|
+
dir: string;
|
|
29
|
+
output: string;
|
|
30
|
+
interfaceName: string;
|
|
31
|
+
typescript?: string | boolean | object | undefined;
|
|
32
|
+
includeDocumentation?: boolean | undefined;
|
|
33
|
+
}): Promise<{
|
|
34
|
+
filePath: string;
|
|
3
35
|
content: string;
|
|
4
36
|
}>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cldmv/slothlet-types",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.16.0",
|
|
4
4
|
"description": "TypeScript declaration files (.d.mts) for @cldmv/slothlet. Install alongside @cldmv/slothlet for editor and type-checker support.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"slothlet",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
},
|
|
42
42
|
"type": "module",
|
|
43
43
|
"engines": {
|
|
44
|
-
"node": ">=22.
|
|
44
|
+
"node": ">=22.12.0"
|
|
45
45
|
},
|
|
46
46
|
"sideEffects": false,
|
|
47
47
|
"exports": {
|
|
@@ -58,29 +58,11 @@
|
|
|
58
58
|
"./runtime": {
|
|
59
59
|
"types": "./lib/runtime/runtime.d.mts"
|
|
60
60
|
},
|
|
61
|
-
"./
|
|
62
|
-
"types": "./lib/
|
|
63
|
-
},
|
|
64
|
-
"./runtime/live": {
|
|
65
|
-
"types": "./lib/runtime/runtime-livebindings.d.mts"
|
|
66
|
-
},
|
|
67
|
-
"./helpers/*": {
|
|
68
|
-
"types": "./lib/helpers/*.d.mts"
|
|
69
|
-
},
|
|
70
|
-
"./modes/*": {
|
|
71
|
-
"types": "./lib/modes/*.d.mts"
|
|
72
|
-
},
|
|
73
|
-
"./builders/*": {
|
|
74
|
-
"types": "./lib/builders/*.d.mts"
|
|
75
|
-
},
|
|
76
|
-
"./processors/*": {
|
|
77
|
-
"types": "./lib/processors/*.d.mts"
|
|
61
|
+
"./helpers/sanitize": {
|
|
62
|
+
"types": "./lib/helpers/sanitize.d.mts"
|
|
78
63
|
},
|
|
79
64
|
"./errors": {
|
|
80
65
|
"types": "./lib/errors.d.mts"
|
|
81
|
-
},
|
|
82
|
-
"./i18n": {
|
|
83
|
-
"types": "./lib/i18n/translations.d.mts"
|
|
84
66
|
}
|
|
85
67
|
},
|
|
86
68
|
"imports": {
|
|
@@ -97,7 +79,7 @@
|
|
|
97
79
|
"LICENSE"
|
|
98
80
|
],
|
|
99
81
|
"peerDependencies": {
|
|
100
|
-
"@cldmv/slothlet": "3.
|
|
82
|
+
"@cldmv/slothlet": "3.16.0"
|
|
101
83
|
},
|
|
102
84
|
"peerDependenciesMeta": {
|
|
103
85
|
"@cldmv/slothlet": {
|
package/slothlet.d.mts
CHANGED
|
@@ -1,3 +1,428 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Create a new Slothlet instance and load an API from a directory.
|
|
3
|
+
* This is the sole public entry point for slothlet. Each call produces an independent
|
|
4
|
+
* API instance with its own component graph, context store, and lifecycle.
|
|
5
|
+
* @alias module:@cldmv/slothlet
|
|
6
|
+
* @async
|
|
7
|
+
* @param {SlothletOptions} config - Configuration options
|
|
8
|
+
* @returns {Promise<SlothletAPI>} Fully loaded, proxy-based API object
|
|
9
|
+
* @public
|
|
10
|
+
* @example
|
|
11
|
+
* // Minimal usage
|
|
12
|
+
* const api = await slothlet({ base: "./api" });
|
|
13
|
+
* const result = await api.math.add(2, 3);
|
|
14
|
+
* await api.slothlet.shutdown();
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* // Lazy mode with background materialization
|
|
18
|
+
* const api = await slothlet({
|
|
19
|
+
* base: "./api",
|
|
20
|
+
* mode: "lazy",
|
|
21
|
+
* backgroundMaterialize: true
|
|
22
|
+
* });
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* // With hooks
|
|
26
|
+
* const api = await slothlet({ base: "./api", hook: true });
|
|
27
|
+
* api.slothlet.hook.on("before", "**", (endpoint, args) => { /* ... *\/ });
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* // Hot-reload a module at runtime
|
|
31
|
+
* await api.slothlet.api.reload("./api/math.mjs");
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* // Strict collision control
|
|
35
|
+
* const api = await slothlet({
|
|
36
|
+
* base: "./api",
|
|
37
|
+
* api: { collision: { initial: "merge", api: "error" } }
|
|
38
|
+
* });
|
|
39
|
+
*/
|
|
40
|
+
export function slothlet(config: SlothletOptions): Promise<SlothletAPI>;
|
|
41
|
+
export namespace slothlet {
|
|
42
|
+
let defaults: Readonly<{
|
|
43
|
+
routines: ReadonlyArray<{
|
|
44
|
+
name: string;
|
|
45
|
+
mode: string;
|
|
46
|
+
}>;
|
|
47
|
+
reservedExports: ReadonlySet<string>;
|
|
48
|
+
}>;
|
|
49
|
+
}
|
|
50
|
+
export default slothlet;
|
|
51
|
+
/**
|
|
52
|
+
* Configuration options passed to `slothlet()`.
|
|
53
|
+
*/
|
|
54
|
+
export type SlothletOptions = {
|
|
55
|
+
/**
|
|
56
|
+
* - Directory (node mode) or file:// URL / base URL (browser mode) to load API modules from.
|
|
57
|
+
* Required in both modes. Plain filesystem paths are automatically converted to `file://` URLs by the default browser-mode resolver.
|
|
58
|
+
*/
|
|
59
|
+
base?: string | undefined;
|
|
60
|
+
/**
|
|
61
|
+
* - Deprecated alias for `base`. Still accepted; emits a `V3_CONFIG_DEPRECATED` warning unless `silent: true`. Will be removed in v4.
|
|
62
|
+
*/
|
|
63
|
+
dir?: string | undefined;
|
|
64
|
+
/**
|
|
65
|
+
* - Loading strategy.
|
|
66
|
+
* - `"eager"` — all modules are loaded immediately at startup (default).
|
|
67
|
+
* - `"lazy"` — modules are loaded on first access via a Proxy.
|
|
68
|
+
* Also accepted: `"immediate"` / `"preload"` (eager aliases); `"deferred"` / `"proxy"` (lazy aliases).
|
|
69
|
+
*/
|
|
70
|
+
mode?: "eager" | "lazy" | undefined;
|
|
71
|
+
/**
|
|
72
|
+
* - Context propagation runtime.
|
|
73
|
+
* - `"async"` — AsyncLocalStorage (Node.js built-in, recommended for production).
|
|
74
|
+
* - `"live"` — Experimental live bindings.
|
|
75
|
+
* Also accepted: `"asynclocalstorage"` / `"als"` / `"node"` as aliases for `"async"`.
|
|
76
|
+
*/
|
|
77
|
+
runtime?: "async" | "live" | undefined;
|
|
78
|
+
/**
|
|
79
|
+
* - Directory traversal depth. `Infinity` scans all subdirectories (default). `0` scans only the root.
|
|
80
|
+
*/
|
|
81
|
+
apiDepth?: number | undefined;
|
|
82
|
+
/**
|
|
83
|
+
* - Glob or array of globs hiding files and folders from the API, matched against each entry's
|
|
84
|
+
* path relative to `base` (folder-style `a/b` or dotted `a.b`; `*` one segment, `**` any depth, `?` one char, `{a,b}` alternation,
|
|
85
|
+
* `!` negation). Files match on their extension-stripped path. Applies on top of the built-in rule that `.`/`__`-prefixed names are
|
|
86
|
+
* hidden by default (`.`/`__`-prefixed folders can be restored via the deprecated `scanHiddenFolders`; files stay hidden). Also accepted per-call by `api.slothlet.api.add(path, dir, { hidden })`, where globs are relative to the added folder.
|
|
87
|
+
*/
|
|
88
|
+
hidden?: string | string[] | undefined;
|
|
89
|
+
/**
|
|
90
|
+
* - Deprecated escape hatch: restore the pre-v3.11 behavior of scanning `.`/`__`-prefixed
|
|
91
|
+
* folders. Emits a `CONFIG_SCAN_HIDDEN_FOLDERS_DEPRECATED` warning when supplied (unless `silent: true`). Will be removed in v4.
|
|
92
|
+
*/
|
|
93
|
+
scanHiddenFolders?: boolean | undefined;
|
|
94
|
+
/**
|
|
95
|
+
* - Object merged into the per-request context accessible inside API functions via `import { context } from "@cldmv/slothlet/runtime"`.
|
|
96
|
+
*/
|
|
97
|
+
context?: object | null | undefined;
|
|
98
|
+
/**
|
|
99
|
+
* - Object whose properties are merged directly onto the root API and also available as `api.slothlet.reference`.
|
|
100
|
+
*/
|
|
101
|
+
reference?: object | null | undefined;
|
|
102
|
+
/**
|
|
103
|
+
* - Controls how per-request scope data is merged. `"shallow"` merges top-level keys; `"deep"` recurses into nested objects.
|
|
104
|
+
*/
|
|
105
|
+
scope?: {
|
|
106
|
+
merge: "shallow" | "deep";
|
|
107
|
+
} | undefined;
|
|
108
|
+
/**
|
|
109
|
+
* - API build and mutation settings.
|
|
110
|
+
*/
|
|
111
|
+
api?: {
|
|
112
|
+
/**
|
|
113
|
+
* - Collision strategy when two modules export the same path.
|
|
114
|
+
* Modes: `"merge"` (default), `"merge-replace"`, `"replace"`, `"skip"`, `"warn"`, `"error"`.
|
|
115
|
+
* Pass an object to use different strategies for the initial build vs. runtime `api.slothlet.api.add()` calls.
|
|
116
|
+
*/
|
|
117
|
+
collision?: string | {
|
|
118
|
+
initial: string;
|
|
119
|
+
api: string;
|
|
120
|
+
} | undefined;
|
|
121
|
+
/**
|
|
122
|
+
* - Enable or disable runtime mutation methods on `api.slothlet.api`.
|
|
123
|
+
* Object with boolean keys `add`, `remove`, `reload` (all default `true`).
|
|
124
|
+
*/
|
|
125
|
+
mutations?: object | undefined;
|
|
126
|
+
} | undefined;
|
|
127
|
+
/**
|
|
128
|
+
* - Hook system configuration.
|
|
129
|
+
* - `false` — disabled (default).
|
|
130
|
+
* - `true` — enabled, all endpoints.
|
|
131
|
+
* - `string` — enabled with a default glob pattern.
|
|
132
|
+
* - `object` — full control: `{ enabled: boolean, pattern?: string, suppressErrors?: boolean }`.
|
|
133
|
+
*/
|
|
134
|
+
hook?: string | boolean | object | undefined;
|
|
135
|
+
/**
|
|
136
|
+
* - Enable verbose internal logging. `true` enables all categories.
|
|
137
|
+
* Pass an object with sub-keys `builder`, `api`, `index`, `modes`, `wrapper`, `ownership`, `context` to target specific subsystems.
|
|
138
|
+
*/
|
|
139
|
+
debug?: boolean | object | undefined;
|
|
140
|
+
/**
|
|
141
|
+
* - Suppress all console output from slothlet (warnings, deprecations). Does not affect `debug`.
|
|
142
|
+
*/
|
|
143
|
+
silent?: boolean | undefined;
|
|
144
|
+
/**
|
|
145
|
+
* - Enable the `api.slothlet.diag.*` introspection namespace. Intended for testing; do not enable in production.
|
|
146
|
+
*/
|
|
147
|
+
diagnostics?: boolean | undefined;
|
|
148
|
+
/**
|
|
149
|
+
* - Construction-time lifecycle subscribers, registered on the lifecycle emitter BEFORE the api builds so events emitted during cold-start `buildAPI` (init-time `impl:warning` / `impl:created` / …) are observable. Maps an event name to a handler `function(data, token)` or an array of them; any event name is accepted. Because they are ordinary subscribers, they also receive runtime events afterward — equivalent to calling `api.slothlet.lifecycle.on(event, fn)` for each, but early enough to catch initialization diagnostics. Example: `{ "impl:warning": (d) => log(d), "impl:error": [onError, audit] }`.
|
|
150
|
+
*/
|
|
151
|
+
lifecycle?: {
|
|
152
|
+
[x: string]: Function | Function[];
|
|
153
|
+
} | undefined;
|
|
154
|
+
/**
|
|
155
|
+
* - DEPRECATED — will be removed in v4. Expands into two implicit `routines` entries (`{name: "^**.shutdown", mode: "shutdown", order: "depth"}` and the `destroy` equivalent) reproducing this option's original whole-tree, cross-mount, deepest-first scope for literally-named `shutdown`/`destroy` leaves, dropping any existing `shutdown`/`destroy`-mode routine (including the built-in `shutdown` default) in favor of these — and sets the effective `autoRoutines` to `true` unless `autoRoutines` is given explicitly. Nested hooks remain directly callable regardless. Emits a `V3_CONFIG_DEPRECATED` warning unless `silent: true`.
|
|
156
|
+
*/
|
|
157
|
+
collectLifecycleHooks?: boolean | undefined;
|
|
158
|
+
/**
|
|
159
|
+
* - Stackable lifecycle routines (#341). Every mounted module exporting a function matching a configured routine name is composed into one callable at its exact composed api path, plus a root cascade (`self.<name>()` ≡ `api.slothlet.<name>()`) that runs every matching contribution anywhere. Entries: `"name"` (mode `"manual"`), `"name:mode"`, or `{ name, mode?, recursive?, order? }` (`recursive`/`order` only settable via the object form). `name` is mount-relative by default (a bare name matches only a mount's own top level; a dotted name matches a fixed relative sub-path, or with `recursive: true` any depth within the mount); a `^`-prefixed name is root-anchored, matched via glob (`*`, `**`, `{}`, `!`) against the full api path, crossing mount boundaries. `order` (`"mount"` | `"depth"`, mode-defaulted) controls the root cascade's grouping order. Providing `routines` at all REPLACES the built-in defaults (`slothlet.defaults.routines`: `initialize` → `startup`, `shutdown` → `shutdown`) — spread `slothlet.defaults.routines` to extend them instead, or pass `[]` to disable every routine. Every configured routine is always wrapped and directly callable regardless of `autoRoutines`. Whether two or more contributors colliding at the identical api path all run is governed by `stackRoutines` (#365), independent of `collisionMode` — by default only the single contribution that actually owns that path runs, matching ordinary collision behavior. A throwing contributor doesn't stop the chain — every contributor runs (best-effort), and one aggregate `ROUTINE_FAILED` error is thrown afterward if any failed. See [LIFECYCLE.md](docs/LIFECYCLE.md#routines).
|
|
160
|
+
*/
|
|
161
|
+
routines?: (string | {
|
|
162
|
+
name: string;
|
|
163
|
+
mode?: ("manual" | "startup" | "shutdown" | "destroy");
|
|
164
|
+
recursive?: boolean;
|
|
165
|
+
order?: ("mount" | "depth");
|
|
166
|
+
})[] | undefined;
|
|
167
|
+
/**
|
|
168
|
+
* - The non-deprecated replacement for `collectLifecycleHooks`. TEMPORARY v3-compat default (#341): `false` for now, so a project upgrading sees no behavior change from a pre-existing nested leaf that happens to share a routine's name (e.g. `shutdown`) — it stays stacked and directly callable, but does not start auto-firing. When `true`, every `mode: "startup"` routine's cascade runs at the end of compose, and every `mode: "shutdown"`/`"destroy"` routine's cascade runs on the corresponding dispose call. Planned to default to `true` in v4 (`collectLifecycleHooks` removed at the same time) — see [LIFECYCLE.md](docs/LIFECYCLE.md#routines).
|
|
169
|
+
*/
|
|
170
|
+
autoRoutines?: boolean | undefined;
|
|
171
|
+
/**
|
|
172
|
+
* - Whether two or more modules' contributions colliding at the exact same composed api path all run, or only the single contribution that actually owns that path (per `collisionMode`) runs (#365). `false` by default, matching ordinary (non-routine) collision behavior everywhere else in the framework. Deliberately independent of `collisionMode` — a module that loses a collision, under any mode, does not run via the routine system unless this is explicitly `true`. The root cascade runs every matching contribution across distinct api paths regardless of this flag; where two or more contributions land on the identical api path, the cascade applies the same filtering a direct call at that path would. See [LIFECYCLE.md](docs/LIFECYCLE.md#stackroutines).
|
|
173
|
+
*/
|
|
174
|
+
stackRoutines?: boolean | undefined;
|
|
175
|
+
/**
|
|
176
|
+
* - Enable internal tracking. Pass `true` or `{ materialization: true }` to track lazy-mode materialization progress.
|
|
177
|
+
*/
|
|
178
|
+
tracking?: boolean | object | undefined;
|
|
179
|
+
/**
|
|
180
|
+
* - When `mode: "lazy"`, immediately begins materializing all paths in the background after init.
|
|
181
|
+
*/
|
|
182
|
+
backgroundMaterialize?: boolean | undefined;
|
|
183
|
+
/**
|
|
184
|
+
* - Internationalization settings (dev-facing, process-global).
|
|
185
|
+
* `{ language: string }` — selects the locale for framework messages (e.g. `"en-us"`, `"fr-fr"`, `"ja-jp"`).
|
|
186
|
+
*/
|
|
187
|
+
i18n?: object | undefined;
|
|
188
|
+
/**
|
|
189
|
+
* - Execution-environment target. Controls whether filesystem-dependent code paths run. Independent of `env` (the `process.env` snapshot).
|
|
190
|
+
* - `"browser"` — browser/worker/Electron-renderer mode. Skips filesystem operations and the `process.env` snapshot. Requires `manifest`.
|
|
191
|
+
* - `"node"` — explicit Node.js mode.
|
|
192
|
+
* - Omitted — auto-detected: `"browser"` when a `manifest` is provided (or no Node `process` is present), `"node"` otherwise.
|
|
193
|
+
*/
|
|
194
|
+
platform?: "browser" | "node" | undefined;
|
|
195
|
+
/**
|
|
196
|
+
* - `process.env` snapshot configuration (Node mode). Independent of `platform`.
|
|
197
|
+
* - `{ include: ["KEY"] }` — allowlist; only the listed keys are captured in `api.slothlet.env`. Non-string entries are silently ignored; an all-non-string array falls back to the full snapshot.
|
|
198
|
+
* - Omitted / `null` — the full `process.env` snapshot is captured.
|
|
199
|
+
*/
|
|
200
|
+
env?: object | null | undefined;
|
|
201
|
+
/**
|
|
202
|
+
* - Allowlist of environment variable names to capture. Only string entries are used.
|
|
203
|
+
*/
|
|
204
|
+
include?: string[] | undefined;
|
|
205
|
+
/**
|
|
206
|
+
* - Pre-generated directory structure for browser mode.
|
|
207
|
+
* Produced at build time by `generateManifest()` from `@cldmv/slothlet/helpers/generate-manifest`. Required when `platform: "browser"`.
|
|
208
|
+
* Presence of `manifest` auto-triggers browser mode without needing an explicit `platform: "browser"`.
|
|
209
|
+
*/
|
|
210
|
+
manifest?: {
|
|
211
|
+
files: Array<{
|
|
212
|
+
path: string;
|
|
213
|
+
name: string;
|
|
214
|
+
fullName: string;
|
|
215
|
+
}>;
|
|
216
|
+
directories: any[];
|
|
217
|
+
} | undefined;
|
|
218
|
+
/**
|
|
219
|
+
* - Browser-mode module resolver: `(fileEntry: {path, name, fullName}) => string | URL`.
|
|
220
|
+
* Maps a manifest file entry to an importable URL or bare specifier. Defaults to resolving against `base` as a `file://` URL.
|
|
221
|
+
* Override to point at a CDN, bundler virtual module, or other browser-friendly source.
|
|
222
|
+
*/
|
|
223
|
+
resolveModuleSpecifier?: Function | undefined;
|
|
224
|
+
/**
|
|
225
|
+
* - Injectable leaf importer: `(specifier: string) => Promise<object>`.
|
|
226
|
+
* Every leaf module load is routed through it instead of slothlet's own dynamic `import()`, so the
|
|
227
|
+
* modules land in the caller's module graph rather than slothlet's. Pass `(s) => import(s)` written
|
|
228
|
+
* inside the consumer's own (transformed) code to make a coverage run attribute leaf execution
|
|
229
|
+
* correctly; unset, slothlet imports natively exactly as before. See [`docs/TESTING.md`](../docs/TESTING.md).
|
|
230
|
+
*/
|
|
231
|
+
import?: Function | undefined;
|
|
232
|
+
/**
|
|
233
|
+
* - Opt out of specific bug-fix behaviors that landed in v3 and become permanent in v4.
|
|
234
|
+
* Each entry uses the `<rule>_<PR>` form (e.g. `"C03_116"`). Each listed rule emits a `WARN_SUPPRESS_FIX_ACTIVE` deprecation warning unless `silent: true`.
|
|
235
|
+
* Temporary escape hatch — will be removed in v4 when the corrected behaviors become permanent.
|
|
236
|
+
*/
|
|
237
|
+
suppressFixes?: string[] | undefined;
|
|
238
|
+
/**
|
|
239
|
+
* - TypeScript support.
|
|
240
|
+
* - `false` — disabled (default).
|
|
241
|
+
* - `true` or `"fast"` — esbuild transpilation, no type checking.
|
|
242
|
+
* - `"strict"` — tsc compilation with type checking and `.d.ts` generation.
|
|
243
|
+
* See [TYPESCRIPT.md](docs/TYPESCRIPT.md) for the full configuration reference.
|
|
244
|
+
*/
|
|
245
|
+
typescript?: boolean | object | "strict" | "fast" | undefined;
|
|
246
|
+
/**
|
|
247
|
+
* - Version routing discriminator for versioned API paths.
|
|
248
|
+
* - **string** (e.g. `"version"`) — at dispatch time, reads that key from the calling module's version metadata to select a version tag.
|
|
249
|
+
* - **function** — called as `(allVersions, caller) => versionTag | null`; return a registered version tag to force routing, or `null`/`undefined` to fall through to the automatic default.
|
|
250
|
+
* - **omitted / `undefined`** — behaves identically to `"version"`.
|
|
251
|
+
* Only relevant when modules are registered via `api.slothlet.api.add()` with a `versionConfig` argument.
|
|
252
|
+
*/
|
|
253
|
+
versionDispatcher?: string | Function | null | undefined;
|
|
254
|
+
};
|
|
255
|
+
/**
|
|
256
|
+
* Bound API object returned by `slothlet()`.
|
|
257
|
+
* The root contains all loaded module exports plus the reserved `slothlet` namespace.
|
|
258
|
+
*/
|
|
259
|
+
export type SlothletAPI = {
|
|
260
|
+
/**
|
|
261
|
+
* - Like `shutdown()` but additionally invokes registered destroy hooks before teardown. %%sig: (): void%% %%example: // ESM usage via slothlet API|import slothlet from "@cldmv/slothlet";|const api = await slothlet({ base: './api' });|await api.destroy();%% %%example: // ESM usage via slothlet API (inside async function)|async function example() {| const { default: slothlet } = await import("@cldmv/slothlet");| const api = await slothlet({ base: './api' });| await api.destroy();|}%% %%example: // CJS usage via slothlet API (top-level)|let slothlet;|(async () => {| ({ slothlet } = await import("@cldmv/slothlet"));| const api = await slothlet({ base: './api' });| await api.destroy();|})();%% %%example: // CJS usage via slothlet API (inside async function)|const slothlet = require("@cldmv/slothlet");|const api = await slothlet({ base: './api' });|await api.destroy();%%
|
|
262
|
+
*/
|
|
263
|
+
destroy: () => void;
|
|
264
|
+
/**
|
|
265
|
+
* - Convenience alias for `slothlet.shutdown()`. Shuts down the instance and invokes any user-provided shutdown hook first. %%sig: (): void%% %%example: // ESM usage via slothlet API|import slothlet from "@cldmv/slothlet";|const api = await slothlet({ base: './api' });|await api.shutdown();%% %%example: // ESM usage via slothlet API (inside async function)|async function example() {| const { default: slothlet } = await import("@cldmv/slothlet");| const api = await slothlet({ base: './api' });| await api.shutdown();|}%% %%example: // CJS usage via slothlet API (top-level)|let slothlet;|(async () => {| ({ slothlet } = await import("@cldmv/slothlet"));| const api = await slothlet({ base: './api' });| await api.shutdown();|})();%% %%example: // CJS usage via slothlet API (inside async function)|const slothlet = require("@cldmv/slothlet");|const api = await slothlet({ base: './api' });|await api.shutdown();%%
|
|
266
|
+
*/
|
|
267
|
+
shutdown: () => void;
|
|
268
|
+
/**
|
|
269
|
+
* - Built-in control namespace. All framework internals live here to avoid collisions with loaded modules.
|
|
270
|
+
*/
|
|
271
|
+
slothlet: {
|
|
272
|
+
env: Readonly<Record<string, string | undefined>>;
|
|
273
|
+
api: {
|
|
274
|
+
add: Function;
|
|
275
|
+
reload: Function;
|
|
276
|
+
remove: Function;
|
|
277
|
+
leaves: Function;
|
|
278
|
+
modules: {
|
|
279
|
+
discover: Function;
|
|
280
|
+
sort: Function;
|
|
281
|
+
addModule: Function;
|
|
282
|
+
addModules: Function;
|
|
283
|
+
removeModule: Function;
|
|
284
|
+
addDiscovered: Function;
|
|
285
|
+
getDiscoveryCache: Function;
|
|
286
|
+
clearDiscoveryCache: Function;
|
|
287
|
+
getStaleMounts: Function;
|
|
288
|
+
};
|
|
289
|
+
};
|
|
290
|
+
context: {
|
|
291
|
+
get: Function;
|
|
292
|
+
inspect: () => Object;
|
|
293
|
+
run: Function;
|
|
294
|
+
scope: Function;
|
|
295
|
+
set: Function;
|
|
296
|
+
};
|
|
297
|
+
diag?: {
|
|
298
|
+
/**
|
|
299
|
+
* - Cache diagnostics sub-namespace.
|
|
300
|
+
*/
|
|
301
|
+
caches?: {
|
|
302
|
+
/**
|
|
303
|
+
* - Get full cache diagnostic data (`{ totalCaches, caches[] }`). Only available when `diagnostics: true`. %%sig: (): Object%% %%example: // ESM usage via slothlet API|import slothlet from "@cldmv/slothlet";|const api = await slothlet({ base: './api', diagnostics: true });|const cacheData = api.slothlet.diag.caches.get();|// { totalCaches: 2, caches: [...] }%% %%example: // ESM usage via slothlet API (inside async function)|async function example() {| const { default: slothlet } = await import("@cldmv/slothlet");| const api = await slothlet({ base: './api', diagnostics: true });| const cacheData = api.slothlet.diag.caches.get();| // { totalCaches: 2, caches: [...] }|}%% %%example: // CJS usage via slothlet API (top-level)|let slothlet;|(async () => {| ({ slothlet } = await import("@cldmv/slothlet"));| const api = await slothlet({ base: './api', diagnostics: true });| const cacheData = api.slothlet.diag.caches.get();| // { totalCaches: 2, caches: [...] }|})();%% %%example: // CJS usage via slothlet API (inside async function)|const slothlet = require("@cldmv/slothlet");|const api = await slothlet({ base: './api', diagnostics: true });|const cacheData = api.slothlet.diag.caches.get();|// { totalCaches: 2, caches: [...] }%%
|
|
304
|
+
*/
|
|
305
|
+
get?: (() => Object) | undefined;
|
|
306
|
+
/**
|
|
307
|
+
* - Return all moduleIDs currently in cache. Only available when `diagnostics: true`. %%sig: (): string[]%% %%example: // ESM usage via slothlet API|import slothlet from "@cldmv/slothlet";|const api = await slothlet({ base: './api', diagnostics: true });|const ids = api.slothlet.diag.caches.getAllModuleIDs();|// ['utils/math.mjs', 'utils/strings.mjs']%% %%example: // ESM usage via slothlet API (inside async function)|async function example() {| const { default: slothlet } = await import("@cldmv/slothlet");| const api = await slothlet({ base: './api', diagnostics: true });| const ids = api.slothlet.diag.caches.getAllModuleIDs();| // ['utils/math.mjs', 'utils/strings.mjs']|}%% %%example: // CJS usage via slothlet API (top-level)|let slothlet;|(async () => {| ({ slothlet } = await import("@cldmv/slothlet"));| const api = await slothlet({ base: './api', diagnostics: true });| const ids = api.slothlet.diag.caches.getAllModuleIDs();| // ['utils/math.mjs', 'utils/strings.mjs']|})();%% %%example: // CJS usage via slothlet API (inside async function)|const slothlet = require("@cldmv/slothlet");|const api = await slothlet({ base: './api', diagnostics: true });|const ids = api.slothlet.diag.caches.getAllModuleIDs();|// ['utils/math.mjs', 'utils/strings.mjs']%%
|
|
308
|
+
*/
|
|
309
|
+
getAllModuleIDs?: (() => string[]) | undefined;
|
|
310
|
+
/**
|
|
311
|
+
* - Check whether a cache entry exists for a given moduleID. Only available when `diagnostics: true`. %%sig: (moduleID: string): boolean%% %%example: // ESM usage via slothlet API|import slothlet from "@cldmv/slothlet";|const api = await slothlet({ base: './api', diagnostics: true });|const exists = api.slothlet.diag.caches.has('utils/math.mjs'); // true or false%% %%example: // ESM usage via slothlet API (inside async function)|async function example() {| const { default: slothlet } = await import("@cldmv/slothlet");| const api = await slothlet({ base: './api', diagnostics: true });| const exists = api.slothlet.diag.caches.has('utils/math.mjs'); // true or false|}%% %%example: // CJS usage via slothlet API (top-level)|let slothlet;|(async () => {| ({ slothlet } = await import("@cldmv/slothlet"));| const api = await slothlet({ base: './api', diagnostics: true });| const exists = api.slothlet.diag.caches.has('utils/math.mjs'); // true or false|})();%% %%example: // CJS usage via slothlet API (inside async function)|const slothlet = require("@cldmv/slothlet");|const api = await slothlet({ base: './api', diagnostics: true });|const exists = api.slothlet.diag.caches.has('utils/math.mjs'); // true or false%%
|
|
312
|
+
*/
|
|
313
|
+
has?: Function | undefined;
|
|
314
|
+
} | undefined;
|
|
315
|
+
/**
|
|
316
|
+
* - The `context` config value as passed to `slothlet()`.
|
|
317
|
+
*/
|
|
318
|
+
context?: object | undefined;
|
|
319
|
+
/**
|
|
320
|
+
* - Describe API structure. Pass `true` to return the full API object; omit for top-level keys only. Only available when `diagnostics: true`. %%sig: ([showAll]: boolean): *%% %%example: // ESM usage via slothlet API|import slothlet from "@cldmv/slothlet";|const api = await slothlet({ base: './api', diagnostics: true });|const keys = api.slothlet.diag.describe();|const full = api.slothlet.diag.describe(true);%% %%example: // ESM usage via slothlet API (inside async function)|async function example() {| const { default: slothlet } = await import("@cldmv/slothlet");| const api = await slothlet({ base: './api', diagnostics: true });| const keys = api.slothlet.diag.describe();| const full = api.slothlet.diag.describe(true);|}%% %%example: // CJS usage via slothlet API (top-level)|let slothlet;|(async () => {| ({ slothlet } = await import("@cldmv/slothlet"));| const api = await slothlet({ base: './api', diagnostics: true });| const keys = api.slothlet.diag.describe();| const full = api.slothlet.diag.describe(true);|})();%% %%example: // CJS usage via slothlet API (inside async function)|const slothlet = require("@cldmv/slothlet");|const api = await slothlet({ base: './api', diagnostics: true });|const keys = api.slothlet.diag.describe();|const full = api.slothlet.diag.describe(true);%%
|
|
321
|
+
*/
|
|
322
|
+
describe?: Function | undefined;
|
|
323
|
+
/**
|
|
324
|
+
* - Return the live bound API proxy object. Only available when `diagnostics: true`. %%sig: (): Object%% %%example: // ESM usage via slothlet API|import slothlet from "@cldmv/slothlet";|const api = await slothlet({ base: './api', diagnostics: true });|const proxy = api.slothlet.diag.getAPI(); // the live bound API proxy%% %%example: // ESM usage via slothlet API (inside async function)|async function example() {| const { default: slothlet } = await import("@cldmv/slothlet");| const api = await slothlet({ base: './api', diagnostics: true });| const proxy = api.slothlet.diag.getAPI(); // the live bound API proxy|}%% %%example: // CJS usage via slothlet API (top-level)|let slothlet;|(async () => {| ({ slothlet } = await import("@cldmv/slothlet"));| const api = await slothlet({ base: './api', diagnostics: true });| const proxy = api.slothlet.diag.getAPI(); // the live bound API proxy|})();%% %%example: // CJS usage via slothlet API (inside async function)|const slothlet = require("@cldmv/slothlet");|const api = await slothlet({ base: './api', diagnostics: true });|const proxy = api.slothlet.diag.getAPI(); // the live bound API proxy%%
|
|
325
|
+
*/
|
|
326
|
+
getAPI?: (() => Object) | undefined;
|
|
327
|
+
/**
|
|
328
|
+
* - Return ownership diagnostics for all registered API paths. Only available when `diagnostics: true`. %%sig: (): Object%% %%example: // ESM usage via slothlet API|import slothlet from "@cldmv/slothlet";|const api = await slothlet({ base: './api', diagnostics: true });|const ownership = api.slothlet.diag.getOwnership();%% %%example: // ESM usage via slothlet API (inside async function)|async function example() {| const { default: slothlet } = await import("@cldmv/slothlet");| const api = await slothlet({ base: './api', diagnostics: true });| const ownership = api.slothlet.diag.getOwnership();|}%% %%example: // CJS usage via slothlet API (top-level)|let slothlet;|(async () => {| ({ slothlet } = await import("@cldmv/slothlet"));| const api = await slothlet({ base: './api', diagnostics: true });| const ownership = api.slothlet.diag.getOwnership();|})();%% %%example: // CJS usage via slothlet API (inside async function)|const slothlet = require("@cldmv/slothlet");|const api = await slothlet({ base: './api', diagnostics: true });|const ownership = api.slothlet.diag.getOwnership();%%
|
|
329
|
+
*/
|
|
330
|
+
getOwnership?: (() => Object) | undefined;
|
|
331
|
+
/**
|
|
332
|
+
* - Hook system diagnostics sub-namespace (present only when hooks are enabled).
|
|
333
|
+
*/
|
|
334
|
+
hook?: object | undefined;
|
|
335
|
+
/**
|
|
336
|
+
* - Return a full diagnostic snapshot of current instance state. Only available when `diagnostics: true`. %%sig: (): Object%% %%example: // ESM usage via slothlet API|import slothlet from "@cldmv/slothlet";|const api = await slothlet({ base: './api', diagnostics: true });|const snapshot = api.slothlet.diag.inspect();|console.log(snapshot.modules, snapshot.hooks);%% %%example: // ESM usage via slothlet API (inside async function)|async function example() {| const { default: slothlet } = await import("@cldmv/slothlet");| const api = await slothlet({ base: './api', diagnostics: true });| const snapshot = api.slothlet.diag.inspect();| console.log(snapshot.modules, snapshot.hooks);|}%% %%example: // CJS usage via slothlet API (top-level)|let slothlet;|(async () => {| ({ slothlet } = await import("@cldmv/slothlet"));| const api = await slothlet({ base: './api', diagnostics: true });| const snapshot = api.slothlet.diag.inspect();| console.log(snapshot.modules, snapshot.hooks);|})();%% %%example: // CJS usage via slothlet API (inside async function)|const slothlet = require("@cldmv/slothlet");|const api = await slothlet({ base: './api', diagnostics: true });|const snapshot = api.slothlet.diag.inspect();|console.log(snapshot.modules, snapshot.hooks);%%
|
|
337
|
+
*/
|
|
338
|
+
inspect?: (() => Object) | undefined;
|
|
339
|
+
/**
|
|
340
|
+
* - Ownership sub-namespace for diagnostics.
|
|
341
|
+
*/
|
|
342
|
+
owner?: {
|
|
343
|
+
/**
|
|
344
|
+
* - Get the owning moduleIDs for a specific API path. Only available when `diagnostics: true`. %%sig: (apiPath: string): string[]%% %%example: // ESM usage via slothlet API|import slothlet from "@cldmv/slothlet";|const api = await slothlet({ base: './api', diagnostics: true });|const owners = api.slothlet.diag.owner.get('math.add');|// ['utils/math.mjs']%% %%example: // ESM usage via slothlet API (inside async function)|async function example() {| const { default: slothlet } = await import("@cldmv/slothlet");| const api = await slothlet({ base: './api', diagnostics: true });| const owners = api.slothlet.diag.owner.get('math.add');| // ['utils/math.mjs']|}%% %%example: // CJS usage via slothlet API (top-level)|let slothlet;|(async () => {| ({ slothlet } = await import("@cldmv/slothlet"));| const api = await slothlet({ base: './api', diagnostics: true });| const owners = api.slothlet.diag.owner.get('math.add');| // ['utils/math.mjs']|})();%% %%example: // CJS usage via slothlet API (inside async function)|const slothlet = require("@cldmv/slothlet");|const api = await slothlet({ base: './api', diagnostics: true });|const owners = api.slothlet.diag.owner.get('math.add');|// ['utils/math.mjs']%%
|
|
345
|
+
*/
|
|
346
|
+
get?: Function | undefined;
|
|
347
|
+
} | undefined;
|
|
348
|
+
/**
|
|
349
|
+
* - The `reference` config value as passed to `slothlet()`.
|
|
350
|
+
*/
|
|
351
|
+
reference?: object | undefined;
|
|
352
|
+
/**
|
|
353
|
+
* - The `SlothletWarning` class — access `.captured` for warnings emitted during tests. Only available when `diagnostics: true`. %%sig: (): SlothletWarning%% %%example: // ESM usage via slothlet API|import slothlet from "@cldmv/slothlet";|const api = await slothlet({ base: './api', diagnostics: true });|const SlothletWarning = api.slothlet.diag.SlothletWarning;|console.log(SlothletWarning.captured); // array of captured warnings%% %%example: // ESM usage via slothlet API (inside async function)|async function example() {| const { default: slothlet } = await import("@cldmv/slothlet");| const api = await slothlet({ base: './api', diagnostics: true });| const SlothletWarning = api.slothlet.diag.SlothletWarning;| console.log(SlothletWarning.captured); // array of captured warnings|}%% %%example: // CJS usage via slothlet API (top-level)|let slothlet;|(async () => {| ({ slothlet } = await import("@cldmv/slothlet"));| const api = await slothlet({ base: './api', diagnostics: true });| const SlothletWarning = api.slothlet.diag.SlothletWarning;| console.log(SlothletWarning.captured); // array of captured warnings|})();%% %%example: // CJS usage via slothlet API (inside async function)|const slothlet = require("@cldmv/slothlet");|const api = await slothlet({ base: './api', diagnostics: true });|const SlothletWarning = api.slothlet.diag.SlothletWarning;|console.log(SlothletWarning.captured); // array of captured warnings%%
|
|
354
|
+
*/
|
|
355
|
+
SlothletWarning?: (() => SlothletWarning) | undefined;
|
|
356
|
+
} | undefined;
|
|
357
|
+
hook: {
|
|
358
|
+
clear: Function;
|
|
359
|
+
disable: Function;
|
|
360
|
+
disablePattern: Function;
|
|
361
|
+
enable: Function;
|
|
362
|
+
enablePattern: Function;
|
|
363
|
+
list: Function;
|
|
364
|
+
off: Function;
|
|
365
|
+
on: Function;
|
|
366
|
+
pin: {
|
|
367
|
+
enabled: boolean;
|
|
368
|
+
enable: Function;
|
|
369
|
+
disable: Function;
|
|
370
|
+
};
|
|
371
|
+
remove: Function;
|
|
372
|
+
resetPatternFilter: Function;
|
|
373
|
+
};
|
|
374
|
+
lifecycle: {
|
|
375
|
+
off: Function;
|
|
376
|
+
on: Function;
|
|
377
|
+
};
|
|
378
|
+
materialize: {
|
|
379
|
+
get: () => Object;
|
|
380
|
+
materialized: boolean;
|
|
381
|
+
wait: () => Promise<void>;
|
|
382
|
+
};
|
|
383
|
+
metadata: {
|
|
384
|
+
caller: () => Object | null;
|
|
385
|
+
get: Function;
|
|
386
|
+
remove: Function;
|
|
387
|
+
getFor: Function;
|
|
388
|
+
removeFor: Function;
|
|
389
|
+
self: () => Object | null;
|
|
390
|
+
set: Function;
|
|
391
|
+
setFor: Function;
|
|
392
|
+
setGlobal: Function;
|
|
393
|
+
};
|
|
394
|
+
owner: {
|
|
395
|
+
get: Function;
|
|
396
|
+
};
|
|
397
|
+
ownership: {
|
|
398
|
+
get: Function;
|
|
399
|
+
unregister: Function;
|
|
400
|
+
};
|
|
401
|
+
permissions: {
|
|
402
|
+
control: {
|
|
403
|
+
enabled: boolean;
|
|
404
|
+
enable: () => void;
|
|
405
|
+
disable: () => void;
|
|
406
|
+
readGatingEnabled: boolean;
|
|
407
|
+
readGating: (arg0: boolean) => void;
|
|
408
|
+
seal: () => void;
|
|
409
|
+
sealed: boolean;
|
|
410
|
+
};
|
|
411
|
+
};
|
|
412
|
+
versioning: {
|
|
413
|
+
list: Function;
|
|
414
|
+
setDefault: Function;
|
|
415
|
+
unregister: Function;
|
|
416
|
+
getVersionMetadata: Function;
|
|
417
|
+
setVersionMetadata: Function;
|
|
418
|
+
};
|
|
419
|
+
lockCaller: Function;
|
|
420
|
+
bind: Function;
|
|
421
|
+
reference?: object | undefined;
|
|
422
|
+
reload: Function;
|
|
423
|
+
run: Function;
|
|
424
|
+
scope: Function;
|
|
425
|
+
shutdown: () => Promise<void>;
|
|
426
|
+
};
|
|
427
|
+
};
|
|
428
|
+
import { SlothletWarning } from "@cldmv/slothlet/errors";
|