@digital-alchemy/core 26.1.9 → 26.5.1

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 (85) hide show
  1. package/CLAUDE.md +302 -0
  2. package/README.md +19 -3
  3. package/dist/helpers/async.d.mts +37 -0
  4. package/dist/helpers/async.mjs +50 -15
  5. package/dist/helpers/async.mjs.map +1 -1
  6. package/dist/helpers/config-environment-loader.d.mts +39 -0
  7. package/dist/helpers/config-environment-loader.mjs +51 -11
  8. package/dist/helpers/config-environment-loader.mjs.map +1 -1
  9. package/dist/helpers/config-file-loader.d.mts +66 -1
  10. package/dist/helpers/config-file-loader.mjs +82 -6
  11. package/dist/helpers/config-file-loader.mjs.map +1 -1
  12. package/dist/helpers/config.d.mts +202 -5
  13. package/dist/helpers/config.mjs +60 -0
  14. package/dist/helpers/config.mjs.map +1 -1
  15. package/dist/helpers/context.d.mts +12 -1
  16. package/dist/helpers/cron.d.mts +154 -7
  17. package/dist/helpers/cron.mjs +47 -4
  18. package/dist/helpers/cron.mjs.map +1 -1
  19. package/dist/helpers/errors.d.mts +45 -0
  20. package/dist/helpers/errors.mjs +45 -0
  21. package/dist/helpers/errors.mjs.map +1 -1
  22. package/dist/helpers/events.d.mts +23 -0
  23. package/dist/helpers/events.mjs +23 -0
  24. package/dist/helpers/events.mjs.map +1 -1
  25. package/dist/helpers/extend.d.mts +50 -0
  26. package/dist/helpers/extend.mjs +63 -0
  27. package/dist/helpers/extend.mjs.map +1 -1
  28. package/dist/helpers/index.d.mts +9 -0
  29. package/dist/helpers/index.mjs +9 -0
  30. package/dist/helpers/index.mjs.map +1 -1
  31. package/dist/helpers/lifecycle.d.mts +102 -16
  32. package/dist/helpers/lifecycle.mjs +19 -1
  33. package/dist/helpers/lifecycle.mjs.map +1 -1
  34. package/dist/helpers/logger.d.mts +178 -17
  35. package/dist/helpers/logger.mjs +41 -1
  36. package/dist/helpers/logger.mjs.map +1 -1
  37. package/dist/helpers/module.d.mts +110 -0
  38. package/dist/helpers/module.mjs +55 -6
  39. package/dist/helpers/module.mjs.map +1 -1
  40. package/dist/helpers/service-runner.d.mts +27 -1
  41. package/dist/helpers/service-runner.mjs +27 -1
  42. package/dist/helpers/service-runner.mjs.map +1 -1
  43. package/dist/helpers/utilities.d.mts +123 -3
  44. package/dist/helpers/utilities.mjs +110 -3
  45. package/dist/helpers/utilities.mjs.map +1 -1
  46. package/dist/helpers/wiring.d.mts +385 -0
  47. package/dist/helpers/wiring.mjs +120 -0
  48. package/dist/helpers/wiring.mjs.map +1 -1
  49. package/dist/services/als.service.d.mts +10 -0
  50. package/dist/services/als.service.mjs +49 -0
  51. package/dist/services/als.service.mjs.map +1 -1
  52. package/dist/services/configuration.service.d.mts +22 -0
  53. package/dist/services/configuration.service.mjs +140 -12
  54. package/dist/services/configuration.service.mjs.map +1 -1
  55. package/dist/services/index.d.mts +8 -0
  56. package/dist/services/index.mjs +8 -0
  57. package/dist/services/index.mjs.map +1 -1
  58. package/dist/services/internal.service.d.mts +98 -19
  59. package/dist/services/internal.service.mjs +91 -9
  60. package/dist/services/internal.service.mjs.map +1 -1
  61. package/dist/services/is.service.d.mts +64 -4
  62. package/dist/services/is.service.mjs +67 -4
  63. package/dist/services/is.service.mjs.map +1 -1
  64. package/dist/services/lifecycle.service.d.mts +26 -0
  65. package/dist/services/lifecycle.service.mjs +67 -9
  66. package/dist/services/lifecycle.service.mjs.map +1 -1
  67. package/dist/services/logger.service.d.mts +27 -0
  68. package/dist/services/logger.service.mjs +133 -9
  69. package/dist/services/logger.service.mjs.map +1 -1
  70. package/dist/services/scheduler.service.d.mts +19 -0
  71. package/dist/services/scheduler.service.mjs +87 -4
  72. package/dist/services/scheduler.service.mjs.map +1 -1
  73. package/dist/services/wiring.service.d.mts +29 -1
  74. package/dist/services/wiring.service.mjs +153 -20
  75. package/dist/services/wiring.service.mjs.map +1 -1
  76. package/dist/testing/index.d.mts +4 -0
  77. package/dist/testing/index.mjs +4 -0
  78. package/dist/testing/index.mjs.map +1 -1
  79. package/dist/testing/mock-logger.d.mts +8 -0
  80. package/dist/testing/mock-logger.mjs +9 -0
  81. package/dist/testing/mock-logger.mjs.map +1 -1
  82. package/dist/testing/test-module.d.mts +107 -27
  83. package/dist/testing/test-module.mjs +58 -1
  84. package/dist/testing/test-module.mjs.map +1 -1
  85. package/package.json +33 -31
