@cldmv/slothlet-types 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/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 +39 -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,8 +1,129 @@
1
+ /**
2
+ * Manages unified API assignment logic
3
+ * @class ApiAssignment
4
+ * @extends ComponentBase
5
+ * @package
6
+ *
7
+ * @description
8
+ * Class-based utility for assigning values to API paths with collision detection,
9
+ * wrapper sync, and merge operations. Extends ComponentBase for Slothlet property access.
10
+ *
11
+ * @example
12
+ * const assignment = new ApiAssignment(slothlet);
13
+ * assignment.assignToApiPath(api, "math", mathWrapper, {});
14
+ */
1
15
  export class ApiAssignment extends ComponentBase {
2
16
  static slothletProperty: string;
3
- isWrapperProxy(value: any): boolean;
4
- mergeOffSlotCollisionFolder(keptWrapper: any): void;
5
- assignToApiPath(targetApi: any, key: any, value: any, options?: {}): boolean;
6
- mergeApiObjects(targetApi: any, sourceApi: any, options?: {}): Promise<void>;
17
+ /**
18
+ * Create an ApiAssignment instance.
19
+ * @param {object} slothlet - Slothlet class instance.
20
+ * @package
21
+ *
22
+ * @description
23
+ * Creates ApiAssignment with ComponentBase support for config access.
24
+ */
25
+ constructor(slothlet: object);
26
+ /**
27
+ * Check if a value is a UnifiedWrapper proxy
28
+ * @param {unknown} value - Value to check
29
+ * @returns {boolean} True if value is a wrapper proxy
30
+ * @private
31
+ */
32
+ private isWrapperProxy;
33
+ /**
34
+ * Merge a callable-vs-callable collision's off-slot folder into the callable that kept the slot.
35
+ *
36
+ * Under the documented `merge` row the first-loaded callable holds the slot, so the folder
37
+ * composes off-slot; its members still belong on the surface — everything the survivor does not
38
+ * already define (first loaded wins conflicts). Idempotent: the handle is cleared on the first
39
+ * run, so a later settle pass over the same wrapper is a no-op.
40
+ *
41
+ * @param {object} keptWrapper - The surviving callable's wrapper (holds the off-slot handle).
42
+ * @returns {void}
43
+ * @package
44
+ */
45
+ mergeOffSlotCollisionFolder(keptWrapper: object): void;
46
+ /**
47
+ * Assign a value to an API object at a given property key.
48
+ * Handles wrapper sync, collision detection, and proper proxy preservation.
49
+ *
50
+ * @param {Object} targetApi - Target object to assign to (may be a UnifiedWrapper proxy)
51
+ * @param {string|symbol} key - Property name to assign
52
+ * @param {unknown} value - Value to assign (may be UnifiedWrapper proxy, raw value, etc.)
53
+ * @param {Object} options - Assignment options
54
+ * @param {boolean} [options.allowOverwrite=false] - Allow overwriting existing non-wrapper values
55
+ * @param {boolean} [options.mutateExisting=false] - Sync existing wrappers instead of replacing
56
+ * @param {boolean} [options.useCollisionDetection=false] - Enable collision detection using config.collision mode
57
+ * @param {Object} [options.config] - Slothlet config (uses config.collision.initial or config.collision.api)
58
+ * @param {string} [options.collisionContext="initial"] - Collision context: "initial" or "api"
59
+ * @param {Function} [options.syncWrapper] - Function to sync two wrapper proxies
60
+ * @param {string} [options.collisionMode="merge"] - Mode used by the mutateExisting/hot-reload path (Case 1) when syncing two existing wrappers
61
+ * @param {string|null} [options.collisionModeOverride=null] - Per-call override (e.g. `api.add()`'s `forceOverwrite`) for the collision-detection branch (Case 2); takes precedence over `config.collision[collisionContext]`
62
+ * @param {string|null} [options.moduleID=null] - Module id to associate with this assignment, forwarded to `syncWrapper`
63
+ * @returns {Promise<boolean>} True if assignment succeeded, false if blocked by collision or other constraint
64
+ *
65
+ * @description
66
+ * This function encapsulates all assignment patterns from processFiles:
67
+ * - Direct assignment when no collision
68
+ * - Wrapper sync when both existing and new are wrappers
69
+ * - Collision detection using config.collision[context] mode (merge/replace/error/skip/warn)
70
+ * - Proper handling of UnifiedWrapper proxies (preserves them, doesn't unwrap)
71
+ *
72
+ * Async (#369) because Case 1 awaits `syncWrapper` — itself async since it force-materializes
73
+ * both sides of a collision (#364). Every caller must await this call: a caller that captures
74
+ * the return value in an `if (assigned)`/truthy check and does NOT await first sees a Promise
75
+ * object, which is always truthy regardless of what it resolves to.
76
+ *
77
+ * @example
78
+ * // Direct assignment
79
+ * await assignment.assignToApiPath(api, "math", mathWrapper, {});
80
+ *
81
+ * @example
82
+ * // Sync existing wrapper with new data
83
+ * await assignment.assignToApiPath(api, "config", newConfigWrapper, { mutateExisting: true, syncWrapper });
84
+ *
85
+ * @example
86
+ * // With collision detection
87
+ * await assignment.assignToApiPath(api.math, "add", addFunction, {
88
+ * useCollisionDetection: true,
89
+ * config,
90
+ * collisionContext: "initial"
91
+ * });
92
+ */
93
+ assignToApiPath(targetApi: Object, key: string | symbol, value: unknown, options?: {
94
+ allowOverwrite?: boolean | undefined;
95
+ mutateExisting?: boolean | undefined;
96
+ useCollisionDetection?: boolean | undefined;
97
+ config?: Object | undefined;
98
+ collisionContext?: string | undefined;
99
+ syncWrapper?: Function | undefined;
100
+ collisionMode?: string | undefined;
101
+ collisionModeOverride?: string | null | undefined;
102
+ moduleID?: string | null | undefined;
103
+ }): Promise<boolean>;
104
+ /**
105
+ * Recursively merge a source object into a target object using assignToApiPath logic.
106
+ *
107
+ * @param {Object} targetApi - Target object
108
+ * @param {Object} sourceApi - Source object to merge from
109
+ * @param {Object} options - Assignment options (passed to assignToApiPath)
110
+ * @param {boolean} [options.removeMissing=false] - Remove keys from target that don't exist in source
111
+ * @returns {Promise<void>}
112
+ *
113
+ * @description
114
+ * Recursively walks the source object and assigns each value to the target using
115
+ * assignToApiPath. This provides consistent merge behavior for both initial build
116
+ * and hot reload operations.
117
+ *
118
+ * @example
119
+ * await assignment.mergeApiObjects(api.config, newConfigApi, {
120
+ * mutateExisting: true,
121
+ * syncWrapper,
122
+ * removeMissing: false
123
+ * });
124
+ */
125
+ mergeApiObjects(targetApi: Object, sourceApi: Object, options?: {
126
+ removeMissing?: boolean | undefined;
127
+ }): Promise<void>;
7
128
  }
