@agentshouse/mdruntime 0.1.0-cd507e16e5fc0 → 0.1.0-cd71aba4d0215
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 +8 -8
- package/dist/acceptance.d.ts +0 -3
- package/dist/acceptance.d.ts.map +1 -1
- package/dist/acceptance.js +74 -145
- package/dist/act-lanes.d.ts +33 -0
- package/dist/act-lanes.d.ts.map +1 -0
- package/dist/act-lanes.js +177 -0
- package/dist/actions.d.ts +7 -2
- package/dist/actions.d.ts.map +1 -1
- package/dist/actions.js +40 -30
- package/dist/adapter.d.ts +27 -45
- package/dist/adapter.d.ts.map +1 -1
- 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.map +1 -1
- package/dist/change.js +4 -2
- package/dist/client.d.ts +7 -12
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +29 -14
- package/dist/collection.d.ts +22 -4
- package/dist/collection.d.ts.map +1 -1
- package/dist/collection.js +12 -2
- package/dist/compile.d.ts.map +1 -1
- package/dist/compile.js +15 -21
- package/dist/connection.d.ts.map +1 -1
- package/dist/connection.js +26 -16
- package/dist/conversation-live.d.ts +8 -6
- package/dist/conversation-live.d.ts.map +1 -1
- package/dist/conversation-live.js +7 -6
- package/dist/conversation.d.ts +23 -10
- package/dist/conversation.d.ts.map +1 -1
- package/dist/conversation.js +127 -102
- 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 +18 -40
- package/dist/durability.d.ts +3 -0
- package/dist/durability.d.ts.map +1 -1
- package/dist/expectation.d.ts +4 -2
- package/dist/expectation.d.ts.map +1 -1
- package/dist/expectation.js +33 -11
- package/dist/failure.d.ts +3 -0
- package/dist/failure.d.ts.map +1 -1
- package/dist/failure.js +6 -0
- package/dist/host.d.ts +17 -2
- package/dist/host.d.ts.map +1 -1
- package/dist/host.js +39 -9
- package/dist/index.d.ts +9 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -3
- package/dist/install.d.ts +1 -3
- package/dist/install.d.ts.map +1 -1
- package/dist/install.js +48 -65
- package/dist/lifecycle.d.ts +1 -1
- package/dist/lifecycle.d.ts.map +1 -1
- package/dist/lifecycle.js +38 -27
- package/dist/listing.d.ts +6 -11
- package/dist/listing.d.ts.map +1 -1
- package/dist/listing.js +25 -62
- package/dist/live.d.ts.map +1 -1
- package/dist/live.js +3 -3
- package/dist/locks.d.ts +2 -4
- package/dist/locks.d.ts.map +1 -1
- package/dist/locks.js +10 -38
- package/dist/lost.d.ts.map +1 -1
- package/dist/lost.js +10 -21
- package/dist/media.d.ts +1 -1
- package/dist/media.d.ts.map +1 -1
- package/dist/media.js +4 -4
- package/dist/memory.d.ts +4 -2
- package/dist/memory.d.ts.map +1 -1
- package/dist/memory.js +38 -21
- package/dist/messages.d.ts +0 -3
- package/dist/messages.d.ts.map +1 -1
- package/dist/messages.js +13 -31
- 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 -136
- package/dist/observation.d.ts.map +1 -1
- package/dist/observation.js +12 -17
- 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 +6 -4
- package/dist/outcome.d.ts +3 -0
- package/dist/outcome.d.ts.map +1 -1
- package/dist/outcome.js +15 -0
- package/dist/overlay.d.ts +2 -1
- package/dist/overlay.d.ts.map +1 -1
- package/dist/overlay.js +32 -21
- 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 -51
- package/dist/parts.d.ts.map +1 -1
- package/dist/parts.js +14 -111
- package/dist/preparation.d.ts.map +1 -1
- package/dist/preparation.js +22 -15
- package/dist/presence.d.ts +52 -0
- package/dist/presence.d.ts.map +1 -0
- package/dist/presence.js +220 -0
- package/dist/queries.d.ts +1 -1
- package/dist/queries.d.ts.map +1 -1
- package/dist/queries.js +5 -7
- package/dist/query.d.ts +0 -1
- package/dist/query.d.ts.map +1 -1
- package/dist/questions.js +1 -1
- package/dist/queue.d.ts +40 -0
- package/dist/queue.d.ts.map +1 -0
- package/dist/queue.js +455 -0
- package/dist/reach.d.ts.map +1 -1
- package/dist/reach.js +27 -8
- package/dist/react.d.ts +11 -0
- package/dist/react.d.ts.map +1 -1
- package/dist/react.js +15 -1
- package/dist/reads.d.ts +3 -1
- package/dist/reads.d.ts.map +1 -1
- package/dist/reads.js +9 -2
- 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 -4
- package/dist/replica.d.ts +5 -11
- package/dist/replica.d.ts.map +1 -1
- package/dist/replica.js +13 -15
- 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 +4 -6
- package/dist/room-draft.d.ts.map +1 -1
- package/dist/room-draft.js +36 -52
- package/dist/room-drafts.d.ts.map +1 -1
- package/dist/room-drafts.js +17 -16
- package/dist/rows.d.ts.map +1 -1
- package/dist/rows.js +3 -4
- package/dist/runtime.d.ts +9 -16
- package/dist/runtime.d.ts.map +1 -1
- package/dist/save.d.ts +41 -90
- package/dist/save.d.ts.map +1 -1
- package/dist/save.js +233 -116
- package/dist/saves.d.ts +2 -40
- package/dist/saves.d.ts.map +1 -1
- package/dist/saves.js +107 -702
- package/dist/seed.d.ts.map +1 -1
- package/dist/seed.js +2 -3
- 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 +4 -3
- package/dist/shown.d.ts.map +1 -1
- package/dist/shown.js +26 -31
- package/dist/socket/lanes.d.ts +2 -1
- package/dist/socket/lanes.d.ts.map +1 -1
- package/dist/socket/lanes.js +5 -2
- package/dist/socket/session.d.ts +0 -1
- package/dist/socket/session.d.ts.map +1 -1
- package/dist/socket.d.ts +2 -4
- package/dist/socket.d.ts.map +1 -1
- package/dist/socket.js +4 -8
- package/dist/source.d.ts.map +1 -1
- package/dist/source.js +5 -4
- package/dist/store/records.d.ts +3 -3
- package/dist/store/records.d.ts.map +1 -1
- package/dist/store/records.js +4 -5
- 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 +10 -5
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +38 -13
- package/dist/stored.d.ts +1 -1
- package/dist/stored.d.ts.map +1 -1
- package/dist/stored.js +6 -6
- package/dist/surface.d.ts.map +1 -1
- package/dist/surface.js +8 -8
- package/dist/sync.d.ts.map +1 -1
- package/dist/sync.js +86 -78
- package/dist/tables.d.ts +0 -5
- package/dist/tables.d.ts.map +1 -1
- package/dist/tables.js +8 -11
- package/dist/tallies.js +5 -5
- package/dist/validation.d.ts.map +1 -1
- package/dist/validation.js +2 -2
- package/dist/wire.d.ts +40 -4
- package/dist/wire.d.ts.map +1 -1
- package/dist/wire.js +12 -3
- 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/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/locks.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"locks.d.ts","sourceRoot":"","sources":["../src/locks.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"locks.d.ts","sourceRoot":"","sources":["../src/locks.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAG5C,wBAAsB,MAAM,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAE5F;AAED,wBAAsB,WAAW,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,OAAO,GAAG,OAAO,CAAC,SAAS,MAAM,EAAE,CAAC,CAK1F;AAED,wBAAsB,QAAQ,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,MAAM,EAAE,iBAMzE;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,QAU9C;AAED,wBAAgB,UAAU,CAAC,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAE7E"}
|
package/dist/locks.js
CHANGED
|
@@ -1,30 +1,11 @@
|
|
|
1
|
+
import { uncaught } from './failure.js';
|
|
1
2
|
import { emitRooms, LOCKS_TOPIC } from './shown.js';
|
|
2
|
-
async function
|
|
3
|
-
|
|
4
|
-
for (const [locator, { room }] of socket.rooms.declarations()) {
|
|
5
|
-
const declaration = room ?? socket.rooms.discovered(locator);
|
|
6
|
-
if (declaration !== undefined)
|
|
7
|
-
modes.set(locator, declaration.replica.offline);
|
|
8
|
-
}
|
|
9
|
-
for (const [locator, { offline }] of (await store.covering()).rooms)
|
|
10
|
-
modes.set(locator, offline);
|
|
11
|
-
return modes;
|
|
3
|
+
export async function locked({ store, presence }, locator) {
|
|
4
|
+
return presence.locked(locator, async () => (await store.open()).offline(locator));
|
|
12
5
|
}
|
|
13
|
-
export async function
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
const held = socket.rooms.declared(locator)?.room ?? socket.rooms.discovered(locator);
|
|
17
|
-
const mode = (await (await store.open()).offline(locator)) ?? held?.replica.offline;
|
|
18
|
-
return mode === 'locked';
|
|
19
|
-
}
|
|
20
|
-
export async function lockedRooms(runtime) {
|
|
21
|
-
const { store, socket } = runtime;
|
|
22
|
-
return [...(await offlineModes(runtime))]
|
|
23
|
-
.filter(([locator, mode]) => mode === 'locked' &&
|
|
24
|
-
!socket.rooms.standing(locator).confirmed &&
|
|
25
|
-
!store.fences.has(locator))
|
|
26
|
-
.map(([locator]) => locator)
|
|
27
|
-
.sort();
|
|
6
|
+
export async function lockedRooms({ store, presence }) {
|
|
7
|
+
const held = (await store.covering()).rooms;
|
|
8
|
+
return presence.lockedAmong(new Map([...held].map(([locator, { offline }]) => [locator, offline])));
|
|
28
9
|
}
|
|
29
10
|
export async function relocked(runtime, before) {
|
|
30
11
|
const after = await lockedRooms(runtime);
|
|
@@ -34,26 +15,17 @@ export async function relocked(runtime, before) {
|
|
|
34
15
|
emitRooms(runtime);
|
|
35
16
|
runtime.store.tell(LOCKS_TOPIC, undefined);
|
|
36
17
|
}
|
|
37
|
-
export function confirmLocks({ socket }, listed) {
|
|
38
|
-
if (!socket.isOpen())
|
|
39
|
-
return;
|
|
40
|
-
for (const room of listed) {
|
|
41
|
-
if (room.replica.admission === 'admitted') {
|
|
42
|
-
socket.rooms.stand(room.locator, { confirmed: true });
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
18
|
export function connectionLost(runtime) {
|
|
47
|
-
const { socket } = runtime;
|
|
19
|
+
const { socket, presence } = runtime;
|
|
48
20
|
if (socket.closed())
|
|
49
21
|
return;
|
|
50
|
-
|
|
22
|
+
presence.connectionLost(() => {
|
|
51
23
|
if (socket.isOpen() || socket.closed())
|
|
52
24
|
return;
|
|
53
25
|
void lockedRooms(runtime).then((before) => {
|
|
54
|
-
|
|
26
|
+
presence.lapse();
|
|
55
27
|
return relocked(runtime, before);
|
|
56
|
-
},
|
|
28
|
+
}, uncaught);
|
|
57
29
|
});
|
|
58
30
|
}
|
|
59
31
|
export function watchLocks({ store }, notify) {
|
package/dist/lost.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lost.d.ts","sourceRoot":"","sources":["../src/lost.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"lost.d.ts","sourceRoot":"","sources":["../src/lost.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAK5C,wBAAsB,WAAW,CAAC,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,MAAM,EAAE,iBAIhF;AAED,wBAAgB,SAAS,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,MAAM,EAAE,QAOtE;AAED,wBAAsB,SAAS,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,MAAM,EAAE,iBA+B5E"}
|
package/dist/lost.js
CHANGED
|
@@ -1,12 +1,8 @@
|
|
|
1
1
|
import { changeSet, mergeChangeSets } from './change-set.js';
|
|
2
|
-
import { ERASE_BATCH
|
|
3
|
-
import {
|
|
2
|
+
import { ERASE_BATCH } from './install.js';
|
|
3
|
+
import { unpair } from './queue.js';
|
|
4
|
+
import { recoverReads } from './shown.js';
|
|
4
5
|
import { yielded } from './turn.js';
|
|
5
|
-
function forget({ store, socket }, locator) {
|
|
6
|
-
forgetInstall(store, locator);
|
|
7
|
-
socket.rooms.forget(locator);
|
|
8
|
-
store.forget(locator);
|
|
9
|
-
}
|
|
10
6
|
export async function eraseFenced({ store }, locators) {
|
|
11
7
|
for (const locator of locators) {
|
|
12
8
|
while (await store.durably((local) => local.erase(locator, ERASE_BATCH)))
|
|
@@ -14,24 +10,18 @@ export async function eraseFenced({ store }, locators) {
|
|
|
14
10
|
}
|
|
15
11
|
}
|
|
16
12
|
export function fenceLive(runtime, locators) {
|
|
17
|
-
const { store, socket, journal } = runtime;
|
|
13
|
+
const { store, socket, presence, journal } = runtime;
|
|
18
14
|
for (const locator of new Set(locators)) {
|
|
19
|
-
if (!
|
|
15
|
+
if (!presence.lose(locator, socket.session.now().discoveries))
|
|
20
16
|
continue;
|
|
21
|
-
forget(
|
|
17
|
+
store.forget(locator);
|
|
22
18
|
journal.record(`room lost ${locator}`);
|
|
23
19
|
}
|
|
24
20
|
}
|
|
25
21
|
export async function loseRooms(runtime, locators) {
|
|
26
|
-
const { store } = runtime;
|
|
22
|
+
const { store, presence } = runtime;
|
|
27
23
|
fenceLive(runtime, locators);
|
|
28
|
-
const fresh = [...new Set(locators)].filter((locator) =>
|
|
29
|
-
const fence = store.fences.of(locator);
|
|
30
|
-
if (fence === undefined || fence.written)
|
|
31
|
-
return false;
|
|
32
|
-
store.fences.mark(locator, true);
|
|
33
|
-
return true;
|
|
34
|
-
});
|
|
24
|
+
const fresh = [...new Set(locators)].filter((locator) => presence.writing(locator));
|
|
35
25
|
if (fresh.length === 0)
|
|
36
26
|
return;
|
|
37
27
|
let held = [];
|
|
@@ -43,7 +33,7 @@ export async function loseRooms(runtime, locators) {
|
|
|
43
33
|
}
|
|
44
34
|
catch (error) {
|
|
45
35
|
for (const locator of fresh)
|
|
46
|
-
|
|
36
|
+
presence.unwritten(locator);
|
|
47
37
|
throw error;
|
|
48
38
|
}
|
|
49
39
|
finally {
|
|
@@ -54,8 +44,7 @@ export async function loseRooms(runtime, locators) {
|
|
|
54
44
|
drafts: held.filter((draft) => draft.locator === locator).map(({ path }) => path),
|
|
55
45
|
}))));
|
|
56
46
|
recoverReads(runtime);
|
|
57
|
-
statusShown(runtime);
|
|
58
47
|
}
|
|
59
|
-
await
|
|
48
|
+
await unpair(runtime);
|
|
60
49
|
await eraseFenced(runtime, fresh);
|
|
61
50
|
}
|
package/dist/media.d.ts
CHANGED
|
@@ -3,6 +3,6 @@ import { type ShownAnswer } from './outcome.js';
|
|
|
3
3
|
export declare const ROOM_MEDIA = "room-media";
|
|
4
4
|
type Show = (room: string, path: string, revision?: string) => Promise<ShownAnswer>;
|
|
5
5
|
export declare function shownBy(show: Show, client: MdRuntimeClient): MdRuntimeClient;
|
|
6
|
-
export declare function defineRoomMedia(client: Promise<MdRuntimeClient> | MdRuntimeClient
|
|
6
|
+
export declare function defineRoomMedia(client: Promise<MdRuntimeClient> | MdRuntimeClient): void;
|
|
7
7
|
export {};
|
|
8
8
|
//# sourceMappingURL=media.d.ts.map
|
package/dist/media.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"media.d.ts","sourceRoot":"","sources":["../src/media.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAa,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3D,eAAO,MAAM,UAAU,eAAe,CAAC;AAwBvC,KAAK,IAAI,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,WAAW,CAAC,CAAC;AAIpF,wBAAgB,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,eAAe,GAAG,eAAe,CAG5E;AAsBD,wBAAgB,eAAe,
|
|
1
|
+
{"version":3,"file":"media.d.ts","sourceRoot":"","sources":["../src/media.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAa,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3D,eAAO,MAAM,UAAU,eAAe,CAAC;AAwBvC,KAAK,IAAI,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,WAAW,CAAC,CAAC;AAIpF,wBAAgB,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,eAAe,GAAG,eAAe,CAG5E;AAsBD,wBAAgB,eAAe,CAAC,MAAM,EAAE,OAAO,CAAC,eAAe,CAAC,GAAG,eAAe,GAAG,IAAI,CA0LxF"}
|
package/dist/media.js
CHANGED
|
@@ -37,8 +37,8 @@ function drawnFor(mediaType) {
|
|
|
37
37
|
return 'audio';
|
|
38
38
|
return null;
|
|
39
39
|
}
|
|
40
|
-
export function defineRoomMedia(client
|
|
41
|
-
if (
|
|
40
|
+
export function defineRoomMedia(client) {
|
|
41
|
+
if (customElements.get(ROOM_MEDIA) !== undefined)
|
|
42
42
|
return;
|
|
43
43
|
const connected = Promise.resolve(client);
|
|
44
44
|
class RoomMedia extends HTMLElement {
|
|
@@ -179,7 +179,7 @@ export function defineRoomMedia(client, registry = customElements) {
|
|
|
179
179
|
if (drawn instanceof HTMLMediaElement) {
|
|
180
180
|
drawn.controls = true;
|
|
181
181
|
drawn.preload = 'metadata';
|
|
182
|
-
if (drawn instanceof HTMLVideoElement)
|
|
182
|
+
if (drawn instanceof HTMLVideoElement && 'playsInline' in drawn)
|
|
183
183
|
drawn.playsInline = true;
|
|
184
184
|
}
|
|
185
185
|
drawn.addEventListener(drawn instanceof HTMLImageElement ? 'load' : 'loadedmetadata', () => {
|
|
@@ -214,5 +214,5 @@ export function defineRoomMedia(client, registry = customElements) {
|
|
|
214
214
|
void this.#load();
|
|
215
215
|
}
|
|
216
216
|
}
|
|
217
|
-
|
|
217
|
+
customElements.define(ROOM_MEDIA, RoomMedia);
|
|
218
218
|
}
|
package/dist/memory.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { ModelResult } from './model.js';
|
|
2
|
-
import { type AcceptedMessage, type ActionResult, type Adapter, type BinaryFile, type Capability, type ConversationAction, type ConversationEvent, type DiscoveredRoom, type SavedFacts, type HeadChange, type ListedAgent, type ListedConversation, type Member, type ProviderLimit, type Retention, type ServiceMode, type TypedPath } from './adapter.js';
|
|
3
|
-
export type MemoryRoom = DiscoveredRoom & {
|
|
2
|
+
import { type AcceptedMessage, type ActionResult, type Adapter, type BinaryFile, type Capability, type ConversationAction, type ConversationEvent, type DiscoveredRoom, type SavedFacts, type HeadChange, type ListedAgent, type ListedConversation, type Member, type ProviderLimit, type Retention, type ServiceMode, type TypedPath, type TypedSelection } from './adapter.js';
|
|
3
|
+
export type MemoryRoom = Omit<DiscoveredRoom, 'typedSelection' | 'authoredPaths'> & {
|
|
4
|
+
typedSelection?: TypedSelection | null;
|
|
5
|
+
authoredPaths?: readonly string[];
|
|
4
6
|
model?: ModelResult;
|
|
5
7
|
documents?: Readonly<Record<string, string>>;
|
|
6
8
|
facts?: Readonly<Record<string, SavedFacts>>;
|
package/dist/memory.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../src/memory.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EACL,KAAK,eAAe,EAEpB,KAAK,YAAY,EACjB,KAAK,OAAO,EAIZ,KAAK,UAAU,EAMf,KAAK,UAAU,EACf,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EAKtB,KAAK,cAAc,EACnB,KAAK,UAAU,EACf,KAAK,UAAU,EAGf,KAAK,WAAW,EAChB,KAAK,kBAAkB,EACvB,KAAK,MAAM,EAGX,KAAK,aAAa,EAIlB,KAAK,SAAS,EAGd,KAAK,WAAW,EAChB,KAAK,SAAS,
|
|
1
|
+
{"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../src/memory.ts"],"names":[],"mappings":"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"}
|
package/dist/memory.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { documentFacts, parse } from '@agentshouse/mdmodel';
|
|
1
|
+
import { definitionAt, documentFacts, parse } from '@agentshouse/mdmodel';
|
|
2
2
|
import { NO_ROOM_TYPES, schemaTypes } from './attached-model.js';
|
|
3
3
|
import { sameChange } from './overlay.js';
|
|
4
4
|
const ATTACHMENTS = 'attachments';
|
|
@@ -53,7 +53,7 @@ export function createMemoryAdapter(options = {}) {
|
|
|
53
53
|
const listeners = new Set();
|
|
54
54
|
const modeObservers = new Set();
|
|
55
55
|
const scripted = new Map();
|
|
56
|
-
const
|
|
56
|
+
const repeats = new Map();
|
|
57
57
|
const historyPageSize = options.historyPageSize;
|
|
58
58
|
const attached = new Map();
|
|
59
59
|
const linked = new WeakMap();
|
|
@@ -113,7 +113,9 @@ export function createMemoryAdapter(options = {}) {
|
|
|
113
113
|
}
|
|
114
114
|
const key = `${path}\u0000${content}`;
|
|
115
115
|
if (!held.has(key)) {
|
|
116
|
-
const facts = documentFacts(path, parse(content, path
|
|
116
|
+
const facts = documentFacts(path, parse(content, path, definitionAt({ types }, path, options.typedPaths)), {
|
|
117
|
+
types,
|
|
118
|
+
});
|
|
117
119
|
held.set(key, facts === null ? null : JSON.parse(JSON.stringify(facts)));
|
|
118
120
|
}
|
|
119
121
|
return held.get(key);
|
|
@@ -147,9 +149,9 @@ export function createMemoryAdapter(options = {}) {
|
|
|
147
149
|
roomVersion: room.roomVersion,
|
|
148
150
|
operations: room.operations,
|
|
149
151
|
replica: room.replica,
|
|
150
|
-
|
|
152
|
+
typedSelection: room.typedSelection ?? null,
|
|
151
153
|
providerOwnedPaths: room.providerOwnedPaths,
|
|
152
|
-
authoredPaths: room.authoredPaths,
|
|
154
|
+
authoredPaths: room.authoredPaths ?? ['**'],
|
|
153
155
|
};
|
|
154
156
|
}
|
|
155
157
|
function page(room, after) {
|
|
@@ -259,16 +261,14 @@ export function createMemoryAdapter(options = {}) {
|
|
|
259
261
|
}
|
|
260
262
|
function pageOf(conversation, after) {
|
|
261
263
|
const messages = conversation.messages ?? [];
|
|
262
|
-
const first = typeof after === 'string' ? messages.findIndex((message) => message.
|
|
264
|
+
const first = typeof after === 'string' ? messages.findIndex((message) => message.change > after) : 0;
|
|
263
265
|
const from = first === -1 ? messages.length : first;
|
|
264
266
|
const page = messages.slice(from, from + (historyPageSize ?? messages.length));
|
|
265
267
|
const last = page.at(-1);
|
|
266
268
|
return {
|
|
267
269
|
conversation: conversation.conversation,
|
|
268
270
|
messages: page,
|
|
269
|
-
...(last !== undefined && from + page.length < messages.length
|
|
270
|
-
? { next: last.position }
|
|
271
|
-
: {}),
|
|
271
|
+
...(last !== undefined && from + page.length < messages.length ? { next: last.change } : {}),
|
|
272
272
|
};
|
|
273
273
|
}
|
|
274
274
|
function historiesOf(request) {
|
|
@@ -288,11 +288,20 @@ export function createMemoryAdapter(options = {}) {
|
|
|
288
288
|
function conversationAction(request) {
|
|
289
289
|
const name = request.name;
|
|
290
290
|
const input = (request.input ?? {});
|
|
291
|
+
const operation = typeof input.operation_id === 'string' ? `${name}\u0000${input.operation_id}` : null;
|
|
292
|
+
const first = (answer) => {
|
|
293
|
+
if (operation !== null)
|
|
294
|
+
repeats.set(operation, answer);
|
|
295
|
+
return answer;
|
|
296
|
+
};
|
|
297
|
+
const repeated = operation === null ? undefined : repeats.get(operation);
|
|
291
298
|
if (name === 'conversations/create') {
|
|
299
|
+
if (repeated !== undefined)
|
|
300
|
+
return repeated;
|
|
292
301
|
issued += 1;
|
|
293
302
|
const conversation = `conversation-${issued}`;
|
|
294
303
|
scripted.set(conversation, { conversation });
|
|
295
|
-
return { kind: 'action', result: { conversation_id: conversation } };
|
|
304
|
+
return first({ kind: 'action', result: { conversation_id: conversation } });
|
|
296
305
|
}
|
|
297
306
|
const named = typeof input.conversation_id === 'string' ? input.conversation_id : '';
|
|
298
307
|
const conversation = scripted.get(named);
|
|
@@ -308,24 +317,30 @@ export function createMemoryAdapter(options = {}) {
|
|
|
308
317
|
if (outcome !== undefined)
|
|
309
318
|
return outcome;
|
|
310
319
|
if (name === 'conversations/send') {
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
if (answered !== undefined)
|
|
314
|
-
return { kind: 'action', result: { message_id: answered } };
|
|
320
|
+
if (repeated !== undefined)
|
|
321
|
+
return repeated;
|
|
315
322
|
issued += 1;
|
|
316
|
-
|
|
317
|
-
if (operation !== null)
|
|
318
|
-
sentTurns.set(operation, turn);
|
|
319
|
-
return { kind: 'action', result: { message_id: turn } };
|
|
323
|
+
return first({ kind: 'action', result: { message_id: `turn-${issued}` } });
|
|
320
324
|
}
|
|
321
325
|
if (name === 'conversations/delete')
|
|
322
326
|
scripted.delete(named);
|
|
323
327
|
return { kind: 'action', result: { conversation_id: named } };
|
|
324
328
|
}
|
|
329
|
+
function decided(request) {
|
|
330
|
+
const { request: asked, message, decision, } = (request.input ?? {});
|
|
331
|
+
return {
|
|
332
|
+
kind: 'action',
|
|
333
|
+
result: {
|
|
334
|
+
request: asked,
|
|
335
|
+
...(message === undefined ? {} : { message }),
|
|
336
|
+
state: decision === 'approve' ? 'started' : 'declined',
|
|
337
|
+
},
|
|
338
|
+
};
|
|
339
|
+
}
|
|
325
340
|
function announceList() {
|
|
326
341
|
const entries = [...scripted.values()].flatMap(({ conversation, listed, messages = [] }) => listed === undefined
|
|
327
342
|
? []
|
|
328
|
-
: [{ conversation, ...listed, newest: messages.at(-1)?.
|
|
343
|
+
: [{ conversation, ...listed, newest: messages.at(-1)?.change ?? null }]);
|
|
329
344
|
for (const listener of listeners) {
|
|
330
345
|
listener({ kind: 'list', entries, whole: true, more: false, cursor: null });
|
|
331
346
|
}
|
|
@@ -599,7 +614,7 @@ export function createMemoryAdapter(options = {}) {
|
|
|
599
614
|
return { kind: 'room-not-readable', locator: request.locator };
|
|
600
615
|
const blob = heldBlob(room, request.path);
|
|
601
616
|
return blob === undefined
|
|
602
|
-
? { kind: 'rejected', code: '
|
|
617
|
+
? { kind: 'rejected', code: 'not_found', fields: {}, retryable: false }
|
|
603
618
|
: { kind: 'binary', body: blob.stream(), mediaType: blob.type };
|
|
604
619
|
}, request);
|
|
605
620
|
},
|
|
@@ -610,7 +625,7 @@ export function createMemoryAdapter(options = {}) {
|
|
|
610
625
|
return { kind: 'room-not-readable', locator: request.locator };
|
|
611
626
|
const blob = heldBlob(room, request.path);
|
|
612
627
|
if (blob === undefined) {
|
|
613
|
-
return { kind: 'rejected', code: '
|
|
628
|
+
return { kind: 'rejected', code: 'not_found', fields: {}, retryable: false };
|
|
614
629
|
}
|
|
615
630
|
const url = linked.get(blob) ?? URL.createObjectURL(blob);
|
|
616
631
|
linked.set(blob, url);
|
|
@@ -631,6 +646,8 @@ export function createMemoryAdapter(options = {}) {
|
|
|
631
646
|
return resolveScript(scripts.action, () => {
|
|
632
647
|
if (request.name.startsWith('conversations/'))
|
|
633
648
|
return conversationAction(request);
|
|
649
|
+
if (request.name === 'agent-functions/decide')
|
|
650
|
+
return decided(request);
|
|
634
651
|
return { kind: 'rejected', code: 'unscripted-action', fields: {}, retryable: false };
|
|
635
652
|
}, request).then((answer) => {
|
|
636
653
|
if (answer.kind === 'action' && answer.at !== undefined)
|
package/dist/messages.d.ts
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import type { AcceptedMessage } from './adapter.js';
|
|
2
|
-
import type { JobMarker } from './job.js';
|
|
3
2
|
import type { Connection } from './tables.js';
|
|
4
3
|
export declare const MESSAGE_TABLES: readonly string[];
|
|
5
4
|
export declare const ROWS = "WITH chosen AS (\n SELECT listed.value AS conversation,\n (SELECT id FROM conversation_messages WHERE conversation = listed.value AND json_extract(message, '$.role') = 'assistant' ORDER BY position DESC, identity DESC LIMIT 1) AS answer,\n (SELECT id FROM conversation_messages WHERE conversation = listed.value AND text <> '' ORDER BY position DESC, identity DESC LIMIT 1) AS said,\n (SELECT id FROM conversation_messages WHERE conversation = listed.value AND json_extract(message, '$.role') = 'house' ORDER BY position, identity LIMIT 1) AS opened,\n (SELECT id FROM conversation_messages WHERE conversation = listed.value AND json_extract(message, '$.role') = 'house' AND json_extract(message, '$.waiting') = 1 ORDER BY position, identity LIMIT 1) AS asking\n FROM json_each(?) AS listed\n )\n SELECT chosen.conversation AS conversation,\n substr(said.text, 1, 512) AS said_text,\n json_extract(said.message, '$.role') AS said_role,\n json_extract(said.message, '$.accepted_at') AS said_at,\n substr(json_extract(answer.message, '$.failure'), 1, 512) AS failure,\n json_extract(opened.message, '$.source') AS opened_source,\n json_extract(opened.message, '$.sender') AS opened_sender,\n asking.identity AS asking_identity,\n asking.text AS asking_text,\n json_extract(asking.message, '$.accepted_at') AS asking_at,\n json_extract(asking.message, '$.source') AS asking_source,\n json_extract(asking.message, '$.sender') AS asking_sender\n FROM chosen\n LEFT JOIN conversation_messages said ON said.id = chosen.said\n LEFT JOIN conversation_messages answer ON answer.id = chosen.answer\n LEFT JOIN conversation_messages opened ON opened.id = chosen.opened\n LEFT JOIN conversation_messages asking ON asking.id = chosen.asking";
|
|
6
|
-
export declare const JOB_MARKERS = "SELECT json_extract(part.value, '$.text') AS said,\n json_extract(message, '$.accepted_at') AS at\n FROM conversation_messages, json_each(message, '$.parts') AS part\n WHERE conversation = ? AND instr(message, '\"marker\":\"job\"') > 0\n AND json_extract(part.value, '$.type') = 'marker'\n AND json_extract(part.value, '$.marker') = 'job'\n ORDER BY position, identity, part.key";
|
|
7
5
|
export type HeldConversation = {
|
|
8
6
|
readonly conversation: string;
|
|
9
7
|
readonly read: string | null | undefined;
|
|
@@ -45,7 +43,6 @@ export declare function keptMessages(connection: Connection, { conversation, mes
|
|
|
45
43
|
export declare function messageWindow(connection: Connection, conversation: string, limit: number, before: readonly [string, string] | null, phrase: string | null): MessageWindow;
|
|
46
44
|
export declare function messageCount(connection: Connection, conversation: string, phrase: string | null): number;
|
|
47
45
|
export declare function conversationRows(connection: Connection, conversations: readonly string[]): HeldRow[];
|
|
48
|
-
export declare function jobMarkers(connection: Connection, conversation: string): JobMarker[];
|
|
49
46
|
export declare function turnArrived(connection: Connection, conversation: string, turn: string): boolean;
|
|
50
47
|
export declare function droppedMessages(connection: Connection, conversations: readonly string[]): void;
|
|
51
48
|
export declare function forgottenMessages(connection: Connection): void;
|
package/dist/messages.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../src/messages.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../src/messages.ts"],"names":[],"mappings":"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"}
|
package/dist/messages.js
CHANGED
|
@@ -2,15 +2,13 @@ import { sql } from '@agentshouse/mdmodel';
|
|
|
2
2
|
import { EXCERPT } from './read.js';
|
|
3
3
|
const SAID_BY_HOUSE = `json_extract(message, '$.role') = 'house'`;
|
|
4
4
|
const ANSWERS_THE_TURN = `json_extract(message, '$.role') = 'assistant'`;
|
|
5
|
-
const MARKS_A_JOB = `instr(message, '"marker":"job"') > 0`;
|
|
6
5
|
export const MESSAGE_TABLES = [
|
|
7
6
|
'CREATE TABLE conversation_reads (conversation TEXT PRIMARY KEY, read TEXT, partial INTEGER NOT NULL) WITHOUT ROWID',
|
|
8
|
-
'CREATE TABLE conversation_messages (id INTEGER PRIMARY KEY, conversation TEXT NOT NULL, identity TEXT NOT NULL, turn TEXT NOT NULL, position TEXT NOT NULL, message TEXT NOT NULL, text TEXT NOT NULL)',
|
|
7
|
+
'CREATE TABLE conversation_messages (id INTEGER PRIMARY KEY, conversation TEXT NOT NULL, identity TEXT NOT NULL, turn TEXT NOT NULL, position TEXT NOT NULL, change TEXT NOT NULL, message TEXT NOT NULL, text TEXT NOT NULL)',
|
|
9
8
|
'CREATE UNIQUE INDEX conversation_messages_identity ON conversation_messages (conversation, identity)',
|
|
10
9
|
'CREATE INDEX conversation_messages_position ON conversation_messages (conversation, position, identity)',
|
|
11
10
|
'CREATE INDEX conversation_messages_turn ON conversation_messages (conversation, turn)',
|
|
12
11
|
`CREATE INDEX conversation_messages_house ON conversation_messages (conversation, position, identity) WHERE ${SAID_BY_HOUSE}`,
|
|
13
|
-
`CREATE INDEX conversation_messages_jobs ON conversation_messages (conversation, position, identity) WHERE ${MARKS_A_JOB}`,
|
|
14
12
|
];
|
|
15
13
|
const NEWEST_FIRST = 'ORDER BY position DESC, identity DESC LIMIT 1';
|
|
16
14
|
const OLDEST_FIRST = 'ORDER BY position, identity LIMIT 1';
|
|
@@ -40,13 +38,6 @@ export const ROWS = `WITH chosen AS (
|
|
|
40
38
|
LEFT JOIN conversation_messages answer ON answer.id = chosen.answer
|
|
41
39
|
LEFT JOIN conversation_messages opened ON opened.id = chosen.opened
|
|
42
40
|
LEFT JOIN conversation_messages asking ON asking.id = chosen.asking`;
|
|
43
|
-
export const JOB_MARKERS = `SELECT json_extract(part.value, '$.text') AS said,
|
|
44
|
-
json_extract(message, '$.accepted_at') AS at
|
|
45
|
-
FROM conversation_messages, json_each(message, '$.parts') AS part
|
|
46
|
-
WHERE conversation = ? AND ${MARKS_A_JOB}
|
|
47
|
-
AND json_extract(part.value, '$.type') = 'marker'
|
|
48
|
-
AND json_extract(part.value, '$.marker') = 'job'
|
|
49
|
-
ORDER BY position, identity, part.key`;
|
|
50
41
|
function text(value) {
|
|
51
42
|
return typeof value === 'string' ? value : String(value);
|
|
52
43
|
}
|
|
@@ -72,19 +63,15 @@ export function heldConversations(connection, conversations) {
|
|
|
72
63
|
}
|
|
73
64
|
export function keptMessages(connection, { conversation, messages, read }) {
|
|
74
65
|
for (const message of messages) {
|
|
75
|
-
|
|
76
|
-
|
|
66
|
+
connection.run('INSERT INTO conversation_messages (conversation, identity, turn, position, change, message, text) VALUES (?, ?, ?, ?, ?, ?, ?) ON CONFLICT (conversation, identity) DO UPDATE SET turn = excluded.turn, position = excluded.position, change = excluded.change, message = excluded.message, text = excluded.text', [
|
|
67
|
+
conversation,
|
|
68
|
+
message.identity,
|
|
77
69
|
message.turn,
|
|
78
70
|
message.position,
|
|
71
|
+
message.change,
|
|
79
72
|
JSON.stringify(message.message ?? null),
|
|
80
73
|
message.text,
|
|
81
|
-
];
|
|
82
|
-
if (held === undefined) {
|
|
83
|
-
connection.run('INSERT INTO conversation_messages (conversation, identity, turn, position, message, text) VALUES (?, ?, ?, ?, ?, ?)', [conversation, message.identity, ...record]);
|
|
84
|
-
}
|
|
85
|
-
else {
|
|
86
|
-
connection.run('UPDATE conversation_messages SET turn = ?, position = ?, message = ?, text = ? WHERE id = ?', [...record, held.id]);
|
|
87
|
-
}
|
|
74
|
+
]);
|
|
88
75
|
}
|
|
89
76
|
if (read !== undefined) {
|
|
90
77
|
connection.run('INSERT OR REPLACE INTO conversation_reads (conversation, read, partial) VALUES (?, ?, ?)', [conversation, read.at, read.partial ? 1 : 0]);
|
|
@@ -96,6 +83,7 @@ function accepted(row) {
|
|
|
96
83
|
identity: text(row.identity),
|
|
97
84
|
turn: text(row.turn),
|
|
98
85
|
position: text(row.position),
|
|
86
|
+
change: text(row.change),
|
|
99
87
|
text: text(row.text),
|
|
100
88
|
message: JSON.parse(text(row.message)),
|
|
101
89
|
};
|
|
@@ -107,7 +95,7 @@ function holding(phrase) {
|
|
|
107
95
|
}
|
|
108
96
|
export function messageWindow(connection, conversation, limit, before, phrase) {
|
|
109
97
|
const held = holding(phrase);
|
|
110
|
-
const rows = connection.rows(`SELECT identity, turn, position, message, text FROM conversation_messages WHERE conversation = ?${held.sql}${before === null ? '' : ' AND (position < ? OR (position = ? AND identity < ?))'} ORDER BY position DESC, identity DESC LIMIT ?`, before === null
|
|
98
|
+
const rows = connection.rows(`SELECT identity, turn, position, change, message, text FROM conversation_messages WHERE conversation = ?${held.sql}${before === null ? '' : ' AND (position < ? OR (position = ? AND identity < ?))'} ORDER BY position DESC, identity DESC LIMIT ?`, before === null
|
|
111
99
|
? [conversation, ...held.bind, limit + 1]
|
|
112
100
|
: [conversation, ...held.bind, before[0], before[0], before[1], limit + 1]);
|
|
113
101
|
return { messages: rows.slice(0, limit).map(accepted).reverse(), more: rows.length > limit };
|
|
@@ -118,11 +106,11 @@ export function messageCount(connection, conversation, phrase) {
|
|
|
118
106
|
return Number(counted?.held ?? 0);
|
|
119
107
|
}
|
|
120
108
|
function textOrNull(value) {
|
|
121
|
-
return value === null
|
|
109
|
+
return value === null ? null : text(value);
|
|
122
110
|
}
|
|
123
111
|
function heldSource(source, sender) {
|
|
124
112
|
return {
|
|
125
|
-
source: source === null
|
|
113
|
+
source: source === null ? null : JSON.parse(text(source)),
|
|
126
114
|
sender: textOrNull(sender),
|
|
127
115
|
};
|
|
128
116
|
}
|
|
@@ -148,19 +136,13 @@ export function conversationRows(connection, conversations) {
|
|
|
148
136
|
},
|
|
149
137
|
}));
|
|
150
138
|
}
|
|
151
|
-
export function jobMarkers(connection, conversation) {
|
|
152
|
-
return connection
|
|
153
|
-
.rows(JOB_MARKERS, [conversation])
|
|
154
|
-
.map((row) => ({ said: text(row.said), at: text(row.at) }));
|
|
155
|
-
}
|
|
156
139
|
export function turnArrived(connection, conversation, turn) {
|
|
157
140
|
return (connection.rows('SELECT 1 FROM conversation_messages WHERE conversation = ? AND turn = ? LIMIT 1', [conversation, turn]).length > 0);
|
|
158
141
|
}
|
|
159
142
|
export function droppedMessages(connection, conversations) {
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
}
|
|
143
|
+
const named = [JSON.stringify(conversations)];
|
|
144
|
+
connection.run('DELETE FROM conversation_messages WHERE conversation IN (SELECT value FROM json_each(?))', named);
|
|
145
|
+
connection.run('DELETE FROM conversation_reads WHERE conversation IN (SELECT value FROM json_each(?))', named);
|
|
164
146
|
}
|
|
165
147
|
export function forgottenMessages(connection) {
|
|
166
148
|
connection.run('DELETE FROM conversation_messages');
|
package/dist/model.d.ts
CHANGED
|
@@ -50,7 +50,6 @@ export type ValidationReceipt = {
|
|
|
50
50
|
source: Open<'current' | 'cached'>;
|
|
51
51
|
};
|
|
52
52
|
export declare const NO_MODEL: ModelState;
|
|
53
|
-
export declare function definitionOf(state: ModelState, type: string | undefined): Definition | undefined;
|
|
54
53
|
export declare function modelTypes(state: ModelState): TypesResult;
|
|
55
54
|
export declare function storedModel(state: ModelState): StoredModel;
|
|
56
55
|
//# sourceMappingURL=model.d.ts.map
|
package/dist/model.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACtE,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEtC,MAAM,MAAM,aAAa,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAClE,MAAM,MAAM,aAAa,GAAG,aAAa,GAAG;IAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC;AAC/F,MAAM,MAAM,sBAAsB,GAAG,IAAI,CAAC,cAAc,GAAG,SAAS,GAAG,cAAc,CAAC,CAAC;AACvF,MAAM,MAAM,WAAW,GACnB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,aAAa,CAAA;CAAE,GAC1C;IAAE,IAAI,EAAE,mBAAmB,CAAC;IAAC,MAAM,EAAE,sBAAsB,CAAA;CAAE,CAAC;AAClE,MAAM,MAAM,MAAM,GAAG,UAAU,CAAC;AAChC,MAAM,MAAM,UAAU,GAClB;IAAE,MAAM,EAAE,aAAa,CAAC;IAAC,MAAM,EAAE,sBAAsB,CAAA;CAAE,GACzD;IACE,MAAM,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC7B,QAAQ,EAAE,aAAa,CAAC;IACxB,YAAY,EAAE,aAAa,CAAC;IAC5B,KAAK,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC;CAC/B,CAAC;AACN,MAAM,MAAM,WAAW,GACnB,OAAO,CAAC,UAAU,EAAE;IAAE,MAAM,EAAE,aAAa,CAAA;CAAE,CAAC,GAC9C,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE;IAAE,MAAM,EAAE,SAAS,GAAG,QAAQ,CAAA;CAAE,CAAC,EAAE,OAAO,CAAC,CAAC;AACzE,MAAM,MAAM,WAAW,GACnB;IAAE,MAAM,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;IAAC,MAAM,EAAE,sBAAsB,CAAC;IAAC,KAAK,EAAE,IAAI,CAAA;CAAE,GAC5E;IACE,MAAM,EAAE,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC,CAAC;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,aAAa,CAAC;IAC5B,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IACzB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB,CAAC;AACN,MAAM,MAAM,iBAAiB,GAAG;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC,CAAC;CACpC,CAAC;AACF,eAAO,MAAM,QAAQ,EAAE,UAA8D,CAAC;AACtF,wBAAgB,
|
|
1
|
+
{"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACtE,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEtC,MAAM,MAAM,aAAa,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAClE,MAAM,MAAM,aAAa,GAAG,aAAa,GAAG;IAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC;AAC/F,MAAM,MAAM,sBAAsB,GAAG,IAAI,CAAC,cAAc,GAAG,SAAS,GAAG,cAAc,CAAC,CAAC;AACvF,MAAM,MAAM,WAAW,GACnB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,aAAa,CAAA;CAAE,GAC1C;IAAE,IAAI,EAAE,mBAAmB,CAAC;IAAC,MAAM,EAAE,sBAAsB,CAAA;CAAE,CAAC;AAClE,MAAM,MAAM,MAAM,GAAG,UAAU,CAAC;AAChC,MAAM,MAAM,UAAU,GAClB;IAAE,MAAM,EAAE,aAAa,CAAC;IAAC,MAAM,EAAE,sBAAsB,CAAA;CAAE,GACzD;IACE,MAAM,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC7B,QAAQ,EAAE,aAAa,CAAC;IACxB,YAAY,EAAE,aAAa,CAAC;IAC5B,KAAK,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC;CAC/B,CAAC;AACN,MAAM,MAAM,WAAW,GACnB,OAAO,CAAC,UAAU,EAAE;IAAE,MAAM,EAAE,aAAa,CAAA;CAAE,CAAC,GAC9C,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE;IAAE,MAAM,EAAE,SAAS,GAAG,QAAQ,CAAA;CAAE,CAAC,EAAE,OAAO,CAAC,CAAC;AACzE,MAAM,MAAM,WAAW,GACnB;IAAE,MAAM,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;IAAC,MAAM,EAAE,sBAAsB,CAAC;IAAC,KAAK,EAAE,IAAI,CAAA;CAAE,GAC5E;IACE,MAAM,EAAE,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC,CAAC;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,aAAa,CAAC;IAC5B,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IACzB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB,CAAC;AACN,MAAM,MAAM,iBAAiB,GAAG;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC,CAAC;CACpC,CAAC;AACF,eAAO,MAAM,QAAQ,EAAE,UAA8D,CAAC;AACtF,wBAAgB,UAAU,CAAC,KAAK,EAAE,UAAU,GAAG,WAAW,CAczD;AACD,wBAAgB,WAAW,CAAC,KAAK,EAAE,UAAU,GAAG,WAAW,CAI1D"}
|
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 }
|
package/dist/models.d.ts
CHANGED
|
@@ -1,14 +1,10 @@
|
|
|
1
|
-
import type { ScopedRefusal } from './adapter.js';
|
|
1
|
+
import type { RoomDeclaration, ScopedRefusal } from './adapter.js';
|
|
2
2
|
import { type ModelState } from './model.js';
|
|
3
|
-
import { type ReplicaRecord } from './replica.js';
|
|
4
3
|
import type { Runtime } from './runtime.js';
|
|
5
|
-
import type { RoomDeclaration } from './socket.js';
|
|
6
4
|
import type { RuntimeStore } from './store.js';
|
|
7
|
-
export declare function declaredAsHeld(held: ReplicaRecord | undefined, room: RoomDeclaration): boolean;
|
|
8
5
|
export declare function revoked(model: ModelState | undefined): boolean;
|
|
9
|
-
export declare function
|
|
10
|
-
export declare function
|
|
11
|
-
export declare function
|
|
12
|
-
export declare function settleModels(runtime: Runtime, held: readonly RoomDeclaration[], status: 'current' | 'cached', local: RuntimeStore): Promise<void>;
|
|
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>;
|
|
13
9
|
export declare function cachedModels(runtime: Runtime, local: RuntimeStore): Promise<void>;
|
|
14
10
|
//# sourceMappingURL=models.d.ts.map
|
package/dist/models.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"models.d.ts","sourceRoot":"","sources":["../src/models.ts"],"names":[],"mappings":"
|
|
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,iBAoB7B;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,iBA+CpB;AAED,wBAAsB,YAAY,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAkBvF"}
|