@agentshouse/mdruntime 0.1.0-cfbf80d8d4644 → 0.1.0-cfcf93be6310b
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 +24 -11
- package/dist/adapter.d.ts +182 -47
- 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 +53 -6
- 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 +33 -5
- package/dist/bootstrap.d.ts.map +1 -1
- package/dist/bootstrap.js +202 -48
- 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 -56
- package/dist/change.d.ts +45 -0
- package/dist/change.d.ts.map +1 -1
- package/dist/change.js +34 -0
- package/dist/client.d.ts +38 -17
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +156 -20
- package/dist/collection.d.ts +13 -14
- package/dist/collection.d.ts.map +1 -1
- package/dist/collection.js +52 -56
- 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 +59 -20
- package/dist/connection.d.ts.map +1 -1
- package/dist/connection.js +4080 -879
- package/dist/context.d.ts +2 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +7 -0
- package/dist/conversation.d.ts +51 -20
- package/dist/conversation.d.ts.map +1 -1
- package/dist/conversation.js +732 -242
- 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/failure.d.ts +13 -0
- package/dist/failure.d.ts.map +1 -0
- package/dist/failure.js +19 -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 +11 -2
- package/dist/host.d.ts.map +1 -1
- package/dist/host.js +128 -24
- package/dist/identity.d.ts +4 -0
- package/dist/identity.d.ts.map +1 -1
- package/dist/identity.js +16 -1
- package/dist/index.d.ts +22 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -0
- package/dist/job.d.ts +14 -0
- package/dist/job.d.ts.map +1 -0
- package/dist/job.js +28 -0
- package/dist/live.d.ts +23 -0
- package/dist/live.d.ts.map +1 -0
- package/dist/live.js +127 -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 +20 -7
- package/dist/memory.d.ts.map +1 -1
- package/dist/memory.js +253 -92
- 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 +19 -4
- package/dist/model.d.ts.map +1 -1
- package/dist/model.js +10 -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 +22 -4
- package/dist/observation.d.ts.map +1 -1
- package/dist/observation.js +120 -14
- package/dist/open.d.ts +2 -0
- package/dist/open.d.ts.map +1 -0
- package/dist/open.js +1 -0
- 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 +72 -5
- package/dist/outcome.d.ts.map +1 -1
- package/dist/outcome.js +81 -1
- package/dist/overlay.d.ts +15 -5
- package/dist/overlay.d.ts.map +1 -1
- package/dist/overlay.js +136 -180
- 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 +75 -5
- package/dist/query.d.ts.map +1 -1
- package/dist/query.js +119 -26
- package/dist/reach.d.ts +18 -4
- package/dist/reach.d.ts.map +1 -1
- package/dist/reach.js +234 -69
- package/dist/react.d.ts +32 -19
- package/dist/react.d.ts.map +1 -1
- package/dist/react.js +13 -21
- 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 +20 -7
- package/dist/refresh.d.ts.map +1 -1
- package/dist/refresh.js +167 -59
- package/dist/replica.d.ts +59 -33
- package/dist/replica.d.ts.map +1 -1
- package/dist/replica.js +324 -157
- package/dist/room-draft.d.ts +59 -11
- package/dist/room-draft.d.ts.map +1 -1
- package/dist/room-draft.js +276 -80
- package/dist/rows.d.ts +40 -34
- package/dist/rows.d.ts.map +1 -1
- package/dist/rows.js +202 -80
- package/dist/save.d.ts +73 -4
- package/dist/save.d.ts.map +1 -1
- package/dist/save.js +825 -152
- package/dist/search.d.ts +15 -54
- 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 +7 -2
- package/dist/status.d.ts.map +1 -1
- package/dist/status.js +3 -9
- package/dist/store.d.ts +118 -59
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +354 -344
- 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 +104 -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 +170 -33
- package/dist/wire.d.ts.map +1 -1
- package/dist/wire.js +69 -31
- package/package.json +26 -15
- package/AGENTS.md +0 -232
- 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 -377
package/dist/reach.js
CHANGED
|
@@ -1,30 +1,38 @@
|
|
|
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
|
+
import { runtimeError } from './failure.js';
|
|
5
|
+
import { failure, lockedRoom, ROOM_LOCKED, undeclared, UNREADABLE, } from './outcome.js';
|
|
4
6
|
import { beneath } from './paths.js';
|
|
5
|
-
import {
|
|
6
|
-
import { moveTarget, readParts } from './room-draft.js';
|
|
7
|
+
import { moveTarget, readParts, staleWrite, } from './room-draft.js';
|
|
7
8
|
import { documentKey } from './rows.js';
|
|
8
9
|
const UNHELD_TYPES = { collection: modelTypes(NO_MODEL), typedSelection: null };
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
return Promise.resolve(UNDECLARED);
|
|
10
|
+
function unconversed(name) {
|
|
11
|
+
return () => Promise.resolve(undeclared(name));
|
|
12
12
|
}
|
|
13
13
|
const NO_CONVERSATION = {
|
|
14
14
|
list: () => Promise.resolve([]),
|
|
15
15
|
read: (conversation) => Promise.resolve(unheldView(conversation)),
|
|
16
|
-
create:
|
|
17
|
-
send:
|
|
18
|
-
answer:
|
|
19
|
-
interrupt:
|
|
20
|
-
kill:
|
|
21
|
-
|
|
22
|
-
delete: undeclared,
|
|
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'),
|
|
23
22
|
};
|
|
24
23
|
const NO_CHAT_DRAFT = {
|
|
25
24
|
write: () => Promise.resolve(),
|
|
25
|
+
prepend: () => Promise.resolve(),
|
|
26
26
|
discard: () => Promise.resolve(),
|
|
27
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
|
+
}
|
|
28
36
|
export function holds(reach, room) {
|
|
29
37
|
return (reach === null ||
|
|
30
38
|
reach.rooms.includes(room) ||
|
|
@@ -45,8 +53,9 @@ export function governs(reach, room) {
|
|
|
45
53
|
}
|
|
46
54
|
function covers(reach, room, path) {
|
|
47
55
|
return (reach === null ||
|
|
48
|
-
reach
|
|
49
|
-
|
|
56
|
+
(!fenced(reach, room, path) &&
|
|
57
|
+
(reach.rooms.includes(room) ||
|
|
58
|
+
reach.documents.some((document) => document.room === room && document.path === path))));
|
|
50
59
|
}
|
|
51
60
|
function conversing(reach) {
|
|
52
61
|
return reach === null || reach.conversations;
|
|
@@ -59,6 +68,9 @@ export function planReach(reach) {
|
|
|
59
68
|
documents: [
|
|
60
69
|
...new Set(reach.documents.map(({ room, path }) => documentKey(room, path))),
|
|
61
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),
|
|
62
74
|
};
|
|
63
75
|
}
|
|
64
76
|
function roomsWithin(reach, rooms) {
|
|
@@ -74,7 +86,7 @@ function typesWithin(reach, room, types) {
|
|
|
74
86
|
};
|
|
75
87
|
}
|
|
76
88
|
function moves(reach, room, move) {
|
|
77
|
-
return move === undefined || covers(reach, room, moveTarget(move));
|
|
89
|
+
return move === undefined || covers(reach, move.room ?? room, moveTarget(move));
|
|
78
90
|
}
|
|
79
91
|
function draftWithin(reach, draft) {
|
|
80
92
|
return covers(reach, draft.room, draft.path) && moves(reach, draft.room, draft.parts.move);
|
|
@@ -88,7 +100,7 @@ function shownDraft(reach, draft) {
|
|
|
88
100
|
function writeWithin(reach, write) {
|
|
89
101
|
return write.outcome === 'written'
|
|
90
102
|
? { outcome: 'written', roomDraft: shownDraft(reach, write.roomDraft) }
|
|
91
|
-
:
|
|
103
|
+
: staleWrite(shownDraft(reach, write.current));
|
|
92
104
|
}
|
|
93
105
|
function savedWithin(reach, room, result) {
|
|
94
106
|
if (reach === null || result.outcome === 'saved')
|
|
@@ -108,136 +120,289 @@ function statusWithin(reach, status) {
|
|
|
108
120
|
return {
|
|
109
121
|
...status,
|
|
110
122
|
attentionRequired: status.attentionRequired.filter((entry) => covers(reach, entry.room, entry.path)),
|
|
123
|
+
unsent: status.unsent.filter((change) => covers(reach, change.room, change.path)),
|
|
111
124
|
};
|
|
112
125
|
}
|
|
113
126
|
function queueWithin(reach, room, entries) {
|
|
114
|
-
return entries
|
|
115
|
-
(
|
|
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
|
+
});
|
|
116
138
|
}
|
|
117
139
|
function unreached(room) {
|
|
118
|
-
return
|
|
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');
|
|
147
|
+
}
|
|
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');
|
|
119
154
|
}
|
|
120
|
-
export function narrowed(runtime, given) {
|
|
155
|
+
export function narrowed(runtime, given, port) {
|
|
121
156
|
const { md, watch } = runtime;
|
|
122
157
|
let reach = given;
|
|
123
158
|
const open = new Set();
|
|
124
|
-
function following(begin) {
|
|
159
|
+
function following(begin, locking = false) {
|
|
125
160
|
let stop = begin();
|
|
126
161
|
const restart = () => {
|
|
127
162
|
stop();
|
|
128
163
|
stop = begin();
|
|
129
164
|
};
|
|
130
165
|
open.add(restart);
|
|
166
|
+
const unwatch = locking ? runtime.watchLocks(restart) : () => { };
|
|
131
167
|
return () => {
|
|
132
168
|
open.delete(restart);
|
|
169
|
+
unwatch();
|
|
133
170
|
stop();
|
|
134
171
|
};
|
|
135
172
|
}
|
|
136
|
-
const
|
|
173
|
+
const unlocking = (rooms) => {
|
|
174
|
+
const locked = (rooms ?? []).filter((room) => runtime.locked(room));
|
|
175
|
+
return locked.length === 0
|
|
176
|
+
? null
|
|
177
|
+
: { pending: locked.map((room) => ({ room, awaits: 'unlock' })) };
|
|
178
|
+
};
|
|
179
|
+
const unlocked = (entries) => entries.filter((entry) => !runtime.locked(entry.room));
|
|
180
|
+
const intoLocked = (held) => held.some((move) => move?.room !== undefined && runtime.locked(move.room));
|
|
181
|
+
const within = (topic, input, deliver, fail) => {
|
|
137
182
|
if (topic === 'rooms') {
|
|
138
|
-
return following(() => watch(topic, input, (rooms) => deliver(roomsWithin(reach, rooms))));
|
|
183
|
+
return following(() => watch(topic, input, (rooms) => deliver(roomsWithin(reach, rooms)), fail));
|
|
184
|
+
}
|
|
185
|
+
if (topic === 'readiness') {
|
|
186
|
+
return following(() => runtime.watchReadiness(port, reach, deliver));
|
|
139
187
|
}
|
|
140
188
|
if (topic === 'sync-status') {
|
|
141
|
-
return following(() => watch(topic, input, (status) =>
|
|
189
|
+
return following(() => watch(topic, input, (status) => {
|
|
190
|
+
const within = statusWithin(reach, status);
|
|
191
|
+
deliver({ ...within, attentionRequired: unlocked(within.attentionRequired) });
|
|
192
|
+
}, fail), true);
|
|
142
193
|
}
|
|
143
194
|
if (topic === 'room-drafts') {
|
|
144
|
-
return following(() => watch(topic, input, (drafts) => deliver(draftsWithin(reach, drafts))));
|
|
195
|
+
return following(() => watch(topic, input, (drafts) => deliver(unlocked(draftsWithin(reach, drafts))), fail), true);
|
|
145
196
|
}
|
|
146
197
|
if (topic === 'queue') {
|
|
147
198
|
const room = input[0];
|
|
148
199
|
return following(() => {
|
|
149
|
-
if (!holds(reach, room)) {
|
|
200
|
+
if (!holds(reach, room) || runtime.locked(room)) {
|
|
150
201
|
deliver([]);
|
|
151
202
|
return () => { };
|
|
152
203
|
}
|
|
153
|
-
return watch(topic, input, (entries) => deliver(queueWithin(reach, room, entries)));
|
|
154
|
-
});
|
|
204
|
+
return watch(topic, input, (entries) => deliver(queueWithin(reach, room, entries)), fail);
|
|
205
|
+
}, true);
|
|
155
206
|
}
|
|
156
207
|
if (topic === 'query') {
|
|
157
208
|
const plan = runtime.plan(input[0], reach);
|
|
158
209
|
let held = null;
|
|
159
210
|
return following(() => {
|
|
211
|
+
const locked = unlocking(plan.rooms);
|
|
212
|
+
if (locked !== null) {
|
|
213
|
+
const answer = { result: locked, keys: [] };
|
|
214
|
+
if (held === null || changeOf(held, answer) !== null)
|
|
215
|
+
deliver(answer);
|
|
216
|
+
held = digestOf(answer);
|
|
217
|
+
return () => { };
|
|
218
|
+
}
|
|
160
219
|
let first = true;
|
|
161
|
-
|
|
220
|
+
let open = true;
|
|
221
|
+
const heard = (message) => {
|
|
162
222
|
if (!first) {
|
|
163
|
-
held =
|
|
223
|
+
held = digestApplied(held, message);
|
|
164
224
|
deliver(message);
|
|
165
225
|
return;
|
|
166
226
|
}
|
|
167
227
|
first = false;
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
228
|
+
const change = held === null ? message : changeOf(held, message);
|
|
229
|
+
held = digestOf(message);
|
|
230
|
+
if (change !== null)
|
|
231
|
+
deliver(change);
|
|
232
|
+
};
|
|
233
|
+
const current = { ...plan, reach: planReach(reach), locked: runtime.lockedRooms() };
|
|
234
|
+
const stop = runtime.watchPlan(current, (message) => {
|
|
235
|
+
if (open)
|
|
236
|
+
heard(message);
|
|
237
|
+
}, (error) => {
|
|
238
|
+
if (open)
|
|
239
|
+
fail(error);
|
|
178
240
|
});
|
|
179
|
-
|
|
241
|
+
return () => {
|
|
242
|
+
open = false;
|
|
243
|
+
stop();
|
|
244
|
+
};
|
|
245
|
+
}, true);
|
|
180
246
|
}
|
|
181
247
|
if (topic === 'conversation') {
|
|
182
248
|
return following(() => {
|
|
183
249
|
if (conversing(reach))
|
|
184
|
-
return watch(topic, input, deliver);
|
|
250
|
+
return watch(topic, input, deliver, fail);
|
|
185
251
|
deliver(unheldView(input[0]));
|
|
186
252
|
return () => { };
|
|
187
253
|
});
|
|
188
254
|
}
|
|
189
|
-
if (topic === 'conversations') {
|
|
255
|
+
if (topic === 'conversations' || topic === 'agents') {
|
|
190
256
|
return following(() => {
|
|
191
257
|
if (conversing(reach))
|
|
192
|
-
return watch(topic, input, deliver);
|
|
258
|
+
return watch(topic, input, deliver, fail);
|
|
193
259
|
deliver([]);
|
|
194
260
|
return () => { };
|
|
195
261
|
});
|
|
196
262
|
}
|
|
197
|
-
return watch(topic, input, deliver);
|
|
263
|
+
return watch(topic, input, deliver, fail);
|
|
198
264
|
};
|
|
265
|
+
const files = new Map();
|
|
266
|
+
let handed = 0;
|
|
267
|
+
async function hand(reading) {
|
|
268
|
+
const answer = await reading;
|
|
269
|
+
if (answer.kind !== 'binary')
|
|
270
|
+
return answer;
|
|
271
|
+
handed += 1;
|
|
272
|
+
const file = String(handed);
|
|
273
|
+
files.set(file, answer.file);
|
|
274
|
+
return { ...answer, file };
|
|
275
|
+
}
|
|
199
276
|
const conversation = () => (conversing(reach) ? md.conversation : NO_CONVERSATION);
|
|
200
277
|
const chatDraft = () => (conversing(reach) ? md.chatDraft : NO_CHAT_DRAFT);
|
|
201
278
|
const view = {
|
|
202
279
|
...md,
|
|
203
|
-
rooms: () => roomsWithin(reach,
|
|
204
|
-
query: ((input) =>
|
|
280
|
+
rooms: () => md.rooms().then((rooms) => roomsWithin(reach, rooms)),
|
|
281
|
+
query: ((input) => {
|
|
282
|
+
const plan = runtime.plan(input, reach);
|
|
283
|
+
return Promise.resolve(unlocking(plan.rooms) ?? runtime.query({ ...plan, locked: runtime.lockedRooms() }));
|
|
284
|
+
}),
|
|
205
285
|
search: (input) => runtime.search(input, reach),
|
|
206
286
|
types(room) {
|
|
287
|
+
if (holds(reach, room) && runtime.locked(room))
|
|
288
|
+
throw lockedError(room);
|
|
207
289
|
if (wholly(reach, room))
|
|
208
290
|
return md.types(room);
|
|
209
291
|
if (!holds(reach, room))
|
|
210
292
|
return structuredClone(UNHELD_TYPES);
|
|
211
|
-
|
|
212
|
-
return typesWithin(reach, listed, md.types(room));
|
|
293
|
+
return typesWithin(reach, runtime.room(room), md.types(room));
|
|
213
294
|
},
|
|
214
295
|
async save(room, roomDrafts, writtenBy) {
|
|
215
296
|
if (!holds(reach, room))
|
|
216
297
|
throw unreached(room);
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
298
|
+
if (runtime.locked(room))
|
|
299
|
+
return { outcome: 'refused', code: ROOM_LOCKED, retryable: true };
|
|
300
|
+
const held = (await Promise.all(roomDrafts.map(({ path }) => md.roomDraft.read(room, path)))).map((draft) => draft?.parts.move);
|
|
301
|
+
const outside = roomDrafts.find(({ path }, at) => !covers(reach, room, path) || !moves(reach, room, held[at]));
|
|
302
|
+
if (outside !== undefined) {
|
|
303
|
+
return { outcome: 'refused', code: 'stale', retryable: false, file: outside.path };
|
|
304
|
+
}
|
|
305
|
+
if (intoLocked(held))
|
|
306
|
+
return { outcome: 'refused', code: ROOM_LOCKED, retryable: true };
|
|
221
307
|
return savedWithin(reach, room, await md.save(room, roomDrafts, writtenBy));
|
|
222
308
|
},
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
309
|
+
async saveParts(room, parts, writtenBy) {
|
|
310
|
+
if (!holds(reach, room))
|
|
311
|
+
throw unreached(room);
|
|
312
|
+
const filed = reach === null ? undefined : parts.find(({ parts: one }) => carriesFile(one));
|
|
313
|
+
if (filed !== undefined) {
|
|
314
|
+
return { outcome: 'refused', code: ATTACH_REQUIRED, retryable: false, file: filed.path };
|
|
315
|
+
}
|
|
316
|
+
if (runtime.locked(room))
|
|
317
|
+
return { outcome: 'refused', code: ROOM_LOCKED, retryable: true };
|
|
318
|
+
const held = parts.map(({ path, parts: one }) => readParts(one, path).move);
|
|
319
|
+
if (parts.some(({ path }, at) => !covers(reach, room, path) || !moves(reach, room, held[at]))) {
|
|
320
|
+
throw unreached(room);
|
|
321
|
+
}
|
|
322
|
+
if (intoLocked(held))
|
|
323
|
+
return { outcome: 'refused', code: ROOM_LOCKED, retryable: true };
|
|
324
|
+
return savedWithin(reach, room, await md.saveParts(room, parts, writtenBy));
|
|
325
|
+
},
|
|
326
|
+
resolve(room, path, destination) {
|
|
327
|
+
const at = runtime.located(room, path, destination);
|
|
328
|
+
return at !== null && !covers(reach, at.room, at.path)
|
|
329
|
+
? Promise.resolve(UNREADABLE)
|
|
330
|
+
: md.resolve(room, path, destination);
|
|
331
|
+
},
|
|
332
|
+
history: (room, path, query) => !covers(reach, room, path)
|
|
333
|
+
? Promise.resolve(failure({ kind: 'room-not-readable', locator: room }))
|
|
334
|
+
: runtime.locked(room)
|
|
335
|
+
? Promise.resolve(lockedRoom(room))
|
|
336
|
+
: md.history(room, path, query),
|
|
337
|
+
binaryFile: {
|
|
338
|
+
read: (room, path, revision) => !covers(reach, room, path)
|
|
339
|
+
? Promise.resolve(failure({ kind: 'room-not-readable', locator: room }))
|
|
340
|
+
: runtime.locked(room)
|
|
341
|
+
? Promise.resolve(lockedRoom(room))
|
|
342
|
+
: hand(md.binaryFile.read(room, path, revision)),
|
|
343
|
+
link: (room, path, revision) => !covers(reach, room, path)
|
|
344
|
+
? Promise.resolve(failure({ kind: 'room-not-readable', locator: room }))
|
|
345
|
+
: runtime.locked(room)
|
|
346
|
+
? Promise.resolve(lockedRoom(room))
|
|
347
|
+
: md.binaryFile.link(room, path, revision),
|
|
348
|
+
show: (room, path, revision) => !covers(reach, room, path)
|
|
349
|
+
? Promise.resolve(failure({ kind: 'room-not-readable', locator: room }))
|
|
350
|
+
: runtime.locked(room)
|
|
351
|
+
? Promise.resolve(lockedRoom(room))
|
|
352
|
+
: hand(md.binaryFile.show(room, path, revision)),
|
|
353
|
+
attach: (room, file) => !wholly(reach, room)
|
|
354
|
+
? Promise.resolve(failure({ kind: 'room-not-readable', locator: room }))
|
|
355
|
+
: runtime.locked(room)
|
|
356
|
+
? Promise.resolve(lockedRoom(room))
|
|
357
|
+
: md.binaryFile.attach(room, file),
|
|
358
|
+
async part(file, part) {
|
|
359
|
+
const key = files.get(file);
|
|
360
|
+
if (key === undefined)
|
|
361
|
+
return null;
|
|
362
|
+
const bytes = await md.binaryFile.part(key, part);
|
|
363
|
+
if (bytes === null)
|
|
364
|
+
files.delete(file);
|
|
365
|
+
return bytes;
|
|
366
|
+
},
|
|
367
|
+
},
|
|
368
|
+
reached: async (room, roomVersion, path) => (path === undefined ? wholly(reach, room) : covers(reach, room, path)) &&
|
|
369
|
+
!runtime.locked(room) &&
|
|
370
|
+
(await md.reached(room, roomVersion, path)),
|
|
228
371
|
log: () => (reach === null ? md.log() : ''),
|
|
372
|
+
cleanUp: () => (reach === null ? md.cleanUp() : Promise.reject(deviceUnreached())),
|
|
229
373
|
roomDraft: {
|
|
230
|
-
list: () => md.roomDraft.list().then((drafts) => draftsWithin(reach, drafts)),
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
374
|
+
list: () => md.roomDraft.list().then((drafts) => unlocked(draftsWithin(reach, drafts))),
|
|
375
|
+
async read(room, path) {
|
|
376
|
+
if (!covers(reach, room, path))
|
|
377
|
+
return null;
|
|
378
|
+
if (runtime.locked(room))
|
|
379
|
+
throw lockedError(room);
|
|
380
|
+
return shownDraft(reach, await md.roomDraft.read(room, path));
|
|
381
|
+
},
|
|
382
|
+
write(room, path, revision, parts, next) {
|
|
383
|
+
try {
|
|
384
|
+
if (reach !== null && carriesFile(parts))
|
|
385
|
+
throw attachRequired();
|
|
386
|
+
const move = readParts(parts, path).move;
|
|
387
|
+
if (!covers(reach, room, path) || !moves(reach, room, move))
|
|
388
|
+
throw unreached(room);
|
|
389
|
+
if (runtime.locked(room))
|
|
390
|
+
throw lockedError(room);
|
|
391
|
+
if (intoLocked([move]))
|
|
392
|
+
throw lockedError(move.room);
|
|
393
|
+
}
|
|
394
|
+
catch (error) {
|
|
395
|
+
return Promise.reject(error);
|
|
235
396
|
}
|
|
236
|
-
return
|
|
397
|
+
return md.roomDraft
|
|
398
|
+
.write(room, path, revision, parts, next)
|
|
399
|
+
.then((written) => writeWithin(reach, written));
|
|
237
400
|
},
|
|
238
401
|
async discard(room, path, revision) {
|
|
239
402
|
if (!covers(reach, room, path))
|
|
240
|
-
return
|
|
403
|
+
return staleWrite(null);
|
|
404
|
+
if (runtime.locked(room))
|
|
405
|
+
throw lockedError(room);
|
|
241
406
|
return writeWithin(reach, await md.roomDraft.discard(room, path, revision));
|
|
242
407
|
},
|
|
243
408
|
},
|
|
@@ -245,15 +410,15 @@ export function narrowed(runtime, given) {
|
|
|
245
410
|
list: () => conversation().list(),
|
|
246
411
|
read: (id, options) => conversation().read(id, options),
|
|
247
412
|
create: (input) => conversation().create(input),
|
|
248
|
-
send: (id) => conversation().send(id),
|
|
413
|
+
send: (id, operation, draft) => conversation().send(id, operation, draft),
|
|
249
414
|
answer: (id, answer) => conversation().answer(id, answer),
|
|
250
415
|
interrupt: (id) => conversation().interrupt(id),
|
|
251
416
|
kill: (id) => conversation().kill(id),
|
|
252
|
-
cancel: (id, turn) => conversation().cancel(id, turn),
|
|
253
417
|
delete: (id) => conversation().delete(id),
|
|
254
418
|
},
|
|
255
419
|
chatDraft: {
|
|
256
|
-
write: (id, draft) => chatDraft().write(id, draft),
|
|
420
|
+
write: (id, draft, revision) => chatDraft().write(id, draft, revision),
|
|
421
|
+
prepend: (id, draft) => chatDraft().prepend(id, draft),
|
|
257
422
|
discard: (id) => chatDraft().discard(id),
|
|
258
423
|
},
|
|
259
424
|
observe: observing(within),
|
package/dist/react.d.ts
CHANGED
|
@@ -1,30 +1,43 @@
|
|
|
1
1
|
import type { MdRuntimeClient } from './client.js';
|
|
2
|
-
import type { AppRoom, ConnectionRefusal, SaveResult } from './connection.js';
|
|
3
|
-
import type { ServiceMode } from './adapter.js';
|
|
4
|
-
import type { ConversationEntry, ConversationOptions, ConversationView } from './conversation.js';
|
|
2
|
+
import type { AppRoom, ConnectionRefusal, SavedRoomDraft, SaveResult } from './connection.js';
|
|
3
|
+
import type { Member, ServiceMode } from './adapter.js';
|
|
4
|
+
import type { ConversationAgent, ConversationEntry, ConversationOptions, ConversationView } from './conversation.js';
|
|
5
|
+
import { type RuntimeError } from './failure.js';
|
|
5
6
|
import type { QueueEntry } from './outcome.js';
|
|
6
|
-
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';
|
|
7
9
|
import type { RoomDraft, RoomDraftParts } from './room-draft.js';
|
|
8
10
|
import type { SyncStatus } from './status.js';
|
|
9
11
|
type Client = MdRuntimeClient | null;
|
|
10
|
-
export
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
export declare function useObserve(client: Client, topic: '
|
|
17
|
-
export declare function useObserve(client: Client, topic: '
|
|
18
|
-
export declare function useObserve(client: Client, topic: '
|
|
19
|
-
export declare function useObserve(client: Client, topic: '
|
|
20
|
-
export declare function useObserve(client: Client, topic: '
|
|
21
|
-
export declare function useObserve(client: Client, topic: '
|
|
22
|
-
export declare function useObserve(client: Client, topic: '
|
|
12
|
+
export type Observed<T> = {
|
|
13
|
+
readonly state: 'loading';
|
|
14
|
+
} | {
|
|
15
|
+
readonly state: 'ready';
|
|
16
|
+
readonly value: T;
|
|
17
|
+
};
|
|
18
|
+
export declare function useObserve(client: Client, topic: 'deployment-facts'): Observed<unknown>;
|
|
19
|
+
export declare function useObserve(client: Client, topic: 'rooms'): Observed<readonly AppRoom[]>;
|
|
20
|
+
export declare function useObserve(client: Client, topic: 'readiness'): Observed<Readiness>;
|
|
21
|
+
export declare function useObserve(client: Client, topic: 'connection-refusal'): Observed<ConnectionRefusal | null>;
|
|
22
|
+
export declare function useObserve(client: Client, topic: 'storage-loss'): Observed<string | null>;
|
|
23
|
+
export declare function useObserve(client: Client, topic: 'sync-status'): Observed<SyncStatus>;
|
|
24
|
+
export declare function useObserve(client: Client, topic: 'service-mode'): Observed<ServiceMode>;
|
|
25
|
+
export declare function useObserve(client: Client, topic: 'member'): Observed<Member | null>;
|
|
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>;
|
|
29
|
+
export declare function useObserve(client: Client, topic: 'queue', locator: string): Observed<readonly QueueEntry[]>;
|
|
30
|
+
export declare function useObserve(client: Client, topic: 'room-drafts'): Observed<readonly RoomDraft[]>;
|
|
31
|
+
export declare function useObserve(client: Client, topic: 'presentation'): Observed<unknown>;
|
|
32
|
+
export declare function useObserve(client: Client, topic: 'conversation', conversation: string, options: ConversationOptions): Observed<ConversationView>;
|
|
33
|
+
export declare function useObserve(client: Client, topic: 'conversations'): Observed<readonly ConversationEntry[]>;
|
|
34
|
+
export declare function useObserve(client: Client, topic: 'agents'): Observed<readonly ConversationAgent[]>;
|
|
23
35
|
export type Saving = {
|
|
24
36
|
readonly busy: boolean;
|
|
25
37
|
readonly outcome: SaveResult | null;
|
|
26
|
-
readonly failure:
|
|
27
|
-
save(room: string,
|
|
38
|
+
readonly failure: RuntimeError | null;
|
|
39
|
+
save(room: string, parts: ReadonlyMap<string, RoomDraftParts>): Promise<SaveResult>;
|
|
40
|
+
saveWritten(room: string, roomDrafts: readonly SavedRoomDraft[]): Promise<SaveResult>;
|
|
28
41
|
};
|
|
29
42
|
export declare function useSave(client: MdRuntimeClient): Saving;
|
|
30
43
|
export {};
|
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,10 +1,12 @@
|
|
|
1
|
-
import { useCallback,
|
|
1
|
+
import { useCallback, useLayoutEffect, useRef, useState } from 'react';
|
|
2
|
+
import { failed } from './failure.js';
|
|
3
|
+
const LOADING = { state: 'loading' };
|
|
2
4
|
export function useObserve(client, topic, ...input) {
|
|
3
5
|
const key = JSON.stringify([topic, ...input]);
|
|
4
6
|
const [held, setHeld] = useState(null);
|
|
5
7
|
const opened = useRef(input);
|
|
6
8
|
opened.current = input;
|
|
7
|
-
|
|
9
|
+
useLayoutEffect(() => {
|
|
8
10
|
if (client === null)
|
|
9
11
|
return;
|
|
10
12
|
let live = true;
|
|
@@ -18,7 +20,7 @@ export function useObserve(client, topic, ...input) {
|
|
|
18
20
|
observation = open;
|
|
19
21
|
const take = (value) => {
|
|
20
22
|
if (live)
|
|
21
|
-
setHeld({ client, key, value });
|
|
23
|
+
setHeld({ client, key, observed: { state: 'ready', value } });
|
|
22
24
|
};
|
|
23
25
|
take(open.current());
|
|
24
26
|
open.subscribe(take);
|
|
@@ -28,35 +30,25 @@ export function useObserve(client, topic, ...input) {
|
|
|
28
30
|
observation?.close();
|
|
29
31
|
};
|
|
30
32
|
}, [client, key]);
|
|
31
|
-
return held !== null && held.client === client && held.key === key ? held.
|
|
33
|
+
return held !== null && held.client === client && held.key === key ? held.observed : LOADING;
|
|
32
34
|
}
|
|
33
35
|
const IDLE = { busy: false, outcome: null, failure: null };
|
|
34
|
-
async function written(client, room, roomDrafts) {
|
|
35
|
-
const kept = [];
|
|
36
|
-
for (const [path, parts] of roomDrafts) {
|
|
37
|
-
const prior = await client.roomDraft.read(room, path);
|
|
38
|
-
const write = await client.roomDraft.write(room, path, prior?.revision ?? null, parts);
|
|
39
|
-
if (write.outcome !== 'written' || write.roomDraft === null) {
|
|
40
|
-
throw new Error(`the Room Draft at ${path} was not written`);
|
|
41
|
-
}
|
|
42
|
-
kept.push({ path, revision: write.roomDraft.revision });
|
|
43
|
-
}
|
|
44
|
-
return client.save(room, kept);
|
|
45
|
-
}
|
|
46
36
|
export function useSave(client) {
|
|
47
37
|
const [state, setState] = useState(IDLE);
|
|
48
|
-
const
|
|
38
|
+
const settled = useCallback(async (saving) => {
|
|
49
39
|
setState({ busy: true, outcome: null, failure: null });
|
|
50
40
|
try {
|
|
51
|
-
const outcome = await
|
|
41
|
+
const outcome = await saving();
|
|
52
42
|
setState({ busy: false, outcome, failure: null });
|
|
53
43
|
return outcome;
|
|
54
44
|
}
|
|
55
45
|
catch (error) {
|
|
56
|
-
const failure =
|
|
46
|
+
const failure = failed(error);
|
|
57
47
|
setState({ busy: false, outcome: null, failure });
|
|
58
48
|
throw failure;
|
|
59
49
|
}
|
|
60
|
-
}, [
|
|
61
|
-
|
|
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 };
|
|
62
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
|