@toa.io/userland 0.10.0 → 0.20.0-alpha.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/example/.env +9 -0
- package/example/components/echo/manifest.toa.yaml +7 -0
- package/example/components/echo/operations/get.js +7 -0
- package/example/components/echo/operations/resolve.js +7 -0
- package/example/components/echo/operations/signal.js +11 -3
- package/example/components/echo/samples/get.yaml +12 -0
- package/example/components/echo/samples/signal.yaml +0 -3
- package/example/components/math.calculations/operations/increment.js +1 -3
- package/example/components/math.calculations/samples/add.yaml +1 -2
- package/example/components/math.calculations/samples/assets/ab.yaml +2 -0
- package/example/components/math.calculations/samples/increment.yaml +3 -6
- package/example/components/tea.pots/manifest.toa.yaml +2 -2
- package/example/components/web/manifest.toa.yaml +8 -0
- package/example/components/web/operations/get.js +14 -0
- package/example/components/web/samples/get.yaml +8 -0
- package/example/context.toa.yaml +7 -0
- package/example/stage/call.test.js +5 -4
- package/example/stage/events.test.js +6 -3
- package/example/stage/invoke.test.js +4 -0
- package/package.json +10 -9
- package/samples/notes.md +2 -2
- package/samples/readme.md +74 -8
- package/samples/src/.replay/.suite/component.js +3 -8
- package/samples/src/.replay/.suite/operation.js +1 -1
- package/samples/src/.replay/.suite/operations.js +5 -3
- package/samples/src/.replay/.suite/translate/.operation/.prepare/cast.js +20 -0
- package/samples/src/.replay/.suite/translate/.operation/.prepare/cast.test.js +94 -0
- package/samples/src/.replay/.suite/translate/.operation/.prepare/expand.js +14 -0
- package/samples/src/.replay/.suite/translate/.operation/.prepare/index.js +7 -0
- package/samples/src/.replay/.suite/translate/.operation/.prepare/shortcuts/.aspect.js +26 -0
- package/samples/src/.replay/.suite/translate/.operation/.prepare/shortcuts/configuration.js +5 -0
- package/samples/src/.replay/.suite/translate/.operation/.prepare/shortcuts/http.js +5 -0
- package/samples/src/.replay/.suite/translate/.operation/.prepare/shortcuts/index.js +9 -0
- package/samples/src/.replay/.suite/translate/.operation/.prepare/shortcuts/state.js +5 -0
- package/samples/src/.replay/.suite/translate/.operation/.prepare/types/async.js +3 -0
- package/samples/src/.replay/.suite/translate/.operation/.prepare/types/cast.js +26 -0
- package/samples/src/.replay/.suite/translate/.operation/.prepare/types/index.js +5 -0
- package/samples/src/.replay/.suite/translate/.operation/.prepare/types/map.js +3 -0
- package/samples/src/.replay/.suite/translate/.operation/.prepare/types/set.js +3 -0
- package/samples/src/.replay/.suite/translate/.operation/.prepare/types/sync.js +3 -0
- package/samples/src/.replay/.suite/translate/.operation/prepare.js +4 -4
- package/samples/src/.replay/index.js +2 -0
- package/samples/src/.replay/stage.js +60 -0
- package/samples/src/.replay/suite.js +3 -2
- package/samples/src/.replay/test.js +5 -3
- package/samples/src/components.js +1 -1
- package/samples/src/context.js +2 -2
- package/samples/src/replay.js +4 -5
- package/samples/src/suite/components.js +3 -3
- package/samples/test/components.test.js +2 -2
- package/samples/test/context.test.js +2 -2
- package/samples/test/replay.test.js +108 -72
- package/samples/test/replay.translate.message.test.js +2 -6
- package/samples/test/replay.translate.operation.test.js +1 -1
- package/samples/test/stage.mock.js +10 -14
- package/samples/test/suite.components.test.js +5 -31
- package/samples/types/operation.d.ts +2 -2
- package/samples/types/replay.d.ts +3 -3
- package/samples/types/suite.d.ts +5 -2
- package/stage/src/binding/binding.js +14 -13
- package/stage/src/component.js +7 -2
- package/stage/src/index.js +0 -3
- package/stage/test/component.test.js +1 -1
- package/stage/types/index.d.ts +2 -1
- package/example/components/tea.pots/samples/messages/store.orders.created.yaml +0 -37
- package/samples/src/.replay/.suite/translate/.operation/specials/configuration.js +0 -26
- package/samples/src/.replay/.suite/translate/.operation/specials/index.js +0 -5
- package/samples/test/replay.fixtures.js +0 -72
|
@@ -34,7 +34,7 @@ it('should define suite as autonomous', async () => {
|
|
|
34
34
|
expect(suite.autonomous).toStrictEqual(true)
|
|
35
35
|
})
|
|
36
36
|
|
|
37
|
-
it('should load
|
|
37
|
+
it('should load operation samples', async () => {
|
|
38
38
|
const expected = await operations()
|
|
39
39
|
|
|
40
40
|
expect(Object.keys(suite.operations)).toStrictEqual([component])
|
|
@@ -47,12 +47,6 @@ it('should load component samples', async () => {
|
|
|
47
47
|
expect(set.undo).toStrictEqual(expected.undo)
|
|
48
48
|
})
|
|
49
49
|
|
|
50
|
-
it('should load message samples', async () => {
|
|
51
|
-
const expected = await messages()
|
|
52
|
-
|
|
53
|
-
expect(suite.messages).toStrictEqual(expected)
|
|
54
|
-
})
|
|
55
|
-
|
|
56
50
|
describe('options', () => {
|
|
57
51
|
const paths = [dummy, pot]
|
|
58
52
|
|
|
@@ -63,11 +57,6 @@ describe('options', () => {
|
|
|
63
57
|
suite = await components(paths, options)
|
|
64
58
|
|
|
65
59
|
expect(suite.operations['dummies.pot']).toBeUndefined()
|
|
66
|
-
|
|
67
|
-
const messages = suite.messages['somewhere.something.happened']
|
|
68
|
-
|
|
69
|
-
expect(messages.length).toStrictEqual(1)
|
|
70
|
-
expect(messages[0].component).toStrictEqual('dummies.dummy')
|
|
71
60
|
})
|
|
72
61
|
|
|
73
62
|
it('should filter samples by operation name', async () => {
|
|
@@ -101,16 +90,14 @@ describe('options', () => {
|
|
|
101
90
|
expect(suite.operations['dummies.dummy'].undo[0].title).toStrictEqual('Should not undo')
|
|
102
91
|
})
|
|
103
92
|
|
|
104
|
-
it('should filter
|
|
93
|
+
it('should filter operation samples by title', async () => {
|
|
105
94
|
/** @type {toa.samples.suite.Options} */
|
|
106
|
-
const options = { title: '
|
|
95
|
+
const options = { title: 'Should not undo' }
|
|
107
96
|
|
|
108
97
|
suite = await components(paths, options)
|
|
109
98
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
expect(messages.length).toStrictEqual(1)
|
|
113
|
-
expect(messages[0].title).toStrictEqual(options.title)
|
|
99
|
+
expect(Object.keys(suite.operations['dummies.dummy']).length).toStrictEqual(1)
|
|
100
|
+
expect(suite.operations['dummies.dummy'].undo[0].title).toStrictEqual(options.title)
|
|
114
101
|
})
|
|
115
102
|
})
|
|
116
103
|
|
|
@@ -133,16 +120,3 @@ const operations = async () => {
|
|
|
133
120
|
do: [...do1, ...do2], undo
|
|
134
121
|
}
|
|
135
122
|
}
|
|
136
|
-
|
|
137
|
-
/**
|
|
138
|
-
*
|
|
139
|
-
* @returns {Promise<toa.samples.messages.Set>}
|
|
140
|
-
*/
|
|
141
|
-
const messages = async () => {
|
|
142
|
-
const label = 'somewhere.something.happened'
|
|
143
|
-
const file = resolve(dummy, 'samples/messages', label + '.yaml')
|
|
144
|
-
const declarations = await yaml.load.all(file)
|
|
145
|
-
const messages = declarations.map((sample) => ({ component, ...sample }))
|
|
146
|
-
|
|
147
|
-
return { [label]: messages }
|
|
148
|
-
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as _core from '@toa.io/core/types'
|
|
2
|
-
import * as _sampling from '@toa.io/extensions.sampling'
|
|
2
|
+
import * as _sampling from '@toa.io/extensions.sampling/types/request'
|
|
3
3
|
|
|
4
4
|
declare namespace toa.samples {
|
|
5
5
|
|
|
@@ -27,7 +27,7 @@ declare namespace toa.samples {
|
|
|
27
27
|
remote?: operations.Calls
|
|
28
28
|
local?: operations.Calls
|
|
29
29
|
events?: operations.Events
|
|
30
|
-
extensions?: _sampling.
|
|
30
|
+
extensions?: _sampling.Extensions
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
}
|
|
@@ -2,9 +2,9 @@ import * as _suite from './suite'
|
|
|
2
2
|
|
|
3
3
|
declare namespace toa.samples.replay {
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
type components = (paths: string[], options?: _suite.Options) => Promise<boolean>
|
|
6
|
+
type context = (path: string, options?: _suite.Options) => Promise<boolean>
|
|
7
|
+
type replay = (suite: _suite.Suite, paths: string[], options?: object) => Promise<boolean>
|
|
8
8
|
|
|
9
9
|
}
|
|
10
10
|
|
package/samples/types/suite.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import * as _core from '@toa.io/core/types'
|
|
1
2
|
import * as _operations from './operation'
|
|
2
3
|
import * as _messages from './message'
|
|
3
4
|
|
|
@@ -8,15 +9,17 @@ declare namespace toa.samples {
|
|
|
8
9
|
|
|
9
10
|
type Options = {
|
|
10
11
|
id?: string
|
|
11
|
-
integration?: boolean
|
|
12
12
|
component?: string
|
|
13
|
+
autonomous?: boolean
|
|
14
|
+
integration?: boolean
|
|
13
15
|
operation?: string
|
|
14
16
|
title?: string
|
|
17
|
+
runner?: object
|
|
15
18
|
}
|
|
16
19
|
}
|
|
17
20
|
|
|
18
21
|
type Suite = {
|
|
19
|
-
title
|
|
22
|
+
title?: string
|
|
20
23
|
autonomous: boolean
|
|
21
24
|
operations?: suite.Operations
|
|
22
25
|
messages?: _messages.Set
|
|
@@ -5,42 +5,43 @@
|
|
|
5
5
|
*/
|
|
6
6
|
class Binding {
|
|
7
7
|
/** @type {Record<string, function[]>} */
|
|
8
|
-
#
|
|
8
|
+
#callbacks = {}
|
|
9
9
|
|
|
10
10
|
/** @type {Record<string, function>} */
|
|
11
|
-
#
|
|
11
|
+
#producers = {}
|
|
12
12
|
|
|
13
13
|
async subscribe (label, callback) {
|
|
14
|
-
if (this.#
|
|
14
|
+
if (this.#callbacks[label] === undefined) this.#callbacks[label] = []
|
|
15
15
|
|
|
16
|
-
this.#
|
|
16
|
+
this.#callbacks[label].push(callback)
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
async emit (label, message) {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
if (callbacks === undefined) return undefined
|
|
20
|
+
if (!(label in this.#callbacks)) return
|
|
23
21
|
|
|
22
|
+
const callbacks = this.#callbacks[label]
|
|
24
23
|
const promises = callbacks.map((callback) => callback(message))
|
|
25
24
|
|
|
26
25
|
await Promise.all(promises)
|
|
27
26
|
}
|
|
28
27
|
|
|
29
28
|
async reply (label, produce) {
|
|
30
|
-
if (
|
|
29
|
+
if (label in this.#producers) throw new Error(`Label '${label}' is already bound`)
|
|
31
30
|
|
|
32
|
-
this.#
|
|
31
|
+
this.#producers[label] = produce
|
|
33
32
|
}
|
|
34
33
|
|
|
35
34
|
async request (label, request) {
|
|
36
|
-
if (
|
|
35
|
+
if (!(label in this.#producers)) throw new Error(`Label '${label}' is not bound`)
|
|
36
|
+
|
|
37
|
+
const produce = this.#producers[label]
|
|
37
38
|
|
|
38
|
-
return
|
|
39
|
+
return produce(request)
|
|
39
40
|
}
|
|
40
41
|
|
|
41
42
|
reset () {
|
|
42
|
-
this.#
|
|
43
|
-
this.#
|
|
43
|
+
this.#callbacks = {}
|
|
44
|
+
this.#producers = {}
|
|
44
45
|
}
|
|
45
46
|
}
|
|
46
47
|
|
package/stage/src/component.js
CHANGED
|
@@ -4,8 +4,10 @@ const boot = require('@toa.io/boot')
|
|
|
4
4
|
const { state } = require('./state')
|
|
5
5
|
|
|
6
6
|
/** @type {toa.stage.Component} */
|
|
7
|
-
const component = async (path) => {
|
|
8
|
-
|
|
7
|
+
const component = async (path, options) => {
|
|
8
|
+
options = Object.assign({}, DEFAULTS, options)
|
|
9
|
+
|
|
10
|
+
const manifest = await boot.manifest(path, options)
|
|
9
11
|
const component = await boot.component(manifest)
|
|
10
12
|
|
|
11
13
|
await component.connect()
|
|
@@ -15,4 +17,7 @@ const component = async (path) => {
|
|
|
15
17
|
return component
|
|
16
18
|
}
|
|
17
19
|
|
|
20
|
+
const binding = require.resolve('./binding')
|
|
21
|
+
const DEFAULTS = { bindings: [binding] }
|
|
22
|
+
|
|
18
23
|
exports.component = component
|
package/stage/src/index.js
CHANGED
|
@@ -7,9 +7,6 @@ const { remote } = require('./remote')
|
|
|
7
7
|
const { shutdown } = require('./shutdown')
|
|
8
8
|
const binding = require('./binding')
|
|
9
9
|
|
|
10
|
-
// staging always runs on local deployment environment
|
|
11
|
-
process.env.TOA_DEV = '1'
|
|
12
|
-
|
|
13
10
|
exports.manifest = manifest
|
|
14
11
|
exports.component = component
|
|
15
12
|
exports.composition = composition
|
|
@@ -18,7 +18,7 @@ it('should boot component', async () => {
|
|
|
18
18
|
const path = generate()
|
|
19
19
|
const component = await stage.component(path)
|
|
20
20
|
|
|
21
|
-
expect(mock.boot.manifest).
|
|
21
|
+
expect(mock.boot.manifest.mock.calls[0][0]).toStrictEqual(path)
|
|
22
22
|
expect(mock.boot.component).toHaveBeenCalledWith(await mock.boot.manifest.mock.results[0].value)
|
|
23
23
|
expect(component).toStrictEqual(await mock.boot.component.mock.results[0].value)
|
|
24
24
|
expect(component.connect).toHaveBeenCalled()
|
package/stage/types/index.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import * as _core from '@toa.io/core/types'
|
|
2
2
|
import * as _norm from '@toa.io/norm/types'
|
|
3
|
+
import * as _composition from '@toa.io/boot/types/composition'
|
|
3
4
|
|
|
4
5
|
declare namespace toa.stage {
|
|
5
6
|
type Manifest = (path: string) => Promise<_norm.Component>
|
|
6
|
-
type Component = (path: string) => Promise<_core.Component>
|
|
7
|
+
type Component = (path: string, options?: _composition.Options) => Promise<_core.Component>
|
|
7
8
|
type Composition = (paths: string[]) => Promise<void>
|
|
8
9
|
type Remote = (id: string) => Promise<_core.Component>
|
|
9
10
|
type Shutdown = () => Promise<void>
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
title: Should book a pot
|
|
2
|
-
payload:
|
|
3
|
-
pot: 1b9d7983bc204c8f8928d843a666a642
|
|
4
|
-
input:
|
|
5
|
-
booked: true
|
|
6
|
-
query:
|
|
7
|
-
id: 1b9d7983bc204c8f8928d843a666a642
|
|
8
|
-
---
|
|
9
|
-
title: Should book a pot (with request sample)
|
|
10
|
-
payload:
|
|
11
|
-
pot: 1b9d7983bc204c8f8928d843a666a642
|
|
12
|
-
input:
|
|
13
|
-
booked: true
|
|
14
|
-
query:
|
|
15
|
-
id: 1b9d7983bc204c8f8928d843a666a642
|
|
16
|
-
request:
|
|
17
|
-
current:
|
|
18
|
-
id: 1b9d7983bc204c8f8928d843a666a642
|
|
19
|
-
material: glass
|
|
20
|
-
booked: false
|
|
21
|
-
next:
|
|
22
|
-
id: 1b9d7983bc204c8f8928d843a666a642
|
|
23
|
-
material: glass
|
|
24
|
-
booked: true
|
|
25
|
-
---
|
|
26
|
-
title: Should book a pot (without receiver output verification)
|
|
27
|
-
payload:
|
|
28
|
-
pot: 1b9d7983bc204c8f8928d843a666a642
|
|
29
|
-
request:
|
|
30
|
-
current:
|
|
31
|
-
id: 1b9d7983bc204c8f8928d843a666a642
|
|
32
|
-
material: glass
|
|
33
|
-
booked: false
|
|
34
|
-
next:
|
|
35
|
-
id: 1b9d7983bc204c8f8928d843a666a642
|
|
36
|
-
material: glass
|
|
37
|
-
booked: true
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* @param {toa.samples.Operation & Object} declaration
|
|
5
|
-
*/
|
|
6
|
-
const configuration = (declaration) => {
|
|
7
|
-
const configuration = declaration.configuration
|
|
8
|
-
|
|
9
|
-
delete declaration.configuration
|
|
10
|
-
|
|
11
|
-
if (declaration.extensions === undefined) declaration.extensions = {}
|
|
12
|
-
|
|
13
|
-
if ('configuration' in declaration.extensions) {
|
|
14
|
-
throw new Error('Configuration extension sample is ambiguous')
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
/** @type {toa.sampling.request.extensions.Call} */
|
|
18
|
-
const call = {
|
|
19
|
-
result: configuration,
|
|
20
|
-
permanent: true
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
declaration.extensions.configuration = [call]
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
exports.configuration = configuration
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const { generate } = require('randomstring')
|
|
4
|
-
const { random } = require('@toa.io/generic')
|
|
5
|
-
|
|
6
|
-
/** @type {toa.samples.Suite} */
|
|
7
|
-
const suite = { autonomous: true, operations: {} }
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* @returns {toa.samples.Operation[]}
|
|
11
|
-
*/
|
|
12
|
-
const ops = () => {
|
|
13
|
-
const samples = []
|
|
14
|
-
|
|
15
|
-
for (let i = 0; i < random(3) + 1; i++) {
|
|
16
|
-
const sample = {
|
|
17
|
-
input: generate(),
|
|
18
|
-
output: generate(),
|
|
19
|
-
local: generate(),
|
|
20
|
-
current: generate(),
|
|
21
|
-
next: generate()
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
samples.push(sample)
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
return samples
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* @returns {toa.samples.Message[]}
|
|
32
|
-
*/
|
|
33
|
-
const msgs = () => {
|
|
34
|
-
/** @type {toa.samples.Message[]} */
|
|
35
|
-
const samples = []
|
|
36
|
-
|
|
37
|
-
for (let i = 0; i < random(3) + 1; i++) {
|
|
38
|
-
const sample = /** @type {toa.samples.Message} */ {
|
|
39
|
-
component: generate(),
|
|
40
|
-
payload: generate(),
|
|
41
|
-
input: generate()
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
samples.push(sample)
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
return samples
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
// components
|
|
51
|
-
for (let i = 0; i < random(3) + 1; i++) {
|
|
52
|
-
const id = generate() + '.' + generate()
|
|
53
|
-
const operations = {}
|
|
54
|
-
const messages = {}
|
|
55
|
-
|
|
56
|
-
for (let j = 0; j < random(3) + 1; j++) {
|
|
57
|
-
const endpoint = generate()
|
|
58
|
-
const label = generate()
|
|
59
|
-
|
|
60
|
-
operations[endpoint] = ops()
|
|
61
|
-
messages[label] = msgs()
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
suite.operations[id] = operations
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
/** @type {string} */
|
|
68
|
-
const label = generate()
|
|
69
|
-
|
|
70
|
-
suite.messages = { [label]: msgs() }
|
|
71
|
-
|
|
72
|
-
exports.suite = suite
|