@agentshouse/mdruntime 0.1.0-cd507e16e5fc0 → 0.1.0-cd574a610e9c8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (269) hide show
  1. package/README.md +21 -19
  2. package/dist/acceptance.d.ts +0 -3
  3. package/dist/acceptance.d.ts.map +1 -1
  4. package/dist/acceptance.js +75 -165
  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 +8 -2
  9. package/dist/actions.d.ts.map +1 -1
  10. package/dist/actions.js +118 -67
  11. package/dist/adapter.d.ts +90 -58
  12. package/dist/adapter.d.ts.map +1 -1
  13. package/dist/attached-model.d.ts +0 -1
  14. package/dist/attached-model.d.ts.map +1 -1
  15. package/dist/attached-model.js +0 -5
  16. package/dist/authored.d.ts +88 -0
  17. package/dist/authored.d.ts.map +1 -0
  18. package/dist/authored.js +345 -0
  19. package/dist/bootstrap.d.ts +1 -1
  20. package/dist/bootstrap.d.ts.map +1 -1
  21. package/dist/bootstrap.js +6 -19
  22. package/dist/change-set.d.ts +4 -0
  23. package/dist/change-set.d.ts.map +1 -1
  24. package/dist/change-set.js +6 -0
  25. package/dist/change.d.ts +4 -0
  26. package/dist/change.d.ts.map +1 -1
  27. package/dist/change.js +7 -2
  28. package/dist/chat-types.d.ts +0 -2
  29. package/dist/chat-types.d.ts.map +1 -1
  30. package/dist/chat-types.js +0 -2
  31. package/dist/client.d.ts +13 -20
  32. package/dist/client.d.ts.map +1 -1
  33. package/dist/client.js +36 -20
  34. package/dist/collection.d.ts +25 -4
  35. package/dist/collection.d.ts.map +1 -1
  36. package/dist/collection.js +19 -2
  37. package/dist/column.d.ts +5 -0
  38. package/dist/column.d.ts.map +1 -0
  39. package/dist/column.js +9 -0
  40. package/dist/compile.d.ts +2 -0
  41. package/dist/compile.d.ts.map +1 -1
  42. package/dist/compile.js +31 -25
  43. package/dist/connection.d.ts.map +1 -1
  44. package/dist/connection.js +31 -24
  45. package/dist/context.d.ts.map +1 -1
  46. package/dist/context.js +1 -1
  47. package/dist/conversation-live.d.ts +26 -12
  48. package/dist/conversation-live.d.ts.map +1 -1
  49. package/dist/conversation-live.js +23 -12
  50. package/dist/conversation-row.d.ts +8 -1
  51. package/dist/conversation-row.d.ts.map +1 -1
  52. package/dist/conversation-row.js +20 -7
  53. package/dist/conversation.d.ts +37 -12
  54. package/dist/conversation.d.ts.map +1 -1
  55. package/dist/conversation.js +320 -234
  56. package/dist/declaration.d.ts +10 -0
  57. package/dist/declaration.d.ts.map +1 -0
  58. package/dist/declaration.js +24 -0
  59. package/dist/discovery.d.ts.map +1 -1
  60. package/dist/discovery.js +19 -44
  61. package/dist/durability.d.ts +4 -0
  62. package/dist/durability.d.ts.map +1 -1
  63. package/dist/durability.js +4 -0
  64. package/dist/entry.js +1 -1
  65. package/dist/expectation.d.ts +26 -13
  66. package/dist/expectation.d.ts.map +1 -1
  67. package/dist/expectation.js +72 -19
  68. package/dist/failure.d.ts +3 -0
  69. package/dist/failure.d.ts.map +1 -1
  70. package/dist/failure.js +6 -0
  71. package/dist/figures.d.ts.map +1 -1
  72. package/dist/figures.js +4 -2
  73. package/dist/file.d.ts +1 -1
  74. package/dist/file.d.ts.map +1 -1
  75. package/dist/file.js +3 -2
  76. package/dist/host.d.ts +18 -2
  77. package/dist/host.d.ts.map +1 -1
  78. package/dist/host.js +59 -15
  79. package/dist/index.d.ts +16 -11
  80. package/dist/index.d.ts.map +1 -1
  81. package/dist/index.js +12 -7
  82. package/dist/install.d.ts +10 -6
  83. package/dist/install.d.ts.map +1 -1
  84. package/dist/install.js +92 -111
  85. package/dist/lifecycle.d.ts +1 -1
  86. package/dist/lifecycle.d.ts.map +1 -1
  87. package/dist/lifecycle.js +54 -40
  88. package/dist/listing.d.ts +11 -12
  89. package/dist/listing.d.ts.map +1 -1
  90. package/dist/listing.js +48 -72
  91. package/dist/live.d.ts +5 -3
  92. package/dist/live.d.ts.map +1 -1
  93. package/dist/live.js +74 -33
  94. package/dist/loaded.d.ts +5 -0
  95. package/dist/loaded.d.ts.map +1 -0
  96. package/dist/loaded.js +40 -0
  97. package/dist/locks.d.ts +2 -4
  98. package/dist/locks.d.ts.map +1 -1
  99. package/dist/locks.js +10 -39
  100. package/dist/lost.d.ts.map +1 -1
  101. package/dist/lost.js +11 -23
  102. package/dist/media.d.ts +6 -1
  103. package/dist/media.d.ts.map +1 -1
  104. package/dist/media.js +68 -17
  105. package/dist/memory.d.ts +8 -3
  106. package/dist/memory.d.ts.map +1 -1
  107. package/dist/memory.js +92 -33
  108. package/dist/messages.d.ts +12 -6
  109. package/dist/messages.d.ts.map +1 -1
  110. package/dist/messages.js +30 -38
  111. package/dist/model.d.ts +0 -1
  112. package/dist/model.d.ts.map +1 -1
  113. package/dist/model.js +0 -5
  114. package/dist/models.d.ts +4 -8
  115. package/dist/models.d.ts.map +1 -1
  116. package/dist/models.js +97 -139
  117. package/dist/observation.d.ts +27 -12
  118. package/dist/observation.d.ts.map +1 -1
  119. package/dist/observation.js +184 -85
  120. package/dist/opened.d.ts +1 -1
  121. package/dist/opened.d.ts.map +1 -1
  122. package/dist/opened.js +5 -5
  123. package/dist/opening.d.ts.map +1 -1
  124. package/dist/opening.js +5 -9
  125. package/dist/outcome.d.ts +13 -1
  126. package/dist/outcome.d.ts.map +1 -1
  127. package/dist/outcome.js +32 -2
  128. package/dist/overlay.d.ts +6 -2
  129. package/dist/overlay.d.ts.map +1 -1
  130. package/dist/overlay.js +37 -24
  131. package/dist/page-metadata.d.ts +8 -0
  132. package/dist/page-metadata.d.ts.map +1 -0
  133. package/dist/page-metadata.js +19 -0
  134. package/dist/parts.d.ts +3 -58
  135. package/dist/parts.d.ts.map +1 -1
  136. package/dist/parts.js +10 -115
  137. package/dist/preparation.d.ts +27 -6
  138. package/dist/preparation.d.ts.map +1 -1
  139. package/dist/preparation.js +156 -68
  140. package/dist/presence.d.ts +58 -0
  141. package/dist/presence.d.ts.map +1 -0
  142. package/dist/presence.js +231 -0
  143. package/dist/queries.d.ts +2 -2
  144. package/dist/queries.d.ts.map +1 -1
  145. package/dist/queries.js +67 -31
  146. package/dist/query.d.ts +0 -1
  147. package/dist/query.d.ts.map +1 -1
  148. package/dist/questions.d.ts +1 -5
  149. package/dist/questions.d.ts.map +1 -1
  150. package/dist/questions.js +1 -7
  151. package/dist/queue.d.ts +40 -0
  152. package/dist/queue.d.ts.map +1 -0
  153. package/dist/queue.js +480 -0
  154. package/dist/reach.d.ts +2 -3
  155. package/dist/reach.d.ts.map +1 -1
  156. package/dist/reach.js +88 -26
  157. package/dist/react.d.ts +8 -1
  158. package/dist/react.d.ts.map +1 -1
  159. package/dist/react.js +33 -1
  160. package/dist/readiness.d.ts +9 -3
  161. package/dist/readiness.d.ts.map +1 -1
  162. package/dist/readiness.js +3 -5
  163. package/dist/reads.d.ts +4 -2
  164. package/dist/reads.d.ts.map +1 -1
  165. package/dist/reads.js +11 -4
  166. package/dist/recovery.d.ts +3 -1
  167. package/dist/recovery.d.ts.map +1 -1
  168. package/dist/recovery.js +29 -7
  169. package/dist/refresh.js +2 -2
  170. package/dist/refusal.d.ts.map +1 -1
  171. package/dist/refusal.js +5 -6
  172. package/dist/replica.d.ts +5 -11
  173. package/dist/replica.d.ts.map +1 -1
  174. package/dist/replica.js +15 -17
  175. package/dist/retried.d.ts +30 -0
  176. package/dist/retried.d.ts.map +1 -0
  177. package/dist/retried.js +72 -0
  178. package/dist/room-draft.d.ts +31 -8
  179. package/dist/room-draft.d.ts.map +1 -1
  180. package/dist/room-draft.js +273 -66
  181. package/dist/room-drafts.d.ts.map +1 -1
  182. package/dist/room-drafts.js +22 -18
  183. package/dist/room-list.d.ts +10 -0
  184. package/dist/room-list.d.ts.map +1 -0
  185. package/dist/room-list.js +45 -0
  186. package/dist/rows.d.ts +2 -1
  187. package/dist/rows.d.ts.map +1 -1
  188. package/dist/rows.js +9 -10
  189. package/dist/runtime.d.ts +9 -18
  190. package/dist/runtime.d.ts.map +1 -1
  191. package/dist/save.d.ts +42 -90
  192. package/dist/save.d.ts.map +1 -1
  193. package/dist/save.js +327 -229
  194. package/dist/saves.d.ts +4 -40
  195. package/dist/saves.d.ts.map +1 -1
  196. package/dist/saves.js +143 -714
  197. package/dist/seed.d.ts.map +1 -1
  198. package/dist/seed.js +4 -5
  199. package/dist/shared.d.ts +0 -5
  200. package/dist/shared.d.ts.map +1 -1
  201. package/dist/shared.js +4 -90
  202. package/dist/shown.d.ts +7 -5
  203. package/dist/shown.d.ts.map +1 -1
  204. package/dist/shown.js +77 -63
  205. package/dist/socket/lanes.d.ts +12 -4
  206. package/dist/socket/lanes.d.ts.map +1 -1
  207. package/dist/socket/lanes.js +34 -8
  208. package/dist/socket/session.d.ts +0 -1
  209. package/dist/socket/session.d.ts.map +1 -1
  210. package/dist/socket.d.ts +3 -6
  211. package/dist/socket.d.ts.map +1 -1
  212. package/dist/socket.js +5 -16
  213. package/dist/source.d.ts +5 -7
  214. package/dist/source.d.ts.map +1 -1
  215. package/dist/source.js +18 -6
  216. package/dist/store/installs.d.ts +2 -2
  217. package/dist/store/installs.d.ts.map +1 -1
  218. package/dist/store/installs.js +10 -4
  219. package/dist/store/readiness.d.ts +5 -4
  220. package/dist/store/readiness.d.ts.map +1 -1
  221. package/dist/store/readiness.js +28 -12
  222. package/dist/store/records.d.ts +18 -7
  223. package/dist/store/records.d.ts.map +1 -1
  224. package/dist/store/records.js +58 -24
  225. package/dist/store/rooms-shown.d.ts +8 -0
  226. package/dist/store/rooms-shown.d.ts.map +1 -0
  227. package/dist/store/rooms-shown.js +13 -0
  228. package/dist/store/space.d.ts +1 -1
  229. package/dist/store/space.d.ts.map +1 -1
  230. package/dist/store/space.js +0 -2
  231. package/dist/store/watchers.js +1 -2
  232. package/dist/store.d.ts +23 -14
  233. package/dist/store.d.ts.map +1 -1
  234. package/dist/store.js +46 -17
  235. package/dist/stored.d.ts +25 -14
  236. package/dist/stored.d.ts.map +1 -1
  237. package/dist/stored.js +83 -32
  238. package/dist/surface.d.ts +5 -3
  239. package/dist/surface.d.ts.map +1 -1
  240. package/dist/surface.js +25 -23
  241. package/dist/sync.d.ts +1 -1
  242. package/dist/sync.d.ts.map +1 -1
  243. package/dist/sync.js +96 -92
  244. package/dist/tables.d.ts +16 -57
  245. package/dist/tables.d.ts.map +1 -1
  246. package/dist/tables.js +91 -332
  247. package/dist/tallies.d.ts.map +1 -1
  248. package/dist/tallies.js +6 -7
  249. package/dist/validation.d.ts.map +1 -1
  250. package/dist/validation.js +4 -10
  251. package/dist/wire.d.ts +53 -7
  252. package/dist/wire.d.ts.map +1 -1
  253. package/dist/wire.js +17 -4
  254. package/package.json +3 -2
  255. package/dist/attempt.d.ts +0 -16
  256. package/dist/attempt.d.ts.map +0 -1
  257. package/dist/attempt.js +0 -70
  258. package/dist/job.d.ts +0 -33
  259. package/dist/job.d.ts.map +0 -1
  260. package/dist/job.js +0 -54
  261. package/dist/log.d.ts +0 -6
  262. package/dist/log.d.ts.map +0 -1
  263. package/dist/log.js +0 -14
  264. package/dist/socket/rooms.d.ts +0 -44
  265. package/dist/socket/rooms.d.ts.map +0 -1
  266. package/dist/socket/rooms.js +0 -90
  267. package/dist/store/fences.d.ts +0 -16
  268. package/dist/store/fences.d.ts.map +0 -1
  269. package/dist/store/fences.js +0 -26