8
129
  import { ComponentBase } from "#factories/component-base";
@@ -1,11 +1,108 @@
1
+ /**
2
+ * Builds final API with built-in methods attached
3
+ * @class ApiBuilder
4
+ * @extends ComponentBase
5
+ * @package
6
+ *
7
+ * @description
8
+ * Class-based builder for final API construction with built-in namespace attachment.
9
+ * Extends ComponentBase for common Slothlet property access.
10
+ *
11
+ * @example
12
+ * const builder = new ApiBuilder(slothlet);
13
+ * const api = await builder.buildFinalAPI(userApi);
14
+ */
1
15
  export class ApiBuilder extends ComponentBase {
2
16
  static slothletProperty: string;
3
- buildFinalAPI(userApi: any): Promise<any>;
4
- createSlothletNamespace(userApi: any): Promise<any>;
5
- createShutdownFunction(): () => Promise<any>;
6
- createRunFunction(): (contextData: any, callback: any, ...args: any[]) => Promise<any>;
7
- createScopeFunction(): (options: any) => Promise<any>;
8
- createDestroyFunction(api: any): () => Promise<void>;
9
- attachBuiltins(userApi: any, builtins: any): void;
17
+ /**
18
+ * Create an ApiBuilder instance.
19
+ * @param {object} slothlet - Slothlet class instance.
20
+ * @package
21
+ *
22
+ * @description
23
+ * Creates ApiBuilder with ComponentBase support for config, debug, instanceID access.
24
+ */
25
+ constructor(slothlet: object);
26
+ /**
27
+ * Build final API with built-in methods attached
28
+ * @param {Object} userApi - User API object from mode builder
29
+ * @returns {Promise<Object>} Final API with built-ins attached
30
+ * @public
31
+ */
32
+ public buildFinalAPI(userApi: Object): Promise<Object>;
33
+ /**
34
+ * @param {object} userApi - User API object (for diagnostics).
35
+ * @returns {Promise<object>} Slothlet namespace object.
36
+ * @private
37
+ *
38
+ * @description
39
+ * Builds the slothlet namespace with version metadata, API controls, and lifecycle
40
+ * helpers for the current instance.
41
+ *
42
+ * @example
43
+ * const namespace = await this.createSlothletNamespace(api);
44
+ */
45
+ private createSlothletNamespace;
46
+ /**
47
+ * Create root-level shutdown function (convenience)
48
+ * @returns {Function} Shutdown function that dynamically calls user hooks
49
+ * @private
50
+ */
51
+ private createShutdownFunction;
52
+ /**
53
+ * Create root-level run function (per-request context isolation)
54
+ * @returns {Function} Run function that executes callbacks with isolated context
55
+ * @private
56
+ */
57
+ private createRunFunction;
58
+ /**
59
+ * Create root-level scope function (structured per-request context with options)
60
+ * @returns {Function} Scope function that executes functions with isolated context
61
+ * @private
62
+ */
63
+ private createScopeFunction;
64
+ /**
65
+ * Create root-level destroy function (permanent destruction)
66
+ * @param {Object} api - Full API object
67
+ * @returns {Function} Destroy function that dynamically calls user hooks
68
+ * @private
69
+ */
70
+ private createDestroyFunction;
71
+ /**
72
+ * Attach built-in methods to user API
73
+ * @param {Object} userApi - User API object
74
+ * @param {Object} builtins - Built-in methods to attach
75
+ * @private
76
+ */
77
+ private attachBuiltins;
10
78
  }
