@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.
- package/README.md +7 -5
- package/dist/lib/builders/api-assignment.mjs +1 -1
- package/dist/lib/builders/api_builder.mjs +1 -1
- package/dist/lib/builders/builder.mjs +1 -1
- package/dist/lib/builders/modes-processor.mjs +1 -1
- package/dist/lib/handlers/api-cache-manager.mjs +1 -1
- package/dist/lib/handlers/api-manager.mjs +1 -1
- package/dist/lib/handlers/module-manager.mjs +1 -1
- package/dist/lib/handlers/ownership.mjs +1 -1
- package/dist/lib/handlers/routine-manager.mjs +17 -0
- package/dist/lib/handlers/unified-wrapper.mjs +1 -1
- package/dist/lib/helpers/config.mjs +1 -1
- package/dist/lib/helpers/defaults.mjs +1 -1
- package/dist/lib/helpers/eventtarget-property-context.mjs +17 -0
- package/dist/lib/helpers/observer-context.mjs +17 -0
- package/dist/lib/helpers/scheduler-context.mjs +1 -1
- package/dist/lib/i18n/languages/en-us.json +2 -0
- package/dist/lib/modes/eager.mjs +1 -1
- package/dist/lib/processors/flatten.mjs +1 -1
- package/dist/slothlet.mjs +1 -1
- package/index.cjs +20 -0
- package/index.mjs +14 -0
- package/package.json +8 -7
- package/types/stub/devcheck.d.mts +1 -1
- package/types/stub/lib/builders/api-assignment.d.mts +130 -2
- package/types/stub/lib/builders/api_builder.d.mts +109 -2
- package/types/stub/lib/builders/builder.d.mts +87 -2
- package/types/stub/lib/builders/modes-processor.d.mts +71 -2
- package/types/stub/lib/factories/component-base.d.mts +177 -0
- package/types/stub/lib/helpers/caller-pinning.d.mts +22 -2
- package/types/stub/lib/helpers/class-instance-wrapper.d.mts +58 -2
- package/types/stub/lib/helpers/config.d.mts +321 -2
- package/types/stub/lib/helpers/defaults.d.mts +41 -2
- package/types/stub/lib/helpers/eventemitter-context.d.mts +31 -2
- package/types/stub/lib/helpers/eventtarget-context.d.mts +21 -2
- package/types/stub/lib/helpers/eventtarget-property-context.d.mts +23 -0
- package/types/stub/lib/helpers/generate-manifest.d.mts +180 -2
- package/types/stub/lib/helpers/hint-detector.d.mts +27 -2
- package/types/stub/lib/helpers/manifest-resolver.d.mts +101 -2
- package/types/stub/lib/helpers/modes-utils.d.mts +35 -2
- package/types/stub/lib/helpers/module-discovery.d.mts +81 -2
- package/types/stub/lib/helpers/module-manifest-validator.d.mts +37 -2
- package/types/stub/lib/helpers/module-sort.d.mts +65 -2
- package/types/stub/lib/helpers/observer-context.d.mts +23 -0
- package/types/stub/lib/helpers/pattern-matcher.d.mts +44 -2
- package/types/stub/lib/helpers/platform.d.mts +111 -2
- package/types/stub/lib/helpers/resolve-from-caller.d.mts +33 -2
- package/types/stub/lib/helpers/scheduler-context.d.mts +23 -2
- package/types/stub/lib/helpers/utilities.d.mts +57 -2
- package/types/stub/lib/i18n/translations.d.mts +52 -2
- package/types/stub/lib/modes/eager.d.mts +56 -2
- package/types/stub/lib/modes/lazy.d.mts +67 -2
- package/types/stub/lib/processors/flatten.d.mts +123 -2
- package/types/stub/lib/processors/loader.d.mts +83 -2
- package/types/stub/lib/processors/type-generator.d.mts +19 -2
- package/types/stub/lib/processors/typescript.d.mts +174 -2
- package/types/stub/lib/runtime/runtime-asynclocalstorage.d.mts +72 -2
- package/types/stub/lib/runtime/runtime-livebindings.d.mts +38 -2
|
@@ -1,3 +1,28 @@
|
|
|
1
1
|
// AUTO-GENERATED by tools/build/build-typestubs.mjs — do not edit.
|
|
2
|
-
//
|
|
3
|
-
|
|
2
|
+
// Self-contained copy: this subpath is internal and not published by @cldmv/slothlet-types.
|
|
3
|
+
/**
|
|
4
|
+
* Hint detection for providing helpful error hints
|
|
5
|
+
* @class HintDetector
|
|
6
|
+
* @extends ComponentBase
|
|
7
|
+
* @package
|
|
8
|
+
*/
|
|
9
|
+
export class HintDetector extends ComponentBase {
|
|
10
|
+
static slothletProperty: string;
|
|
11
|
+
/**
|
|
12
|
+
* Detect appropriate hint key based on error
|
|
13
|
+
* @param {Error} error - The original error
|
|
14
|
+
* @param {string} errorCode - The SlothletError code
|
|
15
|
+
* @returns {string|undefined} Hint key for i18n translation, or undefined
|
|
16
|
+
* @public
|
|
17
|
+
*/
|
|
18
|
+
public detectHint(error: Error, errorCode: string): string | undefined;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Detect appropriate hint key based on error
|
|
22
|
+
* @param {Error} error - The original error
|
|
23
|
+
* @param {string} errorCode - The SlothletError code
|
|
24
|
+
* @returns {string|undefined} Hint key for i18n translation, or undefined
|
|
25
|
+
* @public
|
|
26
|
+
*/
|
|
27
|
+
export function detectHint(error: Error, errorCode: string): string | undefined;
|
|
28
|
+
import { ComponentBase } from "#factories/component-base";
|
|
@@ -1,3 +1,102 @@
|
|
|
1
1
|
// AUTO-GENERATED by tools/build/build-typestubs.mjs — do not edit.
|
|
2
|
-
//
|
|
3
|
-
|
|
2
|
+
// Self-contained copy: this subpath is internal and not published by @cldmv/slothlet-types.
|
|
3
|
+
/**
|
|
4
|
+
* @Project: @cldmv/slothlet
|
|
5
|
+
* @Filename: /src/lib/helpers/manifest-resolver.mjs
|
|
6
|
+
* @Date: 2026-05-28 00:00:00 -07:00 (1748419200)
|
|
7
|
+
* @Author: Nate Corcoran <CLDMV>
|
|
8
|
+
* @Email: <Shinrai@users.noreply.github.com>
|
|
9
|
+
* -----
|
|
10
|
+
* @Last modified by: Nate Corcoran <CLDMV> (Shinrai@users.noreply.github.com)
|
|
11
|
+
* @Last modified time: 2026-05-28 08:10:28 -07:00 (1779981028)
|
|
12
|
+
* -----
|
|
13
|
+
* @Copyright: Copyright (c) 2013-2026 Catalyzed Motivation Inc. All rights reserved.
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* @fileoverview Browser-safe factory for the `resolveModuleSpecifier` callback.
|
|
17
|
+
*
|
|
18
|
+
* @description
|
|
19
|
+
* `createManifestResolver(base)` produces a `resolveModuleSpecifier` function that
|
|
20
|
+
* resolves manifest-relative file paths to absolute URLs using the standard
|
|
21
|
+
* `new URL(path, base)` algorithm. This is the correct resolver for any deployment
|
|
22
|
+
* where API modules are served from a known base URL (the vast majority of use cases).
|
|
23
|
+
*
|
|
24
|
+
* This file has **no Node.js-specific imports** — it is safe to include in a browser
|
|
25
|
+
* bundle directly. For the build-time `generateManifest` utility (which uses `node:fs`)
|
|
26
|
+
* see `@cldmv/slothlet/helpers/generate-manifest`.
|
|
27
|
+
*
|
|
28
|
+
* ### Typical browser workflow
|
|
29
|
+
*
|
|
30
|
+
* ```text
|
|
31
|
+
* Build time → generateManifest("./src/api") → api-manifest.json
|
|
32
|
+
* Bundle time → import api-manifest.json
|
|
33
|
+
* Runtime → createManifestResolver(import.meta.url) → pass to slothlet()
|
|
34
|
+
* ```
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* // API modules live next to the current module
|
|
38
|
+
* import { createManifestResolver } from "@cldmv/slothlet/helpers/manifest-resolver";
|
|
39
|
+
* import manifest from "./api-manifest.json" assert { type: "json" };
|
|
40
|
+
* import { slothlet } from "@cldmv/slothlet";
|
|
41
|
+
*
|
|
42
|
+
* const api = await slothlet({
|
|
43
|
+
* manifest,
|
|
44
|
+
* resolveModuleSpecifier: createManifestResolver(import.meta.url)
|
|
45
|
+
* });
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* // API modules live in a sub-directory relative to the current module
|
|
49
|
+
* import { createManifestResolver } from "@cldmv/slothlet/helpers/manifest-resolver";
|
|
50
|
+
*
|
|
51
|
+
* const api = await slothlet({
|
|
52
|
+
* manifest,
|
|
53
|
+
* resolveModuleSpecifier: createManifestResolver(new URL("./api/", import.meta.url))
|
|
54
|
+
* });
|
|
55
|
+
*
|
|
56
|
+
* @module @cldmv/slothlet/helpers/manifest-resolver
|
|
57
|
+
* @public
|
|
58
|
+
*/
|
|
59
|
+
/**
|
|
60
|
+
* Create a `resolveModuleSpecifier` callback that resolves manifest file entries
|
|
61
|
+
* to absolute URLs using a fixed base URL.
|
|
62
|
+
*
|
|
63
|
+
* The returned function implements the exact signature expected by
|
|
64
|
+
* `slothlet({ resolveModuleSpecifier })`: it receives a manifest file entry object
|
|
65
|
+
* and returns an importable URL string.
|
|
66
|
+
*
|
|
67
|
+
* @param {string|URL} base - The base URL that all manifest paths are relative to.
|
|
68
|
+
* Pass `import.meta.url` when API modules sit next to your entry point, or
|
|
69
|
+
* `new URL("./api/", import.meta.url)` when they are in a sub-directory.
|
|
70
|
+
* @returns {(entry: { path: string, name: string, fullName: string }) => string}
|
|
71
|
+
* A `resolveModuleSpecifier` function ready to pass to `slothlet()`.
|
|
72
|
+
*
|
|
73
|
+
* @throws {TypeError} If `base` is not a string or URL instance.
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* // Modules in the same directory as the current file
|
|
77
|
+
* const resolver = createManifestResolver(import.meta.url);
|
|
78
|
+
* // resolver({ path: "math.mjs", name: "math", fullName: "math.mjs" })
|
|
79
|
+
* // => "https://example.com/app/math.mjs"
|
|
80
|
+
*
|
|
81
|
+
* @example
|
|
82
|
+
* // Modules in an ./api/ sub-directory
|
|
83
|
+
* const resolver = createManifestResolver(new URL("./api/", import.meta.url));
|
|
84
|
+
* // resolver({ path: "auth.mjs", name: "auth", fullName: "auth.mjs" })
|
|
85
|
+
* // => "https://example.com/app/api/auth.mjs"
|
|
86
|
+
*
|
|
87
|
+
* @example
|
|
88
|
+
* // Full slothlet integration
|
|
89
|
+
* import manifest from "./api-manifest.json" assert { type: "json" };
|
|
90
|
+
* import { slothlet } from "@cldmv/slothlet";
|
|
91
|
+
* import { createManifestResolver } from "@cldmv/slothlet/helpers/manifest-resolver";
|
|
92
|
+
*
|
|
93
|
+
* const api = await slothlet({
|
|
94
|
+
* manifest,
|
|
95
|
+
* resolveModuleSpecifier: createManifestResolver(new URL("./api/", import.meta.url))
|
|
96
|
+
* });
|
|
97
|
+
*/
|
|
98
|
+
export function createManifestResolver(base: string | URL): (entry: {
|
|
99
|
+
path: string;
|
|
100
|
+
name: string;
|
|
101
|
+
fullName: string;
|
|
102
|
+
}) => string;
|
|
@@ -1,3 +1,36 @@
|
|
|
1
1
|
// AUTO-GENERATED by tools/build/build-typestubs.mjs — do not edit.
|
|
2
|
-
//
|
|
3
|
-
|
|
2
|
+
// Self-contained copy: this subpath is internal and not published by @cldmv/slothlet-types.
|
|
3
|
+
/**
|
|
4
|
+
* Mode processing utilities component class
|
|
5
|
+
* @extends ComponentBase
|
|
6
|
+
*/
|
|
7
|
+
export class ModesUtils extends ComponentBase {
|
|
8
|
+
static slothletProperty: string;
|
|
9
|
+
/**
|
|
10
|
+
* Create a named wrapper for default export functions when they are anonymous.
|
|
11
|
+
* NOTE: This function is now a pass-through since UnifiedWrapper handles name/length/toString
|
|
12
|
+
* through its proxy get trap. Wrapping is no longer needed and causes toString mismatches.
|
|
13
|
+
* @param {Function} fn - Original function.
|
|
14
|
+
* @param {string} nameHint - Name to apply if fn is anonymous or named "default" (unused).
|
|
15
|
+
* @returns {Function} Original function unmodified.
|
|
16
|
+
* @public
|
|
17
|
+
*/
|
|
18
|
+
public ensureNamedExportFunction(fn: Function, ____nameHint: any): Function;
|
|
19
|
+
/**
|
|
20
|
+
* Clone eager-mode module exports to avoid mutating import cache objects.
|
|
21
|
+
* @param {unknown} value - Value to clone for wrapping
|
|
22
|
+
* @param {string} mode - Current mode ("eager" or "lazy")
|
|
23
|
+
* @returns {unknown} Cloned value for eager mode, original otherwise
|
|
24
|
+
* @public
|
|
25
|
+
*/
|
|
26
|
+
public cloneWrapperImpl(value: unknown, mode: string): unknown;
|
|
27
|
+
/**
|
|
28
|
+
* Helper to determine collision mode for ownership conflicts
|
|
29
|
+
* @param {Object} config - Slothlet configuration
|
|
30
|
+
* @param {string} collisionContext - Either 'initial' or 'api'
|
|
31
|
+
* @returns {string} Collision mode from config
|
|
32
|
+
* @public
|
|
33
|
+
*/
|
|
34
|
+
public getOwnershipCollisionMode(config: Object, collisionContext?: string): string;
|
|
35
|
+
}
|
|
36
|
+
import { ComponentBase } from "#factories/component-base";
|
|
@@ -1,3 +1,82 @@
|
|
|
1
1
|
// AUTO-GENERATED by tools/build/build-typestubs.mjs — do not edit.
|
|
2
|
-
//
|
|
3
|
-
|
|
2
|
+
// Self-contained copy: this subpath is internal and not published by @cldmv/slothlet-types.
|
|
3
|
+
/**
|
|
4
|
+
* @typedef {object} DiscoverOptions
|
|
5
|
+
* @property {string|string[]} [scanRoot] - Filesystem path(s) to scan. Default: upward-walk from process.cwd() to nearest node_modules ancestor.
|
|
6
|
+
* @property {string} [manifest="slothlet.module.json"] - Manifest filename, or `<file>#<dotted.key>` locator pointing at a subkey of another file (e.g. `"package.json#slothlet"`).
|
|
7
|
+
* @property {Record<string, string>} [schema] - Field-name remap for legacy manifests. Maps canonical name → legacy name.
|
|
8
|
+
* @property {string|string[]} [prefix] - Name-prefix filter applied BEFORE manifest read. Matches against full package name including scope.
|
|
9
|
+
* @property {(manifest: object, packageName: string) => boolean} [filter] - Content-based filter applied AFTER manifest validation.
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* @typedef {object} DiscoverResult
|
|
13
|
+
* @property {string} packageName - Package name from package.json.
|
|
14
|
+
* @property {string} packageRoot - Resolved absolute filesystem path to the package directory.
|
|
15
|
+
* @property {string[]} mountPath - Normalized mountPath segments (always an array).
|
|
16
|
+
* @property {string} apiDir - Absolute resolved filesystem path to the apiDir inside the package.
|
|
17
|
+
* @property {object} manifest - Normalized + deep-frozen manifest (per M3).
|
|
18
|
+
*/
|
|
19
|
+
/**
|
|
20
|
+
* Walk the filesystem and return validated module candidates.
|
|
21
|
+
*
|
|
22
|
+
* @param {DiscoverOptions} [options] - Discovery options.
|
|
23
|
+
* @returns {Promise<DiscoverResult[]>} Discovered modules in walk order (apply `sort()` for deterministic ordering).
|
|
24
|
+
* @throws {SlothletError} `MODULE_*` codes on manifest validation failures or G7 duplicate-name-version-mismatch.
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* import { discoverModules } from "@cldmv/slothlet/helpers/module-discovery";
|
|
28
|
+
*
|
|
29
|
+
* const found = await discoverModules();
|
|
30
|
+
* // Default upward-walk scanRoot, default slothlet.module.json manifest.
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* const drivers = await discoverModules({
|
|
34
|
+
* prefix: "@cldmv/packrat-driver-",
|
|
35
|
+
* filter: (m) => m.kind === "driver"
|
|
36
|
+
* });
|
|
37
|
+
*/
|
|
38
|
+
export function discoverModules(options?: DiscoverOptions): Promise<DiscoverResult[]>;
|
|
39
|
+
export type DiscoverOptions = {
|
|
40
|
+
/**
|
|
41
|
+
* - Filesystem path(s) to scan. Default: upward-walk from process.cwd() to nearest node_modules ancestor.
|
|
42
|
+
*/
|
|
43
|
+
scanRoot?: string | string[] | undefined;
|
|
44
|
+
/**
|
|
45
|
+
* - Manifest filename, or `<file>#<dotted.key>` locator pointing at a subkey of another file (e.g. `"package.json#slothlet"`).
|
|
46
|
+
*/
|
|
47
|
+
manifest?: string | undefined;
|
|
48
|
+
/**
|
|
49
|
+
* - Field-name remap for legacy manifests. Maps canonical name → legacy name.
|
|
50
|
+
*/
|
|
51
|
+
schema?: Record<string, string> | undefined;
|
|
52
|
+
/**
|
|
53
|
+
* - Name-prefix filter applied BEFORE manifest read. Matches against full package name including scope.
|
|
54
|
+
*/
|
|
55
|
+
prefix?: string | string[] | undefined;
|
|
56
|
+
/**
|
|
57
|
+
* - Content-based filter applied AFTER manifest validation.
|
|
58
|
+
*/
|
|
59
|
+
filter?: ((manifest: object, packageName: string) => boolean) | undefined;
|
|
60
|
+
};
|
|
61
|
+
export type DiscoverResult = {
|
|
62
|
+
/**
|
|
63
|
+
* - Package name from package.json.
|
|
64
|
+
*/
|
|
65
|
+
packageName: string;
|
|
66
|
+
/**
|
|
67
|
+
* - Resolved absolute filesystem path to the package directory.
|
|
68
|
+
*/
|
|
69
|
+
packageRoot: string;
|
|
70
|
+
/**
|
|
71
|
+
* - Normalized mountPath segments (always an array).
|
|
72
|
+
*/
|
|
73
|
+
mountPath: string[];
|
|
74
|
+
/**
|
|
75
|
+
* - Absolute resolved filesystem path to the apiDir inside the package.
|
|
76
|
+
*/
|
|
77
|
+
apiDir: string;
|
|
78
|
+
/**
|
|
79
|
+
* - Normalized + deep-frozen manifest (per M3).
|
|
80
|
+
*/
|
|
81
|
+
manifest: object;
|
|
82
|
+
};
|
|
@@ -1,3 +1,38 @@
|
|
|
1
1
|
// AUTO-GENERATED by tools/build/build-typestubs.mjs — do not edit.
|
|
2
|
-
//
|
|
3
|
-
|
|
2
|
+
// Self-contained copy: this subpath is internal and not published by @cldmv/slothlet-types.
|
|
3
|
+
/**
|
|
4
|
+
* Validate a parsed slothlet.module.json manifest and return a normalized form.
|
|
5
|
+
*
|
|
6
|
+
* @param {object} manifest - Parsed JSON manifest object (must already be valid JSON).
|
|
7
|
+
* @param {object} packageContext - Context derived from the host package.
|
|
8
|
+
* @param {string} packageContext.packageName - npm package `name` from package.json.
|
|
9
|
+
* @param {string} packageContext.packageVersion - npm package `version` from package.json.
|
|
10
|
+
* @param {string} [packageContext.packageDescription] - npm package `description` from package.json.
|
|
11
|
+
* @param {string} packageContext.packageRoot - Absolute filesystem path to the package root.
|
|
12
|
+
* @param {string} packageContext.manifestPath - Path to the manifest file (used in error context for diagnostics).
|
|
13
|
+
* @returns {object} Normalized manifest with the following shape:
|
|
14
|
+
* - All optional fields filled in from defaults / package.json fallbacks
|
|
15
|
+
* - `name`, `version` always present (from package.json if absent in manifest)
|
|
16
|
+
* - `description` from manifest (override) or package.json (fallback)
|
|
17
|
+
* - `priority` defaults to 0 if absent
|
|
18
|
+
* - `mountPath` normalized to an array of segments
|
|
19
|
+
* @throws {SlothletError} with `MODULE_*` code on any validation failure.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* const manifest = JSON.parse(await fs.readFile(manifestPath, "utf8"));
|
|
23
|
+
* const pkgJson = JSON.parse(await fs.readFile(path.join(packageRoot, "package.json"), "utf8"));
|
|
24
|
+
* const normalized = validateModuleManifest(manifest, {
|
|
25
|
+
* packageName: pkgJson.name,
|
|
26
|
+
* packageVersion: pkgJson.version,
|
|
27
|
+
* packageDescription: pkgJson.description,
|
|
28
|
+
* packageRoot,
|
|
29
|
+
* manifestPath
|
|
30
|
+
* });
|
|
31
|
+
*/
|
|
32
|
+
export function validateModuleManifest(manifest: object, packageContext: {
|
|
33
|
+
packageName: string;
|
|
34
|
+
packageVersion: string;
|
|
35
|
+
packageDescription?: string | undefined;
|
|
36
|
+
packageRoot: string;
|
|
37
|
+
manifestPath: string;
|
|
38
|
+
}): object;
|
|
@@ -1,3 +1,66 @@
|
|
|
1
1
|
// AUTO-GENERATED by tools/build/build-typestubs.mjs — do not edit.
|
|
2
|
-
//
|
|
3
|
-
|
|
2
|
+
// Self-contained copy: this subpath is internal and not published by @cldmv/slothlet-types.
|
|
3
|
+
/**
|
|
4
|
+
* @Project: @cldmv/slothlet
|
|
5
|
+
* @Filename: /src/lib/helpers/module-sort.mjs
|
|
6
|
+
* @Date: 2026-05-27T11:22:33-07:00 (1779906153)
|
|
7
|
+
* @Author: Nate Corcoran <CLDMV>
|
|
8
|
+
* @Email: <Shinrai@users.noreply.github.com>
|
|
9
|
+
* -----
|
|
10
|
+
* @Last modified by: Nate Corcoran <CLDMV> (Shinrai@users.noreply.github.com)
|
|
11
|
+
* @Last modified time: 2026-05-27 18:57:20 -07:00 (1779933440)
|
|
12
|
+
* -----
|
|
13
|
+
* @Copyright: Copyright (c) 2013-2026 Catalyzed Motivation Inc. All rights reserved.
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* @fileoverview Pure sort function for `DiscoverResult[]`.
|
|
17
|
+
* @module @cldmv/slothlet/helpers/module-sort
|
|
18
|
+
* @internal
|
|
19
|
+
*
|
|
20
|
+
* @description
|
|
21
|
+
* Default comparator sorts by `manifest.priority` descending (higher first)
|
|
22
|
+
* with `packageName` ascending as the tiebreak. Pass any custom comparator
|
|
23
|
+
* matching `Array.prototype.sort`'s `(a, b) => number` signature to override.
|
|
24
|
+
*
|
|
25
|
+
* Pure function: returns a new array; never mutates the input. The
|
|
26
|
+
* `DiscoverResult` entries are already deep-frozen by `discoverModules()`
|
|
27
|
+
* per M3, so the comparator cannot mutate them through this surface either.
|
|
28
|
+
*/
|
|
29
|
+
/**
|
|
30
|
+
* @typedef {object} DiscoverResult
|
|
31
|
+
* @property {string} packageName
|
|
32
|
+
* @property {string} packageRoot
|
|
33
|
+
* @property {string[]} mountPath
|
|
34
|
+
* @property {string} apiDir
|
|
35
|
+
* @property {object} manifest
|
|
36
|
+
*/
|
|
37
|
+
/**
|
|
38
|
+
* Sort a `DiscoverResult[]` and return a new array. Pure function.
|
|
39
|
+
*
|
|
40
|
+
* @param {DiscoverResult[]} results - Discovery results to sort.
|
|
41
|
+
* @param {(a: DiscoverResult, b: DiscoverResult) => number} [comparator] - Custom comparator. Defaults to priority desc + alphabetical tiebreak.
|
|
42
|
+
* @returns {DiscoverResult[]} New array sorted by the chosen comparator. Input is not mutated.
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
* import { sortModules } from "@cldmv/slothlet/helpers/module-sort";
|
|
46
|
+
*
|
|
47
|
+
* const sorted = sortModules(found);
|
|
48
|
+
* // Default: priority desc, then packageName asc.
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* // Custom: alphabetical only.
|
|
52
|
+
* const alpha = sortModules(found, (a, b) => a.packageName.localeCompare(b.packageName));
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* // Topological over manifest.dependencies (caller's responsibility to
|
|
56
|
+
* // implement; slothlet ships the plumbing, not the topo sort itself).
|
|
57
|
+
* const topo = sortModules(found, makeDependencyComparator(found));
|
|
58
|
+
*/
|
|
59
|
+
export function sortModules(results: DiscoverResult[], comparator?: (a: DiscoverResult, b: DiscoverResult) => number): DiscoverResult[];
|
|
60
|
+
export type DiscoverResult = {
|
|
61
|
+
packageName: string;
|
|
62
|
+
packageRoot: string;
|
|
63
|
+
mountPath: string[];
|
|
64
|
+
apiDir: string;
|
|
65
|
+
manifest: object;
|
|
66
|
+
};
|
|
@@ -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 observer callbacks to the module that constructs 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 enableObserverPatching(): void;
|
|
14
|
+
/**
|
|
15
|
+
* Restore the original observer constructors.
|
|
16
|
+
*
|
|
17
|
+
* Restores a constructor only when the wrapper installed here is still in place, so anything that
|
|
18
|
+
* replaced it afterwards keeps ownership of its own restore.
|
|
19
|
+
*
|
|
20
|
+
* @returns {void}
|
|
21
|
+
* @public
|
|
22
|
+
*/
|
|
23
|
+
export function disableObserverPatching(): void;
|
|
@@ -1,3 +1,45 @@
|
|
|
1
1
|
// AUTO-GENERATED by tools/build/build-typestubs.mjs — do not edit.
|
|
2
|
-
//
|
|
3
|
-
|
|
2
|
+
// Self-contained copy: this subpath is internal and not published by @cldmv/slothlet-types.
|
|
3
|
+
/**
|
|
4
|
+
* Compile a glob pattern into a matcher function.
|
|
5
|
+
* Supports: * (any chars except .), ** (any chars including .), ? (single char),
|
|
6
|
+
* {a,b} brace expansion, !pattern negation
|
|
7
|
+
*
|
|
8
|
+
* @param {string} pattern - Glob pattern
|
|
9
|
+
* @param {object} [options={}] - Options
|
|
10
|
+
* @param {Function} [options.onMaxDepth] - Called when brace expansion exceeds max depth.
|
|
11
|
+
* Should throw an error. If not provided, a SlothletError("BRACE_EXPANSION_MAX_DEPTH") is thrown.
|
|
12
|
+
* @returns {function} Matcher function that takes a path and returns boolean
|
|
13
|
+
* @example
|
|
14
|
+
* const matcher = compilePattern("payments.**");
|
|
15
|
+
* matcher("payments.charge"); // true
|
|
16
|
+
* matcher("admin.users"); // false
|
|
17
|
+
*/
|
|
18
|
+
export function compilePattern(pattern: string, options?: {
|
|
19
|
+
onMaxDepth?: Function | undefined;
|
|
20
|
+
}): Function;
|
|
21
|
+
/**
|
|
22
|
+
* Expand brace patterns {a,b,c} into multiple patterns.
|
|
23
|
+
* Supports nested braces with configurable depth limit.
|
|
24
|
+
*
|
|
25
|
+
* @param {string} pattern - Pattern with braces to expand
|
|
26
|
+
* @param {number} [depth=0] - Current recursion depth
|
|
27
|
+
* @param {number} [maxDepth=10] - Maximum nesting depth
|
|
28
|
+
* @param {object} [options={}] - Options
|
|
29
|
+
* @param {Function} [options.onMaxDepth] - Called when max depth exceeded. Should throw.
|
|
30
|
+
* @returns {string[]} Array of expanded patterns
|
|
31
|
+
* @example
|
|
32
|
+
* expandBraces("{a,b}.path"); // ["a.path", "b.path"]
|
|
33
|
+
*/
|
|
34
|
+
export function expandBraces(pattern: string, depth?: number, maxDepth?: number, options?: {
|
|
35
|
+
onMaxDepth?: Function | undefined;
|
|
36
|
+
}): string[];
|
|
37
|
+
/**
|
|
38
|
+
* Split brace alternatives on commas, respecting nested braces.
|
|
39
|
+
*
|
|
40
|
+
* @param {string} content - Content inside braces
|
|
41
|
+
* @returns {string[]} Array of alternatives
|
|
42
|
+
* @example
|
|
43
|
+
* splitBraceAlternatives("a,b,c"); // ["a", "b", "c"]
|
|
44
|
+
*/
|
|
45
|
+
export function splitBraceAlternatives(content: string): string[];
|
|
@@ -1,3 +1,112 @@
|
|
|
1
1
|
// AUTO-GENERATED by tools/build/build-typestubs.mjs — do not edit.
|
|
2
|
-
//
|
|
3
|
-
|
|
2
|
+
// Self-contained copy: this subpath is internal and not published by @cldmv/slothlet-types.
|
|
3
|
+
/**
|
|
4
|
+
* @Project: @cldmv/slothlet
|
|
5
|
+
* @Filename: /src/lib/helpers/platform.mjs
|
|
6
|
+
* @Date: 2026-05-29 22:02:43 -07:00 (1780117363)
|
|
7
|
+
* @Author: Nate Corcoran <CLDMV>
|
|
8
|
+
* @Email: <Shinrai@users.noreply.github.com>
|
|
9
|
+
* -----
|
|
10
|
+
* @Last modified by: Nate Corcoran <CLDMV> (Shinrai@users.noreply.github.com)
|
|
11
|
+
* @Last modified time: 2026-06-03 21:17:59 -07:00 (1780546679)
|
|
12
|
+
* -----
|
|
13
|
+
* @Copyright: Copyright (c) 2013-2026 Catalyzed Motivation Inc. All rights reserved.
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* @fileoverview Single source of truth for Node.js-vs-browser host differences.
|
|
17
|
+
* @module @cldmv/slothlet/helpers/platform
|
|
18
|
+
* @internal
|
|
19
|
+
*
|
|
20
|
+
* @description
|
|
21
|
+
* Slothlet runs in two hosts: Node.js (full filesystem access) and browser /
|
|
22
|
+
* Electron-renderer "browser mode" (no `node:*` builtins, manifest-based loading).
|
|
23
|
+
* Rather than scatter `typeof process` checks and gated `await import("node:*")`
|
|
24
|
+
* blocks across a dozen modules (#123), every host difference is decided ONCE here
|
|
25
|
+
* and the rest of the codebase imports the resolved builtins (or browser shims)
|
|
26
|
+
* plus `isNode` via plain static imports — no `node:*` specifier ever enters the
|
|
27
|
+
* static-import graph a browser must parse.
|
|
28
|
+
*
|
|
29
|
+
* The builtins are pulled in through a single top-level-await `import()` block
|
|
30
|
+
* guarded by `isNode`. In a browser the same exports resolve to `null` (for the
|
|
31
|
+
* Node-only ones, whose every call site is `isNode`-guarded) or to a minimal shim
|
|
32
|
+
* (`util`, which is consumed in both hosts for `inspect` / `types.isProxy`).
|
|
33
|
+
*
|
|
34
|
+
* Anything that genuinely cannot run outside Node and is never reachable from a
|
|
35
|
+
* browser module graph (TypeScript compilation, type generation, manifest
|
|
36
|
+
* generation) keeps its own direct `node:*` imports — routing those through here
|
|
37
|
+
* would only drag build-time-only builtins (`crypto`, `os`) into the shared hub.
|
|
38
|
+
*
|
|
39
|
+
* ## Browser-only branches & coverage (policy)
|
|
40
|
+
* The browser arms here — and in the modules that import `isNode` (the `else`/`: null` shims, the
|
|
41
|
+
* i18n browser paths, the live-mode null-ALS arm) — are UNREACHABLE under the Node coverage run:
|
|
42
|
+
* `process.versions.node` is always truthy there, even in the `platform:"browser"` node-side suites.
|
|
43
|
+
*
|
|
44
|
+
* They are now genuinely covered+counted by a **vitest browser-mode** run (real headless Chromium,
|
|
45
|
+
* Playwright provider — `.configs/vitest.browser.config.mjs`, `tests/browser/*.browser.test.mjs`).
|
|
46
|
+
* Because that run uses the SAME `@vitest/coverage-v8` provider over vite-transformed source as the
|
|
47
|
+
* node run, the two `coverage-final.json` maps align and merge cleanly
|
|
48
|
+
* (`tools/coverage/merge-browser-coverage.mjs`, wired as `npm run coverage:all`). An earlier merge was
|
|
49
|
+
* rejected, but that was of the raw-source Playwright *smoke* (`npm run test:browser`), whose importmap
|
|
50
|
+
* serves raw `src/` — those maps don't align with node's. The vitest-browser run does, which is what
|
|
51
|
+
* makes the merge correct. Only arms unreachable in BOTH hosts (e.g. an exotic non-Node host with no
|
|
52
|
+
* `process`/`navigator`) keep a precise v8 ignore-next comment. The smoke remains as a raw-importmap
|
|
53
|
+
* load check (the path a real consumer uses), not the coverage justification.
|
|
54
|
+
*/
|
|
55
|
+
export const isNode: boolean;
|
|
56
|
+
/**
|
|
57
|
+
* Resolved Node.js builtins (Node host) or browser shims / `null` (browser host).
|
|
58
|
+
*
|
|
59
|
+
* Each is initialized to `null` and reassigned to the real builtin inside the `isNode`
|
|
60
|
+
* block below; in a browser the Node-only ones stay `null` (every call site is
|
|
61
|
+
* `isNode`-guarded) and `util` becomes a minimal shim. Annotated `any` (not bare `null`,
|
|
62
|
+
* which would make a TS consumer treat them as non-callable, nor the precise
|
|
63
|
+
* `typeof import("node:*")` shape, which would force `@types/node` onto every consumer —
|
|
64
|
+
* including browser ones — and break the no-extra-types export contract). `any` keeps them
|
|
65
|
+
* usable from TS while the polymorphic real-module / shim / `null` behavior is documented here.
|
|
66
|
+
* @private
|
|
67
|
+
*/
|
|
68
|
+
/** @type {any} */
|
|
69
|
+
export let fs: any;
|
|
70
|
+
/** @type {any} */
|
|
71
|
+
export let fsp: any;
|
|
72
|
+
/** @type {any} */
|
|
73
|
+
export let path: any;
|
|
74
|
+
/** @type {any} */
|
|
75
|
+
export let url: any;
|
|
76
|
+
/** @type {any} */
|
|
77
|
+
export let util: any;
|
|
78
|
+
/** @type {any} */
|
|
79
|
+
export let EventEmitter: any;
|
|
80
|
+
/** @type {any} */
|
|
81
|
+
export let AsyncLocalStorage: any;
|
|
82
|
+
/** @type {any} */
|
|
83
|
+
export let AsyncResource: any;
|
|
84
|
+
/** @type {any} */
|
|
85
|
+
export let createRequire: any;
|
|
86
|
+
/**
|
|
87
|
+
* Load and parse JSON, branching on host — this is the single place that knows how each
|
|
88
|
+
* environment reads JSON.
|
|
89
|
+
*
|
|
90
|
+
* @description
|
|
91
|
+
* - **Node**: synchronous `fs.readFileSync` + parse. Returns the parsed object directly (or
|
|
92
|
+
* `null` on a read/parse failure). `ref` is a filesystem path or `file:` URL.
|
|
93
|
+
* - **Browser**: asynchronous dynamic `import(ref, { with: { type: "json" } })`. Returns a
|
|
94
|
+
* `Promise<object|null>` — a miss resolves to `null` (callers keep their bundled default;
|
|
95
|
+
* a failed import also surfaces a console error, which is harmless). `ref` is a module
|
|
96
|
+
* specifier resolvable via the page's importmap (e.g. `@cldmv/slothlet/i18n/language/es-mx.json`).
|
|
97
|
+
*
|
|
98
|
+
* The return type is therefore polymorphic by host: `object|null` in Node, `Promise<object|null>`
|
|
99
|
+
* in a browser. Callers that already branch on `isNode` consume the matching form directly;
|
|
100
|
+
* `await loadJson(...)` is safe in both (awaiting a non-promise is a no-op).
|
|
101
|
+
*
|
|
102
|
+
* @param {string} ref - Filesystem path / `file:` URL (Node) or importmap specifier (browser).
|
|
103
|
+
* @returns {object|null|Promise<object|null>} Parsed JSON (Node, sync) or a promise of it (browser).
|
|
104
|
+
* @internal
|
|
105
|
+
*
|
|
106
|
+
* @example
|
|
107
|
+
* // Node (sync):
|
|
108
|
+
* const pkg = loadJson(new URL("../../package.json", import.meta.url));
|
|
109
|
+
* // Browser (async):
|
|
110
|
+
* const es = await loadJson("@cldmv/slothlet/i18n/language/es-mx.json");
|
|
111
|
+
*/
|
|
112
|
+
export function loadJson(ref: string): object | null | Promise<object | null>;
|
|
@@ -1,3 +1,34 @@
|
|
|
1
1
|
// AUTO-GENERATED by tools/build/build-typestubs.mjs — do not edit.
|
|
2
|
-
//
|
|
3
|
-
|
|
2
|
+
// Self-contained copy: this subpath is internal and not published by @cldmv/slothlet-types.
|
|
3
|
+
/**
|
|
4
|
+
* Path resolver component
|
|
5
|
+
* @class Resolver
|
|
6
|
+
* @extends ComponentBase
|
|
7
|
+
* @package
|
|
8
|
+
*/
|
|
9
|
+
export class Resolver extends ComponentBase {
|
|
10
|
+
static slothletProperty: string;
|
|
11
|
+
/**
|
|
12
|
+
* Get V8 stack trace as CallSite array.
|
|
13
|
+
* @param {Function} [skipFn] - Optional function to skip from stack trace
|
|
14
|
+
* @returns {Array} Array of CallSite objects
|
|
15
|
+
* @public
|
|
16
|
+
*/
|
|
17
|
+
public getStack(skipFn?: Function): any[];
|
|
18
|
+
/**
|
|
19
|
+
* Convert file:// URL to filesystem path or return as-is.
|
|
20
|
+
* @param {any} v - Value to convert
|
|
21
|
+
* @returns {string|null} Filesystem path or null
|
|
22
|
+
* @public
|
|
23
|
+
*/
|
|
24
|
+
public toFsPath(v: any): string | null;
|
|
25
|
+
/**
|
|
26
|
+
* Resolve relative path from caller's context.
|
|
27
|
+
* @param {string} rel - Relative path to resolve
|
|
28
|
+
* @returns {string} Absolute filesystem path
|
|
29
|
+
* @public
|
|
30
|
+
*/
|
|
31
|
+
public resolvePathFromCaller(rel: string): string;
|
|
32
|
+
#private;
|
|
33
|
+
}
|
|
34
|
+
import { ComponentBase } from "#factories/component-base";
|
|
@@ -1,3 +1,24 @@
|
|
|
1
1
|
// AUTO-GENERATED by tools/build/build-typestubs.mjs — do not edit.
|
|
2
|
-
//
|
|
3
|
-
|
|
2
|
+
// Self-contained copy: this subpath is internal and not published by @cldmv/slothlet-types.
|
|
3
|
+
/**
|
|
4
|
+
* Pin deferred callbacks to the module that schedules them.
|
|
5
|
+
*
|
|
6
|
+
* Called once globally when the first instance is created; later calls are ignored, matching how
|
|
7
|
+
* EventEmitter patching behaves. 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 enableSchedulerPatching(): void;
|
|
14
|
+
/**
|
|
15
|
+
* Restore the original scheduler entry points.
|
|
16
|
+
*
|
|
17
|
+
* Restores an entry point only when the wrapper installed here is still the one in place. Anything
|
|
18
|
+
* that replaced a scheduler afterwards — a test runner's fake timers being the usual case — owns that
|
|
19
|
+
* slot and its own restore, and writing over it would strand the process on a stale function.
|
|
20
|
+
*
|
|
21
|
+
* @returns {void}
|
|
22
|
+
* @public
|
|
23
|
+
*/
|
|
24
|
+
export function disableSchedulerPatching(): void;
|