@agentshouse/mdruntime 0.1.0-cb1f56e16291b → 0.1.0-cb3bb3b233fa1

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 (327) hide show
  1. package/README.md +21 -19
  2. package/dist/acceptance.d.ts +3 -0
  3. package/dist/acceptance.d.ts.map +1 -0
  4. package/dist/acceptance.js +299 -0
  5. package/dist/act-lanes.d.ts +30 -0
  6. package/dist/act-lanes.d.ts.map +1 -0
  7. package/dist/act-lanes.js +225 -0
  8. package/dist/actions.d.ts +26 -0
  9. package/dist/actions.d.ts.map +1 -0
  10. package/dist/actions.js +302 -0
  11. package/dist/adapter.d.ts +113 -81
  12. package/dist/adapter.d.ts.map +1 -1
  13. package/dist/attached-model.d.ts +3 -11
  14. package/dist/attached-model.d.ts.map +1 -1
  15. package/dist/attached-model.js +20 -60
  16. package/dist/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 +9 -5
  20. package/dist/bootstrap.d.ts.map +1 -1
  21. package/dist/bootstrap.js +204 -85
  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 +2 -1
  26. package/dist/chain.d.ts.map +1 -1
  27. package/dist/change-set.d.ts +4 -0
  28. package/dist/change-set.d.ts.map +1 -1
  29. package/dist/change-set.js +6 -0
  30. package/dist/change.d.ts +5 -0
  31. package/dist/change.d.ts.map +1 -1
  32. package/dist/change.js +7 -2
  33. package/dist/chat-types.d.ts +3 -0
  34. package/dist/chat-types.d.ts.map +1 -0
  35. package/dist/chat-types.js +11 -0
  36. package/dist/client.d.ts +30 -22
  37. package/dist/client.d.ts.map +1 -1
  38. package/dist/client.js +39 -20
  39. package/dist/collection.d.ts +26 -4
  40. package/dist/collection.d.ts.map +1 -1
  41. package/dist/collection.js +19 -2
  42. package/dist/column.d.ts +5 -0
  43. package/dist/column.d.ts.map +1 -0
  44. package/dist/column.js +9 -0
  45. package/dist/compile.d.ts +9 -7
  46. package/dist/compile.d.ts.map +1 -1
  47. package/dist/compile.js +252 -318
  48. package/dist/connection.d.ts +5 -141
  49. package/dist/connection.d.ts.map +1 -1
  50. package/dist/connection.js +111 -5282
  51. package/dist/context.d.ts.map +1 -1
  52. package/dist/context.js +1 -1
  53. package/dist/conversation-live.d.ts +150 -0
  54. package/dist/conversation-live.d.ts.map +1 -0
  55. package/dist/conversation-live.js +259 -0
  56. package/dist/conversation-row.d.ts +40 -0
  57. package/dist/conversation-row.d.ts.map +1 -0
  58. package/dist/conversation-row.js +66 -0
  59. package/dist/conversation.d.ts +62 -43
  60. package/dist/conversation.d.ts.map +1 -1
  61. package/dist/conversation.js +987 -902
  62. package/dist/declaration.d.ts +10 -0
  63. package/dist/declaration.d.ts.map +1 -0
  64. package/dist/declaration.js +24 -0
  65. package/dist/discovery.d.ts +10 -0
  66. package/dist/discovery.d.ts.map +1 -0
  67. package/dist/discovery.js +150 -0
  68. package/dist/durability.d.ts +19 -0
  69. package/dist/durability.d.ts.map +1 -1
  70. package/dist/durability.js +4 -0
  71. package/dist/entry.d.ts +2 -2
  72. package/dist/entry.d.ts.map +1 -1
  73. package/dist/entry.js +18 -9
  74. package/dist/expectation.d.ts +26 -13
  75. package/dist/expectation.d.ts.map +1 -1
  76. package/dist/expectation.js +72 -19
  77. package/dist/failure.d.ts +3 -0
  78. package/dist/failure.d.ts.map +1 -1
  79. package/dist/failure.js +6 -0
  80. package/dist/figures.d.ts +49 -0
  81. package/dist/figures.d.ts.map +1 -0
  82. package/dist/figures.js +199 -0
  83. package/dist/file.d.ts +1 -1
  84. package/dist/file.d.ts.map +1 -1
  85. package/dist/file.js +3 -2
  86. package/dist/holdings.d.ts +29 -0
  87. package/dist/holdings.d.ts.map +1 -0
  88. package/dist/holdings.js +95 -0
  89. package/dist/host.d.ts +20 -4
  90. package/dist/host.d.ts.map +1 -1
  91. package/dist/host.js +72 -28
  92. package/dist/identity.d.ts +0 -1
  93. package/dist/identity.d.ts.map +1 -1
  94. package/dist/identity.js +0 -3
  95. package/dist/index.d.ts +32 -12
  96. package/dist/index.d.ts.map +1 -1
  97. package/dist/index.js +14 -5
  98. package/dist/install.d.ts +60 -0
  99. package/dist/install.d.ts.map +1 -0
  100. package/dist/install.js +537 -0
  101. package/dist/lifecycle.d.ts +7 -0
  102. package/dist/lifecycle.d.ts.map +1 -0
  103. package/dist/lifecycle.js +282 -0
  104. package/dist/listing.d.ts +52 -0
  105. package/dist/listing.d.ts.map +1 -0
  106. package/dist/listing.js +152 -0
  107. package/dist/live.d.ts +8 -6
  108. package/dist/live.d.ts.map +1 -1
  109. package/dist/live.js +110 -31
  110. package/dist/loaded.d.ts +5 -0
  111. package/dist/loaded.d.ts.map +1 -0
  112. package/dist/loaded.js +40 -0
  113. package/dist/locks.d.ts +7 -0
  114. package/dist/locks.d.ts.map +1 -0
  115. package/dist/locks.js +32 -0
  116. package/dist/lost.d.ts +5 -0
  117. package/dist/lost.d.ts.map +1 -0
  118. package/dist/lost.js +49 -0
  119. package/dist/media.d.ts +6 -1
  120. package/dist/media.d.ts.map +1 -1
  121. package/dist/media.js +68 -17
  122. package/dist/memory.d.ts +11 -3
  123. package/dist/memory.d.ts.map +1 -1
  124. package/dist/memory.js +132 -33
  125. package/dist/messages.d.ts +33 -3
  126. package/dist/messages.d.ts.map +1 -1
  127. package/dist/messages.js +98 -27
  128. package/dist/model.d.ts +2 -10
  129. package/dist/model.d.ts.map +1 -1
  130. package/dist/model.js +0 -14
  131. package/dist/models.d.ts +10 -0
  132. package/dist/models.d.ts.map +1 -0
  133. package/dist/models.js +153 -0
  134. package/dist/observation.d.ts +27 -12
  135. package/dist/observation.d.ts.map +1 -1
  136. package/dist/observation.js +184 -85
  137. package/dist/opened.d.ts +1 -1
  138. package/dist/opened.d.ts.map +1 -1
  139. package/dist/opened.js +5 -5
  140. package/dist/opening.d.ts +4 -0
  141. package/dist/opening.d.ts.map +1 -0
  142. package/dist/opening.js +53 -0
  143. package/dist/outcome.d.ts +17 -2
  144. package/dist/outcome.d.ts.map +1 -1
  145. package/dist/outcome.js +35 -2
  146. package/dist/overlay.d.ts +7 -2
  147. package/dist/overlay.d.ts.map +1 -1
  148. package/dist/overlay.js +48 -24
  149. package/dist/page-metadata.d.ts +8 -0
  150. package/dist/page-metadata.d.ts.map +1 -0
  151. package/dist/page-metadata.js +19 -0
  152. package/dist/parts.d.ts +4 -0
  153. package/dist/parts.d.ts.map +1 -0
  154. package/dist/parts.js +13 -0
  155. package/dist/paths.d.ts +1 -0
  156. package/dist/paths.d.ts.map +1 -1
  157. package/dist/paths.js +22 -0
  158. package/dist/preparation.d.ts +41 -0
  159. package/dist/preparation.d.ts.map +1 -0
  160. package/dist/preparation.js +314 -0
  161. package/dist/presence.d.ts +58 -0
  162. package/dist/presence.d.ts.map +1 -0
  163. package/dist/presence.js +231 -0
  164. package/dist/queries.d.ts +16 -0
  165. package/dist/queries.d.ts.map +1 -0
  166. package/dist/queries.js +308 -0
  167. package/dist/query.d.ts +13 -213
  168. package/dist/query.d.ts.map +1 -1
  169. package/dist/query.js +3 -524
  170. package/dist/questions.d.ts +30 -0
  171. package/dist/questions.d.ts.map +1 -0
  172. package/dist/questions.js +116 -0
  173. package/dist/queue.d.ts +40 -0
  174. package/dist/queue.d.ts.map +1 -0
  175. package/dist/queue.js +480 -0
  176. package/dist/reach.d.ts +10 -10
  177. package/dist/reach.d.ts.map +1 -1
  178. package/dist/reach.js +235 -120
  179. package/dist/react.d.ts +17 -3
  180. package/dist/react.d.ts.map +1 -1
  181. package/dist/react.js +33 -1
  182. package/dist/read.d.ts +7 -0
  183. package/dist/read.d.ts.map +1 -0
  184. package/dist/read.js +17 -0
  185. package/dist/readiness.d.ts +9 -4
  186. package/dist/readiness.d.ts.map +1 -1
  187. package/dist/readiness.js +3 -5
  188. package/dist/reads.d.ts +39 -0
  189. package/dist/reads.d.ts.map +1 -0
  190. package/dist/reads.js +178 -0
  191. package/dist/recovery.d.ts +3 -1
  192. package/dist/recovery.d.ts.map +1 -1
  193. package/dist/recovery.js +38 -8
  194. package/dist/refresh.d.ts +1 -1
  195. package/dist/refresh.d.ts.map +1 -1
  196. package/dist/refresh.js +10 -22
  197. package/dist/refusal.d.ts +5 -0
  198. package/dist/refusal.d.ts.map +1 -0
  199. package/dist/refusal.js +55 -0
  200. package/dist/replica.d.ts +11 -16
  201. package/dist/replica.d.ts.map +1 -1
  202. package/dist/replica.js +66 -35
  203. package/dist/retried.d.ts +30 -0
  204. package/dist/retried.d.ts.map +1 -0
  205. package/dist/retried.js +72 -0
  206. package/dist/room-draft.d.ts +32 -9
  207. package/dist/room-draft.d.ts.map +1 -1
  208. package/dist/room-draft.js +273 -66
  209. package/dist/room-drafts.d.ts +24 -0
  210. package/dist/room-drafts.d.ts.map +1 -0
  211. package/dist/room-drafts.js +220 -0
  212. package/dist/room-list.d.ts +10 -0
  213. package/dist/room-list.d.ts.map +1 -0
  214. package/dist/room-list.js +45 -0
  215. package/dist/rows.d.ts +16 -23
  216. package/dist/rows.d.ts.map +1 -1
  217. package/dist/rows.js +49 -191
  218. package/dist/runtime.d.ts +34 -0
  219. package/dist/runtime.d.ts.map +1 -0
  220. package/dist/runtime.js +1 -0
  221. package/dist/save.d.ts +42 -86
  222. package/dist/save.d.ts.map +1 -1
  223. package/dist/save.js +332 -228
  224. package/dist/saves.d.ts +34 -0
  225. package/dist/saves.d.ts.map +1 -0
  226. package/dist/saves.js +437 -0
  227. package/dist/search.d.ts.map +1 -1
  228. package/dist/search.js +1 -1
  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 +1 -6
  233. package/dist/shared.d.ts.map +1 -1
  234. package/dist/shared.js +13 -95
  235. package/dist/shown.d.ts +33 -0
  236. package/dist/shown.d.ts.map +1 -0
  237. package/dist/shown.js +309 -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 +59 -0
  257. package/dist/source.d.ts.map +1 -0
  258. package/dist/source.js +93 -0
  259. package/dist/status.d.ts +0 -2
  260. package/dist/status.d.ts.map +1 -1
  261. package/dist/status.js +0 -6
  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 +40 -0
  265. package/dist/store/readiness.d.ts +11 -0
  266. package/dist/store/readiness.d.ts.map +1 -0
  267. package/dist/store/readiness.js +68 -0
  268. package/dist/store/records.d.ts +223 -0
  269. package/dist/store/records.d.ts.map +1 -0
  270. package/dist/store/records.js +465 -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/rooms-shown.d.ts +8 -0
  275. package/dist/store/rooms-shown.d.ts.map +1 -0
  276. package/dist/store/rooms-shown.js +13 -0
  277. package/dist/store/space.d.ts +11 -0
  278. package/dist/store/space.d.ts.map +1 -0
  279. package/dist/store/space.js +41 -0
  280. package/dist/store/watchers.d.ts +17 -0
  281. package/dist/store/watchers.d.ts.map +1 -0
  282. package/dist/store/watchers.js +56 -0
  283. package/dist/store/writes.d.ts +24 -0
  284. package/dist/store/writes.d.ts.map +1 -0
  285. package/dist/store/writes.js +125 -0
  286. package/dist/store.d.ts +115 -152
  287. package/dist/store.d.ts.map +1 -1
  288. package/dist/store.js +171 -395
  289. package/dist/stored.d.ts +72 -67
  290. package/dist/stored.d.ts.map +1 -1
  291. package/dist/stored.js +317 -166
  292. package/dist/surface.d.ts +90 -0
  293. package/dist/surface.d.ts.map +1 -0
  294. package/dist/surface.js +225 -0
  295. package/dist/sync.d.ts +19 -0
  296. package/dist/sync.d.ts.map +1 -0
  297. package/dist/sync.js +536 -0
  298. package/dist/tables.d.ts +112 -89
  299. package/dist/tables.d.ts.map +1 -1
  300. package/dist/tables.js +197 -283
  301. package/dist/tallies.d.ts +18 -0
  302. package/dist/tallies.d.ts.map +1 -0
  303. package/dist/tallies.js +128 -0
  304. package/dist/validation.d.ts.map +1 -1
  305. package/dist/validation.js +9 -12
  306. package/dist/windows.d.ts +1 -12
  307. package/dist/windows.d.ts.map +1 -1
  308. package/dist/windows.js +2 -75
  309. package/dist/wire.d.ts +68 -7
  310. package/dist/wire.d.ts.map +1 -1
  311. package/dist/wire.js +23 -4
  312. package/package.json +3 -2
  313. package/dist/attempt.d.ts +0 -16
  314. package/dist/attempt.d.ts.map +0 -1
  315. package/dist/attempt.js +0 -70
  316. package/dist/fence.d.ts +0 -6
  317. package/dist/fence.d.ts.map +0 -1
  318. package/dist/fence.js +0 -10
  319. package/dist/job.d.ts +0 -14
  320. package/dist/job.d.ts.map +0 -1
  321. package/dist/job.js +0 -28
  322. package/dist/log.d.ts +0 -5
  323. package/dist/log.d.ts.map +0 -1
  324. package/dist/log.js +0 -14
  325. package/dist/phrase.d.ts +0 -3
  326. package/dist/phrase.d.ts.map +0 -1
  327. package/dist/phrase.js +0 -8
