@agentshouse/mdruntime 0.1.0-cb2e390ee7b89 → 0.1.0-cb4f25b82f4b6

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 (392) hide show
  1. package/README.md +23 -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 +163 -125
  12. package/dist/adapter.d.ts.map +1 -1
  13. package/dist/attached-model.d.ts +7 -10
  14. package/dist/attached-model.d.ts.map +1 -1
  15. package/dist/attached-model.js +40 -41
  16. package/dist/binary.d.ts +0 -5
  17. package/dist/binary.d.ts.map +1 -1
  18. package/dist/binary.js +1 -1
  19. package/dist/bootstrap.d.ts +30 -11
  20. package/dist/bootstrap.d.ts.map +1 -1
  21. package/dist/bootstrap.js +309 -113
  22. package/dist/cell.d.ts +6 -0
  23. package/dist/cell.d.ts.map +1 -0
  24. package/dist/cell.js +9 -0
  25. package/dist/chain.d.ts +12 -0
  26. package/dist/chain.d.ts.map +1 -0
  27. package/dist/chain.js +64 -0
  28. package/dist/change-set.d.ts +13 -16
  29. package/dist/change-set.d.ts.map +1 -1
  30. package/dist/change-set.js +17 -89
  31. package/dist/change.d.ts +32 -1
  32. package/dist/change.d.ts.map +1 -1
  33. package/dist/change.js +14 -3
  34. package/dist/chat-types.d.ts +5 -0
  35. package/dist/chat-types.d.ts.map +1 -0
  36. package/dist/chat-types.js +13 -0
  37. package/dist/client.d.ts +36 -24
  38. package/dist/client.d.ts.map +1 -1
  39. package/dist/client.js +118 -23
  40. package/dist/collection.d.ts +29 -21
  41. package/dist/collection.d.ts.map +1 -1
  42. package/dist/collection.js +48 -290
  43. package/dist/compile.d.ts +18 -0
  44. package/dist/compile.d.ts.map +1 -0
  45. package/dist/compile.js +724 -0
  46. package/dist/connection.d.ts +7 -134
  47. package/dist/connection.d.ts.map +1 -1
  48. package/dist/connection.js +107 -3606
  49. package/dist/context.d.ts +2 -0
  50. package/dist/context.d.ts.map +1 -0
  51. package/dist/{chat/context.js → context.js} +1 -4
  52. package/dist/conversation-live.d.ts +143 -0
  53. package/dist/conversation-live.d.ts.map +1 -0
  54. package/dist/conversation-live.js +254 -0
  55. package/dist/conversation-row.d.ts +33 -0
  56. package/dist/conversation-row.d.ts.map +1 -0
  57. package/dist/conversation-row.js +53 -0
  58. package/dist/conversation.d.ts +73 -49
  59. package/dist/conversation.d.ts.map +1 -1
  60. package/dist/conversation.js +1010 -794
  61. package/dist/declaration.d.ts +10 -0
  62. package/dist/declaration.d.ts.map +1 -0
  63. package/dist/declaration.js +24 -0
  64. package/dist/digest.d.ts +7 -0
  65. package/dist/digest.d.ts.map +1 -0
  66. package/dist/digest.js +113 -0
  67. package/dist/discovery.d.ts +10 -0
  68. package/dist/discovery.d.ts.map +1 -0
  69. package/dist/discovery.js +150 -0
  70. package/dist/durability.d.ts +20 -4
  71. package/dist/durability.d.ts.map +1 -1
  72. package/dist/durability.js +9 -0
  73. package/dist/entry.d.ts +5 -2
  74. package/dist/entry.d.ts.map +1 -1
  75. package/dist/entry.js +33 -28
  76. package/dist/expectation.d.ts +26 -13
  77. package/dist/expectation.d.ts.map +1 -1
  78. package/dist/expectation.js +72 -19
  79. package/dist/failure.d.ts +3 -0
  80. package/dist/failure.d.ts.map +1 -1
  81. package/dist/failure.js +6 -0
  82. package/dist/figures.d.ts +49 -0
  83. package/dist/figures.d.ts.map +1 -0
  84. package/dist/figures.js +197 -0
  85. package/dist/file.d.ts +2 -19
  86. package/dist/file.d.ts.map +1 -1
  87. package/dist/file.js +7 -122
  88. package/dist/holdings.d.ts +29 -0
  89. package/dist/holdings.d.ts.map +1 -0
  90. package/dist/holdings.js +95 -0
  91. package/dist/host.d.ts +21 -11
  92. package/dist/host.d.ts.map +1 -1
  93. package/dist/host.js +113 -49
  94. package/dist/identity.d.ts +0 -2
  95. package/dist/identity.d.ts.map +1 -1
  96. package/dist/identity.js +0 -6
  97. package/dist/index.d.ts +39 -15
  98. package/dist/index.d.ts.map +1 -1
  99. package/dist/index.js +18 -4
  100. package/dist/install.d.ts +54 -0
  101. package/dist/install.d.ts.map +1 -0
  102. package/dist/install.js +530 -0
  103. package/dist/lifecycle.d.ts +7 -0
  104. package/dist/lifecycle.d.ts.map +1 -0
  105. package/dist/lifecycle.js +277 -0
  106. package/dist/listing.d.ts +48 -0
  107. package/dist/listing.d.ts.map +1 -0
  108. package/dist/listing.js +139 -0
  109. package/dist/live.d.ts +23 -0
  110. package/dist/live.d.ts.map +1 -0
  111. package/dist/live.js +165 -0
  112. package/dist/locks.d.ts +7 -0
  113. package/dist/locks.d.ts.map +1 -0
  114. package/dist/locks.js +32 -0
  115. package/dist/lost.d.ts +5 -0
  116. package/dist/lost.d.ts.map +1 -0
  117. package/dist/lost.js +49 -0
  118. package/dist/media.d.ts +8 -0
  119. package/dist/media.d.ts.map +1 -0
  120. package/dist/media.js +218 -0
  121. package/dist/memory.d.ts +17 -8
  122. package/dist/memory.d.ts.map +1 -1
  123. package/dist/memory.js +273 -121
  124. package/dist/messages.d.ts +56 -0
  125. package/dist/messages.d.ts.map +1 -0
  126. package/dist/messages.js +158 -0
  127. package/dist/model.d.ts +8 -11
  128. package/dist/model.d.ts.map +1 -1
  129. package/dist/model.js +6 -23
  130. package/dist/models.d.ts +10 -0
  131. package/dist/models.d.ts.map +1 -0
  132. package/dist/models.js +153 -0
  133. package/dist/name.d.ts +4 -0
  134. package/dist/name.d.ts.map +1 -0
  135. package/dist/name.js +122 -0
  136. package/dist/observation.d.ts +17 -3
  137. package/dist/observation.d.ts.map +1 -1
  138. package/dist/observation.js +107 -17
  139. package/dist/opened.d.ts +22 -0
  140. package/dist/opened.d.ts.map +1 -0
  141. package/dist/opened.js +107 -0
  142. package/dist/opening.d.ts +4 -0
  143. package/dist/opening.d.ts.map +1 -0
  144. package/dist/opening.js +53 -0
  145. package/dist/outcome.d.ts +47 -9
  146. package/dist/outcome.d.ts.map +1 -1
  147. package/dist/outcome.js +56 -2
  148. package/dist/overlay.d.ts +7 -5
  149. package/dist/overlay.d.ts.map +1 -1
  150. package/dist/overlay.js +123 -182
  151. package/dist/page-metadata.d.ts +8 -0
  152. package/dist/page-metadata.d.ts.map +1 -0
  153. package/dist/page-metadata.js +19 -0
  154. package/dist/parts.d.ts +4 -0
  155. package/dist/parts.d.ts.map +1 -0
  156. package/dist/parts.js +13 -0
  157. package/dist/paths.d.ts +2 -0
  158. package/dist/paths.d.ts.map +1 -1
  159. package/dist/paths.js +26 -0
  160. package/dist/preparation.d.ts +20 -0
  161. package/dist/preparation.d.ts.map +1 -0
  162. package/dist/preparation.js +227 -0
  163. package/dist/presence.d.ts +52 -0
  164. package/dist/presence.d.ts.map +1 -0
  165. package/dist/presence.js +220 -0
  166. package/dist/queries.d.ts +16 -0
  167. package/dist/queries.d.ts.map +1 -0
  168. package/dist/queries.js +282 -0
  169. package/dist/query.d.ts +21 -203
  170. package/dist/query.d.ts.map +1 -1
  171. package/dist/query.js +3 -491
  172. package/dist/{chat/questions.d.ts → questions.d.ts} +5 -7
  173. package/dist/questions.d.ts.map +1 -0
  174. package/dist/{chat/questions.js → questions.js} +11 -7
  175. package/dist/queue.d.ts +40 -0
  176. package/dist/queue.d.ts.map +1 -0
  177. package/dist/queue.js +450 -0
  178. package/dist/reach.d.ts +20 -9
  179. package/dist/reach.d.ts.map +1 -1
  180. package/dist/reach.js +341 -111
  181. package/dist/react.d.ts +16 -4
  182. package/dist/react.d.ts.map +1 -1
  183. package/dist/react.js +35 -15
  184. package/dist/{chat/read.d.ts → read.d.ts} +2 -0
  185. package/dist/read.d.ts.map +1 -0
  186. package/dist/{chat/read.js → read.js} +4 -0
  187. package/dist/readiness.d.ts +14 -18
  188. package/dist/readiness.d.ts.map +1 -1
  189. package/dist/readiness.js +2 -8
  190. package/dist/reads.d.ts +38 -10
  191. package/dist/reads.d.ts.map +1 -1
  192. package/dist/reads.js +163 -83
  193. package/dist/recovery.d.ts +5 -2
  194. package/dist/recovery.d.ts.map +1 -1
  195. package/dist/recovery.js +65 -8
  196. package/dist/refresh.d.ts +18 -15
  197. package/dist/refresh.d.ts.map +1 -1
  198. package/dist/refresh.js +145 -60
  199. package/dist/refusal.d.ts +5 -0
  200. package/dist/refusal.d.ts.map +1 -0
  201. package/dist/refusal.js +55 -0
  202. package/dist/replica.d.ts +49 -36
  203. package/dist/replica.d.ts.map +1 -1
  204. package/dist/replica.js +320 -196
  205. package/dist/retried.d.ts +30 -0
  206. package/dist/retried.d.ts.map +1 -0
  207. package/dist/retried.js +72 -0
  208. package/dist/room-draft.d.ts +28 -11
  209. package/dist/room-draft.d.ts.map +1 -1
  210. package/dist/room-draft.js +194 -118
  211. package/dist/room-drafts.d.ts +24 -0
  212. package/dist/room-drafts.d.ts.map +1 -0
  213. package/dist/room-drafts.js +217 -0
  214. package/dist/rows.d.ts +31 -30
  215. package/dist/rows.d.ts.map +1 -1
  216. package/dist/rows.js +60 -120
  217. package/dist/runtime.d.ts +34 -0
  218. package/dist/runtime.d.ts.map +1 -0
  219. package/dist/runtime.js +1 -0
  220. package/dist/save.d.ts +43 -49
  221. package/dist/save.d.ts.map +1 -1
  222. package/dist/save.js +776 -275
  223. package/dist/saves.d.ts +32 -0
  224. package/dist/saves.d.ts.map +1 -0
  225. package/dist/saves.js +410 -0
  226. package/dist/search.d.ts +12 -95
  227. package/dist/search.d.ts.map +1 -1
  228. package/dist/search.js +10 -266
  229. package/dist/seed.d.ts +11 -2
  230. package/dist/seed.d.ts.map +1 -1
  231. package/dist/seed.js +71 -1
  232. package/dist/shared.d.ts +6 -7
  233. package/dist/shared.d.ts.map +1 -1
  234. package/dist/shared.js +75 -104
  235. package/dist/shown.d.ts +33 -0
  236. package/dist/shown.d.ts.map +1 -0
  237. package/dist/shown.js +302 -0
  238. package/dist/socket/admission.d.ts +7 -0
  239. package/dist/socket/admission.d.ts.map +1 -0
  240. package/dist/socket/admission.js +39 -0
  241. package/dist/socket/answers.d.ts +6 -0
  242. package/dist/socket/answers.d.ts.map +1 -0
  243. package/dist/socket/answers.js +20 -0
  244. package/dist/socket/lanes.d.ts +28 -0
  245. package/dist/socket/lanes.d.ts.map +1 -0
  246. package/dist/socket/lanes.js +103 -0
  247. package/dist/socket/reads.d.ts +10 -0
  248. package/dist/socket/reads.d.ts.map +1 -0
  249. package/dist/socket/reads.js +31 -0
  250. package/dist/socket/session.d.ts +38 -0
  251. package/dist/socket/session.d.ts.map +1 -0
  252. package/dist/socket/session.js +23 -0
  253. package/dist/socket.d.ts +67 -0
  254. package/dist/socket.d.ts.map +1 -0
  255. package/dist/socket.js +164 -0
  256. package/dist/source.d.ts +54 -0
  257. package/dist/source.d.ts.map +1 -0
  258. package/dist/source.js +82 -0
  259. package/dist/status.d.ts +4 -5
  260. package/dist/status.d.ts.map +1 -1
  261. package/dist/status.js +3 -7
  262. package/dist/store/installs.d.ts +30 -0
  263. package/dist/store/installs.d.ts.map +1 -0
  264. package/dist/store/installs.js +34 -0
  265. package/dist/store/readiness.d.ts +10 -0
  266. package/dist/store/readiness.d.ts.map +1 -0
  267. package/dist/store/readiness.js +52 -0
  268. package/dist/store/records.d.ts +214 -0
  269. package/dist/store/records.d.ts.map +1 -0
  270. package/dist/store/records.js +438 -0
  271. package/dist/store/room-held.d.ts +8 -0
  272. package/dist/store/room-held.d.ts.map +1 -0
  273. package/dist/store/room-held.js +17 -0
  274. package/dist/store/space.d.ts +11 -0
  275. package/dist/store/space.d.ts.map +1 -0
  276. package/dist/store/space.js +41 -0
  277. package/dist/store/watchers.d.ts +17 -0
  278. package/dist/store/watchers.d.ts.map +1 -0
  279. package/dist/store/watchers.js +56 -0
  280. package/dist/store/writes.d.ts +24 -0
  281. package/dist/store/writes.d.ts.map +1 -0
  282. package/dist/store/writes.js +125 -0
  283. package/dist/store.d.ts +111 -164
  284. package/dist/store.d.ts.map +1 -1
  285. package/dist/store.js +159 -754
  286. package/dist/stored.d.ts +157 -0
  287. package/dist/stored.d.ts.map +1 -0
  288. package/dist/stored.js +649 -0
  289. package/dist/surface.d.ts +88 -0
  290. package/dist/surface.d.ts.map +1 -0
  291. package/dist/surface.js +220 -0
  292. package/dist/sync.d.ts +19 -0
  293. package/dist/sync.d.ts.map +1 -0
  294. package/dist/sync.js +535 -0
  295. package/dist/tables.d.ts +415 -0
  296. package/dist/tables.d.ts.map +1 -0
  297. package/dist/tables.js +761 -0
  298. package/dist/tallies.d.ts +18 -0
  299. package/dist/tallies.d.ts.map +1 -0
  300. package/dist/tallies.js +129 -0
  301. package/dist/transfer.d.ts +0 -5
  302. package/dist/transfer.d.ts.map +1 -1
  303. package/dist/turn.d.ts +5 -3
  304. package/dist/turn.d.ts.map +1 -1
  305. package/dist/turn.js +51 -21
  306. package/dist/validation.d.ts +29 -0
  307. package/dist/validation.d.ts.map +1 -0
  308. package/dist/validation.js +104 -0
  309. package/dist/windows.d.ts +9 -16
  310. package/dist/windows.d.ts.map +1 -1
  311. package/dist/windows.js +11 -75
  312. package/dist/wire.d.ts +89 -9
  313. package/dist/wire.d.ts.map +1 -1
  314. package/dist/wire.js +29 -6
  315. package/package.json +19 -19
  316. package/AGENTS.md +0 -299
  317. package/dist/acquisition.d.ts +0 -14
  318. package/dist/acquisition.d.ts.map +0 -1
  319. package/dist/acquisition.js +0 -24
  320. package/dist/attempt.d.ts +0 -16
  321. package/dist/attempt.d.ts.map +0 -1
  322. package/dist/attempt.js +0 -70
  323. package/dist/chat/acts.d.ts +0 -33
  324. package/dist/chat/acts.d.ts.map +0 -1
  325. package/dist/chat/acts.js +0 -36
  326. package/dist/chat/context.d.ts +0 -3
  327. package/dist/chat/context.d.ts.map +0 -1
  328. package/dist/chat/earlier.d.ts +0 -10
  329. package/dist/chat/earlier.d.ts.map +0 -1
  330. package/dist/chat/earlier.js +0 -54
  331. package/dist/chat/input.d.ts +0 -9
  332. package/dist/chat/input.d.ts.map +0 -1
  333. package/dist/chat/input.js +0 -99
  334. package/dist/chat/kit.d.ts +0 -61
  335. package/dist/chat/kit.d.ts.map +0 -1
  336. package/dist/chat/kit.js +0 -123
  337. package/dist/chat/lasting.d.ts +0 -6
  338. package/dist/chat/lasting.d.ts.map +0 -1
  339. package/dist/chat/lasting.js +0 -19
  340. package/dist/chat/list.d.ts +0 -27
  341. package/dist/chat/list.d.ts.map +0 -1
  342. package/dist/chat/list.js +0 -99
  343. package/dist/chat/markdown.d.ts +0 -20
  344. package/dist/chat/markdown.d.ts.map +0 -1
  345. package/dist/chat/markdown.js +0 -188
  346. package/dist/chat/message.d.ts +0 -6
  347. package/dist/chat/message.d.ts.map +0 -1
  348. package/dist/chat/message.js +0 -192
  349. package/dist/chat/messages.d.ts +0 -22
  350. package/dist/chat/messages.d.ts.map +0 -1
  351. package/dist/chat/messages.js +0 -155
  352. package/dist/chat/name.d.ts +0 -6
  353. package/dist/chat/name.d.ts.map +0 -1
  354. package/dist/chat/name.js +0 -37
  355. package/dist/chat/opened.d.ts +0 -11
  356. package/dist/chat/opened.d.ts.map +0 -1
  357. package/dist/chat/opened.js +0 -17
  358. package/dist/chat/overlay.d.ts +0 -31
  359. package/dist/chat/overlay.d.ts.map +0 -1
  360. package/dist/chat/overlay.js +0 -97
  361. package/dist/chat/parts.d.ts +0 -57
  362. package/dist/chat/parts.d.ts.map +0 -1
  363. package/dist/chat/parts.js +0 -119
  364. package/dist/chat/process.d.ts +0 -20
  365. package/dist/chat/process.d.ts.map +0 -1
  366. package/dist/chat/process.js +0 -32
  367. package/dist/chat/provider.d.ts +0 -63
  368. package/dist/chat/provider.d.ts.map +0 -1
  369. package/dist/chat/provider.js +0 -635
  370. package/dist/chat/question.d.ts +0 -9
  371. package/dist/chat/question.d.ts.map +0 -1
  372. package/dist/chat/question.js +0 -69
  373. package/dist/chat/questions.d.ts.map +0 -1
  374. package/dist/chat/read.d.ts.map +0 -1
  375. package/dist/chat/ready.d.ts +0 -34
  376. package/dist/chat/ready.d.ts.map +0 -1
  377. package/dist/chat/ready.js +0 -91
  378. package/dist/chat/style.d.ts +0 -4
  379. package/dist/chat/style.d.ts.map +0 -1
  380. package/dist/chat/style.js +0 -302
  381. package/dist/chat.d.ts +0 -14
  382. package/dist/chat.d.ts.map +0 -1
  383. package/dist/chat.js +0 -8
  384. package/dist/fence.d.ts +0 -6
  385. package/dist/fence.d.ts.map +0 -1
  386. package/dist/fence.js +0 -10
  387. package/dist/log.d.ts +0 -5
  388. package/dist/log.d.ts.map +0 -1
  389. package/dist/log.js +0 -14
  390. package/dist/read-side.d.ts +0 -25
  391. package/dist/read-side.d.ts.map +0 -1
  392. package/dist/read-side.js +0 -761
