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