@agentshouse/mdruntime 0.1.0-c5fe3b2cddda7 → 0.1.0-c6197367d5fad
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 +156 -89
- 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 +33 -23
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +43 -56
- 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 +8 -6
- package/dist/compile.d.ts.map +1 -1
- package/dist/compile.js +286 -336
- package/dist/connection.d.ts +5 -142
- package/dist/connection.d.ts.map +1 -1
- package/dist/connection.js +111 -4993
- package/dist/context.d.ts +2 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +7 -0
- 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 +72 -51
- package/dist/conversation.d.ts.map +1 -1
- package/dist/conversation.js +1001 -926
- 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 +11 -0
- package/dist/discovery.d.ts.map +1 -0
- package/dist/discovery.js +157 -0
- package/dist/download.d.ts +6 -0
- package/dist/download.d.ts.map +1 -0
- package/dist/download.js +42 -0
- package/dist/durability.d.ts +20 -0
- package/dist/durability.d.ts.map +1 -1
- package/dist/durability.js +7 -0
- package/dist/entry.d.ts +2 -2
- package/dist/entry.d.ts.map +1 -1
- package/dist/entry.js +18 -8
- 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 +21 -7
- package/dist/host.d.ts.map +1 -1
- package/dist/host.js +83 -41
- 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 +37 -14
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +17 -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 +9 -6
- package/dist/live.d.ts.map +1 -1
- package/dist/live.js +118 -36
- 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 +19 -2
- package/dist/media.d.ts.map +1 -1
- package/dist/media.js +105 -27
- package/dist/memory.d.ts +18 -6
- package/dist/memory.d.ts.map +1 -1
- package/dist/memory.js +214 -91
- package/dist/messages.d.ts +35 -5
- package/dist/messages.d.ts.map +1 -1
- package/dist/messages.js +109 -39
- 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 +28 -13
- package/dist/observation.d.ts.map +1 -1
- package/dist/observation.js +185 -81
- 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 +14 -210
- package/dist/query.d.ts.map +1 -1
- package/dist/query.js +3 -505
- 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 +16 -15
- package/dist/reach.d.ts.map +1 -1
- package/dist/reach.js +257 -148
- package/dist/react.d.ts +19 -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 -6
- 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 +2 -1
- package/dist/refresh.d.ts.map +1 -1
- package/dist/refresh.js +31 -3
- 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 -32
- 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 +34 -10
- package/dist/room-draft.d.ts.map +1 -1
- package/dist/room-draft.js +331 -111
- 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 -22
- package/dist/rows.d.ts.map +1 -1
- package/dist/rows.js +49 -186
- 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 +12 -63
- package/dist/search.d.ts.map +1 -1
- package/dist/search.js +9 -52
- 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 +35 -0
- package/dist/shown.d.ts.map +1 -0
- package/dist/shown.js +313 -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 +224 -0
- package/dist/store/records.d.ts.map +1 -0
- package/dist/store/records.js +466 -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 -143
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +171 -364
- package/dist/stored.d.ts +72 -35
- package/dist/stored.d.ts.map +1 -1
- package/dist/stored.js +337 -197
- package/dist/surface.d.ts +92 -0
- package/dist/surface.d.ts.map +1 -0
- package/dist/surface.js +251 -0
- package/dist/sync.d.ts +19 -0
- package/dist/sync.d.ts.map +1 -0
- package/dist/sync.js +538 -0
- package/dist/tables.d.ts +118 -67
- package/dist/tables.d.ts.map +1 -1
- package/dist/tables.js +199 -278
- 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 +72 -9
- package/dist/wire.d.ts.map +1 -1
- package/dist/wire.js +26 -5
- 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/fulltext.d.ts +0 -27
- package/dist/fulltext.d.ts.map +0 -1
- package/dist/fulltext.js +0 -370
- package/dist/log.d.ts +0 -5
- package/dist/log.d.ts.map +0 -1
- package/dist/log.js +0 -14
- package/dist/words.d.ts +0 -19
- package/dist/words.d.ts.map +0 -1
- package/dist/words.js +0 -156
package/dist/overlay.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import { apply,
|
|
1
|
+
import { apply, create, documentValue, parse, serialize, TYPE_FIELD, } from '@agentshouse/mdmodel';
|
|
2
|
+
import { definitionsAt } from './collection.js';
|
|
3
|
+
import { isPart, } from './change.js';
|
|
2
4
|
import { drafted, entriesIn, settling } from './shared.js';
|
|
3
5
|
import { ROW_WEIGHT } from './turn.js';
|
|
4
6
|
export function* acceptedBinaries(files) {
|
|
@@ -24,10 +26,6 @@ export function sameChange(left, right) {
|
|
|
24
26
|
left.author?.id === right.author?.id &&
|
|
25
27
|
left.author?.name === right.author?.name);
|
|
26
28
|
}
|
|
27
|
-
const EMPTY_FRONTMATTER = '---\n---\n';
|
|
28
|
-
function isPart(change) {
|
|
29
|
-
return change.kind === 'field' || change.kind === 'section' || change.kind === 'preamble';
|
|
30
|
-
}
|
|
31
29
|
function at(path, name) {
|
|
32
30
|
return `${path} ${name}`;
|
|
33
31
|
}
|
|
@@ -53,16 +51,27 @@ function* priorsOf(preconditions) {
|
|
|
53
51
|
preamble: (path) => preambles.get(path) ?? '',
|
|
54
52
|
};
|
|
55
53
|
}
|
|
56
|
-
function
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
54
|
+
export function composed(path, fields, sections, composition) {
|
|
55
|
+
const declared = fields[TYPE_FIELD];
|
|
56
|
+
const type = typeof declared === 'string' && declared !== '' ? declared : undefined;
|
|
57
|
+
const definition = definitionsAt(composition, path)(type);
|
|
58
|
+
return apply(create(type, definition), [
|
|
59
|
+
...Object.entries(fields).flatMap(([name, value]) => (name !== TYPE_FIELD || type === undefined) && documentValue(value)
|
|
60
|
+
? [{ kind: 'field', name, value, prior: undefined }]
|
|
61
|
+
: []),
|
|
62
|
+
...Object.entries(sections).map(([name, value]) => ({
|
|
63
|
+
kind: 'section',
|
|
64
|
+
name,
|
|
65
|
+
value,
|
|
66
|
+
prior: undefined,
|
|
67
|
+
})),
|
|
68
|
+
], definition);
|
|
69
|
+
}
|
|
70
|
+
export function compose(path, fields, sections, composition) {
|
|
71
|
+
const next = composed(path, fields, sections, composition);
|
|
72
|
+
if (next.outcome !== 'applied')
|
|
73
|
+
throw new Error(`the creation of ${path} writes no document`);
|
|
74
|
+
return serialize(next.document);
|
|
66
75
|
}
|
|
67
76
|
function edited(change, priors) {
|
|
68
77
|
if (change.kind === 'field')
|
|
@@ -81,17 +90,19 @@ function edited(change, priors) {
|
|
|
81
90
|
prior: priors.section(change.path, change.name),
|
|
82
91
|
};
|
|
83
92
|
}
|
|
84
|
-
function edit(staged, changes, priors) {
|
|
93
|
+
function edit(staged, changes, priors, composition) {
|
|
85
94
|
const path = changes[0].path;
|
|
86
95
|
delete staged.revisions[path];
|
|
87
96
|
const text = staged.documents[path];
|
|
88
97
|
if (text === undefined)
|
|
89
98
|
return changes.length;
|
|
90
|
-
const
|
|
99
|
+
const definitions = definitionsAt(composition, path);
|
|
100
|
+
const parsed = parse(text, path, definitions);
|
|
91
101
|
if (!parsed.ok)
|
|
92
102
|
return changes.length;
|
|
103
|
+
const definition = definitions(parsed.document.type);
|
|
93
104
|
const wanted = changes.map((change) => edited(change, priors));
|
|
94
|
-
const first = apply(parsed.document, wanted);
|
|
105
|
+
const first = apply(parsed.document, wanted, definition);
|
|
95
106
|
if (first.outcome === 'refuse')
|
|
96
107
|
return changes.length;
|
|
97
108
|
if (first.outcome === 'applied') {
|
|
@@ -100,7 +111,7 @@ function edit(staged, changes, priors) {
|
|
|
100
111
|
}
|
|
101
112
|
const stale = new Set(first.stale);
|
|
102
113
|
const kept = wanted.filter((_, at) => !stale.has(at));
|
|
103
|
-
const rest = apply(parsed.document, kept);
|
|
114
|
+
const rest = apply(parsed.document, kept, definition);
|
|
104
115
|
if (rest.outcome !== 'applied')
|
|
105
116
|
return changes.length;
|
|
106
117
|
staged.documents[path] = serialize(rest.document);
|
|
@@ -125,16 +136,21 @@ function relocate(staged, from, to) {
|
|
|
125
136
|
function moveHead(heads, from, to) {
|
|
126
137
|
const revision = heads.revisions[from];
|
|
127
138
|
const fileId = heads.fileIds[from];
|
|
139
|
+
const created = heads.created[from];
|
|
128
140
|
const change = heads.changes[from];
|
|
129
141
|
delete heads.revisions[from];
|
|
130
142
|
delete heads.fileIds[from];
|
|
143
|
+
delete heads.created[from];
|
|
131
144
|
delete heads.changes[from];
|
|
132
145
|
delete heads.fileIds[to];
|
|
146
|
+
delete heads.created[to];
|
|
133
147
|
delete heads.changes[to];
|
|
134
148
|
if (revision !== undefined)
|
|
135
149
|
heads.revisions[to] = revision;
|
|
136
150
|
if (fileId !== undefined)
|
|
137
151
|
heads.fileIds[to] = fileId;
|
|
152
|
+
if (created !== undefined)
|
|
153
|
+
heads.created[to] = created;
|
|
138
154
|
if (change !== undefined)
|
|
139
155
|
heads.changes[to] = change;
|
|
140
156
|
}
|
|
@@ -142,14 +158,18 @@ function erase(staged, path) {
|
|
|
142
158
|
delete staged.documents[path];
|
|
143
159
|
delete staged.revisions[path];
|
|
144
160
|
delete staged.fileIds[path];
|
|
161
|
+
delete staged.created[path];
|
|
145
162
|
delete staged.changes[path];
|
|
146
163
|
delete staged.binaries[path];
|
|
147
164
|
}
|
|
148
|
-
function stage(staged, change) {
|
|
165
|
+
function stage(staged, change, composition) {
|
|
149
166
|
if (change.kind === 'create') {
|
|
150
167
|
staged.documents[change.path] =
|
|
151
|
-
'content' in change
|
|
168
|
+
'content' in change
|
|
169
|
+
? change.content
|
|
170
|
+
: compose(change.path, change.fields, change.sections, composition);
|
|
152
171
|
delete staged.fileIds[change.path];
|
|
172
|
+
delete staged.created[change.path];
|
|
153
173
|
delete staged.changes[change.path];
|
|
154
174
|
return true;
|
|
155
175
|
}
|
|
@@ -194,15 +214,18 @@ function arrive(heads, change) {
|
|
|
194
214
|
heads.revisions[change.path] = change.revision;
|
|
195
215
|
if (change.fileId !== undefined)
|
|
196
216
|
heads.fileIds[change.path] = change.fileId;
|
|
217
|
+
if (change.created !== undefined)
|
|
218
|
+
heads.created[change.path] = change.created;
|
|
197
219
|
if (change.change !== undefined)
|
|
198
220
|
heads.changes[change.path] = change.change;
|
|
199
221
|
}
|
|
200
|
-
export function* overlaying(base, queue, unapplied) {
|
|
222
|
+
export function* overlaying(base, queue, composition, unapplied) {
|
|
201
223
|
const staged = {
|
|
202
224
|
documents: drafted(base.documents),
|
|
203
225
|
binaries: drafted(base.binaries),
|
|
204
226
|
revisions: drafted(base.revisions),
|
|
205
227
|
fileIds: drafted(base.fileIds),
|
|
228
|
+
created: drafted(base.created),
|
|
206
229
|
changes: drafted(base.changes),
|
|
207
230
|
};
|
|
208
231
|
for (const batch of queue) {
|
|
@@ -210,7 +233,7 @@ export function* overlaying(base, queue, unapplied) {
|
|
|
210
233
|
for (let index = 0; index < batch.changes.length; index += 1) {
|
|
211
234
|
const change = batch.changes[index];
|
|
212
235
|
if (!isPart(change)) {
|
|
213
|
-
if (!stage(staged, change))
|
|
236
|
+
if (!stage(staged, change, composition))
|
|
214
237
|
unapplied?.();
|
|
215
238
|
yield ROW_WEIGHT;
|
|
216
239
|
continue;
|
|
@@ -224,7 +247,7 @@ export function* overlaying(base, queue, unapplied) {
|
|
|
224
247
|
index += 1;
|
|
225
248
|
}
|
|
226
249
|
const text = staged.documents[change.path] ?? '';
|
|
227
|
-
for (let left = edit(staged, run, priors); left > 0; left -= 1)
|
|
250
|
+
for (let left = edit(staged, run, priors, composition); left > 0; left -= 1)
|
|
228
251
|
unapplied?.();
|
|
229
252
|
yield ROW_WEIGHT + text.length;
|
|
230
253
|
}
|
|
@@ -234,6 +257,7 @@ export function* overlaying(base, queue, unapplied) {
|
|
|
234
257
|
binaries: yield* settling(staged.binaries),
|
|
235
258
|
revisions: yield* settling(staged.revisions),
|
|
236
259
|
fileIds: yield* settling(staged.fileIds),
|
|
260
|
+
created: yield* settling(staged.created),
|
|
237
261
|
changes: yield* settling(staged.changes),
|
|
238
262
|
};
|
|
239
263
|
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare const PAGE_METADATA_WORDS: {
|
|
2
|
+
readonly heading: 'Page metadata';
|
|
3
|
+
readonly app: 'App';
|
|
4
|
+
readonly address: 'Address';
|
|
5
|
+
readonly queries: 'Local Queries';
|
|
6
|
+
};
|
|
7
|
+
export declare function pageMetadataBlock(app: string, address: string, queries: readonly unknown[]): string;
|
|
8
|
+
//# sourceMappingURL=page-metadata.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"page-metadata.d.ts","sourceRoot":"","sources":["../src/page-metadata.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,mBAAmB;aAC9B,OAAO,EAAE,eAAe;aACxB,GAAG,EAAE,KAAK;aACV,OAAO,EAAE,SAAS;aAClB,OAAO,EAAE,eAAe;CAChB,CAAC;AAIX,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,SAAS,OAAO,EAAE,GAC1B,MAAM,CAUR"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { queryKey } from '@agentshouse/mdmodel';
|
|
2
|
+
export const PAGE_METADATA_WORDS = {
|
|
3
|
+
heading: 'Page metadata',
|
|
4
|
+
app: 'App',
|
|
5
|
+
address: 'Address',
|
|
6
|
+
queries: 'Local Queries',
|
|
7
|
+
};
|
|
8
|
+
const PAGE_METADATA_QUERIES = 10;
|
|
9
|
+
export function pageMetadataBlock(app, address, queries) {
|
|
10
|
+
const held = [...new Set(queries.map(queryKey))];
|
|
11
|
+
return [
|
|
12
|
+
PAGE_METADATA_WORDS.heading,
|
|
13
|
+
`${PAGE_METADATA_WORDS.app}: ${app}`,
|
|
14
|
+
`${PAGE_METADATA_WORDS.address}: ${address}`,
|
|
15
|
+
...(held.length === 0 || held.length > PAGE_METADATA_QUERIES
|
|
16
|
+
? []
|
|
17
|
+
: [`${PAGE_METADATA_WORDS.queries}:`, ...held]),
|
|
18
|
+
].join('\n');
|
|
19
|
+
}
|
package/dist/parts.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parts.d.ts","sourceRoot":"","sources":["../src/parts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,KAAK,IAAI,EAAE,MAAM,8BAA8B,CAAC;AAGhE,wBAAgB,WAAW,CAAC,KAAK,EAAE,SAAS,IAAI,EAAE,GAAG,MAAM,GAAG,IAAI,CAGjE;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,SAAS,IAAI,EAAE,GAAG,MAAM,GAAG,IAAI,CAKjE"}
|
package/dist/parts.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { isOwn } from '@agentshouse/session-content';
|
|
2
|
+
import { excerpt } from './read.js';
|
|
3
|
+
export function currentStep(parts) {
|
|
4
|
+
const call = [...parts].reverse().find((part) => part.type === 'call');
|
|
5
|
+
return call?.type === 'call' && call.line !== '' ? call.line : null;
|
|
6
|
+
}
|
|
7
|
+
export function runningLine(parts) {
|
|
8
|
+
const own = parts.filter(isOwn);
|
|
9
|
+
const note = [...own].reverse().find((part) => part.type === 'text' && part.text.trim() !== '');
|
|
10
|
+
if (note?.type === 'text')
|
|
11
|
+
return excerpt(note.text);
|
|
12
|
+
return currentStep(own);
|
|
13
|
+
}
|
package/dist/paths.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export declare function normalize(path: string): string | null;
|
|
2
2
|
export declare function beneath(prefix: string, path: string): boolean;
|
|
3
3
|
export declare function covered(prefixes: readonly string[], path: string): boolean;
|
|
4
|
+
export declare function authoredAt(patterns: readonly string[], path: string): boolean;
|
|
4
5
|
export declare function ancestors(path: string): readonly string[];
|
|
5
6
|
//# sourceMappingURL=paths.d.ts.map
|
package/dist/paths.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"AAEA,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAYrD;AAED,wBAAgB,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAE7D;AAED,wBAAgB,OAAO,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAK1E;AAwBD,wBAAgB,UAAU,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAE7E;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAGzD"}
|
package/dist/paths.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isDocumentPath } from '@agentshouse/mdmodel';
|
|
1
2
|
export function normalize(path) {
|
|
2
3
|
const parts = [];
|
|
3
4
|
for (const part of path.split('/')) {
|
|
@@ -22,6 +23,27 @@ export function covered(prefixes, path) {
|
|
|
22
23
|
return normalized !== null && (normalized === '' || beneath(normalized, path));
|
|
23
24
|
});
|
|
24
25
|
}
|
|
26
|
+
function named(pattern, name) {
|
|
27
|
+
const star = pattern.indexOf('*');
|
|
28
|
+
if (star === -1)
|
|
29
|
+
return pattern === name;
|
|
30
|
+
const before = pattern.slice(0, star);
|
|
31
|
+
const after = pattern.slice(star + 1);
|
|
32
|
+
return (name.length > before.length + after.length && name.startsWith(before) && name.endsWith(after));
|
|
33
|
+
}
|
|
34
|
+
function matched(pattern, path) {
|
|
35
|
+
if (pattern === '/')
|
|
36
|
+
return isDocumentPath(path);
|
|
37
|
+
const wanted = pattern.split('/');
|
|
38
|
+
const names = path.split('/');
|
|
39
|
+
const open = wanted.at(-1) === '**';
|
|
40
|
+
const fixed = open ? wanted.slice(0, -1) : wanted;
|
|
41
|
+
return ((open ? names.length > fixed.length : names.length === fixed.length) &&
|
|
42
|
+
fixed.every((one, at) => named(one, names[at])));
|
|
43
|
+
}
|
|
44
|
+
export function authoredAt(patterns, path) {
|
|
45
|
+
return patterns.some((pattern) => matched(pattern, path));
|
|
46
|
+
}
|
|
25
47
|
export function ancestors(path) {
|
|
26
48
|
const parts = path.split('/');
|
|
27
49
|
return parts.slice(1).map((_, at) => parts.slice(0, at + 1).join('/'));
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { type InstallShare } from './install.js';
|
|
2
|
+
import { type ReadinessChange } from './observation.js';
|
|
3
|
+
import { type PortReach } from './reach.js';
|
|
4
|
+
import { type CodeAvailability, type ConnectionAvailability, type Readiness, type RoomCoverage } from './readiness.js';
|
|
5
|
+
import type { Runtime } from './runtime.js';
|
|
6
|
+
export type ReadinessPort = {
|
|
7
|
+
readonly target: string;
|
|
8
|
+
readonly code: CodeAvailability;
|
|
9
|
+
};
|
|
10
|
+
export type ReadinessMessage = Readiness | ReadinessChange;
|
|
11
|
+
export type ReadinessWatch = {
|
|
12
|
+
readonly port: ReadinessPort;
|
|
13
|
+
readonly reach: PortReach | null;
|
|
14
|
+
readonly deliver: (readiness: ReadinessMessage) => void;
|
|
15
|
+
};
|
|
16
|
+
type Share = InstallShare & {
|
|
17
|
+
readonly coverage: RoomCoverage;
|
|
18
|
+
};
|
|
19
|
+
type Totals = {
|
|
20
|
+
installing: number;
|
|
21
|
+
downloading: number;
|
|
22
|
+
acquiring: number;
|
|
23
|
+
unsettled: number;
|
|
24
|
+
done: number;
|
|
25
|
+
total: number;
|
|
26
|
+
};
|
|
27
|
+
export type ReadinessShowing = {
|
|
28
|
+
readonly listing: number;
|
|
29
|
+
readonly roomsListed: boolean;
|
|
30
|
+
readonly named: ReadonlySet<string> | null;
|
|
31
|
+
readonly rooms: Map<string, Share>;
|
|
32
|
+
readonly totals: Totals;
|
|
33
|
+
shown: string;
|
|
34
|
+
};
|
|
35
|
+
export declare function prepare(runtime: Runtime, locators?: readonly string[]): void;
|
|
36
|
+
export declare function connectionNow(runtime: Runtime): Promise<ConnectionAvailability>;
|
|
37
|
+
export declare function deliverOwedReadiness(runtime: Runtime, owed: readonly ReadinessWatch[], touched: ReadonlySet<string> | null): Promise<void>;
|
|
38
|
+
export declare function watchReadiness({ store }: Runtime, port: ReadinessPort, reach: PortReach | null, deliver: (readiness: ReadinessMessage) => void): () => void;
|
|
39
|
+
export declare function filled(runtime: Runtime): void;
|
|
40
|
+
export {};
|
|
41
|
+
//# sourceMappingURL=preparation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preparation.d.ts","sourceRoot":"","sources":["../src/preparation.ts"],"names":[],"mappings":"AAEA,OAAO,EAAgC,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC;AAE/E,OAAO,EAKL,KAAK,eAAe,EACrB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAa,KAAK,SAAS,EAAE,MAAM,YAAY,CAAC;AACvD,OAAO,EAGL,KAAK,gBAAgB,EACrB,KAAK,sBAAsB,EAE3B,KAAK,SAAS,EAEd,KAAK,YAAY,EAElB,MAAM,gBAAgB,CAAC;AAExB,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAK5C,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,gBAAgB,CAAC;CACjC,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG,eAAe,CAAC;AAE3D,MAAM,MAAM,cAAc,GAAG;IAC3B,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI,CAAC;IACjC,QAAQ,CAAC,OAAO,EAAE,CAAC,SAAS,EAAE,gBAAgB,KAAK,IAAI,CAAC;CACzD,CAAC;AAEF,KAAK,KAAK,GAAG,YAAY,GAAG;IAAE,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAA;CAAE,CAAC;AAEhE,KAAK,MAAM,GAAG;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;IAC9B,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;IAC3C,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IACnC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAwCF,wBAAgB,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,GAAE,SAAS,MAAM,EAAO,QA4BzE;AAuDD,wBAAsB,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAMrF;AAkMD,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,SAAS,cAAc,EAAE,EAC/B,OAAO,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,IAAI,iBAKpC;AAED,wBAAgB,cAAc,CAC5B,EAAE,KAAK,EAAE,EAAE,OAAO,EAClB,IAAI,EAAE,aAAa,EACnB,KAAK,EAAE,SAAS,GAAG,IAAI,EACvB,OAAO,EAAE,CAAC,SAAS,EAAE,gBAAgB,KAAK,IAAI,GAC7C,MAAM,IAAI,CAQZ;AAED,wBAAgB,MAAM,CAAC,OAAO,EAAE,OAAO,QAKtC"}
|
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
import { changeSet } from './change-set.js';
|
|
2
|
+
import { uncaught } from './failure.js';
|
|
3
|
+
import { installationOf, installShare } from './install.js';
|
|
4
|
+
import { listedLocators, listedOrHeld } from './listing.js';
|
|
5
|
+
import { keyedAt, keyedChange, unchanged, } from './observation.js';
|
|
6
|
+
import { planReach } from './reach.js';
|
|
7
|
+
import { COMPLETE_ROOMS, readinessOf, } from './readiness.js';
|
|
8
|
+
import { roomsOfReach } from './rows.js';
|
|
9
|
+
import { recoverReads } from './shown.js';
|
|
10
|
+
import { yielded } from './turn.js';
|
|
11
|
+
async function prepareReplica(runtime, locator) {
|
|
12
|
+
const { store, socket } = runtime;
|
|
13
|
+
for (;;) {
|
|
14
|
+
const held = (await store.rooms([locator])).get(locator);
|
|
15
|
+
if (held === undefined || socket.closed() || held.indexed)
|
|
16
|
+
return;
|
|
17
|
+
const key = held.record.key;
|
|
18
|
+
const done = await store.exclusive(async () => {
|
|
19
|
+
const local = await store.open();
|
|
20
|
+
return store.rederive(local, key, store.composed(held.record));
|
|
21
|
+
});
|
|
22
|
+
if (!done.done)
|
|
23
|
+
continue;
|
|
24
|
+
if ((await store.rooms([locator])).get(locator)?.record.key !== key)
|
|
25
|
+
continue;
|
|
26
|
+
store.changed(changeSet(locator, { documents: null }));
|
|
27
|
+
recoverReads(runtime, [locator]);
|
|
28
|
+
store.readiness.queue([locator]);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
async function unprepared({ store }) {
|
|
33
|
+
const held = (await store.covering()).rooms;
|
|
34
|
+
const { unpreparedDemand, unpreparable } = store.device.now();
|
|
35
|
+
return [...unpreparedDemand, ...held.keys()].find((locator) => !(held.get(locator)?.indexed ?? false) && !unpreparable.has(locator));
|
|
36
|
+
}
|
|
37
|
+
function unpreparedBy({ store }, locator) {
|
|
38
|
+
const { unpreparable } = store.device.now();
|
|
39
|
+
store.device.set({ unpreparable: new Set([...unpreparable, locator]) });
|
|
40
|
+
store.readiness.queue([locator]);
|
|
41
|
+
}
|
|
42
|
+
export function prepare(runtime, locators = []) {
|
|
43
|
+
const { store, socket } = runtime;
|
|
44
|
+
const { device } = store;
|
|
45
|
+
if (locators.length > 0) {
|
|
46
|
+
device.set({ unpreparedDemand: new Set([...device.now().unpreparedDemand, ...locators]) });
|
|
47
|
+
}
|
|
48
|
+
if (device.now().preparing)
|
|
49
|
+
return;
|
|
50
|
+
device.set({ preparing: true });
|
|
51
|
+
void (async () => {
|
|
52
|
+
try {
|
|
53
|
+
for (let waiting = await unprepared(runtime); waiting !== undefined; waiting = await unprepared(runtime)) {
|
|
54
|
+
await yielded();
|
|
55
|
+
if (socket.closed())
|
|
56
|
+
return;
|
|
57
|
+
const demand = new Set(device.now().unpreparedDemand);
|
|
58
|
+
demand.delete(waiting);
|
|
59
|
+
device.set({ unpreparedDemand: demand });
|
|
60
|
+
await prepareReplica(runtime, waiting).catch(() => unpreparedBy(runtime, waiting));
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
uncaught(error);
|
|
65
|
+
}
|
|
66
|
+
finally {
|
|
67
|
+
device.set({ preparing: false });
|
|
68
|
+
}
|
|
69
|
+
})();
|
|
70
|
+
}
|
|
71
|
+
function requires(runtime, named, held, room) {
|
|
72
|
+
const listed = listedOrHeld(runtime, held, room);
|
|
73
|
+
if (named === null)
|
|
74
|
+
return listed;
|
|
75
|
+
return named.has(room) && (!runtime.socket.session.now().roomsListed || listed);
|
|
76
|
+
}
|
|
77
|
+
function requiredRooms(runtime, named, held) {
|
|
78
|
+
return [...(named ?? listedLocators(runtime, held))]
|
|
79
|
+
.filter((room) => requires(runtime, named, held, room))
|
|
80
|
+
.sort();
|
|
81
|
+
}
|
|
82
|
+
function roomState({ socket, presence }, locator, held) {
|
|
83
|
+
if (socket.session.now().roomsListed &&
|
|
84
|
+
(presence.room(locator) === undefined || !presence.available(locator)))
|
|
85
|
+
return 'unadmitted';
|
|
86
|
+
const stored = held.get(locator);
|
|
87
|
+
if (stored === undefined)
|
|
88
|
+
return 'acquiring';
|
|
89
|
+
if (!stored.indexed)
|
|
90
|
+
return 'preparing';
|
|
91
|
+
return 'complete';
|
|
92
|
+
}
|
|
93
|
+
function conversationCoverage({ socket, conversations }, reach) {
|
|
94
|
+
const declaredConversations = reach === null || reach.conversations;
|
|
95
|
+
if (!declaredConversations || socket.conversations() === undefined)
|
|
96
|
+
return 'undeclared';
|
|
97
|
+
if (!conversations.known() || !conversations.current())
|
|
98
|
+
return 'acquiring';
|
|
99
|
+
return 'complete';
|
|
100
|
+
}
|
|
101
|
+
function connectionOf({ socket }, lastCompleted) {
|
|
102
|
+
if (socket.isOpen())
|
|
103
|
+
return 'connected';
|
|
104
|
+
if (socket.session.now().moving.providerUnreachable)
|
|
105
|
+
return 'unreachable';
|
|
106
|
+
return !socket.streamed && lastCompleted !== null ? 'connected' : 'connecting';
|
|
107
|
+
}
|
|
108
|
+
export async function connectionNow(runtime) {
|
|
109
|
+
const { store, socket } = runtime;
|
|
110
|
+
if (socket.isOpen() || socket.session.now().moving.providerUnreachable || socket.streamed) {
|
|
111
|
+
return connectionOf(runtime, null);
|
|
112
|
+
}
|
|
113
|
+
return connectionOf(runtime, (await (await store.open()).facts(['lastCompleted'])).lastCompleted);
|
|
114
|
+
}
|
|
115
|
+
async function readinessHeld({ store }) {
|
|
116
|
+
const local = await store.open();
|
|
117
|
+
const [held, facts] = await Promise.all([
|
|
118
|
+
store.covering(),
|
|
119
|
+
local.facts(['lastCompleted', 'targets']),
|
|
120
|
+
]);
|
|
121
|
+
return { held: held.rooms, facts };
|
|
122
|
+
}
|
|
123
|
+
function shareOf(runtime, room, held) {
|
|
124
|
+
const coverage = Object.freeze({ room, state: roomState(runtime, room, held) });
|
|
125
|
+
return { ...installShare(runtime.store, coverage, held), coverage };
|
|
126
|
+
}
|
|
127
|
+
function sameState(was, now) {
|
|
128
|
+
return was.coverage.state === now.coverage.state;
|
|
129
|
+
}
|
|
130
|
+
function coverageOf(change) {
|
|
131
|
+
return {
|
|
132
|
+
...change,
|
|
133
|
+
changed: change.changed.map(([room, share]) => [room, share.coverage]),
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
function counted(totals, share, sign) {
|
|
137
|
+
const { state } = share.coverage;
|
|
138
|
+
totals.installing += share.installing ? sign : 0;
|
|
139
|
+
totals.downloading += share.downloading ? sign : 0;
|
|
140
|
+
totals.acquiring += state === 'acquiring' ? sign : 0;
|
|
141
|
+
totals.unsettled += COMPLETE_ROOMS.has(state) ? 0 : sign;
|
|
142
|
+
totals.done += sign * share.bytes.done;
|
|
143
|
+
totals.total += sign * share.bytes.total;
|
|
144
|
+
}
|
|
145
|
+
function showingOf(runtime, reach, held) {
|
|
146
|
+
const planned = planReach(reach);
|
|
147
|
+
const named = planned === null ? null : roomsOfReach(planned);
|
|
148
|
+
const totals = { installing: 0, downloading: 0, acquiring: 0, unsettled: 0, done: 0, total: 0 };
|
|
149
|
+
const rooms = new Map();
|
|
150
|
+
for (const room of requiredRooms(runtime, named, held)) {
|
|
151
|
+
const share = shareOf(runtime, room, held);
|
|
152
|
+
rooms.set(room, share);
|
|
153
|
+
counted(totals, share, 1);
|
|
154
|
+
}
|
|
155
|
+
return {
|
|
156
|
+
listing: runtime.presence.listing(),
|
|
157
|
+
roomsListed: runtime.socket.session.now().roomsListed,
|
|
158
|
+
named,
|
|
159
|
+
rooms,
|
|
160
|
+
totals,
|
|
161
|
+
shown: '',
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
function moved(runtime, showing, held, touched) {
|
|
165
|
+
const at = new Map();
|
|
166
|
+
for (const room of touched) {
|
|
167
|
+
at.set(room, requires(runtime, showing.named, held, room) ? shareOf(runtime, room, held) : null);
|
|
168
|
+
}
|
|
169
|
+
const change = keyedAt(showing.rooms, at, sameState);
|
|
170
|
+
if (change === null || change.removed.length > 0)
|
|
171
|
+
return null;
|
|
172
|
+
for (const [room, share] of at) {
|
|
173
|
+
if (share === null)
|
|
174
|
+
continue;
|
|
175
|
+
counted(showing.totals, showing.rooms.get(room), -1);
|
|
176
|
+
counted(showing.totals, share, 1);
|
|
177
|
+
showing.rooms.set(room, share);
|
|
178
|
+
}
|
|
179
|
+
return change;
|
|
180
|
+
}
|
|
181
|
+
function preparingIn(runtime, showing, rooms) {
|
|
182
|
+
const { unpreparable } = runtime.store.device.now();
|
|
183
|
+
const preparing = [...rooms].filter((room) => showing.rooms.get(room)?.coverage.state === 'preparing' && !unpreparable.has(room));
|
|
184
|
+
if (preparing.length > 0)
|
|
185
|
+
prepare(runtime, preparing);
|
|
186
|
+
}
|
|
187
|
+
function shownOf(runtime, { port, reach }, { named, totals }, { facts }) {
|
|
188
|
+
const { store, socket, usableWhenHeld } = runtime;
|
|
189
|
+
const { persistence, storageLoss, heldWhenOpened } = store.device.now();
|
|
190
|
+
const { roomsListed } = socket.session.now();
|
|
191
|
+
return readinessOf({
|
|
192
|
+
code: port.code,
|
|
193
|
+
coverage: {
|
|
194
|
+
listed: named === null ? roomsListed : roomsListed || totals.acquiring === 0,
|
|
195
|
+
unsettled: totals.unsettled,
|
|
196
|
+
conversations: conversationCoverage(runtime, reach),
|
|
197
|
+
},
|
|
198
|
+
persistence,
|
|
199
|
+
connection: connectionOf(runtime, facts.lastCompleted),
|
|
200
|
+
house: socket.session.now().refusal !== null
|
|
201
|
+
? 'refused'
|
|
202
|
+
: socket.writesHeld()
|
|
203
|
+
? 'write-halted'
|
|
204
|
+
: 'open',
|
|
205
|
+
space: store.space.full() ? 'full' : null,
|
|
206
|
+
installation: installationOf(totals.installing, totals.downloading, {
|
|
207
|
+
done: totals.done,
|
|
208
|
+
total: totals.total,
|
|
209
|
+
}),
|
|
210
|
+
lost: storageLoss !== null,
|
|
211
|
+
established: facts.targets[port.target]?.established === true ||
|
|
212
|
+
(heldWhenOpened && usableWhenHeld.includes(port.target)),
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
function establish(runtime, name) {
|
|
216
|
+
const { store } = runtime;
|
|
217
|
+
const { device } = store;
|
|
218
|
+
if (device.now().establishing.has(name))
|
|
219
|
+
return;
|
|
220
|
+
device.set({ establishing: new Set([...device.now().establishing, name]) });
|
|
221
|
+
void store
|
|
222
|
+
.durably(async (local) => {
|
|
223
|
+
const { targets } = await local.facts(['targets']);
|
|
224
|
+
await local.fact('targets', { ...targets, [name]: { established: true } });
|
|
225
|
+
})
|
|
226
|
+
.then(() => {
|
|
227
|
+
store.readiness.queue([]);
|
|
228
|
+
void probeEachMinute(runtime);
|
|
229
|
+
}, uncaught)
|
|
230
|
+
.finally(() => {
|
|
231
|
+
const establishing = new Set(device.now().establishing);
|
|
232
|
+
establishing.delete(name);
|
|
233
|
+
device.set({ establishing });
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
function deliverReadiness(runtime, watch, held, touched) {
|
|
237
|
+
const { readiness } = runtime.store;
|
|
238
|
+
if (!readiness.held(watch))
|
|
239
|
+
return;
|
|
240
|
+
const kept = readiness.kept(watch);
|
|
241
|
+
const patched = kept === undefined ||
|
|
242
|
+
touched === null ||
|
|
243
|
+
kept.listing !== runtime.presence.listing() ||
|
|
244
|
+
kept.roomsListed !== runtime.socket.session.now().roomsListed
|
|
245
|
+
? null
|
|
246
|
+
: moved(runtime, kept, held.held, touched);
|
|
247
|
+
const showing = patched === null ? showingOf(runtime, watch.reach, held.held) : kept;
|
|
248
|
+
preparingIn(runtime, showing, patched === null ? showing.rooms.keys() : touched);
|
|
249
|
+
const shown = shownOf(runtime, watch, showing, held);
|
|
250
|
+
if (shown.ready && held.facts.targets[watch.port.target]?.established !== true) {
|
|
251
|
+
establish(runtime, watch.port.target);
|
|
252
|
+
}
|
|
253
|
+
const text = JSON.stringify(shown);
|
|
254
|
+
const before = kept?.shown;
|
|
255
|
+
showing.shown = text;
|
|
256
|
+
readiness.keep(watch, showing);
|
|
257
|
+
if (kept === undefined) {
|
|
258
|
+
watch.deliver({
|
|
259
|
+
...shown,
|
|
260
|
+
coverage: {
|
|
261
|
+
...shown.coverage,
|
|
262
|
+
rooms: [...showing.rooms.values()].map(({ coverage }) => coverage),
|
|
263
|
+
},
|
|
264
|
+
});
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
const rooms = coverageOf(patched ??
|
|
268
|
+
keyedChange(kept.rooms, [...showing.rooms.keys()], [...showing.rooms.values()], sameState));
|
|
269
|
+
if (text === before && unchanged(rooms))
|
|
270
|
+
return;
|
|
271
|
+
watch.deliver({ shown, rooms });
|
|
272
|
+
}
|
|
273
|
+
export async function deliverOwedReadiness(runtime, owed, touched) {
|
|
274
|
+
const held = await readinessHeld(runtime);
|
|
275
|
+
if (runtime.socket.closed())
|
|
276
|
+
return;
|
|
277
|
+
for (const watch of owed)
|
|
278
|
+
deliverReadiness(runtime, watch, held, touched);
|
|
279
|
+
}
|
|
280
|
+
export function watchReadiness({ store }, port, reach, deliver) {
|
|
281
|
+
const watch = { port, reach, deliver };
|
|
282
|
+
const stop = store.readiness.add(watch);
|
|
283
|
+
void store.open().then(() => store.readiness.owe([watch]), () => store.readiness.owe([watch]));
|
|
284
|
+
return stop;
|
|
285
|
+
}
|
|
286
|
+
export function filled(runtime) {
|
|
287
|
+
const { store, socket } = runtime;
|
|
288
|
+
if (socket.closed() || !store.space.fill())
|
|
289
|
+
return;
|
|
290
|
+
store.readiness.queue([]);
|
|
291
|
+
void probeEachMinute(runtime);
|
|
292
|
+
}
|
|
293
|
+
async function installedTarget({ store }) {
|
|
294
|
+
if (store.device.now().heldWhenOpened)
|
|
295
|
+
return true;
|
|
296
|
+
const { targets } = await (await store.open()).facts(['targets']);
|
|
297
|
+
return Object.values(targets).some((target) => target.established);
|
|
298
|
+
}
|
|
299
|
+
async function probeEachMinute(runtime) {
|
|
300
|
+
const { store, socket } = runtime;
|
|
301
|
+
const { space } = store;
|
|
302
|
+
const idle = () => !space.full() || space.probing() || socket.closed();
|
|
303
|
+
if (idle())
|
|
304
|
+
return;
|
|
305
|
+
const installed = await installedTarget(runtime).catch((error) => {
|
|
306
|
+
uncaught(error);
|
|
307
|
+
return false;
|
|
308
|
+
});
|
|
309
|
+
if (!installed)
|
|
310
|
+
return;
|
|
311
|
+
if (idle())
|
|
312
|
+
return;
|
|
313
|
+
space.probeEachMinute();
|
|
314
|
+
}
|