@agentshouse/mdruntime 0.1.0-c3903a68dcbbf → 0.1.0-c56daf494ecb4
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 +184 -92
- package/README.md +22 -12
- package/dist/adapter.d.ts +125 -63
- 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 +93 -39
- package/dist/change-set.d.ts.map +1 -1
- package/dist/change-set.js +20 -17
- 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 +34 -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 +60 -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 +26 -0
- package/dist/chat/list.d.ts.map +1 -0
- package/dist/chat/list.js +62 -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 +21 -0
- package/dist/chat/messages.d.ts.map +1 -0
- package/dist/chat/messages.js +151 -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 +645 -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 +33 -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 +17 -13
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +68 -31
- package/dist/collection.d.ts +6 -13
- package/dist/collection.d.ts.map +1 -1
- package/dist/collection.js +56 -29
- package/dist/connection.d.ts +28 -33
- package/dist/connection.d.ts.map +1 -1
- package/dist/connection.js +951 -745
- package/dist/conversation.d.ts +32 -13
- package/dist/conversation.d.ts.map +1 -1
- package/dist/conversation.js +293 -108
- 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/host.d.ts +9 -3
- package/dist/host.d.ts.map +1 -1
- package/dist/host.js +49 -68
- package/dist/identity.d.ts +3 -0
- package/dist/identity.d.ts.map +1 -1
- package/dist/identity.js +13 -1
- package/dist/index.d.ts +9 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/memory.d.ts +14 -7
- package/dist/memory.d.ts.map +1 -1
- package/dist/memory.js +137 -46
- package/dist/model.d.ts +13 -12
- package/dist/model.d.ts.map +1 -1
- package/dist/model.js +6 -3
- package/dist/observation.d.ts +2 -0
- package/dist/observation.d.ts.map +1 -1
- package/dist/observation.js +24 -14
- 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 -23
- package/dist/outcome.d.ts.map +1 -1
- package/dist/outcome.js +41 -1
- package/dist/overlay.d.ts +14 -3
- package/dist/overlay.d.ts.map +1 -1
- package/dist/overlay.js +75 -37
- 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 +12 -3
- package/dist/query.d.ts.map +1 -1
- package/dist/query.js +78 -36
- package/dist/reach.d.ts +42 -0
- package/dist/reach.d.ts.map +1 -0
- package/dist/reach.js +294 -0
- package/dist/react.d.ts +41 -0
- package/dist/react.d.ts.map +1 -0
- package/dist/react.js +64 -0
- package/dist/read-side.d.ts +4 -0
- package/dist/read-side.d.ts.map +1 -1
- package/dist/read-side.js +125 -56
- package/dist/refresh.d.ts +12 -1
- package/dist/refresh.d.ts.map +1 -1
- package/dist/refresh.js +44 -36
- package/dist/replica.d.ts +9 -6
- package/dist/replica.d.ts.map +1 -1
- package/dist/replica.js +83 -68
- package/dist/room-draft.d.ts +29 -9
- package/dist/room-draft.d.ts.map +1 -1
- package/dist/room-draft.js +137 -26
- package/dist/rows.d.ts +7 -2
- package/dist/rows.d.ts.map +1 -1
- package/dist/rows.js +85 -40
- package/dist/save.d.ts +27 -3
- package/dist/save.d.ts.map +1 -1
- package/dist/save.js +435 -86
- package/dist/search.d.ts +3 -2
- package/dist/search.d.ts.map +1 -1
- package/dist/status.d.ts +2 -2
- package/dist/status.d.ts.map +1 -1
- package/dist/status.js +0 -8
- package/dist/store.d.ts +41 -25
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +315 -191
- package/dist/wire.d.ts +58 -19
- package/dist/wire.d.ts.map +1 -1
- package/dist/wire.js +65 -67
- 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/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
|
+
}
|
package/dist/read-side.d.ts
CHANGED
|
@@ -10,5 +10,9 @@ export type ReadSide = {
|
|
|
10
10
|
document(room: string, path: string): SearchedDocument | null;
|
|
11
11
|
close(): void;
|
|
12
12
|
};
|
|
13
|
+
export declare function reconciled(previous: KeyedResult, next: KeyedResult): {
|
|
14
|
+
keyed: KeyedResult;
|
|
15
|
+
change: QueryChange;
|
|
16
|
+
} | null;
|
|
13
17
|
export declare function createReadSide(): ReadSide;
|
|
14
18
|
//# sourceMappingURL=read-side.d.ts.map
|
package/dist/read-side.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"read-side.d.ts","sourceRoot":"","sources":["../src/read-side.ts"],"names":[],"mappings":"
|
|
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"}
|
package/dist/read-side.js
CHANGED
|
@@ -1,62 +1,71 @@
|
|
|
1
|
-
import { and, BasicIndex, configureIndexDevMode, count, createCollection, createLiveQueryCollection, deepEquals, eq,
|
|
1
|
+
import { and, BasicIndex, configureIndexDevMode, count, createCollection, createLiveQueryCollection, deepEquals, eq, inArray, or, toArray, } from '@tanstack/db';
|
|
2
|
+
import { ARRAY_INDEX, pointerSegments } from '@agentshouse/mdmodel';
|
|
2
3
|
import { rowsOf } from './observation.js';
|
|
3
4
|
import { documentKey } from './rows.js';
|
|
4
5
|
function every(expressions) {
|
|
5
6
|
const [first, second, ...rest] = expressions;
|
|
6
7
|
return second === undefined ? first : and(first, second, ...rest);
|
|
7
8
|
}
|
|
8
|
-
function
|
|
9
|
-
|
|
10
|
-
return second === undefined ? first : or(first, second, ...rest);
|
|
9
|
+
function same(held, value) {
|
|
10
|
+
return Array.isArray(held) ? held.includes(value) : held === value;
|
|
11
11
|
}
|
|
12
|
-
function
|
|
13
|
-
|
|
12
|
+
function ordered(held, [operator, bound]) {
|
|
13
|
+
if (typeof held !== typeof bound || held === null || typeof held === 'object')
|
|
14
|
+
return false;
|
|
15
|
+
const left = held;
|
|
16
|
+
const right = bound;
|
|
17
|
+
if (operator === 'gt')
|
|
18
|
+
return left > right;
|
|
19
|
+
if (operator === 'gte')
|
|
20
|
+
return left >= right;
|
|
21
|
+
if (operator === 'lt')
|
|
22
|
+
return left < right;
|
|
23
|
+
return left <= right;
|
|
14
24
|
}
|
|
15
|
-
function
|
|
25
|
+
function satisfied(test, held) {
|
|
16
26
|
if (test.op === 'eq')
|
|
17
|
-
return
|
|
18
|
-
if (test.op === 'ne')
|
|
19
|
-
return test.value
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
const compare = { gt, gte, lt, lte };
|
|
37
|
-
return every(test.bounds.map(([operator, bound]) => compare[operator](field, bound)));
|
|
38
|
-
}
|
|
39
|
-
if (test.op === 'all') {
|
|
40
|
-
return every([not(isUndefined(size)), ...test.values.map((value) => inArray(value, field))]);
|
|
41
|
-
}
|
|
42
|
-
if (test.op === 'size')
|
|
43
|
-
return eq(size, test.size);
|
|
44
|
-
return test.exists ? not(isUndefined(written)) : isUndefined(written);
|
|
27
|
+
return same(held, test.value);
|
|
28
|
+
if (test.op === 'ne')
|
|
29
|
+
return !same(held, test.value);
|
|
30
|
+
if (test.op === 'in')
|
|
31
|
+
return test.values.some((value) => same(held, value));
|
|
32
|
+
if (test.op === 'nin')
|
|
33
|
+
return !test.values.some((value) => same(held, value));
|
|
34
|
+
if (test.op === 'range')
|
|
35
|
+
return test.bounds.every((bound) => ordered(held, bound));
|
|
36
|
+
if (test.op === 'all')
|
|
37
|
+
return Array.isArray(held) && test.values.every((value) => same(held, value));
|
|
38
|
+
return Array.isArray(held) && held.length === test.size;
|
|
39
|
+
}
|
|
40
|
+
function tested(test, reached) {
|
|
41
|
+
if (test.op === 'exists')
|
|
42
|
+
return test.exists === (reached !== undefined);
|
|
43
|
+
if (reached === undefined)
|
|
44
|
+
return test.op === 'ne' || test.op === 'nin';
|
|
45
|
+
return reached.some((held) => satisfied(test, held));
|
|
45
46
|
}
|
|
46
47
|
function conditioned(condition, row) {
|
|
47
48
|
if ('every' in condition)
|
|
48
|
-
return
|
|
49
|
+
return condition.every.every((item) => conditioned(item, row));
|
|
49
50
|
if ('some' in condition)
|
|
50
|
-
return
|
|
51
|
-
return tested(condition.test, row.
|
|
51
|
+
return condition.some.some((item) => conditioned(item, row));
|
|
52
|
+
return tested(condition.test, row.reached[condition.field]);
|
|
52
53
|
}
|
|
53
|
-
function
|
|
54
|
+
function narrowed(query, where, alias) {
|
|
55
|
+
return where === null ? query : query.fn.where((row) => conditioned(where, row[alias]));
|
|
56
|
+
}
|
|
57
|
+
function reached(reach, room, document) {
|
|
58
|
+
return reach === null
|
|
59
|
+
? []
|
|
60
|
+
: [or(inArray(room, [...reach.rooms]), inArray(document, [...reach.documents]))];
|
|
61
|
+
}
|
|
62
|
+
function scoped(scope, row, rooms, reach) {
|
|
54
63
|
return every([
|
|
55
64
|
eq(row.kind, 'document'),
|
|
56
65
|
...(rooms === null ? [] : [inArray(row.room, [...rooms])]),
|
|
66
|
+
...reached(reach, row.room, row.key),
|
|
57
67
|
...(scope.types === null ? [] : [inArray(row.type, [...scope.types])]),
|
|
58
68
|
...(scope.pathPrefix === null ? [] : [inArray(scope.pathPrefix, row.directories)]),
|
|
59
|
-
...(scope.where === null ? [] : [conditioned(scope.where, row)]),
|
|
60
69
|
]);
|
|
61
70
|
}
|
|
62
71
|
function keyed(key, row) {
|
|
@@ -68,25 +77,26 @@ function live(query) {
|
|
|
68
77
|
startSync: true,
|
|
69
78
|
});
|
|
70
79
|
}
|
|
71
|
-
function related(q, rows, scope, field, kept) {
|
|
80
|
+
function related(q, rows, scope, field, kept, reach) {
|
|
72
81
|
const matched = kept === 'source' ? 'target' : 'source';
|
|
73
82
|
const from = q.from({ r: rows });
|
|
74
|
-
|
|
75
|
-
.where(({ r }) => every([eq(r.kind, 'reference'), ...(field === null ? [] : [
|
|
83
|
+
const joined = from
|
|
84
|
+
.where(({ r }) => every([eq(r.kind, 'reference'), ...(field === null ? [] : [inArray(field, r.forms)])]))
|
|
76
85
|
.innerJoin({ m: rows }, ({ r, m }) => eq(r[matched], m.key))
|
|
77
|
-
.where(({ m }) => scoped(scope, m, null))
|
|
86
|
+
.where(({ m }) => scoped(scope, m, null, reach));
|
|
87
|
+
return narrowed(joined, scope.where, 'm')
|
|
78
88
|
.groupBy(({ r }) => r[kept])
|
|
79
89
|
.select(({ r }) => ({ key: r[kept] }));
|
|
80
90
|
}
|
|
81
91
|
function filtered(q, rows, plan) {
|
|
82
92
|
const from = q.from({ d: rows });
|
|
83
|
-
let query = from.where(({ d }) => scoped(plan.root, d, plan.rooms));
|
|
93
|
+
let query = narrowed(from.where(({ d }) => scoped(plan.root, d, plan.rooms, plan.reach)), plan.root.where, 'd');
|
|
84
94
|
if (plan.hop !== null) {
|
|
85
|
-
const hop = related(q, rows, plan.hop, plan.hop.field, 'source');
|
|
95
|
+
const hop = related(q, rows, plan.hop, plan.hop.field, 'source', plan.reach);
|
|
86
96
|
query = query.innerJoin({ h: hop }, ({ d, h }) => eq(d.key, h.key));
|
|
87
97
|
}
|
|
88
98
|
if (plan.backlinks !== null) {
|
|
89
|
-
const backlinks = related(q, rows, plan.backlinks, plan.backlinks.field, 'target');
|
|
99
|
+
const backlinks = related(q, rows, plan.backlinks, plan.backlinks.field, 'target', plan.reach);
|
|
90
100
|
query = query.innerJoin({ k: backlinks }, ({ d, k }) => eq(d.key, k.key));
|
|
91
101
|
}
|
|
92
102
|
return query;
|
|
@@ -111,20 +121,20 @@ function documents(q, rows, plan, shape) {
|
|
|
111
121
|
room: d.room,
|
|
112
122
|
path: d.path,
|
|
113
123
|
type: d.type,
|
|
114
|
-
|
|
115
|
-
...(
|
|
124
|
+
binary: d.binary,
|
|
125
|
+
...(shape.fields === null ? {} : { fields: d.fields }),
|
|
116
126
|
...(shape.sections === 'all' ? { sections: b.sections } : {}),
|
|
117
127
|
...(Array.isArray(shape.sections) ? named('section', shape.sections, b.sections) : {}),
|
|
118
128
|
...(shape.preamble ? { preamble: b.preamble } : {}),
|
|
119
129
|
...(shape.markdown ? { markdown: b.markdown } : {}),
|
|
120
|
-
...(shape.backlinks ? { backlinks: toArray(backlinked(q, rows, d)) } : {}),
|
|
130
|
+
...(shape.backlinks ? { backlinks: toArray(backlinked(q, rows, d, plan.reach)) } : {}),
|
|
121
131
|
...(shape.change ? { change: d.change } : {}),
|
|
122
132
|
}));
|
|
123
133
|
}
|
|
124
|
-
function backlinked(q, rows, document) {
|
|
134
|
+
function backlinked(q, rows, document, reach) {
|
|
125
135
|
const from = q.from({ r: rows });
|
|
126
136
|
return from
|
|
127
|
-
.where(({ r }) => eq(r.target, document.key))
|
|
137
|
+
.where(({ r }) => every([eq(r.target, document.key), ...reached(reach, r.room, r.source)]))
|
|
128
138
|
.orderBy(({ r }) => r.path, { stringSort: 'lexical' })
|
|
129
139
|
.orderBy(({ r }) => r.field, { stringSort: 'lexical' })
|
|
130
140
|
.select(({ r }) => ({ path: r.path, type: r.type, field: r.field }));
|
|
@@ -170,16 +180,75 @@ function part(row, prefix, names, whole) {
|
|
|
170
180
|
return whole;
|
|
171
181
|
return present(names.map((name, index) => [name, row[`${prefix}${index}`]]));
|
|
172
182
|
}
|
|
183
|
+
function masked(pointers) {
|
|
184
|
+
const root = { whole: false, members: new Map() };
|
|
185
|
+
for (const pointer of pointers) {
|
|
186
|
+
let mask = root;
|
|
187
|
+
for (const token of pointerSegments(pointer)) {
|
|
188
|
+
const next = mask.members.get(token) ?? { whole: false, members: new Map() };
|
|
189
|
+
mask.members.set(token, next);
|
|
190
|
+
mask = next;
|
|
191
|
+
}
|
|
192
|
+
mask.whole = true;
|
|
193
|
+
}
|
|
194
|
+
return root;
|
|
195
|
+
}
|
|
196
|
+
function merged(left, right) {
|
|
197
|
+
if (left === undefined)
|
|
198
|
+
return right;
|
|
199
|
+
const members = new Map(left.members);
|
|
200
|
+
for (const [token, mask] of right.members)
|
|
201
|
+
members.set(token, merged(members.get(token), mask));
|
|
202
|
+
return { whole: left.whole || right.whole, members };
|
|
203
|
+
}
|
|
204
|
+
function cut(value, mask) {
|
|
205
|
+
if (mask.whole)
|
|
206
|
+
return value;
|
|
207
|
+
if (Array.isArray(value)) {
|
|
208
|
+
const each = {
|
|
209
|
+
whole: false,
|
|
210
|
+
members: new Map([...mask.members].filter(([token]) => !ARRAY_INDEX.test(token))),
|
|
211
|
+
};
|
|
212
|
+
const kept = [];
|
|
213
|
+
value.forEach((item, index) => {
|
|
214
|
+
const part = cut(item, merged(mask.members.get(String(index)), each));
|
|
215
|
+
if (part !== undefined)
|
|
216
|
+
kept[index] = part;
|
|
217
|
+
});
|
|
218
|
+
return kept.length === 0 ? undefined : kept;
|
|
219
|
+
}
|
|
220
|
+
if (typeof value !== 'object' || value === null)
|
|
221
|
+
return undefined;
|
|
222
|
+
const kept = Object.entries(value).flatMap(([key, held]) => {
|
|
223
|
+
const member = mask.members.get(key);
|
|
224
|
+
const part = member === undefined ? undefined : cut(held, member);
|
|
225
|
+
return part === undefined ? [] : [[key, part]];
|
|
226
|
+
});
|
|
227
|
+
return kept.length === 0 ? undefined : Object.fromEntries(kept);
|
|
228
|
+
}
|
|
229
|
+
function selected(fields, pointers) {
|
|
230
|
+
return (cut(fields, masked(pointers)) ?? {});
|
|
231
|
+
}
|
|
173
232
|
function documentOf(row, shape) {
|
|
174
|
-
if (row.type === null)
|
|
175
|
-
|
|
233
|
+
if (row.type === null) {
|
|
234
|
+
const binary = row.binary;
|
|
235
|
+
return {
|
|
236
|
+
room: row.room,
|
|
237
|
+
path: row.path,
|
|
238
|
+
...(binary === null ? {} : { binaryFile: binary }),
|
|
239
|
+
};
|
|
240
|
+
}
|
|
176
241
|
return {
|
|
177
242
|
room: row.room,
|
|
178
243
|
path: row.path,
|
|
179
244
|
type: row.type,
|
|
180
245
|
...(shape.fields === null
|
|
181
246
|
? {}
|
|
182
|
-
: {
|
|
247
|
+
: {
|
|
248
|
+
fields: shape.fields === 'all'
|
|
249
|
+
? row.fields
|
|
250
|
+
: selected(row.fields, shape.fields),
|
|
251
|
+
}),
|
|
183
252
|
...(shape.sections === null
|
|
184
253
|
? {}
|
|
185
254
|
: {
|
|
@@ -214,7 +283,7 @@ function keyedOf(plan, entries) {
|
|
|
214
283
|
keys: bounded.map(([key]) => key),
|
|
215
284
|
};
|
|
216
285
|
}
|
|
217
|
-
function reconciled(previous, next) {
|
|
286
|
+
export function reconciled(previous, next) {
|
|
218
287
|
const before = rowsOf(previous.result);
|
|
219
288
|
const held = new Map(previous.keys.map((key, index) => [key, before[index]]));
|
|
220
289
|
const changed = [];
|
package/dist/refresh.d.ts
CHANGED
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
import type { Adapter, AdapterFailure, Authorization, RetryableRefusal } from './adapter.js';
|
|
2
|
+
import type { Remodel } from './bootstrap.js';
|
|
2
3
|
import { type ConfirmedLayer } from './replica.js';
|
|
4
|
+
import type { ReplicaRecord } from './store.js';
|
|
3
5
|
import { type Refused, type Unconfirmed } from './transfer.js';
|
|
6
|
+
export type Advancement = {
|
|
7
|
+
kind: 'still-current';
|
|
8
|
+
} | {
|
|
9
|
+
kind: 'advanced';
|
|
10
|
+
record: ReplicaRecord;
|
|
11
|
+
} | {
|
|
12
|
+
kind: 'beyond-horizon';
|
|
13
|
+
} | RetryableRefusal | Unconfirmed | AdapterFailure;
|
|
4
14
|
export type RefreshOutcome = {
|
|
5
15
|
kind: 'still-current';
|
|
6
16
|
} | {
|
|
@@ -9,5 +19,6 @@ export type RefreshOutcome = {
|
|
|
9
19
|
} | {
|
|
10
20
|
kind: 'beyond-horizon';
|
|
11
21
|
} | RetryableRefusal | Unconfirmed | Refused | AdapterFailure;
|
|
12
|
-
export declare function
|
|
22
|
+
export declare function advancement(adapter: Adapter, authorization: Authorization, held: ReplicaRecord, remodel: Remodel, continuing: () => boolean): Promise<Advancement>;
|
|
23
|
+
export declare function refreshRoom(adapter: Adapter, authorization: Authorization, confirmed: ConfirmedLayer, remodel: Remodel, continuing: () => boolean): Promise<RefreshOutcome>;
|
|
13
24
|
//# sourceMappingURL=refresh.d.ts.map
|
package/dist/refresh.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"refresh.d.ts","sourceRoot":"","sources":["../src/refresh.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,OAAO,EACP,cAAc,EACd,aAAa,EAGb,gBAAgB,
|
|
1
|
+
{"version":3,"file":"refresh.d.ts","sourceRoot":"","sources":["../src/refresh.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,OAAO,EACP,cAAc,EACd,aAAa,EAGb,gBAAgB,EACjB,MAAM,cAAc,CAAC;AAEtB,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAc,KAAK,cAAc,EAAE,MAAM,cAAc,CAAC;AAC/D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAe,KAAK,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5E,MAAM,MAAM,WAAW,GACnB;IAAE,IAAI,EAAE,eAAe,CAAA;CAAE,GACzB;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,MAAM,EAAE,aAAa,CAAA;CAAE,GAC3C;IAAE,IAAI,EAAE,gBAAgB,CAAA;CAAE,GAC1B,gBAAgB,GAChB,WAAW,GACX,cAAc,CAAC;AAEnB,MAAM,MAAM,cAAc,GACtB;IAAE,IAAI,EAAE,eAAe,CAAA;CAAE,GACzB;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,SAAS,EAAE,cAAc,CAAA;CAAE,GAC/C;IAAE,IAAI,EAAE,gBAAgB,CAAA;CAAE,GAC1B,gBAAgB,GAChB,WAAW,GACX,OAAO,GACP,cAAc,CAAC;AAEnB,wBAAsB,WAAW,CAC/B,OAAO,EAAE,OAAO,EAChB,aAAa,EAAE,aAAa,EAC5B,IAAI,EAAE,aAAa,EACnB,OAAO,EAAE,OAAO,EAChB,UAAU,EAAE,MAAM,OAAO,GACxB,OAAO,CAAC,WAAW,CAAC,CAwEtB;AAED,wBAAsB,WAAW,CAC/B,OAAO,EAAE,OAAO,EAChB,aAAa,EAAE,aAAa,EAC5B,SAAS,EAAE,cAAc,EACzB,OAAO,EAAE,OAAO,EAChB,UAAU,EAAE,MAAM,OAAO,GACxB,OAAO,CAAC,cAAc,CAAC,CAKzB"}
|
package/dist/refresh.js
CHANGED
|
@@ -1,48 +1,47 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { acceptedBinaries } from './overlay.js';
|
|
2
2
|
import { readStaged } from './replica.js';
|
|
3
3
|
import { unconfirmed } from './transfer.js';
|
|
4
|
-
export async function
|
|
5
|
-
const locator =
|
|
6
|
-
const fromRoomVersion =
|
|
4
|
+
export async function advancement(adapter, authorization, held, remodel, continuing) {
|
|
5
|
+
const locator = held.locator;
|
|
6
|
+
const fromRoomVersion = held.roomVersion;
|
|
7
7
|
const first = await adapter.refresh(authorization, {
|
|
8
8
|
locator,
|
|
9
|
-
selection:
|
|
9
|
+
selection: held.replica.selection,
|
|
10
10
|
fromRoomVersion,
|
|
11
|
-
...(minPosition === undefined ? {} : { minPosition }),
|
|
12
11
|
});
|
|
13
12
|
if (first.kind !== 'net-advancement')
|
|
14
13
|
return first;
|
|
15
14
|
const roomVersion = first.roomVersion;
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
const
|
|
21
|
-
const
|
|
15
|
+
const models = remodel(first.models, {
|
|
16
|
+
collection: held.model,
|
|
17
|
+
selection: held.selectionModel,
|
|
18
|
+
});
|
|
19
|
+
const documents = { ...held.documents };
|
|
20
|
+
const revisions = { ...held.revisions };
|
|
21
|
+
const changes = { ...held.changes };
|
|
22
|
+
const written = { ...held.written };
|
|
23
|
+
const binaries = { ...held.binaries };
|
|
22
24
|
const stage = (page) => {
|
|
23
|
-
if (page.attachments !== undefined)
|
|
24
|
-
attachments.push(page.attachments);
|
|
25
|
-
Object.assign(documents, page.documents);
|
|
26
|
-
Object.assign(revisions, page.revisions);
|
|
27
25
|
for (const path of Object.keys(page.documents)) {
|
|
28
|
-
|
|
26
|
+
delete binaries[path];
|
|
29
27
|
delete changes[path];
|
|
30
28
|
written[path] = roomVersion;
|
|
31
29
|
}
|
|
32
|
-
for (const
|
|
33
|
-
delete documents[
|
|
34
|
-
delete
|
|
35
|
-
delete
|
|
36
|
-
delete written[target];
|
|
37
|
-
binaryTargets.add(target);
|
|
30
|
+
for (const path of Object.keys(page.binaryFiles)) {
|
|
31
|
+
delete documents[path];
|
|
32
|
+
delete changes[path];
|
|
33
|
+
delete written[path];
|
|
38
34
|
}
|
|
35
|
+
Object.assign(documents, page.documents);
|
|
36
|
+
Object.assign(binaries, acceptedBinaries(page.binaryFiles));
|
|
37
|
+
Object.assign(revisions, page.revisions);
|
|
39
38
|
Object.assign(changes, page.changes);
|
|
40
39
|
for (const path of page.removals) {
|
|
41
40
|
delete documents[path];
|
|
42
41
|
delete revisions[path];
|
|
43
42
|
delete changes[path];
|
|
44
43
|
delete written[path];
|
|
45
|
-
|
|
44
|
+
delete binaries[path];
|
|
46
45
|
}
|
|
47
46
|
};
|
|
48
47
|
stage(first);
|
|
@@ -52,9 +51,8 @@ export async function refreshRoom(adapter, authorization, confirmed, continuing,
|
|
|
52
51
|
return unconfirmed;
|
|
53
52
|
const page = await adapter.refresh(authorization, {
|
|
54
53
|
locator,
|
|
55
|
-
selection:
|
|
54
|
+
selection: held.replica.selection,
|
|
56
55
|
fromRoomVersion,
|
|
57
|
-
...(minPosition === undefined ? {} : { minPosition }),
|
|
58
56
|
pageToken,
|
|
59
57
|
});
|
|
60
58
|
if (page.kind === 'still-current' || page.kind === 'beyond-horizon')
|
|
@@ -66,15 +64,25 @@ export async function refreshRoom(adapter, authorization, confirmed, continuing,
|
|
|
66
64
|
stage(page);
|
|
67
65
|
pageToken = page.pageToken;
|
|
68
66
|
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
67
|
+
return {
|
|
68
|
+
kind: 'advanced',
|
|
69
|
+
record: {
|
|
70
|
+
...held,
|
|
71
|
+
model: models.collection,
|
|
72
|
+
selectionModel: models.selection,
|
|
73
|
+
roomVersion,
|
|
74
|
+
documents,
|
|
75
|
+
binaries,
|
|
76
|
+
revisions,
|
|
77
|
+
changes,
|
|
78
|
+
written,
|
|
79
|
+
},
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
export async function refreshRoom(adapter, authorization, confirmed, remodel, continuing) {
|
|
83
|
+
const advanced = await advancement(adapter, authorization, confirmed.record, remodel, continuing);
|
|
84
|
+
if (advanced.kind !== 'advanced')
|
|
85
|
+
return advanced;
|
|
86
|
+
const staged = readStaged(advanced.record, confirmed);
|
|
79
87
|
return staged.kind === 'staged' ? { kind: 'advanced', confirmed: staged.confirmed } : staged;
|
|
80
88
|
}
|
package/dist/replica.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type ChangeBatch } from './change.js';
|
|
2
2
|
import { type Collection, type Composition } from './collection.js';
|
|
3
3
|
import { type Layer } from './overlay.js';
|
|
4
|
-
import {
|
|
4
|
+
import type { MutationResult } from './adapter.js';
|
|
5
5
|
import type { ReplicaRecord } from './store.js';
|
|
6
6
|
import type { Refused } from './transfer.js';
|
|
7
7
|
export type ConfirmedLayer = {
|
|
@@ -29,15 +29,18 @@ type ReplayStep = {
|
|
|
29
29
|
collection?: Collection;
|
|
30
30
|
};
|
|
31
31
|
export declare function compositionOf(record: ReplicaRecord): Composition;
|
|
32
|
-
export declare function
|
|
32
|
+
export declare function confirmedOf(record: ReplicaRecord, previous?: ConfirmedLayer): ConfirmedLayer;
|
|
33
33
|
export declare function sameMembership(record: ReplicaRecord, other: ReplicaRecord): boolean;
|
|
34
34
|
export declare function readStaged(record: ReplicaRecord, previous?: ConfirmedLayer): Staged;
|
|
35
35
|
export declare function readReclassified(record: ReplicaRecord, previous: ConfirmedLayer): Staged | {
|
|
36
36
|
kind: 'deferred';
|
|
37
37
|
};
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
export declare function
|
|
38
|
+
type Accepted = Extract<MutationResult, {
|
|
39
|
+
kind: 'accepted';
|
|
40
|
+
}>;
|
|
41
|
+
export declare function applyReturned(confirmed: ConfirmedLayer, submitted: ChangeBatch, accepted: Accepted, roomVersion: string, writtenAt: string): Staged;
|
|
42
|
+
export declare function replicaOf(confirmed: ConfirmedLayer, queue: readonly ChangeBatch[], previous?: Replica): Replica;
|
|
43
|
+
export declare function landed(batch: ChangeBatch, confirmed: ConfirmedLayer, current?: Readonly<Record<string, string>>): boolean;
|
|
44
|
+
export declare function withdrawals(confirmed: ConfirmedLayer, queue: readonly ChangeBatch[], withdrawable: (batch: ChangeBatch) => boolean, local: boolean): readonly ChangeBatch[];
|
|
42
45
|
export {};
|
|
43
46
|
//# sourceMappingURL=replica.d.ts.map
|
package/dist/replica.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"replica.d.ts","sourceRoot":"","sources":["../src/replica.ts"],"names":[],"mappings":"AACA,OAAO,
|
|
1
|
+
{"version":3,"file":"replica.d.ts","sourceRoot":"","sources":["../src/replica.ts"],"names":[],"mappings":"AACA,OAAO,EAAmC,KAAK,WAAW,EAAqB,MAAM,aAAa,CAAC;AACnG,OAAO,EAIL,KAAK,UAAU,EACf,KAAK,WAAW,EACjB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAML,KAAK,KAAK,EACX,MAAM,cAAc,CAAC;AAEtB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAE7C,MAAM,MAAM,cAAc,GAAG;IAC3B,MAAM,EAAE,aAAa,CAAC;IACtB,UAAU,EAAE,UAAU,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,KAAK,GAAG;IACjC,UAAU,EAAE,UAAU,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,MAAM,GAAG;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,SAAS,EAAE,cAAc,CAAA;CAAE,GAAG,OAAO,CAAC;AAE7E,MAAM,MAAM,OAAO,GAAG;IACpB,SAAS,EAAE,cAAc,CAAC;IAC1B,KAAK,EAAE,SAAS,WAAW,EAAE,CAAC;IAC9B,OAAO,EAAE,YAAY,CAAC;IACtB,MAAM,EAAE,SAAS,UAAU,EAAE,CAAC;CAC/B,CAAC;AAEF,KAAK,UAAU,GAAG;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,KAAK,CAAC;IACd,KAAK,EAAE,KAAK,CAAC;IACb,SAAS,EAAE,WAAW,CAAC;IACvB,UAAU,CAAC,EAAE,UAAU,CAAC;CACzB,CAAC;AAEF,wBAAgB,aAAa,CAAC,MAAM,EAAE,aAAa,GAAG,WAAW,CAQhE;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,aAAa,EAAE,QAAQ,CAAC,EAAE,cAAc,GAAG,cAAc,CAK5F;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,aAAa,EAAE,KAAK,EAAE,aAAa,GAAG,OAAO,CAKnF;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,aAAa,EAAE,QAAQ,CAAC,EAAE,cAAc,GAAG,MAAM,CA2BnF;AAED,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,aAAa,EACrB,QAAQ,EAAE,cAAc,GACvB,MAAM,GAAG;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,CAW/B;AAoBD,KAAK,QAAQ,GAAG,OAAO,CAAC,cAAc,EAAE;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,CAAC,CAAC;AAE9D,wBAAgB,aAAa,CAC3B,SAAS,EAAE,cAAc,EACzB,SAAS,EAAE,WAAW,EACtB,QAAQ,EAAE,QAAQ,EAClB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,GAChB,MAAM,CA+BR;AAgDD,wBAAgB,SAAS,CACvB,SAAS,EAAE,cAAc,EACzB,KAAK,EAAE,SAAS,WAAW,EAAE,EAC7B,QAAQ,CAAC,EAAE,OAAO,GACjB,OAAO,CA8BT;AA0ED,wBAAgB,MAAM,CACpB,KAAK,EAAE,WAAW,EAClB,SAAS,EAAE,cAAc,EACzB,OAAO,GAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAM,GAC7C,OAAO,CAiBT;AAED,wBAAgB,WAAW,CACzB,SAAS,EAAE,cAAc,EACzB,KAAK,EAAE,SAAS,WAAW,EAAE,EAC7B,YAAY,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,OAAO,EAC7C,KAAK,EAAE,OAAO,GACb,SAAS,WAAW,EAAE,CA2BxB"}
|