79
+ /**
80
+ * i18n translation helpers exposed on every Slothlet namespace.
81
+ */
82
+ export type I18nNamespace = {
83
+ /**
84
+ * - Set the active locale (e.g. "en-us"). Synchronous; in a browser, non-default locales load in the background.
85
+ */
86
+ setLanguage: Function;
87
+ /**
88
+ * - Set the active locale and await its load. Browser-capable (resolves once the locale module is fetched).
89
+ */
90
+ setLanguageAsync: Function;
91
+ /**
92
+ * - Return the current active locale string.
93
+ */
94
+ getLanguage: Function;
95
+ /**
96
+ * - Translate an error code with optional params.
97
+ */
98
+ translate: Function;
99
+ /**
100
+ * - Alias for translate.
101
+ */
102
+ t: Function;
103
+ /**
104
+ * - Initialise the i18n system with options.
105
+ */
106
+ initI18n: Function;
107
+ };
11
108
  import { ComponentBase } from "#factories/component-base";
@@ -1,5 +1,86 @@
1
+ /**
2
+ * API builder class for orchestrating mode-based API construction.
3
+ * @class Builder
4
+ * @extends ComponentBase
5
+ * @package
6
+ *
7
+ * @description
8
+ * Orchestrates API building by delegating to mode-specific builders (eager/lazy).
9
+ * Extends ComponentBase for access to Slothlet configuration and error classes.
10
+ *
11
+ * @example
12
+ * const builder = new Builder(slothlet);
13
+ * const api = await builder.buildAPI({ dir: "./api" });
14
+ */
1
15
  export class Builder extends ComponentBase {
2
16
  static slothletProperty: string;
3
- buildAPI(options: any): Promise<any>;
17
+ /**
18
+ * Create Builder instance.
19
+ * @param {object} slothlet - Slothlet orchestrator instance.
20
+ * @package
21
+ *
22
+ * @description
23
+ * Stores Slothlet reference for accessing configuration and components.
24
+ *
25
+ * @example
26
+ * const builder = new Builder(slothlet);
27
+ */
28
+ constructor(slothlet: object);
29
+ /**
30
+ * Build API from directory or file.
31
+ * @param {Object} options - Build options
32
+ * @param {string} [options.dir] - Directory or file to build from. Required unless `syntheticExports` is set (synthetic / in-memory leaf, #117).
33
+ * @param {string} [options.mode="eager"] - Loading mode (eager or lazy)
34
+ * @param {Object} [options.ownership] - Ownership manager (uses slothlet's if not provided)
35
+ * @param {Object} [options.contextManager] - Context manager (uses slothlet's if not provided)
36
+ * @param {string} [options.instanceID] - Instance ID (uses slothlet's if not provided)
37
+ * @param {Object} [options.config] - Configuration (uses slothlet's if not provided)
38
+ * @param {string} [options.apiPathPrefix=""] - Prefix for API paths (for api.add support)
39
+ * @param {string} [options.collisionContext="initial"] - Collision context
40
+ * @param {string} [options.moduleID] - Stable module identifier (cache key; enables later reload/remove)
41
+ * @param {string|null} [options.cacheBust=null] - Cache-busting value forwarded to the loader/mode
42
+ * @param {string|null} [options.collisionMode=null] - Per-call collision mode override (lazy builds)
43
+ * @param {Function|null} [options.fileFilter=null] - Optional filter function (fileName) => boolean to load specific files only
44
+ * @param {Object|null} [options.syntheticExports=null] - Inline `{ default?, ...named }` exports to build
45
+ * from instead of scanning `dir` (synthetic / in-memory leaf, #117). When set, `dir` is not required.
46
+ * @param {string} [options.syntheticName="synthetic"] - Intermediate key name for the synthetic build.
47
+ * @param {boolean} [options.rootUnwrap=false] - The mount exposes the single root entry's exports
48
+ * directly at the mount path (a single-file or synthetic `api.add()`), so that entry creates no api
49
+ * level and must contribute no path segment either.
50
+ * @returns {Promise<Object>} Raw API object (unwrapped)
51
+ * @public
52
+ *
53
+ * @description
54
+ * Validates inputs and delegates to mode-specific builder (buildEagerAPI or buildLazyAPI).
55
+ * When fileFilter is provided, only files matching the filter are loaded.
56
+ *
57
+ * @example
58
+ * const api = await builder.buildAPI({ dir: "./api_tests/api_test", mode: "eager" });
59
+ *
60
+ * @example
61
+ * // Load specific file only
62
+ * const api = await builder.buildAPI({
63
+ * dir: "./api_tests/api_test",
64
+ * mode: "eager",
65
+ * fileFilter: (fileName) => fileName === "math.mjs"
66
+ * });
67
+ */
68
+ public buildAPI(options: {
69
+ dir?: string | undefined;
70
+ mode?: string | undefined;
71
+ ownership?: Object | undefined;
72
+ contextManager?: Object | undefined;
73
+ instanceID?: string | undefined;
74
+ config?: Object | undefined;
75
+ apiPathPrefix?: string | undefined;
76
+ collisionContext?: string | undefined;
77
+ moduleID?: string | undefined;
78
+ cacheBust?: string | null | undefined;
79
+ collisionMode?: string | null | undefined;
80
+ fileFilter?: Function | null | undefined;
81
+ syntheticExports?: Object | null | undefined;
82
+ syntheticName?: string | undefined;
83
+ rootUnwrap?: boolean | undefined;
84
+ }): Promise<Object>;
4
85
  }
