@composurecdk/core 0.7.0 → 0.8.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 (92) hide show
  1. package/dist/commonjs/builder.d.ts.map +1 -0
  2. package/dist/commonjs/builder.js +86 -0
  3. package/dist/commonjs/builder.js.map +1 -0
  4. package/dist/commonjs/compose.d.ts.map +1 -0
  5. package/dist/commonjs/compose.js +114 -0
  6. package/dist/commonjs/compose.js.map +1 -0
  7. package/dist/commonjs/construct-id.d.ts.map +1 -0
  8. package/dist/commonjs/construct-id.js +58 -0
  9. package/dist/commonjs/construct-id.js.map +1 -0
  10. package/dist/commonjs/cyclic-dependency-error.d.ts.map +1 -0
  11. package/dist/commonjs/cyclic-dependency-error.js +20 -0
  12. package/dist/commonjs/cyclic-dependency-error.js.map +1 -0
  13. package/dist/commonjs/index.d.ts.map +1 -0
  14. package/dist/commonjs/index.js +22 -0
  15. package/dist/commonjs/index.js.map +1 -0
  16. package/dist/commonjs/lifecycle.d.ts.map +1 -0
  17. package/dist/commonjs/lifecycle.js +3 -0
  18. package/dist/{lifecycle.js.map → commonjs/lifecycle.js.map} +1 -1
  19. package/dist/commonjs/package.json +3 -0
  20. package/dist/{ref.d.ts → commonjs/ref.d.ts} +16 -0
  21. package/dist/commonjs/ref.d.ts.map +1 -0
  22. package/dist/commonjs/ref.js +129 -0
  23. package/dist/commonjs/ref.js.map +1 -0
  24. package/dist/commonjs/stack-strategy.d.ts.map +1 -0
  25. package/dist/commonjs/stack-strategy.js +59 -0
  26. package/dist/commonjs/stack-strategy.js.map +1 -0
  27. package/dist/commonjs/testing.d.ts.map +1 -0
  28. package/dist/commonjs/testing.js +124 -0
  29. package/dist/commonjs/testing.js.map +1 -0
  30. package/dist/esm/builder.d.ts +103 -0
  31. package/dist/esm/builder.d.ts.map +1 -0
  32. package/dist/esm/builder.js.map +1 -0
  33. package/dist/esm/compose.d.ts +177 -0
  34. package/dist/esm/compose.d.ts.map +1 -0
  35. package/dist/esm/compose.js.map +1 -0
  36. package/dist/esm/construct-id.d.ts +45 -0
  37. package/dist/esm/construct-id.d.ts.map +1 -0
  38. package/dist/esm/construct-id.js.map +1 -0
  39. package/dist/esm/cyclic-dependency-error.d.ts +12 -0
  40. package/dist/esm/cyclic-dependency-error.d.ts.map +1 -0
  41. package/dist/esm/cyclic-dependency-error.js.map +1 -0
  42. package/dist/esm/index.d.ts +8 -0
  43. package/dist/esm/index.d.ts.map +1 -0
  44. package/dist/esm/index.js.map +1 -0
  45. package/dist/esm/lifecycle.d.ts +23 -0
  46. package/dist/esm/lifecycle.d.ts.map +1 -0
  47. package/dist/esm/lifecycle.js.map +1 -0
  48. package/dist/esm/package.json +3 -0
  49. package/dist/esm/ref.d.ts +133 -0
  50. package/dist/esm/ref.d.ts.map +1 -0
  51. package/dist/{ref.js → esm/ref.js} +17 -1
  52. package/dist/esm/ref.js.map +1 -0
  53. package/dist/esm/stack-strategy.d.ts +75 -0
  54. package/dist/esm/stack-strategy.d.ts.map +1 -0
  55. package/dist/esm/stack-strategy.js.map +1 -0
  56. package/dist/esm/testing.d.ts +71 -0
  57. package/dist/esm/testing.d.ts.map +1 -0
  58. package/dist/esm/testing.js.map +1 -0
  59. package/package.json +42 -17
  60. package/dist/builder.d.ts.map +0 -1
  61. package/dist/builder.js.map +0 -1
  62. package/dist/compose.d.ts.map +0 -1
  63. package/dist/compose.js.map +0 -1
  64. package/dist/construct-id.d.ts.map +0 -1
  65. package/dist/construct-id.js.map +0 -1
  66. package/dist/cyclic-dependency-error.d.ts.map +0 -1
  67. package/dist/cyclic-dependency-error.js.map +0 -1
  68. package/dist/index.d.ts.map +0 -1
  69. package/dist/index.js.map +0 -1
  70. package/dist/lifecycle.d.ts.map +0 -1
  71. package/dist/ref.d.ts.map +0 -1
  72. package/dist/ref.js.map +0 -1
  73. package/dist/stack-strategy.d.ts.map +0 -1
  74. package/dist/stack-strategy.js.map +0 -1
  75. package/dist/testing.d.ts.map +0 -1
  76. package/dist/testing.js.map +0 -1
  77. /package/dist/{builder.d.ts → commonjs/builder.d.ts} +0 -0
  78. /package/dist/{compose.d.ts → commonjs/compose.d.ts} +0 -0
  79. /package/dist/{construct-id.d.ts → commonjs/construct-id.d.ts} +0 -0
  80. /package/dist/{cyclic-dependency-error.d.ts → commonjs/cyclic-dependency-error.d.ts} +0 -0
  81. /package/dist/{index.d.ts → commonjs/index.d.ts} +0 -0
  82. /package/dist/{lifecycle.d.ts → commonjs/lifecycle.d.ts} +0 -0
  83. /package/dist/{stack-strategy.d.ts → commonjs/stack-strategy.d.ts} +0 -0
  84. /package/dist/{testing.d.ts → commonjs/testing.d.ts} +0 -0
  85. /package/dist/{builder.js → esm/builder.js} +0 -0
  86. /package/dist/{compose.js → esm/compose.js} +0 -0
  87. /package/dist/{construct-id.js → esm/construct-id.js} +0 -0
  88. /package/dist/{cyclic-dependency-error.js → esm/cyclic-dependency-error.js} +0 -0
  89. /package/dist/{index.js → esm/index.js} +0 -0
  90. /package/dist/{lifecycle.js → esm/lifecycle.js} +0 -0
  91. /package/dist/{stack-strategy.js → esm/stack-strategy.js} +0 -0
  92. /package/dist/{testing.js → esm/testing.js} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../../src/builder.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,KAAK,WAAW,CAAC,CAAC,IAAI,UAAU,CAAC,CAAC;AAElC;;;GAGG;AACH,UAAU,eAAe,CAAC,KAAK,SAAS,MAAM;IAC5C,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;CACvB;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,UAAU,eAA+C,CAAC;AAEvE;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,MAAM,QAAQ,CAAC,KAAK,SAAS,MAAM,EAAE,CAAC,IAAI;KAC7C,CAAC,IAAI,MAAM,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,KAAK,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC;CACjF,GAAG;KACD,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,IAAI,EAAE,CAAC,KAAK,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CACjG,GAAG;IACF;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,IAAI,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;CAC5B,CAAC;AAEF;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,OAAO,CAAC,KAAK,SAAS,MAAM,EAAE,CAAC,SAAS,eAAe,CAAC,KAAK,CAAC,EAC5E,WAAW,EAAE,WAAW,CAAC,CAAC,CAAC,EAC3B,QAAQ,GAAE,CAAqB,GAC9B,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,CA+CpB"}