package/dist/reach.js CHANGED
@@ -1,8 +1,10 @@
1
+ import { QueryError } from '@agentshouse/mdmodel';
2
+ import { selected } from './collection.js';
1
3
  import { unheldView } from './conversation.js';
2
4
  import { modelTypes, NO_MODEL } from './model.js';
3
- import { changeOf, digestApplied, digestOf, observing, } from './observation.js';
4
- import { runtimeError } from './failure.js';
5
- import { failure, lockedRoom, ROOM_LOCKED, undeclared, UNREADABLE, } from './outcome.js';
5
+ import { changeOf, digestApplied, digestOf, observing, unchanged, } from './observation.js';
6
+ import { runtimeError, uncaught } from './failure.js';
7
+ import { absentBinary, failure, lockedRoom, ROOM_LOCKED, undeclared, UNREADABLE, } from './outcome.js';
6
8
  import { beneath } from './paths.js';
7
9
  import { moveTarget, readParts, staleWrite, } from './room-draft.js';
8
10
  import { documentKey } from './rows.js';
@@ -19,10 +21,21 @@ const NO_CONVERSATION = {
19
21
  interrupt: unconversed('conversations/interrupt'),
20
22
  kill: unconversed('conversations/kill'),
21
23
  delete: unconversed('conversations/delete'),
24
+ takeOut: unconversed('conversations/take-out'),
25
+ decide: unconversed('agent-functions/decide'),
26
+ rename: unconversed('conversations/rename'),
27
+ option: unconversed('conversations/option/set'),
28
+ retry: unconversed('conversations/retry'),
29
+ pin: () => Promise.resolve(),
30
+ openTurn: () => Promise.resolve(),
31
+ dismissSuggestion: () => Promise.resolve(),
32
+ attach: () => Promise.resolve(undeclared('conversation.attach')),
33
+ attachment: (link) => Promise.resolve(absentBinary(link)),
22
34
  };