package/dist/install.js CHANGED
@@ -1,11 +1,12 @@
1
1
  import { attachedModel } from './attached-model.js';
2
2
  import { bootstrapRoom } from './bootstrap.js';
3
3
  import { refusedForSpace } from './durability.js';
4
- import { name, usable } from './listing.js';
4
+ import { uncaught } from './failure.js';
5
+ import { name } from './listing.js';
5
6
  import { NO_MODEL } from './model.js';
7
+ import { settle } from './queue.js';
6
8
  import { advancement } from './refresh.js';
7
- import { recoverReads, statusShown } from './shown.js';
8
- import { NO_INSTALL, } from './store.js';
9
+ import { recoverReads } from './shown.js';
9
10
  import { unconfirmed } from './transfer.js';
10
11
  import { ROW_WEIGHT, yielded } from './turn.js';
11
12
  // Bytes still arriving are reported at most this often, so readiness is not rebuilt for every chunk the network hands over while a slow link still moves the figure.
@@ -78,28 +79,32 @@ function batchEnd(entries, from, bytes) {
78
79
  }
79
80
  return end;
80
81
  }
81
- export function installationOf(store, coverage, held) {
82
- const bytes = { done: 0, total: 0 };
83
- let installing = 0;
84
- let downloading = false;
85
- for (const { room, state } of coverage) {
86
- if (state === 'unadmitted')
87
- continue;
88
- const install = store.installs.of(room);
89
- const underway = state === 'acquiring' || (install.installing && state !== 'complete');
90
- if (underway)
91
- installing += 1;
92
- if (underway && (install.streaming || install.arrived === null))
93
- downloading = true;
94
- const kept = underway ? NOTHING_HELD.bytes : (held.get(room)?.bytes ?? NOTHING_HELD.bytes);
95
- const now = amountOf(install, kept);
96
- const earlier = underway ? install.startedOver : null;
97
- bytes.done += Math.max(now.done, earlier?.done ?? 0);
98
- bytes.total += Math.max(now.total, earlier?.total ?? 0);
99
- }
82
+ const UNSHARED = {
83
+ installing: false,
84
+ downloading: false,
85
+ bytes: { done: 0, total: 0 },
86
+ };
87
+ export function installShare(store, { room, state }, held) {
88
+ if (state === 'unadmitted')
89
+ return UNSHARED;
90
+ const install = store.installs.of(room);
91
+ const underway = state === 'acquiring' || (install.installing && state !== 'complete');
92
+ const kept = underway ? NOTHING_HELD.bytes : (held.get(room)?.bytes ?? NOTHING_HELD.bytes);
93
+ const now = amountOf(install, kept);
94
+ const earlier = underway ? install.startedOver : null;
95
+ return {
96
+ installing: underway,
97
+ downloading: underway && (install.streaming || install.arrived === null),
98
+ bytes: {
99
+ done: Math.max(now.done, earlier?.done ?? 0),
100
+ total: Math.max(now.total, earlier?.total ?? 0),
101
+ },
102
+ };
103
+ }
104
+ export function installationOf(installing, downloading, bytes) {
100
105
  const step = installing === 0
101
106
  ? null
102
- : downloading
107
+ : downloading > 0
103
108
  ? 'downloading'
104
109
  : bytes.done < bytes.total
105
110
  ? 'writing'
@@ -112,15 +117,15 @@ export function roomInFlight(store, locator) {
112
117
  }
113
118
  function installing(runtime, locator) {
114
119
  runtime.store.installs.change(locator, (held) => ({ ...held, installing: true }));
115
- runtime.store.readiness.queue();
120
+ runtime.store.readiness.queue([locator]);
116
121
  }
117
122
  function installed(runtime, locator) {
118
123
  if (!runtime.store.installs.of(locator).installing)
119
124
  return;
120
125
  runtime.store.installs.change(locator, (held) => ({ ...held, installing: false }));
121
- runtime.store.readiness.queue();
126
+ runtime.store.readiness.queue([locator]);
122
127
  }
123
- export function sweep({ store, socket, journal }) {
128
+ export function sweep({ store, socket }) {
124
129
  if (store.device.now().sweeping || socket.closed())
125
130
  return;
126
131
  store.device.set({ sweeping: true });
@@ -130,32 +135,23 @@ export function sweep({ store, socket, journal }) {
130
135
  await yielded();
131
136
  }
132
137
  }
133
- catch {
134
- journal.record('erasure failed');
138
+ catch (error) {
139
+ uncaught(error);
135
140
  }
136
141
  finally {
137
142
  store.device.set({ sweeping: false });
138
143
  }
139
144
  })();
140
145
  }
141
- export function forgetInstall(store, locator) {
142
- store.installs.change(locator, ({ installing }) => ({ ...NO_INSTALL, installing }));
143
- }
144
146
  export function caughtUpTo(runtime, locator) {
145
147
  if (!runtime.store.installs.of(locator).catching)
146
148
  return;
147
149
  runtime.store.installs.change(locator, (held) => ({ ...held, catching: false }));
148
- recoverReads(runtime);
150
+ recoverReads(runtime, [locator]);
149
151
  }
150
152
  export function catching(store, locator) {
151
153
  store.installs.change(locator, (held) => ({ ...held, catching: true }));
152
154
  }
153
- export function confirmedAgain(store, locator) {
154
- store.installs.change(locator, (held) => ({
155
- ...held,
156
- confirmations: held.confirmations + 1,
157
- }));
158
- }
159
155
  export function standingAt(store, locator, held) {
160
156
  return { key: held?.key ?? null, confirmed: store.installs.of(locator).confirmations };
161
157
  }
@@ -270,7 +266,7 @@ function refreshingOf(runtime, local, locator, key, composition, liveness, repla
270
266
  export async function pullRefresh(runtime, authorized, record, liveness, hold, refresh) {
271
267
  if (!liveness())
272
268
  return unconfirmed;
273
- const { store, journal } = runtime;
269
+ const { store } = runtime;
274
270
  const from = standingAt(store, record.locator, record);
275
271
  const local = await store.open();
276
272
  try {
@@ -284,11 +280,8 @@ export async function pullRefresh(runtime, authorized, record, liveness, hold, r
284
280
  hold.take();
285
281
  }
286
282
  }, authorized, record, (models, kept) => (liveness() ? remodel(runtime, models, kept) : kept), liveness, refreshingOf(runtime, local, record.locator, record.key, store.composed(record), liveness, false, record.roomVersion));
287
- if (result.kind !== 'advanced') {
288
- journal.record(`transfer refresh ${record.locator} ${result.kind}`);
283
+ if (result.kind !== 'advanced')
289
284
  return result;
290
- }
291
- journal.record(`transfer refresh ${record.locator} ${result.record.roomVersion}`);
292
285
  return {
293
286
  kind: 'advanced',
294
287
  record: result.record,
@@ -299,14 +292,14 @@ export async function pullRefresh(runtime, authorized, record, liveness, hold, r
299
292
  catch (error) {
300
293
  if (refusedForSpace(error))
301
294
  return unconfirmed;
302
- journal.record(`transfer refresh ${record.locator} transport-uncertainty`);
303
295
  throw error;
304
296
  }
305
297
  }
306
298
  async function abandoned(runtime, local, locator) {
307
299
  await local.abandon(locator);
308
300
  runtime.store.installs.change(locator, (held) => transferGone(setBack(held)));
309
- recoverReads(runtime);
301
+ recoverReads(runtime, [locator]);
302
+ runtime.store.readiness.queue([locator]);
310
303
  sweep(runtime);
311
304
  }
312
305
  function staging(runtime, local, liveness, unheld) {
@@ -320,7 +313,7 @@ function staging(runtime, local, liveness, unheld) {
320
313
  if (done === null)
321
314
  return false;
322
315
  store.installs.change(locator, (held) => built(held, done.done, done.text));
323
- runtime.store.readiness.queue();
316
+ runtime.store.readiness.queue([locator]);
324
317
  if (done.done)
325
318
  return true;
326
319
  }
@@ -344,9 +337,9 @@ function staging(runtime, local, liveness, unheld) {
344
337
  arrived: bytes,
345
338
  streaming: true,
346
339
  }));
347
- if (!store.installs.arrivalDue(performance.now(), ARRIVAL_REPORT_MS))
348
- return;
349
- runtime.store.readiness.queue();
340
+ const due = store.installs.arrivalsDue(locator, performance.now(), ARRIVAL_REPORT_MS);
341
+ if (due.length > 0)
342
+ runtime.store.readiness.queue(due);
350
343
  },
351
344
  end() {
352
345
  if (ended)
@@ -355,7 +348,7 @@ function staging(runtime, local, liveness, unheld) {
355
348
  if (!store.installs.of(locator).streaming)
356
349
  return;
357
350
  store.installs.change(locator, (held) => ({ ...held, streaming: false }));
358
- runtime.store.readiness.queue();
351
+ runtime.store.readiness.queue([locator]);
359
352
  },
360
353
  };
361
354
  },
