@agentshouse/mdruntime 0.1.0-cfcbb238a5fa0 → 0.1.0-cfcf93be6310b

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 (236) hide show
  1. package/README.md +19 -16
  2. package/dist/adapter.d.ts +142 -70
  3. package/dist/adapter.d.ts.map +1 -1
  4. package/dist/attached-model.d.ts +5 -1
  5. package/dist/attached-model.d.ts.map +1 -1
  6. package/dist/attached-model.js +38 -4
  7. package/dist/binary.d.ts +0 -5
  8. package/dist/binary.d.ts.map +1 -1
  9. package/dist/binary.js +1 -1
  10. package/dist/bootstrap.d.ts +26 -11
  11. package/dist/bootstrap.d.ts.map +1 -1
  12. package/dist/bootstrap.js +181 -103
  13. package/dist/chain.d.ts +11 -0
  14. package/dist/chain.d.ts.map +1 -0
  15. package/dist/chain.js +64 -0
  16. package/dist/change-set.d.ts +9 -16
  17. package/dist/change-set.d.ts.map +1 -1
  18. package/dist/change-set.js +11 -89
  19. package/dist/change.d.ts +31 -1
  20. package/dist/change.d.ts.map +1 -1
  21. package/dist/change.js +10 -1
  22. package/dist/client.d.ts +17 -9
  23. package/dist/client.d.ts.map +1 -1
  24. package/dist/client.js +86 -9
  25. package/dist/collection.d.ts +11 -21
  26. package/dist/collection.d.ts.map +1 -1
  27. package/dist/collection.js +39 -291
  28. package/dist/compile.d.ts +16 -0
  29. package/dist/compile.d.ts.map +1 -0
  30. package/dist/compile.js +789 -0
  31. package/dist/connection.d.ts +26 -16
  32. package/dist/connection.d.ts.map +1 -1
  33. package/dist/connection.js +3210 -1397
  34. package/dist/context.d.ts +2 -0
  35. package/dist/context.d.ts.map +1 -0
  36. package/dist/{chat/context.js → context.js} +1 -4
  37. package/dist/conversation.d.ts +29 -14
  38. package/dist/conversation.d.ts.map +1 -1
  39. package/dist/conversation.js +422 -198
  40. package/dist/digest.d.ts +7 -0
  41. package/dist/digest.d.ts.map +1 -0
  42. package/dist/digest.js +113 -0
  43. package/dist/durability.d.ts +2 -5
  44. package/dist/durability.d.ts.map +1 -1
  45. package/dist/durability.js +5 -0
  46. package/dist/entry.d.ts +4 -1
  47. package/dist/entry.d.ts.map +1 -1
  48. package/dist/entry.js +20 -24
  49. package/dist/file.d.ts +2 -19
  50. package/dist/file.d.ts.map +1 -1
  51. package/dist/file.js +7 -122
  52. package/dist/host.d.ts +3 -10
  53. package/dist/host.d.ts.map +1 -1
  54. package/dist/host.js +64 -38
  55. package/dist/identity.d.ts +0 -1
  56. package/dist/identity.d.ts.map +1 -1
  57. package/dist/identity.js +0 -3
  58. package/dist/index.d.ts +17 -12
  59. package/dist/index.d.ts.map +1 -1
  60. package/dist/index.js +8 -2
  61. package/dist/job.d.ts +14 -0
  62. package/dist/job.d.ts.map +1 -0
  63. package/dist/job.js +28 -0
  64. package/dist/live.d.ts +23 -0
  65. package/dist/live.d.ts.map +1 -0
  66. package/dist/live.js +127 -0
  67. package/dist/media.d.ts +8 -0
  68. package/dist/media.d.ts.map +1 -0
  69. package/dist/media.js +218 -0
  70. package/dist/memory.d.ts +12 -6
  71. package/dist/memory.d.ts.map +1 -1
  72. package/dist/memory.js +202 -103
  73. package/dist/messages.d.ts +28 -0
  74. package/dist/messages.d.ts.map +1 -0
  75. package/dist/messages.js +89 -0
  76. package/dist/model.d.ts +6 -1
  77. package/dist/model.d.ts.map +1 -1
  78. package/dist/model.js +7 -10
  79. package/dist/name.d.ts +4 -0
  80. package/dist/name.d.ts.map +1 -0
  81. package/dist/name.js +122 -0
  82. package/dist/observation.d.ts +17 -2
  83. package/dist/observation.d.ts.map +1 -1
  84. package/dist/observation.js +100 -5
  85. package/dist/opened.d.ts +22 -0
  86. package/dist/opened.d.ts.map +1 -0
  87. package/dist/opened.js +107 -0
  88. package/dist/outcome.d.ts +45 -7
  89. package/dist/outcome.d.ts.map +1 -1
  90. package/dist/outcome.js +39 -0
  91. package/dist/overlay.d.ts +2 -5
  92. package/dist/overlay.d.ts.map +1 -1
  93. package/dist/overlay.js +87 -172
  94. package/dist/paths.d.ts +1 -0
  95. package/dist/paths.d.ts.map +1 -1
  96. package/dist/paths.js +4 -0
  97. package/dist/phrase.d.ts +3 -0
  98. package/dist/phrase.d.ts.map +1 -0
  99. package/dist/phrase.js +8 -0
  100. package/dist/query.d.ts +36 -2
  101. package/dist/query.d.ts.map +1 -1
  102. package/dist/query.js +60 -6
  103. package/dist/reach.d.ts +17 -8
  104. package/dist/reach.d.ts.map +1 -1
  105. package/dist/reach.js +219 -90
  106. package/dist/react.d.ts +2 -2
  107. package/dist/react.d.ts.map +1 -1
  108. package/dist/react.js +2 -14
  109. package/dist/readiness.d.ts +14 -17
  110. package/dist/readiness.d.ts.map +1 -1
  111. package/dist/readiness.js +2 -8
  112. package/dist/recovery.d.ts +3 -2
  113. package/dist/recovery.d.ts.map +1 -1
  114. package/dist/recovery.js +34 -7
  115. package/dist/refresh.d.ts +18 -15
  116. package/dist/refresh.d.ts.map +1 -1
  117. package/dist/refresh.js +155 -58
  118. package/dist/replica.d.ts +56 -33
  119. package/dist/replica.d.ts.map +1 -1
  120. package/dist/replica.js +301 -191
  121. package/dist/room-draft.d.ts +23 -4
  122. package/dist/room-draft.d.ts.map +1 -1
  123. package/dist/room-draft.js +158 -71
  124. package/dist/rows.d.ts +39 -30
  125. package/dist/rows.d.ts.map +1 -1
  126. package/dist/rows.js +178 -96
  127. package/dist/save.d.ts +53 -14
  128. package/dist/save.d.ts.map +1 -1
  129. package/dist/save.js +529 -185
  130. package/dist/search.d.ts +12 -82
  131. package/dist/search.d.ts.map +1 -1
  132. package/dist/search.js +10 -207
  133. package/dist/seed.d.ts.map +1 -1
  134. package/dist/seed.js +18 -4
  135. package/dist/shared.d.ts +7 -3
  136. package/dist/shared.d.ts.map +1 -1
  137. package/dist/shared.js +119 -66
  138. package/dist/status.d.ts +4 -3
  139. package/dist/status.d.ts.map +1 -1
  140. package/dist/status.js +3 -1
  141. package/dist/store.d.ts +99 -97
  142. package/dist/store.d.ts.map +1 -1
  143. package/dist/store.js +336 -665
  144. package/dist/stored.d.ts +162 -0
  145. package/dist/stored.d.ts.map +1 -0
  146. package/dist/stored.js +549 -0
  147. package/dist/tables.d.ts +353 -0
  148. package/dist/tables.d.ts.map +1 -0
  149. package/dist/tables.js +585 -0
  150. package/dist/transfer.d.ts +0 -5
  151. package/dist/transfer.d.ts.map +1 -1
  152. package/dist/turn.d.ts +5 -3
  153. package/dist/turn.d.ts.map +1 -1
  154. package/dist/turn.js +51 -21
  155. package/dist/validation.d.ts +29 -0
  156. package/dist/validation.d.ts.map +1 -0
  157. package/dist/validation.js +104 -0
  158. package/dist/windows.d.ts +22 -0
  159. package/dist/windows.d.ts.map +1 -0
  160. package/dist/windows.js +89 -0
  161. package/dist/wire.d.ts +34 -5
  162. package/dist/wire.d.ts.map +1 -1
  163. package/dist/wire.js +10 -2
  164. package/package.json +18 -19
  165. package/AGENTS.md +0 -299
  166. package/dist/acquisition.d.ts +0 -14
  167. package/dist/acquisition.d.ts.map +0 -1
  168. package/dist/acquisition.js +0 -24
  169. package/dist/chat/acts.d.ts +0 -33
  170. package/dist/chat/acts.d.ts.map +0 -1
  171. package/dist/chat/acts.js +0 -36
  172. package/dist/chat/context.d.ts +0 -3
  173. package/dist/chat/context.d.ts.map +0 -1
  174. package/dist/chat/input.d.ts +0 -9
  175. package/dist/chat/input.d.ts.map +0 -1
  176. package/dist/chat/input.js +0 -99
  177. package/dist/chat/kit.d.ts +0 -61
  178. package/dist/chat/kit.d.ts.map +0 -1
  179. package/dist/chat/kit.js +0 -123
  180. package/dist/chat/lasting.d.ts +0 -6
  181. package/dist/chat/lasting.d.ts.map +0 -1
  182. package/dist/chat/lasting.js +0 -19
  183. package/dist/chat/list.d.ts +0 -27
  184. package/dist/chat/list.d.ts.map +0 -1
  185. package/dist/chat/list.js +0 -63
  186. package/dist/chat/markdown.d.ts +0 -20
  187. package/dist/chat/markdown.d.ts.map +0 -1
  188. package/dist/chat/markdown.js +0 -188
  189. package/dist/chat/message.d.ts +0 -6
  190. package/dist/chat/message.d.ts.map +0 -1
  191. package/dist/chat/message.js +0 -192
  192. package/dist/chat/messages.d.ts +0 -22
  193. package/dist/chat/messages.d.ts.map +0 -1
  194. package/dist/chat/messages.js +0 -155
  195. package/dist/chat/name.d.ts +0 -6
  196. package/dist/chat/name.d.ts.map +0 -1
  197. package/dist/chat/name.js +0 -37
  198. package/dist/chat/opened.d.ts +0 -11
  199. package/dist/chat/opened.d.ts.map +0 -1
  200. package/dist/chat/opened.js +0 -17
  201. package/dist/chat/overlay.d.ts +0 -31
  202. package/dist/chat/overlay.d.ts.map +0 -1
  203. package/dist/chat/overlay.js +0 -97
  204. package/dist/chat/parts.d.ts +0 -57
  205. package/dist/chat/parts.d.ts.map +0 -1
  206. package/dist/chat/parts.js +0 -119
  207. package/dist/chat/process.d.ts +0 -20
  208. package/dist/chat/process.d.ts.map +0 -1
  209. package/dist/chat/process.js +0 -32
  210. package/dist/chat/provider.d.ts +0 -63
  211. package/dist/chat/provider.d.ts.map +0 -1
  212. package/dist/chat/provider.js +0 -629
  213. package/dist/chat/question.d.ts +0 -9
  214. package/dist/chat/question.d.ts.map +0 -1
  215. package/dist/chat/question.js +0 -80
  216. package/dist/chat/questions.d.ts +0 -31
  217. package/dist/chat/questions.d.ts.map +0 -1
  218. package/dist/chat/questions.js +0 -111
  219. package/dist/chat/read.d.ts +0 -5
  220. package/dist/chat/read.d.ts.map +0 -1
  221. package/dist/chat/read.js +0 -13
  222. package/dist/chat/ready.d.ts +0 -34
  223. package/dist/chat/ready.d.ts.map +0 -1
  224. package/dist/chat/ready.js +0 -91
  225. package/dist/chat/style.d.ts +0 -4
  226. package/dist/chat/style.d.ts.map +0 -1
  227. package/dist/chat/style.js +0 -302
  228. package/dist/chat.d.ts +0 -14
  229. package/dist/chat.d.ts.map +0 -1
  230. package/dist/chat.js +0 -8
  231. package/dist/read-side.d.ts +0 -25
  232. package/dist/read-side.d.ts.map +0 -1
  233. package/dist/read-side.js +0 -642
  234. package/dist/reads.d.ts +0 -11
  235. package/dist/reads.d.ts.map +0 -1
  236. package/dist/reads.js +0 -98
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,135 @@ 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);
144
+ }
145
+ function deviceUnreached() {
146
+ return runtimeError('device-unreached', 'Only the panel cleans up 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');
135
154
  }