@@ -0,0 +1,277 @@
1
+ import { catchUpConversations, receiveConversationEvent, reconcileConversations, } from './conversation.js';
2
+ import { declared } from './declaration.js';
3
+ import { uncaught } from './failure.js';
4
+ import { catching, replaced } from './install.js';
5
+ import { connectionLost } from './locks.js';
6
+ import { fenceLive } from './lost.js';
7
+ import { cachedModels, revoked, settleModels } from './models.js';
8
+ import { refuse } from './refusal.js';
9
+ import { moveTo, recoverReads, rest, SERVICE_MODE_TOPIC, show, submissionDue, transferring, } from './shown.js';
10
+ import { applyRoom, changeAuthority, countAuthorityChange, finishOpening, loadRoom, OPENING_LANE, reload, resynchronize, sync, } from './sync.js';
11
+ const CONVERSATION_LANE = 'conversations';
12
+ const RELOADING = 'reloading';
13
+ function closing(runtime, opened) {
14
+ const { store, socket } = runtime;
15
+ return socket.lanes.task(OPENING_LANE, async (live) => {
16
+ if (!live())
17
+ return;
18
+ const local = await store.open();
19
+ if (!opened && !socket.isOpen())
20
+ await cachedModels(runtime, local);
21
+ await rest(runtime, null, live);
22
+ });
23
+ }
24
+ function closedSocket(runtime, lapsed, lost, opened) {
25
+ const { socket, presence, conversations } = runtime;
26
+ const { session } = socket;
27
+ socket.notifyReady();
28
+ presence.stopAsking();
29
+ connectionLost(runtime);
30
+ if (lost)
31
+ conversations.lost();
32
+ if (lapsed) {
33
+ void refuse(runtime, 'revoked-authorization');
34
+ return;
35
+ }
36
+ session.set({ complete: false });
37
+ const { streamed, moving } = session.now();
38
+ if (streamed !== null)
39
+ streamed.complete = false;
40
+ moveTo(runtime, {
41
+ ...moving,
42
+ state: moving.state === 'synced' ? 'syncing' : moving.state,
43
+ providerUnreachable: moving.providerUnreachable || (!opened && lost),
44
+ });
45
+ void closing(runtime, opened);
46
+ }
47
+ function owedReloads(runtime, expired, held) {
48
+ const { store, presence } = runtime;
49
+ const reloading = presence
50
+ .rooms()
51
+ .filter((room) => !expired.includes(room.locator) && revoked(held.get(room.locator)?.record.model))
52
+ .map((room) => room.locator);
53
+ for (const locator of reloading)
54
+ catching(store, locator);
55
+ recoverReads(runtime);
56
+ return reloading;
57
+ }
58
+ async function reloadNow(runtime, replacing, progress, held, installing) {
59
+ const { store, socket, presence } = runtime;
60
+ const { lanes } = socket;
61
+ const discovered = presence.rooms();
62
+ const reloaded = discovered.filter((room) => held.has(room.locator) && !installing.has(room.locator) && replacing(room));
63
+ const acquired = discovered.filter((room) => (!held.has(room.locator) || installing.has(room.locator)) &&
64
+ room.replica.admission === 'admitted' &&
65
+ replacing(room));
66
+ for (const room of reloaded)
67
+ presence.reload(room.locator, true);
68
+ try {
69
+ const local = await store.open();
70
+ const kept = acquired.length === 0 ? new Set() : (await local.held()).staged;
71
+ for (const room of reloaded) {
72
+ void lanes
73
+ .roomTask(room.locator, (live) => reload(runtime, room, local, progress, live))
74
+ .then(() => rest(runtime, progress));
75
+ }
76
+ for (const room of acquired) {
77
+ const unheld = installing.has(room.locator) ? undefined : { staged: kept.has(room.locator) };
78
+ void lanes
79
+ .roomTask(room.locator, (live) => loadRoom(runtime, room, local, progress, live, unheld))
80
+ .then(() => rest(runtime, progress));
81
+ }
82
+ runtime.retries.succeeded('download', RELOADING);
83
+ }
84
+ catch (error) {
85
+ runtime.retries.failed('download', RELOADING, error);
86
+ for (const room of reloaded)
87
+ presence.reload(room.locator, false);
88
+ progress.reachable = false;
89
+ }
90
+ }
91
+ function caughtUpRooms(runtime, expired) {
92
+ const { store, socket, presence } = runtime;
93
+ const { session } = socket;
94
+ const progress = session.now().underway;
95
+ session.set({ underway: null });
96
+ socket.named();
97
+ const cycle = progress ?? { complete: true, reachable: true };
98
+ replaced(store, expired);
99
+ const installing = store.installs.underway();
100
+ const held = progress === null ? store.rooms(expired) : store.rooms();
101
+ const reloading = progress === null
102
+ ? Promise.resolve([])
103
+ : held.then((stored) => owedReloads(runtime, expired, stored));
104
+ const replacing = Promise.all([held, reloading]).then(([stored, owed]) => reloadNow(runtime, (room) => expired.includes(room.locator) || owed.includes(room.locator), cycle, stored, installing));
105
+ return socket.lanes.task(OPENING_LANE, async (live) => {
106
+ if (!live())
107
+ return;
108
+ if (progress === null) {
109
+ await replacing;
110
+ await rest(runtime, cycle, live);
111
+ return;
112
+ }
113
+ try {
114
+ const local = await store.open();
115
+ await replacing;
116
+ if (progress.reachable) {
117
+ const stored = await held;
118
+ const owed = await reloading;
119
+ await settleModels(runtime, new Map(presence
120
+ .rooms()
121
+ .filter((room) => stored.has(room.locator) &&
122
+ !expired.includes(room.locator) &&
123
+ !owed.includes(room.locator))
124
+ .map((room) => [room.locator, declared(room)])), 'current', local);
125
+ }
126
+ runtime.retries.succeeded('download', OPENING_LANE);
127
+ }
128
+ catch (error) {
129
+ runtime.retries.failed('download', OPENING_LANE, error);
130
+ progress.complete = false;
131
+ progress.reachable = false;
132
+ }
133
+ if (live())
134
+ await finishOpening(runtime, progress, live);
135
+ });
136
+ }
137
+ function signalled(runtime, mode) {
138
+ const { store, socket } = runtime;
139
+ const { session } = socket;
140
+ const { closed, serviceMode, haltedRefusal, openSignals } = session.now();
141
+ if (closed)
142
+ return;
143
+ if (mode === 'open')
144
+ session.set({ openSignals: openSignals + 1 });
145
+ const releasing = mode === 'open' && (haltedRefusal || serviceMode === 'write-halted');
146
+ if (mode === 'open')
147
+ session.set({ haltedRefusal: false });
148
+ if (mode !== serviceMode) {
149
+ session.set({ serviceMode: mode });
150
+ store.readiness.queue();
151
+ store.tell(SERVICE_MODE_TOPIC, mode);
152
+ }
153
+ if (releasing)
154
+ void submissionDue(runtime);
155
+ }
156
+ async function runCurrency(runtime, live) {
157
+ const { socket, conversations } = runtime;
158
+ const { session } = socket;
159
+ if (session.now().currencyQueued === socket.generation())
160
+ session.set({ currencyQueued: null });
161
+ if (!live())
162
+ return;
163
+ await reconcileConversations(conversations);
164
+ if (conversations.current()) {
165
+ await rest(runtime, null, live);
166
+ return;
167
+ }
168
+ const progress = {
169
+ complete: false,
170
+ reachable: !session.now().moving.providerUnreachable,
171
+ };
172
+ moveTo(runtime, transferring(runtime));
173
+ try {
174
+ await catchUpConversations(conversations, progress);
175
+ runtime.retries.succeeded('conversations', CONVERSATION_LANE);
176
+ }
177
+ catch (error) {
178
+ runtime.retries.failed('conversations', CONVERSATION_LANE, error);
179
+ progress.reachable = false;
180
+ }
181
+ await rest(runtime, progress, live);
182
+ }
183
+ export function scheduleCurrency(runtime) {
184
+ const { socket } = runtime;
185
+ const { session } = socket;
186
+ if (session.now().currencyQueued === socket.generation() || socket.closed() || socket.stopping())
187
+ return;
188
+ session.set({ currencyQueued: socket.generation() });
189
+ void socket.lanes.task(CONVERSATION_LANE, (live) => runCurrency(runtime, live));
190
+ }
191
+ export function spaceFreed(runtime) {
192
+ const { store, socket } = runtime;
193
+ store.prepareAgain();
194
+ store.readiness.queue();
195
+ const { closed, authorization } = socket.session.now();
196
+ if (closed || authorization === undefined)
197
+ return;
198
+ if (!socket.streamed)
199
+ void sync(runtime, 'unstreamed', null);
200
+ else
201
+ void resynchronize(runtime);
202
+ }
203
+ export function close({ store, socket, presence, conversations, recovery, liveQueries, figures, }) {
204
+ if (socket.closed())
205
+ return;
206
+ socket.close();
207
+ presence.close();
208
+ conversations.close();
209
+ void recovery.retire();
210
+ liveQueries.close();
211
+ figures.close();
212
+ store.close();
213
+ }
214
+ export async function stop(runtime) {
215
+ const { store, socket, presence, recovery } = runtime;
216
+ socket.session.set({ stopping: true });
217
+ presence.stopAsking();
218
+ socket.stopReads();
219
+ await recovery.retire();
220
+ await socket.lanes.finished();
221
+ await store.written();
222
+ close(runtime);
223
+ }
224
+ export function start(runtime, signal) {
225
+ const { store, socket, presence, conversations, lastAnswers, recovery } = runtime;
226
+ const closeRuntime = () => close(runtime);
227
+ socket.observeServiceMode((mode) => signalled(runtime, mode));
228
+ socket.observeConversations((event) => {
229
+ if (event.kind === 'list' || event.kind === 'listed' || event.kind === 'unlisted')
230
+ store.readiness.queue();
231
+ receiveConversationEvent(conversations, event);
232
+ if (event.kind !== 'gap' || conversations.current())
233
+ return;
234
+ show(runtime);
235
+ scheduleCurrency(runtime);
236
+ });
237
+ signal?.addEventListener('abort', closeRuntime, { once: true });
238
+ if (signal?.aborted)
239
+ closeRuntime();
240
+ socket.observe((event) => {
241
+ if (event.kind === 'opened') {
242
+ presence.connectionLive();
243
+ conversations.reopened();
244
+ lastAnswers.reopened();
245
+ recovery.resume();
246
+ }
247
+ else if (event.kind === 'discovered') {
248
+ if (event.missed)
249
+ countAuthorityChange(runtime);
250
+ void sync(runtime, 'opened', event.discovery);
251
+ }
252
+ else if (event.kind === 'closed') {
253
+ closedSocket(runtime, event.revoked, event.lost, event.opened);
254
+ }
255
+ else if (event.kind === 'caught-up')
256
+ void caughtUpRooms(runtime, event.expired);
257
+ else if (event.kind === 'authority-changed') {
258
+ if (socket.isAnnounced() && socket.isOpen())
259
+ fenceLive(runtime, event.left);
260
+ void changeAuthority(runtime, event);
261
+ }
262
+ else
263
+ void applyRoom(runtime, event);
264
+ });
265
+ void store
266
+ .open()
267
+ .then(async (local) => {
268
+ if ((await local.facts()).capabilities.length > 0)
269
+ socket.readyFromStore();
270
+ })
271
+ .catch((error) => {
272
+ socket.readyFromStore();
273
+ uncaught(error);
274
+ });
275
+ if (!socket.streamed)
276
+ void sync(runtime, 'unstreamed', null);
277
+ }
@@ -0,0 +1,48 @@
1
+ import type { HeldRooms } from '@agentshouse/mdmodel';
2
+ import type { DiscoveredRoom, HeldRoom, OperationScopes, ProviderRefusal, ReplicaAdmission, RoomDeclaration } from './adapter.js';
3
+ import type { Composition } from './collection.js';
4
+ import { type ModelState, type TypesResult } from './model.js';
5
+ import { type PortReach } from './reach.js';
6
+ import type { ReplicaRecord } from './replica.js';
7
+ import type { Runtime } from './runtime.js';
8
+ import type { Stored } from './store.js';
9
+ export type AppTypedSelection = {
10
+ roots: readonly string[];
11
+ model: TypesResult;
12
+ };
13
+ export type AppRoom = {
14
+ name: string;
15
+ locator: string;
16
+ handle: string;
17
+ operations: OperationScopes;
18
+ replica: ReplicaAdmission;
19
+ model: TypesResult;
20
+ typedSelection: AppTypedSelection | null;
21
+ providerOwnedPaths: readonly string[];
22
+ authoredPaths: readonly string[];
23
+ roomVersion: string | null;
24
+ documents: number;
25
+ synchronizationAvailable: boolean;
26
+ refusal: ProviderRefusal | null;
27
+ locked: boolean;
28
+ };
29
+ type ListedRoom = Omit<AppRoom, 'documents' | 'locked'>;
30
+ type ListedEntry = ListedRoom & {
31
+ readonly documents: number;
32
+ };
33
+ export type Listing = ReadonlyMap<string, ListedEntry>;
34
+ export declare function modelIn({ socket, presence }: Runtime, locator: string, stored: Stored | undefined): ModelState;
35
+ export declare function compositionFor(runtime: Runtime, record: ReplicaRecord): Composition;
36
+ export declare function declarationOf({ presence }: Runtime, locator: string, stored: Stored | undefined): {
37
+ readonly room: RoomDeclaration;
38
+ readonly available: boolean;
39
+ } | undefined;
40
+ export declare function listedLocators({ presence }: Runtime, held: ReadonlyMap<string, unknown>): string[];
41
+ export declare function patchedListing(runtime: Runtime, changed: ReadonlySet<string>): Promise<Listing | null>;
42
+ export declare function listingNow(runtime: Runtime): Promise<Listing>;
43
+ export declare function shownRooms({ presence }: Runtime, listing: Listing): readonly AppRoom[];
44
+ export declare function roomFacts(runtime: Runtime, reach?: PortReach | null): Promise<HeldRooms>;
45
+ export declare function heldRooms({ store }: Runtime, listed: readonly DiscoveredRoom[]): Promise<HeldRoom[]>;
46
+ export declare function name(runtime: Runtime, locator: string): Promise<void>;
47
+ export {};
48
+ //# sourceMappingURL=listing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"listing.d.ts","sourceRoot":"","sources":["../src/listing.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,139 @@
1
+ import { declared } from './declaration.js';
2
+ import { modelTypes, NO_MODEL } from './model.js';
3
+ import { governs, holds } from './reach.js';
4
+ export function modelIn({ socket, presence }, locator, stored) {
5
+ if (socket.session.now().refusal?.code === 'revoked-authorization')
6
+ return { status: 'unavailable', reason: 'revoked' };
7
+ return stored?.record.model ?? presence.unheldModel(locator) ?? NO_MODEL;
8
+ }
9
+ export function compositionFor(runtime, record) {
10
+ return runtime.store.composed({
11
+ ...record,
12
+ model: modelIn(runtime, record.locator, { record, indexed: true, documents: 0 }),
13
+ });
14
+ }
15
+ export function declarationOf({ presence }, locator, stored) {
16
+ const listed = presence.room(locator);
17
+ const room = stored?.record.declaration ?? (listed === undefined ? undefined : declared(listed));
18
+ if (room === undefined)
19
+ return undefined;
20
+ return {
21
+ room,
22
+ available: presence.available(locator, stored?.record.declaration.replica.selection),
23
+ };
24
+ }
25
+ export function listedLocators({ presence }, held) {
26
+ const listed = presence.rooms().map(({ locator }) => locator);
27
+ return [...new Set([...listed, ...held.keys()])];
28
+ }
29
+ function selectionModel({ socket, builtIn }) {
30
+ return socket.session.now().refusal?.code === 'revoked-authorization'
31
+ ? { status: 'unavailable', reason: 'revoked' }
32
+ : builtIn;
33
+ }
34
+ function listedRoom(runtime, locator, stored) {
35
+ const declaration = declarationOf(runtime, locator, stored);
36
+ if (declaration === undefined)
37
+ return undefined;
38
+ const { room, available } = declaration;
39
+ const selection = room.typedSelection;
40
+ return {
41
+ name: room.name,
42
+ locator,
43
+ handle: room.handle,
44
+ operations: room.operations,
45
+ replica: room.replica,
46
+ model: modelTypes(modelIn(runtime, locator, stored)),
47
+ typedSelection: selection === null
48
+ ? null
49
+ : { roots: selection.roots, model: modelTypes(selectionModel(runtime)) },
50
+ providerOwnedPaths: room.providerOwnedPaths,
51
+ authoredPaths: room.authoredPaths,
52
+ roomVersion: stored?.record.roomVersion ?? null,
53
+ synchronizationAvailable: available,
54
+ refusal: runtime.presence.refusal(locator),
55
+ documents: stored?.documents ?? 0,
56
+ };
57
+ }
58
+ function listingOf(runtime, held) {
59
+ const listing = new Map();
60
+ for (const locator of listedLocators(runtime, held)) {
61
+ const room = listedRoom(runtime, locator, held.get(locator));
62
+ if (room !== undefined)
63
+ listing.set(locator, room);
64
+ }
65
+ return listing;
66
+ }
67
+ export async function patchedListing(runtime, changed) {
68
+ const { store } = runtime;
69
+ const { roomsShown } = store.device.now();
70
+ if (roomsShown === null)
71
+ return null;
72
+ const held = await store.rooms([...changed]);
73
+ const listing = new Map(roomsShown);
74
+ for (const locator of changed) {
75
+ const room = listedRoom(runtime, locator, held.get(locator));
76
+ if (room === undefined || !listing.has(locator))
77
+ return null;
78
+ listing.set(locator, room);
79
+ }
80
+ return listing;
81
+ }
82
+ export async function listingNow(runtime) {
83
+ return listingOf(runtime, await runtime.store.rooms());
84
+ }
85
+ export function shownRooms({ presence }, listing) {
86
+ const locked = new Set(presence.lockedAmong(new Map([...listing].map(([locator, room]) => [locator, room.replica.offline]))));
87
+ return structuredClone([...listing.values()].map(({ documents, ...room }) => locked.has(room.locator)
88
+ ? {
89
+ ...room,
90
+ model: modelTypes(NO_MODEL),
91
+ typedSelection: null,
92
+ documents: 0,
93
+ locked: true,
94
+ }
95
+ : { ...room, documents, locked: false }));
96
+ }
97
+ export async function roomFacts(runtime, reach = null) {
98
+ const { store, socket, builtIn } = runtime;
99
+ const held = await store.rooms();
100
+ const rooms = [...listingOf(runtime, held).values()]
101
+ .filter((room) => holds(reach, room.locator))
102
+ .map((room) => {
103
+ const governed = governs(reach, room);
104
+ const attached = [
105
+ ...(governed.collection ? [modelIn(runtime, room.locator, held.get(room.locator))] : []),
106
+ ...(governed.selection ? [builtIn] : []),
107
+ ];
108
+ return {
109
+ locator: room.locator,
110
+ available: attached.every((model) => model.status !== 'unavailable'),
111
+ types: attached.flatMap((model) => model.status === 'unavailable' ? [] : Object.values(model.types)),
112
+ };
113
+ });
114
+ return { listed: socket.session.now().roomsListed, rooms };
115
+ }
116
+ export async function heldRooms({ store }, listed) {
117
+ const stored = await store.rooms(listed.map((room) => room.locator));
118
+ return listed.flatMap((room) => {
119
+ const record = stored.get(room.locator)?.record;
120
+ if (record === undefined) {
121
+ return room.replica.admission === 'admitted'
122
+ ? [{ locator: room.locator, roomVersion: null }]
123
+ : [];
124
+ }
125
+ if (record.declaration.replica.selection !== room.replica.selection)
126
+ return [];
127
+ return [{ locator: room.locator, roomVersion: record.roomVersion }];
128
+ });
129
+ }
130
+ export async function name(runtime, locator) {
131
+ const { socket, presence } = runtime;
132
+ const room = presence.room(locator);
133
+ if (!socket.streamed || room === undefined || !socket.isOpen() || !socket.isHanded())
134
+ return;
135
+ const [held] = await heldRooms(runtime, [room]);
136
+ if (held === undefined || !socket.isOpen() || !socket.isHanded())
137
+ return;
138
+ socket.name(held);
139
+ }
package/dist/live.d.ts ADDED
@@ -0,0 +1,23 @@
1
+ import type { ChangeSet } from './change-set.js';
2
+ import { type KeyedResult, type QueryMessage } from './observation.js';
3
+ import type { PendingResult, Plan, QueryCoverage } from './query.js';
4
+ import type { Fail } from './reach.js';
5
+ import type { QueryRoom } from './tables.js';
6
+ export type Cover = {
7
+ coverage: QueryCoverage;
8
+ rooms: readonly QueryRoom[];
9
+ } | PendingResult;
10
+ export type Ran = KeyedResult & {
11
+ readonly current: () => boolean;
12
+ };
13
+ export type Run = (plan: Plan, cover: () => Promise<Cover>) => Promise<Ran>;
14
+ type Listener = (message: QueryMessage) => void;
15
+ export type LiveQueries<H> = {
16
+ touched(set: ChangeSet): void;
17
+ recover(): void;
18
+ watch(plan: Plan, identity: string, cover: (held: H) => Cover, deliver: Listener, failed: Fail): () => void;
19
+ close(): void;
20
+ };
21
+ export declare function createLiveQueries<H>(run: Run, holding: () => Promise<H>): LiveQueries<H>;
22
+ export {};
23
+ //# sourceMappingURL=live.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"live.d.ts","sourceRoot":"","sources":["../src/live.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAIL,KAAK,WAAW,EAChB,KAAK,YAAY,EAClB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AACrE,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAGvC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C,MAAM,MAAM,KAAK,GAAG;IAAE,QAAQ,EAAE,aAAa,CAAC;IAAC,KAAK,EAAE,SAAS,SAAS,EAAE,CAAA;CAAE,GAAG,aAAa,CAAC;AAE7F,MAAM,MAAM,GAAG,GAAG,WAAW,GAAG;IAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,OAAO,CAAA;CAAE,CAAC;AAEpE,MAAM,MAAM,GAAG,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC,KAAK,CAAC,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;AAE5E,KAAK,QAAQ,GAAG,CAAC,OAAO,EAAE,YAAY,KAAK,IAAI,CAAC;AAchD,MAAM,MAAM,WAAW,CAAC,CAAC,IAAI;IAC3B,OAAO,CAAC,GAAG,EAAE,SAAS,GAAG,IAAI,CAAC;IAC9B,OAAO,IAAI,IAAI,CAAC;IAChB,KAAK,CACH,IAAI,EAAE,IAAI,EACV,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,KAAK,EACzB,OAAO,EAAE,QAAQ,EACjB,MAAM,EAAE,IAAI,GACX,MAAM,IAAI,CAAC;IACd,KAAK,IAAI,IAAI,CAAC;CACf,CAAC;AAmCF,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,CA2HxF"}
package/dist/live.js ADDED
@@ -0,0 +1,165 @@
1
+ import { changeOf, digestOf, } from './observation.js';
2
+ import { uncaught } from './failure.js';
3
+ import { roomOfKey } from './rows.js';
4
+ function narrowed(plan) {
5
+ return (plan.paths !== null &&
6
+ plan.hop === null &&
7
+ plan.backlinks === null &&
8
+ !(plan.shape.kind === 'documents' && plan.shape.backlinks));
9
+ }
10
+ function reads(plan, locator) {
11
+ if (plan.locked.includes(locator))
12
+ return false;
13
+ if (plan.rooms !== null && !plan.rooms.includes(locator))
14
+ return false;
15
+ if (plan.reach === null)
16
+ return true;
17
+ return (plan.reach.rooms.includes(locator) ||
18
+ plan.reach.documents.some((document) => roomOfKey(document) === locator));
19
+ }
20
+ function affected(plan, set) {
21
+ if (set.rooms.some((locator) => reads(plan, locator)))
22
+ return true;
23
+ const paths = narrowed(plan) ? new Set(plan.paths) : null;
24
+ return set.documents.some(({ locator, path }) => reads(plan, locator) && (paths === null || path === null || paths.has(path)));
25
+ }
26
+ function shown(entry, held) {
27
+ const cover = entry.cover(held);
28
+ return JSON.stringify('pending' in cover ? cover : cover.coverage);
29
+ }
30
+ export function createLiveQueries(run, holding) {
31
+ const entries = new Map();
32
+ let closed = false;
33
+ let recovering = false;
34
+ let recoverAgain = false;
35
+ function deliver(entry, next) {
36
+ const previous = entry.digest;
37
+ entry.digest = digestOf(next);
38
+ entry.covered = JSON.stringify('pending' in next.result ? next.result : next.result.coverage);
39
+ const change = previous === undefined ? null : changeOf(previous, next);
40
+ if (change !== null) {
41
+ for (const listener of entry.ready)
42
+ listener(change);
43
+ }
44
+ for (const listener of entry.fresh.keys()) {
45
+ entry.ready.add(listener);
46
+ listener(next);
47
+ }
48
+ entry.fresh.clear();
49
+ }
50
+ async function delivered(entry) {
51
+ const { current, ...next } = await run(entry.plan, async () => entry.cover(await holding()));
52
+ if (closed || entry.listeners.size === 0)
53
+ return null;
54
+ deliver(entry, next);
55
+ return current;
56
+ }
57
+ function schedule(entry) {
58
+ if (closed || entry.listeners.size === 0)
59
+ return;
60
+ if (entry.running) {
61
+ entry.dirty = true;
62
+ return;
63
+ }
64
+ entry.running = true;
65
+ void (async () => {
66
+ try {
67
+ for (;;) {
68
+ entry.dirty = false;
69
+ const current = await delivered(entry);
70
+ if (current === null)
71
+ return;
72
+ const held = await holding();
73
+ if (entry.fresh.size > 0 || (entry.dirty && !current()))
74
+ continue;
75
+ if (shown(entry, held) === entry.covered)
76
+ break;
77
+ }
78
+ }
79
+ catch (error) {
80
+ const unanswered = [...entry.fresh.values()];
81
+ entry.fresh.clear();
82
+ for (const failed of unanswered)
83
+ failed(error);
84
+ }
85
+ finally {
86
+ entry.running = false;
87
+ }
88
+ })();
89
+ }
90
+ function recovered() {
91
+ if (recovering) {
92
+ recoverAgain = true;
93
+ return;
94
+ }
95
+ recovering = true;
96
+ void (async () => {
97
+ try {
98
+ do {
99
+ recoverAgain = false;
100
+ for (const entry of entries.values()) {
101
+ if (entry.running)
102
+ entry.dirty = true;
103
+ }
104
+ const waiting = [...entries.values()].filter((entry) => !entry.running);
105
+ if (waiting.length === 0 || closed)
106
+ continue;
107
+ const held = await holding();
108
+ for (const entry of waiting) {
109
+ if (entry.running)
110
+ continue;
111
+ if (entry.digest === undefined || shown(entry, held) !== entry.covered)
112
+ schedule(entry);
113
+ }
114
+ } while (recoverAgain && !closed);
115
+ }
116
+ catch (error) {
117
+ uncaught(error);
118
+ }
119
+ finally {
120
+ recovering = false;
121
+ }
122
+ })();
123
+ }
124
+ return {
125
+ touched(set) {
126
+ for (const entry of entries.values()) {
127
+ if (affected(entry.plan, set))
128
+ schedule(entry);
129
+ }
130
+ },
131
+ recover: recovered,
132
+ watch(plan, identity, cover, listener, failed) {
133
+ let entry = entries.get(identity);
134
+ if (entry === undefined) {
135
+ entry = {
136
+ plan,
137
+ cover,
138
+ listeners: new Set(),
139
+ fresh: new Map(),
140
+ ready: new Set(),
141
+ digest: undefined,
142
+ covered: '',
143
+ dirty: false,
144
+ running: false,
145
+ };
146
+ entries.set(identity, entry);
147
+ }
148
+ const held = entry;
149
+ held.listeners.add(listener);
150
+ held.fresh.set(listener, failed);
151
+ schedule(held);
152
+ return () => {
153
+ held.listeners.delete(listener);
154
+ held.fresh.delete(listener);
155
+ held.ready.delete(listener);
156
+ if (held.listeners.size === 0 && entries.get(identity) === held)
157
+ entries.delete(identity);
158
+ };
159
+ },
160
+ close() {
161
+ closed = true;
162
+ entries.clear();
163
+ },
164
+ };
165
+ }
@@ -0,0 +1,7 @@
1
+ import type { Runtime } from './runtime.js';
2
+ export declare function locked({ store, presence }: Runtime, locator: string): Promise<boolean>;
3
+ export declare function lockedRooms({ store, presence }: Runtime): Promise<readonly string[]>;
4
+ export declare function relocked(runtime: Runtime, before: readonly string[]): Promise<void>;
5
+ export declare function connectionLost(runtime: Runtime): void;
6
+ export declare function watchLocks({ store }: Runtime, notify: () => void): () => void;
7
+ //# sourceMappingURL=locks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"locks.d.ts","sourceRoot":"","sources":["../src/locks.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAG5C,wBAAsB,MAAM,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAE5F;AAED,wBAAsB,WAAW,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,OAAO,GAAG,OAAO,CAAC,SAAS,MAAM,EAAE,CAAC,CAK1F;AAED,wBAAsB,QAAQ,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,MAAM,EAAE,iBAKzE;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,QAU9C;AAED,wBAAgB,UAAU,CAAC,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAE7E"}