@toa.io/core 1.0.0-alpha.24 → 1.0.0-alpha.246

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 (56) hide show
  1. package/package.json +7 -9
  2. package/src/call.js +12 -0
  3. package/src/cascade.js +7 -5
  4. package/src/component.js +41 -17
  5. package/src/composition.js +1 -1
  6. package/src/connector.js +21 -14
  7. package/src/context.js +4 -0
  8. package/src/contract/contract.js +22 -0
  9. package/src/contract/reply.js +26 -9
  10. package/src/contract/request.js +15 -5
  11. package/src/contract/schemas/query.yaml +14 -1
  12. package/src/discovery.js +13 -7
  13. package/src/effect.js +19 -0
  14. package/src/entities/changeset.js +5 -8
  15. package/src/entities/entity.js +48 -23
  16. package/src/entities/factory.js +15 -4
  17. package/src/entities/newid.js +11 -0
  18. package/src/entities/set.js +13 -0
  19. package/src/event.js +19 -1
  20. package/src/exceptions.js +26 -19
  21. package/src/exposition.js +3 -2
  22. package/src/guard.js +17 -0
  23. package/src/index.js +6 -0
  24. package/src/observation.js +1 -9
  25. package/src/operation.js +28 -7
  26. package/src/query/options.js +3 -2
  27. package/src/query.js +3 -1
  28. package/src/receiver.js +60 -11
  29. package/src/remote.js +7 -7
  30. package/src/state.js +69 -33
  31. package/src/transition.js +8 -19
  32. package/src/transmission.js +12 -3
  33. package/src/unmanaged.js +11 -0
  34. package/test/component.test.js +4 -3
  35. package/test/connector.fixtures.js +8 -0
  36. package/test/connector.test.js +20 -0
  37. package/test/contract/conditions.test.js +5 -5
  38. package/test/contract/request.test.js +7 -7
  39. package/test/discovery.test.js +56 -0
  40. package/test/entities/entity.test.js +0 -45
  41. package/test/entities/factory.test.js +3 -3
  42. package/test/event.test.js +4 -4
  43. package/test/receiver.fixtures.js +1 -0
  44. package/test/state.test.js +0 -14
  45. package/types/bindings.d.ts +7 -5
  46. package/types/bridges.ts +3 -0
  47. package/types/component.d.ts +4 -1
  48. package/types/extensions.d.ts +6 -3
  49. package/types/index.ts +1 -0
  50. package/types/message.d.ts +1 -0
  51. package/types/operations.d.ts +6 -0
  52. package/types/query.d.ts +2 -0
  53. package/types/remote.d.ts +18 -0
  54. package/types/request.d.ts +5 -0
  55. package/types/storages.d.ts +11 -9
  56. package/src/contract/conditions.js +0 -21
package/src/transition.js CHANGED
@@ -1,12 +1,8 @@
1
1
  'use strict'
2
2
 
3
3
  const { retry } = require('@toa.io/generic')
4
-
5
4
  const { Operation } = require('./operation')
6
- const {
7
- StateConcurrencyException,
8
- StateNotFoundException
9
- } = require('./exceptions')
5
+ const { StateConcurrencyException, StateNotFoundException } = require('./exceptions')
10
6
 