5
86
  import { ComponentBase } from "#factories/component-base";
@@ -1,7 +1,70 @@
1
+ /**
2
+ * ModesProcessor - Handles mode-specific file and directory processing.
3
+ *
4
+ * @class
5
+ * @extends ComponentBase
6
+ * @package
7
+ */
1
8
  export class ModesProcessor extends ComponentBase {
2
9
  static slothletProperty: string;
3
- processFiles(api: any, files: any, directory: any, currentDepth: any, mode: any, isRoot: any, recursive: any, populateDirectly?: boolean, apiPathPrefix?: string, collisionContext?: string, moduleID?: null, sourceFolder?: null, cacheBust?: null, collisionModeOverride?: null, rootUnwrap?: boolean): Promise<any>;
4
- createLazySubdirectoryWrapper(dir: any, apiPath: any, moduleID?: null, sourceFolder?: null, cacheBust?: null, fileFolderCollisionImpl?: null, collisionMode?: string): any;
5
- applyRootContributor(api: any, rootFunction: any, mode: any): Promise<any>;
10
+ /**
11
+ * Creates a new ModesProcessor instance.
12
+ *
13
+ * @param {Object} slothlet - Parent slothlet instance
14
+ */
15
+ constructor(slothlet: Object);
16
+ /**
17
+ * Recursively walk a directory's scanned files/subdirectories and compose them onto `api`.
18
+ * @param {Object} api - Root api object being built.
19
+ * @param {Array<Object>} files - This directory's own files (from the loader's scan structure).
20
+ * @param {{name: string, path?: string, children: {files: Array, directories: Array}}} directory - This directory's own scan node.
21
+ * @param {number} currentDepth - Recursion depth, for `apiDepth` enforcement.
22
+ * @param {string} mode - `"eager"` or `"lazy"`.
23
+ * @param {boolean} isRoot - Whether this call is the top-level (mount root) invocation.
24
+ * @param {boolean} recursive - Whether to descend into subdirectories at all.
25
+ * @param {boolean} [populateDirectly=false] - Pour this directory's contents directly into `api` (no nested namespace level) — used for transparent-folder and lazy-materialization callers.
26
+ * @param {string} [apiPathPrefix=""] - Dotted api path prefix this directory's own entries are built under.
27
+ * @param {string} [collisionContext="initial"] - `"initial"` or `"api"` — which `config.collision` policy governs this build.
28
+ * @param {string|null} [moduleID=null] - Module id every leaf produced by this call is attributed to.
29
+ * @param {string|null} [sourceFolder=null] - Filesystem path this directory was scanned from, for metadata.
30
+ * @param {string|null} [cacheBust=null] - Cache-busting value forwarded to dynamic imports.
31
+ * @param {string|null} [collisionModeOverride=null] - Per-call override (e.g. `api.add()`'s `forceOverwrite`) that takes precedence over `collisionContext`'s config default for every leaf this call (and its own recursive calls) produces.
32
+ * @param {boolean} [rootUnwrap=false] - The mount exposes its single root entry's exports directly at the mount path (a single-file or synthetic `api.add()`), so that entry creates no api level.
33
+ * @returns {Promise<Function|null>} The root-level default-export contributor function, if one was found at this call's own top level; otherwise `null`.
34
+ * @package
35
+ */
36
+ processFiles(api: Object, files: Array<Object>, directory: {
37
+ name: string;
38
+ path?: string;
39
+ children: {
40
+ files: any[];
41
+ directories: any[];
42
+ };
43
+ }, currentDepth: number, mode: string, isRoot: boolean, recursive: boolean, populateDirectly?: boolean, apiPathPrefix?: string, collisionContext?: string, moduleID?: string | null, sourceFolder?: string | null, cacheBust?: string | null, collisionModeOverride?: string | null, rootUnwrap?: boolean): Promise<Function | null>;
44
+ /**
45
+ * Create lazy wrapper for subdirectory (lazy mode only)
46
+ * @param {Object} dir - Directory structure to materialize on first access.
47
+ * @param {string} apiPath - Current (already composed) API path for this subdirectory.
48
+ * @param {string} [moduleID] - Owning module id, threaded into the loader and ownership registration.
49
+ * @param {string} [sourceFolder] - Parent's source folder path; this subdirectory's own source folder is derived from it.
50
+ * @param {*} [cacheBust] - Cache-busting token passed through to `loadModule`.
51
+ * @param {Object} [fileFolderCollisionImpl] - Pre-existing implementation properties from a file/folder name collision, merged onto the materialized result so they survive lazy materialization.
52
+ * @param {string} [collisionMode] - Effective (override-or-config-resolved) collision mode to apply within this subdirectory.
53
+ * @param {string} [collisionContext] - Collision context ("initial" | "api") this subdirectory was mounted under, threaded to ownership/ collision-detection calls.
54
+ * @returns {Proxy} Lazy unified wrapper
55
+ * @public
56
+ */
57
+ public createLazySubdirectoryWrapper(dir: Object, apiPath: string, moduleID?: string, sourceFolder?: string, cacheBust?: any, fileFolderCollisionImpl?: Object, collisionMode?: string, collisionContext?: string): ProxyConstructor;
58
+ /**
59
+ * Apply root contributor pattern - merge API into root function
60
+ * @param {Object} api - API object with properties
61
+ * @param {Function|null} rootFunction - Root contributor function
62
+ * @param {Object} config - Configuration
63
+ * @param {string} mode - Mode name for debug messages
64
+ * @returns {Promise<Object|Function>} Final API (function if root contributor, object otherwise)
65
+ * @public
66
+ */
67
+ public applyRootContributor(api: Object, rootFunction: Function | null, mode: string): Promise<Object | Function>;
68
+ #private;
6
69
  }
