@agentshouse/mdruntime 0.1.0-cd26b960b7262 → 0.1.0-cd30853a1b15e
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/README.md +21 -19
- package/dist/acceptance.d.ts +0 -3
- package/dist/acceptance.d.ts.map +1 -1
- package/dist/acceptance.js +72 -158
- package/dist/act-lanes.d.ts +30 -0
- package/dist/act-lanes.d.ts.map +1 -0
- package/dist/act-lanes.js +225 -0
- package/dist/actions.d.ts +8 -2
- package/dist/actions.d.ts.map +1 -1
- package/dist/actions.js +118 -67
- package/dist/adapter.d.ts +81 -56
- package/dist/adapter.d.ts.map +1 -1
- package/dist/attached-model.d.ts +0 -1
- package/dist/attached-model.d.ts.map +1 -1
- package/dist/attached-model.js +0 -5
- package/dist/authored.d.ts +88 -0
- package/dist/authored.d.ts.map +1 -0
- package/dist/authored.js +345 -0
- package/dist/bootstrap.d.ts +1 -1
- package/dist/bootstrap.d.ts.map +1 -1
- package/dist/bootstrap.js +6 -19
- package/dist/change-set.d.ts +4 -0
- package/dist/change-set.d.ts.map +1 -1
- package/dist/change-set.js +6 -0
- package/dist/change.d.ts +4 -0
- package/dist/change.d.ts.map +1 -1
- package/dist/change.js +3 -0
- package/dist/chat-types.d.ts +0 -2
- package/dist/chat-types.d.ts.map +1 -1
- package/dist/chat-types.js +0 -2
- package/dist/client.d.ts +10 -19
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +30 -18
- package/dist/collection.d.ts +25 -4
- package/dist/collection.d.ts.map +1 -1
- package/dist/collection.js +19 -2
- package/dist/column.d.ts +5 -0
- package/dist/column.d.ts.map +1 -0
- package/dist/column.js +9 -0
- package/dist/compile.d.ts +2 -0
- package/dist/compile.d.ts.map +1 -1
- package/dist/compile.js +17 -5
- package/dist/connection.d.ts.map +1 -1
- package/dist/connection.js +31 -24
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +1 -1
- package/dist/conversation-live.d.ts +26 -12
- package/dist/conversation-live.d.ts.map +1 -1
- package/dist/conversation-live.js +23 -12
- package/dist/conversation-row.d.ts +8 -1
- package/dist/conversation-row.d.ts.map +1 -1
- package/dist/conversation-row.js +20 -7
- package/dist/conversation.d.ts +32 -10
- package/dist/conversation.d.ts.map +1 -1
- package/dist/conversation.js +317 -232
- package/dist/declaration.d.ts +10 -0
- package/dist/declaration.d.ts.map +1 -0
- package/dist/declaration.js +24 -0
- package/dist/discovery.d.ts.map +1 -1
- package/dist/discovery.js +19 -44
- package/dist/durability.d.ts +4 -0
- package/dist/durability.d.ts.map +1 -1
- package/dist/durability.js +4 -0
- package/dist/entry.js +1 -1
- package/dist/expectation.d.ts +25 -14
- package/dist/expectation.d.ts.map +1 -1
- package/dist/expectation.js +51 -20
- package/dist/failure.d.ts +3 -0
- package/dist/failure.d.ts.map +1 -1
- package/dist/failure.js +6 -0
- package/dist/figures.d.ts.map +1 -1
- package/dist/figures.js +4 -2
- package/dist/file.d.ts.map +1 -1
- package/dist/file.js +2 -1
- package/dist/host.d.ts +18 -2
- package/dist/host.d.ts.map +1 -1
- package/dist/host.js +55 -15
- package/dist/index.d.ts +15 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -7
- package/dist/install.d.ts +10 -6
- package/dist/install.d.ts.map +1 -1
- package/dist/install.js +92 -109
- package/dist/lifecycle.d.ts +1 -1
- package/dist/lifecycle.d.ts.map +1 -1
- package/dist/lifecycle.js +54 -40
- package/dist/listing.d.ts +11 -12
- package/dist/listing.d.ts.map +1 -1
- package/dist/listing.js +48 -72
- package/dist/live.d.ts +5 -3
- package/dist/live.d.ts.map +1 -1
- package/dist/live.js +74 -31
- package/dist/loaded.d.ts +5 -0
- package/dist/loaded.d.ts.map +1 -0
- package/dist/loaded.js +40 -0
- package/dist/locks.d.ts +2 -4
- package/dist/locks.d.ts.map +1 -1
- package/dist/locks.js +10 -39
- package/dist/lost.d.ts.map +1 -1
- package/dist/lost.js +11 -23
- package/dist/media.d.ts +5 -0
- package/dist/media.d.ts.map +1 -1
- package/dist/media.js +65 -14
- package/dist/memory.d.ts +7 -3
- package/dist/memory.d.ts.map +1 -1
- package/dist/memory.js +56 -26
- package/dist/messages.d.ts +12 -6
- package/dist/messages.d.ts.map +1 -1
- package/dist/messages.js +25 -27
- package/dist/model.d.ts +0 -1
- package/dist/model.d.ts.map +1 -1
- package/dist/model.js +0 -5
- package/dist/models.d.ts +4 -8
- package/dist/models.d.ts.map +1 -1
- package/dist/models.js +97 -139
- package/dist/observation.d.ts +27 -12
- package/dist/observation.d.ts.map +1 -1
- package/dist/observation.js +173 -69
- package/dist/opened.d.ts +1 -1
- package/dist/opened.d.ts.map +1 -1
- package/dist/opened.js +2 -2
- package/dist/opening.d.ts.map +1 -1
- package/dist/opening.js +5 -9
- package/dist/outcome.d.ts +7 -0
- package/dist/outcome.d.ts.map +1 -1
- package/dist/outcome.js +23 -2
- package/dist/overlay.d.ts +6 -2
- package/dist/overlay.d.ts.map +1 -1
- package/dist/overlay.js +37 -24
- package/dist/page-metadata.d.ts +8 -0
- package/dist/page-metadata.d.ts.map +1 -0
- package/dist/page-metadata.js +19 -0
- package/dist/parts.d.ts +3 -59
- package/dist/parts.d.ts.map +1 -1
- package/dist/parts.js +10 -123
- package/dist/preparation.d.ts +27 -6
- package/dist/preparation.d.ts.map +1 -1
- package/dist/preparation.js +154 -66
- package/dist/presence.d.ts +58 -0
- package/dist/presence.d.ts.map +1 -0
- package/dist/presence.js +231 -0
- package/dist/queries.d.ts +2 -2
- package/dist/queries.d.ts.map +1 -1
- package/dist/queries.js +66 -30
- package/dist/questions.d.ts +1 -5
- package/dist/questions.d.ts.map +1 -1
- package/dist/questions.js +1 -7
- package/dist/queue.d.ts +40 -0
- package/dist/queue.d.ts.map +1 -0
- package/dist/queue.js +480 -0
- package/dist/reach.d.ts +2 -3
- package/dist/reach.d.ts.map +1 -1
- package/dist/reach.js +83 -25
- package/dist/react.d.ts +8 -5
- package/dist/react.d.ts.map +1 -1
- package/dist/react.js +28 -5
- package/dist/readiness.d.ts +9 -3
- package/dist/readiness.d.ts.map +1 -1
- package/dist/readiness.js +3 -5
- package/dist/reads.d.ts +4 -2
- package/dist/reads.d.ts.map +1 -1
- package/dist/reads.js +11 -4
- package/dist/recovery.d.ts +3 -1
- package/dist/recovery.d.ts.map +1 -1
- package/dist/recovery.js +29 -7
- package/dist/refresh.js +2 -2
- package/dist/refusal.d.ts.map +1 -1
- package/dist/refusal.js +5 -5
- package/dist/replica.d.ts +5 -11
- package/dist/replica.d.ts.map +1 -1
- package/dist/replica.js +14 -16
- package/dist/retried.d.ts +30 -0
- package/dist/retried.d.ts.map +1 -0
- package/dist/retried.js +72 -0
- package/dist/room-draft.d.ts +30 -5
- package/dist/room-draft.d.ts.map +1 -1
- package/dist/room-draft.js +270 -63
- package/dist/room-drafts.d.ts.map +1 -1
- package/dist/room-drafts.js +8 -5
- package/dist/room-list.d.ts +10 -0
- package/dist/room-list.d.ts.map +1 -0
- package/dist/room-list.js +45 -0
- package/dist/rows.d.ts +2 -1
- package/dist/rows.d.ts.map +1 -1
- package/dist/rows.js +9 -10
- package/dist/runtime.d.ts +9 -18
- package/dist/runtime.d.ts.map +1 -1
- package/dist/save.d.ts +42 -90
- package/dist/save.d.ts.map +1 -1
- package/dist/save.js +314 -223
- package/dist/saves.d.ts +2 -40
- package/dist/saves.d.ts.map +1 -1
- package/dist/saves.js +124 -703
- package/dist/seed.d.ts.map +1 -1
- package/dist/seed.js +4 -4
- package/dist/shown.d.ts +7 -5
- package/dist/shown.d.ts.map +1 -1
- package/dist/shown.js +75 -58
- package/dist/socket/lanes.d.ts +12 -4
- package/dist/socket/lanes.d.ts.map +1 -1
- package/dist/socket/lanes.js +34 -8
- package/dist/socket.d.ts +3 -6
- package/dist/socket.d.ts.map +1 -1
- package/dist/socket.js +3 -14
- package/dist/source.d.ts +5 -7
- package/dist/source.d.ts.map +1 -1
- package/dist/source.js +13 -2
- package/dist/store/installs.d.ts +2 -2
- package/dist/store/installs.d.ts.map +1 -1
- package/dist/store/installs.js +10 -4
- package/dist/store/readiness.d.ts +5 -4
- package/dist/store/readiness.d.ts.map +1 -1
- package/dist/store/readiness.js +28 -12
- package/dist/store/records.d.ts +17 -6
- package/dist/store/records.d.ts.map +1 -1
- package/dist/store/records.js +56 -22
- package/dist/store/rooms-shown.d.ts +8 -0
- package/dist/store/rooms-shown.d.ts.map +1 -0
- package/dist/store/rooms-shown.js +13 -0
- package/dist/store.d.ts +23 -14
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +46 -17
- package/dist/stored.d.ts +24 -13
- package/dist/stored.d.ts.map +1 -1
- package/dist/stored.js +80 -29
- package/dist/surface.d.ts +5 -3
- package/dist/surface.d.ts.map +1 -1
- package/dist/surface.js +23 -21
- package/dist/sync.d.ts +1 -1
- package/dist/sync.d.ts.map +1 -1
- package/dist/sync.js +89 -85
- package/dist/tables.d.ts +16 -56
- package/dist/tables.d.ts.map +1 -1
- package/dist/tables.js +86 -327
- package/dist/tallies.d.ts.map +1 -1
- package/dist/tallies.js +1 -2
- package/dist/validation.d.ts.map +1 -1
- package/dist/validation.js +4 -10
- package/dist/wire.d.ts +45 -7
- package/dist/wire.d.ts.map +1 -1
- package/dist/wire.js +15 -4
- package/package.json +3 -2
- package/dist/attempt.d.ts +0 -16
- package/dist/attempt.d.ts.map +0 -1
- package/dist/attempt.js +0 -70
- package/dist/job.d.ts +0 -33
- package/dist/job.d.ts.map +0 -1
- package/dist/job.js +0 -54
- package/dist/log.d.ts +0 -6
- package/dist/log.d.ts.map +0 -1
- package/dist/log.js +0 -14
- package/dist/socket/rooms.d.ts +0 -44
- package/dist/socket/rooms.d.ts.map +0 -1
- package/dist/socket/rooms.js +0 -90
- package/dist/store/fences.d.ts +0 -16
- package/dist/store/fences.d.ts.map +0 -1
- package/dist/store/fences.js +0 -26
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
import { expectedList } from './expectation.js';
|
|
2
|
+
import { changeBatchIdentity } from './identity.js';
|
|
3
|
+
const IDLE = { busy: false, drawn: false, ended: null };
|
|
4
|
+
export function acting(rules) {
|
|
5
|
+
const { store, uncertain, ending, settles } = rules;
|
|
6
|
+
const mint = rules.mint ?? (() => changeBatchIdentity());
|
|
7
|
+
const identities = new Map();
|
|
8
|
+
const waiting = new Map();
|
|
9
|
+
const settling = new Map();
|
|
10
|
+
const blobs = new WeakMap();
|
|
11
|
+
let counted = 0;
|
|
12
|
+
let touches = 0;
|
|
13
|
+
const requestOf = (name, input) => {
|
|
14
|
+
const carried = [];
|
|
15
|
+
const json = JSON.stringify(input, (_key, value) => {
|
|
16
|
+
if (!(value instanceof Blob))
|
|
17
|
+
return value;
|
|
18
|
+
let one = blobs.get(value);
|
|
19
|
+
if (one === undefined) {
|
|
20
|
+
counted += 1;
|
|
21
|
+
one = counted;
|
|
22
|
+
blobs.set(value, one);
|
|
23
|
+
}
|
|
24
|
+
carried.push(one);
|
|
25
|
+
return null;
|
|
26
|
+
});
|
|
27
|
+
return `${name}\u0000${json}\u0000${carried.join(',')}`;
|
|
28
|
+
};
|
|
29
|
+
const identityOf = (request) => {
|
|
30
|
+
const held = identities.get(request);
|
|
31
|
+
if (held !== undefined)
|
|
32
|
+
return held;
|
|
33
|
+
const fresh = { operation: mint(), touched: 0, flying: 0 };
|
|
34
|
+
identities.set(request, fresh);
|
|
35
|
+
return fresh;
|
|
36
|
+
};
|
|
37
|
+
const settled = (act, ended, calls) => {
|
|
38
|
+
const released = new Map();
|
|
39
|
+
for (const { request, identity, ended: answered } of calls) {
|
|
40
|
+
const heard = answered === 'accepted' || answered === 'refused';
|
|
41
|
+
if (ended === 'accepted' && heard)
|
|
42
|
+
released.set(request, identity.touched);
|
|
43
|
+
else {
|
|
44
|
+
touches += 1;
|
|
45
|
+
identity.touched = touches;
|
|
46
|
+
identities.set(request, identity);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
if (ended === 'refused' || ended === 'unsent')
|
|
50
|
+
store.drop(act);
|
|
51
|
+
for (const { request, ended: answered } of calls) {
|
|
52
|
+
const earlier = waiting.get(request);
|
|
53
|
+
if (answered === 'unsent' && earlier !== undefined)
|
|
54
|
+
continue;
|
|
55
|
+
if (earlier !== undefined && earlier !== act)
|
|
56
|
+
store.drop(earlier);
|
|
57
|
+
if (ended === 'unanswered')
|
|
58
|
+
waiting.set(request, act);
|
|
59
|
+
else
|
|
60
|
+
waiting.delete(request);
|
|
61
|
+
}
|
|
62
|
+
if (ended === 'accepted' || calls.some((one) => one.ended === 'accepted'))
|
|
63
|
+
rules.acted?.();
|
|
64
|
+
return released;
|
|
65
|
+
};
|
|
66
|
+
const release = (released) => {
|
|
67
|
+
for (const [request, touched] of released) {
|
|
68
|
+
const held = identities.get(request);
|
|
69
|
+
if (held !== undefined && held.touched === touched && held.flying === 0) {
|
|
70
|
+
identities.delete(request);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
return {
|
|
75
|
+
open() {
|
|
76
|
+
const listeners = new Set();
|
|
77
|
+
const releasing = new Map();
|
|
78
|
+
let tail = Promise.resolve();
|
|
79
|
+
let pressed = 0;
|
|
80
|
+
let drawing = 0;
|
|
81
|
+
let ended = null;
|
|
82
|
+
let held = null;
|
|
83
|
+
let presses = 0;
|
|
84
|
+
let shown = IDLE;
|
|
85
|
+
const show = () => {
|
|
86
|
+
const busy = pressed > 0;
|
|
87
|
+
const drawn = drawing > 0;
|
|
88
|
+
if (shown.busy === busy && shown.drawn === drawn && shown.ended === ended)
|
|
89
|
+
return;
|
|
90
|
+
shown = { busy, drawn, ended };
|
|
91
|
+
for (const listener of listeners)
|
|
92
|
+
listener();
|
|
93
|
+
};
|
|
94
|
+
const awaiting = (outcome, operations, heard, again) => new Promise((resolve) => {
|
|
95
|
+
const forgotten = () => {
|
|
96
|
+
for (const operation of operations)
|
|
97
|
+
if (settling.get(operation) === record)
|
|
98
|
+
settling.delete(operation);
|
|
99
|
+
};
|
|
100
|
+
const record = {
|
|
101
|
+
supersede() {
|
|
102
|
+
if (held !== record)
|
|
103
|
+
return;
|
|
104
|
+
held = null;
|
|
105
|
+
forgotten();
|
|
106
|
+
resolve(outcome);
|
|
107
|
+
},
|
|
108
|
+
};
|
|
109
|
+
held = record;
|
|
110
|
+
for (const operation of operations)
|
|
111
|
+
settling.set(operation, record);
|
|
112
|
+
const answers = operations.map((operation) => heard(operation).then((answered) => {
|
|
113
|
+
if (!answered)
|
|
114
|
+
record.supersede();
|
|
115
|
+
return answered;
|
|
116
|
+
}));
|
|
117
|
+
void Promise.all(answers).then(() => {
|
|
118
|
+
if (held !== record)
|
|
119
|
+
return;
|
|
120
|
+
held = null;
|
|
121
|
+
forgotten();
|
|
122
|
+
resolve(again());
|
|
123
|
+
}, () => record.supersede());
|
|
124
|
+
});
|
|
125
|
+
const attempt = (steps, expected, press) => {
|
|
126
|
+
const act = store.begin();
|
|
127
|
+
let drew = false;
|
|
128
|
+
const expect = (more) => {
|
|
129
|
+
if (expectedList(more).length === 0)
|
|
130
|
+
return;
|
|
131
|
+
store.expect(act, more);
|
|
132
|
+
if (drew)
|
|
133
|
+
return;
|
|
134
|
+
drew = true;
|
|
135
|
+
drawing += 1;
|
|
136
|
+
show();
|
|
137
|
+
};
|
|
138
|
+
pressed += 1;
|
|
139
|
+
expect(expected);
|
|
140
|
+
show();
|
|
141
|
+
const calls = [];
|
|
142
|
+
const send = Object.assign(async (name, input, sending) => {
|
|
143
|
+
const request = requestOf(name, input);
|
|
144
|
+
const identity = identityOf(request);
|
|
145
|
+
settling.get(identity.operation)?.supersede();
|
|
146
|
+
const called = { request, identity, ended: null };
|
|
147
|
+
calls.push(called);
|
|
148
|
+
touches += 1;
|
|
149
|
+
identity.touched = touches;
|
|
150
|
+
identity.flying += 1;
|
|
151
|
+
let outcome;
|
|
152
|
+
try {
|
|
153
|
+
outcome = await sending(identity.operation);
|
|
154
|
+
}
|
|
155
|
+
catch {
|
|
156
|
+
outcome = uncertain;
|
|
157
|
+
}
|
|
158
|
+
finally {
|
|
159
|
+
identity.flying -= 1;
|
|
160
|
+
}
|
|
161
|
+
called.ended = ending(outcome);
|
|
162
|
+
return outcome;
|
|
163
|
+
}, { expect });
|
|
164
|
+
const end = (outcome, how) => {
|
|
165
|
+
for (const [request, touched] of settled(act, how, calls))
|
|
166
|
+
releasing.set(request, touched);
|
|
167
|
+
pressed -= 1;
|
|
168
|
+
if (drew)
|
|
169
|
+
drawing -= 1;
|
|
170
|
+
ended = outcome;
|
|
171
|
+
if (pressed === 0) {
|
|
172
|
+
release(releasing);
|
|
173
|
+
releasing.clear();
|
|
174
|
+
}
|
|
175
|
+
show();
|
|
176
|
+
};
|
|
177
|
+
const turn = tail.then(async () => {
|
|
178
|
+
ended = null;
|
|
179
|
+
show();
|
|
180
|
+
let outcome;
|
|
181
|
+
try {
|
|
182
|
+
outcome = await steps(send);
|
|
183
|
+
}
|
|
184
|
+
catch (error) {
|
|
185
|
+
end(uncertain, 'unanswered');
|
|
186
|
+
throw error;
|
|
187
|
+
}
|
|
188
|
+
const how = ending(outcome);
|
|
189
|
+
end(outcome, how);
|
|
190
|
+
return { outcome, how };
|
|
191
|
+
});
|
|
192
|
+
tail = turn.catch(() => undefined);
|
|
193
|
+
return turn.then(({ outcome, how }) => {
|
|
194
|
+
const lost = calls.flatMap(({ identity, ended: answered }) => answered === 'unanswered' ? [identity.operation] : []);
|
|
195
|
+
if (how !== 'unanswered' || lost.length === 0 || settles === undefined)
|
|
196
|
+
return outcome;
|
|
197
|
+
if (press !== presses)
|
|
198
|
+
return outcome;
|
|
199
|
+
return awaiting(outcome, lost, settles, () => attempt(steps, expected, press));
|
|
200
|
+
});
|
|
201
|
+
};
|
|
202
|
+
const run = (steps, expected = null) => {
|
|
203
|
+
held?.supersede();
|
|
204
|
+
presses += 1;
|
|
205
|
+
return attempt(steps, expected, presses);
|
|
206
|
+
};
|
|
207
|
+
return {
|
|
208
|
+
run,
|
|
209
|
+
shown: () => shown,
|
|
210
|
+
subscribe(listener) {
|
|
211
|
+
listeners.add(listener);
|
|
212
|
+
return () => {
|
|
213
|
+
listeners.delete(listener);
|
|
214
|
+
};
|
|
215
|
+
},
|
|
216
|
+
forget() {
|
|
217
|
+
if (pressed > 0 || ended === null)
|
|
218
|
+
return;
|
|
219
|
+
ended = null;
|
|
220
|
+
show();
|
|
221
|
+
},
|
|
222
|
+
};
|
|
223
|
+
},
|
|
224
|
+
};
|
|
225
|
+
}
|
package/dist/actions.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { ConversationHistoryRequest } from './adapter.js';
|
|
2
2
|
import { type CallResult, type HistoryAnswer, type Resolution } from './outcome.js';
|
|
3
3
|
import type { Attempted } from './recovery.js';
|
|
4
|
+
import type { Attempt } from './retried.js';
|
|
4
5
|
import type { Runtime } from './runtime.js';
|
|
5
6
|
export type HistoryQuery = {
|
|
6
7
|
revision?: string;
|
|
@@ -12,9 +13,14 @@ export declare function located(runtime: Runtime, room: string, path: string, de
|
|
|
12
13
|
path: string;
|
|
13
14
|
} | null>;
|
|
14
15
|
export declare function resolveReference(runtime: Runtime, room: string, path: string, destination: string): Promise<Resolution>;
|
|
15
|
-
export
|
|
16
|
+
export type Invoked = {
|
|
17
|
+
readonly dispatching?: () => Promise<void>;
|
|
18
|
+
readonly attempt?: Attempt;
|
|
19
|
+
};
|
|
20
|
+
export declare function invokeAction(runtime: Runtime, name: string, input: unknown, { dispatching, attempt }?: Invoked): Promise<CallResult>;
|
|
16
21
|
export declare function readConversationHistory(runtime: Runtime, request: ConversationHistoryRequest): Promise<CallResult>;
|
|
17
|
-
export declare function called(runtime: Runtime, name: string, input: unknown): Promise<CallResult>;
|
|
22
|
+
export declare function called(runtime: Runtime, name: string, input: unknown, attempt?: Attempt): Promise<CallResult>;
|
|
23
|
+
export declare function answeredCall(runtime: Runtime, operation: string): Promise<boolean>;
|
|
18
24
|
export declare function resendCalls(runtime: Runtime, signal: AbortSignal): Promise<Attempted>;
|
|
19
25
|
export declare function resendLater(runtime: Runtime): void;
|
|
20
26
|
//# sourceMappingURL=actions.d.ts.map
|
package/dist/actions.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../src/actions.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../src/actions.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,cAAc,CAAC;AAM/D,OAAO,EAWL,KAAK,UAAU,EACf,KAAK,aAAa,EAClB,KAAK,UAAU,EAChB,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE/C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAG5C,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAOF,wBAAsB,WAAW,CAC/B,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,KAAK,GAAE,YAAiB,GACvB,OAAO,CAAC,aAAa,CAAC,CA+BxB;AAED,wBAAsB,OAAO,CAC3B,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CAShD;AAED,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,UAAU,CAAC,CAuBrB;AAwBD,MAAM,MAAM,OAAO,GAAG;IACpB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3C,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;CAC5B,CAAC;AAEF,wBAAsB,YAAY,CAChC,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,OAAO,EACd,EAAE,WAAW,EAAE,OAAO,EAAE,GAAE,OAAY,GACrC,OAAO,CAAC,UAAU,CAAC,CA6BrB;AAED,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,0BAA0B,GAClC,OAAO,CAAC,UAAU,CAAC,CAerB;AA4GD,wBAAsB,MAAM,CAC1B,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,OAAO,EACd,OAAO,CAAC,EAAE,OAAO,GAChB,OAAO,CAAC,UAAU,CAAC,CAKrB;AAED,wBAAsB,YAAY,CAAC,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAaxF;AAED,wBAAsB,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,SAAS,CAAC,CAe3F;AAiBD,wBAAgB,WAAW,CAAC,OAAO,EAAE,OAAO,QAG3C"}
|
package/dist/actions.js
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import { roomTarget, target } from '@agentshouse/mdmodel';
|
|
2
|
-
import { resendConversations } from './conversation.js';
|
|
2
|
+
import { CATCHING_UP, holdsSubmission, resendConversations } from './conversation.js';
|
|
3
3
|
import { listingNow } from './listing.js';
|
|
4
4
|
import { locked, lockedRooms } from './locks.js';
|
|
5
5
|
import { scoped } from './models.js';
|
|
6
|
-
import { ABSENT_TARGET,
|
|
6
|
+
import { ABSENT_TARGET, failure, historyAnswer, LOCKED_UNREADABLE, lockedRoom, handedOutcome, UNANSWERED, undeclared, UNCERTAIN, UNREADABLE, } from './outcome.js';
|
|
7
7
|
import { refuse } from './refusal.js';
|
|
8
8
|
function operationOf(input) {
|
|
9
9
|
const operation = input?.operation_id;
|
|
10
10
|
return typeof operation === 'string' ? operation : null;
|
|
11
11
|
}
|
|
12
12
|
export async function readHistory(runtime, locator, path, query = {}) {
|
|
13
|
-
const { store, socket,
|
|
13
|
+
const { store, socket, presence } = runtime;
|
|
14
14
|
const { session } = socket;
|
|
15
15
|
if (socket.closed() || session.now().refusal !== null)
|
|
16
16
|
return UNCERTAIN;
|
|
@@ -26,13 +26,7 @@ export async function readHistory(runtime, locator, path, query = {}) {
|
|
|
26
26
|
const { closed, authorization, refusal } = session.now();
|
|
27
27
|
if (closed || authorization === undefined || refusal !== null)
|
|
28
28
|
return UNCERTAIN;
|
|
29
|
-
const since =
|
|
30
|
-
const transfer = ['transfer', 'history', locator, path];
|
|
31
|
-
if (query.revision !== undefined)
|
|
32
|
-
transfer.push(query.revision);
|
|
33
|
-
if (query.pageToken !== undefined)
|
|
34
|
-
transfer.push(query.pageToken);
|
|
35
|
-
journal.record(transfer.join(' '));
|
|
29
|
+
const since = presence.losses();
|
|
36
30
|
try {
|
|
37
31
|
const result = await socket.history(authorization, {
|
|
38
32
|
locator,
|
|
@@ -40,20 +34,18 @@ export async function readHistory(runtime, locator, path, query = {}) {
|
|
|
40
34
|
...(query.revision === undefined ? {} : { revision: query.revision }),
|
|
41
35
|
...(query.pageToken === undefined ? {} : { pageToken: query.pageToken }),
|
|
42
36
|
});
|
|
43
|
-
|
|
44
|
-
if (store.fences.since(locator, since))
|
|
37
|
+
if (presence.lostSince(locator, since))
|
|
45
38
|
return failure({ kind: 'room-not-readable', locator });
|
|
46
39
|
if (result.kind === 'scoped-refusal') {
|
|
47
40
|
const room = await store.record(result.locator);
|
|
48
41
|
if (room !== undefined)
|
|
49
|
-
await scoped(runtime, result, room,
|
|
42
|
+
await scoped(runtime, result, room.locator, room.declaration);
|
|
50
43
|
}
|
|
51
44
|
if (result.kind === 'revoked-authorization')
|
|
52
45
|
await refuse(runtime, 'revoked-authorization');
|
|
53
46
|
return historyAnswer(result);
|
|
54
47
|
}
|
|
55
48
|
catch {
|
|
56
|
-
journal.record('outcome history transport-uncertainty');
|
|
57
49
|
return UNCERTAIN;
|
|
58
50
|
}
|
|
59
51
|
}
|
|
@@ -110,62 +102,57 @@ async function calledRooms(runtime, name, input) {
|
|
|
110
102
|
const named = input[member];
|
|
111
103
|
return (Array.isArray(named) ? named : [named]).filter((room) => typeof room === 'string');
|
|
112
104
|
}
|
|
113
|
-
export async function invokeAction(runtime, name, input, dispatching) {
|
|
114
|
-
const { store, socket,
|
|
105
|
+
export async function invokeAction(runtime, name, input, { dispatching, attempt } = {}) {
|
|
106
|
+
const { store, socket, retries } = runtime;
|
|
115
107
|
const { session } = socket;
|
|
116
108
|
await socket.ready;
|
|
117
|
-
if (socket.closed() || session.now().refusal !== null)
|
|
118
|
-
return
|
|
109
|
+
if (socket.closed() || session.now().refusal !== null) {
|
|
110
|
+
return handedOutcome(retries, attempt, UNANSWERED);
|
|
111
|
+
}
|
|
119
112
|
if ((await declaredAction(runtime, name)) === undefined)
|
|
120
113
|
return undeclared(name);
|
|
121
114
|
try {
|
|
122
115
|
await socket.authorize();
|
|
123
116
|
}
|
|
124
117
|
catch {
|
|
125
|
-
return
|
|
118
|
+
return handedOutcome(retries, attempt, UNANSWERED);
|
|
126
119
|
}
|
|
127
120
|
const { closed, authorization, refusal } = session.now();
|
|
128
|
-
if (closed || authorization === undefined || refusal !== null)
|
|
129
|
-
return
|
|
121
|
+
if (closed || authorization === undefined || refusal !== null) {
|
|
122
|
+
return handedOutcome(retries, attempt, UNANSWERED);
|
|
123
|
+
}
|
|
130
124
|
await dispatching?.();
|
|
131
|
-
journal.record(`transfer action ${name}`);
|
|
132
125
|
try {
|
|
133
126
|
const result = await socket.action(authorization, { name, input });
|
|
134
127
|
if (result.kind === 'scoped-refusal') {
|
|
135
128
|
const room = await store.record(result.locator);
|
|
136
129
|
if (room !== undefined)
|
|
137
|
-
await scoped(runtime, result, room,
|
|
130
|
+
await scoped(runtime, result, room.locator, room.declaration);
|
|
138
131
|
}
|
|
139
132
|
if (result.kind === 'revoked-authorization')
|
|
140
133
|
await refuse(runtime, 'revoked-authorization');
|
|
141
|
-
|
|
142
|
-
if (result.kind === 'rejected')
|
|
143
|
-
journal.record(`refusal rejected ${result.code}`);
|
|
144
|
-
return calledResult(result);
|
|
134
|
+
return handedOutcome(retries, attempt, result);
|
|
145
135
|
}
|
|
146
|
-
catch {
|
|
147
|
-
|
|
148
|
-
return UNCERTAIN;
|
|
136
|
+
catch (error) {
|
|
137
|
+
return handedOutcome(retries, attempt, { kind: 'transport-uncertainty', failure: error });
|
|
149
138
|
}
|
|
150
139
|
}
|
|
151
140
|
export async function readConversationHistory(runtime, request) {
|
|
152
|
-
const { socket,
|
|
141
|
+
const { socket, retries } = runtime;
|
|
142
|
+
const caught = { step: 'conversations', instance: CATCHING_UP };
|
|
153
143
|
await socket.ready;
|
|
154
144
|
const stream = socket.conversations();
|
|
155
145
|
if (socket.closed() || socket.session.now().refusal !== null || stream?.history === undefined) {
|
|
156
|
-
return
|
|
146
|
+
return handedOutcome(retries, caught, UNANSWERED);
|
|
157
147
|
}
|
|
158
|
-
journal.record('transfer conversation history');
|
|
159
148
|
try {
|
|
160
149
|
const result = await stream.history(request);
|
|
161
150
|
if (result.kind === 'revoked-authorization')
|
|
162
151
|
await refuse(runtime, 'revoked-authorization');
|
|
163
|
-
|
|
164
|
-
return calledResult(result);
|
|
152
|
+
return handedOutcome(retries, caught, result);
|
|
165
153
|
}
|
|
166
|
-
catch {
|
|
167
|
-
|
|
168
|
-
return UNCERTAIN;
|
|
154
|
+
catch (error) {
|
|
155
|
+
return handedOutcome(retries, caught, { kind: 'transport-uncertainty', failure: error });
|
|
169
156
|
}
|
|
170
157
|
}
|
|
171
158
|
function unsettled(result) {
|
|
@@ -173,59 +160,123 @@ function unsettled(result) {
|
|
|
173
160
|
return false;
|
|
174
161
|
return result.retryable && (result.kind !== 'rejected' || result.reset === undefined);
|
|
175
162
|
}
|
|
176
|
-
|
|
177
|
-
|
|
163
|
+
function numberedCall(runtime, name, input, operation, dispatching) {
|
|
164
|
+
return invokeAction(runtime, name, input, {
|
|
165
|
+
dispatching,
|
|
166
|
+
attempt: { step: 'sending', instance: `action ${operation}` },
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
function keptSender(runtime, name, input, operation, resent = false) {
|
|
170
|
+
const { store, socket } = runtime;
|
|
178
171
|
const { lanes } = socket;
|
|
172
|
+
const dispatching = async () => (await store.open()).keepCall({ operation, name, input });
|
|
173
|
+
let waiting = [];
|
|
174
|
+
let last = UNCERTAIN;
|
|
175
|
+
let lost = resent;
|
|
176
|
+
const tell = (result) => {
|
|
177
|
+
last = result;
|
|
178
|
+
const told = waiting;
|
|
179
|
+
waiting = [];
|
|
180
|
+
for (const answer of told)
|
|
181
|
+
answer(result);
|
|
182
|
+
};
|
|
183
|
+
const sender = {
|
|
184
|
+
next: () => new Promise((answer) => waiting.push(answer)),
|
|
185
|
+
async send() {
|
|
186
|
+
let result;
|
|
187
|
+
try {
|
|
188
|
+
result = await numberedCall(runtime, name, input, operation, dispatching);
|
|
189
|
+
}
|
|
190
|
+
catch (error) {
|
|
191
|
+
tell(last);
|
|
192
|
+
throw error;
|
|
193
|
+
}
|
|
194
|
+
if (unsettled(result))
|
|
195
|
+
lost = true;
|
|
196
|
+
else {
|
|
197
|
+
await (await store.open()).dropCall(operation);
|
|
198
|
+
lanes.settle(operation, lost);
|
|
199
|
+
}
|
|
200
|
+
tell(result);
|
|
201
|
+
return result;
|
|
202
|
+
},
|
|
203
|
+
release() {
|
|
204
|
+
lanes.sent(operation, sender);
|
|
205
|
+
tell(last);
|
|
206
|
+
},
|
|
207
|
+
};
|
|
208
|
+
lanes.sending(operation, sender);
|
|
209
|
+
return sender;
|
|
210
|
+
}
|
|
211
|
+
async function recoveredAction(runtime, name, input, attempt) {
|
|
212
|
+
const { socket, recovery } = runtime;
|
|
179
213
|
const operation = operationOf(input);
|
|
180
214
|
if (operation === null)
|
|
181
|
-
return invokeAction(runtime, name, input);
|
|
182
|
-
const
|
|
183
|
-
|
|
215
|
+
return invokeAction(runtime, name, input, { attempt });
|
|
216
|
+
const held = socket.lanes.sender(operation);
|
|
217
|
+
if (held !== undefined)
|
|
218
|
+
return held.next();
|
|
219
|
+
const sender = keptSender(runtime, name, input, operation);
|
|
220
|
+
let first;
|
|
184
221
|
try {
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
if (!socket.isOpen())
|
|
191
|
-
return 'again';
|
|
192
|
-
result = await invokeAction(runtime, name, input, kept);
|
|
193
|
-
return unsettled(result) ? 'again' : 'done';
|
|
194
|
-
}, { again: true });
|
|
195
|
-
}
|
|
196
|
-
if (!unsettled(result))
|
|
197
|
-
await (await store.open()).dropCall(operation);
|
|
198
|
-
return result;
|
|
222
|
+
first = await sender.send();
|
|
223
|
+
}
|
|
224
|
+
catch (error) {
|
|
225
|
+
sender.release();
|
|
226
|
+
throw error;
|
|
199
227
|
}
|
|
200
|
-
|
|
201
|
-
|
|
228
|
+
if (!unsettled(first)) {
|
|
229
|
+
sender.release();
|
|
230
|
+
return first;
|
|
202
231
|
}
|
|
232
|
+
void recovery
|
|
233
|
+
.attempt(`action ${operation}`, async () => {
|
|
234
|
+
if (socket.closed() || socket.session.now().refusal !== null)
|
|
235
|
+
return 'done';
|
|
236
|
+
if (!socket.isOpen())
|
|
237
|
+
return 'again';
|
|
238
|
+
return unsettled(await sender.send()) ? 'again' : 'done';
|
|
239
|
+
}, { again: true })
|
|
240
|
+
.finally(() => sender.release());
|
|
241
|
+
return first;
|
|
203
242
|
}
|
|
204
|
-
export async function called(runtime, name, input) {
|
|
243
|
+
export async function called(runtime, name, input, attempt) {
|
|
205
244
|
await runtime.socket.ready;
|
|
206
245
|
const lockedNow = await lockedRooms(runtime);
|
|
207
246
|
const room = (await calledRooms(runtime, name, input)).find((one) => lockedNow.includes(one));
|
|
208
|
-
return room === undefined ? recoveredAction(runtime, name, input) : lockedRoom(room);
|
|
247
|
+
return room === undefined ? recoveredAction(runtime, name, input, attempt) : lockedRoom(room);
|
|
209
248
|
}
|
|
210
|
-
export async function
|
|
249
|
+
export async function answeredCall(runtime, operation) {
|
|
211
250
|
const { store, socket } = runtime;
|
|
212
251
|
const { lanes } = socket;
|
|
252
|
+
const held = () => lanes.sender(operation) !== undefined || lanes.unclaimed(operation);
|
|
253
|
+
if (!held()) {
|
|
254
|
+
const calls = await (await store.open()).calls();
|
|
255
|
+
const kept = calls.some((one) => one.operation === operation) ||
|
|
256
|
+
(await holdsSubmission(runtime.conversations, operation));
|
|
257
|
+
if (!held() && !kept)
|
|
258
|
+
return false;
|
|
259
|
+
}
|
|
260
|
+
await lanes.settled(operation);
|
|
261
|
+
return true;
|
|
262
|
+
}
|
|
263
|
+
export async function resendCalls(runtime, signal) {
|
|
264
|
+
const { store, socket } = runtime;
|
|
213
265
|
if (!socket.isOpen() || socket.closed() || socket.stopping())
|
|
214
266
|
return 'done';
|
|
215
267
|
const local = await store.open();
|
|
216
268
|
for (const held of await local.calls()) {
|
|
217
|
-
if (lanes.
|
|
269
|
+
if (socket.lanes.sender(held.operation) !== undefined)
|
|
218
270
|
continue;
|
|
219
271
|
if (socket.closed() || signal.aborted)
|
|
220
272
|
return 'done';
|
|
221
|
-
|
|
273
|
+
const sender = keptSender(runtime, held.name, held.input, held.operation, true);
|
|
222
274
|
try {
|
|
223
|
-
if (unsettled(await
|
|
275
|
+
if (unsettled(await sender.send()))
|
|
224
276
|
return 'again';
|
|
225
|
-
await local.dropCall(held.operation);
|
|
226
277
|
}
|
|
227
278
|
finally {
|
|
228
|
-
|
|
279
|
+
sender.release();
|
|
229
280
|
}
|
|
230
281
|
}
|
|
231
282
|
return 'done';
|