11
7
  class Transition extends Operation {
12
8
  #concurrency
@@ -26,33 +22,26 @@ class Transition extends Operation {
26
22
 
27
23
  store.scope = request.query ? await this.query(request.query) : this.scope.init()
28
24
 
29
- if (store.scope === null) {
25
+ if (store.scope === null || (store.scope.deleted === true && request.query?.options?.deleted !== true))
30
26
  throw new StateNotFoundException()
31
- }
32
-
27
+
33
28
  store.state = store.scope.get()
34
29
  }
35
30
 
36
31
  async commit (store) {
37
- const {
38
- scope,
39
- state,
40
- reply,
41
- retry
42
- } = store
32
+ const { scope, state, reply, retry } = store
43
33
 
44
34
  if (reply.error !== undefined) return
45
35
 
46
36
  scope.set(state)
47
37
 
48
- const result = await this.scope.commit(scope)
38
+ const result = await this.scope.commit(scope, store.request.input)
49
39
 
50
40
  if (result === false) {
51
- if (this.#concurrency === 'retry') {
41
+ if (this.#concurrency === 'retry')
52
42
  return retry()
53
- } else {
43
+ else
54
44
  throw new StateConcurrencyException()
55
- }
56
45
  }
57
46
  }
58
47
 
@@ -67,7 +56,7 @@ const RETRY = {
67
56
  base: 10,
68
57
  max: 5000,
69
58
  dispersion: 1,
70
- retries: Infinity
59
+ retries: 32
71
60
  }
72
61
 
73
62
  exports.Transition = Transition
@@ -18,13 +18,22 @@ class Transmission extends Connector {
18
18
  let i = 0
19
19
 
20
20
  while (reply === false && i < this.#bindings.length) {
21
- reply = await this.#bindings[i].request(request)
21
+ const binding = this.#bindings[i]
22
+
22
23
  i++
24
+
25
+ if (request?.task === true) {
26
+ if (binding.task === undefined)
27
+ continue
28
+
29
+ await binding.task(request)
30
+ reply = null
31
+ } else
32
+ reply = await binding.request(request)
23
33
  }
24
34
 
25
- if (reply === false) {
35
+ if (reply === false)
26
36
  throw new TransmissionException(`All (${this.#bindings.length}) bindings rejected.`)
27
- }
28
37
 
29
38
  return reply
30
39
  }
@@ -0,0 +1,11 @@
1
+ 'use strict'
2
+
3
+ const { Operation } = require('./operation')
4
+
5
+ class Unmanaged extends Operation {
6
+ acquire (context) {
7
+ context.state = this.scope.storage.raw
8
+ }
9
+ }
10
+
11
+ exports.Unmanaged = Unmanaged
@@ -3,6 +3,7 @@
3
3
  const { Component } = require('../src/component')
4
4
  const { codes } = require('../src/exceptions')
5
5
  const fixtures = require('./component.fixtures')
6
+ const { AssertionError } = require('node:assert')
6
7
 
7
8
  describe('Invocations', () => {
8
9
  const name = ['foo', 'bar'][Math.floor(2 * Math.random())]
@@ -16,12 +17,12 @@ describe('Invocations', () => {
16
17
  it('should invoke', async () => {
17
18
  await component.invoke(name)
18
19
 
19
- expect(invocation.invoke).toBeCalled()
20
+ expect(invocation.invoke).toHaveBeenCalled()
20
21
  })
21
22
 
22
23
  it('should throw on unknown invocation name', async () => {
23
24
  await expect(() => component.invoke('baz'))
24
- .rejects.toMatchObject({ code: codes.NotImplemented })
25
+ .rejects.toThrow(AssertionError)
25
26
  })
26
27
 
27
28
  it('should invoke input and query', async () => {
@@ -29,7 +30,7 @@ describe('Invocations', () => {
29
30
  const query = { test: Math.random() }
30
31
  await component.invoke(name, { input, query })
31
32
 
32
- expect(invocation.invoke).toBeCalledWith({ input, query })
33
+ expect(invocation.invoke).toHaveBeenCalledWith({ input, query })
33
34
  })
34
35
 
35
36
  it('should return io', async () => {
@@ -36,5 +36,13 @@ class FailingConnector extends Connector {
36
36
  }
37
37
  }
38
38
 
39
+ /** Stands for a connector waiting for something that never arrives. */
40
+ class StuckConnector extends Connector {
41
+ async open () {
42
+ return new Promise(() => undefined)
43
+ }
44
+ }
45
+
39
46
  exports.TestConnector = TestConnector
40
47
  exports.FailingConnector = FailingConnector
48
+ exports.StuckConnector = StuckConnector
@@ -1,5 +1,7 @@
1
1
  'use strict'
2
2
 
3
+ const { timeout } = require('@toa.io/generic')
4
+
3
5
  const fixtures = require('./connector.fixtures')
4
6
 
5
7
  let sequence
@@ -105,6 +107,7 @@ describe('dependencies', () => {
105
107
  a.depends(b).depends(c)
106
108
  b.depends(d)
107
109
 
110
+ await a.connect()
108
111
  await a.disconnect()
109
112
 
110
113
  expect(sequence.indexOf('-a')).toBeLessThan(sequence.indexOf('-b'))
@@ -146,6 +149,23 @@ describe('dependencies', () => {
146
149
  expect(() => a.depends({})).toThrow()
147
150
  })
148
151
 
152
+ it('should disconnect while still connecting', async () => {
153
+ const stuck = new fixtures.StuckConnector()
154
+
155
+ a.depends(stuck).depends(b)
156
+
157
+ void a.connect()
158
+
159
+ while (b.connected !== true) await timeout(1)
160
+
161
+ // `a` never connects, and disconnecting must not wait for it to
162
+ expect(a.connected).toStrictEqual(false)
163
+
164
+ await a.disconnect()
165
+
166
+ expect(sequence).toEqual(['+b', '-b', '*b', '*a'])
167
+ })
168
+
149
169
  describe('errors', () => {
150
170
  let f
151
171
 
@@ -2,19 +2,19 @@
2
2
 
3
3
  const { generate } = require('randomstring')
4
4
 
5
- const { Conditions } = require('../../src/contract/conditions')
5
+ const { Contract } = require('../../src/contract/contract')
6
6
  const fixtures = require('./contract.fixtures')
7
7
 
8
- let conditions
8
+ let contract
9
9
 
10
10
  beforeEach(() => {
11
- conditions = new Conditions(fixtures.schema)
11
+ contract = new Contract(fixtures.schema)
12
12
  })
13
13
 
14
14
  it('should fit value', () => {
15
15
  const value = { foo: generate() }
16
16
 
17
- conditions.fit(value)
17
+ contract.fit(value)
18
18
 
19
19
  expect(fixtures.schema.fit).toHaveBeenCalledWith(value)
20
20
  })
@@ -22,5 +22,5 @@ it('should fit value', () => {
22
22
  it('should throw on invalid value', () => {
23
23
  const value = { invalid: true }
24
24
 
25
- expect(() => conditions.fit(value)).toThrow()
25
+ expect(() => contract.fit(value)).toThrow()
26
26
  })
@@ -3,10 +3,10 @@
3
3
  const clone = require('clone-deep')
4
4
  const { generate } = require('randomstring')
5
5
 
6
- jest.mock('../../src/contract/conditions')
6
+ jest.mock('../../src/contract/contract')
7
7
 
8
8
  const { Request } = require('../../src/contract/request')
9
- const { Conditions } = require('../../src/contract/conditions')
9
+ const { Contract } = require('../../src/contract/contract')
10
10
  const fixtures = require('./contract.fixtures')
11
11
 
12
12
  let contract
@@ -14,14 +14,14 @@ let contract
14
14
  beforeEach(() => {
15
15
  jest.clearAllMocks()
16
16
 
17
- contract = new Request(fixtures.schema)
17
+ contract = new Request(fixtures.schema, {})
18
18
  })
19
19
 
20
20
  const dummy = { schema: { properties: {} } }
21
21
 
22
22
  it('should extend Conditions', () => {
23
- expect(contract).toBeInstanceOf(Conditions)
24
- expect(Conditions).toHaveBeenCalledWith(fixtures.schema)
23
+ expect(contract).toBeInstanceOf(Contract)
24
+ expect(Contract).toHaveBeenCalledWith(fixtures.schema)
25
25
  })
26
26
 
27
27
  it('should fit request', () => {
@@ -29,7 +29,7 @@ it('should fit request', () => {
29
29
 
30
30
  contract.fit(request)
31
31
 
32
- expect(Conditions.mock.instances[0].fit).toHaveBeenCalledWith(request)
32
+ expect(Contract.mock.instances[0].fit).toHaveBeenCalledWith(request)
33
33
  })
34
34
 
35
35
  describe('schema', () => {
@@ -59,7 +59,7 @@ describe('schema', () => {
59
59
 
60
60
  it('should not contain query if declaration.query is false', () => {
61
61
  schema.properties.query = { type: 'null' }
62
- expect(Request.schema({ query: false }, dummy)).toStrictEqual(schema)
62
+ expect(Request.schema({ query: false }, dummy)).toMatchObject(schema)
63
63
  })
64
64
 
65
65
  it('should require query if declaration.query is true', () => {
@@ -0,0 +1,56 @@
1
+ 'use strict'
2
+
3
+ const { console } = require('openspan')
4
+ const { Connector } = require('../src/connector')
5
+ const { Discovery } = require('../src/discovery')
6
+
7
+ class Lookup extends Connector {
8
+ invoke = jest.fn(async () => ({ operations: {} }))
9
+ }
10
+
11
+ /** @type {Lookup} */
12
+ let lookup
13
+
14
+ /** @type {Discovery} */
15
+ let discovery
16
+
17
+ /** @type {jest.SpyInstance} */
18
+ let warn
19
+
20
+ const locator = { id: 'dummies.one' }
21
+
22
+ beforeEach(async () => {
23
+ jest.useFakeTimers()
24
+
25
+ warn = jest.spyOn(console, 'warn').mockImplementation(() => undefined)
26
+ lookup = new Lookup()
27
+ discovery = new Discovery(async () => lookup)
28
+
29
+ await discovery.connect()
30
+ })
31
+
32
+ afterEach(() => {
33
+ warn.mockRestore()
34
+ jest.useRealTimers()
35
+ })
36
+
37
+ it('should not warn if a lookup is answered', async () => {
38
+ await discovery.lookup(locator)
39
+
40
+ jest.advanceTimersByTime(60_000)
41
+
42
+ expect(warn).not.toHaveBeenCalled()
43
+ })
44
+
45
+ it('should keep warning while a lookup is unanswered', async () => {
46
+ lookup.invoke.mockImplementation(() => new Promise(() => undefined))
47
+
48
+ void discovery.lookup(locator)
49
+
50
+ await jest.advanceTimersByTimeAsync(12_000)
51
+
52
+ expect(warn).toHaveBeenCalledTimes(2)
53
+
54
+ expect(warn).toHaveBeenLastCalledWith('Waiting for lookup response',
55
+ { component: locator.id, waiting: 10 })
56
+ })
@@ -7,35 +7,7 @@ beforeEach(() => {
7
7
  jest.clearAllMocks()
8
8
  })
9
9
 
10
- describe('new', () => {
11
- it('should throw on schema error', () => {
12
- const entity = new Entity(fixtures.schema)
13
-
14
- expect(() => entity.set(fixtures.failed())).toThrow()
15
- })
16
-
17
- it('should provide state', () => {
18
- const entity = new Entity(fixtures.schema)
19
- const state = fixtures.state()
20
-
21
- entity.set(state)
22
-
23
- expect(entity.get()).toEqual(state)
24
- })
25
- })
26
-
27
10
  describe('argument', () => {
28
- it('should provide initial state if no argument passed', () => {
29
- const entity = new Entity(fixtures.schema)
30
- const defaults = fixtures.schema.defaults.mock.results[0].value
31
- const expected = {
32
- ...defaults,
33
- _version: 0
34
- }
35
-
36
- expect(entity.get()).toStrictEqual(expect.objectContaining(expected))
37
- })
38
-
39
11
  it('should set state', () => {
40
12
  const state = fixtures.state()
41
13
  const entity = new Entity(fixtures.schema, state)
@@ -63,20 +35,3 @@ it('should provide event', () => {
63
35
  })
64
36
  }))
65
37
  })
66
-
67
- it('should define `id` as readonly', async () => {
68
- const origin = fixtures.state()
69
- const entity = new Entity(fixtures.schema, origin)
70
- const state = entity.get()
71
-
72
- expect(() => (state.id = 1)).toThrow('assign to read only property')
73
- })
74
-
75
- it('should seal id', async () => {
76
- const origin = fixtures.state()
77
- const entity = new Entity(fixtures.schema, origin)
78
- const state = entity.get()
79
- const redefine = () => Object.defineProperty(state, 'id', { writable: true })
80
-
81
- expect(redefine).toThrow('redefine property')
82
- })
@@ -23,14 +23,14 @@ it('should create initial', () => {
23
23
  const initial = factory.init(id)
24
24
 
25
25
  expect(initial).toBeInstanceOf(mock.Entity)
26
- expect(initial.constructor).toHaveBeenCalledWith(fixtures.schema, id)
26
+ expect(initial.constructor).toHaveBeenCalledWith(fixtures.schema, id, expect.any(Function))
27
27
  })
28
28
 
29
29
  it('should create instance', () => {
30
30
  const object = factory.object(fixtures.entity)
31
31
 
32
32
  expect(object).toBeInstanceOf(mock.Entity)
33
- expect(object.constructor).toHaveBeenCalledWith(fixtures.schema, fixtures.entity)
33
+ expect(object.constructor).toHaveBeenCalledWith(fixtures.schema, fixtures.entity, expect.any(Function))
34
34
  })
35
35
 
36
36
  it('should create set', () => {
@@ -39,7 +39,7 @@ it('should create set', () => {
39
39
  expect(objects).toBeInstanceOf(mock.EntitySet)
40
40
 
41
41
  const instances = fixtures.set.map((entity, index) => {
42
- expect(mock.Entity).toHaveBeenNthCalledWith(index + 1, fixtures.schema, entity)
42
+ expect(mock.Entity).toHaveBeenNthCalledWith(index + 1, fixtures.schema, entity, expect.any(Function))
43
43
 
44
44
  return mock.Entity.mock.instances[index]
45
45
  })
@@ -41,7 +41,7 @@ describe('condition', () => {
41
41
  await emit()
42
42
 
43
43
  const payload = await fixtures.bridge.payload.mock.results[0].value
44
- const message = { payload }
44
+ const message = { payload, telemetry: expect.any(String) }
45
45
  expect(fixtures.binding.emit).toHaveBeenCalledWith(message)
46
46
  })
47
47
 
@@ -71,7 +71,7 @@ describe('condition', () => {
71
71
  expect(fixtures.bridge.condition).not.toHaveBeenCalledWith()
72
72
 
73
73
  const payload = await fixtures.bridge.payload.mock.results[0].value
74
- const message = { payload }
74
+ const message = { payload, telemetry: expect.any(String) }
75
75
 
76
76
  expect(fixtures.binding.emit).toHaveBeenCalledWith(message)
77
77
  })
@@ -84,7 +84,7 @@ describe('payload', () => {
84
84
  await emit()
85
85
 
86
86
  const payload = await fixtures.bridge.payload.mock.results[0].value
87
- const message = { payload }
87
+ const message = { payload, telemetry: expect.any(String) }
88
88
 
89
89
  expect(fixtures.binding.emit).toHaveBeenCalledWith(message)
90
90
  })
@@ -110,7 +110,7 @@ describe('payload', () => {
110
110
  await emit()
111
111
 
112
112
  const payload = fixtures.event.state
113
- const message = { payload }
113
+ const message = { payload, telemetry: expect.any(String) }
114
114
 
115
115
  expect(fixtures.binding.emit).toHaveBeenCalledWith(message)
116
116
  })
@@ -9,6 +9,7 @@ const definition = /** @type {toa.norm.component.Receiver} */ {
9
9
  }
10
10
 
11
11
  const local = /** @type {toa.core.Component} */ {
12
+ locator: { id: 'default.dummy' },
12
13
  invoke: jest.fn()
13
14
  }
14
15
 
@@ -19,14 +19,6 @@ it('should provide object', async () => {
19
19
  expect(fixtures.factory.object).toHaveBeenCalledWith(fixtures.storage.get.mock.results[0].value)
20
20
  })
21
21
 
22
- it('should provide objects', async () => {
23
- const set = await state.objects(fixtures.query)
24
-
25
- expect(fixtures.storage.find).toHaveBeenCalledWith(fixtures.query)
26
- expect(set).toStrictEqual(fixtures.factory.objects.mock.results[0].value)
27
- expect(fixtures.factory.objects).toHaveBeenCalledWith(fixtures.storage.find.mock.results[0].value)
28
- })
29
-
30
22
  it('should store entity', async () => {
31
23
  await state.commit(fixtures.initial)
32
24
 
@@ -38,9 +30,3 @@ it('should emit', async () => {
38
30
 
39
31
  expect(fixtures.emitter.emit).toHaveBeenCalledWith(fixtures.entity.event.mock.results[0].value)
40
32
  })
41
-
42
- it('should not emit if state has not been changed', async () => {
43
- await state.commit(fixtures.unchanged)
44
-
45
- expect(fixtures.emitter.emit).not.toHaveBeenCalled()
46
- })
@@ -1,26 +1,28 @@
1
1
  import * as _core from './index'
2
2
 
3
- declare namespace toa.core.bindings{
3
+ declare namespace toa.core.bindings {
4
4
 
5
5
  type Properties = {
6
6
  async?: boolean
7
7
  }
8
8
 
9
- interface Consumer extends _core.Connector{
9
+ interface Consumer extends _core.Connector {
10
10
  request (request: Request): Promise<_core.Reply>
11
+
12
+ task (request: Request): Promise<void>
11
13
  }
12
14
 
13
- interface Emitter extends _core.Connector{
15
+ interface Emitter extends _core.Connector {
14
16
  emit (message: _core.Message): Promise<void>
15
17
  }
16
18
 
17
- interface Broadcast<L> extends _core.Connector{
19
+ interface Broadcast<L> extends _core.Connector {
18
20
  transmit<T> (label: L, payload: T): Promise<void>
19
21
 
20
22
  receive<T> (label: L, callback: (payload: T) => void | Promise<void>): Promise<void>
21
23
  }
22
24
 
23
- interface Factory{
25
+ interface Factory {
24
26
  producer? (locator: _core.Locator, endpoints: Array<string>, producer: _core.Component): _core.Connector
25
27
 
26
28
  consumer? (locator: _core.Locator, endpoint: string): Consumer
package/types/bridges.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import type { Request, Reply } from './request'
2
2
  import type { Context } from './context'
3
+ import type { Connector } from './connector'
3
4
 
4
5
  export interface Algorithm {
5
6
  mount: (context?: Context) => Promise<void>
@@ -27,4 +28,6 @@ export interface Factory {
27
28
  event?: (path: string, label: string) => Event
28
29
 
29
30
  receiver?: (path: string, label: string) => Receiver
31
+
32
+ rc?: (path: string, context: Context) => Promise<Connector>
30
33
  }
@@ -1,9 +1,12 @@
1
1
  import { Connector } from './connector'
2
2
  import { Locator } from './locator'
3
3
  import { Request } from './request'
4
+ import { Operation } from './operations'
4
5
 
5
- export interface Component extends Connector{
6
+ export class Component extends Connector {
6
7
  locator: Locator
7
8
 
9
+ constructor (locator: Locator, operations: Record<string, Operation>)
10
+
8
11
  invoke<T = any> (endpoint: string, request: Request): Promise<T>
9
12
  }
@@ -3,9 +3,10 @@ import * as _component from './component'
3
3
  import * as _context from './context'
4
4
  import * as _storages from './storages'
5
5
  import * as _bindings from './bindings'
6
+ import { Manifest } from '@toa.io/norm'
6
7
 
7
- export interface Factory{
8
- tenant? (locator: _core.Locator, manifest: object): _core.Connector
8
+ export interface Factory {
9
+ tenant? (locator: _core.Locator, manifest: object, component: Manifest): _core.Connector
9
10
 
10
11
  aspect? (locator: _core.Locator, manifest: object | null): Aspect | Aspect[]
11
12
 
@@ -15,6 +16,8 @@ export interface Factory{
15
16
 
16
17
  context? (context: _context.Context): _context.Context
17
18
 
19
+ manage? (composition: _core.Connector): _core.Connector
20
+
18
21
  storage? (storage: _storages.Storage): _storages.Storage
19
22
 
20
23
  emitter? (emitter: _bindings.Emitter, label: string): _bindings.Emitter
@@ -22,7 +25,7 @@ export interface Factory{
22
25
  receiver? (receiver: _core.Receiver, locator: _core.Locator): _core.Receiver
23
26
  }
24
27
 
25
- export interface Aspect extends _core.Connector{
28
+ export interface Aspect extends _core.Connector {
26
29
  name: string
27
30
 
28
31
  invoke (...args: any[]): any
package/types/index.ts CHANGED
@@ -5,6 +5,7 @@ export * as bridges from './bridges'
5
5
  export * as operations from './operations'
6
6
 
7
7
  export type { Component } from './component'
8
+ export type { Remote } from './remote'
8
9
  export { Connector } from './connector'
9
10
  export type { Context } from './context'
10
11
  export type { Exception } from './exception'
@@ -1,3 +1,4 @@
1
1
  export interface Message<T = any> {
2
2
  payload: T
3
+ telemetry?: string // W3C traceparent
3
4
  }
@@ -1,2 +1,8 @@
1
+ import { Request } from './request'
2
+
1
3
  export type type = 'transition' | 'observation' | 'assignment' | 'computation' | 'effect'
2
4
  export type scope = 'object' | 'objects' | 'changeset'
5
+
6
+ export class Operation {
7
+ invoke<T = any> (request: Request): Promise<T>
8
+ }
package/types/query.d.ts CHANGED
@@ -4,6 +4,8 @@ declare namespace toa.core {
4
4
  id?: string
5
5
  version?: number
6
6
  criteria?: Object
7
+ search?: string
8
+ sample?: number
7
9
  omit?: number
8
10
  limit?: number
9
11
  sort?: string[]
@@ -0,0 +1,18 @@
1
+ import { Component } from './component'
2
+
3
+ export class Remote extends Component {
4
+ explain (endpoint: string): Promise<Explanation>
5
+ }
6
+
7
+ interface Explanation {
8
+ input: Schema | null
9
+ output: Schema | null
10
+ errors?: string[]
11
+ }
12
+
13
+ interface Schema {
14
+ type: string
15
+ properties: {
16
+ [key: string]: Schema
17
+ }
18
+ }
@@ -3,17 +3,22 @@ import { Exception } from './exception'
3
3
  export interface Query {
4
4
  id?: string
5
5
  criteria?: string
6
+ search?: string
7
+ sample?: number
6
8
  omit?: number
7
9
  limit?: number
8
10
  sort?: Array<string>
9
11
  projection?: Array<string>
10
12
  version?: number
13
+ deleted?: boolean
11
14
  }
12
15
 
13
16
  export interface Request {
14
17
  input?: any
15
18
  query?: Query
16
19
  authentic?: boolean
20
+ task?: boolean
21
+ telemetry?: string // W3C traceparent
17
22
  }
18
23
 
19
24
  export interface Reply {