@toa.io/userland 1.0.0-alpha.3 → 1.0.0-alpha.300

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 (154) hide show
  1. package/CHANGELOG.md +107 -0
  2. package/example/components/echo/manifest.toa.yaml +15 -5
  3. package/example/components/echo/operations/get.js +1 -5
  4. package/example/components/echo/operations/resolve.js +1 -5
  5. package/example/components/echo/operations/signal.js +3 -7
  6. package/example/components/math.calculations/manifest.toa.yaml +19 -6
  7. package/example/components/math.calculations/operations/add.js +1 -5
  8. package/example/components/math.calculations/operations/increment.js +1 -5
  9. package/example/components/math.proxy/manifest.toa.yaml +8 -3
  10. package/example/components/math.proxy/operations/add.js +1 -5
  11. package/example/components/tea.pots/manifest.toa.yaml +37 -9
  12. package/example/components/tea.pots/operations/same.js +1 -5
  13. package/example/components/tea.pots/receivers/store.orders.created.js +1 -5
  14. package/example/components/web/manifest.toa.yaml +2 -4
  15. package/example/components/web/operations/get.js +3 -8
  16. package/example/context.toa.yaml +2 -7
  17. package/example/stage/call.test.js +17 -10
  18. package/example/stage/events.test.js +63 -16
  19. package/example/stage/invoke.test.js +12 -9
  20. package/package.json +18 -13
  21. package/readme.md +0 -2
  22. package/stage/package.json +1 -0
  23. package/stage/src/component.js +3 -12
  24. package/stage/src/composition.js +3 -11
  25. package/stage/src/index.js +17 -17
  26. package/stage/src/manifest.js +2 -6
  27. package/stage/src/remote.js +11 -8
  28. package/stage/src/service.js +11 -10
  29. package/stage/src/shutdown.js +10 -9
  30. package/stage/src/state.js +2 -4
  31. package/stage/src/workload.js +19 -0
  32. package/stage/test/boot.mock.js +9 -11
  33. package/stage/test/component.test.js +20 -10
  34. package/stage/test/composition.test.js +11 -20
  35. package/stage/test/manifest.test.js +15 -8
  36. package/stage/test/remote.test.js +14 -12
  37. package/stage/test/shutdown.test.js +26 -22
  38. package/stage/test/state.mock.js +5 -6
  39. package/stage/test/state.test.js +13 -12
  40. package/stage/types/index.d.ts +17 -9
  41. package/stage/types/state.d.ts +3 -4
  42. package/example/components/echo/samples/get.yaml +0 -12
  43. package/example/components/echo/samples/signal.yaml +0 -4
  44. package/example/components/math.calculations/samples/add.yaml +0 -10
  45. package/example/components/math.calculations/samples/assets/ab.yaml +0 -2
  46. package/example/components/math.calculations/samples/increment.yaml +0 -27
  47. package/example/components/math.proxy/samples/add.yaml +0 -11
  48. package/example/components/tea.pots/samples/same.yaml +0 -8
  49. package/example/components/tea.pots/samples/transit.yaml +0 -43
  50. package/example/components/web/samples/get.yaml +0 -8
  51. package/example/samples/math.proxy.add.yaml +0 -5
  52. package/example/samples/messages/store.orders.created.yaml +0 -8
  53. package/samples/docs/sampling-dark.jpg +0 -0
  54. package/samples/docs/sampling-light.jpg +0 -0
  55. package/samples/notes.md +0 -12
  56. package/samples/package.json +0 -5
  57. package/samples/readme.md +0 -131
  58. package/samples/src/.replay/.suite/component.js +0 -20
  59. package/samples/src/.replay/.suite/index.js +0 -7
  60. package/samples/src/.replay/.suite/messages.js +0 -39
  61. package/samples/src/.replay/.suite/operation.js +0 -28
  62. package/samples/src/.replay/.suite/operations.js +0 -20
  63. package/samples/src/.replay/.suite/translate/.message/index.js +0 -5
  64. package/samples/src/.replay/.suite/translate/.message/request.js +0 -31
  65. package/samples/src/.replay/.suite/translate/.operation/.prepare/cast.js +0 -20
  66. package/samples/src/.replay/.suite/translate/.operation/.prepare/cast.test.js +0 -94
  67. package/samples/src/.replay/.suite/translate/.operation/.prepare/expand.js +0 -14
  68. package/samples/src/.replay/.suite/translate/.operation/.prepare/index.js +0 -7
  69. package/samples/src/.replay/.suite/translate/.operation/.prepare/shortcuts/.aspect.js +0 -26
  70. package/samples/src/.replay/.suite/translate/.operation/.prepare/shortcuts/configuration.js +0 -5
  71. package/samples/src/.replay/.suite/translate/.operation/.prepare/shortcuts/http.js +0 -5
  72. package/samples/src/.replay/.suite/translate/.operation/.prepare/shortcuts/index.js +0 -9
  73. package/samples/src/.replay/.suite/translate/.operation/.prepare/shortcuts/state.js +0 -5
  74. package/samples/src/.replay/.suite/translate/.operation/.prepare/types/async.js +0 -3
  75. package/samples/src/.replay/.suite/translate/.operation/.prepare/types/cast.js +0 -26
  76. package/samples/src/.replay/.suite/translate/.operation/.prepare/types/index.js +0 -5
  77. package/samples/src/.replay/.suite/translate/.operation/.prepare/types/map.js +0 -3
  78. package/samples/src/.replay/.suite/translate/.operation/.prepare/types/set.js +0 -3
  79. package/samples/src/.replay/.suite/translate/.operation/.prepare/types/sync.js +0 -3
  80. package/samples/src/.replay/.suite/translate/.operation/calls.js +0 -49
  81. package/samples/src/.replay/.suite/translate/.operation/cleanup.js +0 -16
  82. package/samples/src/.replay/.suite/translate/.operation/events.js +0 -16
  83. package/samples/src/.replay/.suite/translate/.operation/index.js +0 -11
  84. package/samples/src/.replay/.suite/translate/.operation/prepare.js +0 -14
  85. package/samples/src/.replay/.suite/translate/index.js +0 -7
  86. package/samples/src/.replay/.suite/translate/message.js +0 -26
  87. package/samples/src/.replay/.suite/translate/operation.js +0 -47
  88. package/samples/src/.replay/.suite/translate/schemas/index.js +0 -7
  89. package/samples/src/.replay/.suite/translate/schemas/message.cos.yaml +0 -10
  90. package/samples/src/.replay/.suite/translate/schemas/operation.cos.yaml +0 -23
  91. package/samples/src/.replay/index.js +0 -7
  92. package/samples/src/.replay/stage.js +0 -60
  93. package/samples/src/.replay/suite.js +0 -23
  94. package/samples/src/.replay/test.js +0 -19
  95. package/samples/src/components.js +0 -13
  96. package/samples/src/context.js +0 -23
  97. package/samples/src/index.js +0 -9
  98. package/samples/src/replay.js +0 -16
  99. package/samples/src/suite/.read/filter.js +0 -15
  100. package/samples/src/suite/.read/index.js +0 -7
  101. package/samples/src/suite/.read/messages.js +0 -40
  102. package/samples/src/suite/.read/operations.js +0 -51
  103. package/samples/src/suite/.read/parse.js +0 -20
  104. package/samples/src/suite/components.js +0 -31
  105. package/samples/src/suite/context.js +0 -20
  106. package/samples/src/suite/index.js +0 -7
  107. package/samples/test/components.test.js +0 -42
  108. package/samples/test/context/components/dummy/manifest.toa.yaml +0 -2
  109. package/samples/test/context/components/dummy/samples/do.yaml +0 -11
  110. package/samples/test/context/components/dummy/samples/dummies.dummy.do.yaml +0 -11
  111. package/samples/test/context/components/dummy/samples/dummies.dummy.undo.yaml +0 -7
  112. package/samples/test/context/components/dummy/samples/messages/somewhere.something.happened.yaml +0 -6
  113. package/samples/test/context/components/pot/manifest.toa.yaml +0 -2
  114. package/samples/test/context/components/pot/samples/do.yaml +0 -11
  115. package/samples/test/context/components/pot/samples/messages/somewhere.something.happened.yaml +0 -6
  116. package/samples/test/context/context.toa.yaml +0 -3
  117. package/samples/test/context/samples/dummies.dummy.observe.yaml +0 -6
  118. package/samples/test/context/samples/dummies.dummy.transit.yaml +0 -10
  119. package/samples/test/context/samples/messages/somewhere.something.happened.yaml +0 -6
  120. package/samples/test/context.fixtures.js +0 -8
  121. package/samples/test/context.test.js +0 -82
  122. package/samples/test/replay.mock.js +0 -7
  123. package/samples/test/replay.test.js +0 -152
  124. package/samples/test/replay.translate.message.fixtures.js +0 -24
  125. package/samples/test/replay.translate.message.test.js +0 -119
  126. package/samples/test/replay.translate.mock.js +0 -17
  127. package/samples/test/replay.translate.operation.fixtures.js +0 -107
  128. package/samples/test/replay.translate.operation.test.js +0 -68
  129. package/samples/test/stage.mock.js +0 -30
  130. package/samples/test/suite.components.test.js +0 -122
  131. package/samples/test/suite.context.test.js +0 -79
  132. package/samples/test/suite.mock.js +0 -10
  133. package/samples/types/index.d.ts +0 -8
  134. package/samples/types/message.d.ts +0 -24
  135. package/samples/types/operation.d.ts +0 -36
  136. package/samples/types/replay.d.ts +0 -13
  137. package/samples/types/suite.d.ts +0 -31
  138. package/stage/src/binding/binding.js +0 -50
  139. package/stage/src/binding/consumer.js +0 -30
  140. package/stage/src/binding/emitter.js +0 -26
  141. package/stage/src/binding/factory.js +0 -49
  142. package/stage/src/binding/index.js +0 -10
  143. package/stage/src/binding/label.js +0 -12
  144. package/stage/src/binding/producer.js +0 -43
  145. package/stage/src/binding/receiver.js +0 -34
  146. package/stage/test/binding/binding.test.js +0 -15
  147. package/stage/test/binding/consumer.test.js +0 -52
  148. package/stage/test/binding/emitter.test.js +0 -54
  149. package/stage/test/binding/producer.fixtures.js +0 -10
  150. package/stage/test/binding/producer.test.js +0 -49
  151. package/stage/test/binding/receiver.fixtures.js +0 -7
  152. package/stage/test/binding/receiver.test.js +0 -54
  153. package/stage/test/binding.mock.js +0 -8
  154. package/stage/types/binding.d.ts +0 -20
