@agentshouse/mdruntime 0.1.0-cfbf80d8d4644 → 0.1.0-cfe148b32e3d8
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/AGENTS.md +299 -214
- package/README.md +21 -10
- package/dist/adapter.d.ts +126 -29
- package/dist/adapter.d.ts.map +1 -1
- package/dist/attached-model.d.ts +4 -1
- package/dist/attached-model.d.ts.map +1 -1
- package/dist/attached-model.js +28 -5
- 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 +36 -5
- package/dist/bootstrap.d.ts.map +1 -1
- package/dist/bootstrap.js +207 -46
- 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/chat/acts.d.ts +33 -0
- package/dist/chat/acts.d.ts.map +1 -0
- package/dist/chat/acts.js +36 -0
- package/dist/chat/context.d.ts +3 -0
- package/dist/chat/context.d.ts.map +1 -0
- package/dist/chat/context.js +10 -0
- package/dist/chat/earlier.d.ts +10 -0
- package/dist/chat/earlier.d.ts.map +1 -0
- package/dist/chat/earlier.js +54 -0
- package/dist/chat/house.d.ts +25 -0
- package/dist/chat/house.d.ts.map +1 -0
- package/dist/chat/house.js +38 -0
- package/dist/chat/input.d.ts +11 -0
- package/dist/chat/input.d.ts.map +1 -0
- package/dist/chat/input.js +92 -0
- package/dist/chat/kit.d.ts +61 -0
- package/dist/chat/kit.d.ts.map +1 -0
- package/dist/chat/kit.js +123 -0
- package/dist/chat/lasting.d.ts +6 -0
- package/dist/chat/lasting.d.ts.map +1 -0
- package/dist/chat/lasting.js +19 -0
- package/dist/chat/list.d.ts +28 -0
- package/dist/chat/list.d.ts.map +1 -0
- package/dist/chat/list.js +103 -0
- package/dist/chat/markdown.d.ts +20 -0
- package/dist/chat/markdown.d.ts.map +1 -0
- package/dist/chat/markdown.js +229 -0
- package/dist/chat/message.d.ts +7 -0
- package/dist/chat/message.d.ts.map +1 -0
- package/dist/chat/message.js +254 -0
- package/dist/chat/messages.d.ts +35 -0
- package/dist/chat/messages.d.ts.map +1 -0
- package/dist/chat/messages.js +210 -0
- package/dist/chat/name.d.ts +7 -0
- package/dist/chat/name.d.ts.map +1 -0
- package/dist/chat/name.js +37 -0
- package/dist/chat/opened.d.ts +12 -0
- package/dist/chat/opened.d.ts.map +1 -0
- package/dist/chat/opened.js +19 -0
- package/dist/chat/overlay.d.ts +32 -0
- package/dist/chat/overlay.d.ts.map +1 -0
- package/dist/chat/overlay.js +103 -0
- package/dist/chat/parts.d.ts +58 -0
- package/dist/chat/parts.d.ts.map +1 -0
- package/dist/chat/parts.js +120 -0
- package/dist/chat/pieces.d.ts +62 -0
- package/dist/chat/pieces.d.ts.map +1 -0
- package/dist/chat/pieces.js +1110 -0
- package/dist/chat/process.d.ts +20 -0
- package/dist/chat/process.d.ts.map +1 -0
- package/dist/chat/process.js +32 -0
- package/dist/chat/provider.d.ts +70 -0
- package/dist/chat/provider.d.ts.map +1 -0
- package/dist/chat/provider.js +635 -0
- package/dist/chat/question.d.ts +9 -0
- package/dist/chat/question.d.ts.map +1 -0
- package/dist/chat/question.js +69 -0
- package/dist/chat/questions.d.ts +31 -0
- package/dist/chat/questions.d.ts.map +1 -0
- package/dist/chat/questions.js +111 -0
- package/dist/chat/read.d.ts +5 -0
- package/dist/chat/read.d.ts.map +1 -0
- package/dist/chat/read.js +13 -0
- package/dist/chat/ready.d.ts +37 -0
- package/dist/chat/ready.d.ts.map +1 -0
- package/dist/chat/ready.js +93 -0
- package/dist/chat/room-file.d.ts +8 -0
- package/dist/chat/room-file.d.ts.map +1 -0
- package/dist/chat/room-file.js +72 -0
- package/dist/chat/steady.d.ts +3 -0
- package/dist/chat/steady.d.ts.map +1 -0
- package/dist/chat/steady.js +26 -0
- package/dist/chat/style.d.ts +4 -0
- package/dist/chat/style.d.ts.map +1 -0
- package/dist/chat/style.js +307 -0
- package/dist/chat.d.ts +15 -0
- package/dist/chat.d.ts.map +1 -0
- package/dist/chat.js +8 -0
- package/dist/client.d.ts +33 -13
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +105 -16
- package/dist/collection.d.ts +9 -13
- package/dist/collection.d.ts.map +1 -1
- package/dist/collection.js +47 -56
- package/dist/compile.d.ts +16 -0
- package/dist/compile.d.ts.map +1 -0
- package/dist/compile.js +721 -0
- package/dist/connection.d.ts +57 -18
- package/dist/connection.d.ts.map +1 -1
- package/dist/connection.js +3572 -640
- package/dist/conversation.d.ts +39 -12
- package/dist/conversation.d.ts.map +1 -1
- package/dist/conversation.js +552 -177
- 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 +9 -1
- package/dist/durability.d.ts.map +1 -1
- package/dist/entry.d.ts +19 -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 -10
- package/dist/file.d.ts.map +1 -1
- package/dist/file.js +3 -120
- package/dist/fulltext.d.ts +27 -0
- package/dist/fulltext.d.ts.map +1 -0
- package/dist/fulltext.js +368 -0
- package/dist/host.d.ts +15 -2
- package/dist/host.d.ts.map +1 -1
- package/dist/host.js +111 -20
- 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 +21 -10
- 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 +123 -0
- package/dist/memory.d.ts +12 -4
- package/dist/memory.d.ts.map +1 -1
- package/dist/memory.js +97 -25
- 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 +14 -4
- package/dist/model.d.ts.map +1 -1
- package/dist/model.js +12 -1
- 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 +19 -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 +62 -3
- package/dist/outcome.d.ts.map +1 -1
- package/dist/outcome.js +67 -1
- package/dist/overlay.d.ts +15 -5
- package/dist/overlay.d.ts.map +1 -1
- package/dist/overlay.js +136 -180
- package/dist/query.d.ts +65 -5
- package/dist/query.d.ts.map +1 -1
- package/dist/query.js +100 -26
- package/dist/reach.d.ts +11 -4
- package/dist/reach.d.ts.map +1 -1
- package/dist/reach.js +194 -57
- package/dist/react.d.ts +31 -19
- package/dist/react.d.ts.map +1 -1
- package/dist/react.js +13 -21
- package/dist/readiness.d.ts +68 -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 +100 -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 +16 -8
- package/dist/refresh.d.ts.map +1 -1
- package/dist/refresh.js +93 -55
- package/dist/replica.d.ts +60 -33
- package/dist/replica.d.ts.map +1 -1
- package/dist/replica.js +319 -153
- package/dist/room-draft.d.ts +40 -9
- package/dist/room-draft.d.ts.map +1 -1
- package/dist/room-draft.js +153 -37
- package/dist/rows.d.ts +30 -34
- package/dist/rows.d.ts.map +1 -1
- package/dist/rows.js +170 -81
- package/dist/save.d.ts +71 -4
- package/dist/save.d.ts.map +1 -1
- package/dist/save.js +815 -148
- 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 +6 -2
- package/dist/status.d.ts.map +1 -1
- package/dist/status.js +0 -8
- package/dist/store.d.ts +124 -58
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +359 -344
- package/dist/stored.d.ts +145 -0
- package/dist/stored.d.ts.map +1 -0
- package/dist/stored.js +567 -0
- package/dist/tables.d.ts +342 -0
- package/dist/tables.d.ts.map +1 -0
- package/dist/tables.js +576 -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 +169 -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 +150 -0
- package/package.json +33 -15
- 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,28 +1,31 @@
|
|
|
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
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
17
|
+
create: unconversed('conversation.create'),
|
|
18
|
+
send: unconversed('conversation.send'),
|
|
19
|
+
attach: unconversed('conversation.attach'),
|
|
20
|
+
answer: unconversed('conversation.answer'),
|
|
21
|
+
interrupt: unconversed('conversation.interrupt'),
|
|
22
|
+
kill: unconversed('conversation.kill'),
|
|
23
|
+
cancel: unconversed('conversation.cancel'),
|
|
24
|
+
delete: unconversed('conversation.delete'),
|
|
23
25
|
};
|
|
24
26
|
const NO_CHAT_DRAFT = {
|
|
25
27
|
write: () => Promise.resolve(),
|
|
28
|
+
prepend: () => Promise.resolve(),
|
|
26
29
|
discard: () => Promise.resolve(),
|
|
27
30
|
};
|
|
28
31
|
export function holds(reach, room) {
|
|
@@ -74,7 +77,7 @@ function typesWithin(reach, room, types) {
|
|
|
74
77
|
};
|
|
75
78
|
}
|
|
76
79
|
function moves(reach, room, move) {
|
|
77
|
-
return move === undefined || covers(reach, room, moveTarget(move));
|
|
80
|
+
return move === undefined || covers(reach, move.room ?? room, moveTarget(move));
|
|
78
81
|
}
|
|
79
82
|
function draftWithin(reach, draft) {
|
|
80
83
|
return covers(reach, draft.room, draft.path) && moves(reach, draft.room, draft.parts.move);
|
|
@@ -88,7 +91,7 @@ function shownDraft(reach, draft) {
|
|
|
88
91
|
function writeWithin(reach, write) {
|
|
89
92
|
return write.outcome === 'written'
|
|
90
93
|
? { outcome: 'written', roomDraft: shownDraft(reach, write.roomDraft) }
|
|
91
|
-
:
|
|
94
|
+
: staleWrite(shownDraft(reach, write.current));
|
|
92
95
|
}
|
|
93
96
|
function savedWithin(reach, room, result) {
|
|
94
97
|
if (reach === null || result.outcome === 'saved')
|
|
@@ -107,76 +110,120 @@ function savedWithin(reach, room, result) {
|
|
|
107
110
|
function statusWithin(reach, status) {
|
|
108
111
|
return {
|
|
109
112
|
...status,
|
|
110
|
-
attentionRequired: status.attentionRequired.filter((entry) => covers(reach, entry.room, entry.path)),
|
|
113
|
+
attentionRequired: status.attentionRequired.filter((entry) => 'refusal' in entry ? wholly(reach, entry.room) : covers(reach, entry.room, entry.path)),
|
|
111
114
|
};
|
|
112
115
|
}
|
|
113
116
|
function queueWithin(reach, room, entries) {
|
|
114
|
-
return entries
|
|
115
|
-
(
|
|
117
|
+
return entries
|
|
118
|
+
.filter(({ batch }) => batch.changes.every((change) => covers(reach, room, change.path) &&
|
|
119
|
+
(change.kind !== 'move' || covers(reach, room, change.to))))
|
|
120
|
+
.map((entry) => {
|
|
121
|
+
const { between, ...batch } = entry.batch;
|
|
122
|
+
if (between === undefined)
|
|
123
|
+
return entry;
|
|
124
|
+
return wholly(reach, between.source.room) && wholly(reach, between.destination.room)
|
|
125
|
+
? entry
|
|
126
|
+
: { ...entry, batch };
|
|
127
|
+
});
|
|
116
128
|
}
|
|
117
129
|
function unreached(room) {
|
|
118
|
-
return
|
|
130
|
+
return runtimeError('room-not-held', `No Local Replica for ${room}`);
|
|
119
131
|
}
|
|
120
|
-
|
|
132
|
+
function lockedError(room) {
|
|
133
|
+
return runtimeError(ROOM_LOCKED, `${room} is locked until House confirms its access`, true);
|
|
134
|
+
}
|
|
135
|
+
function deviceUnreached() {
|
|
136
|
+
return runtimeError('device-unreached', 'Only the panel cleans up this device');
|
|
137
|
+
}
|
|
138
|
+
export function narrowed(runtime, given, told) {
|
|
121
139
|
const { md, watch } = runtime;
|
|
122
140
|
let reach = given;
|
|
141
|
+
let port = told;
|
|
123
142
|
const open = new Set();
|
|
124
|
-
function following(begin) {
|
|
143
|
+
function following(begin, locking = false) {
|
|
125
144
|
let stop = begin();
|
|
126
145
|
const restart = () => {
|
|
127
146
|
stop();
|
|
128
147
|
stop = begin();
|
|
129
148
|
};
|
|
130
149
|
open.add(restart);
|
|
150
|
+
const unwatch = locking ? runtime.watchLocks(restart) : () => { };
|
|
131
151
|
return () => {
|
|
132
152
|
open.delete(restart);
|
|
153
|
+
unwatch();
|
|
133
154
|
stop();
|
|
134
155
|
};
|
|
135
156
|
}
|
|
157
|
+
const unlocking = (rooms) => {
|
|
158
|
+
const locked = (rooms ?? []).filter((room) => runtime.locked(room));
|
|
159
|
+
return locked.length === 0
|
|
160
|
+
? null
|
|
161
|
+
: { pending: locked.map((room) => ({ room, awaits: 'unlock' })) };
|
|
162
|
+
};
|
|
163
|
+
const unlocked = (entries) => entries.filter((entry) => !runtime.locked(entry.room));
|
|
164
|
+
const intoLocked = (held) => held.some((move) => move?.room !== undefined && runtime.locked(move.room));
|
|
136
165
|
const within = (topic, input, deliver) => {
|
|
137
166
|
if (topic === 'rooms') {
|
|
138
167
|
return following(() => watch(topic, input, (rooms) => deliver(roomsWithin(reach, rooms))));
|
|
139
168
|
}
|
|
169
|
+
if (topic === 'readiness') {
|
|
170
|
+
return following(() => runtime.watchReadiness(port, reach, deliver));
|
|
171
|
+
}
|
|
140
172
|
if (topic === 'sync-status') {
|
|
141
|
-
return following(() => watch(topic, input, (status) =>
|
|
173
|
+
return following(() => watch(topic, input, (status) => {
|
|
174
|
+
const within = statusWithin(reach, status);
|
|
175
|
+
deliver({ ...within, attentionRequired: unlocked(within.attentionRequired) });
|
|
176
|
+
}), true);
|
|
142
177
|
}
|
|
143
178
|
if (topic === 'room-drafts') {
|
|
144
|
-
return following(() => watch(topic, input, (drafts) => deliver(draftsWithin(reach, drafts))));
|
|
179
|
+
return following(() => watch(topic, input, (drafts) => deliver(unlocked(draftsWithin(reach, drafts)))), true);
|
|
145
180
|
}
|
|
146
181
|
if (topic === 'queue') {
|
|
147
182
|
const room = input[0];
|
|
148
183
|
return following(() => {
|
|
149
|
-
if (!holds(reach, room)) {
|
|
184
|
+
if (!holds(reach, room) || runtime.locked(room)) {
|
|
150
185
|
deliver([]);
|
|
151
186
|
return () => { };
|
|
152
187
|
}
|
|
153
188
|
return watch(topic, input, (entries) => deliver(queueWithin(reach, room, entries)));
|
|
154
|
-
});
|
|
189
|
+
}, true);
|
|
155
190
|
}
|
|
156
191
|
if (topic === 'query') {
|
|
157
192
|
const plan = runtime.plan(input[0], reach);
|
|
158
193
|
let held = null;
|
|
159
194
|
return following(() => {
|
|
195
|
+
const locked = unlocking(plan.rooms);
|
|
196
|
+
if (locked !== null) {
|
|
197
|
+
const answer = { result: locked, keys: [] };
|
|
198
|
+
if (held === null || changeOf(held, answer) !== null)
|
|
199
|
+
deliver(answer);
|
|
200
|
+
held = digestOf(answer);
|
|
201
|
+
return () => { };
|
|
202
|
+
}
|
|
160
203
|
let first = true;
|
|
161
|
-
|
|
204
|
+
let open = true;
|
|
205
|
+
const heard = (message) => {
|
|
162
206
|
if (!first) {
|
|
163
|
-
held =
|
|
207
|
+
held = digestApplied(held, message);
|
|
164
208
|
deliver(message);
|
|
165
209
|
return;
|
|
166
210
|
}
|
|
167
211
|
first = false;
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
deliver(next.change);
|
|
212
|
+
const change = held === null ? message : changeOf(held, message);
|
|
213
|
+
held = digestOf(message);
|
|
214
|
+
if (change !== null)
|
|
215
|
+
deliver(change);
|
|
216
|
+
};
|
|
217
|
+
const current = { ...plan, reach: planReach(reach), locked: runtime.lockedRooms() };
|
|
218
|
+
const stop = runtime.watchPlan(current, (message) => {
|
|
219
|
+
if (open)
|
|
220
|
+
heard(message);
|
|
178
221
|
});
|
|
179
|
-
|
|
222
|
+
return () => {
|
|
223
|
+
open = false;
|
|
224
|
+
stop();
|
|
225
|
+
};
|
|
226
|
+
}, true);
|
|
180
227
|
}
|
|
181
228
|
if (topic === 'conversation') {
|
|
182
229
|
return following(() => {
|
|
@@ -186,7 +233,7 @@ export function narrowed(runtime, given) {
|
|
|
186
233
|
return () => { };
|
|
187
234
|
});
|
|
188
235
|
}
|
|
189
|
-
if (topic === 'conversations') {
|
|
236
|
+
if (topic === 'conversations' || topic === 'agents') {
|
|
190
237
|
return following(() => {
|
|
191
238
|
if (conversing(reach))
|
|
192
239
|
return watch(topic, input, deliver);
|
|
@@ -196,14 +243,32 @@ export function narrowed(runtime, given) {
|
|
|
196
243
|
}
|
|
197
244
|
return watch(topic, input, deliver);
|
|
198
245
|
};
|
|
246
|
+
const files = new Map();
|
|
247
|
+
let handed = 0;
|
|
248
|
+
const hand = async (reading) => {
|
|
249
|
+
const answer = await reading;
|
|
250
|
+
if (answer.kind !== 'binary')
|
|
251
|
+
return answer;
|
|
252
|
+
handed += 1;
|
|
253
|
+
const file = String(handed);
|
|
254
|
+
files.set(file, answer.file);
|
|
255
|
+
return { ...answer, file };
|
|
256
|
+
};
|
|
199
257
|
const conversation = () => (conversing(reach) ? md.conversation : NO_CONVERSATION);
|
|
200
258
|
const chatDraft = () => (conversing(reach) ? md.chatDraft : NO_CHAT_DRAFT);
|
|
201
259
|
const view = {
|
|
202
260
|
...md,
|
|
203
261
|
rooms: () => roomsWithin(reach, md.rooms()),
|
|
204
|
-
query: ((input) =>
|
|
205
|
-
|
|
262
|
+
query: ((input) => {
|
|
263
|
+
const plan = runtime.plan(input, reach);
|
|
264
|
+
return Promise.resolve(unlocking(plan.rooms) ?? runtime.query({ ...plan, locked: runtime.lockedRooms() }));
|
|
265
|
+
}),
|
|
266
|
+
search: (input) => port.search === 'required'
|
|
267
|
+
? runtime.search(input, reach, runtime.lockedRooms())
|
|
268
|
+
: Promise.resolve(undeclaredSearch()),
|
|
206
269
|
types(room) {
|
|
270
|
+
if (holds(reach, room) && runtime.locked(room))
|
|
271
|
+
throw lockedError(room);
|
|
207
272
|
if (wholly(reach, room))
|
|
208
273
|
return md.types(room);
|
|
209
274
|
if (!holds(reach, room))
|
|
@@ -214,30 +279,91 @@ export function narrowed(runtime, given) {
|
|
|
214
279
|
async save(room, roomDrafts, writtenBy) {
|
|
215
280
|
if (!holds(reach, room))
|
|
216
281
|
throw unreached(room);
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
282
|
+
if (runtime.locked(room))
|
|
283
|
+
return { outcome: 'refused', code: ROOM_LOCKED, retryable: true };
|
|
284
|
+
const held = (await Promise.all(roomDrafts.map(({ path }) => md.roomDraft.read(room, path)))).map((draft) => draft?.parts.move);
|
|
285
|
+
const outside = roomDrafts.find(({ path }, at) => !covers(reach, room, path) || !moves(reach, room, held[at]));
|
|
286
|
+
if (outside !== undefined) {
|
|
287
|
+
return { outcome: 'refused', code: 'stale', retryable: false, file: outside.path };
|
|
288
|
+
}
|
|
289
|
+
if (intoLocked(held))
|
|
290
|
+
return { outcome: 'refused', code: ROOM_LOCKED, retryable: true };
|
|
221
291
|
return savedWithin(reach, room, await md.save(room, roomDrafts, writtenBy));
|
|
222
292
|
},
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
293
|
+
async saveParts(room, parts, writtenBy) {
|
|
294
|
+
if (!holds(reach, room))
|
|
295
|
+
throw unreached(room);
|
|
296
|
+
if (runtime.locked(room))
|
|
297
|
+
return { outcome: 'refused', code: ROOM_LOCKED, retryable: true };
|
|
298
|
+
const held = parts.map(({ parts: one }) => readParts(one).move);
|
|
299
|
+
if (parts.some(({ path }, at) => !covers(reach, room, path) || !moves(reach, room, held[at]))) {
|
|
300
|
+
throw unreached(room);
|
|
301
|
+
}
|
|
302
|
+
if (intoLocked(held))
|
|
303
|
+
return { outcome: 'refused', code: ROOM_LOCKED, retryable: true };
|
|
304
|
+
return savedWithin(reach, room, await md.saveParts(room, parts, writtenBy));
|
|
305
|
+
},
|
|
306
|
+
resolve(room, path, destination) {
|
|
307
|
+
const at = runtime.located(room, path, destination);
|
|
308
|
+
return at !== null && !covers(reach, at.room, at.path)
|
|
309
|
+
? Promise.resolve(UNREADABLE)
|
|
310
|
+
: md.resolve(room, path, destination);
|
|
311
|
+
},
|
|
312
|
+
history: (room, path, query) => !covers(reach, room, path)
|
|
313
|
+
? Promise.resolve(failure({ kind: 'room-not-readable', locator: room }))
|
|
314
|
+
: runtime.locked(room)
|
|
315
|
+
? Promise.resolve(lockedRoom(room))
|
|
316
|
+
: md.history(room, path, query),
|
|
317
|
+
binaryFile: {
|
|
318
|
+
read: (room, path, revision) => !covers(reach, room, path)
|
|
319
|
+
? Promise.resolve(failure({ kind: 'room-not-readable', locator: room }))
|
|
320
|
+
: runtime.locked(room)
|
|
321
|
+
? Promise.resolve(lockedRoom(room))
|
|
322
|
+
: hand(md.binaryFile.read(room, path, revision)),
|
|
323
|
+
link: (room, path, revision) => !covers(reach, room, path)
|
|
324
|
+
? Promise.resolve(failure({ kind: 'room-not-readable', locator: room }))
|
|
325
|
+
: runtime.locked(room)
|
|
326
|
+
? Promise.resolve(lockedRoom(room))
|
|
327
|
+
: md.binaryFile.link(room, path, revision),
|
|
328
|
+
async part(file, part) {
|
|
329
|
+
const key = files.get(file);
|
|
330
|
+
if (key === undefined)
|
|
331
|
+
return null;
|
|
332
|
+
const bytes = await md.binaryFile.part(key, part);
|
|
333
|
+
if (bytes === null)
|
|
334
|
+
files.delete(file);
|
|
335
|
+
return bytes;
|
|
336
|
+
},
|
|
337
|
+
},
|
|
338
|
+
reached: async (room, roomVersion, path) => (path === undefined ? wholly(reach, room) : covers(reach, room, path)) &&
|
|
339
|
+
!runtime.locked(room) &&
|
|
340
|
+
(await md.reached(room, roomVersion, path)),
|
|
228
341
|
log: () => (reach === null ? md.log() : ''),
|
|
342
|
+
cleanUp: () => (reach === null ? md.cleanUp() : Promise.reject(deviceUnreached())),
|
|
229
343
|
roomDraft: {
|
|
230
|
-
list: () => md.roomDraft.list().then((drafts) => draftsWithin(reach, drafts)),
|
|
231
|
-
|
|
344
|
+
list: () => md.roomDraft.list().then((drafts) => unlocked(draftsWithin(reach, drafts))),
|
|
345
|
+
async read(room, path) {
|
|
346
|
+
if (!covers(reach, room, path))
|
|
347
|
+
return null;
|
|
348
|
+
if (runtime.locked(room))
|
|
349
|
+
throw lockedError(room);
|
|
350
|
+
return shownDraft(reach, await md.roomDraft.read(room, path));
|
|
351
|
+
},
|
|
232
352
|
async write(room, path, revision, parts) {
|
|
233
|
-
|
|
353
|
+
const move = readParts(parts).move;
|
|
354
|
+
if (!covers(reach, room, path) || !moves(reach, room, move))
|
|
234
355
|
throw unreached(room);
|
|
235
|
-
|
|
356
|
+
if (runtime.locked(room))
|
|
357
|
+
throw lockedError(room);
|
|
358
|
+
if (intoLocked([move]))
|
|
359
|
+
throw lockedError(move.room);
|
|
236
360
|
return writeWithin(reach, await md.roomDraft.write(room, path, revision, parts));
|
|
237
361
|
},
|
|
238
362
|
async discard(room, path, revision) {
|
|
239
363
|
if (!covers(reach, room, path))
|
|
240
|
-
return
|
|
364
|
+
return staleWrite(null);
|
|
365
|
+
if (runtime.locked(room))
|
|
366
|
+
throw lockedError(room);
|
|
241
367
|
return writeWithin(reach, await md.roomDraft.discard(room, path, revision));
|
|
242
368
|
},
|
|
243
369
|
},
|
|
@@ -245,7 +371,12 @@ export function narrowed(runtime, given) {
|
|
|
245
371
|
list: () => conversation().list(),
|
|
246
372
|
read: (id, options) => conversation().read(id, options),
|
|
247
373
|
create: (input) => conversation().create(input),
|
|
248
|
-
send: (id) => conversation().send(id),
|
|
374
|
+
send: (id, operation, draft) => conversation().send(id, operation, draft),
|
|
375
|
+
attach: (room, file) => !wholly(reach, room)
|
|
376
|
+
? Promise.resolve(failure({ kind: 'room-not-readable', locator: room }))
|
|
377
|
+
: runtime.locked(room)
|
|
378
|
+
? Promise.resolve(lockedRoom(room))
|
|
379
|
+
: conversation().attach(room, file),
|
|
249
380
|
answer: (id, answer) => conversation().answer(id, answer),
|
|
250
381
|
interrupt: (id) => conversation().interrupt(id),
|
|
251
382
|
kill: (id) => conversation().kill(id),
|
|
@@ -253,7 +384,8 @@ export function narrowed(runtime, given) {
|
|
|
253
384
|
delete: (id) => conversation().delete(id),
|
|
254
385
|
},
|
|
255
386
|
chatDraft: {
|
|
256
|
-
write: (id, draft) => chatDraft().write(id, draft),
|
|
387
|
+
write: (id, draft, revision) => chatDraft().write(id, draft, revision),
|
|
388
|
+
prepend: (id, draft) => chatDraft().prepend(id, draft),
|
|
257
389
|
discard: (id) => chatDraft().discard(id),
|
|
258
390
|
},
|
|
259
391
|
observe: observing(within),
|
|
@@ -266,5 +398,10 @@ export function narrowed(runtime, given) {
|
|
|
266
398
|
for (const restart of [...open])
|
|
267
399
|
restart();
|
|
268
400
|
},
|
|
401
|
+
facts(next) {
|
|
402
|
+
port = next;
|
|
403
|
+
for (const restart of [...open])
|
|
404
|
+
restart();
|
|
405
|
+
},
|
|
269
406
|
};
|
|
270
407
|
}
|
package/dist/react.d.ts
CHANGED
|
@@ -1,30 +1,42 @@
|
|
|
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: 'query', query: DocumentQuery): Observed<DocumentResult | PendingResult>;
|
|
27
|
+
export declare function useObserve(client: Client, topic: 'query', query: GroupQuery): Observed<GroupResult | PendingResult>;
|
|
28
|
+
export declare function useObserve(client: Client, topic: 'queue', locator: string): Observed<readonly QueueEntry[]>;
|
|
29
|
+
export declare function useObserve(client: Client, topic: 'room-drafts'): Observed<readonly RoomDraft[]>;
|
|
30
|
+
export declare function useObserve(client: Client, topic: 'presentation'): Observed<unknown>;
|
|
31
|
+
export declare function useObserve(client: Client, topic: 'conversation', conversation: string, options: ConversationOptions): Observed<ConversationView>;
|
|
32
|
+
export declare function useObserve(client: Client, topic: 'conversations'): Observed<readonly ConversationEntry[]>;
|
|
33
|
+
export declare function useObserve(client: Client, topic: 'agents'): Observed<readonly ConversationAgent[]>;
|
|
23
34
|
export type Saving = {
|
|
24
35
|
readonly busy: boolean;
|
|
25
36
|
readonly outcome: SaveResult | null;
|
|
26
|
-
readonly failure:
|
|
27
|
-
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>;
|
|
28
40
|
};
|
|
29
41
|
export declare function useSave(client: MdRuntimeClient): Saving;
|
|
30
42
|
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,68 @@
|
|
|
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 CapacityCause = {
|
|
22
|
+
readonly cause: Open<'insufficient-space' | 'storage-exceeded'>;
|
|
23
|
+
readonly needed: number | null;
|
|
24
|
+
readonly available: number | null;
|
|
25
|
+
};
|
|
26
|
+
export type RefusedRoom = {
|
|
27
|
+
readonly room: string;
|
|
28
|
+
readonly file: string;
|
|
29
|
+
readonly rule: string;
|
|
30
|
+
readonly location: string | null;
|
|
31
|
+
};
|
|
32
|
+
export type InstallationStep = Open<'listing' | 'downloading' | 'writing' | 'replaying'>;
|
|
33
|
+
export type InstallationPause = Open<'hidden'>;
|
|
34
|
+
export type InstallationAmount = {
|
|
35
|
+
readonly done: number;
|
|
36
|
+
readonly total: number;
|
|
37
|
+
};
|
|
38
|
+
export type Installation = {
|
|
39
|
+
readonly step: InstallationStep | null;
|
|
40
|
+
readonly paused: InstallationPause | null;
|
|
41
|
+
readonly rooms: InstallationAmount;
|
|
42
|
+
readonly parts: InstallationAmount;
|
|
43
|
+
readonly bytes: InstallationAmount;
|
|
44
|
+
readonly received: InstallationAmount;
|
|
45
|
+
};
|
|
46
|
+
export type ReadinessStatus = Open<'preparing' | 'paused' | 'refused' | 'ready' | 'lost'>;
|
|
47
|
+
export type Readiness = {
|
|
48
|
+
readonly status: ReadinessStatus;
|
|
49
|
+
readonly ready: boolean;
|
|
50
|
+
readonly usable: boolean;
|
|
51
|
+
readonly code: CodeAvailability;
|
|
52
|
+
readonly coverage: TargetCoverage;
|
|
53
|
+
readonly durability: Durability;
|
|
54
|
+
readonly persistence: Persistence;
|
|
55
|
+
readonly connection: ConnectionAvailability;
|
|
56
|
+
readonly house: HouseOutcome;
|
|
57
|
+
readonly capacity: CapacityCause | null;
|
|
58
|
+
readonly installation: Installation;
|
|
59
|
+
readonly refused: readonly RefusedRoom[];
|
|
60
|
+
readonly lost: boolean;
|
|
61
|
+
};
|
|
62
|
+
export type ReadinessFacts = Omit<Readiness, 'status' | 'ready' | 'usable' | 'durability' | 'coverage'> & {
|
|
63
|
+
readonly coverage: Omit<TargetCoverage, 'complete'>;
|
|
64
|
+
readonly established: boolean;
|
|
65
|
+
};
|
|
66
|
+
export declare const SETTLED_ROOMS: ReadonlySet<string>;
|
|
67
|
+
export declare function readinessOf(facts: ReadinessFacts): Readiness;
|
|
68
|
+
//# 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,33 @@
|
|
|
1
|
+
const COMPLETE_ROOMS = new Set(['complete', 'unadmitted']);
|
|
2
|
+
export const SETTLED_ROOMS = new Set([...COMPLETE_ROOMS, 'refused']);
|
|
3
|
+
export function readinessOf(facts) {
|
|
4
|
+
const { established, coverage: held, ...reported } = facts;
|
|
5
|
+
const settledConversations = held.conversations === 'complete' || held.conversations === 'undeclared';
|
|
6
|
+
const complete = held.listed &&
|
|
7
|
+
settledConversations &&
|
|
8
|
+
held.rooms.every((room) => COMPLETE_ROOMS.has(room.state));
|
|
9
|
+
const settled = held.listed &&
|
|
10
|
+
settledConversations &&
|
|
11
|
+
held.rooms.every((room) => SETTLED_ROOMS.has(room.state));
|
|
12
|
+
const coverage = { ...held, complete };
|
|
13
|
+
const stored = facts.code === 'stored';
|
|
14
|
+
const ready = stored && complete;
|
|
15
|
+
const usable = stored && (ready || established);
|
|
16
|
+
const status = ready
|
|
17
|
+
? 'ready'
|
|
18
|
+
: facts.capacity !== null || facts.installation.paused !== null
|
|
19
|
+
? 'paused'
|
|
20
|
+
: facts.lost && !established
|
|
21
|
+
? 'lost'
|
|
22
|
+
: settled && !complete
|
|
23
|
+
? 'refused'
|
|
24
|
+
: 'preparing';
|
|
25
|
+
return {
|
|
26
|
+
...reported,
|
|
27
|
+
coverage,
|
|
28
|
+
status,
|
|
29
|
+
ready,
|
|
30
|
+
usable,
|
|
31
|
+
durability: facts.persistence === 'granted' ? 'persistent' : 'best-effort',
|
|
32
|
+
};
|
|
33
|
+
}
|