@toa.io/definitions 1.0.0-alpha.288 → 1.0.0-alpha.293

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 (141) hide show
  1. package/LICENSE +22 -0
  2. package/digest/extensions.configuration.json +1 -1
  3. package/digest/extensions.exposition.json +1 -1
  4. package/digest/extensions.introspection.json +1 -1
  5. package/digest/extensions.realtime.json +1 -1
  6. package/package.json +27 -9
  7. package/readme.md +1 -0
  8. package/transpiled/bridges.node/exports.js +25 -2
  9. package/transpiled/bridges.node/exports.js.map +1 -1
  10. package/transpiled/digest/generate.js +23 -3
  11. package/transpiled/digest/generate.js.map +1 -1
  12. package/transpiled/digest/read.d.ts +8 -0
  13. package/transpiled/digest/read.js +11 -0
  14. package/transpiled/digest/read.js.map +1 -1
  15. package/transpiled/extensions.exposition/index.d.ts +1 -0
  16. package/transpiled/extensions.exposition/index.js +1 -0
  17. package/transpiled/extensions.exposition/index.js.map +1 -1
  18. package/transpiled/extensions.exposition/packages.d.ts +11 -0
  19. package/transpiled/extensions.exposition/packages.js +17 -0
  20. package/transpiled/extensions.exposition/packages.js.map +1 -0
  21. package/transpiled/extensions.storages/index.d.ts +1 -0
  22. package/transpiled/extensions.storages/index.js +1 -0
  23. package/transpiled/extensions.storages/index.js.map +1 -1
  24. package/transpiled/extensions.storages/packages.d.ts +19 -0
  25. package/transpiled/extensions.storages/packages.js +41 -0
  26. package/transpiled/extensions.storages/packages.js.map +1 -0
  27. package/source/bindings.amqp/annotation.ts +0 -26
  28. package/source/bindings.amqp/context.ts +0 -68
  29. package/source/bindings.amqp/deployment.ts +0 -14
  30. package/source/bindings.amqp/index.ts +0 -9
  31. package/source/bindings.amqp/instance.ts +0 -3
  32. package/source/bindings.amqp/sources.ts +0 -39
  33. package/source/bindings.loop/index.ts +0 -3
  34. package/source/bridges.bash/const.ts +0 -2
  35. package/source/bridges.bash/define.ts +0 -38
  36. package/source/bridges.bash/index.ts +0 -2
  37. package/source/bridges.node/define.ts +0 -69
  38. package/source/bridges.node/exports.ts +0 -175
  39. package/source/bridges.node/index.ts +0 -6
  40. package/source/bridges.node/operations.ts +0 -127
  41. package/source/bridges.node/sources.ts +0 -44
  42. package/source/definition.ts +0 -38
  43. package/source/digest/generate.ts +0 -77
  44. package/source/digest/read.ts +0 -39
  45. package/source/extensions.cadence/components.ts +0 -6
  46. package/source/extensions.cadence/const.ts +0 -31
  47. package/source/extensions.cadence/context.ts +0 -10
  48. package/source/extensions.cadence/deployment.ts +0 -37
  49. package/source/extensions.cadence/index.ts +0 -8
  50. package/source/extensions.cadence/manifest.ts +0 -64
  51. package/source/extensions.cadence/schemas.ts +0 -10
  52. package/source/extensions.cadence/types.ts +0 -41
  53. package/source/extensions.configuration/components.ts +0 -6
  54. package/source/extensions.configuration/const.ts +0 -30
  55. package/source/extensions.configuration/context.ts +0 -13
  56. package/source/extensions.configuration/deployment.ts +0 -159
  57. package/source/extensions.configuration/epoch.ts +0 -22
  58. package/source/extensions.configuration/index.ts +0 -10
  59. package/source/extensions.configuration/manifest.ts +0 -12
  60. package/source/extensions.configuration/schemas.ts +0 -9
  61. package/source/extensions.exposition/Annotation.ts +0 -91
  62. package/source/extensions.exposition/components.ts +0 -6
  63. package/source/extensions.exposition/const.ts +0 -45
  64. package/source/extensions.exposition/deployment.ts +0 -95
  65. package/source/extensions.exposition/index.ts +0 -16
  66. package/source/extensions.exposition/manifest.ts +0 -56
  67. package/source/extensions.exposition/schemas.ts +0 -16
  68. package/source/extensions.exposition/shortcuts.ts +0 -14
  69. package/source/extensions.exposition/syntax/index.ts +0 -2
  70. package/source/extensions.exposition/syntax/parse.ts +0 -171
  71. package/source/extensions.exposition/syntax/types.ts +0 -69
  72. package/source/extensions.fetch/context.ts +0 -10
  73. package/source/extensions.fetch/index.ts +0 -1
  74. package/source/extensions.introspection/annotation.ts +0 -87
  75. package/source/extensions.introspection/components.ts +0 -13
  76. package/source/extensions.introspection/const.ts +0 -46
  77. package/source/extensions.introspection/deployment.ts +0 -48
  78. package/source/extensions.introspection/index.ts +0 -6
  79. package/source/extensions.introspection/manifest.ts +0 -18
  80. package/source/extensions.introspection/schemas.ts +0 -12
  81. package/source/extensions.realtime/components.ts +0 -5
  82. package/source/extensions.realtime/deployment.ts +0 -89
  83. package/source/extensions.realtime/index.ts +0 -4
  84. package/source/extensions.stash/context.ts +0 -10
  85. package/source/extensions.stash/deployment.ts +0 -22
  86. package/source/extensions.stash/index.ts +0 -2
  87. package/source/extensions.state/context.ts +0 -9
  88. package/source/extensions.state/index.ts +0 -1
  89. package/source/extensions.storages/Annotation.ts +0 -57
  90. package/source/extensions.storages/context.ts +0 -14
  91. package/source/extensions.storages/deployment.ts +0 -91
  92. package/source/extensions.storages/index.ts +0 -9
  93. package/source/extensions.storages/manifest.ts +0 -7
  94. package/source/extensions.storages/schemas.ts +0 -15
  95. package/source/extensions.storages/secrets.ts +0 -22
  96. package/source/extensions.telemetry/const.ts +0 -6
  97. package/source/extensions.telemetry/context.ts +0 -11
  98. package/source/extensions.telemetry/deployment.ts +0 -91
  99. package/source/extensions.telemetry/index.ts +0 -5
  100. package/source/extensions.telemetry/ready.ts +0 -33
  101. package/source/index.ts +0 -2
  102. package/source/storages.mongodb/deployment.ts +0 -22
  103. package/source/storages.mongodb/index.ts +0 -1
  104. package/source/version.ts +0 -10
  105. package/transpiled/bindings.amqp/annotation.test.d.ts +0 -1
  106. package/transpiled/bindings.amqp/annotation.test.js +0 -36
  107. package/transpiled/bindings.amqp/annotation.test.js.map +0 -1
  108. package/transpiled/bindings.amqp/properties.test.d.ts +0 -1
  109. package/transpiled/bindings.amqp/properties.test.js +0 -7
  110. package/transpiled/bindings.amqp/properties.test.js.map +0 -1
  111. package/transpiled/bindings.loop/properties.test.d.ts +0 -1
  112. package/transpiled/bindings.loop/properties.test.js +0 -7
  113. package/transpiled/bindings.loop/properties.test.js.map +0 -1
  114. package/transpiled/bridges.node/exports.test.d.ts +0 -1
  115. package/transpiled/bridges.node/exports.test.js +0 -88
  116. package/transpiled/bridges.node/exports.test.js.map +0 -1
  117. package/transpiled/bridges.node/operations.test.d.ts +0 -1
  118. package/transpiled/bridges.node/operations.test.js +0 -108
  119. package/transpiled/bridges.node/operations.test.js.map +0 -1
  120. package/transpiled/extensions.cadence/manifest.test.d.ts +0 -1
  121. package/transpiled/extensions.cadence/manifest.test.js +0 -41
  122. package/transpiled/extensions.cadence/manifest.test.js.map +0 -1
  123. package/transpiled/extensions.configuration/deployment.test.d.ts +0 -1
  124. package/transpiled/extensions.configuration/deployment.test.js +0 -74
  125. package/transpiled/extensions.configuration/deployment.test.js.map +0 -1
  126. package/transpiled/extensions.configuration/manifest.test.d.ts +0 -1
  127. package/transpiled/extensions.configuration/manifest.test.js +0 -14
  128. package/transpiled/extensions.configuration/manifest.test.js.map +0 -1
  129. package/transpiled/extensions.exposition/manifest.test.d.ts +0 -1
  130. package/transpiled/extensions.exposition/manifest.test.js +0 -38
  131. package/transpiled/extensions.exposition/manifest.test.js.map +0 -1
  132. package/transpiled/extensions.exposition/schemas.test.d.ts +0 -1
  133. package/transpiled/extensions.exposition/schemas.test.js +0 -22
  134. package/transpiled/extensions.exposition/schemas.test.js.map +0 -1
  135. package/transpiled/extensions.exposition/syntax/parse.test.d.ts +0 -1
  136. package/transpiled/extensions.exposition/syntax/parse.test.js +0 -156
  137. package/transpiled/extensions.exposition/syntax/parse.test.js.map +0 -1
  138. package/transpiled/extensions.storages/schemas.test.d.ts +0 -1
  139. package/transpiled/extensions.storages/schemas.test.js +0 -59
  140. package/transpiled/extensions.storages/schemas.test.js.map +0 -1
  141. package/tsconfig.json +0 -10
