@k8ts/instruments 0.9.3 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (169) hide show
  1. package/dist/core/graph/entity.d.ts +24 -5
  2. package/dist/core/graph/entity.d.ts.map +1 -1
  3. package/dist/core/graph/entity.js +11 -5
  4. package/dist/core/graph/entity.js.map +1 -1
  5. package/dist/core/graph/node.d.ts +31 -8
  6. package/dist/core/graph/node.d.ts.map +1 -1
  7. package/dist/core/graph/node.js +53 -26
  8. package/dist/core/graph/node.js.map +1 -1
  9. package/dist/core/graph/origin/entity.d.ts +9 -4
  10. package/dist/core/graph/origin/entity.d.ts.map +1 -1
  11. package/dist/core/graph/origin/entity.js +22 -2
  12. package/dist/core/graph/origin/entity.js.map +1 -1
  13. package/dist/core/graph/origin/events.d.ts +6 -6
  14. package/dist/core/graph/origin/events.d.ts.map +1 -1
  15. package/dist/core/graph/origin/exporter.d.ts +5 -4
  16. package/dist/core/graph/origin/exporter.d.ts.map +1 -1
  17. package/dist/core/graph/origin/exporter.js +9 -5
  18. package/dist/core/graph/origin/exporter.js.map +1 -1
  19. package/dist/core/graph/origin/external.d.ts +6 -2
  20. package/dist/core/graph/origin/external.d.ts.map +1 -1
  21. package/dist/core/graph/origin/external.js +4 -0
  22. package/dist/core/graph/origin/external.js.map +1 -1
  23. package/dist/core/graph/origin/kind-map/index.d.ts +7 -7
  24. package/dist/core/graph/origin/kind-map/index.d.ts.map +1 -1
  25. package/dist/core/graph/origin/kind-map/index.js +2 -2
  26. package/dist/core/graph/origin/kind-map/index.js.map +1 -1
  27. package/dist/core/graph/origin/node.d.ts +5 -5
  28. package/dist/core/graph/origin/node.d.ts.map +1 -1
  29. package/dist/core/graph/origin/origin-events.d.ts +6 -6
  30. package/dist/core/graph/origin/origin-events.d.ts.map +1 -1
  31. package/dist/core/graph/origin/tracker.d.ts +1 -1
  32. package/dist/core/graph/origin/tracker.d.ts.map +1 -1
  33. package/dist/core/graph/origin/tracker.js +2 -1
  34. package/dist/core/graph/origin/tracker.js.map +1 -1
  35. package/dist/core/graph/relation.d.ts +2 -2
  36. package/dist/core/graph/relation.d.ts.map +1 -1
  37. package/dist/core/graph/relation.js +1 -0
  38. package/dist/core/graph/relation.js.map +1 -1
  39. package/dist/core/graph/resource/api-kind/index.d.ts +51 -57
  40. package/dist/core/graph/resource/api-kind/index.d.ts.map +1 -1
  41. package/dist/core/graph/resource/api-kind/index.js +191 -205
  42. package/dist/core/graph/resource/api-kind/index.js.map +1 -1
  43. package/dist/core/graph/resource/child.d.ts +7 -6
  44. package/dist/core/graph/resource/child.d.ts.map +1 -1
  45. package/dist/core/graph/resource/child.js +3 -3
  46. package/dist/core/graph/resource/child.js.map +1 -1
  47. package/dist/core/graph/resource/entity.d.ts +8 -10
  48. package/dist/core/graph/resource/entity.d.ts.map +1 -1
  49. package/dist/core/graph/resource/entity.js +21 -11
  50. package/dist/core/graph/resource/entity.js.map +1 -1
  51. package/dist/core/graph/resource/external/base.d.ts +4 -9
  52. package/dist/core/graph/resource/external/base.d.ts.map +1 -1
  53. package/dist/core/graph/resource/external/base.js +5 -12
  54. package/dist/core/graph/resource/external/base.js.map +1 -1
  55. package/dist/core/graph/resource/external/features.d.ts +1 -10
  56. package/dist/core/graph/resource/external/features.d.ts.map +1 -1
  57. package/dist/core/graph/resource/external/props.d.ts +2 -2
  58. package/dist/core/graph/resource/external/props.d.ts.map +1 -1
  59. package/dist/core/graph/resource/node.d.ts +9 -9
  60. package/dist/core/graph/resource/node.d.ts.map +1 -1
  61. package/dist/core/graph/resource/node.js +6 -6
  62. package/dist/core/graph/resource/node.js.map +1 -1
  63. package/dist/core/graph/resource/ref-key/ref-key.d.ts +70 -7
  64. package/dist/core/graph/resource/ref-key/ref-key.d.ts.map +1 -1
  65. package/dist/core/graph/resource/ref-key/ref-key.js +47 -2
  66. package/dist/core/graph/resource/ref-key/ref-key.js.map +1 -1
  67. package/dist/core/graph/resource/reference/fw-ref-exports.d.ts +40 -9
  68. package/dist/core/graph/resource/reference/fw-ref-exports.d.ts.map +1 -1
  69. package/dist/core/graph/resource/reference/fw-ref-exports.js +47 -13
  70. package/dist/core/graph/resource/reference/fw-ref-exports.js.map +1 -1
  71. package/dist/core/graph/resource/reference/fw-ref.d.ts +41 -12
  72. package/dist/core/graph/resource/reference/fw-ref.d.ts.map +1 -1
  73. package/dist/core/graph/resource/reference/fw-ref.js +42 -10
  74. package/dist/core/graph/resource/reference/fw-ref.js.map +1 -1
  75. package/dist/core/graph/resource/reference/index.d.ts +2 -2
  76. package/dist/core/graph/resource/reference/index.d.ts.map +1 -1
  77. package/dist/core/graph/resource/reference/index.js +3 -3
  78. package/dist/core/graph/resource/reference/index.js.map +1 -1
  79. package/dist/core/graph/resource/reference/refable.d.ts +11 -12
  80. package/dist/core/graph/resource/reference/refable.d.ts.map +1 -1
  81. package/dist/core/graph/resource/top.d.ts +6 -5
  82. package/dist/core/graph/resource/top.d.ts.map +1 -1
  83. package/dist/core/graph/resource/top.js +6 -3
  84. package/dist/core/graph/resource/top.js.map +1 -1
  85. package/dist/core/manifest/index.d.ts +2 -2
  86. package/dist/core/manifest/index.d.ts.map +1 -1
  87. package/dist/core/manifest/index.js.map +1 -1
  88. package/dist/expressions/data-sources/base.d.ts +23 -0
  89. package/dist/expressions/data-sources/base.d.ts.map +1 -1
  90. package/dist/expressions/data-sources/base.js +22 -0
  91. package/dist/expressions/data-sources/base.js.map +1 -1
  92. package/dist/expressions/data-sources/env-var.d.ts +24 -1
  93. package/dist/expressions/data-sources/env-var.d.ts.map +1 -1
  94. package/dist/expressions/data-sources/env-var.js +22 -2
  95. package/dist/expressions/data-sources/env-var.js.map +1 -1
  96. package/dist/expressions/data-sources/interface.d.ts +30 -0
  97. package/dist/expressions/data-sources/interface.d.ts.map +1 -1
  98. package/dist/expressions/data-sources/local-file.d.ts +41 -3
  99. package/dist/expressions/data-sources/local-file.d.ts.map +1 -1
  100. package/dist/expressions/data-sources/local-file.js +37 -2
  101. package/dist/expressions/data-sources/local-file.js.map +1 -1
  102. package/dist/expressions/network/ports/index.d.ts +6 -6
  103. package/dist/expressions/network/ports/index.d.ts.map +1 -1
  104. package/dist/expressions/network/ports/index.js +4 -4
  105. package/dist/expressions/network/ports/index.js.map +1 -1
  106. package/dist/expressions/network/ports/map.d.ts +50 -8
  107. package/dist/expressions/network/ports/map.d.ts.map +1 -1
  108. package/dist/expressions/network/ports/map.js +34 -5
  109. package/dist/expressions/network/ports/map.js.map +1 -1
  110. package/dist/expressions/network/ports/set.d.ts +88 -13
  111. package/dist/expressions/network/ports/set.d.ts.map +1 -1
  112. package/dist/expressions/network/ports/set.js +49 -7
  113. package/dist/expressions/network/ports/set.js.map +1 -1
  114. package/dist/expressions/network/ports/tools/entry.d.ts +5 -4
  115. package/dist/expressions/network/ports/tools/entry.d.ts.map +1 -1
  116. package/dist/expressions/network/ports/tools/entry.js +1 -1
  117. package/dist/expressions/network/ports/tools/entry.js.map +1 -1
  118. package/dist/expressions/network/ports/tools/parse.d.ts +2 -2
  119. package/dist/expressions/network/ports/tools/parse.d.ts.map +1 -1
  120. package/dist/expressions/network/ports/tools/parse.js.map +1 -1
  121. package/dist/expressions/network/ports/types.d.ts +13 -22
  122. package/dist/expressions/network/ports/types.d.ts.map +1 -1
  123. package/dist/expressions/quantities/reqlem/objects.d.ts +2 -2
  124. package/dist/expressions/quantities/reqlem/objects.d.ts.map +1 -1
  125. package/dist/expressions/quantities/reqlem/objects.js +4 -4
  126. package/dist/expressions/quantities/reqlem/objects.js.map +1 -1
  127. package/dist/expressions/quantities/units/unit-parser.d.ts.map +1 -1
  128. package/dist/expressions/quantities/units/unit-parser.js +0 -1
  129. package/dist/expressions/quantities/units/unit-parser.js.map +1 -1
  130. package/package.json +5 -5
  131. package/src/core/graph/entities.md +1 -0
  132. package/src/core/graph/entity.ts +36 -9
  133. package/src/core/graph/node.ts +72 -41
  134. package/src/core/graph/origin/entity.ts +27 -7
  135. package/src/core/graph/origin/events.ts +6 -6
  136. package/src/core/graph/origin/exporter.ts +14 -12
  137. package/src/core/graph/origin/external.ts +6 -3
  138. package/src/core/graph/origin/kind-map/index.ts +13 -13
  139. package/src/core/graph/origin/node.ts +3 -3
  140. package/src/core/graph/origin/origin-events.ts +6 -6
  141. package/src/core/graph/origin/tracker.ts +2 -2
  142. package/src/core/graph/readme.md +161 -0
  143. package/src/core/graph/relation.ts +4 -2
  144. package/src/core/graph/resource/api-kind/index.ts +139 -160
  145. package/src/core/graph/resource/child.ts +7 -10
  146. package/src/core/graph/resource/entity.ts +25 -12
  147. package/src/core/graph/resource/external/base.ts +4 -12
  148. package/src/core/graph/resource/external/features.ts +0 -16
  149. package/src/core/graph/resource/external/props.ts +2 -2
  150. package/src/core/graph/resource/node.ts +8 -8
  151. package/src/core/graph/resource/ref-key/ref-key.ts +77 -11
  152. package/src/core/graph/resource/reference/fw-ref-exports.ts +69 -20
  153. package/src/core/graph/resource/reference/fw-ref.ts +75 -21
  154. package/src/core/graph/resource/reference/index.ts +2 -2
  155. package/src/core/graph/resource/reference/refable.ts +13 -18
  156. package/src/core/graph/resource/top.ts +8 -5
  157. package/src/core/manifest/index.ts +2 -2
  158. package/src/expressions/data-sources/base.ts +24 -0
  159. package/src/expressions/data-sources/env-var.ts +23 -1
  160. package/src/expressions/data-sources/interface.ts +32 -0
  161. package/src/expressions/data-sources/local-file.ts +59 -3
  162. package/src/expressions/network/ports/index.ts +7 -7
  163. package/src/expressions/network/ports/map.ts +58 -10
  164. package/src/expressions/network/ports/set.ts +100 -25
  165. package/src/expressions/network/ports/tools/entry.ts +9 -14
  166. package/src/expressions/network/ports/tools/parse.ts +3 -3
  167. package/src/expressions/network/ports/types.ts +12 -26
  168. package/src/expressions/quantities/reqlem/objects.ts +3 -3
  169. package/src/expressions/quantities/units/unit-parser.ts +0 -1
