@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.
Files changed (316) hide show
  1. package/README.md +21 -19
  2. package/dist/acceptance.d.ts +3 -0
  3. package/dist/acceptance.d.ts.map +1 -0
  4. package/dist/acceptance.js +299 -0
  5. package/dist/act-lanes.d.ts +30 -0
  6. package/dist/act-lanes.d.ts.map +1 -0
  7. package/dist/act-lanes.js +225 -0
  8. package/dist/actions.d.ts +26 -0
  9. package/dist/actions.d.ts.map +1 -0
  10. package/dist/actions.js +302 -0
  11. package/dist/adapter.d.ts +108 -85
  12. package/dist/adapter.d.ts.map +1 -1
  13. package/dist/attached-model.d.ts +3 -11
  14. package/dist/attached-model.d.ts.map +1 -1
  15. package/dist/attached-model.js +20 -60
  16. package/dist/bootstrap.d.ts +9 -5
  17. package/dist/bootstrap.d.ts.map +1 -1
  18. package/dist/bootstrap.js +204 -85
  19. package/dist/cell.d.ts +6 -0
  20. package/dist/cell.d.ts.map +1 -0
  21. package/dist/cell.js +9 -0
  22. package/dist/chain.d.ts +2 -1
  23. package/dist/chain.d.ts.map +1 -1
  24. package/dist/change-set.d.ts +4 -0
  25. package/dist/change-set.d.ts.map +1 -1
  26. package/dist/change-set.js +6 -0
  27. package/dist/change.d.ts +1 -0
  28. package/dist/change.d.ts.map +1 -1
  29. package/dist/change.js +4 -2
  30. package/dist/chat-types.d.ts +3 -0
  31. package/dist/chat-types.d.ts.map +1 -0
  32. package/dist/chat-types.js +11 -0
  33. package/dist/client.d.ts +29 -22
  34. package/dist/client.d.ts.map +1 -1
  35. package/dist/client.js +36 -20
  36. package/dist/collection.d.ts +26 -4
  37. package/dist/collection.d.ts.map +1 -1
  38. package/dist/collection.js +19 -2
  39. package/dist/compile.d.ts +8 -6
  40. package/dist/compile.d.ts.map +1 -1
  41. package/dist/compile.js +286 -336
  42. package/dist/connection.d.ts +5 -142
  43. package/dist/connection.d.ts.map +1 -1
  44. package/dist/connection.js +110 -4970
  45. package/dist/context.d.ts +2 -0
  46. package/dist/context.d.ts.map +1 -0
  47. package/dist/context.js +7 -0
  48. package/dist/conversation-live.d.ts +150 -0
  49. package/dist/conversation-live.d.ts.map +1 -0
  50. package/dist/conversation-live.js +259 -0
  51. package/dist/conversation-row.d.ts +35 -0
  52. package/dist/conversation-row.d.ts.map +1 -0
  53. package/dist/conversation-row.js +55 -0
  54. package/dist/conversation.d.ts +65 -44
  55. package/dist/conversation.d.ts.map +1 -1
  56. package/dist/conversation.js +999 -881
  57. package/dist/declaration.d.ts +10 -0
  58. package/dist/declaration.d.ts.map +1 -0
  59. package/dist/declaration.js +24 -0
  60. package/dist/discovery.d.ts +10 -0
  61. package/dist/discovery.d.ts.map +1 -0
  62. package/dist/discovery.js +150 -0
  63. package/dist/durability.d.ts +19 -0
  64. package/dist/durability.d.ts.map +1 -1
  65. package/dist/durability.js +4 -0
  66. package/dist/entry.d.ts +2 -2
  67. package/dist/entry.d.ts.map +1 -1
  68. package/dist/entry.js +18 -8
  69. package/dist/expectation.d.ts +26 -13
  70. package/dist/expectation.d.ts.map +1 -1
  71. package/dist/expectation.js +72 -19
  72. package/dist/failure.d.ts +3 -0
  73. package/dist/failure.d.ts.map +1 -1
  74. package/dist/failure.js +6 -0
  75. package/dist/figures.d.ts +49 -0
  76. package/dist/figures.d.ts.map +1 -0
  77. package/dist/figures.js +199 -0
  78. package/dist/file.d.ts.map +1 -1
  79. package/dist/file.js +2 -1
  80. package/dist/holdings.d.ts +29 -0
  81. package/dist/holdings.d.ts.map +1 -0
  82. package/dist/holdings.js +95 -0
  83. package/dist/host.d.ts +21 -7
  84. package/dist/host.d.ts.map +1 -1
  85. package/dist/host.js +77 -41
  86. package/dist/identity.d.ts +0 -1
  87. package/dist/identity.d.ts.map +1 -1
  88. package/dist/identity.js +0 -3
  89. package/dist/index.d.ts +34 -12
  90. package/dist/index.d.ts.map +1 -1
  91. package/dist/index.js +16 -5
  92. package/dist/install.d.ts +60 -0
  93. package/dist/install.d.ts.map +1 -0
  94. package/dist/install.js +537 -0
  95. package/dist/lifecycle.d.ts +7 -0
  96. package/dist/lifecycle.d.ts.map +1 -0
  97. package/dist/lifecycle.js +278 -0
  98. package/dist/listing.d.ts +52 -0
  99. package/dist/listing.d.ts.map +1 -0
  100. package/dist/listing.js +152 -0
  101. package/dist/live.d.ts +9 -6
  102. package/dist/live.d.ts.map +1 -1
  103. package/dist/live.js +118 -36
  104. package/dist/locks.d.ts +7 -0
  105. package/dist/locks.d.ts.map +1 -0
  106. package/dist/locks.js +32 -0
  107. package/dist/lost.d.ts +5 -0
  108. package/dist/lost.d.ts.map +1 -0
  109. package/dist/lost.js +49 -0
  110. package/dist/media.d.ts +1 -1
  111. package/dist/media.d.ts.map +1 -1
  112. package/dist/media.js +10 -13
  113. package/dist/memory.d.ts +15 -6
  114. package/dist/memory.d.ts.map +1 -1
  115. package/dist/memory.js +178 -89
  116. package/dist/messages.d.ts +35 -5
  117. package/dist/messages.d.ts.map +1 -1
  118. package/dist/messages.js +108 -36
  119. package/dist/model.d.ts +2 -10
  120. package/dist/model.d.ts.map +1 -1
  121. package/dist/model.js +0 -14
  122. package/dist/models.d.ts +10 -0
  123. package/dist/models.d.ts.map +1 -0
  124. package/dist/models.js +153 -0
  125. package/dist/observation.d.ts +28 -13
  126. package/dist/observation.d.ts.map +1 -1
  127. package/dist/observation.js +185 -81
  128. package/dist/opened.d.ts +1 -1
  129. package/dist/opened.d.ts.map +1 -1
  130. package/dist/opened.js +5 -5
  131. package/dist/opening.d.ts +4 -0
  132. package/dist/opening.d.ts.map +1 -0
  133. package/dist/opening.js +53 -0
  134. package/dist/outcome.d.ts +11 -1
  135. package/dist/outcome.d.ts.map +1 -1
  136. package/dist/outcome.js +26 -2
  137. package/dist/overlay.d.ts +6 -1
  138. package/dist/overlay.d.ts.map +1 -1
  139. package/dist/overlay.js +47 -21
  140. package/dist/page-metadata.d.ts +8 -0
  141. package/dist/page-metadata.d.ts.map +1 -0
  142. package/dist/page-metadata.js +19 -0
  143. package/dist/parts.d.ts +4 -0
  144. package/dist/parts.d.ts.map +1 -0
  145. package/dist/parts.js +13 -0
  146. package/dist/paths.d.ts +1 -0
  147. package/dist/paths.d.ts.map +1 -1
  148. package/dist/paths.js +22 -0
  149. package/dist/preparation.d.ts +41 -0
  150. package/dist/preparation.d.ts.map +1 -0
  151. package/dist/preparation.js +314 -0
  152. package/dist/presence.d.ts +58 -0
  153. package/dist/presence.d.ts.map +1 -0
  154. package/dist/presence.js +233 -0
  155. package/dist/queries.d.ts +16 -0
  156. package/dist/queries.d.ts.map +1 -0
  157. package/dist/queries.js +308 -0
  158. package/dist/query.d.ts +14 -210
  159. package/dist/query.d.ts.map +1 -1
  160. package/dist/query.js +3 -505
  161. package/dist/questions.d.ts +29 -0
  162. package/dist/questions.d.ts.map +1 -0
  163. package/dist/questions.js +115 -0
  164. package/dist/queue.d.ts +40 -0
  165. package/dist/queue.d.ts.map +1 -0
  166. package/dist/queue.js +450 -0
  167. package/dist/reach.d.ts +16 -15
  168. package/dist/reach.d.ts.map +1 -1
  169. package/dist/reach.js +248 -147
  170. package/dist/react.d.ts +17 -3
  171. package/dist/react.d.ts.map +1 -1
  172. package/dist/react.js +33 -1
  173. package/dist/read.d.ts +7 -0
  174. package/dist/read.d.ts.map +1 -0
  175. package/dist/read.js +17 -0
  176. package/dist/readiness.d.ts +9 -6
  177. package/dist/readiness.d.ts.map +1 -1
  178. package/dist/readiness.js +3 -5
  179. package/dist/reads.d.ts +39 -0
  180. package/dist/reads.d.ts.map +1 -0
  181. package/dist/reads.js +178 -0
  182. package/dist/recovery.d.ts +3 -1
  183. package/dist/recovery.d.ts.map +1 -1
  184. package/dist/recovery.js +38 -8
  185. package/dist/refresh.d.ts +2 -1
  186. package/dist/refresh.d.ts.map +1 -1
  187. package/dist/refresh.js +31 -3
  188. package/dist/refusal.d.ts +5 -0
  189. package/dist/refusal.d.ts.map +1 -0
  190. package/dist/refusal.js +55 -0
  191. package/dist/replica.d.ts +11 -16
  192. package/dist/replica.d.ts.map +1 -1
  193. package/dist/replica.js +64 -30
  194. package/dist/retried.d.ts +30 -0
  195. package/dist/retried.d.ts.map +1 -0
  196. package/dist/retried.js +72 -0
  197. package/dist/room-draft.d.ts +7 -8
  198. package/dist/room-draft.d.ts.map +1 -1
  199. package/dist/room-draft.js +113 -111
  200. package/dist/room-drafts.d.ts +24 -0
  201. package/dist/room-drafts.d.ts.map +1 -0
  202. package/dist/room-drafts.js +217 -0
  203. package/dist/rows.d.ts +16 -22
  204. package/dist/rows.d.ts.map +1 -1
  205. package/dist/rows.js +49 -186
  206. package/dist/runtime.d.ts +34 -0
  207. package/dist/runtime.d.ts.map +1 -0
  208. package/dist/runtime.js +1 -0
  209. package/dist/save.d.ts +42 -86
  210. package/dist/save.d.ts.map +1 -1
  211. package/dist/save.js +344 -174
  212. package/dist/saves.d.ts +32 -0
  213. package/dist/saves.d.ts.map +1 -0
  214. package/dist/saves.js +409 -0
  215. package/dist/search.d.ts +12 -63
  216. package/dist/search.d.ts.map +1 -1
  217. package/dist/search.js +9 -52
  218. package/dist/seed.d.ts +11 -2
  219. package/dist/seed.d.ts.map +1 -1
  220. package/dist/seed.js +71 -1
  221. package/dist/shared.d.ts +1 -6
  222. package/dist/shared.d.ts.map +1 -1
  223. package/dist/shared.js +13 -95
  224. package/dist/shown.d.ts +33 -0
  225. package/dist/shown.d.ts.map +1 -0
  226. package/dist/shown.js +309 -0
  227. package/dist/socket/admission.d.ts +7 -0
  228. package/dist/socket/admission.d.ts.map +1 -0
  229. package/dist/socket/admission.js +39 -0
  230. package/dist/socket/answers.d.ts +6 -0
  231. package/dist/socket/answers.d.ts.map +1 -0
  232. package/dist/socket/answers.js +20 -0
  233. package/dist/socket/lanes.d.ts +28 -0
  234. package/dist/socket/lanes.d.ts.map +1 -0
  235. package/dist/socket/lanes.js +103 -0
  236. package/dist/socket/reads.d.ts +10 -0
  237. package/dist/socket/reads.d.ts.map +1 -0
  238. package/dist/socket/reads.js +31 -0
  239. package/dist/socket/session.d.ts +38 -0
  240. package/dist/socket/session.d.ts.map +1 -0
  241. package/dist/socket/session.js +23 -0
  242. package/dist/socket.d.ts +67 -0
  243. package/dist/socket.d.ts.map +1 -0
  244. package/dist/socket.js +164 -0
  245. package/dist/source.d.ts +54 -0
  246. package/dist/source.d.ts.map +1 -0
  247. package/dist/source.js +82 -0
  248. package/dist/status.d.ts +0 -2
  249. package/dist/status.d.ts.map +1 -1
  250. package/dist/status.js +0 -6
  251. package/dist/store/installs.d.ts +30 -0
  252. package/dist/store/installs.d.ts.map +1 -0
  253. package/dist/store/installs.js +40 -0
  254. package/dist/store/readiness.d.ts +11 -0
  255. package/dist/store/readiness.d.ts.map +1 -0
  256. package/dist/store/readiness.js +68 -0
  257. package/dist/store/records.d.ts +217 -0
  258. package/dist/store/records.d.ts.map +1 -0
  259. package/dist/store/records.js +464 -0
  260. package/dist/store/room-held.d.ts +8 -0
  261. package/dist/store/room-held.d.ts.map +1 -0
  262. package/dist/store/room-held.js +17 -0
  263. package/dist/store/rooms-shown.d.ts +8 -0
  264. package/dist/store/rooms-shown.d.ts.map +1 -0
  265. package/dist/store/rooms-shown.js +13 -0
  266. package/dist/store/space.d.ts +11 -0
  267. package/dist/store/space.d.ts.map +1 -0
  268. package/dist/store/space.js +41 -0
  269. package/dist/store/watchers.d.ts +17 -0
  270. package/dist/store/watchers.d.ts.map +1 -0
  271. package/dist/store/watchers.js +56 -0
  272. package/dist/store/writes.d.ts +24 -0
  273. package/dist/store/writes.d.ts.map +1 -0
  274. package/dist/store/writes.js +125 -0
  275. package/dist/store.d.ts +113 -144
  276. package/dist/store.d.ts.map +1 -1
  277. package/dist/store.js +171 -364
  278. package/dist/stored.d.ts +72 -35
  279. package/dist/stored.d.ts.map +1 -1
  280. package/dist/stored.js +340 -197
  281. package/dist/surface.d.ts +89 -0
  282. package/dist/surface.d.ts.map +1 -0
  283. package/dist/surface.js +222 -0
  284. package/dist/sync.d.ts +19 -0
  285. package/dist/sync.d.ts.map +1 -0
  286. package/dist/sync.js +535 -0
  287. package/dist/tables.d.ts +124 -30
  288. package/dist/tables.d.ts.map +1 -1
  289. package/dist/tables.js +242 -62
  290. package/dist/tallies.d.ts +18 -0
  291. package/dist/tallies.d.ts.map +1 -0
  292. package/dist/tallies.js +128 -0
  293. package/dist/validation.d.ts.map +1 -1
  294. package/dist/validation.js +9 -12
  295. package/dist/windows.d.ts +1 -12
  296. package/dist/windows.d.ts.map +1 -1
  297. package/dist/windows.js +2 -75
  298. package/dist/wire.d.ts +58 -9
  299. package/dist/wire.d.ts.map +1 -1
  300. package/dist/wire.js +21 -5
  301. package/package.json +3 -2
  302. package/dist/attempt.d.ts +0 -16
  303. package/dist/attempt.d.ts.map +0 -1
  304. package/dist/attempt.js +0 -70
  305. package/dist/fence.d.ts +0 -6
  306. package/dist/fence.d.ts.map +0 -1
  307. package/dist/fence.js +0 -10
  308. package/dist/fulltext.d.ts +0 -27
  309. package/dist/fulltext.d.ts.map +0 -1
  310. package/dist/fulltext.js +0 -370
  311. package/dist/log.d.ts +0 -5
  312. package/dist/log.d.ts.map +0 -1
  313. package/dist/log.js +0 -14
  314. package/dist/words.d.ts +0 -19
  315. package/dist/words.d.ts.map +0 -1
  316. package/dist/words.js +0 -156