136
- export function narrowed(runtime, given, told) {
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) => {
174
+ const locked = (rooms ?? []).filter((room) => runtime.locked(room));
175
+ return locked.length === 0
176
+ ? null
177
+ : { pending: locked.map((room) => ({ room, awaits: 'unlock' })) };
178
+ };
179
+ const unlocked = (entries) => entries.filter((entry) => !runtime.locked(entry.room));
180
+ const intoLocked = (held) => held.some((move) => move?.room !== undefined && runtime.locked(move.room));
181
+ const within = (topic, input, deliver, fail) => {
154
182
  if (topic === 'rooms') {
155
- return following(() => watch(topic, input, (rooms) => deliver(roomsWithin(reach, rooms))));
183
+ return following(() => watch(topic, input, (rooms) => deliver(roomsWithin(reach, rooms)), fail));
156
184
  }
157
185
  if (topic === 'readiness') {
158
186
  return following(() => runtime.watchReadiness(port, reach, deliver));
159
187
  }
160
188
  if (topic === 'sync-status') {
161
- return following(() => watch(topic, input, (status) => deliver(statusWithin(reach, status))));
189
+ return following(() => watch(topic, input, (status) => {
190
+ const within = statusWithin(reach, status);
191
+ deliver({ ...within, attentionRequired: unlocked(within.attentionRequired) });
192
+ }, fail), true);
162
193
  }
163
194
  if (topic === 'room-drafts') {
164
- return following(() => watch(topic, input, (drafts) => deliver(draftsWithin(reach, drafts))));
195
+ return following(() => watch(topic, input, (drafts) => deliver(unlocked(draftsWithin(reach, drafts))), fail), true);
165
196
  }
166
197
  if (topic === 'queue') {
167
198
  const room = input[0];
168
199
  return following(() => {
169
- if (!holds(reach, room)) {
200
+ if (!holds(reach, room) || runtime.locked(room)) {
170
201
  deliver([]);
171
202
  return () => { };
172
203
  }
173
- return watch(topic, input, (entries) => deliver(queueWithin(reach, room, entries)));
174
- });
204
+ return watch(topic, input, (entries) => deliver(queueWithin(reach, room, entries)), fail);
205
+ }, true);
175
206
  }
