@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.
- package/LICENSE.md +7 -0
- package/README.md +3 -0
- package/dist/_embedder/base.d.ts +11 -0
- package/dist/_embedder/base.d.ts.map +1 -0
- package/dist/_embedder/base.js +39 -0
- package/dist/_embedder/base.js.map +1 -0
- package/dist/_embedder/index.d.ts +2 -0
- package/dist/_embedder/index.d.ts.map +1 -0
- package/dist/_embedder/index.js +18 -0
- package/dist/_embedder/index.js.map +1 -0
- package/dist/_string/index.d.ts +6 -0
- package/dist/_string/index.d.ts.map +1 -0
- package/dist/_string/index.js +22 -0
- package/dist/_string/index.js.map +1 -0
- package/dist/_string/markers.d.ts +3 -0
- package/dist/_string/markers.d.ts.map +1 -0
- package/dist/_string/markers.js +48 -0
- package/dist/_string/markers.js.map +1 -0
- package/dist/_string/post-processor.d.ts +7 -0
- package/dist/_string/post-processor.d.ts.map +1 -0
- package/dist/_string/post-processor.js +30 -0
- package/dist/_string/post-processor.js.map +1 -0
- package/dist/_string/pretty-objects.d.ts +27 -0
- package/dist/_string/pretty-objects.d.ts.map +1 -0
- package/dist/_string/pretty-objects.js +192 -0
- package/dist/_string/pretty-objects.js.map +1 -0
- package/dist/_string/pretty-print.d.ts +2 -0
- package/dist/_string/pretty-print.d.ts.map +1 -0
- package/dist/_string/pretty-print.js +27 -0
- package/dist/_string/pretty-print.js.map +1 -0
- package/dist/_string/super-script.d.ts +2 -0
- package/dist/_string/super-script.d.ts.map +1 -0
- package/dist/_string/super-script.js +20 -0
- package/dist/_string/super-script.js.map +1 -0
- package/dist/api-kind/index.d.ts +43 -0
- package/dist/api-kind/index.d.ts.map +1 -0
- package/dist/api-kind/index.js +102 -0
- package/dist/api-kind/index.js.map +1 -0
- package/dist/cmd/cli-command.d.ts +23 -0
- package/dist/cmd/cli-command.d.ts.map +1 -0
- package/dist/cmd/cli-command.js +73 -0
- package/dist/cmd/cli-command.js.map +1 -0
- package/dist/cmd/cli-term.d.ts +25 -0
- package/dist/cmd/cli-term.d.ts.map +1 -0
- package/dist/cmd/cli-term.js +55 -0
- package/dist/cmd/cli-term.js.map +1 -0
- package/dist/cmd/index.d.ts +3 -0
- package/dist/cmd/index.d.ts.map +1 -0
- package/dist/cmd/index.js +7 -0
- package/dist/cmd/index.js.map +1 -0
- package/dist/cmd/types.d.ts +5 -0
- package/dist/cmd/types.d.ts.map +1 -0
- package/dist/cmd/types.js +3 -0
- package/dist/cmd/types.js.map +1 -0
- package/dist/displayers/displayers.d.ts +33 -0
- package/dist/displayers/displayers.d.ts.map +1 -0
- package/dist/displayers/displayers.js +129 -0
- package/dist/displayers/displayers.js.map +1 -0
- package/dist/displayers/index.d.ts +2 -0
- package/dist/displayers/index.d.ts.map +1 -0
- package/dist/displayers/index.js +18 -0
- package/dist/displayers/index.js.map +1 -0
- package/dist/env/env.d.ts +20 -0
- package/dist/env/env.d.ts.map +1 -0
- package/dist/env/env.js +68 -0
- package/dist/env/env.js.map +1 -0
- package/dist/env/index.d.ts +3 -0
- package/dist/env/index.d.ts.map +1 -0
- package/dist/env/index.js +7 -0
- package/dist/env/index.js.map +1 -0
- package/dist/env/types.d.ts +4 -0
- package/dist/env/types.d.ts.map +1 -0
- package/dist/env/types.js +3 -0
- package/dist/env/types.js.map +1 -0
- package/dist/env/validate-name.d.ts +2 -0
- package/dist/env/validate-name.d.ts.map +1 -0
- package/dist/env/validate-name.js +12 -0
- package/dist/env/validate-name.js.map +1 -0
- package/dist/error.d.ts +8 -0
- package/dist/error.d.ts.map +1 -0
- package/dist/error.js +20 -0
- package/dist/error.js.map +1 -0
- package/dist/forward-exports/delayed-exports.d.ts +18 -0
- package/dist/forward-exports/delayed-exports.d.ts.map +1 -0
- package/dist/forward-exports/delayed-exports.js +119 -0
- package/dist/forward-exports/delayed-exports.js.map +1 -0
- package/dist/forward-exports/index.d.ts +2 -0
- package/dist/forward-exports/index.d.ts.map +1 -0
- package/dist/forward-exports/index.js +18 -0
- package/dist/forward-exports/index.js.map +1 -0
- package/dist/graph/base-node.d.ts +34 -0
- package/dist/graph/base-node.d.ts.map +1 -0
- package/dist/graph/base-node.js +102 -0
- package/dist/graph/base-node.js.map +1 -0
- package/dist/graph/base-origin-entity.d.ts +19 -0
- package/dist/graph/base-origin-entity.d.ts.map +1 -0
- package/dist/graph/base-origin-entity.js +105 -0
- package/dist/graph/base-origin-entity.js.map +1 -0
- package/dist/graph/dependencies.d.ts +12 -0
- package/dist/graph/dependencies.d.ts.map +1 -0
- package/dist/graph/dependencies.js +82 -0
- package/dist/graph/dependencies.js.map +1 -0
- package/dist/graph/index.d.ts +7 -0
- package/dist/graph/index.d.ts.map +1 -0
- package/dist/graph/index.js +23 -0
- package/dist/graph/index.js.map +1 -0
- package/dist/graph/origin-node.d.ts +32 -0
- package/dist/graph/origin-node.d.ts.map +1 -0
- package/dist/graph/origin-node.js +161 -0
- package/dist/graph/origin-node.js.map +1 -0
- package/dist/graph/relations.d.ts +26 -0
- package/dist/graph/relations.d.ts.map +1 -0
- package/dist/graph/relations.js +38 -0
- package/dist/graph/relations.js.map +1 -0
- package/dist/graph/resource-node.d.ts +28 -0
- package/dist/graph/resource-node.d.ts.map +1 -0
- package/dist/graph/resource-node.js +144 -0
- package/dist/graph/resource-node.js.map +1 -0
- package/dist/image/family.d.ts +26 -0
- package/dist/image/family.d.ts.map +1 -0
- package/dist/image/family.js +63 -0
- package/dist/image/family.js.map +1 -0
- package/dist/image/index.d.ts +2 -0
- package/dist/image/index.d.ts.map +1 -0
- package/dist/image/index.js +9 -0
- package/dist/image/index.js.map +1 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +35 -0
- package/dist/index.js.map +1 -0
- package/dist/kind-map/index.d.ts +44 -0
- package/dist/kind-map/index.d.ts.map +1 -0
- package/dist/kind-map/index.js +123 -0
- package/dist/kind-map/index.js.map +1 -0
- package/dist/manifest/index.d.ts +46 -0
- package/dist/manifest/index.d.ts.map +1 -0
- package/dist/manifest/index.js +21 -0
- package/dist/manifest/index.js.map +1 -0
- package/dist/manifest/manifest-builder.d.ts +45 -0
- package/dist/manifest/manifest-builder.d.ts.map +1 -0
- package/dist/manifest/manifest-builder.js +66 -0
- package/dist/manifest/manifest-builder.js.map +1 -0
- package/dist/ports/error.d.ts +5 -0
- package/dist/ports/error.d.ts.map +1 -0
- package/dist/ports/error.js +13 -0
- package/dist/ports/error.js.map +1 -0
- package/dist/ports/index.d.ts +7 -0
- package/dist/ports/index.d.ts.map +1 -0
- package/dist/ports/index.js +13 -0
- package/dist/ports/index.js.map +1 -0
- package/dist/ports/map.d.ts +13 -0
- package/dist/ports/map.d.ts.map +1 -0
- package/dist/ports/map.js +38 -0
- package/dist/ports/map.js.map +1 -0
- package/dist/ports/set.d.ts +18 -0
- package/dist/ports/set.d.ts.map +1 -0
- package/dist/ports/set.js +60 -0
- package/dist/ports/set.js.map +1 -0
- package/dist/ports/tools/entry.d.ts +6 -0
- package/dist/ports/tools/entry.d.ts.map +1 -0
- package/dist/ports/tools/entry.js +36 -0
- package/dist/ports/tools/entry.js.map +1 -0
- package/dist/ports/tools/parse.d.ts +3 -0
- package/dist/ports/tools/parse.d.ts.map +1 -0
- package/dist/ports/tools/parse.js +35 -0
- package/dist/ports/tools/parse.js.map +1 -0
- package/dist/ports/types.d.ts +37 -0
- package/dist/ports/types.d.ts.map +1 -0
- package/dist/ports/types.js +3 -0
- package/dist/ports/types.js.map +1 -0
- package/dist/producer/index.d.ts +2 -0
- package/dist/producer/index.d.ts.map +1 -0
- package/dist/producer/index.js +18 -0
- package/dist/producer/index.js.map +1 -0
- package/dist/producer/producer.d.ts +6 -0
- package/dist/producer/producer.d.ts.map +1 -0
- package/dist/producer/producer.js +13 -0
- package/dist/producer/producer.js.map +1 -0
- package/dist/ref-key/index.d.ts +2 -0
- package/dist/ref-key/index.d.ts.map +1 -0
- package/dist/ref-key/index.js +18 -0
- package/dist/ref-key/index.js.map +1 -0
- package/dist/ref-key/ref-key.d.ts +23 -0
- package/dist/ref-key/ref-key.d.ts.map +1 -0
- package/dist/ref-key/ref-key.js +67 -0
- package/dist/ref-key/ref-key.js.map +1 -0
- package/dist/reference/forward-ref.d.ts +22 -0
- package/dist/reference/forward-ref.d.ts.map +1 -0
- package/dist/reference/forward-ref.js +126 -0
- package/dist/reference/forward-ref.js.map +1 -0
- package/dist/reference/index.d.ts +4 -0
- package/dist/reference/index.d.ts.map +1 -0
- package/dist/reference/index.js +8 -0
- package/dist/reference/index.js.map +1 -0
- package/dist/reference/refable.d.ts +12 -0
- package/dist/reference/refable.d.ts.map +1 -0
- package/dist/reference/refable.js +3 -0
- package/dist/reference/refable.js.map +1 -0
- package/dist/resources/index.d.ts +3 -0
- package/dist/resources/index.d.ts.map +1 -0
- package/dist/resources/index.js +19 -0
- package/dist/resources/index.js.map +1 -0
- package/dist/resources/objects.d.ts +22 -0
- package/dist/resources/objects.d.ts.map +1 -0
- package/dist/resources/objects.js +93 -0
- package/dist/resources/objects.js.map +1 -0
- package/dist/resources/parser.d.ts +4 -0
- package/dist/resources/parser.d.ts.map +1 -0
- package/dist/resources/parser.js +21 -0
- package/dist/resources/parser.js.map +1 -0
- package/dist/resources/types.d.ts +18 -0
- package/dist/resources/types.d.ts.map +1 -0
- package/dist/resources/types.js +3 -0
- package/dist/resources/types.js.map +1 -0
- package/dist/src.tsbuildinfo +1 -0
- package/dist/test.tsbuildinfo +1 -0
- package/dist/tracing/git.d.ts +19 -0
- package/dist/tracing/git.d.ts.map +1 -0
- package/dist/tracing/git.js +45 -0
- package/dist/tracing/git.js.map +1 -0
- package/dist/tracing/index.d.ts +4 -0
- package/dist/tracing/index.d.ts.map +1 -0
- package/dist/tracing/index.js +20 -0
- package/dist/tracing/index.js.map +1 -0
- package/dist/tracing/trace.d.ts +11 -0
- package/dist/tracing/trace.d.ts.map +1 -0
- package/dist/tracing/trace.js +27 -0
- package/dist/tracing/trace.js.map +1 -0
- package/dist/tracing/traced.d.ts +4 -0
- package/dist/tracing/traced.d.ts.map +1 -0
- package/dist/tracing/traced.js +6 -0
- package/dist/tracing/traced.js.map +1 -0
- package/dist/units/index.d.ts +3 -0
- package/dist/units/index.d.ts.map +1 -0
- package/dist/units/index.js +22 -0
- package/dist/units/index.js.map +1 -0
- package/dist/units/unit-parser.d.ts +19 -0
- package/dist/units/unit-parser.d.ts.map +1 -0
- package/dist/units/unit-parser.js +53 -0
- package/dist/units/unit-parser.js.map +1 -0
- package/dist/units/units.d.ts +37 -0
- package/dist/units/units.d.ts.map +1 -0
- package/dist/units/units.js +36 -0
- package/dist/units/units.js.map +1 -0
- package/package.json +89 -0
- package/src/_embedder/base.ts +42 -0
- package/src/_embedder/index.ts +1 -0
- package/src/_string/index.ts +5 -0
- package/src/_string/markers.ts +47 -0
- package/src/_string/post-processor.ts +25 -0
- package/src/_string/pretty-objects.ts +65 -0
- package/src/_string/pretty-print.ts +24 -0
- package/src/_string/super-script.ts +17 -0
- package/src/api-kind/index.ts +134 -0
- package/src/cmd/cli-command.ts +89 -0
- package/src/cmd/cli-term.ts +60 -0
- package/src/cmd/index.ts +2 -0
- package/src/cmd/types.ts +4 -0
- package/src/displayers/displayers.ts +147 -0
- package/src/displayers/index.ts +1 -0
- package/src/env/env.ts +74 -0
- package/src/env/index.ts +2 -0
- package/src/env/types.ts +7 -0
- package/src/env/validate-name.ts +10 -0
- package/src/error.ts +15 -0
- package/src/forward-exports/delayed-exports.ts +155 -0
- package/src/forward-exports/index.ts +1 -0
- package/src/graph/base-node.ts +125 -0
- package/src/graph/base-origin-entity.ts +44 -0
- package/src/graph/dependencies.ts +27 -0
- package/src/graph/index.ts +6 -0
- package/src/graph/origin-node.ts +118 -0
- package/src/graph/relations.ts +62 -0
- package/src/graph/resource-node.ts +104 -0
- package/src/image/family.ts +71 -0
- package/src/image/index.ts +1 -0
- package/src/index.ts +18 -0
- package/src/kind-map/index.ts +150 -0
- package/src/manifest/index.ts +53 -0
- package/src/manifest/manifest-builder.ts +98 -0
- package/src/ports/error.ts +8 -0
- package/src/ports/index.ts +8 -0
- package/src/ports/map.ts +41 -0
- package/src/ports/set.ts +79 -0
- package/src/ports/tools/entry.ts +43 -0
- package/src/ports/tools/parse.ts +40 -0
- package/src/ports/types.ts +42 -0
- package/src/producer/index.ts +1 -0
- package/src/producer/producer.ts +18 -0
- package/src/ref-key/index.ts +1 -0
- package/src/ref-key/ref-key.ts +76 -0
- package/src/reference/forward-ref.ts +122 -0
- package/src/reference/index.ts +3 -0
- package/src/reference/refable.ts +11 -0
- package/src/resources/index.ts +2 -0
- package/src/resources/objects.ts +99 -0
- package/src/resources/parser.ts +24 -0
- package/src/resources/types.ts +23 -0
- package/src/tracing/git.ts +51 -0
- package/src/tracing/index.ts +3 -0
- package/src/tracing/trace.ts +31 -0
- package/src/tracing/traced.ts +4 -0
- package/src/tsconfig.json +10 -0
- package/src/units/index.ts +2 -0
- package/src/units/unit-parser.ts +63 -0
- package/src/units/units.ts +53 -0
- package/tsconfig.json +15 -0
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
export type JoinIfNotEmpty<A extends string, J extends string, B extends string> = A extends ""
|
|
2
|
+
? B
|
|
3
|
+
: B extends ""
|
|
4
|
+
? A
|
|
5
|
+
: `${A}${J}${B}`
|
|
6
|
+
export class ImageHost<Text extends string = string> {
|
|
7
|
+
private readonly _url: Text
|
|
8
|
+
constructor(source: Text) {
|
|
9
|
+
this._url = source
|
|
10
|
+
this.toString = () => this[Symbol.toStringTag]
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
image<Image extends string>(name: Image) {
|
|
14
|
+
return new BaseImage<JoinIfNotEmpty<Text, "/", Image>>(this, name)
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
get [Symbol.toStringTag]() {
|
|
18
|
+
return this._url
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export class BaseImage<Text extends string = string> {
|
|
23
|
+
constructor(
|
|
24
|
+
private readonly _source: ImageHost,
|
|
25
|
+
private readonly _name: string
|
|
26
|
+
) {
|
|
27
|
+
this.toString = () => this[Symbol.toStringTag]
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
tag<Tag extends string>(tag: Tag) {
|
|
31
|
+
return new TaggedImage<JoinIfNotEmpty<Text, ":", Tag>>(this, tag)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
get [Symbol.toStringTag]() {
|
|
35
|
+
if (this._source[Symbol.toStringTag] === "") {
|
|
36
|
+
return this._name
|
|
37
|
+
}
|
|
38
|
+
return [this._source, this._name].join("/")
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export class TaggedImage<Text extends string = string> {
|
|
43
|
+
constructor(
|
|
44
|
+
private readonly _family: BaseImage<string>,
|
|
45
|
+
private readonly _tag: string
|
|
46
|
+
) {
|
|
47
|
+
this.toString = () => this.text
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
get text() {
|
|
51
|
+
const fam = this._family[Symbol.toStringTag]
|
|
52
|
+
if (this._tag === "") {
|
|
53
|
+
return fam
|
|
54
|
+
}
|
|
55
|
+
return [fam, this._tag].join(":")
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
get [Symbol.toStringTag]() {
|
|
59
|
+
return this.text
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export namespace Image {
|
|
64
|
+
export function name<Name extends string>(name: Name) {
|
|
65
|
+
return new ImageHost("").image(name)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export function host<Host extends string>(url: Host) {
|
|
69
|
+
return new ImageHost(url)
|
|
70
|
+
}
|
|
71
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { BaseImage, Image, ImageHost, TaggedImage } from "./family"
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export * from "./_embedder"
|
|
2
|
+
export * from "./_string"
|
|
3
|
+
export * from "./api-kind"
|
|
4
|
+
export * from "./cmd"
|
|
5
|
+
export * from "./displayers"
|
|
6
|
+
export * from "./env"
|
|
7
|
+
export * from "./forward-exports"
|
|
8
|
+
export * from "./graph"
|
|
9
|
+
export * from "./image"
|
|
10
|
+
export * from "./kind-map"
|
|
11
|
+
export * from "./manifest"
|
|
12
|
+
export * from "./ports"
|
|
13
|
+
export * from "./producer"
|
|
14
|
+
export * from "./ref-key"
|
|
15
|
+
export * from "./reference"
|
|
16
|
+
export * from "./resources"
|
|
17
|
+
export * from "./tracing"
|
|
18
|
+
export * from "./units"
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import { Map, type Set } from "immutable"
|
|
2
|
+
import { Kind } from "../api-kind"
|
|
3
|
+
import { InstrumentsError } from "../error"
|
|
4
|
+
import { RefKey } from "../ref-key"
|
|
5
|
+
const separator = "/"
|
|
6
|
+
export type LookupKey = NodeEntry[keyof NodeEntry]
|
|
7
|
+
interface NodeEntry {
|
|
8
|
+
kind: string
|
|
9
|
+
class: Function
|
|
10
|
+
ident: Kind.Identifier
|
|
11
|
+
}
|
|
12
|
+
export class KindMap {
|
|
13
|
+
constructor(
|
|
14
|
+
private _entryMap: Map<LookupKey, NodeEntry> = Map([]) as any,
|
|
15
|
+
private _parent: KindMap | undefined = undefined
|
|
16
|
+
) {}
|
|
17
|
+
|
|
18
|
+
refKey<Kind extends string, Name extends string>(
|
|
19
|
+
kind: Kind | Kind.Identifier<Kind>,
|
|
20
|
+
name: Name
|
|
21
|
+
): RefKey<Kind, Name> {
|
|
22
|
+
const trueKind = this.getKind(kind)
|
|
23
|
+
return new RefKey.RefKey(trueKind, name) as any
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
private _bindEntry(entry: NodeEntry) {
|
|
27
|
+
for (const key of [entry.kind, entry.class, entry.ident]) {
|
|
28
|
+
this._entryMap = this._entryMap.set(key, entry)
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
add(kind: Kind.Identifier, klass: Function) {
|
|
33
|
+
this._bindEntry({
|
|
34
|
+
kind: kind.name,
|
|
35
|
+
class: klass,
|
|
36
|
+
ident: kind
|
|
37
|
+
})
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
parse(ref: string | RefKey) {
|
|
41
|
+
const result = this.tryParse(ref)
|
|
42
|
+
if (!result) {
|
|
43
|
+
throw new InstrumentsError(`Could not parse reference key: ${ref}`)
|
|
44
|
+
}
|
|
45
|
+
return result
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
tryParse(ref: unknown): RefKey.RefKey | undefined {
|
|
49
|
+
if (typeof ref !== "string" && typeof ref !== "object") {
|
|
50
|
+
return undefined
|
|
51
|
+
}
|
|
52
|
+
if (ref == null) {
|
|
53
|
+
return undefined
|
|
54
|
+
}
|
|
55
|
+
if (ref instanceof RefKey.RefKey) {
|
|
56
|
+
return ref
|
|
57
|
+
}
|
|
58
|
+
if (typeof ref === "object") {
|
|
59
|
+
return undefined
|
|
60
|
+
}
|
|
61
|
+
const [kind, name] = ref.split(separator).map(s => s.trim())
|
|
62
|
+
if (!kind || !name) {
|
|
63
|
+
return undefined
|
|
64
|
+
}
|
|
65
|
+
return this.refKey(kind, name)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
get kinds(): Set<string> {
|
|
69
|
+
return this._entryMap
|
|
70
|
+
.keySeq()
|
|
71
|
+
.filter(k => typeof k === "string")
|
|
72
|
+
.toSet()
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
private _unknownNameError(kind: string) {
|
|
76
|
+
return new InstrumentsError(`The shorthand name ${kind} is not registered`)
|
|
77
|
+
}
|
|
78
|
+
private _unknownIdentError(ident: Kind.Identifier) {
|
|
79
|
+
return new InstrumentsError(`The kind identifier ${ident} is not registered`)
|
|
80
|
+
}
|
|
81
|
+
private _unknownClassError(klass: Function) {
|
|
82
|
+
return new InstrumentsError(`The class ${klass.name} is not registered`)
|
|
83
|
+
}
|
|
84
|
+
private _convert(something: LookupKey | RefKey.RefKey) {
|
|
85
|
+
if (typeof something === "string") {
|
|
86
|
+
if (something.includes("/")) {
|
|
87
|
+
return this.parse(something).kind
|
|
88
|
+
}
|
|
89
|
+
return something
|
|
90
|
+
} else if (typeof something === "function" || something instanceof Kind.Identifier) {
|
|
91
|
+
return something
|
|
92
|
+
} else if (something instanceof RefKey.RefKey) {
|
|
93
|
+
return something.kind
|
|
94
|
+
}
|
|
95
|
+
throw new InstrumentsError(`Invalid argument ${something}`)
|
|
96
|
+
}
|
|
97
|
+
private _getEntry(key: LookupKey | RefKey.RefKey) {
|
|
98
|
+
const converted = this._convert(key)
|
|
99
|
+
const entry = this._tryGetEntry(key)
|
|
100
|
+
if (!entry) {
|
|
101
|
+
if (typeof converted === "string") {
|
|
102
|
+
throw this._unknownNameError(converted)
|
|
103
|
+
} else if (converted instanceof Kind.Identifier) {
|
|
104
|
+
throw this._unknownIdentError(converted)
|
|
105
|
+
} else if (typeof converted === "function") {
|
|
106
|
+
throw this._unknownClassError(converted)
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return entry!
|
|
110
|
+
}
|
|
111
|
+
private _tryGetEntry(key: LookupKey | RefKey.RefKey): NodeEntry | undefined {
|
|
112
|
+
const converted = this._convert(key)
|
|
113
|
+
return this._entryMap.get(converted) ?? this._parent?._tryGetEntry(converted) ?? undefined
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
tryGetKind<Name extends string>(refKey: RefKey.RefKey<Name>): Kind.Identifier<Name> | undefined
|
|
117
|
+
tryGetKind<F extends Kind.Identifier>(klass: F): F
|
|
118
|
+
tryGetKind<Name extends string>(kind: Name): Kind.Identifier<Name> | undefined
|
|
119
|
+
tryGetKind(key: LookupKey): Kind.Identifier | undefined
|
|
120
|
+
tryGetKind(kindOrIdent: LookupKey | RefKey.RefKey): Kind.Identifier | undefined {
|
|
121
|
+
return this._tryGetEntry(kindOrIdent)?.ident
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
getKind<K extends Kind.Identifier>(kind: K): K
|
|
125
|
+
getKind<Name extends string>(kind: Name): Kind.Identifier<Name>
|
|
126
|
+
getKind(kindOrClass: LookupKey): Kind.Identifier
|
|
127
|
+
getKind(kindOrClass: string | Function): Kind.Identifier {
|
|
128
|
+
return this._getEntry(kindOrClass).ident
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
tryGetClass(refKey: RefKey.RefKey): Function | undefined
|
|
132
|
+
tryGetClass<F extends Function>(klass: F): F
|
|
133
|
+
tryGetClass(kind: string): Function | undefined
|
|
134
|
+
tryGetClass(ident: Kind.Identifier): Function | undefined
|
|
135
|
+
tryGetClass(kindOrIdent: LookupKey | RefKey.RefKey): Function | undefined {
|
|
136
|
+
return this._tryGetEntry(kindOrIdent)?.class
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
getClass(refKey: RefKey.RefKey): Function
|
|
140
|
+
getClass<F extends Function>(klass: F): F
|
|
141
|
+
getClass(kind: string): Function
|
|
142
|
+
getClass<T extends Function | string>(kindOrClass: T): T extends Function ? string : Function
|
|
143
|
+
getClass(kindOrClass: string | Function | RefKey.RefKey): Function | string {
|
|
144
|
+
return this._getEntry(kindOrClass).class
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
has(kindOrClass: LookupKey): boolean {
|
|
148
|
+
return this._entryMap.has(kindOrClass as any)
|
|
149
|
+
}
|
|
150
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { Embedder } from "../_embedder/base"
|
|
2
|
+
import { ResourceEntity } from "../graph/resource-node"
|
|
3
|
+
export interface ManifestMetadata {
|
|
4
|
+
labels: Record<string, string>
|
|
5
|
+
annotations: Record<string, string>
|
|
6
|
+
name: string
|
|
7
|
+
namespace?: string
|
|
8
|
+
}
|
|
9
|
+
export interface ManifestIdentFields {
|
|
10
|
+
kind: string
|
|
11
|
+
apiVersion: string
|
|
12
|
+
}
|
|
13
|
+
export interface BuilderInputTypes {
|
|
14
|
+
body: PreManifest
|
|
15
|
+
metadata?: ManifestMetadata
|
|
16
|
+
idents?: ManifestIdentFields
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export type JsonSerializable =
|
|
20
|
+
| string
|
|
21
|
+
| number
|
|
22
|
+
| boolean
|
|
23
|
+
| null
|
|
24
|
+
| JsonSerializable[]
|
|
25
|
+
| { [key: string]: JsonSerializable }
|
|
26
|
+
|
|
27
|
+
export interface PreManifest {
|
|
28
|
+
metadata?: {
|
|
29
|
+
name?: string
|
|
30
|
+
namespace?: string
|
|
31
|
+
annotations?: Record<string, string>
|
|
32
|
+
labels?: Record<string, string>
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
export interface BaseManifest {
|
|
36
|
+
[key: string]: JsonSerializable
|
|
37
|
+
[key: number]: never
|
|
38
|
+
apiVersion: string
|
|
39
|
+
kind: string
|
|
40
|
+
metadata: {
|
|
41
|
+
name: string
|
|
42
|
+
namespace?: string
|
|
43
|
+
labels?: Record<string, string>
|
|
44
|
+
annotations?: Record<string, string>
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export interface SpecManifest<T extends JsonSerializable> extends BaseManifest {
|
|
49
|
+
spec: T
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export const ManifestSourceEmbedder = new Embedder<object, ResourceEntity>("ManifestSource")
|
|
53
|
+
export * from "./manifest-builder"
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BaseManifest,
|
|
3
|
+
ManifestIdentFields,
|
|
4
|
+
ManifestMetadata,
|
|
5
|
+
ManifestSourceEmbedder,
|
|
6
|
+
PreManifest
|
|
7
|
+
} from "."
|
|
8
|
+
import { Embedder } from "../_embedder/base"
|
|
9
|
+
import { MetadataEntity } from "../graph/resource-node"
|
|
10
|
+
|
|
11
|
+
export namespace ManifestBuilder {
|
|
12
|
+
export interface Out {
|
|
13
|
+
body: () => PreManifest
|
|
14
|
+
metadata: () => ManifestMetadata
|
|
15
|
+
ident: () => ManifestIdentFields
|
|
16
|
+
manifest: () => BaseManifest
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export type In<Target extends MetadataEntity = MetadataEntity> = Partial<{
|
|
20
|
+
[K in keyof Out]: (self: Target) => ReturnType<Out[K]>
|
|
21
|
+
}> & {
|
|
22
|
+
body: (self: Target) => PreManifest
|
|
23
|
+
} & {
|
|
24
|
+
[key: string]: (self: Target, ...args: any[]) => any
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
class BuilderDecorator {
|
|
29
|
+
private _system = new Embedder<MetadataEntity, ManifestBuilder.In>("builder")
|
|
30
|
+
|
|
31
|
+
implement(
|
|
32
|
+
ctor: { new (...args: any[]): MetadataEntity },
|
|
33
|
+
input: ManifestBuilder.In<MetadataEntity>
|
|
34
|
+
) {
|
|
35
|
+
this._system.set(ctor.prototype, {
|
|
36
|
+
...input
|
|
37
|
+
})
|
|
38
|
+
}
|
|
39
|
+
private _metadata(self: MetadataEntity) {
|
|
40
|
+
return {
|
|
41
|
+
name: self.meta.get("name"),
|
|
42
|
+
namespace: self.meta.tryGet("namespace"),
|
|
43
|
+
labels: self.meta.labels,
|
|
44
|
+
annotations: self.meta.annotations
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
private _idents(self: MetadataEntity) {
|
|
49
|
+
return {
|
|
50
|
+
apiVersion: self.kind.parent!.text,
|
|
51
|
+
kind: self.kind.name
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
manifest(trait: ManifestBuilder.Out, self: MetadataEntity) {
|
|
56
|
+
const mani = {
|
|
57
|
+
...trait.ident(),
|
|
58
|
+
metadata: trait.metadata(),
|
|
59
|
+
...trait.body()
|
|
60
|
+
}
|
|
61
|
+
ManifestSourceEmbedder.set(mani, self)
|
|
62
|
+
return mani
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
idents(self: MetadataEntity) {
|
|
66
|
+
return {
|
|
67
|
+
kind: self.kind.name,
|
|
68
|
+
apiVersion: self.kind.parent!.text
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
get(target: MetadataEntity): ManifestBuilder.Out {
|
|
72
|
+
const input = this._system.get(target)
|
|
73
|
+
const o: ManifestBuilder.Out = {
|
|
74
|
+
ident: () => input.ident?.call(o, target) ?? this._idents(target),
|
|
75
|
+
metadata: () => input.metadata?.call(o, target) ?? this._metadata(target),
|
|
76
|
+
body: () => input.body.call(o, target),
|
|
77
|
+
manifest: () => this.manifest(o, target) as any
|
|
78
|
+
}
|
|
79
|
+
return o
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
get decorator() {
|
|
83
|
+
return <Target extends new (...args: any[]) => MetadataEntity>(
|
|
84
|
+
input: ManifestBuilder.In<InstanceType<Target>>
|
|
85
|
+
) => {
|
|
86
|
+
return (ctor: Target) => {
|
|
87
|
+
this.implement(ctor, input as any)
|
|
88
|
+
return ctor
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export const Builder = new BuilderDecorator()
|
|
95
|
+
|
|
96
|
+
export const manifest = Builder.decorator
|
|
97
|
+
|
|
98
|
+
// writing the decorator itself
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { PortSet } from "./set"
|
|
2
|
+
import type { InputPortSetRecord } from "./types"
|
|
3
|
+
export { PortMap } from "./map"
|
|
4
|
+
export { PortSet } from "./set"
|
|
5
|
+
export { InputPortMapping, InputPortSetRecord, PortMapEntry, PortSetEntry } from "./types"
|
|
6
|
+
export function ports<Names extends string>(input: InputPortSetRecord<Names>): PortSet<Names> {
|
|
7
|
+
return PortSet.make(input)
|
|
8
|
+
}
|
package/src/ports/map.ts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { Map } from "immutable"
|
|
2
|
+
import { PortError } from "./error"
|
|
3
|
+
import type { PortMapEntry } from "./types"
|
|
4
|
+
export class PortMap<Names extends string> {
|
|
5
|
+
constructor(private readonly _map: Map<string, PortMapEntry>) {}
|
|
6
|
+
|
|
7
|
+
private _apply(f: (map: Map<string, PortMapEntry>) => Map<string, PortMapEntry>): PortMap<any> {
|
|
8
|
+
return new PortMap(f(this._map))
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
pick<InNames extends Names>(...name: InNames[]): PortMap<InNames> {
|
|
12
|
+
return this._apply(map => map.filter((_, key) => name.includes(key as InNames)))
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
get values() {
|
|
16
|
+
return this._map
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
map(mapping: Record<Names, number>): PortMap<Names> {
|
|
20
|
+
return new PortMap(
|
|
21
|
+
this._map.map(entry => {
|
|
22
|
+
return {
|
|
23
|
+
...entry,
|
|
24
|
+
source: entry.target,
|
|
25
|
+
target: mapping[entry.name as keyof typeof mapping]
|
|
26
|
+
}
|
|
27
|
+
})
|
|
28
|
+
)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
get(name: Names): PortMapEntry {
|
|
32
|
+
if (!this._map.has(name)) {
|
|
33
|
+
throw new PortError(`Port ${name} not found`)
|
|
34
|
+
}
|
|
35
|
+
return this._map.get(name) as PortMapEntry
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
toMap() {
|
|
39
|
+
return this._map
|
|
40
|
+
}
|
|
41
|
+
}
|
package/src/ports/set.ts
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { Map } from "immutable"
|
|
2
|
+
import { PortError } from "./error"
|
|
3
|
+
import { PortMap } from "./map"
|
|
4
|
+
import { parsePortInput, portRecordInput } from "./tools/entry"
|
|
5
|
+
import type {
|
|
6
|
+
InputPort,
|
|
7
|
+
InputPortMapping,
|
|
8
|
+
InputPortSetEntry,
|
|
9
|
+
InputPortSetRecord,
|
|
10
|
+
InputProtocol,
|
|
11
|
+
PortSetEntry
|
|
12
|
+
} from "./types"
|
|
13
|
+
|
|
14
|
+
declare const __NAMES__: unique symbol
|
|
15
|
+
export class PortSet<Names extends string = never> {
|
|
16
|
+
constructor(private readonly _map: Map<Names, PortSetEntry> = Map()) {}
|
|
17
|
+
|
|
18
|
+
private _apply(f: (map: Map<string, PortSetEntry>) => Map<string, PortSetEntry>) {
|
|
19
|
+
return new PortSet(f(this._map))
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
union<InNames extends string>(other: PortSet<InNames>): PortSet<Names | InNames> {
|
|
23
|
+
return new PortSet(this._map.merge(other._map))
|
|
24
|
+
}
|
|
25
|
+
add<Name extends string>(
|
|
26
|
+
name: Name,
|
|
27
|
+
port: InputPort,
|
|
28
|
+
protocol: InputProtocol
|
|
29
|
+
): PortSet<Names | Name>
|
|
30
|
+
add<Name extends string>(name: Name, entry: InputPortSetEntry): PortSet<Names | Name>
|
|
31
|
+
add<InNames extends string>(input: InputPortSetRecord<InNames>): PortSet<Names | InNames>
|
|
32
|
+
add(a: any, b?: any, c?: any): any {
|
|
33
|
+
if (c) {
|
|
34
|
+
return this._apply(map => map.set(a, { name: a, port: +b, protocol: c.toUpperCase() }))
|
|
35
|
+
}
|
|
36
|
+
if (b) {
|
|
37
|
+
return this._apply(map => map.set(a, parsePortInput(a, b)))
|
|
38
|
+
}
|
|
39
|
+
return this._apply(map => {
|
|
40
|
+
const processed = portRecordInput(a)
|
|
41
|
+
return map.merge(processed)
|
|
42
|
+
})
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
pick<InNames extends Names>(...name: InNames[]): PortSet<InNames> {
|
|
46
|
+
return this._apply(map => map.filter((_, key) => name.includes(key as InNames))) as any
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
get(name: Names): PortSetEntry {
|
|
50
|
+
if (!this._map.has(name)) {
|
|
51
|
+
throw new PortError(`Port ${name} not found`)
|
|
52
|
+
}
|
|
53
|
+
return this._map.get(name)!
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
get values() {
|
|
57
|
+
return this._map
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
map(mapping: InputPortMapping<Names>): PortMap<Names> {
|
|
61
|
+
return new PortMap(
|
|
62
|
+
this._map.map(entry => {
|
|
63
|
+
if (!(entry.name in mapping)) {
|
|
64
|
+
throw new PortError(`Port ${entry.name} not found in mapping`)
|
|
65
|
+
}
|
|
66
|
+
return {
|
|
67
|
+
name: entry.name,
|
|
68
|
+
protocol: entry.protocol,
|
|
69
|
+
source: entry.port,
|
|
70
|
+
target: mapping[entry.name as keyof typeof mapping]
|
|
71
|
+
}
|
|
72
|
+
})
|
|
73
|
+
)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
static make<Names extends string>(input: InputPortSetRecord<Names>) {
|
|
77
|
+
return new PortSet().add(input)
|
|
78
|
+
}
|
|
79
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { Map } from "immutable"
|
|
2
|
+
import { PortSet } from "../set"
|
|
3
|
+
import type {
|
|
4
|
+
InputPortSetEntry,
|
|
5
|
+
InputPortSetRecord,
|
|
6
|
+
InputPortSetSpec,
|
|
7
|
+
PortSetEntry,
|
|
8
|
+
Protocol
|
|
9
|
+
} from "../types"
|
|
10
|
+
import { parsePortSpec } from "./parse"
|
|
11
|
+
|
|
12
|
+
function portSetEntry(name: string, value: InputPortSetEntry): PortSetEntry {
|
|
13
|
+
return {
|
|
14
|
+
name,
|
|
15
|
+
port: value.port,
|
|
16
|
+
protocol: value.protocol.toUpperCase() as Protocol
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function parsePortInput(name: string, input: InputPortSetSpec): PortSetEntry {
|
|
21
|
+
if (typeof input === "string") {
|
|
22
|
+
return portSetEntry(name, parsePortSpec(name, input))
|
|
23
|
+
}
|
|
24
|
+
if (typeof input === "number") {
|
|
25
|
+
return portSetEntry(name, {
|
|
26
|
+
port: input,
|
|
27
|
+
protocol: "TCP" as const
|
|
28
|
+
})
|
|
29
|
+
}
|
|
30
|
+
return portSetEntry(name, input)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function portRecordInput(
|
|
34
|
+
record: InputPortSetRecord<string> | PortSet<string>
|
|
35
|
+
): Map<string, PortSetEntry> {
|
|
36
|
+
if (record instanceof PortSet) {
|
|
37
|
+
return record.values
|
|
38
|
+
}
|
|
39
|
+
const inputMap = Map(record)
|
|
40
|
+
return inputMap
|
|
41
|
+
.map((v, k) => parsePortInput(k, v))
|
|
42
|
+
.map((value, key) => portSetEntry(key, value))
|
|
43
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { anyStringOf, int, string } from "parjs"
|
|
2
|
+
import { map, maybe, must, qthen, then } from "parjs/combinators"
|
|
3
|
+
import { PortError } from "../error"
|
|
4
|
+
import type { InputPortSetEntry, Protocol } from "../types"
|
|
5
|
+
|
|
6
|
+
function validatePort(port: number) {
|
|
7
|
+
if (port < 0 || port > 65535) {
|
|
8
|
+
return {
|
|
9
|
+
kind: "Hard" as const,
|
|
10
|
+
message: "Port must be between 0 and 65535"
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
return true
|
|
14
|
+
}
|
|
15
|
+
const pProtocol = anyStringOf("tcp", "udp", "TCP", "UDP").pipe(
|
|
16
|
+
map(s => s.toUpperCase() as Protocol)
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
const pPort = int().pipe(must(validatePort))
|
|
20
|
+
const pProtocolPart = string("/").pipe(qthen(pProtocol), maybe("TCP"))
|
|
21
|
+
const pPortSpec = pPort.pipe(
|
|
22
|
+
then(pProtocolPart),
|
|
23
|
+
map(arr => {
|
|
24
|
+
const [port, protocol] = arr
|
|
25
|
+
return {
|
|
26
|
+
port,
|
|
27
|
+
protocol: protocol?.toUpperCase() ?? "TCP"
|
|
28
|
+
} as InputPortSetEntry
|
|
29
|
+
})
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
export function parsePortSpec(name: string, input: string) {
|
|
33
|
+
const result = pPortSpec.parse(input)
|
|
34
|
+
if (result.kind === "OK") {
|
|
35
|
+
return result.value
|
|
36
|
+
}
|
|
37
|
+
throw new PortError(name, {
|
|
38
|
+
parseError: result.reason
|
|
39
|
+
})
|
|
40
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export interface PortSpecObj {
|
|
2
|
+
port: Port
|
|
3
|
+
protocol: Protocol
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export type Port = number
|
|
7
|
+
export type InputPort = Port | `${Port}`
|
|
8
|
+
export type InputProtocol = Protocol | Lowercase<Protocol>
|
|
9
|
+
export type Protocol = "TCP" | "UDP"
|
|
10
|
+
export type InputPortProto = `${Port}/${InputProtocol}`
|
|
11
|
+
export interface PortMapEntry {
|
|
12
|
+
name: string
|
|
13
|
+
protocol: Protocol
|
|
14
|
+
source: number
|
|
15
|
+
target: number
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface PortSetEntry {
|
|
19
|
+
name: string
|
|
20
|
+
port: number
|
|
21
|
+
protocol: Protocol
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface InputPortSetEntry {
|
|
25
|
+
port: Port
|
|
26
|
+
protocol: InputProtocol
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export type InputPortSetSpec = InputPortSetEntry | InputPort | InputPortProto
|
|
30
|
+
|
|
31
|
+
export interface InputPortMapEntry {
|
|
32
|
+
source: Port
|
|
33
|
+
target: Port
|
|
34
|
+
protocol: InputProtocol
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export type InputPortSetRecord<Names extends string = string> = {
|
|
38
|
+
[K in Names]: InputPortSetSpec
|
|
39
|
+
}
|
|
40
|
+
export type InputPortMapping<Names extends string = string> = {
|
|
41
|
+
[K in Names]: number
|
|
42
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./producer"
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export type Producer<Factory extends object, Thing extends object> = Producer.Producer<
|
|
2
|
+
Factory,
|
|
3
|
+
Thing
|
|
4
|
+
>
|
|
5
|
+
export namespace Producer {
|
|
6
|
+
export type Producer<Factory extends object, Produced extends object> = (
|
|
7
|
+
factory: Factory
|
|
8
|
+
) => Iterable<Produced>
|
|
9
|
+
|
|
10
|
+
export function map<Factory extends object, Produced extends object, NewInput extends object>(
|
|
11
|
+
producer: Producer<Factory, Produced>,
|
|
12
|
+
projection: (input: NewInput) => Factory
|
|
13
|
+
) {
|
|
14
|
+
return function bound_producer(input: NewInput) {
|
|
15
|
+
return producer(projection(input))
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./ref-key"
|