@toa.io/userland 1.0.0-alpha.9 → 1.0.0-alpha.92

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@toa.io/userland",
3
- "version": "1.0.0-alpha.9",
3
+ "version": "1.0.0-alpha.92",
4
4
  "description": "Toa development kit",
5
5
  "homepage": "https://toa.io",
6
6
  "author": {
@@ -16,7 +16,7 @@
16
16
  "url": "https://github.com/toa-io/toa/issues"
17
17
  },
18
18
  "engines": {
19
- "node": ">= 18.0.0"
19
+ "node": ">= 20.0.0"
20
20
  },
21
21
  "publishConfig": {
22
22
  "access": "public"
@@ -24,15 +24,14 @@
24
24
  "main": "src/index.js",
25
25
  "types": "types/index.d.ts",
26
26
  "dependencies": {
27
- "@toa.io/boot": "1.0.0-alpha.9",
28
- "@toa.io/core": "1.0.0-alpha.9",
29
- "@toa.io/filesystem": "1.0.0-alpha.9",
30
- "@toa.io/generic": "1.0.0-alpha.9",
31
- "@toa.io/norm": "1.0.0-alpha.9",
32
- "@toa.io/schemas": "1.0.0-alpha.9",
27
+ "@toa.io/boot": "1.0.0-alpha.92",
28
+ "@toa.io/core": "1.0.0-alpha.92",
29
+ "@toa.io/filesystem": "1.0.0-alpha.63",
30
+ "@toa.io/generic": "1.0.0-alpha.63",
31
+ "@toa.io/norm": "1.0.0-alpha.92",
32
+ "@toa.io/schemas": "1.0.0-alpha.63",
33
33
  "@toa.io/storages.null": "0.22.0",
34
- "@toa.io/yaml": "1.0.0-alpha.9",
35
- "tap": "16.3.4"
34
+ "@toa.io/yaml": "1.0.0-alpha.63"
36
35
  },
37
- "gitHead": "017a3fa22e8c60654c240f8e55908773d44d4ed1"
36
+ "gitHead": "975ee5af6194354efb6dd8c646b22a89c4d96f7a"
38
37
  }
@@ -5,8 +5,6 @@ const { state } = require('./state')
5
5
 
6
6
  /** @type {toa.stage.Component} */
