@agentshouse/mdruntime 0.1.0-c3fa75348e547 → 0.1.0-c3faae279d4d2

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 (368) hide show
  1. package/README.md +19 -16
  2. package/dist/acceptance.d.ts +6 -0
  3. package/dist/acceptance.d.ts.map +1 -0
  4. package/dist/acceptance.js +385 -0
  5. package/dist/actions.d.ts +20 -0
  6. package/dist/actions.d.ts.map +1 -0
  7. package/dist/actions.js +251 -0
  8. package/dist/adapter.d.ts +150 -81
  9. package/dist/adapter.d.ts.map +1 -1
  10. package/dist/attached-model.d.ts +7 -10
  11. package/dist/attached-model.d.ts.map +1 -1
  12. package/dist/attached-model.js +40 -41
  13. package/dist/binary.d.ts +0 -5
  14. package/dist/binary.d.ts.map +1 -1
  15. package/dist/binary.js +1 -1
  16. package/dist/bootstrap.d.ts +30 -11
  17. package/dist/bootstrap.d.ts.map +1 -1
  18. package/dist/bootstrap.js +320 -111
  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 +12 -0
  23. package/dist/chain.d.ts.map +1 -0
  24. package/dist/chain.js +64 -0
  25. package/dist/change-set.d.ts +9 -16
  26. package/dist/change-set.d.ts.map +1 -1
  27. package/dist/change-set.js +11 -89
  28. package/dist/change.d.ts +32 -1
  29. package/dist/change.d.ts.map +1 -1
  30. package/dist/change.js +14 -3
  31. package/dist/chat-types.d.ts +5 -0
  32. package/dist/chat-types.d.ts.map +1 -0
  33. package/dist/chat-types.js +13 -0
  34. package/dist/client.d.ts +33 -10
  35. package/dist/client.d.ts.map +1 -1
  36. package/dist/client.js +90 -10
  37. package/dist/collection.d.ts +11 -21
  38. package/dist/collection.d.ts.map +1 -1
  39. package/dist/collection.js +39 -291
  40. package/dist/compile.d.ts +16 -0
  41. package/dist/compile.d.ts.map +1 -0
  42. package/dist/compile.js +711 -0
  43. package/dist/connection.d.ts +7 -132
  44. package/dist/connection.d.ts.map +1 -1
  45. package/dist/connection.js +100 -3568
  46. package/dist/context.d.ts +2 -0
  47. package/dist/context.d.ts.map +1 -0
  48. package/dist/{chat/context.js → context.js} +1 -4
  49. package/dist/conversation-live.d.ts +136 -0
  50. package/dist/conversation-live.d.ts.map +1 -0
  51. package/dist/conversation-live.js +248 -0
  52. package/dist/conversation-row.d.ts +33 -0
  53. package/dist/conversation-row.d.ts.map +1 -0
  54. package/dist/conversation-row.js +53 -0
  55. package/dist/conversation.d.ts +53 -44
  56. package/dist/conversation.d.ts.map +1 -1
  57. package/dist/conversation.js +938 -715
  58. package/dist/digest.d.ts +7 -0
  59. package/dist/digest.d.ts.map +1 -0
  60. package/dist/digest.js +113 -0
  61. package/dist/discovery.d.ts +10 -0
  62. package/dist/discovery.d.ts.map +1 -0
  63. package/dist/discovery.js +175 -0
  64. package/dist/durability.d.ts +16 -4
  65. package/dist/durability.d.ts.map +1 -1
  66. package/dist/durability.js +5 -0
  67. package/dist/entry.d.ts +5 -2
  68. package/dist/entry.d.ts.map +1 -1
  69. package/dist/entry.js +33 -28
  70. package/dist/figures.d.ts +49 -0
  71. package/dist/figures.d.ts.map +1 -0
  72. package/dist/figures.js +197 -0
  73. package/dist/file.d.ts +2 -19
  74. package/dist/file.d.ts.map +1 -1
  75. package/dist/file.js +7 -122
  76. package/dist/holdings.d.ts +29 -0
  77. package/dist/holdings.d.ts.map +1 -0
  78. package/dist/holdings.js +95 -0
  79. package/dist/host.d.ts +4 -10
  80. package/dist/host.d.ts.map +1 -1
  81. package/dist/host.js +74 -41
  82. package/dist/identity.d.ts +0 -2
  83. package/dist/identity.d.ts.map +1 -1
  84. package/dist/identity.js +0 -6
  85. package/dist/index.d.ts +33 -13
  86. package/dist/index.d.ts.map +1 -1
  87. package/dist/index.js +12 -2
  88. package/dist/install.d.ts +56 -0
  89. package/dist/install.d.ts.map +1 -0
  90. package/dist/install.js +554 -0
  91. package/dist/job.d.ts +33 -0
  92. package/dist/job.d.ts.map +1 -0
  93. package/dist/job.js +54 -0
  94. package/dist/lifecycle.d.ts +7 -0
  95. package/dist/lifecycle.d.ts.map +1 -0
  96. package/dist/lifecycle.js +268 -0
  97. package/dist/listing.d.ts +53 -0
  98. package/dist/listing.d.ts.map +1 -0
  99. package/dist/listing.js +176 -0
  100. package/dist/live.d.ts +23 -0
  101. package/dist/live.d.ts.map +1 -0
  102. package/dist/live.js +163 -0
  103. package/dist/locks.d.ts +9 -0
  104. package/dist/locks.d.ts.map +1 -0
  105. package/dist/locks.js +61 -0
  106. package/dist/log.d.ts +1 -0
  107. package/dist/log.d.ts.map +1 -1
  108. package/dist/lost.d.ts +5 -0
  109. package/dist/lost.d.ts.map +1 -0
  110. package/dist/lost.js +61 -0
  111. package/dist/media.d.ts +8 -0
  112. package/dist/media.d.ts.map +1 -0
  113. package/dist/media.js +218 -0
  114. package/dist/memory.d.ts +14 -7
  115. package/dist/memory.d.ts.map +1 -1
  116. package/dist/memory.js +241 -107
  117. package/dist/messages.d.ts +52 -0
  118. package/dist/messages.d.ts.map +1 -0
  119. package/dist/messages.js +162 -0
  120. package/dist/model.d.ts +8 -10
  121. package/dist/model.d.ts.map +1 -1
  122. package/dist/model.js +6 -18
  123. package/dist/models.d.ts +14 -0
  124. package/dist/models.d.ts.map +1 -0
  125. package/dist/models.js +195 -0
  126. package/dist/name.d.ts +4 -0
  127. package/dist/name.d.ts.map +1 -0
  128. package/dist/name.js +122 -0
  129. package/dist/observation.d.ts +17 -2
  130. package/dist/observation.d.ts.map +1 -1
  131. package/dist/observation.js +107 -17
  132. package/dist/opened.d.ts +22 -0
  133. package/dist/opened.d.ts.map +1 -0
  134. package/dist/opened.js +107 -0
  135. package/dist/opening.d.ts +4 -0
  136. package/dist/opening.d.ts.map +1 -0
  137. package/dist/opening.js +57 -0
  138. package/dist/outcome.d.ts +49 -8
  139. package/dist/outcome.d.ts.map +1 -1
  140. package/dist/outcome.js +42 -0
  141. package/dist/overlay.d.ts +3 -5
  142. package/dist/overlay.d.ts.map +1 -1
  143. package/dist/overlay.js +98 -172
  144. package/dist/{chat/parts.d.ts → parts.d.ts} +12 -9
  145. package/dist/parts.d.ts.map +1 -0
  146. package/dist/{chat/parts.js → parts.js} +53 -46
  147. package/dist/paths.d.ts +2 -0
  148. package/dist/paths.d.ts.map +1 -1
  149. package/dist/paths.js +26 -0
  150. package/dist/preparation.d.ts +20 -0
  151. package/dist/preparation.d.ts.map +1 -0
  152. package/dist/preparation.js +226 -0
  153. package/dist/queries.d.ts +16 -0
  154. package/dist/queries.d.ts.map +1 -0
  155. package/dist/queries.js +272 -0
  156. package/dist/query.d.ts +25 -191
  157. package/dist/query.d.ts.map +1 -1
  158. package/dist/query.js +3 -470
  159. package/dist/{chat/questions.d.ts → questions.d.ts} +5 -2
  160. package/dist/questions.d.ts.map +1 -0
  161. package/dist/{chat/questions.js → questions.js} +13 -2
  162. package/dist/reach.d.ts +20 -9
  163. package/dist/reach.d.ts.map +1 -1
  164. package/dist/reach.js +287 -99
  165. package/dist/react.d.ts +11 -4
  166. package/dist/react.d.ts.map +1 -1
  167. package/dist/react.js +2 -14
  168. package/dist/{chat/read.d.ts → read.d.ts} +2 -0
  169. package/dist/read.d.ts.map +1 -0
  170. package/dist/{chat/read.js → read.js} +4 -0
  171. package/dist/readiness.d.ts +13 -17
  172. package/dist/readiness.d.ts.map +1 -1
  173. package/dist/readiness.js +2 -8
  174. package/dist/reads.d.ts +36 -10
  175. package/dist/reads.d.ts.map +1 -1
  176. package/dist/reads.js +157 -84
  177. package/dist/recovery.d.ts +3 -2
  178. package/dist/recovery.d.ts.map +1 -1
  179. package/dist/recovery.js +43 -8
  180. package/dist/refresh.d.ts +18 -15
  181. package/dist/refresh.d.ts.map +1 -1
  182. package/dist/refresh.js +143 -58
  183. package/dist/refusal.d.ts +5 -0
  184. package/dist/refusal.d.ts.map +1 -0
  185. package/dist/refusal.js +55 -0
  186. package/dist/replica.d.ts +56 -33
  187. package/dist/replica.d.ts.map +1 -1
  188. package/dist/replica.js +332 -190
  189. package/dist/room-draft.d.ts +25 -8
  190. package/dist/room-draft.d.ts.map +1 -1
  191. package/dist/room-draft.js +161 -74
  192. package/dist/room-drafts.d.ts +24 -0
  193. package/dist/room-drafts.d.ts.map +1 -0
  194. package/dist/room-drafts.js +217 -0
  195. package/dist/rows.d.ts +31 -30
  196. package/dist/rows.d.ts.map +1 -1
  197. package/dist/rows.js +59 -118
  198. package/dist/runtime.d.ts +43 -0
  199. package/dist/runtime.d.ts.map +1 -0
  200. package/dist/runtime.js +1 -0
  201. package/dist/save.d.ts +57 -14
  202. package/dist/save.d.ts.map +1 -1
  203. package/dist/save.js +537 -192
  204. package/dist/saves.d.ts +70 -0
  205. package/dist/saves.d.ts.map +1 -0
  206. package/dist/saves.js +1005 -0
  207. package/dist/search.d.ts +12 -82
  208. package/dist/search.d.ts.map +1 -1
  209. package/dist/search.js +10 -207
  210. package/dist/seed.d.ts +11 -2
  211. package/dist/seed.d.ts.map +1 -1
  212. package/dist/seed.js +89 -5
  213. package/dist/shared.d.ts +6 -7
  214. package/dist/shared.d.ts.map +1 -1
  215. package/dist/shared.js +75 -104
  216. package/dist/shown.d.ts +31 -0
  217. package/dist/shown.d.ts.map +1 -0
  218. package/dist/shown.js +292 -0
  219. package/dist/socket/admission.d.ts +7 -0
  220. package/dist/socket/admission.d.ts.map +1 -0
  221. package/dist/socket/admission.js +39 -0
  222. package/dist/socket/answers.d.ts +6 -0
  223. package/dist/socket/answers.d.ts.map +1 -0
  224. package/dist/socket/answers.js +20 -0
  225. package/dist/socket/lanes.d.ts +20 -0
  226. package/dist/socket/lanes.d.ts.map +1 -0
  227. package/dist/socket/lanes.js +77 -0
  228. package/dist/socket/reads.d.ts +10 -0
  229. package/dist/socket/reads.d.ts.map +1 -0
  230. package/dist/socket/reads.js +31 -0
  231. package/dist/socket/rooms.d.ts +44 -0
  232. package/dist/socket/rooms.d.ts.map +1 -0
  233. package/dist/socket/rooms.js +90 -0
  234. package/dist/socket/session.d.ts +38 -0
  235. package/dist/socket/session.d.ts.map +1 -0
  236. package/dist/socket/session.js +23 -0
  237. package/dist/socket.d.ts +70 -0
  238. package/dist/socket.d.ts.map +1 -0
  239. package/dist/socket.js +175 -0
  240. package/dist/source.d.ts +61 -0
  241. package/dist/source.d.ts.map +1 -0
  242. package/dist/source.js +82 -0
  243. package/dist/status.d.ts +4 -5
  244. package/dist/status.d.ts.map +1 -1
  245. package/dist/status.js +3 -7
  246. package/dist/store/fences.d.ts +16 -0
  247. package/dist/store/fences.d.ts.map +1 -0
  248. package/dist/store/fences.js +26 -0
  249. package/dist/store/installs.d.ts +30 -0
  250. package/dist/store/installs.d.ts.map +1 -0
  251. package/dist/store/installs.js +34 -0
  252. package/dist/store/readiness.d.ts +10 -0
  253. package/dist/store/readiness.d.ts.map +1 -0
  254. package/dist/store/readiness.js +52 -0
  255. package/dist/store/records.d.ts +212 -0
  256. package/dist/store/records.d.ts.map +1 -0
  257. package/dist/store/records.js +431 -0
  258. package/dist/store/room-held.d.ts +8 -0
  259. package/dist/store/room-held.d.ts.map +1 -0
  260. package/dist/store/room-held.js +17 -0
  261. package/dist/store/space.d.ts +11 -0
  262. package/dist/store/space.d.ts.map +1 -0
  263. package/dist/store/space.js +41 -0
  264. package/dist/store/watchers.d.ts +17 -0
  265. package/dist/store/watchers.d.ts.map +1 -0
  266. package/dist/store/watchers.js +56 -0
  267. package/dist/store/writes.d.ts +24 -0
  268. package/dist/store/writes.d.ts.map +1 -0
  269. package/dist/store/writes.js +125 -0
  270. package/dist/store.d.ts +106 -158
  271. package/dist/store.d.ts.map +1 -1
  272. package/dist/store.js +136 -734
  273. package/dist/stored.d.ts +156 -0
  274. package/dist/stored.d.ts.map +1 -0
  275. package/dist/stored.js +649 -0
  276. package/dist/surface.d.ts +88 -0
  277. package/dist/surface.d.ts.map +1 -0
  278. package/dist/surface.js +223 -0
  279. package/dist/sync.d.ts +19 -0
  280. package/dist/sync.d.ts.map +1 -0
  281. package/dist/sync.js +532 -0
  282. package/dist/tables.d.ts +416 -0
  283. package/dist/tables.d.ts.map +1 -0
  284. package/dist/tables.js +740 -0
  285. package/dist/tallies.d.ts +18 -0
  286. package/dist/tallies.d.ts.map +1 -0
  287. package/dist/tallies.js +129 -0
  288. package/dist/transfer.d.ts +0 -5
  289. package/dist/transfer.d.ts.map +1 -1
  290. package/dist/turn.d.ts +5 -3
  291. package/dist/turn.d.ts.map +1 -1
  292. package/dist/turn.js +51 -21
  293. package/dist/validation.d.ts +29 -0
  294. package/dist/validation.d.ts.map +1 -0
  295. package/dist/validation.js +104 -0
  296. package/dist/windows.d.ts +11 -0
  297. package/dist/windows.d.ts.map +1 -0
  298. package/dist/windows.js +16 -0
  299. package/dist/wire.d.ts +50 -6
  300. package/dist/wire.d.ts.map +1 -1
  301. package/dist/wire.js +16 -2
  302. package/package.json +18 -19
  303. package/AGENTS.md +0 -299
  304. package/dist/acquisition.d.ts +0 -14
  305. package/dist/acquisition.d.ts.map +0 -1
  306. package/dist/acquisition.js +0 -24
  307. package/dist/chat/acts.d.ts +0 -33
  308. package/dist/chat/acts.d.ts.map +0 -1
  309. package/dist/chat/acts.js +0 -36
  310. package/dist/chat/context.d.ts +0 -3
  311. package/dist/chat/context.d.ts.map +0 -1
  312. package/dist/chat/input.d.ts +0 -9
  313. package/dist/chat/input.d.ts.map +0 -1
  314. package/dist/chat/input.js +0 -99
  315. package/dist/chat/kit.d.ts +0 -61
  316. package/dist/chat/kit.d.ts.map +0 -1
  317. package/dist/chat/kit.js +0 -123
  318. package/dist/chat/lasting.d.ts +0 -6
  319. package/dist/chat/lasting.d.ts.map +0 -1
  320. package/dist/chat/lasting.js +0 -19
  321. package/dist/chat/list.d.ts +0 -27
  322. package/dist/chat/list.d.ts.map +0 -1
  323. package/dist/chat/list.js +0 -63
  324. package/dist/chat/markdown.d.ts +0 -20
  325. package/dist/chat/markdown.d.ts.map +0 -1
  326. package/dist/chat/markdown.js +0 -188
  327. package/dist/chat/message.d.ts +0 -6
  328. package/dist/chat/message.d.ts.map +0 -1
  329. package/dist/chat/message.js +0 -192
  330. package/dist/chat/messages.d.ts +0 -22
  331. package/dist/chat/messages.d.ts.map +0 -1
  332. package/dist/chat/messages.js +0 -155
  333. package/dist/chat/name.d.ts +0 -6
  334. package/dist/chat/name.d.ts.map +0 -1
  335. package/dist/chat/name.js +0 -37
  336. package/dist/chat/opened.d.ts +0 -11
  337. package/dist/chat/opened.d.ts.map +0 -1
  338. package/dist/chat/opened.js +0 -17
  339. package/dist/chat/overlay.d.ts +0 -31
  340. package/dist/chat/overlay.d.ts.map +0 -1
  341. package/dist/chat/overlay.js +0 -97
  342. package/dist/chat/parts.d.ts.map +0 -1
  343. package/dist/chat/process.d.ts +0 -20
  344. package/dist/chat/process.d.ts.map +0 -1
  345. package/dist/chat/process.js +0 -32
  346. package/dist/chat/provider.d.ts +0 -63
  347. package/dist/chat/provider.d.ts.map +0 -1
  348. package/dist/chat/provider.js +0 -629
  349. package/dist/chat/question.d.ts +0 -9
  350. package/dist/chat/question.d.ts.map +0 -1
  351. package/dist/chat/question.js +0 -80
  352. package/dist/chat/questions.d.ts.map +0 -1
  353. package/dist/chat/read.d.ts.map +0 -1
  354. package/dist/chat/ready.d.ts +0 -34
  355. package/dist/chat/ready.d.ts.map +0 -1
  356. package/dist/chat/ready.js +0 -91
  357. package/dist/chat/style.d.ts +0 -4
  358. package/dist/chat/style.d.ts.map +0 -1
  359. package/dist/chat/style.js +0 -302
  360. package/dist/chat.d.ts +0 -14
  361. package/dist/chat.d.ts.map +0 -1
  362. package/dist/chat.js +0 -8
  363. package/dist/fence.d.ts +0 -6
  364. package/dist/fence.d.ts.map +0 -1
  365. package/dist/fence.js +0 -10
  366. package/dist/read-side.d.ts +0 -25
  367. package/dist/read-side.d.ts.map +0 -1
  368. package/dist/read-side.js +0 -642