176
207
  if (topic === 'query') {
177
208
  const plan = runtime.plan(input[0], reach);
178
209
  let held = null;
179
210
  return following(() => {
211
+ const locked = unlocking(plan.rooms);
212
+ if (locked !== null) {
213
+ const answer = { result: locked, keys: [] };
214
+ if (held === null || changeOf(held, answer) !== null)
215
+ deliver(answer);
216
+ held = digestOf(answer);
217
+ return () => { };
218
+ }
180
219
  let first = true;
181
- return runtime.watchPlan({ ...plan, reach: planReach(reach) }, (message) => {
220
+ let open = true;
221
+ const heard = (message) => {
182
222
  if (!first) {
183
- held = applied(held, message);
223
+ held = digestApplied(held, message);
184
224
  deliver(message);
185
225
  return;
186
226
  }
187
227
  first = false;
188
- if (held === null) {
189
- held = message;
190
- deliver(message);
191
- return;
192
- }
193
- const next = reconciled(held, message);
194
- if (next === null)
195
- return;
196
- held = next.keyed;
197
- deliver(next.message);
228
+ const change = held === null ? message : changeOf(held, message);
229
+ held = digestOf(message);
230
+ if (change !== null)
231
+ deliver(change);
232
+ };
233
+ const current = { ...plan, reach: planReach(reach), locked: runtime.lockedRooms() };
234
+ const stop = runtime.watchPlan(current, (message) => {
235
+ if (open)
236
+ heard(message);
237
+ }, (error) => {
238
+ if (open)
239
+ fail(error);
198
240
  });
199
- });
241
+ return () => {
242
+ open = false;
243
+ stop();
244
+ };
245
+ }, true);
200
246
  }
