@agentshouse/mdruntime 0.1.0-c967d1ca66fee → 0.1.0-c96e80d38e5f0
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 +22 -9
- package/dist/adapter.d.ts +172 -49
- package/dist/adapter.d.ts.map +1 -1
- package/dist/attached-model.d.ts +5 -1
- package/dist/attached-model.d.ts.map +1 -1
- package/dist/attached-model.js +38 -4
- package/dist/attempt.d.ts +16 -0
- package/dist/attempt.d.ts.map +1 -0
- package/dist/attempt.js +70 -0
- package/dist/binary.d.ts +18 -0
- package/dist/binary.d.ts.map +1 -0
- package/dist/binary.js +8 -0
- package/dist/bootstrap.d.ts +27 -11
- package/dist/bootstrap.d.ts.map +1 -1
- package/dist/bootstrap.js +184 -84
- package/dist/chain.d.ts +11 -0
- package/dist/chain.d.ts.map +1 -0
- package/dist/chain.js +64 -0
- package/dist/change-set.d.ts +9 -14
- package/dist/change-set.d.ts.map +1 -1
- package/dist/change-set.js +11 -62
- package/dist/change.d.ts +41 -0
- package/dist/change.d.ts.map +1 -1
- package/dist/change.js +34 -0
- package/dist/client.d.ts +34 -15
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +104 -8
- package/dist/collection.d.ts +10 -7
- package/dist/collection.d.ts.map +1 -1
- package/dist/collection.js +38 -79
- package/dist/compile.d.ts +16 -0
- package/dist/compile.d.ts.map +1 -0
- package/dist/compile.js +789 -0
- package/dist/connection.d.ts +51 -17
- package/dist/connection.d.ts.map +1 -1
- package/dist/connection.js +3951 -907
- package/dist/conversation.d.ts +48 -19
- package/dist/conversation.d.ts.map +1 -1
- package/dist/conversation.js +726 -240
- package/dist/digest.d.ts +7 -0
- package/dist/digest.d.ts.map +1 -0
- package/dist/digest.js +113 -0
- package/dist/durability.d.ts +4 -1
- package/dist/durability.d.ts.map +1 -1
- package/dist/durability.js +5 -0
- package/dist/entry.d.ts +20 -0
- package/dist/entry.d.ts.map +1 -0
- package/dist/entry.js +152 -0
- package/dist/expectation.d.ts +21 -0
- package/dist/expectation.d.ts.map +1 -0
- package/dist/expectation.js +70 -0
- package/dist/fence.d.ts +6 -0
- package/dist/fence.d.ts.map +1 -0
- package/dist/fence.js +10 -0
- package/dist/file.d.ts +2 -19
- package/dist/file.d.ts.map +1 -1
- package/dist/file.js +7 -122
- package/dist/host.d.ts +12 -3
- package/dist/host.d.ts.map +1 -1
- package/dist/host.js +125 -18
- package/dist/identity.d.ts +3 -0
- package/dist/identity.d.ts.map +1 -1
- package/dist/identity.js +9 -0
- package/dist/index.d.ts +19 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -0
- package/dist/live.d.ts +22 -0
- package/dist/live.d.ts.map +1 -0
- package/dist/live.js +123 -0
- package/dist/media.d.ts +8 -0
- package/dist/media.d.ts.map +1 -0
- package/dist/media.js +218 -0
- package/dist/memory.d.ts +18 -7
- package/dist/memory.d.ts.map +1 -1
- package/dist/memory.js +231 -91
- package/dist/messages.d.ts +28 -0
- package/dist/messages.d.ts.map +1 -0
- package/dist/messages.js +89 -0
- package/dist/model.d.ts +9 -2
- package/dist/model.d.ts.map +1 -1
- package/dist/model.js +8 -2
- package/dist/name.d.ts +4 -0
- package/dist/name.d.ts.map +1 -0
- package/dist/name.js +122 -0
- package/dist/observation.d.ts +20 -2
- package/dist/observation.d.ts.map +1 -1
- package/dist/observation.js +113 -12
- package/dist/opened.d.ts +22 -0
- package/dist/opened.d.ts.map +1 -0
- package/dist/opened.js +107 -0
- package/dist/outcome.d.ts +52 -4
- package/dist/outcome.d.ts.map +1 -1
- package/dist/outcome.js +46 -0
- package/dist/overlay.d.ts +15 -5
- package/dist/overlay.d.ts.map +1 -1
- package/dist/overlay.js +129 -177
- package/dist/paths.d.ts +1 -0
- package/dist/paths.d.ts.map +1 -1
- package/dist/paths.js +4 -0
- package/dist/phrase.d.ts +3 -0
- package/dist/phrase.d.ts.map +1 -0
- package/dist/phrase.js +8 -0
- package/dist/query.d.ts +72 -4
- package/dist/query.d.ts.map +1 -1
- package/dist/query.js +67 -7
- package/dist/reach.d.ts +16 -2
- package/dist/reach.d.ts.map +1 -1
- package/dist/reach.js +222 -56
- package/dist/react.d.ts +11 -7
- package/dist/react.d.ts.map +1 -1
- package/dist/react.js +7 -17
- package/dist/readiness.d.ts +50 -0
- package/dist/readiness.d.ts.map +1 -0
- package/dist/readiness.js +27 -0
- package/dist/recovery.d.ts +26 -0
- package/dist/recovery.d.ts.map +1 -0
- package/dist/recovery.js +224 -0
- package/dist/refresh.d.ts +17 -14
- package/dist/refresh.d.ts.map +1 -1
- package/dist/refresh.js +155 -56
- package/dist/replica.d.ts +58 -33
- package/dist/replica.d.ts.map +1 -1
- package/dist/replica.js +310 -159
- package/dist/room-draft.d.ts +52 -5
- package/dist/room-draft.d.ts.map +1 -1
- package/dist/room-draft.js +261 -56
- package/dist/rows.d.ts +38 -35
- package/dist/rows.d.ts.map +1 -1
- package/dist/rows.js +178 -102
- package/dist/save.d.ts +70 -3
- package/dist/save.d.ts.map +1 -1
- package/dist/save.js +805 -147
- package/dist/search.d.ts +15 -55
- package/dist/search.d.ts.map +1 -1
- package/dist/search.js +10 -121
- package/dist/seed.d.ts +16 -0
- package/dist/seed.d.ts.map +1 -0
- package/dist/seed.js +75 -0
- package/dist/shared.d.ts +15 -0
- package/dist/shared.d.ts.map +1 -0
- package/dist/shared.js +421 -0
- package/dist/status.d.ts +5 -0
- package/dist/status.d.ts.map +1 -1
- package/dist/status.js +3 -1
- package/dist/store.d.ts +116 -80
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +355 -461
- package/dist/stored.d.ts +162 -0
- package/dist/stored.d.ts.map +1 -0
- package/dist/stored.js +549 -0
- package/dist/tables.d.ts +353 -0
- package/dist/tables.d.ts.map +1 -0
- package/dist/tables.js +585 -0
- package/dist/transfer.d.ts +0 -5
- package/dist/transfer.d.ts.map +1 -1
- package/dist/turn.d.ts +9 -0
- package/dist/turn.d.ts.map +1 -0
- package/dist/turn.js +75 -0
- package/dist/validation.d.ts +29 -0
- package/dist/validation.d.ts.map +1 -0
- package/dist/validation.js +101 -0
- package/dist/windows.d.ts +22 -0
- package/dist/windows.d.ts.map +1 -0
- package/dist/windows.js +89 -0
- package/dist/wire.d.ts +166 -30
- package/dist/wire.d.ts.map +1 -1
- package/dist/wire.js +57 -29
- package/package.json +26 -15
- package/AGENTS.md +0 -269
- package/dist/attachment.d.ts +0 -3
- package/dist/attachment.d.ts.map +0 -1
- package/dist/attachment.js +0 -8
- package/dist/read-side.d.ts +0 -18
- package/dist/read-side.d.ts.map +0 -1
- package/dist/read-side.js +0 -433
package/dist/reach.js
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { unheldView } from './conversation.js';
|
|
2
2
|
import { modelTypes, NO_MODEL } from './model.js';
|
|
3
|
-
import {
|
|
3
|
+
import { changeOf, digestApplied, digestOf, observing, } from './observation.js';
|
|
4
4
|
import { runtimeError } from './failure.js';
|
|
5
|
-
import { failure, undeclared } from './outcome.js';
|
|
5
|
+
import { failure, lockedRoom, ROOM_LOCKED, undeclared, UNREADABLE, } from './outcome.js';
|
|
6
6
|
import { beneath } from './paths.js';
|
|
7
|
-
import { reconciled } from './read-side.js';
|
|
8
7
|
import { moveTarget, readParts, staleWrite, } from './room-draft.js';
|
|
9
8
|
import { documentKey } from './rows.js';
|
|
10
9
|
const UNHELD_TYPES = { collection: modelTypes(NO_MODEL), typedSelection: null };
|
|
@@ -14,18 +13,26 @@ function unconversed(name) {
|
|
|
14
13
|
const NO_CONVERSATION = {
|
|
15
14
|
list: () => Promise.resolve([]),
|
|
16
15
|
read: (conversation) => Promise.resolve(unheldView(conversation)),
|
|
17
|
-
create: unconversed('
|
|
18
|
-
send: unconversed('
|
|
19
|
-
answer: unconversed('
|
|
20
|
-
interrupt: unconversed('
|
|
21
|
-
kill: unconversed('
|
|
22
|
-
|
|
23
|
-
delete: unconversed('conversation.delete'),
|
|
16
|
+
create: unconversed('conversations/create'),
|
|
17
|
+
send: unconversed('conversations/send'),
|
|
18
|
+
answer: unconversed('conversations/interaction/answer'),
|
|
19
|
+
interrupt: unconversed('conversations/interrupt'),
|
|
20
|
+
kill: unconversed('conversations/kill'),
|
|
21
|
+
delete: unconversed('conversations/delete'),
|
|
24
22
|
};
|
|
25
23
|
const NO_CHAT_DRAFT = {
|
|
26
24
|
write: () => Promise.resolve(),
|
|
25
|
+
prepend: () => Promise.resolve(),
|
|
27
26
|
discard: () => Promise.resolve(),
|
|
28
27
|
};
|
|
28
|
+
function areasOf(reach) {
|
|
29
|
+
return reach.areas ?? [];
|
|
30
|
+
}
|
|
31
|
+
function fenced(reach, room, path) {
|
|
32
|
+
return areasOf(reach).some((area) => area.room === room &&
|
|
33
|
+
beneath(area.path, path) &&
|
|
34
|
+
!area.open.some((open) => beneath(open, path)));
|
|
35
|
+
}
|
|
29
36
|
export function holds(reach, room) {
|
|
30
37
|
return (reach === null ||
|
|
31
38
|
reach.rooms.includes(room) ||
|
|
@@ -46,8 +53,9 @@ export function governs(reach, room) {
|
|
|
46
53
|
}
|
|
47
54
|
function covers(reach, room, path) {
|
|
48
55
|
return (reach === null ||
|
|
49
|
-
reach
|
|
50
|
-
|
|
56
|
+
(!fenced(reach, room, path) &&
|
|
57
|
+
(reach.rooms.includes(room) ||
|
|
58
|
+
reach.documents.some((document) => document.room === room && document.path === path))));
|
|
51
59
|
}
|
|
52
60
|
function conversing(reach) {
|
|
53
61
|
return reach === null || reach.conversations;
|
|
@@ -60,6 +68,9 @@ export function planReach(reach) {
|
|
|
60
68
|
documents: [
|
|
61
69
|
...new Set(reach.documents.map(({ room, path }) => documentKey(room, path))),
|
|
62
70
|
].sort(),
|
|
71
|
+
areas: areasOf(reach)
|
|
72
|
+
.map(({ room, path, open }) => ({ room, path, open: [...new Set(open)].sort() }))
|
|
73
|
+
.sort((left, right) => documentKey(left.room, left.path) < documentKey(right.room, right.path) ? -1 : 1),
|
|
63
74
|
};
|
|
64
75
|
}
|
|
65
76
|
function roomsWithin(reach, rooms) {
|
|
@@ -75,7 +86,7 @@ function typesWithin(reach, room, types) {
|
|
|
75
86
|
};
|
|
76
87
|
}
|
|
77
88
|
function moves(reach, room, move) {
|
|
78
|
-
return move === undefined || covers(reach, room, moveTarget(move));
|
|
89
|
+
return move === undefined || covers(reach, move.room ?? room, moveTarget(move));
|
|
79
90
|
}
|
|
80
91
|
function draftWithin(reach, draft) {
|
|
81
92
|
return covers(reach, draft.room, draft.path) && moves(reach, draft.room, draft.parts.move);
|
|
@@ -109,75 +120,127 @@ function statusWithin(reach, status) {
|
|
|
109
120
|
return {
|
|
110
121
|
...status,
|
|
111
122
|
attentionRequired: status.attentionRequired.filter((entry) => covers(reach, entry.room, entry.path)),
|
|
123
|
+
unsent: status.unsent.filter((change) => covers(reach, change.room, change.path)),
|
|
112
124
|
};
|
|
113
125
|
}
|
|
114
126
|
function queueWithin(reach, room, entries) {
|
|
115
|
-
return entries
|
|
116
|
-
(
|
|
127
|
+
return entries
|
|
128
|
+
.filter(({ batch }) => batch.changes.every((change) => covers(reach, room, change.path) &&
|
|
129
|
+
(change.kind !== 'move' || covers(reach, room, change.to))))
|
|
130
|
+
.map((entry) => {
|
|
131
|
+
const { between, ...batch } = entry.batch;
|
|
132
|
+
if (between === undefined)
|
|
133
|
+
return entry;
|
|
134
|
+
return wholly(reach, between.source.room) && wholly(reach, between.destination.room)
|
|
135
|
+
? entry
|
|
136
|
+
: { ...entry, batch };
|
|
137
|
+
});
|
|
117
138
|
}
|
|
118
139
|
function unreached(room) {
|
|
119
|
-
return runtimeError('room
|
|
140
|
+
return runtimeError('unknown-room', `Unknown Room ${room}`);
|
|
141
|
+
}
|
|
142
|
+
function lockedError(room) {
|
|
143
|
+
return runtimeError(ROOM_LOCKED, `${room} is locked until House confirms its access`, true);
|
|
144
|
+
}
|
|
145
|
+
function deviceUnreached() {
|
|
146
|
+
return runtimeError('device-unreached', 'Only the panel cleans up this device');
|
|
120
147
|
}
|
|
121
|
-
|
|
148
|
+
const ATTACH_REQUIRED = 'attach-required';
|
|
149
|
+
function attachRequired() {
|
|
150
|
+
return runtimeError(ATTACH_REQUIRED, 'App code takes a file in with binaryFile.attach');
|
|
151
|
+
}
|
|
152
|
+
function carriesFile(parts) {
|
|
153
|
+
return parts !== null && typeof parts === 'object' && Object.hasOwn(parts, 'file');
|
|
154
|
+
}
|
|
155
|
+
export function narrowed(runtime, given, told) {
|
|
122
156
|
const { md, watch } = runtime;
|
|
123
157
|
let reach = given;
|
|
158
|
+
let port = told;
|
|
124
159
|
const open = new Set();
|
|
125
|
-
function following(begin) {
|
|
160
|
+
function following(begin, locking = false) {
|
|
126
161
|
let stop = begin();
|
|
127
162
|
const restart = () => {
|
|
128
163
|
stop();
|
|
129
164
|
stop = begin();
|
|
130
165
|
};
|
|
131
166
|
open.add(restart);
|
|
167
|
+
const unwatch = locking ? runtime.watchLocks(restart) : () => { };
|
|
132
168
|
return () => {
|
|
133
169
|
open.delete(restart);
|
|
170
|
+
unwatch();
|
|
134
171
|
stop();
|
|
135
172
|
};
|
|
136
173
|
}
|
|
174
|
+
const unlocking = (rooms) => {
|
|
175
|
+
const locked = (rooms ?? []).filter((room) => runtime.locked(room));
|
|
176
|
+
return locked.length === 0
|
|
177
|
+
? null
|
|
178
|
+
: { pending: locked.map((room) => ({ room, awaits: 'unlock' })) };
|
|
179
|
+
};
|
|
180
|
+
const unlocked = (entries) => entries.filter((entry) => !runtime.locked(entry.room));
|
|
181
|
+
const intoLocked = (held) => held.some((move) => move?.room !== undefined && runtime.locked(move.room));
|
|
137
182
|
const within = (topic, input, deliver) => {
|
|
138
183
|
if (topic === 'rooms') {
|
|
139
184
|
return following(() => watch(topic, input, (rooms) => deliver(roomsWithin(reach, rooms))));
|
|
140
185
|
}
|
|
186
|
+
if (topic === 'readiness') {
|
|
187
|
+
return following(() => runtime.watchReadiness(port, reach, deliver));
|
|
188
|
+
}
|
|
141
189
|
if (topic === 'sync-status') {
|
|
142
|
-
return following(() => watch(topic, input, (status) =>
|
|
190
|
+
return following(() => watch(topic, input, (status) => {
|
|
191
|
+
const within = statusWithin(reach, status);
|
|
192
|
+
deliver({ ...within, attentionRequired: unlocked(within.attentionRequired) });
|
|
193
|
+
}), true);
|
|
143
194
|
}
|
|
144
195
|
if (topic === 'room-drafts') {
|
|
145
|
-
return following(() => watch(topic, input, (drafts) => deliver(draftsWithin(reach, drafts))));
|
|
196
|
+
return following(() => watch(topic, input, (drafts) => deliver(unlocked(draftsWithin(reach, drafts)))), true);
|
|
146
197
|
}
|
|
147
198
|
if (topic === 'queue') {
|
|
148
199
|
const room = input[0];
|
|
149
200
|
return following(() => {
|
|
150
|
-
if (!holds(reach, room)) {
|
|
201
|
+
if (!holds(reach, room) || runtime.locked(room)) {
|
|
151
202
|
deliver([]);
|
|
152
203
|
return () => { };
|
|
153
204
|
}
|
|
154
205
|
return watch(topic, input, (entries) => deliver(queueWithin(reach, room, entries)));
|
|
155
|
-
});
|
|
206
|
+
}, true);
|
|
156
207
|
}
|
|
157
208
|
if (topic === 'query') {
|
|
158
209
|
const plan = runtime.plan(input[0], reach);
|
|
159
210
|
let held = null;
|
|
160
211
|
return following(() => {
|
|
212
|
+
const locked = unlocking(plan.rooms);
|
|
213
|
+
if (locked !== null) {
|
|
214
|
+
const answer = { result: locked, keys: [] };
|
|
215
|
+
if (held === null || changeOf(held, answer) !== null)
|
|
216
|
+
deliver(answer);
|
|
217
|
+
held = digestOf(answer);
|
|
218
|
+
return () => { };
|
|
219
|
+
}
|
|
161
220
|
let first = true;
|
|
162
|
-
|
|
221
|
+
let open = true;
|
|
222
|
+
const heard = (message) => {
|
|
163
223
|
if (!first) {
|
|
164
|
-
held =
|
|
224
|
+
held = digestApplied(held, message);
|
|
165
225
|
deliver(message);
|
|
166
226
|
return;
|
|
167
227
|
}
|
|
168
228
|
first = false;
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
deliver(next.change);
|
|
229
|
+
const change = held === null ? message : changeOf(held, message);
|
|
230
|
+
held = digestOf(message);
|
|
231
|
+
if (change !== null)
|
|
232
|
+
deliver(change);
|
|
233
|
+
};
|
|
234
|
+
const current = { ...plan, reach: planReach(reach), locked: runtime.lockedRooms() };
|
|
235
|
+
const stop = runtime.watchPlan(current, (message) => {
|
|
236
|
+
if (open)
|
|
237
|
+
heard(message);
|
|
179
238
|
});
|
|
180
|
-
|
|
239
|
+
return () => {
|
|
240
|
+
open = false;
|
|
241
|
+
stop();
|
|
242
|
+
};
|
|
243
|
+
}, true);
|
|
181
244
|
}
|
|
182
245
|
if (topic === 'conversation') {
|
|
183
246
|
return following(() => {
|
|
@@ -187,7 +250,7 @@ export function narrowed(runtime, given) {
|
|
|
187
250
|
return () => { };
|
|
188
251
|
});
|
|
189
252
|
}
|
|
190
|
-
if (topic === 'conversations') {
|
|
253
|
+
if (topic === 'conversations' || topic === 'agents') {
|
|
191
254
|
return following(() => {
|
|
192
255
|
if (conversing(reach))
|
|
193
256
|
return watch(topic, input, deliver);
|
|
@@ -197,49 +260,147 @@ export function narrowed(runtime, given) {
|
|
|
197
260
|
}
|
|
198
261
|
return watch(topic, input, deliver);
|
|
199
262
|
};
|
|
263
|
+
const files = new Map();
|
|
264
|
+
let handed = 0;
|
|
265
|
+
async function hand(reading) {
|
|
266
|
+
const answer = await reading;
|
|
267
|
+
if (answer.kind !== 'binary')
|
|
268
|
+
return answer;
|
|
269
|
+
handed += 1;
|
|
270
|
+
const file = String(handed);
|
|
271
|
+
files.set(file, answer.file);
|
|
272
|
+
return { ...answer, file };
|
|
273
|
+
}
|
|
200
274
|
const conversation = () => (conversing(reach) ? md.conversation : NO_CONVERSATION);
|
|
201
275
|
const chatDraft = () => (conversing(reach) ? md.chatDraft : NO_CHAT_DRAFT);
|
|
202
276
|
const view = {
|
|
203
277
|
...md,
|
|
204
|
-
rooms: () => roomsWithin(reach,
|
|
205
|
-
query: ((input) =>
|
|
278
|
+
rooms: () => md.rooms().then((rooms) => roomsWithin(reach, rooms)),
|
|
279
|
+
query: ((input) => {
|
|
280
|
+
const plan = runtime.plan(input, reach);
|
|
281
|
+
return Promise.resolve(unlocking(plan.rooms) ?? runtime.query({ ...plan, locked: runtime.lockedRooms() }));
|
|
282
|
+
}),
|
|
206
283
|
search: (input) => runtime.search(input, reach),
|
|
207
284
|
types(room) {
|
|
285
|
+
if (holds(reach, room) && runtime.locked(room))
|
|
286
|
+
throw lockedError(room);
|
|
208
287
|
if (wholly(reach, room))
|
|
209
288
|
return md.types(room);
|
|
210
289
|
if (!holds(reach, room))
|
|
211
290
|
return structuredClone(UNHELD_TYPES);
|
|
212
|
-
|
|
213
|
-
return typesWithin(reach, listed, md.types(room));
|
|
291
|
+
return typesWithin(reach, runtime.room(room), md.types(room));
|
|
214
292
|
},
|
|
215
293
|
async save(room, roomDrafts, writtenBy) {
|
|
216
294
|
if (!holds(reach, room))
|
|
217
295
|
throw unreached(room);
|
|
218
|
-
|
|
219
|
-
|
|
296
|
+
if (runtime.locked(room))
|
|
297
|
+
return { outcome: 'refused', code: ROOM_LOCKED, retryable: true };
|
|
298
|
+
const held = (await Promise.all(roomDrafts.map(({ path }) => md.roomDraft.read(room, path)))).map((draft) => draft?.parts.move);
|
|
299
|
+
const outside = roomDrafts.find(({ path }, at) => !covers(reach, room, path) || !moves(reach, room, held[at]));
|
|
220
300
|
if (outside !== undefined) {
|
|
221
301
|
return { outcome: 'refused', code: 'stale', retryable: false, file: outside.path };
|
|
222
302
|
}
|
|
303
|
+
if (intoLocked(held))
|
|
304
|
+
return { outcome: 'refused', code: ROOM_LOCKED, retryable: true };
|
|
223
305
|
return savedWithin(reach, room, await md.save(room, roomDrafts, writtenBy));
|
|
224
306
|
},
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
307
|
+
async saveParts(room, parts, writtenBy) {
|
|
308
|
+
if (!holds(reach, room))
|
|
309
|
+
throw unreached(room);
|
|
310
|
+
const filed = reach === null ? undefined : parts.find(({ parts: one }) => carriesFile(one));
|
|
311
|
+
if (filed !== undefined) {
|
|
312
|
+
return { outcome: 'refused', code: ATTACH_REQUIRED, retryable: false, file: filed.path };
|
|
313
|
+
}
|
|
314
|
+
if (runtime.locked(room))
|
|
315
|
+
return { outcome: 'refused', code: ROOM_LOCKED, retryable: true };
|
|
316
|
+
const held = parts.map(({ path, parts: one }) => readParts(one, path).move);
|
|
317
|
+
if (parts.some(({ path }, at) => !covers(reach, room, path) || !moves(reach, room, held[at]))) {
|
|
318
|
+
throw unreached(room);
|
|
319
|
+
}
|
|
320
|
+
if (intoLocked(held))
|
|
321
|
+
return { outcome: 'refused', code: ROOM_LOCKED, retryable: true };
|
|
322
|
+
return savedWithin(reach, room, await md.saveParts(room, parts, writtenBy));
|
|
323
|
+
},
|
|
324
|
+
resolve(room, path, destination) {
|
|
325
|
+
const at = runtime.located(room, path, destination);
|
|
326
|
+
return at !== null && !covers(reach, at.room, at.path)
|
|
327
|
+
? Promise.resolve(UNREADABLE)
|
|
328
|
+
: md.resolve(room, path, destination);
|
|
329
|
+
},
|
|
330
|
+
history: (room, path, query) => !covers(reach, room, path)
|
|
331
|
+
? Promise.resolve(failure({ kind: 'room-not-readable', locator: room }))
|
|
332
|
+
: runtime.locked(room)
|
|
333
|
+
? Promise.resolve(lockedRoom(room))
|
|
334
|
+
: md.history(room, path, query),
|
|
335
|
+
binaryFile: {
|
|
336
|
+
read: (room, path, revision) => !covers(reach, room, path)
|
|
337
|
+
? Promise.resolve(failure({ kind: 'room-not-readable', locator: room }))
|
|
338
|
+
: runtime.locked(room)
|
|
339
|
+
? Promise.resolve(lockedRoom(room))
|
|
340
|
+
: hand(md.binaryFile.read(room, path, revision)),
|
|
341
|
+
link: (room, path, revision) => !covers(reach, room, path)
|
|
342
|
+
? Promise.resolve(failure({ kind: 'room-not-readable', locator: room }))
|
|
343
|
+
: runtime.locked(room)
|
|
344
|
+
? Promise.resolve(lockedRoom(room))
|
|
345
|
+
: md.binaryFile.link(room, path, revision),
|
|
346
|
+
show: (room, path, revision) => !covers(reach, room, path)
|
|
347
|
+
? Promise.resolve(failure({ kind: 'room-not-readable', locator: room }))
|
|
348
|
+
: runtime.locked(room)
|
|
349
|
+
? Promise.resolve(lockedRoom(room))
|
|
350
|
+
: hand(md.binaryFile.show(room, path, revision)),
|
|
351
|
+
attach: (room, file) => !wholly(reach, room)
|
|
352
|
+
? Promise.resolve(failure({ kind: 'room-not-readable', locator: room }))
|
|
353
|
+
: runtime.locked(room)
|
|
354
|
+
? Promise.resolve(lockedRoom(room))
|
|
355
|
+
: md.binaryFile.attach(room, file),
|
|
356
|
+
async part(file, part) {
|
|
357
|
+
const key = files.get(file);
|
|
358
|
+
if (key === undefined)
|
|
359
|
+
return null;
|
|
360
|
+
const bytes = await md.binaryFile.part(key, part);
|
|
361
|
+
if (bytes === null)
|
|
362
|
+
files.delete(file);
|
|
363
|
+
return bytes;
|
|
364
|
+
},
|
|
365
|
+
},
|
|
366
|
+
reached: async (room, roomVersion, path) => (path === undefined ? wholly(reach, room) : covers(reach, room, path)) &&
|
|
367
|
+
!runtime.locked(room) &&
|
|
368
|
+
(await md.reached(room, roomVersion, path)),
|
|
230
369
|
log: () => (reach === null ? md.log() : ''),
|
|
370
|
+
cleanUp: () => (reach === null ? md.cleanUp() : Promise.reject(deviceUnreached())),
|
|
231
371
|
roomDraft: {
|
|
232
|
-
list: () => md.roomDraft.list().then((drafts) => draftsWithin(reach, drafts)),
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
372
|
+
list: () => md.roomDraft.list().then((drafts) => unlocked(draftsWithin(reach, drafts))),
|
|
373
|
+
async read(room, path) {
|
|
374
|
+
if (!covers(reach, room, path))
|
|
375
|
+
return null;
|
|
376
|
+
if (runtime.locked(room))
|
|
377
|
+
throw lockedError(room);
|
|
378
|
+
return shownDraft(reach, await md.roomDraft.read(room, path));
|
|
379
|
+
},
|
|
380
|
+
write(room, path, revision, parts, next) {
|
|
381
|
+
try {
|
|
382
|
+
if (reach !== null && carriesFile(parts))
|
|
383
|
+
throw attachRequired();
|
|
384
|
+
const move = readParts(parts, path).move;
|
|
385
|
+
if (!covers(reach, room, path) || !moves(reach, room, move))
|
|
386
|
+
throw unreached(room);
|
|
387
|
+
if (runtime.locked(room))
|
|
388
|
+
throw lockedError(room);
|
|
389
|
+
if (intoLocked([move]))
|
|
390
|
+
throw lockedError(move.room);
|
|
237
391
|
}
|
|
238
|
-
|
|
392
|
+
catch (error) {
|
|
393
|
+
return Promise.reject(error);
|
|
394
|
+
}
|
|
395
|
+
return md.roomDraft
|
|
396
|
+
.write(room, path, revision, parts, next)
|
|
397
|
+
.then((written) => writeWithin(reach, written));
|
|
239
398
|
},
|
|
240
399
|
async discard(room, path, revision) {
|
|
241
400
|
if (!covers(reach, room, path))
|
|
242
401
|
return staleWrite(null);
|
|
402
|
+
if (runtime.locked(room))
|
|
403
|
+
throw lockedError(room);
|
|
243
404
|
return writeWithin(reach, await md.roomDraft.discard(room, path, revision));
|
|
244
405
|
},
|
|
245
406
|
},
|
|
@@ -247,15 +408,15 @@ export function narrowed(runtime, given) {
|
|
|
247
408
|
list: () => conversation().list(),
|
|
248
409
|
read: (id, options) => conversation().read(id, options),
|
|
249
410
|
create: (input) => conversation().create(input),
|
|
250
|
-
send: (id) => conversation().send(id),
|
|
411
|
+
send: (id, operation, draft) => conversation().send(id, operation, draft),
|
|
251
412
|
answer: (id, answer) => conversation().answer(id, answer),
|
|
252
413
|
interrupt: (id) => conversation().interrupt(id),
|
|
253
414
|
kill: (id) => conversation().kill(id),
|
|
254
|
-
cancel: (id, turn) => conversation().cancel(id, turn),
|
|
255
415
|
delete: (id) => conversation().delete(id),
|
|
256
416
|
},
|
|
257
417
|
chatDraft: {
|
|
258
|
-
write: (id, draft) => chatDraft().write(id, draft),
|
|
418
|
+
write: (id, draft, revision) => chatDraft().write(id, draft, revision),
|
|
419
|
+
prepend: (id, draft) => chatDraft().prepend(id, draft),
|
|
259
420
|
discard: (id) => chatDraft().discard(id),
|
|
260
421
|
},
|
|
261
422
|
observe: observing(within),
|
|
@@ -268,5 +429,10 @@ export function narrowed(runtime, given) {
|
|
|
268
429
|
for (const restart of [...open])
|
|
269
430
|
restart();
|
|
270
431
|
},
|
|
432
|
+
facts(next) {
|
|
433
|
+
port = next;
|
|
434
|
+
for (const restart of [...open])
|
|
435
|
+
restart();
|
|
436
|
+
},
|
|
271
437
|
};
|
|
272
438
|
}
|
package/dist/react.d.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import type { MdRuntimeClient } from './client.js';
|
|
2
|
-
import type { AppRoom, ConnectionRefusal, SaveResult } from './connection.js';
|
|
2
|
+
import type { AppRoom, ConnectionRefusal, SavedRoomDraft, SaveResult } from './connection.js';
|
|
3
3
|
import type { Member, ServiceMode } from './adapter.js';
|
|
4
|
-
import type { ConversationEntry, ConversationOptions, ConversationView } from './conversation.js';
|
|
4
|
+
import type { ConversationAgent, ConversationEntry, ConversationOptions, ConversationView } from './conversation.js';
|
|
5
5
|
import { type RuntimeError } from './failure.js';
|
|
6
6
|
import type { QueueEntry } from './outcome.js';
|
|
7
|
-
import type { DocumentQuery, DocumentResult, GroupQuery, GroupResult } from './query.js';
|
|
7
|
+
import type { DocumentQuery, DocumentResult, GroupQuery, GroupResult, PendingResult } from './query.js';
|
|
8
|
+
import type { Readiness } from './readiness.js';
|
|
8
9
|
import type { RoomDraft, RoomDraftParts } from './room-draft.js';
|
|
9
10
|
import type { SyncStatus } from './status.js';
|
|
10
11
|
type Client = MdRuntimeClient | null;
|
|
@@ -16,25 +17,28 @@ export type Observed<T> = {
|
|
|
16
17
|
};
|
|
17
18
|
export declare function useObserve(client: Client, topic: 'deployment-facts'): Observed<unknown>;
|
|
18
19
|
export declare function useObserve(client: Client, topic: 'rooms'): Observed<readonly AppRoom[]>;
|
|
20
|
+
export declare function useObserve(client: Client, topic: 'readiness'): Observed<Readiness>;
|
|
19
21
|
export declare function useObserve(client: Client, topic: 'connection-refusal'): Observed<ConnectionRefusal | null>;
|
|
20
22
|
export declare function useObserve(client: Client, topic: 'storage-loss'): Observed<string | null>;
|
|
21
23
|
export declare function useObserve(client: Client, topic: 'sync-status'): Observed<SyncStatus>;
|
|
22
24
|
export declare function useObserve(client: Client, topic: 'service-mode'): Observed<ServiceMode>;
|
|
23
25
|
export declare function useObserve(client: Client, topic: 'member'): Observed<Member | null>;
|
|
24
|
-
export declare function useObserve(client: Client, topic: '
|
|
25
|
-
export declare function useObserve(client: Client, topic: 'query', query:
|
|
26
|
+
export declare function useObserve(client: Client, topic: 'authority-changes'): Observed<number>;
|
|
27
|
+
export declare function useObserve(client: Client, topic: 'query', query: DocumentQuery): Observed<DocumentResult | PendingResult>;
|
|
28
|
+
export declare function useObserve(client: Client, topic: 'query', query: GroupQuery): Observed<GroupResult | PendingResult>;
|
|
26
29
|
export declare function useObserve(client: Client, topic: 'queue', locator: string): Observed<readonly QueueEntry[]>;
|
|
27
30
|
export declare function useObserve(client: Client, topic: 'room-drafts'): Observed<readonly RoomDraft[]>;
|
|
28
31
|
export declare function useObserve(client: Client, topic: 'presentation'): Observed<unknown>;
|
|
29
32
|
export declare function useObserve(client: Client, topic: 'conversation', conversation: string, options: ConversationOptions): Observed<ConversationView>;
|
|
30
33
|
export declare function useObserve(client: Client, topic: 'conversations'): Observed<readonly ConversationEntry[]>;
|
|
34
|
+
export declare function useObserve(client: Client, topic: 'agents'): Observed<readonly ConversationAgent[]>;
|
|
31
35
|
export type Saving = {
|
|
32
36
|
readonly busy: boolean;
|
|
33
37
|
readonly outcome: SaveResult | null;
|
|
34
38
|
readonly failure: RuntimeError | null;
|
|
35
|
-
save(room: string,
|
|
39
|
+
save(room: string, parts: ReadonlyMap<string, RoomDraftParts>): Promise<SaveResult>;
|
|
40
|
+
saveWritten(room: string, roomDrafts: readonly SavedRoomDraft[]): Promise<SaveResult>;
|
|
36
41
|
};
|
|
37
|
-
export declare function saveRoomDrafts(client: MdRuntimeClient, room: string, roomDrafts: ReadonlyMap<string, RoomDraftParts>): Promise<SaveResult>;
|
|
38
42
|
export declare function useSave(client: MdRuntimeClient): Saving;
|
|
39
43
|
export {};
|
|
40
44
|
//# sourceMappingURL=react.d.ts.map
|
package/dist/react.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../src/react.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,KAAK,EAAE,OAAO,EAAE,iBAAiB,
|
|
1
|
+
{"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../src/react.ts"],"names":[],"mappings":"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"}
|
package/dist/react.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useCallback, useLayoutEffect, useRef, useState } from 'react';
|
|
2
|
-
import { failed
|
|
2
|
+
import { failed } from './failure.js';
|
|
3
3
|
const LOADING = { state: 'loading' };
|
|
4
4
|
export function useObserve(client, topic, ...input) {
|
|
5
5
|
const key = JSON.stringify([topic, ...input]);
|
|
@@ -33,24 +33,12 @@ export function useObserve(client, topic, ...input) {
|
|
|
33
33
|
return held !== null && held.client === client && held.key === key ? held.observed : LOADING;
|
|
34
34
|
}
|
|
35
35
|
const IDLE = { busy: false, outcome: null, failure: null };
|
|
36
|
-
export async function saveRoomDrafts(client, room, roomDrafts) {
|
|
37
|
-
const kept = [];
|
|
38
|
-
for (const [path, parts] of roomDrafts) {
|
|
39
|
-
const prior = await client.roomDraft.read(room, path);
|
|
40
|
-
const write = await client.roomDraft.write(room, path, prior?.revision ?? null, parts);
|
|
41
|
-
if (write.outcome !== 'written' || write.roomDraft === null) {
|
|
42
|
-
throw runtimeError(write.outcome === 'stale' ? write.code : 'room-draft-unwritten', `the Room Draft at ${path} was not written`);
|
|
43
|
-
}
|
|
44
|
-
kept.push({ path, revision: write.roomDraft.revision });
|
|
45
|
-
}
|
|
46
|
-
return client.save(room, kept);
|
|
47
|
-
}
|
|
48
36
|
export function useSave(client) {
|
|
49
37
|
const [state, setState] = useState(IDLE);
|
|
50
|
-
const
|
|
38
|
+
const settled = useCallback(async (saving) => {
|
|
51
39
|
setState({ busy: true, outcome: null, failure: null });
|
|
52
40
|
try {
|
|
53
|
-
const outcome = await
|
|
41
|
+
const outcome = await saving();
|
|
54
42
|
setState({ busy: false, outcome, failure: null });
|
|
55
43
|
return outcome;
|
|
56
44
|
}
|
|
@@ -59,6 +47,8 @@ export function useSave(client) {
|
|
|
59
47
|
setState({ busy: false, outcome: null, failure });
|
|
60
48
|
throw failure;
|
|
61
49
|
}
|
|
62
|
-
}, [
|
|
63
|
-
|
|
50
|
+
}, []);
|
|
51
|
+
const save = useCallback((room, parts) => settled(() => client.saveParts(room, [...parts].map(([path, one]) => ({ path, parts: one })))), [client, settled]);
|
|
52
|
+
const saveWritten = useCallback((room, roomDrafts) => settled(() => client.save(room, roomDrafts)), [client, settled]);
|
|
53
|
+
return { ...state, save, saveWritten };
|
|
64
54
|
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { Open } from './open.js';
|
|
2
|
+
export type CodeAvailability = Open<'stored' | 'absent'>;
|
|
3
|
+
export type RoomPreparation = Open<'complete' | 'acquiring' | 'preparing' | 'unadmitted'>;
|
|
4
|
+
export type RoomCoverage = {
|
|
5
|
+
readonly room: string;
|
|
6
|
+
readonly state: RoomPreparation;
|
|
7
|
+
};
|
|
8
|
+
export type ConversationCoverage = Open<'complete' | 'acquiring' | 'undeclared'>;
|
|
9
|
+
export type TargetCoverage = {
|
|
10
|
+
readonly complete: boolean;
|
|
11
|
+
readonly listed: boolean;
|
|
12
|
+
readonly rooms: readonly RoomCoverage[];
|
|
13
|
+
readonly conversations: ConversationCoverage;
|
|
14
|
+
};
|
|
15
|
+
export type Persistence = Open<'granted' | 'denied' | 'unavailable'>;
|
|
16
|
+
export type Durability = Open<'persistent' | 'best-effort'>;
|
|
17
|
+
export type ConnectionAvailability = Open<'connected' | 'connecting' | 'unreachable'>;
|
|
18
|
+
export type HouseOutcome = Open<'open' | 'write-halted' | 'refused'>;
|
|
19
|
+
export type Space = Open<'full'>;
|
|
20
|
+
export type InstallationStep = Open<'downloading' | 'writing' | 'replaying'>;
|
|
21
|
+
export type InstallationAmount = {
|
|
22
|
+
readonly done: number;
|
|
23
|
+
readonly total: number;
|
|
24
|
+
};
|
|
25
|
+
export type Installation = {
|
|
26
|
+
readonly step: InstallationStep | null;
|
|
27
|
+
readonly rooms: InstallationAmount;
|
|
28
|
+
readonly bytes: InstallationAmount;
|
|
29
|
+
};
|
|
30
|
+
export type ReadinessStatus = Open<'preparing' | 'paused' | 'ready' | 'lost'>;
|
|
31
|
+
export type Readiness = {
|
|
32
|
+
readonly status: ReadinessStatus;
|
|
33
|
+
readonly ready: boolean;
|
|
34
|
+
readonly usable: boolean;
|
|
35
|
+
readonly code: CodeAvailability;
|
|
36
|
+
readonly coverage: TargetCoverage;
|
|
37
|
+
readonly durability: Durability;
|
|
38
|
+
readonly persistence: Persistence;
|
|
39
|
+
readonly connection: ConnectionAvailability;
|
|
40
|
+
readonly house: HouseOutcome;
|
|
41
|
+
readonly space: Space | null;
|
|
42
|
+
readonly installation: Installation;
|
|
43
|
+
readonly lost: boolean;
|
|
44
|
+
};
|
|
45
|
+
export type ReadinessFacts = Omit<Readiness, 'status' | 'ready' | 'usable' | 'durability' | 'coverage'> & {
|
|
46
|
+
readonly coverage: Omit<TargetCoverage, 'complete'>;
|
|
47
|
+
readonly established: boolean;
|
|
48
|
+
};
|
|
49
|
+
export declare function readinessOf(facts: ReadinessFacts): Readiness;
|
|
50
|
+
//# sourceMappingURL=readiness.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"readiness.d.ts","sourceRoot":"","sources":["../src/readiness.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
const COMPLETE_ROOMS = new Set(['complete', 'unadmitted']);
|
|
2
|
+
export function readinessOf(facts) {
|
|
3
|
+
const { established, coverage: held, ...reported } = facts;
|
|
4
|
+
const settledConversations = held.conversations === 'complete' || held.conversations === 'undeclared';
|
|
5
|
+
const complete = held.listed &&
|
|
6
|
+
settledConversations &&
|
|
7
|
+
held.rooms.every((room) => COMPLETE_ROOMS.has(room.state));
|
|
8
|
+
const coverage = { ...held, complete };
|
|
9
|
+
const stored = facts.code === 'stored';
|
|
10
|
+
const ready = stored && complete;
|
|
11
|
+
const usable = stored && (ready || established);
|
|
12
|
+
const status = ready
|
|
13
|
+
? 'ready'
|
|
14
|
+
: facts.space !== null
|
|
15
|
+
? 'paused'
|
|
16
|
+
: facts.lost && !established
|
|
17
|
+
? 'lost'
|
|
18
|
+
: 'preparing';
|
|
19
|
+
return {
|
|
20
|
+
...reported,
|
|
21
|
+
coverage,
|
|
22
|
+
status,
|
|
23
|
+
ready,
|
|
24
|
+
usable,
|
|
25
|
+
durability: facts.persistence === 'granted' ? 'persistent' : 'best-effort',
|
|
26
|
+
};
|
|
27
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export type Attempted = 'done' | 'again' | {
|
|
2
|
+
readonly at: number;
|
|
3
|
+
};
|
|
4
|
+
export type Attempt = (signal: AbortSignal) => Promise<Attempted>;
|
|
5
|
+
export type AttemptOptions = {
|
|
6
|
+
readonly at?: number;
|
|
7
|
+
readonly again?: boolean;
|
|
8
|
+
};
|
|
9
|
+
export type RecoveryOptions = {
|
|
10
|
+
readonly firstMs?: number;
|
|
11
|
+
readonly maxMs?: number;
|
|
12
|
+
readonly attempts?: number;
|
|
13
|
+
readonly inFlight?: number;
|
|
14
|
+
};
|
|
15
|
+
export type Recovery = {
|
|
16
|
+
attempt(intent: string, run: Attempt, options?: AttemptOptions): Promise<boolean>;
|
|
17
|
+
pending(intent: string): boolean;
|
|
18
|
+
resume(): void;
|
|
19
|
+
cancel(intent: string): void;
|
|
20
|
+
scope(inFlight?: number): Recovery;
|
|
21
|
+
retire(): Promise<void>;
|
|
22
|
+
};
|
|
23
|
+
export declare function retryDelay(tries: number, firstMs?: number, maxMs?: number): number;
|
|
24
|
+
export declare function untilAnswered<T>(ask: () => Promise<T>, signal: AbortSignal, answered?: (answer: T) => boolean): Promise<T>;
|
|
25
|
+
export declare function createRecovery(options?: RecoveryOptions): Recovery;
|
|
26
|
+
//# sourceMappingURL=recovery.d.ts.map
|