@toa.io/boot 0.8.2-dev.0 → 0.20.0-alpha.1

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,10 +1,11 @@
1
1
  {
2
2
  "name": "@toa.io/boot",
3
- "version": "0.8.2-dev.0",
3
+ "version": "0.20.0-alpha.1",
4
4
  "description": "Toa Boot",
5
5
  "author": "temich <tema.gurtovoy@gmail.com>",
6
6
  "homepage": "https://github.com/toa-io/toa#readme",
7
7
  "main": "src/index.js",
8
+ "types": "types/index.d.ts",
8
9
  "repository": {
9
10
  "type": "git",
10
11
  "url": "git+https://github.com/toa-io/toa.git"
@@ -19,12 +20,13 @@
19
20
  "test": "echo \"Error: run tests from root\" && exit 1"
20
21
  },
21
22
  "dependencies": {
22
- "@toa.io/core": "0.8.1",
23
- "@toa.io/filesystem": "0.7.2",
24
- "@toa.io/generic": "0.9.0",
25
- "@toa.io/norm": "0.10.1-dev.0",
26
- "@toa.io/schema": "0.7.3",
27
- "clone-deep": "4.0.1"
23
+ "@toa.io/core": "0.20.0-alpha.1",
24
+ "@toa.io/filesystem": "0.20.0-alpha.1",
25
+ "@toa.io/generic": "0.20.0-alpha.1",
26
+ "@toa.io/norm": "0.20.0-alpha.1",
27
+ "@toa.io/schema": "0.20.0-alpha.1",
28
+ "clone-deep": "4.0.1",
29
+ "dotenv": "16.1.1"
28
30
  },
29
- "gitHead": "7f1fdbfe3aa33eb4a06cb1a33d15be18854bcd88"
31
+ "gitHead": "d1a5369c0ee4ee423f792b83e9753fd2fd943cce"
30
32
  }
@@ -2,6 +2,6 @@
2
2
 
3
3
  const { factory } = require('./factory')
4
4
 
5
- const broadcast = (binding, name, group) => factory(binding).broadcast(name, group)
5
+ const broadcast = (channel, group, binding = '@toa.io/bindings.amqp') => factory(binding).broadcast(channel, group)
6
6
 
7
7
  exports.broadcast = broadcast
@@ -2,6 +2,6 @@
2
2
 
3
3
  const { factory } = require('./factory')
4
4
 
5
- const receive = (binding, source, label, group, receiver) => factory(binding).receiver(source, label, group, receiver)
5
+ const receive = (binding, locator, label, group, receiver) => factory(binding).receiver(locator, label, group, receiver)
6
6
 
7
7
  exports.receive = receive
package/src/bridge.js CHANGED
@@ -8,7 +8,7 @@ const algorithm = (bridge, path, endpoint, context) => {
8
8
  return algorithm
9
9
  }
10
10
 
11
- const event = (bridge, path, label) => resolve(bridge).event(path, label)
11
+ const event = (bridge, path, label, context) => resolve(bridge).event(path, label, context)
12
12
  const receiver = (bridge, path, label) => resolve(bridge).receiver(path, label)
13
13
 
14
14
  const factories = {}
package/src/component.js CHANGED
@@ -11,10 +11,12 @@ const boot = require('./index')
11
11
  * @returns {Promise<toa.core.Component>}
12
12
  */
