@agentshouse/mdruntime 0.1.0-ce531b51ff088 → 0.1.0-ceb97106cc2fd
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.
- package/AGENTS.md +273 -175
- package/README.md +21 -11
- package/dist/acquisition.d.ts +14 -0
- package/dist/acquisition.d.ts.map +1 -0
- package/dist/acquisition.js +24 -0
- package/dist/adapter.d.ts +129 -41
- package/dist/adapter.d.ts.map +1 -1
- package/dist/adapter.js +1 -9
- package/dist/attached-model.d.ts +11 -0
- package/dist/attached-model.d.ts.map +1 -0
- package/dist/attached-model.js +47 -0
- package/dist/attempt.d.ts +16 -0
- package/dist/attempt.d.ts.map +1 -0
- package/dist/attempt.js +70 -0
- package/dist/binary.d.ts +23 -0
- package/dist/binary.d.ts.map +1 -0
- package/dist/binary.js +8 -0
- package/dist/bootstrap.d.ts +20 -6
- package/dist/bootstrap.d.ts.map +1 -1
- package/dist/bootstrap.js +114 -37
- package/dist/change-set.d.ts +2 -0
- package/dist/change-set.d.ts.map +1 -1
- package/dist/change-set.js +49 -16
- package/dist/change.d.ts +15 -0
- package/dist/change.d.ts.map +1 -1
- package/dist/change.js +26 -1
- package/dist/chat/acts.d.ts +33 -0
- package/dist/chat/acts.d.ts.map +1 -0
- package/dist/chat/acts.js +36 -0
- package/dist/chat/context.d.ts +3 -0
- package/dist/chat/context.d.ts.map +1 -0
- package/dist/chat/context.js +10 -0
- package/dist/chat/input.d.ts +9 -0
- package/dist/chat/input.d.ts.map +1 -0
- package/dist/chat/input.js +99 -0
- package/dist/chat/kit.d.ts +61 -0
- package/dist/chat/kit.d.ts.map +1 -0
- package/dist/chat/kit.js +123 -0
- package/dist/chat/lasting.d.ts +6 -0
- package/dist/chat/lasting.d.ts.map +1 -0
- package/dist/chat/lasting.js +19 -0
- package/dist/chat/list.d.ts +27 -0
- package/dist/chat/list.d.ts.map +1 -0
- package/dist/chat/list.js +63 -0
- package/dist/chat/markdown.d.ts +20 -0
- package/dist/chat/markdown.d.ts.map +1 -0
- package/dist/chat/markdown.js +188 -0
- package/dist/chat/message.d.ts +6 -0
- package/dist/chat/message.d.ts.map +1 -0
- package/dist/chat/message.js +192 -0
- package/dist/chat/messages.d.ts +22 -0
- package/dist/chat/messages.d.ts.map +1 -0
- package/dist/chat/messages.js +155 -0
- package/dist/chat/name.d.ts +6 -0
- package/dist/chat/name.d.ts.map +1 -0
- package/dist/chat/name.js +37 -0
- package/dist/chat/opened.d.ts +11 -0
- package/dist/chat/opened.d.ts.map +1 -0
- package/dist/chat/opened.js +17 -0
- package/dist/chat/overlay.d.ts +31 -0
- package/dist/chat/overlay.d.ts.map +1 -0
- package/dist/chat/overlay.js +97 -0
- package/dist/chat/parts.d.ts +57 -0
- package/dist/chat/parts.d.ts.map +1 -0
- package/dist/chat/parts.js +119 -0
- package/dist/chat/process.d.ts +20 -0
- package/dist/chat/process.d.ts.map +1 -0
- package/dist/chat/process.js +32 -0
- package/dist/chat/provider.d.ts +63 -0
- package/dist/chat/provider.d.ts.map +1 -0
- package/dist/chat/provider.js +629 -0
- package/dist/chat/question.d.ts +9 -0
- package/dist/chat/question.d.ts.map +1 -0
- package/dist/chat/question.js +80 -0
- package/dist/chat/questions.d.ts +31 -0
- package/dist/chat/questions.d.ts.map +1 -0
- package/dist/chat/questions.js +111 -0
- package/dist/chat/read.d.ts +5 -0
- package/dist/chat/read.d.ts.map +1 -0
- package/dist/chat/read.js +13 -0
- package/dist/chat/ready.d.ts +34 -0
- package/dist/chat/ready.d.ts.map +1 -0
- package/dist/chat/ready.js +91 -0
- package/dist/chat/style.d.ts +4 -0
- package/dist/chat/style.d.ts.map +1 -0
- package/dist/chat/style.js +302 -0
- package/dist/chat.d.ts +14 -0
- package/dist/chat.d.ts.map +1 -0
- package/dist/chat.js +8 -0
- package/dist/client.d.ts +28 -14
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +71 -26
- package/dist/collection.d.ts +21 -12
- package/dist/collection.d.ts.map +1 -1
- package/dist/collection.js +271 -23
- package/dist/connection.d.ts +50 -23
- package/dist/connection.d.ts.map +1 -1
- package/dist/connection.js +2074 -735
- package/dist/conversation.d.ts +41 -14
- package/dist/conversation.d.ts.map +1 -1
- package/dist/conversation.js +546 -214
- package/dist/durability.d.ts +7 -1
- package/dist/durability.d.ts.map +1 -1
- package/dist/entry.d.ts +17 -0
- package/dist/entry.d.ts.map +1 -0
- package/dist/entry.js +156 -0
- package/dist/expectation.d.ts +21 -0
- package/dist/expectation.d.ts.map +1 -0
- package/dist/expectation.js +70 -0
- package/dist/failure.d.ts +13 -0
- package/dist/failure.d.ts.map +1 -0
- package/dist/failure.js +19 -0
- package/dist/fence.d.ts +6 -0
- package/dist/fence.d.ts.map +1 -0
- package/dist/fence.js +10 -0
- package/dist/host.d.ts +24 -2
- package/dist/host.d.ts.map +1 -1
- package/dist/host.js +126 -45
- package/dist/identity.d.ts +5 -0
- package/dist/identity.d.ts.map +1 -1
- package/dist/identity.js +19 -1
- package/dist/index.d.ts +16 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -0
- package/dist/memory.d.ts +17 -7
- package/dist/memory.d.ts.map +1 -1
- package/dist/memory.js +159 -46
- package/dist/model.d.ts +17 -14
- package/dist/model.d.ts.map +1 -1
- package/dist/model.js +16 -4
- package/dist/observation.d.ts +6 -1
- package/dist/observation.d.ts.map +1 -1
- package/dist/observation.js +38 -17
- package/dist/open.d.ts +2 -0
- package/dist/open.d.ts.map +1 -0
- package/dist/open.js +1 -0
- package/dist/outcome.d.ts +32 -3
- package/dist/outcome.d.ts.map +1 -1
- package/dist/outcome.js +42 -1
- package/dist/overlay.d.ts +16 -3
- package/dist/overlay.d.ts.map +1 -1
- package/dist/overlay.js +118 -77
- package/dist/paths.d.ts +0 -1
- package/dist/paths.d.ts.map +1 -1
- package/dist/paths.js +0 -16
- package/dist/query.d.ts +46 -6
- package/dist/query.d.ts.map +1 -1
- package/dist/query.js +85 -37
- package/dist/reach.d.ts +45 -0
- package/dist/reach.d.ts.map +1 -0
- package/dist/reach.js +306 -0
- package/dist/react.d.ts +44 -0
- package/dist/react.d.ts.map +1 -0
- package/dist/react.js +66 -0
- package/dist/read-side.d.ts +16 -5
- package/dist/read-side.d.ts.map +1 -1
- package/dist/read-side.js +408 -137
- package/dist/readiness.d.ts +53 -0
- package/dist/readiness.d.ts.map +1 -0
- package/dist/readiness.js +33 -0
- package/dist/recovery.d.ts +25 -0
- package/dist/recovery.d.ts.map +1 -0
- package/dist/recovery.js +197 -0
- package/dist/refresh.d.ts +12 -1
- package/dist/refresh.d.ts.map +1 -1
- package/dist/refresh.js +51 -36
- package/dist/replica.d.ts +10 -7
- package/dist/replica.d.ts.map +1 -1
- package/dist/replica.js +129 -73
- package/dist/room-draft.d.ts +41 -9
- package/dist/room-draft.d.ts.map +1 -1
- package/dist/room-draft.js +139 -28
- package/dist/rows.d.ts +11 -14
- package/dist/rows.d.ts.map +1 -1
- package/dist/rows.js +87 -50
- package/dist/save.d.ts +32 -3
- package/dist/save.d.ts.map +1 -1
- package/dist/save.js +465 -92
- package/dist/search.d.ts +37 -8
- package/dist/search.d.ts.map +1 -1
- package/dist/search.js +116 -45
- package/dist/seed.d.ts +16 -0
- package/dist/seed.d.ts.map +1 -0
- package/dist/seed.js +61 -0
- package/dist/shared.d.ts +11 -0
- package/dist/shared.d.ts.map +1 -0
- package/dist/shared.js +368 -0
- package/dist/status.d.ts +6 -2
- package/dist/status.d.ts.map +1 -1
- package/dist/status.js +0 -8
- package/dist/store.d.ts +76 -19
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +539 -200
- package/dist/turn.d.ts +7 -0
- package/dist/turn.d.ts.map +1 -0
- package/dist/turn.js +45 -0
- package/dist/wire.d.ts +162 -19
- package/dist/wire.d.ts.map +1 -1
- package/dist/wire.js +82 -61
- package/package.json +31 -7
- package/dist/attachment.d.ts +0 -3
- package/dist/attachment.d.ts.map +0 -1
- package/dist/attachment.js +0 -8
package/dist/query.js
CHANGED
|
@@ -1,16 +1,22 @@
|
|
|
1
|
+
import { pointerFacts, } from '@agentshouse/mdmodel';
|
|
2
|
+
import { referenceField } from './model.js';
|
|
1
3
|
import { normalize } from './paths.js';
|
|
2
4
|
export class QueryError extends Error {
|
|
5
|
+
code;
|
|
6
|
+
retryable = false;
|
|
3
7
|
constructor(code, at, problem) {
|
|
4
8
|
super(`${code} at ${at}: ${problem}`);
|
|
9
|
+
this.code = code;
|
|
5
10
|
}
|
|
6
11
|
}
|
|
7
12
|
const RANGE = ['$gt', '$gte', '$lt', '$lte'];
|
|
8
13
|
const SINGLE = ['$eq', '$ne', '$in', '$nin', '$all', '$size', '$exists'];
|
|
9
14
|
const FILTER = ['rooms', 'types', 'where', 'pathPrefix', 'hop', 'backlinks'];
|
|
10
15
|
const RELATED = ['types', 'where', 'pathPrefix', 'field'];
|
|
11
|
-
const PARTS = ['fields', 'sections', 'preamble', 'markdown', 'backlinks', 'change'];
|
|
16
|
+
const PARTS = ['fields', 'sections', 'preamble', 'markdown', 'backlinks', 'change', 'fileId'];
|
|
12
17
|
const ORDER = ['by', 'direction', 'nulls', 'stringSort', 'locale', 'localeOptions'];
|
|
13
18
|
const CALENDAR_DATE = /^(\d{4})-(\d{2})-(\d{2})$/;
|
|
19
|
+
const STRAY_ESCAPE = /~(?![01])/u;
|
|
14
20
|
export function invalid(at, problem) {
|
|
15
21
|
throw new QueryError('invalid-query', at, problem);
|
|
16
22
|
}
|
|
@@ -68,23 +74,29 @@ function calendarDate(value) {
|
|
|
68
74
|
const date = new Date(Date.UTC(year, month - 1, day));
|
|
69
75
|
return (date.getUTCFullYear() === year && date.getUTCMonth() === month - 1 && date.getUTCDate() === day);
|
|
70
76
|
}
|
|
71
|
-
function
|
|
72
|
-
|
|
73
|
-
|
|
77
|
+
function itemOf(facts) {
|
|
78
|
+
return facts.type === 'array' ? facts.items : facts;
|
|
79
|
+
}
|
|
80
|
+
function fits(facts, value) {
|
|
81
|
+
const item = itemOf(facts);
|
|
82
|
+
if (item?.type === undefined)
|
|
83
|
+
return true;
|
|
84
|
+
if (item.values !== undefined)
|
|
85
|
+
return item.values.includes(value);
|
|
86
|
+
if (item.type === 'number')
|
|
74
87
|
return typeof value === 'number';
|
|
75
|
-
if (
|
|
88
|
+
if (item.type === 'integer')
|
|
89
|
+
return Number.isSafeInteger(value);
|
|
90
|
+
if (item.type === 'boolean')
|
|
91
|
+
return typeof value === 'boolean';
|
|
92
|
+
if (item.type !== 'string' || typeof value !== 'string')
|
|
76
93
|
return false;
|
|
77
|
-
if (item.
|
|
78
|
-
return item.values.includes(value);
|
|
79
|
-
if (item.kind === 'date')
|
|
80
|
-
return calendarDate(value);
|
|
81
|
-
if (item.kind === 'reference')
|
|
94
|
+
if (item.reference !== undefined)
|
|
82
95
|
return value !== '' && normalize(value) === value;
|
|
96
|
+
if (item.format === 'date')
|
|
97
|
+
return calendarDate(value);
|
|
83
98
|
return true;
|
|
84
99
|
}
|
|
85
|
-
function reference(spec) {
|
|
86
|
-
return spec.kind === 'reference' || (spec.kind === 'list' && spec.of.kind === 'reference');
|
|
87
|
-
}
|
|
88
100
|
function typing(facts, rooms, types, at) {
|
|
89
101
|
const read = rooms === null ? facts.rooms : facts.rooms.filter((room) => rooms.includes(room.locator));
|
|
90
102
|
const acquiring = !facts.listed &&
|
|
@@ -102,22 +114,46 @@ function typing(facts, rooms, types, at) {
|
|
|
102
114
|
types: types === null ? declared : declared.filter((type) => types.includes(type.name)),
|
|
103
115
|
};
|
|
104
116
|
}
|
|
105
|
-
function
|
|
106
|
-
|
|
117
|
+
function pointer(input, at) {
|
|
118
|
+
if (typeof input !== 'string' || !input.startsWith('/') || STRAY_ESCAPE.test(input)) {
|
|
119
|
+
invalid(at, 'expects a JSON Pointer');
|
|
120
|
+
}
|
|
121
|
+
return input;
|
|
122
|
+
}
|
|
123
|
+
function specs(typed, input, at) {
|
|
124
|
+
const field = pointer(input, at);
|
|
125
|
+
const declared = typed.types.flatMap((type) => {
|
|
126
|
+
const spec = pointerFacts(type, field);
|
|
127
|
+
return spec === undefined ? [] : [spec];
|
|
128
|
+
});
|
|
107
129
|
if (declared.length === 0 && !typed.untyped) {
|
|
108
130
|
throw new QueryError('unknown-field', at, `no MD Type it reads declares ${field}`);
|
|
109
131
|
}
|
|
110
|
-
|
|
132
|
+
if (!declared.some((spec) => spec.conditional))
|
|
133
|
+
return declared;
|
|
134
|
+
return declared.map((spec) => ({
|
|
135
|
+
facts: { prose: false },
|
|
136
|
+
through: several(spec),
|
|
137
|
+
conditional: true,
|
|
138
|
+
}));
|
|
139
|
+
}
|
|
140
|
+
function several(spec) {
|
|
141
|
+
return spec.through || spec.facts.type === 'array';
|
|
142
|
+
}
|
|
143
|
+
function single(spec) {
|
|
144
|
+
return spec.facts.type !== undefined && spec.facts.type !== 'array';
|
|
145
|
+
}
|
|
146
|
+
function every(declared, holds) {
|
|
147
|
+
return declared.length > 0 && declared.every(holds);
|
|
111
148
|
}
|
|
112
149
|
function kind(declared, checked, at) {
|
|
113
|
-
if (checked === null ||
|
|
150
|
+
if (checked === null ||
|
|
151
|
+
declared.length === 0 ||
|
|
152
|
+
declared.some((spec) => fits(spec.facts, checked))) {
|
|
114
153
|
return;
|
|
115
154
|
}
|
|
116
155
|
throw new QueryError('wrong-kind', at, `${JSON.stringify(checked)} is not of its field's kind`);
|
|
117
156
|
}
|
|
118
|
-
function listed(declared, list) {
|
|
119
|
-
return declared.length > 0 && declared.every((spec) => (spec.kind === 'list') === list);
|
|
120
|
-
}
|
|
121
157
|
function test(declared, input, at) {
|
|
122
158
|
if (!plain(input)) {
|
|
123
159
|
const equal = value(input, at);
|
|
@@ -131,8 +167,11 @@ function test(declared, input, at) {
|
|
|
131
167
|
const stray = operators.find((operator) => !RANGE.includes(operator));
|
|
132
168
|
if (stray !== undefined)
|
|
133
169
|
invalid(place(at, stray), 'cannot join a range');
|
|
134
|
-
if (
|
|
170
|
+
if (every(declared, (spec) => spec.facts.type === 'array'))
|
|
135
171
|
invalid(at, 'a range on a list');
|
|
172
|
+
if (every(declared, (spec) => spec.facts.type === 'boolean' || spec.facts.type === 'object')) {
|
|
173
|
+
throw new QueryError('wrong-kind', at, 'its field does not compare in order');
|
|
174
|
+
}
|
|
136
175
|
return {
|
|
137
176
|
op: 'range',
|
|
138
177
|
bounds: RANGE.filter((operator) => operators.includes(operator)).map((operator) => {
|
|
@@ -165,7 +204,7 @@ function test(declared, input, at) {
|
|
|
165
204
|
return { op: 'nin', values: compared };
|
|
166
205
|
if (compared.includes(null))
|
|
167
206
|
invalid(where, 'a list holds no null');
|
|
168
|
-
if (
|
|
207
|
+
if (every(declared, single))
|
|
169
208
|
invalid(where, 'the field is not a list');
|
|
170
209
|
return { op: 'all', values: compared };
|
|
171
210
|
}
|
|
@@ -173,7 +212,7 @@ function test(declared, input, at) {
|
|
|
173
212
|
if (!Number.isSafeInteger(operand) || operand < 0) {
|
|
174
213
|
invalid(where, 'expects a nonnegative integer');
|
|
175
214
|
}
|
|
176
|
-
if (
|
|
215
|
+
if (every(declared, single))
|
|
177
216
|
invalid(where, 'the field is not a list');
|
|
178
217
|
return { op: 'size', size: operand };
|
|
179
218
|
}
|
|
@@ -186,7 +225,7 @@ function condition(typed, input, at) {
|
|
|
186
225
|
invalid(at, 'expects an object of field predicates');
|
|
187
226
|
const conditions = [];
|
|
188
227
|
for (const name of Object.keys(input).sort()) {
|
|
189
|
-
const where = place(at, name);
|
|
228
|
+
const where = name.startsWith('/') ? `${at}${name}` : place(at, name);
|
|
190
229
|
const entry = input[name];
|
|
191
230
|
if (name === '$and' || name === '$or') {
|
|
192
231
|
const nested = list(entry, where).map((item, index) => condition(typed, item, `${where}[${index}]`));
|
|
@@ -215,19 +254,19 @@ function scope(facts, rooms, input, at) {
|
|
|
215
254
|
pathPrefix: input.pathPrefix === undefined ? null : directory(input.pathPrefix, place(at, 'pathPrefix')),
|
|
216
255
|
};
|
|
217
256
|
}
|
|
218
|
-
function
|
|
219
|
-
if (typeof field !== 'string')
|
|
220
|
-
invalid(at, 'expects a field name');
|
|
257
|
+
function referenceName(typed, field, at) {
|
|
221
258
|
const declared = specs(typed, field, at);
|
|
222
|
-
if (declared.length > 0 &&
|
|
259
|
+
if (declared.length > 0 &&
|
|
260
|
+
!declared.some((spec) => spec.conditional || referenceField(spec.facts))) {
|
|
223
261
|
invalid(at, 'not a reference field');
|
|
262
|
+
}
|
|
224
263
|
return field;
|
|
225
264
|
}
|
|
226
265
|
function hopOf(facts, rooms, root, input) {
|
|
227
266
|
if (!plain(input))
|
|
228
267
|
invalid('hop', 'expects an object');
|
|
229
268
|
known(input, RELATED, 'hop');
|
|
230
|
-
const field =
|
|
269
|
+
const field = referenceName(root, input.field, 'hop.field');
|
|
231
270
|
const { types, where, pathPrefix } = scope(facts, rooms, input, 'hop');
|
|
232
271
|
return { types, where, pathPrefix, field };
|
|
233
272
|
}
|
|
@@ -236,14 +275,16 @@ function backlinksOf(facts, rooms, input) {
|
|
|
236
275
|
invalid('backlinks', 'expects an object');
|
|
237
276
|
known(input, RELATED, 'backlinks');
|
|
238
277
|
const { typed, types, where, pathPrefix } = scope(facts, rooms, input, 'backlinks');
|
|
239
|
-
const field = input.field === undefined ? null :
|
|
278
|
+
const field = input.field === undefined ? null : referenceName(typed, input.field, 'backlinks.field');
|
|
240
279
|
return { types, where, pathPrefix, field };
|
|
241
280
|
}
|
|
242
281
|
function keyPlan(typed, input, at, path) {
|
|
243
282
|
if (input === 'room' || input === 'type' || (path && input === 'path'))
|
|
244
283
|
return { of: input };
|
|
245
|
-
if (plain(input) &&
|
|
246
|
-
specs(typed, input.field, place(at, 'field'))
|
|
284
|
+
if (plain(input) && Object.hasOwn(input, 'field') && Object.keys(input).length === 1) {
|
|
285
|
+
if (specs(typed, input.field, place(at, 'field')).some(several)) {
|
|
286
|
+
invalid(place(at, 'field'), 'a path that can hold several values');
|
|
287
|
+
}
|
|
247
288
|
return { of: 'field', field: input.field };
|
|
248
289
|
}
|
|
249
290
|
return invalid(at, path ? 'expects room, path, type or a field' : 'expects room, type or a field');
|
|
@@ -301,10 +342,10 @@ function parts(typed, input, at, fields) {
|
|
|
301
342
|
return 'all';
|
|
302
343
|
const named = list(input, at);
|
|
303
344
|
named.forEach((name, index) => {
|
|
304
|
-
if (typeof name !== 'string')
|
|
305
|
-
invalid(`${at}[${index}]`, 'expects a name');
|
|
306
345
|
if (fields)
|
|
307
346
|
specs(typed, name, `${at}[${index}]`);
|
|
347
|
+
else if (typeof name !== 'string')
|
|
348
|
+
invalid(`${at}[${index}]`, 'expects a name');
|
|
308
349
|
});
|
|
309
350
|
return named;
|
|
310
351
|
}
|
|
@@ -336,6 +377,7 @@ function documentShape(typed, input) {
|
|
|
336
377
|
markdown: true,
|
|
337
378
|
backlinks: true,
|
|
338
379
|
change: true,
|
|
380
|
+
fileId: true,
|
|
339
381
|
orderBy,
|
|
340
382
|
};
|
|
341
383
|
}
|
|
@@ -350,6 +392,7 @@ function documentShape(typed, input) {
|
|
|
350
392
|
markdown: flag(select.markdown, 'select.markdown'),
|
|
351
393
|
backlinks: flag(select.backlinks, 'select.backlinks'),
|
|
352
394
|
change: flag(select.change, 'select.change'),
|
|
395
|
+
fileId: flag(select.fileId, 'select.fileId'),
|
|
353
396
|
orderBy,
|
|
354
397
|
};
|
|
355
398
|
}
|
|
@@ -372,7 +415,7 @@ function groupShape(typed, input) {
|
|
|
372
415
|
});
|
|
373
416
|
return { kind: 'groups', groupBy, orderBy };
|
|
374
417
|
}
|
|
375
|
-
export function planOf(input, facts) {
|
|
418
|
+
export function planOf(input, facts, reach = null) {
|
|
376
419
|
if (!plain(input))
|
|
377
420
|
invalid('query', 'expects a query object');
|
|
378
421
|
const grouped = input.groupBy !== undefined;
|
|
@@ -385,7 +428,9 @@ export function planOf(input, facts) {
|
|
|
385
428
|
const rooms = input.rooms === undefined ? null : names(input.rooms, 'rooms');
|
|
386
429
|
const { typed, ...root } = scope(facts, rooms, input, '');
|
|
387
430
|
return {
|
|
431
|
+
key: queryKey(input),
|
|
388
432
|
rooms,
|
|
433
|
+
reach,
|
|
389
434
|
root,
|
|
390
435
|
hop: input.hop === undefined ? null : hopOf(facts, rooms, typed, input.hop),
|
|
391
436
|
backlinks: input.backlinks === undefined ? null : backlinksOf(facts, rooms, input.backlinks),
|
|
@@ -401,11 +446,14 @@ export function limitOf(input) {
|
|
|
401
446
|
}
|
|
402
447
|
return input;
|
|
403
448
|
}
|
|
404
|
-
export function filterOf(input, facts) {
|
|
449
|
+
export function filterOf(input, facts, reach = null) {
|
|
405
450
|
if (!plain(input))
|
|
406
451
|
invalid('documents', 'expects a filter object');
|
|
407
452
|
known(input, FILTER, '');
|
|
408
|
-
return planOf({ ...input, select: {} }, facts);
|
|
453
|
+
return planOf({ ...input, select: {} }, facts, reach);
|
|
454
|
+
}
|
|
455
|
+
export function queryKey(query) {
|
|
456
|
+
return canonical(query);
|
|
409
457
|
}
|
|
410
458
|
function canonical(value) {
|
|
411
459
|
if (Array.isArray(value))
|
package/dist/reach.d.ts
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { ReferrerScope } from './adapter.js';
|
|
2
|
+
import type { MdRuntime, ReadinessPort, RuntimeTopic } from './connection.js';
|
|
3
|
+
import type { Plan, PlanReach, QueryResult } from './query.js';
|
|
4
|
+
import type { Readiness } from './readiness.js';
|
|
5
|
+
import { type SearchResult } from './search.js';
|
|
6
|
+
export type ReachedDocument = {
|
|
7
|
+
readonly room: string;
|
|
8
|
+
readonly path: string;
|
|
9
|
+
};
|
|
10
|
+
export type PortReach = {
|
|
11
|
+
readonly rooms: readonly string[];
|
|
12
|
+
readonly documents: readonly ReachedDocument[];
|
|
13
|
+
readonly conversations: boolean;
|
|
14
|
+
};
|
|
15
|
+
export type Deliver = (message: unknown) => void;
|
|
16
|
+
export type Watch = (topic: RuntimeTopic, input: readonly unknown[], deliver: Deliver) => () => void;
|
|
17
|
+
export type RuntimeView = {
|
|
18
|
+
md: MdRuntime;
|
|
19
|
+
watch: Watch;
|
|
20
|
+
};
|
|
21
|
+
export type NarrowedView = RuntimeView & {
|
|
22
|
+
narrow(reach: PortReach | null): void;
|
|
23
|
+
facts(port: ReadinessPort): void;
|
|
24
|
+
};
|
|
25
|
+
export type Reachable = RuntimeView & {
|
|
26
|
+
plan(input: unknown, reach: PortReach | null): Plan;
|
|
27
|
+
query(plan: Plan): Promise<QueryResult>;
|
|
28
|
+
watchPlan(plan: Plan, deliver: (message: unknown) => void): () => void;
|
|
29
|
+
search(input: unknown, reach: PortReach | null): Promise<SearchResult>;
|
|
30
|
+
watchReadiness(port: ReadinessPort, reach: PortReach | null, deliver: (readiness: Readiness) => void): () => void;
|
|
31
|
+
referrerScope(referrer: unknown): ReferrerScope | null;
|
|
32
|
+
};
|
|
33
|
+
export declare function holds(reach: PortReach | null, room: string): boolean;
|
|
34
|
+
export declare function governs(reach: PortReach | null, room: {
|
|
35
|
+
readonly locator: string;
|
|
36
|
+
readonly typedSelection: {
|
|
37
|
+
roots: readonly string[];
|
|
38
|
+
} | null;
|
|
39
|
+
}): {
|
|
40
|
+
readonly collection: boolean;
|
|
41
|
+
readonly selection: boolean;
|
|
42
|
+
};
|
|
43
|
+
export declare function planReach(reach: PortReach | null): PlanReach | null;
|
|
44
|
+
export declare function narrowed(runtime: Reachable, given: PortReach | null, told: ReadinessPort): NarrowedView;
|
|
45
|
+
//# sourceMappingURL=reach.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reach.d.ts","sourceRoot":"","sources":["../src/reach.ts"],"names":[],"mappings":"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"}
|
package/dist/reach.js
ADDED
|
@@ -0,0 +1,306 @@
|
|
|
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
|
+
import { undeclaredSearch } from './search.js';
|
|
11
|
+
const UNHELD_TYPES = { collection: modelTypes(NO_MODEL), typedSelection: null };
|
|
12
|
+
function unconversed(name) {
|
|
13
|
+
return () => Promise.resolve(undeclared(name));
|
|
14
|
+
}
|
|
15
|
+
const NO_CONVERSATION = {
|
|
16
|
+
list: () => Promise.resolve([]),
|
|
17
|
+
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'),
|
|
25
|
+
};
|
|
26
|
+
const NO_CHAT_DRAFT = {
|
|
27
|
+
write: () => Promise.resolve(),
|
|
28
|
+
discard: () => Promise.resolve(),
|
|
29
|
+
};
|
|
30
|
+
export function holds(reach, room) {
|
|
31
|
+
return (reach === null ||
|
|
32
|
+
reach.rooms.includes(room) ||
|
|
33
|
+
reach.documents.some((document) => document.room === room));
|
|
34
|
+
}
|
|
35
|
+
function wholly(reach, room) {
|
|
36
|
+
return reach === null || reach.rooms.includes(room);
|
|
37
|
+
}
|
|
38
|
+
export function governs(reach, room) {
|
|
39
|
+
if (wholly(reach, room.locator)) {
|
|
40
|
+
return { collection: true, selection: room.typedSelection !== null };
|
|
41
|
+
}
|
|
42
|
+
const selected = (path) => room.typedSelection?.roots.some((root) => beneath(root, path)) ?? false;
|
|
43
|
+
const paths = reach.documents
|
|
44
|
+
.filter((document) => document.room === room.locator)
|
|
45
|
+
.map(({ path }) => path);
|
|
46
|
+
return { collection: paths.some((path) => !selected(path)), selection: paths.some(selected) };
|
|
47
|
+
}
|
|
48
|
+
function covers(reach, room, path) {
|
|
49
|
+
return (reach === null ||
|
|
50
|
+
reach.rooms.includes(room) ||
|
|
51
|
+
reach.documents.some((document) => document.room === room && document.path === path));
|
|
52
|
+
}
|
|
53
|
+
function conversing(reach) {
|
|
54
|
+
return reach === null || reach.conversations;
|
|
55
|
+
}
|
|
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
|
+
export function planReach(reach) {
|
|
71
|
+
return reach === null
|
|
72
|
+
? null
|
|
73
|
+
: {
|
|
74
|
+
rooms: [...new Set(reach.rooms)].sort(),
|
|
75
|
+
documents: [
|
|
76
|
+
...new Set(reach.documents.map(({ room, path }) => documentKey(room, path))),
|
|
77
|
+
].sort(),
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
function roomsWithin(reach, rooms) {
|
|
81
|
+
return rooms.filter((room) => wholly(reach, room.locator));
|
|
82
|
+
}
|
|
83
|
+
function typesWithin(reach, room, types) {
|
|
84
|
+
if (room === undefined)
|
|
85
|
+
return structuredClone(UNHELD_TYPES);
|
|
86
|
+
const governed = governs(reach, room);
|
|
87
|
+
return {
|
|
88
|
+
collection: governed.collection ? types.collection : modelTypes(NO_MODEL),
|
|
89
|
+
typedSelection: governed.selection ? types.typedSelection : null,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
function moves(reach, room, move) {
|
|
93
|
+
return move === undefined || covers(reach, room, moveTarget(move));
|
|
94
|
+
}
|
|
95
|
+
function draftWithin(reach, draft) {
|
|
96
|
+
return covers(reach, draft.room, draft.path) && moves(reach, draft.room, draft.parts.move);
|
|
97
|
+
}
|
|
98
|
+
function draftsWithin(reach, drafts) {
|
|
99
|
+
return drafts.filter((draft) => draftWithin(reach, draft));
|
|
100
|
+
}
|
|
101
|
+
function shownDraft(reach, draft) {
|
|
102
|
+
return draft !== null && draftWithin(reach, draft) ? draft : null;
|
|
103
|
+
}
|
|
104
|
+
function writeWithin(reach, write) {
|
|
105
|
+
return write.outcome === 'written'
|
|
106
|
+
? { outcome: 'written', roomDraft: shownDraft(reach, write.roomDraft) }
|
|
107
|
+
: staleWrite(shownDraft(reach, write.current));
|
|
108
|
+
}
|
|
109
|
+
function savedWithin(reach, room, result) {
|
|
110
|
+
if (reach === null || result.outcome === 'saved')
|
|
111
|
+
return result;
|
|
112
|
+
const { file, location, referrers, ...refusal } = result;
|
|
113
|
+
const hidden = file !== undefined && !covers(reach, room, file);
|
|
114
|
+
return {
|
|
115
|
+
...refusal,
|
|
116
|
+
...(file === undefined || hidden ? {} : { file }),
|
|
117
|
+
...(location === undefined || hidden ? {} : { location }),
|
|
118
|
+
...(referrers === undefined
|
|
119
|
+
? {}
|
|
120
|
+
: { referrers: referrers.filter((path) => covers(reach, room, path)) }),
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
function statusWithin(reach, status) {
|
|
124
|
+
return {
|
|
125
|
+
...status,
|
|
126
|
+
attentionRequired: status.attentionRequired.filter((entry) => 'refusal' in entry ? wholly(reach, entry.room) : covers(reach, entry.room, entry.path)),
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
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))));
|
|
132
|
+
}
|
|
133
|
+
function unreached(room) {
|
|
134
|
+
return runtimeError('room-not-held', `No Local Replica for ${room}`);
|
|
135
|
+
}
|
|
136
|
+
export function narrowed(runtime, given, told) {
|
|
137
|
+
const { md, watch } = runtime;
|
|
138
|
+
let reach = given;
|
|
139
|
+
let port = told;
|
|
140
|
+
const open = new Set();
|
|
141
|
+
function following(begin) {
|
|
142
|
+
let stop = begin();
|
|
143
|
+
const restart = () => {
|
|
144
|
+
stop();
|
|
145
|
+
stop = begin();
|
|
146
|
+
};
|
|
147
|
+
open.add(restart);
|
|
148
|
+
return () => {
|
|
149
|
+
open.delete(restart);
|
|
150
|
+
stop();
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
const within = (topic, input, deliver) => {
|
|
154
|
+
if (topic === 'rooms') {
|
|
155
|
+
return following(() => watch(topic, input, (rooms) => deliver(roomsWithin(reach, rooms))));
|
|
156
|
+
}
|
|
157
|
+
if (topic === 'readiness') {
|
|
158
|
+
return following(() => runtime.watchReadiness(port, reach, deliver));
|
|
159
|
+
}
|
|
160
|
+
if (topic === 'sync-status') {
|
|
161
|
+
return following(() => watch(topic, input, (status) => deliver(statusWithin(reach, status))));
|
|
162
|
+
}
|
|
163
|
+
if (topic === 'room-drafts') {
|
|
164
|
+
return following(() => watch(topic, input, (drafts) => deliver(draftsWithin(reach, drafts))));
|
|
165
|
+
}
|
|
166
|
+
if (topic === 'queue') {
|
|
167
|
+
const room = input[0];
|
|
168
|
+
return following(() => {
|
|
169
|
+
if (!holds(reach, room)) {
|
|
170
|
+
deliver([]);
|
|
171
|
+
return () => { };
|
|
172
|
+
}
|
|
173
|
+
return watch(topic, input, (entries) => deliver(queueWithin(reach, room, entries)));
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
if (topic === 'query') {
|
|
177
|
+
const plan = runtime.plan(input[0], reach);
|
|
178
|
+
let held = null;
|
|
179
|
+
return following(() => {
|
|
180
|
+
let first = true;
|
|
181
|
+
return runtime.watchPlan({ ...plan, reach: planReach(reach) }, (message) => {
|
|
182
|
+
if (!first) {
|
|
183
|
+
held = applied(held, message);
|
|
184
|
+
deliver(message);
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
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);
|
|
198
|
+
});
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
if (topic === 'conversation') {
|
|
202
|
+
return following(() => {
|
|
203
|
+
if (conversing(reach))
|
|
204
|
+
return watch(topic, input, deliver);
|
|
205
|
+
deliver(unheldView(input[0]));
|
|
206
|
+
return () => { };
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
if (topic === 'conversations' || topic === 'agents') {
|
|
210
|
+
return following(() => {
|
|
211
|
+
if (conversing(reach))
|
|
212
|
+
return watch(topic, input, deliver);
|
|
213
|
+
deliver([]);
|
|
214
|
+
return () => { };
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
return watch(topic, input, deliver);
|
|
218
|
+
};
|
|
219
|
+
const conversation = () => (conversing(reach) ? md.conversation : NO_CONVERSATION);
|
|
220
|
+
const chatDraft = () => (conversing(reach) ? md.chatDraft : NO_CHAT_DRAFT);
|
|
221
|
+
const view = {
|
|
222
|
+
...md,
|
|
223
|
+
rooms: () => roomsWithin(reach, md.rooms()),
|
|
224
|
+
query: ((input) => runtime.query(runtime.plan(input, reach))),
|
|
225
|
+
search: (input) => port.search === 'required'
|
|
226
|
+
? runtime.search(input, reach)
|
|
227
|
+
: Promise.resolve(undeclaredSearch()),
|
|
228
|
+
types(room) {
|
|
229
|
+
if (wholly(reach, room))
|
|
230
|
+
return md.types(room);
|
|
231
|
+
if (!holds(reach, room))
|
|
232
|
+
return structuredClone(UNHELD_TYPES);
|
|
233
|
+
const listed = md.rooms().find(({ locator }) => locator === room);
|
|
234
|
+
return typesWithin(reach, listed, md.types(room));
|
|
235
|
+
},
|
|
236
|
+
async save(room, roomDrafts, writtenBy) {
|
|
237
|
+
if (!holds(reach, room))
|
|
238
|
+
throw unreached(room);
|
|
239
|
+
const outside = roomDrafts.find(({ path }) => !covers(reach, room, path) ||
|
|
240
|
+
!moves(reach, room, md.roomDraft.read(room, path)?.parts.move));
|
|
241
|
+
if (outside !== undefined) {
|
|
242
|
+
return { outcome: 'refused', code: 'stale', retryable: false, file: outside.path };
|
|
243
|
+
}
|
|
244
|
+
return savedWithin(reach, room, await md.save(room, roomDrafts, writtenBy));
|
|
245
|
+
},
|
|
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 })),
|
|
249
|
+
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)),
|
|
256
|
+
},
|
|
257
|
+
reached: (room, roomVersion, path) => (path === undefined ? wholly(reach, room) : covers(reach, room, path)) &&
|
|
258
|
+
md.reached(room, roomVersion, path),
|
|
259
|
+
log: () => (reach === null ? md.log() : ''),
|
|
260
|
+
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);
|
|
266
|
+
}
|
|
267
|
+
return writeWithin(reach, await md.roomDraft.write(room, path, revision, parts));
|
|
268
|
+
},
|
|
269
|
+
async discard(room, path, revision) {
|
|
270
|
+
if (!covers(reach, room, path))
|
|
271
|
+
return staleWrite(null);
|
|
272
|
+
return writeWithin(reach, await md.roomDraft.discard(room, path, revision));
|
|
273
|
+
},
|
|
274
|
+
},
|
|
275
|
+
conversation: {
|
|
276
|
+
list: () => conversation().list(),
|
|
277
|
+
read: (id, options) => conversation().read(id, options),
|
|
278
|
+
create: (input) => conversation().create(input),
|
|
279
|
+
send: (id, operation, draft) => conversation().send(id, operation, draft),
|
|
280
|
+
answer: (id, answer) => conversation().answer(id, answer),
|
|
281
|
+
interrupt: (id) => conversation().interrupt(id),
|
|
282
|
+
kill: (id) => conversation().kill(id),
|
|
283
|
+
cancel: (id, turn) => conversation().cancel(id, turn),
|
|
284
|
+
delete: (id) => conversation().delete(id),
|
|
285
|
+
},
|
|
286
|
+
chatDraft: {
|
|
287
|
+
write: (id, draft, revision) => chatDraft().write(id, draft, revision),
|
|
288
|
+
discard: (id) => chatDraft().discard(id),
|
|
289
|
+
},
|
|
290
|
+
observe: observing(within),
|
|
291
|
+
};
|
|
292
|
+
return {
|
|
293
|
+
md: view,
|
|
294
|
+
watch: within,
|
|
295
|
+
narrow(next) {
|
|
296
|
+
reach = next;
|
|
297
|
+
for (const restart of [...open])
|
|
298
|
+
restart();
|
|
299
|
+
},
|
|
300
|
+
facts(next) {
|
|
301
|
+
port = next;
|
|
302
|
+
for (const restart of [...open])
|
|
303
|
+
restart();
|
|
304
|
+
},
|
|
305
|
+
};
|
|
306
|
+
}
|
package/dist/react.d.ts
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
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 { 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, PendingResult } from './query.js';
|
|
8
|
+
import type { Readiness } from './readiness.js';
|
|
9
|
+
import type { RoomDraft, RoomDraftParts } from './room-draft.js';
|
|
10
|
+
import type { SyncStatus } from './status.js';
|
|
11
|
+
type Client = MdRuntimeClient | null;
|
|
12
|
+
export type Observed<T> = {
|
|
13
|
+
readonly state: 'loading';
|
|
14
|
+
} | {
|
|
15
|
+
readonly state: 'ready';
|
|
16
|
+
readonly value: T;
|
|
17
|
+
};
|
|
18
|
+
export declare function useObserve(client: Client, topic: 'deployment-facts'): Observed<unknown>;
|
|
19
|
+
export declare function useObserve(client: Client, topic: 'rooms'): Observed<readonly AppRoom[]>;
|
|
20
|
+
export declare function useObserve(client: Client, topic: 'readiness'): Observed<Readiness>;
|
|
21
|
+
export declare function useObserve(client: Client, topic: 'connection-refusal'): Observed<ConnectionRefusal | null>;
|
|
22
|
+
export declare function useObserve(client: Client, topic: 'storage-loss'): Observed<string | null>;
|
|
23
|
+
export declare function useObserve(client: Client, topic: 'sync-status'): Observed<SyncStatus>;
|
|
24
|
+
export declare function useObserve(client: Client, topic: 'service-mode'): Observed<ServiceMode>;
|
|
25
|
+
export declare function useObserve(client: Client, topic: 'member'): Observed<Member | null>;
|
|
26
|
+
export declare function useObserve(client: Client, topic: 'query', query: DocumentQuery): Observed<DocumentResult | PendingResult>;
|
|
27
|
+
export declare function useObserve(client: Client, topic: 'query', query: GroupQuery): Observed<GroupResult | PendingResult>;
|
|
28
|
+
export declare function useObserve(client: Client, topic: 'queue', locator: string): Observed<readonly QueueEntry[]>;
|
|
29
|
+
export declare function useObserve(client: Client, topic: 'room-drafts'): Observed<readonly RoomDraft[]>;
|
|
30
|
+
export declare function useObserve(client: Client, topic: 'presentation'): Observed<unknown>;
|
|
31
|
+
export declare function useObserve(client: Client, topic: 'conversation', conversation: string, options: ConversationOptions): Observed<ConversationView>;
|
|
32
|
+
export declare function useObserve(client: Client, topic: 'conversations'): Observed<readonly ConversationEntry[]>;
|
|
33
|
+
export declare function useObserve(client: Client, topic: 'agents'): Observed<readonly ConversationAgent[]>;
|
|
34
|
+
export type Saving = {
|
|
35
|
+
readonly busy: boolean;
|
|
36
|
+
readonly outcome: SaveResult | null;
|
|
37
|
+
readonly failure: RuntimeError | null;
|
|
38
|
+
save(room: string, roomDrafts: ReadonlyMap<string, RoomDraftParts>): Promise<SaveResult>;
|
|
39
|
+
saveWritten(room: string, roomDrafts: readonly SavedRoomDraft[]): Promise<SaveResult>;
|
|
40
|
+
};
|
|
41
|
+
export declare function saveRoomDrafts(client: MdRuntimeClient, room: string, roomDrafts: ReadonlyMap<string, RoomDraftParts>): Promise<SaveResult>;
|
|
42
|
+
export declare function useSave(client: MdRuntimeClient): Saving;
|
|
43
|
+
export {};
|
|
44
|
+
//# sourceMappingURL=react.d.ts.map
|