@@ -0,0 +1,86 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.COPY_STATE = void 0;
4
+ exports.Builder = Builder;
5
+ /**
6
+ * Optional hook a builder class can implement to clone non-`props` state
7
+ * during {@link IBuilder.copy}.
8
+ *
9
+ * The default `.copy()` shallow-clones `props` and wraps a fresh instance.
10
+ * State stored outside `props` (private fields, internal accumulators) is
11
+ * invisible to that default. A class with such state defines a method
12
+ * keyed by this symbol to copy it onto the new instance.
13
+ *
14
+ * See ADR-0005 for the full protocol, including how decorator layers
15
+ * participate.
16
+ *
17
+ * @example
18
+ * ```ts
19
+ * class StackBuilder {
20
+ * props: Partial<StackProps> = {};
21
+ * readonly #tags: [string, string][] = [];
22
+ *
23
+ * [COPY_STATE](target: StackBuilder): void {
24
+ * target.#tags.push(...this.#tags);
25
+ * }
26
+ * }
27
+ * ```
28
+ */
29
+ exports.COPY_STATE = Symbol.for("composurecdk.builder.copyState");
30
+ /**
31
+ * Creates a fluent builder wrapping an instance of `T`.
32
+ *
33
+ * The builder is backed by a {@link Proxy} that intercepts property access:
34
+ * - For `copy`: returns a function that produces an independent builder with
35
+ * the same configured state (see {@link IBuilder.copy}).
36
+ * - For keys in `Props`: returns a getter/setter function. When called with a
37
+ * value, it sets the prop and returns the builder. When called with no args,
38
+ * it returns the current value.
39
+ * - For methods on `T` that return `T`: wraps them to return the builder instead.
40
+ * - For all other members: delegates directly to the underlying instance.
41
+ *
42
+ * @param constructor - The class to instantiate and wrap.
43
+ * @param instance - Optional pre-existing instance to wrap. Defaults to
44
+ * `new constructor()`. Used internally by {@link IBuilder.copy} to wrap a
45
+ * freshly cloned instance without re-running the constructor for new state.
46
+ * @returns A fluent {@link IBuilder} wrapping `instance`.
47
+ */
48
+ function Builder(constructor, instance = new constructor()) {
49
+ const methods = new Set(Object.getOwnPropertyNames(Object.getPrototypeOf(instance)).filter((key) => key !== "constructor" && typeof instance[key] === "function"));
50
+ const proxy = new Proxy(instance, {
51
+ get(target, prop) {
52
+ if (typeof prop === "symbol") {
53
+ return Reflect.get(target, prop);
54
+ }
55
+ if (prop === "copy") {
56
+ return () => {
57
+ const next = new constructor();
58
+ next.props = { ...target.props };
59
+ const hook = target[exports.COPY_STATE];
60
+ if (typeof hook === "function") {
61
+ hook.call(target, next);
62
+ }
63
+ return Builder(constructor, next);
64
+ };
65
+ }
66
+ // Props getter/setter
67
+ if (!methods.has(prop)) {
68
+ return (...args) => {
69
+ if (args.length === 0) {
70
+ return target.props[prop];
71
+ }
72
+ target.props[prop] = args[0];
73
+ return proxy;
74
+ };
75
+ }
76
+ // Method on target — wrap to return proxy for chainable methods
77
+ const method = target[prop];
78
+ return (...args) => {
79
+ const result = method.apply(target, args);
80
+ return result === target ? proxy : result;
81
+ };
82
+ },
83
+ });
84
+ return proxy;
85
+ }
86
+ //# sourceMappingURL=builder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builder.js","sourceRoot":"","sources":["../../src/builder.ts"],"names":[],"mappings":";;;AAwGA,0BAkDC;AA7ID;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACU,QAAA,UAAU,GAAG,MAAM,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC;AAiDvE;;;;;;;;;;;;;;;;;GAiBG;AACH,SAAgB,OAAO,CACrB,WAA2B,EAC3B,WAAc,IAAI,WAAW,EAAE;IAE/B,MAAM,OAAO,GAAG,IAAI,GAAG,CACrB,MAAM,CAAC,mBAAmB,CAAC,MAAM,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAChE,CAAC,GAAG,EAAE,EAAE,CACN,GAAG,KAAK,aAAa,IAAI,OAAQ,QAAoC,CAAC,GAAG,CAAC,KAAK,UAAU,CAC5F,CACF,CAAC;IAEF,MAAM,KAAK,GAAuB,IAAI,KAAK,CAAC,QAAQ,EAAE;QACpD,GAAG,CAAC,MAAS,EAAE,IAAqB;YAClC,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAC7B,OAAO,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAY,CAAC;YAC9C,CAAC;YAED,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;gBACpB,OAAO,GAAG,EAAE;oBACV,MAAM,IAAI,GAAG,IAAI,WAAW,EAAE,CAAC;oBAC/B,IAAI,CAAC,KAAK,GAAG,EAAE,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC;oBACjC,MAAM,IAAI,GAAI,MAA6C,CAAC,kBAAU,CAAC,CAAC;oBACxE,IAAI,OAAO,IAAI,KAAK,UAAU,EAAE,CAAC;wBAC9B,IAA0B,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;oBACjD,CAAC;oBACD,OAAO,OAAO,CAAW,WAAW,EAAE,IAAI,CAAC,CAAC;gBAC9C,CAAC,CAAC;YACJ,CAAC;YAED,sBAAsB;YACtB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;gBACvB,OAAO,CAAC,GAAG,IAAe,EAAE,EAAE;oBAC5B,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;wBACtB,OAAO,MAAM,CAAC,KAAK,CAAC,IAAmB,CAAC,CAAC;oBAC3C,CAAC;oBACD,MAAM,CAAC,KAAK,CAAC,IAAmB,CAAC,GAAG,IAAI,CAAC,CAAC,CAAuB,CAAC;oBAClE,OAAO,KAAK,CAAC;gBACf,CAAC,CAAC;YACJ,CAAC;YAED,gEAAgE;YAChE,MAAM,MAAM,GAAI,MAAkC,CAAC,IAAI,CAAiC,CAAC;YACzF,OAAO,CAAC,GAAG,IAAe,EAAE,EAAE;gBAC5B,MAAM,MAAM,GAAY,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;gBACnD,OAAO,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC;YAC5C,CAAC,CAAC;QACJ,CAAC;KACF,CAAuB,CAAC;IAEzB,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compose.d.ts","sourceRoot":"","sources":["../../src/compose.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD;;;;;;GAMG;AACH,KAAK,WAAW,CAAC,CAAC,SAAS;KAAG,QAAQ,IAAI,MAAM,CAAC,GAAG,SAAS;CAAE,IAAI;KAChE,QAAQ,IAAI,MAAM,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC;CACxD,CAAC;AAEF;;;;;;GAMG;AACH,KAAK,UAAU,CAAC,UAAU,SAAS,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,IAAI,CAAC,MAAM,UAAU,CAAC,EAAE,CAAC;AA+BrF;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,MAAM,cAAc,CAAC,CAAC,SAAS,MAAM,IAAI,CAC7C,KAAK,EAAE,UAAU,EACjB,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,CAAC,EACV,eAAe,EAAE;IAAE,QAAQ,EAAE,CAAC,IAAI,MAAM,CAAC,GAAG,UAAU;CAAE,KACrD,IAAI,CAAC;AAEV;;;;;;;;GAQG;AACH,MAAM,WAAW,cAAc,CAAC,UAAU,SAAS,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAE,SAAQ,SAAS,CAC7F,WAAW,CAAC,UAAU,CAAC,CACxB;IACC;;;;;;;;;;;;;;;;;OAiBG;IACH,UAAU,CAAC,MAAM,EAAE;SAAG,CAAC,IAAI,MAAM,UAAU,CAAC,CAAC,EAAE,UAAU;KAAE,GAAG,gBAAgB,CAAC,UAAU,CAAC,CAAC;IAE3F;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,iBAAiB,CAAC,QAAQ,EAAE,aAAa,GAAG,gBAAgB,CAAC,UAAU,CAAC,CAAC;IAEzE;;;;;;;;;;;;;;;;;;;;;;;;;;OA0BG;IACH,UAAU,CAAC,IAAI,EAAE,cAAc,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC,GAAG,gBAAgB,CAAC,UAAU,CAAC,CAAC;CACzF;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,gBAAgB,CAAC,UAAU,SAAS,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAE,SAAQ,SAAS,CAC/F,WAAW,CAAC,UAAU,CAAC,CACxB;IACC;;;;;;OAMG;IACH,UAAU,CAAC,IAAI,EAAE,cAAc,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC,GAAG,gBAAgB,CAAC,UAAU,CAAC,CAAC;CACzF;AA0HD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,OAAO,CAAC,UAAU,SAAS,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,EAClE,UAAU,EAAE,UAAU,EACtB,YAAY,EAAE;KAAG,QAAQ,IAAI,MAAM,UAAU,GAAG,UAAU,CAAC,UAAU,CAAC;CAAE,GACvE,cAAc,CAAC,UAAU,CAAC,CAE5B"}
@@ -0,0 +1,114 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.compose = compose;
4
+ const graphlib_1 = require("@dagrejs/graphlib");
5
+ const cyclic_dependency_error_js_1 = require("./cyclic-dependency-error.js");
6
+ /**
7
+ * Builds a directed acyclic graph from component dependency declarations.
8
+ * The graph is described declaratively as nodes and edges, then constructed
9
+ * via {@link json.read}. Nodes are component keys, edges point from a
10
+ * dependency to its dependent. Throws if the graph contains a cycle.
11
+ */
12
+ function buildDependencyGraph(components, dependencies) {
13
+ const nodes = Object.keys(components).map((v) => ({ v }));
14
+ const edges = Object.entries(dependencies).flatMap(([key, deps]) => deps.map((dep) => ({ v: dep, w: key })));
15
+ const graph = graphlib_1.json.read({
16
+ options: { directed: true },
17
+ nodes,
18
+ edges,
19
+ });
20
+ if (!graphlib_1.alg.isAcyclic(graph)) {
21
+ throw new cyclic_dependency_error_js_1.CyclicDependencyError(graphlib_1.alg.findCycles(graph));
22
+ }
23
+ return graph;
24
+ }
25
+ /**
26
+ * A composed system of {@link Lifecycle} components. Holds the dependency graph
27
+ * built at composition time and traverses it in topological order during build.
28
+ */
29
+ class ComposedLifecycle {
30
+ #graph;
31
+ #components;
32
+ #dependencies;
33
+ constructor(components, dependencies) {
34
+ this.#components = components;
35
+ this.#dependencies = dependencies;
36
+ this.#graph = buildDependencyGraph(components, dependencies);
37
+ }
38
+ withStacks(stacks) {
39
+ return new ConfiguredLifecycle((scope, id, parentContext) => this.#buildWith(scope, id, stacks, parentContext));
40
+ }
41
+ withStackStrategy(strategy) {
42
+ return new ConfiguredLifecycle((scope, id, parentContext) => {
43
+ const stacks = Object.fromEntries(Object.keys(this.#components).map((key) => [key, strategy.resolve(scope, id, key)]));
44
+ return this.#buildWith(scope, id, stacks, parentContext);
45
+ });
46
+ }
47
+ afterBuild(hook) {
48
+ return new ConfiguredLifecycle((scope, id, parentContext) => this.#buildWith(scope, id, undefined, parentContext)).afterBuild(hook);
49
+ }
50
+ build(scope, id, parentContext) {
51
+ return this.#buildWith(scope, id, undefined, parentContext).results;
52
+ }
53
+ #buildWith(scope, id, stacks, parentContext) {
54
+ const results = {};
55
+ const componentScopes = {};
56
+ for (const key of graphlib_1.alg.topsort(this.#graph)) {
57
+ const componentScope = stacks?.[key] ?? scope;
58
+ componentScopes[key] = componentScope;
59
+ const deps = (this.#dependencies[key] ?? []);
60
+ // Inner deps shadow parent context on key collision.
61
+ const innerContext = Object.fromEntries(deps.map((dep) => [dep, results[dep]]));
62
+ const context = { ...parentContext, ...innerContext };
63
+ results[key] = this.#components[key].build(componentScope, `${id}/${key}`, context);
64
+ }
65
+ return {
66
+ results: results,
67
+ componentScopes: componentScopes,
68
+ };
69
+ }
70
+ }
71
+ /**
72
+ * A configured lifecycle that accumulates post-build hooks and applies them
73
+ * after the underlying build function completes. Returned by
74
+ * {@link ComposedLifecycle}'s `withStacks`, `withStackStrategy`, and
75
+ * `afterBuild` methods.
76
+ */
77
+ class ConfiguredLifecycle {
78
+ #hooks = [];
79
+ #buildFn;
80
+ constructor(buildFn) {
81
+ this.#buildFn = buildFn;
82
+ }
83
+ afterBuild(hook) {
84
+ this.#hooks.push(hook);
85
+ return this;
86
+ }
87
+ build(scope, id, parentContext) {
88
+ const { results, componentScopes } = this.#buildFn(scope, id, parentContext);
89
+ for (const hook of this.#hooks) {
90
+ hook(scope, id, results, componentScopes);
91
+ }
92
+ return results;
93
+ }
94
+ }
95
+ /**
96
+ * Composes a set of {@link Lifecycle} components into a single system that
97
+ * manages their build order and dependency resolution.
98
+ *
99
+ * A directed acyclic graph is built eagerly from the declared dependencies.
100
+ * Cyclic dependencies are detected at composition time and throw immediately.
101
+ * When `build` is called, components are built in topological order, each
102
+ * receiving the build outputs of its dependencies as its context.
103
+ *
104
+ * The returned {@link ComposedSystem} is a {@link Lifecycle}, so it can be
105
+ * nested as a component in a larger `compose` call.
106
+ *
107
+ * @param components - A record of named {@link Lifecycle} components.
108
+ * @param dependencies - For each component, the list of other component keys it depends on.
109
+ * @returns A {@link ComposedSystem} whose build output is the combined {@link BuildResult} of all components.
110
+ */
111
+ function compose(components, dependencies) {
112
+ return new ComposedLifecycle(components, dependencies);
113
+ }
114
+ //# sourceMappingURL=compose.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compose.js","sourceRoot":"","sources":["../../src/compose.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"construct-id.d.ts","sourceRoot":"","sources":["../../src/construct-id.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAKH;;;;;;;;;;;;;GAaG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,WAAW,CAAC,GAAG,KAAK,EAAE,SAAS,CAAC,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,KAAK,CAAC,EAAE,GAAG,MAAM,CAK5F"}
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ /**
3
+ * Utilities for producing safe CDK construct IDs from arbitrary strings.
4
+ *
5
+ * The `constructs` library uses `/` as the path separator between construct
6
+ * IDs. When user-supplied strings (DNS names, ARNs, filesystem paths) are
7
+ * passed through to a construct ID, any embedded `/` silently gets rewritten
8
+ * to `--`, which produces unreadable CloudFormation logical IDs. Control
9
+ * characters are likewise unsafe.
10
+ *
11
+ * These helpers consolidate that sanitization in one place so every builder
12
+ * in the monorepo applies the same constraints.
13
+ */
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.sanitizeConstructId = sanitizeConstructId;
16
+ exports.constructId = constructId;
17
+ // eslint-disable-next-line no-control-regex -- the regex must literally match control characters to strip them from construct IDs
18
+ const UNSAFE = /[/\x00-\x1f\x7f]/g;
19
+ /**
20
+ * Return a construct-ID-safe copy of `raw` by replacing unsafe characters
21
+ * (`/` and control characters) with a single `-`.
22
+ *
23
+ * Does not touch other characters — CDK construct IDs are otherwise
24
+ * permissive, and collapsing further (e.g., to PascalCase) would destroy
25
+ * information a reader expects to see in the synthesised tree.
26
+ *
27
+ * @example
28
+ * ```ts
29
+ * sanitizeConstructId("a/b") // "a-b"
30
+ * sanitizeConstructId("_sip._tcp") // "_sip._tcp" (unchanged)
31
+ * ```
32
+ */
33
+ function sanitizeConstructId(raw) {
34
+ return raw.replace(UNSAFE, "-");
35
+ }
36
+ /**
37
+ * Join the supplied parts into a single construct ID. Falsy parts are
38
+ * dropped; each remaining part is passed through {@link sanitizeConstructId}
39
+ * and the results are joined with `-`.
40
+ *
41
+ * Intended for composing IDs from a mix of static prefixes and user-supplied
42
+ * fragments — the sanitization step means callers don't have to reason about
43
+ * what characters their inputs might contain.
44
+ *
45
+ * @example
46
+ * ```ts
47
+ * constructId("records", "a", "api") // "records-a-api"
48
+ * constructId("zone", undefined, "www") // "zone-www"
49
+ * constructId("records", "a/b") // "records-a-b"
50
+ * ```
51
+ */
52
+ function constructId(...parts) {
53
+ return parts
54
+ .filter((p) => typeof p === "string" && p.length > 0)
55
+ .map(sanitizeConstructId)
56
+ .join("-");
57
+ }
58
+ //# sourceMappingURL=construct-id.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"construct-id.js","sourceRoot":"","sources":["../../src/construct-id.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;GAWG;;AAmBH,kDAEC;AAkBD,kCAKC;AA1CD,kIAAkI;AAClI,MAAM,MAAM,GAAG,mBAAmB,CAAC;AAEnC;;;;;;;;;;;;;GAaG;AACH,SAAgB,mBAAmB,CAAC,GAAW;IAC7C,OAAO,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAClC,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,SAAgB,WAAW,CAAC,GAAG,KAAqD;IAClF,OAAO,KAAK;SACT,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;SACjE,GAAG,CAAC,mBAAmB,CAAC;SACxB,IAAI,CAAC,GAAG,CAAC,CAAC;AACf,CAAC"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cyclic-dependency-error.d.ts","sourceRoot":"","sources":["../../src/cyclic-dependency-error.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,qBAAa,qBAAsB,SAAQ,KAAK;aAIlB,MAAM,EAAE,MAAM,EAAE,EAAE;IAH9C;;OAEG;gBACyB,MAAM,EAAE,MAAM,EAAE,EAAE;CAI/C"}
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CyclicDependencyError = void 0;
4
+ /**
5
+ * Thrown when {@link compose} detects a cycle in the component dependency graph.
6
+ * Carries the detected cycles so callers can inspect or report them programmatically.
7
+ */
8
+ class CyclicDependencyError extends Error {
9
+ cycles;
10
+ /**
11
+ * @param cycles - Each element is an array of component keys forming a cycle.
12
+ */
13
+ constructor(cycles) {
14
+ super(`Cyclic dependencies detected: ${cycles.map((c) => c.join(" -> ")).join("; ")}`);
15
+ this.cycles = cycles;
16
+ this.name = "CyclicDependencyError";
17
+ }
18
+ }
19
+ exports.CyclicDependencyError = CyclicDependencyError;
20
+ //# sourceMappingURL=cyclic-dependency-error.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cyclic-dependency-error.js","sourceRoot":"","sources":["../../src/cyclic-dependency-error.ts"],"names":[],"mappings":";;;AAAA;;;GAGG;AACH,MAAa,qBAAsB,SAAQ,KAAK;IAIlB;IAH5B;;OAEG;IACH,YAA4B,MAAkB;QAC5C,KAAK,CAAC,iCAAiC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAD7D,WAAM,GAAN,MAAM,CAAY;QAE5C,IAAI,CAAC,IAAI,GAAG,uBAAuB,CAAC;IACtC,CAAC;CACF;AARD,sDAQC"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,KAAK,QAAQ,EAAE,MAAM,cAAc,CAAC;AAClE,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACrE,OAAO,EACL,OAAO,EACP,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,cAAc,GACpB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AACrE,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,UAAU,EAAE,MAAM,UAAU,CAAC;AACrE,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,WAAW,EACX,aAAa,GACd,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.groupedStacks = exports.singleStack = exports.isRef = exports.resolve = exports.ref = exports.Ref = exports.CyclicDependencyError = exports.compose = exports.sanitizeConstructId = exports.constructId = exports.COPY_STATE = exports.Builder = void 0;
4
+ var builder_js_1 = require("./builder.js");
5
+ Object.defineProperty(exports, "Builder", { enumerable: true, get: function () { return builder_js_1.Builder; } });
6
+ Object.defineProperty(exports, "COPY_STATE", { enumerable: true, get: function () { return builder_js_1.COPY_STATE; } });
7
+ var construct_id_js_1 = require("./construct-id.js");
8
+ Object.defineProperty(exports, "constructId", { enumerable: true, get: function () { return construct_id_js_1.constructId; } });
9
+ Object.defineProperty(exports, "sanitizeConstructId", { enumerable: true, get: function () { return construct_id_js_1.sanitizeConstructId; } });
10
+ var compose_js_1 = require("./compose.js");
11
+ Object.defineProperty(exports, "compose", { enumerable: true, get: function () { return compose_js_1.compose; } });
12
+ var cyclic_dependency_error_js_1 = require("./cyclic-dependency-error.js");
13
+ Object.defineProperty(exports, "CyclicDependencyError", { enumerable: true, get: function () { return cyclic_dependency_error_js_1.CyclicDependencyError; } });
14
+ var ref_js_1 = require("./ref.js");
15
+ Object.defineProperty(exports, "Ref", { enumerable: true, get: function () { return ref_js_1.Ref; } });
16
+ Object.defineProperty(exports, "ref", { enumerable: true, get: function () { return ref_js_1.ref; } });
17
+ Object.defineProperty(exports, "resolve", { enumerable: true, get: function () { return ref_js_1.resolve; } });
18
+ Object.defineProperty(exports, "isRef", { enumerable: true, get: function () { return ref_js_1.isRef; } });
19
+ var stack_strategy_js_1 = require("./stack-strategy.js");
20
+ Object.defineProperty(exports, "singleStack", { enumerable: true, get: function () { return stack_strategy_js_1.singleStack; } });
21
+ Object.defineProperty(exports, "groupedStacks", { enumerable: true, get: function () { return stack_strategy_js_1.groupedStacks; } });
22
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;AAAA,2CAAkE;AAAzD,qGAAA,OAAO,OAAA;AAAE,wGAAA,UAAU,OAAA;AAC5B,qDAAqE;AAA5D,8GAAA,WAAW,OAAA;AAAE,sHAAA,mBAAmB,OAAA;AACzC,2CAKsB;AAJpB,qGAAA,OAAO,OAAA;AAKT,2EAAqE;AAA5D,mIAAA,qBAAqB,OAAA;AAE9B,mCAAqE;AAA5D,6FAAA,GAAG,OAAA;AAAE,6FAAA,GAAG,OAAA;AAAE,iGAAA,OAAO,OAAA;AAAE,+FAAA,KAAK,OAAA;AACjC,yDAK6B;AAF3B,gHAAA,WAAW,OAAA;AACX,kHAAA,aAAa,OAAA"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lifecycle.d.ts","sourceRoot":"","sources":["../../src/lifecycle.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C;;;GAGG;AACH,KAAK,sBAAsB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAErD;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,SAAS,CACxB,CAAC,SAAS,MAAM,GAAG,MAAM,EACzB,OAAO,SAAS,sBAAsB,GAAG,sBAAsB;IAE/D,KAAK,CAAC,KAAK,EAAE,UAAU,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,CAAC,CAAC;CAC5D"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=lifecycle.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../src/lifecycle.ts"],"names":[],"mappings":""}
1
+ {"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../../src/lifecycle.ts"],"names":[],"mappings":""}
@@ -0,0 +1,3 @@
1
+ {
2
+ "type": "commonjs"
3
+ }
@@ -1,3 +1,12 @@
1
+ /**
2
+ * @internal Brands every {@link Ref} instance so {@link isRef} can recognise
3
+ * one without `instanceof`. `instanceof` is realm-bound: when `@composurecdk/core`
4
+ * is loaded as both ESM and CommonJS in the same process (the dual-package
5
+ * hazard), each copy has its own `Ref` class and `instanceof` fails across the
6
+ * boundary. A `Symbol.for(...)` brand is registered in the global symbol
7
+ * registry, so a `Ref` minted by either copy is still recognised by either.
8
+ */
9
+ export declare const REF_BRAND: unique symbol;
1
10
  /**
2
11
  * A lazy reference to a value produced by another component at build time.
3
12
  *
@@ -27,6 +36,8 @@
27
36
  */
28
37
  export declare class Ref<T> {
29
38
  #private;
39
+ /** @internal Realm-agnostic brand — see {@link REF_BRAND}. */
40
+ readonly [REF_BRAND] = true;
30
41
  private constructor();
31
42
  /**
32
43
  * Creates a `Ref` that resolves to a component's full build output.
@@ -100,6 +111,11 @@ export declare function ref<T extends object, U>(component: string, transform: (
100
111
  export type Resolvable<T> = T | Ref<T>;
101
112
  /**
102
113
  * Type guard that checks whether a value is a {@link Ref}.
114
+ *
115
+ * Recognises a `Ref` by its {@link REF_BRAND} symbol rather than `instanceof`,
116
+ * so it works across the dual-package boundary — a `Ref` produced by the ESM
117
+ * copy of `@composurecdk/core` is still recognised by the CommonJS copy and
118
+ * vice versa.
103
119
  */
104
120
  export declare function isRef<T>(value: Resolvable<T>): value is Ref<T>;
105
121
  /**
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ref.d.ts","sourceRoot":"","sources":["../../src/ref.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,eAAO,MAAM,SAAS,eAAiC,CAAC;AAExD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,qBAAa,GAAG,CAAC,CAAC;;IAChB,8DAA8D;IAC9D,QAAQ,CAAC,CAAC,SAAS,CAAC,QAAQ;IAI5B,OAAO;IAIP;;;;;OAKG;IACH,MAAM,CAAC,EAAE,CAAC,CAAC,SAAS,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC;IAYtD;;;;;OAKG;IACH,GAAG,CAAC,CAAC,SAAS,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAIzC;;;;;;;;;OASG;IACH,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;IAInC;;;;;;;OAOG;IACH,OAAO,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC;CAG5C;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,GAAG,CAAC,CAAC,SAAS,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;AAEjE,wBAAgB,GAAG,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;AAShG;;;;;GAKG;AACH,MAAM,MAAM,UAAU,CAAC,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;AAEvC;;;;;;;GAOG;AACH,wBAAgB,KAAK,CAAC,CAAC,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,KAAK,IAAI,GAAG,CAAC,CAAC,CAAC,CAE9D;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,OAAO,CAAC,CAAC,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,CAEpF"}
@@ -0,0 +1,129 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Ref = exports.REF_BRAND = void 0;
4
+ exports.ref = ref;
5
+ exports.isRef = isRef;
6
+ exports.resolve = resolve;
7
+ /**
8
+ * @internal Brands every {@link Ref} instance so {@link isRef} can recognise
9
+ * one without `instanceof`. `instanceof` is realm-bound: when `@composurecdk/core`
10
+ * is loaded as both ESM and CommonJS in the same process (the dual-package
11
+ * hazard), each copy has its own `Ref` class and `instanceof` fails across the
12
+ * boundary. A `Symbol.for(...)` brand is registered in the global symbol
13
+ * registry, so a `Ref` minted by either copy is still recognised by either.
14
+ */
15
+ exports.REF_BRAND = Symbol.for("composurecdk.ref");
16
+ /**
17
+ * A lazy reference to a value produced by another component at build time.
18
+ *
19
+ * `Ref` enables declarative cross-component wiring: a builder can capture a
20
+ * reference to a dependency's output at configuration time, and the value is
21
+ * resolved when the system is built. This keeps all configuration in one
22
+ * place — no split between eager props and deferred hooks.
23
+ *
24
+ * Create a `Ref` with the {@link ref} factory, then optionally narrow it
25
+ * with {@link Ref.get | .get()} or transform it with {@link Ref.map | .map()}.
26
+ *
27
+ * @typeParam T - The type of the value this reference resolves to.
28
+ *
29
+ * @example
30
+ * ```ts
31
+ * // Reference a component's full build output
32
+ * ref<FunctionBuilderResult>("handler")
33
+ *
34
+ * // Narrow to a specific property
35
+ * ref<FunctionBuilderResult>("handler").get("function")
36
+ *
37
+ * // Transform the referenced value
38
+ * ref<FunctionBuilderResult>("handler")
39
+ * .get("function")
40
+ * .map(fn => new LambdaIntegration(fn))
41
+ * ```
42
+ */
43
+ class Ref {
44
+ /** @internal Realm-agnostic brand — see {@link REF_BRAND}. */
45
+ [exports.REF_BRAND] = true;
46
+ #resolver;
47
+ constructor(resolver) {
48
+ this.#resolver = resolver;
49
+ }
50
+ /**
51
+ * Creates a `Ref` that resolves to a component's full build output.
52
+ *
53
+ * @param component - The key of the component in the composed system.
54
+ * @returns A `Ref` to the component's build result.
55
+ */
56
+ static to(component) {
57
+ return new Ref((context) => {
58
+ if (!(component in context)) {
59
+ throw new Error(`Ref to "${component}" cannot be resolved: component not found in context. ` +
60
+ `Ensure "${component}" is declared as a dependency.`);
61
+ }
62
+ return context[component];
63
+ });
64
+ }
65
+ /**
66
+ * Narrows this reference to a specific property of the resolved value.
67
+ *
68
+ * @param key - The property key to select.
69
+ * @returns A new `Ref` to the selected property.
70
+ */
71
+ get(key) {
72
+ return new Ref((context) => this.#resolver(context)[key]);
73
+ }
74
+ /**
75
+ * Transforms the resolved value using the provided function.
76
+ *
77
+ * This is the primary way to adapt a dependency's output into the shape
78
+ * a consumer needs — for example, wrapping a Lambda function in a
79
+ * `LambdaIntegration`.
80
+ *
81
+ * @param fn - A function that transforms the resolved value.
82
+ * @returns A new `Ref` whose resolved value is the result of `fn`.
83
+ */
84
+ map(fn) {
85
+ return new Ref((context) => fn(this.#resolver(context)));
86
+ }
87
+ /**
88
+ * Resolves this reference against a build context.
89
+ *
90
+ * Called internally during the build phase. Not typically called by users.
91
+ *
92
+ * @param context - The resolved dependency outputs, keyed by component name.
93
+ * @returns The resolved value.
94
+ */
95
+ resolve(context) {
96
+ return this.#resolver(context);
97
+ }
98
+ }
99
+ exports.Ref = Ref;
100
+ function ref(component, transform) {
101
+ const base = Ref.to(component);
102
+ return transform ? base.map(transform) : base;
103
+ }
104
+ /**
105
+ * Type guard that checks whether a value is a {@link Ref}.
106
+ *
107
+ * Recognises a `Ref` by its {@link REF_BRAND} symbol rather than `instanceof`,
108
+ * so it works across the dual-package boundary — a `Ref` produced by the ESM
109
+ * copy of `@composurecdk/core` is still recognised by the CommonJS copy and
110
+ * vice versa.
111
+ */
112
+ function isRef(value) {
113
+ return typeof value === "object" && value !== null && exports.REF_BRAND in value;
114
+ }
115
+ /**
116
+ * Resolves a {@link Resolvable} value. If it is a {@link Ref}, resolves it
117
+ * against the provided context (or an empty context if none is given).
118
+ * Otherwise returns the value as-is.
119
+ *
120
+ * @param value - A concrete value or a `Ref`.
121
+ * @param context - The resolved dependency outputs, keyed by component name.
122
+ * Omit for standalone builds where no refs are in use — a `Ref` resolved
123
+ * against an empty context will throw "component not found".
124
+ * @returns The concrete value.
125
+ */
126
+ function resolve(value, context) {
127
+ return isRef(value) ? value.resolve(context ?? {}) : value;
128
+ }
129
+ //# sourceMappingURL=ref.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ref.js","sourceRoot":"","sources":["../../src/ref.ts"],"names":[],"mappings":";;;AAmIA,kBAMC;AAkBD,sBAEC;AAaD,0BAEC;AA5KD;;;;;;;GAOG;AACU,QAAA,SAAS,GAAG,MAAM,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;AAExD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAa,GAAG;IACd,8DAA8D;IACrD,CAAC,iBAAS,CAAC,GAAG,IAAI,CAAC;IAEnB,SAAS,CAAyC;IAE3D,YAAoB,QAAgD;QAClE,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC;IAC5B,CAAC;IAED;;;;;OAKG;IACH,MAAM,CAAC,EAAE,CAAmB,SAAiB;QAC3C,OAAO,IAAI,GAAG,CAAI,CAAC,OAAO,EAAE,EAAE;YAC5B,IAAI,CAAC,CAAC,SAAS,IAAI,OAAO,CAAC,EAAE,CAAC;gBAC5B,MAAM,IAAI,KAAK,CACb,WAAW,SAAS,wDAAwD;oBAC1E,WAAW,SAAS,gCAAgC,CACvD,CAAC;YACJ,CAAC;YACD,OAAO,OAAO,CAAC,SAAS,CAAM,CAAC;QACjC,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;;OAKG;IACH,GAAG,CAAoB,GAAM;QAC3B,OAAO,IAAI,GAAG,CAAO,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAClE,CAAC;IAED;;;;;;;;;OASG;IACH,GAAG,CAAI,EAAmB;QACxB,OAAO,IAAI,GAAG,CAAI,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IAC9D,CAAC;IAED;;;;;;;OAOG;IACH,OAAO,CAAC,OAA+B;QACrC,OAAO,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IACjC,CAAC;CACF;AA/DD,kBA+DC;AA+BD,SAAgB,GAAG,CACjB,SAAiB,EACjB,SAA2B;IAE3B,MAAM,IAAI,GAAG,GAAG,CAAC,EAAE,CAAI,SAAS,CAAC,CAAC;IAClC,OAAO,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAChD,CAAC;AAUD;;;;;;;GAOG;AACH,SAAgB,KAAK,CAAI,KAAoB;IAC3C,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,iBAAS,IAAI,KAAK,CAAC;AAC3E,CAAC;AAED;;;;;;;;;;GAUG;AACH,SAAgB,OAAO,CAAI,KAAoB,EAAE,OAAgC;IAC/E,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;AAC7D,CAAC"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stack-strategy.d.ts","sourceRoot":"","sources":["../../src/stack-strategy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C;;;;;;;;GAQG;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,KAAK,EAAE,UAAU,EAAE,EAAE,EAAE,MAAM,KAAK,UAAU,CAAC;AAEzE;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,WAAW,aAAa;IAC5B;;;;;;;OAOG;IACH,OAAO,CAAC,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,UAAU,CAAC;CAChF;AAED;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,aAAa,CAUhE;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,MAAM,EAC1C,OAAO,EAAE,YAAY,GACpB,aAAa,CAaf"}
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.singleStack = singleStack;
4
+ exports.groupedStacks = groupedStacks;
5
+ /**
6
+ * Creates a strategy that places all components in a single auto-created scope.
7
+ *
8
+ * The scope is created lazily on the first call to `resolve` and reused for
9
+ * all subsequent components.
10
+ *
11
+ * @param factory - Factory for creating the scope (e.g. a Stack).
12
+ * @returns A {@link StackStrategy} that groups all components into one scope.
13
+ */
14
+ function singleStack(factory) {
15
+ return {
16
+ resolve: (() => {
17
+ let stack;
18
+ return (scope, systemId) => {
19
+ stack ??= factory(scope, systemId);
20
+ return stack;
21
+ };
22
+ })(),
23
+ };
24
+ }
25
+ /**
26
+ * Creates a strategy that groups components into named scopes determined by
27
+ * a classifier function.
28
+ *
29
+ * Components that return the same group key share a scope. Scopes are created
30
+ * lazily as new group keys are encountered.
31
+ *
32
+ * @param classify - A function that maps a component key to a group name.
33
+ * @param factory - Factory for creating scopes (e.g. Stacks). The factory
34
+ * receives `${systemId}-${group}` as the id.
35
+ * @returns A {@link StackStrategy} that groups components by classifier output.
36
+ *
37
+ * @example
38
+ * ```ts
39
+ * groupedStacks(
40
+ * key => key === "table" ? "persistence" : "service",
41
+ * (app, id) => new Stack(app, id),
42
+ * )
43
+ * ```
44
+ */
45
+ function groupedStacks(classify, factory) {
46
+ const groups = new Map();
47
+ return {
48
+ resolve(scope, systemId, componentKey) {
49
+ const group = classify(componentKey);
50
+ let groupScope = groups.get(group);
51
+ if (!groupScope) {
52
+ groupScope = factory(scope, `${systemId}-${group}`);
53
+ groups.set(group, groupScope);
54
+ }
55
+ return groupScope;
56
+ },
57
+ };
58
+ }
59
+ //# sourceMappingURL=stack-strategy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stack-strategy.js","sourceRoot":"","sources":["../../src/stack-strategy.ts"],"names":[],"mappings":";;AAuDA,kCAUC;AAsBD,sCAgBC;AAzDD;;;;;;;;GAQG;AACH,SAAgB,WAAW,CAAC,OAAqB;IAC/C,OAAO;QACL,OAAO,EAAE,CAAC,GAAG,EAAE;YACb,IAAI,KAA6B,CAAC;YAClC,OAAO,CAAC,KAAiB,EAAE,QAAgB,EAAE,EAAE;gBAC7C,KAAK,KAAK,OAAO,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;gBACnC,OAAO,KAAK,CAAC;YACf,CAAC,CAAC;QACJ,CAAC,CAAC,EAAE;KACL,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,SAAgB,aAAa,CAC3B,QAA0C,EAC1C,OAAqB;IAErB,MAAM,MAAM,GAAG,IAAI,GAAG,EAAsB,CAAC;IAC7C,OAAO;QACL,OAAO,CAAC,KAAiB,EAAE,QAAgB,EAAE,YAAoB;YAC/D,MAAM,KAAK,GAAG,QAAQ,CAAC,YAAY,CAAC,CAAC;YACrC,IAAI,UAAU,GAAG,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YACnC,IAAI,CAAC,UAAU,EAAE,CAAC;gBAChB,UAAU,GAAG,OAAO,CAAC,KAAK,EAAE,GAAG,QAAQ,IAAI,KAAK,EAAE,CAAC,CAAC;gBACpD,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;YAChC,CAAC;YACD,OAAO,UAAU,CAAC;QACpB,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../../src/testing.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4DG;AACH,wBAAgB,wBAAwB,CAAC,CAAC,SAAS;IAAE,IAAI,IAAI,CAAC,CAAA;CAAE,EAAE,CAAC,EAAE,IAAI,EAAE;IACzE,OAAO,EAAE,MAAM,CAAC,CAAC;IACjB,SAAS,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,IAAI,CAAC;IAChC,MAAM,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,IAAI,CAAC;IAC7B,KAAK,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,CAAC;IACzB,OAAO,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,OAAO,CAAC;CACjC,GAAG,IAAI,CAsCP"}