@agentshouse/mdruntime 0.1.0-alpha.9 → 0.1.0-c0105dbd22806

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 (214) hide show
  1. package/AGENTS.md +299 -0
  2. package/README.md +54 -0
  3. package/dist/adapter.d.ts +246 -40
  4. package/dist/adapter.d.ts.map +1 -1
  5. package/dist/adapter.js +1 -10
  6. package/dist/attached-model.d.ts +11 -0
  7. package/dist/attached-model.d.ts.map +1 -0
  8. package/dist/attached-model.js +47 -0
  9. package/dist/attempt.d.ts +16 -0
  10. package/dist/attempt.d.ts.map +1 -0
  11. package/dist/attempt.js +70 -0
  12. package/dist/binary.d.ts +23 -0
  13. package/dist/binary.d.ts.map +1 -0
  14. package/dist/binary.js +8 -0
  15. package/dist/bootstrap.d.ts +17 -7
  16. package/dist/bootstrap.d.ts.map +1 -1
  17. package/dist/bootstrap.js +97 -41
  18. package/dist/change-set.d.ts +33 -0
  19. package/dist/change-set.d.ts.map +1 -0
  20. package/dist/change-set.js +90 -0
  21. package/dist/change.d.ts +24 -0
  22. package/dist/change.d.ts.map +1 -1
  23. package/dist/change.js +31 -5
  24. package/dist/chat/acts.d.ts +34 -0
  25. package/dist/chat/acts.d.ts.map +1 -0
  26. package/dist/chat/acts.js +36 -0
  27. package/dist/chat/context.d.ts +3 -0
  28. package/dist/chat/context.d.ts.map +1 -0
  29. package/dist/chat/context.js +10 -0
  30. package/dist/chat/input.d.ts +9 -0
  31. package/dist/chat/input.d.ts.map +1 -0
  32. package/dist/chat/input.js +99 -0
  33. package/dist/chat/kit.d.ts +60 -0
  34. package/dist/chat/kit.d.ts.map +1 -0
  35. package/dist/chat/kit.js +123 -0
  36. package/dist/chat/lasting.d.ts +6 -0
  37. package/dist/chat/lasting.d.ts.map +1 -0
  38. package/dist/chat/lasting.js +19 -0
  39. package/dist/chat/list.d.ts +26 -0
  40. package/dist/chat/list.d.ts.map +1 -0
  41. package/dist/chat/list.js +62 -0
  42. package/dist/chat/markdown.d.ts +20 -0
  43. package/dist/chat/markdown.d.ts.map +1 -0
  44. package/dist/chat/markdown.js +188 -0
  45. package/dist/chat/message.d.ts +6 -0
  46. package/dist/chat/message.d.ts.map +1 -0
  47. package/dist/chat/message.js +192 -0
  48. package/dist/chat/messages.d.ts +21 -0
  49. package/dist/chat/messages.d.ts.map +1 -0
  50. package/dist/chat/messages.js +151 -0
  51. package/dist/chat/name.d.ts +6 -0
  52. package/dist/chat/name.d.ts.map +1 -0
  53. package/dist/chat/name.js +37 -0
  54. package/dist/chat/opened.d.ts +11 -0
  55. package/dist/chat/opened.d.ts.map +1 -0
  56. package/dist/chat/opened.js +17 -0
  57. package/dist/chat/overlay.d.ts +31 -0
  58. package/dist/chat/overlay.d.ts.map +1 -0
  59. package/dist/chat/overlay.js +97 -0
  60. package/dist/chat/parts.d.ts +57 -0
  61. package/dist/chat/parts.d.ts.map +1 -0
  62. package/dist/chat/parts.js +119 -0
  63. package/dist/chat/process.d.ts +20 -0
  64. package/dist/chat/process.d.ts.map +1 -0
  65. package/dist/chat/process.js +32 -0
  66. package/dist/chat/provider.d.ts +63 -0
  67. package/dist/chat/provider.d.ts.map +1 -0
  68. package/dist/chat/provider.js +645 -0
  69. package/dist/chat/question.d.ts +9 -0
  70. package/dist/chat/question.d.ts.map +1 -0
  71. package/dist/chat/question.js +80 -0
  72. package/dist/chat/questions.d.ts +31 -0
  73. package/dist/chat/questions.d.ts.map +1 -0
  74. package/dist/chat/questions.js +111 -0
  75. package/dist/chat/read.d.ts +5 -0
  76. package/dist/chat/read.d.ts.map +1 -0
  77. package/dist/chat/read.js +13 -0
  78. package/dist/chat/ready.d.ts +33 -0
  79. package/dist/chat/ready.d.ts.map +1 -0
  80. package/dist/chat/ready.js +91 -0
  81. package/dist/chat/style.d.ts +4 -0
  82. package/dist/chat/style.d.ts.map +1 -0
  83. package/dist/chat/style.js +302 -0
  84. package/dist/chat.d.ts +14 -0
  85. package/dist/chat.d.ts.map +1 -0
  86. package/dist/chat.js +8 -0
  87. package/dist/client.d.ts +49 -33
  88. package/dist/client.d.ts.map +1 -1
  89. package/dist/client.js +164 -183
  90. package/dist/collection.d.ts +9 -17
  91. package/dist/collection.d.ts.map +1 -1
  92. package/dist/collection.js +83 -89
  93. package/dist/connection.d.ts +66 -48
  94. package/dist/connection.d.ts.map +1 -1
  95. package/dist/connection.js +1964 -1173
  96. package/dist/conversation.d.ts +65 -24
  97. package/dist/conversation.d.ts.map +1 -1
  98. package/dist/conversation.js +675 -334
  99. package/dist/durability.js +6 -6
  100. package/dist/entry.d.ts +17 -0
  101. package/dist/entry.d.ts.map +1 -0
  102. package/dist/entry.js +156 -0
  103. package/dist/expectation.d.ts +21 -0
  104. package/dist/expectation.d.ts.map +1 -0
  105. package/dist/expectation.js +70 -0
  106. package/dist/failure.d.ts +13 -0
  107. package/dist/failure.d.ts.map +1 -0
  108. package/dist/failure.js +19 -0
  109. package/dist/fence.d.ts +6 -0
  110. package/dist/fence.d.ts.map +1 -0
  111. package/dist/fence.js +10 -0
  112. package/dist/file.d.ts +2 -2
  113. package/dist/file.d.ts.map +1 -1
  114. package/dist/file.js +48 -71
  115. package/dist/host.d.ts +15 -3
  116. package/dist/host.d.ts.map +1 -1
  117. package/dist/host.js +109 -127
  118. package/dist/identity.d.ts +4 -0
  119. package/dist/identity.d.ts.map +1 -1
  120. package/dist/identity.js +22 -9
  121. package/dist/index.d.ts +17 -11
  122. package/dist/index.d.ts.map +1 -1
  123. package/dist/index.js +4 -3
  124. package/dist/log.js +5 -6
  125. package/dist/memory.d.ts +19 -8
  126. package/dist/memory.d.ts.map +1 -1
  127. package/dist/memory.js +304 -216
  128. package/dist/model.d.ts +16 -30
  129. package/dist/model.d.ts.map +1 -1
  130. package/dist/model.js +21 -21
  131. package/dist/observation.d.ts +27 -0
  132. package/dist/observation.d.ts.map +1 -0
  133. package/dist/observation.js +95 -0
  134. package/dist/open.d.ts +2 -0
  135. package/dist/open.d.ts.map +1 -0
  136. package/dist/open.js +1 -0
  137. package/dist/outcome.d.ts +37 -31
  138. package/dist/outcome.d.ts.map +1 -1
  139. package/dist/outcome.js +36 -18
  140. package/dist/overlay.d.ts +22 -4
  141. package/dist/overlay.d.ts.map +1 -1
  142. package/dist/overlay.js +236 -54
  143. package/dist/paths.d.ts +0 -2
  144. package/dist/paths.d.ts.map +1 -1
  145. package/dist/paths.js +6 -29
  146. package/dist/query.d.ts +219 -10
  147. package/dist/query.d.ts.map +1 -1
  148. package/dist/query.js +462 -15
  149. package/dist/reach.d.ts +42 -0
  150. package/dist/reach.d.ts.map +1 -0
  151. package/dist/reach.js +294 -0
  152. package/dist/react.d.ts +41 -0
  153. package/dist/react.d.ts.map +1 -0
  154. package/dist/react.js +64 -0
  155. package/dist/read-side.d.ts +18 -0
  156. package/dist/read-side.d.ts.map +1 -0
  157. package/dist/read-side.js +440 -0
  158. package/dist/refresh.d.ts +15 -5
  159. package/dist/refresh.d.ts.map +1 -1
  160. package/dist/refresh.js +64 -41
  161. package/dist/replica.d.ts +28 -5
  162. package/dist/replica.d.ts.map +1 -1
  163. package/dist/replica.js +249 -40
  164. package/dist/room-draft.d.ts +144 -0
  165. package/dist/room-draft.d.ts.map +1 -0
  166. package/dist/room-draft.js +438 -0
  167. package/dist/rows.d.ts +46 -0
  168. package/dist/rows.d.ts.map +1 -0
  169. package/dist/rows.js +145 -0
  170. package/dist/save.d.ts +33 -5
  171. package/dist/save.d.ts.map +1 -1
  172. package/dist/save.js +630 -366
  173. package/dist/search.d.ts +62 -0
  174. package/dist/search.d.ts.map +1 -0
  175. package/dist/search.js +125 -0
  176. package/dist/status.d.ts +6 -8
  177. package/dist/status.d.ts.map +1 -1
  178. package/dist/status.js +8 -20
  179. package/dist/store.d.ts +89 -34
  180. package/dist/store.d.ts.map +1 -1
  181. package/dist/store.js +513 -132
  182. package/dist/transfer.d.ts +5 -0
  183. package/dist/transfer.d.ts.map +1 -1
  184. package/dist/transfer.js +1 -5
  185. package/dist/wire.d.ts +59 -19
  186. package/dist/wire.d.ts.map +1 -1
  187. package/dist/wire.js +88 -105
  188. package/package.json +34 -16
  189. package/dist/adapter.js.map +0 -1
  190. package/dist/bootstrap.js.map +0 -1
  191. package/dist/change.js.map +0 -1
  192. package/dist/client.js.map +0 -1
  193. package/dist/collection.js.map +0 -1
  194. package/dist/connection.js.map +0 -1
  195. package/dist/conversation.js.map +0 -1
  196. package/dist/durability.js.map +0 -1
  197. package/dist/file.js.map +0 -1
  198. package/dist/host.js.map +0 -1
  199. package/dist/identity.js.map +0 -1
  200. package/dist/index.js.map +0 -1
  201. package/dist/log.js.map +0 -1
  202. package/dist/memory.js.map +0 -1
  203. package/dist/model.js.map +0 -1
  204. package/dist/outcome.js.map +0 -1
  205. package/dist/overlay.js.map +0 -1
  206. package/dist/paths.js.map +0 -1
  207. package/dist/query.js.map +0 -1
  208. package/dist/refresh.js.map +0 -1
  209. package/dist/replica.js.map +0 -1
  210. package/dist/save.js.map +0 -1
  211. package/dist/status.js.map +0 -1
  212. package/dist/store.js.map +0 -1
  213. package/dist/transfer.js.map +0 -1
  214. package/dist/wire.js.map +0 -1