7
70
  import { ComponentBase } from "#factories/component-base";
package/lib/errors.d.mts CHANGED
@@ -1,28 +1,123 @@
1
- export class SlothletDebug {
2
- constructor(config?: {});
3
- config: {};
4
- debugFlags: any;
5
- log(code: any, context?: {}): void;
6
- toString(): string;
7
- }
1
+ /**
2
+ * Custom error class for Slothlet-specific errors with context and i18n
3
+ * @public
4
+ */
8
5
  export class SlothletError extends Error {
9
- static #describeThrown(thrown: any): string;
6
+ /**
7
+ * Create a new SlothletError with automatic translation and hint detection
8
+ * @param {string} code - Error code identifier
9
+ * @param {Object} context - Additional context about the error
10
+ * @param {boolean} [context.validationError] - Mark as validation error (no originalError needed)
11
+ * @param {boolean} [context.stub] - Mark as stub error (not-yet-implemented feature)
12
+ * @param {unknown} [originalError] - What was originally thrown. Not necessarily an `Error`:
13
+ * application code may throw a structured payload, a string, or any other value, and all of
14
+ * them are rendered into the message and chained via `cause`. Only `null`/`undefined` mean
15
+ * "no original".
16
+ * @param {Object} [options] - Additional options (alternative to embedding flags in context)
17
+ * @param {boolean} [options.validationError] - Mark as validation error (no originalError needed)
18
+ * @param {boolean} [options.stub] - Mark as stub error (not-yet-implemented feature)
19
+ * @public
20
+ */
21
+ /**
22
+ * Renders a thrown value for message interpolation.
23
+ *
24
+ * @param {unknown} thrown - Whatever the guarded code threw.
25
+ * @returns {string} A human-readable rendering: an Error's message, a string as itself, and
26
+ * any other value JSON-serialized (falling back to String() for unserializable values).
27
+ */
28
+ static #describeThrown(thrown: unknown): string;
10
29
  constructor(code: any, context?: {}, originalError?: null, options?: {});
11
- toJSON(): {
12
- name: string;
13
- code: any;
14
- message: string;
15
- hint: any;
16
- };
30
+ /**
31
+ * Prevent JSON serialization of context (cleaner error display)
32
+ * @returns {Object} Simplified error object
33
+ */
34
+ toJSON(): Object;
17
35
  }
