@agentshouse/mdruntime 0.1.0-c1db74d14e5fa → 0.1.0-c1ff51b87bc3d
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/README.md +18 -15
- package/dist/adapter.d.ts +91 -39
- package/dist/adapter.d.ts.map +1 -1
- package/dist/attached-model.d.ts +5 -1
- package/dist/attached-model.d.ts.map +1 -1
- package/dist/attached-model.js +38 -4
- package/dist/binary.d.ts +0 -5
- package/dist/binary.d.ts.map +1 -1
- package/dist/binary.js +1 -1
- package/dist/bootstrap.d.ts +27 -8
- package/dist/bootstrap.d.ts.map +1 -1
- package/dist/bootstrap.js +174 -98
- package/dist/chain.d.ts +11 -0
- package/dist/chain.d.ts.map +1 -0
- package/dist/chain.js +64 -0
- package/dist/change-set.d.ts +9 -16
- package/dist/change-set.d.ts.map +1 -1
- package/dist/change-set.js +11 -88
- package/dist/change.d.ts +31 -1
- package/dist/change.d.ts.map +1 -1
- package/dist/change.js +10 -1
- package/dist/client.d.ts +15 -6
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +96 -10
- package/dist/collection.d.ts +11 -19
- package/dist/collection.d.ts.map +1 -1
- package/dist/collection.js +53 -289
- package/dist/compile.d.ts +16 -0
- package/dist/compile.d.ts.map +1 -0
- package/dist/compile.js +765 -0
- package/dist/connection.d.ts +29 -13
- package/dist/connection.d.ts.map +1 -1
- package/dist/connection.js +2967 -1070
- package/dist/conversation.d.ts +21 -5
- package/dist/conversation.d.ts.map +1 -1
- package/dist/conversation.js +434 -126
- package/dist/digest.d.ts +7 -0
- package/dist/digest.d.ts.map +1 -0
- package/dist/digest.js +113 -0
- package/dist/durability.d.ts +3 -5
- package/dist/durability.d.ts.map +1 -1
- package/dist/durability.js +5 -0
- package/dist/entry.d.ts +4 -1
- package/dist/entry.d.ts.map +1 -1
- package/dist/entry.js +18 -23
- package/dist/file.d.ts +2 -19
- package/dist/file.d.ts.map +1 -1
- package/dist/file.js +7 -122
- package/dist/fulltext.d.ts +27 -0
- package/dist/fulltext.d.ts.map +1 -0
- package/dist/fulltext.js +368 -0
- package/dist/host.d.ts +10 -8
- package/dist/host.d.ts.map +1 -1
- package/dist/host.js +97 -18
- package/dist/identity.d.ts +0 -1
- package/dist/identity.d.ts.map +1 -1
- package/dist/identity.js +0 -3
- package/dist/index.d.ts +14 -11
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -1
- package/dist/live.d.ts +22 -0
- package/dist/live.d.ts.map +1 -0
- package/dist/live.js +124 -0
- package/dist/media.d.ts +8 -0
- package/dist/media.d.ts.map +1 -0
- package/dist/media.js +208 -0
- package/dist/memory.d.ts +9 -4
- package/dist/memory.d.ts.map +1 -1
- package/dist/memory.js +86 -32
- package/dist/messages.d.ts +28 -0
- package/dist/messages.d.ts.map +1 -0
- package/dist/messages.js +90 -0
- package/dist/model.d.ts +9 -2
- package/dist/model.d.ts.map +1 -1
- package/dist/model.js +8 -2
- package/dist/name.d.ts +4 -0
- package/dist/name.d.ts.map +1 -0
- package/dist/name.js +122 -0
- package/dist/observation.d.ts +15 -0
- package/dist/observation.d.ts.map +1 -1
- package/dist/observation.js +93 -3
- package/dist/opened.d.ts +22 -0
- package/dist/opened.d.ts.map +1 -0
- package/dist/opened.js +107 -0
- package/dist/outcome.d.ts +45 -4
- package/dist/outcome.d.ts.map +1 -1
- package/dist/outcome.js +39 -0
- package/dist/overlay.d.ts +3 -5
- package/dist/overlay.d.ts.map +1 -1
- package/dist/overlay.js +95 -156
- package/dist/paths.d.ts +1 -0
- package/dist/paths.d.ts.map +1 -1
- package/dist/paths.js +4 -0
- package/dist/query.d.ts +39 -2
- package/dist/query.d.ts.map +1 -1
- package/dist/query.js +48 -7
- package/dist/reach.d.ts +14 -6
- package/dist/reach.d.ts.map +1 -1
- package/dist/reach.js +213 -71
- package/dist/react.d.ts +3 -3
- package/dist/react.d.ts.map +1 -1
- package/dist/react.js +7 -17
- package/dist/readiness.d.ts +19 -9
- package/dist/readiness.d.ts.map +1 -1
- package/dist/readiness.js +6 -6
- package/dist/reads.d.ts +11 -0
- package/dist/reads.d.ts.map +1 -0
- package/dist/reads.js +91 -0
- package/dist/recovery.d.ts +2 -2
- package/dist/recovery.d.ts.map +1 -1
- package/dist/recovery.js +8 -7
- package/dist/refresh.d.ts +16 -15
- package/dist/refresh.d.ts.map +1 -1
- package/dist/refresh.js +113 -50
- package/dist/replica.d.ts +56 -33
- package/dist/replica.d.ts.map +1 -1
- package/dist/replica.js +298 -179
- package/dist/room-draft.d.ts +34 -4
- package/dist/room-draft.d.ts.map +1 -1
- package/dist/room-draft.js +105 -31
- package/dist/rows.d.ts +38 -29
- package/dist/rows.d.ts.map +1 -1
- package/dist/rows.js +173 -94
- package/dist/save.d.ts +53 -14
- package/dist/save.d.ts.map +1 -1
- package/dist/save.js +529 -185
- package/dist/search.d.ts +32 -43
- package/dist/search.d.ts.map +1 -1
- package/dist/search.js +37 -168
- package/dist/seed.d.ts +16 -0
- package/dist/seed.d.ts.map +1 -0
- package/dist/seed.js +75 -0
- package/dist/shared.d.ts +8 -3
- package/dist/shared.d.ts.map +1 -1
- package/dist/shared.js +129 -66
- package/dist/status.d.ts +5 -0
- package/dist/status.d.ts.map +1 -1
- package/dist/status.js +3 -1
- package/dist/store.d.ts +97 -89
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +329 -641
- package/dist/stored.d.ts +135 -0
- package/dist/stored.d.ts.map +1 -0
- package/dist/stored.js +574 -0
- package/dist/tables.d.ts +352 -0
- package/dist/tables.d.ts.map +1 -0
- package/dist/tables.js +621 -0
- package/dist/turn.d.ts +5 -3
- package/dist/turn.d.ts.map +1 -1
- package/dist/turn.js +51 -21
- package/dist/validation.d.ts +30 -0
- package/dist/validation.d.ts.map +1 -0
- package/dist/validation.js +162 -0
- package/dist/windows.d.ts +22 -0
- package/dist/windows.d.ts.map +1 -0
- package/dist/windows.js +89 -0
- package/dist/wire.d.ts +167 -33
- package/dist/wire.d.ts.map +1 -1
- package/dist/wire.js +55 -32
- package/dist/words.d.ts +19 -0
- package/dist/words.d.ts.map +1 -0
- package/dist/words.js +156 -0
- package/package.json +18 -19
- package/AGENTS.md +0 -300
- package/dist/acquisition.d.ts +0 -14
- package/dist/acquisition.d.ts.map +0 -1
- package/dist/acquisition.js +0 -24
- package/dist/chat/acts.d.ts +0 -33
- package/dist/chat/acts.d.ts.map +0 -1
- package/dist/chat/acts.js +0 -36
- package/dist/chat/context.d.ts +0 -3
- package/dist/chat/context.d.ts.map +0 -1
- package/dist/chat/context.js +0 -10
- package/dist/chat/input.d.ts +0 -9
- package/dist/chat/input.d.ts.map +0 -1
- package/dist/chat/input.js +0 -99
- package/dist/chat/kit.d.ts +0 -60
- package/dist/chat/kit.d.ts.map +0 -1
- package/dist/chat/kit.js +0 -123
- package/dist/chat/lasting.d.ts +0 -6
- package/dist/chat/lasting.d.ts.map +0 -1
- package/dist/chat/lasting.js +0 -19
- package/dist/chat/list.d.ts +0 -26
- package/dist/chat/list.d.ts.map +0 -1
- package/dist/chat/list.js +0 -62
- package/dist/chat/markdown.d.ts +0 -20
- package/dist/chat/markdown.d.ts.map +0 -1
- package/dist/chat/markdown.js +0 -188
- package/dist/chat/message.d.ts +0 -6
- package/dist/chat/message.d.ts.map +0 -1
- package/dist/chat/message.js +0 -192
- package/dist/chat/messages.d.ts +0 -21
- package/dist/chat/messages.d.ts.map +0 -1
- package/dist/chat/messages.js +0 -151
- package/dist/chat/name.d.ts +0 -6
- package/dist/chat/name.d.ts.map +0 -1
- package/dist/chat/name.js +0 -37
- package/dist/chat/opened.d.ts +0 -11
- package/dist/chat/opened.d.ts.map +0 -1
- package/dist/chat/opened.js +0 -17
- package/dist/chat/overlay.d.ts +0 -31
- package/dist/chat/overlay.d.ts.map +0 -1
- package/dist/chat/overlay.js +0 -97
- package/dist/chat/parts.d.ts +0 -57
- package/dist/chat/parts.d.ts.map +0 -1
- package/dist/chat/parts.js +0 -119
- package/dist/chat/process.d.ts +0 -20
- package/dist/chat/process.d.ts.map +0 -1
- package/dist/chat/process.js +0 -32
- package/dist/chat/provider.d.ts +0 -63
- package/dist/chat/provider.d.ts.map +0 -1
- package/dist/chat/provider.js +0 -620
- package/dist/chat/question.d.ts +0 -9
- package/dist/chat/question.d.ts.map +0 -1
- package/dist/chat/question.js +0 -80
- package/dist/chat/questions.d.ts +0 -31
- package/dist/chat/questions.d.ts.map +0 -1
- package/dist/chat/questions.js +0 -111
- package/dist/chat/read.d.ts +0 -5
- package/dist/chat/read.d.ts.map +0 -1
- package/dist/chat/read.js +0 -13
- package/dist/chat/ready.d.ts +0 -33
- package/dist/chat/ready.d.ts.map +0 -1
- package/dist/chat/ready.js +0 -91
- package/dist/chat/style.d.ts +0 -4
- package/dist/chat/style.d.ts.map +0 -1
- package/dist/chat/style.js +0 -302
- package/dist/chat.d.ts +0 -14
- package/dist/chat.d.ts.map +0 -1
- package/dist/chat.js +0 -8
- package/dist/read-side.d.ts +0 -25
- package/dist/read-side.d.ts.map +0 -1
- package/dist/read-side.js +0 -639
package/dist/query.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { pointerFacts, } from '@agentshouse/mdmodel';
|
|
2
2
|
import { referenceField } from './model.js';
|
|
3
3
|
import { normalize } from './paths.js';
|
|
4
|
+
import { decodedCursor } from './windows.js';
|
|
4
5
|
export class QueryError extends Error {
|
|
5
6
|
code;
|
|
6
7
|
retryable = false;
|
|
@@ -11,9 +12,18 @@ export class QueryError extends Error {
|
|
|
11
12
|
}
|
|
12
13
|
const RANGE = ['$gt', '$gte', '$lt', '$lte'];
|
|
13
14
|
const SINGLE = ['$eq', '$ne', '$in', '$nin', '$all', '$size', '$exists'];
|
|
14
|
-
const FILTER = ['rooms', 'types', 'where', 'pathPrefix', 'hop', 'backlinks'];
|
|
15
|
+
const FILTER = ['rooms', 'types', 'where', 'pathPrefix', 'folder', 'paths', 'hop', 'backlinks'];
|
|
15
16
|
const RELATED = ['types', 'where', 'pathPrefix', 'field'];
|
|
16
|
-
const PARTS = [
|
|
17
|
+
const PARTS = [
|
|
18
|
+
'fields',
|
|
19
|
+
'sections',
|
|
20
|
+
'preamble',
|
|
21
|
+
'markdown',
|
|
22
|
+
'backlinks',
|
|
23
|
+
'change',
|
|
24
|
+
'fileId',
|
|
25
|
+
'revision',
|
|
26
|
+
];
|
|
17
27
|
const ORDER = ['by', 'direction', 'nulls', 'stringSort', 'locale', 'localeOptions'];
|
|
18
28
|
const CALENDAR_DATE = /^(\d{4})-(\d{2})-(\d{2})$/;
|
|
19
29
|
const STRAY_ESCAPE = /~(?![01])/u;
|
|
@@ -60,6 +70,13 @@ function names(input, at) {
|
|
|
60
70
|
invalid(at, 'expects a list of names');
|
|
61
71
|
return [...new Set(listed)].sort();
|
|
62
72
|
}
|
|
73
|
+
function pathsOf(input) {
|
|
74
|
+
const listed = list(input, 'paths');
|
|
75
|
+
if (listed.some((item) => typeof item !== 'string' || item === '' || normalize(item) !== item)) {
|
|
76
|
+
invalid('paths', 'expects a list of Paths');
|
|
77
|
+
}
|
|
78
|
+
return [...new Set(listed)].sort();
|
|
79
|
+
}
|
|
63
80
|
function directory(input, at) {
|
|
64
81
|
if (typeof input !== 'string' || normalize(input) !== input) {
|
|
65
82
|
invalid(at, 'expects a normalized directory');
|
|
@@ -279,15 +296,16 @@ function backlinksOf(facts, rooms, input) {
|
|
|
279
296
|
return { types, where, pathPrefix, field };
|
|
280
297
|
}
|
|
281
298
|
function keyPlan(typed, input, at, path) {
|
|
282
|
-
if (input === 'room' || input === 'type' || (path && input === 'path'))
|
|
299
|
+
if (input === 'room' || input === 'type' || input === 'folder' || (path && input === 'path')) {
|
|
283
300
|
return { of: input };
|
|
301
|
+
}
|
|
284
302
|
if (plain(input) && Object.hasOwn(input, 'field') && Object.keys(input).length === 1) {
|
|
285
303
|
if (specs(typed, input.field, place(at, 'field')).some(several)) {
|
|
286
304
|
invalid(place(at, 'field'), 'a path that can hold several values');
|
|
287
305
|
}
|
|
288
306
|
return { of: 'field', field: input.field };
|
|
289
307
|
}
|
|
290
|
-
return invalid(at, path ? 'expects room, path, type or a field' : 'expects room, type or a field');
|
|
308
|
+
return invalid(at, path ? 'expects room, path, type, folder or a field' : 'expects room, type, folder or a field');
|
|
291
309
|
}
|
|
292
310
|
function direction(input, at) {
|
|
293
311
|
if (input === undefined)
|
|
@@ -349,7 +367,7 @@ function parts(typed, input, at, fields) {
|
|
|
349
367
|
});
|
|
350
368
|
return named;
|
|
351
369
|
}
|
|
352
|
-
function flag(input, at) {
|
|
370
|
+
export function flag(input, at) {
|
|
353
371
|
if (input === undefined)
|
|
354
372
|
return false;
|
|
355
373
|
if (input !== true)
|
|
@@ -377,6 +395,8 @@ function documentShape(typed, input) {
|
|
|
377
395
|
markdown: true,
|
|
378
396
|
backlinks: true,
|
|
379
397
|
change: true,
|
|
398
|
+
fileId: true,
|
|
399
|
+
revision: true,
|
|
380
400
|
orderBy,
|
|
381
401
|
};
|
|
382
402
|
}
|
|
@@ -391,6 +411,8 @@ function documentShape(typed, input) {
|
|
|
391
411
|
markdown: flag(select.markdown, 'select.markdown'),
|
|
392
412
|
backlinks: flag(select.backlinks, 'select.backlinks'),
|
|
393
413
|
change: flag(select.change, 'select.change'),
|
|
414
|
+
fileId: flag(select.fileId, 'select.fileId'),
|
|
415
|
+
revision: flag(select.revision, 'select.revision'),
|
|
394
416
|
orderBy,
|
|
395
417
|
};
|
|
396
418
|
}
|
|
@@ -421,20 +443,36 @@ export function planOf(input, facts, reach = null) {
|
|
|
421
443
|
invalid('select', 'a grouped query selects nothing');
|
|
422
444
|
if (!grouped && input.select === undefined)
|
|
423
445
|
invalid('select', 'a Document query must select');
|
|
424
|
-
known(input, [...FILTER, 'orderBy', 'limit', grouped ? 'groupBy' : 'select'], '');
|
|
446
|
+
known(input, [...FILTER, 'orderBy', 'limit', 'after', 'total', grouped ? 'groupBy' : 'select'], '');
|
|
425
447
|
const limit = limitOf(input.limit);
|
|
426
448
|
const rooms = input.rooms === undefined ? null : names(input.rooms, 'rooms');
|
|
427
449
|
const { typed, ...root } = scope(facts, rooms, input, '');
|
|
450
|
+
const shape = grouped ? groupShape(typed, input) : documentShape(typed, input);
|
|
428
451
|
return {
|
|
452
|
+
key: queryKey(input),
|
|
429
453
|
rooms,
|
|
430
454
|
reach,
|
|
455
|
+
locked: [],
|
|
431
456
|
root,
|
|
457
|
+
folder: input.folder === undefined ? null : directory(input.folder, 'folder'),
|
|
458
|
+
paths: input.paths === undefined ? null : pathsOf(input.paths),
|
|
432
459
|
hop: input.hop === undefined ? null : hopOf(facts, rooms, typed, input.hop),
|
|
433
460
|
backlinks: input.backlinks === undefined ? null : backlinksOf(facts, rooms, input.backlinks),
|
|
434
|
-
shape
|
|
461
|
+
shape,
|
|
435
462
|
limit,
|
|
463
|
+
after: continuationOf(input.after, shape.orderBy.length + 1),
|
|
464
|
+
total: flag(input.total, 'total'),
|
|
436
465
|
};
|
|
437
466
|
}
|
|
467
|
+
function continuationOf(input, arity) {
|
|
468
|
+
if (input === undefined)
|
|
469
|
+
return null;
|
|
470
|
+
const values = typeof input === 'string' ? decodedCursor(input) : null;
|
|
471
|
+
if (values === null || (values.length !== 0 && values.length !== arity)) {
|
|
472
|
+
invalid('after', 'expects the next an earlier result of this query returned');
|
|
473
|
+
}
|
|
474
|
+
return { text: input, values: values.length === 0 ? null : values };
|
|
475
|
+
}
|
|
438
476
|
export function limitOf(input) {
|
|
439
477
|
if (input === undefined)
|
|
440
478
|
return null;
|
|
@@ -449,6 +487,9 @@ export function filterOf(input, facts, reach = null) {
|
|
|
449
487
|
known(input, FILTER, '');
|
|
450
488
|
return planOf({ ...input, select: {} }, facts, reach);
|
|
451
489
|
}
|
|
490
|
+
export function queryKey(query) {
|
|
491
|
+
return canonical(query);
|
|
492
|
+
}
|
|
452
493
|
function canonical(value) {
|
|
453
494
|
if (Array.isArray(value))
|
|
454
495
|
return `[${value.map(canonical).join(',')}]`;
|
package/dist/reach.d.ts
CHANGED
|
@@ -1,15 +1,20 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type { MdRuntime, ReadinessPort, RuntimeTopic } from './connection.js';
|
|
1
|
+
import type { AppRoom, MdRuntime, ReadinessPort, RuntimeTopic } from './connection.js';
|
|
3
2
|
import type { Plan, PlanReach, QueryResult } from './query.js';
|
|
4
3
|
import type { Readiness } from './readiness.js';
|
|
5
|
-
import type
|
|
4
|
+
import { type SearchResult } from './search.js';
|
|
6
5
|
export type ReachedDocument = {
|
|
7
6
|
readonly room: string;
|
|
8
7
|
readonly path: string;
|
|
9
8
|
};
|
|
9
|
+
export type ReachedArea = {
|
|
10
|
+
readonly room: string;
|
|
11
|
+
readonly path: string;
|
|
12
|
+
readonly types: readonly string[];
|
|
13
|
+
};
|
|
10
14
|
export type PortReach = {
|
|
11
15
|
readonly rooms: readonly string[];
|
|
12
16
|
readonly documents: readonly ReachedDocument[];
|
|
17
|
+
readonly areas?: readonly ReachedArea[];
|
|
13
18
|
readonly conversations: boolean;
|
|
14
19
|
};
|
|
15
20
|
export type Deliver = (message: unknown) => void;
|
|
@@ -26,10 +31,13 @@ export type Reachable = RuntimeView & {
|
|
|
26
31
|
plan(input: unknown, reach: PortReach | null): Plan;
|
|
27
32
|
query(plan: Plan): Promise<QueryResult>;
|
|
28
33
|
watchPlan(plan: Plan, deliver: (message: unknown) => void): () => void;
|
|
29
|
-
search(input: unknown, reach: PortReach | null): Promise<SearchResult>;
|
|
30
|
-
searching(target: string): void;
|
|
34
|
+
search(input: unknown, reach: PortReach | null, locked: readonly string[]): Promise<SearchResult>;
|
|
31
35
|
watchReadiness(port: ReadinessPort, reach: PortReach | null, deliver: (readiness: Readiness) => void): () => void;
|
|
32
|
-
|
|
36
|
+
locked(room: string): boolean;
|
|
37
|
+
lockedRooms(): readonly string[];
|
|
38
|
+
watchLocks(notify: () => void): () => void;
|
|
39
|
+
located(room: string, path: string, destination: string): ReachedDocument | null;
|
|
40
|
+
room(locator: string): AppRoom | undefined;
|
|
33
41
|
};
|
|
34
42
|
export declare function holds(reach: PortReach | null, room: string): boolean;
|
|
35
43
|
export declare function governs(reach: PortReach | null, room: {
|
package/dist/reach.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reach.d.ts","sourceRoot":"","sources":["../src/reach.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"reach.d.ts","sourceRoot":"","sources":["../src/reach.ts"],"names":[],"mappings":"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"}
|
package/dist/reach.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { unheldView } from './conversation.js';
|
|
2
2
|
import { modelTypes, NO_MODEL } from './model.js';
|
|
3
|
-
import {
|
|
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';
|
|
9
|
+
import { undeclaredSearch } from './search.js';
|
|
10
10
|
const UNHELD_TYPES = { collection: modelTypes(NO_MODEL), typedSelection: null };
|
|
11
11
|
function unconversed(name) {
|
|
12
12
|
return () => Promise.resolve(undeclared(name));
|
|
@@ -24,12 +24,23 @@ const NO_CONVERSATION = {
|
|
|
24
24
|
};
|
|
25
25
|
const NO_CHAT_DRAFT = {
|
|
26
26
|
write: () => Promise.resolve(),
|
|
27
|
+
prepend: () => Promise.resolve(),
|
|
27
28
|
discard: () => Promise.resolve(),
|
|
28
29
|
};
|
|
30
|
+
function areasOf(reach) {
|
|
31
|
+
return reach.areas ?? [];
|
|
32
|
+
}
|
|
33
|
+
function typedAreas(reach, room) {
|
|
34
|
+
return areasOf(reach).filter((area) => area.room === room && area.types.length > 0);
|
|
35
|
+
}
|
|
36
|
+
function fenced(reach, room, path) {
|
|
37
|
+
return areasOf(reach).some((area) => area.room === room && beneath(area.path, path));
|
|
38
|
+
}
|
|
29
39
|
export function holds(reach, room) {
|
|
30
40
|
return (reach === null ||
|
|
31
41
|
reach.rooms.includes(room) ||
|
|
32
|
-
reach.documents.some((document) => document.room === room)
|
|
42
|
+
reach.documents.some((document) => document.room === room) ||
|
|
43
|
+
typedAreas(reach, room).length > 0);
|
|
33
44
|
}
|
|
34
45
|
function wholly(reach, room) {
|
|
35
46
|
return reach === null || reach.rooms.includes(room);
|
|
@@ -39,33 +50,23 @@ export function governs(reach, room) {
|
|
|
39
50
|
return { collection: true, selection: room.typedSelection !== null };
|
|
40
51
|
}
|
|
41
52
|
const selected = (path) => room.typedSelection?.roots.some((root) => beneath(root, path)) ?? false;
|
|
42
|
-
const paths =
|
|
43
|
-
.
|
|
44
|
-
|
|
53
|
+
const paths = [
|
|
54
|
+
...reach.documents
|
|
55
|
+
.filter((document) => document.room === room.locator)
|
|
56
|
+
.map(({ path }) => path),
|
|
57
|
+
...typedAreas(reach, room.locator).map(({ path }) => path),
|
|
58
|
+
];
|
|
45
59
|
return { collection: paths.some((path) => !selected(path)), selection: paths.some(selected) };
|
|
46
60
|
}
|
|
47
61
|
function covers(reach, room, path) {
|
|
48
62
|
return (reach === null ||
|
|
49
|
-
reach
|
|
50
|
-
|
|
63
|
+
(!fenced(reach, room, path) &&
|
|
64
|
+
(reach.rooms.includes(room) ||
|
|
65
|
+
reach.documents.some((document) => document.room === room && document.path === path))));
|
|
51
66
|
}
|
|
52
67
|
function conversing(reach) {
|
|
53
68
|
return reach === null || reach.conversations;
|
|
54
69
|
}
|
|
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
70
|
export function planReach(reach) {
|
|
70
71
|
return reach === null
|
|
71
72
|
? null
|
|
@@ -74,6 +75,9 @@ export function planReach(reach) {
|
|
|
74
75
|
documents: [
|
|
75
76
|
...new Set(reach.documents.map(({ room, path }) => documentKey(room, path))),
|
|
76
77
|
].sort(),
|
|
78
|
+
areas: areasOf(reach)
|
|
79
|
+
.map(({ room, path, types }) => ({ room, path, types: [...new Set(types)].sort() }))
|
|
80
|
+
.sort((left, right) => documentKey(left.room, left.path) < documentKey(right.room, right.path) ? -1 : 1),
|
|
77
81
|
};
|
|
78
82
|
}
|
|
79
83
|
function roomsWithin(reach, rooms) {
|
|
@@ -89,7 +93,7 @@ function typesWithin(reach, room, types) {
|
|
|
89
93
|
};
|
|
90
94
|
}
|
|
91
95
|
function moves(reach, room, move) {
|
|
92
|
-
return move === undefined || covers(reach, room, moveTarget(move));
|
|
96
|
+
return move === undefined || covers(reach, move.room ?? room, moveTarget(move));
|
|
93
97
|
}
|
|
94
98
|
function draftWithin(reach, draft) {
|
|
95
99
|
return covers(reach, draft.room, draft.path) && moves(reach, draft.room, draft.parts.move);
|
|
@@ -123,32 +127,65 @@ function statusWithin(reach, status) {
|
|
|
123
127
|
return {
|
|
124
128
|
...status,
|
|
125
129
|
attentionRequired: status.attentionRequired.filter((entry) => 'refusal' in entry ? wholly(reach, entry.room) : covers(reach, entry.room, entry.path)),
|
|
130
|
+
unsent: status.unsent.filter((change) => covers(reach, change.room, change.path)),
|
|
126
131
|
};
|
|
127
132
|
}
|
|
128
133
|
function queueWithin(reach, room, entries) {
|
|
129
|
-
return entries
|
|
130
|
-
(
|
|
134
|
+
return entries
|
|
135
|
+
.filter(({ batch }) => batch.changes.every((change) => covers(reach, room, change.path) &&
|
|
136
|
+
(change.kind !== 'move' || covers(reach, room, change.to))))
|
|
137
|
+
.map((entry) => {
|
|
138
|
+
const { between, ...batch } = entry.batch;
|
|
139
|
+
if (between === undefined)
|
|
140
|
+
return entry;
|
|
141
|
+
return wholly(reach, between.source.room) && wholly(reach, between.destination.room)
|
|
142
|
+
? entry
|
|
143
|
+
: { ...entry, batch };
|
|
144
|
+
});
|
|
131
145
|
}
|
|
132
146
|
function unreached(room) {
|
|
133
147
|
return runtimeError('room-not-held', `No Local Replica for ${room}`);
|
|
134
148
|
}
|
|
149
|
+
function lockedError(room) {
|
|
150
|
+
return runtimeError(ROOM_LOCKED, `${room} is locked until House confirms its access`, true);
|
|
151
|
+
}
|
|
152
|
+
function deviceUnreached() {
|
|
153
|
+
return runtimeError('device-unreached', 'Only the panel cleans up this device');
|
|
154
|
+
}
|
|
155
|
+
const ATTACH_REQUIRED = 'attach-required';
|
|
156
|
+
function attachRequired() {
|
|
157
|
+
return runtimeError(ATTACH_REQUIRED, 'App code takes a file in with binaryFile.attach');
|
|
158
|
+
}
|
|
159
|
+
function carriesFile(parts) {
|
|
160
|
+
return parts !== null && typeof parts === 'object' && Object.hasOwn(parts, 'file');
|
|
161
|
+
}
|
|
135
162
|
export function narrowed(runtime, given, told) {
|
|
136
163
|
const { md, watch } = runtime;
|
|
137
164
|
let reach = given;
|
|
138
165
|
let port = told;
|
|
139
166
|
const open = new Set();
|
|
140
|
-
function following(begin) {
|
|
167
|
+
function following(begin, locking = false) {
|
|
141
168
|
let stop = begin();
|
|
142
169
|
const restart = () => {
|
|
143
170
|
stop();
|
|
144
171
|
stop = begin();
|
|
145
172
|
};
|
|
146
173
|
open.add(restart);
|
|
174
|
+
const unwatch = locking ? runtime.watchLocks(restart) : () => { };
|
|
147
175
|
return () => {
|
|
148
176
|
open.delete(restart);
|
|
177
|
+
unwatch();
|
|
149
178
|
stop();
|
|
150
179
|
};
|
|
151
180
|
}
|
|
181
|
+
const unlocking = (rooms) => {
|
|
182
|
+
const locked = (rooms ?? []).filter((room) => runtime.locked(room));
|
|
183
|
+
return locked.length === 0
|
|
184
|
+
? null
|
|
185
|
+
: { pending: locked.map((room) => ({ room, awaits: 'unlock' })) };
|
|
186
|
+
};
|
|
187
|
+
const unlocked = (entries) => entries.filter((entry) => !runtime.locked(entry.room));
|
|
188
|
+
const intoLocked = (held) => held.some((move) => move?.room !== undefined && runtime.locked(move.room));
|
|
152
189
|
const within = (topic, input, deliver) => {
|
|
153
190
|
if (topic === 'rooms') {
|
|
154
191
|
return following(() => watch(topic, input, (rooms) => deliver(roomsWithin(reach, rooms))));
|
|
@@ -157,45 +194,60 @@ export function narrowed(runtime, given, told) {
|
|
|
157
194
|
return following(() => runtime.watchReadiness(port, reach, deliver));
|
|
158
195
|
}
|
|
159
196
|
if (topic === 'sync-status') {
|
|
160
|
-
return following(() => watch(topic, input, (status) =>
|
|
197
|
+
return following(() => watch(topic, input, (status) => {
|
|
198
|
+
const within = statusWithin(reach, status);
|
|
199
|
+
deliver({ ...within, attentionRequired: unlocked(within.attentionRequired) });
|
|
200
|
+
}), true);
|
|
161
201
|
}
|
|
162
202
|
if (topic === 'room-drafts') {
|
|
163
|
-
return following(() => watch(topic, input, (drafts) => deliver(draftsWithin(reach, drafts))));
|
|
203
|
+
return following(() => watch(topic, input, (drafts) => deliver(unlocked(draftsWithin(reach, drafts)))), true);
|
|
164
204
|
}
|
|
165
205
|
if (topic === 'queue') {
|
|
166
206
|
const room = input[0];
|
|
167
207
|
return following(() => {
|
|
168
|
-
if (!holds(reach, room)) {
|
|
208
|
+
if (!holds(reach, room) || runtime.locked(room)) {
|
|
169
209
|
deliver([]);
|
|
170
210
|
return () => { };
|
|
171
211
|
}
|
|
172
212
|
return watch(topic, input, (entries) => deliver(queueWithin(reach, room, entries)));
|
|
173
|
-
});
|
|
213
|
+
}, true);
|
|
174
214
|
}
|
|
175
215
|
if (topic === 'query') {
|
|
176
216
|
const plan = runtime.plan(input[0], reach);
|
|
177
217
|
let held = null;
|
|
178
218
|
return following(() => {
|
|
219
|
+
const locked = unlocking(plan.rooms);
|
|
220
|
+
if (locked !== null) {
|
|
221
|
+
const answer = { result: locked, keys: [] };
|
|
222
|
+
if (held === null || changeOf(held, answer) !== null)
|
|
223
|
+
deliver(answer);
|
|
224
|
+
held = digestOf(answer);
|
|
225
|
+
return () => { };
|
|
226
|
+
}
|
|
179
227
|
let first = true;
|
|
180
|
-
|
|
228
|
+
let open = true;
|
|
229
|
+
const heard = (message) => {
|
|
181
230
|
if (!first) {
|
|
182
|
-
held =
|
|
231
|
+
held = digestApplied(held, message);
|
|
183
232
|
deliver(message);
|
|
184
233
|
return;
|
|
185
234
|
}
|
|
186
235
|
first = false;
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
deliver(next.message);
|
|
236
|
+
const change = held === null ? message : changeOf(held, message);
|
|
237
|
+
held = digestOf(message);
|
|
238
|
+
if (change !== null)
|
|
239
|
+
deliver(change);
|
|
240
|
+
};
|
|
241
|
+
const current = { ...plan, reach: planReach(reach), locked: runtime.lockedRooms() };
|
|
242
|
+
const stop = runtime.watchPlan(current, (message) => {
|
|
243
|
+
if (open)
|
|
244
|
+
heard(message);
|
|
197
245
|
});
|
|
198
|
-
|
|
246
|
+
return () => {
|
|
247
|
+
open = false;
|
|
248
|
+
stop();
|
|
249
|
+
};
|
|
250
|
+
}, true);
|
|
199
251
|
}
|
|
200
252
|
if (topic === 'conversation') {
|
|
201
253
|
return following(() => {
|
|
@@ -215,60 +267,149 @@ export function narrowed(runtime, given, told) {
|
|
|
215
267
|
}
|
|
216
268
|
return watch(topic, input, deliver);
|
|
217
269
|
};
|
|
270
|
+
const files = new Map();
|
|
271
|
+
let handed = 0;
|
|
272
|
+
async function hand(reading) {
|
|
273
|
+
const answer = await reading;
|
|
274
|
+
if (answer.kind !== 'binary')
|
|
275
|
+
return answer;
|
|
276
|
+
handed += 1;
|
|
277
|
+
const file = String(handed);
|
|
278
|
+
files.set(file, answer.file);
|
|
279
|
+
return { ...answer, file };
|
|
280
|
+
}
|
|
218
281
|
const conversation = () => (conversing(reach) ? md.conversation : NO_CONVERSATION);
|
|
219
282
|
const chatDraft = () => (conversing(reach) ? md.chatDraft : NO_CHAT_DRAFT);
|
|
220
283
|
const view = {
|
|
221
284
|
...md,
|
|
222
|
-
rooms: () => roomsWithin(reach,
|
|
223
|
-
query: ((input) =>
|
|
224
|
-
|
|
225
|
-
runtime.
|
|
226
|
-
|
|
227
|
-
|
|
285
|
+
rooms: () => md.rooms().then((rooms) => roomsWithin(reach, rooms)),
|
|
286
|
+
query: ((input) => {
|
|
287
|
+
const plan = runtime.plan(input, reach);
|
|
288
|
+
return Promise.resolve(unlocking(plan.rooms) ?? runtime.query({ ...plan, locked: runtime.lockedRooms() }));
|
|
289
|
+
}),
|
|
290
|
+
search: (input) => port.search === 'required'
|
|
291
|
+
? runtime.search(input, reach, runtime.lockedRooms())
|
|
292
|
+
: Promise.resolve(undeclaredSearch()),
|
|
228
293
|
types(room) {
|
|
294
|
+
if (holds(reach, room) && runtime.locked(room))
|
|
295
|
+
throw lockedError(room);
|
|
229
296
|
if (wholly(reach, room))
|
|
230
297
|
return md.types(room);
|
|
231
298
|
if (!holds(reach, room))
|
|
232
299
|
return structuredClone(UNHELD_TYPES);
|
|
233
|
-
|
|
234
|
-
return typesWithin(reach, listed, md.types(room));
|
|
300
|
+
return typesWithin(reach, runtime.room(room), md.types(room));
|
|
235
301
|
},
|
|
236
302
|
async save(room, roomDrafts, writtenBy) {
|
|
237
303
|
if (!holds(reach, room))
|
|
238
304
|
throw unreached(room);
|
|
239
|
-
|
|
240
|
-
|
|
305
|
+
if (runtime.locked(room))
|
|
306
|
+
return { outcome: 'refused', code: ROOM_LOCKED, retryable: true };
|
|
307
|
+
const held = (await Promise.all(roomDrafts.map(({ path }) => md.roomDraft.read(room, path)))).map((draft) => draft?.parts.move);
|
|
308
|
+
const outside = roomDrafts.find(({ path }, at) => !covers(reach, room, path) || !moves(reach, room, held[at]));
|
|
241
309
|
if (outside !== undefined) {
|
|
242
310
|
return { outcome: 'refused', code: 'stale', retryable: false, file: outside.path };
|
|
243
311
|
}
|
|
312
|
+
if (intoLocked(held))
|
|
313
|
+
return { outcome: 'refused', code: ROOM_LOCKED, retryable: true };
|
|
244
314
|
return savedWithin(reach, room, await md.save(room, roomDrafts, writtenBy));
|
|
245
315
|
},
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
316
|
+
async saveParts(room, parts, writtenBy) {
|
|
317
|
+
if (!holds(reach, room))
|
|
318
|
+
throw unreached(room);
|
|
319
|
+
const filed = reach === null ? undefined : parts.find(({ parts: one }) => carriesFile(one));
|
|
320
|
+
if (filed !== undefined) {
|
|
321
|
+
return { outcome: 'refused', code: ATTACH_REQUIRED, retryable: false, file: filed.path };
|
|
322
|
+
}
|
|
323
|
+
if (runtime.locked(room))
|
|
324
|
+
return { outcome: 'refused', code: ROOM_LOCKED, retryable: true };
|
|
325
|
+
const held = parts.map(({ parts: one }) => readParts(one).move);
|
|
326
|
+
if (parts.some(({ path }, at) => !covers(reach, room, path) || !moves(reach, room, held[at]))) {
|
|
327
|
+
throw unreached(room);
|
|
328
|
+
}
|
|
329
|
+
if (intoLocked(held))
|
|
330
|
+
return { outcome: 'refused', code: ROOM_LOCKED, retryable: true };
|
|
331
|
+
return savedWithin(reach, room, await md.saveParts(room, parts, writtenBy));
|
|
332
|
+
},
|
|
333
|
+
resolve(room, path, destination) {
|
|
334
|
+
const at = runtime.located(room, path, destination);
|
|
335
|
+
return at !== null && !covers(reach, at.room, at.path)
|
|
336
|
+
? Promise.resolve(UNREADABLE)
|
|
337
|
+
: md.resolve(room, path, destination);
|
|
338
|
+
},
|
|
339
|
+
history: (room, path, query) => !covers(reach, room, path)
|
|
340
|
+
? Promise.resolve(failure({ kind: 'room-not-readable', locator: room }))
|
|
341
|
+
: runtime.locked(room)
|
|
342
|
+
? Promise.resolve(lockedRoom(room))
|
|
343
|
+
: md.history(room, path, query),
|
|
249
344
|
binaryFile: {
|
|
250
|
-
read: (room, path, revision) => covers(reach, room, path)
|
|
251
|
-
?
|
|
252
|
-
:
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
345
|
+
read: (room, path, revision) => !covers(reach, room, path)
|
|
346
|
+
? Promise.resolve(failure({ kind: 'room-not-readable', locator: room }))
|
|
347
|
+
: runtime.locked(room)
|
|
348
|
+
? Promise.resolve(lockedRoom(room))
|
|
349
|
+
: hand(md.binaryFile.read(room, path, revision)),
|
|
350
|
+
link: (room, path, revision) => !covers(reach, room, path)
|
|
351
|
+
? Promise.resolve(failure({ kind: 'room-not-readable', locator: room }))
|
|
352
|
+
: runtime.locked(room)
|
|
353
|
+
? Promise.resolve(lockedRoom(room))
|
|
354
|
+
: md.binaryFile.link(room, path, revision),
|
|
355
|
+
show: (room, path, revision) => !covers(reach, room, path)
|
|
356
|
+
? Promise.resolve(failure({ kind: 'room-not-readable', locator: room }))
|
|
357
|
+
: runtime.locked(room)
|
|
358
|
+
? Promise.resolve(lockedRoom(room))
|
|
359
|
+
: hand(md.binaryFile.show(room, path, revision)),
|
|
360
|
+
attach: (room, file) => !wholly(reach, room)
|
|
361
|
+
? Promise.resolve(failure({ kind: 'room-not-readable', locator: room }))
|
|
362
|
+
: runtime.locked(room)
|
|
363
|
+
? Promise.resolve(lockedRoom(room))
|
|
364
|
+
: md.binaryFile.attach(room, file),
|
|
365
|
+
async part(file, part) {
|
|
366
|
+
const key = files.get(file);
|
|
367
|
+
if (key === undefined)
|
|
368
|
+
return null;
|
|
369
|
+
const bytes = await md.binaryFile.part(key, part);
|
|
370
|
+
if (bytes === null)
|
|
371
|
+
files.delete(file);
|
|
372
|
+
return bytes;
|
|
373
|
+
},
|
|
256
374
|
},
|
|
257
|
-
reached: (room, roomVersion, path) => (path === undefined ? wholly(reach, room) : covers(reach, room, path)) &&
|
|
258
|
-
|
|
375
|
+
reached: async (room, roomVersion, path) => (path === undefined ? wholly(reach, room) : covers(reach, room, path)) &&
|
|
376
|
+
!runtime.locked(room) &&
|
|
377
|
+
(await md.reached(room, roomVersion, path)),
|
|
259
378
|
log: () => (reach === null ? md.log() : ''),
|
|
379
|
+
cleanUp: () => (reach === null ? md.cleanUp() : Promise.reject(deviceUnreached())),
|
|
260
380
|
roomDraft: {
|
|
261
|
-
list: () => md.roomDraft.list().then((drafts) => draftsWithin(reach, drafts)),
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
381
|
+
list: () => md.roomDraft.list().then((drafts) => unlocked(draftsWithin(reach, drafts))),
|
|
382
|
+
async read(room, path) {
|
|
383
|
+
if (!covers(reach, room, path))
|
|
384
|
+
return null;
|
|
385
|
+
if (runtime.locked(room))
|
|
386
|
+
throw lockedError(room);
|
|
387
|
+
return shownDraft(reach, await md.roomDraft.read(room, path));
|
|
388
|
+
},
|
|
389
|
+
write(room, path, revision, parts, next) {
|
|
390
|
+
try {
|
|
391
|
+
if (reach !== null && carriesFile(parts))
|
|
392
|
+
throw attachRequired();
|
|
393
|
+
const move = readParts(parts).move;
|
|
394
|
+
if (!covers(reach, room, path) || !moves(reach, room, move))
|
|
395
|
+
throw unreached(room);
|
|
396
|
+
if (runtime.locked(room))
|
|
397
|
+
throw lockedError(room);
|
|
398
|
+
if (intoLocked([move]))
|
|
399
|
+
throw lockedError(move.room);
|
|
400
|
+
}
|
|
401
|
+
catch (error) {
|
|
402
|
+
return Promise.reject(error);
|
|
266
403
|
}
|
|
267
|
-
return
|
|
404
|
+
return md.roomDraft
|
|
405
|
+
.write(room, path, revision, parts, next)
|
|
406
|
+
.then((written) => writeWithin(reach, written));
|
|
268
407
|
},
|
|
269
408
|
async discard(room, path, revision) {
|
|
270
409
|
if (!covers(reach, room, path))
|
|
271
410
|
return staleWrite(null);
|
|
411
|
+
if (runtime.locked(room))
|
|
412
|
+
throw lockedError(room);
|
|
272
413
|
return writeWithin(reach, await md.roomDraft.discard(room, path, revision));
|
|
273
414
|
},
|
|
274
415
|
},
|
|
@@ -285,6 +426,7 @@ export function narrowed(runtime, given, told) {
|
|
|
285
426
|
},
|
|
286
427
|
chatDraft: {
|
|
287
428
|
write: (id, draft, revision) => chatDraft().write(id, draft, revision),
|
|
429
|
+
prepend: (id, draft) => chatDraft().prepend(id, draft),
|
|
288
430
|
discard: (id) => chatDraft().discard(id),
|
|
289
431
|
},
|
|
290
432
|
observe: observing(within),
|
package/dist/react.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { MdRuntimeClient } from './client.js';
|
|
2
|
-
import type { AppRoom, ConnectionRefusal, SaveResult } from './connection.js';
|
|
2
|
+
import type { AppRoom, ConnectionRefusal, SavedRoomDraft, SaveResult } from './connection.js';
|
|
3
3
|
import type { Member, ServiceMode } from './adapter.js';
|
|
4
4
|
import type { ConversationAgent, ConversationEntry, ConversationOptions, ConversationView } from './conversation.js';
|
|
5
5
|
import { type RuntimeError } from './failure.js';
|
|
@@ -35,9 +35,9 @@ export type Saving = {
|
|
|
35
35
|
readonly busy: boolean;
|
|
36
36
|
readonly outcome: SaveResult | null;
|
|
37
37
|
readonly failure: RuntimeError | null;
|
|
38
|
-
save(room: string,
|
|
38
|
+
save(room: string, parts: ReadonlyMap<string, RoomDraftParts>): Promise<SaveResult>;
|
|
39
|
+
saveWritten(room: string, roomDrafts: readonly SavedRoomDraft[]): Promise<SaveResult>;
|
|
39
40
|
};
|
|
40
|
-
export declare function saveRoomDrafts(client: MdRuntimeClient, room: string, roomDrafts: ReadonlyMap<string, RoomDraftParts>): Promise<SaveResult>;
|
|
41
41
|
export declare function useSave(client: MdRuntimeClient): Saving;
|
|
42
42
|
export {};
|
|
43
43
|
//# sourceMappingURL=react.d.ts.map
|