@agentshouse/mdruntime 0.1.0-ca68e8b4bbebc → 0.1.0-ca6edc1abd618
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 +18 -15
- package/dist/adapter.d.ts +70 -36
- 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 +21 -4
- package/dist/binary.d.ts +0 -5
- package/dist/binary.d.ts.map +1 -1
- package/dist/binary.js +1 -1
- package/dist/bootstrap.d.ts +25 -8
- package/dist/bootstrap.d.ts.map +1 -1
- package/dist/bootstrap.js +150 -85
- 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 -16
- package/dist/change-set.d.ts.map +1 -1
- package/dist/change-set.js +11 -89
- package/dist/change.d.ts +31 -1
- package/dist/change.d.ts.map +1 -1
- package/dist/change.js +10 -1
- package/dist/client.d.ts +13 -5
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +37 -6
- package/dist/collection.d.ts +6 -19
- package/dist/collection.d.ts.map +1 -1
- package/dist/collection.js +31 -289
- 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 +22 -12
- package/dist/connection.d.ts.map +1 -1
- package/dist/connection.js +2485 -1036
- package/dist/conversation.d.ts +16 -3
- package/dist/conversation.d.ts.map +1 -1
- package/dist/conversation.js +238 -96
- 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 +3 -5
- package/dist/durability.d.ts.map +1 -1
- package/dist/durability.js +5 -0
- package/dist/entry.d.ts +3 -1
- package/dist/entry.d.ts.map +1 -1
- package/dist/entry.js +18 -23
- 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 +4 -7
- package/dist/host.d.ts.map +1 -1
- package/dist/host.js +51 -18
- package/dist/identity.d.ts +0 -1
- package/dist/identity.d.ts.map +1 -1
- package/dist/identity.js +0 -3
- package/dist/index.d.ts +13 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -1
- 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 +4 -3
- package/dist/memory.d.ts.map +1 -1
- package/dist/memory.js +32 -26
- 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.map +1 -1
- package/dist/model.js +1 -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 +14 -0
- package/dist/observation.d.ts.map +1 -1
- package/dist/observation.js +93 -3
- 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 +34 -4
- package/dist/outcome.d.ts.map +1 -1
- package/dist/outcome.js +25 -0
- package/dist/overlay.d.ts +2 -5
- package/dist/overlay.d.ts.map +1 -1
- package/dist/overlay.js +87 -172
- package/dist/query.d.ts +26 -2
- package/dist/query.d.ts.map +1 -1
- package/dist/query.js +41 -6
- package/dist/reach.d.ts +5 -3
- package/dist/reach.d.ts.map +1 -1
- package/dist/reach.js +167 -59
- package/dist/react.d.ts +1 -2
- package/dist/react.d.ts.map +1 -1
- package/dist/react.js +2 -14
- package/dist/readiness.d.ts +20 -9
- package/dist/readiness.d.ts.map +1 -1
- package/dist/readiness.js +6 -6
- package/dist/reads.d.ts.map +1 -1
- package/dist/reads.js +4 -2
- package/dist/recovery.d.ts +2 -2
- package/dist/recovery.d.ts.map +1 -1
- package/dist/recovery.js +8 -7
- package/dist/refresh.d.ts +15 -14
- package/dist/refresh.d.ts.map +1 -1
- package/dist/refresh.js +113 -56
- package/dist/replica.d.ts +56 -33
- package/dist/replica.d.ts.map +1 -1
- package/dist/replica.js +297 -188
- package/dist/room-draft.d.ts +4 -1
- package/dist/room-draft.d.ts.map +1 -1
- package/dist/room-draft.js +62 -22
- package/dist/rows.d.ts +29 -30
- package/dist/rows.d.ts.map +1 -1
- package/dist/rows.js +113 -64
- package/dist/save.d.ts +51 -14
- package/dist/save.d.ts.map +1 -1
- package/dist/save.js +518 -180
- package/dist/search.d.ts +23 -42
- package/dist/search.d.ts.map +1 -1
- package/dist/search.js +28 -182
- package/dist/seed.d.ts.map +1 -1
- package/dist/seed.js +18 -4
- package/dist/shared.d.ts +8 -3
- package/dist/shared.d.ts.map +1 -1
- package/dist/shared.js +129 -66
- package/dist/store.d.ts +89 -89
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +329 -669
- 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 +354 -0
- package/dist/tables.d.ts.map +1 -0
- package/dist/tables.js +624 -0
- package/dist/turn.d.ts +5 -3
- package/dist/turn.d.ts.map +1 -1
- package/dist/turn.js +51 -21
- 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 +29 -1
- package/dist/wire.d.ts.map +1 -1
- package/dist/wire.js +8 -1
- package/dist/words.d.ts +19 -0
- package/dist/words.d.ts.map +1 -0
- package/dist/words.js +150 -0
- package/package.json +18 -19
- package/AGENTS.md +0 -299
- package/dist/acquisition.d.ts +0 -14
- package/dist/acquisition.d.ts.map +0 -1
- package/dist/acquisition.js +0 -24
- package/dist/chat/acts.d.ts +0 -33
- package/dist/chat/acts.d.ts.map +0 -1
- package/dist/chat/acts.js +0 -36
- package/dist/chat/context.d.ts +0 -3
- package/dist/chat/context.d.ts.map +0 -1
- package/dist/chat/context.js +0 -10
- package/dist/chat/input.d.ts +0 -9
- package/dist/chat/input.d.ts.map +0 -1
- package/dist/chat/input.js +0 -99
- package/dist/chat/kit.d.ts +0 -61
- package/dist/chat/kit.d.ts.map +0 -1
- package/dist/chat/kit.js +0 -123
- package/dist/chat/lasting.d.ts +0 -6
- package/dist/chat/lasting.d.ts.map +0 -1
- package/dist/chat/lasting.js +0 -19
- package/dist/chat/list.d.ts +0 -27
- package/dist/chat/list.d.ts.map +0 -1
- package/dist/chat/list.js +0 -63
- package/dist/chat/markdown.d.ts +0 -20
- package/dist/chat/markdown.d.ts.map +0 -1
- package/dist/chat/markdown.js +0 -188
- package/dist/chat/message.d.ts +0 -6
- package/dist/chat/message.d.ts.map +0 -1
- package/dist/chat/message.js +0 -192
- package/dist/chat/messages.d.ts +0 -22
- package/dist/chat/messages.d.ts.map +0 -1
- package/dist/chat/messages.js +0 -155
- package/dist/chat/name.d.ts +0 -6
- package/dist/chat/name.d.ts.map +0 -1
- package/dist/chat/name.js +0 -37
- package/dist/chat/opened.d.ts +0 -11
- package/dist/chat/opened.d.ts.map +0 -1
- package/dist/chat/opened.js +0 -17
- package/dist/chat/overlay.d.ts +0 -31
- package/dist/chat/overlay.d.ts.map +0 -1
- package/dist/chat/overlay.js +0 -97
- package/dist/chat/parts.d.ts +0 -57
- package/dist/chat/parts.d.ts.map +0 -1
- package/dist/chat/parts.js +0 -119
- package/dist/chat/process.d.ts +0 -20
- package/dist/chat/process.d.ts.map +0 -1
- package/dist/chat/process.js +0 -32
- package/dist/chat/provider.d.ts +0 -63
- package/dist/chat/provider.d.ts.map +0 -1
- package/dist/chat/provider.js +0 -629
- package/dist/chat/question.d.ts +0 -9
- package/dist/chat/question.d.ts.map +0 -1
- package/dist/chat/question.js +0 -80
- package/dist/chat/questions.d.ts +0 -31
- package/dist/chat/questions.d.ts.map +0 -1
- package/dist/chat/questions.js +0 -111
- package/dist/chat/read.d.ts +0 -5
- package/dist/chat/read.d.ts.map +0 -1
- package/dist/chat/read.js +0 -13
- package/dist/chat/ready.d.ts +0 -34
- package/dist/chat/ready.d.ts.map +0 -1
- package/dist/chat/ready.js +0 -91
- package/dist/chat/style.d.ts +0 -4
- package/dist/chat/style.d.ts.map +0 -1
- package/dist/chat/style.js +0 -302
- package/dist/chat.d.ts +0 -14
- package/dist/chat.d.ts.map +0 -1
- package/dist/chat.js +0 -8
- package/dist/read-side.d.ts +0 -25
- package/dist/read-side.d.ts.map +0 -1
- package/dist/read-side.js +0 -642
package/dist/reach.js
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { unheldView } from './conversation.js';
|
|
2
2
|
import { modelTypes, NO_MODEL } from './model.js';
|
|
3
|
-
import {
|
|
3
|
+
import { changeOf, digestApplied, digestOf, observing, } from './observation.js';
|
|
4
4
|
import { runtimeError } from './failure.js';
|
|
5
|
-
import { failure, undeclared, } from './outcome.js';
|
|
5
|
+
import { failure, lockedRoom, ROOM_LOCKED, undeclared, UNREADABLE, } from './outcome.js';
|
|
6
6
|
import { beneath } from './paths.js';
|
|
7
|
-
import { reconciled } from './read-side.js';
|
|
8
7
|
import { moveTarget, readParts, staleWrite, } from './room-draft.js';
|
|
9
8
|
import { documentKey } from './rows.js';
|
|
10
9
|
import { undeclaredSearch } from './search.js';
|
|
@@ -17,6 +16,7 @@ const NO_CONVERSATION = {
|
|
|
17
16
|
read: (conversation) => Promise.resolve(unheldView(conversation)),
|
|
18
17
|
create: unconversed('conversation.create'),
|
|
19
18
|
send: unconversed('conversation.send'),
|
|
19
|
+
attach: unconversed('conversation.attach'),
|
|
20
20
|
answer: unconversed('conversation.answer'),
|
|
21
21
|
interrupt: unconversed('conversation.interrupt'),
|
|
22
22
|
kill: unconversed('conversation.kill'),
|
|
@@ -25,6 +25,7 @@ const NO_CONVERSATION = {
|
|
|
25
25
|
};
|
|
26
26
|
const NO_CHAT_DRAFT = {
|
|
27
27
|
write: () => Promise.resolve(),
|
|
28
|
+
prepend: () => Promise.resolve(),
|
|
28
29
|
discard: () => Promise.resolve(),
|
|
29
30
|
};
|
|
30
31
|
export function holds(reach, room) {
|
|
@@ -53,20 +54,6 @@ function covers(reach, room, path) {
|
|
|
53
54
|
function conversing(reach) {
|
|
54
55
|
return reach === null || reach.conversations;
|
|
55
56
|
}
|
|
56
|
-
function refers(reach, scope) {
|
|
57
|
-
if (reach === null)
|
|
58
|
-
return true;
|
|
59
|
-
if (scope === null)
|
|
60
|
-
return false;
|
|
61
|
-
if (scope.kind === 'conversations')
|
|
62
|
-
return reach.conversations;
|
|
63
|
-
return scope.path === undefined
|
|
64
|
-
? wholly(reach, scope.locator)
|
|
65
|
-
: covers(reach, scope.locator, scope.path);
|
|
66
|
-
}
|
|
67
|
-
function unreachedReference(fileRef) {
|
|
68
|
-
return { kind: 'absent', code: 'binary-file-absent', fields: { fileRef }, retryable: false };
|
|
69
|
-
}
|
|
70
57
|
export function planReach(reach) {
|
|
71
58
|
return reach === null
|
|
72
59
|
? null
|
|
@@ -90,7 +77,7 @@ function typesWithin(reach, room, types) {
|
|
|
90
77
|
};
|
|
91
78
|
}
|
|
92
79
|
function moves(reach, room, move) {
|
|
93
|
-
return move === undefined || covers(reach, room, moveTarget(move));
|
|
80
|
+
return move === undefined || covers(reach, move.room ?? room, moveTarget(move));
|
|
94
81
|
}
|
|
95
82
|
function draftWithin(reach, draft) {
|
|
96
83
|
return covers(reach, draft.room, draft.path) && moves(reach, draft.room, draft.parts.move);
|
|
@@ -127,29 +114,54 @@ function statusWithin(reach, status) {
|
|
|
127
114
|
};
|
|
128
115
|
}
|
|
129
116
|
function queueWithin(reach, room, entries) {
|
|
130
|
-
return entries
|
|
131
|
-
(
|
|
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
|
+
});
|
|
132
128
|
}
|
|
133
129
|
function unreached(room) {
|
|
134
130
|
return runtimeError('room-not-held', `No Local Replica for ${room}`);
|
|
135
131
|
}
|
|
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
|
+
}
|
|
136
138
|
export function narrowed(runtime, given, told) {
|
|
137
139
|
const { md, watch } = runtime;
|
|
138
140
|
let reach = given;
|
|
139
141
|
let port = told;
|
|
140
142
|
const open = new Set();
|
|
141
|
-
function following(begin) {
|
|
143
|
+
function following(begin, locking = false) {
|
|
142
144
|
let stop = begin();
|
|
143
145
|
const restart = () => {
|
|
144
146
|
stop();
|
|
145
147
|
stop = begin();
|
|
146
148
|
};
|
|
147
149
|
open.add(restart);
|
|
150
|
+
const unwatch = locking ? runtime.watchLocks(restart) : () => { };
|
|
148
151
|
return () => {
|
|
149
152
|
open.delete(restart);
|
|
153
|
+
unwatch();
|
|
150
154
|
stop();
|
|
151
155
|
};
|
|
152
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));
|
|
153
165
|
const within = (topic, input, deliver) => {
|
|
154
166
|
if (topic === 'rooms') {
|
|
155
167
|
return following(() => watch(topic, input, (rooms) => deliver(roomsWithin(reach, rooms))));
|
|
@@ -158,45 +170,60 @@ export function narrowed(runtime, given, told) {
|
|
|
158
170
|
return following(() => runtime.watchReadiness(port, reach, deliver));
|
|
159
171
|
}
|
|
160
172
|
if (topic === 'sync-status') {
|
|
161
|
-
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);
|
|
162
177
|
}
|
|
163
178
|
if (topic === 'room-drafts') {
|
|
164
|
-
return following(() => watch(topic, input, (drafts) => deliver(draftsWithin(reach, drafts))));
|
|
179
|
+
return following(() => watch(topic, input, (drafts) => deliver(unlocked(draftsWithin(reach, drafts)))), true);
|
|
165
180
|
}
|
|
166
181
|
if (topic === 'queue') {
|
|
167
182
|
const room = input[0];
|
|
168
183
|
return following(() => {
|
|
169
|
-
if (!holds(reach, room)) {
|
|
184
|
+
if (!holds(reach, room) || runtime.locked(room)) {
|
|
170
185
|
deliver([]);
|
|
171
186
|
return () => { };
|
|
172
187
|
}
|
|
173
188
|
return watch(topic, input, (entries) => deliver(queueWithin(reach, room, entries)));
|
|
174
|
-
});
|
|
189
|
+
}, true);
|
|
175
190
|
}
|
|
176
191
|
if (topic === 'query') {
|
|
177
192
|
const plan = runtime.plan(input[0], reach);
|
|
178
193
|
let held = null;
|
|
179
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
|
+
}
|
|
180
203
|
let first = true;
|
|
181
|
-
|
|
204
|
+
let open = true;
|
|
205
|
+
const heard = (message) => {
|
|
182
206
|
if (!first) {
|
|
183
|
-
held =
|
|
207
|
+
held = digestApplied(held, message);
|
|
184
208
|
deliver(message);
|
|
185
209
|
return;
|
|
186
210
|
}
|
|
187
211
|
first = false;
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
deliver(next.message);
|
|
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);
|
|
198
221
|
});
|
|
199
|
-
|
|
222
|
+
return () => {
|
|
223
|
+
open = false;
|
|
224
|
+
stop();
|
|
225
|
+
};
|
|
226
|
+
}, true);
|
|
200
227
|
}
|
|
201
228
|
if (topic === 'conversation') {
|
|
202
229
|
return following(() => {
|
|
@@ -216,16 +243,32 @@ export function narrowed(runtime, given, told) {
|
|
|
216
243
|
}
|
|
217
244
|
return watch(topic, input, deliver);
|
|
218
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
|
+
};
|
|
219
257
|
const conversation = () => (conversing(reach) ? md.conversation : NO_CONVERSATION);
|
|
220
258
|
const chatDraft = () => (conversing(reach) ? md.chatDraft : NO_CHAT_DRAFT);
|
|
221
259
|
const view = {
|
|
222
260
|
...md,
|
|
223
261
|
rooms: () => roomsWithin(reach, md.rooms()),
|
|
224
|
-
query: ((input) =>
|
|
262
|
+
query: ((input) => {
|
|
263
|
+
const plan = runtime.plan(input, reach);
|
|
264
|
+
return Promise.resolve(unlocking(plan.rooms) ?? runtime.query({ ...plan, locked: runtime.lockedRooms() }));
|
|
265
|
+
}),
|
|
225
266
|
search: (input) => port.search === 'required'
|
|
226
|
-
? runtime.search(input, reach)
|
|
267
|
+
? runtime.search(input, reach, runtime.lockedRooms())
|
|
227
268
|
: Promise.resolve(undeclaredSearch()),
|
|
228
269
|
types(room) {
|
|
270
|
+
if (holds(reach, room) && runtime.locked(room))
|
|
271
|
+
throw lockedError(room);
|
|
229
272
|
if (wholly(reach, room))
|
|
230
273
|
return md.types(room);
|
|
231
274
|
if (!holds(reach, room))
|
|
@@ -236,39 +279,98 @@ export function narrowed(runtime, given, told) {
|
|
|
236
279
|
async save(room, roomDrafts, writtenBy) {
|
|
237
280
|
if (!holds(reach, room))
|
|
238
281
|
throw unreached(room);
|
|
239
|
-
|
|
240
|
-
|
|
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]));
|
|
241
286
|
if (outside !== undefined) {
|
|
242
287
|
return { outcome: 'refused', code: 'stale', retryable: false, file: outside.path };
|
|
243
288
|
}
|
|
289
|
+
if (intoLocked(held))
|
|
290
|
+
return { outcome: 'refused', code: ROOM_LOCKED, retryable: true };
|
|
244
291
|
return savedWithin(reach, room, await md.save(room, roomDrafts, writtenBy));
|
|
245
292
|
},
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
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),
|
|
249
317
|
binaryFile: {
|
|
250
|
-
read: (room, path, revision) => covers(reach, room, path)
|
|
251
|
-
?
|
|
252
|
-
:
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
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
|
+
},
|
|
256
337
|
},
|
|
257
|
-
reached: (room, roomVersion, path) => (path === undefined ? wholly(reach, room) : covers(reach, room, path)) &&
|
|
258
|
-
|
|
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)),
|
|
259
341
|
log: () => (reach === null ? md.log() : ''),
|
|
342
|
+
cleanUp: () => (reach === null ? md.cleanUp() : Promise.reject(deviceUnreached())),
|
|
260
343
|
roomDraft: {
|
|
261
|
-
list: () => md.roomDraft.list().then((drafts) => draftsWithin(reach, drafts)),
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
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
|
+
},
|
|
352
|
+
write(room, path, revision, parts, next) {
|
|
353
|
+
try {
|
|
354
|
+
const move = readParts(parts).move;
|
|
355
|
+
if (!covers(reach, room, path) || !moves(reach, room, move))
|
|
356
|
+
throw unreached(room);
|
|
357
|
+
if (runtime.locked(room))
|
|
358
|
+
throw lockedError(room);
|
|
359
|
+
if (intoLocked([move]))
|
|
360
|
+
throw lockedError(move.room);
|
|
361
|
+
}
|
|
362
|
+
catch (error) {
|
|
363
|
+
return Promise.reject(error);
|
|
266
364
|
}
|
|
267
|
-
return
|
|
365
|
+
return md.roomDraft
|
|
366
|
+
.write(room, path, revision, parts, next)
|
|
367
|
+
.then((written) => writeWithin(reach, written));
|
|
268
368
|
},
|
|
269
369
|
async discard(room, path, revision) {
|
|
270
370
|
if (!covers(reach, room, path))
|
|
271
371
|
return staleWrite(null);
|
|
372
|
+
if (runtime.locked(room))
|
|
373
|
+
throw lockedError(room);
|
|
272
374
|
return writeWithin(reach, await md.roomDraft.discard(room, path, revision));
|
|
273
375
|
},
|
|
274
376
|
},
|
|
@@ -277,6 +379,11 @@ export function narrowed(runtime, given, told) {
|
|
|
277
379
|
read: (id, options) => conversation().read(id, options),
|
|
278
380
|
create: (input) => conversation().create(input),
|
|
279
381
|
send: (id, operation, draft) => conversation().send(id, operation, draft),
|
|
382
|
+
attach: (room, file) => !wholly(reach, room)
|
|
383
|
+
? Promise.resolve(failure({ kind: 'room-not-readable', locator: room }))
|
|
384
|
+
: runtime.locked(room)
|
|
385
|
+
? Promise.resolve(lockedRoom(room))
|
|
386
|
+
: conversation().attach(room, file),
|
|
280
387
|
answer: (id, answer) => conversation().answer(id, answer),
|
|
281
388
|
interrupt: (id) => conversation().interrupt(id),
|
|
282
389
|
kill: (id) => conversation().kill(id),
|
|
@@ -285,6 +392,7 @@ export function narrowed(runtime, given, told) {
|
|
|
285
392
|
},
|
|
286
393
|
chatDraft: {
|
|
287
394
|
write: (id, draft, revision) => chatDraft().write(id, draft, revision),
|
|
395
|
+
prepend: (id, draft) => chatDraft().prepend(id, draft),
|
|
288
396
|
discard: (id) => chatDraft().discard(id),
|
|
289
397
|
},
|
|
290
398
|
observe: observing(within),
|
package/dist/react.d.ts
CHANGED
|
@@ -35,10 +35,9 @@ export type Saving = {
|
|
|
35
35
|
readonly busy: boolean;
|
|
36
36
|
readonly outcome: SaveResult | null;
|
|
37
37
|
readonly failure: RuntimeError | null;
|
|
38
|
-
save(room: string,
|
|
38
|
+
save(room: string, parts: ReadonlyMap<string, RoomDraftParts>): Promise<SaveResult>;
|
|
39
39
|
saveWritten(room: string, roomDrafts: readonly SavedRoomDraft[]): Promise<SaveResult>;
|
|
40
40
|
};
|
|
41
|
-
export declare function saveRoomDrafts(client: MdRuntimeClient, room: string, roomDrafts: ReadonlyMap<string, RoomDraftParts>): Promise<SaveResult>;
|
|
42
41
|
export declare function useSave(client: MdRuntimeClient): Saving;
|
|
43
42
|
export {};
|
|
44
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,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC9F,OAAO,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AACxD,OAAO,KAAK,EACV,iBAAiB,EACjB,iBAAiB,EACjB,mBAAmB,EACnB,gBAAgB,EACjB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,
|
|
1
|
+
{"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../src/react.ts"],"names":[],"mappings":"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"}
|
package/dist/react.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useCallback, useLayoutEffect, useRef, useState } from 'react';
|
|
2
|
-
import { failed
|
|
2
|
+
import { failed } from './failure.js';
|
|
3
3
|
const LOADING = { state: 'loading' };
|
|
4
4
|
export function useObserve(client, topic, ...input) {
|
|
5
5
|
const key = JSON.stringify([topic, ...input]);
|
|
@@ -33,18 +33,6 @@ export function useObserve(client, topic, ...input) {
|
|
|
33
33
|
return held !== null && held.client === client && held.key === key ? held.observed : LOADING;
|
|
34
34
|
}
|
|
35
35
|
const IDLE = { busy: false, outcome: null, failure: null };
|
|
36
|
-
export async function saveRoomDrafts(client, room, roomDrafts) {
|
|
37
|
-
const kept = [];
|
|
38
|
-
for (const [path, parts] of roomDrafts) {
|
|
39
|
-
const prior = await client.roomDraft.read(room, path);
|
|
40
|
-
const write = await client.roomDraft.write(room, path, prior?.revision ?? null, parts);
|
|
41
|
-
if (write.outcome !== 'written' || write.roomDraft === null) {
|
|
42
|
-
throw runtimeError(write.outcome === 'stale' ? write.code : 'room-draft-unwritten', `the Room Draft at ${path} was not written`);
|
|
43
|
-
}
|
|
44
|
-
kept.push({ path, revision: write.roomDraft.revision });
|
|
45
|
-
}
|
|
46
|
-
return client.save(room, kept);
|
|
47
|
-
}
|
|
48
36
|
export function useSave(client) {
|
|
49
37
|
const [state, setState] = useState(IDLE);
|
|
50
38
|
const settled = useCallback(async (saving) => {
|
|
@@ -60,7 +48,7 @@ export function useSave(client) {
|
|
|
60
48
|
throw failure;
|
|
61
49
|
}
|
|
62
50
|
}, []);
|
|
63
|
-
const save = useCallback((room,
|
|
51
|
+
const save = useCallback((room, parts) => settled(() => client.saveParts(room, [...parts].map(([path, one]) => ({ path, parts: one })))), [client, settled]);
|
|
64
52
|
const saveWritten = useCallback((room, roomDrafts) => settled(() => client.save(room, roomDrafts)), [client, settled]);
|
|
65
53
|
return { ...state, save, saveWritten };
|
|
66
54
|
}
|
package/dist/readiness.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import type { Open } from './open.js';
|
|
2
2
|
export type CodeAvailability = Open<'stored' | 'absent'>;
|
|
3
|
-
export type RoomPreparation = Open<'complete' | 'acquiring' | 'preparing' | '
|
|
3
|
+
export type RoomPreparation = Open<'complete' | 'acquiring' | 'preparing' | 'refused' | 'unadmitted'>;
|
|
4
4
|
export type RoomCoverage = {
|
|
5
5
|
readonly room: string;
|
|
6
6
|
readonly state: RoomPreparation;
|
|
7
7
|
};
|
|
8
|
-
export type ConversationCoverage = Open<'complete' | 'acquiring' | '
|
|
8
|
+
export type ConversationCoverage = Open<'complete' | 'acquiring' | 'undeclared'>;
|
|
9
9
|
export type SearchObligation = Open<'required' | 'unused'>;
|
|
10
10
|
export type TargetCoverage = {
|
|
11
11
|
readonly complete: boolean;
|
|
@@ -18,17 +18,28 @@ export type Persistence = Open<'granted' | 'denied' | 'unavailable'>;
|
|
|
18
18
|
export type Durability = Open<'persistent' | 'best-effort'>;
|
|
19
19
|
export type ConnectionAvailability = Open<'connected' | 'connecting' | 'unreachable'>;
|
|
20
20
|
export type HouseOutcome = Open<'open' | 'write-halted' | 'refused'>;
|
|
21
|
-
export type
|
|
22
|
-
readonly cause: Open<'insufficient-space' | 'quota-exceeded'>;
|
|
23
|
-
readonly needed: number | null;
|
|
24
|
-
readonly available: number | null;
|
|
25
|
-
};
|
|
21
|
+
export type Space = Open<'full'>;
|
|
26
22
|
export type RefusedRoom = {
|
|
27
23
|
readonly room: string;
|
|
24
|
+
readonly name: string;
|
|
28
25
|
readonly file: string;
|
|
29
26
|
readonly rule: string;
|
|
30
27
|
readonly location: string | null;
|
|
31
28
|
};
|
|
29
|
+
export type InstallationStep = Open<'listing' | '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
|
+
readonly received: InstallationAmount;
|
|
42
|
+
};
|
|
32
43
|
export type ReadinessStatus = Open<'preparing' | 'paused' | 'refused' | 'ready' | 'lost'>;
|
|
33
44
|
export type Readiness = {
|
|
34
45
|
readonly status: ReadinessStatus;
|
|
@@ -40,7 +51,8 @@ export type Readiness = {
|
|
|
40
51
|
readonly persistence: Persistence;
|
|
41
52
|
readonly connection: ConnectionAvailability;
|
|
42
53
|
readonly house: HouseOutcome;
|
|
43
|
-
readonly
|
|
54
|
+
readonly space: Space | null;
|
|
55
|
+
readonly installation: Installation;
|
|
44
56
|
readonly refused: readonly RefusedRoom[];
|
|
45
57
|
readonly lost: boolean;
|
|
46
58
|
};
|
|
@@ -48,6 +60,5 @@ export type ReadinessFacts = Omit<Readiness, 'status' | 'ready' | 'usable' | 'du
|
|
|
48
60
|
readonly coverage: Omit<TargetCoverage, 'complete'>;
|
|
49
61
|
readonly established: boolean;
|
|
50
62
|
};
|
|
51
|
-
export declare const SETTLED_ROOMS: ReadonlySet<string>;
|
|
52
63
|
export declare function readinessOf(facts: ReadinessFacts): Readiness;
|
|
53
64
|
//# sourceMappingURL=readiness.d.ts.map
|
package/dist/readiness.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"readiness.d.ts","sourceRoot":"","sources":["../src/readiness.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEtC,MAAM,MAAM,gBAAgB,GAAG,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC,CAAC;AAEzD,MAAM,MAAM,eAAe,GAAG,IAAI,CAChC,UAAU,GAAG,WAAW,GAAG,WAAW,GAAG,
|
|
1
|
+
{"version":3,"file":"readiness.d.ts","sourceRoot":"","sources":["../src/readiness.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEtC,MAAM,MAAM,gBAAgB,GAAG,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC,CAAC;AAEzD,MAAM,MAAM,eAAe,GAAG,IAAI,CAChC,UAAU,GAAG,WAAW,GAAG,WAAW,GAAG,SAAS,GAAG,YAAY,CAClE,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,eAAe,CAAA;CAAE,CAAC;AAEtF,MAAM,MAAM,oBAAoB,GAAG,IAAI,CAAC,UAAU,GAAG,WAAW,GAAG,YAAY,CAAC,CAAC;AAEjF,MAAM,MAAM,gBAAgB,GAAG,IAAI,CAAC,UAAU,GAAG,QAAQ,CAAC,CAAC;AAE3D,MAAM,MAAM,cAAc,GAAG;IAC3B,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,SAAS,YAAY,EAAE,CAAC;IACxC,QAAQ,CAAC,aAAa,EAAE,oBAAoB,CAAC;IAC7C,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAC;CACnC,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,GAAG,QAAQ,GAAG,aAAa,CAAC,CAAC;AAErE,MAAM,MAAM,UAAU,GAAG,IAAI,CAAC,YAAY,GAAG,aAAa,CAAC,CAAC;AAE5D,MAAM,MAAM,sBAAsB,GAAG,IAAI,CAAC,WAAW,GAAG,YAAY,GAAG,aAAa,CAAC,CAAC;AAEtF,MAAM,MAAM,YAAY,GAAG,IAAI,CAAC,MAAM,GAAG,cAAc,GAAG,SAAS,CAAC,CAAC;AAErE,MAAM,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;AAEjC,MAAM,MAAM,WAAW,GAAG;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,IAAI,CAAC,SAAS,GAAG,aAAa,GAAG,SAAS,GAAG,WAAW,CAAC,CAAC;AAEzF,MAAM,MAAM,iBAAiB,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;AAE/C,MAAM,MAAM,kBAAkB,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnF,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,CAAC,IAAI,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACvC,QAAQ,CAAC,MAAM,EAAE,iBAAiB,GAAG,IAAI,CAAC;IAC1C,QAAQ,CAAC,KAAK,EAAE,kBAAkB,CAAC;IACnC,QAAQ,CAAC,KAAK,EAAE,kBAAkB,CAAC;IACnC,QAAQ,CAAC,KAAK,EAAE,kBAAkB,CAAC;IACnC,QAAQ,CAAC,QAAQ,EAAE,kBAAkB,CAAC;CACvC,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG,IAAI,CAAC,WAAW,GAAG,QAAQ,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,CAAC,CAAC;AAE1F,MAAM,MAAM,SAAS,GAAG;IACtB,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAC;IACjC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,gBAAgB,CAAC;IAChC,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;IAClC,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAChC,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC;IAClC,QAAQ,CAAC,UAAU,EAAE,sBAAsB,CAAC;IAC5C,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IAC7B,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAC;IACpC,QAAQ,CAAC,OAAO,EAAE,SAAS,WAAW,EAAE,CAAC;IACzC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,IAAI,CAC/B,SAAS,EACT,QAAQ,GAAG,OAAO,GAAG,QAAQ,GAAG,YAAY,GAAG,UAAU,CAC1D,GAAG;IACF,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC,cAAc,EAAE,UAAU,CAAC,CAAC;IACpD,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;CAC/B,CAAC;AAMF,wBAAgB,WAAW,CAAC,KAAK,EAAE,cAAc,GAAG,SAAS,CAiC5D"}
|
package/dist/readiness.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const COMPLETE_ROOMS = new Set(['complete', 'unadmitted']);
|
|
2
|
-
|
|
2
|
+
const SETTLED_ROOMS = new Set([...COMPLETE_ROOMS, 'refused']);
|
|
3
3
|
export function readinessOf(facts) {
|
|
4
4
|
const { established, coverage: held, ...reported } = facts;
|
|
5
5
|
const settledConversations = held.conversations === 'complete' || held.conversations === 'undeclared';
|
|
@@ -15,12 +15,12 @@ export function readinessOf(facts) {
|
|
|
15
15
|
const usable = stored && (ready || established);
|
|
16
16
|
const status = ready
|
|
17
17
|
? 'ready'
|
|
18
|
-
: facts.
|
|
18
|
+
: facts.space !== null || facts.installation.paused !== null
|
|
19
19
|
? 'paused'
|
|
20
|
-
:
|
|
21
|
-
? '
|
|
22
|
-
:
|
|
23
|
-
? '
|
|
20
|
+
: settled && !complete
|
|
21
|
+
? 'refused'
|
|
22
|
+
: facts.lost && !established
|
|
23
|
+
? 'lost'
|
|
24
24
|
: 'preparing';
|
|
25
25
|
return {
|
|
26
26
|
...reported,
|
package/dist/reads.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reads.d.ts","sourceRoot":"","sources":["../src/reads.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,OAAO,EAOR,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAE5C,MAAM,MAAM,SAAS,GAAG,KAAK,GAAG;IAC9B,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9C,MAAM,IAAI,IAAI,CAAC;IACf,OAAO,IAAI,IAAI,CAAC;IAChB,IAAI,IAAI,IAAI,CAAC;CACd,CAAC;
|
|
1
|
+
{"version":3,"file":"reads.d.ts","sourceRoot":"","sources":["../src/reads.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,OAAO,EAOR,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAE5C,MAAM,MAAM,SAAS,GAAG,KAAK,GAAG;IAC9B,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9C,MAAM,IAAI,IAAI,CAAC;IACf,OAAO,IAAI,IAAI,CAAC;IAChB,IAAI,IAAI,IAAI,CAAC;CACd,CAAC;AAkCF,wBAAgB,SAAS,CACvB,OAAO,EAAE,OAAO,EAChB,WAAW,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,EACzC,UAAU,EAAE,MAAM,MAAM,GACvB,SAAS,CA4FX"}
|
package/dist/reads.js
CHANGED
|
@@ -5,7 +5,7 @@ function declaredAs(declaration) {
|
|
|
5
5
|
return declared;
|
|
6
6
|
}
|
|
7
7
|
function sameHeld(one, other) {
|
|
8
|
-
return one
|
|
8
|
+
return one === other;
|
|
9
9
|
}
|
|
10
10
|
function failed(answer) {
|
|
11
11
|
return answer?.kind === 'transport-uncertainty';
|
|
@@ -20,7 +20,7 @@ export function doorReads(adapter, declaration, generation) {
|
|
|
20
20
|
let carrying = false;
|
|
21
21
|
function joined(read, authorization, request, ask) {
|
|
22
22
|
const key = `${read} ${request.locator} ${request.pageToken ?? ''}`;
|
|
23
|
-
const { held, ...named } = request;
|
|
23
|
+
const { held, received, ...named } = request;
|
|
24
24
|
const asked = JSON.stringify([declaredAs(declaration(request.locator)), named]);
|
|
25
25
|
const asking = generation();
|
|
26
26
|
const current = reading.get(key);
|
|
@@ -28,6 +28,7 @@ export function doorReads(adapter, declaration, generation) {
|
|
|
28
28
|
current.authorization === authorization &&
|
|
29
29
|
current.asked === asked &&
|
|
30
30
|
sameHeld(current.held, held) &&
|
|
31
|
+
current.received === received &&
|
|
31
32
|
(!current.settled || current.holder < asking)) {
|
|
32
33
|
if (current.settled && !current.continued)
|
|
33
34
|
reading.delete(key);
|
|
@@ -49,6 +50,7 @@ export function doorReads(adapter, declaration, generation) {
|
|
|
49
50
|
authorization,
|
|
50
51
|
asked,
|
|
51
52
|
held,
|
|
53
|
+
received,
|
|
52
54
|
answer,
|
|
53
55
|
from: asking,
|
|
54
56
|
holder: asking,
|
package/dist/recovery.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ export type AttemptOptions = {
|
|
|
8
8
|
};
|
|
9
9
|
export type RecoveryOptions = {
|
|
10
10
|
readonly firstMs?: number;
|
|
11
|
-
readonly
|
|
11
|
+
readonly maxMs?: number;
|
|
12
12
|
readonly attempts?: number;
|
|
13
13
|
readonly inFlight?: number;
|
|
14
14
|
};
|
|
@@ -20,6 +20,6 @@ export type Recovery = {
|
|
|
20
20
|
scope(inFlight?: number): Recovery;
|
|
21
21
|
retire(): Promise<void>;
|
|
22
22
|
};
|
|
23
|
-
export declare function retryDelay(tries: number, firstMs?: number,
|
|
23
|
+
export declare function retryDelay(tries: number, firstMs?: number, maxMs?: number): number;
|
|
24
24
|
export declare function createRecovery(options?: RecoveryOptions): Recovery;
|
|
25
25
|
//# sourceMappingURL=recovery.d.ts.map
|
package/dist/recovery.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"recovery.d.ts","sourceRoot":"","sources":["../src/recovery.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,OAAO,GAAG;IAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnE,MAAM,MAAM,OAAO,GAAG,CAAC,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC,SAAS,CAAC,CAAC;AAElE,MAAM,MAAM,cAAc,GAAG;IAAE,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAEhF,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,
|
|
1
|
+
{"version":3,"file":"recovery.d.ts","sourceRoot":"","sources":["../src/recovery.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,OAAO,GAAG;IAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnE,MAAM,MAAM,OAAO,GAAG,CAAC,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC,SAAS,CAAC,CAAC;AAElE,MAAM,MAAM,cAAc,GAAG;IAAE,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAEhF,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG;IACrB,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAClF,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;IACjC,MAAM,IAAI,IAAI,CAAC;IACf,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,KAAK,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC;IACnC,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACzB,CAAC;AAsBF,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,SAAW,EAAE,KAAK,SAAS,GAAG,MAAM,CAGpF;AAwKD,wBAAgB,cAAc,CAAC,OAAO,GAAE,eAAoB,GAAG,QAAQ,CAStE"}
|
package/dist/recovery.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
// A first retry waits about a second, so a passing failure clears before the next attempt.
|
|
2
2
|
const FIRST_MS = 1_000;
|
|
3
3
|
// Waits stop doubling at half a minute, so work resumes soon after a long failure ends.
|
|
4
|
-
const
|
|
4
|
+
const MAX_MS = 30_000;
|
|
5
5
|
const ATTEMPTS = 8;
|
|
6
|
-
export function retryDelay(tries, firstMs = FIRST_MS,
|
|
7
|
-
const
|
|
8
|
-
return
|
|
6
|
+
export function retryDelay(tries, firstMs = FIRST_MS, maxMs = MAX_MS) {
|
|
7
|
+
const longest = Math.min(maxMs, firstMs * 2 ** tries);
|
|
8
|
+
return longest / 2 + (Math.random() * longest) / 2;
|
|
9
9
|
}
|
|
10
10
|
function owner(backoff, inFlight, release = () => { }) {
|
|
11
11
|
const intents = new Map();
|
|
@@ -84,7 +84,8 @@ function owner(backoff, inFlight, release = () => { }) {
|
|
|
84
84
|
return;
|
|
85
85
|
}
|
|
86
86
|
if (result === 'again') {
|
|
87
|
-
|
|
87
|
+
// The next attempt waits the doubling backoff, up to its maximum.
|
|
88
|
+
const delay = retryDelay(intent.tries - 1, backoff.firstMs, backoff.maxMs);
|
|
88
89
|
wait(key, intent, Date.now() + delay, false);
|
|
89
90
|
}
|
|
90
91
|
else
|
|
@@ -135,7 +136,7 @@ function owner(backoff, inFlight, release = () => { }) {
|
|
|
135
136
|
wait(key, intent, options.at, true);
|
|
136
137
|
else if (options.again === true) {
|
|
137
138
|
intent.tries = 1;
|
|
138
|
-
wait(key, intent, Date.now() + retryDelay(0, backoff.firstMs, backoff.
|
|
139
|
+
wait(key, intent, Date.now() + retryDelay(0, backoff.firstMs, backoff.maxMs), false);
|
|
139
140
|
}
|
|
140
141
|
else
|
|
141
142
|
launch(key, intent);
|
|
@@ -191,7 +192,7 @@ function owner(backoff, inFlight, release = () => { }) {
|
|
|
191
192
|
export function createRecovery(options = {}) {
|
|
192
193
|
return owner({
|
|
193
194
|
firstMs: options.firstMs ?? FIRST_MS,
|
|
194
|
-
|
|
195
|
+
maxMs: options.maxMs ?? MAX_MS,
|
|
195
196
|
attempts: options.attempts ?? ATTEMPTS,
|
|
196
197
|
}, options.inFlight ?? Infinity);
|
|
197
198
|
}
|