@toa.io/core 1.0.0-alpha.32 → 1.0.0-alpha.320
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 +28 -12
- package/transpiled/abandon.d.ts +9 -0
- package/transpiled/abandon.js +37 -0
- package/transpiled/abandon.js.map +1 -0
- package/transpiled/assignment.d.ts +6 -0
- package/transpiled/assignment.js +25 -0
- package/transpiled/assignment.js.map +1 -0
- package/transpiled/call.d.ts +10 -0
- package/transpiled/call.js +187 -0
- package/transpiled/call.js.map +1 -0
- package/transpiled/cascade.d.ts +7 -0
- package/transpiled/cascade.js +28 -0
- package/transpiled/cascade.js.map +1 -0
- package/transpiled/component.d.ts +15 -0
- package/transpiled/component.js +148 -0
- package/transpiled/component.js.map +1 -0
- package/transpiled/composition.d.ts +6 -0
- package/transpiled/composition.js +20 -0
- package/transpiled/composition.js.map +1 -0
- package/transpiled/connector.d.ts +71 -0
- package/transpiled/connector.js +248 -0
- package/transpiled/connector.js.map +1 -0
- package/transpiled/context.d.ts +25 -0
- package/transpiled/context.js +55 -0
- package/transpiled/context.js.map +1 -0
- package/transpiled/contract/component.d.ts +37 -0
- package/transpiled/contract/component.js +94 -0
- package/transpiled/contract/component.js.map +1 -0
- package/transpiled/contract/contract.d.ts +10 -0
- package/transpiled/contract/contract.js +14 -0
- package/transpiled/contract/contract.js.map +1 -0
- package/transpiled/contract/index.d.ts +4 -0
- package/transpiled/contract/index.js +5 -0
- package/transpiled/contract/index.js.map +1 -0
- package/transpiled/contract/reply.d.ts +7 -0
- package/transpiled/contract/reply.js +48 -0
- package/transpiled/contract/reply.js.map +1 -0
- package/transpiled/contract/request.d.ts +49 -0
- package/transpiled/contract/request.js +152 -0
- package/transpiled/contract/request.js.map +1 -0
- package/transpiled/contract/schemas.d.ts +4 -0
- package/transpiled/contract/schemas.js +38 -0
- package/transpiled/contract/schemas.js.map +1 -0
- package/transpiled/contract/system.d.ts +33 -0
- package/transpiled/contract/system.js +76 -0
- package/transpiled/contract/system.js.map +1 -0
- package/transpiled/deliveries.d.ts +22 -0
- package/transpiled/deliveries.js +31 -0
- package/transpiled/deliveries.js.map +1 -0
- package/transpiled/effect.d.ts +7 -0
- package/transpiled/effect.js +13 -0
- package/transpiled/effect.js.map +1 -0
- package/transpiled/emission.d.ts +10 -0
- package/transpiled/emission.js +16 -0
- package/transpiled/emission.js.map +1 -0
- package/transpiled/encoded.d.ts +16 -0
- package/transpiled/encoded.js +25 -0
- package/transpiled/encoded.js.map +1 -0
- package/transpiled/entities/changeset.d.ts +10 -0
- package/transpiled/entities/changeset.js +27 -0
- package/transpiled/entities/changeset.js.map +1 -0
- package/transpiled/entities/entity.d.ts +19 -0
- package/transpiled/entities/entity.js +137 -0
- package/transpiled/entities/entity.js.map +1 -0
- package/transpiled/entities/factory.d.ts +27 -0
- package/transpiled/entities/factory.js +38 -0
- package/transpiled/entities/factory.js.map +1 -0
- package/transpiled/entities/index.d.ts +5 -0
- package/transpiled/entities/index.js +6 -0
- package/transpiled/entities/index.js.map +1 -0
- package/transpiled/entities/newid.d.ts +11 -0
- package/transpiled/entities/newid.js +41 -0
- package/transpiled/entities/newid.js.map +1 -0
- package/transpiled/entities/set.d.ts +10 -0
- package/transpiled/entities/set.js +19 -0
- package/transpiled/entities/set.js.map +1 -0
- package/transpiled/event.d.ts +20 -0
- package/transpiled/event.js +65 -0
- package/transpiled/event.js.map +1 -0
- package/transpiled/exceptions.d.ts +110 -0
- package/transpiled/exceptions.js +215 -0
- package/transpiled/exceptions.js.map +1 -0
- package/transpiled/gate.d.ts +40 -0
- package/transpiled/gate.js +84 -0
- package/transpiled/gate.js.map +1 -0
- package/transpiled/guard.d.ts +7 -0
- package/transpiled/guard.js +12 -0
- package/transpiled/guard.js.map +1 -0
- package/transpiled/halting.d.ts +16 -0
- package/transpiled/halting.js +25 -0
- package/transpiled/halting.js.map +1 -0
- package/transpiled/index.d.ts +44 -0
- package/transpiled/index.js +36 -0
- package/transpiled/index.js.map +1 -0
- package/transpiled/instance.d.ts +10 -0
- package/transpiled/instance.js +30 -0
- package/transpiled/instance.js.map +1 -0
- package/transpiled/locator.d.ts +12 -0
- package/transpiled/locator.js +32 -0
- package/transpiled/locator.js.map +1 -0
- package/transpiled/measurements.d.ts +20 -0
- package/transpiled/measurements.js +40 -0
- package/transpiled/measurements.js.map +1 -0
- package/transpiled/observation.d.ts +7 -0
- package/transpiled/observation.js +14 -0
- package/transpiled/observation.js.map +1 -0
- package/transpiled/operation.d.ts +73 -0
- package/transpiled/operation.js +213 -0
- package/transpiled/operation.js.map +1 -0
- package/transpiled/outbox.d.ts +45 -0
- package/transpiled/outbox.js +448 -0
- package/transpiled/outbox.js.map +1 -0
- package/transpiled/outbox.measurements.d.ts +4 -0
- package/transpiled/outbox.measurements.js +38 -0
- package/transpiled/outbox.measurements.js.map +1 -0
- package/transpiled/parts.d.ts +20 -0
- package/transpiled/parts.js +23 -0
- package/transpiled/parts.js.map +1 -0
- package/transpiled/query/criteria.d.ts +6 -0
- package/transpiled/query/criteria.js +177 -0
- package/transpiled/query/criteria.js.map +1 -0
- package/transpiled/query/options.d.ts +3 -0
- package/transpiled/query/options.js +34 -0
- package/transpiled/query/options.js.map +1 -0
- package/transpiled/query.d.ts +9 -0
- package/transpiled/query.js +57 -0
- package/transpiled/query.js.map +1 -0
- package/transpiled/receiver.d.ts +20 -0
- package/transpiled/receiver.js +113 -0
- package/transpiled/receiver.js.map +1 -0
- package/transpiled/reflection.d.ts +9 -0
- package/transpiled/reflection.js +13 -0
- package/transpiled/reflection.js.map +1 -0
- package/transpiled/remote.d.ts +10 -0
- package/transpiled/remote.js +11 -0
- package/transpiled/remote.js.map +1 -0
- package/transpiled/rendering.d.ts +13 -0
- package/transpiled/rendering.js +21 -0
- package/transpiled/rendering.js.map +1 -0
- package/transpiled/safety.d.ts +5 -0
- package/transpiled/safety.js +26 -0
- package/transpiled/safety.js.map +1 -0
- package/transpiled/state.d.ts +36 -0
- package/transpiled/state.js +131 -0
- package/transpiled/state.js.map +1 -0
- package/transpiled/trail.d.ts +78 -0
- package/transpiled/trail.js +112 -0
- package/transpiled/trail.js.map +1 -0
- package/transpiled/transition.d.ts +14 -0
- package/transpiled/transition.js +51 -0
- package/transpiled/transition.js.map +1 -0
- package/transpiled/transmission.d.ts +8 -0
- package/transpiled/transmission.js +30 -0
- package/transpiled/transmission.js.map +1 -0
- package/transpiled/types/atomicity.d.ts +58 -0
- package/transpiled/types/atomicity.js +2 -0
- package/transpiled/types/atomicity.js.map +1 -0
- package/transpiled/types/bindings.d.ts +82 -0
- package/transpiled/types/bindings.js +2 -0
- package/transpiled/types/bindings.js.map +1 -0
- package/transpiled/types/bridges.d.ts +41 -0
- package/transpiled/types/bridges.js +2 -0
- package/transpiled/types/bridges.js.map +1 -0
- package/transpiled/types/extensions.d.ts +121 -0
- package/transpiled/types/extensions.js +2 -0
- package/transpiled/types/extensions.js.map +1 -0
- package/transpiled/types/inbox.d.ts +27 -0
- package/transpiled/types/inbox.js +2 -0
- package/transpiled/types/inbox.js.map +1 -0
- package/transpiled/types/index.d.ts +14 -0
- package/transpiled/types/index.js +9 -0
- package/transpiled/types/index.js.map +1 -0
- package/transpiled/types/message.d.ts +16 -0
- package/transpiled/types/message.js +2 -0
- package/transpiled/types/message.js.map +1 -0
- package/transpiled/types/operations.d.ts +15 -0
- package/transpiled/types/operations.js +2 -0
- package/transpiled/types/operations.js.map +1 -0
- package/transpiled/types/outbox.d.ts +68 -0
- package/transpiled/types/outbox.js +2 -0
- package/transpiled/types/outbox.js.map +1 -0
- package/transpiled/types/receiver.d.ts +9 -0
- package/transpiled/types/receiver.js +2 -0
- package/transpiled/types/receiver.js.map +1 -0
- package/transpiled/types/request.d.ts +119 -0
- package/transpiled/types/request.js +2 -0
- package/transpiled/types/request.js.map +1 -0
- package/transpiled/types/state.d.ts +9 -0
- package/transpiled/types/state.js +2 -0
- package/transpiled/types/state.js.map +1 -0
- package/transpiled/types/storages.d.ts +154 -0
- package/transpiled/types/storages.js +2 -0
- package/transpiled/types/storages.js.map +1 -0
- package/transpiled/unmanaged.d.ts +5 -0
- package/transpiled/unmanaged.js +7 -0
- package/transpiled/unmanaged.js.map +1 -0
- package/src/assignment.js +0 -31
- package/src/call.js +0 -42
- package/src/cascade.js +0 -35
- package/src/component.js +0 -41
- package/src/composition.js +0 -25
- package/src/connector.js +0 -183
- package/src/context.js +0 -55
- package/src/contract/conditions.js +0 -21
- package/src/contract/index.js +0 -7
- package/src/contract/reply.js +0 -25
- package/src/contract/request.js +0 -67
- package/src/contract/schemas/error.yaml +0 -9
- package/src/contract/schemas/index.js +0 -7
- package/src/contract/schemas/query.yaml +0 -30
- package/src/discovery.js +0 -44
- package/src/emission.js +0 -23
- package/src/entities/changeset.js +0 -38
- package/src/entities/entity.js +0 -74
- package/src/entities/factory.js +0 -33
- package/src/entities/index.js +0 -5
- package/src/entities/set.js +0 -15
- package/src/event.js +0 -40
- package/src/exceptions.js +0 -100
- package/src/exposition.js +0 -27
- package/src/index.js +0 -47
- package/src/locator.js +0 -54
- package/src/observation.js +0 -20
- package/src/operation.js +0 -69
- package/src/query/criteria.js +0 -41
- package/src/query/options.js +0 -40
- package/src/query.js +0 -41
- package/src/receiver.js +0 -61
- package/src/reflection.js +0 -28
- package/src/remote.js +0 -17
- package/src/state.js +0 -99
- package/src/transition.js +0 -67
- package/src/transmission.js +0 -33
- package/test/call.fixtures.js +0 -27
- package/test/call.test.js +0 -46
- package/test/component.fixtures.js +0 -21
- package/test/component.test.js +0 -40
- package/test/connector.fixtures.js +0 -40
- package/test/connector.test.js +0 -176
- package/test/context.fixtures.js +0 -18
- package/test/context.test.js +0 -29
- package/test/contract/conditions.test.js +0 -26
- package/test/contract/contract.fixtures.js +0 -33
- package/test/contract/request.test.js +0 -112
- package/test/emission.fixtures.js +0 -17
- package/test/emission.test.js +0 -35
- package/test/entities/entity.fixtures.js +0 -29
- package/test/entities/entity.test.js +0 -65
- package/test/entities/factory.fixtures.js +0 -18
- package/test/entities/factory.test.js +0 -48
- package/test/entities/set.fixtures.js +0 -11
- package/test/entities/set.test.js +0 -12
- package/test/event.fixtures.js +0 -29
- package/test/event.test.js +0 -118
- package/test/locator.test.js +0 -113
- package/test/query.fixtures.js +0 -100
- package/test/query.test.js +0 -86
- package/test/receiver.fixtures.js +0 -23
- package/test/receiver.test.js +0 -95
- package/test/reflection.test.js +0 -30
- package/test/state.fixtures.js +0 -47
- package/test/state.test.js +0 -46
- package/test/transmission.fixtures.js +0 -15
- package/test/transmission.test.js +0 -46
- package/types/bindings.d.ts +0 -40
- package/types/bridges.ts +0 -30
- package/types/component.d.ts +0 -9
- package/types/connector.d.ts +0 -18
- package/types/context.d.ts +0 -21
- package/types/entity.d.ts +0 -46
- package/types/event.d.ts +0 -11
- package/types/exception.d.ts +0 -4
- package/types/extensions.d.ts +0 -29
- package/types/index.ts +0 -14
- package/types/locator.d.ts +0 -13
- package/types/message.d.ts +0 -3
- package/types/operations.d.ts +0 -2
- package/types/query.d.ts +0 -15
- package/types/receiver.d.ts +0 -12
- package/types/reflection.d.ts +0 -14
- package/types/request.d.ts +0 -23
- package/types/state.d.ts +0 -35
- package/types/storages.d.ts +0 -71
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import { parse } from '@rsql/parser';
|
|
2
|
+
import { QuerySyntaxException } from '../exceptions.js';
|
|
3
|
+
export function criteria(expression, properties) {
|
|
4
|
+
let ast;
|
|
5
|
+
try {
|
|
6
|
+
ast = parse(expression);
|
|
7
|
+
}
|
|
8
|
+
catch (e) {
|
|
9
|
+
throw new QuerySyntaxException(e.message);
|
|
10
|
+
}
|
|
11
|
+
// what spells neither word holds neither, and pays nothing for this
|
|
12
|
+
if (expression.includes('null') || expression.includes('undefined'))
|
|
13
|
+
nothing(ast, expression);
|
|
14
|
+
if (properties !== undefined)
|
|
15
|
+
read(ast, properties);
|
|
16
|
+
return ast;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* An unquoted `null` or `undefined` is no value, and a quoted one is text. The parser answers
|
|
20
|
+
* both as the text, so which of them was quoted is read from the expression: a value is what
|
|
21
|
+
* follows a comparison operator, or the list in parentheses that does, and the tree holds the
|
|
22
|
+
* values in the order the expression writes them.
|
|
23
|
+
*/
|
|
24
|
+
function nothing(ast, expression) {
|
|
25
|
+
const quoted = values(expression);
|
|
26
|
+
let index = 0;
|
|
27
|
+
function resolve(value) {
|
|
28
|
+
return !quoted[index++] && (value === 'null' || value === 'undefined') ? null : value;
|
|
29
|
+
}
|
|
30
|
+
comparisons(ast, (node) => {
|
|
31
|
+
const right = node.right;
|
|
32
|
+
right.value = Array.isArray(right.value) ? right.value.map(resolve) : resolve(right.value);
|
|
33
|
+
const none = Array.isArray(right.value) ? right.value.includes(null) : right.value === null;
|
|
34
|
+
// no value is neither greater nor less than anything, and a storage asked to order by it
|
|
35
|
+
// finds nothing and says nothing
|
|
36
|
+
if (none && !EQUALITY.includes(node.operator))
|
|
37
|
+
throw new QuerySyntaxException(`Criteria selector '${node.left.selector}' compares no value with '${node.operator}'`);
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
const EQUALITY = ['==', '!=', '=in=', '=out='];
|
|
41
|
+
function comparisons(node, visit) {
|
|
42
|
+
if (node.type === 'COMPARISON')
|
|
43
|
+
visit(node);
|
|
44
|
+
else if (node.type === 'LOGIC') {
|
|
45
|
+
comparisons(node.left, visit);
|
|
46
|
+
comparisons(node.right, visit);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Whether each value of an expression the parser has accepted is quoted, in the order they are
|
|
51
|
+
* written. Tokens are told apart as the parser's lexer tells them.
|
|
52
|
+
*/
|
|
53
|
+
function values(expression) {
|
|
54
|
+
const quoted = [];
|
|
55
|
+
let position = 0;
|
|
56
|
+
let value = false;
|
|
57
|
+
let list = false;
|
|
58
|
+
while (position < expression.length) {
|
|
59
|
+
const char = expression[position];
|
|
60
|
+
if (WHITESPACE.includes(char)) {
|
|
61
|
+
position++;
|
|
62
|
+
}
|
|
63
|
+
else if (char === '"' || char === "'") {
|
|
64
|
+
position = closing(expression, position) + 1;
|
|
65
|
+
if (value)
|
|
66
|
+
quoted.push(true);
|
|
67
|
+
value = list;
|
|
68
|
+
}
|
|
69
|
+
else if (char === '(') {
|
|
70
|
+
position++;
|
|
71
|
+
list = value;
|
|
72
|
+
}
|
|
73
|
+
else if (char === ')') {
|
|
74
|
+
position++;
|
|
75
|
+
list = value = false;
|
|
76
|
+
}
|
|
77
|
+
else if (char === ',' || char === ';') {
|
|
78
|
+
position++;
|
|
79
|
+
}
|
|
80
|
+
else if (OPERATOR_START.includes(char)) {
|
|
81
|
+
OPERATOR.lastIndex = position;
|
|
82
|
+
position = OPERATOR.test(expression) ? OPERATOR.lastIndex : position + 1;
|
|
83
|
+
value = true;
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
position++;
|
|
87
|
+
while (position < expression.length && !RESERVED.includes(expression[position]))
|
|
88
|
+
position++;
|
|
89
|
+
if (value)
|
|
90
|
+
quoted.push(false);
|
|
91
|
+
value = list;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return quoted;
|
|
95
|
+
}
|
|
96
|
+
/** The quote that closes the one at `position`: the first one not escaped by a backslash. */
|
|
97
|
+
function closing(expression, position) {
|
|
98
|
+
const quote = expression[position];
|
|
99
|
+
let end = position;
|
|
100
|
+
for (;;) {
|
|
101
|
+
end = expression.indexOf(quote, end + 1);
|
|
102
|
+
if (end === -1)
|
|
103
|
+
return expression.length;
|
|
104
|
+
let escaped = false;
|
|
105
|
+
for (let back = end - 1; expression[back] === '\\' && back > position; back--)
|
|
106
|
+
escaped = !escaped;
|
|
107
|
+
if (!escaped)
|
|
108
|
+
return end;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
const WHITESPACE = ' \n\t\r';
|
|
112
|
+
const RESERVED = `"'();,=!~<> \n\t\r`;
|
|
113
|
+
const OPERATOR_START = '=!<>';
|
|
114
|
+
const OPERATOR = /=[a-z]*=|[!<>]=?/y;
|
|
115
|
+
function read(node, properties) {
|
|
116
|
+
if (node.type === 'COMPARISON' &&
|
|
117
|
+
node.left?.type === 'SELECTOR' &&
|
|
118
|
+
node.right?.type === 'VALUE') {
|
|
119
|
+
const selector = node.left.selector;
|
|
120
|
+
const property = properties[selector];
|
|
121
|
+
if (property === undefined) {
|
|
122
|
+
throw new QuerySyntaxException(`Criteria selector '${selector}' is not defined`);
|
|
123
|
+
}
|
|
124
|
+
const cast = CAST[property.type];
|
|
125
|
+
// `=in=` and `=out=` carry a list, and casting that as one value gives whatever
|
|
126
|
+
// a comma-separated string reads as
|
|
127
|
+
// no value is no property's to read
|
|
128
|
+
if (cast !== undefined)
|
|
129
|
+
node.right.value = Array.isArray(node.right.value)
|
|
130
|
+
? node.right.value.map((value) => value === null ? null : cast(value, selector))
|
|
131
|
+
: node.right.value === null
|
|
132
|
+
? null
|
|
133
|
+
: cast(node.right.value, selector);
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
if (node.left !== undefined)
|
|
137
|
+
read(node.left, properties);
|
|
138
|
+
if (node.right !== undefined)
|
|
139
|
+
read(node.right, properties);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* A criteria arrives as text, so a value is read as what the property it selects on holds. What
|
|
144
|
+
* cannot be read as that is refused rather than passed on: `parseInt` answers `NaN` for a word
|
|
145
|
+
* and `12` for `12kg`, and a storage asked to match either finds nothing and says nothing —
|
|
146
|
+
* a mistyped filter reads as an empty result.
|
|
147
|
+
*
|
|
148
|
+
* A string is left as it came, because every text is one: what a criteria may compare a string
|
|
149
|
+
* to is not the type's to say.
|
|
150
|
+
*/
|
|
151
|
+
const CAST = {
|
|
152
|
+
number: (value, selector) => finite(value, selector, 'a number'),
|
|
153
|
+
integer: (value, selector) => {
|
|
154
|
+
const number = finite(value, selector, 'an integer');
|
|
155
|
+
if (!Number.isInteger(number))
|
|
156
|
+
refuse(selector, 'an integer', value);
|
|
157
|
+
return number;
|
|
158
|
+
},
|
|
159
|
+
boolean: (value, selector) => {
|
|
160
|
+
if (value === 'true')
|
|
161
|
+
return true;
|
|
162
|
+
if (value === 'false')
|
|
163
|
+
return false;
|
|
164
|
+
return refuse(selector, 'a boolean', value);
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
function finite(value, selector, expected) {
|
|
168
|
+
// `Number` reads a blank string as zero, and a criteria that says nothing says nothing
|
|
169
|
+
const number = value.trim() === '' ? Number.NaN : Number(value);
|
|
170
|
+
if (!Number.isFinite(number))
|
|
171
|
+
refuse(selector, expected, value);
|
|
172
|
+
return number;
|
|
173
|
+
}
|
|
174
|
+
function refuse(selector, expected, value) {
|
|
175
|
+
throw new QuerySyntaxException(`Criteria selector '${selector}' takes ${expected}, and '${value}' is not one`);
|
|
176
|
+
}
|
|
177
|
+
//# sourceMappingURL=criteria.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"criteria.js","sourceRoot":"","sources":["../../source/query/criteria.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { QuerySyntaxException } from '../exceptions.js';
|
|
2
|
+
export function options(given, properties) {
|
|
3
|
+
if (given.sort !== undefined)
|
|
4
|
+
given.sort = sort(given.sort, properties);
|
|
5
|
+
if (given.projection !== undefined)
|
|
6
|
+
given.projection = projection(given.projection, properties);
|
|
7
|
+
return given;
|
|
8
|
+
}
|
|
9
|
+
function sort(sort, properties) {
|
|
10
|
+
const result = [];
|
|
11
|
+
for (const sorting of sort) {
|
|
12
|
+
const [property, direction] = sorting.split(':');
|
|
13
|
+
if (properties[property] === undefined)
|
|
14
|
+
throw new QuerySyntaxException(`Sort property '${property}' is not defined`);
|
|
15
|
+
result.push([property, direction ?? 'asc']);
|
|
16
|
+
}
|
|
17
|
+
return result;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* A copy, because a route declares one projection and sends it with every request it serves,
|
|
21
|
+
* and the system properties are what every read answers besides.
|
|
22
|
+
*/
|
|
23
|
+
function projection(declared, properties) {
|
|
24
|
+
for (const property of declared)
|
|
25
|
+
if (properties[property] === undefined)
|
|
26
|
+
throw new QuerySyntaxException(`Projection property '${property}' is not defined`);
|
|
27
|
+
const projection = declared.slice();
|
|
28
|
+
for (const property of SYSTEM)
|
|
29
|
+
if (!projection.includes(property))
|
|
30
|
+
projection.push(property);
|
|
31
|
+
return projection;
|
|
32
|
+
}
|
|
33
|
+
const SYSTEM = ['VERSION', 'CREATED', 'UPDATED', 'DELETED', 'REGION'];
|
|
34
|
+
//# sourceMappingURL=options.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"options.js","sourceRoot":"","sources":["../../source/query/options.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAA;AAIvD,MAAM,UAAU,OAAO,CAAC,KAA0B,EAAE,UAAsB;IACxE,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS;QAAE,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,UAAU,CAAC,CAAA;IAEvE,IAAI,KAAK,CAAC,UAAU,KAAK,SAAS;QAChC,KAAK,CAAC,UAAU,GAAG,UAAU,CAAC,KAAK,CAAC,UAAU,EAAE,UAAU,CAAC,CAAA;IAE7D,OAAO,KAAgB,CAAA;AACzB,CAAC;AAED,SAAS,IAAI,CAAC,IAAc,EAAE,UAAsB;IAClD,MAAM,MAAM,GAA4B,EAAE,CAAA;IAE1C,KAAK,MAAM,OAAO,IAAI,IAAI,EAAE,CAAC;QAC3B,MAAM,CAAC,QAAQ,EAAE,SAAS,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;QAEhD,IAAI,UAAU,CAAC,QAAQ,CAAC,KAAK,SAAS;YACpC,MAAM,IAAI,oBAAoB,CAAC,kBAAkB,QAAQ,kBAAkB,CAAC,CAAA;QAE9E,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,SAAS,IAAI,KAAK,CAAC,CAAC,CAAA;IAC7C,CAAC;IAED,OAAO,MAAM,CAAA;AACf,CAAC;AAED;;;GAGG;AACH,SAAS,UAAU,CAAC,QAAkB,EAAE,UAAsB;IAC5D,KAAK,MAAM,QAAQ,IAAI,QAAQ;QAC7B,IAAI,UAAU,CAAC,QAAQ,CAAC,KAAK,SAAS;YACpC,MAAM,IAAI,oBAAoB,CAAC,wBAAwB,QAAQ,kBAAkB,CAAC,CAAA;IAEtF,MAAM,UAAU,GAAG,QAAQ,CAAC,KAAK,EAAE,CAAA;IAEnC,KAAK,MAAM,QAAQ,IAAI,MAAM;QAC3B,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,QAAQ,CAAC;YAAE,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;IAE/D,OAAO,UAAU,CAAA;AACnB,CAAC;AAED,MAAM,MAAM,GAAG,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAA"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Properties } from './query/criteria.ts';
|
|
2
|
+
import type { Query as Parsed } from './types/storages.ts';
|
|
3
|
+
import type { Query as Requested } from './types/request.ts';
|
|
4
|
+
/** Translates the query a request carries into the one a storage is given. */
|
|
5
|
+
export declare class Query {
|
|
6
|
+
#private;
|
|
7
|
+
constructor(properties: Properties);
|
|
8
|
+
parse(query: Requested): Parsed;
|
|
9
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { empty } from '@toa.io/generic';
|
|
2
|
+
import * as criteria from './query/criteria.js';
|
|
3
|
+
import * as options from './query/options.js';
|
|
4
|
+
const parse = { ...criteria, ...options };
|
|
5
|
+
/** Translates the query a request carries into the one a storage is given. */
|
|
6
|
+
export class Query {
|
|
7
|
+
#properties;
|
|
8
|
+
/** parsed criteria by their expression */
|
|
9
|
+
#asts = new Map();
|
|
10
|
+
constructor(properties) {
|
|
11
|
+
this.#properties = properties;
|
|
12
|
+
}
|
|
13
|
+
parse(query) {
|
|
14
|
+
const result = {};
|
|
15
|
+
const { id, ids, version, criteria, search, ...rest } = query;
|
|
16
|
+
const options = this.#options(rest);
|
|
17
|
+
if (id !== undefined)
|
|
18
|
+
result.id = id;
|
|
19
|
+
if (ids !== undefined)
|
|
20
|
+
result.ids = ids;
|
|
21
|
+
if (version !== undefined)
|
|
22
|
+
result.version = version;
|
|
23
|
+
if (criteria !== undefined)
|
|
24
|
+
result.criteria = this.#criteria(criteria);
|
|
25
|
+
if (search !== undefined)
|
|
26
|
+
result.search = search;
|
|
27
|
+
if (options !== undefined)
|
|
28
|
+
result.options = options;
|
|
29
|
+
return result;
|
|
30
|
+
}
|
|
31
|
+
#options(given) {
|
|
32
|
+
if (empty(given))
|
|
33
|
+
return undefined;
|
|
34
|
+
return parse.options(given, this.#properties);
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Lexing an RSQL expression is the most expensive thing this class does, and the same
|
|
38
|
+
* expression arrives over and over: a route builds it from its own declaration and the
|
|
39
|
+
* request parameters. The tree is only read downstream — a storage builds a fresh query
|
|
40
|
+
* from it — so it is kept rather than parsed again.
|
|
41
|
+
*
|
|
42
|
+
* Expressions come from the client, hence the bound. An invalid one throws before it
|
|
43
|
+
* reaches the cache.
|
|
44
|
+
*/
|
|
45
|
+
#criteria(criteria) {
|
|
46
|
+
const known = this.#asts.get(criteria);
|
|
47
|
+
if (known !== undefined)
|
|
48
|
+
return known;
|
|
49
|
+
const ast = parse.criteria(criteria, this.#properties);
|
|
50
|
+
if (this.#asts.size >= LIMIT)
|
|
51
|
+
this.#asts.clear();
|
|
52
|
+
this.#asts.set(criteria, ast);
|
|
53
|
+
return ast;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
const LIMIT = 1024;
|
|
57
|
+
//# sourceMappingURL=query.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query.js","sourceRoot":"","sources":["../source/query.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAA;AACvC,OAAO,KAAK,QAAQ,MAAM,qBAAqB,CAAA;AAC/C,OAAO,KAAK,OAAO,MAAM,oBAAoB,CAAA;AAK7C,MAAM,KAAK,GAAG,EAAE,GAAG,QAAQ,EAAE,GAAG,OAAO,EAAE,CAAA;AAEzC,8EAA8E;AAC9E,MAAM,OAAO,KAAK;IACP,WAAW,CAAY;IAEhC,0CAA0C;IACjC,KAAK,GAAG,IAAI,GAAG,EAAgB,CAAA;IAExC,YAAmB,UAAsB;QACvC,IAAI,CAAC,WAAW,GAAG,UAAU,CAAA;IAC/B,CAAC;IAEM,KAAK,CAAC,KAAgB;QAC3B,MAAM,MAAM,GAAW,EAAE,CAAA;QACzB,MAAM,EAAE,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,KAAK,CAAA;QAE7D,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAA;QAEnC,IAAI,EAAE,KAAK,SAAS;YAAE,MAAM,CAAC,EAAE,GAAG,EAAE,CAAA;QACpC,IAAI,GAAG,KAAK,SAAS;YAAE,MAAM,CAAC,GAAG,GAAG,GAAG,CAAA;QACvC,IAAI,OAAO,KAAK,SAAS;YAAE,MAAM,CAAC,OAAO,GAAG,OAAO,CAAA;QACnD,IAAI,QAAQ,KAAK,SAAS;YAAE,MAAM,CAAC,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAA;QACtE,IAAI,MAAM,KAAK,SAAS;YAAE,MAAM,CAAC,MAAM,GAAG,MAAM,CAAA;QAChD,IAAI,OAAO,KAAK,SAAS;YAAE,MAAM,CAAC,OAAO,GAAG,OAAO,CAAA;QAEnD,OAAO,MAAM,CAAA;IACf,CAAC;IAED,QAAQ,CAAC,KAA0B;QACjC,IAAI,KAAK,CAAC,KAAK,CAAC;YAAE,OAAO,SAAS,CAAA;QAElC,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,CAAA;IAC/C,CAAC;IAED;;;;;;;;OAQG;IACH,SAAS,CAAC,QAAgB;QACxB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;QAEtC,IAAI,KAAK,KAAK,SAAS;YAAE,OAAO,KAAK,CAAA;QAErC,MAAM,GAAG,GAAG,KAAK,CAAC,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC,WAAW,CAAC,CAAA;QAEtD,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,KAAK;YAAE,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAA;QAEhD,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAA;QAE7B,OAAO,GAAG,CAAA;IACZ,CAAC;CACF;AAED,MAAM,KAAK,GAAG,IAAI,CAAA"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Connector } from './connector.ts';
|
|
2
|
+
import type { Component } from './component.ts';
|
|
3
|
+
import type { Receiver as Bridge } from './types/bridges.ts';
|
|
4
|
+
import type { Message } from './types/message.ts';
|
|
5
|
+
import type { Source } from './types/request.ts';
|
|
6
|
+
export interface Definition {
|
|
7
|
+
conditioned?: boolean;
|
|
8
|
+
adaptive?: boolean;
|
|
9
|
+
operation: string;
|
|
10
|
+
label?: string;
|
|
11
|
+
destination?: string;
|
|
12
|
+
arguments?: unknown[];
|
|
13
|
+
origin?: Source;
|
|
14
|
+
}
|
|
15
|
+
export declare class Receiver extends Connector {
|
|
16
|
+
#private;
|
|
17
|
+
constructor(definition: Definition, local: Component, bridge?: Bridge);
|
|
18
|
+
/** @hot */
|
|
19
|
+
receive(message: Message): Promise<void>;
|
|
20
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { console, decode, run } from 'openspan';
|
|
2
|
+
import { add } from '@toa.io/generic';
|
|
3
|
+
import { Connector } from './connector.js';
|
|
4
|
+
import * as trail from './trail.js';
|
|
5
|
+
export class Receiver extends Connector {
|
|
6
|
+
#conditioned;
|
|
7
|
+
#adaptive;
|
|
8
|
+
#endpoint;
|
|
9
|
+
#label;
|
|
10
|
+
#destination;
|
|
11
|
+
#arguments;
|
|
12
|
+
#origin;
|
|
13
|
+
#local;
|
|
14
|
+
#bridge;
|
|
15
|
+
#delivery;
|
|
16
|
+
#processing;
|
|
17
|
+
constructor(definition, local, bridge) {
|
|
18
|
+
super();
|
|
19
|
+
const { conditioned, adaptive, operation } = definition;
|
|
20
|
+
this.#conditioned = conditioned;
|
|
21
|
+
this.#adaptive = adaptive;
|
|
22
|
+
this.#endpoint = operation;
|
|
23
|
+
this.#label = definition.label ?? operation;
|
|
24
|
+
this.#destination = definition.destination ?? this.#label;
|
|
25
|
+
this.#arguments = definition.arguments;
|
|
26
|
+
this.#origin = definition.origin;
|
|
27
|
+
this.#local = local;
|
|
28
|
+
this.#bridge = bridge;
|
|
29
|
+
this.depends(local);
|
|
30
|
+
if (bridge !== undefined)
|
|
31
|
+
this.depends(bridge);
|
|
32
|
+
/*
|
|
33
|
+
* The delivery span is created on behalf of the messaging destination, so that
|
|
34
|
+
* each consumer forms its own complete producer/consumer pair, and service graphs
|
|
35
|
+
* display fan-out correctly: producer -> destination -> each consumer
|
|
36
|
+
* (Tempo pairs spans one-to-one, thus multiple consumers can not pair
|
|
37
|
+
* with a single producer span, see grafana/tempo#5408)
|
|
38
|
+
*/
|
|
39
|
+
this.#delivery = {
|
|
40
|
+
name: `${this.#label} deliver`,
|
|
41
|
+
kind: 'producer',
|
|
42
|
+
service: this.#destination,
|
|
43
|
+
attributes: { 'messaging.destination.name': this.#destination }
|
|
44
|
+
};
|
|
45
|
+
this.#processing = {
|
|
46
|
+
name: `${this.#label} process`,
|
|
47
|
+
kind: 'consumer',
|
|
48
|
+
service: local.locator.id,
|
|
49
|
+
attributes: { 'messaging.destination.name': this.#destination }
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
/** @hot */
|
|
53
|
+
async receive(message) {
|
|
54
|
+
/*
|
|
55
|
+
* `trail` is taken out by name rather than left to `add`, which leaves an array the
|
|
56
|
+
* request already has alone and shares the deserialized one by reference where it does
|
|
57
|
+
* not — and validates neither.
|
|
58
|
+
*/
|
|
59
|
+
const { payload, telemetry, id, trail: inbound, ...extensions } = message;
|
|
60
|
+
if (this.#conditioned === true && (await this.#bridge?.condition(payload)) === false)
|
|
61
|
+
return;
|
|
62
|
+
const request = await this.#request(payload);
|
|
63
|
+
add(request, extensions);
|
|
64
|
+
// set after `add`, so that a message field can not spoof the origin
|
|
65
|
+
if (this.#origin !== undefined)
|
|
66
|
+
request.source = this.#origin;
|
|
67
|
+
/*
|
|
68
|
+
* The message's identity is the request's. Not derived any further: a component declares at
|
|
69
|
+
* most one receiver per event, so two of its own cannot collide, and two components have
|
|
70
|
+
* collections of their own. A message from before this existed carries none, and the call
|
|
71
|
+
* this makes mints one — which is to say it is not deduplicated, as it is not today.
|
|
72
|
+
*/
|
|
73
|
+
if (id !== undefined)
|
|
74
|
+
request.id = id;
|
|
75
|
+
/*
|
|
76
|
+
* The event is a hop of its own. What an operator rewires to break a cycle is the
|
|
77
|
+
* subscription rather than the operation, so a chain that named only operations would not
|
|
78
|
+
* say how a component was re-entered. Refusing is left to `Component.invoke`, one hop
|
|
79
|
+
* later, which acquires and commits nothing before it.
|
|
80
|
+
*/
|
|
81
|
+
request.trail = [...trail.received(inbound), trail.event(this.#destination)];
|
|
82
|
+
// continue the trace from the producer span
|
|
83
|
+
const remote = telemetry === undefined ? null : decode(telemetry);
|
|
84
|
+
const task = async () => {
|
|
85
|
+
await this.#process(request);
|
|
86
|
+
};
|
|
87
|
+
if (remote === null)
|
|
88
|
+
await task();
|
|
89
|
+
else
|
|
90
|
+
await run(remote, task);
|
|
91
|
+
}
|
|
92
|
+
async #process(request) {
|
|
93
|
+
return console.span(this.#delivery, async () => console.span(this.#processing, async () => {
|
|
94
|
+
try {
|
|
95
|
+
await this.#local.invoke(this.#endpoint, request);
|
|
96
|
+
}
|
|
97
|
+
catch (error) {
|
|
98
|
+
console.error('Receiver error', {
|
|
99
|
+
component: this.#local.locator.id,
|
|
100
|
+
endpoint: this.#endpoint,
|
|
101
|
+
error
|
|
102
|
+
});
|
|
103
|
+
throw error;
|
|
104
|
+
}
|
|
105
|
+
}));
|
|
106
|
+
}
|
|
107
|
+
async #request(payload) {
|
|
108
|
+
return this.#adaptive === true
|
|
109
|
+
? await this.#bridge.request(payload, ...(this.#arguments ?? []))
|
|
110
|
+
: { input: payload };
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=receiver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"receiver.js","sourceRoot":"","sources":["../source/receiver.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Connector } from './connector.ts';
|
|
2
|
+
/** What a reflection reads, once, as it connects. */
|
|
3
|
+
export type Source<T = any> = () => Promise<T>;
|
|
4
|
+
export declare class Reflection<T = any> extends Connector {
|
|
5
|
+
#private;
|
|
6
|
+
value: T | undefined;
|
|
7
|
+
constructor(source: Source<T>);
|
|
8
|
+
protected open(): Promise<void>;
|
|
9
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Connector } from './connector.js';
|
|
2
|
+
export class Reflection extends Connector {
|
|
3
|
+
value;
|
|
4
|
+
#source;
|
|
5
|
+
constructor(source) {
|
|
6
|
+
super();
|
|
7
|
+
this.#source = source;
|
|
8
|
+
}
|
|
9
|
+
async open() {
|
|
10
|
+
this.value = await this.#source();
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=reflection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reflection.js","sourceRoot":"","sources":["../source/reflection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAK1C,MAAM,OAAO,UAAoB,SAAQ,SAAS;IACzC,KAAK,CAAe;IAElB,OAAO,CAAW;IAE3B,YAAmB,MAAiB;QAClC,KAAK,EAAE,CAAA;QAEP,IAAI,CAAC,OAAO,GAAG,MAAM,CAAA;IACvB,CAAC;IAEkB,KAAK,CAAC,IAAI;QAC3B,IAAI,CAAC,KAAK,GAAG,MAAM,IAAI,CAAC,OAAO,EAAE,CAAA;IACnC,CAAC;CACF"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Component } from './component.ts';
|
|
2
|
+
import type { Invocable } from './component.ts';
|
|
3
|
+
/** A call knows what its endpoint declares, which is what an explanation is read from. */
|
|
4
|
+
export interface Explicable extends Invocable {
|
|
5
|
+
explain(): any;
|
|
6
|
+
}
|
|
7
|
+
export declare class Remote extends Component<Explicable> {
|
|
8
|
+
protected kind: 'client';
|
|
9
|
+
explain(endpoint: string): any;
|
|
10
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Component } from './component.js';
|
|
2
|
+
import { EndpointException } from './exceptions.js';
|
|
3
|
+
export class Remote extends Component {
|
|
4
|
+
kind = 'client';
|
|
5
|
+
explain(endpoint) {
|
|
6
|
+
if (!(endpoint in this.operations))
|
|
7
|
+
throw new EndpointException(`'${endpoint}' is not provided by '${this.locator.id}'`);
|
|
8
|
+
return this.operations[endpoint].explain();
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=remote.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remote.js","sourceRoot":"","sources":["../source/remote.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AAQnD,MAAM,OAAO,MAAO,SAAQ,SAAqB;IAC5B,IAAI,GAAG,QAAiB,CAAA;IAEpC,OAAO,CAAC,QAAgB;QAC7B,IAAI,CAAC,CAAC,QAAQ,IAAI,IAAI,CAAC,UAAU,CAAC;YAChC,MAAM,IAAI,iBAAiB,CAAC,IAAI,QAAQ,yBAAyB,IAAI,CAAC,OAAO,CAAC,EAAE,GAAG,CAAC,CAAA;QAEtF,OAAO,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,OAAO,EAAE,CAAA;IAC5C,CAAC;CACF"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Connector } from './connector.ts';
|
|
2
|
+
import type { Event, Raised } from './event.ts';
|
|
3
|
+
import type { Rendering as Declaration, Row } from './types/outbox.ts';
|
|
4
|
+
/**
|
|
5
|
+
* The component's events, rendered for a destination that writes them somewhere of its own. The
|
|
6
|
+
* condition and the payload are the component's, as they are for the events it publishes, so
|
|
7
|
+
* what the destination writes is what a receiver of the event would have received.
|
|
8
|
+
*/
|
|
9
|
+
export declare class Rendering extends Connector implements Declaration {
|
|
10
|
+
#private;
|
|
11
|
+
constructor(events: Map<string, Event>);
|
|
12
|
+
render(label: string, row: Row): Promise<Raised | null>;
|
|
13
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Connector } from './connector.js';
|
|
2
|
+
/**
|
|
3
|
+
* The component's events, rendered for a destination that writes them somewhere of its own. The
|
|
4
|
+
* condition and the payload are the component's, as they are for the events it publishes, so
|
|
5
|
+
* what the destination writes is what a receiver of the event would have received.
|
|
6
|
+
*/
|
|
7
|
+
export class Rendering extends Connector {
|
|
8
|
+
#events;
|
|
9
|
+
constructor(events) {
|
|
10
|
+
super();
|
|
11
|
+
this.#events = events;
|
|
12
|
+
this.depends([...events.values()]);
|
|
13
|
+
}
|
|
14
|
+
async render(label, row) {
|
|
15
|
+
const event = this.#events.get(label);
|
|
16
|
+
if (event === undefined)
|
|
17
|
+
throw new Error(`Event '${label}' is not rendered`);
|
|
18
|
+
return await event.render(row);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=rendering.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rendering.js","sourceRoot":"","sources":["../source/rendering.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAI1C;;;;GAIG;AACH,MAAM,OAAO,SAAU,SAAQ,SAAS;IAC7B,OAAO,CAAoB;IAEpC,YAAmB,MAA0B;QAC3C,KAAK,EAAE,CAAA;QAEP,IAAI,CAAC,OAAO,GAAG,MAAM,CAAA;QAErB,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAA;IACpC,CAAC;IAEM,KAAK,CAAC,MAAM,CAAC,KAAa,EAAE,GAAQ;QACzC,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;QAErC,IAAI,KAAK,KAAK,SAAS;YAAE,MAAM,IAAI,KAAK,CAAC,UAAU,KAAK,mBAAmB,CAAC,CAAA;QAE5E,OAAO,MAAM,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;IAChC,CAAC;CACF"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether an operation of this type is incapable of changing the State. What a readonly request may
|
|
3
|
+
* reach, and nothing else; see `documentation/readonly.md`.
|
|
4
|
+
*
|
|
5
|
+
* Exhaustive on purpose, as the outcome of an exception code is: a type added later does not
|
|
6
|
+
* compile until it says which it is, because a type nobody classified would otherwise be reachable
|
|
7
|
+
* from a request that promised to read.
|
|
8
|
+
*/
|
|
9
|
+
const SAFE = {
|
|
10
|
+
transition: false,
|
|
11
|
+
observation: true,
|
|
12
|
+
assignment: false,
|
|
13
|
+
computation: true,
|
|
14
|
+
// the type for an operation that reaches outside; what it reaches is not the runtime's to read
|
|
15
|
+
effect: false,
|
|
16
|
+
// its scope is the driver's own handle, and the runtime sees nothing it does with one
|
|
17
|
+
unmanaged: false
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Takes a `string` because it comes off a manifest: an operation of a type this does not know is
|
|
21
|
+
* unsafe, which is what an endpoint nothing can classify has to be.
|
|
22
|
+
*/
|
|
23
|
+
export function safe(type) {
|
|
24
|
+
return SAFE[type] === true;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=safety.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"safety.js","sourceRoot":"","sources":["../source/safety.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AACH,MAAM,IAAI,GAA0B;IAClC,UAAU,EAAE,KAAK;IACjB,WAAW,EAAE,IAAI;IACjB,UAAU,EAAE,KAAK;IACjB,WAAW,EAAE,IAAI;IACjB,+FAA+F;IAC/F,MAAM,EAAE,KAAK;IACb,sFAAsF;IACtF,SAAS,EAAE,KAAK;CACjB,CAAA;AAED;;;GAGG;AACH,MAAM,UAAU,IAAI,CAAC,IAAY;IAC/B,OAAO,IAAI,CAAC,IAAY,CAAC,KAAK,IAAI,CAAA;AACpC,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { EntitySet } from './entities/set.ts';
|
|
2
|
+
import type { Readable } from 'node:stream';
|
|
3
|
+
import type { Factory } from './entities/factory.ts';
|
|
4
|
+
import type { Entity } from './entities/entity.ts';
|
|
5
|
+
import type { Changeset } from './entities/changeset.ts';
|
|
6
|
+
import type { Outbox } from './outbox.ts';
|
|
7
|
+
import type { Call } from './types/inbox.ts';
|
|
8
|
+
import type { Query, Record, Storage } from './types/storages.ts';
|
|
9
|
+
/**
|
|
10
|
+
* What an operation acquires and commits. One method per scope a manifest may declare, which
|
|
11
|
+
* is how an operation reaches the one it was declared with.
|
|
12
|
+
*/
|
|
13
|
+
export declare class State {
|
|
14
|
+
#private;
|
|
15
|
+
readonly storage: Storage;
|
|
16
|
+
constructor(storage: Storage, entities: Factory, outbox: Outbox | undefined, associated?: boolean);
|
|
17
|
+
init(id?: string): Entity;
|
|
18
|
+
fit(values: object): void;
|
|
19
|
+
/** scope `entry` */
|
|
20
|
+
entry(query: Query, mutable?: boolean): Promise<Entity | null>;
|
|
21
|
+
/** scope `entries` */
|
|
22
|
+
entries(query: Query, mutable?: boolean): Promise<EntitySet>;
|
|
23
|
+
/** scope `stream` */
|
|
24
|
+
stream(query: Query): Promise<Readable>;
|
|
25
|
+
/** scope `changeset` */
|
|
26
|
+
changeset(query: Query): Changeset;
|
|
27
|
+
/** scope `none`: an operation that acquires nothing still asks for its scope */
|
|
28
|
+
none(): null;
|
|
29
|
+
/** get-or-create, in one indivisible step */
|
|
30
|
+
/** what the call under this identity answered, or `null` where it was never made */
|
|
31
|
+
recall(id: string): Promise<object | null>;
|
|
32
|
+
ensure(query: Query | undefined, properties: object, input?: object, call?: Call): Promise<Entity>;
|
|
33
|
+
commit(state: Entity | EntitySet, input?: object, call?: Call): Promise<boolean>;
|
|
34
|
+
massCommit(state: EntitySet, input?: object): Promise<boolean>;
|
|
35
|
+
apply(state: Changeset, input?: object, call?: Call): Promise<Record>;
|
|
36
|
+
}
|