@agentshouse/mdruntime 0.1.0-cfcbb238a5fa0 → 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 +229 -211
- package/README.md +9 -8
- package/dist/adapter.d.ts +69 -35
- 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 +13 -3
- 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 +24 -6
- package/dist/bootstrap.d.ts.map +1 -1
- package/dist/bootstrap.js +167 -82
- 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/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 +3 -1
- package/dist/chat/input.d.ts.map +1 -1
- package/dist/chat/input.js +11 -18
- package/dist/chat/list.d.ts +2 -1
- package/dist/chat/list.d.ts.map +1 -1
- package/dist/chat/list.js +45 -5
- package/dist/chat/markdown.d.ts +2 -2
- package/dist/chat/markdown.d.ts.map +1 -1
- package/dist/chat/markdown.js +80 -39
- package/dist/chat/message.d.ts +1 -0
- package/dist/chat/message.d.ts.map +1 -1
- package/dist/chat/message.js +73 -11
- package/dist/chat/messages.d.ts +14 -1
- package/dist/chat/messages.d.ts.map +1 -1
- package/dist/chat/messages.js +79 -24
- package/dist/chat/name.d.ts +1 -0
- package/dist/chat/name.d.ts.map +1 -1
- package/dist/chat/name.js +1 -1
- package/dist/chat/opened.d.ts +1 -0
- package/dist/chat/opened.d.ts.map +1 -1
- package/dist/chat/opened.js +2 -0
- package/dist/chat/overlay.d.ts +1 -0
- package/dist/chat/overlay.d.ts.map +1 -1
- package/dist/chat/overlay.js +11 -5
- package/dist/chat/parts.d.ts +1 -0
- package/dist/chat/parts.d.ts.map +1 -1
- package/dist/chat/parts.js +3 -2
- 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/provider.d.ts +8 -1
- package/dist/chat/provider.d.ts.map +1 -1
- package/dist/chat/provider.js +98 -92
- package/dist/chat/question.d.ts +1 -1
- package/dist/chat/question.d.ts.map +1 -1
- package/dist/chat/question.js +7 -18
- package/dist/chat/ready.d.ts +5 -2
- package/dist/chat/ready.d.ts.map +1 -1
- package/dist/chat/ready.js +7 -5
- 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.map +1 -1
- package/dist/chat/style.js +6 -1
- package/dist/chat.d.ts +3 -2
- package/dist/chat.d.ts.map +1 -1
- package/dist/chat.js +2 -2
- package/dist/client.d.ts +11 -4
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +35 -5
- package/dist/collection.d.ts +6 -19
- package/dist/collection.d.ts.map +1 -1
- package/dist/collection.js +30 -287
- 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 +19 -9
- package/dist/connection.d.ts.map +1 -1
- package/dist/connection.js +2392 -848
- package/dist/conversation.d.ts +14 -3
- package/dist/conversation.d.ts.map +1 -1
- package/dist/conversation.js +198 -89
- 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 -1
- package/dist/durability.d.ts.map +1 -1
- 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 +1 -4
- package/dist/host.d.ts.map +1 -1
- package/dist/host.js +21 -8
- 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 +11 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -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 +3 -2
- package/dist/memory.d.ts.map +1 -1
- package/dist/memory.js +30 -20
- package/dist/messages.d.ts +28 -0
- package/dist/messages.d.ts.map +1 -0
- package/dist/messages.js +90 -0
- 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 +158 -57
- 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 +18 -3
- package/dist/readiness.d.ts.map +1 -1
- package/dist/readiness.js +1 -1
- 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 +11 -13
- package/dist/refresh.d.ts.map +1 -1
- package/dist/refresh.js +78 -51
- package/dist/replica.d.ts +57 -33
- package/dist/replica.d.ts.map +1 -1
- package/dist/replica.js +295 -186
- package/dist/room-draft.d.ts +3 -1
- package/dist/room-draft.d.ts.map +1 -1
- package/dist/room-draft.js +29 -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 +97 -88
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +335 -659
- 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 +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 +10 -4
- package/dist/acquisition.d.ts +0 -14
- package/dist/acquisition.d.ts.map +0 -1
- package/dist/acquisition.js +0 -24
- 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,91 @@ 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
|
-
|
|
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
|
+
},
|
|
263
352
|
async write(room, path, revision, parts) {
|
|
264
|
-
|
|
353
|
+
const move = readParts(parts).move;
|
|
354
|
+
if (!covers(reach, room, path) || !moves(reach, room, move))
|
|
265
355
|
throw unreached(room);
|
|
266
|
-
|
|
356
|
+
if (runtime.locked(room))
|
|
357
|
+
throw lockedError(room);
|
|
358
|
+
if (intoLocked([move]))
|
|
359
|
+
throw lockedError(move.room);
|
|
267
360
|
return writeWithin(reach, await md.roomDraft.write(room, path, revision, parts));
|
|
268
361
|
},
|
|
269
362
|
async discard(room, path, revision) {
|
|
270
363
|
if (!covers(reach, room, path))
|
|
271
364
|
return staleWrite(null);
|
|
365
|
+
if (runtime.locked(room))
|
|
366
|
+
throw lockedError(room);
|
|
272
367
|
return writeWithin(reach, await md.roomDraft.discard(room, path, revision));
|
|
273
368
|
},
|
|
274
369
|
},
|
|
@@ -277,6 +372,11 @@ export function narrowed(runtime, given, told) {
|
|
|
277
372
|
read: (id, options) => conversation().read(id, options),
|
|
278
373
|
create: (input) => conversation().create(input),
|
|
279
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),
|
|
280
380
|
answer: (id, answer) => conversation().answer(id, answer),
|
|
281
381
|
interrupt: (id) => conversation().interrupt(id),
|
|
282
382
|
kill: (id) => conversation().kill(id),
|
|
@@ -285,6 +385,7 @@ export function narrowed(runtime, given, told) {
|
|
|
285
385
|
},
|
|
286
386
|
chatDraft: {
|
|
287
387
|
write: (id, draft, revision) => chatDraft().write(id, draft, revision),
|
|
388
|
+
prepend: (id, draft) => chatDraft().prepend(id, draft),
|
|
288
389
|
discard: (id) => chatDraft().discard(id),
|
|
289
390
|
},
|
|
290
391
|
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;
|
|
@@ -19,7 +19,7 @@ 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
21
|
export type CapacityCause = {
|
|
22
|
-
readonly cause: Open<'insufficient-space' | '
|
|
22
|
+
readonly cause: Open<'insufficient-space' | 'storage-exceeded'>;
|
|
23
23
|
readonly needed: number | null;
|
|
24
24
|
readonly available: number | null;
|
|
25
25
|
};
|
|
@@ -29,6 +29,20 @@ export type RefusedRoom = {
|
|
|
29
29
|
readonly rule: string;
|
|
30
30
|
readonly location: string | null;
|
|
31
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
|
+
};
|
|
32
46
|
export type ReadinessStatus = Open<'preparing' | 'paused' | 'refused' | 'ready' | 'lost'>;
|
|
33
47
|
export type Readiness = {
|
|
34
48
|
readonly status: ReadinessStatus;
|
|
@@ -41,6 +55,7 @@ export type Readiness = {
|
|
|
41
55
|
readonly connection: ConnectionAvailability;
|
|
42
56
|
readonly house: HouseOutcome;
|
|
43
57
|
readonly capacity: CapacityCause | null;
|
|
58
|
+
readonly installation: Installation;
|
|
44
59
|
readonly refused: readonly RefusedRoom[];
|
|
45
60
|
readonly lost: boolean;
|
|
46
61
|
};
|
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":"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"}
|
package/dist/readiness.js
CHANGED
|
@@ -15,7 +15,7 @@ export function readinessOf(facts) {
|
|
|
15
15
|
const usable = stored && (ready || established);
|
|
16
16
|
const status = ready
|
|
17
17
|
? 'ready'
|
|
18
|
-
: facts.capacity !== null
|
|
18
|
+
: facts.capacity !== null || facts.installation.paused !== null
|
|
19
19
|
? 'paused'
|
|
20
20
|
: facts.lost && !established
|
|
21
21
|
? 'lost'
|
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
|
}
|
package/dist/refresh.d.ts
CHANGED
|
@@ -1,24 +1,22 @@
|
|
|
1
1
|
import type { AdapterFailure, Authorization, RetryableRefusal } from './adapter.js';
|
|
2
2
|
import type { Reads, Remodel } from './bootstrap.js';
|
|
3
|
-
import {
|
|
4
|
-
import type {
|
|
5
|
-
import
|
|
3
|
+
import type { ReplicaRecord } from './replica.js';
|
|
4
|
+
import type { RefreshedPage } from './store.js';
|
|
5
|
+
import type { HeldEntry } from './tables.js';
|
|
6
|
+
import { type Unconfirmed } from './transfer.js';
|
|
6
7
|
export type Advancement = {
|
|
7
8
|
kind: 'still-current';
|
|
8
9
|
} | {
|
|
9
10
|
kind: 'advanced';
|
|
10
11
|
record: ReplicaRecord;
|
|
12
|
+
changed: ReadonlySet<string>;
|
|
11
13
|
} | {
|
|
12
14
|
kind: 'beyond-horizon';
|
|
13
15
|
} | RetryableRefusal | Unconfirmed | AdapterFailure;
|
|
14
|
-
export type
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
kind: 'beyond-horizon';
|
|
21
|
-
} | RetryableRefusal | Unconfirmed | Refused | AdapterFailure;
|
|
22
|
-
export declare function advancement(adapter: Reads, authorization: Authorization, held: ReplicaRecord, remodel: Remodel, continuing: () => boolean): Promise<Advancement>;
|
|
23
|
-
export declare function refreshRoom(adapter: Reads, authorization: Authorization, confirmed: ConfirmedLayer, remodel: Remodel, continuing: () => boolean): Promise<RefreshOutcome>;
|
|
16
|
+
export type Refreshing = {
|
|
17
|
+
turn(): Promise<void>;
|
|
18
|
+
prior(paths: readonly string[]): Promise<ReadonlyMap<string, HeldEntry>>;
|
|
19
|
+
stage(page: RefreshedPage): Promise<boolean>;
|
|
20
|
+
};
|
|
21
|
+
export declare function advancement(adapter: Reads, authorization: Authorization, held: ReplicaRecord, remodel: Remodel, continuing: () => boolean, staging: Refreshing): Promise<Advancement>;
|
|
24
22
|
//# sourceMappingURL=refresh.d.ts.map
|