package/dist/reach.js CHANGED
@@ -1,13 +1,11 @@
1
1
  import { unheldView } from './conversation.js';
2
2
  import { modelTypes, NO_MODEL } from './model.js';
3
- import { applied, observing } from './observation.js';
3
+ import { changeOf, digestApplied, digestOf, observing, } from './observation.js';
4
4
  import { runtimeError } from './failure.js';
5
- import { failure, undeclared, } from './outcome.js';
5
+ import { failure, lockedRoom, ROOM_LOCKED, undeclared, UNREADABLE, } from './outcome.js';
6
6
  import { beneath } from './paths.js';
7
- import { reconciled } from './read-side.js';
8
7
  import { moveTarget, readParts, staleWrite, } from './room-draft.js';
9
8
  import { documentKey } from './rows.js';
10
- import { undeclaredSearch } from './search.js';
11
9
  const UNHELD_TYPES = { collection: modelTypes(NO_MODEL), typedSelection: null };
12
10
  function unconversed(name) {
13
11
  return () => Promise.resolve(undeclared(name));
@@ -15,18 +13,26 @@ function unconversed(name) {
15
13
  const NO_CONVERSATION = {
16
14
  list: () => Promise.resolve([]),
17
15
  read: (conversation) => Promise.resolve(unheldView(conversation)),
18
- create: unconversed('conversation.create'),
19
- send: unconversed('conversation.send'),
20
- answer: unconversed('conversation.answer'),
21
- interrupt: unconversed('conversation.interrupt'),
22
- kill: unconversed('conversation.kill'),
23
- cancel: unconversed('conversation.cancel'),
24
- delete: unconversed('conversation.delete'),
16
+ create: unconversed('conversations/create'),
17
+ send: unconversed('conversations/send'),
18
+ answer: unconversed('conversations/interaction/answer'),
19
+ interrupt: unconversed('conversations/interrupt'),
20
+ kill: unconversed('conversations/kill'),
21
+ delete: unconversed('conversations/delete'),
25
22
  };
26
23
  const NO_CHAT_DRAFT = {
27
24
  write: () => Promise.resolve(),
25
+ prepend: () => Promise.resolve(),
28
26
  discard: () => Promise.resolve(),
29
27
  };
28
+ function areasOf(reach) {
29
+ return reach.areas ?? [];
30
+ }
31
+ function fenced(reach, room, path) {
32
+ return areasOf(reach).some((area) => area.room === room &&
33
+ beneath(area.path, path) &&
34
+ !area.open.some((open) => beneath(open, path)));
35
+ }
30
36
  export function holds(reach, room) {
31
37
  return (reach === null ||
32
38
  reach.rooms.includes(room) ||
@@ -47,26 +53,13 @@ export function governs(reach, room) {
47
53
  }
48
54
  function covers(reach, room, path) {
49
55
  return (reach === null ||
50
- reach.rooms.includes(room) ||
51
- reach.documents.some((document) => document.room === room && document.path === path));
56
+ (!fenced(reach, room, path) &&
57
+ (reach.rooms.includes(room) ||
58
+ reach.documents.some((document) => document.room === room && document.path === path))));
52
59
  }
53
60
  function conversing(reach) {
54
61
  return reach === null || reach.conversations;
55
62
  }
56
- function refers(reach, scope) {
57
- if (reach === null)
58
- return true;
59
- if (scope === null)
60
- return false;
61
- if (scope.kind === 'conversations')
62
- return reach.conversations;
63
- return scope.path === undefined
64
- ? wholly(reach, scope.locator)
65
- : covers(reach, scope.locator, scope.path);
66
- }
67
- function unreachedReference(fileRef) {
68
- return { kind: 'absent', code: 'binary-file-absent', fields: { fileRef }, retryable: false };
69
- }
70
63
  export function planReach(reach) {
71
64
  return reach === null
72
65
  ? null
@@ -75,6 +68,9 @@ export function planReach(reach) {
75
68
  documents: [
76
69
  ...new Set(reach.documents.map(({ room, path }) => documentKey(room, path))),
77
70
  ].sort(),
71
+ areas: areasOf(reach)
72
+ .map(({ room, path, open }) => ({ room, path, open: [...new Set(open)].sort() }))
73
+ .sort((left, right) => documentKey(left.room, left.path) < documentKey(right.room, right.path) ? -1 : 1),
78
74
  };
79
75
  }
80
76
  function roomsWithin(reach, rooms) {
@@ -90,7 +86,7 @@ function typesWithin(reach, room, types) {
90
86
  };
91
87
  }
92
88
  function moves(reach, room, move) {
93
- return move === undefined || covers(reach, room, moveTarget(move));
89
+ return move === undefined || covers(reach, move.room ?? room, moveTarget(move));
94
90
  }
95
91
  function draftWithin(reach, draft) {
96
92
  return covers(reach, draft.room, draft.path) && moves(reach, draft.room, draft.parts.move);
@@ -123,85 +119,189 @@ function savedWithin(reach, room, result) {
123
119
  function statusWithin(reach, status) {
124
120
  return {
125
121
  ...status,
126
- attentionRequired: status.attentionRequired.filter((entry) => 'refusal' in entry ? wholly(reach, entry.room) : covers(reach, entry.room, entry.path)),
122
+ attentionRequired: status.attentionRequired.filter((entry) => covers(reach, entry.room, entry.path)),
123
+ unsent: status.unsent.filter((change) => covers(reach, change.room, change.path)),
127
124
  };
128
125
  }
129
126
  function queueWithin(reach, room, entries) {
130
- return entries.filter(({ batch }) => batch.changes.every((change) => covers(reach, room, change.path) &&
131
- (change.kind !== 'move' || covers(reach, room, change.to))));
127
+ return entries
128
+ .filter(({ batch }) => batch.changes.every((change) => covers(reach, room, change.path) &&
129
+ (change.kind !== 'move' || covers(reach, room, change.to))))
130
+ .map((entry) => {
131
+ const { between, ...batch } = entry.batch;
132
+ if (between === undefined)
133
+ return entry;
134
+ return wholly(reach, between.source.room) && wholly(reach, between.destination.room)
135
+ ? entry
136
+ : { ...entry, batch };
137
+ });
132
138
  }
133
139
  function unreached(room) {
134
- return runtimeError('room-not-held', `No Local Replica for ${room}`);
140
+ return runtimeError('unknown-room', `Unknown Room ${room}`);
141
+ }
142
+ function lockedError(room) {
143
+ return runtimeError(ROOM_LOCKED, `${room} is locked until House confirms its access`, true);
135
144
  }
136
- export function narrowed(runtime, given, told) {
145
+ function deviceUnreached() {
146
+ return runtimeError('device-unreached', 'Only the panel reaches this device');
147
+ }
148
+ const ATTACH_REQUIRED = 'attach-required';
149
+ function attachRequired() {
150
+ return runtimeError(ATTACH_REQUIRED, 'App code takes a file in with binaryFile.attach');
151
+ }
152
+ function carriesFile(parts) {
153
+ return parts !== null && typeof parts === 'object' && Object.hasOwn(parts, 'file');
154
+ }
155
+ export function narrowed(runtime, given, port) {
137
156
  const { md, watch } = runtime;
138
157
  let reach = given;
139
- let port = told;
140
158
  const open = new Set();
141
- function following(begin) {
159
+ function following(begin, locking = false) {
142
160
  let stop = begin();
143
161
  const restart = () => {
144
162
  stop();
145
163
  stop = begin();
146
164
  };
147
165
  open.add(restart);
166
+ const unwatch = locking ? runtime.watchLocks(restart) : () => { };
148
167
  return () => {
149
168
  open.delete(restart);
169
+ unwatch();
150
170
  stop();
151
171
  };
152
172
  }
153
- const within = (topic, input, deliver) => {
173
+ const unlocking = (rooms, locked) => {
174
+ const held = (rooms ?? []).filter((room) => locked.includes(room));
175
+ return held.length === 0 ? null : { pending: held.map((room) => ({ room, awaits: 'unlock' })) };
176
+ };
177
+ const unlocked = (entries, locked) => entries.filter((entry) => !locked.includes(entry.room));
178
+ const intoLocked = async (held) => {
179
+ for (const move of held) {
180
+ if (move?.room !== undefined && (await runtime.locked(move.room)))
181
+ return true;
182
+ }
183
+ return false;
184
+ };
185
+ function ordered(deliver) {
186
+ let open = true;
187
+ let shown = Promise.resolve();
188
+ return {
189
+ push(making) {
190
+ shown = shown.then(() => making.then((value) => {
191
+ if (open)
192
+ deliver(value);
193
+ }, () => { }), () => { });
194
+ },
195
+ stop() {
196
+ open = false;
197
+ },
198
+ };
199
+ }
200
+ function unlockedWatch(topic, input, deliver, fail, within) {
201
+ const shown = ordered(deliver);
202
+ const stop = watch(topic, input, (message) => {
203
+ shown.push(runtime.lockedRooms().then((locked) => within(message, locked)));
204
+ }, fail);
205
+ return () => {
206
+ shown.stop();
207
+ stop();
208
+ };
209
+ }
210
+ function lockedFirst(room, start, shut) {
211
+ let open = true;
212
+ let stop = () => { };
213
+ void (async () => {
214
+ const closed = !holds(reach, room) || (await runtime.locked(room));
215
+ if (!open)
216
+ return;
217
+ if (closed)
218
+ shut();
219
+ else
220
+ stop = start();
221
+ })();
222
+ return () => {
223
+ open = false;
224
+ stop();
225
+ };
226
+ }
227
+ const within = (topic, input, deliver, fail) => {
228
+ if (topic === 'read' && reach !== null) {
229
+ fail(deviceUnreached());
230
+ return () => { };
231
+ }
154
232
  if (topic === 'rooms') {
155
- return following(() => watch(topic, input, (rooms) => deliver(roomsWithin(reach, rooms))));
233
+ return following(() => watch(topic, input, (rooms) => deliver(roomsWithin(reach, rooms)), fail));
156
234
  }
157
235
  if (topic === 'readiness') {
158
236
  return following(() => runtime.watchReadiness(port, reach, deliver));
159
237
  }
160
238
  if (topic === 'sync-status') {
161
- return following(() => watch(topic, input, (status) => deliver(statusWithin(reach, status))));
239
+ return following(() => unlockedWatch(topic, input, deliver, fail, (status, locked) => {
240
+ const shown = statusWithin(reach, status);
241
+ return { ...shown, attentionRequired: unlocked(shown.attentionRequired, locked) };
242
+ }), true);
162
243
  }
163
244
  if (topic === 'room-drafts') {
164
- return following(() => watch(topic, input, (drafts) => deliver(draftsWithin(reach, drafts))));
245
+ return following(() => unlockedWatch(topic, input, deliver, fail, (drafts, locked) => unlocked(draftsWithin(reach, drafts), locked)), true);
165
246
  }
166
247
  if (topic === 'queue') {
167
248
  const room = input[0];
168
- return following(() => {
169
- if (!holds(reach, room)) {
170
- deliver([]);
171
- return () => { };
172
- }
173
- return watch(topic, input, (entries) => deliver(queueWithin(reach, room, entries)));
174
- });
249
+ return following(() => lockedFirst(room, () => watch(topic, input, (entries) => deliver(queueWithin(reach, room, entries)), fail), () => deliver([])), true);
175
250
  }
176
251
  if (topic === 'query') {
177
- const plan = runtime.plan(input[0], reach);
252
+ const planning = runtime.plan(input[0], reach);
178
253
  let held = null;
179
254
  return following(() => {
180
- let first = true;
181
- return runtime.watchPlan({ ...plan, reach: planReach(reach) }, (message) => {
182
- if (!first) {
183
- held = applied(held, message);
184
- deliver(message);
255
+ let open = true;
256
+ let stop = () => { };
257
+ void (async () => {
258
+ const plan = await planning;
259
+ const locked = await runtime.lockedRooms();
260
+ if (!open)
185
261
  return;
186
- }
187
- first = false;
188
- if (held === null) {
189
- held = message;
190
- deliver(message);
262
+ const pending = unlocking(plan.rooms, locked);
263
+ if (pending !== null) {
264
+ const answer = { result: pending, keys: [] };
265
+ if (held === null || changeOf(held, answer) !== null)
266
+ deliver(answer);
267
+ held = digestOf(answer);
191
268
  return;
192
269
  }
193
- const next = reconciled(held, message);
194
- if (next === null)
195
- return;
196
- held = next.keyed;
197
- deliver(next.message);
270
+ let first = true;
271
+ const heard = (message) => {
272
+ if (!first) {
273
+ held = digestApplied(held, message);
274
+ deliver(message);
275
+ return;
276
+ }
277
+ first = false;
278
+ const change = held === null ? message : changeOf(held, message);
279
+ held = digestOf(message);
280
+ if (change !== null)
281
+ deliver(change);
282
+ };
283
+ const current = { ...plan, reach: planReach(reach), locked };
284
+ stop = runtime.watchPlan(current, (message) => {
285
+ if (open)
286
+ heard(message);
287
+ }, (error) => {
288
+ if (open)
289
+ fail(error);
290
+ });
291
+ })().catch((error) => {
292
+ if (open)
293
+ fail(error);
198
294
  });
199
- });
295
+ return () => {
296
+ open = false;
297
+ stop();
298
+ };
299
+ }, true);
200
300
  }
201
301
  if (topic === 'conversation') {
202
302
  return following(() => {
203
303
  if (conversing(reach))
204
- return watch(topic, input, deliver);
304
+ return watch(topic, input, deliver, fail);
205
305
  deliver(unheldView(input[0]));
206
306
  return () => { };
207
307
  });
@@ -209,66 +309,159 @@ export function narrowed(runtime, given, told) {
209
309
  if (topic === 'conversations' || topic === 'agents') {
210
310
  return following(() => {
211
311
  if (conversing(reach))
212
- return watch(topic, input, deliver);
312
+ return watch(topic, input, deliver, fail);
213
313
  deliver([]);
214
314
  return () => { };
215
315
  });
216
316
  }
217
- return watch(topic, input, deliver);
317
+ if (topic === 'figures' || topic === 'holdings') {
318
+ if (reach === null)
319
+ return watch(topic, input, deliver, fail);
320
+ fail(deviceUnreached());
321
+ return () => { };
322
+ }
323
+ return watch(topic, input, deliver, fail);
218
324
  };
325
+ const files = new Map();
326
+ let handed = 0;
327
+ async function hand(reading) {
328
+ const answer = await reading;
329
+ if (answer.kind !== 'binary')
330
+ return answer;
331
+ handed += 1;
332
+ const file = String(handed);
333
+ files.set(file, answer.file);
334
+ return { ...answer, file };
335
+ }
219
336
  const conversation = () => (conversing(reach) ? md.conversation : NO_CONVERSATION);
220
337
  const chatDraft = () => (conversing(reach) ? md.chatDraft : NO_CHAT_DRAFT);
221
338
  const view = {
222
339
  ...md,
223
- rooms: () => roomsWithin(reach, md.rooms()),
224
- query: ((input) => runtime.query(runtime.plan(input, reach))),
225
- search: (input) => port.search === 'required'
226
- ? runtime.search(input, reach)
227
- : Promise.resolve(undeclaredSearch()),
228
- types(room) {
340
+ rooms: () => md.rooms().then((rooms) => roomsWithin(reach, rooms)),
341
+ query: (async (input) => {
342
+ const plan = await runtime.plan(input, reach);
343
+ const locked = await runtime.lockedRooms();
344
+ return unlocking(plan.rooms, locked) ?? runtime.query({ ...plan, locked });
345
+ }),
346
+ search: (input) => runtime.search(input, reach),
347
+ async types(room) {
348
+ if (holds(reach, room) && (await runtime.locked(room)))
349
+ throw lockedError(room);
229
350
  if (wholly(reach, room))
230
351
  return md.types(room);
231
352
  if (!holds(reach, room))
232
353
  return structuredClone(UNHELD_TYPES);
233
- const listed = md.rooms().find(({ locator }) => locator === room);
234
- return typesWithin(reach, listed, md.types(room));
354
+ return typesWithin(reach, await runtime.room(room), await md.types(room));
235
355
  },
236
356
  async save(room, roomDrafts, writtenBy) {
237
357
  if (!holds(reach, room))
238
358
  throw unreached(room);
239
- const outside = roomDrafts.find(({ path }) => !covers(reach, room, path) ||
240
- !moves(reach, room, md.roomDraft.read(room, path)?.parts.move));
359
+ if (await runtime.locked(room)) {
360
+ return { outcome: 'refused', code: ROOM_LOCKED, retryable: true };
361
+ }
362
+ const held = (await Promise.all(roomDrafts.map(({ path }) => md.roomDraft.read(room, path)))).map((draft) => draft?.parts.move);
363
+ const outside = roomDrafts.find(({ path }, at) => !covers(reach, room, path) || !moves(reach, room, held[at]));
241
364
  if (outside !== undefined) {
242
365
  return { outcome: 'refused', code: 'stale', retryable: false, file: outside.path };
243
366
  }
367
+ if (await intoLocked(held))
368
+ return { outcome: 'refused', code: ROOM_LOCKED, retryable: true };
244
369
  return savedWithin(reach, room, await md.save(room, roomDrafts, writtenBy));
245
370
  },
246
- history: (room, path, query) => covers(reach, room, path)
247
- ? md.history(room, path, query)
248
- : Promise.resolve(failure({ kind: 'room-not-readable', locator: room })),
371
+ async saveParts(room, parts, writtenBy) {
372
+ if (!holds(reach, room))
373
+ throw unreached(room);
374
+ const filed = reach === null ? undefined : parts.find(({ parts: one }) => carriesFile(one));
375
+ if (filed !== undefined) {
376
+ return { outcome: 'refused', code: ATTACH_REQUIRED, retryable: false, file: filed.path };
377
+ }
378
+ if (await runtime.locked(room)) {
379
+ return { outcome: 'refused', code: ROOM_LOCKED, retryable: true };
380
+ }
381
+ const held = parts.map(({ path, parts: one }) => readParts(one, path).move);
382
+ if (parts.some(({ path }, at) => !covers(reach, room, path) || !moves(reach, room, held[at]))) {
383
+ throw unreached(room);
384
+ }
385
+ if (await intoLocked(held))
386
+ return { outcome: 'refused', code: ROOM_LOCKED, retryable: true };
387
+ return savedWithin(reach, room, await md.saveParts(room, parts, writtenBy));
388
+ },
389
+ async resolve(room, path, destination) {
390
+ const at = await runtime.located(room, path, destination);
391
+ return at !== null && !covers(reach, at.room, at.path)
392
+ ? UNREADABLE
393
+ : md.resolve(room, path, destination);
394
+ },
395
+ history: async (room, path, query) => !covers(reach, room, path)
396
+ ? failure({ kind: 'room-not-readable', locator: room })
397
+ : (await runtime.locked(room))
398
+ ? lockedRoom(room)
399
+ : md.history(room, path, query),
249
400
  binaryFile: {
250
- read: (room, path, revision) => covers(reach, room, path)
251
- ? md.binaryFile.read(room, path, revision)
252
- : Promise.resolve(failure({ kind: 'room-not-readable', locator: room })),
253
- readReference: (reference) => refers(reach, runtime.referrerScope(reference.referrer))
254
- ? md.binaryFile.readReference(reference)
255
- : Promise.resolve(unreachedReference(reference.fileRef)),
401
+ read: async (room, path, revision) => !covers(reach, room, path)
402
+ ? failure({ kind: 'room-not-readable', locator: room })
403
+ : (await runtime.locked(room))
404
+ ? lockedRoom(room)
405
+ : hand(md.binaryFile.read(room, path, revision)),
406
+ link: async (room, path, revision) => !covers(reach, room, path)
407
+ ? failure({ kind: 'room-not-readable', locator: room })
408
+ : (await runtime.locked(room))
409
+ ? lockedRoom(room)
410
+ : md.binaryFile.link(room, path, revision),
411
+ show: async (room, path, revision) => !covers(reach, room, path)
412
+ ? failure({ kind: 'room-not-readable', locator: room })
413
+ : (await runtime.locked(room))
414
+ ? lockedRoom(room)
415
+ : hand(md.binaryFile.show(room, path, revision)),
416
+ attach: async (room, file) => !wholly(reach, room)
417
+ ? failure({ kind: 'room-not-readable', locator: room })
418
+ : (await runtime.locked(room))
419
+ ? lockedRoom(room)
420
+ : md.binaryFile.attach(room, file),
421
+ async part(file, part) {
422
+ const key = files.get(file);
423
+ if (key === undefined)
424
+ return null;
425
+ const bytes = await md.binaryFile.part(key, part);
426
+ if (bytes === null)
427
+ files.delete(file);
428
+ return bytes;
429
+ },
256
430
  },
257
- reached: (room, roomVersion, path) => (path === undefined ? wholly(reach, room) : covers(reach, room, path)) &&
258
- md.reached(room, roomVersion, path),
431
+ reached: async (room, roomVersion, path) => (path === undefined ? wholly(reach, room) : covers(reach, room, path)) &&
432
+ !(await runtime.locked(room)) &&
433
+ (await md.reached(room, roomVersion, path)),
259
434
  log: () => (reach === null ? md.log() : ''),
435
+ cleanUp: () => (reach === null ? md.cleanUp() : Promise.reject(deviceUnreached())),
436
+ unsent: () => (reach === null ? md.unsent() : Promise.reject(deviceUnreached())),
437
+ reset: () => (reach === null ? md.reset() : Promise.reject(deviceUnreached())),
438
+ readAgain: () => (reach === null ? md.readAgain() : Promise.reject(deviceUnreached())),
260
439
  roomDraft: {
261
- list: () => md.roomDraft.list().then((drafts) => draftsWithin(reach, drafts)),
262
- read: (room, path) => covers(reach, room, path) ? shownDraft(reach, md.roomDraft.read(room, path)) : null,
263
- async write(room, path, revision, parts) {
264
- if (!covers(reach, room, path) || !moves(reach, room, readParts(parts).move)) {
440
+ list: async () => unlocked(draftsWithin(reach, await md.roomDraft.list()), await runtime.lockedRooms()),
441
+ async read(room, path) {
442
+ if (!covers(reach, room, path))
443
+ return null;
444
+ if (await runtime.locked(room))
445
+ throw lockedError(room);
446
+ return shownDraft(reach, await md.roomDraft.read(room, path));
447
+ },
448
+ async write(room, path, revision, parts, next) {
449
+ if (reach !== null && carriesFile(parts))
450
+ throw attachRequired();
451
+ const move = readParts(parts, path).move;
452
+ if (!covers(reach, room, path) || !moves(reach, room, move))
265
453
  throw unreached(room);
266
- }
267
- return writeWithin(reach, await md.roomDraft.write(room, path, revision, parts));
454
+ if (await runtime.locked(room))
455
+ throw lockedError(room);
456
+ if (await intoLocked([move]))
457
+ throw lockedError(move.room);
458
+ return writeWithin(reach, await md.roomDraft.write(room, path, revision, parts, next));
268
459
  },
269
460
  async discard(room, path, revision) {
270
461
  if (!covers(reach, room, path))
271
462
  return staleWrite(null);
463
+ if (await runtime.locked(room))
464
+ throw lockedError(room);
272
465
  return writeWithin(reach, await md.roomDraft.discard(room, path, revision));
273
466
  },
274
467
  },
@@ -280,11 +473,11 @@ export function narrowed(runtime, given, told) {
280
473
  answer: (id, answer) => conversation().answer(id, answer),
281
474
  interrupt: (id) => conversation().interrupt(id),
282
475
  kill: (id) => conversation().kill(id),
283
- cancel: (id, turn) => conversation().cancel(id, turn),
284
476
  delete: (id) => conversation().delete(id),
285
477
  },
286
478
  chatDraft: {
287
479
  write: (id, draft, revision) => chatDraft().write(id, draft, revision),
480
+ prepend: (id, draft) => chatDraft().prepend(id, draft),
288
481
  discard: (id) => chatDraft().discard(id),
289
482
  },
290
483
  observe: observing(within),
@@ -297,10 +490,5 @@ export function narrowed(runtime, given, told) {
297
490
  for (const restart of [...open])
298
491
  restart();
299
492
  },
300
- facts(next) {
301
- port = next;
302
- for (const restart of [...open])
303
- restart();
304
- },
305
493
  };
306
494
  }
package/dist/react.d.ts CHANGED
@@ -1,10 +1,15 @@
1
+ import type { DocumentQuery, GroupQuery } from '@agentshouse/mdmodel';
1
2
  import type { MdRuntimeClient } from './client.js';
2
- import type { AppRoom, ConnectionRefusal, SavedRoomDraft, SaveResult } from './connection.js';
3
+ import type { AppRoom } from './listing.js';
4
+ import type { ConnectionRefusal } from './socket.js';
5
+ import type { SavedRoomDraft, SaveResult } from './saves.js';
3
6
  import type { Member, ServiceMode } from './adapter.js';
4
7
  import type { ConversationAgent, ConversationEntry, ConversationOptions, ConversationView } from './conversation.js';
5
8
  import { type RuntimeError } from './failure.js';
9
+ import type { FiguresResult } from './figures.js';
10
+ import type { Holdings } from './holdings.js';
6
11
  import type { QueueEntry } from './outcome.js';
7
- import type { DocumentQuery, DocumentResult, GroupQuery, GroupResult, PendingResult } from './query.js';
12
+ import type { DocumentResult, GroupResult, PendingResult } from './query.js';
8
13
  import type { Readiness } from './readiness.js';
9
14
  import type { RoomDraft, RoomDraftParts } from './room-draft.js';
10
15
  import type { SyncStatus } from './status.js';
@@ -23,6 +28,7 @@ export declare function useObserve(client: Client, topic: 'storage-loss'): Obser
23
28
  export declare function useObserve(client: Client, topic: 'sync-status'): Observed<SyncStatus>;
24
29
  export declare function useObserve(client: Client, topic: 'service-mode'): Observed<ServiceMode>;
25
30
  export declare function useObserve(client: Client, topic: 'member'): Observed<Member | null>;
31
+ export declare function useObserve(client: Client, topic: 'authority-changes'): Observed<number>;
26
32
  export declare function useObserve(client: Client, topic: 'query', query: DocumentQuery): Observed<DocumentResult | PendingResult>;
27
33
  export declare function useObserve(client: Client, topic: 'query', query: GroupQuery): Observed<GroupResult | PendingResult>;
28
34
  export declare function useObserve(client: Client, topic: 'queue', locator: string): Observed<readonly QueueEntry[]>;
@@ -31,14 +37,15 @@ export declare function useObserve(client: Client, topic: 'presentation'): Obser
31
37
  export declare function useObserve(client: Client, topic: 'conversation', conversation: string, options: ConversationOptions): Observed<ConversationView>;
32
38
  export declare function useObserve(client: Client, topic: 'conversations'): Observed<readonly ConversationEntry[]>;
33
39
  export declare function useObserve(client: Client, topic: 'agents'): Observed<readonly ConversationAgent[]>;
40
+ export declare function useObserve(client: Client, topic: 'figures'): Observed<FiguresResult>;
41
+ export declare function useObserve(client: Client, topic: 'holdings'): Observed<Holdings>;
34
42
  export type Saving = {
35
43
  readonly busy: boolean;
36
44
  readonly outcome: SaveResult | null;
37
45
  readonly failure: RuntimeError | null;
38
- save(room: string, roomDrafts: ReadonlyMap<string, RoomDraftParts>): Promise<SaveResult>;
46
+ save(room: string, parts: ReadonlyMap<string, RoomDraftParts>): Promise<SaveResult>;
39
47
  saveWritten(room: string, roomDrafts: readonly SavedRoomDraft[]): Promise<SaveResult>;
40
48
  };
41
- export declare function saveRoomDrafts(client: MdRuntimeClient, room: string, roomDrafts: ReadonlyMap<string, RoomDraftParts>): Promise<SaveResult>;
42
49
  export declare function useSave(client: MdRuntimeClient): Saving;
43
50
  export {};
44
51
  //# sourceMappingURL=react.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../src/react.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,KAAK,EAAE,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC9F,OAAO,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AACxD,OAAO,KAAK,EACV,iBAAiB,EACjB,iBAAiB,EACjB,mBAAmB,EACnB,gBAAgB,EACjB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAwB,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC;AAEvE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,KAAK,EACV,aAAa,EACb,cAAc,EACd,UAAU,EACV,WAAW,EACX,aAAa,EACd,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAG9C,KAAK,MAAM,GAAG,eAAe,GAAG,IAAI,CAAC;AAErC,MAAM,MAAM,QAAQ,CAAC,CAAC,IAClB;IAAE,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAA;CAAE,GAC7B;IAAE,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAA;CAAE,CAAC;AAUnD,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,kBAAkB,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC;AACzF,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,QAAQ,CAAC,SAAS,OAAO,EAAE,CAAC,CAAC;AACzF,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC;AACpF,wBAAgB,UAAU,CACxB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,oBAAoB,GAC1B,QAAQ,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAAC;AACtC,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,GAAG,QAAQ,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;AAC3F,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAC;AACvF,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,GAAG,QAAQ,CAAC,WAAW,CAAC,CAAC;AACzF,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,GAAG,QAAQ,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;AACrF,wBAAgB,UAAU,CACxB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,OAAO,EACd,KAAK,EAAE,aAAa,GACnB,QAAQ,CAAC,cAAc,GAAG,aAAa,CAAC,CAAC;AAC5C,wBAAgB,UAAU,CACxB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,OAAO,EACd,KAAK,EAAE,UAAU,GAChB,QAAQ,CAAC,WAAW,GAAG,aAAa,CAAC,CAAC;AACzC,wBAAgB,UAAU,CACxB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,MAAM,GACd,QAAQ,CAAC,SAAS,UAAU,EAAE,CAAC,CAAC;AACnC,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,QAAQ,CAAC,SAAS,SAAS,EAAE,CAAC,CAAC;AACjG,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC;AACrF,wBAAgB,UAAU,CACxB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,cAAc,EACrB,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,mBAAmB,GAC3B,QAAQ,CAAC,gBAAgB,CAAC,CAAC;AAC9B,wBAAgB,UAAU,CACxB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,eAAe,GACrB,QAAQ,CAAC,SAAS,iBAAiB,EAAE,CAAC,CAAC;AAC1C,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,GAAG,QAAQ,CAAC,SAAS,iBAAiB,EAAE,CAAC,CAAC;AAsCpG,MAAM,MAAM,MAAM,GAAG;IACnB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,UAAU,GAAG,IAAI,CAAC;IACpC,QAAQ,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI,CAAC;IACtC,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,WAAW,CAAC,MAAM,EAAE,cAAc,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IACzF,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,cAAc,EAAE,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;CACvF,CAAC;AAMF,wBAAsB,cAAc,CAClC,MAAM,EAAE,eAAe,EACvB,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,WAAW,CAAC,MAAM,EAAE,cAAc,CAAC,GAC9C,OAAO,CAAC,UAAU,CAAC,CAcrB;AAED,wBAAgB,OAAO,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM,CAyBvD"}
1
+ {"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../src/react.ts"],"names":[],"mappings":"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"}
package/dist/react.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { useCallback, useLayoutEffect, useRef, useState } from 'react';
2
- import { failed, runtimeError } from './failure.js';
2
+ import { failed } from './failure.js';
3
3
  const LOADING = { state: 'loading' };
4
4
  export function useObserve(client, topic, ...input) {
5
5
  const key = JSON.stringify([topic, ...input]);
@@ -33,18 +33,6 @@ export function useObserve(client, topic, ...input) {
33
33
  return held !== null && held.client === client && held.key === key ? held.observed : LOADING;
34
34
  }
35
35
  const IDLE = { busy: false, outcome: null, failure: null };
36
- export async function saveRoomDrafts(client, room, roomDrafts) {
37
- const kept = [];
38
- for (const [path, parts] of roomDrafts) {
39
- const prior = await client.roomDraft.read(room, path);
40
- const write = await client.roomDraft.write(room, path, prior?.revision ?? null, parts);
41
- if (write.outcome !== 'written' || write.roomDraft === null) {
42
- throw runtimeError(write.outcome === 'stale' ? write.code : 'room-draft-unwritten', `the Room Draft at ${path} was not written`);
43
- }
44
- kept.push({ path, revision: write.roomDraft.revision });
45
- }
46
- return client.save(room, kept);
47
- }
48
36
  export function useSave(client) {
49
37
  const [state, setState] = useState(IDLE);
50
38
  const settled = useCallback(async (saving) => {
@@ -60,7 +48,7 @@ export function useSave(client) {
60
48
  throw failure;
61
49
  }
62
50
  }, []);
63
- const save = useCallback((room, roomDrafts) => settled(() => saveRoomDrafts(client, room, roomDrafts)), [client, settled]);
51
+ const save = useCallback((room, parts) => settled(() => client.saveParts(room, [...parts].map(([path, one]) => ({ path, parts: one })))), [client, settled]);
64
52
  const saveWritten = useCallback((room, roomDrafts) => settled(() => client.save(room, roomDrafts)), [client, settled]);
65
53
  return { ...state, save, saveWritten };
66
54
  }
@@ -1,4 +1,6 @@
1
1
  export type Fields = Readonly<Record<string, unknown>>;
2
+ export declare const EXCERPT = 512;
3
+ export declare function excerpt(said: string): string;
2
4
  export declare function record(entry: unknown): Fields;
3
5
  export declare function text(fields: Fields, name: string): string | null;
4
6
  export declare function list(fields: Fields, name: string): readonly unknown[];
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read.d.ts","sourceRoot":"","sources":["../src/read.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAEvD,eAAO,MAAM,OAAO,MAAM,CAAC;AAE3B,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE5C;AAED,wBAAgB,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAI7C;AAED,wBAAgB,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAGhE;AAED,wBAAgB,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,OAAO,EAAE,CAGrE"}
@@ -1,3 +1,7 @@
1
+ export const EXCERPT = 512;
2
+ export function excerpt(said) {
3
+ return [...said.slice(0, EXCERPT * 2)].slice(0, EXCERPT).join('');
4
+ }
1
5
  export function record(entry) {
2
6
  return typeof entry === 'object' && entry !== null && !Array.isArray(entry)
3
7
  ? entry