@@ -1,39 +0,0 @@
1
- import { createVariables, type Request } from '@toa.io/pointer'
2
- import { type Manifest } from '@toa.io/norm'
3
- import { type Dependency } from '@toa.io/operations'
4
- import { type Instance } from './instance.js'
5
- import { type Annotation } from './annotation.js'
6
-
7
- export function createDependency(sources: Sources, instances: Instance[]): Dependency {
8
- const requests = []
9
-
10
- for (const instance of instances) {
11
- const request = createRequest(instance)
12
-
13
- if (request !== null) requests.push(request)
14
- }
15
-
16
- const variables = createVariables(ID, sources, requests)
17
-
18
- return { variables }
19
- }
20
-
21
- function createRequest(instance: Instance): Request | null {
22
- const group = instance.locator.label
23
- const selectors = createSelectors(instance.component)
24
-
25
- if (selectors === null) return null
26
- else return { group, selectors }
27
- }
28
-
29
- function createSelectors(component: Manifest): string[] | null {
30
- if (component.receivers === undefined) return null
31
-
32
- const sources = Object.values(component.receivers).map((receiver) => receiver.source)
33
-
34
- return sources.filter((source) => source !== undefined) as string[]
35
- }
36
-
37
- export const ID = 'amqp-sources'
38
-
39
- type Sources = Annotation['sources']
@@ -1,3 +0,0 @@
1
- import type { bindings } from '@toa.io/core/types'
2
-
3
- export const properties: bindings.Properties = { async: false, local: true }
@@ -1,2 +0,0 @@
1
- export const DIR = 'operations'
2
- export const EXT = '.sh'
@@ -1,38 +0,0 @@
1
- import * as fs from 'node:fs/promises'
2
- import { join, extname } from 'node:path'
3
- import { DIR, EXT } from './const.js'
4
- import type { component } from '@toa.io/norm'
5
-
6
- export async function operations(root: string): Promise<component.Operations> {
7
- const path = join(root, DIR)
8
- const names = await list(path)
9
-
10
- const promises = names.map(async (name) => operation(root, name))
11
-
12
- const operations = await Promise.all(promises)
13
-
14
- return operations.reduce<component.Operations>((acc, operation, index) => {
15
- acc[names[index]] = operation
16
-
17
- return acc
18
- }, {})
19
- }
20
-
21
- export async function operation(
22
- root: string,
23
- name: string
24
- ): Promise<component.Operation> {
25
- const path = join(root, DIR, name + EXT)
26
-
27
- await fs.access(path, fs.constants.F_OK)
28
-
29
- return { type: 'computation' }
30
- }
31
-
32
- async function list(path: string): Promise<string[]> {
33
- const files = await fs.readdir(path)
34
-
35
- return files
36
- .filter((file) => extname(file) === EXT)
37
- .map((file) => file.slice(0, -EXT.length))
38
- }
@@ -1,2 +0,0 @@
1
- export * as define from './define.js'
2
- export { DIR, EXT } from './const.js'
@@ -1,69 +0,0 @@
1
- import { readFile } from 'node:fs/promises'
2
- import { sources } from './sources.js'
3
- import { exports, type Exports } from './exports.js'
4
- import { algorithm, type Definition } from './operations.js'
5
-
6
- /**
7
- * What a component's modules declare, read from their source and never by importing them: a
8
- * deploy reads a component whose dependencies are not installed, and a booting process reads
9
- * the same, so the two cannot disagree.
10
- */
11
- export async function operations(root: string): Promise<Record<string, Definition>> {
12
- const algorithms: Record<string, Definition> = {}
13
-
14
- for (const [name, exported, path] of await read(root, 'operations')) {
15
- const definition = algorithm(exported, path)
16
-
17
- if (definition !== null) algorithms[name] = definition
18
- }
19
-
20
- return algorithms
21
- }
22
-
23
- export async function events(root: string): Promise<Record<string, Event>> {
24
- const events: Record<string, Event> = {}
25
-
26
- for (const [name, exported] of await read(root, 'events'))
27
- events[name] = { conditioned: exported.has('condition'), subjective: exported.has('payload') }
28
-
29
- return events
30
- }
31
-
32
- export async function receivers(root: string): Promise<Record<string, Receiver>> {
33
- const receivers: Record<string, Receiver> = {}
34
-
35
- for (const [name, exported] of await read(root, 'receivers'))
36
- receivers[name] = { conditioned: exported.has('condition'), adaptive: exported.has('request') }
37
-
38
- return receivers
39
- }
40
-
41
- export async function guards(root: string): Promise<Record<string, object>> {
42
- const guards: Record<string, object> = {}
43
-
44
- for (const [name, exported] of await read(root, 'guards')) if (exported.has('guard')) guards[name] = {}
45
-
46
- return guards
47
- }
48
-
49
- async function read(root: string, directory: string): Promise<Array<[string, Exports, string]>> {
50
- const modules = await sources(root, directory)
51
-
52
- return Promise.all(
53
- [...modules].map(async ([name, path]): Promise<[string, Exports, string]> => [
54
- name,
55
- exports(path, await readFile(path, 'utf8')),
56
- path
57
- ])
58
- )
59
- }
60
-
61
- export interface Event {
62
- conditioned: boolean
63
- subjective: boolean
64
- }
65
-
66
- export interface Receiver {
67
- conditioned: boolean
68
- adaptive: boolean
69
- }
@@ -1,175 +0,0 @@
1
- import { parseSync } from 'oxc-parser'
2
-
3
- /**
4
- * What a module exports, read from its source: the name, and what the value is declared as.
5
- * Nothing is imported, so what a module depends on need not be installed to read it.
6
- */
7
- export function exports(path: string, text: string): Exports {
8
- const { program, errors } = parseSync(path, text)
9
-
10
- if (errors.length > 0) throw new Error(`${path}: ${errors[0].message}`)
11
-
12
- const locals = declarations(program.body)
13
- const exported: Exports = new Map()
14
-
15
- for (const node of program.body) {
16
- if (node.type === 'ExportNamedDeclaration') named(node, locals, exported)
17
- else if (node.type === 'ExportDefaultDeclaration')
18
- exported.set('default', binding(node.declaration, locals))
19
- else if (node.type === 'ExpressionStatement') assigned(node.expression, locals, exported)
20
- }
21
-
22
- return exported
23
- }
24
-
25
- export type Exports = Map<string, Binding>
26
-
27
- export interface Binding {
28
- /** what the value is declared as, or `other` where it is computed rather than written */
29
- kind: 'function' | 'class' | 'other'
30
- /** the name a function or class is declared with, which a default export is known by */
31
- declared?: string
32
- /** the parameters' names, `undefined` for one that is not a plain identifier */
33
- params?: Array<string | undefined>
34
- /** a class's methods with their parameters */
35
- methods?: Record<string, Array<string | undefined>>
36
- }
37
-
38
- function named(node: any, locals: Locals, exported: Exports): void {
39
- if (node.exportKind === 'type') return
40
-
41
- const declaration = node.declaration
42
-
43
- if (declaration !== null && declaration !== undefined)
44
- for (const [name, bound] of declared(declaration)) exported.set(name, bound)
45
-
46
- for (const specifier of node.specifiers ?? []) {
47
- if (specifier.exportKind === 'type') return
48
-
49
- exported.set(name(specifier.exported), binding(specifier.local, locals))
50
- }
51
- }
52
-
53
- /** `module.exports = { … }`, `module.exports.x = …` and `exports.x = …` */
54
- function assigned(expression: any, locals: Locals, exported: Exports): void {
55
- if (expression.type !== 'AssignmentExpression' || expression.operator !== '=') return
56
-
57
- const target = expression.left
58
-
59
- if (target.type !== 'MemberExpression') return
60
-
61
- if (isModuleExports(target)) {
62
- if (expression.right.type === 'ObjectExpression')
63
- properties(expression.right, locals, exported)
64
-
65
- return
66
- }
67
-
68
- const object = target.object
69
-
70
- if (isModuleExports(object) || (object.type === 'Identifier' && object.name === 'exports'))
71
- exported.set(name(target.property), binding(expression.right, locals))
72
- }
73
-
74
- /** `{ computation, condition: () => … }` — each property is an export. */
75
- function properties(object: any, locals: Locals, exported: Exports): void {
76
- for (const property of object.properties) {
77
- if (property.type !== 'Property') continue
78
-
79
- exported.set(name(property.key), binding(property.value, locals))
80
- }
81
- }
82
-
83
- function isModuleExports(node: any): boolean {
84
- return (
85
- node.type === 'MemberExpression' &&
86
- node.object.type === 'Identifier' &&
87
- node.object.name === 'module' &&
88
- name(node.property) === 'exports'
89
- )
90
- }
91
-
92
- /** Every top-level declaration, which a specifier or a shorthand property refers to by name. */
93
- function declarations(body: any[]): Locals {
94
- const locals: Locals = new Map()
95
-
96
- for (const node of body) {
97
- const declaration =
98
- node.type === 'ExportNamedDeclaration' ? node.declaration : node
99
-
100
- if (declaration === null || declaration === undefined) continue
101
-
102
- for (const [name, bound] of declared(declaration)) locals.set(name, bound)
103
- }
104
-
105
- return locals
106
- }
107
-
108
- function declared(node: any): Array<[string, Binding]> {
109
- switch (node.type) {
110
- case 'FunctionDeclaration':
111
- case 'ClassDeclaration':
112
- return node.id === null ? [] : [[node.id.name, binding(node)]]
113
- case 'VariableDeclaration':
114
- return node.declarations
115
- .filter((declarator: any) => declarator.id.type === 'Identifier')
116
- .map((declarator: any) => [
117
- declarator.id.name,
118
- declarator.init === null ? OTHER : binding(declarator.init)
119
- ])
120
- default:
121
- return []
122
- }
123
- }
124
-
125
- function binding(node: any, locals?: Locals): Binding {
126
- switch (node.type) {
127
- case 'FunctionDeclaration':
128
- case 'FunctionExpression':
129
- case 'ArrowFunctionExpression':
130
- return { kind: 'function', declared: node.id?.name, params: parameters(node.params) }
131
- case 'ClassDeclaration':
132
- case 'ClassExpression':
133
- return { kind: 'class', declared: node.id?.name, methods: methods(node.body.body) }
134
- case 'Identifier':
135
- return locals?.get(node.name) ?? OTHER
136
- default:
137
- return OTHER
138
- }
139
- }
140
-
141
- function methods(body: any[]): Record<string, Array<string | undefined>> {
142
- const methods: Record<string, Array<string | undefined>> = {}
143
-
144
- for (const member of body) {
145
- if (member.key === undefined || member.key.type === 'PrivateIdentifier') continue
146
-
147
- if (member.type === 'MethodDefinition') methods[name(member.key)] = parameters(member.value.params)
148
- else if (
149
- member.type === 'PropertyDefinition' &&
150
- member.value !== null &&
151
- (member.value.type === 'ArrowFunctionExpression' ||
152
- member.value.type === 'FunctionExpression')
153
- )
154
- methods[name(member.key)] = parameters(member.value.params)
155
- }
156
-
157
- return methods
158
- }
159
-
160
- /** A name is what is read: a pattern, a rest or a `this` annotation is not a name. */
161
- function parameters(params: any[]): Array<string | undefined> {
162
- return params.map((param) => {
163
- const pattern = param.type === 'AssignmentPattern' ? param.left : param
164
-
165
- return pattern.type === 'Identifier' ? pattern.name : undefined
166
- })
167
- }
168
-
169
- function name(key: any): string {
170
- return key.type === 'Identifier' ? key.name : String(key.value)
171
- }
172
-
173
- type Locals = Map<string, Binding>
174
-
175
- const OTHER: Binding = { kind: 'other' }
@@ -1,6 +0,0 @@
1
- export * as define from './define.js'
2
- export { exports } from './exports.js'
3
- export { algorithm, TYPES } from './operations.js'
4
-
5
- export type { Binding, Exports } from './exports.js'
6
- export type { Definition } from './operations.js'
@@ -1,127 +0,0 @@
1
- import type { Binding, Exports } from './exports.js'
2
-
3
- /**
4
- * What an algorithm module declares, by the conventions the bridge reads a module by: the
5
- * exported name is the type, the second parameter's name is the scope. `null` where the module
6
- * exports no algorithm.
7
- */
8
- export function algorithm(exported: Exports, path: string): Definition | null {
9
- const entry = find(exported, path)
10
-
11
- if (entry === null) return null
12
-
13
- const [name, bound] = entry
14
-
15
- if (FACTORY.test(name)) return factory(name, bound, path)
16
- if (CLASSES.has(name)) return klass(name, bound, path)
17
- if (TYPES.has(name)) return func(name, bound)
18
-
19
- throw new Error(`${path}: exported '${name}' does not match conventions`)
20
- }
21
-
22
- export interface Definition {
23
- type: string
24
- scope?: string
25
- input?: null
26
- }
27
-
28
- /**
29
- * A module names its algorithm by exporting it, and it exports one. What a value is cannot
30
- * always be read from its source — `export const computation = wrap(fn)` — so a name written the
31
- * way an algorithm's is counts, whatever it is bound to.
32
- */
33
- function find(exported: Exports, path: string): [string, Binding] | null {
34
- const candidates = [...exported].filter(
35
- ([name, bound]) => name !== '__esModule' && (bound.kind !== 'other' || conventional(name))
36
- )
37
-
38
- if (candidates.length === 0) return null
39
-
40
- if (candidates.length === 1) return resolve(candidates[0])
41
-
42
- const named = candidates.filter(([name]) => name !== 'default')
43
-
44
- if (named.length === 1) return named[0]
45
-
46
- throw new Error(
47
- `${path}: a module must export one algorithm, and this one exports ` +
48
- named.map(([name]) => `'${name}'`).join(', ')
49
- )
50
- }
51
-
52
- /** `export default function transition` says its name in the function itself. */
53
- function resolve([name, bound]: [string, Binding]): [string, Binding] {
54
- return name === 'default' ? [bound.declared ?? '', bound] : [name, bound]
55
- }
56
-
57
- function conventional(name: string): boolean {
58
- return TYPES.has(name) || CLASSES.has(name) || FACTORY.test(name)
59
- }
60
-
61
- function func(type: string, bound: Binding): Definition {
62
- const definition: Definition = { type }
63
-
64
- // computed rather than written: the scope is the manifest's to declare
65
- if (bound.kind === 'other') return definition
66
-
67
- if (bound.kind !== 'function' || bound.params === undefined)
68
- throw new Error(`Exported '${type}' does not match conventions`)
69
-
70
- return signature(definition, bound.params)
71
- }
72
-
73
- function klass(name: string, bound: Binding, path: string): Definition {
74
- if (bound.kind !== 'class') throw new Error(`${path}: '${name}' does not match conventions`)
75
-
76
- const params = bound.methods?.execute
77
-
78
- if (params === undefined) throw new Error(`${path}: Method 'execute' not found in '${name}'`)
79
-
80
- return signature({ type: name.toLowerCase() }, params)
81
- }
82
-
83
- function factory(name: string, bound: Binding, path: string): Definition {
84
- if (bound.kind !== 'class') throw new Error(`${path}: '${name}' does not match conventions`)
85
-
86
- const match = name.match(FACTORY)!
87
- const definition: Definition = { type: match.groups!.type.toLowerCase() }
88
- const scope = match.groups!.scope?.toLowerCase()
89
-
90
- if (scope !== undefined) definition.scope = scope
91
-
92
- return definition
93
- }
94
-
95
- function signature(definition: Definition, params: Array<string | undefined>): Definition {
96
- definition.scope = params.length > 1 ? scope(params[1]) : 'none'
97
-
98
- if (params.length === 0) definition.input = null
99
-
100
- return definition
101
- }
102
-
103
- function scope(name: string | undefined): string | undefined {
104
- if (name === undefined) return undefined
105
- if (SCOPES.has(name)) return name
106
- if (name === 'context') return 'none'
107
-
108
- return undefined
109
- }
110
-
111
- export const TYPES: ReadonlySet<string> = new Set([
112
- 'transition',
113
- 'observation',
114
- 'assignment',
115
- 'computation',
116
- 'effect',
117
- 'unmanaged'
118
- ])
119
-
120
- const SCOPES: ReadonlySet<string> = new Set(['object', 'objects', 'changeset', 'stream'])
121
-
122
- const CLASSES: ReadonlySet<string> = new Set(
123
- [...TYPES].map((type) => type[0].toUpperCase() + type.slice(1))
124
- )
125
-
126
- const FACTORY =
127
- /^(?<scope>Objects?|Changeset)?(?<type>Transition|Observation|Assignment|Computation|Effect)Factory$/
@@ -1,44 +0,0 @@
1
- import { readdir } from 'node:fs/promises'
2
- import { basename, extname, join } from 'node:path'
3
-
4
- /**
5
- * A component's modules by name, whatever extension each was written with.
6
- *
7
- * Two files that resolve to one name are a conflict rather than a race: which of them a scan
8
- * reached first is not something a component may depend on.
9
- */
10
- export async function sources(root: string, directory: string): Promise<Map<string, string>> {
11
- const path = join(root, directory)
12
- const files = (await list(path)).filter((file) => EXTENSIONS.has(extname(file))).sort()
13
- const modules = new Map<string, string>()
14
-
15
- // sorted, so the two files a conflict names are the same two on every machine
16
- for (const file of files) {
17
- const name = basename(file, extname(file))
18
- const found = modules.get(name)
19
-
20
- if (found !== undefined)
21
- throw new Error(
22
- `Component at '${root}' has more than one ${directory}/${name}: ` +
23
- `${basename(found)} and ${file}`
24
- )
25
-
26
- modules.set(name, join(path, file))
27
- }
28
-
29
- return modules
30
- }
31
-
32
- async function list(path: string): Promise<string[]> {
33
- try {
34
- const entries = await readdir(path, { withFileTypes: true })
35
-
36
- return entries.filter((entry) => entry.isFile()).map((entry) => entry.name)
37
- } catch (error: any) {
38
- if (error.code === 'ENOENT') return []
39
-
40
- throw error
41
- }
42
- }
43
-
44
- const EXTENSIONS = new Set(['.js', '.mjs', '.cjs', '.ts'])
@@ -1,38 +0,0 @@
1
- /**
2
- * A first-party package's definition, by the reference a manifest or a context names it by.
3
- * `undefined` for a package this one does not define, which norm then reads on its own.
4
- */
5
- export async function definition(reference: string): Promise<object | undefined> {
6
- if (!reference.startsWith(SCOPE)) return undefined
7
-
8
- const suffix = reference.slice(SCOPE.length)
9
-
10
- if (!DEFINED.has(suffix)) return undefined
11
-
12
- cache[suffix] ??= import(`./${suffix}/index.js`)
13
-
14
- return cache[suffix]
15
- }
16
-
17
- const cache: Record<string, Promise<object>> = {}
18
-
19
- const SCOPE = '@toa.io/'
20
-
21
- /** Every package defined here, by its directory, which is its name within the scope. */
22
- export const DEFINED: ReadonlySet<string> = new Set([
23
- 'bindings.amqp',
24
- 'bindings.loop',
25
- 'bridges.bash',
26
- 'bridges.node',
27
- 'extensions.cadence',
28
- 'extensions.configuration',
29
- 'extensions.exposition',
30
- 'extensions.fetch',
31
- 'extensions.introspection',
32
- 'extensions.realtime',
33
- 'extensions.stash',
34
- 'extensions.state',
35
- 'extensions.storages',
36
- 'extensions.telemetry',
37
- 'storages.mongodb'
38
- ])
@@ -1,77 +0,0 @@
1
- import { createRequire } from 'node:module'
2
- import { dirname, join, relative, resolve, sep } from 'node:path'
3
- import { mkdirSync, readdirSync, writeFileSync } from 'node:fs'
4
- import type { Entry } from './read.js'
5
-
6
- /**
7
- * Writes the digest of the components each extension ships: their manifests as norm reads
8
- * them, with every path that reaches into a package replaced by that package's name — so the
9
- * digest reads the same wherever this package is installed.
10
- *
11
- * Runs after the workspace transpiled, from the workspace, where every extension resolves.
12
- */
13
- const require = createRequire(import.meta.url)
14
-
15
- // norm types its manifests, not its functions
16
- const { component } = (await import('@toa.io/norm')) as unknown as {
17
- component: (path: string) => Promise<object>
18
- }
19
-
20
- const DIGESTED = [
21
- 'extensions.cadence',
22
- 'extensions.configuration',
23
- 'extensions.exposition',
24
- 'extensions.introspection',
25
- 'extensions.realtime'
26
- ]
27
-
28
- const OUT = resolve(import.meta.dirname, '../../digest')
29
-
30
- mkdirSync(OUT, { recursive: true })
31
-
32
- const packages = ['@toa.io/prototype', ...DIGESTED.map((suffix) => '@toa.io/' + suffix)]
33
- const roots = new Map(packages.map((name) => [root(name), name]))
34
-
35
- for (const suffix of DIGESTED) {
36
- const directory = join(root('@toa.io/' + suffix), 'components')
37
- const entries: Entry[] = []
38
-
39
- for (const dirent of readdirSync(directory, { withFileTypes: true })) {
40
- if (!dirent.isDirectory()) continue
41
-
42
- const manifest = await component(join(directory, dirent.name))
43
-
44
- entries.push({ label: dirent.name.replace('.', '-'), manifest: relativize(manifest) })
45
- }
46
-
47
- writeFileSync(join(OUT, suffix + '.json'), JSON.stringify(entries))
48
- }
49
-
50
- function root(name: string): string {
51
- return dirname(require.resolve(name + '/package.json'))
52
- }
53
-
54
- /** Absolute paths into a package become `<name>/<inside>`; the locator norm rebuilds. */
55
- function relativize(value: unknown): any {
56
- if (typeof value === 'string') return specifier(value)
57
- if (Array.isArray(value)) return value.map(relativize)
58
-
59
- if (value !== null && typeof value === 'object') {
60
- const object: Record<string, unknown> = {}
61
-
62
- for (const [key, item] of Object.entries(value))
63
- if (key !== 'locator') object[key] = relativize(item)
64
-
65
- return object
66
- }
67
-
68
- return value
69
- }
70
-
71
- function specifier(value: string): string {
72
- for (const [directory, name] of roots)
73
- if (value === directory || value.startsWith(directory + sep))
74
- return [name, ...relative(directory, value).split(sep)].filter(Boolean).join('/')
75
-
76
- return value
77
- }
@@ -1,39 +0,0 @@
1
- import { readFileSync } from 'node:fs'
2
- import { resolve } from 'node:path'
3
-
4
- /**
5
- * The components an extension ships, as the digest of their manifests generated when this
6
- * package was built. A deploy reads them from here, because the extension is not installed
7
- * beside it; a running service reads them from the extension, where their code is.
8
- */
9
- export function components(suffix: string, filter?: (label: string) => boolean): Components {
10
- const manifests = digest(suffix).filter((manifest) => filter?.(manifest.label) ?? true)
11
-
12
- return {
13
- labels: manifests.map((manifest) => manifest.label),
14
- manifests: manifests.map((manifest) => structuredClone(manifest.manifest))
15
- }
16
- }
17
-
18
- function digest(suffix: string): Entry[] {
19
- cache[suffix] ??= JSON.parse(readFileSync(resolve(ROOT, suffix + '.json'), 'utf8'))
20
-
21
- return cache[suffix]
22
- }
23
-
24
- const cache: Record<string, Entry[]> = {}
25
-
26
- /** `transpiled/digest/read.js` → `digest/` */
27
- const ROOT = resolve(import.meta.dirname, '../../digest')
28
-
29
- export interface Components {
30
- /** what a chart names each component's workload by: `identity-basic` */
31
- labels: string[]
32
- /** the manifests as norm reads them, with `path` as a package-relative specifier */
33
- manifests: object[]
34
- }
35
-
36
- export interface Entry {
37
- label: string
38
- manifest: object
39
- }
@@ -1,6 +0,0 @@
1
- import { components as digest, type Components } from '../digest/read.js'
2
-
3
- /** The components this extension ships, which run inside its own service. */
4
- export function components(): Components {
5
- return digest('extensions.cadence')
6
- }