package/dist/overlay.js CHANGED
@@ -1,4 +1,5 @@
1
- import { apply, frontmatterValue, parse, serialize, } from '@agentshouse/mdmodel';
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 compose(fields, sections) {
57
- const body = Object.entries(sections)
58
- .map(([name, value]) => `\n## ${name}\n${value}`)
59
- .join('');
60
- const skeleton = `${EMPTY_FRONTMATTER}${body}`;
61
- const opened = parse(skeleton);
62
- if (!opened.ok)
63
- return skeleton;
64
- const next = apply(opened.document, Object.entries(fields).flatMap(([name, value]) => frontmatterValue(value) ? [{ kind: 'field', name, value, prior: undefined }] : []));
65
- return serialize(next.outcome === 'applied' ? next.document : opened.document);
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 parsed = parse(text, path);
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 ? change.content : compose(change.fields, change.sections);
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
+ }
@@ -0,0 +1,4 @@
1
+ import { type Part } from '@agentshouse/session-content';
2
+ export declare function currentStep(parts: readonly Part[]): string | null;
3
+ export declare function runningLine(parts: readonly Part[]): string | null;
4
+ //# sourceMappingURL=parts.d.ts.map
@@ -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
@@ -1 +1 @@
1
- {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"AAAA,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;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAGzD"}
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
+ }