@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/README.md
CHANGED
|
@@ -12,14 +12,14 @@ npm install @agentshouse/mdruntime
|
|
|
12
12
|
|
|
13
13
|
## Entries
|
|
14
14
|
|
|
15
|
-
| Entry | For
|
|
16
|
-
| ------------------------------- |
|
|
17
|
-
| `@agentshouse/mdruntime/client` | The host's client: `connectMdRuntime(port)`
|
|
18
|
-
| `@agentshouse/mdruntime/host` | The host that serves a Runtime: `serveMdRuntime`
|
|
19
|
-
| `@agentshouse/mdruntime` | Shared types
|
|
20
|
-
| `@agentshouse/mdruntime/memory` | Tests: `createMemoryAdapter`, an in-memory Adapter
|
|
21
|
-
| `@agentshouse/mdruntime/tables` | The host's database: the Authored store's and
|
|
22
|
-
| `@agentshouse/mdruntime/react` | React over the client: `useObserve`, `useSave`
|
|
15
|
+
| Entry | For |
|
|
16
|
+
| ------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
17
|
+
| `@agentshouse/mdruntime/client` | The host's client: `connectMdRuntime(port)` |
|
|
18
|
+
| `@agentshouse/mdruntime/host` | The host that serves a Runtime: `serveMdRuntime` |
|
|
19
|
+
| `@agentshouse/mdruntime` | Shared types |
|
|
20
|
+
| `@agentshouse/mdruntime/memory` | Tests: `createMemoryAdapter`, an in-memory Adapter |
|
|
21
|
+
| `@agentshouse/mdruntime/tables` | The host's database: `formatted` lays it out for a device format, keeping the Authored store's tables and creating any it lacks, and `answerRuntime` answers it |
|
|
22
|
+
| `@agentshouse/mdruntime/react` | React over the client: `useObserve`, `useSave`; `useExpected`, a reader of an expectation store; `useLane`, a reader of an act lane |
|
|
23
23
|
|
|
24
24
|
## Usage
|
|
25
25
|
|
|
@@ -33,24 +33,26 @@ const rooms = await runtime.rooms();
|
|
|
33
33
|
const notes = await runtime.query({ types: ['note'], select: 'all', limit: 20 });
|
|
34
34
|
```
|
|
35
35
|
|
|
36
|
-
`observe('storage-loss')` reports `null
|
|
37
|
-
|
|
38
|
-
|
|
36
|
+
`observe('storage-loss')` reports `null`, the stable code `storage-loss` when
|
|
37
|
+
unsynchronized Room Drafts and Pending Changes were lost, or `visit` while the host holds
|
|
38
|
+
the database in memory, which ends with the visit; the readiness `persistence` answer is then
|
|
39
|
+
`memory`. The host supplies the user-facing wording.
|
|
39
40
|
|
|
40
41
|
In House the bridge object the page holds as `window.houseBridge` places the Chat, which
|
|
41
|
-
House serves with the page: install and bundle nothing for it. Mount it in an element
|
|
42
|
-
|
|
42
|
+
House serves with the page: install and bundle nothing for it. Mount it in an element it
|
|
43
|
+
fills, where it lays out the User's chats by the element's width, themed by CSS custom
|
|
44
|
+
properties on that element, or as the Chat button, House's dot that opens it in a sheet:
|
|
43
45
|
|
|
44
46
|
```ts
|
|
45
|
-
const chat = await window.houseBridge.chat.mount(element, {
|
|
47
|
+
const chat = await window.houseBridge.chat.mount(element, { conversation });
|
|
46
48
|
element.style.setProperty('--chat-accent', '#2a6cf0');
|
|
47
|
-
chat.update({
|
|
48
|
-
chat.
|
|
49
|
+
chat.update({ conversation: null, agent });
|
|
50
|
+
const button = await window.houseBridge.chat.mountButton({});
|
|
51
|
+
button.open({ agent });
|
|
49
52
|
```
|
|
50
53
|
|
|
51
|
-
The rules an App's agent follows, including Local Query, search, Room
|
|
52
|
-
|
|
53
|
-
`guide/open` opens.
|
|
54
|
+
The rules an App's agent follows, including Local Query, search, Room Draft, Save and the
|
|
55
|
+
Chat, are the `apps/` pages of House's Guide, which House's `guide/open` opens.
|
|
54
56
|
|
|
55
57
|
## License
|
|
56
58
|
|
package/dist/acceptance.d.ts
CHANGED
|
@@ -1,6 +1,3 @@
|
|
|
1
1
|
import type { Runtime } from './runtime.js';
|
|
2
|
-
import type { RuntimeStore } from './store.js';
|
|
3
|
-
export declare function unpair(runtime: Runtime, local: RuntimeStore): Promise<void>;
|
|
4
2
|
export declare function submitLater(runtime: Runtime, locator: string): void;
|
|
5
|
-
export declare function submitAll(runtime: Runtime): Promise<void>;
|
|
6
3
|
//# sourceMappingURL=acceptance.d.ts.map
|
package/dist/acceptance.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"acceptance.d.ts","sourceRoot":"","sources":["../src/acceptance.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"acceptance.d.ts","sourceRoot":"","sources":["../src/acceptance.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AA0V5C,wBAAgB,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,QAK5D"}
|
package/dist/acceptance.js
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
|
+
import { refusalError } from './failure.js';
|
|
1
2
|
import { changeSet } from './change-set.js';
|
|
3
|
+
import { declared } from './declaration.js';
|
|
2
4
|
import { leaving as leavingIn, partnerOf } from './change.js';
|
|
3
|
-
import { runtimeError } from './failure.js';
|
|
4
5
|
import { olderThan, showing } from './install.js';
|
|
5
|
-
import {
|
|
6
|
+
import { scoped } from './models.js';
|
|
7
|
+
import { answered, settle } from './queue.js';
|
|
6
8
|
import { refuse } from './refusal.js';
|
|
7
|
-
import {
|
|
8
|
-
import { batchFile
|
|
9
|
+
import { returnedPaths, returning, slicing } from './replica.js';
|
|
10
|
+
import { batchFile } from './saves.js';
|
|
9
11
|
import { rest, roomUnreadable, statusShown } from './shown.js';
|
|
12
|
+
import { advanced, withhold } from './sync.js';
|
|
10
13
|
import { unconfirmed } from './transfer.js';
|
|
11
14
|
import { stepped } from './turn.js';
|
|
12
|
-
function pendingKey(locator, id) {
|
|
13
|
-
return `${locator}\u0000${id}`;
|
|
14
|
-
}
|
|
15
15
|
async function mark(runtime, local, locator, batch, submission, lost) {
|
|
16
|
-
const { store, socket } = runtime;
|
|
16
|
+
const { store, socket, presence } = runtime;
|
|
17
17
|
const partner = partnerOf(batch, locator);
|
|
18
18
|
for (const held of partner === null ? [locator] : [locator, partner]) {
|
|
19
19
|
const { state, room } = await local.pending(held, batch.id);
|
|
@@ -23,116 +23,86 @@ async function mark(runtime, local, locator, batch, submission, lost) {
|
|
|
23
23
|
continue;
|
|
24
24
|
}
|
|
25
25
|
await local.submit(held, batch.id, submission, lost);
|
|
26
|
-
if (
|
|
26
|
+
if (presence.lost(held))
|
|
27
27
|
continue;
|
|
28
28
|
if (room)
|
|
29
29
|
store.changed(changeSet(held, { queue: true }));
|
|
30
30
|
}
|
|
31
31
|
statusShown(runtime);
|
|
32
32
|
}
|
|
33
|
-
async function keepUpload({
|
|
33
|
+
async function keepUpload({ socket, presence }, local, locator, identifier, upload) {
|
|
34
34
|
if (!socket.continuing())
|
|
35
|
-
throw new Error(
|
|
35
|
+
throw new Error();
|
|
36
36
|
await local.keepUpload(locator, identifier, upload);
|
|
37
|
-
if (
|
|
38
|
-
throw
|
|
37
|
+
if (presence.lost(locator))
|
|
38
|
+
throw new Error();
|
|
39
39
|
if (!socket.continuing())
|
|
40
|
-
throw new Error(
|
|
41
|
-
}
|
|
42
|
-
function leaving(batch, result) {
|
|
43
|
-
return {
|
|
44
|
-
batch,
|
|
45
|
-
returned: {
|
|
46
|
-
kind: result.kind,
|
|
47
|
-
code: result.code,
|
|
48
|
-
fields: result.fields,
|
|
49
|
-
retryable: result.retryable,
|
|
50
|
-
},
|
|
51
|
-
};
|
|
52
|
-
}
|
|
53
|
-
function logAccepted({ journal }, locator, submitted, accepted) {
|
|
54
|
-
journal.record(`outcome ${locator} ${submitted.id} accepted ${accepted.roomVersion}` +
|
|
55
|
-
(accepted.author === undefined ? '' : ` author ${accepted.author}`) +
|
|
56
|
-
(accepted.time === undefined ? '' : ` time ${accepted.time}`));
|
|
57
|
-
}
|
|
58
|
-
function settling(acceptance) {
|
|
59
|
-
return acceptance !== null && 'apply' in acceptance;
|
|
40
|
+
throw new Error();
|
|
60
41
|
}
|
|
61
|
-
function
|
|
62
|
-
return
|
|
42
|
+
function restands(adoptions) {
|
|
43
|
+
return adoptions.flatMap((one) => (one === null || !('record' in one) ? [] : [one]));
|
|
63
44
|
}
|
|
64
|
-
async function
|
|
45
|
+
async function adoption(runtime, room, current, local, submitted, accepted) {
|
|
65
46
|
const { store, socket } = runtime;
|
|
66
47
|
if (!socket.continuing())
|
|
67
48
|
return unconfirmed;
|
|
68
|
-
const work = await store.work(room.locator);
|
|
69
|
-
const current = work.replica;
|
|
70
49
|
if (current === undefined || !current.queue.some((batch) => batch.id === submitted.id)) {
|
|
71
50
|
return null;
|
|
72
51
|
}
|
|
73
52
|
const held = current.record.roomVersion;
|
|
74
|
-
logAccepted(runtime, room.locator, submitted, accepted);
|
|
75
53
|
let record = current.record;
|
|
76
|
-
let
|
|
54
|
+
let adopted;
|
|
77
55
|
if (!socket.reads.reached(room.locator, held, accepted.roomVersion) &&
|
|
78
56
|
!olderThan(runtime, room.locator, accepted.roomVersion, held)) {
|
|
79
57
|
const paths = [...returnedPaths(submitted, accepted)];
|
|
80
58
|
const confirmedLayer = await stepped(slicing(await local.entries(record.key, 'confirmed', paths), paths));
|
|
81
|
-
|
|
59
|
+
adopted = await stepped(returning(confirmedLayer, submitted, accepted, accepted.roomVersion, store.composed(record)));
|
|
82
60
|
record = {
|
|
83
61
|
...record,
|
|
84
62
|
roomVersion: socket.follows(room.locator, held, accepted.roomVersion)
|
|
85
63
|
? accepted.roomVersion
|
|
86
64
|
: held,
|
|
87
65
|
};
|
|
88
|
-
changes = back;
|
|
89
66
|
}
|
|
90
|
-
const settled = await settlement(runtime, local, room.locator, work, record, current.queue.filter((batch) => batch.id !== submitted.id), { room: true, ...(changes === undefined ? {} : { changes }) });
|
|
91
67
|
const reached = record.roomVersion;
|
|
92
68
|
return {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
69
|
+
locator: room.locator,
|
|
70
|
+
record,
|
|
71
|
+
accepted: submitted.id,
|
|
72
|
+
...(adopted === undefined ? {} : { adopted }),
|
|
73
|
+
after() {
|
|
96
74
|
showing(runtime, room.locator, accepted.roomVersion, reached);
|
|
97
|
-
readable(
|
|
98
|
-
return set;
|
|
75
|
+
runtime.presence.readable(room.locator);
|
|
99
76
|
},
|
|
100
77
|
};
|
|
101
78
|
}
|
|
102
|
-
async function adoptedTogether(runtime, local, acceptances) {
|
|
103
|
-
const settlements = acceptances.filter(settling);
|
|
104
|
-
if (settlements.length > 0) {
|
|
105
|
-
const set = await together(runtime, local, settlements);
|
|
106
|
-
void statusShown(runtime);
|
|
107
|
-
void runtime.store.changed(set);
|
|
108
|
-
}
|
|
109
|
-
await unpair(runtime, local);
|
|
110
|
-
}
|
|
111
79
|
async function adopted(runtime, room, local, submitted, accepted) {
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
await
|
|
115
|
-
|
|
80
|
+
let kept = true;
|
|
81
|
+
await settle(runtime, [room.locator], async (held) => {
|
|
82
|
+
const adopting = await adoption(runtime, room, held.get(room.locator)?.replica, local, submitted, accepted);
|
|
83
|
+
kept = adopting !== unconfirmed;
|
|
84
|
+
return restands([adopting]);
|
|
116
85
|
});
|
|
117
|
-
return
|
|
86
|
+
return kept;
|
|
118
87
|
}
|
|
119
88
|
async function adoptedMove(runtime, room, partner, local, submitted, accepted) {
|
|
120
|
-
const
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
const left = await
|
|
124
|
-
const
|
|
89
|
+
const other = runtime.presence.room(partner);
|
|
90
|
+
let kept = true;
|
|
91
|
+
await settle(runtime, [room.locator, partner], async (held) => {
|
|
92
|
+
const left = await adoption(runtime, room, held.get(room.locator)?.replica, local, submitted, accepted);
|
|
93
|
+
const there = held.get(partner)?.replica;
|
|
94
|
+
const arriving = there?.queue.find((batch) => batch.id === submitted.id);
|
|
125
95
|
const arrived = other === undefined || arriving === undefined || accepted.destination === undefined
|
|
126
96
|
? null
|
|
127
|
-
: await
|
|
97
|
+
: await adoption(runtime, other, there, local, arriving, {
|
|
128
98
|
kind: 'accepted',
|
|
129
99
|
...accepted.destination,
|
|
130
100
|
});
|
|
131
|
-
|
|
132
|
-
return
|
|
101
|
+
kept = left !== unconfirmed;
|
|
102
|
+
return restands([left, arrived]);
|
|
133
103
|
});
|
|
134
104
|
submitLater(runtime, partner);
|
|
135
|
-
return
|
|
105
|
+
return kept;
|
|
136
106
|
}
|
|
137
107
|
async function behindIn({ store }, locator, batch) {
|
|
138
108
|
const local = await store.open();
|
|
@@ -142,38 +112,12 @@ async function behindIn({ store }, locator, batch) {
|
|
|
142
112
|
]);
|
|
143
113
|
return room ? order.indexOf(batch.id) > 0 : order.length > 0;
|
|
144
114
|
}
|
|
145
|
-
async function unpaired(local, skipped) {
|
|
146
|
-
const { queued, moving } = await local.moving();
|
|
147
|
-
for (const { locator, batch, state } of moving) {
|
|
148
|
-
const partner = partnerOf(batch, locator);
|
|
149
|
-
if (partner === null || skipped.has(pendingKey(locator, batch.id)))
|
|
150
|
-
continue;
|
|
151
|
-
if (queued.get(partner)?.includes(batch.id) === true)
|
|
152
|
-
continue;
|
|
153
|
-
if (!leavingIn(batch, locator) || withdrawable(new Map([[batch.id, state]]))(batch)) {
|
|
154
|
-
return { locator, batch };
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
return null;
|
|
158
|
-
}
|
|
159
|
-
export async function unpair(runtime, local) {
|
|
160
|
-
const { store, socket } = runtime;
|
|
161
|
-
const handled = new Set();
|
|
162
|
-
for (let held = await unpaired(local, handled); held !== null && socket.continuing(); held = await unpaired(local, handled)) {
|
|
163
|
-
const { locator, batch } = held;
|
|
164
|
-
handled.add(pendingKey(locator, batch.id));
|
|
165
|
-
store.changed(await together(runtime, local, [await unpairing(runtime, local, locator, [batch])]));
|
|
166
|
-
}
|
|
167
|
-
if (handled.size === 0)
|
|
168
|
-
return;
|
|
169
|
-
statusShown(runtime);
|
|
170
|
-
}
|
|
171
115
|
async function submitRoom(runtime, room, local, authorized, progress, signal) {
|
|
172
|
-
const { store, socket,
|
|
116
|
+
const { store, socket, presence } = runtime;
|
|
173
117
|
while (socket.continuing() &&
|
|
174
118
|
socket.session.now().authorization !== undefined &&
|
|
175
119
|
!signal.aborted) {
|
|
176
|
-
const headId = (await local.order(room.locator)).find((id) => store.
|
|
120
|
+
const headId = (await local.order(room.locator)).find((id) => store.conflicted.of(room.locator, id) === undefined);
|
|
177
121
|
if (headId === undefined)
|
|
178
122
|
return 'done';
|
|
179
123
|
const [head, pending] = await Promise.all([
|
|
@@ -202,27 +146,24 @@ async function submitRoom(runtime, room, local, authorized, progress, signal) {
|
|
|
202
146
|
}
|
|
203
147
|
if (socket.writesHeld()) {
|
|
204
148
|
progress.complete = false;
|
|
205
|
-
journal.record(`submission ${room.locator} ${head.id} held`);
|
|
206
149
|
return 'done';
|
|
207
150
|
}
|
|
208
151
|
const lost = earlier || submission.state === 'submitted';
|
|
209
152
|
let result;
|
|
210
|
-
journal.record(`submission ${room.locator} ${head.id}`);
|
|
211
153
|
await store.exclusive(() => mark(runtime, local, room.locator, head, { state: 'submitted' }, lost));
|
|
212
|
-
if (socket.session.now().paused ||
|
|
154
|
+
if (socket.session.now().paused || presence.lost(room.locator))
|
|
213
155
|
return 'done';
|
|
214
156
|
if (signal.aborted || socket.writesHeld()) {
|
|
215
157
|
await store.exclusive(() => mark(runtime, local, room.locator, head, submission, earlier));
|
|
216
158
|
if (signal.aborted)
|
|
217
159
|
return 'done';
|
|
218
160
|
progress.complete = false;
|
|
219
|
-
journal.record(`submission ${room.locator} ${head.id} held`);
|
|
220
161
|
return 'done';
|
|
221
162
|
}
|
|
222
163
|
const opensBefore = socket.session.now().openSignals;
|
|
223
164
|
const answeredHere = socket.awaitingAnswer(room.locator);
|
|
224
165
|
const answeredThere = partner === null ? () => { } : socket.awaitingAnswer(partner);
|
|
225
|
-
const
|
|
166
|
+
const heard = () => {
|
|
226
167
|
answeredHere();
|
|
227
168
|
answeredThere();
|
|
228
169
|
};
|
|
@@ -234,29 +175,33 @@ async function submitRoom(runtime, room, local, authorized, progress, signal) {
|
|
|
234
175
|
...(state?.upload === undefined ? {} : { upload: state.upload }),
|
|
235
176
|
}, (upload) => store.exclusive(() => keepUpload(runtime, local, room.locator, head.id, upload)));
|
|
236
177
|
}
|
|
237
|
-
catch {
|
|
238
|
-
|
|
178
|
+
catch (error) {
|
|
179
|
+
runtime.retries.failed('sending', submitting(room.locator), error);
|
|
180
|
+
heard();
|
|
239
181
|
progress.complete = false;
|
|
240
182
|
if (socket.continuing())
|
|
241
183
|
progress.reachable = false;
|
|
242
184
|
return 'again';
|
|
243
185
|
}
|
|
244
186
|
if (signal.aborted) {
|
|
245
|
-
|
|
187
|
+
heard();
|
|
246
188
|
return 'done';
|
|
247
189
|
}
|
|
248
190
|
if (result.kind !== 'accepted' || !socket.continuing())
|
|
249
|
-
|
|
191
|
+
heard();
|
|
250
192
|
if (!socket.continuing())
|
|
251
193
|
return 'done';
|
|
194
|
+
if (result.kind === 'accepted')
|
|
195
|
+
runtime.retries.succeeded('sending', submitting(room.locator));
|
|
252
196
|
if (result.kind === 'transport-uncertainty') {
|
|
197
|
+
runtime.retries.uncertain('sending', submitting(room.locator), result);
|
|
253
198
|
progress.complete = false;
|
|
254
199
|
progress.reachable = false;
|
|
255
200
|
return 'again';
|
|
256
201
|
}
|
|
257
202
|
if (result.kind === 'room-not-readable') {
|
|
258
203
|
progress.complete = false;
|
|
259
|
-
roomUnreadable(runtime,
|
|
204
|
+
roomUnreadable(runtime, (presence.room(result.locator) ?? room).locator);
|
|
260
205
|
return 'done';
|
|
261
206
|
}
|
|
262
207
|
if (result.kind === 'revoked-authorization') {
|
|
@@ -264,84 +209,54 @@ async function submitRoom(runtime, room, local, authorized, progress, signal) {
|
|
|
264
209
|
return 'done';
|
|
265
210
|
}
|
|
266
211
|
if (result.kind === 'scoped-refusal') {
|
|
267
|
-
await
|
|
212
|
+
await scoped(runtime, result, room.locator, declared(room));
|
|
268
213
|
progress.complete = false;
|
|
269
214
|
return 'done';
|
|
270
215
|
}
|
|
271
216
|
if (result.kind === 'write-halted') {
|
|
272
|
-
journal.record(`outcome ${room.locator} ${head.id} write-halted`);
|
|
273
217
|
await store.exclusive(() => mark(runtime, local, room.locator, head, { state: 'waiting' }, lost));
|
|
274
218
|
if (!socket.haltedSince(opensBefore))
|
|
275
219
|
continue;
|
|
276
220
|
progress.complete = false;
|
|
277
221
|
return 'done';
|
|
278
222
|
}
|
|
279
|
-
const other = partner === null ? undefined :
|
|
280
|
-
if (result.kind === 'conflicted' ||
|
|
281
|
-
result.kind === 'rejected' ||
|
|
282
|
-
result.kind === 'retryable-refusal') {
|
|
283
|
-
journal.record(`outcome ${room.locator} ${head.id} ${result.kind}` +
|
|
284
|
-
(result.kind === 'conflicted' && result.roomVersion !== undefined
|
|
285
|
-
? ` ${result.roomVersion}`
|
|
286
|
-
: ''));
|
|
287
|
-
journal.record(`refusal ${result.kind} ${result.code}`);
|
|
288
|
-
}
|
|
223
|
+
const other = partner === null ? undefined : presence.room(partner);
|
|
289
224
|
if (result.kind === 'retryable-refusal') {
|
|
225
|
+
runtime.retries.failed('sending', submitting(room.locator), refusalError(result));
|
|
290
226
|
const reset = result.reset;
|
|
291
227
|
progress.complete = false;
|
|
292
228
|
await store.exclusive(() => mark(runtime, local, room.locator, head, reset === undefined ? { state: 'waiting' } : { state: 'reset', reset }, lost));
|
|
293
229
|
return reset === undefined ? 'again' : { at: Date.parse(reset) };
|
|
294
230
|
}
|
|
295
231
|
if (result.kind === 'conflicted' || result.kind === 'rejected') {
|
|
296
|
-
const left = leaving(head, result);
|
|
297
232
|
const refreshed = async () => ({
|
|
298
|
-
there: other === undefined ? null : await advanced(other, local, authorized),
|
|
299
|
-
here: await advanced(room, local, authorized),
|
|
233
|
+
there: other === undefined ? null : await advanced(runtime, other, local, authorized),
|
|
234
|
+
here: await advanced(runtime, room, local, authorized),
|
|
300
235
|
});
|
|
301
236
|
const judged = result.kind === 'conflicted' && other !== undefined ? await refreshed() : null;
|
|
302
237
|
if (judged !== null && (judged.there !== null || judged.here !== null)) {
|
|
303
238
|
await store.exclusive(() => mark(runtime, local, room.locator, head, { state: 'waiting' }, lost));
|
|
304
239
|
if (other !== undefined && judged.there !== null) {
|
|
305
|
-
await withhold(judged.there, other, local, progress);
|
|
240
|
+
await withhold(runtime, judged.there, other, local, progress);
|
|
306
241
|
}
|
|
307
242
|
if (judged.here !== null)
|
|
308
|
-
await withhold(judged.here, room, local, progress);
|
|
243
|
+
await withhold(runtime, judged.here, room, local, progress);
|
|
309
244
|
return 'done';
|
|
310
245
|
}
|
|
311
|
-
await
|
|
312
|
-
if (!socket.continuing())
|
|
313
|
-
return;
|
|
314
|
-
const work = await store.work(room.locator);
|
|
315
|
-
const current = work.replica;
|
|
316
|
-
if (current === undefined || !current.queue.some((batch) => batch.id === head.id)) {
|
|
317
|
-
return;
|
|
318
|
-
}
|
|
319
|
-
const confirmedLayer = await sliceAt(store, current.record, 'confirmed', [head]);
|
|
320
|
-
const held = result.kind === 'conflicted' &&
|
|
321
|
-
(await landedWhole(store, room.locator, head, confirmedLayer, result.affected));
|
|
322
|
-
if (held &&
|
|
323
|
-
result.kind === 'conflicted' &&
|
|
324
|
-
partner === null &&
|
|
325
|
-
!landed(head, confirmedLayer)) {
|
|
326
|
-
store.landed.hold(room.locator, head.id, Object.fromEntries([...touchedBy([head])].map((path) => [path, confirmedLayer.revisions[path]])));
|
|
327
|
-
return;
|
|
328
|
-
}
|
|
329
|
-
store.changed(await settle(runtime, local, room.locator, work, current.record, current.queue.filter((batch) => batch.id !== head.id), { leaving: [held ? { ...left, returned: null } : left] }));
|
|
330
|
-
await unpair(runtime, local);
|
|
331
|
-
statusShown(runtime);
|
|
332
|
-
});
|
|
246
|
+
await answered(runtime, room.locator, head, result);
|
|
333
247
|
const { there, here } = judged ?? (await refreshed());
|
|
334
|
-
if (other !== undefined && there !== null)
|
|
335
|
-
await withhold(there, other, local, progress);
|
|
248
|
+
if (other !== undefined && there !== null) {
|
|
249
|
+
await withhold(runtime, there, other, local, progress);
|
|
250
|
+
}
|
|
336
251
|
if (here !== null) {
|
|
337
|
-
await withhold(here, room, local, progress);
|
|
252
|
+
await withhold(runtime, here, room, local, progress);
|
|
338
253
|
return 'done';
|
|
339
254
|
}
|
|
340
255
|
continue;
|
|
341
256
|
}
|
|
342
257
|
const kept = await (partner === null
|
|
343
258
|
? adopted(runtime, room, local, head, result)
|
|
344
|
-
: adoptedMove(runtime, room, partner, local, head, result)).finally(
|
|
259
|
+
: adoptedMove(runtime, room, partner, local, head, result)).finally(heard);
|
|
345
260
|
if (!kept) {
|
|
346
261
|
progress.complete = false;
|
|
347
262
|
return 'done';
|
|
@@ -349,14 +264,17 @@ async function submitRoom(runtime, room, local, authorized, progress, signal) {
|
|
|
349
264
|
}
|
|
350
265
|
return 'done';
|
|
351
266
|
}
|
|
267
|
+
function submitting(locator) {
|
|
268
|
+
return `submit ${locator}`;
|
|
269
|
+
}
|
|
352
270
|
export function submitLater(runtime, locator) {
|
|
353
271
|
if (runtime.localSaves)
|
|
354
272
|
return;
|
|
355
|
-
void runtime.recovery.attempt(
|
|
273
|
+
void runtime.recovery.attempt(submitting(locator), (signal) => submitPass(runtime, locator, signal));
|
|
356
274
|
}
|
|
357
275
|
async function submitPass(runtime, locator, signal) {
|
|
358
|
-
const { store, socket } = runtime;
|
|
359
|
-
const room =
|
|
276
|
+
const { store, socket, presence } = runtime;
|
|
277
|
+
const room = presence.room(locator);
|
|
360
278
|
if (!socket.continuing() || socket.stopping() || room === undefined) {
|
|
361
279
|
return 'done';
|
|
362
280
|
}
|
|
@@ -369,7 +287,8 @@ async function submitPass(runtime, locator, signal) {
|
|
|
369
287
|
return 'done';
|
|
370
288
|
next = await submitRoom(runtime, room, await store.open(), authorization, progress, signal);
|
|
371
289
|
}
|
|
372
|
-
catch {
|
|
290
|
+
catch (error) {
|
|
291
|
+
runtime.retries.failed('sending', submitting(locator), error);
|
|
373
292
|
progress.reachable = false;
|
|
374
293
|
next = 'again';
|
|
375
294
|
}
|
|
@@ -378,12 +297,3 @@ async function submitPass(runtime, locator, signal) {
|
|
|
378
297
|
await rest(runtime, progress);
|
|
379
298
|
return next === 'again' && !socket.isOpen() ? 'done' : next;
|
|
380
299
|
}
|
|
381
|
-
export async function submitAll(runtime) {
|
|
382
|
-
const { store } = runtime;
|
|
383
|
-
if (runtime.localSaves)
|
|
384
|
-
return;
|
|
385
|
-
for (const locator of await (await store.open()).queued()) {
|
|
386
|
-
if (!store.fences.has(locator))
|
|
387
|
-
submitLater(runtime, locator);
|
|
388
|
-
}
|
|
389
|
-
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { type Expected, type Expecting } from './expectation.js';
|
|
2
|
+
export type Ended = 'accepted' | 'refused' | 'unanswered' | 'unsent';
|
|
3
|
+
export type Send<O> = {
|
|
4
|
+
(name: string, input: unknown, sending: (operation: string) => Promise<O>): Promise<O>;
|
|
5
|
+
expect(expected: Expected): void;
|
|
6
|
+
};
|
|
7
|
+
export type LaneShown<O> = {
|
|
8
|
+
readonly busy: boolean;
|
|
9
|
+
readonly drawn: boolean;
|
|
10
|
+
readonly ended: O | null;
|
|
11
|
+
};
|
|
12
|
+
export type Lane<O> = {
|
|
13
|
+
run(steps: (send: Send<O>) => Promise<O>, expected?: Expected): Promise<O>;
|
|
14
|
+
shown(): LaneShown<O>;
|
|
15
|
+
subscribe(listener: () => void): () => void;
|
|
16
|
+
forget(): void;
|
|
17
|
+
};
|
|
18
|
+
export type Acting<O> = {
|
|
19
|
+
open(): Lane<O>;
|
|
20
|
+
};
|
|
21
|
+
export type ActingRules<O> = {
|
|
22
|
+
readonly store: Pick<Expecting, 'begin' | 'expect' | 'drop'>;
|
|
23
|
+
readonly uncertain: O;
|
|
24
|
+
ending(outcome: O): Ended;
|
|
25
|
+
acted?(): void;
|
|
26
|
+
mint?(): string;
|
|
27
|
+
settles?(operation: string): Promise<boolean>;
|
|
28
|
+
};
|
|
29
|
+
export declare function acting<O>(rules: ActingRules<O>): Acting<O>;
|
|
30
|
+
//# sourceMappingURL=act-lanes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"act-lanes.d.ts","sourceRoot":"","sources":["../src/act-lanes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,QAAQ,EAAE,KAAK,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAG/E,MAAM,MAAM,KAAK,GAAG,UAAU,GAAG,SAAS,GAAG,YAAY,GAAG,QAAQ,CAAC;AAErE,MAAM,MAAM,IAAI,CAAC,CAAC,IAAI;IACpB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACvF,MAAM,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAC;CAClC,CAAC;AAEF,MAAM,MAAM,SAAS,CAAC,CAAC,IAAI;IACzB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,IAAI,CAAC,CAAC,IAAI;IACpB,GAAG,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAC3E,KAAK,IAAI,SAAS,CAAC,CAAC,CAAC,CAAC;IACtB,SAAS,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC;IAC5C,MAAM,IAAI,IAAI,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,MAAM,CAAC,CAAC,IAAI;IACtB,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,WAAW,CAAC,CAAC,IAAI;IAC3B,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC,SAAS,EAAE,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC,CAAC;IAC7D,QAAQ,CAAC,SAAS,EAAE,CAAC,CAAC;IACtB,MAAM,CAAC,OAAO,EAAE,CAAC,GAAG,KAAK,CAAC;IAC1B,KAAK,CAAC,IAAI,IAAI,CAAC;IACf,IAAI,CAAC,IAAI,MAAM,CAAC;IAChB,OAAO,CAAC,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC/C,CAAC;AAUF,wBAAgB,MAAM,CAAC,CAAC,EAAE,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CA6N1D"}
|