@@ -382,10 +375,8 @@ function staging(runtime, local, liveness, unheld) {
382
375
  transfer: held,
383
376
  underived: owed,
384
377
  }));
385
- if (before.transfer === null)
386
- recoverReads(runtime);
387
378
  installing(runtime, locator);
388
- recoverReads(runtime);
379
+ recoverReads(runtime, [locator]);
389
380
  if (owed < store.deriveBytes())
390
381
  return held;
391
382
  return (await derived(locator, key, composition)) ? held : null;
@@ -396,7 +387,9 @@ function staging(runtime, local, liveness, unheld) {
396
387
  if (!liveness())
397
388
  return null;
398
389
  const prior = unheld === undefined ? await store.record(locator) : undefined;
399
- const published = prior !== undefined && prior.replica.selection === record.selection ? prior.key : null;
390
+ const published = prior !== undefined && prior.declaration.replica.selection === record.selection
391
+ ? prior.key
392
+ : null;
400
393
  const kept = unheld?.staged ?? (await local.held()).staged.has(locator);
401
394
  if (published === null && !kept)
402
395
  return { record: null, staged: new Set() };
@@ -418,7 +411,8 @@ function staging(runtime, local, liveness, unheld) {
418
411
  done: { bytes },
419
412
  };
420
413
  store.installs.change(locator, (room) => ({ ...room, transfer: held }));
421
- recoverReads(runtime);
414
+ recoverReads(runtime, [locator]);
415
+ store.readiness.queue([locator]);
422
416
  return { record: held, staged: parted };
423
417
  },