7
7
  const component = async (path, options) => {
8
- options = Object.assign({}, DEFAULTS, options)
9
-
10
8
  const manifest = await boot.manifest(path, options)
11
9
  const component = await boot.component(manifest)
12
10
 
@@ -17,7 +15,4 @@ const component = async (path, options) => {
17
15
  return component
18
16
  }
19
17
 
20
- const binding = require.resolve('./binding')
21
- const DEFAULTS = { bindings: [binding] }
22
-
23
18
  exports.component = component
@@ -3,12 +3,8 @@
3
3
  const boot = require('@toa.io/boot')
4
4
  const { state } = require('./state')
5
5
 
6
- const binding = require.resolve('./binding')
7
-
8
6
  /** @type {toa.stage.Composition} */
9
7
  const composition = async (paths, options) => {
10
- options ??= { bindings: [binding] }
11
-
12
8
  const composition = await boot.composition(paths, options)
13
9
 
14
10
  await composition.connect()
@@ -6,7 +6,6 @@ const { composition } = require('./composition')
6
6
  const { service } = require('./service')
7
7
  const { remote } = require('./remote')
8
8
  const { shutdown } = require('./shutdown')
9
- const binding = require('./binding')
10
9
 
11
10
  exports.manifest = manifest
12
11
  exports.component = component
@@ -15,4 +14,3 @@ exports.compose = composition
15
14
  exports.serve = service
16
15
  exports.remote = remote
17
16
  exports.shutdown = shutdown
18
- exports.binding = binding
@@ -1,7 +1,6 @@
1
1
  'use strict'
2
2
 
3
3
  const { state } = require('./state')
4
- const { binding } = require('./binding')
5
4
 
6
5
  /** @type {toa.stage.Shutdown} */
7
6
  const shutdown = async () => {
@@ -14,7 +13,6 @@ const shutdown = async () => {
14
13
  await Promise.all(disconnections)
15
14
 
16
15
  state.reset()
17
- binding.reset()
18
16
  }
19
17
 
20
18
  exports.shutdown = shutdown
@@ -25,14 +25,3 @@ it('should boot composition', async () => {
25
25
 
26
26
  expect(composition.connect).toHaveBeenCalled()
27
27
  })
28
-
29
- it('should override bindings', async () => {
30
- await stage.composition(paths)
31
-
32
- const path = require.resolve('../src/binding')
33
-
34
- /** @type {toa.boot.composition.Options} */
35
- const options = { bindings: [path] }
36
-
37
- expect(mock.boot.composition.mock.calls[0][1]).toStrictEqual(options)
38
- })
@@ -4,16 +4,13 @@ const { generate } = require('randomstring')
4
4
 
5
5
  const mock = {
6
6
  boot: require('./boot.mock'),
7
- state: require('./state.mock'),
8
- binding: require('./binding.mock')
7
+ state: require('./state.mock')
9
8
  }
10
9
 
11
10
  jest.mock('@toa.io/boot', () => mock.boot)
12
11
  jest.mock('../src/state', () => mock.state)
13
- jest.mock('../src/binding', () => mock.binding)
14
12
 
15
13
  const { state } = require('../src/state')
16
- const { binding } = require('../src/binding')
17
14
  const stage = require('../')
18
15
 
19
16
  beforeEach(() => {
@@ -58,9 +55,3 @@ it('should reset state', async () => {
58
55
 
59
56
  expect(state.reset).toHaveBeenCalled()
60
57
  })
61
-
62
- it('should reset binding', async () => {
63
- await stage.shutdown()
64
-
65
- expect(binding.reset).toHaveBeenCalled()
66
- })
@@ -15,5 +15,3 @@ export function serve (ref: string): Promise<_core.Component>
15
15
  export function remote (id: string): Promise<_core.Component>
16
16
 
17
17
  export function shutdown (): Promise<void>
18
-
19
- export * as binding from './binding'
@@ -1,50 +0,0 @@
1
- 'use strict'
2
-
3
- /**
4
- * @implements {toa.stage.binding.Binding}
5
- */
6
- class Binding {
7
- /** @type {Record<string, function[]>} */
8
- #callbacks = {}
9
-
10
- /** @type {Record<string, function>} */
11
- #producers = {}
12
-
13
- async subscribe (label, callback) {
14
- if (this.#callbacks[label] === undefined) this.#callbacks[label] = []
15
-
16
- this.#callbacks[label].push(callback)
17
- }
18
-
19
- async emit (label, message) {
20
- if (!(label in this.#callbacks)) return
21
-
22
- const callbacks = this.#callbacks[label]
23
- const promises = callbacks.map((callback) => callback(message))
24
-
25
- await Promise.all(promises)
26
- }
27
-
28
- async reply (label, produce) {
29
- if (label in this.#producers) throw new Error(`Label '${label}' is already bound`)
30
-
31
- this.#producers[label] = produce
32
- }
33
-
34
- async request (label, request) {
35
- if (!(label in this.#producers)) throw new Error(`Label '${label}' is not bound`)
36
-
37
- const produce = this.#producers[label]
38
-
39
- return produce(request)
40
- }
41
-
42
- reset () {
43
- this.#callbacks = {}
44
- this.#producers = {}
45
- }
46
- }
47
-
48
- const binding = new Binding()
49
-
50
- exports.binding = binding
@@ -1,30 +0,0 @@
1
- 'use strict'
2
-
3
- const { Connector } = require('@toa.io/core')
4
-
5
- const { binding } = require('./binding')
6
- const { label } = require('./label')
7
-
8
- /**
9
- * @implements {toa.core.bindings.Consumer}
10
- */
11
- class Consumer extends Connector {
12
- /** @type {string} */
13
- #label
14
-
15
- /**
16
- * @param {toa.core.Locator} locator
17
- * @param {string} endpoint
18
- */
19
- constructor (locator, endpoint) {
20
- super()
21
-
22
- this.#label = label(locator, endpoint)
23
- }
24
-
25
- async request (request) {
26
- return binding.request(this.#label, request)
27
- }
28
- }
29
-
30
- exports.Consumer = Consumer
@@ -1,26 +0,0 @@
1
- 'use strict'
2
-
3
- const { Connector } = require('@toa.io/core')
4
-
5
- const { binding } = require('./binding')
6
- const { label } = require('./label')
7
-
8
- /**
9
- * @implements {toa.core.bindings.Emitter}
10
- */
11
- class Emitter extends Connector {
12
- /** @type {string} */
13
- #label
14
-
15
- constructor (locator, endpoint) {
16
- super()
17
-
18
- this.#label = label(locator, endpoint)
19
- }
20
-
21
- async emit (message) {
22
- await binding.emit(this.#label, message)
23
- }
24
- }
25
-
26
- exports.Emitter = Emitter
@@ -1,49 +0,0 @@
1
- 'use strict'
2
-
3
- const { Emitter } = require('./emitter')
4
- const { Receiver } = require('./receiver')
5
- const { Consumer } = require('./consumer')
6
- const { Producer } = require('./producer')
7
-
8
- class Factory {
9
- /**
10
- * @param {toa.core.Locator} source
11
- * @param {string} label
12
- * @param {string} group
13
- * @param {toa.core.Receiver} receiver
14
- * @returns {toa.core.Connector}
15
- */
16
- receiver (source, label, group, receiver) {
17
- return new Receiver(label, receiver)
18
- }
19
-
20
- /**
21
- * @param {toa.core.Locator} locator
22
- * @param {string} label
23
- * @returns {toa.core.bindings.Emitter}
24
- */
25
- emitter (locator, label) {
26
- return new Emitter(locator, label)
27
- }
28
-
29
- /**
30
- * @param {toa.core.Locator} locator
31
- * @param {string} endpoint
32
- * @returns {toa.core.bindings.Consumer}
33
- */
34
- consumer (locator, endpoint) {
35
- return new Consumer(locator, endpoint)
36
- }
37
-
38
- /**
39
- * @param {toa.core.Locator} locator
40
- * @param {string[]} endpoints
41
- * @param {toa.core.Component} component
42
- * @returns {toa.core.Connector}
43
- */
44
- producer (locator, endpoints, component) {
45
- return new Producer(locator, endpoints, component)
46
- }
47
- }
48
-
49
- exports.Factory = Factory
@@ -1,10 +0,0 @@
1
- 'use strict'
2
-
3
- const { Factory } = require('./factory')
4
- const { binding } = require('./binding')
5
-
6
- const properties = { async: true }
7
-
8
- exports.properties = properties
9
- exports.Factory = Factory
10
- exports.binding = binding
@@ -1,12 +0,0 @@
1
- 'use strict'
2
-
3
- /**
4
- * @param {toa.core.Locator} locator
5
- * @param {string} endpoint
6
- * @returns {string}
7
- */
8
- const label = (locator, endpoint) => {
9
- return locator.id + '.' + endpoint
10
- }
11
-
12
- exports.label = label
@@ -1,43 +0,0 @@
1
- 'use strict'
2
-
3
- const { Connector } = require('@toa.io/core')
4
-
5
- const { binding } = require('./binding')
6
- const { label } = require('./label')
7
-
8
- /**
9
- * @implements {toa.core.Connector}
10
- */
11
- class Producer extends Connector {
12
- /** @type {toa.core.Locator} */
13
- #locator
14
-
15
- /** @type {string[]} */
16
- #endpoints
17
-
18
- /** @type {toa.core.Component} */
19
- #component
20
-
21
- /**
22
- * @param {toa.core.Locator} locator
23
- * @param {string[]} endpoints
24
- * @param {toa.core.Component} component
25
- */
26
- constructor (locator, endpoints, component) {
27
- super()
28
-
29
- this.#locator = locator
30
- this.#endpoints = endpoints
31
- this.#component = component
32
- }
33
-
34
- async open () {
35
- for (const endpoint of this.#endpoints) {
36
- const command = label(this.#locator, endpoint)
37
-
38
- await binding.reply(command, (request) => this.#component.invoke(endpoint, request))
39
- }
40
- }
41
- }
42
-
43
- exports.Producer = Producer
@@ -1,34 +0,0 @@
1
- 'use strict'
2
-
3
- const { Connector } = require('@toa.io/core')
4
-
5
- const { binding } = require('./binding')
6
-
7
- /**
8
- * @implements {toa.core.Connector}
9
- */
10
- class Receiver extends Connector {
11
- /** @type {string} */
12
- #label
13
-
14
- /** @type {toa.core.Receiver} */
15
- #receiver
16
-
17
- /**
18
- * @param {toa.core.Locator} locator
19
- * @param {string} label
20
- * @param {toa.core.Receiver} receiver
21
- */
22
- constructor (label, receiver) {
23
- super()
24
-
25
- this.#label = label
26
- this.#receiver = receiver
27
- }
28
-
29
- async open () {
30
- await binding.subscribe(this.#label, (message) => this.#receiver.receive(message))
31
- }
32
- }
33
-
34
- exports.Receiver = Receiver
@@ -1,15 +0,0 @@
1
- 'use strict'
2
-
3
- const { properties, binding, Factory } = require('../../src').binding
4
-
5
- it('should be async', async () => {
6
- expect(properties.async).toStrictEqual(true)
7
- })
8
-
9
- it('should export Factory', async () => {
10
- expect(Factory).toBeDefined()
11
- })
12
-
13
- it('should export binding instance', async () => {
14
- expect(binding).toBeDefined()
15
- })
@@ -1,52 +0,0 @@
1
- 'use strict'
2
-
3
- const { generate } = require('randomstring')
4
- const { Connector, Locator } = require('@toa.io/core')
5
-
6
- const { binding, Factory } = require('../../src/binding')
7
-
8
- const factory = new Factory()
9
-
10
- it('should expose consumers factory', async () => {
11
- expect(factory.consumer).toBeDefined()
12
- })
13
-
14
- /** @type {toa.core.bindings.Consumer} */
15
- let consumer
16
-
17
- /** @type {toa.core.Locator} */
18
- let locator
19
-
20
- /** @type {string} */
21
- let label
22
-
23
- const endpoint = generate()
24
-
25
- beforeEach(() => {
26
- jest.clearAllMocks()
27
- binding.reset()
28
-
29
- const namespace = generate()
30
- const name = generate()
31
-
32
- locator = new Locator(name, namespace)
33
- label = locator.id + '.' + endpoint
34
- consumer = factory.consumer(locator, endpoint)
35
- })
36
-
37
- it('should return Connector', async () => {
38
- expect(consumer).toBeInstanceOf(Connector)
39
- })
40
-
41
- it('should return reply', async () => {
42
- const request = generate()
43
- const reply = generate()
44
- const call = jest.fn(async () => reply)
45
-
46
- await binding.reply(label, call)
47
-
48
- const received = await consumer.request(request)
49
-
50
- expect(call).toHaveBeenCalledWith(request)
51
- expect(received).toStrictEqual(reply)
52
- })
@@ -1,54 +0,0 @@
1
- 'use strict'
2
-
3
- const { generate } = require('randomstring')
4
- const { Locator, Connector } = require('@toa.io/core')
5
-
6
- const { binding, Factory } = require('../../src/binding')
7
-
8
- const factory = new Factory()
9
-
10
- it('should expose emitters factory', async () => {
11
- expect(factory.emitter).toBeDefined()
12
- })
13
-
14
- /** @type {toa.core.bindings.Emitter} */
15
- let emitter
16
-
17
- /** @type {string} */
18
- let label
19
-
20
- /** @type {toa.core.Locator} */
21
- let locator
22
-
23
- const endpoint = generate()
24
-
25
- beforeEach(() => {
26
- jest.clearAllMocks()
27
- binding.reset()
28
-
29
- const namespace = generate()
30
- const name = generate()
31
-
32
- locator = new Locator(name, namespace)
33
- label = locator.id + '.' + endpoint
34
- emitter = factory.emitter(locator, endpoint)
35
- })
36
-
37
- it('should return Connector', async () => {
38
- expect(emitter).toBeInstanceOf(Connector)
39
- })
40
-
41
- it('should call receiver', async () => {
42
- const callback = jest.fn(async () => undefined)
43
-
44
- await binding.subscribe(label, callback)
45
-
46
- const payload = { [generate()]: generate() }
47
-
48
- /** @type {toa.core.Message} */
49
- const message = { payload }
50
-
51
- await emitter.emit(message)
52
-
53
- expect(callback).toHaveBeenCalledWith(message)
54
- })
@@ -1,10 +0,0 @@
1
- 'use strict'
2
-
3
- const { generate } = require('randomstring')
4
-
5
- const endpoints = [generate(), generate()]
6
- const invoke = jest.fn(async () => generate())
7
- const producer = /** @type {jest.MockedObject<toa.core.Component>} */ { invoke }
8
-
9
- exports.endpoints = endpoints
10
- exports.producer = producer
@@ -1,49 +0,0 @@
1
- 'use strict'
2
-
3
- const { generate } = require('randomstring')
4
- const { Locator, Connector } = require('@toa.io/core')
5
- const { sample } = require('@toa.io/generic')
6
-
7
- const fixtures = require('./producer.fixtures')
8
- const { binding, Factory } = require('../../src/binding')
9
-
10
- const factory = new Factory()
11
-
12
- it('should expose producers factory', async () => {
13
- expect(factory.producer).toBeDefined()
14
- })
15
-
16
- /** @type {toa.core.Connector} */
17
- let producer
18
-
19
- /** @type {toa.core.Locator} */
20
- let locator
21
-
22
- beforeEach(async () => {
23
- jest.clearAllMocks()
24
- binding.reset()
25
-
26
- const namespace = generate()
27
- const name = generate()
28
-
29
- locator = new Locator(name, namespace)
30
- producer = factory.producer(locator, fixtures.endpoints, fixtures.producer)
31
-
32
- await producer.connect()
33
- })
34
-
35
- it('should return Connector', async () => {
36
- expect(producer).toBeInstanceOf(Connector)
37
- })
38
-
39
- it('should return result', async () => {
40
- const endpoint = sample(fixtures.endpoints)
41
- const label = locator.id + '.' + endpoint
42
- const request = { [generate()]: generate() }
43
-
44
- const reply = await binding.request(label, request)
45
-
46
- expect(fixtures.producer.invoke).toHaveBeenCalledWith(endpoint, request)
47
-
48
- expect(reply).toStrictEqual(await fixtures.producer.invoke.mock.results[0].value)
49
- })
@@ -1,7 +0,0 @@
1
- 'use strict'
2
-
3
- const receiver = /** @type {jest.MockedObject<toa.core.Receiver>} */ {
4
- receive: jest.fn(async () => undefined)
5
- }
6
-
7
- exports.receiver = receiver
@@ -1,54 +0,0 @@
1
- 'use strict'
2
-
3
- const { generate } = require('randomstring')
4
- const { Locator, Connector } = require('@toa.io/core')
5
-
6
- const fixtures = require('./receiver.fixtures')
7
- const { binding, Factory } = require('../../src/binding')
8
-
9
- const factory = new Factory()
10
-
11
- it('should expose receivers factory', async () => {
12
- expect(factory.receiver).toBeDefined()
13
- })
14
-
15
- /** @type {toa.core.Connector} */
16
- let receiver
17
-
18
- /** @type {toa.core.Locator} */
19
- let locator
20
-
21
- /** @type {string} */
22
- let label
23
-
24
- const group = generate()
25
- const endpoint = generate()
26
-
27
- beforeEach(async () => {
28
- jest.clearAllMocks()
29
- binding.reset()
30
-
31
- const namespace = generate()
32
- const name = generate()
33
-
34
- locator = new Locator(name, namespace)
35
- label = locator.id + '.' + endpoint
36
- receiver = factory.receiver(locator, label, group, fixtures.receiver)
37
-
38
- await receiver.connect()
39
- })
40
-
41
- it('should return connector', async () => {
42
- expect(receiver).toBeInstanceOf(Connector)
43
- })
44
-
45
- it('should call receiver', async () => {
46
- const payload = { [generate()]: generate() }
47
-
48
- /** @type {toa.core.Message} */
49
- const message = { payload }
50
-
51
- await binding.emit(label, message)
52
-
53
- expect(fixtures.receiver.receive).toHaveBeenCalledWith(message)
54
- })
@@ -1,8 +0,0 @@
1
- 'use strict'
2
-
3
- const original = jest.requireActual('../src/binding')
4
-
5
- const reset = jest.fn(() => original.binding.reset())
6
- const binding = { ...original.binding, reset }
7
-
8
- module.exports = { binding }
@@ -1,20 +0,0 @@
1
- import * as _core from '@toa.io/core'
2
-
3
- declare namespace toa.stage.binding{
4
-
5
- type Callback = (message: Object) => Promise<void>
6
- type Call = (request: Object) => Promise<Object>
7
-
8
- interface Binding{
9
- subscribe (label: string, callback: Callback): Promise<void>
10
-
11
- emit (label: string, message: Object): Promise<undefined>
12
-
13
- reply (label, call: Call): Promise<Object>
14
- }
15
-
16
- }
17
-
18
- export type Factory = _core.bindings.Factory
19
- export const binding: toa.stage.binding.Binding
20
- export const properties: _core.bindings.Properties