@toa.io/boot 1.0.0-alpha.310 → 1.0.0-alpha.312
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/CHANGELOG.md +17 -0
- package/package.json +8 -8
- package/src/bindings/consume.js +17 -5
- package/src/bindings/produce.js +20 -3
- package/src/call.js +8 -2
- package/src/component.js +4 -0
- package/src/composition.js +4 -0
- package/src/operation.js +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,23 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
# [1.0.0-alpha.312](https://github.com/toa-io/toa/compare/v1.0.0-alpha.311...v1.0.0-alpha.312) (2026-09-18)
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
* **boot:** offer a streamed endpoint to the bindings that carry a stream ([0099b4e](https://github.com/toa-io/toa/commit/0099b4e12bff4ce5dba2d0098f0b8c6a18fff2c5))
|
|
11
|
+
* **boot:** tell a producer which of its endpoints take a stream ([6383adc](https://github.com/toa-io/toa/commit/6383adcebf38d889db80d8cbd19fe38f3ba4eb2e))
|
|
12
|
+
* **core:** refuse a call that carries no stream where the operation takes one ([fb78e02](https://github.com/toa-io/toa/commit/fb78e02fa620b15f6aa7bac184dd8a6ede923150))
|
|
13
|
+
* **core:** require the property that carries a stream, and refuse a task that carries one ([fdc7e6b](https://github.com/toa-io/toa/commit/fdc7e6b345ee22b030a52f1fda0e91e6bf63a392))
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
# [1.0.0-alpha.311](https://github.com/toa-io/toa/compare/v1.0.0-alpha.310...v1.0.0-alpha.311) (2026-09-17)
|
|
17
|
+
|
|
18
|
+
### Features
|
|
19
|
+
|
|
20
|
+
* read the scope of a process once, as it boots ([0d65de5](https://github.com/toa-io/toa/commit/0d65de58ffc655ff872b8e66f95c5609ada3370a))
|
|
21
|
+
|
|
22
|
+
|
|
6
23
|
# [1.0.0-alpha.310](https://github.com/toa-io/toa/compare/v1.0.0-alpha.309...v1.0.0-alpha.310) (2026-09-16)
|
|
7
24
|
|
|
8
25
|
**Note:** Version bump only for package @toa.io/boot
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@toa.io/boot",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.312",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Toa Boot",
|
|
6
6
|
"author": "temich <tema.gurtovoy@gmail.com>",
|
|
@@ -21,15 +21,15 @@
|
|
|
21
21
|
"test": "echo \"Error: run tests from root\" && exit 1"
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@toa.io/atomicity": "1.0.0-alpha.
|
|
25
|
-
"@toa.io/core": "1.0.0-alpha.
|
|
26
|
-
"@toa.io/definitions": "1.0.0-alpha.
|
|
27
|
-
"@toa.io/generic": "1.0.0-alpha.
|
|
28
|
-
"@toa.io/norm": "1.0.0-alpha.
|
|
29
|
-
"@toa.io/schemas": "1.0.0-alpha.
|
|
24
|
+
"@toa.io/atomicity": "1.0.0-alpha.312",
|
|
25
|
+
"@toa.io/core": "1.0.0-alpha.312",
|
|
26
|
+
"@toa.io/definitions": "1.0.0-alpha.312",
|
|
27
|
+
"@toa.io/generic": "1.0.0-alpha.311",
|
|
28
|
+
"@toa.io/norm": "1.0.0-alpha.312",
|
|
29
|
+
"@toa.io/schemas": "1.0.0-alpha.311",
|
|
30
30
|
"clone-deep": "4.0.1",
|
|
31
31
|
"dotenv": "17.4.2",
|
|
32
32
|
"openspan": "1.0.0-alpha.305"
|
|
33
33
|
},
|
|
34
|
-
"gitHead": "
|
|
34
|
+
"gitHead": "3cdff9b9779eeb6ae83913fefc0b502a10a0236a"
|
|
35
35
|
}
|
package/src/bindings/consume.js
CHANGED
|
@@ -1,9 +1,21 @@
|
|
|
1
1
|
import { LOOP } from './constants.js'
|
|
2
2
|
import { factory } from './factory.js'
|
|
3
|
+
import { carries } from './produce.js'
|
|
3
4
|
|
|
4
|
-
export const consume = async (locator, endpoint, bindings) =>
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
export const consume = async (locator, endpoint, bindings, streamed = false) => {
|
|
6
|
+
const declared = [LOOP].concat(bindings)
|
|
7
|
+
const carrying = streamed ? await filter(declared) : declared
|
|
8
|
+
|
|
9
|
+
return await Promise.all(
|
|
10
|
+
carrying.map(async (binding) => (await factory(binding)).consumer(locator, endpoint))
|
|
9
11
|
)
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/** A call that carries a stream is handed to nothing that cannot carry one. */
|
|
15
|
+
const filter = async (bindings) => {
|
|
16
|
+
const carrying = []
|
|
17
|
+
|
|
18
|
+
for (const binding of bindings) if (await carries(binding)) carrying.push(binding)
|
|
19
|
+
|
|
20
|
+
return carrying
|
|
21
|
+
}
|
package/src/bindings/produce.js
CHANGED
|
@@ -6,11 +6,13 @@ export const produce = async (component, operations) => {
|
|
|
6
6
|
const local = []
|
|
7
7
|
const other = []
|
|
8
8
|
const stateful = addressed(operations)
|
|
9
|
+
const streams = streamed(operations)
|
|
9
10
|
|
|
10
|
-
for (const [binding, endpoints] of group(operations)) {
|
|
11
|
+
for (const [binding, endpoints] of await group(operations)) {
|
|
11
12
|
const made = await factory(binding)
|
|
12
13
|
const carried = stateful.filter((endpoint) => endpoints.includes(endpoint))
|
|
13
|
-
const
|
|
14
|
+
const carries = streams.filter((endpoint) => endpoints.includes(endpoint))
|
|
15
|
+
const producer = made.producer(component.locator, endpoints, component, carried, carries)
|
|
14
16
|
const { properties } = (await definition(binding)).module
|
|
15
17
|
|
|
16
18
|
if (properties.local === true) local.push(producer)
|
|
@@ -20,6 +22,14 @@ export const produce = async (component, operations) => {
|
|
|
20
22
|
return { local, other }
|
|
21
23
|
}
|
|
22
24
|
|
|
25
|
+
/** The endpoints that take one of their input properties as a stream. */
|
|
26
|
+
const streamed = (operations) =>
|
|
27
|
+
operations === undefined
|
|
28
|
+
? []
|
|
29
|
+
: Object.entries(operations)
|
|
30
|
+
.filter(([, operation]) => operation.stream !== undefined)
|
|
31
|
+
.map(([endpoint]) => endpoint)
|
|
32
|
+
|
|
23
33
|
/** The endpoints that take addressed calls only. */
|
|
24
34
|
const addressed = (operations) =>
|
|
25
35
|
operations === undefined
|
|
@@ -29,7 +39,7 @@ const addressed = (operations) =>
|
|
|
29
39
|
.map(([endpoint]) => endpoint)
|
|
30
40
|
|
|
31
41
|
/** The endpoints each binding carries, as entries. */
|
|
32
|
-
const group = (operations) => {
|
|
42
|
+
const group = async (operations) => {
|
|
33
43
|
const map = {}
|
|
34
44
|
|
|
35
45
|
if (operations !== undefined)
|
|
@@ -40,6 +50,9 @@ const group = (operations) => {
|
|
|
40
50
|
: [LOOP].concat(operation.bindings)
|
|
41
51
|
|
|
42
52
|
for (const binding of bindings) {
|
|
53
|
+
// an endpoint that takes a stream is served by the bindings that carry one, and by no other
|
|
54
|
+
if (operation.stream !== undefined && !(await carries(binding))) continue
|
|
55
|
+
|
|
43
56
|
if (!map[binding]) map[binding] = []
|
|
44
57
|
|
|
45
58
|
map[binding].push(endpoint)
|
|
@@ -48,3 +61,7 @@ const group = (operations) => {
|
|
|
48
61
|
|
|
49
62
|
return Object.entries(map)
|
|
50
63
|
}
|
|
64
|
+
|
|
65
|
+
/** Whether a binding carries a call whose input holds a stream, which only its module says. */
|
|
66
|
+
export const carries = async (binding) =>
|
|
67
|
+
(await definition(binding)).module.properties.streams === true
|
package/src/call.js
CHANGED
|
@@ -4,7 +4,12 @@ import * as boot from './index.js'
|
|
|
4
4
|
|
|
5
5
|
// eslint-disable-next-line max-params
|
|
6
6
|
export const call = async (locator, endpoint, definition, entity, source) => {
|
|
7
|
-
const consumers = await boot.bindings.consume(
|
|
7
|
+
const consumers = await boot.bindings.consume(
|
|
8
|
+
locator,
|
|
9
|
+
endpoint,
|
|
10
|
+
definition.bindings,
|
|
11
|
+
definition.stream !== undefined
|
|
12
|
+
)
|
|
8
13
|
const transmission = new Transmission(consumers)
|
|
9
14
|
const contract = boot.contract.request(definition, entity)
|
|
10
15
|
|
|
@@ -23,6 +28,7 @@ export const call = async (locator, endpoint, definition, entity, source) => {
|
|
|
23
28
|
`${locator.id}.${endpoint}`,
|
|
24
29
|
source,
|
|
25
30
|
stateful,
|
|
26
|
-
readable
|
|
31
|
+
readable,
|
|
32
|
+
definition.stream
|
|
27
33
|
)
|
|
28
34
|
}
|
package/src/component.js
CHANGED
|
@@ -17,6 +17,10 @@ const create = async (manifest, locator) => {
|
|
|
17
17
|
// component is imported: nothing of it is left in `process.env` for that module to read
|
|
18
18
|
environment.absorb()
|
|
19
19
|
|
|
20
|
+
// the suffix is what it is now, `.env` having been read: whatever this process sets for the
|
|
21
|
+
// processes it starts later does not rename what it has
|
|
22
|
+
environment.suffix()
|
|
23
|
+
|
|
20
24
|
await boot.extensions.load(manifest)
|
|
21
25
|
|
|
22
26
|
// the storage is told whether there will be an outbox, so what it publishes to comes first:
|
package/src/composition.js
CHANGED
|
@@ -11,6 +11,10 @@ export async function composition(paths, options) {
|
|
|
11
11
|
// component is imported: nothing of it is left in `process.env` for that module to read
|
|
12
12
|
environment.absorb()
|
|
13
13
|
|
|
14
|
+
// the suffix is what it is now, `.env` having been read: whatever this process sets for the
|
|
15
|
+
// processes it starts later does not rename what it has
|
|
16
|
+
environment.suffix()
|
|
17
|
+
|
|
14
18
|
options = Object.assign({}, options)
|
|
15
19
|
|
|
16
20
|
return span('boot composition', async () => {
|
package/src/operation.js
CHANGED
|
@@ -21,7 +21,7 @@ export async function operation(
|
|
|
21
21
|
const cascade = await boot.cascade(manifest, endpoint, definition, context, preflight)
|
|
22
22
|
const reply = boot.contract.reply(definition.output, definition.errors)
|
|
23
23
|
const input = definition.input
|
|
24
|
-
const request = boot.contract.request({ input }, manifest.entity)
|
|
24
|
+
const request = boot.contract.request({ input, stream: definition.stream }, manifest.entity)
|
|
25
25
|
const contracts = { reply, request }
|
|
26
26
|
|
|
27
27
|
const query =
|