@k8ts/instruments 0.1.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 (307) hide show
  1. package/LICENSE.md +7 -0
  2. package/README.md +3 -0
  3. package/dist/_embedder/base.d.ts +11 -0
  4. package/dist/_embedder/base.d.ts.map +1 -0
  5. package/dist/_embedder/base.js +39 -0
  6. package/dist/_embedder/base.js.map +1 -0
  7. package/dist/_embedder/index.d.ts +2 -0
  8. package/dist/_embedder/index.d.ts.map +1 -0
  9. package/dist/_embedder/index.js +18 -0
  10. package/dist/_embedder/index.js.map +1 -0
  11. package/dist/_string/index.d.ts +6 -0
  12. package/dist/_string/index.d.ts.map +1 -0
  13. package/dist/_string/index.js +22 -0
  14. package/dist/_string/index.js.map +1 -0
  15. package/dist/_string/markers.d.ts +3 -0
  16. package/dist/_string/markers.d.ts.map +1 -0
  17. package/dist/_string/markers.js +48 -0
  18. package/dist/_string/markers.js.map +1 -0
  19. package/dist/_string/post-processor.d.ts +7 -0
  20. package/dist/_string/post-processor.d.ts.map +1 -0
  21. package/dist/_string/post-processor.js +30 -0
  22. package/dist/_string/post-processor.js.map +1 -0
  23. package/dist/_string/pretty-objects.d.ts +27 -0
  24. package/dist/_string/pretty-objects.d.ts.map +1 -0
  25. package/dist/_string/pretty-objects.js +192 -0
  26. package/dist/_string/pretty-objects.js.map +1 -0
  27. package/dist/_string/pretty-print.d.ts +2 -0
  28. package/dist/_string/pretty-print.d.ts.map +1 -0
  29. package/dist/_string/pretty-print.js +27 -0
  30. package/dist/_string/pretty-print.js.map +1 -0
  31. package/dist/_string/super-script.d.ts +2 -0
  32. package/dist/_string/super-script.d.ts.map +1 -0
  33. package/dist/_string/super-script.js +20 -0
  34. package/dist/_string/super-script.js.map +1 -0
  35. package/dist/api-kind/index.d.ts +43 -0
  36. package/dist/api-kind/index.d.ts.map +1 -0
  37. package/dist/api-kind/index.js +102 -0
  38. package/dist/api-kind/index.js.map +1 -0
  39. package/dist/cmd/cli-command.d.ts +23 -0
  40. package/dist/cmd/cli-command.d.ts.map +1 -0
  41. package/dist/cmd/cli-command.js +73 -0
  42. package/dist/cmd/cli-command.js.map +1 -0
  43. package/dist/cmd/cli-term.d.ts +25 -0
  44. package/dist/cmd/cli-term.d.ts.map +1 -0
  45. package/dist/cmd/cli-term.js +55 -0
  46. package/dist/cmd/cli-term.js.map +1 -0
  47. package/dist/cmd/index.d.ts +3 -0
  48. package/dist/cmd/index.d.ts.map +1 -0
  49. package/dist/cmd/index.js +7 -0
  50. package/dist/cmd/index.js.map +1 -0
  51. package/dist/cmd/types.d.ts +5 -0
  52. package/dist/cmd/types.d.ts.map +1 -0
  53. package/dist/cmd/types.js +3 -0
  54. package/dist/cmd/types.js.map +1 -0
  55. package/dist/displayers/displayers.d.ts +33 -0
  56. package/dist/displayers/displayers.d.ts.map +1 -0
  57. package/dist/displayers/displayers.js +129 -0
  58. package/dist/displayers/displayers.js.map +1 -0
  59. package/dist/displayers/index.d.ts +2 -0
  60. package/dist/displayers/index.d.ts.map +1 -0
  61. package/dist/displayers/index.js +18 -0
  62. package/dist/displayers/index.js.map +1 -0
  63. package/dist/env/env.d.ts +20 -0
  64. package/dist/env/env.d.ts.map +1 -0
  65. package/dist/env/env.js +68 -0
  66. package/dist/env/env.js.map +1 -0
  67. package/dist/env/index.d.ts +3 -0
  68. package/dist/env/index.d.ts.map +1 -0
  69. package/dist/env/index.js +7 -0
  70. package/dist/env/index.js.map +1 -0
  71. package/dist/env/types.d.ts +4 -0
  72. package/dist/env/types.d.ts.map +1 -0
  73. package/dist/env/types.js +3 -0
  74. package/dist/env/types.js.map +1 -0
  75. package/dist/env/validate-name.d.ts +2 -0
  76. package/dist/env/validate-name.d.ts.map +1 -0
  77. package/dist/env/validate-name.js +12 -0
  78. package/dist/env/validate-name.js.map +1 -0
  79. package/dist/error.d.ts +8 -0
  80. package/dist/error.d.ts.map +1 -0
  81. package/dist/error.js +20 -0
  82. package/dist/error.js.map +1 -0
  83. package/dist/forward-exports/delayed-exports.d.ts +18 -0
  84. package/dist/forward-exports/delayed-exports.d.ts.map +1 -0
  85. package/dist/forward-exports/delayed-exports.js +119 -0
  86. package/dist/forward-exports/delayed-exports.js.map +1 -0
  87. package/dist/forward-exports/index.d.ts +2 -0
  88. package/dist/forward-exports/index.d.ts.map +1 -0
  89. package/dist/forward-exports/index.js +18 -0
  90. package/dist/forward-exports/index.js.map +1 -0
  91. package/dist/graph/base-node.d.ts +34 -0
  92. package/dist/graph/base-node.d.ts.map +1 -0
  93. package/dist/graph/base-node.js +102 -0
  94. package/dist/graph/base-node.js.map +1 -0
  95. package/dist/graph/base-origin-entity.d.ts +19 -0
  96. package/dist/graph/base-origin-entity.d.ts.map +1 -0
  97. package/dist/graph/base-origin-entity.js +105 -0
  98. package/dist/graph/base-origin-entity.js.map +1 -0
  99. package/dist/graph/dependencies.d.ts +12 -0
  100. package/dist/graph/dependencies.d.ts.map +1 -0
  101. package/dist/graph/dependencies.js +82 -0
  102. package/dist/graph/dependencies.js.map +1 -0
  103. package/dist/graph/index.d.ts +7 -0
  104. package/dist/graph/index.d.ts.map +1 -0
  105. package/dist/graph/index.js +23 -0
  106. package/dist/graph/index.js.map +1 -0
  107. package/dist/graph/origin-node.d.ts +32 -0
  108. package/dist/graph/origin-node.d.ts.map +1 -0
  109. package/dist/graph/origin-node.js +161 -0
  110. package/dist/graph/origin-node.js.map +1 -0
  111. package/dist/graph/relations.d.ts +26 -0
  112. package/dist/graph/relations.d.ts.map +1 -0
  113. package/dist/graph/relations.js +38 -0
  114. package/dist/graph/relations.js.map +1 -0
  115. package/dist/graph/resource-node.d.ts +28 -0
  116. package/dist/graph/resource-node.d.ts.map +1 -0
  117. package/dist/graph/resource-node.js +144 -0
  118. package/dist/graph/resource-node.js.map +1 -0
  119. package/dist/image/family.d.ts +26 -0
  120. package/dist/image/family.d.ts.map +1 -0
  121. package/dist/image/family.js +63 -0
  122. package/dist/image/family.js.map +1 -0
  123. package/dist/image/index.d.ts +2 -0
  124. package/dist/image/index.d.ts.map +1 -0
  125. package/dist/image/index.js +9 -0
  126. package/dist/image/index.js.map +1 -0
  127. package/dist/index.d.ts +19 -0
  128. package/dist/index.d.ts.map +1 -0
  129. package/dist/index.js +35 -0
  130. package/dist/index.js.map +1 -0
  131. package/dist/kind-map/index.d.ts +44 -0
  132. package/dist/kind-map/index.d.ts.map +1 -0
  133. package/dist/kind-map/index.js +123 -0
  134. package/dist/kind-map/index.js.map +1 -0
  135. package/dist/manifest/index.d.ts +46 -0
  136. package/dist/manifest/index.d.ts.map +1 -0
  137. package/dist/manifest/index.js +21 -0
  138. package/dist/manifest/index.js.map +1 -0
  139. package/dist/manifest/manifest-builder.d.ts +45 -0
  140. package/dist/manifest/manifest-builder.d.ts.map +1 -0
  141. package/dist/manifest/manifest-builder.js +66 -0
  142. package/dist/manifest/manifest-builder.js.map +1 -0
  143. package/dist/ports/error.d.ts +5 -0
  144. package/dist/ports/error.d.ts.map +1 -0
  145. package/dist/ports/error.js +13 -0
  146. package/dist/ports/error.js.map +1 -0
  147. package/dist/ports/index.d.ts +7 -0
  148. package/dist/ports/index.d.ts.map +1 -0
  149. package/dist/ports/index.js +13 -0
  150. package/dist/ports/index.js.map +1 -0
  151. package/dist/ports/map.d.ts +13 -0
  152. package/dist/ports/map.d.ts.map +1 -0
  153. package/dist/ports/map.js +38 -0
  154. package/dist/ports/map.js.map +1 -0
  155. package/dist/ports/set.d.ts +18 -0
  156. package/dist/ports/set.d.ts.map +1 -0
  157. package/dist/ports/set.js +60 -0
  158. package/dist/ports/set.js.map +1 -0
  159. package/dist/ports/tools/entry.d.ts +6 -0
  160. package/dist/ports/tools/entry.d.ts.map +1 -0
  161. package/dist/ports/tools/entry.js +36 -0
  162. package/dist/ports/tools/entry.js.map +1 -0
  163. package/dist/ports/tools/parse.d.ts +3 -0
  164. package/dist/ports/tools/parse.d.ts.map +1 -0
  165. package/dist/ports/tools/parse.js +35 -0
  166. package/dist/ports/tools/parse.js.map +1 -0
  167. package/dist/ports/types.d.ts +37 -0
  168. package/dist/ports/types.d.ts.map +1 -0
  169. package/dist/ports/types.js +3 -0
  170. package/dist/ports/types.js.map +1 -0
  171. package/dist/producer/index.d.ts +2 -0
  172. package/dist/producer/index.d.ts.map +1 -0
  173. package/dist/producer/index.js +18 -0
  174. package/dist/producer/index.js.map +1 -0
  175. package/dist/producer/producer.d.ts +6 -0
  176. package/dist/producer/producer.d.ts.map +1 -0
  177. package/dist/producer/producer.js +13 -0
  178. package/dist/producer/producer.js.map +1 -0
  179. package/dist/ref-key/index.d.ts +2 -0
  180. package/dist/ref-key/index.d.ts.map +1 -0
  181. package/dist/ref-key/index.js +18 -0
  182. package/dist/ref-key/index.js.map +1 -0
  183. package/dist/ref-key/ref-key.d.ts +23 -0
  184. package/dist/ref-key/ref-key.d.ts.map +1 -0
  185. package/dist/ref-key/ref-key.js +67 -0
  186. package/dist/ref-key/ref-key.js.map +1 -0
  187. package/dist/reference/forward-ref.d.ts +22 -0
  188. package/dist/reference/forward-ref.d.ts.map +1 -0
  189. package/dist/reference/forward-ref.js +126 -0
  190. package/dist/reference/forward-ref.js.map +1 -0
  191. package/dist/reference/index.d.ts +4 -0
  192. package/dist/reference/index.d.ts.map +1 -0
  193. package/dist/reference/index.js +8 -0
  194. package/dist/reference/index.js.map +1 -0
  195. package/dist/reference/refable.d.ts +12 -0
  196. package/dist/reference/refable.d.ts.map +1 -0
  197. package/dist/reference/refable.js +3 -0
  198. package/dist/reference/refable.js.map +1 -0
  199. package/dist/resources/index.d.ts +3 -0
  200. package/dist/resources/index.d.ts.map +1 -0
  201. package/dist/resources/index.js +19 -0
  202. package/dist/resources/index.js.map +1 -0
  203. package/dist/resources/objects.d.ts +22 -0
  204. package/dist/resources/objects.d.ts.map +1 -0
  205. package/dist/resources/objects.js +93 -0
  206. package/dist/resources/objects.js.map +1 -0
  207. package/dist/resources/parser.d.ts +4 -0
  208. package/dist/resources/parser.d.ts.map +1 -0
  209. package/dist/resources/parser.js +21 -0
  210. package/dist/resources/parser.js.map +1 -0
  211. package/dist/resources/types.d.ts +18 -0
  212. package/dist/resources/types.d.ts.map +1 -0
  213. package/dist/resources/types.js +3 -0
  214. package/dist/resources/types.js.map +1 -0
  215. package/dist/src.tsbuildinfo +1 -0
  216. package/dist/test.tsbuildinfo +1 -0
  217. package/dist/tracing/git.d.ts +19 -0
  218. package/dist/tracing/git.d.ts.map +1 -0
  219. package/dist/tracing/git.js +45 -0
  220. package/dist/tracing/git.js.map +1 -0
  221. package/dist/tracing/index.d.ts +4 -0
  222. package/dist/tracing/index.d.ts.map +1 -0
  223. package/dist/tracing/index.js +20 -0
  224. package/dist/tracing/index.js.map +1 -0
  225. package/dist/tracing/trace.d.ts +11 -0
  226. package/dist/tracing/trace.d.ts.map +1 -0
  227. package/dist/tracing/trace.js +27 -0
  228. package/dist/tracing/trace.js.map +1 -0
  229. package/dist/tracing/traced.d.ts +4 -0
  230. package/dist/tracing/traced.d.ts.map +1 -0
  231. package/dist/tracing/traced.js +6 -0
  232. package/dist/tracing/traced.js.map +1 -0
  233. package/dist/units/index.d.ts +3 -0
  234. package/dist/units/index.d.ts.map +1 -0
  235. package/dist/units/index.js +22 -0
  236. package/dist/units/index.js.map +1 -0
  237. package/dist/units/unit-parser.d.ts +19 -0
  238. package/dist/units/unit-parser.d.ts.map +1 -0
  239. package/dist/units/unit-parser.js +53 -0
  240. package/dist/units/unit-parser.js.map +1 -0
  241. package/dist/units/units.d.ts +37 -0
  242. package/dist/units/units.d.ts.map +1 -0
  243. package/dist/units/units.js +36 -0
  244. package/dist/units/units.js.map +1 -0
  245. package/package.json +89 -0
  246. package/src/_embedder/base.ts +42 -0
  247. package/src/_embedder/index.ts +1 -0
  248. package/src/_string/index.ts +5 -0
  249. package/src/_string/markers.ts +47 -0
  250. package/src/_string/post-processor.ts +25 -0
  251. package/src/_string/pretty-objects.ts +65 -0
  252. package/src/_string/pretty-print.ts +24 -0
  253. package/src/_string/super-script.ts +17 -0
  254. package/src/api-kind/index.ts +134 -0
  255. package/src/cmd/cli-command.ts +89 -0
  256. package/src/cmd/cli-term.ts +60 -0
  257. package/src/cmd/index.ts +2 -0
  258. package/src/cmd/types.ts +4 -0
  259. package/src/displayers/displayers.ts +147 -0
  260. package/src/displayers/index.ts +1 -0
  261. package/src/env/env.ts +74 -0
  262. package/src/env/index.ts +2 -0
  263. package/src/env/types.ts +7 -0
  264. package/src/env/validate-name.ts +10 -0
  265. package/src/error.ts +15 -0
  266. package/src/forward-exports/delayed-exports.ts +155 -0
  267. package/src/forward-exports/index.ts +1 -0
  268. package/src/graph/base-node.ts +125 -0
  269. package/src/graph/base-origin-entity.ts +44 -0
  270. package/src/graph/dependencies.ts +27 -0
  271. package/src/graph/index.ts +6 -0
  272. package/src/graph/origin-node.ts +118 -0
  273. package/src/graph/relations.ts +62 -0
  274. package/src/graph/resource-node.ts +104 -0
  275. package/src/image/family.ts +71 -0
  276. package/src/image/index.ts +1 -0
  277. package/src/index.ts +18 -0
  278. package/src/kind-map/index.ts +150 -0
  279. package/src/manifest/index.ts +53 -0
  280. package/src/manifest/manifest-builder.ts +98 -0
  281. package/src/ports/error.ts +8 -0
  282. package/src/ports/index.ts +8 -0
  283. package/src/ports/map.ts +41 -0
  284. package/src/ports/set.ts +79 -0
  285. package/src/ports/tools/entry.ts +43 -0
  286. package/src/ports/tools/parse.ts +40 -0
  287. package/src/ports/types.ts +42 -0
  288. package/src/producer/index.ts +1 -0
  289. package/src/producer/producer.ts +18 -0
  290. package/src/ref-key/index.ts +1 -0
  291. package/src/ref-key/ref-key.ts +76 -0
  292. package/src/reference/forward-ref.ts +122 -0
  293. package/src/reference/index.ts +3 -0
  294. package/src/reference/refable.ts +11 -0
  295. package/src/resources/index.ts +2 -0
  296. package/src/resources/objects.ts +99 -0
  297. package/src/resources/parser.ts +24 -0
  298. package/src/resources/types.ts +23 -0
  299. package/src/tracing/git.ts +51 -0
  300. package/src/tracing/index.ts +3 -0
  301. package/src/tracing/trace.ts +31 -0
  302. package/src/tracing/traced.ts +4 -0
  303. package/src/tsconfig.json +10 -0
  304. package/src/units/index.ts +2 -0
  305. package/src/units/unit-parser.ts +63 -0
  306. package/src/units/units.ts +53 -0
  307. package/tsconfig.json +15 -0