23
35
  const NO_CHAT_DRAFT = {
24
36
  write: () => Promise.resolve(),
25
37
  prepend: () => Promise.resolve(),
38
+ append: () => Promise.resolve(),
26
39
  discard: () => Promise.resolve(),
27
40
  };
28
41
  function areasOf(reach) {
@@ -45,11 +58,11 @@ export function governs(reach, room) {
45
58
  if (wholly(reach, room.locator)) {
46
59
  return { collection: true, selection: room.typedSelection !== null };
47
60
  }
48
- const selected = (path) => room.typedSelection?.roots.some((root) => beneath(root, path)) ?? false;
61
+ const within = (path) => selected({ selection: room.typedSelection }, path);
49
62
  const paths = reach.documents
50
63
  .filter((document) => document.room === room.locator)
51
64
  .map(({ path }) => path);
52
- return { collection: paths.some((path) => !selected(path)), selection: paths.some(selected) };
65
+ return { collection: paths.some((path) => !within(path)), selection: paths.some(within) };
53
66
  }
54
67
  function covers(reach, room, path) {
55
68
  return (reach === null ||
@@ -60,6 +73,19 @@ function covers(reach, room, path) {
60
73
  function conversing(reach) {
61
74
  return reach === null || reach.conversations;
62
75
  }
76
+ function roomsAwaited(error, reach) {
77
+ return error.code === 'unknown-type' && reach !== null && reach.rooms.length === 0;
78
+ }
79
+ async function planInReach(runtime, input, reach, answered) {
80
+ try {
81
+ return await runtime.plan(input, reach);
82
+ }
83
+ catch (error) {
84
+ if (error instanceof QueryError && (answered || roomsAwaited(error, reach)))
85
+ return null;
86
+ throw error;
87
+ }
88
+ }
63
89
  export function planReach(reach) {
64
90
  return reach === null
65
91
  ? null
@@ -76,6 +102,14 @@ export function planReach(reach) {
76
102
  function roomsWithin(reach, rooms) {
77
103
  return rooms.filter((room) => wholly(reach, room.locator));
78
104
  }
105
+ function roomsChangeWithin(reach, { changed, removed, order }) {
106
+ const within = {
107
+ changed: changed.filter(([locator]) => wholly(reach, locator)),
108
+ removed,
109
+ order: order === null ? null : order.filter((locator) => wholly(reach, locator)),
110
+ };
111
+ return unchanged(within) ? null : within;
112
+ }
79
113
  function typesWithin(reach, room, types) {
80
114
  if (room === undefined)
81
115
  return structuredClone(UNHELD_TYPES);
@@ -105,12 +139,13 @@ function writeWithin(reach, write) {
105
139
  function savedWithin(reach, room, result) {
106
140
  if (reach === null || result.outcome === 'saved')
107
141
  return result;
108
- const { file, location, referrers, ...refusal } = result;
142
+ const { file, location, line, referrers, ...refusal } = result;
109
143
  const hidden = file !== undefined && !covers(reach, room, file);
110
144
  return {
111
145
  ...refusal,
112
146
  ...(file === undefined || hidden ? {} : { file }),
113
147
  ...(location === undefined || hidden ? {} : { location }),
148
+ ...(line === undefined || hidden ? {} : { line }),
114
149
  ...(referrers === undefined
115
150
  ? {}
116
151
  : { referrers: referrers.filter((path) => covers(reach, room, path)) }),
@@ -143,7 +178,7 @@ function lockedError(room) {
143
178
  return runtimeError(ROOM_LOCKED, `${room} is locked until House confirms its access`, true);
144
179
  }
145
180
  function deviceUnreached() {
146
- return runtimeError('device-unreached', 'Only the panel cleans up this device');
181
+ return runtimeError('device-unreached', 'Only the panel reaches this device');
147
182
  }
148
183
  const ATTACH_REQUIRED = 'attach-required';
149
184
  function attachRequired() {
@@ -152,10 +187,9 @@ function attachRequired() {
152
187
  function carriesFile(parts) {
153
188
  return parts !== null && typeof parts === 'object' && Object.hasOwn(parts, 'file');
154
189
  }
155
- export function narrowed(runtime, given, told) {
190
+ export function narrowed(runtime, given, port) {
156
191
  const { md, watch } = runtime;
157
192
  let reach = given;
158
- let port = told;
159
193
  const open = new Set();
160
194
  function following(begin, locking = false) {
161
195
  let stop = begin();
@@ -171,71 +205,137 @@ export function narrowed(runtime, given, told) {
171
205
  stop();
172
206
  };
173
207
  }
174
- const unlocking = (rooms) => {
175
- const locked = (rooms ?? []).filter((room) => runtime.locked(room));
176
- return locked.length === 0
177
- ? null
178
- : { pending: locked.map((room) => ({ room, awaits: 'unlock' })) };
208
+ const unlocking = (rooms, locked) => {
209
+ const held = (rooms ?? []).filter((room) => locked.includes(room));
210
+ return held.length === 0 ? null : { pending: held.map((room) => ({ room, awaits: 'unlock' })) };
211
+ };
212
+ const unlocked = (entries, locked) => entries.filter((entry) => !locked.includes(entry.room));
213
+ const intoLocked = async (held) => {
214
+ for (const move of held) {
215
+ if (move?.room !== undefined && (await runtime.locked(move.room)))
216
+ return true;
217
+ }
218
+ return false;
179
219
  };
180
- const unlocked = (entries) => entries.filter((entry) => !runtime.locked(entry.room));
181
- const intoLocked = (held) => held.some((move) => move?.room !== undefined && runtime.locked(move.room));
220
+ function ordered(deliver) {
221
+ let open = true;
222
+ let shown = Promise.resolve();
223
+ return {
224
+ push(making) {
225
+ shown = shown.then(() => making.then((value) => {
226
+ if (open)
227
+ deliver(value);
228
+ }, uncaught), uncaught);
229
+ },
230
+ stop() {
231
+ open = false;
232
+ },
233
+ };
234
+ }
235
+ function unlockedWatch(topic, input, deliver, fail, within) {
236
+ const shown = ordered(deliver);
237
+ const stop = watch(topic, input, (message) => {
238
+ shown.push(runtime.lockedRooms().then((locked) => within(message, locked)));
239
+ }, fail);
240
+ return () => {
241
+ shown.stop();
242
+ stop();
243
+ };
244
+ }
245
+ function lockedFirst(room, start, shut) {
246
+ let open = true;
247
+ let stop = () => { };
248
+ void (async () => {
249
+ const closed = !holds(reach, room) || (await runtime.locked(room));
250
+ if (!open)
251
+ return;
252
+ if (closed)
253
+ shut();
254
+ else
255
+ stop = start();
256
+ })();
257
+ return () => {
258
+ open = false;
259
+ stop();
260
+ };
261
+ }
182
262
  const within = (topic, input, deliver, fail) => {
263
+ if (topic === 'read' && reach !== null) {
264
+ fail(deviceUnreached());
265
+ return () => { };
266
+ }
183
267
  if (topic === 'rooms') {
184
- return following(() => watch(topic, input, (rooms) => deliver(roomsWithin(reach, rooms)), fail));
268
+ return following(() => watch(topic, input, (rooms) => {
269
+ const shown = Array.isArray(rooms)
270
+ ? roomsWithin(reach, rooms)
271
+ : roomsChangeWithin(reach, rooms);
272
+ if (shown !== null)
273
+ deliver(shown);
274
+ }, fail));
185
275
  }
186
276
  if (topic === 'readiness') {
187
277
  return following(() => runtime.watchReadiness(port, reach, deliver));
188
278
  }
189
279
  if (topic === 'sync-status') {
190
- return following(() => watch(topic, input, (status) => {
191
- const within = statusWithin(reach, status);
192
- deliver({ ...within, attentionRequired: unlocked(within.attentionRequired) });
193
- }, fail), true);
280
+ return following(() => unlockedWatch(topic, input, deliver, fail, (status, locked) => {
281
+ const shown = statusWithin(reach, status);
282
+ return { ...shown, attentionRequired: unlocked(shown.attentionRequired, locked) };
283
+ }), true);
194
284
  }
195
285
  if (topic === 'room-drafts') {
196
- return following(() => watch(topic, input, (drafts) => deliver(unlocked(draftsWithin(reach, drafts))), fail), true);
286
+ return following(() => unlockedWatch(topic, input, deliver, fail, (drafts, locked) => unlocked(draftsWithin(reach, drafts), locked)), true);
197
287
  }
198
288
  if (topic === 'queue') {
199
289
  const room = input[0];
200
- return following(() => {
201
- if (!holds(reach, room) || runtime.locked(room)) {
202
- deliver([]);
203
- return () => { };
204
- }
205
- return watch(topic, input, (entries) => deliver(queueWithin(reach, room, entries)), fail);
206
- }, true);
290
+ return following(() => lockedFirst(room, () => watch(topic, input, (entries) => deliver(queueWithin(reach, room, entries)), fail), () => deliver([])), true);
207
291
  }
208
292
  if (topic === 'query') {
209
- const plan = runtime.plan(input[0], reach);
210
293
  let held = null;
294
+ let planning = null;
295
+ const waiting = (result) => {
296
+ const answer = { result, keys: [] };
297
+ if (held === null || changeOf(held, answer) !== null)
298
+ deliver(answer);
299
+ held = digestOf(answer);
300
+ };
211
301
  return following(() => {
212
- const locked = unlocking(plan.rooms);
213
- if (locked !== null) {
214
- const answer = { result: locked, keys: [] };
215
- if (held === null || changeOf(held, answer) !== null)
216
- deliver(answer);
217
- held = digestOf(answer);
218
- return () => { };
219
- }
220
- let first = true;
221
302
  let open = true;
222
- const heard = (message) => {
223
- if (!first) {
224
- held = digestApplied(held, message);
225
- deliver(message);
303
+ let stop = () => { };
304
+ if (planning?.reach !== reach) {
305
+ planning = { reach, plan: planInReach(runtime, input[0], reach, held !== null) };
306
+ }
307
+ const planned = planning.plan;
308
+ void (async () => {
309
+ const plan = await planned;
310
+ const locked = await runtime.lockedRooms();
311
+ if (!open)
226
312
  return;
227
- }
228
- first = false;
229
- const change = held === null ? message : changeOf(held, message);
230
- held = digestOf(message);
231
- if (change !== null)
232
- deliver(change);
233
- };
234
- const current = { ...plan, reach: planReach(reach), locked: runtime.lockedRooms() };
235
- const stop = runtime.watchPlan(current, (message) => {
236
- if (open)
237
- heard(message);
238
- }, (error) => {
313
+ if (plan === null)
314
+ return waiting({ pending: [] });
315
+ const pending = unlocking(plan.rooms, locked);
316
+ if (pending !== null)
317
+ return waiting(pending);
318
+ let first = true;
319
+ const heard = (message) => {
320
+ if (!first) {
321
+ held = digestApplied(held, message);
322
+ deliver(message);
323
+ return;
324
+ }
325
+ first = false;
326
+ const change = held === null ? message : changeOf(held, message);
327
+ held = digestOf(message);
328
+ if (change !== null)
329
+ deliver(change);
330
+ };
331
+ stop = runtime.watchPlan({ ...plan, locked }, (message) => {
332
+ if (open)
333
+ heard(message);
334
+ }, (error) => {
335
+ if (open)
336
+ fail(error);
337
+ });
338
+ })().catch((error) => {
239
339
  if (open)
240
340
  fail(error);
241
341
  });
@@ -261,6 +361,15 @@ export function narrowed(runtime, given, told) {
261
361
  return () => { };
262
362
  });
263
363
  }
364
+ if (topic === 'figures' ||
365
+ topic === 'holdings' ||
366
+ topic === 'listed-agents' ||
367
+ topic === 'room-list') {
368
+ if (reach === null)
369
+ return watch(topic, input, deliver, fail);
370
+ fail(deviceUnreached());
371
+ return () => { };
372
+ }
264
373
  return watch(topic, input, deliver, fail);
265
374
  };
266
375
  const files = new Map();
@@ -279,31 +388,35 @@ export function narrowed(runtime, given, told) {
279
388
  const view = {
280
389
  ...md,
281
390
  rooms: () => md.rooms().then((rooms) => roomsWithin(reach, rooms)),
282
- query: ((input) => {
283
- const plan = runtime.plan(input, reach);
284
- return Promise.resolve(unlocking(plan.rooms) ?? runtime.query({ ...plan, locked: runtime.lockedRooms() }));
391
+ query: (async (input) => {
392
+ const plan = await planInReach(runtime, input, reach, false);
393
+ if (plan === null)
394
+ return { pending: [] };
395
+ const locked = await runtime.lockedRooms();
396
+ return unlocking(plan.rooms, locked) ?? runtime.query({ ...plan, locked });
285
397
  }),
286
398
  search: (input) => runtime.search(input, reach),
287
- types(room) {
288
- if (holds(reach, room) && runtime.locked(room))
399
+ async types(room) {
400
+ if (holds(reach, room) && (await runtime.locked(room)))
289
401
  throw lockedError(room);
290
402
  if (wholly(reach, room))
291
403
  return md.types(room);
292
404
  if (!holds(reach, room))
293
405
  return structuredClone(UNHELD_TYPES);
294
- return typesWithin(reach, runtime.room(room), md.types(room));
406
+ return typesWithin(reach, await runtime.room(room), await md.types(room));
295
407
  },
296
408
  async save(room, roomDrafts, writtenBy) {
297
409
  if (!holds(reach, room))
298
410
  throw unreached(room);
299
- if (runtime.locked(room))
411
+ if (await runtime.locked(room)) {
300
412
  return { outcome: 'refused', code: ROOM_LOCKED, retryable: true };
413
+ }
301
414
  const held = (await Promise.all(roomDrafts.map(({ path }) => md.roomDraft.read(room, path)))).map((draft) => draft?.parts.move);
302
415
  const outside = roomDrafts.find(({ path }, at) => !covers(reach, room, path) || !moves(reach, room, held[at]));
303
416
  if (outside !== undefined) {
304
417
  return { outcome: 'refused', code: 'stale', retryable: false, file: outside.path };
305
418
  }
306
- if (intoLocked(held))
419
+ if (await intoLocked(held))
307
420
  return { outcome: 'refused', code: ROOM_LOCKED, retryable: true };
308
421
  return savedWithin(reach, room, await md.save(room, roomDrafts, writtenBy));
309
422
  },
@@ -314,47 +427,48 @@ export function narrowed(runtime, given, told) {
314
427
  if (filed !== undefined) {
315
428
  return { outcome: 'refused', code: ATTACH_REQUIRED, retryable: false, file: filed.path };
316
429
  }
317
- if (runtime.locked(room))
430
+ if (await runtime.locked(room)) {
318
431
  return { outcome: 'refused', code: ROOM_LOCKED, retryable: true };
432
+ }
319
433
  const held = parts.map(({ path, parts: one }) => readParts(one, path).move);
320
434
  if (parts.some(({ path }, at) => !covers(reach, room, path) || !moves(reach, room, held[at]))) {
321
435
  throw unreached(room);
322
436
  }
323
- if (intoLocked(held))
437
+ if (await intoLocked(held))
324
438
  return { outcome: 'refused', code: ROOM_LOCKED, retryable: true };
325
439
  return savedWithin(reach, room, await md.saveParts(room, parts, writtenBy));
326
440
  },
327
- resolve(room, path, destination) {
328
- const at = runtime.located(room, path, destination);
441
+ async resolve(room, path, destination) {
442
+ const at = await runtime.located(room, path, destination);
329
443
  return at !== null && !covers(reach, at.room, at.path)
330
- ? Promise.resolve(UNREADABLE)
444
+ ? UNREADABLE
331
445
  : md.resolve(room, path, destination);
332
446
  },
333
- history: (room, path, query) => !covers(reach, room, path)
334
- ? Promise.resolve(failure({ kind: 'room-not-readable', locator: room }))
335
- : runtime.locked(room)
336
- ? Promise.resolve(lockedRoom(room))
447
+ history: async (room, path, query) => !covers(reach, room, path)
448
+ ? failure({ kind: 'room-not-readable', locator: room })
449
+ : (await runtime.locked(room))
450
+ ? lockedRoom(room)
337
451
  : md.history(room, path, query),
338
452
  binaryFile: {
339
- read: (room, path, revision) => !covers(reach, room, path)
340
- ? Promise.resolve(failure({ kind: 'room-not-readable', locator: room }))
341
- : runtime.locked(room)
342
- ? Promise.resolve(lockedRoom(room))
453
+ read: async (room, path, revision) => !covers(reach, room, path)
454
+ ? failure({ kind: 'room-not-readable', locator: room })
455
+ : (await runtime.locked(room))
456
+ ? lockedRoom(room)
343
457
  : hand(md.binaryFile.read(room, path, revision)),
344
- link: (room, path, revision) => !covers(reach, room, path)
345
- ? Promise.resolve(failure({ kind: 'room-not-readable', locator: room }))
346
- : runtime.locked(room)
347
- ? Promise.resolve(lockedRoom(room))
458
+ link: async (room, path, revision) => !covers(reach, room, path)
459
+ ? failure({ kind: 'room-not-readable', locator: room })
460
+ : (await runtime.locked(room))
461
+ ? lockedRoom(room)
348
462
  : md.binaryFile.link(room, path, revision),
349
- show: (room, path, revision) => !covers(reach, room, path)
350
- ? Promise.resolve(failure({ kind: 'room-not-readable', locator: room }))
351
- : runtime.locked(room)
352
- ? Promise.resolve(lockedRoom(room))
463
+ show: async (room, path, revision) => !covers(reach, room, path)
464
+ ? failure({ kind: 'room-not-readable', locator: room })
465
+ : (await runtime.locked(room))
466
+ ? lockedRoom(room)
353
467
  : hand(md.binaryFile.show(room, path, revision)),
354
- attach: (room, file) => !wholly(reach, room)
355
- ? Promise.resolve(failure({ kind: 'room-not-readable', locator: room }))
356
- : runtime.locked(room)
357
- ? Promise.resolve(lockedRoom(room))
468
+ attach: async (room, file) => !wholly(reach, room)
469
+ ? failure({ kind: 'room-not-readable', locator: room })
470
+ : (await runtime.locked(room))
471
+ ? lockedRoom(room)
358
472
  : md.binaryFile.attach(room, file),
359
473
  async part(file, part) {
360
474
  const key = files.get(file);
@@ -367,42 +481,37 @@ export function narrowed(runtime, given, told) {
367
481
  },
368
482
  },
369
483
  reached: async (room, roomVersion, path) => (path === undefined ? wholly(reach, room) : covers(reach, room, path)) &&
370
- !runtime.locked(room) &&
484
+ !(await runtime.locked(room)) &&
371
485
  (await md.reached(room, roomVersion, path)),
372
- log: () => (reach === null ? md.log() : ''),
373
486
  cleanUp: () => (reach === null ? md.cleanUp() : Promise.reject(deviceUnreached())),
487
+ unsent: () => (reach === null ? md.unsent() : Promise.reject(deviceUnreached())),
488
+ reset: () => (reach === null ? md.reset() : Promise.reject(deviceUnreached())),
489
+ readAgain: () => (reach === null ? md.readAgain() : Promise.reject(deviceUnreached())),
374
490
  roomDraft: {
375
- list: () => md.roomDraft.list().then((drafts) => unlocked(draftsWithin(reach, drafts))),
491
+ list: async () => unlocked(draftsWithin(reach, await md.roomDraft.list()), await runtime.lockedRooms()),
376
492
  async read(room, path) {
377
493
  if (!covers(reach, room, path))
378
494
  return null;
379
- if (runtime.locked(room))
495
+ if (await runtime.locked(room))
380
496
  throw lockedError(room);
381
497
  return shownDraft(reach, await md.roomDraft.read(room, path));
382
498
  },
383
- write(room, path, revision, parts, next) {
384
- try {
385
- if (reach !== null && carriesFile(parts))
386
- throw attachRequired();
387
- const move = readParts(parts, path).move;
388
- if (!covers(reach, room, path) || !moves(reach, room, move))
389
- throw unreached(room);
390
- if (runtime.locked(room))
391
- throw lockedError(room);
392
- if (intoLocked([move]))
393
- throw lockedError(move.room);
394
- }
395
- catch (error) {
396
- return Promise.reject(error);
397
- }
398
- return md.roomDraft
399
- .write(room, path, revision, parts, next)
400
- .then((written) => writeWithin(reach, written));
499
+ async write(room, path, revision, parts, next) {
500
+ if (reach !== null && carriesFile(parts))
501
+ throw attachRequired();
502
+ const move = readParts(parts, path).move;
503
+ if (!covers(reach, room, path) || !moves(reach, room, move))
504
+ throw unreached(room);
505
+ if (await runtime.locked(room))
506
+ throw lockedError(room);
507
+ if (await intoLocked([move]))
508
+ throw lockedError(move.room);
509
+ return writeWithin(reach, await md.roomDraft.write(room, path, revision, parts, next));
401
510
  },
402
511
  async discard(room, path, revision) {
403
512
  if (!covers(reach, room, path))
404
513
  return staleWrite(null);
405
- if (runtime.locked(room))
514
+ if (await runtime.locked(room))
406
515
  throw lockedError(room);
407
516
  return writeWithin(reach, await md.roomDraft.discard(room, path, revision));
408
517
  },
@@ -412,14 +521,25 @@ export function narrowed(runtime, given, told) {
412
521
  read: (id, options) => conversation().read(id, options),
413
522
  create: (input) => conversation().create(input),
414
523
  send: (id, operation, draft) => conversation().send(id, operation, draft),
415
- answer: (id, answer) => conversation().answer(id, answer),
416
- interrupt: (id) => conversation().interrupt(id),
417
- kill: (id) => conversation().kill(id),
418
- delete: (id) => conversation().delete(id),
524
+ answer: (id, answer, operation) => conversation().answer(id, answer, operation),
525
+ interrupt: (id, operation) => conversation().interrupt(id, operation),
526
+ kill: (id, operation) => conversation().kill(id, operation),
527
+ delete: (id, operation) => conversation().delete(id, operation),
528
+ takeOut: (id, message, operation) => conversation().takeOut(id, message, operation),
529
+ decide: (request, decision, operation) => conversation().decide(request, decision, operation),
530
+ rename: (id, name, operation) => conversation().rename(id, name, operation),
531
+ option: (id, option, value, operation) => conversation().option(id, option, value, operation),
532
+ retry: (id, message, operation) => conversation().retry(id, message, operation),
533
+ pin: (figures) => conversation().pin(figures),
534
+ openTurn: (id, turn) => conversation().openTurn(id, turn),
535
+ dismissSuggestion: (id, suggestion) => conversation().dismissSuggestion(id, suggestion),
536
+ attach: (file) => conversation().attach(file),
537
+ attachment: (link) => conversation().attachment(link),
419
538
  },
420
539
  chatDraft: {
421
540
  write: (id, draft, revision) => chatDraft().write(id, draft, revision),
422
541
  prepend: (id, draft) => chatDraft().prepend(id, draft),
542
+ append: (id, draft) => chatDraft().append(id, draft),
423
543
  discard: (id) => chatDraft().discard(id),
424
544
  },
425
545
  observe: observing(within),
@@ -432,10 +552,5 @@ export function narrowed(runtime, given, told) {
432
552
  for (const restart of [...open])
433
553
  restart();
434
554
  },
435
- facts(next) {
436
- port = next;
437
- for (const restart of [...open])
438
- restart();
439
- },
440
555
  };
441
556
  }
package/dist/react.d.ts CHANGED
@@ -1,10 +1,17 @@
1
+ import type { DocumentQuery, GroupQuery } from '@agentshouse/mdmodel';
2
+ import type { Acting, Lane, LaneShown } from './act-lanes.js';
1
3
  import type { MdRuntimeClient } from './client.js';
2
- import type { AppRoom, ConnectionRefusal, SavedRoomDraft, SaveResult } from './connection.js';
3
- import type { Member, ServiceMode } from './adapter.js';
4
+ import type { AppRoom } from './listing.js';
5
+ import type { ConnectionRefusal } from './socket.js';
6
+ import type { SavedRoomDraft, SaveResult } from './saves.js';
7
+ import type { ListedAgent, Member, RoomList, ServiceMode } from './adapter.js';
4
8
  import type { ConversationAgent, ConversationEntry, ConversationOptions, ConversationView } from './conversation.js';
5
9
  import { type RuntimeError } from './failure.js';
10
+ import type { FiguresResult } from './figures.js';
11
+ import type { Holdings } from './holdings.js';
12
+ import type { Descriptor, Expecting } from './expectation.js';
6
13
  import type { QueueEntry } from './outcome.js';
7
- import type { DocumentQuery, DocumentResult, GroupQuery, GroupResult, PendingResult } from './query.js';
14
+ import type { DocumentResult, GroupResult, PendingResult } from './query.js';
8
15
  import type { Readiness } from './readiness.js';
9
16
  import type { RoomDraft, RoomDraftParts } from './room-draft.js';
10
17
  import type { SyncStatus } from './status.js';
@@ -32,6 +39,13 @@ export declare function useObserve(client: Client, topic: 'presentation'): Obser
32
39
  export declare function useObserve(client: Client, topic: 'conversation', conversation: string, options: ConversationOptions): Observed<ConversationView>;
33
40
  export declare function useObserve(client: Client, topic: 'conversations'): Observed<readonly ConversationEntry[]>;
34
41
  export declare function useObserve(client: Client, topic: 'agents'): Observed<readonly ConversationAgent[]>;
42
+ export declare function useObserve(client: Client, topic: 'listed-agents'): Observed<readonly ListedAgent[]>;
43
+ export declare function useObserve(client: Client, topic: 'room-list'): Observed<RoomList | null>;
44
+ export declare function useObserve(client: Client, topic: 'figures'): Observed<FiguresResult>;
45
+ export declare function useObserve(client: Client, topic: 'holdings'): Observed<Holdings>;
46
+ export declare function useExpected<A, T>(store: Expecting, descriptor: Descriptor<A, T>, places: readonly A[], held: ReadonlyMap<A, T> | null): (place: A, held: T) => T;
47
+ export type LaneHeld<O> = LaneShown<O> & Pick<Lane<O>, 'run' | 'forget'>;
48
+ export declare function useLane<O>(lanes: Acting<O>): LaneHeld<O>;
35
49
  export type Saving = {
36
50
  readonly busy: boolean;
37
51
  readonly outcome: SaveResult | null;
@@ -1 +1 @@
1
- {"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../src/react.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../src/react.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACtE,OAAO,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC9D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC/E,OAAO,KAAK,EACV,iBAAiB,EACjB,iBAAiB,EACjB,mBAAmB,EACnB,gBAAgB,EACjB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAU,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC;AACzD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAE9D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC7E,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,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,mBAAmB,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC;AACzF,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;AACpG,wBAAgB,UAAU,CACxB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,eAAe,GACrB,QAAQ,CAAC,SAAS,WAAW,EAAE,CAAC,CAAC;AACpC,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,GAAG,QAAQ,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;AAC1F,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,GAAG,QAAQ,CAAC,aAAa,CAAC,CAAC;AACtF,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;AAoDlF,wBAAgB,WAAW,CAAC,CAAC,EAAE,CAAC,EAC9B,KAAK,EAAE,SAAS,EAChB,UAAU,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,EAC5B,MAAM,EAAE,SAAS,CAAC,EAAE,EACpB,IAAI,EAAE,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI,GAC7B,CAAC,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,KAAK,CAAC,CAmB1B;AAED,MAAM,MAAM,QAAQ,CAAC,CAAC,IAAI,SAAS,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,KAAK,GAAG,QAAQ,CAAC,CAAC;AAEzE,wBAAgB,OAAO,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAIxD;AAED,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,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,cAAc,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IACpF,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,cAAc,EAAE,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;CACvF,CAAC;AAMF,wBAAgB,OAAO,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM,CA8BvD"}
package/dist/react.js CHANGED
@@ -1,4 +1,4 @@
1
- import { useCallback, useLayoutEffect, useRef, useState } from 'react';
1
+ import { useCallback, useEffect, useId, useLayoutEffect, useMemo, useRef, useState, useSyncExternalStore, } from 'react';
2
2
  import { failed } from './failure.js';
3
3
  const LOADING = { state: 'loading' };
4
4
  export function useObserve(client, topic, ...input) {
@@ -32,6 +32,38 @@ export function useObserve(client, topic, ...input) {
32
32
  }, [client, key]);
33
33
  return held !== null && held.client === client && held.key === key ? held.observed : LOADING;
34
34
  }
35
+ function sameHeld(descriptor, was, now) {
36
+ if (was === now)
37
+ return true;
38
+ if (was === null || now === null || was.size !== now.size)
39
+ return false;
40
+ const before = new Map([...was].map(([place, value]) => [descriptor.place(place), value]));
41
+ return [...now].every(([place, value]) => {
42
+ const at = descriptor.place(place);
43
+ return before.has(at) && Object.is(before.get(at), value);
44
+ });
45
+ }
46
+ export function useExpected(store, descriptor, places, held) {
47
+ const reader = useId();
48
+ const version = useSyncExternalStore(store.subscribe, store.version);
49
+ const asked = JSON.stringify(places.map((one) => descriptor.place(one)));
50
+ const kept = useRef(held);
51
+ if (!sameHeld(descriptor, kept.current, held))
52
+ kept.current = held;
53
+ const shown = kept.current;
54
+ useLayoutEffect(() => store.reads(reader, descriptor, places), [store, reader, descriptor, asked]);
55
+ useLayoutEffect(() => () => store.left(reader), [store, reader]);
56
+ useEffect(() => {
57
+ if (shown !== null)
58
+ store.heard(reader, descriptor, shown);
59
+ }, [store, reader, descriptor, shown]);
60
+ return useCallback((place, value) => store.draw(descriptor, place, value), [store, descriptor, version]);
61
+ }
62
+ export function useLane(lanes) {
63
+ const lane = useMemo(() => lanes.open(), [lanes]);
64
+ const shown = useSyncExternalStore(lane.subscribe, lane.shown);
65
+ return useMemo(() => ({ ...shown, run: lane.run, forget: lane.forget }), [shown, lane]);
66
+ }
35
67
  const IDLE = { busy: false, outcome: null, failure: null };
36
68
  export function useSave(client) {
37
69
  const [state, setState] = useState(IDLE);
package/dist/read.d.ts ADDED
@@ -0,0 +1,7 @@
1
+ export type Fields = Readonly<Record<string, unknown>>;
2
+ export declare const EXCERPT = 512;
3
+ export declare function excerpt(said: string): string;
4
+ export declare function record(entry: unknown): Fields;
5
+ export declare function text(fields: Fields, name: string): string | null;
6
+ export declare function list(fields: Fields, name: string): readonly unknown[];
7
+ //# sourceMappingURL=read.d.ts.map
@@ -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"}