@@ -1,13 +1,26 @@
1
- import type { Ref2_Of } from ".."
2
1
  import { InstrumentsError } from "../../../../error"
3
- import type { Kind } from "../api-kind"
4
- import { External_Base, type External_Props, type External_WithFeatures } from "../external"
5
-
2
+ import type { Ident_Kind } from "../api-kind"
3
+ import type { External } from "../external"
4
+ import { type External_Props } from "../external"
5
+ import type { Rsc_Ref } from "../reference"
6
+ /** Input type for reference keys. Accepts either a RefKey instance or its string representation. */
6
7
  export type RefKey_Input = RefKey | RefKey["string"]
8
+
9
+ /**
10
+ * String format template for reference keys.
11
+ *
12
+ * @template Kind - The Kubernetes resource kind
13
+ * @template Name - The resource name
14
+ */
7
15
  export type RefKey_sFormat<Kind extends string, Name extends string> = `${Kind}/${Name}`
16
+
8
17
  const separator = "/"
18
+
19
+ /** Parsed representation of a reference key string. */
9
20
  export interface RefKey_Parsed {
21
+ /** The Kubernetes resource kind */
10
22
  kind: string
23
+ /** The resource name */
11
24
  name: string
12
25
  }
13
26
 
@@ -19,6 +32,13 @@ export function parse(ref: string) {
19
32
  return result
20
33
  }