@@ -0,0 +1,155 @@
1
+ import { seq } from "doddle"
2
+ import { ProxyOperationError } from "../error"
3
+ import { Origin } from "../graph/origin-node"
4
+ import type { LiveRefable } from "../reference"
5
+ import { ForwardRef } from "../reference"
6
+
7
+ export type FutureExports<Exps extends LiveRefable> = FutureExports.FutureExports<Exps>
8
+ export namespace FutureExports {
9
+ export type FutureExports<Exps extends LiveRefable> = _ExportsByKey<Exps>
10
+ type _ExportsByKey<Exports extends LiveRefable = LiveRefable> = {
11
+ [E in Exports as `${E["kind"]["name"]}/${E["node"]["key"]["name"]}`]: ForwardRef<E>
12
+ }
13
+ export interface Props<
14
+ Actual extends object = object,
15
+ Exports extends LiveRefable = LiveRefable
16
+ > {
17
+ readonly origin: Origin
18
+ readonly actual: Actual
19
+ readonly exports: Iterable<Exports>
20
+ }
21
+
22
+ export function make<T extends LiveRefable, Actual extends object>(
23
+ props: Props<Actual, T>
24
+ ): Actual & FutureExports<LiveRefable> {
25
+ const handler = new Handler(props)
26
+ return new Proxy(props.actual, handler) as any
27
+ }
28
+ class Handler implements ProxyHandler<object> {
29
+ constructor(private readonly _props: Props) {}
30
+
31
+ #createImmutableError(action: string) {
32
+ return new ProxyOperationError(
33
+ `Tried to ${action} an the exports constructs of ${this._props.origin}, but it is immutable.`
34
+ )
35
+ }
36
+
37
+ defineProperty(_: object, property: string | symbol, __: PropertyDescriptor): boolean {
38
+ throw this.#createImmutableError(`define property ${String(property)} on`)
39
+ }
40
+
41
+ deleteProperty(_: object, property: string | symbol): boolean {
42
+ throw this.#createImmutableError(`delete property ${String(property)} from`)
43
+ }
44
+
45
+ getPrototypeOf(_: Iterable<LiveRefable>): object | null {
46
+ return Reflect.getPrototypeOf(this._target)
47
+ }
48
+
49
+ get seq() {
50
+ return seq(this._props.exports)
51
+ }
52
+
53
+ #isValidReferant(prop: PropertyKey) {
54
+ return this._props.origin.resourceKinds.tryParse(prop as string) != null
55
+ }
56
+
57
+ get _target() {
58
+ return this._props.actual
59
+ }
60
+
61
+ get(target: any, property: string | symbol): any {
62
+ const key = property as string
63
+ if (Reflect.has(this._target, key)) {
64
+ const x = Reflect.get(this._target, property)
65
+ if (typeof x === "function") {
66
+ return x.bind(this._target)
67
+ }
68
+ return x
69
+ }
70
+
71
+ const refKey = this._props.origin.resourceKinds.tryParse(key)
72
+ if (refKey == null) {
73
+ return undefined
74
+ }
75
+ const cls = this._props.origin.resourceKinds.getClass(refKey)
76
+ return ForwardRef.make({
77
+ class: cls,
78
+ key: refKey,
79
+ origin: this._props.origin,
80
+ namespace: this._props.origin.meta.tryGet("namespace"),
81
+ resolver: this.seq
82
+ .find(exp => exp.node.key.equals(refKey))
83
+ .map(x => {
84
+ if (x == null) {
85
+ throw new ProxyOperationError(
86
+ `Failed to resolve forward reference to ${refKey} in ${this._props.origin}.`
87
+ )
88
+ }
89
+ return x
90
+ })
91
+ })
92
+ }
93
+
94
+ has(_: Iterable<LiveRefable>, p: string | symbol): boolean {
95
+ if (Reflect.has(this._target, p)) {
96
+ return true
97
+ }
98
+ if (!this.#isValidReferant(p)) {
99
+ return false
100
+ }
101
+ return true
102
+ }
103
+
104
+ isExtensible(target: Iterable<LiveRefable>): boolean {
105
+ return false
106
+ }
107
+
108
+ preventExtensions(target: Iterable<LiveRefable>): boolean {
109
+ return true
110
+ }
111
+
112
+ ownKeys(target: Iterable<LiveRefable>): ArrayLike<string | symbol> {
113
+ throw new ProxyOperationError(
114
+ `Cannot list all keys of a dynamic exports construct for ${this._props.origin}.`
115
+ )
116
+ }
117
+
118
+ set(
119
+ target: Iterable<LiveRefable>,
120
+ p: string | symbol,
121
+ newValue: any,
122
+ receiver: any
123
+ ): boolean {
124
+ throw this.#createImmutableError(`set property ${String(p)} on`)
125
+ }
126
+
127
+ setPrototypeOf(target: Iterable<LiveRefable>, v: any): boolean {
128
+ throw this.#createImmutableError(`set prototype of`)
129
+ }
130
+
131
+ _tryTargetDescriptor(p: PropertyKey) {
132
+ return Object.getOwnPropertyDescriptor(this._target, p)
133
+ }
134
+
135
+ getOwnPropertyDescriptor(
136
+ target: Iterable<LiveRefable>,
137
+ p: string | symbol
138
+ ): PropertyDescriptor | undefined {
139
+ const desc = this._tryTargetDescriptor(p)
140
+ if (desc) {
141
+ return desc
142
+ }
143
+ const value = this.get(this._target, p)
144
+ if (value == null) {
145
+ return undefined
146
+ }
147
+ return {
148
+ configurable: false,
149
+ enumerable: true,
150
+ value,
151
+ writable: false
152
+ }
153
+ }
154
+ }
155
+ }
@@ -0,0 +1 @@
1
+ export * from "./delayed-exports"
@@ -0,0 +1,125 @@
1
+ import { Seq, seq } from "doddle"
2
+ import { hash, Set } from "immutable"
3
+ import { Kind } from "../api-kind"
4
+ import { RefKey } from "../ref-key"
5
+ import { ForwardRef } from "../reference"
6
+ import { NeedsEdge } from "./dependencies"
7
+
8
+ export interface BaseEntity<Node extends BaseNode<Node>> {
9
+ readonly node: Node
10
+
11
+ readonly shortFqn: string
12
+ readonly kind: Kind.Identifier
13
+ readonly name: string
14
+ }
15
+
16
+ export abstract class BaseNode<
17
+ Node extends BaseNode<Node, Entity>,
18
+ Entity extends BaseEntity<Node> = BaseEntity<Node>
19
+ > {
20
+ abstract readonly key: RefKey
21
+ get kind() {
22
+ return this.key.kind
23
+ }
24
+
25
+ abstract readonly kids: Seq<Node>
26
+ abstract readonly needs: Seq<NeedsEdge<Node>>
27
+ abstract readonly parent: Node | null
28
+ protected get _asNode() {
29
+ return this as any as Node
30
+ }
31
+
32
+ constructor(readonly _entity: Entity) {}
33
+
34
+ get shortFqn() {
35
+ return `${this.kind.name}/${this.name}`
36
+ }
37
+ get root(): Node {
38
+ return (this.ancestors.at(-1).pull() as any) ?? (this as any)
39
+ }
40
+ get name() {
41
+ return this.key.name
42
+ }
43
+ get isRoot() {
44
+ return this.parent === null
45
+ }
46
+
47
+ hashCode() {
48
+ return hash(this)
49
+ }
50
+ equals(other: any) {
51
+ if (ForwardRef.is(other)) {
52
+ return other.equals(this)
53
+ }
54
+ return this === other
55
+ }
56
+
57
+ readonly ancestors = seq(() => {
58
+ const seen = Set<Node>()
59
+ const recurse = function* (from: Node): Iterable<Node> {
60
+ const parent = from.parent
61
+ if (parent && !seen.has(parent)) {
62
+ seen.add(parent)
63
+ yield parent
64
+ yield* recurse(parent)
65
+ }
66
+ }
67
+ return seq(recurse.bind(null, this._asNode))
68
+ }).cache()
69
+
70
+ readonly descendants = seq(() => {
71
+ const self = this
72
+ let seen = Set<Node>()
73
+ const recurse = function* (from: Node): Iterable<Node> {
74
+ for (const kid of from.kids) {
75
+ if (seen.has(kid)) {
76
+ continue
77
+ }
78
+ seen = seen.add(kid)
79
+ yield kid
80
+ yield* recurse(kid)
81
+ }
82
+ }
83
+ return seq(recurse.bind(null, self._asNode))
84
+ }).cache()
85
+
86
+ isParentOf(other: Node): boolean {
87
+ if (ForwardRef.is(other)) {
88
+ return other.isChildOf(this._asNode)
89
+ }
90
+ return Set(this.descendants).has(other)
91
+ }
92
+
93
+ isChildOf(other: Node): boolean {
94
+ if (ForwardRef.is(other)) {
95
+ return other.isParentOf(this._asNode)
96
+ }
97
+ return this.equals(other) || Set(this.ancestors).has(other._asNode)
98
+ }
99
+
100
+ isNeeding(other: Node): boolean {
101
+ return this.needsGraph.some(x => x.needed.equals(other)).pull()
102
+ }
103
+
104
+ readonly needsGraph = seq(() => {
105
+ let resources = Set<Node>()
106
+ const recurseIntoDependency = function* (root: NeedsEdge<Node>): Iterable<NeedsEdge<Node>> {
107
+ yield root
108
+ if (resources.has(root.needed)) {
109
+ return
110
+ }
111
+ resources = resources.add(root.needed)
112
+
113
+ const ownDeps = root.needed.needs
114
+ for (const needsEdge of ownDeps) {
115
+ yield* recurseIntoDependency(needsEdge)
116
+ }
117
+ }
118
+ return seq(recurseIntoDependency.bind(null, new NeedsEdge<Node>("self", this._asNode)))
119
+ .after(() => {
120
+ resources = Set()
121
+ })
122
+ .cache()
123
+ })
124
+ }
125
+ export type Formats = "short" | "fqn" | "shortFqn"
@@ -0,0 +1,44 @@
1
+ import { Meta } from "@k8ts/metadata"
2
+ import chalk from "chalk"
3
+ import { doddle, Doddle } from "doddle"
4
+ import { Kind } from "../api-kind"
5
+ import { displayers } from "../displayers"
6
+ import { RefKey } from "../ref-key"
7
+ import { Origin, OriginEntity } from "./origin-node"
8
+ export interface OriginEntityProps {
9
+ meta?: Meta.Input
10
+ alias?: string
11
+ }
12
+ @displayers({
13
+ simple: x => `[${x.shortFqn}]`,
14
+ pretty(origin) {
15
+ const kindPart = chalk.greenBright.bold(origin.kind.name)
16
+ const originName = chalk.cyan(origin.name)
17
+ return `${kindPart}/${originName}`
18
+ }
19
+ })
20
+ export abstract class BaseOriginEntity<Props extends OriginEntityProps = OriginEntityProps>
21
+ implements OriginEntity
22
+ {
23
+ abstract readonly kind: Kind.Kind
24
+ #node: Doddle<Origin>
25
+
26
+ meta: Meta
27
+ get alias() {
28
+ return this.props.alias ?? undefined
29
+ }
30
+ get node() {
31
+ return this.#node.pull()
32
+ }
33
+ constructor(
34
+ readonly name: string,
35
+ readonly props: Props,
36
+ parent: Origin | null
37
+ ) {
38
+ this.#node = doddle(() => new Origin(parent, this, RefKey.make(this.kind, name)))
39
+ this.meta = Meta.make(props.meta)
40
+ }
41
+ get shortFqn() {
42
+ return this.node.shortFqn
43
+ }
44
+ }
@@ -0,0 +1,27 @@
1
+ import chalk from "chalk"
2
+ import { pretty } from "../_string"
3
+ import { displayers } from "../displayers"
4
+ import { BaseNode } from "./base-node"
5
+ import { ResourceEntity } from "./resource-node"
6
+
7
+ export namespace Dependencies {
8
+ export type Input = Record<string, ResourceEntity>
9
+ }
10
+ export function dependencies(record: Dependencies.Input) {
11
+ return Object.entries(record).map(([key, value]) => {
12
+ return new NeedsEdge(key, value.node)
13
+ })
14
+ }
15
+ @displayers({
16
+ simple: s => [s.why, "-->", s.needed],
17
+ pretty: (dep, format) => {
18
+ const neededFmt = pretty`${["lowkey", dep.needed]}`
19
+ return [`${chalk.gray.italic.white(`${dep.why}`)}`, "➜ ", chalk.italic(`${neededFmt}`)]
20
+ }
21
+ })
22
+ export class NeedsEdge<Node extends BaseNode<Node>> {
23
+ constructor(
24
+ readonly why: string,
25
+ readonly needed: Node
26
+ ) {}
27
+ }
@@ -0,0 +1,6 @@
1
+ export * from "./base-node"
2
+ export * from "./base-origin-entity"
3
+ export * from "./dependencies"
4
+ export * from "./origin-node"
5
+ export * from "./relations"
6
+ export * from "./resource-node"
@@ -0,0 +1,118 @@
1
+ import { Meta } from "@k8ts/metadata"
2
+ import chalk from "chalk"
3
+ import { doddle, seq, Seq } from "doddle"
4
+ import StackTracey from "stacktracey"
5
+ import { getMarkerForIndex, toSuperScript } from "../_string"
6
+ import { displayers } from "../displayers"
7
+ import { KindMap } from "../kind-map"
8
+ import { RefKey } from "../ref-key"
9
+ import { TraceEmbedder } from "../tracing"
10
+ import { Trace } from "../tracing/trace"
11
+ import { BaseEntity, BaseNode } from "./base-node"
12
+ import { ResourceNode } from "./resource-node"
13
+ @displayers({
14
+ simple: s => `[${s.shortFqn}]`,
15
+ prefix: s => {
16
+ if (s.name === "EXTERNAL") {
17
+ return "🌐"
18
+ }
19
+ return getMarkerForIndex(s.index, s._entity.alias ?? toSuperScript(s.index))
20
+ },
21
+ pretty(origin, format) {
22
+ const kindName = chalk.greenBright.bold(origin.kind.name)
23
+ const resourceName = chalk.cyan(origin.name)
24
+ const pref = this.prefix!()
25
+
26
+ return `${kindName}:${resourceName} (${pref})`
27
+ }
28
+ })
29
+ export class Origin extends BaseNode<Origin, OriginEntity> implements Iterable<ResourceNode> {
30
+ private _kids = [] as Origin[]
31
+ get kids() {
32
+ return seq(this._kids)
33
+ }
34
+ get meta() {
35
+ return this._entity.meta
36
+ }
37
+ readonly index: number
38
+ private readonly _getIndex = doddle(() => {
39
+ let index = 1
40
+ return () => index++
41
+ }).pull()
42
+ constructor(
43
+ readonly parent: Origin | null,
44
+ entity: OriginEntity,
45
+ readonly key: RefKey
46
+ ) {
47
+ super(entity)
48
+ this.index = parent?._getIndex() ?? 0
49
+ this._kindMap = new KindMap(undefined, parent?._kindMap)
50
+ }
51
+ get resourceKinds() {
52
+ return this._kindMap
53
+ }
54
+ private _kindMap: KindMap
55
+ private _attached = [] as ResourceNode[]
56
+
57
+ get needs() {
58
+ return seq.empty()
59
+ }
60
+ [Symbol.iterator]() {
61
+ return this.resources[Symbol.iterator]()
62
+ }
63
+ readonly attachedTree: Seq<ResourceNode> = seq(() => {
64
+ const self = this
65
+ const desc = self.descendants.prepend(this).concatMap(function* (x) {
66
+ yield* self.resources
67
+ for (const kid of self.kids) {
68
+ yield* kid.resources
69
+ }
70
+ })
71
+ return desc
72
+ }).cache()
73
+
74
+ get resources() {
75
+ return this._attached
76
+ }
77
+ static registerWithOrigin<F extends Function>(ctor: F) {
78
+ const prototype = ctor.prototype
79
+ for (const key of Object.getOwnPropertyNames(prototype)) {
80
+ const value = prototype[key]
81
+ if (!key.match(/^[A-Z]/) || typeof value !== "function") {
82
+ continue
83
+ }
84
+ const orig = prototype[key]
85
+ prototype[key] = {
86
+ [key](this: any, ...args: any[]) {
87
+ const result = orig.apply(this, args) as BaseEntity<any>
88
+ if (
89
+ typeof result === "object" &&
90
+ "node" in result &&
91
+ result.node instanceof ResourceNode
92
+ ) {
93
+ result.node.origin.__attach_resource__([result.node])
94
+ TraceEmbedder.set(result.node, new Trace(new StackTracey().slice(1)))
95
+ }
96
+ return result
97
+ }
98
+ }[key]
99
+ }
100
+ }
101
+
102
+ private __attach_child__(child: Origin) {
103
+ this._kids.push(child)
104
+ }
105
+
106
+ private __attach_resource__(resources: ResourceNode | Iterable<ResourceNode>) {
107
+ resources = Symbol.iterator in resources ? resources : [resources]
108
+ for (const resource of resources) {
109
+ this._attached.push(resource)
110
+ }
111
+ }
112
+ }
113
+ export interface OriginEntity extends BaseEntity<Origin> {
114
+ alias?: string
115
+ meta: Meta
116
+ }
117
+
118
+ export const auto_register = Origin.registerWithOrigin
@@ -0,0 +1,62 @@
1
+ import { Embedder } from "../_embedder/base"
2
+ import { Dependencies, dependencies, NeedsEdge } from "./dependencies"
3
+ import { ResourceEntity, ResourceNode } from "./resource-node"
4
+
5
+ export namespace Relations {
6
+ export interface Out {
7
+ needs: () => Iterable<NeedsEdge<ResourceNode>>
8
+ parent: () => ResourceNode | null
9
+ kids: () => ResourceNode[]
10
+ }
11
+
12
+ export type In<Target extends ResourceEntity = ResourceEntity> = {
13
+ needs: (self: Target) => Dependencies.Input
14
+ parent: (self: Target) => ResourceEntity | null
15
+ kids: (self: Target) => ResourceEntity[]
16
+ } & {
17
+ [key: string]: (self: Target, ...args: any[]) => any
18
+ }
19
+ }
20
+
21
+ class RelationsService {
22
+ private _system = new Embedder<ResourceEntity, Relations.In>("relations")
23
+
24
+ implement(
25
+ ctor: abstract new (...args: any[]) => ResourceEntity,
26
+ input: Relations.In<ResourceEntity>
27
+ ) {
28
+ const existing = this._system.tryGet(ctor.prototype)
29
+ if (existing) {
30
+ input = Object.assign({}, existing, input)
31
+ }
32
+ this._system.set(ctor.prototype, input)
33
+ }
34
+
35
+ get(target: ResourceEntity): Relations.Out {
36
+ const input = this._system.get(target)
37
+ const o = {
38
+ kids: () => input.kids?.call(o, target).map(x => x.node) ?? [],
39
+ parent: () => input.parent?.call(o, target)?.node ?? null,
40
+ needs: () => dependencies(input.needs?.call(o, target) ?? {})
41
+ }
42
+ return o
43
+ }
44
+
45
+ get decorator() {
46
+ return <
47
+ Target extends abstract new (...args: any[]) => ResourceEntity,
48
+ Impl extends Partial<Relations.In<InstanceType<Target>>> | "none"
49
+ >(
50
+ input: Impl
51
+ ) => {
52
+ return (ctor: Target) => {
53
+ this.implement(ctor, input === "none" ? {} : (input as any))
54
+ return ctor
55
+ }
56
+ }
57
+ }
58
+ }
59
+ export const Relations = new RelationsService()
60
+ export const relations = Relations.decorator
61
+
62
+ // writing the decorator itself
@@ -0,0 +1,104 @@
1
+ import { MutableMeta } from "@k8ts/metadata"
2
+ import chalk from "chalk"
3
+ import { seq } from "doddle"
4
+ import { displayers } from "../displayers"
5
+ import { RefKey } from "../ref-key"
6
+ import { TraceEmbedder } from "../tracing"
7
+ import { BaseEntity, BaseNode, Formats } from "./base-node"
8
+ import { Origin } from "./origin-node"
9
+ import { Relations } from "./relations"
10
+
11
+ @displayers({
12
+ simple: s => `[${s.shortFqn}]`,
13
+ pretty(resource, format) {
14
+ format ??= "global"
15
+
16
+ let kindName = chalk.greenBright(resource.kind.name)
17
+ if (format !== "lowkey") {
18
+ kindName = chalk.bold(kindName)
19
+ }
20
+ const resourceName = chalk.blueBright(resource.name)
21
+ const mainPart = `${kindName}/${resourceName}`
22
+ let originPart = ` (${displayers.get(resource.origin).prefix!()})`
23
+ let text = ""
24
+
25
+ text += mainPart
26
+ if (format !== "local") {
27
+ text += originPart
28
+ }
29
+ return text
30
+ }
31
+ })
32
+ export class ResourceNode extends BaseNode<ResourceNode, ResourceEntity> {
33
+ get needs() {
34
+ return seq(this._relations.needs)
35
+ }
36
+
37
+ get trace() {
38
+ return TraceEmbedder.get(this)
39
+ }
40
+
41
+ get isExported() {
42
+ return this.meta?.tryGet("#k8ts.org/is-exported") ?? false
43
+ }
44
+
45
+ get meta() {
46
+ return "meta" in this._entity ? (this._entity.meta as MutableMeta) : undefined
47
+ }
48
+
49
+ get isExternal() {
50
+ return this.origins.some(x => x.name === "EXTERNAL").pull()
51
+ }
52
+
53
+ get origins() {
54
+ const self = this
55
+ return seq(function* () {
56
+ let current: Origin | null = self.origin
57
+ while (current) {
58
+ yield current
59
+ current = current.parent
60
+ }
61
+ })
62
+ }
63
+
64
+ get kids() {
65
+ return seq(this._relations.kids)
66
+ }
67
+
68
+ get parent() {
69
+ return this._relations.parent()
70
+ }
71
+
72
+ override get shortFqn() {
73
+ return `${this.origin.name}:${this.key}`
74
+ }
75
+
76
+ get localName() {
77
+ return this.key.string
78
+ }
79
+
80
+ format(format: Formats) {
81
+ switch (format) {
82
+ case "short":
83
+ return this.name
84
+ case "fqn":
85
+ return this.key.string
86
+ case "shortFqn":
87
+ return this.key.name
88
+ }
89
+ }
90
+ private get _relations() {
91
+ return Relations.get(this._entity)
92
+ }
93
+ constructor(
94
+ readonly origin: Origin,
95
+ readonly entity: ResourceEntity,
96
+ readonly key: RefKey
97
+ ) {
98
+ super(entity)
99
+ }
100
+ }
101
+ export interface MetadataEntity extends BaseEntity<ResourceNode> {
102
+ meta: MutableMeta
103
+ }
104
+ export interface ResourceEntity extends BaseEntity<ResourceNode> {}