package/dist/reach.js ADDED
@@ -0,0 +1,294 @@
1
+ import { unheldView } from './conversation.js';
2
+ import { modelTypes, NO_MODEL } from './model.js';
3
+ import { applied, observing } from './observation.js';
4
+ import { runtimeError } from './failure.js';
5
+ import { failure, undeclared, } from './outcome.js';
6
+ import { beneath } from './paths.js';
7
+ import { reconciled } from './read-side.js';
8
+ import { moveTarget, readParts, staleWrite, } from './room-draft.js';
9
+ import { documentKey } from './rows.js';
10
+ const UNHELD_TYPES = { collection: modelTypes(NO_MODEL), typedSelection: null };
11
+ function unconversed(name) {
12
+ return () => Promise.resolve(undeclared(name));
13
+ }
14
+ const NO_CONVERSATION = {
15
+ list: () => Promise.resolve([]),
16
+ read: (conversation) => Promise.resolve(unheldView(conversation)),
17
+ create: unconversed('conversation.create'),
18
+ send: unconversed('conversation.send'),
19
+ answer: unconversed('conversation.answer'),
20
+ interrupt: unconversed('conversation.interrupt'),
21
+ kill: unconversed('conversation.kill'),
22
+ cancel: unconversed('conversation.cancel'),
23
+ delete: unconversed('conversation.delete'),
24
+ };
25
+ const NO_CHAT_DRAFT = {
26
+ write: () => Promise.resolve(),
27
+ discard: () => Promise.resolve(),
28
+ };
29
+ export function holds(reach, room) {
30
+ return (reach === null ||
31
+ reach.rooms.includes(room) ||
32
+ reach.documents.some((document) => document.room === room));
33
+ }
34
+ function wholly(reach, room) {
35
+ return reach === null || reach.rooms.includes(room);
36
+ }
37
+ export function governs(reach, room) {
38
+ if (wholly(reach, room.locator)) {
39
+ return { collection: true, selection: room.typedSelection !== null };
40
+ }
41
+ const selected = (path) => room.typedSelection?.roots.some((root) => beneath(root, path)) ?? false;
42
+ const paths = reach.documents
43
+ .filter((document) => document.room === room.locator)
44
+ .map(({ path }) => path);
45
+ return { collection: paths.some((path) => !selected(path)), selection: paths.some(selected) };
46
+ }
47
+ function covers(reach, room, path) {
48
+ return (reach === null ||
49
+ reach.rooms.includes(room) ||
50
+ reach.documents.some((document) => document.room === room && document.path === path));
51
+ }
52
+ function conversing(reach) {
53
+ return reach === null || reach.conversations;
54
+ }
55
+ function refers(reach, scope) {
56
+ if (reach === null)
57
+ return true;
58
+ if (scope === null)
59
+ return false;
60
+ if (scope.kind === 'conversations')
61
+ return reach.conversations;
62
+ return scope.path === undefined
63
+ ? wholly(reach, scope.locator)
64
+ : covers(reach, scope.locator, scope.path);
65
+ }
66
+ function unreachedReference(fileRef) {
67
+ return { kind: 'absent', code: 'binary-file-absent', fields: { fileRef }, retryable: false };
68
+ }
69
+ export function planReach(reach) {
70
+ return reach === null
71
+ ? null
72
+ : {
73
+ rooms: [...new Set(reach.rooms)].sort(),
74
+ documents: [
75
+ ...new Set(reach.documents.map(({ room, path }) => documentKey(room, path))),
76
+ ].sort(),
77
+ };
78
+ }
79
+ function roomsWithin(reach, rooms) {
80
+ return rooms.filter((room) => wholly(reach, room.locator));
81
+ }
82
+ function typesWithin(reach, room, types) {
83
+ if (room === undefined)
84
+ return structuredClone(UNHELD_TYPES);
85
+ const governed = governs(reach, room);
86
+ return {
87
+ collection: governed.collection ? types.collection : modelTypes(NO_MODEL),
88
+ typedSelection: governed.selection ? types.typedSelection : null,
89
+ };
90
+ }
91
+ function moves(reach, room, move) {
92
+ return move === undefined || covers(reach, room, moveTarget(move));
93
+ }
94
+ function draftWithin(reach, draft) {
95
+ return covers(reach, draft.room, draft.path) && moves(reach, draft.room, draft.parts.move);
96
+ }
97
+ function draftsWithin(reach, drafts) {
98
+ return drafts.filter((draft) => draftWithin(reach, draft));
99
+ }
100
+ function shownDraft(reach, draft) {
101
+ return draft !== null && draftWithin(reach, draft) ? draft : null;
102
+ }
103
+ function writeWithin(reach, write) {
104
+ return write.outcome === 'written'
105
+ ? { outcome: 'written', roomDraft: shownDraft(reach, write.roomDraft) }
106
+ : staleWrite(shownDraft(reach, write.current));
107
+ }
108
+ function savedWithin(reach, room, result) {
109
+ if (reach === null || result.outcome === 'saved')
110
+ return result;
111
+ const { file, location, referrers, ...refusal } = result;
112
+ const hidden = file !== undefined && !covers(reach, room, file);
113
+ return {
114
+ ...refusal,
115
+ ...(file === undefined || hidden ? {} : { file }),
116
+ ...(location === undefined || hidden ? {} : { location }),
117
+ ...(referrers === undefined
118
+ ? {}
119
+ : { referrers: referrers.filter((path) => covers(reach, room, path)) }),
120
+ };
121
+ }
122
+ function statusWithin(reach, status) {
123
+ return {
124
+ ...status,
125
+ attentionRequired: status.attentionRequired.filter((entry) => covers(reach, entry.room, entry.path)),
126
+ };
127
+ }
128
+ function queueWithin(reach, room, entries) {
129
+ return entries.filter(({ batch }) => batch.changes.every((change) => covers(reach, room, change.path) &&
130
+ (change.kind !== 'move' || covers(reach, room, change.to))));
131
+ }
132
+ function unreached(room) {
133
+ return runtimeError('room-not-held', `No Local Replica for ${room}`);
134
+ }
135
+ export function narrowed(runtime, given) {
136
+ const { md, watch } = runtime;
137
+ let reach = given;
138
+ const open = new Set();
139
+ function following(begin) {
140
+ let stop = begin();
141
+ const restart = () => {
142
+ stop();
143
+ stop = begin();
144
+ };
145
+ open.add(restart);
146
+ return () => {
147
+ open.delete(restart);
148
+ stop();
149
+ };
150
+ }
151
+ const within = (topic, input, deliver) => {
152
+ if (topic === 'rooms') {
153
+ return following(() => watch(topic, input, (rooms) => deliver(roomsWithin(reach, rooms))));
154
+ }
155
+ if (topic === 'sync-status') {
156
+ return following(() => watch(topic, input, (status) => deliver(statusWithin(reach, status))));
157
+ }
158
+ if (topic === 'room-drafts') {
159
+ return following(() => watch(topic, input, (drafts) => deliver(draftsWithin(reach, drafts))));
160
+ }
161
+ if (topic === 'queue') {
162
+ const room = input[0];
163
+ return following(() => {
164
+ if (!holds(reach, room)) {
165
+ deliver([]);
166
+ return () => { };
167
+ }
168
+ return watch(topic, input, (entries) => deliver(queueWithin(reach, room, entries)));
169
+ });
170
+ }
171
+ if (topic === 'query') {
172
+ const plan = runtime.plan(input[0], reach);
173
+ let held = null;
174
+ return following(() => {
175
+ let first = true;
176
+ return runtime.watchPlan({ ...plan, reach: planReach(reach) }, (message) => {
177
+ if (!first) {
178
+ held = applied(held, message);
179
+ deliver(message);
180
+ return;
181
+ }
182
+ first = false;
183
+ if (held === null) {
184
+ held = message;
185
+ deliver(message);
186
+ return;
187
+ }
188
+ const next = reconciled(held, message);
189
+ if (next === null)
190
+ return;
191
+ held = next.keyed;
192
+ deliver(next.change);
193
+ });
194
+ });
195
+ }
196
+ if (topic === 'conversation') {
197
+ return following(() => {
198
+ if (conversing(reach))
199
+ return watch(topic, input, deliver);
200
+ deliver(unheldView(input[0]));
201
+ return () => { };
202
+ });
203
+ }
204
+ if (topic === 'conversations' || topic === 'agents') {
205
+ return following(() => {
206
+ if (conversing(reach))
207
+ return watch(topic, input, deliver);
208
+ deliver([]);
209
+ return () => { };
210
+ });
211
+ }
212
+ return watch(topic, input, deliver);
213
+ };
214
+ const conversation = () => (conversing(reach) ? md.conversation : NO_CONVERSATION);
215
+ const chatDraft = () => (conversing(reach) ? md.chatDraft : NO_CHAT_DRAFT);
216
+ const view = {
217
+ ...md,
218
+ rooms: () => roomsWithin(reach, md.rooms()),
219
+ query: ((input) => runtime.query(runtime.plan(input, reach))),
220
+ search: (input) => runtime.search(input, reach),
221
+ types(room) {
222
+ if (wholly(reach, room))
223
+ return md.types(room);
224
+ if (!holds(reach, room))
225
+ return structuredClone(UNHELD_TYPES);
226
+ const listed = md.rooms().find(({ locator }) => locator === room);
227
+ return typesWithin(reach, listed, md.types(room));
228
+ },
229
+ async save(room, roomDrafts, writtenBy) {
230
+ if (!holds(reach, room))
231
+ throw unreached(room);
232
+ const outside = roomDrafts.find(({ path }) => !covers(reach, room, path) ||
233
+ !moves(reach, room, md.roomDraft.read(room, path)?.parts.move));
234
+ if (outside !== undefined) {
235
+ return { outcome: 'refused', code: 'stale', retryable: false, file: outside.path };
236
+ }
237
+ return savedWithin(reach, room, await md.save(room, roomDrafts, writtenBy));
238
+ },
239
+ history: (room, path, query) => covers(reach, room, path)
240
+ ? md.history(room, path, query)
241
+ : Promise.resolve(failure({ kind: 'room-not-readable', locator: room })),
242
+ binaryFile: {
243
+ read: (room, path, revision) => covers(reach, room, path)
244
+ ? md.binaryFile.read(room, path, revision)
245
+ : Promise.resolve(failure({ kind: 'room-not-readable', locator: room })),
246
+ readReference: (reference) => refers(reach, runtime.referrerScope(reference.referrer))
247
+ ? md.binaryFile.readReference(reference)
248
+ : Promise.resolve(unreachedReference(reference.fileRef)),
249
+ },
250
+ reached: (room, roomVersion, path) => (path === undefined ? wholly(reach, room) : covers(reach, room, path)) &&
251
+ md.reached(room, roomVersion, path),
252
+ log: () => (reach === null ? md.log() : ''),
253
+ roomDraft: {
254
+ list: () => md.roomDraft.list().then((drafts) => draftsWithin(reach, drafts)),
255
+ read: (room, path) => covers(reach, room, path) ? shownDraft(reach, md.roomDraft.read(room, path)) : null,
256
+ async write(room, path, revision, parts) {
257
+ if (!covers(reach, room, path) || !moves(reach, room, readParts(parts).move)) {
258
+ throw unreached(room);
259
+ }
260
+ return writeWithin(reach, await md.roomDraft.write(room, path, revision, parts));
261
+ },
262
+ async discard(room, path, revision) {
263
+ if (!covers(reach, room, path))
264
+ return staleWrite(null);
265
+ return writeWithin(reach, await md.roomDraft.discard(room, path, revision));
266
+ },
267
+ },
268
+ conversation: {
269
+ list: () => conversation().list(),
270
+ read: (id, options) => conversation().read(id, options),
271
+ create: (input) => conversation().create(input),
272
+ send: (id) => conversation().send(id),
273
+ answer: (id, answer) => conversation().answer(id, answer),
274
+ interrupt: (id) => conversation().interrupt(id),
275
+ kill: (id) => conversation().kill(id),
276
+ cancel: (id, turn) => conversation().cancel(id, turn),
277
+ delete: (id) => conversation().delete(id),
278
+ },
279
+ chatDraft: {
280
+ write: (id, draft, revision) => chatDraft().write(id, draft, revision),
281
+ discard: (id) => chatDraft().discard(id),
282
+ },
283
+ observe: observing(within),
284
+ };
285
+ return {
286
+ md: view,
287
+ watch: within,
288
+ narrow(next) {
289
+ reach = next;
290
+ for (const restart of [...open])
291
+ restart();
292
+ },
293
+ };
294
+ }
@@ -0,0 +1,41 @@
1
+ import type { MdRuntimeClient } from './client.js';
2
+ import type { AppRoom, ConnectionRefusal, SaveResult } from './connection.js';
3
+ import type { Member, ServiceMode } from './adapter.js';
4
+ import type { ConversationAgent, ConversationEntry, ConversationOptions, ConversationView } from './conversation.js';
5
+ import { type RuntimeError } from './failure.js';
6
+ import type { QueueEntry } from './outcome.js';
7
+ import type { DocumentQuery, DocumentResult, GroupQuery, GroupResult } from './query.js';
8
+ import type { RoomDraft, RoomDraftParts } from './room-draft.js';
9
+ import type { SyncStatus } from './status.js';
10
+ type Client = MdRuntimeClient | null;
11
+ export type Observed<T> = {
12
+ readonly state: 'loading';
13
+ } | {
14
+ readonly state: 'ready';
15
+ readonly value: T;
16
+ };
17
+ export declare function useObserve(client: Client, topic: 'deployment-facts'): Observed<unknown>;
18
+ export declare function useObserve(client: Client, topic: 'rooms'): Observed<readonly AppRoom[]>;
19
+ export declare function useObserve(client: Client, topic: 'connection-refusal'): Observed<ConnectionRefusal | null>;
20
+ export declare function useObserve(client: Client, topic: 'storage-loss'): Observed<string | null>;
21
+ export declare function useObserve(client: Client, topic: 'sync-status'): Observed<SyncStatus>;
22
+ export declare function useObserve(client: Client, topic: 'service-mode'): Observed<ServiceMode>;
23
+ export declare function useObserve(client: Client, topic: 'member'): Observed<Member | null>;
24
+ export declare function useObserve(client: Client, topic: 'query', query: DocumentQuery): Observed<DocumentResult>;
25
+ export declare function useObserve(client: Client, topic: 'query', query: GroupQuery): Observed<GroupResult>;
26
+ export declare function useObserve(client: Client, topic: 'queue', locator: string): Observed<readonly QueueEntry[]>;
27
+ export declare function useObserve(client: Client, topic: 'room-drafts'): Observed<readonly RoomDraft[]>;
28
+ export declare function useObserve(client: Client, topic: 'presentation'): Observed<unknown>;
29
+ export declare function useObserve(client: Client, topic: 'conversation', conversation: string, options: ConversationOptions): Observed<ConversationView>;
30
+ export declare function useObserve(client: Client, topic: 'conversations'): Observed<readonly ConversationEntry[]>;
31
+ export declare function useObserve(client: Client, topic: 'agents'): Observed<readonly ConversationAgent[]>;
32
+ export type Saving = {
33
+ readonly busy: boolean;
34
+ readonly outcome: SaveResult | null;
35
+ readonly failure: RuntimeError | null;
36
+ save(room: string, roomDrafts: ReadonlyMap<string, RoomDraftParts>): Promise<SaveResult>;
37
+ };
38
+ export declare function saveRoomDrafts(client: MdRuntimeClient, room: string, roomDrafts: ReadonlyMap<string, RoomDraftParts>): Promise<SaveResult>;
39
+ export declare function useSave(client: MdRuntimeClient): Saving;
40
+ export {};
41
+ //# sourceMappingURL=react.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../src/react.ts"],"names":[],"mappings":"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"}
package/dist/react.js ADDED
@@ -0,0 +1,64 @@
1
+ import { useCallback, useLayoutEffect, useRef, useState } from 'react';
2
+ import { failed, runtimeError } from './failure.js';
3
+ const LOADING = { state: 'loading' };
4
+ export function useObserve(client, topic, ...input) {
5
+ const key = JSON.stringify([topic, ...input]);
6
+ const [held, setHeld] = useState(null);
7
+ const opened = useRef(input);
8
+ opened.current = input;
9
+ useLayoutEffect(() => {
10
+ if (client === null)
11
+ return;
12
+ let live = true;
13
+ let observation = null;
14
+ const observe = client.observe;
15
+ void observe(topic, ...opened.current).then((open) => {
16
+ if (!live) {
17
+ open.close();
18
+ return;
19
+ }
20
+ observation = open;
21
+ const take = (value) => {
22
+ if (live)
23
+ setHeld({ client, key, observed: { state: 'ready', value } });
24
+ };
25
+ take(open.current());
26
+ open.subscribe(take);
27
+ });
28
+ return () => {
29
+ live = false;
30
+ observation?.close();
31
+ };
32
+ }, [client, key]);
33
+ return held !== null && held.client === client && held.key === key ? held.observed : LOADING;
34
+ }
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
+ export function useSave(client) {
49
+ const [state, setState] = useState(IDLE);
50
+ const save = useCallback(async (room, roomDrafts) => {
51
+ setState({ busy: true, outcome: null, failure: null });
52
+ try {
53
+ const outcome = await saveRoomDrafts(client, room, roomDrafts);
54
+ setState({ busy: false, outcome, failure: null });
55
+ return outcome;
56
+ }
57
+ catch (error) {
58
+ const failure = failed(error);
59
+ setState({ busy: false, outcome: null, failure });
60
+ throw failure;
61
+ }
62
+ }, [client]);
63
+ return { ...state, save };
64
+ }
@@ -0,0 +1,18 @@
1
+ import type { ChangeSet } from './change-set.js';
2
+ import { type KeyedResult, type QueryChange } from './observation.js';
3
+ import type { Plan, QueryResult } from './query.js';
4
+ import type { SearchedDocument } from './search.js';
5
+ export type ReadSide = {
6
+ apply(set: ChangeSet): void;
7
+ query(plan: Plan): Promise<QueryResult>;
8
+ watch(plan: Plan, identity: string, deliver: (message: KeyedResult | QueryChange) => void): () => void;
9
+ documents(): readonly SearchedDocument[];
10
+ document(room: string, path: string): SearchedDocument | null;
11
+ close(): void;
12
+ };
13
+ export declare function reconciled(previous: KeyedResult, next: KeyedResult): {
14
+ keyed: KeyedResult;
15
+ change: QueryChange;
16
+ } | null;
17
+ export declare function createReadSide(): ReadSide;
18
+ //# sourceMappingURL=read-side.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read-side.d.ts","sourceRoot":"","sources":["../src/read-side.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAU,KAAK,WAAW,EAAE,KAAK,WAAW,EAAe,MAAM,kBAAkB,CAAC;AAC3F,OAAO,KAAK,EAOV,IAAI,EAIJ,WAAW,EAIZ,MAAM,YAAY,CAAC;AAEpB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAuDpD,MAAM,MAAM,QAAQ,GAAG;IACrB,KAAK,CAAC,GAAG,EAAE,SAAS,GAAG,IAAI,CAAC;IAC5B,KAAK,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IACxC,KAAK,CACH,IAAI,EAAE,IAAI,EACV,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,CAAC,OAAO,EAAE,WAAW,GAAG,WAAW,KAAK,IAAI,GACpD,MAAM,IAAI,CAAC;IACd,SAAS,IAAI,SAAS,gBAAgB,EAAE,CAAC;IACzC,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAAC;IAC9D,KAAK,IAAI,IAAI,CAAC;CACf,CAAC;AAuVF,wBAAgB,UAAU,CACxB,QAAQ,EAAE,WAAW,EACrB,IAAI,EAAE,WAAW,GAChB;IAAE,KAAK,EAAE,WAAW,CAAC;IAAC,MAAM,EAAE,WAAW,CAAA;CAAE,GAAG,IAAI,CA4BpD;AAED,wBAAgB,cAAc,IAAI,QAAQ,CA4HzC"}