21
34
 
35
+ /**
36
+ * Attempts to parse a reference key string into its kind and name components. Returns undefined if
37
+ * the string cannot be parsed.
38
+ *
39
+ * @param ref - The reference key string to parse (format: "Kind/Name")
40
+ * @returns The parsed reference key, or undefined if parsing fails
41
+ */
22
42
  export function tryParse(ref: string): RefKey_Parsed | undefined {
23
43
  if (typeof ref !== "string") {
24
44
  return undefined
@@ -39,16 +59,40 @@ export function tryParse(ref: string): RefKey_Parsed | undefined {
39
59
  }
40
60
  }
41
61
 
42
- type nsKind = Kind<"", "v1", "Namespace">
62
+ type nsKind = Ident_Kind<"", "v1", "Namespace">
43
63
 
64
+ /**
65
+ * Options for creating a RefKey instance.
66
+ *
67
+ * @template Name - The resource name type
68
+ */
44
69
  export interface RefKey_Options<Name extends string = string> {
70
+ /** The resource name */
45
71
  name: Name
46
- namespace?: RefKey<nsKind> | string | Ref2_Of<nsKind>
72
+ /** Optional namespace for namespaced resources. Can be a RefKey, string, or Ref2 */
73
+ namespace?: RefKey<nsKind> | string | Rsc_Ref<nsKind>
47
74
  }
48
75
 
49
- export class RefKey<K extends Kind.IdentParent = Kind.IdentParent, Name extends string = string> {
76
+ /**
77
+ * A unique identifier for a k8s resource consisting of a Kind, name, and namespace. Used by
78
+ * resources to reference other resources. Serves as the basis for the {@link External} resource
79
+ * type.
80
+ *
81
+ * Important: This class is ambiguous because it can represent keys for namespaced resources but
82
+ * ignore the namespace. Needs some kind of refactor.
83
+ */
84
+ export class RefKey<K extends Ident_Kind = Ident_Kind, Name extends string = string> {
85
+ /** The resource name */
50
86
  readonly name: string
87
+ /** The optional namespace for namespaced resources */
51
88
  readonly namespace: string | undefined
89
+
90
+ /**
91
+ * Creates a new RefKey instance.
92
+ *
93
+ * @param kind - The Kubernetes resource kind
94
+ * @param options - Configuration options including name and optional namespace
95
+ */
52
96
  constructor(
53
97
  readonly kind: K,
54
98
  options: RefKey_Options<Name>
@@ -58,12 +102,22 @@ export class RefKey<K extends Kind.IdentParent = Kind.IdentParent, Name extends
58
102
  typeof options.namespace === "string" ? options.namespace : options.namespace?.name
59
103
  }
60
104
 
105
+ /**
106
+ * Returns the string representation of this reference key. Format: "Kind/Namespace/Name" or
107
+ * "Kind/Name" for cluster-scoped resources.
108
+ */
61
109
  get string(): RefKey_sFormat<K["name"], Name> {
62
110
  return [this.kind.name, this.namespace, this.name]
63
111
  .filter(x => !!x)
64
112
  .join(separator) as RefKey_sFormat<K["name"], Name>
65
113
  }
66
114
 
115
+ /**
116
+ * Checks if this RefKey is equal to another RefKey by comparing kind, name, and namespace.
117
+ *
118
+ * @param other - The RefKey to compare with
119
+ * @returns True if both RefKeys have the same kind, name, and namespace
120
+ */
67
121
  equals(other: RefKey): boolean {
68
122
  if (other == null) {
69
123
  return false
@@ -78,13 +132,25 @@ export class RefKey<K extends Kind.IdentParent = Kind.IdentParent, Name extends
78
132
  )
79
133
  }
80
134
 
135
+ /**
136
+ * Returns the string representation of this reference key.
137
+ *
138
+ * @returns The reference key in string format
139
+ */
81
140
  toString() {
82
141
  return this.string
83
142
  }
84
143
 
85
- External<const P extends External_Props<K> = External_Props<K>>(
86
- options?: P
87
- ): External_WithFeatures<K, P> {
88
- return new External_Base(this, options ?? {}) as any
144
+ /**
145
+ * Creates an External reference to this resource.
146
+ *
147
+ * @template P - The external properties type
148
+ * @param options - Optional external properties configuration
149
+ * @returns An External instance with the specified features
150
+ */
151
+ External(options?: External_Props<K>): External<K> {
152
+ const External = require("../external").External
153
+
154
+ return new External(this, options ?? {}) as any
89
155
  }
90
156
  }
@@ -1,27 +1,59 @@
1
1
  import { seq } from "doddle"
2
- import type { Ref2_Of } from "."
3
- import { FwReference } from "."
4
- import type { Origin_Exporter } from "../../origin"
2
+ import { Origin_Entity } from "../../origin"
3
+ import type { Origin_Exporter } from "../../origin/exporter"
4
+ import { RefKey } from "../ref-key"
5
5
  import { ProxyOperationError } from "./error"
6
+ import { FwRef } from "./fw-ref"
7
+ import type { Rsc_Ref } from "./refable"
6
8
 
7
- export type FwRef_Exports_ByKey<Exports extends Ref2_Of = Ref2_Of> = {
8
- [E in Exports as `${E["kind"]["name"]}/${E["name"]}`]: FwReference<E>
9
+ /** Expands the resources exported by an Origin_Exported into a dictionary of name to FwRef. */
10
+ export type FwRef_Exports_ByKey<Exports extends Rsc_Ref = Rsc_Ref> = {
11
+ [E in Exports as `${E["kind"]["name"]}/${E["name"]}`]: FwRef<E>
9
12
  }
10
-
11
- export type FwRef_Exports<Exported extends Ref2_Of = Ref2_Of> = FxRef_Exports_Proxied &
13
+ /**
14
+ * A type describing all resources exported by an {@link Origin_Exporter} as forward references.
15
+ *
16
+ * FwRefs can be accessed using a key lookup, using the shorthand of `KindName/name`. For example, a
17
+ * Deployment named "my-app" can be accessed via `exports["Deployment/my-app"]`.
18
+ *
19
+ * This construct is immutable; attempts to modify it will will throw errors.
20
+ *
21
+ * The underlying entity can be accessed via the `__entity__()` method.
22
+ *
23
+ * During TypeScript compilation, this serves as a type-safe way to reference resources between
24
+ * entities. During runtime, it provides a dynamic proxy that resolves forward references to the
25
+ * actual resources when accessed.
26
+ *
27
+ * During runtime, this construct can provide references to all resources attached to the Origin,
28
+ * even if they were not explicitly exported.
29
+ */
30
+ export type Rsc_FwRef_Exports<Exported extends Rsc_Ref = any> = Rsc_FwRef_Exports_Proxied &
12
31
  FwRef_Exports_ByKey<Exported>
13
32
 
14
- export type FwRef_Exports_Brand = FxRef_Exports_Proxied
15
-
16
- export function FwRef_Exports<Exported extends Ref2_Of>(
33
+ /**
34
+ * Creates a forward reference exports construct for the given {@link Origin_Exporter} entity.
35
+ *
36
+ * @param entity
37
+ * @returns
38
+ */
39
+ export function Rsc_FwRef_Exports<Exported extends Rsc_Ref>(
17
40
  entity: Origin_Exporter
18
- ): FwRef_Exports<Exported> {
19
- const proxied = new FxRef_Exports_Proxied(entity)
41
+ ): Rsc_FwRef_Exports<Exported> {
42
+ const proxied = new Rsc_FwRef_Exports_Proxied(entity)
20
43
  const handler = new FwRef_Exports_Handler(proxied)
21
44
  return new Proxy(proxied, handler) as any
22
45
  }
46
+ export namespace Rsc_FwRef_Exports {
47
+ export function is(obj: any): obj is Rsc_FwRef_Exports {
48
+ return obj instanceof Rsc_FwRef_Exports_Proxied
49
+ }
50
+ }
23
51
 
24
- export class FxRef_Exports_Proxied {
52
+ /**
53
+ * A basic core of the {@link Rsc_FwRef_Exports} construct, containing information about the
54
+ * underlying {@link Origin_Exporter} entity.
55
+ */
56
+ export class Rsc_FwRef_Exports_Proxied {
25
57
  #entity: Origin_Exporter
26
58
  constructor(entity: Origin_Exporter) {
27
59
  this.#entity = entity
@@ -30,10 +62,27 @@ export class FxRef_Exports_Proxied {
30
62
  __entity__(act?: (entity: Origin_Exporter) => any): Origin_Exporter {
31
63
  return this.#entity as any
32
64
  }
65
+
66
+ equals(other: any): boolean {
67
+ if (!other) {
68
+ return false
69
+ }
70
+ if (Rsc_FwRef_Exports.is(other)) {
71
+ return this.#entity.equals(other.#entity)
72
+ }
73
+ if (other instanceof Origin_Entity) {
74
+ return other.equals(this.#entity)
75
+ }
76
+ return false
77
+ }
33
78
  }
34
79
 
80
+ /**
81
+ * Proxy handler for the {@link Rsc_FwRef_Exports} construct, providing dynamic access to the
82
+ * resources attached to the underlying {@link Origin_Exporter} entity.
83
+ */
35
84
  class FwRef_Exports_Handler<Entity extends Origin_Exporter> implements ProxyHandler<Entity> {
36
- constructor(private readonly _subject: FxRef_Exports_Proxied) {}
85
+ constructor(private readonly _subject: Rsc_FwRef_Exports_Proxied) {}
37
86
 
38
87
  get entity() {
39
88
  return this._subject["__entity__"]()
@@ -60,8 +109,7 @@ class FwRef_Exports_Handler<Entity extends Origin_Exporter> implements ProxyHand
60
109
  }
61
110
 
62
111
  getPrototypeOf(_: Entity): object | null {
63
- const r = Reflect.getPrototypeOf(this.entity)
64
- return r
112
+ return Rsc_FwRef_Exports_Proxied.prototype
65
113
  }
66
114
 
67
115
  get exported() {
@@ -91,13 +139,14 @@ class FwRef_Exports_Handler<Entity extends Origin_Exporter> implements ProxyHand
91
139
  if (refKey == null) {
92
140
  return undefined
93
141
  }
94
- return FwReference({
142
+ return FwRef({
95
143
  class: clazz,
96
- key: refKey,
144
+ key: new RefKey(refKey.kind, {
145
+ name: refKey.name
146
+ }),
97
147
  origin: this.entity,
98
- namespace: this.entity.meta.tryGet("namespace"),
99
148
  resolver: this.exported
100
- .first(exp => exp.node.key.equals(refKey))
149
+ .first(exp => exp.node.name === refKey.name && exp.node.kind.equals(refKey.kind))
101
150
  .map(x => {
102
151
  if (x == null) {
103
152
  throw new ProxyOperationError(
@@ -1,36 +1,73 @@
1
1
  import type { Doddle } from "doddle"
2
2
  import type { AnyCtor } from "what-are-you"
3
- import type { RefKey } from "../ref-key"
3
+ import { RefKey } from "../ref-key"
4
4
  import { ProxyOperationError } from "./error"
5
- import type { Ref2_Of } from "./refable"
5
+ import type { Rsc_Ref } from "./refable"
6
6
 
7
- export type FwReference<T extends Ref2_Of = Ref2_Of> = FwReference_Proxied<T> & T
8
- export function FwReference<Referenced extends Ref2_Of>(
9
- props: FwReference_Props<Referenced>
10
- ): FwReference<Referenced> {
11
- const core = new FwReference_Proxied(props)
12
- return new Proxy(core, new FwRef_Handler(core)) as FwReference<Referenced>
7
+ /**
8
+ * The type of a forward reference to a resource.
9
+ *
10
+ * Acts as a stand-in for a resource that may not yet be available. Can be used to reference
11
+ * resources across different Origins while deferring their actual resolution until needed. This
12
+ * allows for circular references and more flexible resource definitions.
13
+ *
14
+ * The base `FwRef` object only has some basic properties about the resource being referenced, such
15
+ * as its {@link RefKey} and class type. Accessing any other properties or methods on the `FwRef`
16
+ * will trigger the resolution of the actual resource via a resolver.
17
+ *
18
+ * Because the `FwRef` avoids resolving the actual resource until needed, it won't detect missing
19
+ * resources when the reference is created. Instead, the missing resource will be detected later on,
20
+ * typically until resources are manifested. This makes it a bit harder to debug such issues.
21
+ */
22
+ export type FwRef<T extends Rsc_Ref = Rsc_Ref> = FwRef_Proxied<T> & T
23
+
24
+ /**
25
+ * Creates a forward reference to a resource, returning a proxy that defers resource resolution
26
+ * until properties or methods are accessed.
27
+ *
28
+ * @param props The properties of the forward reference.
29
+ * @returns The forward reference proxy.
30
+ */
31
+ export function FwRef<Referenced extends Rsc_Ref>(
32
+ props: FwRef_Props<Referenced>
33
+ ): FwRef<Referenced> {
34
+ const core = new FwRef_Proxied(props)
35
+ return new Proxy(core, new FwRef_Handler(core)) as FwRef<Referenced>
13
36
  }
14
- export namespace FwReference {
15
- export function is(obj: any): obj is FwReference {
16
- return FwReference_Proxied.is(obj)
37
+ export namespace FwRef {
38
+ export function is(obj: any): obj is FwRef {
39
+ return FwRef_Proxied.is(obj)
17
40
  }
18
41
  }
19
- export interface FwReference_Props<Referenced extends Ref2_Of> {
42
+ /** Properties for creating a forward reference to a resource. */
43
+ export interface FwRef_Props<Referenced extends Rsc_Ref> {
44
+ /** The class constructor of the referenced resource. */
20
45
  readonly class?: AnyCtor<Referenced>
46
+ /** The reference key identifying the referenced resource. */
21
47
  readonly key: RefKey
22
- readonly namespace?: string
23
48
  readonly origin: object
24
49
  readonly resolver: Doddle<Referenced>
25
50
  }
26
51
 
27
- class FwReference_Proxied<To extends Ref2_Of> {
28
- readonly #props: FwReference_Props<To>
29
- constructor(props: FwReference_Props<To>) {
52
+ class FwRef_Proxied<To extends Rsc_Ref> {
53
+ readonly #props: FwRef_Props<To>
54
+ constructor(props: FwRef_Props<To>) {
30
55
  this.#props = props
31
56
  }
32
57
 
33
- static is(obj: any): obj is FwReference {
58
+ get name() {
59
+ return this.#props.key.name
60
+ }
61
+
62
+ get namespace() {
63
+ return this.__pull__().namespace // The $props.key won't have a namespace
64
+ }
65
+
66
+ get kind() {
67
+ return this.#props.key.kind
68
+ }
69
+
70
+ static is(obj: any): obj is FwRef {
34
71
  return obj && typeof obj === "object" && "__reference_props__" in obj
35
72
  }
36
73
 
@@ -41,13 +78,30 @@ class FwReference_Proxied<To extends Ref2_Of> {
41
78
  protected __reference_props__() {
42
79
  return this.#props
43
80
  }
81
+
82
+ get key() {
83
+ return new RefKey(this.kind, {
84
+ name: this.name,
85
+ namespace: this.namespace
86
+ })
87
+ }
88
+
89
+ equals(other: any): boolean {
90
+ if (!other) {
91
+ return false
92
+ }
93
+ // Resource_Top has a key property, but Resource_Child doesn't
94
+ // However in that case, the kind will be different anyway
95
+ // since FwRefs are just for top resources.
96
+ return this.key.equals(other.key)
97
+ }
44
98
  }
45
99
 
46
- class FwRef_Handler<T extends Ref2_Of> implements ProxyHandler<T> {
100
+ class FwRef_Handler<T extends Rsc_Ref> implements ProxyHandler<T> {
47
101
  get _props() {
48
102
  return this._subject["__reference_props__"]()
49
103
  }
50
- constructor(private readonly _subject: FwReference_Proxied<T>) {}
104
+ constructor(private readonly _subject: FwRef_Proxied<T>) {}
51
105
 
52
106
  get(target: T, prop: PropertyKey) {
53
107
  const { _props, _subject } = this
@@ -65,8 +119,8 @@ class FwRef_Handler<T extends Ref2_Of> implements ProxyHandler<T> {
65
119
  return result
66
120
  }
67
121
  getPrototypeOf(target: T) {
68
- const Resource_Top = require("../top").Resource_Top
69
- return this._props.class?.prototype ?? Resource_Top.prototype
122
+ const Rsc_Top = require("../top").Rsc_Top
123
+ return this._props.class?.prototype ?? Rsc_Top.prototype
70
124
  }
71
125
  has(target: T, prop: PropertyKey) {
72
126
  const { _props, _subject } = this
@@ -1,3 +1,3 @@
1
- export { FwReference } from "./fw-ref"
2
- export { FwRef_Exports, type FwRef_Exports_Brand } from "./fw-ref-exports"
1
+ export { FwRef } from "./fw-ref"
2
+ export { Rsc_FwRef_Exports } from "./fw-ref-exports"
3
3
  export type * from "./refable"
@@ -1,28 +1,23 @@
1
1
  import type { AnyCtor } from "what-are-you"
2
- import type { Kind } from "../api-kind"
3
- import type { Resource_Entity } from "../entity"
4
- import type { Resource_Node } from "../node"
5
-
6
- export type Resource_Ref_Min<K extends Kind.IdentParent = Kind.IdentParent> = { kind: K }
7
- export type Resource_Ctor_Of<K extends Kind.IdentParent = Kind.IdentParent> = AnyCtor<
8
- Ref2_Of<K>
9
- > & {
10
- prototype: Ref2_Of<K>
2
+ import type { RefLike } from "../../entity"
3
+ import type { Ident_Like } from "../api-kind"
4
+ import type { Rsc_Node } from "../node"
5
+ export type Rsc_Ctor_Of<K extends Ident_Like = Ident_Like> = AnyCtor<Rsc_Ref<K>> & {
6
+ prototype: Rsc_Ref<K>
11
7
  }
12
- export type Ref2_Of<
13
- Kind extends Kind.IdentParent = Kind.IdentParent,
8
+ export type Rsc_Ref<
9
+ _Kind extends Ident_Like = Ident_Like,
14
10
  Name extends string = string
15
- > = Resource_Ref_Min<Kind> & {
11
+ > = RefLike & {
12
+ kind: _Kind
16
13
  name: Name
14
+ namespace?: string
15
+ is<_Kind2 extends Ident_Like>(kind: _Kind2): this is Rsc_Ref<_Kind2>
17
16
  equals(other: any): boolean
18
- node: Resource_Node
17
+ node: Rsc_Node
19
18
  }
20
- export type Resource_Ref_Full<
21
- _Kind extends Kind.IdentParent = Kind.IdentParent,
22
- _Name extends string = string
23
- > = Ref2_Of<_Kind, _Name> & Resource_Entity<_Name>
24
19
 
25
- export type Resource_Ref_Keys_Of<X extends Resource_Ref_Min, Else = never> = [X] extends [
20
+ export type Rsc_Ref_Keys_Of<X extends Rsc_Ref, Else = never> = [X] extends [
26
21
  {
27
22
  keys: (infer K extends string)[]
28
23
  }
@@ -4,16 +4,19 @@ import { type Manifest, type Manifest_Ident, type Manifest_Metadata } from "../.
4
4
  import { Trace, TraceEmbedder } from "../../tracing"
5
5
  import type { Origin_Entity } from "../origin/entity"
6
6
  import { OriginContextTracker } from "../origin/tracker"
7
- import type { Kind } from "./api-kind"
8
- import { Resource_Entity } from "./entity"
9
- export abstract class Resource_Top<
7
+ import type { Ident_Kind } from "./api-kind"
8
+ import { Rsc_Entity } from "./entity"
9
+ export abstract class Rsc_Top<
10
10
  Name extends string = string,
11
11
  Props extends object = object
12
- > extends Resource_Entity<Name, Props> {
12
+ > extends Rsc_Entity<Name, Props> {
13
13
  private readonly _origin: Origin_Entity
14
14
  readonly meta: Meta
15
- abstract readonly kind: Kind.IdentParent
15
+ abstract readonly kind: Ident_Kind
16
16
 
17
+ get key() {
18
+ return this.kind.refKey({ name: this.name, namespace: this.namespace })
19
+ }
17
20
  get disabled() {
18
21
  return this.meta.tryGet("#k8ts.org/disabled", "") !== ""
19
22
  }
@@ -1,5 +1,5 @@
1
1
  import { Embedder } from "../../utils/embedder"
2
- import { Resource_Entity } from "../graph/resource/entity"
2
+ import { Rsc_Entity } from "../graph/resource/entity"
3
3
  export interface Manifest_Metadata {
4
4
  labels: Record<string, string>
5
5
  annotations: Record<string, string>
@@ -35,4 +35,4 @@ export interface SpecManifest<T extends JsonSerializable> extends Manifest {
35
35
  spec: T
36
36
  }
37
37
 
38
- export const ManifestSourceEmbedder = new Embedder<object, Resource_Entity>("ManifestSource")
38
+ export const ManifestSourceEmbedder = new Embedder<object, Rsc_Entity>("ManifestSource")
@@ -1,13 +1,37 @@
1
1
  import { doddle, type DoddleAsync } from "doddle"
2
2
 
3
+ /** Unique symbol used to identify data source objects. */
3
4
  export declare const DATA_SOURCE: unique symbol
4
5
 
6
+ /**
7
+ * Lazy-loading data source that caches the result of a getter function. The getter is executed only
8
+ * once, and the result is memoized for subsequent calls.
9
+ *
10
+ * @example
11
+ * const lazy = new DataSource_Lazy(() => expensiveComputation())
12
+ * const value1 = await lazy.get() // Computes value
13
+ * const value2 = await lazy.get() // Returns cached value
14
+ *
15
+ * @typeParam T - The type of data this source provides
16
+ */
5
17
  export class DataSource_Lazy<T = any> {
6
18
  private readonly _data: DoddleAsync<T>
19
+
20
+ /**
21
+ * Creates a new lazy data source.
22
+ *
23
+ * @param getter - Function that computes or retrieves the value (can be async)
24
+ */
7
25
  constructor(getter: () => T | Promise<T>) {
8
26
  this._data = doddle(async () => getter())
9
27
  }
10
28
 
29
+ /**
30
+ * Retrieves the value, computing it on first call and returning cached value on subsequent
31
+ * calls.
32
+ *
33
+ * @returns Promise resolving to the data value
34
+ */
11
35
  get() {
12
36
  return this._data.pull()
13
37
  }
@@ -1,6 +1,17 @@
1
1
  import { DataSource_Lazy } from "./base"
2
2
 
3
- export class DataSource_EnvVar extends DataSource_Lazy<string> {
3
+ /**
4
+ * Data source that retrieves values from environment variables. Throws an error if the environment
5
+ * variable is not set.
6
+ *
7
+ * Can be used instead of a primitive in some cases when building Kubernetes manifests.
8
+ */
9
+ class DataSource_EnvVar extends DataSource_Lazy<string> {
10
+ /**
11
+ * Creates an environment variable data source.
12
+ *
13
+ * @param name - The name of the environment variable
14
+ */
4
15
  constructor(public readonly name: string) {
5
16
  super(async () => {
6
17
  const value = process.env[this.name]
@@ -12,6 +23,17 @@ export class DataSource_EnvVar extends DataSource_Lazy<string> {
12
23
  }
13
24
  }
14
25
 
26
+ /**
27
+ * Creates a lazy data source that reads from an environment variable.
28
+ *
29
+ * @example
30
+ * const apiKey = localRefEnvVar("API_KEY")
31
+ * const key = await apiKey.get() // Reads from process.env.API_KEY
32
+ *
33
+ * @param name - The name of the environment variable to read
34
+ * @returns A lazy data source for the environment variable
35
+ * @throws {Error} When the environment variable is not set
36
+ */
15
37
  export function localRefEnvVar(name: string) {
16
38
  return new DataSource_EnvVar(name)
17
39
  }
@@ -1,13 +1,45 @@
1
+ /** Supported data source type names for type-safe data source handling. */
1
2
  export type DataSource_Type_Name = "string" | "binary"
3
+
4
+ /**
5
+ * Maps a data source type name to its corresponding value type.
6
+ *
7
+ * @typeParam Name - The type name ("string" or "binary")
8
+ * @returns String for "string" type, Uint8Array for "binary" type
9
+ */
2
10
  export type DataSource_Value<Name extends DataSource_Type_Name> = Name extends "string"
3
11
  ? string
4
12
  : Name extends "binary"
5
13
  ? Uint8Array
6
14
  : DataSource_Type_Name
15
+
16
+ /**
17
+ * Interface for objects that provide data source values. Implementations can return values
18
+ * synchronously or asynchronously.
19
+ *
20
+ * @example
21
+ * class MySource implements DataSource_Object<"string"> {
22
+ * get() {
23
+ * return "value"
24
+ * }
25
+ * }
26
+ *
27
+ * @typeParam TypeName - The type of data this source provides
28
+ */
7
29
  export interface DataSource_Object<TypeName extends DataSource_Type_Name = DataSource_Type_Name> {
8
30
  get(): DataSource_Value<TypeName> | Promise<DataSource_Value<TypeName>>
9
31
  }
10
32
 
33
+ /**
34
+ * A data source can be either a DataSource_Object or a direct value. This allows for flexible API
35
+ * design where values can be passed directly or lazily loaded.
36
+ *
37
+ * @example
38
+ * const direct: DataSource<"string"> = "hello"
39
+ * const lazy: DataSource<"string"> = { get: () => "hello" }
40
+ *
41
+ * @typeParam Only - Constrains the data source to a specific type
42
+ */
11
43
  export type DataSource<Only extends DataSource_Type_Name = DataSource_Type_Name> =
12
44
  | DataSource_Object<Only>
13
45
  | DataSource_Value<Only>