424
418
  derive: derived,
@@ -434,7 +428,8 @@ function staging(runtime, local, liveness, unheld) {
434
428
  if (!liveness())
435
429
  return;
436
430
  store.installs.change(locator, (held) => transferGone(setBack(held)));
437
- recoverReads(runtime);
431
+ recoverReads(runtime, [locator]);
432
+ store.readiness.queue([locator]);
438
433
  },
439
434
  release: (key) => store.exclusive(async () => {
440
435
  await local.release(key);
@@ -445,23 +440,20 @@ function staging(runtime, local, liveness, unheld) {
445
440
  export async function pullBootstrap(runtime, authorized, room, local, liveness, prior, from = runtime.socket.reads, unheld) {
446
441
  if (!liveness())
447
442
  return unconfirmed;
448
- const { store, journal } = runtime;
443
+ const { store } = runtime;
449
444
  if (prior !== undefined) {
450
445
  catching(store, room.locator);
451
- recoverReads(runtime);
446
+ recoverReads(runtime, [room.locator]);
452
447
  }
453
448
  try {
454
449
  const result = await bootstrapRoom(from, authorized, room, {
455
- collection: prior?.model ?? runtime.socket.rooms.standing(room.locator).unheldModel ?? NO_MODEL,
450
+ collection: prior?.model ?? runtime.presence.unheldModel(room.locator) ?? NO_MODEL,
456
451
  }, runtime.builtIn, runtime.typedPaths, (models, held) => (liveness() ? remodel(runtime, models, held) : held), liveness, staging(runtime, local, liveness, unheld));
457
- const detail = result.kind === 'staged' ? result.record.roomVersion : result.kind;
458
- journal.record(`transfer bootstrap ${room.locator} ${detail}`);
459
452
  if (result.kind === 'staged' &&
460
453
  (await older(runtime, room.locator, result.record.roomVersion))) {
461
454
  caughtUpTo(runtime, room.locator);
462
455
  installed(runtime, room.locator);
463
456
  await abandoned(runtime, local, room.locator);
464
- journal.record(`transfer bootstrap ${room.locator} older than shown`);
465
457
  return { kind: 'transport-uncertainty' };
466
458
  }
467
459
  if (result.kind !== 'staged') {
@@ -475,27 +467,27 @@ export async function pullBootstrap(runtime, authorized, room, local, liveness,
475
467
  installed(runtime, room.locator);
476
468
  if (refusedForSpace(error))
477
469
  return unconfirmed;
478
- journal.record(`transfer bootstrap ${room.locator} transport-uncertainty`);
479
470
  throw error;
480
471
  }
481
472
  }
482
473
  export function publish(runtime, local, room, reached, landing, live) {
483
474
  const { store } = runtime;
484
- const landed = store.exclusive(async () => {
475
+ let published = true;
476
+ const landed = settle(runtime, [room.locator], async (held) => {
485
477
  if (!live()) {
486
478
  caughtUpTo(runtime, room.locator);
487
- return true;
479
+ return [];
488
480
  }
489
- const work = await store.work(room.locator);
490
- const prior = work.replica;
481
+ const prior = held.get(room.locator)?.replica;
491
482
  if (!standsAt(store, room.locator, prior?.record, landing.from)) {
483
+ published = false;
492
484
  if (landing.kind === 'refreshed') {
493
485
  await local.unrefresh(reached.key);
494
- return false;
486
+ return [];
495
487
  }
496
488
  caughtUpTo(runtime, room.locator);
497
489
  await abandoned(runtime, local, room.locator);
498
- return false;
490
+ return [];
499
491
  }
500
492
  const record = landing.kind === 'refreshed' && prior !== undefined
501
493
  ? {
@@ -504,51 +496,40 @@ export function publish(runtime, local, room, reached, landing, live) {
504
496
  ...(landing.remodelled ? { model: reached.model } : {}),
505
497
  }
506
498
  : reached;
507
- let set;
508
- try {
509
- set = await runtime.settle(local, room.locator, work, record, work.queue, landing.kind === 'refreshed'
510
- ? {
511
- room: true,
512
- view: 'refreshed',
513
- commit: { refreshed: true },
514
- }
515
- : {
516
- room: true,
517
- view: landing.refreshed ? 'refreshed' : 'confirmed',
518
- commit: {
499
+ return [
500
+ {
501
+ locator: room.locator,
502
+ record,
503
+ installed: landing.kind === 'refreshed'
504
+ ? { refreshed: true }
505
+ : {
519
506
  published: { from: prior?.record.key ?? null },
520
507
  ...(landing.refreshed ? { refreshed: true } : {}),
521
508
  },
522
- });
523
- }
524
- catch (error) {
525
- if (!refusedForSpace(error))
526
- throw error;
527
- caughtUpTo(runtime, room.locator);
528
- return true;
529
- }
530
- if (landing.kind === 'bootstrapped') {
531
- runtime.socket.rooms.readied(room.locator);
532
- store.installs.change(room.locator, (held) => ({
533
- ...transferGone(held),
534
- highest: null,
535
- beyondHorizon: false,
536
- startedOver: null,
537
- catching: false,
538
- }));
539
- runtime.socket.rooms.stand(room.locator, { unheldModel: null });
540
- if (prior !== undefined && prior.record.key !== record.key)
541
- sweep(runtime);
542
- void name(runtime, room.locator);
543
- }
544
- usable(runtime, room);
545
- void runtime.store.changed(set);
546
- await runtime.unpair(local);
547
- void statusShown(runtime);
548
- if (landing.kind === 'bootstrapped' && work.queue.length > 0) {
549
- runtime.submitLater(room.locator);
550
- }
551
- return true;
509
+ after() {
510
+ runtime.presence.installed(room.locator, landing.kind === 'bootstrapped');
511
+ runtime.retries.succeeded('download', room.locator);
512
+ store.prepareAgain(room.locator);
513
+ if (landing.kind === 'bootstrapped') {
514
+ store.installs.change(room.locator, (held) => ({
515
+ ...transferGone(held),
516
+ highest: null,
517
+ beyondHorizon: false,
518
+ startedOver: null,
519
+ catching: false,
520
+ }));
521
+ if (prior !== undefined && prior.record.key !== record.key)
522
+ sweep(runtime);
523
+ void name(runtime, room.locator);
524
+ }
525
+ },
526
+ },
527
+ ];
528
+ }).then(() => published, (error) => {
529
+ if (!refusedForSpace(error))
530
+ throw error;
531
+ caughtUpTo(runtime, room.locator);
532
+ return published;
552
533
  });
553
534
  return landing.kind === 'refreshed'
554
535
  ? landed
@@ -1,7 +1,7 @@
1
1
  import type { Runtime } from './runtime.js';
2
2
  export declare function scheduleCurrency(runtime: Runtime): void;
3
3
  export declare function spaceFreed(runtime: Runtime): void;
4
- export declare function close({ store, socket, conversations, recovery, liveQueries, figures }: Runtime): void;
4
+ export declare function close({ store, socket, presence, conversations, recovery, liveQueries, figures, }: Runtime): void;
5
5
  export declare function stop(runtime: Runtime): Promise<void>;
6
6
  export declare function start(runtime: Runtime, signal: AbortSignal | undefined): void;
7
7
  //# sourceMappingURL=lifecycle.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"lifecycle.d.ts","sourceRoot":"","sources":["../src/lifecycle.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AA8M5C,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,QAOhD;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,OAAO,QAS1C;AAED,wBAAgB,KAAK,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,QAAQ,EAAE,WAAW,EAAE,OAAO,EAAE,EAAE,OAAO,QAQ9F;AAED,wBAAsB,IAAI,CAAC,OAAO,EAAE,OAAO,iBAS1C;AAED,wBAAgB,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,GAAG,SAAS,QAwCtE"}
1
+ {"version":3,"file":"lifecycle.d.ts","sourceRoot":"","sources":["../src/lifecycle.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAoO5C,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,QAOhD;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,OAAO,QAQ1C;AAED,wBAAgB,KAAK,CAAC,EACpB,KAAK,EACL,MAAM,EACN,QAAQ,EACR,aAAa,EACb,QAAQ,EACR,WAAW,EACX,OAAO,GACR,EAAE,OAAO,QAST;AAED,wBAAsB,IAAI,CAAC,OAAO,EAAE,OAAO,iBAS1C;AAED,wBAAgB,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,GAAG,SAAS,QA2CtE"}
package/dist/lifecycle.js CHANGED
@@ -1,13 +1,16 @@
1
- import { submitAll } from './acceptance.js';
2
1
  import { catchUpConversations, receiveConversationEvent, reconcileConversations, } from './conversation.js';
2
+ import { declared } from './declaration.js';
3
+ import { uncaught } from './failure.js';
3
4
  import { catching, replaced } from './install.js';
4
5
  import { connectionLost } from './locks.js';
5
6
  import { fenceLive } from './lost.js';
6
7
  import { cachedModels, revoked, settleModels } from './models.js';
7
8
  import { refuse } from './refusal.js';
8
- import { moveTo, recoverReads, rest, SERVICE_MODE_TOPIC, show, transferring } from './shown.js';
9
+ import { roomsListed } from './room-list.js';
10
+ import { moveTo, recoverReads, rest, SERVICE_MODE_TOPIC, show, submissionDue, transferring, } from './shown.js';
9
11
  import { applyRoom, changeAuthority, countAuthorityChange, finishOpening, loadRoom, OPENING_LANE, reload, resynchronize, sync, } from './sync.js';
10
12
  const CONVERSATION_LANE = 'conversations';
13
+ const RELOADING = 'reloading';
11
14
  function closing(runtime, opened) {
12
15
  const { store, socket } = runtime;
13
16
  return socket.lanes.task(OPENING_LANE, async (live) => {
@@ -20,10 +23,10 @@ function closing(runtime, opened) {
20
23
  });
21
24
  }
22
25
  function closedSocket(runtime, lapsed, lost, opened) {
23
- const { socket, conversations } = runtime;
26
+ const { socket, presence, conversations } = runtime;
24
27
  const { session } = socket;
25
28
  socket.notifyReady();
26
- socket.rooms.unreadied();
29
+ presence.stopAsking();
27
30
  connectionLost(runtime);
28
31
  if (lost)
29
32
  conversations.lost();
@@ -43,26 +46,26 @@ function closedSocket(runtime, lapsed, lost, opened) {
43
46
  void closing(runtime, opened);
44
47
  }
45
48
  function owedReloads(runtime, expired, held) {
46
- const { store, socket } = runtime;
47
- const reloading = socket.rooms
48
- .discoveredRooms()
49
+ const { store, presence } = runtime;
50
+ const reloading = presence
51
+ .rooms()
49
52
  .filter((room) => !expired.includes(room.locator) && revoked(held.get(room.locator)?.record.model))
50
53
  .map((room) => room.locator);
51
54
  for (const locator of reloading)
52
55
  catching(store, locator);
53
- recoverReads(runtime);
56
+ recoverReads(runtime, reloading);
54
57
  return reloading;
55
58
  }
56
- async function reloadNow(runtime, replacing, progress, held, installing) {
57
- const { store, socket } = runtime;
58
- const { rooms, lanes } = socket;
59
- const discovered = rooms.discoveredRooms();
59
+ async function reloadNow(runtime, among, replacing, progress, held, installing) {
60
+ const { store, socket, presence } = runtime;
61
+ const { lanes } = socket;
62
+ const discovered = among === null ? presence.rooms() : among.flatMap((locator) => presence.room(locator) ?? []);
60
63
  const reloaded = discovered.filter((room) => held.has(room.locator) && !installing.has(room.locator) && replacing(room));
61
64
  const acquired = discovered.filter((room) => (!held.has(room.locator) || installing.has(room.locator)) &&
62
65
  room.replica.admission === 'admitted' &&
63
66
  replacing(room));
64
67
  for (const room of reloaded)
65
- rooms.stand(room.locator, { reloadDue: true });
68
+ presence.reload(room.locator, true);
66
69
  try {
67
70
  const local = await store.open();
68
71
  const kept = acquired.length === 0 ? new Set() : (await local.held()).staged;
@@ -77,27 +80,30 @@ async function reloadNow(runtime, replacing, progress, held, installing) {
77
80
  .roomTask(room.locator, (live) => loadRoom(runtime, room, local, progress, live, unheld))
78
81
  .then(() => rest(runtime, progress));
79
82
  }
83
+ runtime.retries.succeeded('download', RELOADING);
80
84
  }
81
- catch {
85
+ catch (error) {
86
+ runtime.retries.failed('download', RELOADING, error);
82
87
  for (const room of reloaded)
83
- rooms.stand(room.locator, { reloadDue: false });
88
+ presence.reload(room.locator, false);
84
89
  progress.reachable = false;
85
90
  }
86
91
  }
87
92
  function caughtUpRooms(runtime, expired) {
88
- const { store, socket } = runtime;
93
+ const { store, socket, presence } = runtime;
89
94
  const { session } = socket;
90
95
  const progress = session.now().underway;
91
96
  session.set({ underway: null });
92
97
  socket.named();
93
98
  const cycle = progress ?? { complete: true, reachable: true };
94
99
  replaced(store, expired);
95
- const installing = store.installs.underway();
96
- const held = progress === null ? store.rooms(expired) : store.rooms();
100
+ const among = progress === null ? expired : null;
101
+ const installing = store.installs.underway(among);
102
+ const held = among === null ? store.rooms() : store.rooms(among);
97
103
  const reloading = progress === null
98
104
  ? Promise.resolve([])
99
105
  : held.then((stored) => owedReloads(runtime, expired, stored));
100
- const replacing = Promise.all([held, reloading]).then(([stored, owed]) => reloadNow(runtime, (room) => expired.includes(room.locator) || owed.includes(room.locator), cycle, stored, installing));
106
+ const replacing = Promise.all([held, reloading]).then(([stored, owed]) => reloadNow(runtime, among, (room) => expired.includes(room.locator) || owed.includes(room.locator), cycle, stored, installing));
101
107
  return socket.lanes.task(OPENING_LANE, async (live) => {
102
108
  if (!live())
103
109
  return;
@@ -112,14 +118,17 @@ function caughtUpRooms(runtime, expired) {
112
118
  if (progress.reachable) {
113
119
  const stored = await held;
114
120
  const owed = await reloading;
115
- await settleModels(runtime, socket.rooms
116
- .discoveredRooms()
121
+ await settleModels(runtime, new Map(presence
122
+ .rooms()
117
123
  .filter((room) => stored.has(room.locator) &&
118
124
  !expired.includes(room.locator) &&
119
- !owed.includes(room.locator)), 'current', local);
125
+ !owed.includes(room.locator))
126
+ .map((room) => [room.locator, declared(room)])), 'current', local);
120
127
  }
128
+ runtime.retries.succeeded('download', OPENING_LANE);
121
129
  }
122
- catch {
130
+ catch (error) {
131
+ runtime.retries.failed('download', OPENING_LANE, error);
123
132
  progress.complete = false;
124
133
  progress.reachable = false;
125
134
  }
@@ -128,7 +137,7 @@ function caughtUpRooms(runtime, expired) {
128
137
  });
129
138
  }
130
139
  function signalled(runtime, mode) {
131
- const { store, socket, journal } = runtime;
140
+ const { store, socket } = runtime;
132
141
  const { session } = socket;
133
142
  const { closed, serviceMode, haltedRefusal, openSignals } = session.now();
134
143
  if (closed)
@@ -140,12 +149,11 @@ function signalled(runtime, mode) {
140
149
  session.set({ haltedRefusal: false });
141
150
  if (mode !== serviceMode) {
142
151
  session.set({ serviceMode: mode });
143
- store.readiness.queue();
144
- journal.record(`service mode ${mode}`);
152
+ store.readiness.queue([]);
145
153
  store.tell(SERVICE_MODE_TOPIC, mode);
146
154
  }
147
155
  if (releasing)
148
- submitAll(runtime);
156
+ void submissionDue(runtime);
149
157
  }
150
158
  async function runCurrency(runtime, live) {
151
159
  const { socket, conversations } = runtime;
@@ -156,7 +164,7 @@ async function runCurrency(runtime, live) {
156
164
  return;
157
165
  await reconcileConversations(conversations);
158
166
  if (conversations.current()) {
159
- show(runtime);
167
+ await rest(runtime, null, live);
160
168
  return;
161
169
  }
162
170
  const progress = {
@@ -166,8 +174,10 @@ async function runCurrency(runtime, live) {
166
174
  moveTo(runtime, transferring(runtime));
167
175
  try {
168
176
  await catchUpConversations(conversations, progress);
177
+ runtime.retries.succeeded('conversations', CONVERSATION_LANE);
169
178
  }
170
- catch {
179
+ catch (error) {
180
+ runtime.retries.failed('conversations', CONVERSATION_LANE, error);
171
181
  progress.reachable = false;
172
182
  }
173
183
  await rest(runtime, progress, live);
@@ -181,9 +191,8 @@ export function scheduleCurrency(runtime) {
181
191
  void socket.lanes.task(CONVERSATION_LANE, (live) => runCurrency(runtime, live));
182
192
  }
183
193
  export function spaceFreed(runtime) {
184
- const { store, socket, journal } = runtime;
185
- socket.rooms.standAll({ unpreparable: false });
186
- journal.record('space freed');
194
+ const { store, socket } = runtime;
195
+ store.prepareAgain();
187
196
  store.readiness.queue();
188
197
  const { closed, authorization } = socket.session.now();
189
198
  if (closed || authorization === undefined)
@@ -193,10 +202,11 @@ export function spaceFreed(runtime) {
193
202
  else
194
203
  void resynchronize(runtime);
195
204
  }
196
- export function close({ store, socket, conversations, recovery, liveQueries, figures }) {
205
+ export function close({ store, socket, presence, conversations, recovery, liveQueries, figures, }) {
197
206
  if (socket.closed())
198
207
  return;
199
208
  socket.close();
209
+ presence.close();
200
210
  conversations.close();
201
211
  void recovery.retire();
202
212
  liveQueries.close();
@@ -204,9 +214,9 @@ export function close({ store, socket, conversations, recovery, liveQueries, fig
204
214
  store.close();
205
215
  }
206
216
  export async function stop(runtime) {
207
- const { store, socket, recovery } = runtime;
217
+ const { store, socket, presence, recovery } = runtime;
208
218
  socket.session.set({ stopping: true });
209
- socket.rooms.unreadied();
219
+ presence.stopAsking();
210
220
  socket.stopReads();
211
221
  await recovery.retire();
212
222
  await socket.lanes.finished();
@@ -214,12 +224,12 @@ export async function stop(runtime) {
214
224
  close(runtime);
215
225
  }
216
226
  export function start(runtime, signal) {
217
- const { store, socket, conversations, lastAnswers, recovery } = runtime;
227
+ const { store, socket, presence, conversations, lastAnswers, recovery } = runtime;
218
228
  const closeRuntime = () => close(runtime);
219
229
  socket.observeServiceMode((mode) => signalled(runtime, mode));
220
230
  socket.observeConversations((event) => {
221
231
  if (event.kind === 'list' || event.kind === 'listed' || event.kind === 'unlisted')
222
- store.readiness.queue();
232
+ store.readiness.queue([]);
223
233
  receiveConversationEvent(conversations, event);
224
234
  if (event.kind !== 'gap' || conversations.current())
225
235
  return;
@@ -231,14 +241,15 @@ export function start(runtime, signal) {
231
241
  closeRuntime();
232
242
  socket.observe((event) => {
233
243
  if (event.kind === 'opened') {
234
- socket.rooms.connectionLive();
244
+ presence.connectionLive();
235
245
  conversations.reopened();
236
246
  lastAnswers.reopened();
237
247
  recovery.resume();
238
248
  }
239
249
  else if (event.kind === 'discovered') {
250
+ const listed = roomsListed(runtime, event.discovery.roomList);
240
251
  if (event.missed)
241
- countAuthorityChange(runtime);
252
+ countAuthorityChange(runtime, listed);
242
253
  void sync(runtime, 'opened', event.discovery);
243
254
  }
244
255
  else if (event.kind === 'closed') {
@@ -246,6 +257,8 @@ export function start(runtime, signal) {
246
257
  }
247
258
  else if (event.kind === 'caught-up')
248
259
  void caughtUpRooms(runtime, event.expired);
260
+ else if (event.kind === 'reported')
261
+ lastAnswers.again();
249
262
  else if (event.kind === 'authority-changed') {
250
263
  if (socket.isAnnounced() && socket.isOpen())
251
264
  fenceLive(runtime, event.left);
@@ -260,8 +273,9 @@ export function start(runtime, signal) {
260
273
  if ((await local.facts()).capabilities.length > 0)
261
274
  socket.readyFromStore();
262
275
  })
263
- .catch(() => {
276
+ .catch((error) => {
264
277
  socket.readyFromStore();
278
+ uncaught(error);
265
279
  });
266
280
  if (!socket.streamed)
267
281
  void sync(runtime, 'unstreamed', null);