@toa.io/core 1.0.0-alpha.291 → 1.0.0-alpha.293

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 (90) hide show
  1. package/package.json +11 -5
  2. package/CHANGELOG.md +0 -35
  3. package/source/assignment.ts +0 -27
  4. package/source/call.ts +0 -63
  5. package/source/cascade.ts +0 -32
  6. package/source/component.ts +0 -83
  7. package/source/composition.ts +0 -27
  8. package/source/connector.ts +0 -217
  9. package/source/context.ts +0 -68
  10. package/source/contract/contract.ts +0 -23
  11. package/source/contract/index.ts +0 -2
  12. package/source/contract/reply.ts +0 -56
  13. package/source/contract/request.ts +0 -140
  14. package/source/contract/schemas.ts +0 -39
  15. package/source/discovery.ts +0 -53
  16. package/source/effect.ts +0 -14
  17. package/source/emission.ts +0 -21
  18. package/source/entities/changeset.ts +0 -37
  19. package/source/entities/entity.ts +0 -137
  20. package/source/entities/factory.ts +0 -52
  21. package/source/entities/index.ts +0 -4
  22. package/source/entities/newid.ts +0 -9
  23. package/source/entities/set.ts +0 -27
  24. package/source/event.ts +0 -57
  25. package/source/exceptions.ts +0 -133
  26. package/source/exposition.ts +0 -33
  27. package/source/guard.ts +0 -16
  28. package/source/index.ts +0 -36
  29. package/source/locator.ts +0 -37
  30. package/source/observation.ts +0 -16
  31. package/source/operation.ts +0 -139
  32. package/source/outbox/index.ts +0 -1
  33. package/source/outbox/outbox.ts +0 -341
  34. package/source/query/criteria.ts +0 -90
  35. package/source/query/options.ts +0 -35
  36. package/source/query.ts +0 -67
  37. package/source/receiver.ts +0 -120
  38. package/source/reflection.ts +0 -20
  39. package/source/remote.ts +0 -20
  40. package/source/state.ts +0 -179
  41. package/source/transition.ts +0 -79
  42. package/source/transmission.ts +0 -38
  43. package/source/types/atomicity.ts +0 -63
  44. package/source/types/bindings.ts +0 -59
  45. package/source/types/bridges.ts +0 -54
  46. package/source/types/extensions.ts +0 -89
  47. package/source/types/index.ts +0 -14
  48. package/source/types/message.ts +0 -5
  49. package/source/types/operations.ts +0 -31
  50. package/source/types/outbox.ts +0 -35
  51. package/source/types/receiver.ts +0 -10
  52. package/source/types/request.ts +0 -54
  53. package/source/types/state.ts +0 -9
  54. package/source/types/storages.ts +0 -134
  55. package/source/unmanaged.ts +0 -8
  56. package/test/call.fixtures.js +0 -25
  57. package/test/call.test.js +0 -79
  58. package/test/component.fixtures.js +0 -18
  59. package/test/component.test.js +0 -57
  60. package/test/connector.fixtures.js +0 -56
  61. package/test/connector.test.js +0 -266
  62. package/test/context.fixtures.js +0 -14
  63. package/test/context.test.js +0 -40
  64. package/test/contract/conditions.test.js +0 -32
  65. package/test/contract/contract.fixtures.js +0 -28
  66. package/test/contract/request.test.js +0 -196
  67. package/test/discovery.test.js +0 -71
  68. package/test/emission.fixtures.js +0 -13
  69. package/test/emission.test.js +0 -60
  70. package/test/entities/entity.fixtures.js +0 -24
  71. package/test/entities/entity.test.js +0 -137
  72. package/test/entities/factory.fixtures.js +0 -31
  73. package/test/entities/factory.test.js +0 -99
  74. package/test/entities/set.fixtures.js +0 -9
  75. package/test/entities/set.test.js +0 -13
  76. package/test/event.fixtures.js +0 -24
  77. package/test/event.test.js +0 -162
  78. package/test/locator.test.js +0 -120
  79. package/test/outbox.test.js +0 -202
  80. package/test/query.fixtures.js +0 -96
  81. package/test/query.test.js +0 -183
  82. package/test/receiver.fixtures.js +0 -20
  83. package/test/receiver.test.js +0 -144
  84. package/test/reflection.test.js +0 -31
  85. package/test/state.fixtures.js +0 -49
  86. package/test/state.test.js +0 -162
  87. package/test/transmission.fixtures.js +0 -13
  88. package/test/transmission.test.js +0 -77
  89. package/tsconfig.json +0 -10
  90. package/tsconfig.tsbuildinfo +0 -1