@@ -1,23 +1,63 @@
1
+ /**
2
+ * Logger interface and configuration — dual-arity log methods, color schemes,
3
+ * and a last-resort stderr writer.
4
+ *
5
+ * @remarks
6
+ * The logger supports six severity levels (trace, debug, info, warn, error, fatal)
7
+ * and dual-arity calls: `logger.info("message")` or `logger.info({ context, id }, "message")`.
8
+ * The logger service wraps this interface with chalk/stdout formatting, ALS
9
+ * integration, and LOG_LEVEL filtering. `fatalLog` is the last-resort writer for
10
+ * fatal conditions that cannot use the logger (e.g., during bootstrap failure).
11
+ */
1
12
  import fs from "node:fs";
2
13
  import { is, SINGLE } from "../index.mjs";
14
+ /**
15
+ * Mapping from log level to console color for pretty-printed output.
16
+ */
3
17
  export const METHOD_COLORS = new Map([
4
18
  ["trace", "grey"],
5
19
  ["debug", "blue"],
20
+ ["info", "green"],
6
21
  ["warn", "yellow"],
7
22
  ["error", "red"],
8
- ["info", "green"],
9
23
  ["fatal", "magenta"],
10
24
  ]);
25
+ /**
26
+ * Event name for log level configuration updates.
27
+ *
28
+ * @internal
29
+ */
11
30
  export const EVENT_UPDATE_LOG_LEVELS = "EVENT_UPDATE_LOG_LEVELS";
