@xplane/core 1.1.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -32,26 +32,49 @@ interface CompositionResult {
32
32
  /** Resources to emit to Crossplane as desired composed resources. */
33
33
  resources: DesiredResource[];
34
34
  /**
35
- * Names of resources that are blocked (pending resolution). The handler
36
- * uses these to preserve any previously-observed documents in desired state
37
- * (preventing accidental deletion) and to prevent premature XR readiness.
35
+ * Resources that are blocked (pending resolution). The handler uses these
36
+ * to preserve any previously-observed documents in desired state (preventing
37
+ * accidental deletion), to prevent premature XR readiness, and to populate
38
+ * `status.xplane.blockedResources` on the XR.
38
39
  */
39
- blockedResources: string[];
40
+ blockedResources: BlockedResource[];
40
41
  /** External resources that need to be fetched via requireResource. */
41
42
  externalResources: ExternalResourceRequest[];
42
43
  /** Desired XR status patches (from this.xr.status assignments). */
43
44
  xrStatus: Record<string, unknown>;
44
45
  /** Diagnostic reports for blocked/unresolved resources. */
45
46
  diagnostics: Diagnostic[];
47
+ /**
48
+ * When `true`, the runtime should inject a structured `status.xplane`
49
+ * payload on the XR. Controlled by `Composition.emitXplaneStatus`.
50
+ */
51
+ emitXplaneStatus: boolean;
46
52
  }
47
53
  /** A desired composed resource ready for emission. */
48
54
  interface DesiredResource {
49
- /** The resource name (construct path without "Composition/" prefix). */
50
- name: string;
55
+ /**
56
+ * The construct path (without the `Composition/` prefix). This doubles as the
57
+ * Crossplane composed-resource key in the function-pipeline desired map and
58
+ * uniquely identifies the resource within the composition.
59
+ */
60
+ nodePath: string;
61
+ /**
62
+ * The actual Kubernetes `metadata.name` of the resolved document, when known.
63
+ * May be undefined if the name is provider-generated or not yet resolved.
64
+ */
65
+ name?: string;
66
+ /** The Kubernetes `metadata.namespace` of the document, when present. */
67
+ namespace?: string;
51
68
  /** The fully-resolved desired Kubernetes resource document. */
52
69
  document: Record<string, unknown>;
53
70
  /** Whether this resource is ready (readiness already evaluated). */
54
71
  ready: boolean;
72
+ /**
73
+ * True when this resource is blocked (pending dependencies) and is being emitted
74
+ * as its previously-observed state to prevent Crossplane from deleting it.
75
+ * The handler must mark it as READY_FALSE and must not evaluate readiness.
76
+ */
77
+ preserved?: boolean;
55
78
  }
56
79
  /** A request to fetch an external (existing) resource. */