@@ -1,133 +0,0 @@
1
- import { swap } from '@toa.io/generic'
2
- import type { SchemaError } from '@toa.io/schemas'
3
-
4
- export const codes = {
5
- System: 0,
6
-
7
- Contract: 200,
8
- RequestSyntax: 201,
9
- RequestContract: 202,
10
- RequestConflict: 203,
11
- ResponseContract: 211,
12
- EntityContract: 212,
13
- EntityGuard: 213,
14
- QuerySyntax: 221,
15
-
16
- State: 300,
17
- StateNotFound: 302,
18
- StatePrecondition: 303,
19
- StateConcurrency: 304,
20
- StateInitialization: 305,
21
- Duplicate: 306,
22
-
23
- Communication: 400,
24
- Transmission: 401
25
- }
26
-
27
- export class Exception {
28
- public readonly code: number
29
- public readonly message: string
30
- public cause?: unknown;
31
-
32
- /** what a contract exception copies off the schema error it refused with */
33
- [key: string]: unknown
34
-
35
- public constructor(code: number, message: string, cause?: unknown) {
36
- this.code = code
37
- this.message = message
38
-
39
- if (cause !== undefined) this.cause = cause
40
- }
41
- }
42
-
43
- export class SystemException extends Exception {
44
- public readonly stack?: string
45
-
46
- public constructor(error: Error | string) {
47
- super(codes.System, typeof error === 'string' ? error : error.message)
48
-
49
- if (typeof error !== 'string' && error.stack !== undefined) this.stack = error.stack
50
- }
51
- }
52
-
53
- export class ContractException extends Exception {
54
- public constructor(
55
- code: number | undefined,
56
- error: SchemaError | string | null,
57
- cause?: unknown
58
- ) {
59
- super(
60
- code ?? codes.Contract,
61
- typeof error === 'string' ? error : (error?.message ?? ''),
62
- cause
63
- )
64
-
65
- if (typeof error === 'object' && error !== null)
66
- for (const k of ['keyword', 'property', 'schema', 'path', 'params'] as const)
67
- if (k in error) this[k] = (error as unknown as Record<string, unknown>)[k]
68
- }
69
- }
70
-
71
- export class RequestContractException extends ContractException {
72
- public constructor(error: SchemaError | string, cause?: unknown) {
73
- super(codes.RequestContract, error, cause)
74
- }
75
- }
76
-
77
- export class ResponseContractException extends ContractException {
78
- public constructor(error: SchemaError | string, cause?: unknown) {
79
- super(codes.ResponseContract, error, cause)
80
- }
81
- }
82
-
83
- export class EntityContractException extends ContractException {
84
- public constructor(error: SchemaError | string, cause?: unknown) {
85
- super(codes.EntityContract, error, cause)
86
- }
87
- }
88
-
89
- export class EntityGuardException extends ContractException {
90
- public constructor(name: string, cause?: unknown) {
91
- super(codes.EntityGuard, name, cause)
92
- }
93
- }
94
-
95
- // #region exports
96
-
97
- // a module's exports are static, so the ones that follow a code are named rather
98
- // than generated onto the namespace
99
- type Derived = new (message?: string, cause?: unknown) => Exception
100
-
101
- function derive(name: keyof typeof codes): Derived {
102
- const classname = name + 'Exception'
103
-
104
- const derived = class extends Exception {
105
- public constructor(message?: string, cause?: unknown) {
106
- super(
107
- codes[name],
108
- message === undefined ? classname : `${classname}: ${message}`,
109
- cause
110
- )
111
- }
112
- }
113
-
114
- // the name is the class's own, and a class expression has none worth reporting
115
- Object.defineProperty(derived, 'name', { value: classname })
116
-
117
- return derived
118
- }
119
-
120
- export const RequestSyntaxException = derive('RequestSyntax')
121
- export const RequestConflictException = derive('RequestConflict')
122
- export const QuerySyntaxException = derive('QuerySyntax')
123
- export const StateException = derive('State')
124
- export const StateNotFoundException = derive('StateNotFound')
125
- export const StatePreconditionException = derive('StatePrecondition')
126
- export const StateConcurrencyException = derive('StateConcurrency')
127
- export const StateInitializationException = derive('StateInitialization')
128
- export const DuplicateException = derive('Duplicate')
129
- export const CommunicationException = derive('Communication')
130
- export const TransmissionException = derive('Transmission')
131
-
132
- export const names = swap(codes)
133
- // #endregion
@@ -1,33 +0,0 @@
1
- import { Connector } from './connector.js'
2
- import type { Locator } from './locator.js'
3
-
4
- interface Manifest {
5
- namespace: string
6
- name: string
7
- entity?: object
8
- operations?: object
9
- events?: object
10
- }
11
-
12
- export class Exposition extends Connector {
13
- public readonly locator: Locator
14
-
15
- readonly #exposition: Partial<Manifest>
16
-
17
- public constructor(locator: Locator, manifest: Manifest) {
18
- super()
19
-
20
- this.locator = locator
21
- this.#exposition = expose(manifest)
22
- }
23
-
24
- public async invoke(): Promise<{ output: Partial<Manifest> }> {
25
- return { output: this.#exposition }
26
- }
27
- }
28
-
29
- function expose(manifest: Manifest): Partial<Manifest> {
30
- const { namespace, name, entity, operations, events } = manifest
31
-
32
- return { namespace, name, entity, operations, events }
33
- }
package/source/guard.ts DELETED
@@ -1,16 +0,0 @@
1
- import type { Guard as Bridge } from './types/bridges.js'
2
-
3
- export class Guard {
4
- public readonly name: string
5
-
6
- readonly #bridge: Bridge
7
-
8
- public constructor(name: string, bridge: Bridge) {
9
- this.name = name
10
- this.#bridge = bridge
11
- }
12
-
13
- public fit(state: object, origin: object | null): boolean {
14
- return this.#bridge.fit(state, origin)
15
- }
16
- }
package/source/index.ts DELETED
@@ -1,36 +0,0 @@
1
- export { Assignment } from './assignment.js'
2
- export { Call } from './call.js'
3
- export { Cascade } from './cascade.js'
4
- export { Component } from './component.js'
5
- export { Composition } from './composition.js'
6
- export { Connector } from './connector.js'
7
- export { Context } from './context.js'
8
- export { Discovery } from './discovery.js'
9
- export { Effect } from './effect.js'
10
- export { Emission } from './emission.js'
11
- export { Event } from './event.js'
12
- export { Exposition } from './exposition.js'
13
- export { Locator } from './locator.js'
14
- export { Observation } from './observation.js'
15
- export { Outbox } from './outbox/index.js'
16
- export { Operation } from './operation.js'
17
- export { Query } from './query.js'
18
- export { Receiver } from './receiver.js'
19
- export { Reflection } from './reflection.js'
20
- export { Remote } from './remote.js'
21
- export { State } from './state.js'
22
- export { Transition } from './transition.js'
23
- export { Transmission } from './transmission.js'
24
- export { Unmanaged } from './unmanaged.js'
25
- export { Guard } from './guard.js'
26
- export * as entities from './entities/index.js'
27
- export * as exceptions from './exceptions.js'
28
- export * as contract from './contract/index.js'
29
-
30
- export type { Exception } from './exceptions.js'
31
- export type { Invocable } from './component.js'
32
- export type { Explicable } from './remote.js'
33
- export type { Scoped, Store } from './operation.js'
34
- export type { Source as ReflectionSource } from './reflection.js'
35
- export type { Explanation } from './contract/request.js'
36
- export type { JSONSchema } from './contract/schemas.js'
package/source/locator.ts DELETED
@@ -1,37 +0,0 @@
1
- import { concat } from '@toa.io/generic'
2
-
3
- /** Where a component is, as every name derived from it. */
4
- export class Locator {
5
- public readonly name: string
6
- public readonly namespace: string | undefined
7
-
8
- public readonly id: string
9
- public readonly label: string
10
- public readonly uppercase: string
11
- public readonly lowercase: string
12
-
13
- public constructor(name: string, namespace?: string) {
14
- if (name === undefined) throw new TypeError('Locator name must be defined')
15
-
16
- this.name = name
17
- this.namespace = namespace
18
-
19
- this.id = concat(namespace, '.') + name
20
- this.label = (concat(namespace, '-') + name).toLowerCase()
21
- this.uppercase = (concat(namespace, '_') + name).toUpperCase()
22
- this.lowercase = (concat(namespace, '_') + name).toLowerCase()
23
- }
24
-
25
- public static parse(string: string): Locator {
26
- const [namespace, name] = string.split(DOT)
27
-
28
- if (name === undefined) return new Locator(namespace)
29
- else return new Locator(name, namespace)
30
- }
31
-
32
- public hostname(prefix?: string): string {
33
- return concat(prefix?.toLowerCase(), '-') + this.label
34
- }
35
- }
36
-
37
- const DOT = '.'
@@ -1,16 +0,0 @@
1
- import { Operation } from './operation.js'
2
- import type { Store } from './operation.js'
3
- import type { Entity } from './entities/entity.js'
4
-
5
- export class Observation extends Operation {
6
- protected override async run(store: Store): Promise<void> {
7
- const scope = store.scope as Entity | null
8
-
9
- if (
10
- scope === null ||
11
- (scope?.deleted === true && (store.request.query as any)?.options?.deleted !== true)
12
- )
13
- store.reply = null
14
- else await super.run(store)
15
- }
16
- }
@@ -1,139 +0,0 @@
1
- import { Readable } from 'node:stream'
2
- import { Connector } from './connector.js'
3
- import { SystemException, RequestContractException } from './exceptions.js'
4
- import { environment } from '@toa.io/generic'
5
- import type { Cascade } from './cascade.js'
6
- import type { State } from './state.js'
7
- import type { Query as Translator } from './query.js'
8
- import type { Contract } from './contract/contract.js'
9
- import type { Entity } from './entities/entity.js'
10
- import type { EntitySet } from './entities/set.js'
11
- import type { Changeset } from './entities/changeset.js'
12
- import type { scope as Scope } from './types/operations.js'
13
- import type { Query, Request } from './types/request.js'
14
-
15
- /** What an operation acquires for the algorithm to run against. */
16
- export type Scoped = Entity | EntitySet | Changeset | Readable | null
17
-
18
- /** What one invocation carries from step to step. */
19
- export interface Store {
20
- request: Request
21
- scope?: Scoped
22
- state?: any
23
- reply?: any
24
- /** set by a transition, which is the only operation that runs its steps again */
25
- retry?: () => Promise<any>
26
- }
27
-
28
- export interface Contracts {
29
- request: Contract
30
- reply: Contract
31
- }
32
-
33
- export interface Definition {
34
- scope: Scope
35
- concurrency?: string
36
- }
37
-
38
- export class Operation extends Connector {
39
- public scope: State
40
-
41
- /**
42
- * Whether what this operation acquires may be modified and committed. Only a
43
- * transition commits, and only a commit needs the pre-image an entity keeps
44
- * to diff the new state against.
45
- *
46
- * @protected
47
- */
48
- protected mutable: boolean = false
49
-
50
- readonly #cascade: Cascade
51
- readonly #contracts: Contracts
52
- readonly #query: Translator
53
- readonly #scope: Scope
54
-
55
- // eslint-disable-next-line max-params
56
- public constructor(
57
- cascade: Cascade,
58
- scope: State,
59
- contracts: Contracts,
60
- query: Translator,
61
- definition: Definition
62
- ) {
63
- super()
64
-
65
- this.scope = scope
66
-
67
- this.#cascade = cascade
68
- this.#contracts = contracts
69
- this.#query = query
70
- this.#scope = definition.scope
71
-
72
- this.depends(cascade)
73
- }
74
-
75
- public async invoke(request: Request): Promise<any> {
76
- try {
77
- if (request.authentic !== true) this.#contracts.request.fit(request)
78
-
79
- // the request carries the query onward in its parsed form: what a storage is given,
80
- // not what the caller sent
81
- if ('query' in request)
82
- request.query = this.#query.parse(request.query as Query) as any
83
-
84
- // validate entity
85
- if ('entity' in request) this.scope.fit(request.entity)
86
-
87
- const store = { request }
88
-
89
- return await this.process(store)
90
- } catch (e) {
91
- const exception = e instanceof Error ? new SystemException(e) : e
92
-
93
- return { exception }
94
- }
95
- }
96
-
97
- protected async process(store: Store): Promise<any> {
98
- await this.acquire(store)
99
- await this.run(store)
100
- await this.commit(store)
101
-
102
- return store.reply
103
- }
104
-
105
- protected async acquire(store: Store): Promise<void> {
106
- if (this.#scope === 'none') return
107
-
108
- const scope = await this.query(store.request.query)
109
- const raw = scope === null || scope instanceof Readable
110
-
111
- store.scope = scope
112
- store.state = raw ? scope : (scope as Entity).get()
113
- }
114
-
115
- protected async run(store: Store): Promise<void> {
116
- const { request, state } = store
117
- const reply = await this.#cascade.run(request.input, state)
118
-
119
- // validate reply only on local environments
120
- if (environment.get('TOA_ENV') === 'local' && !(reply instanceof Readable))
121
- this.#contracts.reply.fit(reply)
122
-
123
- store.reply = reply
124
- }
125
-
126
- protected async commit(_store: Store): Promise<void> {}
127
-
128
- protected async query(query?: Query): Promise<Scoped> {
129
- if (query === undefined)
130
- throw new RequestContractException('Request query is required')
131
-
132
- const acquire = this.scope[this.#scope] as (
133
- query: Query,
134
- mutable?: boolean
135
- ) => Promise<Scoped>
136
-
137
- return acquire.call(this.scope, query, this.mutable)
138
- }
139
- }
@@ -1 +0,0 @@
1
- export { Outbox, LANES } from './outbox.js'