@agentshouse/mdruntime 0.1.0-cd507e16e5fc0 → 0.1.0-cd574a610e9c8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -19
- package/dist/acceptance.d.ts +0 -3
- package/dist/acceptance.d.ts.map +1 -1
- package/dist/acceptance.js +75 -165
- package/dist/act-lanes.d.ts +30 -0
- package/dist/act-lanes.d.ts.map +1 -0
- package/dist/act-lanes.js +225 -0
- package/dist/actions.d.ts +8 -2
- package/dist/actions.d.ts.map +1 -1
- package/dist/actions.js +118 -67
- package/dist/adapter.d.ts +90 -58
- package/dist/adapter.d.ts.map +1 -1
- package/dist/attached-model.d.ts +0 -1
- package/dist/attached-model.d.ts.map +1 -1
- package/dist/attached-model.js +0 -5
- package/dist/authored.d.ts +88 -0
- package/dist/authored.d.ts.map +1 -0
- package/dist/authored.js +345 -0
- package/dist/bootstrap.d.ts +1 -1
- package/dist/bootstrap.d.ts.map +1 -1
- package/dist/bootstrap.js +6 -19
- package/dist/change-set.d.ts +4 -0
- package/dist/change-set.d.ts.map +1 -1
- package/dist/change-set.js +6 -0
- package/dist/change.d.ts +4 -0
- package/dist/change.d.ts.map +1 -1
- package/dist/change.js +7 -2
- package/dist/chat-types.d.ts +0 -2
- package/dist/chat-types.d.ts.map +1 -1
- package/dist/chat-types.js +0 -2
- package/dist/client.d.ts +13 -20
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +36 -20
- package/dist/collection.d.ts +25 -4
- package/dist/collection.d.ts.map +1 -1
- package/dist/collection.js +19 -2
- package/dist/column.d.ts +5 -0
- package/dist/column.d.ts.map +1 -0
- package/dist/column.js +9 -0
- package/dist/compile.d.ts +2 -0
- package/dist/compile.d.ts.map +1 -1
- package/dist/compile.js +31 -25
- package/dist/connection.d.ts.map +1 -1
- package/dist/connection.js +31 -24
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +1 -1
- package/dist/conversation-live.d.ts +26 -12
- package/dist/conversation-live.d.ts.map +1 -1
- package/dist/conversation-live.js +23 -12
- package/dist/conversation-row.d.ts +8 -1
- package/dist/conversation-row.d.ts.map +1 -1
- package/dist/conversation-row.js +20 -7
- package/dist/conversation.d.ts +37 -12
- package/dist/conversation.d.ts.map +1 -1
- package/dist/conversation.js +320 -234
- package/dist/declaration.d.ts +10 -0
- package/dist/declaration.d.ts.map +1 -0
- package/dist/declaration.js +24 -0
- package/dist/discovery.d.ts.map +1 -1
- package/dist/discovery.js +19 -44
- package/dist/durability.d.ts +4 -0
- package/dist/durability.d.ts.map +1 -1
- package/dist/durability.js +4 -0
- package/dist/entry.js +1 -1
- package/dist/expectation.d.ts +26 -13
- package/dist/expectation.d.ts.map +1 -1
- package/dist/expectation.js +72 -19
- package/dist/failure.d.ts +3 -0
- package/dist/failure.d.ts.map +1 -1
- package/dist/failure.js +6 -0
- package/dist/figures.d.ts.map +1 -1
- package/dist/figures.js +4 -2
- package/dist/file.d.ts +1 -1
- package/dist/file.d.ts.map +1 -1
- package/dist/file.js +3 -2
- package/dist/host.d.ts +18 -2
- package/dist/host.d.ts.map +1 -1
- package/dist/host.js +59 -15
- package/dist/index.d.ts +16 -11
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -7
- package/dist/install.d.ts +10 -6
- package/dist/install.d.ts.map +1 -1
- package/dist/install.js +92 -111
- package/dist/lifecycle.d.ts +1 -1
- package/dist/lifecycle.d.ts.map +1 -1
- package/dist/lifecycle.js +54 -40
- package/dist/listing.d.ts +11 -12
- package/dist/listing.d.ts.map +1 -1
- package/dist/listing.js +48 -72
- package/dist/live.d.ts +5 -3
- package/dist/live.d.ts.map +1 -1
- package/dist/live.js +74 -33
- package/dist/loaded.d.ts +5 -0
- package/dist/loaded.d.ts.map +1 -0
- package/dist/loaded.js +40 -0
- package/dist/locks.d.ts +2 -4
- package/dist/locks.d.ts.map +1 -1
- package/dist/locks.js +10 -39
- package/dist/lost.d.ts.map +1 -1
- package/dist/lost.js +11 -23
- package/dist/media.d.ts +6 -1
- package/dist/media.d.ts.map +1 -1
- package/dist/media.js +68 -17
- package/dist/memory.d.ts +8 -3
- package/dist/memory.d.ts.map +1 -1
- package/dist/memory.js +92 -33
- package/dist/messages.d.ts +12 -6
- package/dist/messages.d.ts.map +1 -1
- package/dist/messages.js +30 -38
- package/dist/model.d.ts +0 -1
- package/dist/model.d.ts.map +1 -1
- package/dist/model.js +0 -5
- package/dist/models.d.ts +4 -8
- package/dist/models.d.ts.map +1 -1
- package/dist/models.js +97 -139
- package/dist/observation.d.ts +27 -12
- package/dist/observation.d.ts.map +1 -1
- package/dist/observation.js +184 -85
- package/dist/opened.d.ts +1 -1
- package/dist/opened.d.ts.map +1 -1
- package/dist/opened.js +5 -5
- package/dist/opening.d.ts.map +1 -1
- package/dist/opening.js +5 -9
- package/dist/outcome.d.ts +13 -1
- package/dist/outcome.d.ts.map +1 -1
- package/dist/outcome.js +32 -2
- package/dist/overlay.d.ts +6 -2
- package/dist/overlay.d.ts.map +1 -1
- package/dist/overlay.js +37 -24
- package/dist/page-metadata.d.ts +8 -0
- package/dist/page-metadata.d.ts.map +1 -0
- package/dist/page-metadata.js +19 -0
- package/dist/parts.d.ts +3 -58
- package/dist/parts.d.ts.map +1 -1
- package/dist/parts.js +10 -115
- package/dist/preparation.d.ts +27 -6
- package/dist/preparation.d.ts.map +1 -1
- package/dist/preparation.js +156 -68
- package/dist/presence.d.ts +58 -0
- package/dist/presence.d.ts.map +1 -0
- package/dist/presence.js +231 -0
- package/dist/queries.d.ts +2 -2
- package/dist/queries.d.ts.map +1 -1
- package/dist/queries.js +67 -31
- package/dist/query.d.ts +0 -1
- package/dist/query.d.ts.map +1 -1
- package/dist/questions.d.ts +1 -5
- package/dist/questions.d.ts.map +1 -1
- package/dist/questions.js +1 -7
- package/dist/queue.d.ts +40 -0
- package/dist/queue.d.ts.map +1 -0
- package/dist/queue.js +480 -0
- package/dist/reach.d.ts +2 -3
- package/dist/reach.d.ts.map +1 -1
- package/dist/reach.js +88 -26
- package/dist/react.d.ts +8 -1
- package/dist/react.d.ts.map +1 -1
- package/dist/react.js +33 -1
- package/dist/readiness.d.ts +9 -3
- package/dist/readiness.d.ts.map +1 -1
- package/dist/readiness.js +3 -5
- package/dist/reads.d.ts +4 -2
- package/dist/reads.d.ts.map +1 -1
- package/dist/reads.js +11 -4
- package/dist/recovery.d.ts +3 -1
- package/dist/recovery.d.ts.map +1 -1
- package/dist/recovery.js +29 -7
- package/dist/refresh.js +2 -2
- package/dist/refusal.d.ts.map +1 -1
- package/dist/refusal.js +5 -6
- package/dist/replica.d.ts +5 -11
- package/dist/replica.d.ts.map +1 -1
- package/dist/replica.js +15 -17
- package/dist/retried.d.ts +30 -0
- package/dist/retried.d.ts.map +1 -0
- package/dist/retried.js +72 -0
- package/dist/room-draft.d.ts +31 -8
- package/dist/room-draft.d.ts.map +1 -1
- package/dist/room-draft.js +273 -66
- package/dist/room-drafts.d.ts.map +1 -1
- package/dist/room-drafts.js +22 -18
- package/dist/room-list.d.ts +10 -0
- package/dist/room-list.d.ts.map +1 -0
- package/dist/room-list.js +45 -0
- package/dist/rows.d.ts +2 -1
- package/dist/rows.d.ts.map +1 -1
- package/dist/rows.js +9 -10
- package/dist/runtime.d.ts +9 -18
- package/dist/runtime.d.ts.map +1 -1
- package/dist/save.d.ts +42 -90
- package/dist/save.d.ts.map +1 -1
- package/dist/save.js +327 -229
- package/dist/saves.d.ts +4 -40
- package/dist/saves.d.ts.map +1 -1
- package/dist/saves.js +143 -714
- package/dist/seed.d.ts.map +1 -1
- package/dist/seed.js +4 -5
- package/dist/shared.d.ts +0 -5
- package/dist/shared.d.ts.map +1 -1
- package/dist/shared.js +4 -90
- package/dist/shown.d.ts +7 -5
- package/dist/shown.d.ts.map +1 -1
- package/dist/shown.js +77 -63
- package/dist/socket/lanes.d.ts +12 -4
- package/dist/socket/lanes.d.ts.map +1 -1
- package/dist/socket/lanes.js +34 -8
- package/dist/socket/session.d.ts +0 -1
- package/dist/socket/session.d.ts.map +1 -1
- package/dist/socket.d.ts +3 -6
- package/dist/socket.d.ts.map +1 -1
- package/dist/socket.js +5 -16
- package/dist/source.d.ts +5 -7
- package/dist/source.d.ts.map +1 -1
- package/dist/source.js +18 -6
- package/dist/store/installs.d.ts +2 -2
- package/dist/store/installs.d.ts.map +1 -1
- package/dist/store/installs.js +10 -4
- package/dist/store/readiness.d.ts +5 -4
- package/dist/store/readiness.d.ts.map +1 -1
- package/dist/store/readiness.js +28 -12
- package/dist/store/records.d.ts +18 -7
- package/dist/store/records.d.ts.map +1 -1
- package/dist/store/records.js +58 -24
- package/dist/store/rooms-shown.d.ts +8 -0
- package/dist/store/rooms-shown.d.ts.map +1 -0
- package/dist/store/rooms-shown.js +13 -0
- package/dist/store/space.d.ts +1 -1
- package/dist/store/space.d.ts.map +1 -1
- package/dist/store/space.js +0 -2
- package/dist/store/watchers.js +1 -2
- package/dist/store.d.ts +23 -14
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +46 -17
- package/dist/stored.d.ts +25 -14
- package/dist/stored.d.ts.map +1 -1
- package/dist/stored.js +83 -32
- package/dist/surface.d.ts +5 -3
- package/dist/surface.d.ts.map +1 -1
- package/dist/surface.js +25 -23
- package/dist/sync.d.ts +1 -1
- package/dist/sync.d.ts.map +1 -1
- package/dist/sync.js +96 -92
- package/dist/tables.d.ts +16 -57
- package/dist/tables.d.ts.map +1 -1
- package/dist/tables.js +91 -332
- package/dist/tallies.d.ts.map +1 -1
- package/dist/tallies.js +6 -7
- package/dist/validation.d.ts.map +1 -1
- package/dist/validation.js +4 -10
- package/dist/wire.d.ts +53 -7
- package/dist/wire.d.ts.map +1 -1
- package/dist/wire.js +17 -4
- package/package.json +3 -2
- package/dist/attempt.d.ts +0 -16
- package/dist/attempt.d.ts.map +0 -1
- package/dist/attempt.js +0 -70
- package/dist/job.d.ts +0 -33
- package/dist/job.d.ts.map +0 -1
- package/dist/job.js +0 -54
- package/dist/log.d.ts +0 -6
- package/dist/log.d.ts.map +0 -1
- package/dist/log.js +0 -14
- package/dist/socket/rooms.d.ts +0 -44
- package/dist/socket/rooms.d.ts.map +0 -1
- package/dist/socket/rooms.js +0 -90
- package/dist/store/fences.d.ts +0 -16
- package/dist/store/fences.d.ts.map +0 -1
- package/dist/store/fences.js +0 -26
package/dist/preparation.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { changeSet } from './change-set.js';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { uncaught } from './failure.js';
|
|
3
|
+
import { installationOf, installShare } from './install.js';
|
|
4
|
+
import { listedLocators, listedOrHeld } from './listing.js';
|
|
5
|
+
import { keyedAt, keyedChange, unchanged, } from './observation.js';
|
|
4
6
|
import { planReach } from './reach.js';
|
|
5
|
-
import { readinessOf, } from './readiness.js';
|
|
6
|
-
import {
|
|
7
|
+
import { COMPLETE_ROOMS, readinessOf, } from './readiness.js';
|
|
8
|
+
import { roomsOfReach } from './rows.js';
|
|
7
9
|
import { recoverReads } from './shown.js';
|
|
8
10
|
import { yielded } from './turn.js';
|
|
9
11
|
async function prepareReplica(runtime, locator) {
|
|
@@ -22,22 +24,23 @@ async function prepareReplica(runtime, locator) {
|
|
|
22
24
|
if ((await store.rooms([locator])).get(locator)?.record.key !== key)
|
|
23
25
|
continue;
|
|
24
26
|
store.changed(changeSet(locator, { documents: null }));
|
|
25
|
-
recoverReads(runtime);
|
|
26
|
-
store.readiness.queue();
|
|
27
|
+
recoverReads(runtime, [locator]);
|
|
28
|
+
store.readiness.queue([locator]);
|
|
27
29
|
return;
|
|
28
30
|
}
|
|
29
31
|
}
|
|
30
|
-
async function unprepared({ store
|
|
32
|
+
async function unprepared({ store }) {
|
|
31
33
|
const held = (await store.covering()).rooms;
|
|
32
|
-
|
|
34
|
+
const { unpreparedDemand, unpreparable } = store.device.now();
|
|
35
|
+
return [...unpreparedDemand, ...held.keys()].find((locator) => !(held.get(locator)?.indexed ?? false) && !unpreparable.has(locator));
|
|
33
36
|
}
|
|
34
|
-
function unpreparedBy({ store
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
store.readiness.queue();
|
|
37
|
+
function unpreparedBy({ store }, locator) {
|
|
38
|
+
const { unpreparable } = store.device.now();
|
|
39
|
+
store.device.set({ unpreparable: new Set([...unpreparable, locator]) });
|
|
40
|
+
store.readiness.queue([locator]);
|
|
38
41
|
}
|
|
39
42
|
export function prepare(runtime, locators = []) {
|
|
40
|
-
const { store, socket
|
|
43
|
+
const { store, socket } = runtime;
|
|
41
44
|
const { device } = store;
|
|
42
45
|
if (locators.length > 0) {
|
|
43
46
|
device.set({ unpreparedDemand: new Set([...device.now().unpreparedDemand, ...locators]) });
|
|
@@ -54,37 +57,31 @@ export function prepare(runtime, locators = []) {
|
|
|
54
57
|
const demand = new Set(device.now().unpreparedDemand);
|
|
55
58
|
demand.delete(waiting);
|
|
56
59
|
device.set({ unpreparedDemand: demand });
|
|
57
|
-
await prepareReplica(runtime, waiting).catch((
|
|
60
|
+
await prepareReplica(runtime, waiting).catch(() => unpreparedBy(runtime, waiting));
|
|
58
61
|
}
|
|
59
62
|
}
|
|
60
|
-
catch {
|
|
61
|
-
|
|
63
|
+
catch (error) {
|
|
64
|
+
uncaught(error);
|
|
62
65
|
}
|
|
63
66
|
finally {
|
|
64
67
|
device.set({ preparing: false });
|
|
65
68
|
}
|
|
66
69
|
})();
|
|
67
70
|
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
return { listed: named.every((room) => held.has(room)), rooms: named };
|
|
81
|
-
}
|
|
82
|
-
function roomState({ socket }, locator, held) {
|
|
83
|
-
const listedRoom = socket.rooms.discovered(locator);
|
|
71
|
+
function requires(runtime, named, held, room) {
|
|
72
|
+
const listed = listedOrHeld(runtime, held, room);
|
|
73
|
+
if (named === null)
|
|
74
|
+
return listed;
|
|
75
|
+
return named.has(room) && (!runtime.socket.session.now().roomsListed || listed);
|
|
76
|
+
}
|
|
77
|
+
function requiredRooms(runtime, named, held) {
|
|
78
|
+
return [...(named ?? listedLocators(runtime, held))]
|
|
79
|
+
.filter((room) => requires(runtime, named, held, room))
|
|
80
|
+
.sort();
|
|
81
|
+
}
|
|
82
|
+
function roomState({ socket, presence }, locator, held) {
|
|
84
83
|
if (socket.session.now().roomsListed &&
|
|
85
|
-
(
|
|
86
|
-
listedRoom.replica.admission !== 'admitted' ||
|
|
87
|
-
socket.rooms.standing(locator).unreadable))
|
|
84
|
+
(presence.room(locator) === undefined || !presence.available(locator)))
|
|
88
85
|
return 'unadmitted';
|
|
89
86
|
const stored = held.get(locator);
|
|
90
87
|
if (stored === undefined)
|
|
@@ -113,28 +110,89 @@ export async function connectionNow(runtime) {
|
|
|
113
110
|
if (socket.isOpen() || socket.session.now().moving.providerUnreachable || socket.streamed) {
|
|
114
111
|
return connectionOf(runtime, null);
|
|
115
112
|
}
|
|
116
|
-
return connectionOf(runtime, (await (await store.open()).facts()).lastCompleted);
|
|
113
|
+
return connectionOf(runtime, (await (await store.open()).facts(['lastCompleted'])).lastCompleted);
|
|
117
114
|
}
|
|
118
115
|
async function readinessHeld({ store }) {
|
|
119
116
|
const local = await store.open();
|
|
120
|
-
const [held, facts] = await Promise.all([
|
|
117
|
+
const [held, facts] = await Promise.all([
|
|
118
|
+
store.covering(),
|
|
119
|
+
local.facts(['lastCompleted', 'targets']),
|
|
120
|
+
]);
|
|
121
121
|
return { held: held.rooms, facts };
|
|
122
122
|
}
|
|
123
|
-
function
|
|
124
|
-
const {
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
123
|
+
function shareOf(runtime, room, held) {
|
|
124
|
+
const coverage = Object.freeze({ room, state: roomState(runtime, room, held) });
|
|
125
|
+
return { ...installShare(runtime.store, coverage, held), coverage };
|
|
126
|
+
}
|
|
127
|
+
function sameState(was, now) {
|
|
128
|
+
return was.coverage.state === now.coverage.state;
|
|
129
|
+
}
|
|
130
|
+
function coverageOf(change) {
|
|
131
|
+
return {
|
|
132
|
+
...change,
|
|
133
|
+
changed: change.changed.map(([room, share]) => [room, share.coverage]),
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
function counted(totals, share, sign) {
|
|
137
|
+
const { state } = share.coverage;
|
|
138
|
+
totals.installing += share.installing ? sign : 0;
|
|
139
|
+
totals.downloading += share.downloading ? sign : 0;
|
|
140
|
+
totals.acquiring += state === 'acquiring' ? sign : 0;
|
|
141
|
+
totals.unsettled += COMPLETE_ROOMS.has(state) ? 0 : sign;
|
|
142
|
+
totals.done += sign * share.bytes.done;
|
|
143
|
+
totals.total += sign * share.bytes.total;
|
|
144
|
+
}
|
|
145
|
+
function showingOf(runtime, reach, held) {
|
|
146
|
+
const planned = planReach(reach);
|
|
147
|
+
const named = planned === null ? null : roomsOfReach(planned);
|
|
148
|
+
const totals = { installing: 0, downloading: 0, acquiring: 0, unsettled: 0, done: 0, total: 0 };
|
|
149
|
+
const rooms = new Map();
|
|
150
|
+
for (const room of requiredRooms(runtime, named, held)) {
|
|
151
|
+
const share = shareOf(runtime, room, held);
|
|
152
|
+
rooms.set(room, share);
|
|
153
|
+
counted(totals, share, 1);
|
|
154
|
+
}
|
|
155
|
+
return {
|
|
156
|
+
listing: runtime.presence.listing(),
|
|
157
|
+
roomsListed: runtime.socket.session.now().roomsListed,
|
|
158
|
+
named,
|
|
159
|
+
rooms,
|
|
160
|
+
totals,
|
|
161
|
+
shown: '',
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
function moved(runtime, showing, held, touched) {
|
|
165
|
+
const at = new Map();
|
|
166
|
+
for (const room of touched) {
|
|
167
|
+
at.set(room, requires(runtime, showing.named, held, room) ? shareOf(runtime, room, held) : null);
|
|
168
|
+
}
|
|
169
|
+
const change = keyedAt(showing.rooms, at, sameState);
|
|
170
|
+
if (change === null || change.removed.length > 0)
|
|
171
|
+
return null;
|
|
172
|
+
for (const [room, share] of at) {
|
|
173
|
+
if (share === null)
|
|
174
|
+
continue;
|
|
175
|
+
counted(showing.totals, showing.rooms.get(room), -1);
|
|
176
|
+
counted(showing.totals, share, 1);
|
|
177
|
+
showing.rooms.set(room, share);
|
|
178
|
+
}
|
|
179
|
+
return change;
|
|
180
|
+
}
|
|
181
|
+
function preparingIn(runtime, showing, rooms) {
|
|
182
|
+
const { unpreparable } = runtime.store.device.now();
|
|
183
|
+
const preparing = [...rooms].filter((room) => showing.rooms.get(room)?.coverage.state === 'preparing' && !unpreparable.has(room));
|
|
130
184
|
if (preparing.length > 0)
|
|
131
185
|
prepare(runtime, preparing);
|
|
186
|
+
}
|
|
187
|
+
function shownOf(runtime, { port, reach }, { named, totals }, { facts }) {
|
|
188
|
+
const { store, socket, usableWhenHeld } = runtime;
|
|
132
189
|
const { persistence, storageLoss, heldWhenOpened } = store.device.now();
|
|
190
|
+
const { roomsListed } = socket.session.now();
|
|
133
191
|
return readinessOf({
|
|
134
192
|
code: port.code,
|
|
135
193
|
coverage: {
|
|
136
|
-
listed:
|
|
137
|
-
|
|
194
|
+
listed: named === null ? roomsListed : roomsListed || totals.acquiring === 0,
|
|
195
|
+
unsettled: totals.unsettled,
|
|
138
196
|
conversations: conversationCoverage(runtime, reach),
|
|
139
197
|
},
|
|
140
198
|
persistence,
|
|
@@ -145,52 +203,79 @@ function readinessFor(runtime, port, reach, { held, facts }) {
|
|
|
145
203
|
? 'write-halted'
|
|
146
204
|
: 'open',
|
|
147
205
|
space: store.space.full() ? 'full' : null,
|
|
148
|
-
installation: installationOf(
|
|
206
|
+
installation: installationOf(totals.installing, totals.downloading, {
|
|
207
|
+
done: totals.done,
|
|
208
|
+
total: totals.total,
|
|
209
|
+
}),
|
|
149
210
|
lost: storageLoss !== null,
|
|
150
211
|
established: facts.targets[port.target]?.established === true ||
|
|
151
212
|
(heldWhenOpened && usableWhenHeld.includes(port.target)),
|
|
152
213
|
});
|
|
153
214
|
}
|
|
154
215
|
function establish(runtime, name) {
|
|
155
|
-
const { store
|
|
216
|
+
const { store } = runtime;
|
|
156
217
|
const { device } = store;
|
|
157
218
|
if (device.now().establishing.has(name))
|
|
158
219
|
return;
|
|
159
220
|
device.set({ establishing: new Set([...device.now().establishing, name]) });
|
|
160
221
|
void store
|
|
161
222
|
.durably(async (local) => {
|
|
162
|
-
const { targets } = await local.facts();
|
|
223
|
+
const { targets } = await local.facts(['targets']);
|
|
163
224
|
await local.fact('targets', { ...targets, [name]: { established: true } });
|
|
164
225
|
})
|
|
165
226
|
.then(() => {
|
|
166
|
-
store.readiness.queue();
|
|
227
|
+
store.readiness.queue([]);
|
|
167
228
|
void probeEachMinute(runtime);
|
|
168
|
-
},
|
|
169
|
-
journal.record(`target record failed ${name}`);
|
|
170
|
-
})
|
|
229
|
+
}, uncaught)
|
|
171
230
|
.finally(() => {
|
|
172
231
|
const establishing = new Set(device.now().establishing);
|
|
173
232
|
establishing.delete(name);
|
|
174
233
|
device.set({ establishing });
|
|
175
234
|
});
|
|
176
235
|
}
|
|
177
|
-
function deliverReadiness(runtime, watch, held) {
|
|
178
|
-
|
|
236
|
+
function deliverReadiness(runtime, watch, held, touched) {
|
|
237
|
+
const { readiness } = runtime.store;
|
|
238
|
+
if (!readiness.held(watch))
|
|
179
239
|
return;
|
|
180
|
-
const
|
|
181
|
-
|
|
240
|
+
const kept = readiness.kept(watch);
|
|
241
|
+
const patched = kept === undefined ||
|
|
242
|
+
touched === null ||
|
|
243
|
+
kept.listing !== runtime.presence.listing() ||
|
|
244
|
+
kept.roomsListed !== runtime.socket.session.now().roomsListed
|
|
245
|
+
? null
|
|
246
|
+
: moved(runtime, kept, held.held, touched);
|
|
247
|
+
const showing = patched === null ? showingOf(runtime, watch.reach, held.held) : kept;
|
|
248
|
+
preparingIn(runtime, showing, patched === null ? showing.rooms.keys() : touched);
|
|
249
|
+
const shown = shownOf(runtime, watch, showing, held);
|
|
250
|
+
if (shown.ready && held.facts.targets[watch.port.target]?.established !== true) {
|
|
182
251
|
establish(runtime, watch.port.target);
|
|
183
252
|
}
|
|
184
|
-
|
|
253
|
+
const text = JSON.stringify(shown);
|
|
254
|
+
const before = kept?.shown;
|
|
255
|
+
showing.shown = text;
|
|
256
|
+
readiness.keep(watch, showing);
|
|
257
|
+
if (kept === undefined) {
|
|
258
|
+
watch.deliver({
|
|
259
|
+
...shown,
|
|
260
|
+
coverage: {
|
|
261
|
+
...shown.coverage,
|
|
262
|
+
rooms: [...showing.rooms.values()].map(({ coverage }) => coverage),
|
|
263
|
+
},
|
|
264
|
+
});
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
const rooms = coverageOf(patched ??
|
|
268
|
+
keyedChange(kept.rooms, [...showing.rooms.keys()], [...showing.rooms.values()], sameState));
|
|
269
|
+
if (text === before && unchanged(rooms))
|
|
185
270
|
return;
|
|
186
|
-
watch.deliver(
|
|
271
|
+
watch.deliver({ shown, rooms });
|
|
187
272
|
}
|
|
188
|
-
export async function deliverOwedReadiness(runtime, owed) {
|
|
273
|
+
export async function deliverOwedReadiness(runtime, owed, touched) {
|
|
189
274
|
const held = await readinessHeld(runtime);
|
|
190
275
|
if (runtime.socket.closed())
|
|
191
276
|
return;
|
|
192
277
|
for (const watch of owed)
|
|
193
|
-
deliverReadiness(runtime, watch, held);
|
|
278
|
+
deliverReadiness(runtime, watch, held, touched);
|
|
194
279
|
}
|
|
195
280
|
export function watchReadiness({ store }, port, reach, deliver) {
|
|
196
281
|
const watch = { port, reach, deliver };
|
|
@@ -199,17 +284,16 @@ export function watchReadiness({ store }, port, reach, deliver) {
|
|
|
199
284
|
return stop;
|
|
200
285
|
}
|
|
201
286
|
export function filled(runtime) {
|
|
202
|
-
const { store, socket
|
|
287
|
+
const { store, socket } = runtime;
|
|
203
288
|
if (socket.closed() || !store.space.fill())
|
|
204
289
|
return;
|
|
205
|
-
|
|
206
|
-
store.readiness.queue();
|
|
290
|
+
store.readiness.queue([]);
|
|
207
291
|
void probeEachMinute(runtime);
|
|
208
292
|
}
|
|
209
|
-
async function installedTarget({ store
|
|
210
|
-
if (store.device.now().heldWhenOpened
|
|
293
|
+
async function installedTarget({ store }) {
|
|
294
|
+
if (store.device.now().heldWhenOpened)
|
|
211
295
|
return true;
|
|
212
|
-
const { targets } = await (await store.open()).facts();
|
|
296
|
+
const { targets } = await (await store.open()).facts(['targets']);
|
|
213
297
|
return Object.values(targets).some((target) => target.established);
|
|
214
298
|
}
|
|
215
299
|
async function probeEachMinute(runtime) {
|
|
@@ -218,7 +302,11 @@ async function probeEachMinute(runtime) {
|
|
|
218
302
|
const idle = () => !space.full() || space.probing() || socket.closed();
|
|
219
303
|
if (idle())
|
|
220
304
|
return;
|
|
221
|
-
|
|
305
|
+
const installed = await installedTarget(runtime).catch((error) => {
|
|
306
|
+
uncaught(error);
|
|
307
|
+
return false;
|
|
308
|
+
});
|
|
309
|
+
if (!installed)
|
|
222
310
|
return;
|
|
223
311
|
if (idle())
|
|
224
312
|
return;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { DiscoveredRoom, ProviderRefusal, ScopedRefusal } from './adapter.js';
|
|
2
|
+
import type { ModelState } from './model.js';
|
|
3
|
+
type Repairable = {
|
|
4
|
+
readonly reset: string | undefined;
|
|
5
|
+
};
|
|
6
|
+
type Standing = {
|
|
7
|
+
readonly stale: boolean;
|
|
8
|
+
readonly repairable: Repairable | null;
|
|
9
|
+
readonly repairing: boolean;
|
|
10
|
+
readonly reloadDue: boolean;
|
|
11
|
+
};
|
|
12
|
+
export declare function lockingMode(mode: string | undefined): boolean;
|
|
13
|
+
type Listing = {
|
|
14
|
+
readonly whole: boolean;
|
|
15
|
+
readonly live: boolean;
|
|
16
|
+
};
|
|
17
|
+
export type Presence = {
|
|
18
|
+
list(found: readonly DiscoveredRoom[], how: Listing): readonly DiscoveredRoom[];
|
|
19
|
+
room(locator: string): DiscoveredRoom | undefined;
|
|
20
|
+
rooms(): readonly DiscoveredRoom[];
|
|
21
|
+
available(locator: string, selection?: string): boolean;
|
|
22
|
+
refusal(locator: string): ProviderRefusal | null;
|
|
23
|
+
unheldModel(locator: string): ModelState | null;
|
|
24
|
+
refused(locator: string, refusal: ScopedRefusal | null): void;
|
|
25
|
+
readable(locator: string): boolean;
|
|
26
|
+
modelled(locator: string, model: ModelState | null): void;
|
|
27
|
+
installed(locator: string, bootstrapped: boolean): void;
|
|
28
|
+
locked(locator: string, stored: () => Promise<string | null>): Promise<boolean>;
|
|
29
|
+
lockedAmong(stored: ReadonlyMap<string, {
|
|
30
|
+
readonly offline: string;
|
|
31
|
+
}>, locking: ReadonlySet<string>): readonly string[];
|
|
32
|
+
lockedAs(locator: string, mode: string | undefined): boolean;
|
|
33
|
+
connectionLost(lapsed: () => void): void;
|
|
34
|
+
connectionLive(): void;
|
|
35
|
+
lapse(): void;
|
|
36
|
+
stood(locator: string, stale: boolean, repairable?: Repairable | null): void;
|
|
37
|
+
repairing(locator: string, running: boolean): void;
|
|
38
|
+
reload(locator: string, due: boolean): void;
|
|
39
|
+
standing(locator: string): Standing;
|
|
40
|
+
settled(): boolean;
|
|
41
|
+
repairsOwed(): readonly string[];
|
|
42
|
+
askAgain(locator: string, ask: () => void): void;
|
|
43
|
+
stopAsking(locator?: string): void;
|
|
44
|
+
lose(locator: string, during: number): boolean;
|
|
45
|
+
writing(locator: string): boolean;
|
|
46
|
+
unwritten(locator: string): void;
|
|
47
|
+
lost(locator: string): boolean;
|
|
48
|
+
losing(): boolean;
|
|
49
|
+
listing(): number;
|
|
50
|
+
losses(): number;
|
|
51
|
+
lostSince(locator: string, losses: number): boolean;
|
|
52
|
+
liftable(locator: string, discovery: number): boolean;
|
|
53
|
+
lift(locator: string, discovery: number, unfenced: boolean): void;
|
|
54
|
+
close(): void;
|
|
55
|
+
};
|
|
56
|
+
export declare function createPresence(notReadyWaitMs: (asked: number) => number): Presence;
|
|
57
|
+
export {};
|
|
58
|
+
//# sourceMappingURL=presence.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"presence.d.ts","sourceRoot":"","sources":["../src/presence.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AACnF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,KAAK,UAAU,GAAG;IAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,CAAC;AAEzD,KAAK,QAAQ,GAAG;IACd,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,UAAU,EAAE,UAAU,GAAG,IAAI,CAAC;IACvC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;CAC7B,CAAC;AAUF,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAE7D;AAgBD,KAAK,OAAO,GAAG;IAAE,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;CAAE,CAAC;AAEnE,MAAM,MAAM,QAAQ,GAAG;IACrB,IAAI,CAAC,KAAK,EAAE,SAAS,cAAc,EAAE,EAAE,GAAG,EAAE,OAAO,GAAG,SAAS,cAAc,EAAE,CAAC;IAChF,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAAC;IAClD,KAAK,IAAI,SAAS,cAAc,EAAE,CAAC;IACnC,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACxD,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,CAAC;IACjD,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAAC;IAChD,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,GAAG,IAAI,GAAG,IAAI,CAAC;IAC9D,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;IACnC,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,IAAI,GAAG,IAAI,CAAC;IAC1D,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,OAAO,GAAG,IAAI,CAAC;IACxD,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAChF,WAAW,CACT,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE;QAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,EACzD,OAAO,EAAE,WAAW,CAAC,MAAM,CAAC,GAC3B,SAAS,MAAM,EAAE,CAAC;IACrB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC;IAC7D,cAAc,CAAC,MAAM,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;IACzC,cAAc,IAAI,IAAI,CAAC;IACvB,KAAK,IAAI,IAAI,CAAC;IACd,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,UAAU,CAAC,EAAE,UAAU,GAAG,IAAI,GAAG,IAAI,CAAC;IAC7E,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IACnD,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,GAAG,IAAI,CAAC;IAC5C,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,QAAQ,CAAC;IACpC,OAAO,IAAI,OAAO,CAAC;IACnB,WAAW,IAAI,SAAS,MAAM,EAAE,CAAC;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;IACjD,UAAU,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;IAC/C,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;IAClC,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;IAC/B,MAAM,IAAI,OAAO,CAAC;IAClB,OAAO,IAAI,MAAM,CAAC;IAClB,MAAM,IAAI,MAAM,CAAC;IACjB,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;IACpD,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC;IACtD,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,GAAG,IAAI,CAAC;IAClE,KAAK,IAAI,IAAI,CAAC;CACf,CAAC;AAKF,wBAAgB,cAAc,CAAC,cAAc,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,QAAQ,CAqNlF"}
|
package/dist/presence.js
ADDED
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
export function lockingMode(mode) {
|
|
2
|
+
return mode === 'locked';
|
|
3
|
+
}
|
|
4
|
+
const UNANSWERED = {
|
|
5
|
+
stale: false,
|
|
6
|
+
repairable: null,
|
|
7
|
+
repairing: false,
|
|
8
|
+
reloadDue: false,
|
|
9
|
+
refusal: null,
|
|
10
|
+
unreading: false,
|
|
11
|
+
unreadable: false,
|
|
12
|
+
unheldModel: null,
|
|
13
|
+
confirmed: false,
|
|
14
|
+
};
|
|
15
|
+
// A Room that locks offline stays readable this long after the connection drops, so a laptop waking or changing network keeps working while a disconnected device locks soon after.
|
|
16
|
+
const LOCK_GRACE_MS = 120_000;
|
|
17
|
+
export function createPresence(notReadyWaitMs) {
|
|
18
|
+
const listed = new Map();
|
|
19
|
+
const lockable = new Set();
|
|
20
|
+
let listings = 0;
|
|
21
|
+
const answered = new Map();
|
|
22
|
+
const marks = new Map();
|
|
23
|
+
const lastLost = new Map();
|
|
24
|
+
const unready = new Map();
|
|
25
|
+
let lossCount = 0;
|
|
26
|
+
let lockGrace = null;
|
|
27
|
+
function answer(locator) {
|
|
28
|
+
return answered.get(locator) ?? UNANSWERED;
|
|
29
|
+
}
|
|
30
|
+
function change(locator, next) {
|
|
31
|
+
answered.set(locator, { ...answer(locator), ...next });
|
|
32
|
+
}
|
|
33
|
+
function heard(locator, next) {
|
|
34
|
+
if (!marks.has(locator))
|
|
35
|
+
change(locator, next);
|
|
36
|
+
}
|
|
37
|
+
function readied(locator) {
|
|
38
|
+
const held = unready.get(locator);
|
|
39
|
+
if (held === undefined)
|
|
40
|
+
return;
|
|
41
|
+
if (held.timer !== null)
|
|
42
|
+
clearTimeout(held.timer);
|
|
43
|
+
unready.delete(locator);
|
|
44
|
+
}
|
|
45
|
+
function stopAsking(locator) {
|
|
46
|
+
for (const held of locator === undefined ? [...unready.keys()] : [locator])
|
|
47
|
+
readied(held);
|
|
48
|
+
}
|
|
49
|
+
function connectionLive() {
|
|
50
|
+
if (lockGrace !== null)
|
|
51
|
+
clearTimeout(lockGrace);
|
|
52
|
+
lockGrace = null;
|
|
53
|
+
}
|
|
54
|
+
function readable(locator) {
|
|
55
|
+
const { unreadable, unreading } = answer(locator);
|
|
56
|
+
if (!unreadable || marks.has(locator))
|
|
57
|
+
return false;
|
|
58
|
+
change(locator, {
|
|
59
|
+
unreadable: false,
|
|
60
|
+
...(unreading ? { refusal: null, unreading: false } : {}),
|
|
61
|
+
});
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
function locks(locator, mode) {
|
|
65
|
+
return lockingMode(mode) && !answer(locator).confirmed && !marks.has(locator);
|
|
66
|
+
}
|
|
67
|
+
function liftable(locator, discovery) {
|
|
68
|
+
const mark = marks.get(locator);
|
|
69
|
+
return mark === undefined || mark.during < discovery;
|
|
70
|
+
}
|
|
71
|
+
return {
|
|
72
|
+
list(found, { whole, live }) {
|
|
73
|
+
listings += 1;
|
|
74
|
+
const kept = found.filter(({ locator }) => !marks.has(locator));
|
|
75
|
+
if (whole) {
|
|
76
|
+
listed.clear();
|
|
77
|
+
lockable.clear();
|
|
78
|
+
}
|
|
79
|
+
for (const room of kept) {
|
|
80
|
+
listed.set(room.locator, room);
|
|
81
|
+
if (lockingMode(room.replica.offline))
|
|
82
|
+
lockable.add(room.locator);
|
|
83
|
+
else
|
|
84
|
+
lockable.delete(room.locator);
|
|
85
|
+
change(room.locator, {
|
|
86
|
+
refusal: null,
|
|
87
|
+
unreading: false,
|
|
88
|
+
...(live && room.replica.admission === 'admitted' ? { confirmed: true } : {}),
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
return kept;
|
|
92
|
+
},
|
|
93
|
+
room: (locator) => listed.get(locator),
|
|
94
|
+
rooms: () => [...listed.values()],
|
|
95
|
+
available(locator, selection) {
|
|
96
|
+
if (marks.has(locator))
|
|
97
|
+
return false;
|
|
98
|
+
const room = listed.get(locator);
|
|
99
|
+
if (room === undefined)
|
|
100
|
+
return true;
|
|
101
|
+
return ((selection === undefined || selection === room.replica.selection) &&
|
|
102
|
+
room.replica.admission === 'admitted' &&
|
|
103
|
+
!answer(locator).unreadable);
|
|
104
|
+
},
|
|
105
|
+
refusal: (locator) => answer(locator).refusal,
|
|
106
|
+
unheldModel: (locator) => answer(locator).unheldModel,
|
|
107
|
+
refused(locator, refusal) {
|
|
108
|
+
if (refusal === null) {
|
|
109
|
+
heard(locator, { unreadable: true });
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
const unreading = refusal.scope !== 'operation' && refusal.scope !== 'model';
|
|
113
|
+
heard(locator, {
|
|
114
|
+
refusal: { code: refusal.code, fields: refusal.fields, retryable: refusal.retryable },
|
|
115
|
+
unreading,
|
|
116
|
+
...(unreading ? { unreadable: true } : {}),
|
|
117
|
+
});
|
|
118
|
+
},
|
|
119
|
+
readable,
|
|
120
|
+
modelled(locator, model) {
|
|
121
|
+
heard(locator, { unheldModel: model });
|
|
122
|
+
},
|
|
123
|
+
installed(locator, bootstrapped) {
|
|
124
|
+
if (marks.has(locator))
|
|
125
|
+
return;
|
|
126
|
+
if (bootstrapped) {
|
|
127
|
+
readied(locator);
|
|
128
|
+
change(locator, { unheldModel: null });
|
|
129
|
+
}
|
|
130
|
+
change(locator, { stale: false });
|
|
131
|
+
readable(locator);
|
|
132
|
+
},
|
|
133
|
+
async locked(locator, stored) {
|
|
134
|
+
if (marks.has(locator) || answer(locator).confirmed)
|
|
135
|
+
return false;
|
|
136
|
+
return locks(locator, (await stored()) ?? listed.get(locator)?.replica.offline);
|
|
137
|
+
},
|
|
138
|
+
lockedAs: locks,
|
|
139
|
+
lockedAmong(stored, locking) {
|
|
140
|
+
return [...new Set([...lockable, ...locking])]
|
|
141
|
+
.filter((locator) => locks(locator, stored.get(locator)?.offline ?? listed.get(locator)?.replica.offline))
|
|
142
|
+
.sort();
|
|
143
|
+
},
|
|
144
|
+
connectionLost(lapsed) {
|
|
145
|
+
if (lockGrace !== null)
|
|
146
|
+
return;
|
|
147
|
+
lockGrace = setTimeout(() => {
|
|
148
|
+
lockGrace = null;
|
|
149
|
+
lapsed();
|
|
150
|
+
}, LOCK_GRACE_MS);
|
|
151
|
+
},
|
|
152
|
+
connectionLive,
|
|
153
|
+
lapse() {
|
|
154
|
+
for (const [locator, held] of answered) {
|
|
155
|
+
if (held.confirmed)
|
|
156
|
+
answered.set(locator, { ...held, confirmed: false });
|
|
157
|
+
}
|
|
158
|
+
},
|
|
159
|
+
stood(locator, stale, repairable) {
|
|
160
|
+
heard(locator, { stale, ...(repairable === undefined ? {} : { repairable }) });
|
|
161
|
+
},
|
|
162
|
+
repairing(locator, running) {
|
|
163
|
+
change(locator, { repairing: running });
|
|
164
|
+
},
|
|
165
|
+
reload(locator, due) {
|
|
166
|
+
change(locator, { reloadDue: due });
|
|
167
|
+
},
|
|
168
|
+
standing(locator) {
|
|
169
|
+
const { stale, repairable, repairing, reloadDue } = answer(locator);
|
|
170
|
+
return { stale, repairable, repairing, reloadDue };
|
|
171
|
+
},
|
|
172
|
+
settled: () => ![...answered].some(([locator, { stale }]) => stale && !marks.has(locator)),
|
|
173
|
+
repairsOwed: () => [...answered]
|
|
174
|
+
.filter(([locator, { stale, repairable }]) => stale && repairable !== null && !marks.has(locator))
|
|
175
|
+
.map(([locator]) => locator),
|
|
176
|
+
askAgain(locator, ask) {
|
|
177
|
+
const held = unready.get(locator) ?? { tries: 0, timer: null };
|
|
178
|
+
unready.set(locator, held);
|
|
179
|
+
if (held.timer !== null)
|
|
180
|
+
return;
|
|
181
|
+
const wait = notReadyWaitMs(held.tries);
|
|
182
|
+
held.tries += 1;
|
|
183
|
+
held.timer = setTimeout(() => {
|
|
184
|
+
held.timer = null;
|
|
185
|
+
ask();
|
|
186
|
+
}, wait);
|
|
187
|
+
},
|
|
188
|
+
stopAsking,
|
|
189
|
+
lose(locator, during) {
|
|
190
|
+
if (marks.has(locator))
|
|
191
|
+
return false;
|
|
192
|
+
marks.set(locator, { during, written: false });
|
|
193
|
+
lastLost.set(locator, ++lossCount);
|
|
194
|
+
listings += 1;
|
|
195
|
+
listed.delete(locator);
|
|
196
|
+
lockable.delete(locator);
|
|
197
|
+
readied(locator);
|
|
198
|
+
const { repairing, reloadDue } = answer(locator);
|
|
199
|
+
answered.set(locator, { ...UNANSWERED, repairing, reloadDue });
|
|
200
|
+
return true;
|
|
201
|
+
},
|
|
202
|
+
writing(locator) {
|
|
203
|
+
const mark = marks.get(locator);
|
|
204
|
+
if (mark === undefined || mark.written)
|
|
205
|
+
return false;
|
|
206
|
+
marks.set(locator, { ...mark, written: true });
|
|
207
|
+
return true;
|
|
208
|
+
},
|
|
209
|
+
unwritten(locator) {
|
|
210
|
+
const mark = marks.get(locator);
|
|
211
|
+
if (mark !== undefined)
|
|
212
|
+
marks.set(locator, { ...mark, written: false });
|
|
213
|
+
},
|
|
214
|
+
lost: (locator) => marks.has(locator),
|
|
215
|
+
losing: () => marks.size > 0,
|
|
216
|
+
listing: () => listings,
|
|
217
|
+
losses: () => lossCount,
|
|
218
|
+
lostSince: (locator, losses) => marks.has(locator) || (lastLost.get(locator) ?? 0) > losses,
|
|
219
|
+
liftable,
|
|
220
|
+
lift(locator, discovery, unfenced) {
|
|
221
|
+
const mark = marks.get(locator);
|
|
222
|
+
if (mark !== undefined && liftable(locator, discovery) && (unfenced || !mark.written)) {
|
|
223
|
+
marks.delete(locator);
|
|
224
|
+
}
|
|
225
|
+
},
|
|
226
|
+
close() {
|
|
227
|
+
stopAsking();
|
|
228
|
+
connectionLive();
|
|
229
|
+
},
|
|
230
|
+
};
|
|
231
|
+
}
|
package/dist/queries.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type FiguresCover } from './figures.js';
|
|
2
|
-
import type
|
|
2
|
+
import { type Cover, type Ran } from './live.js';
|
|
3
3
|
import { type Plan, type QueryResult } from './query.js';
|
|
4
4
|
import { type Deliver, type Fail, type PortReach } from './reach.js';
|
|
5
5
|
import type { Runtime } from './runtime.js';
|
|
@@ -9,7 +9,7 @@ export declare function figuresCover(runtime: Runtime): Promise<FiguresCover>;
|
|
|
9
9
|
export declare function answeredPlan(runtime: Runtime, plan: Plan, cover: () => Promise<Cover>): Promise<Ran>;
|
|
10
10
|
export declare function rowsQuery(runtime: Runtime, plan: Plan): Promise<QueryResult>;
|
|
11
11
|
export declare function planned(runtime: Runtime, input: unknown, reach: PortReach | null): Promise<Plan>;
|
|
12
|
-
export declare function roomTallies(runtime: Runtime, rooms: readonly QueryRoom[], since: string): Promise<readonly import("./tallies.
|
|
12
|
+
export declare function roomTallies(runtime: Runtime, rooms: readonly QueryRoom[], since: string): Promise<readonly import("./tallies.ts").RoomTally[]>;
|
|
13
13
|
export declare function watchPlan(runtime: Runtime, plan: Plan, deliver: Deliver, fail: Fail): () => void;
|
|
14
14
|
export declare function watchPlanned(runtime: Runtime, planning: Promise<Plan>, deliver: Deliver, fail: Fail): () => void;
|
|
15
15
|
export declare function searched(runtime: Runtime, input: unknown, reach: PortReach | null): Promise<SearchResult>;
|
package/dist/queries.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"queries.d.ts","sourceRoot":"","sources":["../src/queries.ts"],"names":[],"mappings":"AACA,OAAO,EAAe,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC;AAE9D,OAAO,KAAK,EAAE,KAAK,
|
|
1
|
+
{"version":3,"file":"queries.d.ts","sourceRoot":"","sources":["../src/queries.ts"],"names":[],"mappings":"AACA,OAAO,EAAe,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC;AAE9D,OAAO,EAAY,KAAK,KAAK,EAAE,KAAK,GAAG,EAAE,MAAM,WAAW,CAAC;AAK3D,OAAO,EAKL,KAAK,IAAI,EACT,KAAK,WAAW,EAEjB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAa,KAAK,OAAO,EAAE,KAAK,IAAI,EAAE,KAAK,SAAS,EAAE,MAAM,YAAY,CAAC;AAGhF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAgB,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAE9D,OAAO,KAAK,EAAa,SAAS,EAAgB,MAAM,YAAY,CAAC;AAiHrE,wBAAsB,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,YAAY,CAAC,CAa1E;AAoGD,wBAAsB,YAAY,CAChC,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,MAAM,OAAO,CAAC,KAAK,CAAC,GAC1B,OAAO,CAAC,GAAG,CAAC,CAQd;AAQD,wBAAsB,SAAS,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,WAAW,CAAC,CAWlF;AAED,wBAAsB,OAAO,CAC3B,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,OAAO,EACd,KAAK,EAAE,SAAS,GAAG,IAAI,GACtB,OAAO,CAAC,IAAI,CAAC,CAOf;AAED,wBAAsB,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,SAAS,EAAE,EAAE,KAAK,EAAE,MAAM,wDAO7F;AAED,wBAAgB,SAAS,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,GAAG,MAAM,IAAI,CAmBhG;AAED,wBAAgB,YAAY,CAC1B,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC,EACvB,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,IAAI,GACT,MAAM,IAAI,CAeZ;AAED,wBAAsB,QAAQ,CAC5B,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,OAAO,EACd,KAAK,EAAE,SAAS,GAAG,IAAI,GACtB,OAAO,CAAC,YAAY,CAAC,CAkDvB"}
|