13
13
  const component = async (manifest) => {
14
+ boot.extensions.load(manifest)
15
+
14
16
  const locator = new Locator(manifest.name, manifest.namespace)
15
17
  const storage = boot.storage(manifest)
16
18
  const context = await boot.context(manifest)
17
- const emission = boot.emission(manifest.events, locator)
19
+ const emission = boot.emission(manifest.events, locator, context)
18
20
  const schema = new Schema(manifest.entity.schema)
19
21
  const entity = new entities.Factory(schema)
20
22
  const state = new State(storage, entity, emission, manifest.entity.initialized)
@@ -7,17 +7,9 @@ const boot = require('./index')
7
7
  async function composition (paths, options) {
8
8
  options = Object.assign({}, options)
9
9
 
10
- /** @type {toa.norm.Component[]} */
11
10
  const manifests = await Promise.all(paths.map((path) => boot.manifest(path, options)))
12
-
13
- boot.extensions.load(manifests, options.extensions)
14
-
15
- /** @type {toa.core.Connector[]} */
16
11
  const tenants = await Promise.all(manifests.map(boot.extensions.tenants))
17
-
18
12
  const expositions = await Promise.all(manifests.map(boot.discovery.expose))
19
-
20
- /** @type {toa.core.Component[]} */
21
13
  const components = await Promise.all(manifests.map(boot.component))
22
14
 
23
15
  const producers = components.map((component, index) =>
package/src/contract.js CHANGED
@@ -5,14 +5,14 @@ const { Schema } = require('@toa.io/schema')
5
5
 
6
6
  const request = (definition) => {
7
7
  const request = Request.schema(definition)
8
- const schema = new Schema(request)
8
+ const schema = new Schema(request, { removeAdditional: true }) // inputs soft
9
9
 
10
10
  return new Request(schema)
11
11
  }
12
12
 
13
13
  const reply = (output, error) => {
14
14
  const reply = Reply.schema(output, error)
15
- const schema = new Schema(reply)
15
+ const schema = new Schema(reply) // outputs strict
16
16
 
17
17
  return new Reply(schema)
18
18
  }
package/src/deployment.js CHANGED
@@ -9,10 +9,26 @@ const { context: load } = require('@toa.io/norm')
9
9
  * @returns {Promise<toa.deployment.Operator>}
10
10
  */
11
11
  const deployment = async (path, environment) => {
12
- const context = await load(path, environment)
13
- const factory = new Factory(context)
12
+ const factory = await getFactory(path, environment)
14
13
 
15
14
  return factory.operator()
16
15
  }
17
16
 
17
+ /**
18
+ * @param {string} path
19
+ * @returns {Promise<toa.deployment.Registry>}
20
+ */
21
+ const registry = async (path) => {
22
+ const factory = await getFactory(path)
23
+
24
+ return factory.registry()
25
+ }
26
+
27
+ async function getFactory (path, environment) {
28
+ const context = await load(path, environment)
29
+
30
+ return new Factory(context)
31
+ }
32
+
18
33
  exports.deployment = deployment
34
+ exports.registry = registry
package/src/emission.js CHANGED
@@ -5,13 +5,13 @@ const { Emission, Event } = require('@toa.io/core')
5
5
  const boot = require('./index')
6
6
  const extensions = require('./extensions')
7
7
 
8
- const emission = (definitions, locator) => {
8
+ const emission = (definitions, locator, context) => {
9
9
  if (definitions === undefined) return
10
10
 
11
11
  const events = Object.entries(definitions).map(([label, definition]) => {
12
12
  const emitter = boot.bindings.emit(definition.binding, locator, label)
13
13
  const decorator = extensions.emitter(emitter, label)
14
- const bridge = boot.bridge.event(definition.bridge, definition.path, label)
14
+ const bridge = boot.bridge.event(definition.bridge, definition.path, label, context)
15
15
 
16
16
  return new Event(definition, decorator, bridge)
17
17
  })
package/src/env.js ADDED
@@ -0,0 +1,15 @@
1
+ 'use strict'
2
+
3
+ const { file } = require('@toa.io/filesystem')
4
+
5
+ async function setup () {
6
+ const path = await file.dot('env')
7
+
8
+ if (path !== undefined) require('dotenv').config({ path })
9
+ }
10
+
11
+ if (!('TOA_ENV' in process.env)) {
12
+ (async () => {
13
+ await setup()
14
+ })()
15
+ }
@@ -3,25 +3,12 @@
3
3
  const { resolve } = require('./resolve')
4
4
 
5
5
  /**
6
- * @param {toa.norm.Component[]} manifests
7
- * @param {string[]} defaults
6
+ * @param {toa.norm.Component} manifest
8
7
  */
9
- const load = (manifests, defaults) => {
10
- scan(manifests)
11
- defaults.map((name) => resolve(name))
12
- }
13
-
14
- /**
15
- * @param {toa.norm.Component[]} manifests
16
- */
17
- const scan = (manifests) => {
18
- for (const manifest of manifests) {
19
- if (manifest.extensions === undefined) continue
8
+ const load = (manifest) => {
9
+ if (manifest.extensions === undefined) return
20
10
 
21
- for (const name of Object.keys(manifest.extensions)) {
22
- resolve(name, manifest.path)
23
- }
24
- }
11
+ for (const name of Object.keys(manifest.extensions)) resolve(name, manifest.path)
25
12
  }
26
13
 
27
14
  exports.load = load
package/src/index.js CHANGED
@@ -1,11 +1,13 @@
1
1
  'use strict'
2
2
 
3
+ require('./env')
4
+
3
5
  const { call } = require('./call')
4
6
  const { cascade } = require('./cascade')
5
7
  const { component } = require('./component')
6
8
  const { composition } = require('./composition')
7
9
  const { context } = require('./context')
8
- const { deployment } = require('./deployment')
10
+ const { deployment, registry } = require('./deployment')
9
11
  const { emission } = require('./emission')
10
12
  const { exposition } = require('./exposition')
11
13
  const { images } = require('./images')
@@ -33,5 +35,6 @@ exports.images = images
33
35
  exports.manifest = manifest
34
36
  exports.operation = operation
35
37
  exports.receivers = receivers
38
+ exports.registry = registry
36
39
  exports.remote = remote
37
40
  exports.storage = storage
package/src/manifest.js CHANGED
@@ -1,5 +1,6 @@
1
1
  'use strict'
2
2
 
3
+ const clone = require('clone-deep')
3
4
  const { merge } = require('@toa.io/generic')
4
5
  const { component: load } = require('@toa.io/norm')
5
6
  const { Locator } = require('@toa.io/core')
@@ -8,7 +9,7 @@ const { Locator } = require('@toa.io/core')
8
9
  * @type {toa.boot.Manifest}
9
10
  */
10
11
  const manifest = async (path, options = {}) => {
11
- merge(options, DEFAULTS)
12
+ options = merge(clone(options), DEFAULTS)
12
13
 
13
14
  const manifest = await load(path)
14
15
 
@@ -31,19 +32,22 @@ const manifest = async (path, options = {}) => {
31
32
  }
32
33
  }
33
34
 
34
- if (!('extensions' in manifest)) manifest.extensions = {}
35
+ if (manifest.extensions === undefined) manifest.extensions = {}
35
36
 
37
+ // add `null` manifests
36
38
  for (const extension of options.extensions) {
37
39
  if (!(extension in manifest.extensions)) manifest.extensions[extension] = null
38
40
  }
39
41
 
42
+ if ('storage' in options && 'entity' in manifest) manifest.entity.storage = options.storage
43
+
40
44
  manifest.locator = new Locator(manifest.name, manifest.namespace)
41
45
 
42
46
  return manifest
43
47
  }
44
48
 
45
49
  const DEFAULTS = {
46
- extensions: ['@toa.io/extensions.sampling', '@toa.io/extensions.state']
50
+ extensions: ['@toa.io/extensions.sampling']
47
51
  }
48
52
 
49
53
  exports.manifest = manifest
@@ -0,0 +1,23 @@
1
+ 'use strict'
2
+
3
+ const { generate } = require('randomstring')
4
+
5
+ jest.mock('@toa.io/norm', () => ({
6
+ component: () => mockComponent()
7
+ }))
8
+
9
+ const { manifest } = require('./manifest')
10
+
11
+ const path = generate()
12
+
13
+ it('should not modify options', async () => {
14
+ const options = { extensions: ['foo', 'bar'] }
15
+
16
+ await manifest(path, options)
17
+
18
+ expect(options.extensions.length).toStrictEqual(2)
19
+ })
20
+
21
+ function mockComponent () {
22
+ return { name: generate(), namespace: generate() }
23
+ }
package/src/operation.js CHANGED
@@ -6,11 +6,14 @@ const boot = require('./index')
6
6
 
7
7
  const operation = (manifest, endpoint, definition, context, scope) => {
8
8
  const cascade = boot.cascade(manifest, endpoint, definition, context)
9
- const contract = boot.contract.reply(definition.output, definition.error)
9
+ const reply = boot.contract.reply(definition.output, definition.error)
10
+ const input = definition.input
11
+ const request = boot.contract.request({ input })
12
+ const contracts = { reply, request }
10
13
  const query = new Query(manifest.entity.schema.properties)
11
14
  const Type = TYPES[definition.type]
12
15
 
13
- return new Type(cascade, scope, contract, query, definition)
16
+ return new Type(cascade, scope, contracts, query, definition)
14
17
  }
15
18
 
16
19
  const TYPES = {
package/src/receivers.js CHANGED
@@ -12,7 +12,7 @@ const receivers = async (manifest, runtime) => {
12
12
 
13
13
  for (const [label, definition] of Object.entries(manifest.receivers)) {
14
14
  const local = await boot.remote(manifest.locator, manifest)
15
- const bridge = boot.bridge.receiver(definition.bridge, manifest.path, label)
15
+ const bridge = definition.bridge !== undefined ? boot.bridge.receiver(definition.bridge, manifest.path, label) : undefined
16
16
  const receiver = new Receiver(definition, local, bridge)
17
17
  const decorator = extensions.receiver(receiver, manifest.locator)
18
18
 
@@ -0,0 +1,3 @@
1
+ import type { bindings } from '@toa.io/core'
2
+
3
+ export function broadcast (name: string, group?: string, binding?: string): bindings.Broadcast
@@ -1,19 +1,5 @@
1
- import * as _core from '@toa.io/core/types'
2
-
3
- declare namespace toa.boot {
4
-
5
- namespace composition {
6
-
7
- type Options = {
8
- bindings?: string[]
9
- extensions?: string[]
10
- }
11
-
12
- }
13
-
14
- type Composition = (paths: string[], options: composition.Options) => Promise<_core.Connector>
15
-
1
+ export type Options = {
2
+ bindings?: string[]
3
+ storage?: string
4
+ extensions?: string[]
16
5
  }
17
-
18
- export type Options = toa.boot.composition.Options
19
- export type Composition = toa.boot.Composition
package/types/index.d.ts CHANGED
@@ -1,3 +1,8 @@
1
- import { Composition } from './composition'
1
+ import * as core from '@toa.io/core'
2
+ import * as composition from './composition'
2
3
 
3
- export const composition: Composition
4
+ export * as bindings from './bindings'
5
+
6
+ export async function composition (paths: string[], options?: composition.Options): Promise<core.Connector>
7
+
8
+ export async function remote (locator: core.Locator): Promise<core.Component>