@cldmv/slothlet 3.15.2 → 3.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/README.md +8 -6
  2. package/dist/lib/builders/api-assignment.mjs +1 -1
  3. package/dist/lib/builders/api_builder.mjs +1 -1
  4. package/dist/lib/builders/builder.mjs +1 -1
  5. package/dist/lib/builders/modes-processor.mjs +1 -1
  6. package/dist/lib/handlers/api-cache-manager.mjs +1 -1
  7. package/dist/lib/handlers/api-manager.mjs +1 -1
  8. package/dist/lib/handlers/hook-manager.mjs +1 -1
  9. package/dist/lib/handlers/module-manager.mjs +1 -1
  10. package/dist/lib/handlers/ownership.mjs +1 -1
  11. package/dist/lib/handlers/routine-manager.mjs +17 -0
  12. package/dist/lib/handlers/unified-wrapper.mjs +1 -1
  13. package/dist/lib/helpers/config.mjs +1 -1
  14. package/dist/lib/helpers/defaults.mjs +17 -0
  15. package/dist/lib/helpers/eventtarget-property-context.mjs +17 -0
  16. package/dist/lib/helpers/observer-context.mjs +17 -0
  17. package/dist/lib/helpers/scheduler-context.mjs +1 -1
  18. package/dist/lib/i18n/languages/en-us.json +2 -0
  19. package/dist/lib/modes/eager.mjs +1 -1
  20. package/dist/lib/modes/lazy.mjs +1 -1
  21. package/dist/lib/processors/flatten.mjs +1 -1
  22. package/dist/lib/processors/loader.mjs +1 -1
  23. package/dist/slothlet.mjs +1 -1
  24. package/index.cjs +20 -0
  25. package/index.mjs +14 -0
  26. package/package.json +8 -7
  27. package/types/stub/devcheck.d.mts +1 -1
  28. package/types/stub/lib/builders/api-assignment.d.mts +130 -2
  29. package/types/stub/lib/builders/api_builder.d.mts +109 -2
  30. package/types/stub/lib/builders/builder.d.mts +87 -2
  31. package/types/stub/lib/builders/modes-processor.d.mts +71 -2
  32. package/types/stub/lib/factories/component-base.d.mts +177 -0
  33. package/types/stub/lib/helpers/caller-pinning.d.mts +22 -2
  34. package/types/stub/lib/helpers/class-instance-wrapper.d.mts +58 -2
  35. package/types/stub/lib/helpers/config.d.mts +321 -2
  36. package/types/stub/lib/helpers/defaults.d.mts +42 -0
  37. package/types/stub/lib/helpers/eventemitter-context.d.mts +31 -2
  38. package/types/stub/lib/helpers/eventtarget-context.d.mts +21 -2
  39. package/types/stub/lib/helpers/eventtarget-property-context.d.mts +23 -0
  40. package/types/stub/lib/helpers/generate-manifest.d.mts +180 -2
  41. package/types/stub/lib/helpers/hint-detector.d.mts +27 -2
  42. package/types/stub/lib/helpers/manifest-resolver.d.mts +101 -2
  43. package/types/stub/lib/helpers/modes-utils.d.mts +35 -2
  44. package/types/stub/lib/helpers/module-discovery.d.mts +81 -2
  45. package/types/stub/lib/helpers/module-manifest-validator.d.mts +37 -2
  46. package/types/stub/lib/helpers/module-sort.d.mts +65 -2
  47. package/types/stub/lib/helpers/observer-context.d.mts +23 -0
  48. package/types/stub/lib/helpers/pattern-matcher.d.mts +44 -2
  49. package/types/stub/lib/helpers/platform.d.mts +111 -2
  50. package/types/stub/lib/helpers/resolve-from-caller.d.mts +33 -2
  51. package/types/stub/lib/helpers/scheduler-context.d.mts +23 -2
  52. package/types/stub/lib/helpers/utilities.d.mts +57 -2
  53. package/types/stub/lib/i18n/translations.d.mts +52 -2
  54. package/types/stub/lib/modes/eager.d.mts +56 -2
  55. package/types/stub/lib/modes/lazy.d.mts +67 -2
  56. package/types/stub/lib/processors/flatten.d.mts +123 -2
  57. package/types/stub/lib/processors/loader.d.mts +83 -2
  58. package/types/stub/lib/processors/type-generator.d.mts +19 -2
  59. package/types/stub/lib/processors/typescript.d.mts +174 -2
  60. package/types/stub/lib/runtime/runtime-asynclocalstorage.d.mts +72 -2
  61. 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
- // Re-exports the real declarations from @cldmv/slothlet-types (install it for TypeScript support).
3
- export * from "@cldmv/slothlet-types/helpers/hint-detector";
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
- // Re-exports the real declarations from @cldmv/slothlet-types (install it for TypeScript support).
3
- export * from "@cldmv/slothlet-types/helpers/manifest-resolver";
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
- // Re-exports the real declarations from @cldmv/slothlet-types (install it for TypeScript support).
3
- export * from "@cldmv/slothlet-types/helpers/modes-utils";
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
- // Re-exports the real declarations from @cldmv/slothlet-types (install it for TypeScript support).
3
- export * from "@cldmv/slothlet-types/helpers/module-discovery";
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
- // Re-exports the real declarations from @cldmv/slothlet-types (install it for TypeScript support).
3
- export * from "@cldmv/slothlet-types/helpers/module-manifest-validator";
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
- // Re-exports the real declarations from @cldmv/slothlet-types (install it for TypeScript support).
3
- export * from "@cldmv/slothlet-types/helpers/module-sort";
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
- // Re-exports the real declarations from @cldmv/slothlet-types (install it for TypeScript support).
3
- export * from "@cldmv/slothlet-types/helpers/pattern-matcher";
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
- // Re-exports the real declarations from @cldmv/slothlet-types (install it for TypeScript support).
3
- export * from "@cldmv/slothlet-types/helpers/platform";
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
- // Re-exports the real declarations from @cldmv/slothlet-types (install it for TypeScript support).
3
- export * from "@cldmv/slothlet-types/helpers/resolve-from-caller";
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
- // Re-exports the real declarations from @cldmv/slothlet-types (install it for TypeScript support).
3
- export * from "@cldmv/slothlet-types/helpers/scheduler-context";
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;