201
247
  if (topic === 'conversation') {
202
248
  return following(() => {
203
249
  if (conversing(reach))
204
- return watch(topic, input, deliver);
250
+ return watch(topic, input, deliver, fail);
205
251
  deliver(unheldView(input[0]));
206
252
  return () => { };
207
253
  });
@@ -209,66 +255,154 @@ export function narrowed(runtime, given, told) {
209
255
  if (topic === 'conversations' || topic === 'agents') {
210
256
  return following(() => {
211
257
  if (conversing(reach))
212
- return watch(topic, input, deliver);
258
+ return watch(topic, input, deliver, fail);
213
259
  deliver([]);
214
260
  return () => { };
215
261
  });
216
262
  }
217
- return watch(topic, input, deliver);
263
+ return watch(topic, input, deliver, fail);
218
264
  };
265
+ const files = new Map();
266
+ let handed = 0;
267
+ async function hand(reading) {
268
+ const answer = await reading;
269
+ if (answer.kind !== 'binary')
270
+ return answer;
271
+ handed += 1;
272
+ const file = String(handed);
273
+ files.set(file, answer.file);
274
+ return { ...answer, file };
275
+ }
219
276
  const conversation = () => (conversing(reach) ? md.conversation : NO_CONVERSATION);
220
277
  const chatDraft = () => (conversing(reach) ? md.chatDraft : NO_CHAT_DRAFT);
221
278
  const view = {
222
279
  ...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()),
280
+ rooms: () => md.rooms().then((rooms) => roomsWithin(reach, rooms)),
281
+ query: ((input) => {
282
+ const plan = runtime.plan(input, reach);
283
+ return Promise.resolve(unlocking(plan.rooms) ?? runtime.query({ ...plan, locked: runtime.lockedRooms() }));
284
+ }),
285
+ search: (input) => runtime.search(input, reach),
228
286
  types(room) {
287
+ if (holds(reach, room) && runtime.locked(room))
288
+ throw lockedError(room);
229
289
  if (wholly(reach, room))
230
290
  return md.types(room);
231
291
  if (!holds(reach, room))
232
292
  return structuredClone(UNHELD_TYPES);
233
- const listed = md.rooms().find(({ locator }) => locator === room);
234
- return typesWithin(reach, listed, md.types(room));
293
+ return typesWithin(reach, runtime.room(room), md.types(room));
235
294
  },
236
295
  async save(room, roomDrafts, writtenBy) {
237
296
  if (!holds(reach, room))
238
297
  throw unreached(room);
239
- const outside = roomDrafts.find(({ path }) => !covers(reach, room, path) ||
240
- !moves(reach, room, md.roomDraft.read(room, path)?.parts.move));
298
+ if (runtime.locked(room))
299
+ return { outcome: 'refused', code: ROOM_LOCKED, retryable: true };
300
+ const held = (await Promise.all(roomDrafts.map(({ path }) => md.roomDraft.read(room, path)))).map((draft) => draft?.parts.move);
301
+ const outside = roomDrafts.find(({ path }, at) => !covers(reach, room, path) || !moves(reach, room, held[at]));
241
302
  if (outside !== undefined) {
242
303
  return { outcome: 'refused', code: 'stale', retryable: false, file: outside.path };
243
304
  }
305
+ if (intoLocked(held))
306
+ return { outcome: 'refused', code: ROOM_LOCKED, retryable: true };
244
307
  return savedWithin(reach, room, await md.save(room, roomDrafts, writtenBy));
245
308
  },
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 })),
309
+ async saveParts(room, parts, writtenBy) {
310
+ if (!holds(reach, room))
311
+ throw unreached(room);
312
+ const filed = reach === null ? undefined : parts.find(({ parts: one }) => carriesFile(one));
313
+ if (filed !== undefined) {
314
+ return { outcome: 'refused', code: ATTACH_REQUIRED, retryable: false, file: filed.path };
315
+ }
316
+ if (runtime.locked(room))
317
+ return { outcome: 'refused', code: ROOM_LOCKED, retryable: true };
318
+ const held = parts.map(({ path, parts: one }) => readParts(one, path).move);
319
+ if (parts.some(({ path }, at) => !covers(reach, room, path) || !moves(reach, room, held[at]))) {
320
+ throw unreached(room);
321
+ }
322
+ if (intoLocked(held))
323
+ return { outcome: 'refused', code: ROOM_LOCKED, retryable: true };
324
+ return savedWithin(reach, room, await md.saveParts(room, parts, writtenBy));
325
+ },
326
+ resolve(room, path, destination) {
327
+ const at = runtime.located(room, path, destination);
328
+ return at !== null && !covers(reach, at.room, at.path)
329
+ ? Promise.resolve(UNREADABLE)
330
+ : md.resolve(room, path, destination);
331
+ },
332
+ history: (room, path, query) => !covers(reach, room, path)
333
+ ? Promise.resolve(failure({ kind: 'room-not-readable', locator: room }))
334
+ : runtime.locked(room)
335
+ ? Promise.resolve(lockedRoom(room))
336
+ : md.history(room, path, query),
249
337
  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)),
