@toa.io/boot 1.0.0-alpha.298 → 1.0.0-alpha.299
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 +9 -0
- package/package.json +7 -7
- package/src/bindings/inbound.js +11 -0
- package/src/bindings/index.js +2 -0
- package/src/bindings/outbound.js +10 -0
- package/src/component.js +8 -3
- package/src/extensions/destinations.js +27 -0
- package/src/extensions/index.js +1 -0
- package/src/extensions/storage.js +3 -2
- package/src/host.js +3 -1
- package/src/outbox.js +10 -5
- package/src/storage.js +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,15 @@
|
|
|
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.299](https://github.com/toa-io/toa/compare/v1.0.0-alpha.298...v1.0.0-alpha.299) (2026-09-10)
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
* **bindings.amqp:** a binding carries a channel, addressed by label ([17cf178](https://github.com/toa-io/toa/commit/17cf1782d1c47d033c02f99947b766eb9d45df75))
|
|
11
|
+
* **convergence:** deployments of one context converge ([8a70343](https://github.com/toa-io/toa/commit/8a70343cf6953aab58d4a25bac215508ff8d9a37))
|
|
12
|
+
* **core:** an outbox row is published to destinations ([cfb77b4](https://github.com/toa-io/toa/commit/cfb77b4826ff0f9560769a0996981e143d6525af))
|
|
13
|
+
|
|
14
|
+
|
|
6
15
|
# [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)
|
|
7
16
|
|
|
8
17
|
**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.299",
|
|
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.
|
|
24
|
+
"@toa.io/atomicity": "1.0.0-alpha.299",
|
|
25
|
+
"@toa.io/core": "1.0.0-alpha.299",
|
|
26
|
+
"@toa.io/definitions": "1.0.0-alpha.299",
|
|
27
27
|
"@toa.io/generic": "1.0.0-alpha.292",
|
|
28
|
-
"@toa.io/norm": "1.0.0-alpha.
|
|
29
|
-
"@toa.io/schemas": "1.0.0-alpha.
|
|
28
|
+
"@toa.io/norm": "1.0.0-alpha.299",
|
|
29
|
+
"@toa.io/schemas": "1.0.0-alpha.299",
|
|
30
30
|
"clone-deep": "4.0.1",
|
|
31
31
|
"dotenv": "17.4.2",
|
|
32
32
|
"openspan": "1.0.0-alpha.293"
|
|
33
33
|
},
|
|
34
|
-
"gitHead": "
|
|
34
|
+
"gitHead": "2ba95b16f2cf06f82d6ff8d436761e843e5e4b43"
|
|
35
35
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { factory } from './factory.js'
|
|
2
|
+
|
|
3
|
+
// eslint-disable-next-line max-params
|
|
4
|
+
export const inbound = async (binding, channel, uris, label, sink) => {
|
|
5
|
+
const instance = await factory(binding)
|
|
6
|
+
|
|
7
|
+
if (instance.inbound === undefined)
|
|
8
|
+
throw new Error(`Binding '${binding}' does not consume a channel`)
|
|
9
|
+
|
|
10
|
+
return instance.inbound(channel, uris, label, sink)
|
|
11
|
+
}
|
package/src/bindings/index.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
export { broadcast } from './broadcast.js'
|
|
2
2
|
export { consume } from './consume.js'
|
|
3
3
|
export { emit } from './emit.js'
|
|
4
|
+
export { inbound } from './inbound.js'
|
|
5
|
+
export { outbound } from './outbound.js'
|
|
4
6
|
export { produce } from './produce.js'
|
|
5
7
|
export { receive } from './receive.js'
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { factory } from './factory.js'
|
|
2
|
+
|
|
3
|
+
export const outbound = async (binding, channel, uris) => {
|
|
4
|
+
const instance = await factory(binding)
|
|
5
|
+
|
|
6
|
+
if (instance.outbound === undefined)
|
|
7
|
+
throw new Error(`Binding '${binding}' does not publish a channel`)
|
|
8
|
+
|
|
9
|
+
return instance.outbound(channel, uris)
|
|
10
|
+
}
|
package/src/component.js
CHANGED
|
@@ -19,12 +19,17 @@ const create = async (manifest, locator) => {
|
|
|
19
19
|
|
|
20
20
|
await boot.extensions.load(manifest)
|
|
21
21
|
|
|
22
|
-
// the storage is told whether there will be an outbox, so
|
|
22
|
+
// the storage is told whether there will be an outbox, so what it publishes to comes first:
|
|
23
|
+
// its own events, and whatever an extension adds
|
|
23
24
|
const events = boot.events(manifest)
|
|
24
|
-
const
|
|
25
|
+
const destinations = await boot.extensions.destinations(manifest)
|
|
26
|
+
const storage = await boot.storage(
|
|
27
|
+
manifest,
|
|
28
|
+
events !== undefined || destinations.length > 0
|
|
29
|
+
)
|
|
25
30
|
const context = await boot.context(manifest)
|
|
26
31
|
const emission = await boot.emission(events, locator, context)
|
|
27
|
-
const outbox = boot.outbox(manifest, storage, emission)
|
|
32
|
+
const outbox = boot.outbox(manifest, storage, emission, destinations)
|
|
28
33
|
|
|
29
34
|
let state
|
|
30
35
|
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { instance } from './resolve.js'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Where a committed state change of this component goes, beside its own events. An extension
|
|
5
|
+
* that contributes one gives the component an outbox whether or not it declares an event, so
|
|
6
|
+
* this is read before the storage is made.
|
|
7
|
+
*
|
|
8
|
+
* @param {toa.norm.Component} manifest
|
|
9
|
+
* @returns {Promise<import('@toa.io/core/types').outbox.Destination[]>}
|
|
10
|
+
*/
|
|
11
|
+
export const destinations = async (manifest) => {
|
|
12
|
+
const destinations = []
|
|
13
|
+
|
|
14
|
+
if (manifest.extensions === undefined) return destinations
|
|
15
|
+
|
|
16
|
+
for (const [name, declaration] of Object.entries(manifest.extensions)) {
|
|
17
|
+
const factory = instance(name, manifest.path)
|
|
18
|
+
|
|
19
|
+
if (factory.destination === undefined) continue
|
|
20
|
+
|
|
21
|
+
const destination = await factory.destination(manifest.locator, declaration, manifest)
|
|
22
|
+
|
|
23
|
+
if (destination !== undefined) destinations.push(destination)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return destinations
|
|
27
|
+
}
|
package/src/extensions/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export { aspects } from './aspects.js'
|
|
2
2
|
export { component } from './component.js'
|
|
3
3
|
export { context } from './context.js'
|
|
4
|
+
export { destinations } from './destinations.js'
|
|
4
5
|
export { emitter } from './emitter.js'
|
|
5
6
|
export { load } from './load.js'
|
|
6
7
|
export { manage } from './manage.js'
|
|
@@ -2,13 +2,14 @@ import { instances } from './instances.js'
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* @param {import('@toa.io/core/types').storages.Storage} storage
|
|
5
|
+
* @param {import('@toa.io/core').Locator} locator whose storage it is
|
|
5
6
|
* @returns {import('@toa.io/core/types').storages.Storage}
|
|
6
7
|
*/
|
|
7
|
-
export const storage = (storage) => {
|
|
8
|
+
export const storage = (storage, locator) => {
|
|
8
9
|
let decorated = storage
|
|
9
10
|
|
|
10
11
|
for (const factory of Object.values(instances)) {
|
|
11
|
-
if (factory.storage !== undefined) decorated = factory.storage(decorated)
|
|
12
|
+
if (factory.storage !== undefined) decorated = factory.storage(decorated, locator)
|
|
12
13
|
}
|
|
13
14
|
|
|
14
15
|
return decorated
|
package/src/host.js
CHANGED
package/src/outbox.js
CHANGED
|
@@ -3,15 +3,20 @@ import { Outbox } from '@toa.io/core'
|
|
|
3
3
|
import * as boot from './index.js'
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
|
-
* A component with
|
|
7
|
-
*
|
|
6
|
+
* A component with nothing to publish to has no outbox — the static check that keeps the
|
|
7
|
+
* common case free of a transaction. Its own events are one destination; an extension may
|
|
8
|
+
* contribute others, and a component that declares no event at all has an outbox where one of
|
|
9
|
+
* those is there.
|
|
8
10
|
*
|
|
9
11
|
* @param {toa.norm.Component} manifest
|
|
10
12
|
* @param {import('@toa.io/core/types').storages.Storage} [storage]
|
|
11
13
|
* @param {import('@toa.io/core').Emission} [emission]
|
|
14
|
+
* @param {import('@toa.io/core/types').outbox.Destination[]} [contributed]
|
|
12
15
|
*/
|
|
13
|
-
export const outbox = (manifest, storage, emission) => {
|
|
14
|
-
|
|
16
|
+
export const outbox = (manifest, storage, emission, contributed = []) => {
|
|
17
|
+
const destinations = emission === undefined ? contributed : [emission, ...contributed]
|
|
15
18
|
|
|
16
|
-
|
|
19
|
+
if (destinations.length === 0) return
|
|
20
|
+
|
|
21
|
+
return new Outbox(destinations, storage, boot.atomicity(manifest.locator.id), {})
|
|
17
22
|
}
|
package/src/storage.js
CHANGED
|
@@ -33,7 +33,7 @@ export const storage = async (manifest, outbox) => {
|
|
|
33
33
|
`which storage '${manifest.entity.storage}' does not apply`
|
|
34
34
|
)
|
|
35
35
|
|
|
36
|
-
return extensions.storage(storage)
|
|
36
|
+
return extensions.storage(storage, manifest.locator)
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
async function load(component) {
|