package/CHANGELOG.md ADDED
@@ -0,0 +1,107 @@
1
+ # Change Log
2
+
3
+ All notable changes to this project will be documented in this file.
4
+ See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
+
6
+ # [1.0.0-alpha.300](https://github.com/toa-io/toa/compare/v1.0.0-alpha.299...v1.0.0-alpha.300) (2026-09-11)
7
+
8
+ * feat(boot)!: a process is a thing, and an extension may keep something in one ([528d6cd](https://github.com/toa-io/toa/commit/528d6cdd307b45a6c30b6a184d7e06b3328cecf8))
9
+
10
+ ### BREAKING CHANGES
11
+
12
+ * a composition booted directly has no readiness probe. Readiness is
13
+ the process's, and a composition is not a process. `stage.workload` boots one where a
14
+ suite needs it.
15
+
16
+
17
+ # [1.0.0-alpha.299](https://github.com/toa-io/toa/compare/v1.0.0-alpha.298...v1.0.0-alpha.299) (2026-09-10)
18
+
19
+ **Note:** Version bump only for package @toa.io/userland
20
+
21
+
22
+
23
+
24
+
25
+ # [1.0.0-alpha.298](https://github.com/toa-io/toa/compare/v1.0.0-alpha.297...v1.0.0-alpha.298) (2026-09-08)
26
+
27
+ **Note:** Version bump only for package @toa.io/userland
28
+
29
+
30
+
31
+
32
+
33
+ # [1.0.0-alpha.297](https://github.com/toa-io/toa/compare/v1.0.0-alpha.296...v1.0.0-alpha.297) (2026-09-08)
34
+
35
+ **Note:** Version bump only for package @toa.io/userland
36
+
37
+
38
+
39
+
40
+
41
+ # [1.0.0-alpha.296](https://github.com/toa-io/toa/compare/v1.0.0-alpha.295...v1.0.0-alpha.296) (2026-09-08)
42
+
43
+ **Note:** Version bump only for package @toa.io/userland
44
+
45
+
46
+
47
+
48
+
49
+ # [1.0.0-alpha.295](https://github.com/toa-io/toa/compare/v1.0.0-alpha.294...v1.0.0-alpha.295) (2026-09-07)
50
+
51
+ **Note:** Version bump only for package @toa.io/userland
52
+
53
+
54
+
55
+
56
+
57
+ # [1.0.0-alpha.294](https://github.com/toa-io/toa/compare/v1.0.0-alpha.293...v1.0.0-alpha.294) (2026-09-07)
58
+
59
+ **Note:** Version bump only for package @toa.io/userland
60
+
61
+
62
+
63
+
64
+
65
+ # [1.0.0-alpha.293](https://github.com/toa-io/toa/compare/v1.0.0-alpha.292...v1.0.0-alpha.293) (2026-09-07)
66
+
67
+ **Note:** Version bump only for package @toa.io/userland
68
+
69
+
70
+
71
+
72
+
73
+ # [1.0.0-alpha.292](https://github.com/toa-io/toa/compare/v1.0.0-alpha.291...v1.0.0-alpha.292) (2026-09-07)
74
+
75
+ **Note:** Version bump only for package @toa.io/userland
76
+
77
+
78
+
79
+
80
+
81
+ # [1.0.0-alpha.291](https://github.com/toa-io/toa/compare/v1.0.0-alpha.290...v1.0.0-alpha.291) (2026-09-07)
82
+
83
+ **Note:** Version bump only for package @toa.io/userland
84
+
85
+
86
+
87
+
88
+
89
+ # [1.0.0-alpha.289](https://github.com/toa-io/toa/compare/v1.0.0-alpha.288...v1.0.0-alpha.289) (2026-09-07)
90
+
91
+ **Note:** Version bump only for package @toa.io/userland
92
+
93
+
94
+
95
+
96
+
97
+ # [1.0.0-alpha.288](https://github.com/toa-io/toa/compare/v1.0.0-alpha.287...v1.0.0-alpha.288) (2026-09-06)
98
+
99
+ **Note:** Version bump only for package @toa.io/userland
100
+
101
+
102
+
103
+
104
+
105
+ # [1.0.0-alpha.287](https://github.com/toa-io/toa/compare/v1.0.0-alpha.286...v1.0.0-alpha.287) (2026-09-06)
106
+
107
+ **Note:** Version bump only for package @toa.io/userland
@@ -2,14 +2,24 @@ name: echo
2
2
 
3
3
  operations:
4
4
  signal:
5
- output: string
5
+ output:
6
+ type: string
6
7
  get:
7
- output: string
8
+ output:
9
+ type: string
8
10
  resolve:
9
- input: string
10
- output: string
11
+ input:
12
+ type: string
13
+ output:
14
+ type: string
11
15
 
12
16
  configuration:
13
- signal: quack
17
+ schema:
18
+ type: object
19
+ properties:
20
+ signal:
21
+ type: string
22
+ defaults:
23
+ signal: quack
14
24
 
15
25
  state: ~
@@ -1,7 +1,3 @@
1
- 'use strict'
2
-
3
- async function computation (_, context) {
1
+ export async function computation(_, context) {
4
2
  return context.state.value
5
3
  }
6
-
7
- exports.computation = computation
@@ -1,7 +1,3 @@
1
- 'use strict'
2
-
3
- async function computation (key, context) {
1
+ export async function computation(key, context) {
4
2
  return context.state.values.get(key)
5
3
  }
6
-
7
- exports.computation = computation
@@ -1,15 +1,11 @@
1
- 'use strict'
2
-
3
- class Computation {
1
+ export class Computation {
4
2
  #context
5
3
 
6
- async mount (context) {
4
+ async mount(context) {
7
5
  this.#context = context
8
6
  }
9
7
 
10
- async execute () {
8
+ async execute() {
11
9
  return this.#context.configuration.signal
12
10
  }
13
11
  }
14
-
15
- exports.Computation = Computation
@@ -4,11 +4,24 @@ namespace: math
4
4
  operations:
5
5
  add:
6
6
  input:
7
- a: number
8
- b: number
9
- output: number
7
+ properties:
8
+ a:
9
+ type: number
10
+ b:
11
+ type: number
12
+ type: object
13
+ output:
14
+ type: number
10
15
  increment:
11
16
  input:
12
- value: number
13
- times: 1
14
- output: number
17
+ properties:
18
+ value:
19
+ type: number
20
+ times:
21
+ type: number
22
+ type: object
23
+ required:
24
+ - value
25
+ - times
26
+ output:
27
+ type: number
@@ -1,7 +1,3 @@
1
- 'use strict'
2
-
3
- async function computation (input) {
1
+ export async function computation(input) {
4
2
  return input.a + input.b
5
3
  }
6
-
7
- exports.computation = computation
@@ -1,6 +1,4 @@
1
- 'use strict'
2
-
3
- async function computation (input, context) {
1
+ export async function computation(input, context) {
4
2
  let value = input.value
5
3
 
6
4
  for (let i = 0; i < input.times; i++) {
@@ -9,5 +7,3 @@ async function computation (input, context) {
9
7
 
10
8
  return value
11
9
  }
12
-
13
- exports.computation = computation
@@ -4,6 +4,11 @@ namespace: math
4
4
  operations:
5
5
  add:
6
6
  input:
7
- a: number
8
- b: number
9
- output: number
7
+ properties:
8
+ a:
9
+ type: number
10
+ b:
11
+ type: number
12
+ type: object
13
+ output:
14
+ type: number
@@ -1,10 +1,6 @@
1
- 'use strict'
2
-
3
- async function computation (input, context) {
1
+ export async function computation(input, context) {
4
2
  const request = { input }
5
3
 
6
4
  // noinspection JSUnresolvedVariable
7
5
  return context.remote.math.calculations.add(request)
8
6
  }
9
-
10
- exports.computation = computation
@@ -3,21 +3,43 @@ namespace: tea
3
3
 
4
4
  entity:
5
5
  storage: mongodb
6
- schema:
7
- material*: [ glass, ceramic, steel ]
8
- volume: number
6
+ properties:
7
+ volume:
8
+ type: number
9
+ booked:
10
+ type: boolean
11
+ material:
12
+ type: string
13
+ enum:
14
+ - glass
15
+ - ceramic
16
+ - steel
17
+ required:
18
+ - material
19
+ blank:
9
20
  booked: false
10
21
 
11
22
  operations:
12
23
  transit:
13
24
  concurrency: none
14
25
  input:
15
- material: .
16
- volume: .
17
- booked: .
26
+ properties:
27
+ material:
28
+ type: string
29
+ default: .
30
+ volume:
31
+ type: string
32
+ default: .
33
+ booked:
34
+ type: string
35
+ default: .
36
+ type: object
18
37
  same:
19
- input: .material
20
- output: array
38
+ input:
39
+ type: string
40
+ default: .material
41
+ output:
42
+ type: array
21
43
 
22
44
  receivers:
23
45
  store.orders.created:
@@ -25,4 +47,10 @@ receivers:
25
47
  binding: amqp # avoid discovery
26
48
 
27
49
  configuration:
28
- step: 0.5
50
+ schema:
51
+ type: object
52
+ properties:
53
+ step:
54
+ type: number
55
+ defaults:
56
+ step: 0.5
@@ -1,6 +1,4 @@
1
- 'use strict'
2
-
3
- async function computation (input, context) {
1
+ export async function computation(input, context) {
4
2
  const criteria = `material==${input}`
5
3
  const query = { criteria, limit }
6
4
 
@@ -9,5 +7,3 @@ async function computation (input, context) {
9
7
  }
10
8
 
11
9
  const limit = 10
12
-
13
- exports.computation = computation
@@ -1,8 +1,4 @@
1
- 'use strict'
2
-
3
- const request = async (payload) => ({
1
+ export const request = async (payload) => ({
4
2
  input: { booked: true },
5
3
  query: { id: payload.pot }
6
4
  })
7
-
8
- exports.request = request
@@ -2,7 +2,5 @@ name: web
2
2
 
3
3
  operations:
4
4
  get:
5
- output: object
6
-
7
- origins:
8
- dev: http://api.example.com
5
+ output:
6
+ type: object
@@ -1,15 +1,10 @@
1
- 'use strict'
2
-
3
- async function computation (_, context) {
4
- const response = await context.http.dev.path.to.resource.get()
1
+ export async function computation(_, context) {
2
+ const response = await context.fetch('http://api.example.com/path/to/resource')
5
3
  const type = response.headers.get('content-type')
6
4
 
7
- if (type !== 'application/json')
8
- return ERR_UNSUPPORTED_MEDIA_TYPE
5
+ if (type !== 'application/json') return ERR_UNSUPPORTED_MEDIA_TYPE
9
6
 
10
7
  return await response.json()
11
8
  }
12
9
 
13
10
  const ERR_UNSUPPORTED_MEDIA_TYPE = new Error('UNSUPPORTED_MEDIA_TYPE')
14
-
15
- exports.computation = computation
@@ -1,10 +1,5 @@
1
1
  name: examples
2
- packages: components/*
3
2
  registry: example
4
3
 
5
- amqp: amqp://localhost
6
- mongodb: mongodb://localhost
7
-
8
- origins:
9
- default.web:
10
- dev: http://localhost
4
+ amqp: amqp://localhost:31010
5
+ mongodb: mongodb://localhost:31020
@@ -1,16 +1,21 @@
1
- 'use strict'
1
+ import { it, before, after } from 'node:test'
2
+ import assert from 'node:assert/strict'
2
3
 
3
- const { resolve } = require('node:path')
4
- const { exceptions: { RequestContractException } } = require('@toa.io/core')
5
- const stage = require('@toa.io/userland/stage')
4
+ import { resolve } from 'node:path'
5
+ import { exceptions } from '@toa.io/core'
6
+ import * as stage from '@toa.io/userland/stage'
6
7
 
7
- const root = resolve(__dirname, '../components')
8
+ const { RequestContractException } = exceptions
9
+
10
+ const root = resolve(import.meta.dirname, '../components')
8
11
 
9
12
  let echo
10
13
  let math
11
14
 
12
- beforeAll(async () => {
15
+ before(async () => {
13
16
  process.env.TOA_DEV = '1'
17
+ process.env.TOA_CONFIGURATION_DEFAULT_ECHO = '{}'
18
+ process.env.TOA_CONFIGURATION_TEA_POTS = '{}'
14
19
 
15
20
  const paths = ['echo', 'math.calculations'].map((rel) => resolve(root, rel))
16
21
 
@@ -20,7 +25,7 @@ beforeAll(async () => {
20
25
  math = await stage.remote('math.calculations')
21
26
  })
22
27
 
23
- afterAll(async () => {
28
+ after(async () => {
24
29
  await stage.shutdown()
25
30
 
26
31
  delete process.env.TOA_DEV
@@ -29,13 +34,15 @@ afterAll(async () => {
29
34
  it('should call endpoint', async () => {
30
35
  const reply = await echo.invoke('signal', {})
31
36
 
32
- expect(reply).toStrictEqual('quack')
37
+ assert.deepStrictEqual(reply, 'quack')
33
38
  })
34
39
 
35
40
  it('should throw on invalid input', async () => {
36
41
  const a = 'not a number'
37
42
  const b = 'neither'
38
43
 
39
- await expect(math.invoke('add', { input: { a, b } }))
40
- .rejects.toBeInstanceOf(RequestContractException)
44
+ await assert.rejects(math.invoke('add', { input: { a, b } }), (error) => {
45
+ assert.ok(error instanceof RequestContractException)
46
+ return true
47
+ })
41
48
  })
@@ -1,51 +1,98 @@
1
- 'use strict'
1
+ import { it, before, after } from 'node:test'
2
+ import assert from 'node:assert/strict'
2
3
 
3
- const { resolve } = require('node:path')
4
- const stage = require('@toa.io/userland/stage')
4
+ import { resolve } from 'node:path'
5
+ import * as boot from '@toa.io/boot'
6
+ import { Connector, Locator } from '@toa.io/core'
7
+ import { timeout } from '@toa.io/generic'
8
+ import * as stage from '@toa.io/userland/stage'
5
9
 
6
- const binding = stage.binding.binding
7
- const root = resolve(__dirname, '../components')
10
+ const root = resolve(import.meta.dirname, '../components')
8
11
 
9
12
  let remote
13
+ let emitter
14
+ let consumer
10
15
 
11
- beforeAll(async () => {
16
+ before(async () => {
12
17
  process.env.TOA_DEV = '1'
18
+ process.env.TOA_CONFIGURATION_TEA_POTS = '{}'
19
+
20
+ // the outbox pumps on a tick; at the default five seconds a test would end before it ran
21
+ process.env.TOA_OUTBOX_INTERVAL = '100'
13
22
 
14
23
  const path = resolve(root, 'tea.pots')
15
24
 
16
25
  await stage.composition([path])
17
26
 
18
27
  remote = await stage.remote('tea.pots')
28
+
29
+ // what `store.orders` would emit, sent the way it would send it
30
+ emitter = await boot.bindings.emit(AMQP, new Locator('orders', 'store'), 'created')
31
+
32
+ await emitter.connect()
19
33
  })
20
34
 
21
- afterAll(async () => {
35
+ after(async () => {
36
+ await consumer?.disconnect()
37
+ await emitter.disconnect()
22
38
  await stage.shutdown()
23
39
 
24
40
  delete process.env.TOA_DEV
41
+ delete process.env.TOA_CONFIGURATION_TEA_POTS
42
+ delete process.env.TOA_OUTBOX_INTERVAL
25
43
  })
26
44
 
27
45
  it('should receive event', async () => {
28
46
  const created = await remote.invoke('transit', { input: { material: 'glass' } })
29
47
  const id = created.id
30
- const payload = { pot: id }
31
- const message = { payload }
32
48
  const request = { query: { id } }
33
49
 
34
- await binding.emit('store.orders.created', message)
50
+ await emitter.emit({ payload: { pot: id } })
51
+
52
+ // the receiver books the pot on delivery, which is asynchronous
53
+ const deadline = Date.now() + 5000
35
54
 
36
- const reply = await remote.invoke('observe', request)
55
+ let reply
37
56
 
38
- expect(reply.booked).toStrictEqual(true)
57
+ do {
58
+ await timeout(50)
59
+
60
+ reply = await remote.invoke('observe', request)
61
+ } while (reply.booked !== true && Date.now() < deadline)
62
+
63
+ assert.deepStrictEqual(reply.booked, true)
39
64
  })
40
65
 
41
66
  it('should emit event', async () => {
42
- expect.assertions(1)
43
-
44
67
  const material = 'steel'
45
68
 
46
- await binding.subscribe('tea.pots.created', (pot) => {
47
- expect(pot.payload.material).toStrictEqual(material)
69
+ const received = new Promise((resolve) => {
70
+ consumer = boot.receive('tea.pots.created', new Subscriber(resolve))
48
71
  })
49
72
 
73
+ consumer = await consumer
74
+
75
+ await consumer.connect()
50
76
  await remote.invoke('transit', { input: { material } })
77
+
78
+ const payload = await received
79
+
80
+ assert.deepStrictEqual(payload.material, material)
51
81
  })
82
+
83
+ /** What the event consumer hands deliveries to. */
84
+ class Subscriber extends Connector {
85
+ #handler
86
+
87
+ constructor(handler) {
88
+ super()
89
+
90
+ this.#handler = handler
91
+ }
92
+
93
+ async receive(message) {
94
+ this.#handler(message.payload)
95
+ }
96
+ }
97
+
98
+ const AMQP = '@toa.io/bindings.amqp'
@@ -1,22 +1,25 @@
1
- 'use strict'
1
+ import { it, before, after } from 'node:test'
2
+ import assert from 'node:assert/strict'
2
3
 
3
- const { resolve } = require('node:path')
4
- const stage = require('@toa.io/userland/stage')
4
+ import { resolve } from 'node:path'
5
+ import * as stage from '@toa.io/userland/stage'
5
6
 
6
- const root = resolve(__dirname, '../components')
7
+ const root = resolve(import.meta.dirname, '../components')
7
8
 
8
- /** @type {toa.core.Component} */
9
+ /** @type {import('@toa.io/core').Component} */
9
10
  let component
10
11
 
11
- beforeAll(async () => {
12
+ before(async () => {
12
13
  process.env.TOA_DEV = '1'
14
+ process.env.TOA_CONFIGURATION_DEFAULT_ECHO = '{}'
15
+ process.env.TOA_CONFIGURATION_TEA_POTS = '{}'
13
16
 
14
17
  const path = resolve(root, 'math.calculations')
15
18
 
16
19
  component = await stage.component(path)
17
20
  })
18
21
 
19
- afterAll(async () => {
22
+ after(async () => {
20
23
  await stage.shutdown()
21
24
 
22
25
  delete process.env.TOA_DEV
@@ -28,6 +31,6 @@ it('should invoke', async () => {
28
31
 
29
32
  const reply = await component.invoke('add', { input: { a, b } })
30
33
 
31
- expect(reply.exception).toBeUndefined()
32
- expect(reply.output).toStrictEqual(a + b)
34
+ assert.strictEqual(reply.exception, undefined)
35
+ assert.deepStrictEqual(reply.output, a + b)
33
36
  })
package/package.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "@toa.io/userland",
3
- "version": "1.0.0-alpha.3",
3
+ "version": "1.0.0-alpha.300",
4
+ "type": "module",
4
5
  "description": "Toa development kit",
5
6
  "homepage": "https://toa.io",
6
7
  "author": {
@@ -16,23 +17,27 @@
16
17
  "url": "https://github.com/toa-io/toa/issues"
17
18
  },
18
19
  "engines": {
19
- "node": ">= 18.0.0"
20
+ "node": ">= 24.0.0"
20
21
  },
21
22
  "publishConfig": {
22
23
  "access": "public"
23
24
  },
24
25
  "main": "src/index.js",
25
- "types": "types/index.d.ts",
26
+ "exports": {
27
+ ".": "./src/index.js",
28
+ "./stage": {
29
+ "types": "./stage/types/index.d.ts",
30
+ "default": "./stage/src/index.js"
31
+ },
32
+ "./package.json": "./package.json"
33
+ },
26
34
  "dependencies": {
27
- "@toa.io/boot": "1.0.0-alpha.3",
28
- "@toa.io/core": "1.0.0-alpha.3",
29
- "@toa.io/filesystem": "1.0.0-alpha.3",
30
- "@toa.io/generic": "1.0.0-alpha.3",
31
- "@toa.io/norm": "1.0.0-alpha.3",
32
- "@toa.io/schemas": "1.0.0-alpha.3",
33
- "@toa.io/storages.null": "0.22.0",
34
- "@toa.io/yaml": "1.0.0-alpha.3",
35
- "tap": "16.3.4"
35
+ "@toa.io/boot": "1.0.0-alpha.300",
36
+ "@toa.io/core": "1.0.0-alpha.300",
37
+ "@toa.io/generic": "1.0.0-alpha.292",
38
+ "@toa.io/norm": "1.0.0-alpha.300",
39
+ "@toa.io/schemas": "1.0.0-alpha.299",
40
+ "@toa.io/storages.null": "1.0.0-alpha.300"
36
41
  },
37
- "gitHead": "e36ac7871fc14d15863aaf8f9bbdeace8bdfa9f0"
42
+ "gitHead": "f91131a9aeb29aa271f177c4055ddcf0cda8c75e"
38
43
  }
package/readme.md CHANGED
@@ -1,8 +1,6 @@
1
1
  # Toa development kit
2
2
 
3
3
  - [Stage](./stage): integration tests framework (Node.js)
4
- - [Samples](./samples): YAML-based declarative tests
5
- - Features[^1]: Gherkin steps definition ([cucumber.js](https://github.com/cucumber/cucumber-js))
6
4
 
7
5
  See [example](./example).
8
6
 
@@ -1,4 +1,5 @@
1
1
  {
2
+ "type": "module",
2
3
  "private": true,
3
4
  "main": "src/index.js",
4
5
  "types": "types/index.d.ts"