338
+ read: (room, path, revision) => !covers(reach, room, path)
339
+ ? Promise.resolve(failure({ kind: 'room-not-readable', locator: room }))
340
+ : runtime.locked(room)
341
+ ? Promise.resolve(lockedRoom(room))
342
+ : hand(md.binaryFile.read(room, path, revision)),
343
+ link: (room, path, revision) => !covers(reach, room, path)
344
+ ? Promise.resolve(failure({ kind: 'room-not-readable', locator: room }))
345
+ : runtime.locked(room)
346
+ ? Promise.resolve(lockedRoom(room))
347
+ : md.binaryFile.link(room, path, revision),
348
+ show: (room, path, revision) => !covers(reach, room, path)
349
+ ? Promise.resolve(failure({ kind: 'room-not-readable', locator: room }))
350
+ : runtime.locked(room)
351
+ ? Promise.resolve(lockedRoom(room))
352
+ : hand(md.binaryFile.show(room, path, revision)),
353
+ attach: (room, file) => !wholly(reach, room)
354
+ ? Promise.resolve(failure({ kind: 'room-not-readable', locator: room }))
355
+ : runtime.locked(room)
356
+ ? Promise.resolve(lockedRoom(room))
357
+ : md.binaryFile.attach(room, file),
358
+ async part(file, part) {
359
+ const key = files.get(file);
360
+ if (key === undefined)
361
+ return null;
362
+ const bytes = await md.binaryFile.part(key, part);
363
+ if (bytes === null)
364
+ files.delete(file);
365
+ return bytes;
366
+ },
256
367
  },
