@agentshouse/mdruntime 0.1.0-cb1f56e16291b → 0.1.0-cb3bb3b233fa1
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 +3 -0
- package/dist/acceptance.d.ts.map +1 -0
- package/dist/acceptance.js +299 -0
- 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 +26 -0
- package/dist/actions.d.ts.map +1 -0
- package/dist/actions.js +302 -0
- package/dist/adapter.d.ts +113 -81
- package/dist/adapter.d.ts.map +1 -1
- package/dist/attached-model.d.ts +3 -11
- package/dist/attached-model.d.ts.map +1 -1
- package/dist/attached-model.js +20 -60
- 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 +9 -5
- package/dist/bootstrap.d.ts.map +1 -1
- package/dist/bootstrap.js +204 -85
- package/dist/cell.d.ts +6 -0
- package/dist/cell.d.ts.map +1 -0
- package/dist/cell.js +9 -0
- package/dist/chain.d.ts +2 -1
- package/dist/chain.d.ts.map +1 -1
- 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 +5 -0
- package/dist/change.d.ts.map +1 -1
- package/dist/change.js +7 -2
- package/dist/chat-types.d.ts +3 -0
- package/dist/chat-types.d.ts.map +1 -0
- package/dist/chat-types.js +11 -0
- package/dist/client.d.ts +30 -22
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +39 -20
- package/dist/collection.d.ts +26 -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 +9 -7
- package/dist/compile.d.ts.map +1 -1
- package/dist/compile.js +252 -318
- package/dist/connection.d.ts +5 -141
- package/dist/connection.d.ts.map +1 -1
- package/dist/connection.js +111 -5282
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +1 -1
- package/dist/conversation-live.d.ts +150 -0
- package/dist/conversation-live.d.ts.map +1 -0
- package/dist/conversation-live.js +259 -0
- package/dist/conversation-row.d.ts +40 -0
- package/dist/conversation-row.d.ts.map +1 -0
- package/dist/conversation-row.js +66 -0
- package/dist/conversation.d.ts +62 -43
- package/dist/conversation.d.ts.map +1 -1
- package/dist/conversation.js +987 -902
- 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 +10 -0
- package/dist/discovery.d.ts.map +1 -0
- package/dist/discovery.js +150 -0
- package/dist/durability.d.ts +19 -0
- package/dist/durability.d.ts.map +1 -1
- package/dist/durability.js +4 -0
- package/dist/entry.d.ts +2 -2
- package/dist/entry.d.ts.map +1 -1
- package/dist/entry.js +18 -9
- 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 +49 -0
- package/dist/figures.d.ts.map +1 -0
- package/dist/figures.js +199 -0
- package/dist/file.d.ts +1 -1
- package/dist/file.d.ts.map +1 -1
- package/dist/file.js +3 -2
- package/dist/holdings.d.ts +29 -0
- package/dist/holdings.d.ts.map +1 -0
- package/dist/holdings.js +95 -0
- package/dist/host.d.ts +20 -4
- package/dist/host.d.ts.map +1 -1
- package/dist/host.js +72 -28
- 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 +32 -12
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +14 -5
- package/dist/install.d.ts +60 -0
- package/dist/install.d.ts.map +1 -0
- package/dist/install.js +537 -0
- package/dist/lifecycle.d.ts +7 -0
- package/dist/lifecycle.d.ts.map +1 -0
- package/dist/lifecycle.js +282 -0
- package/dist/listing.d.ts +52 -0
- package/dist/listing.d.ts.map +1 -0
- package/dist/listing.js +152 -0
- package/dist/live.d.ts +8 -6
- package/dist/live.d.ts.map +1 -1
- package/dist/live.js +110 -31
- 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 +7 -0
- package/dist/locks.d.ts.map +1 -0
- package/dist/locks.js +32 -0
- package/dist/lost.d.ts +5 -0
- package/dist/lost.d.ts.map +1 -0
- package/dist/lost.js +49 -0
- 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 +11 -3
- package/dist/memory.d.ts.map +1 -1
- package/dist/memory.js +132 -33
- package/dist/messages.d.ts +33 -3
- package/dist/messages.d.ts.map +1 -1
- package/dist/messages.js +98 -27
- package/dist/model.d.ts +2 -10
- package/dist/model.d.ts.map +1 -1
- package/dist/model.js +0 -14
- package/dist/models.d.ts +10 -0
- package/dist/models.d.ts.map +1 -0
- package/dist/models.js +153 -0
- 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 +4 -0
- package/dist/opening.d.ts.map +1 -0
- package/dist/opening.js +53 -0
- package/dist/outcome.d.ts +17 -2
- package/dist/outcome.d.ts.map +1 -1
- package/dist/outcome.js +35 -2
- package/dist/overlay.d.ts +7 -2
- package/dist/overlay.d.ts.map +1 -1
- package/dist/overlay.js +48 -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 +4 -0
- package/dist/parts.d.ts.map +1 -0
- package/dist/parts.js +13 -0
- package/dist/paths.d.ts +1 -0
- package/dist/paths.d.ts.map +1 -1
- package/dist/paths.js +22 -0
- package/dist/preparation.d.ts +41 -0
- package/dist/preparation.d.ts.map +1 -0
- package/dist/preparation.js +314 -0
- 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 +16 -0
- package/dist/queries.d.ts.map +1 -0
- package/dist/queries.js +308 -0
- package/dist/query.d.ts +13 -213
- package/dist/query.d.ts.map +1 -1
- package/dist/query.js +3 -524
- package/dist/questions.d.ts +30 -0
- package/dist/questions.d.ts.map +1 -0
- package/dist/questions.js +116 -0
- 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 +10 -10
- package/dist/reach.d.ts.map +1 -1
- package/dist/reach.js +235 -120
- package/dist/react.d.ts +17 -3
- package/dist/react.d.ts.map +1 -1
- package/dist/react.js +33 -1
- package/dist/read.d.ts +7 -0
- package/dist/read.d.ts.map +1 -0
- package/dist/read.js +17 -0
- package/dist/readiness.d.ts +9 -4
- package/dist/readiness.d.ts.map +1 -1
- package/dist/readiness.js +3 -5
- package/dist/reads.d.ts +39 -0
- package/dist/reads.d.ts.map +1 -0
- package/dist/reads.js +178 -0
- package/dist/recovery.d.ts +3 -1
- package/dist/recovery.d.ts.map +1 -1
- package/dist/recovery.js +38 -8
- package/dist/refresh.d.ts +1 -1
- package/dist/refresh.d.ts.map +1 -1
- package/dist/refresh.js +10 -22
- package/dist/refusal.d.ts +5 -0
- package/dist/refusal.d.ts.map +1 -0
- package/dist/refusal.js +55 -0
- package/dist/replica.d.ts +11 -16
- package/dist/replica.d.ts.map +1 -1
- package/dist/replica.js +66 -35
- 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 +32 -9
- package/dist/room-draft.d.ts.map +1 -1
- package/dist/room-draft.js +273 -66
- package/dist/room-drafts.d.ts +24 -0
- package/dist/room-drafts.d.ts.map +1 -0
- package/dist/room-drafts.js +220 -0
- 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 +16 -23
- package/dist/rows.d.ts.map +1 -1
- package/dist/rows.js +49 -191
- package/dist/runtime.d.ts +34 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +1 -0
- package/dist/save.d.ts +42 -86
- package/dist/save.d.ts.map +1 -1
- package/dist/save.js +332 -228
- package/dist/saves.d.ts +34 -0
- package/dist/saves.d.ts.map +1 -0
- package/dist/saves.js +437 -0
- package/dist/search.d.ts.map +1 -1
- package/dist/search.js +1 -1
- package/dist/seed.d.ts +11 -2
- package/dist/seed.d.ts.map +1 -1
- package/dist/seed.js +71 -1
- package/dist/shared.d.ts +1 -6
- package/dist/shared.d.ts.map +1 -1
- package/dist/shared.js +13 -95
- package/dist/shown.d.ts +33 -0
- package/dist/shown.d.ts.map +1 -0
- package/dist/shown.js +309 -0
- package/dist/socket/admission.d.ts +7 -0
- package/dist/socket/admission.d.ts.map +1 -0
- package/dist/socket/admission.js +39 -0
- package/dist/socket/answers.d.ts +6 -0
- package/dist/socket/answers.d.ts.map +1 -0
- package/dist/socket/answers.js +20 -0
- package/dist/socket/lanes.d.ts +28 -0
- package/dist/socket/lanes.d.ts.map +1 -0
- package/dist/socket/lanes.js +103 -0
- package/dist/socket/reads.d.ts +10 -0
- package/dist/socket/reads.d.ts.map +1 -0
- package/dist/socket/reads.js +31 -0
- package/dist/socket/session.d.ts +38 -0
- package/dist/socket/session.d.ts.map +1 -0
- package/dist/socket/session.js +23 -0
- package/dist/socket.d.ts +67 -0
- package/dist/socket.d.ts.map +1 -0
- package/dist/socket.js +164 -0
- package/dist/source.d.ts +59 -0
- package/dist/source.d.ts.map +1 -0
- package/dist/source.js +93 -0
- package/dist/status.d.ts +0 -2
- package/dist/status.d.ts.map +1 -1
- package/dist/status.js +0 -6
- package/dist/store/installs.d.ts +30 -0
- package/dist/store/installs.d.ts.map +1 -0
- package/dist/store/installs.js +40 -0
- package/dist/store/readiness.d.ts +11 -0
- package/dist/store/readiness.d.ts.map +1 -0
- package/dist/store/readiness.js +68 -0
- package/dist/store/records.d.ts +223 -0
- package/dist/store/records.d.ts.map +1 -0
- package/dist/store/records.js +465 -0
- package/dist/store/room-held.d.ts +8 -0
- package/dist/store/room-held.d.ts.map +1 -0
- package/dist/store/room-held.js +17 -0
- 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 +11 -0
- package/dist/store/space.d.ts.map +1 -0
- package/dist/store/space.js +41 -0
- package/dist/store/watchers.d.ts +17 -0
- package/dist/store/watchers.d.ts.map +1 -0
- package/dist/store/watchers.js +56 -0
- package/dist/store/writes.d.ts +24 -0
- package/dist/store/writes.d.ts.map +1 -0
- package/dist/store/writes.js +125 -0
- package/dist/store.d.ts +115 -152
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +171 -395
- package/dist/stored.d.ts +72 -67
- package/dist/stored.d.ts.map +1 -1
- package/dist/stored.js +317 -166
- package/dist/surface.d.ts +90 -0
- package/dist/surface.d.ts.map +1 -0
- package/dist/surface.js +225 -0
- package/dist/sync.d.ts +19 -0
- package/dist/sync.d.ts.map +1 -0
- package/dist/sync.js +536 -0
- package/dist/tables.d.ts +112 -89
- package/dist/tables.d.ts.map +1 -1
- package/dist/tables.js +197 -283
- package/dist/tallies.d.ts +18 -0
- package/dist/tallies.d.ts.map +1 -0
- package/dist/tallies.js +128 -0
- package/dist/validation.d.ts.map +1 -1
- package/dist/validation.js +9 -12
- package/dist/windows.d.ts +1 -12
- package/dist/windows.d.ts.map +1 -1
- package/dist/windows.js +2 -75
- package/dist/wire.d.ts +68 -7
- package/dist/wire.d.ts.map +1 -1
- package/dist/wire.js +23 -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/fence.d.ts +0 -6
- package/dist/fence.d.ts.map +0 -1
- package/dist/fence.js +0 -10
- package/dist/job.d.ts +0 -14
- package/dist/job.d.ts.map +0 -1
- package/dist/job.js +0 -28
- package/dist/log.d.ts +0 -5
- package/dist/log.d.ts.map +0 -1
- package/dist/log.js +0 -14
- package/dist/phrase.d.ts +0 -3
- package/dist/phrase.d.ts.map +0 -1
- package/dist/phrase.js +0 -8
package/dist/model.js
CHANGED
|
@@ -1,9 +1,4 @@
|
|
|
1
1
|
export const NO_MODEL = { status: 'unavailable', reason: 'not-acquired' };
|
|
2
|
-
export function definitionOf(state, type) {
|
|
3
|
-
if (state.status === 'unavailable' || type === undefined)
|
|
4
|
-
return undefined;
|
|
5
|
-
return Object.hasOwn(state.types, type) ? state.types[type] : undefined;
|
|
6
|
-
}
|
|
7
2
|
export function modelTypes(state) {
|
|
8
3
|
return state.status === 'unavailable'
|
|
9
4
|
? { ...state, types: null }
|
|
@@ -23,12 +18,3 @@ export function storedModel(state) {
|
|
|
23
18
|
const { types: _types, ...stored } = state;
|
|
24
19
|
return stored;
|
|
25
20
|
}
|
|
26
|
-
export function cached(state) {
|
|
27
|
-
return state.status === 'unavailable' ? state : { ...state, status: 'cached' };
|
|
28
|
-
}
|
|
29
|
-
export function sameModel(left, right) {
|
|
30
|
-
return left.identity === right.identity && left.version === right.version;
|
|
31
|
-
}
|
|
32
|
-
export function referenceField(facts) {
|
|
33
|
-
return facts?.reference !== undefined || facts?.items?.reference !== undefined;
|
|
34
|
-
}
|
package/dist/models.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { RoomDeclaration, ScopedRefusal } from './adapter.js';
|
|
2
|
+
import { type ModelState } from './model.js';
|
|
3
|
+
import type { Runtime } from './runtime.js';
|
|
4
|
+
import type { RuntimeStore } from './store.js';
|
|
5
|
+
export declare function revoked(model: ModelState | undefined): boolean;
|
|
6
|
+
export declare function retainModel(runtime: Runtime, locator: string, declaration: RoomDeclaration, given: ModelState | null, refused?: true): Promise<void>;
|
|
7
|
+
export declare function scoped(runtime: Runtime, result: ScopedRefusal, locator: string, declaration: RoomDeclaration): Promise<void>;
|
|
8
|
+
export declare function settleModels(runtime: Runtime, held: ReadonlyMap<string, RoomDeclaration>, status: 'current' | 'cached', local: RuntimeStore): Promise<void>;
|
|
9
|
+
export declare function cachedModels(runtime: Runtime, local: RuntimeStore): Promise<void>;
|
|
10
|
+
//# sourceMappingURL=models.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"models.d.ts","sourceRoot":"","sources":["../src/models.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAOnE,OAAO,EAAY,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAGvD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAE5C,OAAO,KAAK,EAAc,YAAY,EAAS,MAAM,YAAY,CAAC;AAMlE,wBAAgB,OAAO,CAAC,KAAK,EAAE,UAAU,GAAG,SAAS,GAAG,OAAO,CAE9D;AA0DD,wBAAsB,WAAW,CAC/B,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,eAAe,EAC5B,KAAK,EAAE,UAAU,GAAG,IAAI,EACxB,OAAO,CAAC,EAAE,IAAI,iBA2Bf;AAED,wBAAsB,MAAM,CAC1B,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,aAAa,EACrB,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,eAAe,iBAkB7B;AAED,wBAAsB,YAAY,CAChC,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,WAAW,CAAC,MAAM,EAAE,eAAe,CAAC,EAC1C,MAAM,EAAE,SAAS,GAAG,QAAQ,EAC5B,KAAK,EAAE,YAAY,iBAkDpB;AAED,wBAAsB,YAAY,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAkBvF"}
|
package/dist/models.js
ADDED
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { equalValue } from '@agentshouse/mdmodel';
|
|
2
|
+
import { changeSet } from './change-set.js';
|
|
3
|
+
import { composedOf } from './collection.js';
|
|
4
|
+
import { declared, sameDeclaration } from './declaration.js';
|
|
5
|
+
import { uncaught } from './failure.js';
|
|
6
|
+
import { declarationOf, listedLocators } from './listing.js';
|
|
7
|
+
import { loseRooms } from './lost.js';
|
|
8
|
+
import { NO_MODEL } from './model.js';
|
|
9
|
+
import { settle } from './queue.js';
|
|
10
|
+
import { storedRecord } from './replica.js';
|
|
11
|
+
import { emitRooms } from './shown.js';
|
|
12
|
+
function declaredAsHeld(held, declaration) {
|
|
13
|
+
return held === undefined || sameDeclaration(held.declaration, declaration);
|
|
14
|
+
}
|
|
15
|
+
export function revoked(model) {
|
|
16
|
+
return model?.status === 'unavailable' && model.reason === 'revoked';
|
|
17
|
+
}
|
|
18
|
+
function unheldModelOf({ presence }, locator) {
|
|
19
|
+
return presence.unheldModel(locator) ?? NO_MODEL;
|
|
20
|
+
}
|
|
21
|
+
async function modelNow(runtime, locator) {
|
|
22
|
+
return (await runtime.store.record(locator))?.model ?? unheldModelOf(runtime, locator);
|
|
23
|
+
}
|
|
24
|
+
function restands(held, model, declaration) {
|
|
25
|
+
return (JSON.stringify(held.model) !== JSON.stringify(model) ||
|
|
26
|
+
!equalValue(held.declaration.typedSelection, declaration.typedSelection));
|
|
27
|
+
}
|
|
28
|
+
function recordAlone(store, record) {
|
|
29
|
+
return {
|
|
30
|
+
locator: record.locator,
|
|
31
|
+
key: record.key,
|
|
32
|
+
record: storedRecord(record),
|
|
33
|
+
composed: composedOf(store.composed(record)),
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
function unheld(runtime, locator, model) {
|
|
37
|
+
runtime.presence.modelled(locator, model);
|
|
38
|
+
emitRooms(runtime, [locator]);
|
|
39
|
+
}
|
|
40
|
+
function recorded(runtime, locator, declaration, model) {
|
|
41
|
+
const { store, socket } = runtime;
|
|
42
|
+
return store.exclusive(async () => {
|
|
43
|
+
if (!socket.continuing())
|
|
44
|
+
return;
|
|
45
|
+
const current = await store.record(locator);
|
|
46
|
+
if (current === undefined) {
|
|
47
|
+
unheld(runtime, locator, model);
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
const answer = await (await store.open()).commit({ rooms: [recordAlone(store, { ...current, declaration, model })] });
|
|
51
|
+
void store.changed(changeSet(locator, {
|
|
52
|
+
documents: answer.changed[locator] ?? [],
|
|
53
|
+
room: true,
|
|
54
|
+
unindexed: answer.indexed[locator] === false,
|
|
55
|
+
}));
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
export async function retainModel(runtime, locator, declaration, given, refused) {
|
|
59
|
+
const { store, socket } = runtime;
|
|
60
|
+
const held = await store.record(locator);
|
|
61
|
+
const previous = held?.model ?? unheldModelOf(runtime, locator);
|
|
62
|
+
const next = given ?? previous;
|
|
63
|
+
if (JSON.stringify(previous) === JSON.stringify(next) && declaredAsHeld(held, declaration))
|
|
64
|
+
return;
|
|
65
|
+
if (held !== undefined && !restands(held, next, declaration)) {
|
|
66
|
+
await recorded(runtime, locator, declaration, next);
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
await settle(runtime, [locator], async (works) => {
|
|
70
|
+
if (!socket.continuing())
|
|
71
|
+
return [];
|
|
72
|
+
const current = works.get(locator)?.replica;
|
|
73
|
+
if (current === undefined) {
|
|
74
|
+
unheld(runtime, locator, next);
|
|
75
|
+
return [];
|
|
76
|
+
}
|
|
77
|
+
return [
|
|
78
|
+
{
|
|
79
|
+
locator,
|
|
80
|
+
record: { ...current.record, declaration, model: next },
|
|
81
|
+
...(refused === undefined ? {} : { refused }),
|
|
82
|
+
},
|
|
83
|
+
];
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
export async function scoped(runtime, result, locator, declaration) {
|
|
87
|
+
const { socket, presence } = runtime;
|
|
88
|
+
if (result.scope === 'content' && !result.retryable) {
|
|
89
|
+
await loseRooms(runtime, [locator]);
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
presence.refused(locator, result);
|
|
93
|
+
if (result.scope === 'model')
|
|
94
|
+
await retainModel(runtime, locator, declaration, { status: 'unavailable', reason: 'not-readable' }, true);
|
|
95
|
+
if (!socket.continuing())
|
|
96
|
+
return;
|
|
97
|
+
emitRooms(runtime, [locator]);
|
|
98
|
+
}
|
|
99
|
+
export async function settleModels(runtime, held, status, local) {
|
|
100
|
+
const { store, socket, presence } = runtime;
|
|
101
|
+
const owed = (model) => model.status !== 'unavailable' && model.status !== status;
|
|
102
|
+
const declaredAnew = await store.exclusive(async () => {
|
|
103
|
+
if (!socket.continuing())
|
|
104
|
+
return [];
|
|
105
|
+
const stored = await store.rooms([...held.keys()]);
|
|
106
|
+
const unchanged = [...held].filter(([locator, declaration]) => {
|
|
107
|
+
const record = stored.get(locator)?.record;
|
|
108
|
+
return (owed(record?.model ?? unheldModelOf(runtime, locator)) &&
|
|
109
|
+
declaredAsHeld(record, declaration));
|
|
110
|
+
});
|
|
111
|
+
const records = unchanged.flatMap(([locator]) => {
|
|
112
|
+
const record = stored.get(locator)?.record;
|
|
113
|
+
return record === undefined
|
|
114
|
+
? []
|
|
115
|
+
: [{ ...record, model: { ...record.model, status } }];
|
|
116
|
+
});
|
|
117
|
+
if (records.length > 0) {
|
|
118
|
+
try {
|
|
119
|
+
await local.commit({ rooms: records.map((record) => recordAlone(store, record)) });
|
|
120
|
+
}
|
|
121
|
+
catch (error) {
|
|
122
|
+
uncaught(error);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
for (const [locator] of unchanged) {
|
|
126
|
+
const unheldModel = presence.unheldModel(locator);
|
|
127
|
+
if (!stored.has(locator) && unheldModel !== null) {
|
|
128
|
+
presence.modelled(locator, { ...unheldModel, status });
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
if (unchanged.length > 0)
|
|
132
|
+
emitRooms(runtime, unchanged.map(([locator]) => locator));
|
|
133
|
+
const kept = new Set(unchanged.map(([locator]) => locator));
|
|
134
|
+
return [...held].filter(([locator]) => !kept.has(locator) &&
|
|
135
|
+
owed(stored.get(locator)?.record.model ?? unheldModelOf(runtime, locator)));
|
|
136
|
+
});
|
|
137
|
+
for (const [locator, declaration] of declaredAnew) {
|
|
138
|
+
const model = await modelNow(runtime, locator);
|
|
139
|
+
if (owed(model))
|
|
140
|
+
await retainModel(runtime, locator, declaration, { ...model, status });
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
export async function cachedModels(runtime, local) {
|
|
144
|
+
const { store, presence } = runtime;
|
|
145
|
+
const held = await store.rooms();
|
|
146
|
+
await settleModels(runtime, new Map(listedLocators(runtime, held).flatMap((locator) => {
|
|
147
|
+
const discovered = presence.room(locator);
|
|
148
|
+
const declaration = discovered === undefined
|
|
149
|
+
? declarationOf(runtime, locator, held.get(locator))?.room
|
|
150
|
+
: declared(discovered);
|
|
151
|
+
return declaration === undefined ? [] : [[locator, declaration]];
|
|
152
|
+
})), 'cached', local);
|
|
153
|
+
}
|
package/dist/observation.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type { QueryCoverage, QueryDocument, QueryGroup, QueryResult } from './query.js';
|
|
1
|
+
import type { PendingRoom, QueryCoverage, QueryDocument, QueryGroup, QueryResult } from './query.js';
|
|
2
|
+
import type { ReadinessShown, RoomCoverage } from './readiness.js';
|
|
2
3
|
export type Observation<T> = {
|
|
3
4
|
current(): T;
|
|
4
5
|
subscribe(listener: (value: T) => void): () => void;
|
|
@@ -9,15 +10,24 @@ export type KeyedResult = {
|
|
|
9
10
|
result: QueryResult;
|
|
10
11
|
keys: readonly RowKey[];
|
|
11
12
|
};
|
|
12
|
-
export type
|
|
13
|
-
changed: readonly (readonly [
|
|
14
|
-
removed: readonly
|
|
15
|
-
order: readonly
|
|
13
|
+
export type KeyedChange<K, T> = {
|
|
14
|
+
readonly changed: readonly (readonly [K, T])[];
|
|
15
|
+
readonly removed: readonly K[];
|
|
16
|
+
readonly order: readonly K[] | null;
|
|
17
|
+
};
|
|
18
|
+
export type QueryChange = KeyedChange<RowKey, QueryDocument | QueryGroup> & {
|
|
16
19
|
coverage?: QueryCoverage;
|
|
17
20
|
next?: string | null;
|
|
18
21
|
total?: number;
|
|
19
22
|
};
|
|
20
|
-
export type
|
|
23
|
+
export type ReadinessChange = {
|
|
24
|
+
readonly shown: ReadinessShown;
|
|
25
|
+
readonly rooms: KeyedChange<string, RoomCoverage>;
|
|
26
|
+
};
|
|
27
|
+
export type PendingChange = {
|
|
28
|
+
readonly pending: KeyedChange<string, PendingRoom>;
|
|
29
|
+
};
|
|
30
|
+
export type QueryMessage = KeyedResult | QueryChange | PendingChange;
|
|
21
31
|
export type Observed = {
|
|
22
32
|
observation: Observation<unknown>;
|
|
23
33
|
receive(message: unknown): void;
|
|
@@ -25,15 +35,20 @@ export type Observed = {
|
|
|
25
35
|
};
|
|
26
36
|
export declare function rowsOf(result: QueryResult): readonly (QueryDocument | QueryGroup)[];
|
|
27
37
|
export declare function whole(message: QueryMessage): message is KeyedResult;
|
|
28
|
-
export declare function
|
|
29
|
-
export declare function
|
|
30
|
-
export declare function
|
|
38
|
+
export declare function pendingChange(message: QueryMessage): message is PendingChange;
|
|
39
|
+
export declare function unchanged(change: KeyedChange<unknown, unknown>): boolean;
|
|
40
|
+
export declare function keyedChange<K, H, T>(held: ReadonlyMap<K, H>, keys: readonly K[], rows: readonly T[], same: (was: H, now: T) => boolean): KeyedChange<K, T>;
|
|
41
|
+
export declare function keyedAt<K, H, T>(held: ReadonlyMap<K, H>, at: ReadonlyMap<K, T | null>, same: (was: H, now: T) => boolean): KeyedChange<K, T> | null;
|
|
42
|
+
export declare function keyedInto<K, T>(held: Map<K, T>, change: KeyedChange<K, T>): void;
|
|
43
|
+
export declare function samePending(was: PendingRoom, now: PendingRoom): boolean;
|
|
44
|
+
export declare function replaces(topic: string, message: unknown): boolean;
|
|
45
|
+
export declare function observed(first: unknown, stop: () => void, topic: string): Observed;
|
|
46
|
+
export declare function opened(watch: (deliver: (message: unknown) => void, fail: (error: unknown) => void) => () => void, topic: string): Promise<Observation<unknown>>;
|
|
31
47
|
export declare function observing<Topic extends string>(watch: (topic: Topic, input: readonly unknown[], deliver: (message: unknown) => void, fail: (error: unknown) => void) => () => void): (topic: Topic, ...input: unknown[]) => Promise<Observation<unknown>>;
|
|
32
48
|
export type Digest = {
|
|
33
|
-
readonly pending: string
|
|
49
|
+
readonly pending: Map<string, PendingRoom>;
|
|
34
50
|
} | {
|
|
35
|
-
readonly
|
|
36
|
-
readonly rows: ReadonlyMap<RowKey, number>;
|
|
51
|
+
readonly rows: Map<RowKey, number>;
|
|
37
52
|
readonly coverage: string;
|
|
38
53
|
readonly next: string | undefined;
|
|
39
54
|
readonly total: number | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"observation.d.ts","sourceRoot":"","sources":["../src/observation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"observation.d.ts","sourceRoot":"","sources":["../src/observation.ts"],"names":[],"mappings":"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"}
|
package/dist/observation.js
CHANGED
|
@@ -6,49 +6,165 @@ export function rowsOf(result) {
|
|
|
6
6
|
export function whole(message) {
|
|
7
7
|
return 'result' in message;
|
|
8
8
|
}
|
|
9
|
-
export function
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
const
|
|
22
|
-
const kept =
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
9
|
+
export function pendingChange(message) {
|
|
10
|
+
return 'pending' in message;
|
|
11
|
+
}
|
|
12
|
+
export function unchanged(change) {
|
|
13
|
+
return change.changed.length === 0 && change.removed.length === 0 && change.order === null;
|
|
14
|
+
}
|
|
15
|
+
export function keyedChange(held, keys, rows, same) {
|
|
16
|
+
const present = new Set(keys);
|
|
17
|
+
const changed = keys.flatMap((key, at) => {
|
|
18
|
+
const was = held.get(key);
|
|
19
|
+
return was !== undefined && same(was, rows[at]) ? [] : [[key, rows[at]]];
|
|
20
|
+
});
|
|
21
|
+
const removed = [];
|
|
22
|
+
const kept = [];
|
|
23
|
+
for (const key of held.keys())
|
|
24
|
+
(present.has(key) ? kept : removed).push(key);
|
|
25
|
+
const moved = kept.length !== keys.length || kept.some((key, at) => keys[at] !== key);
|
|
26
|
+
return { changed, removed, order: moved ? keys : null };
|
|
27
|
+
}
|
|
28
|
+
export function keyedAt(held, at, same) {
|
|
29
|
+
const changed = [];
|
|
30
|
+
const removed = [];
|
|
31
|
+
for (const [key, now] of at) {
|
|
32
|
+
const was = held.get(key);
|
|
33
|
+
if (was === undefined) {
|
|
34
|
+
if (now !== null)
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
else if (now === null)
|
|
38
|
+
removed.push(key);
|
|
39
|
+
else if (!same(was, now))
|
|
40
|
+
changed.push([key, now]);
|
|
41
|
+
}
|
|
42
|
+
return { changed, removed, order: null };
|
|
43
|
+
}
|
|
44
|
+
export function keyedInto(held, change) {
|
|
45
|
+
for (const key of change.removed)
|
|
46
|
+
held.delete(key);
|
|
47
|
+
for (const [key, row] of change.changed)
|
|
48
|
+
held.set(key, row);
|
|
49
|
+
if (change.order === null)
|
|
50
|
+
return;
|
|
51
|
+
const placed = change.order.map((key) => [key, held.get(key)]);
|
|
52
|
+
held.clear();
|
|
53
|
+
for (const [key, row] of placed)
|
|
54
|
+
held.set(key, row);
|
|
55
|
+
}
|
|
56
|
+
export function samePending(was, now) {
|
|
57
|
+
return was.awaits === now.awaits;
|
|
58
|
+
}
|
|
59
|
+
function keyedRows(keys, rows) {
|
|
60
|
+
const held = new Map(keys.map((key, at) => [key, rows[at]]));
|
|
61
|
+
let shown = rows;
|
|
62
|
+
return {
|
|
63
|
+
rows: () => shown,
|
|
64
|
+
apply(change) {
|
|
65
|
+
if (unchanged(change))
|
|
66
|
+
return shown;
|
|
67
|
+
keyedInto(held, change);
|
|
68
|
+
shown = [...held.values()];
|
|
69
|
+
return shown;
|
|
70
|
+
},
|
|
29
71
|
};
|
|
72
|
+
}
|
|
73
|
+
function located(rooms) {
|
|
74
|
+
return keyedRows(rooms.map(({ locator }) => locator), rooms);
|
|
75
|
+
}
|
|
76
|
+
function keyedRooms(first) {
|
|
77
|
+
let held = located(first);
|
|
78
|
+
return {
|
|
79
|
+
value: first,
|
|
80
|
+
next(message) {
|
|
81
|
+
if (!Array.isArray(message))
|
|
82
|
+
return held.apply(message);
|
|
83
|
+
held = located(message);
|
|
84
|
+
return held.rows();
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
function covered(readiness) {
|
|
89
|
+
return keyedRows(readiness.coverage.rooms.map(({ room }) => room), readiness.coverage.rooms);
|
|
90
|
+
}
|
|
91
|
+
function keyedReadiness(first) {
|
|
92
|
+
let held = covered(first);
|
|
30
93
|
return {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
94
|
+
value: first,
|
|
95
|
+
next(message) {
|
|
96
|
+
if (!('shown' in message)) {
|
|
97
|
+
held = covered(message);
|
|
98
|
+
return message;
|
|
99
|
+
}
|
|
100
|
+
const { shown, rooms } = message;
|
|
101
|
+
return { ...shown, coverage: { ...shown.coverage, rooms: held.apply(rooms) } };
|
|
102
|
+
},
|
|
35
103
|
};
|
|
36
104
|
}
|
|
105
|
+
function awaiting(pending) {
|
|
106
|
+
return keyedRows(pending.map(({ room }) => room), pending);
|
|
107
|
+
}
|
|
37
108
|
function keyedResult(first) {
|
|
38
|
-
let
|
|
109
|
+
let result = first.result;
|
|
110
|
+
let rows = keyedRows([], []);
|
|
111
|
+
let pending = awaiting([]);
|
|
112
|
+
const take = ({ result: next, keys }) => {
|
|
113
|
+
result = next;
|
|
114
|
+
if ('pending' in next)
|
|
115
|
+
pending = awaiting(next.pending);
|
|
116
|
+
else
|
|
117
|
+
rows = keyedRows(keys, rowsOf(next));
|
|
118
|
+
return result;
|
|
119
|
+
};
|
|
120
|
+
take(first);
|
|
39
121
|
return {
|
|
40
122
|
value: first.result,
|
|
41
123
|
next(message) {
|
|
42
|
-
|
|
43
|
-
|
|
124
|
+
const asked = message;
|
|
125
|
+
if (whole(asked))
|
|
126
|
+
return take(asked);
|
|
127
|
+
if (pendingChange(asked)) {
|
|
128
|
+
if ('pending' in result)
|
|
129
|
+
result = { pending: pending.apply(asked.pending) };
|
|
130
|
+
return result;
|
|
131
|
+
}
|
|
132
|
+
if ('pending' in result)
|
|
133
|
+
return result;
|
|
134
|
+
const kept = rows.apply(asked);
|
|
135
|
+
const coverage = asked.coverage ?? result.coverage;
|
|
136
|
+
const next = asked.next === undefined ? result.next : (asked.next ?? undefined);
|
|
137
|
+
const total = asked.total ?? result.total;
|
|
138
|
+
const window = {
|
|
139
|
+
...(next === undefined ? {} : { next }),
|
|
140
|
+
...(total === undefined ? {} : { total }),
|
|
141
|
+
};
|
|
142
|
+
result =
|
|
143
|
+
'groups' in result
|
|
144
|
+
? { groups: kept, coverage, ...window }
|
|
145
|
+
: { documents: kept, coverage, ...window };
|
|
146
|
+
return result;
|
|
44
147
|
},
|
|
45
148
|
};
|
|
46
149
|
}
|
|
150
|
+
const FOLDS = {
|
|
151
|
+
query: (first) => keyedResult(first),
|
|
152
|
+
rooms: (first) => keyedRooms(first),
|
|
153
|
+
readiness: (first) => keyedReadiness(first),
|
|
154
|
+
};
|
|
155
|
+
const WHOLE = {
|
|
156
|
+
query: (message) => whole(message),
|
|
157
|
+
rooms: (message) => Array.isArray(message),
|
|
158
|
+
readiness: (message) => !('shown' in message),
|
|
159
|
+
};
|
|
160
|
+
export function replaces(topic, message) {
|
|
161
|
+
return WHOLE[topic]?.(message) ?? true;
|
|
162
|
+
}
|
|
47
163
|
function replaced(first) {
|
|
48
164
|
return { value: first, next: (message) => message };
|
|
49
165
|
}
|
|
50
|
-
export function observed(first, stop,
|
|
51
|
-
const reducer =
|
|
166
|
+
export function observed(first, stop, topic) {
|
|
167
|
+
const reducer = (FOLDS[topic] ?? replaced)(first);
|
|
52
168
|
let value = reducer.value;
|
|
53
169
|
let open = true;
|
|
54
170
|
const listeners = new Set();
|
|
@@ -86,34 +202,29 @@ export function observed(first, stop, keyed) {
|
|
|
86
202
|
end,
|
|
87
203
|
};
|
|
88
204
|
}
|
|
89
|
-
export function opened(watch,
|
|
205
|
+
export function opened(watch, topic) {
|
|
90
206
|
return new Promise((resolve, reject) => {
|
|
91
207
|
let handle;
|
|
92
208
|
let stop = () => { };
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
stop();
|
|
105
|
-
reject(error);
|
|
106
|
-
});
|
|
107
|
-
}
|
|
108
|
-
catch (error) {
|
|
209
|
+
stop = watch((message) => {
|
|
210
|
+
if (handle !== undefined) {
|
|
211
|
+
handle.receive(message);
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
handle = observed(message, () => stop(), topic);
|
|
215
|
+
resolve(handle.observation);
|
|
216
|
+
}, (error) => {
|
|
217
|
+
if (handle !== undefined)
|
|
218
|
+
return;
|
|
219
|
+
stop();
|
|
109
220
|
reject(error);
|
|
110
|
-
}
|
|
221
|
+
});
|
|
111
222
|
});
|
|
112
223
|
}
|
|
113
224
|
export function observing(watch) {
|
|
114
225
|
return (topic, ...input) => opened((deliver, fail) => watch(topic, input, (message) => {
|
|
115
226
|
deliver(structuredClone(message));
|
|
116
|
-
}, fail), topic
|
|
227
|
+
}, fail), topic);
|
|
117
228
|
}
|
|
118
229
|
export function hashed(text) {
|
|
119
230
|
let first = 0xdeadbeef;
|
|
@@ -134,10 +245,9 @@ function rowDigest(row) {
|
|
|
134
245
|
}
|
|
135
246
|
export function digestOf({ result, keys }) {
|
|
136
247
|
if ('pending' in result)
|
|
137
|
-
return { pending:
|
|
248
|
+
return { pending: new Map(result.pending.map((room) => [room.room, room])) };
|
|
138
249
|
const rows = rowsOf(result);
|
|
139
250
|
return {
|
|
140
|
-
keys,
|
|
141
251
|
rows: new Map(keys.map((key, index) => [key, rowDigest(rows[index])])),
|
|
142
252
|
coverage: JSON.stringify(result.coverage),
|
|
143
253
|
next: result.next,
|
|
@@ -145,16 +255,22 @@ export function digestOf({ result, keys }) {
|
|
|
145
255
|
};
|
|
146
256
|
}
|
|
147
257
|
export function digestApplied(digest, message) {
|
|
148
|
-
if (whole(message)
|
|
149
|
-
return
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
258
|
+
if (whole(message))
|
|
259
|
+
return digestOf(message);
|
|
260
|
+
if (pendingChange(message)) {
|
|
261
|
+
if ('pending' in digest)
|
|
262
|
+
keyedInto(digest.pending, message.pending);
|
|
263
|
+
return digest;
|
|
264
|
+
}
|
|
265
|
+
if ('pending' in digest)
|
|
266
|
+
return digest;
|
|
267
|
+
keyedInto(digest.rows, {
|
|
268
|
+
changed: message.changed.map(([key, row]) => [key, rowDigest(row)]),
|
|
269
|
+
removed: message.removed,
|
|
270
|
+
order: message.order,
|
|
271
|
+
});
|
|
155
272
|
return {
|
|
156
|
-
|
|
157
|
-
rows,
|
|
273
|
+
rows: digest.rows,
|
|
158
274
|
coverage: message.coverage === undefined ? digest.coverage : JSON.stringify(message.coverage),
|
|
159
275
|
next: message.next === undefined ? digest.next : (message.next ?? undefined),
|
|
160
276
|
total: message.total ?? digest.total,
|
|
@@ -162,35 +278,18 @@ export function digestApplied(digest, message) {
|
|
|
162
278
|
}
|
|
163
279
|
export function changeOf(previous, next) {
|
|
164
280
|
const after = next.result;
|
|
165
|
-
if ('pending' in previous
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
: next;
|
|
281
|
+
if ('pending' in previous && 'pending' in after) {
|
|
282
|
+
const pending = keyedChange(previous.pending, after.pending.map(({ room }) => room), after.pending, samePending);
|
|
283
|
+
return unchanged(pending) ? null : { pending };
|
|
169
284
|
}
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
const
|
|
173
|
-
|
|
174
|
-
const row = later[index];
|
|
175
|
-
if (previous.rows.get(key) !== rowDigest(row))
|
|
176
|
-
changed.push([key, row]);
|
|
177
|
-
});
|
|
178
|
-
const removed = previous.keys.filter((key) => !present.has(key));
|
|
179
|
-
const kept = previous.keys.filter((key) => present.has(key));
|
|
180
|
-
const moved = kept.length !== next.keys.length || kept.some((key, index) => next.keys[index] !== key);
|
|
181
|
-
const coverage = JSON.stringify(after.coverage);
|
|
182
|
-
const covered = previous.coverage !== coverage;
|
|
285
|
+
if ('pending' in previous || 'pending' in after)
|
|
286
|
+
return next;
|
|
287
|
+
const rows = keyedChange(previous.rows, next.keys, rowsOf(after), (was, row) => was === rowDigest(row));
|
|
288
|
+
const covered = previous.coverage !== JSON.stringify(after.coverage);
|
|
183
289
|
const framing = reframed(previous, after);
|
|
184
|
-
if (
|
|
290
|
+
if (unchanged(rows) && !covered && framing === null)
|
|
185
291
|
return null;
|
|
186
|
-
}
|
|
187
|
-
return {
|
|
188
|
-
changed,
|
|
189
|
-
removed,
|
|
190
|
-
order: moved ? next.keys : null,
|
|
191
|
-
...(covered ? { coverage: after.coverage } : {}),
|
|
192
|
-
...framing,
|
|
193
|
-
};
|
|
292
|
+
return { ...rows, ...(covered ? { coverage: after.coverage } : {}), ...framing };
|
|
194
293
|
}
|
|
195
294
|
function reframed(before, after) {
|
|
196
295
|
const next = before.next === after.next ? {} : { next: after.next ?? null };
|
package/dist/opened.d.ts
CHANGED
|
@@ -18,5 +18,5 @@ export type OpenedFiles = {
|
|
|
18
18
|
find(name: OpenedName): Promise<KeptBinary | null>;
|
|
19
19
|
fetch(name: OpenedName, read: () => Promise<BinaryResult>): Promise<KeptResult>;
|
|
20
20
|
};
|
|
21
|
-
export declare function openedFiles(database: RuntimeDatabase,
|
|
21
|
+
export declare function openedFiles(database: RuntimeDatabase, lost: (locator: string) => boolean): OpenedFiles;
|
|
22
22
|
//# sourceMappingURL=opened.d.ts.map
|
package/dist/opened.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"opened.d.ts","sourceRoot":"","sources":["../src/opened.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAGjD,OAAO,EAAoC,KAAK,eAAe,EAAE,MAAM,aAAa,CAAC;AAErF,MAAM,MAAM,UAAU,GAAG;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG,OAAO,CAAC,YAAY,EAAE;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,CAAC,CAAC;AAEhF,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;IACnD,KAAK,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC,YAAY,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;CACjF,CAAC;AAsBF,wBAAgB,WAAW,CACzB,QAAQ,EAAE,eAAe,EACzB,
|
|
1
|
+
{"version":3,"file":"opened.d.ts","sourceRoot":"","sources":["../src/opened.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAGjD,OAAO,EAAoC,KAAK,eAAe,EAAE,MAAM,aAAa,CAAC;AAErF,MAAM,MAAM,UAAU,GAAG;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG,OAAO,CAAC,YAAY,EAAE;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,CAAC,CAAC;AAEhF,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;IACnD,KAAK,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC,YAAY,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;CACjF,CAAC;AAsBF,wBAAgB,WAAW,CACzB,QAAQ,EAAE,eAAe,EACzB,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,GACjC,WAAW,CAsFb"}
|
package/dist/opened.js
CHANGED
|
@@ -20,7 +20,7 @@ function taken(chunks, size) {
|
|
|
20
20
|
}
|
|
21
21
|
return part;
|
|
22
22
|
}
|
|
23
|
-
export function openedFiles(database,
|
|
23
|
+
export function openedFiles(database, lost) {
|
|
24
24
|
const fetching = new Map();
|
|
25
25
|
async function find(name) {
|
|
26
26
|
const held = await database.ask({ kind: 'opened.find', ...name });
|
|
@@ -36,14 +36,14 @@ export function openedFiles(database, fenced) {
|
|
|
36
36
|
let part = 0;
|
|
37
37
|
const write = async (bytes) => {
|
|
38
38
|
if (!(await database.ask({ kind: 'opened.part', key, part, bytes }))) {
|
|
39
|
-
throw new Error(
|
|
39
|
+
throw new Error();
|
|
40
40
|
}
|
|
41
41
|
part += 1;
|
|
42
42
|
};
|
|
43
43
|
try {
|
|
44
|
-
if (
|
|
44
|
+
if (lost(name.locator) ||
|
|
45
45
|
!(await database.ask({ kind: 'opened.begin', key, ...name, mediaType }))) {
|
|
46
|
-
throw new Error(
|
|
46
|
+
throw new Error();
|
|
47
47
|
}
|
|
48
48
|
for (;;) {
|
|
49
49
|
const read = await reader.read();
|
|
@@ -61,7 +61,7 @@ export function openedFiles(database, fenced) {
|
|
|
61
61
|
await write(taken(chunks, held));
|
|
62
62
|
const received = hashed.hex();
|
|
63
63
|
if (sha256 !== undefined && sha256 !== received) {
|
|
64
|
-
throw new Error(
|
|
64
|
+
throw new Error();
|
|
65
65
|
}
|
|
66
66
|
const whole = await database.ask({
|
|
67
67
|
kind: 'opened.keep',
|