31
+ /**
32
+ * Last-resort logger for fatal conditions that cannot use the normal logger.
33
+ *
34
+ * @remarks
35
+ * Writes directly to `stderr` bypassing the logger service. Use only when the
36
+ * logger is not available (e.g., during bootstrap failure before services are
37
+ * wired). If `data` is an Error, extracts and formats `name`, `cause`, `message`,
38
+ * and stack trace; otherwise, JSON-stringifies it. Always adds a trailing newline.
39
+ *
40
+ * @example
41
+ * ```typescript
42
+ * try {
43
+ * await bootstrap();
44
+ * } catch (error) {
45
+ * fatalLog("bootstrap failed", error);
46
+ * process.exit(1);
47
+ * }
48
+ * ```
49
+ */
12
50
  export function fatalLog(message, data) {
13
51
  if (data) {
14
52
  if (data instanceof Error) {
53
+ // extract structured error fields with fallback defaults
15
54
  const cause = is.string(data?.cause) && !is.empty(data?.cause) ? ` - ${data.cause}` : "";
16
55
  const stack = data.stack ? `\n` + data.stack.split("\n").slice(SINGLE).join("\n") : ``;
17
56
  const errorOutput = `${data.name || "Error"}${cause}: ${data.message || "Unknown error"}${stack}`;
18
57
  message = [message, errorOutput].join("\n");
19
58
  }
20
59
  else {
60
+ // pretty-print non-error data
21
61
  message = [message, JSON.stringify(data, undefined, " ")].join("\n");
22
62
  }
23
63
  }
@@ -1 +1 @@
1
- {"version":3,"file":"logger.mjs","sourceRoot":"","sources":["../../src/helpers/logger.mts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AAIzB,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AA+E1C,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,GAAG,CAAgC;IAClE,CAAC,OAAO,EAAE,MAAM,CAAC;IACjB,CAAC,OAAO,EAAE,MAAM,CAAC;IACjB,CAAC,MAAM,EAAE,QAAQ,CAAC;IAClB,CAAC,OAAO,EAAE,KAAK,CAAC;IAChB,CAAC,MAAM,EAAE,OAAO,CAAC;IACjB,CAAC,OAAO,EAAE,SAAS,CAAC;CACrB,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,uBAAuB,GAAG,yBAAyB,CAAC;AAEjE,MAAM,UAAU,QAAQ,CAAC,OAAe,EAAE,IAAc;IACtD,IAAI,IAAI,EAAE,CAAC;QACT,IAAI,IAAI,YAAY,KAAK,EAAE,CAAC;YAC1B,MAAM,KAAK,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACzF,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACvF,MAAM,WAAW,GAAG,GAAG,IAAI,CAAC,IAAI,IAAI,OAAO,GAAG,KAAK,KAAK,IAAI,CAAC,OAAO,IAAI,eAAe,GAAG,KAAK,EAAE,CAAC;YAClG,OAAO,GAAG,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC9C,CAAC;aAAM,CAAC;YACN,OAAO,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACxE,CAAC;IACH,CAAC;IACD,EAAE,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,GAAG,OAAO,IAAI,CAAC,CAAC;AAClD,CAAC"}
1
+ {"version":3,"file":"logger.mjs","sourceRoot":"","sources":["../../src/helpers/logger.mts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,MAAM,SAAS,CAAC;AAIzB,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAqN1C;;GAEG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,GAAG,CAAgC;IAClE,CAAC,OAAO,EAAE,MAAM,CAAC;IACjB,CAAC,OAAO,EAAE,MAAM,CAAC;IACjB,CAAC,MAAM,EAAE,OAAO,CAAC;IACjB,CAAC,MAAM,EAAE,QAAQ,CAAC;IAClB,CAAC,OAAO,EAAE,KAAK,CAAC;IAChB,CAAC,OAAO,EAAE,SAAS,CAAC;CACrB,CAAC,CAAC;AAOH;;;;GAIG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,yBAAyB,CAAC;AAEjE;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,QAAQ,CAAC,OAAe,EAAE,IAAc;IACtD,IAAI,IAAI,EAAE,CAAC;QACT,IAAI,IAAI,YAAY,KAAK,EAAE,CAAC;YAC1B,yDAAyD;YACzD,MAAM,KAAK,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACzF,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACvF,MAAM,WAAW,GAAG,GAAG,IAAI,CAAC,IAAI,IAAI,OAAO,GAAG,KAAK,KAAK,IAAI,CAAC,OAAO,IAAI,eAAe,GAAG,KAAK,EAAE,CAAC;YAClG,OAAO,GAAG,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC9C,CAAC;aAAM,CAAC;YACN,8BAA8B;YAC9B,OAAO,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACxE,CAAC;IACH,CAAC;IACD,EAAE,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,GAAG,OAAO,IAAI,CAAC,CAAC;AAClD,CAAC"}
@@ -2,13 +2,31 @@ import type { Except, Merge } from "type-fest";
2
2
  import type { iTestRunner } from "../index.mts";
3
3
  import type { OptionalModuleConfiguration } from "./config.mts";
4
4
  import type { ApplicationDefinition, LibraryDefinition, ServiceFunction, ServiceMap, TLibrary } from "./wiring.mts";
5
+ /**
6
+ * Options that control how {@link DigitalAlchemyModule.extend} behaves when
7
+ * forking a module into a modified copy.
8
+ */
5
9
  export type ExtendOptions = {
10
+ /** Override the name given to the extended module. */
6
11
  name?: string;
7
12
  /**
8
13
  * default: true
9
14
  */
10
15
  keepConfiguration?: boolean;
11
16
  };
17
+ /**
18
+ * Intermediate representation of a Digital Alchemy module before it is
19
+ * committed to a concrete form (library, application, or test runner).
20
+ *
21
+ * @remarks
22
+ * A `DigitalAlchemyModule` holds the full set of services and configuration
23
+ * that would be passed to `CreateLibrary` or `CreateApplication`, but defers
24
+ * that commitment so callers can compose and mutate before export.
25
+ *
26
+ * Call `.extend()` to obtain a {@link ModuleExtension} builder, then chain
27
+ * mutations before finalising with `.toLibrary()`, `.toApplication()`, or
28
+ * `.toTest()`.
29
+ */
12
30
  export type DigitalAlchemyModule<S extends ServiceMap, C extends OptionalModuleConfiguration> = {
13
31
  services: S;
14
32
  configuration: C;
@@ -18,6 +36,14 @@ export type DigitalAlchemyModule<S extends ServiceMap, C extends OptionalModuleC
18
36
  priorityInit: string[];
19
37
  extend: (options?: ExtendOptions) => ModuleExtension<S, C>;
20
38
  };
39
+ /**
40
+ * Input shape required to construct a {@link DigitalAlchemyModule}.
41
+ *
42
+ * @remarks
43
+ * Mirrors `LibraryConfigurationOptions` but without the `type` discriminant or
44
+ * the runtime wiring symbol — those are added by `CreateLibrary` /
45
+ * `CreateApplication` at export time.
46
+ */
21
47
  export type CreateModuleOptions<S extends ServiceMap, C extends OptionalModuleConfiguration> = {
22
48
  services: S;
23
49
  configuration: C;
@@ -27,46 +53,130 @@ export type CreateModuleOptions<S extends ServiceMap, C extends OptionalModuleCo
27
53
  priorityInit: string[];
28
54
  };
29
55
  /**
56
+ * Chainable builder returned by {@link DigitalAlchemyModule.extend}.
57
+ *
58
+ * @remarks
59
+ * Each mutation method returns the same `ModuleExtension` instance (or a
60
+ * narrowed variant of it), enabling fluent composition. The builder holds
61
+ * mutable references to the service map and dependency list; calling any
62
+ * terminal method (`.toLibrary()`, `.toApplication()`, `.toTest()`) reads the
63
+ * current state and produces an immutable definition.
64
+ *
65
+ * **Method categories:**
66
+ * - *Dependency mutations:* `appendLibrary`, `replaceLibrary`
67
+ * - *Service mutations:* `appendService`, `replaceService`, `pickService`,
68
+ * `omitService`, `rebuild`
69
+ * - *Terminal exports:* `toApplication`, `toLibrary`, `toTest`
70
+ *
30
71
  * commands mutate module
31
72
  */
32
73
  export type ModuleExtension<S extends ServiceMap, C extends OptionalModuleConfiguration> = {
74
+ /**
75
+ * Add a new library dependency not present in the base module.
76
+ *
77
+ * @remarks
78
+ * Throws if the library name is already appended or exists in the base
79
+ * `depends` list — use `replaceLibrary` in that case.
80
+ */
33
81
  appendLibrary: (library: TLibrary) => ModuleExtension<S, C>;
82
+ /**
83
+ * Inject an additional service that is not declared in the base module.
84
+ *
85
+ * @remarks
86
+ * Throws if a service with the same name already exists — use
87
+ * `replaceService` in that case.
88
+ */
34
89
  appendService: (name: string, target: ServiceFunction) => ModuleExtension<S, C>;
35
90
  /**
91
+ * Swap a library dependency by name.
92
+ *
36
93
  * name must match existing library
37
94
  */
38
95
  replaceLibrary: (library: TLibrary) => ModuleExtension<S, C>;
39
96
  /**
97
+ * Swap an existing service implementation while keeping the same key.
98
+ *
99
+ * @remarks
100
+ * The return type is narrowed to reflect the new function's signature.
101
+ * Throws if `name` does not exist in the current service map.
102
+ *
40
103
  * name must match existing service
41
104
  */
42
105
  replaceService: <TARGET extends keyof S, FN extends ServiceFunction>(name: TARGET, target: FN) => ModuleExtension<Merge<S, {
43
106
  [key in TARGET]: FN;
44
107
  }>, C>;
45
108
  /**
109
+ * Reduce the service map to only the named services.
110
+ *
111
+ * @remarks
112
+ * Throws if any supplied name does not exist in the current service map.
113
+ *
46
114
  * throws if any service does not exist
47
115
  */
48
116
  pickService: <PICK extends keyof S>(...services: PICK[]) => ModuleExtension<Pick<S, PICK>, C>;
49
117
  /**
118
+ * Remove specific services from the service map.
119
+ *
120
+ * @remarks
121
+ * Throws if any supplied name does not exist in the current service map.
122
+ *
50
123
  * throws if any service does not exist
51
124
  */
52
125
  omitService: <OMIT extends keyof S>(...services: OMIT[]) => ModuleExtension<Except<S, OMIT>, C>;
53
126
  /**
127
+ * Replace the entire service map with a new set.
128
+ *
129
+ * @remarks
130
+ * `services` must extend `S` (i.e., it must be API-compatible with the
131
+ * original map). Use when rebuilding several services at once.
132
+ *
54
133
  * build api compatible replacement (potentially adding)
55
134
  */
56
135
  rebuild: <REPLACEMENTS extends S>(services: Partial<REPLACEMENTS>) => ModuleExtension<REPLACEMENTS, C>;
57
136
  /**
137
+ * Finalise as an {@link ApplicationDefinition} for use with `bootstrap`.
138
+ *
58
139
  * export as application
59
140
  */
60
141
  toApplication: () => ApplicationDefinition<S, C>;
61
142
  /**
143
+ * Finalise as a {@link LibraryDefinition} for use as a dependency.
144
+ *
62
145
  * export as library
63
146
  */
64
147
  toLibrary: () => LibraryDefinition<S, C>;
65
148
  /**
149
+ * Finalise as an `iTestRunner` for use in vitest specs.
150
+ *
151
+ * @remarks
152
+ * Internally calls `.toApplication()` and wraps the result in a `TestRunner`.
153
+ * Prefer `.toTest()` in spec files over manually constructing both.
154
+ *
66
155
  * export as test
67
156
  */
68
157
  toTest: () => iTestRunner<S, C>;
69
158
  };
159
+ /**
160
+ * Construct a new {@link DigitalAlchemyModule} from a raw options object.
161
+ *
162
+ * @remarks
163
+ * `createModule` is the entry point for the chainable module pattern. It
164
+ * captures the options into a working module object and exposes `.extend()` to
165
+ * begin the mutation chain. No library or application definition is produced
166
+ * until a terminal method is called on the resulting {@link ModuleExtension}.
167
+ *
168
+ * Use the static helpers `createModule.fromApplication` and
169
+ * `createModule.fromLibrary` to seed the builder from an existing definition
170
+ * instead of building from scratch.
171
+ *
172
+ * Typical call sequence:
173
+ * ```typescript
174
+ * createModule({ name: "my-lib", services, configuration, depends: [], priorityInit: [] })
175
+ * .extend()
176
+ * .appendLibrary(someLibrary)
177
+ * .toLibrary();
178
+ * ```
179
+ */
70
180
  export declare function createModule<S extends ServiceMap, C extends OptionalModuleConfiguration>(options: CreateModuleOptions<S, C>): DigitalAlchemyModule<S, C>;
71
181
  export declare namespace createModule {
72
182
  var fromApplication: <S extends ServiceMap, C extends OptionalModuleConfiguration>(application: ApplicationDefinition<S, C>) => DigitalAlchemyModule<S, C>;
@@ -1,7 +1,32 @@
1
1
  import { CreateApplication, TestRunner } from "../index.mjs";
2
+ import { BootstrapException } from "./errors.mjs";
2
3
  import { deepExtend } from "./extend.mjs";
3
4
  import { CreateLibrary } from "./wiring.mjs";
4
- // #MARK: createModule
5
+ // pure-helper file has no TServiceParams; tag bootstrap errors with a stable
6
+ // module-scoped context so consumers can identify the origin in stack traces
7
+ const MODULE_CONTEXT = "digital-alchemy:module";
8
+ // --- createModule factory -----------------------------------------------------
9
+ /**
10
+ * Construct a new {@link DigitalAlchemyModule} from a raw options object.
11
+ *
12
+ * @remarks
13
+ * `createModule` is the entry point for the chainable module pattern. It
14
+ * captures the options into a working module object and exposes `.extend()` to
15
+ * begin the mutation chain. No library or application definition is produced
16
+ * until a terminal method is called on the resulting {@link ModuleExtension}.
17
+ *
18
+ * Use the static helpers `createModule.fromApplication` and
19
+ * `createModule.fromLibrary` to seed the builder from an existing definition
20
+ * instead of building from scratch.
21
+ *
22
+ * Typical call sequence:
23
+ * ```typescript
24
+ * createModule({ name: "my-lib", services, configuration, depends: [], priorityInit: [] })
25
+ * .extend()
26
+ * .appendLibrary(someLibrary)
27
+ * .toLibrary();
28
+ * ```
29
+ */
5
30
  export function createModule(options) {
6
31
  function extend(extendOptions) {
7
32
  const appendLibrary = new Map();
@@ -10,18 +35,20 @@ export function createModule(options) {
10
35
  appendLibrary: (library) => {
11
36
  const name = library.name;
12
37
  if (appendLibrary.has(name)) {
13
- throw new Error(`${name} already is appended`);
38
+ throw new BootstrapException(MODULE_CONTEXT, "LIBRARY_ALREADY_APPENDED", `${name} already is appended`);
14
39
  }
15
40
  const exists = workingModule.depends.some(i => i.name === name);
16
41
  if (exists) {
17
- throw new Error(`${name} exists as a library in base, use replaceLibrary`);
42
+ // base depends list owns this name; callers must use replaceLibrary to swap it
43
+ throw new BootstrapException(MODULE_CONTEXT, "LIBRARY_USE_REPLACE", `${name} exists as a library in base, use replaceLibrary`);
18
44
  }
19
45
  appendLibrary.set(name, library);
20
46
  return extend;
21
47
  },
22
48
  appendService: (name, service) => {
23
49
  if (name in services) {
24
- throw new Error(`${name} exists as a service in base, use replaceService`);
50
+ // service already registered; callers must explicitly opt into replacement
51
+ throw new BootstrapException(MODULE_CONTEXT, "SERVICE_USE_REPLACE", `${name} exists as a service in base, use replaceService`);
25
52
  }
26
53
  // @ts-expect-error the interface makes this type properly, idc
27
54
  services[name] = service;
@@ -42,12 +69,14 @@ export function createModule(options) {
42
69
  replaceLibrary: (library) => {
43
70
  const name = library.name;
44
71
  if (appendLibrary.has(name)) {
72
+ // already in the appended set — replace in-place
45
73
  appendLibrary.set(name, library);
46
74
  }
47
75
  else {
48
76
  const exists = workingModule.depends.some(i => i.name === name);
49
77
  if (!exists) {
50
- throw new Error(`${name} does not exist in module yet`);
78
+ // neither appended nor in base depends; require explicit append first
79
+ throw new BootstrapException(MODULE_CONTEXT, "LIBRARY_NOT_FOUND", `${name} does not exist in module yet`);
51
80
  }
52
81
  appendLibrary.set(name, library);
53
82
  }
@@ -56,13 +85,14 @@ export function createModule(options) {
56
85
  // @ts-expect-error I don't care
57
86
  replaceService: (name, target) => {
58
87
  if (!(name in services)) {
59
- throw new Error(`${String(name)} does not exist to replace`);
88
+ throw new BootstrapException(MODULE_CONTEXT, "SERVICE_NOT_FOUND", `${String(name)} does not exist to replace`);
60
89
  }
61
90
  // @ts-expect-error I don't care
62
91
  services[name] = target;
63
92
  return extend;
64
93
  },
65
94
  toApplication: () => {
95
+ // merge base depends and appended libraries; appended wins on name collision
66
96
  const depends = {};
67
97
  workingModule.depends?.forEach(i => (depends[i.name] = i));
68
98
  appendLibrary.forEach((value, key) => (depends[key] = value));
@@ -77,6 +107,7 @@ export function createModule(options) {
77
107
  });
78
108
  },
79
109
  toLibrary: () => {
110
+ // same merge logic as toApplication; both export forms share the same dependency union
80
111
  const depends = {};
81
112
  workingModule.depends?.forEach(i => (depends[i.name] = i));
82
113
  appendLibrary.forEach((value, key) => (depends[key] = value));
@@ -108,6 +139,16 @@ export function createModule(options) {
108
139
  };
109
140
  return workingModule;
110
141
  }
142
+ // --- Static helpers on createModule -------------------------------------------
143
+ /**
144
+ * Seed a {@link DigitalAlchemyModule} from an existing
145
+ * {@link ApplicationDefinition}.
146
+ *
147
+ * @remarks
148
+ * Copies services, configuration, libraries, and `priorityInit` into the
149
+ * intermediate module shape so callers can fork and modify an application
150
+ * without reconstructing it from scratch.
151
+ */
111
152
  // #MARK: fromApplication
112
153
  createModule.fromApplication = (application) => {
113
154
  return createModule({
@@ -119,6 +160,14 @@ createModule.fromApplication = (application) => {
119
160
  services: application.services,
120
161
  });
121
162
  };
163
+ /**
164
+ * Seed a {@link DigitalAlchemyModule} from an existing
165
+ * {@link LibraryDefinition}.
166
+ *
167
+ * @remarks
168
+ * Mirrors `fromApplication` but for library definitions, preserving
169
+ * `optionalDepends` which applications do not carry.
170
+ */
122
171
  // #MARK: fromLibrary
123
172
  createModule.fromLibrary = (library) => {
124
173
  return createModule({
@@ -1 +1 @@
1
- {"version":3,"file":"module.mjs","sourceRoot":"","sources":["../../src/helpers/module.mts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"module.mjs","sourceRoot":"","sources":["../../src/helpers/module.mts"],"names":[],"mappings":"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"}
@@ -1,3 +1,13 @@
1
+ /**
2
+ * Minimal single-service bootstrap helper for scripts and one-off operations.
3
+ *
4
+ * @remarks
5
+ * `ServiceRunner` creates a complete DI graph for a single service, handling
6
+ * all wiring, lifecycle, and teardown. It is useful for scripts that need
7
+ * access to the full framework without building an application. The service
8
+ * function receives the same `TServiceParams` as a normal service, allowing
9
+ * access to config, logger, scheduler, and other boilerplate.
10
+ */
1
11
  import type { OptionalModuleConfiguration } from "./config.mts";
2
12
  import type { ApplicationConfigurationOptions, BootstrapOptions, ConfigTypes, ServiceMap, TInjectedConfig, TServiceParams } from "./wiring.mts";
3
13
  type ServiceRunnerConfiguration<C extends OptionalModuleConfiguration, NAME extends string> = Omit<ApplicationConfigurationOptions<ServiceMap, C>, "services" | "name" | "priorityInit"> & {
@@ -7,7 +17,23 @@ type LocalServiceParams<C extends OptionalModuleConfiguration, NAME extends stri
7
17
  config: TInjectedConfig & Record<NAME, ConfigTypes<C>>;
8
18
  };
9
19
  /**
10
- * Type safe way to kick off a mini service / script
20
+ * Bootstrap and run a single typed service with full framework support.
21
+ *
22
+ * @remarks
23
+ * Creates an application with a single service, invokes its bootstrap lifecycle,
24
+ * and returns when the service completes. The service runs synchronously within
25
+ * the context of a fully-initialized DI graph, with access to all boilerplate
26
+ * services (logger, scheduler, lifecycle, config, etc.).
27
+ *
28
+ * @example
29
+ * ```typescript
30
+ * await ServiceRunner(
31
+ * { configuration: { myLib: {...} } },
32
+ * ({ logger, config }) => {
33
+ * logger.info("running with config:", config.myLib);
34
+ * }
35
+ * );
36
+ * ```
11
37
  */
12
38
  export declare function ServiceRunner<C extends OptionalModuleConfiguration, NAME extends string = "dynamic">({ bootstrap, ...config }: ServiceRunnerConfiguration<C, NAME> & {
13
39
  bootstrap?: BootstrapOptions;
@@ -1,6 +1,32 @@
1
+ /**
2
+ * Minimal single-service bootstrap helper for scripts and one-off operations.
3
+ *
4
+ * @remarks
5
+ * `ServiceRunner` creates a complete DI graph for a single service, handling
6
+ * all wiring, lifecycle, and teardown. It is useful for scripts that need
7
+ * access to the full framework without building an application. The service
8
+ * function receives the same `TServiceParams` as a normal service, allowing
9
+ * access to config, logger, scheduler, and other boilerplate.
10
+ */
1
11
  import { CreateApplication } from "../index.mjs";
2
12
  /**
3
- * Type safe way to kick off a mini service / script
13
+ * Bootstrap and run a single typed service with full framework support.
14
+ *
15
+ * @remarks
16
+ * Creates an application with a single service, invokes its bootstrap lifecycle,
17
+ * and returns when the service completes. The service runs synchronously within
18
+ * the context of a fully-initialized DI graph, with access to all boilerplate
19
+ * services (logger, scheduler, lifecycle, config, etc.).
20
+ *
21
+ * @example
22
+ * ```typescript
23
+ * await ServiceRunner(
24
+ * { configuration: { myLib: {...} } },
25
+ * ({ logger, config }) => {
26
+ * logger.info("running with config:", config.myLib);
27
+ * }
28
+ * );
29
+ * ```
4
30
  */
5
31
  export async function ServiceRunner({ bootstrap, ...config }, service) {
6
32
  await CreateApplication({
@@ -1 +1 @@
1
- {"version":3,"file":"service-runner.mjs","sourceRoot":"","sources":["../../src/helpers/service-runner.mts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAwBjD;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAIjC,EAAE,SAAS,EAAE,GAAG,MAAM,EAA0E,EAChG,OAAsE;IAEtE,MAAM,iBAAiB,CAAC;QACtB,0DAA0D;QAC1D,IAAI,EAAE,SAAS;QACf,oCAAoC;QACpC,GAAG,MAAM;QACT,QAAQ,EAAE;YACR,OAAO,EAAE,OAA0B;SACpC;KACF,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;AAC1B,CAAC"}
1
+ {"version":3,"file":"service-runner.mjs","sourceRoot":"","sources":["../../src/helpers/service-runner.mts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAwBjD;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAIjC,EAAE,SAAS,EAAE,GAAG,MAAM,EAA0E,EAChG,OAAsE;IAEtE,MAAM,iBAAiB,CAAC;QACtB,0DAA0D;QAC1D,IAAI,EAAE,SAAS;QACf,oCAAoC;QACpC,GAAG,MAAM;QACT,QAAQ,EAAE;YACR,OAAO,EAAE,OAA0B;SACpC;KACF,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;AAC1B,CAAC"}