36
+ /**
37
+ * Warning class for non-fatal issues with i18n support
38
+ * @public
39
+ */
18
40
  export class SlothletWarning {
19
41
  static captured: any[];
20
42
  static suppressConsole: boolean;
21
- static clearCaptured(): void;
22
- constructor(code: any, context?: {});
43
+ /**
44
+ * Clear captured warnings (for testing)
45
+ * @public
46
+ */
47
+ public static clearCaptured(): void;
48
+ /**
49
+ * Create and emit a warning with automatic translation
50
+ * @param {string} code - Warning code identifier
51
+ * @param {Object} context - Additional context about the warning
52
+ * @param {string} [context.key] - Optional translation key override. When provided, this key
53
+ * is used for translation instead of `code`. All other context properties are used as
54
+ * interpolation params. Allows sub-key variants without changing the warning code.
55
+ * @public
56
+ */
57
+ constructor(code: string, context?: {
58
+ key?: string | undefined;
59
+ });
23
60
  name: string;
24
- code: any;
25
- message: any;
26
- context: {};
61
+ code: string;
62
+ /** @type {string} */
63
+ message: string;
64
+ context: {
65
+ key?: string | undefined;
66
+ };
67
+ /**
68
+ * Custom string representation
69
+ * @returns {string} Formatted warning string
70
+ */
71
+ toString(): string;
72
+ }
73
+ /**
74
+ * Debug utility class for centralized conditional console output with i18n
75
+ * @public
76
+ */
77
+ export class SlothletDebug {
78
+ /**
79
+ * Create a debug logger instance bound to a config
80
+ * @param {Object} config - Configuration object (typically slothlet.config)
81
+ * @public
82
+ */
83
+ constructor(config?: Object);
84
+ config: Object;
85
+ debugFlags: any;
86
+ /**
87
+ * Log a debug message if the code's debug flag is enabled
88
+ * @param {string} code - Debug code/category (e.g., "modes", "wrapper", "api")
89
+ * @param {Object} context - Contextual information to display
90
+ * @param {string} [context.key] - Translation key for the message (e.g. "DEBUG_MODE_FLATTENING").
91
+ * When provided, translates via i18n using the remaining context properties as interpolation
92
+ * params - no `await t()` needed at the call site. Falls back to `DEBUG_{CODE}` category key
93
+ * if omitted, then to `context.message` for backwards compatibility.
94
+ * @param {string} [context.message] - Raw message string (backwards-compat fallback).
95
+ * Prefer `context.key` for new call sites so messages are translatable.
96
+ * @public
97
+ *
98
+ * @description
99
+ * Centralized debug logging that respects debug configuration flags.
100
+ * Only outputs when the specified code matches a truthy debug flag.
101
+ * Translates messages using i18n system with the following key resolution order:
102
+ * 1. `context.key` - explicit per-message translation key (preferred)
103
+ * 2. `DEBUG_{CODE}` - category-level key (e.g. DEBUG_MODES)
104
+ * 3. `context.message` - raw string fallback for backwards compatibility
105
+ *
106
+ * @example
107
+ * // Preferred: pass translation key directly - no await needed
108
+ * this.debug("modes", { key: "DEBUG_MODE_FLATTENING", mode, categoryName });
109
+ *
110
+ * @example
111
+ * // Legacy: raw message string (still works, but not translatable)
112
+ * this.debug("wrapper", { message: "Category reuse - using existing wrapper", apiPath });
113
+ */
114
+ public log(code: string, context?: {
115
+ key?: string | undefined;
116
+ message?: string | undefined;
117
+ }): void;
118
+ /**
119
+ * Custom string representation
120
+ * @returns {string} Debug info
121
+ */
27
122
  toString(): string;
28
123
  }