@agentshouse/mdruntime 0.1.0-c069136dcb4e8 → 0.1.0-c076b00ebf42a
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 +108 -85
- 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/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 +1 -0
- package/dist/change.d.ts.map +1 -1
- package/dist/change.js +4 -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 +29 -22
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +36 -20
- package/dist/collection.d.ts +26 -4
- package/dist/collection.d.ts.map +1 -1
- package/dist/collection.js +19 -2
- 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 +110 -4970
- 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 +35 -0
- package/dist/conversation-row.d.ts.map +1 -0
- package/dist/conversation-row.js +55 -0
- package/dist/conversation.d.ts +65 -44
- package/dist/conversation.d.ts.map +1 -1
- package/dist/conversation.js +999 -881
- package/dist/declaration.d.ts +10 -0
- package/dist/declaration.d.ts.map +1 -0
- package/dist/declaration.js +24 -0
- package/dist/discovery.d.ts +10 -0
- package/dist/discovery.d.ts.map +1 -0
- package/dist/discovery.js +150 -0
- package/dist/durability.d.ts +19 -0
- package/dist/durability.d.ts.map +1 -1
- package/dist/durability.js +4 -0
- package/dist/entry.d.ts +2 -2
- package/dist/entry.d.ts.map +1 -1
- package/dist/entry.js +18 -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.map +1 -1
- package/dist/file.js +2 -1
- 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 +77 -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 +34 -12
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +16 -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 +278 -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/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 +1 -1
- package/dist/media.d.ts.map +1 -1
- package/dist/media.js +10 -13
- package/dist/memory.d.ts +15 -6
- package/dist/memory.d.ts.map +1 -1
- package/dist/memory.js +178 -89
- package/dist/messages.d.ts +35 -5
- package/dist/messages.d.ts.map +1 -1
- package/dist/messages.js +108 -36
- 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 +11 -1
- package/dist/outcome.d.ts.map +1 -1
- package/dist/outcome.js +26 -2
- package/dist/overlay.d.ts +6 -1
- package/dist/overlay.d.ts.map +1 -1
- package/dist/overlay.js +47 -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 +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 +233 -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 +29 -0
- package/dist/questions.d.ts.map +1 -0
- package/dist/questions.js +115 -0
- package/dist/queue.d.ts +40 -0
- package/dist/queue.d.ts.map +1 -0
- package/dist/queue.js +450 -0
- package/dist/reach.d.ts +16 -15
- package/dist/reach.d.ts.map +1 -1
- package/dist/reach.js +248 -147
- package/dist/react.d.ts +17 -3
- package/dist/react.d.ts.map +1 -1
- package/dist/react.js +33 -1
- package/dist/read.d.ts +7 -0
- package/dist/read.d.ts.map +1 -0
- package/dist/read.js +17 -0
- package/dist/readiness.d.ts +9 -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 +64 -30
- 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 +7 -8
- package/dist/room-draft.d.ts.map +1 -1
- package/dist/room-draft.js +113 -111
- package/dist/room-drafts.d.ts +24 -0
- package/dist/room-drafts.d.ts.map +1 -0
- package/dist/room-drafts.js +217 -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 +344 -174
- package/dist/saves.d.ts +32 -0
- package/dist/saves.d.ts.map +1 -0
- package/dist/saves.js +409 -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 +33 -0
- package/dist/shown.d.ts.map +1 -0
- package/dist/shown.js +309 -0
- package/dist/socket/admission.d.ts +7 -0
- package/dist/socket/admission.d.ts.map +1 -0
- package/dist/socket/admission.js +39 -0
- package/dist/socket/answers.d.ts +6 -0
- package/dist/socket/answers.d.ts.map +1 -0
- package/dist/socket/answers.js +20 -0
- package/dist/socket/lanes.d.ts +28 -0
- package/dist/socket/lanes.d.ts.map +1 -0
- package/dist/socket/lanes.js +103 -0
- package/dist/socket/reads.d.ts +10 -0
- package/dist/socket/reads.d.ts.map +1 -0
- package/dist/socket/reads.js +31 -0
- package/dist/socket/session.d.ts +38 -0
- package/dist/socket/session.d.ts.map +1 -0
- package/dist/socket/session.js +23 -0
- package/dist/socket.d.ts +67 -0
- package/dist/socket.d.ts.map +1 -0
- package/dist/socket.js +164 -0
- package/dist/source.d.ts +54 -0
- package/dist/source.d.ts.map +1 -0
- package/dist/source.js +82 -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 +217 -0
- package/dist/store/records.d.ts.map +1 -0
- package/dist/store/records.js +464 -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 +113 -144
- 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 +340 -197
- package/dist/surface.d.ts +89 -0
- package/dist/surface.d.ts.map +1 -0
- package/dist/surface.js +222 -0
- package/dist/sync.d.ts +19 -0
- package/dist/sync.d.ts.map +1 -0
- package/dist/sync.js +535 -0
- package/dist/tables.d.ts +124 -30
- package/dist/tables.d.ts.map +1 -1
- package/dist/tables.js +242 -62
- 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 +58 -9
- package/dist/wire.d.ts.map +1 -1
- package/dist/wire.js +21 -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,5 @@
|
|
|
1
|
-
import { apply,
|
|
1
|
+
import { apply, create, documentValue, parse, serialize, TYPE_FIELD, } from '@agentshouse/mdmodel';
|
|
2
|
+
import { definitionsAt } from './collection.js';
|
|
2
3
|
import { drafted, entriesIn, settling } from './shared.js';
|
|
3
4
|
import { ROW_WEIGHT } from './turn.js';
|
|
4
5
|
export function* acceptedBinaries(files) {
|
|
@@ -24,7 +25,6 @@ export function sameChange(left, right) {
|
|
|
24
25
|
left.author?.id === right.author?.id &&
|
|
25
26
|
left.author?.name === right.author?.name);
|
|
26
27
|
}
|
|
27
|
-
const EMPTY_FRONTMATTER = '---\n---\n';
|
|
28
28
|
function isPart(change) {
|
|
29
29
|
return change.kind === 'field' || change.kind === 'section' || change.kind === 'preamble';
|
|
30
30
|
}
|
|
@@ -53,16 +53,27 @@ function* priorsOf(preconditions) {
|
|
|
53
53
|
preamble: (path) => preambles.get(path) ?? '',
|
|
54
54
|
};
|
|
55
55
|
}
|
|
56
|
-
function
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
56
|
+
export function composed(path, fields, sections, composition) {
|
|
57
|
+
const declared = fields[TYPE_FIELD];
|
|
58
|
+
const type = typeof declared === 'string' && declared !== '' ? declared : undefined;
|
|
59
|
+
const definition = definitionsAt(composition, path)(type);
|
|
60
|
+
return apply(create(type, definition), [
|
|
61
|
+
...Object.entries(fields).flatMap(([name, value]) => (name !== TYPE_FIELD || type === undefined) && documentValue(value)
|
|
62
|
+
? [{ kind: 'field', name, value, prior: undefined }]
|
|
63
|
+
: []),
|
|
64
|
+
...Object.entries(sections).map(([name, value]) => ({
|
|
65
|
+
kind: 'section',
|
|
66
|
+
name,
|
|
67
|
+
value,
|
|
68
|
+
prior: undefined,
|
|
69
|
+
})),
|
|
70
|
+
], definition);
|
|
71
|
+
}
|
|
72
|
+
export function compose(path, fields, sections, composition) {
|
|
73
|
+
const next = composed(path, fields, sections, composition);
|
|
74
|
+
if (next.outcome !== 'applied')
|
|
75
|
+
throw new Error(`the creation of ${path} writes no document`);
|
|
76
|
+
return serialize(next.document);
|
|
66
77
|
}
|
|
67
78
|
function edited(change, priors) {
|
|
68
79
|
if (change.kind === 'field')
|
|
@@ -81,17 +92,19 @@ function edited(change, priors) {
|
|
|
81
92
|
prior: priors.section(change.path, change.name),
|
|
82
93
|
};
|
|
83
94
|
}
|
|
84
|
-
function edit(staged, changes, priors) {
|
|
95
|
+
function edit(staged, changes, priors, composition) {
|
|
85
96
|
const path = changes[0].path;
|
|
86
97
|
delete staged.revisions[path];
|
|
87
98
|
const text = staged.documents[path];
|
|
88
99
|
if (text === undefined)
|
|
89
100
|
return changes.length;
|
|
90
|
-
const
|
|
101
|
+
const definitions = definitionsAt(composition, path);
|
|
102
|
+
const parsed = parse(text, path, definitions);
|
|
91
103
|
if (!parsed.ok)
|
|
92
104
|
return changes.length;
|
|
105
|
+
const definition = definitions(parsed.document.type);
|
|
93
106
|
const wanted = changes.map((change) => edited(change, priors));
|
|
94
|
-
const first = apply(parsed.document, wanted);
|
|
107
|
+
const first = apply(parsed.document, wanted, definition);
|
|
95
108
|
if (first.outcome === 'refuse')
|
|
96
109
|
return changes.length;
|
|
97
110
|
if (first.outcome === 'applied') {
|
|
@@ -100,7 +113,7 @@ function edit(staged, changes, priors) {
|
|
|
100
113
|
}
|
|
101
114
|
const stale = new Set(first.stale);
|
|
102
115
|
const kept = wanted.filter((_, at) => !stale.has(at));
|
|
103
|
-
const rest = apply(parsed.document, kept);
|
|
116
|
+
const rest = apply(parsed.document, kept, definition);
|
|
104
117
|
if (rest.outcome !== 'applied')
|
|
105
118
|
return changes.length;
|
|
106
119
|
staged.documents[path] = serialize(rest.document);
|
|
@@ -125,16 +138,21 @@ function relocate(staged, from, to) {
|
|
|
125
138
|
function moveHead(heads, from, to) {
|
|
126
139
|
const revision = heads.revisions[from];
|
|
127
140
|
const fileId = heads.fileIds[from];
|
|
141
|
+
const created = heads.created[from];
|
|
128
142
|
const change = heads.changes[from];
|
|
129
143
|
delete heads.revisions[from];
|
|
130
144
|
delete heads.fileIds[from];
|
|
145
|
+
delete heads.created[from];
|
|
131
146
|
delete heads.changes[from];
|
|
132
147
|
delete heads.fileIds[to];
|
|
148
|
+
delete heads.created[to];
|
|
133
149
|
delete heads.changes[to];
|
|
134
150
|
if (revision !== undefined)
|
|
135
151
|
heads.revisions[to] = revision;
|
|
136
152
|
if (fileId !== undefined)
|
|
137
153
|
heads.fileIds[to] = fileId;
|
|
154
|
+
if (created !== undefined)
|
|
155
|
+
heads.created[to] = created;
|
|
138
156
|
if (change !== undefined)
|
|
139
157
|
heads.changes[to] = change;
|
|
140
158
|
}
|
|
@@ -142,14 +160,18 @@ function erase(staged, path) {
|
|
|
142
160
|
delete staged.documents[path];
|
|
143
161
|
delete staged.revisions[path];
|
|
144
162
|
delete staged.fileIds[path];
|
|
163
|
+
delete staged.created[path];
|
|
145
164
|
delete staged.changes[path];
|
|
146
165
|
delete staged.binaries[path];
|
|
147
166
|
}
|
|
148
|
-
function stage(staged, change) {
|
|
167
|
+
function stage(staged, change, composition) {
|
|
149
168
|
if (change.kind === 'create') {
|
|
150
169
|
staged.documents[change.path] =
|
|
151
|
-
'content' in change
|
|
170
|
+
'content' in change
|
|
171
|
+
? change.content
|
|
172
|
+
: compose(change.path, change.fields, change.sections, composition);
|
|
152
173
|
delete staged.fileIds[change.path];
|
|
174
|
+
delete staged.created[change.path];
|
|
153
175
|
delete staged.changes[change.path];
|
|
154
176
|
return true;
|
|
155
177
|
}
|
|
@@ -194,15 +216,18 @@ function arrive(heads, change) {
|
|
|
194
216
|
heads.revisions[change.path] = change.revision;
|
|
195
217
|
if (change.fileId !== undefined)
|
|
196
218
|
heads.fileIds[change.path] = change.fileId;
|
|
219
|
+
if (change.created !== undefined)
|
|
220
|
+
heads.created[change.path] = change.created;
|
|
197
221
|
if (change.change !== undefined)
|
|
198
222
|
heads.changes[change.path] = change.change;
|
|
199
223
|
}
|
|
200
|
-
export function* overlaying(base, queue, unapplied) {
|
|
224
|
+
export function* overlaying(base, queue, composition, unapplied) {
|
|
201
225
|
const staged = {
|
|
202
226
|
documents: drafted(base.documents),
|
|
203
227
|
binaries: drafted(base.binaries),
|
|
204
228
|
revisions: drafted(base.revisions),
|
|
205
229
|
fileIds: drafted(base.fileIds),
|
|
230
|
+
created: drafted(base.created),
|
|
206
231
|
changes: drafted(base.changes),
|
|
207
232
|
};
|
|
208
233
|
for (const batch of queue) {
|
|
@@ -210,7 +235,7 @@ export function* overlaying(base, queue, unapplied) {
|
|
|
210
235
|
for (let index = 0; index < batch.changes.length; index += 1) {
|
|
211
236
|
const change = batch.changes[index];
|
|
212
237
|
if (!isPart(change)) {
|
|
213
|
-
if (!stage(staged, change))
|
|
238
|
+
if (!stage(staged, change, composition))
|
|
214
239
|
unapplied?.();
|
|
215
240
|
yield ROW_WEIGHT;
|
|
216
241
|
continue;
|
|
@@ -224,7 +249,7 @@ export function* overlaying(base, queue, unapplied) {
|
|
|
224
249
|
index += 1;
|
|
225
250
|
}
|
|
226
251
|
const text = staged.documents[change.path] ?? '';
|
|
227
|
-
for (let left = edit(staged, run, priors); left > 0; left -= 1)
|
|
252
|
+
for (let left = edit(staged, run, priors, composition); left > 0; left -= 1)
|
|
228
253
|
unapplied?.();
|
|
229
254
|
yield ROW_WEIGHT + text.length;
|
|
230
255
|
}
|
|
@@ -234,6 +259,7 @@ export function* overlaying(base, queue, unapplied) {
|
|
|
234
259
|
binaries: yield* settling(staged.binaries),
|
|
235
260
|
revisions: yield* settling(staged.revisions),
|
|
236
261
|
fileIds: yield* settling(staged.fileIds),
|
|
262
|
+
created: yield* settling(staged.created),
|
|
237
263
|
changes: yield* settling(staged.changes),
|
|
238
264
|
};
|
|
239
265
|
}
|
|
@@ -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
|
+
}
|