257
- reached: (room, roomVersion, path) => (path === undefined ? wholly(reach, room) : covers(reach, room, path)) &&
258
- md.reached(room, roomVersion, path),
368
+ reached: async (room, roomVersion, path) => (path === undefined ? wholly(reach, room) : covers(reach, room, path)) &&
369
+ !runtime.locked(room) &&
370
+ (await md.reached(room, roomVersion, path)),
259
371
  log: () => (reach === null ? md.log() : ''),
372
+ cleanUp: () => (reach === null ? md.cleanUp() : Promise.reject(deviceUnreached())),
260
373
  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)) {
265
- throw unreached(room);
374
+ list: () => md.roomDraft.list().then((drafts) => unlocked(draftsWithin(reach, drafts))),
375
+ async read(room, path) {
376
+ if (!covers(reach, room, path))
377
+ return null;
378
+ if (runtime.locked(room))
379
+ throw lockedError(room);
380
+ return shownDraft(reach, await md.roomDraft.read(room, path));
381
+ },
382
+ write(room, path, revision, parts, next) {
383
+ try {
384
+ if (reach !== null && carriesFile(parts))
385
+ throw attachRequired();
386
+ const move = readParts(parts, path).move;
387
+ if (!covers(reach, room, path) || !moves(reach, room, move))
388
+ throw unreached(room);
389
+ if (runtime.locked(room))
390
+ throw lockedError(room);
391
+ if (intoLocked([move]))
392
+ throw lockedError(move.room);
266
393
  }
267
- return writeWithin(reach, await md.roomDraft.write(room, path, revision, parts));
394
+ catch (error) {
395
+ return Promise.reject(error);
396
+ }
397
+ return md.roomDraft
398
+ .write(room, path, revision, parts, next)
399
+ .then((written) => writeWithin(reach, written));
268
400
  },
269
401
  async discard(room, path, revision) {
270
402
  if (!covers(reach, room, path))
271
403
  return staleWrite(null);
404
+ if (runtime.locked(room))
405
+ throw lockedError(room);
272
406
  return writeWithin(reach, await md.roomDraft.discard(room, path, revision));
273
407
  },
274
408
  },