57
80
  interface ExternalResourceRequest {
@@ -64,6 +87,24 @@ interface ExternalResourceRequest {
64
87
  /** Optional namespace. */
65
88
  namespace?: string;
66
89
  }
90
+ /**
91
+ * A blocked composed resource. Surfaced on the XR as
92
+ * `status.xplane.blockedResources` for visibility.
93
+ */
94
+ interface BlockedResource {
95
+ /** Construct path (also used as the Crossplane composed resource key). */
96
+ nodePath: string;
97
+ /** The actual Kubernetes `metadata.name` of the resolved document, when known. */
98
+ name?: string;
99
+ /** The Kubernetes `metadata.namespace` of the document, when present. */
100
+ namespace?: string;
101
+ /** The desired resource's apiVersion. */
102
+ apiVersion: string;
103
+ /** The desired resource's kind. */
104
+ kind: string;
105
+ /** Human-readable list of things this resource is waiting for. */
106
+ waitingFor?: string[];
107
+ }
67
108
  /** A diagnostic report for a blocked resource. */
68
109
  interface Diagnostic {
69
110
  /** The resource name (construct path). */
@@ -303,6 +344,30 @@ declare class Composition<TSpec = Record<string, unknown>, TStatus = Record<stri
303
344
  readonly graph: DependencyGraph;
304
345
  /** The edge collector accumulating dependency edges. */
305
346
  readonly collector: EdgeCollector;
347
+ /**
348
+ * When `true`, the runtime injects a structured `status.xplane` payload on
349
+ * the XR containing `emittedResources` and `blockedResources`. Defaults to
350
+ * `false` because writing this field requires the XRD's `openAPIV3Schema`
351
+ * to declare `status.xplane` (or `status` to allow unknown fields) — typed
352
+ * patches will otherwise be rejected by Crossplane.
353
+ *
354
+ * To enable, set in your composition's constructor:
355
+ *
356
+ * ```ts
357
+ * this.emitXplaneStatus = true;
358
+ * ```
359
+ *
360
+ * and add the following to your XRD's status schema:
361
+ *
362
+ * ```yaml
363
+ * status:
364
+ * properties:
365
+ * xplane:
366
+ * type: object
367
+ * x-kubernetes-preserve-unknown-fields: true
368
+ * ```
369
+ */
370
+ emitXplaneStatus: boolean;
306
371
  constructor();
307
372
  /**
308
373
  * Read-only accessor for Crossplane function pipeline context.
@@ -335,6 +400,8 @@ interface CompositionContext {
335
400
  pipelineContext: ReadonlyMap<string, unknown>;
336
401
  /** Pre-populated data for existing resources (from prior iterations). */
337
402
  requiredResources: ReadonlyMap<string, Record<string, unknown>>;
403
+ /** Pre-populated data for composed resources (from prior iterations), keyed by `Composition/{path}`. */
404
+ observedComposed: ReadonlyMap<string, Record<string, unknown>>;
338
405
  /** The dependency graph for this composition run. */
339
406
  graph: DependencyGraph;
340
407
  /** The edge collector for this composition run. */
@@ -571,6 +638,12 @@ interface EmittedResource {
571
638
  autoReady: boolean;
572
639
  /** Custom readiness checks registered by the composition author. */
573
640
  readyChecks: ReadyCheck[];
641
+ /**
642
+ * True when this resource is blocked (pending dependencies) but has previously-observed
643
+ * state that is being emitted as-is to prevent Crossplane from deleting it.
644
+ * The handler must mark it as READY_FALSE.
645
+ */
646
+ preserved?: boolean;
574
647
  }
575
648
  //#endregion
576
649
  //#region src/pipeline/diagnose.d.ts
@@ -592,6 +665,10 @@ declare function diagnose(state: PipelineState): PipelineState;
592
665
  * Kubernetes resource document ready for Crossplane.
593
666
  *
594
667
  * Also extracts the XR desired status from this.xr.status assignments.
668
+ *
669
+ * For resources classified as 'blocked' that have previously-observed state,
670
+ * emits the observed document as-is (marked `preserved: true`) so that
671
+ * Crossplane does not delete them while their dependencies are still resolving.
595
672
  */
596
673
  declare function emit(state: PipelineState): PipelineState;
597
674
  //#endregion
@@ -663,5 +740,5 @@ declare function runPipeline(input: PipelineInput): PipelineState;
663
740
  */
664
741
  declare function runComposition<TSpec, TStatus, TContext extends object>(CompositionClass: new () => Composition<TSpec, TStatus, TContext>, input: CompositionInput): CompositionResult;
665
742
  //#endregion
666
- export { Composition, type CompositionContext, type CompositionInput, type CompositionModule, type CompositionResult, Construct, DEFAULT_CHECKS, type DependencyEdge, DependencyGraph, type DesiredResource, type Diagnostic, type DiagnosticReport, EdgeCollector, type EmittedResource, type ExternalResourceRef, type ExternalResourceRequest, type KubernetesResource, Pending, PendingTemplate, type PipelineContextAccessor, type PipelineInput, type PipelineState, type ReadProxyMeta, type ReadyCheck, type ReadyCheckFn, Resource, type ResourceClassification, type ResourceConfig, type ResourceProps, type ResourceRef, type XplaneLogger, type XrProxy, compositionStorage, createPrimitiveReadProxy, createReadProxy, createTokenRegistry, createWriteProxy, diagnose, emit, evaluateReadiness, getCompositionContext, getDesiredDocument, getExternalRef, getLogger, getObservedDocument, getReadProxyMeta, getReadyChecks, getResourceInternals, getResourceRef, getXrDesiredStatus, hydrate, hydrateObserved, isExternal, isReadProxy, resolve, runComposition, runPipeline, sequence, tokenRegistryStorage, withLogger };
743
+ export { type BlockedResource, Composition, type CompositionContext, type CompositionInput, type CompositionModule, type CompositionResult, Construct, DEFAULT_CHECKS, type DependencyEdge, DependencyGraph, type DesiredResource, type Diagnostic, type DiagnosticReport, EdgeCollector, type EmittedResource, type ExternalResourceRef, type ExternalResourceRequest, type KubernetesResource, Pending, PendingTemplate, type PipelineContextAccessor, type PipelineInput, type PipelineState, type ReadProxyMeta, type ReadyCheck, type ReadyCheckFn, Resource, type ResourceClassification, type ResourceConfig, type ResourceProps, type ResourceRef, type XplaneLogger, type XrProxy, compositionStorage, createPrimitiveReadProxy, createReadProxy, createTokenRegistry, createWriteProxy, diagnose, emit, evaluateReadiness, getCompositionContext, getDesiredDocument, getExternalRef, getLogger, getObservedDocument, getReadProxyMeta, getReadyChecks, getResourceInternals, getResourceRef, getXrDesiredStatus, hydrate, hydrateObserved, isExternal, isReadProxy, resolve, runComposition, runPipeline, sequence, tokenRegistryStorage, withLogger };
667
744
  //# sourceMappingURL=index.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/contract.ts","../src/tracking/types.ts","../src/tracking/dependency-graph.ts","../src/tracking/read-proxy.ts","../src/tracking/token-registry.ts","../src/tracking/write-proxy.ts","../src/core/composition.ts","../src/core/context.ts","../src/readiness/types.ts","../src/readiness/defaults.ts","../src/readiness/evaluate.ts","../src/core/resource.ts","../src/logging/types.ts","../src/logging/context.ts","../src/pipeline/types.ts","../src/pipeline/diagnose.ts","../src/pipeline/emit.ts","../src/pipeline/hydrate.ts","../src/pipeline/resolve.ts","../src/pipeline/sequence.ts","../src/pipeline/index.ts","../src/run.ts"],"mappings":"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"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/contract.ts","../src/tracking/types.ts","../src/tracking/dependency-graph.ts","../src/tracking/read-proxy.ts","../src/tracking/token-registry.ts","../src/tracking/write-proxy.ts","../src/core/composition.ts","../src/core/context.ts","../src/readiness/types.ts","../src/readiness/defaults.ts","../src/readiness/evaluate.ts","../src/core/resource.ts","../src/logging/types.ts","../src/logging/context.ts","../src/pipeline/types.ts","../src/pipeline/diagnose.ts","../src/pipeline/emit.ts","../src/pipeline/hydrate.ts","../src/pipeline/resolve.ts","../src/pipeline/sequence.ts","../src/pipeline/index.ts","../src/run.ts"],"mappings":"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"}
package/dist/index.mjs CHANGED
@@ -46,6 +46,30 @@ var Composition = class extends Construct$1 {
46
46
  graph;
47
47
  /** The edge collector accumulating dependency edges. */
48
48
  collector;
49
+ /**
50
+ * When `true`, the runtime injects a structured `status.xplane` payload on
51
+ * the XR containing `emittedResources` and `blockedResources`. Defaults to
52
+ * `false` because writing this field requires the XRD's `openAPIV3Schema`
53
+ * to declare `status.xplane` (or `status` to allow unknown fields) — typed
54
+ * patches will otherwise be rejected by Crossplane.
55
+ *
56
+ * To enable, set in your composition's constructor:
57
+ *
58
+ * ```ts
59
+ * this.emitXplaneStatus = true;
60
+ * ```
61
+ *
62
+ * and add the following to your XRD's status schema:
63
+ *
64
+ * ```yaml
65
+ * status:
66
+ * properties:
67
+ * xplane:
68
+ * type: object
69
+ * x-kubernetes-preserve-unknown-fields: true
70
+ * ```
71
+ */
72
+ emitXplaneStatus = false;
49
73
  constructor() {
50
74
  super(void 0, "Composition");
51
75
  const ctx = getCompositionContext();
@@ -625,8 +649,14 @@ var Resource = class Resource extends Construct$1 {
625
649
  collector
626
650
  };
627
651
  internals.set(this, internal);
652
+ const ctx = compositionStorage.getStore();
653
+ if (ctx) {
654
+ const observed = ctx.observedComposed.get(this.node.path);
655
+ if (observed) Object.assign(internal.observed, observed);
656
+ }
628
657
  const proxy = createResourceProxy(this, internal);
629
658
  scope.node._children[this.node.id] = proxy;
659
+ this.node.host = proxy;
630
660
  return proxy;
631
661
  }
632
662
  /**
@@ -948,12 +978,12 @@ function diagnose(state) {
948
978
  if (!ref) continue;
949
979
  const observed = getObservedDocument(resource);
950
980
  if (Object.keys(observed).length > 0) continue;
951
- const nameDisplay = typeof ref.name === "string" ? ref.name : ref.name == null ? "(unresolved)" : "(unresolved)";
981
+ if (typeof ref.name !== "string" || ref.name.startsWith("__pending__")) continue;
952
982
  const nsDisplay = ref.namespace ? ` in namespace '${ref.namespace}'` : "";
953
983
  diagnostics.push({
954
984
  resource: getResourceRef(resource).id,
955
985
  reason: "not-found",
956
- detail: `External resource ${ref.apiVersion}/${ref.kind} '${nameDisplay}'${nsDisplay} was required but not found by Crossplane`
986
+ detail: `External resource ${ref.apiVersion}/${ref.kind} '${ref.name}'${nsDisplay} was required but not found by Crossplane`
957
987
  });
958
988
  }
959
989
  const pendingDiagnostics = [];
@@ -1017,22 +1047,39 @@ function findPendingPaths(obj, basePath) {
1017
1047
  * Kubernetes resource document ready for Crossplane.
1018
1048
  *
1019
1049
  * Also extracts the XR desired status from this.xr.status assignments.
1050
+ *
1051
+ * For resources classified as 'blocked' that have previously-observed state,
1052
+ * emits the observed document as-is (marked `preserved: true`) so that
1053
+ * Crossplane does not delete them while their dependencies are still resolving.
1020
1054
  */
1021
1055
  function emit(state) {
1022
1056
  const emitted = [];
1023
1057
  for (const resource of state.resources) {
1024
1058
  if (isExternal(resource)) continue;
1025
1059
  const ref = getResourceRef(resource);
1026
- if (state.classification.get(ref.id) !== "emit") continue;
1027
- const internal = getResourceInternals(resource);
1028
- const desired = getDesiredDocument(resource);
1029
- const name = ref.id.startsWith("Composition/") ? ref.id.slice(12) : ref.id;
1030
- emitted.push({
1031
- name,
1032
- document: deepClean(desired),
1033
- autoReady: internal.config.autoReady,
1034
- readyChecks: getReadyChecks(resource)
1035
- });
1060
+ const classification = state.classification.get(ref.id);
1061
+ if (classification === "emit") {
1062
+ const internal = getResourceInternals(resource);
1063
+ const desired = getDesiredDocument(resource);
1064
+ const name = ref.id.startsWith("Composition/") ? ref.id.slice(12) : ref.id;
1065
+ emitted.push({
1066
+ name,
1067
+ document: deepClean(desired),
1068
+ autoReady: internal.config.autoReady,
1069
+ readyChecks: getReadyChecks(resource)
1070
+ });
1071
+ } else if (classification === "blocked") {
1072
+ const observed = getObservedDocument(resource);
1073
+ if (Object.keys(observed).length === 0) continue;
1074
+ const name = ref.id.startsWith("Composition/") ? ref.id.slice(12) : ref.id;
1075
+ emitted.push({
1076
+ name,
1077
+ document: stripServerFields(deepClean(observed)),
1078
+ autoReady: false,
1079
+ readyChecks: [],
1080
+ preserved: true
1081
+ });
1082
+ }
1036
1083
  }
1037
1084
  const resourceById = new Map(state.resources.map((r) => [getResourceRef(r).id, r]));
1038
1085
  const xrStatusPatches = resolveXrStatus(getXrDesiredStatus(state.composition), resourceById);
@@ -1061,6 +1108,36 @@ function cleanValue(value) {
1061
1108
  return result;
1062
1109
  }
1063
1110
  /**
1111
+ * Strip server-managed Kubernetes fields from an observed document before
1112
+ * emitting it as a preserved desired resource.
1113
+ *
1114
+ * These fields are set by the API server / controllers and must not appear
1115
+ * in the desired state — including them causes Crossplane to try propagating
1116
+ * them (e.g. `uid`) into XR resourceRefs fields that the XRD schema may not
1117
+ * declare, resulting in a typed-patch validation failure.
1118
+ */
1119
+ const SERVER_MANAGED_METADATA = new Set([
1120
+ "uid",
1121
+ "resourceVersion",
1122
+ "generation",
1123
+ "creationTimestamp",
1124
+ "deletionTimestamp",
1125
+ "deletionGracePeriodSeconds",
1126
+ "managedFields",
1127
+ "ownerReferences",
1128
+ "selfLink"
1129
+ ]);
1130
+ function stripServerFields(doc) {
1131
+ const result = { ...doc };
1132
+ delete result.status;
1133
+ if (result.metadata && typeof result.metadata === "object") {
1134
+ const meta = { ...result.metadata };
1135
+ for (const field of SERVER_MANAGED_METADATA) delete meta[field];
1136
+ result.metadata = meta;
1137
+ }
1138
+ return result;
1139
+ }
1140
+ /**
1064
1141
  * Resolve ReadProxy values in XR status using observed resource data.
1065
1142
  * This is needed because XR status is written at construction time (before hydration),
1066
1143
  * so read proxy references need to be resolved post-hydration.
@@ -1316,6 +1393,18 @@ function conditionReady(observed) {
1316
1393
  return ready.status === "True";
1317
1394
  }
1318
1395
  /**
1396
+ * Vetoes readiness when a `Synced` condition is explicitly `False` (Crossplane
1397
+ * provider reconciliation error). Returns `undefined` otherwise so this check
1398
+ * does not by itself imply readiness — it only blocks it.
1399
+ */
1400
+ function syncedNotFalse(observed) {
1401
+ const conditions = observed.status?.conditions;
1402
+ if (!conditions || !Array.isArray(conditions)) return void 0;
1403
+ const synced = conditions.find((c) => c.type === "Synced");
1404
+ if (!synced) return void 0;
1405
+ return synced.status === "False" ? false : void 0;
1406
+ }
1407
+ /**
1319
1408
  * Checks if the resource has `status.ready === true`.
1320
1409
  */
1321
1410
  function statusReady(observed) {
@@ -1340,6 +1429,11 @@ const DEFAULT_CHECKS = [
1340
1429
  priority: 100,
1341
1430
  name: "conditionReady"
1342
1431
  },
1432
+ {
1433
+ fn: syncedNotFalse,
1434
+ priority: 100,
1435
+ name: "syncedNotFalse"
1436
+ },
1343
1437
  {
1344
1438
  fn: statusReady,
1345
1439
  priority: 200,
@@ -1435,22 +1529,36 @@ function runComposition(CompositionClass, input) {
1435
1529
  xr: input.xr,
1436
1530
  pipelineContext,
1437
1531
  requiredResources: observedRequired,
1532
+ observedComposed,
1438
1533
  graph,
1439
1534
  collector
1440
1535
  };
1536
+ const composition = compositionStorage.run(ctx, () => tokenRegistryStorage.run(createTokenRegistry(), () => new CompositionClass()));
1441
1537
  const state = runPipeline({
1442
- composition: compositionStorage.run(ctx, () => tokenRegistryStorage.run(createTokenRegistry(), () => new CompositionClass())),
1538
+ composition,
1443
1539
  observedComposed,
1444
1540
  observedRequired
1445
1541
  });
1446
1542
  const resources = state.emitted.map((emitted) => {
1543
+ const k8sName = extractMetadataName(emitted.document);
1544
+ const namespace = extractMetadataNamespace(emitted.document);
1545
+ if (emitted.preserved) return {
1546
+ nodePath: emitted.name,
1547
+ document: emitted.document,
1548
+ ready: false,
1549
+ preserved: true,
1550
+ ...k8sName ? { name: k8sName } : {},
1551
+ ...namespace ? { namespace } : {}
1552
+ };
1447
1553
  const allChecks = [...emitted.readyChecks, ...DEFAULT_CHECKS];
1448
1554
  const observed = observedComposed.get(`Composition/${emitted.name}`);
1449
1555
  const ready = emitted.autoReady ? evaluateReadiness(allChecks, observed) : true;
1450
1556
  return {
1451
- name: emitted.name,
1557
+ nodePath: emitted.name,
1452
1558
  document: emitted.document,
1453
- ready
1559
+ ready,
1560
+ ...k8sName ? { name: k8sName } : {},
1561
+ ...namespace ? { namespace } : {}
1454
1562
  };
1455
1563
  });
1456
1564
  const externalResources = [];
@@ -1472,17 +1580,58 @@ function runComposition(CompositionClass, input) {
1472
1580
  if (isExternal(resource)) continue;
1473
1581
  const ref = getResourceRef(resource);
1474
1582
  if (state.classification.get(ref.id) !== "blocked") continue;
1475
- const name = ref.id.startsWith("Composition/") ? ref.id.slice(12) : ref.id;
1476
- blockedResources.push(name);
1583
+ const nodePath = ref.id.startsWith("Composition/") ? ref.id.slice(12) : ref.id;
1584
+ const desired = getDesiredDocument(resource);
1585
+ const apiVersion = typeof desired.apiVersion === "string" ? desired.apiVersion : "";
1586
+ const kind = typeof desired.kind === "string" ? desired.kind : "";
1587
+ const k8sName = extractMetadataName(desired);
1588
+ const namespace = extractMetadataNamespace(desired);
1589
+ const waitingFor = describeWaitingFor(nodePath, state.diagnostics);
1590
+ blockedResources.push({
1591
+ nodePath,
1592
+ apiVersion,
1593
+ kind,
1594
+ ...k8sName ? { name: k8sName } : {},
1595
+ ...namespace ? { namespace } : {},
1596
+ ...waitingFor && waitingFor.length > 0 ? { waitingFor } : {}
1597
+ });
1477
1598
  }
1478
1599
  return {
1479
1600
  resources,
1480
1601
  blockedResources,
1481
1602
  externalResources,
1482
1603
  xrStatus: state.xrStatusPatches,
1483
- diagnostics: state.diagnostics
1604
+ diagnostics: state.diagnostics,
1605
+ emitXplaneStatus: composition.emitXplaneStatus === true
1484
1606
  };
1485
1607
  }
1608
+ /**
1609
+ * Build a human-readable `waitingFor` list for a blocked resource from the
1610
+ * matching diagnostic. Each entry describes one thing the resource is waiting
1611
+ * on (one entry per pending path, or a single entry for cycle/not-found).
1612
+ */
1613
+ function describeWaitingFor(name, diagnostics) {
1614
+ const id = `Composition/${name}`;
1615
+ const diag = diagnostics.find((d) => d.resource === id || d.resource === name);
1616
+ if (!diag) return void 0;
1617
+ if (diag.reason === "cycle") return [`circular dependency: ${(diag.cycle ?? []).join(" → ")}`];
1618
+ if (diag.reason === "not-found") return [diag.detail ?? "external resource not found"];
1619
+ if (diag.pendingPaths && diag.pendingPaths.length > 0) return diag.pendingPaths.map((p) => {
1620
+ return `${p.waitingOn.resource.startsWith("Composition/") ? p.waitingOn.resource.slice(12) : p.waitingOn.resource}.${p.waitingOn.path}`;
1621
+ });
1622
+ }
1623
+ function extractMetadataName(doc) {
1624
+ const metadata = doc.metadata;
1625
+ if (!metadata || typeof metadata !== "object") return void 0;
1626
+ const name = metadata.name;
1627
+ return typeof name === "string" && name.length > 0 ? name : void 0;
1628
+ }
1629
+ function extractMetadataNamespace(doc) {
1630
+ const metadata = doc.metadata;
1631
+ if (!metadata || typeof metadata !== "object") return void 0;
1632
+ const namespace = metadata.namespace;
1633
+ return typeof namespace === "string" && namespace.length > 0 ? namespace : void 0;
1634
+ }
1486
1635
  //#endregion
1487
1636
  export { Composition, Construct, DEFAULT_CHECKS, DependencyGraph, EdgeCollector, Pending, PendingTemplate, Resource, compositionStorage, createPrimitiveReadProxy, createReadProxy, createTokenRegistry, createWriteProxy, diagnose, emit, evaluateReadiness, getCompositionContext, getDesiredDocument, getExternalRef, getLogger, getObservedDocument, getReadProxyMeta, getReadyChecks, getResourceInternals, getResourceRef, getXrDesiredStatus, hydrate, hydrateObserved, isExternal, isReadProxy, resolve, runComposition, runPipeline, sequence, tokenRegistryStorage, withLogger };
1488
1637
 
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["Construct","tryExtractPrimitive","Construct","tryExtractPrimitive","getNestedValue"],"sources":["../src/core/context.ts","../src/core/composition.ts","../src/tracking/dependency-graph.ts","../src/tracking/types.ts","../src/tracking/token-registry.ts","../src/tracking/read-proxy.ts","../src/tracking/write-proxy.ts","../src/core/resource.ts","../src/logging/context.ts","../src/pipeline/diagnose.ts","../src/pipeline/emit.ts","../src/pipeline/hydrate.ts","../src/pipeline/resolve.ts","../src/pipeline/sequence.ts","../src/pipeline/index.ts","../src/readiness/defaults.ts","../src/readiness/evaluate.ts","../src/run.ts"],"sourcesContent":["import { AsyncLocalStorage } from 'node:async_hooks';\n\nimport type { DependencyGraph, EdgeCollector } from '../tracking/index.js';\n\n/**\n * Runtime context passed into a Composition during construction\n * via AsyncLocalStorage. Holds everything the Composition needs\n * without relying on static state or globalThis.\n */\nexport interface CompositionContext {\n /** Observed XR data. */\n xr: Record<string, unknown>;\n /** Full Crossplane function pipeline context (all keys). */\n pipelineContext: ReadonlyMap<string, unknown>;\n /** Pre-populated data for existing resources (from prior iterations). */\n requiredResources: ReadonlyMap<string, Record<string, unknown>>;\n /** The dependency graph for this composition run. */\n graph: DependencyGraph;\n /** The edge collector for this composition run. */\n collector: EdgeCollector;\n}\n\n/**\n * AsyncLocalStorage instance that carries the CompositionContext.\n * The handler sets it before constructing the user's Composition,\n * and the Composition constructor reads from it.\n */\nexport const compositionStorage = new AsyncLocalStorage<CompositionContext>();\n\n/**\n * Get the current composition context from AsyncLocalStorage.\n * Throws if called outside of a composition construction scope.\n */\nexport function getCompositionContext(): CompositionContext {\n const ctx = compositionStorage.getStore();\n if (ctx) return ctx;\n\n throw new Error(\n 'No composition context found. Ensure the Composition is constructed within compositionStorage.run().',\n );\n}\n","import { Construct } from 'constructs';\n\nimport type { DependencyGraph, EdgeCollector } from '../tracking/index.js';\nimport { getCompositionContext } from './context.js';\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\n/**\n * Base generics for a Composition.\n * - TSpec: shape of the XR's spec\n * - TStatus: shape of the XR's status (writable)\n * - TContext: shape of the pipeline context map keys→values\n */\nexport type CompositionProps<\n TSpec = Record<string, unknown>,\n TStatus = Record<string, unknown>,\n TContext extends object = Record<string, unknown>,\n> = {\n spec?: TSpec;\n status?: TStatus;\n context?: TContext;\n};\n\n/** The shape of the XR proxy exposed via `this.xr`. */\nexport interface XrProxy<TSpec = Record<string, unknown>, TStatus = Record<string, unknown>> {\n spec: TSpec;\n status: TStatus;\n metadata: {\n name: string;\n namespace?: string;\n labels?: Record<string, string>;\n annotations?: Record<string, string>;\n [key: string]: unknown;\n };\n [key: string]: unknown;\n}\n\n// ─── Composition class ────────────────────────────────────────────────────────\n\n/**\n * Base class for user-authored Crossplane compositions.\n *\n * Users extend this class and define resources in the constructor:\n *\n * ```ts\n * class MyComposition extends Composition<MySpec, MyStatus> {\n * constructor() {\n * super();\n * const vpc = new Vpc(this, 'vpc', { spec: { ... } });\n * this.xr.status.vpcId = vpc.status.atProvider.vpcId;\n * }\n * }\n * ```\n *\n * `this.xr` is a \"desired-first, fallback-to-observed\" proxy over the XR.\n * `this.pipelineContext` provides typed read-only access to Crossplane function context.\n */\nexport class Composition<\n TSpec = Record<string, unknown>,\n TStatus = Record<string, unknown>,\n TContext extends object = Record<string, unknown>,\n> extends Construct {\n /**\n * The XR proxy — reads from desired first (status writes), falls through to observed.\n * Writing to `this.xr.status.*` sets the composite status output.\n */\n readonly xr: XrProxy<TSpec, TStatus>;\n\n /** The dependency graph tracking resource relationships. */\n readonly graph: DependencyGraph;\n\n /** The edge collector accumulating dependency edges. */\n readonly collector: EdgeCollector;\n\n constructor() {\n // Use 'Composition' as the root construct ID\n super(undefined as unknown as Construct, 'Composition');\n\n const ctx = getCompositionContext();\n\n this.graph = ctx.graph;\n this.collector = ctx.collector;\n\n // Set context values on the construct tree so Resources can find them\n this.node.setContext('xplane:graph', ctx.graph);\n this.node.setContext('xplane:collector', ctx.collector);\n\n // Set XR metadata on tree for Resource.uniqueName()\n const xrMeta = ctx.xr.metadata as { name?: string; namespace?: string } | undefined;\n if (xrMeta) {\n this.node.setContext('xplane:xr-meta', xrMeta);\n }\n\n // Build the XR proxy\n this.xr = createXrProxy<TSpec, TStatus>(ctx);\n }\n\n /**\n * Read-only accessor for Crossplane function pipeline context.\n * Keys are the context keys set by Crossplane or prior functions in the pipeline.\n */\n get pipelineContext(): PipelineContextAccessor<TContext> {\n const ctx = getCompositionContext();\n return {\n get<K extends keyof TContext>(key: K): TContext[K] | undefined {\n return ctx.pipelineContext.get(key as string) as TContext[K] | undefined;\n },\n has(key: keyof TContext): boolean {\n return ctx.pipelineContext.has(key as string);\n },\n keys(): IterableIterator<keyof TContext> {\n return ctx.pipelineContext.keys() as IterableIterator<keyof TContext>;\n },\n };\n }\n}\n\n/** Typed read-only interface for pipeline context. */\nexport interface PipelineContextAccessor<TContext extends object = Record<string, unknown>> {\n get<K extends keyof TContext>(key: K): TContext[K] | undefined;\n has(key: keyof TContext): boolean;\n keys(): IterableIterator<keyof TContext>;\n}\n\n// ─── XR Proxy ─────────────────────────────────────────────────────────────────\n\n/**\n * Creates the \"desired-first, fallback-to-observed\" proxy for the XR.\n *\n * - Reading `xr.spec.*` reads from observed XR spec (creates ReadProxy for tracking)\n * - Writing `xr.status.*` writes to a desired-status store (emitted as composite status)\n * - Other reads fall through to observed\n */\nfunction createXrProxy<TSpec, TStatus>(ctx: {\n xr: Record<string, unknown>;\n graph: DependencyGraph;\n collector: EdgeCollector;\n}): XrProxy<TSpec, TStatus> {\n const xrObserved = ctx.xr;\n const xrDesiredStatus: Record<string, unknown> = {};\n\n // The XR ref for dependency tracking\n const xrRef = { id: '__xr__' };\n ctx.graph.addResource(xrRef);\n\n const statusProxy = new Proxy(xrDesiredStatus, {\n get(_target, prop) {\n if (typeof prop === 'symbol') return undefined;\n const key = String(prop);\n // Desired-first\n if (key in xrDesiredStatus) return xrDesiredStatus[key];\n // Fallback to observed status\n const observedStatus = xrObserved.status as Record<string, unknown> | undefined;\n if (observedStatus && key in observedStatus) {\n return observedStatus[key];\n }\n return undefined;\n },\n set(_target, prop, value) {\n if (typeof prop === 'symbol') return false;\n xrDesiredStatus[String(prop)] = value;\n return true;\n },\n has(_target, prop) {\n if (typeof prop === 'symbol') return false;\n const key = String(prop);\n if (key in xrDesiredStatus) return true;\n const observedStatus = xrObserved.status as Record<string, unknown> | undefined;\n return observedStatus ? key in observedStatus : false;\n },\n });\n\n const proxy = new Proxy({} as XrProxy<TSpec, TStatus>, {\n get(_target, prop) {\n if (typeof prop === 'symbol') return undefined;\n const key = String(prop);\n if (key === 'status') return statusProxy;\n // Everything else reads from observed XR\n if (key in xrObserved) return xrObserved[key];\n return undefined;\n },\n set(_target, prop, value) {\n if (typeof prop === 'symbol') return false;\n const key = String(prop);\n if (key === 'status') {\n // Allow replacing entire status\n Object.assign(xrDesiredStatus, value as object);\n return true;\n }\n // Writes to other top-level XR fields are unusual but allowed\n (xrObserved as Record<string, unknown>)[key] = value;\n return true;\n },\n has(_target, prop) {\n if (typeof prop === 'symbol') return false;\n return String(prop) in xrObserved || String(prop) === 'status';\n },\n });\n\n return proxy;\n}\n\n/**\n * Extract the desired XR status from a Composition instance.\n * Used by the emit pipeline phase to produce composite status output.\n */\nexport function getXrDesiredStatus(composition: Composition): Record<string, unknown> {\n // Access the internal status proxy target\n const statusProxy = composition.xr.status;\n // Collect all keys from the status proxy.\n // We intentionally return raw values (including ReadProxy references) so\n // that the emit phase can resolve them from observed resource data.\n const result: Record<string, unknown> = {};\n if (statusProxy && typeof statusProxy === 'object') {\n for (const key of Object.keys(statusProxy)) {\n const value = (statusProxy as Record<string, unknown>)[key];\n if (value != null) {\n result[key] = value;\n }\n }\n }\n return result;\n}\n","import type { DependencyEdge, ResourceRef } from './types.js';\n\n/**\n * Tracks dependency relationships between resources as a directed acyclic graph.\n * Edges are added as resources reference each other's observed state.\n */\nexport class DependencyGraph {\n private readonly _adjacency = new Map<string, Set<string>>();\n private readonly _resources = new Map<string, ResourceRef>();\n private readonly _edges: DependencyEdge[] = [];\n\n addResource(ref: ResourceRef): void {\n this._resources.set(ref.id, ref);\n if (!this._adjacency.has(ref.id)) {\n this._adjacency.set(ref.id, new Set());\n }\n }\n\n addEdge(edge: DependencyEdge): void {\n this.addResource(edge.from);\n this.addResource(edge.to);\n this._adjacency.get(edge.to.id)!.add(edge.from.id);\n this._edges.push(edge);\n }\n\n addEdges(edges: ReadonlyArray<DependencyEdge>): void {\n for (const edge of edges) this.addEdge(edge);\n }\n\n addExplicitDependency(dependent: ResourceRef, dependency: ResourceRef): void {\n this.addResource(dependent);\n this.addResource(dependency);\n this._adjacency.get(dependent.id)!.add(dependency.id);\n }\n\n /** Get the set of resource IDs that `resourceId` depends on. */\n getDependencies(resourceId: string): ReadonlySet<string> {\n return this._adjacency.get(resourceId) ?? new Set();\n }\n\n get resourceIds(): ReadonlyArray<string> {\n return [...this._resources.keys()];\n }\n\n get edges(): ReadonlyArray<DependencyEdge> {\n return this._edges;\n }\n\n /**\n * Returns a topological ordering of resources.\n * If a cycle is detected, returns { order: null, cycle: string[] }.\n */\n topologicalSort(): { order: string[] } | { order: null; cycle: string[] } {\n const visited = new Set<string>();\n const visiting = new Set<string>();\n const sorted: string[] = [];\n\n const visit = (id: string): string[] | null => {\n if (visited.has(id)) return null;\n if (visiting.has(id)) {\n // Build cycle path\n return [...visiting, id];\n }\n visiting.add(id);\n const deps = this._adjacency.get(id);\n if (deps) {\n for (const depId of deps) {\n const cycle = visit(depId);\n if (cycle) return cycle;\n }\n }\n visiting.delete(id);\n visited.add(id);\n sorted.push(id);\n return null;\n };\n\n for (const id of this._resources.keys()) {\n const cycle = visit(id);\n if (cycle) {\n // Trim cycle to start from the repeated node\n const start = cycle[cycle.length - 1]!;\n const startIdx = cycle.indexOf(start);\n return { order: null, cycle: cycle.slice(startIdx) };\n }\n }\n return { order: sorted };\n }\n}\n","/** Identifies a resource in the dependency graph. */\nexport interface ResourceRef {\n readonly id: string;\n}\n\n/** A dependency edge between two resources at specific field paths. */\nexport interface DependencyEdge {\n /** Resource being read from (observed state). */\n readonly from: ResourceRef;\n /** Path in the source resource's observed data. */\n readonly fromPath: string;\n /** Resource being written to (desired state). */\n readonly to: ResourceRef;\n /** Path in the target resource's desired data. */\n readonly toPath: string;\n}\n\n/**\n * A Pending marker stored in a desired document when a ReadProxy value\n * is assigned. Carries full source info so the resolve phase knows\n * where to look for the concrete value.\n */\nconst PENDING_TAG: unique symbol = Symbol.for('xplane.pending') as unknown as typeof PENDING_TAG;\n\nexport class Pending {\n static readonly TAG = PENDING_TAG;\n readonly [PENDING_TAG] = true;\n\n constructor(\n /** The resource that owns the observed data. */\n readonly source: ResourceRef,\n /** The path within that resource's observed data. */\n readonly path: string,\n ) {}\n\n static is(value: unknown): value is Pending {\n return (\n typeof value === 'object' &&\n value !== null &&\n (value as Record<symbol, unknown>)[PENDING_TAG] === true\n );\n }\n}\n\n/** Metadata associated with a ReadProxy instance. */\nexport interface ReadProxyMeta {\n readonly owner: ResourceRef;\n readonly path: string;\n}\n\n// ─── PendingTemplate ─────────────────────────────────────────────────────────\n\n/**\n * A Pending-like marker for strings produced by template literals that\n * interpolate one or more unresolved ReadProxy values.\n *\n * Holds the template structure so the resolve phase can reconstruct the\n * final string once all dependency slots are available.\n *\n * Invariant: parts.length === slots.length + 1\n * result = parts[0] + resolved[0] + parts[1] + … + resolved[n-1] + parts[n]\n */\nconst PENDING_TEMPLATE_TAG: unique symbol = Symbol.for(\n 'xplane.pendingTemplate',\n) as unknown as typeof PENDING_TEMPLATE_TAG;\n\nexport class PendingTemplate {\n static readonly TAG = PENDING_TEMPLATE_TAG;\n readonly [PENDING_TEMPLATE_TAG] = true;\n\n constructor(\n /** Literal text segments between (and around) pending slots. */\n readonly parts: readonly string[],\n /** The pending slots — each maps to an entry in a resource's observed state. */\n readonly slots: ReadonlyArray<{ source: ResourceRef; path: string }>,\n ) {}\n\n static is(value: unknown): value is PendingTemplate {\n return (\n typeof value === 'object' &&\n value !== null &&\n (value as Record<symbol, unknown>)[PENDING_TEMPLATE_TAG] === true\n );\n }\n}\n","import { AsyncLocalStorage } from 'node:async_hooks';\nimport type { ReadProxyMeta, ResourceRef } from './types.js';\nimport { PendingTemplate } from './types.js';\n\n// ─── Token Registry ───────────────────────────────────────────────────────────\n\nexport interface TokenRegistry {\n readonly byToken: Map<string, ReadProxyMeta>;\n readonly byKey: Map<string, string>;\n counter: number;\n}\n\n/**\n * Per-run AsyncLocalStorage for the template-literal token registry.\n * Kept separate from compositionStorage (core/) to avoid circular deps.\n */\nexport const tokenRegistryStorage = new AsyncLocalStorage<TokenRegistry>();\n\nexport function createTokenRegistry(): TokenRegistry {\n return { byToken: new Map(), byKey: new Map(), counter: 0 };\n}\n\n/**\n * Get or create a stable token for a given (owner, path) pair.\n * Returns null when no registry is active (outside of a composition run).\n */\nexport function getOrCreateToken(owner: ResourceRef, path: string): string | null {\n const registry = tokenRegistryStorage.getStore();\n if (!registry) return null;\n\n const key = `${owner.id}\\0${path}`;\n const existing = registry.byKey.get(key);\n if (existing !== undefined) return existing;\n\n const token = `__pending__tpl_${registry.counter++}__`;\n registry.byToken.set(token, { owner, path });\n registry.byKey.set(key, token);\n return token;\n}\n\nexport function lookupToken(token: string): ReadProxyMeta | undefined {\n return tokenRegistryStorage.getStore()?.byToken.get(token);\n}\n\n// ─── String Processing ────────────────────────────────────────────────────────\n\nconst TEMPLATE_TOKEN_RE = /__pending__tpl_\\d+__/g;\n\n/**\n * Scan a string for pending template tokens. If any are found, calls\n * `onSlot` for each registered token and returns a PendingTemplate.\n * Returns the original string if no tokens are found or none are registered.\n */\nexport function processStringValue(\n value: string,\n onSlot: (meta: ReadProxyMeta) => void,\n): PendingTemplate | string {\n const parts: string[] = [];\n const slots: Array<{ source: ResourceRef; path: string }> = [];\n let lastIndex = 0;\n let hasSlots = false;\n\n // Reset lastIndex before iterating (regex is stateful)\n TEMPLATE_TOKEN_RE.lastIndex = 0;\n\n for (const match of value.matchAll(TEMPLATE_TOKEN_RE)) {\n const meta = lookupToken(match[0]!);\n if (!meta) continue; // token not in registry — treat as literal\n\n hasSlots = true;\n parts.push(value.slice(lastIndex, match.index!));\n slots.push({ source: meta.owner, path: meta.path });\n onSlot(meta);\n lastIndex = match.index! + match[0]!.length;\n }\n\n if (!hasSlots) return value;\n\n parts.push(value.slice(lastIndex));\n return new PendingTemplate(parts, slots);\n}\n","import { getOrCreateToken } from './token-registry.js';\nimport type { ReadProxyMeta, ResourceRef } from './types.js';\n\n/**\n * WeakMap storing metadata for ReadProxy instances.\n * This avoids polluting proxy objects with symbols.\n */\nconst proxyMeta = new WeakMap<object, ReadProxyMeta>();\n\n/** Sentinel symbol to identify ReadProxy instances. */\nconst READ_PROXY_TAG = Symbol.for('xplane.readProxy');\n\n/**\n * Check if a value is a ReadProxy.\n */\nexport function isReadProxy(value: unknown): value is object {\n return (\n typeof value === 'object' &&\n value !== null &&\n (value as Record<symbol, unknown>)[READ_PROXY_TAG] === true\n );\n}\n\n/**\n * Get the metadata for a ReadProxy value.\n */\nexport function getReadProxyMeta(value: unknown): ReadProxyMeta | undefined {\n if (!isReadProxy(value)) return undefined;\n return proxyMeta.get(value as object);\n}\n\n/**\n * Creates a ReadProxy that wraps observed data.\n *\n * - Property access navigates into the data, building up the path.\n * - Missing paths return `undefined` (no placeholder proxies).\n * - The proxy carries owner + path metadata so that when it's assigned\n * to a WriteProxy, the dependency edge can be recorded.\n */\nexport function createReadProxy<T extends object>(\n target: T,\n owner: ResourceRef,\n basePath: string,\n): T {\n const proxy = new Proxy(target, {\n get(obj, prop, receiver) {\n // Identity checks\n if (prop === READ_PROXY_TAG) return true;\n if (typeof prop === 'symbol') return Reflect.get(obj, prop, receiver);\n if (prop === 'toJSON') return () => obj;\n\n const childPath = basePath ? `${basePath}.${String(prop)}` : String(prop);\n const value = Reflect.get(obj, prop, receiver);\n\n if (value === undefined || value === null) {\n // Return a \"leaf\" proxy with undefined target — carries metadata\n // for dependency edge creation but resolves to undefined\n return createLeafReadProxy(owner, childPath);\n }\n\n if (typeof value === 'object') {\n // Wrap nested objects so path accumulates\n return createReadProxy(value as object, owner, childPath);\n }\n\n // Primitive — wrap in a tagged object so it can carry metadata\n // when assigned to a WriteProxy\n return createPrimitiveReadProxy(value as string | number | boolean, owner, childPath);\n },\n\n has(obj, prop) {\n if (prop === READ_PROXY_TAG) return true;\n return Reflect.has(obj, prop);\n },\n });\n\n proxyMeta.set(proxy, { owner, path: basePath });\n return proxy as T;\n}\n\n/**\n * A \"leaf\" ReadProxy for paths that don't exist in observed data yet.\n * Carries metadata for edge creation. Resolves to `undefined` when\n * coerced to a primitive.\n */\nfunction createLeafReadProxy(owner: ResourceRef, path: string): object {\n const target = Object.create(null) as Record<string | symbol, unknown>;\n const getToken = () => getOrCreateToken(owner, path) ?? `__pending__${owner.id}__${path}`;\n const proxy = new Proxy(target, {\n get(_obj, prop) {\n if (prop === READ_PROXY_TAG) return true;\n if (prop === Symbol.toPrimitive) return () => getToken();\n if (typeof prop === 'symbol') return undefined;\n if (prop === 'toJSON') return () => undefined;\n if (prop === 'toString') return () => getToken();\n if (prop === 'valueOf') return () => proxy;\n // Nested access on a leaf — still a leaf with extended path\n return createLeafReadProxy(owner, `${path}.${String(prop)}`);\n },\n has(_obj, prop) {\n if (prop === READ_PROXY_TAG) return true;\n return false;\n },\n });\n proxyMeta.set(proxy, { owner, path });\n return proxy;\n}\n\n/**\n * Wraps a concrete primitive value so it carries ReadProxy metadata.\n * This allows the WriteProxy to detect it during assignment and\n * record the dependency edge, while the value itself resolves correctly.\n */\nexport function createPrimitiveReadProxy(\n value: string | number | boolean,\n owner: ResourceRef,\n path: string,\n): object {\n const target = Object.create(null) as Record<string | symbol, unknown>;\n const proxy = new Proxy(target, {\n get(_obj, prop) {\n if (prop === READ_PROXY_TAG) return true;\n if (prop === Symbol.toPrimitive) return () => value;\n if (prop === 'valueOf') return () => value;\n if (prop === 'toString') return () => String(value);\n if (prop === 'toJSON') return () => value;\n if (typeof prop === 'symbol') return undefined;\n // Navigating into a primitive — leaf\n return createLeafReadProxy(owner, `${path}.${String(prop)}`);\n },\n has(_obj, prop) {\n if (prop === READ_PROXY_TAG) return true;\n return false;\n },\n });\n proxyMeta.set(proxy, { owner, path });\n return proxy;\n}\n","import {\n createPrimitiveReadProxy,\n createReadProxy,\n getReadProxyMeta,\n isReadProxy,\n} from './read-proxy.js';\nimport { processStringValue } from './token-registry.js';\nimport { type DependencyEdge, Pending, type ResourceRef } from './types.js';\n\n/**\n * Collector that accumulates dependency edges discovered during\n * WriteProxy assignments.\n */\nexport class EdgeCollector {\n private readonly _edges: DependencyEdge[] = [];\n\n add(edge: DependencyEdge): void {\n // Deduplicate\n const exists = this._edges.some(\n (e) =>\n e.from.id === edge.from.id &&\n e.fromPath === edge.fromPath &&\n e.to.id === edge.to.id &&\n e.toPath === edge.toPath,\n );\n if (!exists) this._edges.push(edge);\n }\n\n get edges(): ReadonlyArray<DependencyEdge> {\n return this._edges;\n }\n}\n\nexport interface WriteProxyOptions {\n /** The resource that owns this desired document. */\n owner: ResourceRef;\n /** The collector to record edges into. */\n collector: EdgeCollector;\n /** Base path prefix (e.g., \"spec\" when wrapping the spec subtree). */\n basePath?: string;\n /** Optional observed state at the same path for fallback reads. */\n observed?: Record<string, unknown>;\n}\n\n/**\n * Creates a WriteProxy that wraps a desired document.\n *\n * - Writes store values in the target.\n * - When a ReadProxy value is assigned, it records a dependency edge\n * and stores a Pending marker if the value is not yet concrete.\n * - Reads return the stored value (desired-first).\n */\nexport function createWriteProxy<T extends object>(target: T, opts: WriteProxyOptions): T {\n const { owner, collector, basePath = '', observed } = opts;\n\n return new Proxy(target, {\n get(obj, prop, receiver) {\n if (typeof prop === 'symbol') return Reflect.get(obj, prop, receiver);\n if (prop === 'toJSON') return () => obj;\n\n const value = Reflect.get(obj, prop, receiver);\n\n // If the value is a nested object (not a Pending), wrap it recursively\n if (typeof value === 'object' && value !== null && !Pending.is(value)) {\n const childPath = basePath ? `${basePath}.${String(prop)}` : String(prop);\n const childObserved =\n observed && String(prop) in observed && typeof observed[String(prop)] === 'object'\n ? (observed[String(prop)] as Record<string, unknown>)\n : undefined;\n return createWriteProxy(value as object, {\n owner,\n collector,\n basePath: childPath,\n observed: childObserved,\n });\n }\n\n // If value is undefined and observed has data at this path, fall through to ReadProxy\n if (value === undefined && observed && String(prop) in observed) {\n const childPath = basePath ? `${basePath}.${String(prop)}` : String(prop);\n const obsValue = observed[String(prop)];\n if (typeof obsValue === 'object' && obsValue !== null) {\n return createReadProxy(obsValue as object, owner, childPath);\n }\n if (obsValue !== undefined && obsValue !== null) {\n return createPrimitiveReadProxy(obsValue as string | number | boolean, owner, childPath);\n }\n }\n\n // If value is undefined and observed doesn't have it either, return a leaf ReadProxy\n // so that cross-resource references create proper dependency edges and Pending markers\n if (value === undefined && observed !== undefined) {\n const childPath = basePath ? `${basePath}.${String(prop)}` : String(prop);\n return createReadProxy(Object.create(null) as object, owner, childPath);\n }\n\n return value;\n },\n\n set(obj, prop, value) {\n if (typeof prop === 'symbol') return Reflect.set(obj, prop, value);\n\n const targetPath = basePath ? `${basePath}.${String(prop)}` : String(prop);\n\n // Check if the value being assigned is a ReadProxy\n if (isReadProxy(value)) {\n const meta = getReadProxyMeta(value);\n if (meta && meta.owner.id !== owner.id) {\n // Record dependency edge\n collector.add({\n from: meta.owner,\n fromPath: meta.path,\n to: owner,\n toPath: targetPath,\n });\n\n // Try to extract a concrete value via Symbol.toPrimitive\n const primitive = tryExtractPrimitive(value);\n if (primitive !== undefined) {\n // The value is already concrete (primitive from observed data)\n return Reflect.set(obj, prop, primitive);\n }\n\n // Not concrete — store a Pending marker\n return Reflect.set(obj, prop, new Pending(meta.owner, meta.path));\n }\n\n // Self-reference or XR — try to extract value\n const primitive = tryExtractPrimitive(value);\n if (primitive !== undefined) {\n return Reflect.set(obj, prop, primitive);\n }\n\n // XR leaf with no value — store Pending\n if (meta) {\n collector.add({\n from: meta.owner,\n fromPath: meta.path,\n to: owner,\n toPath: targetPath,\n });\n return Reflect.set(obj, prop, new Pending(meta.owner, meta.path));\n }\n }\n\n // String with pending template tokens\n if (typeof value === 'string') {\n const processed = processStringValue(value, (meta) => {\n collector.add({ from: meta.owner, fromPath: meta.path, to: owner, toPath: targetPath });\n });\n return Reflect.set(obj, prop, processed);\n }\n\n // Plain object — deep-process to catch nested ReadProxy values\n if (typeof value === 'object' && value !== null && !Pending.is(value)) {\n const processed = deepProcessValue(value, owner, targetPath, collector);\n return Reflect.set(obj, prop, processed);\n }\n\n return Reflect.set(obj, prop, value);\n },\n\n deleteProperty(obj, prop) {\n return Reflect.deleteProperty(obj, prop);\n },\n }) as T;\n}\n\n/**\n * Try to extract a primitive value from a ReadProxy via Symbol.toPrimitive.\n * Returns `undefined` if the proxy represents a non-existent (leaf) value.\n */\nfunction tryExtractPrimitive(proxy: object): string | number | boolean | undefined {\n const toPrim = (proxy as Record<symbol, unknown>)[Symbol.toPrimitive];\n if (typeof toPrim === 'function') {\n const result = (toPrim as () => unknown)();\n if (result !== undefined && result !== null && typeof result !== 'object') {\n // Leaf proxy placeholders are not real values\n if (typeof result === 'string' && result.startsWith('__pending__')) return undefined;\n return result as string | number | boolean;\n }\n }\n return undefined;\n}\n\n/**\n * Deep-process a plain object/array being assigned to a WriteProxy.\n * Replaces any nested ReadProxy values with Pending markers or concrete values.\n */\nfunction deepProcessValue(\n value: unknown,\n owner: ResourceRef,\n basePath: string,\n collector: EdgeCollector,\n): unknown {\n if (value === null || value === undefined) return value;\n\n if (typeof value === 'string') {\n return processStringValue(value, (meta) => {\n collector.add({ from: meta.owner, fromPath: meta.path, to: owner, toPath: basePath });\n });\n }\n\n if (typeof value !== 'object') return value;\n\n if (isReadProxy(value)) {\n const meta = getReadProxyMeta(value)!;\n collector.add({\n from: meta.owner,\n fromPath: meta.path,\n to: owner,\n toPath: basePath,\n });\n const primitive = tryExtractPrimitive(value as object);\n if (primitive !== undefined) return primitive;\n return new Pending(meta.owner, meta.path);\n }\n\n if (Array.isArray(value as object)) {\n return (value as unknown[]).map((item, i) =>\n deepProcessValue(item, owner, `${basePath}[${i}]`, collector),\n );\n }\n\n // Plain object — recurse\n const result: Record<string, unknown> = {};\n for (const [key, val] of Object.entries(value as Record<string, unknown>)) {\n result[key] = deepProcessValue(val, owner, `${basePath}.${key}`, collector);\n }\n return result;\n}\n","import { Construct } from 'constructs';\n\nimport type { ReadyCheck, ReadyCheckFn } from '../readiness/index.js';\nimport {\n createPrimitiveReadProxy,\n createReadProxy,\n createWriteProxy,\n type DependencyGraph,\n type EdgeCollector,\n getReadProxyMeta,\n isReadProxy,\n Pending,\n type ResourceRef,\n} from '../tracking/index.js';\nimport { processStringValue } from '../tracking/token-registry.js';\nimport { compositionStorage } from './context.js';\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\n/** Minimal shape for a Kubernetes resource — only apiVersion + kind required. */\nexport interface KubernetesResource {\n apiVersion: string;\n kind: string;\n metadata?: {\n name?: string;\n namespace?: string;\n labels?: Record<string, string>;\n annotations?: Record<string, string>;\n [key: string]: unknown;\n };\n [key: string]: unknown;\n}\n\n/** Props passed to the Resource constructor — becomes the desired document. */\nexport interface ResourceProps {\n apiVersion: string;\n kind: string;\n [key: string]: unknown;\n}\n\n/** Framework configuration accessible via `resource.resource`. */\nexport interface ResourceConfig {\n autoReady: boolean;\n addReadyCheck(fn: ReadyCheckFn, priority?: number): void;\n}\n\n/** Internal metadata stored per Resource (not exposed on the proxy). */\ninterface ResourceInternals {\n /** Unique reference for the dependency graph. */\n ref: ResourceRef;\n /** The desired document (what the user wrote). */\n desired: Record<string, unknown>;\n /** The observed document (populated by the hydrate phase). */\n observed: Record<string, unknown>;\n /** Whether this is an external (existing) resource. */\n external: boolean;\n /** For external resources: the lookup key. */\n externalRef?: ExternalResourceRef;\n /** Framework config. */\n config: ResourceConfig;\n /** Custom readiness checks registered by the composition author. */\n readyChecks: ReadyCheck[];\n /** The dependency graph. */\n graph: DependencyGraph;\n /** The edge collector. */\n collector: EdgeCollector;\n}\n\nexport interface ExternalResourceRef {\n apiVersion: string;\n kind: string;\n name: unknown;\n namespace?: string;\n refKey: string;\n}\n\n// ─── WeakMap stores for internal data ─────────────────────────────────────────\n\nconst internals = new WeakMap<Resource, ResourceInternals>();\n\n// ─── Resource class ───────────────────────────────────────────────────────────\n\n/**\n * A Kubernetes resource within a Composition.\n *\n * The Resource instance acts as a \"desired-first, fallback-to-observed\" proxy:\n * - Reading a path that exists in the desired document returns the desired value.\n * - Reading a path that does NOT exist in desired falls through to a tracked\n * ReadProxy over observed state (creates dependency edges).\n * - Writing always goes to the desired document.\n *\n * The only reserved properties are `node` (from Construct) and `resource`\n * (framework config namespace).\n */\nexport class Resource extends Construct {\n readonly resource: ResourceConfig;\n declare metadata: {\n name?: string;\n namespace?: string;\n labels?: Record<string, string>;\n annotations?: Record<string, string>;\n [key: string]: unknown;\n };\n\n constructor(scope: Construct, id: string, props: ResourceProps) {\n super(scope, id);\n\n const graph = scope.node.tryGetContext('xplane:graph') as DependencyGraph;\n const collector = scope.node.tryGetContext('xplane:collector') as EdgeCollector;\n\n if (!graph || !collector) {\n throw new Error('Resource must be created within a Composition tree.');\n }\n\n const ref: ResourceRef = { id: this.node.path };\n graph.addResource(ref);\n\n const readyChecks: ReadyCheck[] = [];\n const config: ResourceConfig = {\n autoReady: true,\n addReadyCheck(fn: ReadyCheckFn, priority = 50) {\n readyChecks.push({ fn, priority });\n },\n };\n this.resource = config;\n\n // Process props — deep scan for ReadProxy values in the desired doc\n const desired = processDesiredProps(props, ref, collector);\n\n const internal: ResourceInternals = {\n ref,\n desired,\n observed: {},\n external: false,\n config,\n readyChecks,\n graph,\n collector,\n };\n internals.set(this, internal);\n\n // Return a proxy over `this` that implements the desired-first/observed-fallback\n const proxy = createResourceProxy(this, internal);\n\n // Patch the construct tree so node.children / findAll() yield the proxy\n // instead of the raw instance (which was registered during super()).\n // biome-ignore lint/suspicious/noExplicitAny: accessing private _children is intentional\n (scope.node as any)._children[this.node.id] = proxy;\n\n // biome-ignore lint/correctness/noConstructorReturn: Proxy wrapping is intentional\n return proxy;\n }\n\n /**\n * Look up an existing cluster resource by name.\n * Returns a Resource that only has observed state (no desired output).\n *\n * The `name` parameter accepts either a plain string or a PrimitiveReadProxy\n * (returned when reading a tracked property like `ns.metadata.labels['x']`).\n * Proxies are coerced to their underlying string via `Symbol.toPrimitive`.\n */\n static fromExistingByName(\n scope: Construct,\n apiVersion: string,\n kind: string,\n name: unknown,\n namespace?: string,\n ): Resource {\n const resolvedName = coerceToString(name);\n const refKey = computeRefKey(apiVersion, kind, resolvedName, namespace);\n const id = `__existing__${refKey.replace(/\\//g, '_')}`;\n\n const instance = new Resource(scope, id, { apiVersion, kind });\n const internal = internals.get(instance)!;\n internal.external = true;\n internal.externalRef = { apiVersion, kind, name: resolvedName ?? name, namespace, refKey };\n\n // Pre-hydrate from context if observed data is already available (from a prior iteration)\n const ctx = compositionStorage.getStore();\n if (ctx) {\n const observed = ctx.requiredResources.get(refKey);\n if (observed) {\n Object.assign(internal.observed, observed);\n }\n }\n\n return instance;\n }\n\n /**\n * Generate a deterministic unique name based on the XR identity and construct path.\n * Useful for resource fields that need unique names (e.g., AWS resource names).\n */\n static uniqueName(\n scope: Construct,\n options: {\n maxLength?: number;\n separator?: string;\n allowedPattern?: RegExp;\n extra?: string;\n } = {},\n ): string {\n const maxLength = options.maxLength ?? 63;\n const separator = options.separator ?? '-';\n const allowedPattern = options.allowedPattern ?? /[^a-zA-Z0-9]/g;\n const escapedSep = separator.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n const collapseRe = new RegExp(`${escapedSep}+`, 'g');\n\n const clean = (s: string) =>\n s\n .replace(/\\s+/g, '')\n .replace(allowedPattern, separator)\n .replace(collapseRe, separator)\n .replace(new RegExp(`^${escapedSep}|${escapedSep}$`, 'g'), '');\n\n const xrMeta = scope.node.tryGetContext('xplane:xr-meta') as\n | { name?: string; namespace?: string }\n | undefined;\n\n const parts: string[] = [];\n if (xrMeta?.namespace) parts.push(clean(xrMeta.namespace));\n if (xrMeta?.name) parts.push(clean(xrMeta.name));\n for (const s of scope.node.scopes.slice(1)) {\n const c = clean(s.node.id);\n if (c) parts.push(c);\n }\n if (options.extra) {\n const c = clean(options.extra);\n if (c) parts.push(c);\n }\n\n const full = parts.join(separator);\n const hash = shortHash(full);\n const withHash = `${full}${separator}${hash}`;\n\n if (withHash.length <= maxLength) return withHash;\n const prefix = full.slice(0, maxLength - hash.length - separator.length);\n return `${prefix}${separator}${hash}`;\n }\n\n /**\n * Like {@link uniqueName} but produces names compliant with RFC 1123 DNS labels:\n * lowercase alphanumeric characters and hyphens only, starting and ending with\n * an alphanumeric character. Suitable for use as Kubernetes resource names.\n */\n static uniqueNameRfc1123(\n scope: Construct,\n options: {\n maxLength?: number;\n extra?: string;\n } = {},\n ): string {\n const maxLength = options.maxLength ?? 63;\n\n const clean = (s: string) =>\n s\n .toLowerCase()\n .replace(/\\s+/g, '')\n .replace(/[^a-z0-9-]/g, '-')\n .replace(/-+/g, '-')\n .replace(/^-|-$/g, '');\n\n const xrMeta = scope.node.tryGetContext('xplane:xr-meta') as\n | { name?: string; namespace?: string }\n | undefined;\n\n const parts: string[] = [];\n if (xrMeta?.namespace) parts.push(clean(xrMeta.namespace));\n if (xrMeta?.name) parts.push(clean(xrMeta.name));\n for (const s of scope.node.scopes.slice(1)) {\n const c = clean(s.node.id);\n if (c) parts.push(c);\n }\n if (options.extra) {\n const c = clean(options.extra);\n if (c) parts.push(c);\n }\n\n const full = parts.join('-');\n const hash = shortHash(full);\n const withHash = `${full}-${hash}`;\n\n if (withHash.length <= maxLength) return withHash;\n const prefix = full.slice(0, maxLength - hash.length - 1);\n const trimmedPrefix = prefix.replace(/-+$/, '');\n return trimmedPrefix ? `${trimmedPrefix}-${hash}` : hash;\n }\n}\n\n// ─── Internal accessors (used by pipeline phases) ─────────────────────────────\n\nexport function getResourceInternals(resource: Resource): ResourceInternals {\n const internal = internals.get(resource);\n if (!internal) throw new Error('Resource internals not found');\n return internal;\n}\n\nexport function getResourceRef(resource: Resource): ResourceRef {\n return getResourceInternals(resource).ref;\n}\n\nexport function getDesiredDocument(resource: Resource): Record<string, unknown> {\n return getResourceInternals(resource).desired;\n}\n\nexport function getObservedDocument(resource: Resource): Record<string, unknown> {\n return getResourceInternals(resource).observed;\n}\n\nexport function hydrateObserved(resource: Resource, data: Record<string, unknown>): void {\n const internal = getResourceInternals(resource);\n Object.assign(internal.observed, data);\n}\n\nexport function isExternal(resource: Resource): boolean {\n return getResourceInternals(resource).external;\n}\n\nexport function getExternalRef(resource: Resource): ExternalResourceRef | undefined {\n return getResourceInternals(resource).externalRef;\n}\n\nexport function getReadyChecks(resource: Resource): ReadyCheck[] {\n return getResourceInternals(resource).readyChecks;\n}\n\n// ─── Helpers ──────────────────────────────────────────────────────────────────\n\n/**\n * Coerce a value to a string, handling PrimitiveReadProxy objects that wrap\n * primitive values behind a `Symbol.toPrimitive` method.\n * Returns `undefined` if the value cannot be resolved to a string.\n */\nfunction coerceToString(value: unknown): string | undefined {\n if (typeof value === 'string') return value;\n if (\n value != null &&\n typeof (value as { [Symbol.toPrimitive]?: unknown })[Symbol.toPrimitive] === 'function'\n ) {\n return String(value);\n }\n return undefined;\n}\n\nexport function computeRefKey(\n apiVersion: string,\n kind: string,\n name: string | undefined,\n namespace?: string,\n): string {\n const namePart = name ?? '__unresolved__';\n if (namespace) return `${apiVersion}/${kind}/${namespace}/${namePart}`;\n return `${apiVersion}/${kind}/${namePart}`;\n}\n\nfunction shortHash(s: string): string {\n let h = 5381;\n for (let i = 0; i < s.length; i++) {\n h = ((h << 5) + h) ^ s.charCodeAt(i);\n h = h >>> 0;\n }\n return h.toString(16).padStart(8, '0');\n}\n\n/**\n * Process the desired props — deep-scan for ReadProxy values and replace them\n * with Pending markers (recording edges in the collector).\n */\nfunction processDesiredProps(\n props: ResourceProps,\n owner: ResourceRef,\n collector: EdgeCollector,\n): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(props)) {\n result[key] = processValue(value, owner, key, collector);\n }\n return result;\n}\n\nfunction processValue(\n value: unknown,\n owner: ResourceRef,\n path: string,\n collector: EdgeCollector,\n): unknown {\n if (value === null || value === undefined) return value;\n\n if (typeof value === 'string') {\n return processStringValue(value, (meta) => {\n collector.add({ from: meta.owner, fromPath: meta.path, to: owner, toPath: path });\n });\n }\n\n if (typeof value !== 'object') return value;\n\n if (isReadProxy(value)) {\n const meta = getReadProxyMeta(value)!;\n collector.add({\n from: meta.owner,\n fromPath: meta.path,\n to: owner,\n toPath: path,\n });\n // Try to get concrete value\n const prim = tryExtractPrimitive(value);\n if (prim !== undefined) return prim;\n return new Pending(meta.owner, meta.path);\n }\n\n if (Array.isArray(value as object)) {\n return (value as unknown[]).map((item, i) =>\n processValue(item, owner, `${path}[${i}]`, collector),\n );\n }\n\n const result: Record<string, unknown> = {};\n for (const [key, val] of Object.entries(value as Record<string, unknown>)) {\n result[key] = processValue(val, owner, `${path}.${key}`, collector);\n }\n return result;\n}\n\nfunction tryExtractPrimitive(proxy: object): string | number | boolean | undefined {\n const toPrim = (proxy as Record<symbol, unknown>)[Symbol.toPrimitive];\n if (typeof toPrim === 'function') {\n const result = (toPrim as () => unknown)();\n if (result !== undefined && result !== null && typeof result !== 'object') {\n // Leaf proxy placeholders are not real values\n if (typeof result === 'string' && result.startsWith('__pending__')) return undefined;\n return result as string | number | boolean;\n }\n }\n return undefined;\n}\n\n/**\n * Creates the \"desired-first, fallback-to-observed\" proxy around a Resource.\n */\nfunction createResourceProxy(resource: Resource, internal: ResourceInternals): Resource {\n const { ref, desired, collector } = internal;\n\n const proxy = new Proxy(resource, {\n get(target, prop, receiver) {\n // Framework reserved properties\n if (prop === 'node') return Reflect.get(target, prop, receiver);\n if (prop === 'resource') return Reflect.get(target, prop, receiver);\n if (typeof prop === 'symbol') return Reflect.get(target, prop, receiver);\n\n // Prototype methods and inherited Construct methods (e.g. .with(), .toString())\n if (prop === 'constructor') return Reflect.get(target, prop, receiver);\n const protoValue = Reflect.get(target, prop, receiver);\n if (typeof protoValue === 'function') return protoValue.bind(proxy);\n\n // Check desired first\n if (prop in desired) {\n const value = desired[String(prop)];\n if (typeof value === 'object' && value !== null && !Pending.is(value)) {\n // Return a WriteProxy so nested writes go to desired\n // Pass observed at the same path for fallback reads\n const observed = internal.observed;\n const observedAtPath =\n String(prop) in observed && typeof observed[String(prop)] === 'object'\n ? (observed[String(prop)] as Record<string, unknown>)\n : {};\n return createWriteProxy(value as object, {\n owner: ref,\n collector,\n basePath: String(prop),\n observed: observedAtPath,\n });\n }\n return value;\n }\n\n // Fallback to observed via ReadProxy\n const observed = internal.observed;\n if (String(prop) in observed) {\n const value = observed[String(prop)];\n if (typeof value === 'object' && value !== null) {\n return createReadProxy(value as object, ref, String(prop));\n }\n // Primitive observed value — wrap in ReadProxy for tracking\n return createPrimitiveReadProxyFromResource(value, ref, String(prop));\n }\n\n // Path exists in neither — return a lazy-init proxy that behaves as a\n // ReadProxy for reads but auto-initializes the path in desired on write.\n return createLazyInitProxy(desired, ref, collector, String(prop));\n },\n\n set(target, prop, value) {\n if (typeof prop === 'symbol') return Reflect.set(target, prop, value);\n if (prop === 'resource') return Reflect.set(target, prop, value);\n\n // All writes go to desired, processing ReadProxy values\n const path = String(prop);\n desired[path] = processValue(value, ref, path, collector);\n return true;\n },\n\n has(target, prop) {\n if (typeof prop === 'symbol') return Reflect.has(target, prop);\n if (prop === 'node' || prop === 'resource') return true;\n return prop in desired || prop in internal.observed;\n },\n }) as Resource;\n\n // Store internal mapping for the proxy too, so internals.get(proxy) works\n internals.set(proxy, internal);\n return proxy;\n}\n\n/**\n * Wrap a primitive observed value so it carries ReadProxy metadata\n * for dependency tracking when assigned elsewhere.\n */\nfunction createPrimitiveReadProxyFromResource(\n value: unknown,\n owner: ResourceRef,\n path: string,\n): unknown {\n if (value === null || value === undefined) return value;\n return createPrimitiveReadProxy(value as string | number | boolean, owner, path);\n}\n\n/**\n * Creates a proxy for a path that exists in neither desired nor observed.\n * - Reading nested properties returns ReadProxy leaves (for dependency tracking).\n * - Writing a nested property auto-initializes the path in desired and stores the value.\n */\nfunction createLazyInitProxy(\n desired: Record<string, unknown>,\n owner: ResourceRef,\n collector: EdgeCollector,\n basePath: string,\n): object {\n const readProxy = createReadProxy({} as object, owner, basePath);\n\n return new Proxy(readProxy as object, {\n get(target, prop, receiver) {\n if (typeof prop === 'symbol') return Reflect.get(target, prop, receiver);\n // Delegate reads to the ReadProxy (for tracking)\n return Reflect.get(target, prop, receiver);\n },\n\n set(_target, prop, value) {\n if (typeof prop === 'symbol') return false;\n // Auto-initialize the parent object in desired\n let container = desired[basePath] as Record<string, unknown> | undefined;\n if (!container || typeof container !== 'object') {\n container = {};\n desired[basePath] = container;\n }\n container[String(prop)] = processValue(\n value,\n owner,\n `${basePath}.${String(prop)}`,\n collector,\n );\n return true;\n },\n });\n}\n","import { AsyncLocalStorage } from 'node:async_hooks';\n\nimport type { XplaneLogger } from './types.js';\n\nconst noopLogger: XplaneLogger = {\n debug() {},\n info() {},\n warn() {},\n};\n\nconst loggerStorage = new AsyncLocalStorage<XplaneLogger>();\n\n/**\n * Get the current logger from async context.\n * Returns a no-op logger if none has been set (silent by default).\n */\nexport function getLogger(): XplaneLogger {\n return loggerStorage.getStore() ?? noopLogger;\n}\n\n/**\n * Run a function with a logger available in async context.\n * All code within `fn` (and any nested async calls) can access\n * the logger via `getLogger()`.\n */\nexport function withLogger<T>(logger: XplaneLogger, fn: () => T): T {\n return loggerStorage.run(logger, fn);\n}\n","import {\n getDesiredDocument,\n getExternalRef,\n getObservedDocument,\n getResourceRef,\n isExternal,\n} from '../core/resource.js';\nimport { Pending } from '../tracking/index.js';\n\nimport type { DiagnosticReport, PipelineState } from './types.js';\n\n/**\n * DIAGNOSE phase: produce structured diagnostics for blocked resources.\n *\n * For each resource classified as 'blocked':\n * - Find all Pending markers in the desired document\n * - Report what they're waiting on (source resource + path)\n *\n * For circular dependencies (detected in sequence phase):\n * - Produce a 'cycle' diagnostic with the full cycle path\n */\nexport function diagnose(state: PipelineState): PipelineState {\n const diagnostics: DiagnosticReport[] = [];\n\n // Check for cycles from the graph\n const sortResult = state.graph.topologicalSort();\n if (sortResult.order === null && sortResult.cycle) {\n const firstCycleMember = sortResult.cycle[0];\n if (firstCycleMember) {\n diagnostics.push({\n resource: firstCycleMember,\n reason: 'cycle',\n cycle: sortResult.cycle,\n });\n }\n }\n\n // Report external resources that were required but not found\n for (const resource of state.resources) {\n if (!isExternal(resource)) continue;\n const ref = getExternalRef(resource);\n if (!ref) continue;\n const observed = getObservedDocument(resource);\n if (Object.keys(observed).length > 0) continue; // hydrated, no problem\n const nameDisplay =\n typeof ref.name === 'string' ? ref.name : ref.name == null ? '(unresolved)' : '(unresolved)';\n const nsDisplay = ref.namespace ? ` in namespace '${ref.namespace}'` : '';\n diagnostics.push({\n resource: getResourceRef(resource).id,\n reason: 'not-found',\n detail: `External resource ${ref.apiVersion}/${ref.kind} '${nameDisplay}'${nsDisplay} was required but not found by Crossplane`,\n });\n }\n\n // For each blocked resource, find pending paths\n const pendingDiagnostics: DiagnosticReport[] = [];\n for (const resource of state.resources) {\n if (isExternal(resource)) continue;\n\n const ref = getResourceRef(resource);\n const classification = state.classification.get(ref.id);\n if (classification !== 'blocked') continue;\n\n // Skip if already reported as cycle member\n if (sortResult.order === null && sortResult.cycle?.includes(ref.id)) continue;\n\n const desired = getDesiredDocument(resource);\n const pendingPaths = findPendingPaths(desired, '');\n\n if (pendingPaths.length > 0) {\n pendingDiagnostics.push({\n resource: ref.id,\n reason: 'pending',\n pendingPaths,\n });\n }\n }\n\n // Filter out cascading diagnostics: only keep pending diagnostics that have\n // at least one dependency that is NOT itself blocked or not-found.\n // This surfaces only root causes rather than the full dependency cascade.\n const notFoundIds = new Set(\n diagnostics.filter((d) => d.reason === 'not-found').map((d) => d.resource),\n );\n const blockedIds = new Set(pendingDiagnostics.map((d) => d.resource));\n\n for (const diag of pendingDiagnostics) {\n const isRootCause = diag.pendingPaths?.some((p) => {\n const dep = p.waitingOn.resource;\n // If waiting on something that isn't blocked or not-found, this IS a root cause\n return !blockedIds.has(dep) && !notFoundIds.has(dep);\n });\n if (isRootCause) {\n diagnostics.push(diag);\n }\n }\n\n return { ...state, diagnostics };\n}\n\n/**\n * Recursively find all Pending markers in a document and report their source.\n */\nfunction findPendingPaths(\n obj: unknown,\n basePath: string,\n): Array<{ path: string; waitingOn: { resource: string; path: string } }> {\n const results: Array<{ path: string; waitingOn: { resource: string; path: string } }> = [];\n\n if (obj === null || obj === undefined) return results;\n if (Pending.is(obj)) {\n results.push({\n path: basePath,\n waitingOn: { resource: obj.source.id, path: obj.path },\n });\n return results;\n }\n if (typeof obj !== 'object') return results;\n\n if (Array.isArray(obj)) {\n for (let i = 0; i < obj.length; i++) {\n const childPath = basePath ? `${basePath}[${i}]` : `[${i}]`;\n results.push(...findPendingPaths(obj[i], childPath));\n }\n return results;\n }\n\n for (const [key, value] of Object.entries(obj as Record<string, unknown>)) {\n const childPath = basePath ? `${basePath}.${key}` : key;\n results.push(...findPendingPaths(value, childPath));\n }\n return results;\n}\n","import { getXrDesiredStatus } from '../core/composition.js';\nimport {\n getDesiredDocument,\n getObservedDocument,\n getReadyChecks,\n getResourceInternals,\n getResourceRef,\n isExternal,\n} from '../core/resource.js';\nimport { getReadProxyMeta, isReadProxy } from '../tracking/index.js';\nimport { PendingTemplate } from '../tracking/types.js';\n\nimport type { EmittedResource, PipelineState } from './types.js';\n\n/**\n * EMIT phase: serialize each resource classified as 'emit' into a plain\n * Kubernetes resource document ready for Crossplane.\n *\n * Also extracts the XR desired status from this.xr.status assignments.\n */\nexport function emit(state: PipelineState): PipelineState {\n const emitted: EmittedResource[] = [];\n\n for (const resource of state.resources) {\n if (isExternal(resource)) continue;\n\n const ref = getResourceRef(resource);\n const classification = state.classification.get(ref.id);\n if (classification !== 'emit') continue;\n\n const internal = getResourceInternals(resource);\n const desired = getDesiredDocument(resource);\n\n // Strip the construct path prefix to get the resource name\n // The name is the full construct path minus the root \"Composition/\" prefix\n const name = ref.id.startsWith('Composition/') ? ref.id.slice('Composition/'.length) : ref.id;\n\n emitted.push({\n name,\n document: deepClean(desired),\n autoReady: internal.config.autoReady,\n readyChecks: getReadyChecks(resource),\n });\n }\n\n // Extract XR status and resolve any ReadProxy values using observed data\n const resourceById = new Map(state.resources.map((r) => [getResourceRef(r).id, r]));\n const rawStatus = getXrDesiredStatus(state.composition);\n const xrStatusPatches = resolveXrStatus(rawStatus, resourceById);\n\n return { ...state, emitted, xrStatusPatches };\n}\n\n/**\n * Deep-clone an object, stripping any remaining framework internals.\n * This produces a clean JSON-serializable Kubernetes document.\n */\nfunction deepClean(obj: Record<string, unknown>): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(obj)) {\n result[key] = cleanValue(value);\n }\n\n return result;\n}\n\nfunction cleanValue(value: unknown): unknown {\n if (value === null || value === undefined) return value;\n if (typeof value !== 'object') return value;\n\n if (PendingTemplate.is(value)) {\n // Should never reach emit — indicates a bug in the pipeline\n throw new Error(\n `PendingTemplate reached emit phase — resource should have been classified as blocked. Parts: ${JSON.stringify(value.parts)}`,\n );\n }\n\n if (Array.isArray(value)) {\n return value.map(cleanValue);\n }\n\n // Plain objects — recurse\n const result: Record<string, unknown> = {};\n for (const [key, val] of Object.entries(value as Record<string, unknown>)) {\n result[key] = cleanValue(val);\n }\n return result;\n}\n\n/**\n * Resolve ReadProxy values in XR status using observed resource data.\n * This is needed because XR status is written at construction time (before hydration),\n * so read proxy references need to be resolved post-hydration.\n */\nfunction resolveXrStatus(\n status: Record<string, unknown>,\n resourceById: ReadonlyMap<string, import('../core/resource.js').Resource>,\n): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(status)) {\n const resolved = resolveStatusValue(value, resourceById);\n if (resolved !== undefined) {\n result[key] = resolved;\n }\n }\n return result;\n}\n\nfunction resolveStatusValue(\n value: unknown,\n resourceById: ReadonlyMap<string, import('../core/resource.js').Resource>,\n): unknown {\n if (value === null || value === undefined) return undefined;\n\n if (isReadProxy(value)) {\n const meta = getReadProxyMeta(value);\n if (!meta) return undefined;\n\n // Try to extract a concrete primitive (already resolved read proxy)\n const prim = tryExtractPrimitive(value as object);\n if (prim !== undefined) return prim;\n\n // Leaf proxy — try to resolve from observed data\n const resource = resourceById.get(meta.owner.id);\n if (!resource) return undefined;\n const observed = getObservedDocument(resource);\n return getNestedValue(observed, meta.path);\n }\n\n if (Array.isArray(value)) {\n return value.map((v) => resolveStatusValue(v, resourceById)).filter((v) => v != null);\n }\n\n if (typeof value === 'object') {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value as Record<string, unknown>)) {\n const resolved = resolveStatusValue(v, resourceById);\n if (resolved !== undefined) {\n out[k] = resolved;\n }\n }\n return Object.keys(out).length > 0 ? out : undefined;\n }\n\n return value;\n}\n\nfunction tryExtractPrimitive(proxy: object): string | number | boolean | undefined {\n const toPrim = (proxy as Record<symbol, unknown>)[Symbol.toPrimitive];\n if (typeof toPrim === 'function') {\n const result = (toPrim as () => unknown)();\n if (result !== undefined && result !== null && typeof result !== 'object') {\n // Leaf proxy placeholders are not real values — skip them\n if (typeof result === 'string' && result.startsWith('__pending__')) return undefined;\n return result as string | number | boolean;\n }\n }\n return undefined;\n}\n\nfunction getNestedValue(obj: Record<string, unknown>, path: string): unknown {\n const parts = path.split('.');\n let current: unknown = obj;\n for (const part of parts) {\n if (current === null || current === undefined || typeof current !== 'object') return undefined;\n current = (current as Record<string, unknown>)[part];\n }\n return current;\n}\n","import { getExternalRef, hydrateObserved, isExternal } from '../core/resource.js';\n\nimport type { PipelineState } from './types.js';\n\n/**\n * HYDRATE phase: feed observed state from Crossplane into each resource.\n *\n * - Composed resources are matched by their construct path (resource name).\n * - External resources are matched by their refKey.\n */\nexport function hydrate(state: PipelineState): PipelineState {\n for (const resource of state.resources) {\n if (isExternal(resource)) {\n const ref = getExternalRef(resource);\n if (ref) {\n const observed = state.observedRequired.get(ref.refKey);\n if (observed) {\n hydrateObserved(resource, observed);\n }\n }\n } else {\n // Match by construct path\n const name = resource.node.path;\n const observed = state.observedComposed.get(name);\n if (observed) {\n hydrateObserved(resource, observed);\n }\n }\n }\n\n return state;\n}\n","import { getDesiredDocument, getObservedDocument, getResourceRef } from '../core/resource.js';\nimport { Pending, PendingTemplate } from '../tracking/index.js';\n\nimport type { PipelineState } from './types.js';\n\n/**\n * RESOLVE phase: walk dependency edges and replace Pending markers\n * with concrete values from observed state where available.\n *\n * For each resource's desired document, recursively find Pending values.\n * Look up the source resource's observed state at the source path.\n * If concrete → replace. If not available → leave Pending in place.\n */\nexport function resolve(state: PipelineState): PipelineState {\n // Build a lookup: resource id → Resource instance\n const resourceById = new Map(state.resources.map((r) => [getResourceRef(r).id, r]));\n\n for (const resource of state.resources) {\n const desired = getDesiredDocument(resource);\n resolvePending(desired, resourceById);\n }\n\n return state;\n}\n\n/**\n * Recursively walk an object and resolve any Pending markers.\n */\nfunction resolvePending(\n obj: Record<string, unknown>,\n resourceById: ReadonlyMap<string, import('../core/resource.js').Resource>,\n): void {\n for (const [key, value] of Object.entries(obj)) {\n if (Pending.is(value)) {\n const sourceResource = resourceById.get(value.source.id);\n if (sourceResource) {\n const observed = getObservedDocument(sourceResource);\n const resolved = getNestedValue(observed, value.path);\n if (resolved !== undefined) {\n obj[key] = resolved;\n }\n // else: leave Pending in place — still unresolved\n }\n } else if (PendingTemplate.is(value)) {\n const resolved = resolvePendingTemplate(value, resourceById);\n if (resolved !== undefined) obj[key] = resolved;\n } else if (Array.isArray(value)) {\n resolveArray(value, resourceById);\n } else if (value !== null && typeof value === 'object') {\n resolvePending(value as Record<string, unknown>, resourceById);\n }\n }\n}\n\nfunction resolveArray(\n arr: unknown[],\n resourceById: ReadonlyMap<string, import('../core/resource.js').Resource>,\n): void {\n for (let i = 0; i < arr.length; i++) {\n const value = arr[i];\n if (Pending.is(value)) {\n const sourceResource = resourceById.get(value.source.id);\n if (sourceResource) {\n const observed = getObservedDocument(sourceResource);\n const resolved = getNestedValue(observed, value.path);\n if (resolved !== undefined) {\n arr[i] = resolved;\n }\n }\n } else if (PendingTemplate.is(value)) {\n const resolved = resolvePendingTemplate(value, resourceById);\n if (resolved !== undefined) arr[i] = resolved;\n } else if (Array.isArray(value)) {\n resolveArray(value, resourceById);\n } else if (value !== null && typeof value === 'object') {\n resolvePending(value as Record<string, unknown>, resourceById);\n }\n }\n}\n\n/**\n * Get a nested value from an object by dot-separated path.\n */\nfunction getNestedValue(obj: Record<string, unknown>, path: string): unknown {\n const segments = path.split('.');\n let current: unknown = obj;\n\n for (const segment of segments) {\n if (current === null || current === undefined) return undefined;\n if (typeof current !== 'object') return undefined;\n current = (current as Record<string, unknown>)[segment];\n }\n\n return current;\n}\n\n/**\n * Attempt to resolve all slots of a PendingTemplate.\n * Returns the reconstructed string if all slots resolve, undefined otherwise.\n */\nfunction resolvePendingTemplate(\n template: PendingTemplate,\n resourceById: ReadonlyMap<string, import('../core/resource.js').Resource>,\n): string | undefined {\n const values: string[] = [];\n for (const slot of template.slots) {\n const sourceResource = resourceById.get(slot.source.id);\n if (!sourceResource) return undefined;\n const observed = getObservedDocument(sourceResource);\n const resolved = getNestedValue(observed, slot.path);\n if (resolved === undefined || resolved === null) return undefined;\n values.push(String(resolved));\n }\n let result = template.parts[0]!;\n for (let i = 0; i < values.length; i++) {\n result += values[i] + template.parts[i + 1]!;\n }\n return result;\n}\n","import { getDesiredDocument, getResourceRef, isExternal } from '../core/resource.js';\nimport { Pending, PendingTemplate } from '../tracking/index.js';\n\nimport type { PipelineState, ResourceClassification } from './types.js';\n\n/**\n * SEQUENCE phase: topological sort and classification.\n *\n * - Runs topological sort on the dependency graph.\n * - Classifies each resource as 'emit', 'blocked', or 'external'.\n * - A resource is 'blocked' if it still has Pending markers in its desired document.\n * - External resources are classified as 'external' (never emitted).\n * - Circular dependencies are detected via the graph's topological sort.\n */\nexport function sequence(state: PipelineState): PipelineState {\n const classification = new Map<string, ResourceClassification>();\n\n // Run topological sort for cycle detection\n const sortResult = state.graph.topologicalSort();\n\n // Classify each resource\n for (const resource of state.resources) {\n const ref = getResourceRef(resource);\n\n if (isExternal(resource)) {\n classification.set(ref.id, 'external');\n continue;\n }\n\n // Check if this resource has any remaining Pending markers\n const desired = getDesiredDocument(resource);\n const hasPending = containsPending(desired);\n\n if (hasPending) {\n classification.set(ref.id, 'blocked');\n } else {\n classification.set(ref.id, 'emit');\n }\n }\n\n // If there's a cycle, mark all cycle members as blocked\n if (sortResult.order === null && sortResult.cycle) {\n for (const id of sortResult.cycle) {\n if (classification.get(id) !== 'external') {\n classification.set(id, 'blocked');\n }\n }\n }\n\n return { ...state, classification };\n}\n\n/**\n * Recursively check if an object contains any Pending markers.\n */\nfunction containsPending(obj: unknown): boolean {\n if (obj === null || obj === undefined) return false;\n if (Pending.is(obj)) return true;\n if (PendingTemplate.is(obj)) return true;\n if (typeof obj !== 'object') return false;\n\n if (Array.isArray(obj)) {\n return obj.some(containsPending);\n }\n\n for (const value of Object.values(obj as Record<string, unknown>)) {\n if (containsPending(value)) return true;\n }\n return false;\n}\n","import type { Composition } from '../core/composition.js';\nimport type { Resource } from '../core/resource.js';\n\nimport { diagnose } from './diagnose.js';\nimport { emit } from './emit.js';\nimport { hydrate } from './hydrate.js';\nimport { resolve } from './resolve.js';\nimport { sequence } from './sequence.js';\nimport type { PipelineState } from './types.js';\n\nexport { diagnose } from './diagnose.js';\nexport { emit } from './emit.js';\nexport { hydrate } from './hydrate.js';\nexport { resolve } from './resolve.js';\nexport { sequence } from './sequence.js';\nexport type {\n DiagnosticReport,\n EmittedResource,\n PipelineState,\n ResourceClassification,\n} from './types.js';\n\n/**\n * Input to the pipeline — provided by the handler or simulator.\n */\nexport interface PipelineInput {\n /** The constructed Composition instance. */\n composition: Composition;\n /** Observed composed resources from Crossplane (keyed by resource name). */\n observedComposed: ReadonlyMap<string, Record<string, unknown>>;\n /** Observed existing/required resources (keyed by refKey). */\n observedRequired: ReadonlyMap<string, Record<string, unknown>>;\n}\n\n/**\n * Run the full rendering pipeline.\n *\n * Phases: hydrate → resolve → sequence → diagnose → emit\n */\nexport function runPipeline(input: PipelineInput): PipelineState {\n const resources = collectResources(input.composition);\n\n const initialState: PipelineState = {\n composition: input.composition,\n resources,\n graph: input.composition.graph,\n observedComposed: input.observedComposed,\n observedRequired: input.observedRequired,\n classification: new Map(),\n diagnostics: [],\n emitted: [],\n xrStatusPatches: {},\n };\n\n // Run phases sequentially — each transforms the state\n let state = initialState;\n state = hydrate(state);\n state = resolve(state);\n state = sequence(state);\n state = diagnose(state);\n state = emit(state);\n\n return state;\n}\n\n/**\n * Collect all Resource instances from the composition's construct tree.\n */\nfunction collectResources(composition: Composition): Resource[] {\n const resources: Resource[] = [];\n collectFromNode(composition, resources);\n return resources;\n}\n\nfunction collectFromNode(construct: import('constructs').Construct, resources: Resource[]): void {\n for (const child of construct.node.children) {\n // Check if it's a Resource (has our internals)\n if (isResourceInstance(child)) {\n resources.push(child as Resource);\n }\n // Recurse into children\n collectFromNode(child, resources);\n }\n}\n\nfunction isResourceInstance(obj: unknown): obj is Resource {\n if (obj === null || typeof obj !== 'object') return false;\n const r = obj as Record<string, unknown>;\n if (!('resource' in r) || r.resource === null || typeof r.resource !== 'object') return false;\n return 'autoReady' in (r.resource as object);\n}\n","import type { ReadyCheck } from './types.js';\n\n/**\n * Checks if the resource has a `Ready` condition with status `True`.\n */\nexport function conditionReady(observed: Record<string, unknown>): boolean | undefined {\n const status = observed.status as Record<string, unknown> | undefined;\n const conditions = status?.conditions as Array<Record<string, unknown>> | undefined;\n if (!conditions || !Array.isArray(conditions)) return undefined;\n\n const ready = conditions.find((c) => c.type === 'Ready');\n if (!ready) return undefined;\n\n return ready.status === 'True';\n}\n\n/**\n * Checks if the resource has `status.ready === true`.\n */\nexport function statusReady(observed: Record<string, unknown>): boolean | undefined {\n const status = observed.status as Record<string, unknown> | undefined;\n if (status === undefined) return undefined;\n if (!('ready' in status)) return undefined;\n\n return status.ready === true;\n}\n\n/**\n * Fallback: resource exists in observed state → ready.\n * Always returns `true` (only called when observed is defined).\n */\nexport function exists(_observed: Record<string, unknown>): boolean {\n return true;\n}\n\n/**\n * Built-in default readiness checks, appended at low priority.\n */\nexport const DEFAULT_CHECKS: ReadyCheck[] = [\n { fn: conditionReady, priority: 100, name: 'conditionReady' },\n { fn: statusReady, priority: 200, name: 'statusReady' },\n { fn: exists, priority: 1000, name: 'exists' },\n];\n","import { getLogger } from '../logging/index.js';\n\nimport type { ReadyCheck } from './types.js';\n\n/**\n * Evaluate readiness for a resource by running checks grouped by priority.\n *\n * - If `observed` is undefined, the resource doesn't exist yet → not ready.\n * - Checks are grouped by priority (ascending). Within a group, all checks\n * are AND-ed: if any returns `false`, the resource is not ready. If at least\n * one returns `true` and none return `false`, the resource is ready.\n * If all return `undefined`, cascade to the next priority group.\n * - Final fallback (no group had a definitive answer): not ready.\n */\nexport function evaluateReadiness(\n checks: ReadyCheck[],\n observed: Record<string, unknown> | undefined,\n): boolean {\n const log = getLogger();\n\n if (!observed) {\n log.debug('readiness: resource not observed, not ready');\n return false;\n }\n\n // Group checks by priority\n const groups = new Map<number, ReadyCheck[]>();\n for (const check of checks) {\n const group = groups.get(check.priority);\n if (group) {\n group.push(check);\n } else {\n groups.set(check.priority, [check]);\n }\n }\n\n // Process groups in ascending priority order\n const priorities = [...groups.keys()].sort((a, b) => a - b);\n\n for (const priority of priorities) {\n const group = groups.get(priority)!;\n let hasTrue = false;\n let hasFalse = false;\n const results: Array<{ name: string; result: boolean | undefined }> = [];\n\n for (const check of group) {\n const result = check.fn(observed);\n results.push({ name: check.name ?? 'anonymous', result });\n\n if (result === false) {\n hasFalse = true;\n break; // Short-circuit: one false in the group → not ready\n }\n if (result === true) {\n hasTrue = true;\n }\n }\n\n log.debug('readiness: evaluated group', { priority, results });\n\n if (hasFalse) {\n log.debug('readiness: group returned false, not ready', { priority });\n return false;\n }\n if (hasTrue) {\n log.debug('readiness: group returned true, ready', { priority });\n return true;\n }\n // All undefined → cascade to next group\n }\n\n log.debug('readiness: no group had definitive answer, not ready');\n return false;\n}\n","import type {\n CompositionInput,\n CompositionResult,\n DesiredResource,\n ExternalResourceRequest,\n} from './contract.js';\nimport type { Composition } from './core/composition.js';\nimport type { CompositionContext } from './core/context.js';\nimport { compositionStorage } from './core/context.js';\nimport { getExternalRef, getResourceRef, isExternal } from './core/resource.js';\nimport { runPipeline } from './pipeline/index.js';\nimport { DEFAULT_CHECKS, evaluateReadiness } from './readiness/index.js';\nimport { DependencyGraph, EdgeCollector } from './tracking/index.js';\nimport { createTokenRegistry, tokenRegistryStorage } from './tracking/token-registry.js';\n\n/**\n * Run a composition class with the given input and return a plain-data result.\n *\n * This is the single entry point that bridges the composition author's class\n * with the runtime. It handles:\n * 1. Setting up internal context (DependencyGraph, EdgeCollector, ALS)\n * 2. Instantiating the Composition class\n * 3. Running the full pipeline (hydrate → resolve → sequence → diagnose → emit)\n * 4. Evaluating readiness per resource\n * 5. Returning a fully serializable CompositionResult\n *\n * The runtime never needs to access framework internals — everything it needs\n * is in the returned plain-data structure.\n */\nexport function runComposition<TSpec, TStatus, TContext extends object>(\n CompositionClass: new () => Composition<TSpec, TStatus, TContext>,\n input: CompositionInput,\n): CompositionResult {\n // Convert plain Records to Maps for the internal pipeline\n const observedComposed = new Map(Object.entries(input.observedComposed));\n const observedRequired = new Map(Object.entries(input.observedRequired));\n\n // Set up internal context\n const graph = new DependencyGraph();\n const collector = new EdgeCollector();\n const pipelineContext = new Map(Object.entries(input.pipelineContext));\n\n const ctx: CompositionContext = {\n xr: input.xr,\n pipelineContext,\n requiredResources: observedRequired,\n graph,\n collector,\n };\n\n // Instantiate composition within ALS context\n const composition = compositionStorage.run(ctx, () =>\n tokenRegistryStorage.run(createTokenRegistry(), () => new CompositionClass()),\n ) as Composition;\n\n // Run the pipeline\n const state = runPipeline({ composition, observedComposed, observedRequired });\n\n // Build the result — plain data only\n const resources: DesiredResource[] = state.emitted.map((emitted) => {\n const allChecks = [...emitted.readyChecks, ...DEFAULT_CHECKS];\n // Look up observed using the full construct path (Composition/{name})\n const observed = observedComposed.get(`Composition/${emitted.name}`);\n const ready = emitted.autoReady ? evaluateReadiness(allChecks, observed) : true;\n\n return {\n name: emitted.name,\n document: emitted.document,\n ready,\n };\n });\n\n const externalResources: ExternalResourceRequest[] = [];\n for (const resource of state.resources) {\n if (!isExternal(resource)) continue;\n const ref = getExternalRef(resource);\n if (!ref || typeof ref.name !== 'string') continue;\n if (ref.name.startsWith('__pending__')) continue;\n\n externalResources.push({\n refKey: ref.refKey,\n apiVersion: ref.apiVersion,\n kind: ref.kind,\n name: ref.name,\n ...(ref.namespace ? { namespace: ref.namespace } : {}),\n });\n }\n\n // Collect blocked resource names so the handler can preserve observed state\n // in desired (preventing accidental deletion) and prevent premature XR readiness.\n const blockedResources: string[] = [];\n for (const resource of state.resources) {\n if (isExternal(resource)) continue;\n const ref = getResourceRef(resource);\n if (state.classification.get(ref.id) !== 'blocked') continue;\n const name = ref.id.startsWith('Composition/') ? ref.id.slice('Composition/'.length) : ref.id;\n blockedResources.push(name);\n }\n\n return {\n resources,\n blockedResources,\n externalResources,\n xrStatus: state.xrStatusPatches,\n diagnostics: state.diagnostics,\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":["Construct","tryExtractPrimitive","Construct","tryExtractPrimitive","getNestedValue"],"sources":["../src/core/context.ts","../src/core/composition.ts","../src/tracking/dependency-graph.ts","../src/tracking/types.ts","../src/tracking/token-registry.ts","../src/tracking/read-proxy.ts","../src/tracking/write-proxy.ts","../src/core/resource.ts","../src/logging/context.ts","../src/pipeline/diagnose.ts","../src/pipeline/emit.ts","../src/pipeline/hydrate.ts","../src/pipeline/resolve.ts","../src/pipeline/sequence.ts","../src/pipeline/index.ts","../src/readiness/defaults.ts","../src/readiness/evaluate.ts","../src/run.ts"],"sourcesContent":["import { AsyncLocalStorage } from 'node:async_hooks';\n\nimport type { DependencyGraph, EdgeCollector } from '../tracking/index.js';\n\n/**\n * Runtime context passed into a Composition during construction\n * via AsyncLocalStorage. Holds everything the Composition needs\n * without relying on static state or globalThis.\n */\nexport interface CompositionContext {\n /** Observed XR data. */\n xr: Record<string, unknown>;\n /** Full Crossplane function pipeline context (all keys). */\n pipelineContext: ReadonlyMap<string, unknown>;\n /** Pre-populated data for existing resources (from prior iterations). */\n requiredResources: ReadonlyMap<string, Record<string, unknown>>;\n /** Pre-populated data for composed resources (from prior iterations), keyed by `Composition/{path}`. */\n observedComposed: ReadonlyMap<string, Record<string, unknown>>;\n /** The dependency graph for this composition run. */\n graph: DependencyGraph;\n /** The edge collector for this composition run. */\n collector: EdgeCollector;\n}\n\n/**\n * AsyncLocalStorage instance that carries the CompositionContext.\n * The handler sets it before constructing the user's Composition,\n * and the Composition constructor reads from it.\n */\nexport const compositionStorage = new AsyncLocalStorage<CompositionContext>();\n\n/**\n * Get the current composition context from AsyncLocalStorage.\n * Throws if called outside of a composition construction scope.\n */\nexport function getCompositionContext(): CompositionContext {\n const ctx = compositionStorage.getStore();\n if (ctx) return ctx;\n\n throw new Error(\n 'No composition context found. Ensure the Composition is constructed within compositionStorage.run().',\n );\n}\n","import { Construct } from 'constructs';\n\nimport type { DependencyGraph, EdgeCollector } from '../tracking/index.js';\nimport { getCompositionContext } from './context.js';\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\n/**\n * Base generics for a Composition.\n * - TSpec: shape of the XR's spec\n * - TStatus: shape of the XR's status (writable)\n * - TContext: shape of the pipeline context map keys→values\n */\nexport type CompositionProps<\n TSpec = Record<string, unknown>,\n TStatus = Record<string, unknown>,\n TContext extends object = Record<string, unknown>,\n> = {\n spec?: TSpec;\n status?: TStatus;\n context?: TContext;\n};\n\n/** The shape of the XR proxy exposed via `this.xr`. */\nexport interface XrProxy<TSpec = Record<string, unknown>, TStatus = Record<string, unknown>> {\n spec: TSpec;\n status: TStatus;\n metadata: {\n name: string;\n namespace?: string;\n labels?: Record<string, string>;\n annotations?: Record<string, string>;\n [key: string]: unknown;\n };\n [key: string]: unknown;\n}\n\n// ─── Composition class ────────────────────────────────────────────────────────\n\n/**\n * Base class for user-authored Crossplane compositions.\n *\n * Users extend this class and define resources in the constructor:\n *\n * ```ts\n * class MyComposition extends Composition<MySpec, MyStatus> {\n * constructor() {\n * super();\n * const vpc = new Vpc(this, 'vpc', { spec: { ... } });\n * this.xr.status.vpcId = vpc.status.atProvider.vpcId;\n * }\n * }\n * ```\n *\n * `this.xr` is a \"desired-first, fallback-to-observed\" proxy over the XR.\n * `this.pipelineContext` provides typed read-only access to Crossplane function context.\n */\nexport class Composition<\n TSpec = Record<string, unknown>,\n TStatus = Record<string, unknown>,\n TContext extends object = Record<string, unknown>,\n> extends Construct {\n /**\n * The XR proxy — reads from desired first (status writes), falls through to observed.\n * Writing to `this.xr.status.*` sets the composite status output.\n */\n readonly xr: XrProxy<TSpec, TStatus>;\n\n /** The dependency graph tracking resource relationships. */\n readonly graph: DependencyGraph;\n\n /** The edge collector accumulating dependency edges. */\n readonly collector: EdgeCollector;\n\n /**\n * When `true`, the runtime injects a structured `status.xplane` payload on\n * the XR containing `emittedResources` and `blockedResources`. Defaults to\n * `false` because writing this field requires the XRD's `openAPIV3Schema`\n * to declare `status.xplane` (or `status` to allow unknown fields) — typed\n * patches will otherwise be rejected by Crossplane.\n *\n * To enable, set in your composition's constructor:\n *\n * ```ts\n * this.emitXplaneStatus = true;\n * ```\n *\n * and add the following to your XRD's status schema:\n *\n * ```yaml\n * status:\n * properties:\n * xplane:\n * type: object\n * x-kubernetes-preserve-unknown-fields: true\n * ```\n */\n emitXplaneStatus = false;\n\n constructor() {\n // Use 'Composition' as the root construct ID\n super(undefined as unknown as Construct, 'Composition');\n\n const ctx = getCompositionContext();\n\n this.graph = ctx.graph;\n this.collector = ctx.collector;\n\n // Set context values on the construct tree so Resources can find them\n this.node.setContext('xplane:graph', ctx.graph);\n this.node.setContext('xplane:collector', ctx.collector);\n\n // Set XR metadata on tree for Resource.uniqueName()\n const xrMeta = ctx.xr.metadata as { name?: string; namespace?: string } | undefined;\n if (xrMeta) {\n this.node.setContext('xplane:xr-meta', xrMeta);\n }\n\n // Build the XR proxy\n this.xr = createXrProxy<TSpec, TStatus>(ctx);\n }\n\n /**\n * Read-only accessor for Crossplane function pipeline context.\n * Keys are the context keys set by Crossplane or prior functions in the pipeline.\n */\n get pipelineContext(): PipelineContextAccessor<TContext> {\n const ctx = getCompositionContext();\n return {\n get<K extends keyof TContext>(key: K): TContext[K] | undefined {\n return ctx.pipelineContext.get(key as string) as TContext[K] | undefined;\n },\n has(key: keyof TContext): boolean {\n return ctx.pipelineContext.has(key as string);\n },\n keys(): IterableIterator<keyof TContext> {\n return ctx.pipelineContext.keys() as IterableIterator<keyof TContext>;\n },\n };\n }\n}\n\n/** Typed read-only interface for pipeline context. */\nexport interface PipelineContextAccessor<TContext extends object = Record<string, unknown>> {\n get<K extends keyof TContext>(key: K): TContext[K] | undefined;\n has(key: keyof TContext): boolean;\n keys(): IterableIterator<keyof TContext>;\n}\n\n// ─── XR Proxy ─────────────────────────────────────────────────────────────────\n\n/**\n * Creates the \"desired-first, fallback-to-observed\" proxy for the XR.\n *\n * - Reading `xr.spec.*` reads from observed XR spec (creates ReadProxy for tracking)\n * - Writing `xr.status.*` writes to a desired-status store (emitted as composite status)\n * - Other reads fall through to observed\n */\nfunction createXrProxy<TSpec, TStatus>(ctx: {\n xr: Record<string, unknown>;\n graph: DependencyGraph;\n collector: EdgeCollector;\n}): XrProxy<TSpec, TStatus> {\n const xrObserved = ctx.xr;\n const xrDesiredStatus: Record<string, unknown> = {};\n\n // The XR ref for dependency tracking\n const xrRef = { id: '__xr__' };\n ctx.graph.addResource(xrRef);\n\n const statusProxy = new Proxy(xrDesiredStatus, {\n get(_target, prop) {\n if (typeof prop === 'symbol') return undefined;\n const key = String(prop);\n // Desired-first\n if (key in xrDesiredStatus) return xrDesiredStatus[key];\n // Fallback to observed status\n const observedStatus = xrObserved.status as Record<string, unknown> | undefined;\n if (observedStatus && key in observedStatus) {\n return observedStatus[key];\n }\n return undefined;\n },\n set(_target, prop, value) {\n if (typeof prop === 'symbol') return false;\n xrDesiredStatus[String(prop)] = value;\n return true;\n },\n has(_target, prop) {\n if (typeof prop === 'symbol') return false;\n const key = String(prop);\n if (key in xrDesiredStatus) return true;\n const observedStatus = xrObserved.status as Record<string, unknown> | undefined;\n return observedStatus ? key in observedStatus : false;\n },\n });\n\n const proxy = new Proxy({} as XrProxy<TSpec, TStatus>, {\n get(_target, prop) {\n if (typeof prop === 'symbol') return undefined;\n const key = String(prop);\n if (key === 'status') return statusProxy;\n // Everything else reads from observed XR\n if (key in xrObserved) return xrObserved[key];\n return undefined;\n },\n set(_target, prop, value) {\n if (typeof prop === 'symbol') return false;\n const key = String(prop);\n if (key === 'status') {\n // Allow replacing entire status\n Object.assign(xrDesiredStatus, value as object);\n return true;\n }\n // Writes to other top-level XR fields are unusual but allowed\n (xrObserved as Record<string, unknown>)[key] = value;\n return true;\n },\n has(_target, prop) {\n if (typeof prop === 'symbol') return false;\n return String(prop) in xrObserved || String(prop) === 'status';\n },\n });\n\n return proxy;\n}\n\n/**\n * Extract the desired XR status from a Composition instance.\n * Used by the emit pipeline phase to produce composite status output.\n */\nexport function getXrDesiredStatus(composition: Composition): Record<string, unknown> {\n // Access the internal status proxy target\n const statusProxy = composition.xr.status;\n // Collect all keys from the status proxy.\n // We intentionally return raw values (including ReadProxy references) so\n // that the emit phase can resolve them from observed resource data.\n const result: Record<string, unknown> = {};\n if (statusProxy && typeof statusProxy === 'object') {\n for (const key of Object.keys(statusProxy)) {\n const value = (statusProxy as Record<string, unknown>)[key];\n if (value != null) {\n result[key] = value;\n }\n }\n }\n return result;\n}\n","import type { DependencyEdge, ResourceRef } from './types.js';\n\n/**\n * Tracks dependency relationships between resources as a directed acyclic graph.\n * Edges are added as resources reference each other's observed state.\n */\nexport class DependencyGraph {\n private readonly _adjacency = new Map<string, Set<string>>();\n private readonly _resources = new Map<string, ResourceRef>();\n private readonly _edges: DependencyEdge[] = [];\n\n addResource(ref: ResourceRef): void {\n this._resources.set(ref.id, ref);\n if (!this._adjacency.has(ref.id)) {\n this._adjacency.set(ref.id, new Set());\n }\n }\n\n addEdge(edge: DependencyEdge): void {\n this.addResource(edge.from);\n this.addResource(edge.to);\n this._adjacency.get(edge.to.id)!.add(edge.from.id);\n this._edges.push(edge);\n }\n\n addEdges(edges: ReadonlyArray<DependencyEdge>): void {\n for (const edge of edges) this.addEdge(edge);\n }\n\n addExplicitDependency(dependent: ResourceRef, dependency: ResourceRef): void {\n this.addResource(dependent);\n this.addResource(dependency);\n this._adjacency.get(dependent.id)!.add(dependency.id);\n }\n\n /** Get the set of resource IDs that `resourceId` depends on. */\n getDependencies(resourceId: string): ReadonlySet<string> {\n return this._adjacency.get(resourceId) ?? new Set();\n }\n\n get resourceIds(): ReadonlyArray<string> {\n return [...this._resources.keys()];\n }\n\n get edges(): ReadonlyArray<DependencyEdge> {\n return this._edges;\n }\n\n /**\n * Returns a topological ordering of resources.\n * If a cycle is detected, returns { order: null, cycle: string[] }.\n */\n topologicalSort(): { order: string[] } | { order: null; cycle: string[] } {\n const visited = new Set<string>();\n const visiting = new Set<string>();\n const sorted: string[] = [];\n\n const visit = (id: string): string[] | null => {\n if (visited.has(id)) return null;\n if (visiting.has(id)) {\n // Build cycle path\n return [...visiting, id];\n }\n visiting.add(id);\n const deps = this._adjacency.get(id);\n if (deps) {\n for (const depId of deps) {\n const cycle = visit(depId);\n if (cycle) return cycle;\n }\n }\n visiting.delete(id);\n visited.add(id);\n sorted.push(id);\n return null;\n };\n\n for (const id of this._resources.keys()) {\n const cycle = visit(id);\n if (cycle) {\n // Trim cycle to start from the repeated node\n const start = cycle[cycle.length - 1]!;\n const startIdx = cycle.indexOf(start);\n return { order: null, cycle: cycle.slice(startIdx) };\n }\n }\n return { order: sorted };\n }\n}\n","/** Identifies a resource in the dependency graph. */\nexport interface ResourceRef {\n readonly id: string;\n}\n\n/** A dependency edge between two resources at specific field paths. */\nexport interface DependencyEdge {\n /** Resource being read from (observed state). */\n readonly from: ResourceRef;\n /** Path in the source resource's observed data. */\n readonly fromPath: string;\n /** Resource being written to (desired state). */\n readonly to: ResourceRef;\n /** Path in the target resource's desired data. */\n readonly toPath: string;\n}\n\n/**\n * A Pending marker stored in a desired document when a ReadProxy value\n * is assigned. Carries full source info so the resolve phase knows\n * where to look for the concrete value.\n */\nconst PENDING_TAG: unique symbol = Symbol.for('xplane.pending') as unknown as typeof PENDING_TAG;\n\nexport class Pending {\n static readonly TAG = PENDING_TAG;\n readonly [PENDING_TAG] = true;\n\n constructor(\n /** The resource that owns the observed data. */\n readonly source: ResourceRef,\n /** The path within that resource's observed data. */\n readonly path: string,\n ) {}\n\n static is(value: unknown): value is Pending {\n return (\n typeof value === 'object' &&\n value !== null &&\n (value as Record<symbol, unknown>)[PENDING_TAG] === true\n );\n }\n}\n\n/** Metadata associated with a ReadProxy instance. */\nexport interface ReadProxyMeta {\n readonly owner: ResourceRef;\n readonly path: string;\n}\n\n// ─── PendingTemplate ─────────────────────────────────────────────────────────\n\n/**\n * A Pending-like marker for strings produced by template literals that\n * interpolate one or more unresolved ReadProxy values.\n *\n * Holds the template structure so the resolve phase can reconstruct the\n * final string once all dependency slots are available.\n *\n * Invariant: parts.length === slots.length + 1\n * result = parts[0] + resolved[0] + parts[1] + … + resolved[n-1] + parts[n]\n */\nconst PENDING_TEMPLATE_TAG: unique symbol = Symbol.for(\n 'xplane.pendingTemplate',\n) as unknown as typeof PENDING_TEMPLATE_TAG;\n\nexport class PendingTemplate {\n static readonly TAG = PENDING_TEMPLATE_TAG;\n readonly [PENDING_TEMPLATE_TAG] = true;\n\n constructor(\n /** Literal text segments between (and around) pending slots. */\n readonly parts: readonly string[],\n /** The pending slots — each maps to an entry in a resource's observed state. */\n readonly slots: ReadonlyArray<{ source: ResourceRef; path: string }>,\n ) {}\n\n static is(value: unknown): value is PendingTemplate {\n return (\n typeof value === 'object' &&\n value !== null &&\n (value as Record<symbol, unknown>)[PENDING_TEMPLATE_TAG] === true\n );\n }\n}\n","import { AsyncLocalStorage } from 'node:async_hooks';\nimport type { ReadProxyMeta, ResourceRef } from './types.js';\nimport { PendingTemplate } from './types.js';\n\n// ─── Token Registry ───────────────────────────────────────────────────────────\n\nexport interface TokenRegistry {\n readonly byToken: Map<string, ReadProxyMeta>;\n readonly byKey: Map<string, string>;\n counter: number;\n}\n\n/**\n * Per-run AsyncLocalStorage for the template-literal token registry.\n * Kept separate from compositionStorage (core/) to avoid circular deps.\n */\nexport const tokenRegistryStorage = new AsyncLocalStorage<TokenRegistry>();\n\nexport function createTokenRegistry(): TokenRegistry {\n return { byToken: new Map(), byKey: new Map(), counter: 0 };\n}\n\n/**\n * Get or create a stable token for a given (owner, path) pair.\n * Returns null when no registry is active (outside of a composition run).\n */\nexport function getOrCreateToken(owner: ResourceRef, path: string): string | null {\n const registry = tokenRegistryStorage.getStore();\n if (!registry) return null;\n\n const key = `${owner.id}\\0${path}`;\n const existing = registry.byKey.get(key);\n if (existing !== undefined) return existing;\n\n const token = `__pending__tpl_${registry.counter++}__`;\n registry.byToken.set(token, { owner, path });\n registry.byKey.set(key, token);\n return token;\n}\n\nexport function lookupToken(token: string): ReadProxyMeta | undefined {\n return tokenRegistryStorage.getStore()?.byToken.get(token);\n}\n\n// ─── String Processing ────────────────────────────────────────────────────────\n\nconst TEMPLATE_TOKEN_RE = /__pending__tpl_\\d+__/g;\n\n/**\n * Scan a string for pending template tokens. If any are found, calls\n * `onSlot` for each registered token and returns a PendingTemplate.\n * Returns the original string if no tokens are found or none are registered.\n */\nexport function processStringValue(\n value: string,\n onSlot: (meta: ReadProxyMeta) => void,\n): PendingTemplate | string {\n const parts: string[] = [];\n const slots: Array<{ source: ResourceRef; path: string }> = [];\n let lastIndex = 0;\n let hasSlots = false;\n\n // Reset lastIndex before iterating (regex is stateful)\n TEMPLATE_TOKEN_RE.lastIndex = 0;\n\n for (const match of value.matchAll(TEMPLATE_TOKEN_RE)) {\n const meta = lookupToken(match[0]!);\n if (!meta) continue; // token not in registry — treat as literal\n\n hasSlots = true;\n parts.push(value.slice(lastIndex, match.index!));\n slots.push({ source: meta.owner, path: meta.path });\n onSlot(meta);\n lastIndex = match.index! + match[0]!.length;\n }\n\n if (!hasSlots) return value;\n\n parts.push(value.slice(lastIndex));\n return new PendingTemplate(parts, slots);\n}\n","import { getOrCreateToken } from './token-registry.js';\nimport type { ReadProxyMeta, ResourceRef } from './types.js';\n\n/**\n * WeakMap storing metadata for ReadProxy instances.\n * This avoids polluting proxy objects with symbols.\n */\nconst proxyMeta = new WeakMap<object, ReadProxyMeta>();\n\n/** Sentinel symbol to identify ReadProxy instances. */\nconst READ_PROXY_TAG = Symbol.for('xplane.readProxy');\n\n/**\n * Check if a value is a ReadProxy.\n */\nexport function isReadProxy(value: unknown): value is object {\n return (\n typeof value === 'object' &&\n value !== null &&\n (value as Record<symbol, unknown>)[READ_PROXY_TAG] === true\n );\n}\n\n/**\n * Get the metadata for a ReadProxy value.\n */\nexport function getReadProxyMeta(value: unknown): ReadProxyMeta | undefined {\n if (!isReadProxy(value)) return undefined;\n return proxyMeta.get(value as object);\n}\n\n/**\n * Creates a ReadProxy that wraps observed data.\n *\n * - Property access navigates into the data, building up the path.\n * - Missing paths return `undefined` (no placeholder proxies).\n * - The proxy carries owner + path metadata so that when it's assigned\n * to a WriteProxy, the dependency edge can be recorded.\n */\nexport function createReadProxy<T extends object>(\n target: T,\n owner: ResourceRef,\n basePath: string,\n): T {\n const proxy = new Proxy(target, {\n get(obj, prop, receiver) {\n // Identity checks\n if (prop === READ_PROXY_TAG) return true;\n if (typeof prop === 'symbol') return Reflect.get(obj, prop, receiver);\n if (prop === 'toJSON') return () => obj;\n\n const childPath = basePath ? `${basePath}.${String(prop)}` : String(prop);\n const value = Reflect.get(obj, prop, receiver);\n\n if (value === undefined || value === null) {\n // Return a \"leaf\" proxy with undefined target — carries metadata\n // for dependency edge creation but resolves to undefined\n return createLeafReadProxy(owner, childPath);\n }\n\n if (typeof value === 'object') {\n // Wrap nested objects so path accumulates\n return createReadProxy(value as object, owner, childPath);\n }\n\n // Primitive — wrap in a tagged object so it can carry metadata\n // when assigned to a WriteProxy\n return createPrimitiveReadProxy(value as string | number | boolean, owner, childPath);\n },\n\n has(obj, prop) {\n if (prop === READ_PROXY_TAG) return true;\n return Reflect.has(obj, prop);\n },\n });\n\n proxyMeta.set(proxy, { owner, path: basePath });\n return proxy as T;\n}\n\n/**\n * A \"leaf\" ReadProxy for paths that don't exist in observed data yet.\n * Carries metadata for edge creation. Resolves to `undefined` when\n * coerced to a primitive.\n */\nfunction createLeafReadProxy(owner: ResourceRef, path: string): object {\n const target = Object.create(null) as Record<string | symbol, unknown>;\n const getToken = () => getOrCreateToken(owner, path) ?? `__pending__${owner.id}__${path}`;\n const proxy = new Proxy(target, {\n get(_obj, prop) {\n if (prop === READ_PROXY_TAG) return true;\n if (prop === Symbol.toPrimitive) return () => getToken();\n if (typeof prop === 'symbol') return undefined;\n if (prop === 'toJSON') return () => undefined;\n if (prop === 'toString') return () => getToken();\n if (prop === 'valueOf') return () => proxy;\n // Nested access on a leaf — still a leaf with extended path\n return createLeafReadProxy(owner, `${path}.${String(prop)}`);\n },\n has(_obj, prop) {\n if (prop === READ_PROXY_TAG) return true;\n return false;\n },\n });\n proxyMeta.set(proxy, { owner, path });\n return proxy;\n}\n\n/**\n * Wraps a concrete primitive value so it carries ReadProxy metadata.\n * This allows the WriteProxy to detect it during assignment and\n * record the dependency edge, while the value itself resolves correctly.\n */\nexport function createPrimitiveReadProxy(\n value: string | number | boolean,\n owner: ResourceRef,\n path: string,\n): object {\n const target = Object.create(null) as Record<string | symbol, unknown>;\n const proxy = new Proxy(target, {\n get(_obj, prop) {\n if (prop === READ_PROXY_TAG) return true;\n if (prop === Symbol.toPrimitive) return () => value;\n if (prop === 'valueOf') return () => value;\n if (prop === 'toString') return () => String(value);\n if (prop === 'toJSON') return () => value;\n if (typeof prop === 'symbol') return undefined;\n // Navigating into a primitive — leaf\n return createLeafReadProxy(owner, `${path}.${String(prop)}`);\n },\n has(_obj, prop) {\n if (prop === READ_PROXY_TAG) return true;\n return false;\n },\n });\n proxyMeta.set(proxy, { owner, path });\n return proxy;\n}\n","import {\n createPrimitiveReadProxy,\n createReadProxy,\n getReadProxyMeta,\n isReadProxy,\n} from './read-proxy.js';\nimport { processStringValue } from './token-registry.js';\nimport { type DependencyEdge, Pending, type ResourceRef } from './types.js';\n\n/**\n * Collector that accumulates dependency edges discovered during\n * WriteProxy assignments.\n */\nexport class EdgeCollector {\n private readonly _edges: DependencyEdge[] = [];\n\n add(edge: DependencyEdge): void {\n // Deduplicate\n const exists = this._edges.some(\n (e) =>\n e.from.id === edge.from.id &&\n e.fromPath === edge.fromPath &&\n e.to.id === edge.to.id &&\n e.toPath === edge.toPath,\n );\n if (!exists) this._edges.push(edge);\n }\n\n get edges(): ReadonlyArray<DependencyEdge> {\n return this._edges;\n }\n}\n\nexport interface WriteProxyOptions {\n /** The resource that owns this desired document. */\n owner: ResourceRef;\n /** The collector to record edges into. */\n collector: EdgeCollector;\n /** Base path prefix (e.g., \"spec\" when wrapping the spec subtree). */\n basePath?: string;\n /** Optional observed state at the same path for fallback reads. */\n observed?: Record<string, unknown>;\n}\n\n/**\n * Creates a WriteProxy that wraps a desired document.\n *\n * - Writes store values in the target.\n * - When a ReadProxy value is assigned, it records a dependency edge\n * and stores a Pending marker if the value is not yet concrete.\n * - Reads return the stored value (desired-first).\n */\nexport function createWriteProxy<T extends object>(target: T, opts: WriteProxyOptions): T {\n const { owner, collector, basePath = '', observed } = opts;\n\n return new Proxy(target, {\n get(obj, prop, receiver) {\n if (typeof prop === 'symbol') return Reflect.get(obj, prop, receiver);\n if (prop === 'toJSON') return () => obj;\n\n const value = Reflect.get(obj, prop, receiver);\n\n // If the value is a nested object (not a Pending), wrap it recursively\n if (typeof value === 'object' && value !== null && !Pending.is(value)) {\n const childPath = basePath ? `${basePath}.${String(prop)}` : String(prop);\n const childObserved =\n observed && String(prop) in observed && typeof observed[String(prop)] === 'object'\n ? (observed[String(prop)] as Record<string, unknown>)\n : undefined;\n return createWriteProxy(value as object, {\n owner,\n collector,\n basePath: childPath,\n observed: childObserved,\n });\n }\n\n // If value is undefined and observed has data at this path, fall through to ReadProxy\n if (value === undefined && observed && String(prop) in observed) {\n const childPath = basePath ? `${basePath}.${String(prop)}` : String(prop);\n const obsValue = observed[String(prop)];\n if (typeof obsValue === 'object' && obsValue !== null) {\n return createReadProxy(obsValue as object, owner, childPath);\n }\n if (obsValue !== undefined && obsValue !== null) {\n return createPrimitiveReadProxy(obsValue as string | number | boolean, owner, childPath);\n }\n }\n\n // If value is undefined and observed doesn't have it either, return a leaf ReadProxy\n // so that cross-resource references create proper dependency edges and Pending markers\n if (value === undefined && observed !== undefined) {\n const childPath = basePath ? `${basePath}.${String(prop)}` : String(prop);\n return createReadProxy(Object.create(null) as object, owner, childPath);\n }\n\n return value;\n },\n\n set(obj, prop, value) {\n if (typeof prop === 'symbol') return Reflect.set(obj, prop, value);\n\n const targetPath = basePath ? `${basePath}.${String(prop)}` : String(prop);\n\n // Check if the value being assigned is a ReadProxy\n if (isReadProxy(value)) {\n const meta = getReadProxyMeta(value);\n if (meta && meta.owner.id !== owner.id) {\n // Record dependency edge\n collector.add({\n from: meta.owner,\n fromPath: meta.path,\n to: owner,\n toPath: targetPath,\n });\n\n // Try to extract a concrete value via Symbol.toPrimitive\n const primitive = tryExtractPrimitive(value);\n if (primitive !== undefined) {\n // The value is already concrete (primitive from observed data)\n return Reflect.set(obj, prop, primitive);\n }\n\n // Not concrete — store a Pending marker\n return Reflect.set(obj, prop, new Pending(meta.owner, meta.path));\n }\n\n // Self-reference or XR — try to extract value\n const primitive = tryExtractPrimitive(value);\n if (primitive !== undefined) {\n return Reflect.set(obj, prop, primitive);\n }\n\n // XR leaf with no value — store Pending\n if (meta) {\n collector.add({\n from: meta.owner,\n fromPath: meta.path,\n to: owner,\n toPath: targetPath,\n });\n return Reflect.set(obj, prop, new Pending(meta.owner, meta.path));\n }\n }\n\n // String with pending template tokens\n if (typeof value === 'string') {\n const processed = processStringValue(value, (meta) => {\n collector.add({ from: meta.owner, fromPath: meta.path, to: owner, toPath: targetPath });\n });\n return Reflect.set(obj, prop, processed);\n }\n\n // Plain object — deep-process to catch nested ReadProxy values\n if (typeof value === 'object' && value !== null && !Pending.is(value)) {\n const processed = deepProcessValue(value, owner, targetPath, collector);\n return Reflect.set(obj, prop, processed);\n }\n\n return Reflect.set(obj, prop, value);\n },\n\n deleteProperty(obj, prop) {\n return Reflect.deleteProperty(obj, prop);\n },\n }) as T;\n}\n\n/**\n * Try to extract a primitive value from a ReadProxy via Symbol.toPrimitive.\n * Returns `undefined` if the proxy represents a non-existent (leaf) value.\n */\nfunction tryExtractPrimitive(proxy: object): string | number | boolean | undefined {\n const toPrim = (proxy as Record<symbol, unknown>)[Symbol.toPrimitive];\n if (typeof toPrim === 'function') {\n const result = (toPrim as () => unknown)();\n if (result !== undefined && result !== null && typeof result !== 'object') {\n // Leaf proxy placeholders are not real values\n if (typeof result === 'string' && result.startsWith('__pending__')) return undefined;\n return result as string | number | boolean;\n }\n }\n return undefined;\n}\n\n/**\n * Deep-process a plain object/array being assigned to a WriteProxy.\n * Replaces any nested ReadProxy values with Pending markers or concrete values.\n */\nfunction deepProcessValue(\n value: unknown,\n owner: ResourceRef,\n basePath: string,\n collector: EdgeCollector,\n): unknown {\n if (value === null || value === undefined) return value;\n\n if (typeof value === 'string') {\n return processStringValue(value, (meta) => {\n collector.add({ from: meta.owner, fromPath: meta.path, to: owner, toPath: basePath });\n });\n }\n\n if (typeof value !== 'object') return value;\n\n if (isReadProxy(value)) {\n const meta = getReadProxyMeta(value)!;\n collector.add({\n from: meta.owner,\n fromPath: meta.path,\n to: owner,\n toPath: basePath,\n });\n const primitive = tryExtractPrimitive(value as object);\n if (primitive !== undefined) return primitive;\n return new Pending(meta.owner, meta.path);\n }\n\n if (Array.isArray(value as object)) {\n return (value as unknown[]).map((item, i) =>\n deepProcessValue(item, owner, `${basePath}[${i}]`, collector),\n );\n }\n\n // Plain object — recurse\n const result: Record<string, unknown> = {};\n for (const [key, val] of Object.entries(value as Record<string, unknown>)) {\n result[key] = deepProcessValue(val, owner, `${basePath}.${key}`, collector);\n }\n return result;\n}\n","import { Construct } from 'constructs';\n\nimport type { ReadyCheck, ReadyCheckFn } from '../readiness/index.js';\nimport {\n createPrimitiveReadProxy,\n createReadProxy,\n createWriteProxy,\n type DependencyGraph,\n type EdgeCollector,\n getReadProxyMeta,\n isReadProxy,\n Pending,\n type ResourceRef,\n} from '../tracking/index.js';\nimport { processStringValue } from '../tracking/token-registry.js';\nimport { compositionStorage } from './context.js';\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\n/** Minimal shape for a Kubernetes resource — only apiVersion + kind required. */\nexport interface KubernetesResource {\n apiVersion: string;\n kind: string;\n metadata?: {\n name?: string;\n namespace?: string;\n labels?: Record<string, string>;\n annotations?: Record<string, string>;\n [key: string]: unknown;\n };\n [key: string]: unknown;\n}\n\n/** Props passed to the Resource constructor — becomes the desired document. */\nexport interface ResourceProps {\n apiVersion: string;\n kind: string;\n [key: string]: unknown;\n}\n\n/** Framework configuration accessible via `resource.resource`. */\nexport interface ResourceConfig {\n autoReady: boolean;\n addReadyCheck(fn: ReadyCheckFn, priority?: number): void;\n}\n\n/** Internal metadata stored per Resource (not exposed on the proxy). */\ninterface ResourceInternals {\n /** Unique reference for the dependency graph. */\n ref: ResourceRef;\n /** The desired document (what the user wrote). */\n desired: Record<string, unknown>;\n /** The observed document (populated by the hydrate phase). */\n observed: Record<string, unknown>;\n /** Whether this is an external (existing) resource. */\n external: boolean;\n /** For external resources: the lookup key. */\n externalRef?: ExternalResourceRef;\n /** Framework config. */\n config: ResourceConfig;\n /** Custom readiness checks registered by the composition author. */\n readyChecks: ReadyCheck[];\n /** The dependency graph. */\n graph: DependencyGraph;\n /** The edge collector. */\n collector: EdgeCollector;\n}\n\nexport interface ExternalResourceRef {\n apiVersion: string;\n kind: string;\n name: unknown;\n namespace?: string;\n refKey: string;\n}\n\n// ─── WeakMap stores for internal data ─────────────────────────────────────────\n\nconst internals = new WeakMap<Resource, ResourceInternals>();\n\n// ─── Resource class ───────────────────────────────────────────────────────────\n\n/**\n * A Kubernetes resource within a Composition.\n *\n * The Resource instance acts as a \"desired-first, fallback-to-observed\" proxy:\n * - Reading a path that exists in the desired document returns the desired value.\n * - Reading a path that does NOT exist in desired falls through to a tracked\n * ReadProxy over observed state (creates dependency edges).\n * - Writing always goes to the desired document.\n *\n * The only reserved properties are `node` (from Construct) and `resource`\n * (framework config namespace).\n */\nexport class Resource extends Construct {\n readonly resource: ResourceConfig;\n declare metadata: {\n name?: string;\n namespace?: string;\n labels?: Record<string, string>;\n annotations?: Record<string, string>;\n [key: string]: unknown;\n };\n\n constructor(scope: Construct, id: string, props: ResourceProps) {\n super(scope, id);\n\n const graph = scope.node.tryGetContext('xplane:graph') as DependencyGraph;\n const collector = scope.node.tryGetContext('xplane:collector') as EdgeCollector;\n\n if (!graph || !collector) {\n throw new Error('Resource must be created within a Composition tree.');\n }\n\n const ref: ResourceRef = { id: this.node.path };\n graph.addResource(ref);\n\n const readyChecks: ReadyCheck[] = [];\n const config: ResourceConfig = {\n autoReady: true,\n addReadyCheck(fn: ReadyCheckFn, priority = 50) {\n readyChecks.push({ fn, priority });\n },\n };\n this.resource = config;\n\n // Process props — deep scan for ReadProxy values in the desired doc\n const desired = processDesiredProps(props, ref, collector);\n\n const internal: ResourceInternals = {\n ref,\n desired,\n observed: {},\n external: false,\n config,\n readyChecks,\n graph,\n collector,\n };\n internals.set(this, internal);\n\n // Pre-hydrate composed resources from observed data if available — so that\n // proxy reads during sibling construction (e.g. `Secret.fromExistingByName(this, other.status.x)`)\n // return real values instead of pending tokens that bake into construct IDs.\n const ctx = compositionStorage.getStore();\n if (ctx) {\n const observed = ctx.observedComposed.get(this.node.path);\n if (observed) {\n Object.assign(internal.observed, observed);\n }\n }\n\n // Return a proxy over `this` that implements the desired-first/observed-fallback\n const proxy = createResourceProxy(this, internal);\n\n // Patch the construct tree so node.children / findAll() yield the proxy\n // instead of the raw instance (which was registered during super()).\n // biome-ignore lint/suspicious/noExplicitAny: accessing private _children is intentional\n (scope.node as any)._children[this.node.id] = proxy;\n\n // Patch node.host so that node.findAll() (used by .with()) starts from the\n // proxy rather than the raw instance. Without this, applyTo() receives the\n // raw Resource where declared-only fields like `spec` are undefined at runtime.\n // biome-ignore lint/suspicious/noExplicitAny: patching constructs Node internals is intentional\n (this.node as any).host = proxy;\n\n // biome-ignore lint/correctness/noConstructorReturn: Proxy wrapping is intentional\n return proxy;\n }\n\n /**\n * Look up an existing cluster resource by name.\n * Returns a Resource that only has observed state (no desired output).\n *\n * The `name` parameter accepts either a plain string or a PrimitiveReadProxy\n * (returned when reading a tracked property like `ns.metadata.labels['x']`).\n * Proxies are coerced to their underlying string via `Symbol.toPrimitive`.\n */\n static fromExistingByName(\n scope: Construct,\n apiVersion: string,\n kind: string,\n name: unknown,\n namespace?: string,\n ): Resource {\n const resolvedName = coerceToString(name);\n const refKey = computeRefKey(apiVersion, kind, resolvedName, namespace);\n const id = `__existing__${refKey.replace(/\\//g, '_')}`;\n\n const instance = new Resource(scope, id, { apiVersion, kind });\n const internal = internals.get(instance)!;\n internal.external = true;\n internal.externalRef = { apiVersion, kind, name: resolvedName ?? name, namespace, refKey };\n\n // Pre-hydrate from context if observed data is already available (from a prior iteration)\n const ctx = compositionStorage.getStore();\n if (ctx) {\n const observed = ctx.requiredResources.get(refKey);\n if (observed) {\n Object.assign(internal.observed, observed);\n }\n }\n\n return instance;\n }\n\n /**\n * Generate a deterministic unique name based on the XR identity and construct path.\n * Useful for resource fields that need unique names (e.g., AWS resource names).\n */\n static uniqueName(\n scope: Construct,\n options: {\n maxLength?: number;\n separator?: string;\n allowedPattern?: RegExp;\n extra?: string;\n } = {},\n ): string {\n const maxLength = options.maxLength ?? 63;\n const separator = options.separator ?? '-';\n const allowedPattern = options.allowedPattern ?? /[^a-zA-Z0-9]/g;\n const escapedSep = separator.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n const collapseRe = new RegExp(`${escapedSep}+`, 'g');\n\n const clean = (s: string) =>\n s\n .replace(/\\s+/g, '')\n .replace(allowedPattern, separator)\n .replace(collapseRe, separator)\n .replace(new RegExp(`^${escapedSep}|${escapedSep}$`, 'g'), '');\n\n const xrMeta = scope.node.tryGetContext('xplane:xr-meta') as\n | { name?: string; namespace?: string }\n | undefined;\n\n const parts: string[] = [];\n if (xrMeta?.namespace) parts.push(clean(xrMeta.namespace));\n if (xrMeta?.name) parts.push(clean(xrMeta.name));\n for (const s of scope.node.scopes.slice(1)) {\n const c = clean(s.node.id);\n if (c) parts.push(c);\n }\n if (options.extra) {\n const c = clean(options.extra);\n if (c) parts.push(c);\n }\n\n const full = parts.join(separator);\n const hash = shortHash(full);\n const withHash = `${full}${separator}${hash}`;\n\n if (withHash.length <= maxLength) return withHash;\n const prefix = full.slice(0, maxLength - hash.length - separator.length);\n return `${prefix}${separator}${hash}`;\n }\n\n /**\n * Like {@link uniqueName} but produces names compliant with RFC 1123 DNS labels:\n * lowercase alphanumeric characters and hyphens only, starting and ending with\n * an alphanumeric character. Suitable for use as Kubernetes resource names.\n */\n static uniqueNameRfc1123(\n scope: Construct,\n options: {\n maxLength?: number;\n extra?: string;\n } = {},\n ): string {\n const maxLength = options.maxLength ?? 63;\n\n const clean = (s: string) =>\n s\n .toLowerCase()\n .replace(/\\s+/g, '')\n .replace(/[^a-z0-9-]/g, '-')\n .replace(/-+/g, '-')\n .replace(/^-|-$/g, '');\n\n const xrMeta = scope.node.tryGetContext('xplane:xr-meta') as\n | { name?: string; namespace?: string }\n | undefined;\n\n const parts: string[] = [];\n if (xrMeta?.namespace) parts.push(clean(xrMeta.namespace));\n if (xrMeta?.name) parts.push(clean(xrMeta.name));\n for (const s of scope.node.scopes.slice(1)) {\n const c = clean(s.node.id);\n if (c) parts.push(c);\n }\n if (options.extra) {\n const c = clean(options.extra);\n if (c) parts.push(c);\n }\n\n const full = parts.join('-');\n const hash = shortHash(full);\n const withHash = `${full}-${hash}`;\n\n if (withHash.length <= maxLength) return withHash;\n const prefix = full.slice(0, maxLength - hash.length - 1);\n const trimmedPrefix = prefix.replace(/-+$/, '');\n return trimmedPrefix ? `${trimmedPrefix}-${hash}` : hash;\n }\n}\n\n// ─── Internal accessors (used by pipeline phases) ─────────────────────────────\n\nexport function getResourceInternals(resource: Resource): ResourceInternals {\n const internal = internals.get(resource);\n if (!internal) throw new Error('Resource internals not found');\n return internal;\n}\n\nexport function getResourceRef(resource: Resource): ResourceRef {\n return getResourceInternals(resource).ref;\n}\n\nexport function getDesiredDocument(resource: Resource): Record<string, unknown> {\n return getResourceInternals(resource).desired;\n}\n\nexport function getObservedDocument(resource: Resource): Record<string, unknown> {\n return getResourceInternals(resource).observed;\n}\n\nexport function hydrateObserved(resource: Resource, data: Record<string, unknown>): void {\n const internal = getResourceInternals(resource);\n Object.assign(internal.observed, data);\n}\n\nexport function isExternal(resource: Resource): boolean {\n return getResourceInternals(resource).external;\n}\n\nexport function getExternalRef(resource: Resource): ExternalResourceRef | undefined {\n return getResourceInternals(resource).externalRef;\n}\n\nexport function getReadyChecks(resource: Resource): ReadyCheck[] {\n return getResourceInternals(resource).readyChecks;\n}\n\n// ─── Helpers ──────────────────────────────────────────────────────────────────\n\n/**\n * Coerce a value to a string, handling PrimitiveReadProxy objects that wrap\n * primitive values behind a `Symbol.toPrimitive` method.\n * Returns `undefined` if the value cannot be resolved to a string.\n */\nfunction coerceToString(value: unknown): string | undefined {\n if (typeof value === 'string') return value;\n if (\n value != null &&\n typeof (value as { [Symbol.toPrimitive]?: unknown })[Symbol.toPrimitive] === 'function'\n ) {\n return String(value);\n }\n return undefined;\n}\n\nexport function computeRefKey(\n apiVersion: string,\n kind: string,\n name: string | undefined,\n namespace?: string,\n): string {\n const namePart = name ?? '__unresolved__';\n if (namespace) return `${apiVersion}/${kind}/${namespace}/${namePart}`;\n return `${apiVersion}/${kind}/${namePart}`;\n}\n\nfunction shortHash(s: string): string {\n let h = 5381;\n for (let i = 0; i < s.length; i++) {\n h = ((h << 5) + h) ^ s.charCodeAt(i);\n h = h >>> 0;\n }\n return h.toString(16).padStart(8, '0');\n}\n\n/**\n * Process the desired props — deep-scan for ReadProxy values and replace them\n * with Pending markers (recording edges in the collector).\n */\nfunction processDesiredProps(\n props: ResourceProps,\n owner: ResourceRef,\n collector: EdgeCollector,\n): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(props)) {\n result[key] = processValue(value, owner, key, collector);\n }\n return result;\n}\n\nfunction processValue(\n value: unknown,\n owner: ResourceRef,\n path: string,\n collector: EdgeCollector,\n): unknown {\n if (value === null || value === undefined) return value;\n\n if (typeof value === 'string') {\n return processStringValue(value, (meta) => {\n collector.add({ from: meta.owner, fromPath: meta.path, to: owner, toPath: path });\n });\n }\n\n if (typeof value !== 'object') return value;\n\n if (isReadProxy(value)) {\n const meta = getReadProxyMeta(value)!;\n collector.add({\n from: meta.owner,\n fromPath: meta.path,\n to: owner,\n toPath: path,\n });\n // Try to get concrete value\n const prim = tryExtractPrimitive(value);\n if (prim !== undefined) return prim;\n return new Pending(meta.owner, meta.path);\n }\n\n if (Array.isArray(value as object)) {\n return (value as unknown[]).map((item, i) =>\n processValue(item, owner, `${path}[${i}]`, collector),\n );\n }\n\n const result: Record<string, unknown> = {};\n for (const [key, val] of Object.entries(value as Record<string, unknown>)) {\n result[key] = processValue(val, owner, `${path}.${key}`, collector);\n }\n return result;\n}\n\nfunction tryExtractPrimitive(proxy: object): string | number | boolean | undefined {\n const toPrim = (proxy as Record<symbol, unknown>)[Symbol.toPrimitive];\n if (typeof toPrim === 'function') {\n const result = (toPrim as () => unknown)();\n if (result !== undefined && result !== null && typeof result !== 'object') {\n // Leaf proxy placeholders are not real values\n if (typeof result === 'string' && result.startsWith('__pending__')) return undefined;\n return result as string | number | boolean;\n }\n }\n return undefined;\n}\n\n/**\n * Creates the \"desired-first, fallback-to-observed\" proxy around a Resource.\n */\nfunction createResourceProxy(resource: Resource, internal: ResourceInternals): Resource {\n const { ref, desired, collector } = internal;\n\n const proxy = new Proxy(resource, {\n get(target, prop, receiver) {\n // Framework reserved properties\n if (prop === 'node') return Reflect.get(target, prop, receiver);\n if (prop === 'resource') return Reflect.get(target, prop, receiver);\n if (typeof prop === 'symbol') return Reflect.get(target, prop, receiver);\n\n // Prototype methods and inherited Construct methods (e.g. .with(), .toString())\n if (prop === 'constructor') return Reflect.get(target, prop, receiver);\n const protoValue = Reflect.get(target, prop, receiver);\n if (typeof protoValue === 'function') return protoValue.bind(proxy);\n\n // Check desired first\n if (prop in desired) {\n const value = desired[String(prop)];\n if (typeof value === 'object' && value !== null && !Pending.is(value)) {\n // Return a WriteProxy so nested writes go to desired\n // Pass observed at the same path for fallback reads\n const observed = internal.observed;\n const observedAtPath =\n String(prop) in observed && typeof observed[String(prop)] === 'object'\n ? (observed[String(prop)] as Record<string, unknown>)\n : {};\n return createWriteProxy(value as object, {\n owner: ref,\n collector,\n basePath: String(prop),\n observed: observedAtPath,\n });\n }\n return value;\n }\n\n // Fallback to observed via ReadProxy\n const observed = internal.observed;\n if (String(prop) in observed) {\n const value = observed[String(prop)];\n if (typeof value === 'object' && value !== null) {\n return createReadProxy(value as object, ref, String(prop));\n }\n // Primitive observed value — wrap in ReadProxy for tracking\n return createPrimitiveReadProxyFromResource(value, ref, String(prop));\n }\n\n // Path exists in neither — return a lazy-init proxy that behaves as a\n // ReadProxy for reads but auto-initializes the path in desired on write.\n return createLazyInitProxy(desired, ref, collector, String(prop));\n },\n\n set(target, prop, value) {\n if (typeof prop === 'symbol') return Reflect.set(target, prop, value);\n if (prop === 'resource') return Reflect.set(target, prop, value);\n\n // All writes go to desired, processing ReadProxy values\n const path = String(prop);\n desired[path] = processValue(value, ref, path, collector);\n return true;\n },\n\n has(target, prop) {\n if (typeof prop === 'symbol') return Reflect.has(target, prop);\n if (prop === 'node' || prop === 'resource') return true;\n return prop in desired || prop in internal.observed;\n },\n }) as Resource;\n\n // Store internal mapping for the proxy too, so internals.get(proxy) works\n internals.set(proxy, internal);\n return proxy;\n}\n\n/**\n * Wrap a primitive observed value so it carries ReadProxy metadata\n * for dependency tracking when assigned elsewhere.\n */\nfunction createPrimitiveReadProxyFromResource(\n value: unknown,\n owner: ResourceRef,\n path: string,\n): unknown {\n if (value === null || value === undefined) return value;\n return createPrimitiveReadProxy(value as string | number | boolean, owner, path);\n}\n\n/**\n * Creates a proxy for a path that exists in neither desired nor observed.\n * - Reading nested properties returns ReadProxy leaves (for dependency tracking).\n * - Writing a nested property auto-initializes the path in desired and stores the value.\n */\nfunction createLazyInitProxy(\n desired: Record<string, unknown>,\n owner: ResourceRef,\n collector: EdgeCollector,\n basePath: string,\n): object {\n const readProxy = createReadProxy({} as object, owner, basePath);\n\n return new Proxy(readProxy as object, {\n get(target, prop, receiver) {\n if (typeof prop === 'symbol') return Reflect.get(target, prop, receiver);\n // Delegate reads to the ReadProxy (for tracking)\n return Reflect.get(target, prop, receiver);\n },\n\n set(_target, prop, value) {\n if (typeof prop === 'symbol') return false;\n // Auto-initialize the parent object in desired\n let container = desired[basePath] as Record<string, unknown> | undefined;\n if (!container || typeof container !== 'object') {\n container = {};\n desired[basePath] = container;\n }\n container[String(prop)] = processValue(\n value,\n owner,\n `${basePath}.${String(prop)}`,\n collector,\n );\n return true;\n },\n });\n}\n","import { AsyncLocalStorage } from 'node:async_hooks';\n\nimport type { XplaneLogger } from './types.js';\n\nconst noopLogger: XplaneLogger = {\n debug() {},\n info() {},\n warn() {},\n};\n\nconst loggerStorage = new AsyncLocalStorage<XplaneLogger>();\n\n/**\n * Get the current logger from async context.\n * Returns a no-op logger if none has been set (silent by default).\n */\nexport function getLogger(): XplaneLogger {\n return loggerStorage.getStore() ?? noopLogger;\n}\n\n/**\n * Run a function with a logger available in async context.\n * All code within `fn` (and any nested async calls) can access\n * the logger via `getLogger()`.\n */\nexport function withLogger<T>(logger: XplaneLogger, fn: () => T): T {\n return loggerStorage.run(logger, fn);\n}\n","import {\n getDesiredDocument,\n getExternalRef,\n getObservedDocument,\n getResourceRef,\n isExternal,\n} from '../core/resource.js';\nimport { Pending } from '../tracking/index.js';\n\nimport type { DiagnosticReport, PipelineState } from './types.js';\n\n/**\n * DIAGNOSE phase: produce structured diagnostics for blocked resources.\n *\n * For each resource classified as 'blocked':\n * - Find all Pending markers in the desired document\n * - Report what they're waiting on (source resource + path)\n *\n * For circular dependencies (detected in sequence phase):\n * - Produce a 'cycle' diagnostic with the full cycle path\n */\nexport function diagnose(state: PipelineState): PipelineState {\n const diagnostics: DiagnosticReport[] = [];\n\n // Check for cycles from the graph\n const sortResult = state.graph.topologicalSort();\n if (sortResult.order === null && sortResult.cycle) {\n const firstCycleMember = sortResult.cycle[0];\n if (firstCycleMember) {\n diagnostics.push({\n resource: firstCycleMember,\n reason: 'cycle',\n cycle: sortResult.cycle,\n });\n }\n }\n\n // Report external resources that were required but not found.\n // Skip externals whose lookup name is itself unresolved (still a pending\n // template token, or non-string): the handler never sent a require for\n // them, so they aren't \"not found\" — they are downstream-blocked, and the\n // root cause (whatever upstream they're waiting on) will be reported on\n // its own.\n for (const resource of state.resources) {\n if (!isExternal(resource)) continue;\n const ref = getExternalRef(resource);\n if (!ref) continue;\n const observed = getObservedDocument(resource);\n if (Object.keys(observed).length > 0) continue; // hydrated, no problem\n if (typeof ref.name !== 'string' || ref.name.startsWith('__pending__')) continue;\n const nsDisplay = ref.namespace ? ` in namespace '${ref.namespace}'` : '';\n diagnostics.push({\n resource: getResourceRef(resource).id,\n reason: 'not-found',\n detail: `External resource ${ref.apiVersion}/${ref.kind} '${ref.name}'${nsDisplay} was required but not found by Crossplane`,\n });\n }\n\n // For each blocked resource, find pending paths\n const pendingDiagnostics: DiagnosticReport[] = [];\n for (const resource of state.resources) {\n if (isExternal(resource)) continue;\n\n const ref = getResourceRef(resource);\n const classification = state.classification.get(ref.id);\n if (classification !== 'blocked') continue;\n\n // Skip if already reported as cycle member\n if (sortResult.order === null && sortResult.cycle?.includes(ref.id)) continue;\n\n const desired = getDesiredDocument(resource);\n const pendingPaths = findPendingPaths(desired, '');\n\n if (pendingPaths.length > 0) {\n pendingDiagnostics.push({\n resource: ref.id,\n reason: 'pending',\n pendingPaths,\n });\n }\n }\n\n // Filter out cascading diagnostics: only keep pending diagnostics that have\n // at least one dependency that is NOT itself blocked or not-found.\n // This surfaces only root causes rather than the full dependency cascade.\n const notFoundIds = new Set(\n diagnostics.filter((d) => d.reason === 'not-found').map((d) => d.resource),\n );\n const blockedIds = new Set(pendingDiagnostics.map((d) => d.resource));\n\n for (const diag of pendingDiagnostics) {\n const isRootCause = diag.pendingPaths?.some((p) => {\n const dep = p.waitingOn.resource;\n // If waiting on something that isn't blocked or not-found, this IS a root cause\n return !blockedIds.has(dep) && !notFoundIds.has(dep);\n });\n if (isRootCause) {\n diagnostics.push(diag);\n }\n }\n\n return { ...state, diagnostics };\n}\n\n/**\n * Recursively find all Pending markers in a document and report their source.\n */\nfunction findPendingPaths(\n obj: unknown,\n basePath: string,\n): Array<{ path: string; waitingOn: { resource: string; path: string } }> {\n const results: Array<{ path: string; waitingOn: { resource: string; path: string } }> = [];\n\n if (obj === null || obj === undefined) return results;\n if (Pending.is(obj)) {\n results.push({\n path: basePath,\n waitingOn: { resource: obj.source.id, path: obj.path },\n });\n return results;\n }\n if (typeof obj !== 'object') return results;\n\n if (Array.isArray(obj)) {\n for (let i = 0; i < obj.length; i++) {\n const childPath = basePath ? `${basePath}[${i}]` : `[${i}]`;\n results.push(...findPendingPaths(obj[i], childPath));\n }\n return results;\n }\n\n for (const [key, value] of Object.entries(obj as Record<string, unknown>)) {\n const childPath = basePath ? `${basePath}.${key}` : key;\n results.push(...findPendingPaths(value, childPath));\n }\n return results;\n}\n","import { getXrDesiredStatus } from '../core/composition.js';\nimport {\n getDesiredDocument,\n getObservedDocument,\n getReadyChecks,\n getResourceInternals,\n getResourceRef,\n isExternal,\n} from '../core/resource.js';\nimport { getReadProxyMeta, isReadProxy } from '../tracking/index.js';\nimport { PendingTemplate } from '../tracking/types.js';\n\nimport type { EmittedResource, PipelineState } from './types.js';\n\n/**\n * EMIT phase: serialize each resource classified as 'emit' into a plain\n * Kubernetes resource document ready for Crossplane.\n *\n * Also extracts the XR desired status from this.xr.status assignments.\n *\n * For resources classified as 'blocked' that have previously-observed state,\n * emits the observed document as-is (marked `preserved: true`) so that\n * Crossplane does not delete them while their dependencies are still resolving.\n */\nexport function emit(state: PipelineState): PipelineState {\n const emitted: EmittedResource[] = [];\n\n for (const resource of state.resources) {\n if (isExternal(resource)) continue;\n\n const ref = getResourceRef(resource);\n const classification = state.classification.get(ref.id);\n\n if (classification === 'emit') {\n const internal = getResourceInternals(resource);\n const desired = getDesiredDocument(resource);\n\n // Strip the construct path prefix to get the resource name\n // The name is the full construct path minus the root \"Composition/\" prefix\n const name = ref.id.startsWith('Composition/') ? ref.id.slice('Composition/'.length) : ref.id;\n\n emitted.push({\n name,\n document: deepClean(desired),\n autoReady: internal.config.autoReady,\n readyChecks: getReadyChecks(resource),\n });\n } else if (classification === 'blocked') {\n // If this resource has been observed before (i.e. Crossplane already created it),\n // emit the observed document stripped of server-managed fields so Crossplane does\n // not delete it while its dependencies are still pending.\n const observed = getObservedDocument(resource);\n if (Object.keys(observed).length === 0) continue;\n\n const name = ref.id.startsWith('Composition/') ? ref.id.slice('Composition/'.length) : ref.id;\n\n emitted.push({\n name,\n document: stripServerFields(deepClean(observed)),\n autoReady: false,\n readyChecks: [],\n preserved: true,\n });\n }\n }\n\n // Extract XR status and resolve any ReadProxy values using observed data\n const resourceById = new Map(state.resources.map((r) => [getResourceRef(r).id, r]));\n const rawStatus = getXrDesiredStatus(state.composition);\n const xrStatusPatches = resolveXrStatus(rawStatus, resourceById);\n\n return { ...state, emitted, xrStatusPatches };\n}\n\n/**\n * Deep-clone an object, stripping any remaining framework internals.\n * This produces a clean JSON-serializable Kubernetes document.\n */\nfunction deepClean(obj: Record<string, unknown>): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(obj)) {\n result[key] = cleanValue(value);\n }\n\n return result;\n}\n\nfunction cleanValue(value: unknown): unknown {\n if (value === null || value === undefined) return value;\n if (typeof value !== 'object') return value;\n\n if (PendingTemplate.is(value)) {\n // Should never reach emit — indicates a bug in the pipeline\n throw new Error(\n `PendingTemplate reached emit phase — resource should have been classified as blocked. Parts: ${JSON.stringify(value.parts)}`,\n );\n }\n\n if (Array.isArray(value)) {\n return value.map(cleanValue);\n }\n\n // Plain objects — recurse\n const result: Record<string, unknown> = {};\n for (const [key, val] of Object.entries(value as Record<string, unknown>)) {\n result[key] = cleanValue(val);\n }\n return result;\n}\n\n/**\n * Strip server-managed Kubernetes fields from an observed document before\n * emitting it as a preserved desired resource.\n *\n * These fields are set by the API server / controllers and must not appear\n * in the desired state — including them causes Crossplane to try propagating\n * them (e.g. `uid`) into XR resourceRefs fields that the XRD schema may not\n * declare, resulting in a typed-patch validation failure.\n */\nconst SERVER_MANAGED_METADATA = new Set([\n 'uid',\n 'resourceVersion',\n 'generation',\n 'creationTimestamp',\n 'deletionTimestamp',\n 'deletionGracePeriodSeconds',\n 'managedFields',\n 'ownerReferences',\n 'selfLink',\n]);\n\nfunction stripServerFields(doc: Record<string, unknown>): Record<string, unknown> {\n const result: Record<string, unknown> = { ...doc };\n\n // Remove top-level status — it is managed by the controller, not desired state\n delete result.status;\n\n // Strip server-managed metadata sub-fields\n if (result.metadata && typeof result.metadata === 'object') {\n const meta = { ...(result.metadata as Record<string, unknown>) };\n for (const field of SERVER_MANAGED_METADATA) {\n delete meta[field];\n }\n result.metadata = meta;\n }\n\n return result;\n}\n\n/**\n * Resolve ReadProxy values in XR status using observed resource data.\n * This is needed because XR status is written at construction time (before hydration),\n * so read proxy references need to be resolved post-hydration.\n */\nfunction resolveXrStatus(\n status: Record<string, unknown>,\n resourceById: ReadonlyMap<string, import('../core/resource.js').Resource>,\n): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(status)) {\n const resolved = resolveStatusValue(value, resourceById);\n if (resolved !== undefined) {\n result[key] = resolved;\n }\n }\n return result;\n}\n\nfunction resolveStatusValue(\n value: unknown,\n resourceById: ReadonlyMap<string, import('../core/resource.js').Resource>,\n): unknown {\n if (value === null || value === undefined) return undefined;\n\n if (isReadProxy(value)) {\n const meta = getReadProxyMeta(value);\n if (!meta) return undefined;\n\n // Try to extract a concrete primitive (already resolved read proxy)\n const prim = tryExtractPrimitive(value as object);\n if (prim !== undefined) return prim;\n\n // Leaf proxy — try to resolve from observed data\n const resource = resourceById.get(meta.owner.id);\n if (!resource) return undefined;\n const observed = getObservedDocument(resource);\n return getNestedValue(observed, meta.path);\n }\n\n if (Array.isArray(value)) {\n return value.map((v) => resolveStatusValue(v, resourceById)).filter((v) => v != null);\n }\n\n if (typeof value === 'object') {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value as Record<string, unknown>)) {\n const resolved = resolveStatusValue(v, resourceById);\n if (resolved !== undefined) {\n out[k] = resolved;\n }\n }\n return Object.keys(out).length > 0 ? out : undefined;\n }\n\n return value;\n}\n\nfunction tryExtractPrimitive(proxy: object): string | number | boolean | undefined {\n const toPrim = (proxy as Record<symbol, unknown>)[Symbol.toPrimitive];\n if (typeof toPrim === 'function') {\n const result = (toPrim as () => unknown)();\n if (result !== undefined && result !== null && typeof result !== 'object') {\n // Leaf proxy placeholders are not real values — skip them\n if (typeof result === 'string' && result.startsWith('__pending__')) return undefined;\n return result as string | number | boolean;\n }\n }\n return undefined;\n}\n\nfunction getNestedValue(obj: Record<string, unknown>, path: string): unknown {\n const parts = path.split('.');\n let current: unknown = obj;\n for (const part of parts) {\n if (current === null || current === undefined || typeof current !== 'object') return undefined;\n current = (current as Record<string, unknown>)[part];\n }\n return current;\n}\n","import { getExternalRef, hydrateObserved, isExternal } from '../core/resource.js';\n\nimport type { PipelineState } from './types.js';\n\n/**\n * HYDRATE phase: feed observed state from Crossplane into each resource.\n *\n * - Composed resources are matched by their construct path (resource name).\n * - External resources are matched by their refKey.\n */\nexport function hydrate(state: PipelineState): PipelineState {\n for (const resource of state.resources) {\n if (isExternal(resource)) {\n const ref = getExternalRef(resource);\n if (ref) {\n const observed = state.observedRequired.get(ref.refKey);\n if (observed) {\n hydrateObserved(resource, observed);\n }\n }\n } else {\n // Match by construct path\n const name = resource.node.path;\n const observed = state.observedComposed.get(name);\n if (observed) {\n hydrateObserved(resource, observed);\n }\n }\n }\n\n return state;\n}\n","import { getDesiredDocument, getObservedDocument, getResourceRef } from '../core/resource.js';\nimport { Pending, PendingTemplate } from '../tracking/index.js';\n\nimport type { PipelineState } from './types.js';\n\n/**\n * RESOLVE phase: walk dependency edges and replace Pending markers\n * with concrete values from observed state where available.\n *\n * For each resource's desired document, recursively find Pending values.\n * Look up the source resource's observed state at the source path.\n * If concrete → replace. If not available → leave Pending in place.\n */\nexport function resolve(state: PipelineState): PipelineState {\n // Build a lookup: resource id → Resource instance\n const resourceById = new Map(state.resources.map((r) => [getResourceRef(r).id, r]));\n\n for (const resource of state.resources) {\n const desired = getDesiredDocument(resource);\n resolvePending(desired, resourceById);\n }\n\n return state;\n}\n\n/**\n * Recursively walk an object and resolve any Pending markers.\n */\nfunction resolvePending(\n obj: Record<string, unknown>,\n resourceById: ReadonlyMap<string, import('../core/resource.js').Resource>,\n): void {\n for (const [key, value] of Object.entries(obj)) {\n if (Pending.is(value)) {\n const sourceResource = resourceById.get(value.source.id);\n if (sourceResource) {\n const observed = getObservedDocument(sourceResource);\n const resolved = getNestedValue(observed, value.path);\n if (resolved !== undefined) {\n obj[key] = resolved;\n }\n // else: leave Pending in place — still unresolved\n }\n } else if (PendingTemplate.is(value)) {\n const resolved = resolvePendingTemplate(value, resourceById);\n if (resolved !== undefined) obj[key] = resolved;\n } else if (Array.isArray(value)) {\n resolveArray(value, resourceById);\n } else if (value !== null && typeof value === 'object') {\n resolvePending(value as Record<string, unknown>, resourceById);\n }\n }\n}\n\nfunction resolveArray(\n arr: unknown[],\n resourceById: ReadonlyMap<string, import('../core/resource.js').Resource>,\n): void {\n for (let i = 0; i < arr.length; i++) {\n const value = arr[i];\n if (Pending.is(value)) {\n const sourceResource = resourceById.get(value.source.id);\n if (sourceResource) {\n const observed = getObservedDocument(sourceResource);\n const resolved = getNestedValue(observed, value.path);\n if (resolved !== undefined) {\n arr[i] = resolved;\n }\n }\n } else if (PendingTemplate.is(value)) {\n const resolved = resolvePendingTemplate(value, resourceById);\n if (resolved !== undefined) arr[i] = resolved;\n } else if (Array.isArray(value)) {\n resolveArray(value, resourceById);\n } else if (value !== null && typeof value === 'object') {\n resolvePending(value as Record<string, unknown>, resourceById);\n }\n }\n}\n\n/**\n * Get a nested value from an object by dot-separated path.\n */\nfunction getNestedValue(obj: Record<string, unknown>, path: string): unknown {\n const segments = path.split('.');\n let current: unknown = obj;\n\n for (const segment of segments) {\n if (current === null || current === undefined) return undefined;\n if (typeof current !== 'object') return undefined;\n current = (current as Record<string, unknown>)[segment];\n }\n\n return current;\n}\n\n/**\n * Attempt to resolve all slots of a PendingTemplate.\n * Returns the reconstructed string if all slots resolve, undefined otherwise.\n */\nfunction resolvePendingTemplate(\n template: PendingTemplate,\n resourceById: ReadonlyMap<string, import('../core/resource.js').Resource>,\n): string | undefined {\n const values: string[] = [];\n for (const slot of template.slots) {\n const sourceResource = resourceById.get(slot.source.id);\n if (!sourceResource) return undefined;\n const observed = getObservedDocument(sourceResource);\n const resolved = getNestedValue(observed, slot.path);\n if (resolved === undefined || resolved === null) return undefined;\n values.push(String(resolved));\n }\n let result = template.parts[0]!;\n for (let i = 0; i < values.length; i++) {\n result += values[i] + template.parts[i + 1]!;\n }\n return result;\n}\n","import { getDesiredDocument, getResourceRef, isExternal } from '../core/resource.js';\nimport { Pending, PendingTemplate } from '../tracking/index.js';\n\nimport type { PipelineState, ResourceClassification } from './types.js';\n\n/**\n * SEQUENCE phase: topological sort and classification.\n *\n * - Runs topological sort on the dependency graph.\n * - Classifies each resource as 'emit', 'blocked', or 'external'.\n * - A resource is 'blocked' if it still has Pending markers in its desired document.\n * - External resources are classified as 'external' (never emitted).\n * - Circular dependencies are detected via the graph's topological sort.\n */\nexport function sequence(state: PipelineState): PipelineState {\n const classification = new Map<string, ResourceClassification>();\n\n // Run topological sort for cycle detection\n const sortResult = state.graph.topologicalSort();\n\n // Classify each resource\n for (const resource of state.resources) {\n const ref = getResourceRef(resource);\n\n if (isExternal(resource)) {\n classification.set(ref.id, 'external');\n continue;\n }\n\n // Check if this resource has any remaining Pending markers\n const desired = getDesiredDocument(resource);\n const hasPending = containsPending(desired);\n\n if (hasPending) {\n classification.set(ref.id, 'blocked');\n } else {\n classification.set(ref.id, 'emit');\n }\n }\n\n // If there's a cycle, mark all cycle members as blocked\n if (sortResult.order === null && sortResult.cycle) {\n for (const id of sortResult.cycle) {\n if (classification.get(id) !== 'external') {\n classification.set(id, 'blocked');\n }\n }\n }\n\n return { ...state, classification };\n}\n\n/**\n * Recursively check if an object contains any Pending markers.\n */\nfunction containsPending(obj: unknown): boolean {\n if (obj === null || obj === undefined) return false;\n if (Pending.is(obj)) return true;\n if (PendingTemplate.is(obj)) return true;\n if (typeof obj !== 'object') return false;\n\n if (Array.isArray(obj)) {\n return obj.some(containsPending);\n }\n\n for (const value of Object.values(obj as Record<string, unknown>)) {\n if (containsPending(value)) return true;\n }\n return false;\n}\n","import type { Composition } from '../core/composition.js';\nimport type { Resource } from '../core/resource.js';\n\nimport { diagnose } from './diagnose.js';\nimport { emit } from './emit.js';\nimport { hydrate } from './hydrate.js';\nimport { resolve } from './resolve.js';\nimport { sequence } from './sequence.js';\nimport type { PipelineState } from './types.js';\n\nexport { diagnose } from './diagnose.js';\nexport { emit } from './emit.js';\nexport { hydrate } from './hydrate.js';\nexport { resolve } from './resolve.js';\nexport { sequence } from './sequence.js';\nexport type {\n DiagnosticReport,\n EmittedResource,\n PipelineState,\n ResourceClassification,\n} from './types.js';\n\n/**\n * Input to the pipeline — provided by the handler or simulator.\n */\nexport interface PipelineInput {\n /** The constructed Composition instance. */\n composition: Composition;\n /** Observed composed resources from Crossplane (keyed by resource name). */\n observedComposed: ReadonlyMap<string, Record<string, unknown>>;\n /** Observed existing/required resources (keyed by refKey). */\n observedRequired: ReadonlyMap<string, Record<string, unknown>>;\n}\n\n/**\n * Run the full rendering pipeline.\n *\n * Phases: hydrate → resolve → sequence → diagnose → emit\n */\nexport function runPipeline(input: PipelineInput): PipelineState {\n const resources = collectResources(input.composition);\n\n const initialState: PipelineState = {\n composition: input.composition,\n resources,\n graph: input.composition.graph,\n observedComposed: input.observedComposed,\n observedRequired: input.observedRequired,\n classification: new Map(),\n diagnostics: [],\n emitted: [],\n xrStatusPatches: {},\n };\n\n // Run phases sequentially — each transforms the state\n let state = initialState;\n state = hydrate(state);\n state = resolve(state);\n state = sequence(state);\n state = diagnose(state);\n state = emit(state);\n\n return state;\n}\n\n/**\n * Collect all Resource instances from the composition's construct tree.\n */\nfunction collectResources(composition: Composition): Resource[] {\n const resources: Resource[] = [];\n collectFromNode(composition, resources);\n return resources;\n}\n\nfunction collectFromNode(construct: import('constructs').Construct, resources: Resource[]): void {\n for (const child of construct.node.children) {\n // Check if it's a Resource (has our internals)\n if (isResourceInstance(child)) {\n resources.push(child as Resource);\n }\n // Recurse into children\n collectFromNode(child, resources);\n }\n}\n\nfunction isResourceInstance(obj: unknown): obj is Resource {\n if (obj === null || typeof obj !== 'object') return false;\n const r = obj as Record<string, unknown>;\n if (!('resource' in r) || r.resource === null || typeof r.resource !== 'object') return false;\n return 'autoReady' in (r.resource as object);\n}\n","import type { ReadyCheck } from './types.js';\n\n/**\n * Checks if the resource has a `Ready` condition with status `True`.\n */\nexport function conditionReady(observed: Record<string, unknown>): boolean | undefined {\n const status = observed.status as Record<string, unknown> | undefined;\n const conditions = status?.conditions as Array<Record<string, unknown>> | undefined;\n if (!conditions || !Array.isArray(conditions)) return undefined;\n\n const ready = conditions.find((c) => c.type === 'Ready');\n if (!ready) return undefined;\n\n return ready.status === 'True';\n}\n\n/**\n * Vetoes readiness when a `Synced` condition is explicitly `False` (Crossplane\n * provider reconciliation error). Returns `undefined` otherwise so this check\n * does not by itself imply readiness — it only blocks it.\n */\nexport function syncedNotFalse(observed: Record<string, unknown>): boolean | undefined {\n const status = observed.status as Record<string, unknown> | undefined;\n const conditions = status?.conditions as Array<Record<string, unknown>> | undefined;\n if (!conditions || !Array.isArray(conditions)) return undefined;\n\n const synced = conditions.find((c) => c.type === 'Synced');\n if (!synced) return undefined;\n\n return synced.status === 'False' ? false : undefined;\n}\n\n/**\n * Checks if the resource has `status.ready === true`.\n */\nexport function statusReady(observed: Record<string, unknown>): boolean | undefined {\n const status = observed.status as Record<string, unknown> | undefined;\n if (status === undefined) return undefined;\n if (!('ready' in status)) return undefined;\n\n return status.ready === true;\n}\n\n/**\n * Fallback: resource exists in observed state → ready.\n * Always returns `true` (only called when observed is defined).\n */\nexport function exists(_observed: Record<string, unknown>): boolean {\n return true;\n}\n\n/**\n * Built-in default readiness checks, appended at low priority.\n */\nexport const DEFAULT_CHECKS: ReadyCheck[] = [\n { fn: conditionReady, priority: 100, name: 'conditionReady' },\n { fn: syncedNotFalse, priority: 100, name: 'syncedNotFalse' },\n { fn: statusReady, priority: 200, name: 'statusReady' },\n { fn: exists, priority: 1000, name: 'exists' },\n];\n","import { getLogger } from '../logging/index.js';\n\nimport type { ReadyCheck } from './types.js';\n\n/**\n * Evaluate readiness for a resource by running checks grouped by priority.\n *\n * - If `observed` is undefined, the resource doesn't exist yet → not ready.\n * - Checks are grouped by priority (ascending). Within a group, all checks\n * are AND-ed: if any returns `false`, the resource is not ready. If at least\n * one returns `true` and none return `false`, the resource is ready.\n * If all return `undefined`, cascade to the next priority group.\n * - Final fallback (no group had a definitive answer): not ready.\n */\nexport function evaluateReadiness(\n checks: ReadyCheck[],\n observed: Record<string, unknown> | undefined,\n): boolean {\n const log = getLogger();\n\n if (!observed) {\n log.debug('readiness: resource not observed, not ready');\n return false;\n }\n\n // Group checks by priority\n const groups = new Map<number, ReadyCheck[]>();\n for (const check of checks) {\n const group = groups.get(check.priority);\n if (group) {\n group.push(check);\n } else {\n groups.set(check.priority, [check]);\n }\n }\n\n // Process groups in ascending priority order\n const priorities = [...groups.keys()].sort((a, b) => a - b);\n\n for (const priority of priorities) {\n const group = groups.get(priority)!;\n let hasTrue = false;\n let hasFalse = false;\n const results: Array<{ name: string; result: boolean | undefined }> = [];\n\n for (const check of group) {\n const result = check.fn(observed);\n results.push({ name: check.name ?? 'anonymous', result });\n\n if (result === false) {\n hasFalse = true;\n break; // Short-circuit: one false in the group → not ready\n }\n if (result === true) {\n hasTrue = true;\n }\n }\n\n log.debug('readiness: evaluated group', { priority, results });\n\n if (hasFalse) {\n log.debug('readiness: group returned false, not ready', { priority });\n return false;\n }\n if (hasTrue) {\n log.debug('readiness: group returned true, ready', { priority });\n return true;\n }\n // All undefined → cascade to next group\n }\n\n log.debug('readiness: no group had definitive answer, not ready');\n return false;\n}\n","import type {\n BlockedResource,\n CompositionInput,\n CompositionResult,\n DesiredResource,\n ExternalResourceRequest,\n} from './contract.js';\nimport type { Composition } from './core/composition.js';\nimport type { CompositionContext } from './core/context.js';\nimport { compositionStorage } from './core/context.js';\nimport { getDesiredDocument, getExternalRef, getResourceRef, isExternal } from './core/resource.js';\nimport { runPipeline } from './pipeline/index.js';\nimport { DEFAULT_CHECKS, evaluateReadiness } from './readiness/index.js';\nimport { DependencyGraph, EdgeCollector } from './tracking/index.js';\nimport { createTokenRegistry, tokenRegistryStorage } from './tracking/token-registry.js';\n\n/**\n * Run a composition class with the given input and return a plain-data result.\n *\n * This is the single entry point that bridges the composition author's class\n * with the runtime. It handles:\n * 1. Setting up internal context (DependencyGraph, EdgeCollector, ALS)\n * 2. Instantiating the Composition class\n * 3. Running the full pipeline (hydrate → resolve → sequence → diagnose → emit)\n * 4. Evaluating readiness per resource\n * 5. Returning a fully serializable CompositionResult\n *\n * The runtime never needs to access framework internals — everything it needs\n * is in the returned plain-data structure.\n */\nexport function runComposition<TSpec, TStatus, TContext extends object>(\n CompositionClass: new () => Composition<TSpec, TStatus, TContext>,\n input: CompositionInput,\n): CompositionResult {\n // Convert plain Records to Maps for the internal pipeline\n const observedComposed = new Map(Object.entries(input.observedComposed));\n const observedRequired = new Map(Object.entries(input.observedRequired));\n\n // Set up internal context\n const graph = new DependencyGraph();\n const collector = new EdgeCollector();\n const pipelineContext = new Map(Object.entries(input.pipelineContext));\n\n const ctx: CompositionContext = {\n xr: input.xr,\n pipelineContext,\n requiredResources: observedRequired,\n observedComposed,\n graph,\n collector,\n };\n\n // Instantiate composition within ALS context\n const composition = compositionStorage.run(ctx, () =>\n tokenRegistryStorage.run(createTokenRegistry(), () => new CompositionClass()),\n ) as Composition;\n\n // Run the pipeline\n const state = runPipeline({ composition, observedComposed, observedRequired });\n\n // Build the result — plain data only\n const resources: DesiredResource[] = state.emitted.map((emitted) => {\n const k8sName = extractMetadataName(emitted.document);\n const namespace = extractMetadataNamespace(emitted.document);\n if (emitted.preserved) {\n // Blocked resource being emitted as its observed state — mark not ready.\n return {\n nodePath: emitted.name,\n document: emitted.document,\n ready: false,\n preserved: true,\n ...(k8sName ? { name: k8sName } : {}),\n ...(namespace ? { namespace } : {}),\n };\n }\n const allChecks = [...emitted.readyChecks, ...DEFAULT_CHECKS];\n // Look up observed using the full construct path (Composition/{name})\n const observed = observedComposed.get(`Composition/${emitted.name}`);\n const ready = emitted.autoReady ? evaluateReadiness(allChecks, observed) : true;\n\n return {\n nodePath: emitted.name,\n document: emitted.document,\n ready,\n ...(k8sName ? { name: k8sName } : {}),\n ...(namespace ? { namespace } : {}),\n };\n });\n\n const externalResources: ExternalResourceRequest[] = [];\n for (const resource of state.resources) {\n if (!isExternal(resource)) continue;\n const ref = getExternalRef(resource);\n if (!ref || typeof ref.name !== 'string') continue;\n if (ref.name.startsWith('__pending__')) continue;\n\n externalResources.push({\n refKey: ref.refKey,\n apiVersion: ref.apiVersion,\n kind: ref.kind,\n name: ref.name,\n ...(ref.namespace ? { namespace: ref.namespace } : {}),\n });\n }\n\n // Collect blocked resource info so the handler can preserve observed state\n // in desired (preventing accidental deletion), prevent premature XR readiness,\n // and surface a structured `status.xplane.blockedResources` entry on the XR.\n const blockedResources: BlockedResource[] = [];\n for (const resource of state.resources) {\n if (isExternal(resource)) continue;\n const ref = getResourceRef(resource);\n if (state.classification.get(ref.id) !== 'blocked') continue;\n const nodePath = ref.id.startsWith('Composition/')\n ? ref.id.slice('Composition/'.length)\n : ref.id;\n const desired = getDesiredDocument(resource);\n const apiVersion = typeof desired.apiVersion === 'string' ? desired.apiVersion : '';\n const kind = typeof desired.kind === 'string' ? desired.kind : '';\n const k8sName = extractMetadataName(desired);\n const namespace = extractMetadataNamespace(desired);\n const waitingFor = describeWaitingFor(nodePath, state.diagnostics);\n blockedResources.push({\n nodePath,\n apiVersion,\n kind,\n ...(k8sName ? { name: k8sName } : {}),\n ...(namespace ? { namespace } : {}),\n ...(waitingFor && waitingFor.length > 0 ? { waitingFor } : {}),\n });\n }\n\n return {\n resources,\n blockedResources,\n externalResources,\n xrStatus: state.xrStatusPatches,\n diagnostics: state.diagnostics,\n emitXplaneStatus: composition.emitXplaneStatus === true,\n };\n}\n\n/**\n * Build a human-readable `waitingFor` list for a blocked resource from the\n * matching diagnostic. Each entry describes one thing the resource is waiting\n * on (one entry per pending path, or a single entry for cycle/not-found).\n */\nfunction describeWaitingFor(\n name: string,\n diagnostics: ReadonlyArray<{\n resource: string;\n reason: 'pending' | 'cycle' | 'not-found';\n pendingPaths?: Array<{ path: string; waitingOn: { resource: string; path: string } }>;\n cycle?: string[];\n detail?: string;\n }>,\n): string[] | undefined {\n const id = `Composition/${name}`;\n const diag = diagnostics.find((d) => d.resource === id || d.resource === name);\n if (!diag) return undefined;\n\n if (diag.reason === 'cycle') {\n return [`circular dependency: ${(diag.cycle ?? []).join(' → ')}`];\n }\n if (diag.reason === 'not-found') {\n return [diag.detail ?? 'external resource not found'];\n }\n if (diag.pendingPaths && diag.pendingPaths.length > 0) {\n return diag.pendingPaths.map((p) => {\n const dep = p.waitingOn.resource.startsWith('Composition/')\n ? p.waitingOn.resource.slice('Composition/'.length)\n : p.waitingOn.resource;\n return `${dep}.${p.waitingOn.path}`;\n });\n }\n return undefined;\n}\n\nfunction extractMetadataName(doc: Record<string, unknown>): string | undefined {\n const metadata = doc.metadata;\n if (!metadata || typeof metadata !== 'object') return undefined;\n const name = (metadata as Record<string, unknown>).name;\n return typeof name === 'string' && name.length > 0 ? name : undefined;\n}\n\nfunction extractMetadataNamespace(doc: Record<string, unknown>): string | undefined {\n const metadata = doc.metadata;\n if (!metadata || typeof metadata !== 'object') return undefined;\n const namespace = (metadata as Record<string, unknown>).namespace;\n return typeof namespace === 'string' && namespace.length > 0 ? namespace : undefined;\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xplane/core",
3
- "version": "1.1.0",
3
+ "version": "1.3.0",
4
4
  "type": "module",
5
5
  "description": "Core CDK-style composition library for Crossplane functions",
6
6
  "license": "Apache-2.0",