@@ -280,11 +414,11 @@ export function narrowed(runtime, given, told) {
280
414
  answer: (id, answer) => conversation().answer(id, answer),
281
415
  interrupt: (id) => conversation().interrupt(id),
282
416
  kill: (id) => conversation().kill(id),
283
- cancel: (id, turn) => conversation().cancel(id, turn),
284
417
  delete: (id) => conversation().delete(id),
285
418
  },
286
419
  chatDraft: {
287
420
  write: (id, draft, revision) => chatDraft().write(id, draft, revision),
421
+ prepend: (id, draft) => chatDraft().prepend(id, draft),
288
422
  discard: (id) => chatDraft().discard(id),
289
423
  },
290
424
  observe: observing(within),
@@ -297,10 +431,5 @@ export function narrowed(runtime, given, told) {
297
431
  for (const restart of [...open])
298
432
  restart();
299
433
  },
300
- facts(next) {
301
- port = next;
302
- for (const restart of [...open])
303
- restart();
304
- },
305
434
  };
306
435
  }
package/dist/react.d.ts CHANGED
@@ -23,6 +23,7 @@ export declare function useObserve(client: Client, topic: 'storage-loss'): Obser
23
23
  export declare function useObserve(client: Client, topic: 'sync-status'): Observed<SyncStatus>;
24
24
  export declare function useObserve(client: Client, topic: 'service-mode'): Observed<ServiceMode>;
25
25
  export declare function useObserve(client: Client, topic: 'member'): Observed<Member | null>;
26
+ export declare function useObserve(client: Client, topic: 'authority-changes'): Observed<number>;
26
27
  export declare function useObserve(client: Client, topic: 'query', query: DocumentQuery): Observed<DocumentResult | PendingResult>;
27
28
  export declare function useObserve(client: Client, topic: 'query', query: GroupQuery): Observed<GroupResult | PendingResult>;
28
29
  export declare function useObserve(client: Client, topic: 'queue', locator: string): Observed<readonly QueueEntry[]>;
@@ -35,10 +36,9 @@ export type Saving = {
35
36
  readonly busy: boolean;
36
37
  readonly outcome: SaveResult | null;
37
38
  readonly failure: RuntimeError | null;
38
- save(room: string, roomDrafts: ReadonlyMap<string, RoomDraftParts>): Promise<SaveResult>;
39
+ save(room: string, parts: ReadonlyMap<string, RoomDraftParts>): Promise<SaveResult>;
39
40
  saveWritten(room: string, roomDrafts: readonly SavedRoomDraft[]): Promise<SaveResult>;
40
41
  };
41
- export declare function saveRoomDrafts(client: MdRuntimeClient, room: string, roomDrafts: ReadonlyMap<string, RoomDraftParts>): Promise<SaveResult>;
42
42
  export declare function useSave(client: MdRuntimeClient): Saving;
43
43
  export {};
44
44
  //# sourceMappingURL=react.d.ts.map
@@ -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":"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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,35 +1,33 @@
1
1
  import type { Open } from './open.js';
2
2
  export type CodeAvailability = Open<'stored' | 'absent'>;
3
- export type RoomPreparation = Open<'complete' | 'acquiring' | 'preparing' | 'indexing' | 'refused' | 'unadmitted'>;
3
+ export type RoomPreparation = Open<'complete' | 'acquiring' | 'preparing' | 'unadmitted'>;
4
4
  export type RoomCoverage = {
5
5
  readonly room: string;
6
6
  readonly state: RoomPreparation;
7
7
  };
8
- export type ConversationCoverage = Open<'complete' | 'acquiring' | 'indexing' | 'undeclared'>;
9
- export type SearchObligation = Open<'required' | 'unused'>;
8
+ export type ConversationCoverage = Open<'complete' | 'acquiring' | 'undeclared'>;
10
9
  export type TargetCoverage = {
11
10
  readonly complete: boolean;
12
11
  readonly listed: boolean;
13
12
  readonly rooms: readonly RoomCoverage[];
14
13
  readonly conversations: ConversationCoverage;
15
- readonly search: SearchObligation;
16
14
  };
17
15
  export type Persistence = Open<'granted' | 'denied' | 'unavailable'>;
18
16
  export type Durability = Open<'persistent' | 'best-effort'>;
19
17
  export type ConnectionAvailability = Open<'connected' | 'connecting' | 'unreachable'>;
20
18
  export type HouseOutcome = Open<'open' | 'write-halted' | 'refused'>;
21
- export type CapacityCause = {
22
- readonly cause: Open<'insufficient-space' | 'quota-exceeded'>;
23
- readonly needed: number | null;
24
- readonly available: number | null;
19
+ export type Space = Open<'full'>;
20
+ export type InstallationStep = Open<'downloading' | 'writing' | 'replaying'>;
21
+ export type InstallationAmount = {
22
+ readonly done: number;
23
+ readonly total: number;
25
24
  };
26
- export type RefusedRoom = {
27
- readonly room: string;
28
- readonly file: string;
29
- readonly rule: string;
30
- readonly location: string | null;
25
+ export type Installation = {
26
+ readonly step: InstallationStep | null;
27
+ readonly rooms: InstallationAmount;
28
+ readonly bytes: InstallationAmount;
31
29
  };
32
- export type ReadinessStatus = Open<'preparing' | 'paused' | 'refused' | 'ready' | 'lost'>;
30
+ export type ReadinessStatus = Open<'preparing' | 'paused' | 'ready' | 'lost'>;
33
31
  export type Readiness = {
34
32
  readonly status: ReadinessStatus;
35
33
  readonly ready: boolean;
@@ -40,14 +38,13 @@ export type Readiness = {
40
38
  readonly persistence: Persistence;
41
39
  readonly connection: ConnectionAvailability;
42
40
  readonly house: HouseOutcome;
43
- readonly capacity: CapacityCause | null;
44
- readonly refused: readonly RefusedRoom[];
41
+ readonly space: Space | null;
42
+ readonly installation: Installation;
45
43
  readonly lost: boolean;
46
44
  };
47
45
  export type ReadinessFacts = Omit<Readiness, 'status' | 'ready' | 'usable' | 'durability' | 'coverage'> & {
48
46
  readonly coverage: Omit<TargetCoverage, 'complete'>;
49
47
  readonly established: boolean;
50
48
  };
51
- export declare const SETTLED_ROOMS: ReadonlySet<string>;
52
49
  export declare function readinessOf(facts: ReadinessFacts): Readiness;
53
50
  //# sourceMappingURL=readiness.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"readiness.d.ts","sourceRoot":"","sources":["../src/readiness.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"readiness.d.ts","sourceRoot":"","sources":["../src/readiness.ts"],"names":[],"mappings":"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"}