@agentshouse/mdruntime 0.1.0-cacb4c3f6734e → 0.1.0-cb0eb0d87ff49
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 +164 -99
- package/README.md +13 -3
- package/dist/adapter.d.ts +72 -16
- package/dist/adapter.d.ts.map +1 -1
- package/dist/attached-model.d.ts.map +1 -1
- package/dist/attached-model.js +15 -2
- 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 +17 -5
- package/dist/bootstrap.d.ts.map +1 -1
- package/dist/bootstrap.js +109 -37
- package/dist/change-set.d.ts +2 -0
- package/dist/change-set.d.ts.map +1 -1
- package/dist/change-set.js +48 -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 +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 +620 -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 +20 -11
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +66 -16
- 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 +29 -14
- package/dist/connection.d.ts.map +1 -1
- package/dist/connection.js +1262 -377
- package/dist/conversation.d.ts +23 -10
- package/dist/conversation.d.ts.map +1 -1
- package/dist/conversation.js +304 -136
- 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 +4 -1
- package/dist/host.d.ts.map +1 -1
- package/dist/host.js +17 -12
- 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 +12 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/memory.d.ts +5 -3
- package/dist/memory.d.ts.map +1 -1
- package/dist/memory.js +70 -21
- package/dist/model.d.ts +11 -2
- package/dist/model.d.ts.map +1 -1
- package/dist/model.js +11 -0
- package/dist/observation.d.ts +5 -2
- package/dist/observation.d.ts.map +1 -1
- package/dist/observation.js +22 -11
- 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 +15 -3
- package/dist/overlay.d.ts.map +1 -1
- package/dist/overlay.js +94 -77
- package/dist/query.d.ts +32 -3
- package/dist/query.d.ts.map +1 -1
- package/dist/query.js +5 -31
- package/dist/reach.d.ts +2 -0
- package/dist/reach.d.ts.map +1 -1
- package/dist/reach.js +45 -21
- package/dist/react.d.ts +26 -17
- package/dist/react.d.ts.map +1 -1
- package/dist/react.js +8 -6
- package/dist/read-side.d.ts +13 -6
- package/dist/read-side.d.ts.map +1 -1
- package/dist/read-side.js +291 -85
- 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 +10 -0
- package/dist/refresh.d.ts.map +1 -1
- package/dist/refresh.js +43 -38
- package/dist/replica.d.ts +9 -6
- package/dist/replica.d.ts.map +1 -1
- package/dist/replica.js +116 -68
- package/dist/room-draft.d.ts +26 -9
- package/dist/room-draft.d.ts.map +1 -1
- package/dist/room-draft.js +132 -23
- package/dist/rows.d.ts +8 -13
- package/dist/rows.d.ts.map +1 -1
- package/dist/rows.js +12 -14
- package/dist/save.d.ts +31 -1
- package/dist/save.d.ts.map +1 -1
- package/dist/save.js +376 -45
- package/dist/search.d.ts +31 -8
- package/dist/search.d.ts.map +1 -1
- package/dist/search.js +109 -44
- 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 +2 -2
- package/dist/status.d.ts.map +1 -1
- package/dist/status.js +0 -8
- package/dist/store.d.ts +66 -17
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +506 -196
- 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 +7 -3
- package/dist/wire.d.ts.map +1 -1
- package/dist/wire.js +15 -2
- package/package.json +26 -14
- package/dist/attachment.d.ts +0 -3
- package/dist/attachment.d.ts.map +0 -1
- package/dist/attachment.js +0 -8
package/dist/react.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../src/react.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,KAAK,EAAE,OAAO,EAAE,iBAAiB,EAAkB,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC9F,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../src/react.ts"],"names":[],"mappings":"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"}
|
package/dist/react.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import { useCallback,
|
|
1
|
+
import { useCallback, useLayoutEffect, useRef, useState } from 'react';
|
|
2
|
+
import { failed, runtimeError } from './failure.js';
|
|
3
|
+
const LOADING = { state: 'loading' };
|
|
2
4
|
export function useObserve(client, topic, ...input) {
|
|
3
5
|
const key = JSON.stringify([topic, ...input]);
|
|
4
6
|
const [held, setHeld] = useState(null);
|
|
5
7
|
const opened = useRef(input);
|
|
6
8
|
opened.current = input;
|
|
7
|
-
|
|
9
|
+
useLayoutEffect(() => {
|
|
8
10
|
if (client === null)
|
|
9
11
|
return;
|
|
10
12
|
let live = true;
|
|
@@ -18,7 +20,7 @@ export function useObserve(client, topic, ...input) {
|
|
|
18
20
|
observation = open;
|
|
19
21
|
const take = (value) => {
|
|
20
22
|
if (live)
|
|
21
|
-
setHeld({ client, key, value });
|
|
23
|
+
setHeld({ client, key, observed: { state: 'ready', value } });
|
|
22
24
|
};
|
|
23
25
|
take(open.current());
|
|
24
26
|
open.subscribe(take);
|
|
@@ -28,7 +30,7 @@ export function useObserve(client, topic, ...input) {
|
|
|
28
30
|
observation?.close();
|
|
29
31
|
};
|
|
30
32
|
}, [client, key]);
|
|
31
|
-
return held !== null && held.client === client && held.key === key ? held.
|
|
33
|
+
return held !== null && held.client === client && held.key === key ? held.observed : LOADING;
|
|
32
34
|
}
|
|
33
35
|
const IDLE = { busy: false, outcome: null, failure: null };
|
|
34
36
|
export async function saveRoomDrafts(client, room, roomDrafts) {
|
|
@@ -37,7 +39,7 @@ export async function saveRoomDrafts(client, room, roomDrafts) {
|
|
|
37
39
|
const prior = await client.roomDraft.read(room, path);
|
|
38
40
|
const write = await client.roomDraft.write(room, path, prior?.revision ?? null, parts);
|
|
39
41
|
if (write.outcome !== 'written' || write.roomDraft === null) {
|
|
40
|
-
throw
|
|
42
|
+
throw runtimeError(write.outcome === 'stale' ? write.code : 'room-draft-unwritten', `the Room Draft at ${path} was not written`);
|
|
41
43
|
}
|
|
42
44
|
kept.push({ path, revision: write.roomDraft.revision });
|
|
43
45
|
}
|
|
@@ -53,7 +55,7 @@ export function useSave(client) {
|
|
|
53
55
|
return outcome;
|
|
54
56
|
}
|
|
55
57
|
catch (error) {
|
|
56
|
-
const failure =
|
|
58
|
+
const failure = failed(error);
|
|
57
59
|
setState({ busy: false, outcome: null, failure });
|
|
58
60
|
throw failure;
|
|
59
61
|
}
|
package/dist/read-side.d.ts
CHANGED
|
@@ -1,18 +1,25 @@
|
|
|
1
1
|
import type { ChangeSet } from './change-set.js';
|
|
2
|
-
import { type KeyedResult, type
|
|
3
|
-
import type { Plan,
|
|
2
|
+
import { type KeyedResult, type QueryMessage } from './observation.js';
|
|
3
|
+
import type { PendingResult, Plan, QueryCoverage, QueryRows } from './query.js';
|
|
4
4
|
import type { SearchedDocument } from './search.js';
|
|
5
|
+
export type Cover = {
|
|
6
|
+
coverage: QueryCoverage;
|
|
7
|
+
} | PendingResult;
|
|
5
8
|
export type ReadSide = {
|
|
6
9
|
apply(set: ChangeSet): void;
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
+
recover(): void;
|
|
11
|
+
query<T>(plan: Plan, at: () => T): Promise<{
|
|
12
|
+
rows: QueryRows;
|
|
13
|
+
at: T;
|
|
14
|
+
}>;
|
|
15
|
+
watch(plan: Plan, identity: string, cover: () => Cover, deliver: (message: QueryMessage) => void): () => void;
|
|
16
|
+
room(room: string): readonly string[];
|
|
10
17
|
document(room: string, path: string): SearchedDocument | null;
|
|
11
18
|
close(): void;
|
|
12
19
|
};
|
|
13
20
|
export declare function reconciled(previous: KeyedResult, next: KeyedResult): {
|
|
14
21
|
keyed: KeyedResult;
|
|
15
|
-
|
|
22
|
+
message: QueryMessage;
|
|
16
23
|
} | null;
|
|
17
24
|
export declare function createReadSide(): ReadSide;
|
|
18
25
|
//# 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,EAAE,KAAK,WAAW,EAAE,KAAK,YAAY,EAAe,MAAM,kBAAkB,CAAC;AACpF,OAAO,KAAK,EAOV,aAAa,EACb,IAAI,EAEJ,aAAa,EAGb,SAAS,EAIV,MAAM,YAAY,CAAC;AAGpB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AA4CpD,MAAM,MAAM,KAAK,GAAG;IAAE,QAAQ,EAAE,aAAa,CAAA;CAAE,GAAG,aAAa,CAAC;AAuBhE,MAAM,MAAM,QAAQ,GAAG;IACrB,KAAK,CAAC,GAAG,EAAE,SAAS,GAAG,IAAI,CAAC;IAC5B,OAAO,IAAI,IAAI,CAAC;IAChB,KAAK,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,SAAS,CAAC;QAAC,EAAE,EAAE,CAAC,CAAA;KAAE,CAAC,CAAC;IACvE,KAAK,CACH,IAAI,EAAE,IAAI,EACV,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,KAAK,EAClB,OAAO,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,IAAI,GACvC,MAAM,IAAI,CAAC;IACd,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAAC;IACtC,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAAC;IAC9D,KAAK,IAAI,IAAI,CAAC;CACf,CAAC;AAqWF,wBAAgB,UAAU,CACxB,QAAQ,EAAE,WAAW,EACrB,IAAI,EAAE,WAAW,GAChB;IAAE,KAAK,EAAE,WAAW,CAAC;IAAC,OAAO,EAAE,YAAY,CAAA;CAAE,GAAG,IAAI,CAuCtD;AAgBD,wBAAgB,cAAc,IAAI,QAAQ,CA+QzC"}
|
package/dist/read-side.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { and, BasicIndex, configureIndexDevMode, count, createCollection, createLiveQueryCollection, deepEquals, eq, inArray, or, toArray, } from '@tanstack/db';
|
|
2
|
-
import { ARRAY_INDEX, pointerSegments } from '@agentshouse/mdmodel';
|
|
3
|
-
import { rowsOf } from './observation.js';
|
|
2
|
+
import { ARRAY_INDEX, parse, pointerSegments } from '@agentshouse/mdmodel';
|
|
4
3
|
import { documentKey } from './rows.js';
|
|
4
|
+
import { after, inUnits, ROW_WEIGHT } from './turn.js';
|
|
5
5
|
function every(expressions) {
|
|
6
6
|
const [first, second, ...rest] = expressions;
|
|
7
7
|
return second === undefined ? first : and(first, second, ...rest);
|
|
@@ -101,14 +101,11 @@ function filtered(q, rows, plan) {
|
|
|
101
101
|
}
|
|
102
102
|
return query;
|
|
103
103
|
}
|
|
104
|
-
function
|
|
105
|
-
return
|
|
104
|
+
function bodied(shape) {
|
|
105
|
+
return shape.sections !== null || shape.preamble || shape.markdown;
|
|
106
106
|
}
|
|
107
107
|
function documents(q, rows, plan, shape) {
|
|
108
108
|
let query = filtered(q, rows, plan);
|
|
109
|
-
if (shape.sections !== null || shape.preamble || shape.markdown) {
|
|
110
|
-
query = query.leftJoin({ b: rows }, ({ d, b }) => eq(d.body, b.key));
|
|
111
|
-
}
|
|
112
109
|
for (const { key, options } of shape.orderBy) {
|
|
113
110
|
query = query.orderBy(({ d }) => keyed(key, d), options);
|
|
114
111
|
}
|
|
@@ -117,15 +114,13 @@ function documents(q, rows, plan, shape) {
|
|
|
117
114
|
}
|
|
118
115
|
if (plan.limit !== null)
|
|
119
116
|
query = query.limit(plan.limit);
|
|
120
|
-
return query.select(({ d
|
|
117
|
+
return query.select(({ d }) => ({
|
|
121
118
|
room: d.room,
|
|
122
119
|
path: d.path,
|
|
123
120
|
type: d.type,
|
|
121
|
+
binary: d.binary,
|
|
124
122
|
...(shape.fields === null ? {} : { fields: d.fields }),
|
|
125
|
-
...(shape
|
|
126
|
-
...(Array.isArray(shape.sections) ? named('section', shape.sections, b.sections) : {}),
|
|
127
|
-
...(shape.preamble ? { preamble: b.preamble } : {}),
|
|
128
|
-
...(shape.markdown ? { markdown: b.markdown } : {}),
|
|
123
|
+
...(bodied(shape) ? { text: d.text } : {}),
|
|
129
124
|
...(shape.backlinks ? { backlinks: toArray(backlinked(q, rows, d, plan.reach)) } : {}),
|
|
130
125
|
...(shape.change ? { change: d.change } : {}),
|
|
131
126
|
}));
|
|
@@ -171,13 +166,22 @@ function built(rows, plan) {
|
|
|
171
166
|
},
|
|
172
167
|
};
|
|
173
168
|
}
|
|
174
|
-
function
|
|
175
|
-
return Object.fromEntries(entries.filter(([, value]) => value !== undefined));
|
|
176
|
-
}
|
|
177
|
-
function part(row, prefix, names, whole) {
|
|
169
|
+
function sectionsOf(sections, names) {
|
|
178
170
|
if (names === 'all')
|
|
179
|
-
return
|
|
180
|
-
return
|
|
171
|
+
return sections;
|
|
172
|
+
return Object.fromEntries(names.flatMap((name) => (Object.hasOwn(sections, name) ? [[name, sections[name]]] : [])));
|
|
173
|
+
}
|
|
174
|
+
function bodyOf(row, key, bodies) {
|
|
175
|
+
const text = row.text;
|
|
176
|
+
if (text === null)
|
|
177
|
+
return null;
|
|
178
|
+
const held = bodies?.get(key);
|
|
179
|
+
if (held !== undefined && held.text === text)
|
|
180
|
+
return held.document;
|
|
181
|
+
const read = parse(text, row.path);
|
|
182
|
+
const document = read.ok ? read.document : null;
|
|
183
|
+
bodies?.set(key, { text, document });
|
|
184
|
+
return document;
|
|
181
185
|
}
|
|
182
186
|
function masked(pointers) {
|
|
183
187
|
const root = { whole: false, members: new Map() };
|
|
@@ -228,9 +232,16 @@ function cut(value, mask) {
|
|
|
228
232
|
function selected(fields, pointers) {
|
|
229
233
|
return (cut(fields, masked(pointers)) ?? {});
|
|
230
234
|
}
|
|
231
|
-
function documentOf(row, shape) {
|
|
232
|
-
if (row.type === null)
|
|
233
|
-
|
|
235
|
+
function documentOf(key, row, shape, bodies) {
|
|
236
|
+
if (row.type === null) {
|
|
237
|
+
const binary = row.binary;
|
|
238
|
+
return {
|
|
239
|
+
room: row.room,
|
|
240
|
+
path: row.path,
|
|
241
|
+
...(binary === null ? {} : { binaryFile: binary }),
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
const body = bodied(shape) ? bodyOf(row, key, bodies) : null;
|
|
234
245
|
return {
|
|
235
246
|
room: row.room,
|
|
236
247
|
path: row.path,
|
|
@@ -242,13 +253,11 @@ function documentOf(row, shape) {
|
|
|
242
253
|
? row.fields
|
|
243
254
|
: selected(row.fields, shape.fields),
|
|
244
255
|
}),
|
|
245
|
-
...(shape.sections === null
|
|
256
|
+
...(shape.sections === null || body === null
|
|
246
257
|
? {}
|
|
247
|
-
: {
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
...(shape.preamble ? { preamble: row.preamble } : {}),
|
|
251
|
-
...(shape.markdown ? { markdown: row.markdown } : {}),
|
|
258
|
+
: { sections: sectionsOf(body.sections, shape.sections) }),
|
|
259
|
+
...(shape.preamble && body !== null ? { preamble: body.preamble } : {}),
|
|
260
|
+
...(shape.markdown && body !== null ? { markdown: body.content } : {}),
|
|
252
261
|
...(shape.backlinks
|
|
253
262
|
? {
|
|
254
263
|
backlinks: row.backlinks.map(({ path, type, field }) => ({ path, type, field })),
|
|
@@ -257,30 +266,40 @@ function documentOf(row, shape) {
|
|
|
257
266
|
...(shape.change ? { change: row.change } : {}),
|
|
258
267
|
};
|
|
259
268
|
}
|
|
260
|
-
function
|
|
269
|
+
function weight(row) {
|
|
270
|
+
return ROW_WEIGHT + (typeof row?.text === 'string' ? row.text.length : 0);
|
|
271
|
+
}
|
|
272
|
+
function rowsOfPlan(plan, entries, bodies, each = (row) => row) {
|
|
261
273
|
const shape = plan.shape;
|
|
262
274
|
if (shape.kind === 'documents') {
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
275
|
+
const documents = [];
|
|
276
|
+
return after(inUnits(entries, ([key, row]) => {
|
|
277
|
+
documents.push(each(documentOf(key, row, shape, bodies)));
|
|
278
|
+
return weight(row);
|
|
279
|
+
}), () => ({ rows: { documents }, keys: entries.map(([key]) => key) }));
|
|
267
280
|
}
|
|
268
281
|
const bounded = shape.orderBy.length === 0 && plan.limit !== null ? entries.slice(0, plan.limit) : entries;
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
};
|
|
282
|
+
const groups = [];
|
|
283
|
+
return after(inUnits(bounded, ([, row]) => {
|
|
284
|
+
groups.push(each({
|
|
285
|
+
key: shape.groupBy.map((_, index) => row[`key${index}`]),
|
|
286
|
+
count: row.count,
|
|
287
|
+
}));
|
|
288
|
+
return ROW_WEIGHT;
|
|
289
|
+
}), () => ({ rows: { groups }, keys: bounded.map(([key]) => key) }));
|
|
278
290
|
}
|
|
279
291
|
export function reconciled(previous, next) {
|
|
280
|
-
const before =
|
|
281
|
-
const
|
|
292
|
+
const before = previous.result;
|
|
293
|
+
const after = next.result;
|
|
294
|
+
if ('pending' in before || 'pending' in after) {
|
|
295
|
+
if (deepEquals(before, after))
|
|
296
|
+
return null;
|
|
297
|
+
return { keyed: next, message: next };
|
|
298
|
+
}
|
|
299
|
+
const earlier = 'groups' in before ? before.groups : before.documents;
|
|
300
|
+
const held = new Map(previous.keys.map((key, index) => [key, earlier[index]]));
|
|
282
301
|
const changed = [];
|
|
283
|
-
const rows =
|
|
302
|
+
const rows = ('groups' in after ? after.groups : after.documents).map((row, index) => {
|
|
284
303
|
const key = next.keys[index];
|
|
285
304
|
const kept = held.get(key);
|
|
286
305
|
if (kept !== undefined && deepEquals(kept, row))
|
|
@@ -289,22 +308,37 @@ export function reconciled(previous, next) {
|
|
|
289
308
|
return row;
|
|
290
309
|
});
|
|
291
310
|
const present = new Set(next.keys);
|
|
292
|
-
const survivors = previous.keys.filter((key) => present.has(key));
|
|
293
311
|
const removed = previous.keys.filter((key) => !present.has(key));
|
|
294
|
-
const moved =
|
|
295
|
-
|
|
296
|
-
if (changed.length === 0 && removed.length === 0 && !moved)
|
|
312
|
+
const moved = reordered(previous.keys, next.keys, present);
|
|
313
|
+
const covered = !deepEquals(before.coverage, after.coverage);
|
|
314
|
+
if (changed.length === 0 && removed.length === 0 && !moved && !covered)
|
|
297
315
|
return null;
|
|
298
316
|
return {
|
|
299
317
|
keyed: {
|
|
300
|
-
result: 'groups' in
|
|
301
|
-
? { groups: rows }
|
|
302
|
-
: { documents: rows },
|
|
318
|
+
result: 'groups' in after
|
|
319
|
+
? { groups: rows, coverage: after.coverage }
|
|
320
|
+
: { documents: rows, coverage: after.coverage },
|
|
303
321
|
keys: next.keys,
|
|
304
322
|
},
|
|
305
|
-
|
|
323
|
+
message: {
|
|
324
|
+
changed,
|
|
325
|
+
removed,
|
|
326
|
+
order: moved ? next.keys : null,
|
|
327
|
+
...(covered ? { coverage: after.coverage } : {}),
|
|
328
|
+
},
|
|
306
329
|
};
|
|
307
330
|
}
|
|
331
|
+
function reordered(previous, next, present) {
|
|
332
|
+
let at = 0;
|
|
333
|
+
for (const key of previous) {
|
|
334
|
+
if (!present.has(key))
|
|
335
|
+
continue;
|
|
336
|
+
if (next[at] !== key)
|
|
337
|
+
return true;
|
|
338
|
+
at += 1;
|
|
339
|
+
}
|
|
340
|
+
return at !== next.length;
|
|
341
|
+
}
|
|
308
342
|
export function createReadSide() {
|
|
309
343
|
configureIndexDevMode({ enabled: false });
|
|
310
344
|
let sync;
|
|
@@ -324,23 +358,139 @@ export function createReadSide() {
|
|
|
324
358
|
});
|
|
325
359
|
const shared = new Map();
|
|
326
360
|
function searched(row) {
|
|
327
|
-
const
|
|
361
|
+
const read = row.text === null ? null : parse(row.text, row.path);
|
|
362
|
+
if (read === null || !read.ok)
|
|
363
|
+
return null;
|
|
328
364
|
return {
|
|
329
365
|
room: row.room,
|
|
330
366
|
path: row.path,
|
|
331
367
|
type: row.type,
|
|
332
368
|
fields: row.fields,
|
|
333
|
-
preamble:
|
|
334
|
-
sections:
|
|
369
|
+
preamble: read.document.preamble,
|
|
370
|
+
sections: read.document.sections,
|
|
335
371
|
};
|
|
336
372
|
}
|
|
337
|
-
function
|
|
338
|
-
const
|
|
339
|
-
if (
|
|
373
|
+
function kept(entry, key, row) {
|
|
374
|
+
const held = entry.rows.get(key);
|
|
375
|
+
if (held !== undefined && deepEquals(held, row))
|
|
340
376
|
return;
|
|
341
|
-
entry.
|
|
342
|
-
|
|
343
|
-
|
|
377
|
+
entry.rows.set(key, row);
|
|
378
|
+
}
|
|
379
|
+
function rebuilt(entry) {
|
|
380
|
+
return after(rowsOfPlan(entry.plan, [...entry.built.live.entries()], entry.bodies), ({ rows: found, keys }) => {
|
|
381
|
+
const present = new Set(keys);
|
|
382
|
+
for (const key of [...entry.rows.keys()])
|
|
383
|
+
if (!present.has(key))
|
|
384
|
+
entry.rows.delete(key);
|
|
385
|
+
for (const key of [...entry.bodies.keys()]) {
|
|
386
|
+
if (!present.has(key))
|
|
387
|
+
entry.bodies.delete(key);
|
|
388
|
+
}
|
|
389
|
+
keys.forEach((key, index) => kept(entry, key, rowAt(found, index)));
|
|
390
|
+
return keys;
|
|
391
|
+
});
|
|
392
|
+
}
|
|
393
|
+
function refreshed(entry, dirty) {
|
|
394
|
+
const shape = entry.plan.shape;
|
|
395
|
+
const keys = [...entry.built.live.keys()];
|
|
396
|
+
const named = new Set([...dirty, ...keys.filter((key) => !entry.rows.has(key))]);
|
|
397
|
+
const values = [...named].map((key) => [key, entry.built.live.get(key)]);
|
|
398
|
+
const done = inUnits(values, ([key, value]) => {
|
|
399
|
+
if (value !== undefined)
|
|
400
|
+
kept(entry, key, documentOf(key, value, shape, entry.bodies));
|
|
401
|
+
else {
|
|
402
|
+
entry.rows.delete(key);
|
|
403
|
+
entry.bodies.delete(key);
|
|
404
|
+
}
|
|
405
|
+
return weight(value);
|
|
406
|
+
});
|
|
407
|
+
return after(done, () => keys);
|
|
408
|
+
}
|
|
409
|
+
function current(entry, keys, coverage) {
|
|
410
|
+
const found = keys.map((key) => entry.rows.get(key));
|
|
411
|
+
return {
|
|
412
|
+
result: entry.plan.shape.kind === 'groups'
|
|
413
|
+
? { groups: found, coverage }
|
|
414
|
+
: { documents: found, coverage },
|
|
415
|
+
keys,
|
|
416
|
+
};
|
|
417
|
+
}
|
|
418
|
+
function delivered(entry, next) {
|
|
419
|
+
const previous = entry.result;
|
|
420
|
+
entry.result = next;
|
|
421
|
+
const message = previous === undefined ? null : changedFrom(previous, next);
|
|
422
|
+
if (message !== null)
|
|
423
|
+
for (const listener of entry.ready)
|
|
424
|
+
listener(message);
|
|
425
|
+
for (const listener of entry.fresh) {
|
|
426
|
+
entry.ready.add(listener);
|
|
427
|
+
listener(next);
|
|
428
|
+
}
|
|
429
|
+
entry.fresh.clear();
|
|
430
|
+
}
|
|
431
|
+
function run(entry) {
|
|
432
|
+
while (entry.listeners.size > 0 &&
|
|
433
|
+
(entry.whole || entry.dirty.size > 0 || entry.stale || entry.fresh.size > 0)) {
|
|
434
|
+
entry.stale = false;
|
|
435
|
+
const cover = entry.cover();
|
|
436
|
+
if ('pending' in cover) {
|
|
437
|
+
entry.whole = true;
|
|
438
|
+
entry.dirty.clear();
|
|
439
|
+
entry.rows.clear();
|
|
440
|
+
entry.bodies.clear();
|
|
441
|
+
delivered(entry, { result: cover, keys: [] });
|
|
442
|
+
break;
|
|
443
|
+
}
|
|
444
|
+
const whole = entry.whole ||
|
|
445
|
+
entry.plan.shape.kind === 'groups' ||
|
|
446
|
+
entry.result === undefined ||
|
|
447
|
+
'pending' in entry.result.result;
|
|
448
|
+
const dirty = entry.dirty;
|
|
449
|
+
entry.dirty = new Set();
|
|
450
|
+
entry.whole = false;
|
|
451
|
+
const keys = whole ? rebuilt(entry) : refreshed(entry, dirty);
|
|
452
|
+
if (keys instanceof Promise) {
|
|
453
|
+
void keys
|
|
454
|
+
.then((found) => {
|
|
455
|
+
if (entry.listeners.size > 0)
|
|
456
|
+
delivered(entry, current(entry, found, cover.coverage));
|
|
457
|
+
run(entry);
|
|
458
|
+
})
|
|
459
|
+
.catch(() => {
|
|
460
|
+
entry.running = false;
|
|
461
|
+
});
|
|
462
|
+
return;
|
|
463
|
+
}
|
|
464
|
+
delivered(entry, current(entry, keys, cover.coverage));
|
|
465
|
+
}
|
|
466
|
+
entry.running = false;
|
|
467
|
+
}
|
|
468
|
+
function wake(entry) {
|
|
469
|
+
if (entry.subscription === null || entry.running)
|
|
470
|
+
return;
|
|
471
|
+
entry.running = true;
|
|
472
|
+
try {
|
|
473
|
+
run(entry);
|
|
474
|
+
}
|
|
475
|
+
catch (error) {
|
|
476
|
+
entry.running = false;
|
|
477
|
+
throw error;
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
function recover() {
|
|
481
|
+
for (const entry of shared.values()) {
|
|
482
|
+
if (entry.result === undefined || entry.subscription === null)
|
|
483
|
+
continue;
|
|
484
|
+
const cover = entry.cover();
|
|
485
|
+
const before = entry.result.result;
|
|
486
|
+
const held = 'pending' in cover
|
|
487
|
+
? deepEquals(before, cover)
|
|
488
|
+
: 'coverage' in before && deepEquals(before.coverage, cover.coverage);
|
|
489
|
+
if (held)
|
|
490
|
+
continue;
|
|
491
|
+
entry.stale = true;
|
|
492
|
+
wake(entry);
|
|
493
|
+
}
|
|
344
494
|
}
|
|
345
495
|
return {
|
|
346
496
|
apply(set) {
|
|
@@ -351,38 +501,52 @@ export function createReadSide() {
|
|
|
351
501
|
for (const row of change.after)
|
|
352
502
|
next.set(row.key, row);
|
|
353
503
|
}
|
|
354
|
-
if (next.size
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
504
|
+
if (next.size > 0) {
|
|
505
|
+
sync.begin();
|
|
506
|
+
for (const [key, row] of next) {
|
|
507
|
+
if (row === null) {
|
|
508
|
+
if (rows.has(key))
|
|
509
|
+
sync.write({ type: 'delete', key });
|
|
510
|
+
continue;
|
|
511
|
+
}
|
|
512
|
+
sync.write({ type: rows.has(key) ? 'update' : 'insert', value: row });
|
|
362
513
|
}
|
|
363
|
-
sync.
|
|
514
|
+
sync.commit();
|
|
364
515
|
}
|
|
365
|
-
|
|
516
|
+
recover();
|
|
366
517
|
},
|
|
367
|
-
|
|
518
|
+
recover,
|
|
519
|
+
async query(plan, at) {
|
|
368
520
|
const { live: collection, dispose } = built(rows, plan);
|
|
369
521
|
try {
|
|
370
522
|
await collection.toArrayWhenReady();
|
|
371
|
-
|
|
523
|
+
const entries = [...collection.entries()];
|
|
524
|
+
const held = at();
|
|
525
|
+
const found = await rowsOfPlan(plan, entries, null, structuredClone);
|
|
526
|
+
return { rows: found.rows, at: held };
|
|
372
527
|
}
|
|
373
528
|
finally {
|
|
374
529
|
dispose();
|
|
375
530
|
}
|
|
376
531
|
},
|
|
377
|
-
watch(plan, identity,
|
|
532
|
+
watch(plan, identity, cover, deliverTo) {
|
|
378
533
|
let entry = shared.get(identity);
|
|
379
534
|
if (entry === undefined) {
|
|
380
535
|
const created = {
|
|
381
536
|
plan,
|
|
382
537
|
built: built(rows, plan),
|
|
538
|
+
cover,
|
|
383
539
|
result: undefined,
|
|
540
|
+
rows: new Map(),
|
|
541
|
+
bodies: new Map(),
|
|
384
542
|
listeners: new Set(),
|
|
543
|
+
fresh: new Set(),
|
|
544
|
+
ready: new Set(),
|
|
385
545
|
subscription: null,
|
|
546
|
+
whole: true,
|
|
547
|
+
dirty: new Set(),
|
|
548
|
+
stale: false,
|
|
549
|
+
running: false,
|
|
386
550
|
};
|
|
387
551
|
created.built.live.on('status:change', ({ status }) => {
|
|
388
552
|
if (status === 'cleaned-up' && created.listeners.size === 0)
|
|
@@ -392,29 +556,40 @@ export function createReadSide() {
|
|
|
392
556
|
entry = created;
|
|
393
557
|
}
|
|
394
558
|
const observed = entry;
|
|
395
|
-
observed.listeners.add(
|
|
559
|
+
observed.listeners.add(deliverTo);
|
|
396
560
|
observed.built.live.onFirstReady(() => {
|
|
397
|
-
if (!observed.listeners.has(
|
|
561
|
+
if (!observed.listeners.has(deliverTo))
|
|
398
562
|
return;
|
|
563
|
+
observed.fresh.add(deliverTo);
|
|
399
564
|
if (observed.subscription === null) {
|
|
400
|
-
observed.
|
|
401
|
-
observed.subscription = observed.built.live.subscribeChanges(() => {
|
|
402
|
-
|
|
565
|
+
observed.whole = true;
|
|
566
|
+
observed.subscription = observed.built.live.subscribeChanges((changes) => {
|
|
567
|
+
if (observed.plan.shape.kind === 'groups')
|
|
568
|
+
observed.whole = true;
|
|
569
|
+
else
|
|
570
|
+
for (const { key } of changes)
|
|
571
|
+
observed.dirty.add(key);
|
|
572
|
+
wake(observed);
|
|
403
573
|
}, { includeInitialState: false });
|
|
404
574
|
}
|
|
405
|
-
|
|
575
|
+
wake(observed);
|
|
406
576
|
});
|
|
407
577
|
return () => {
|
|
408
|
-
|
|
578
|
+
observed.fresh.delete(deliverTo);
|
|
579
|
+
observed.ready.delete(deliverTo);
|
|
580
|
+
if (!observed.listeners.delete(deliverTo) || observed.listeners.size > 0)
|
|
409
581
|
return;
|
|
410
582
|
observed.subscription?.unsubscribe();
|
|
411
583
|
observed.subscription = null;
|
|
584
|
+
observed.result = undefined;
|
|
585
|
+
observed.rows.clear();
|
|
586
|
+
observed.bodies.clear();
|
|
587
|
+
observed.dirty.clear();
|
|
588
|
+
observed.whole = true;
|
|
412
589
|
};
|
|
413
590
|
},
|
|
414
|
-
|
|
415
|
-
return rows.toArray
|
|
416
|
-
.filter((row) => row.kind === 'document' && row.type !== null)
|
|
417
|
-
.map(searched);
|
|
591
|
+
room(room) {
|
|
592
|
+
return rows.toArray.flatMap((row) => row.kind !== 'document' || row.type === null || row.room !== room ? [] : [row.path]);
|
|
418
593
|
},
|
|
419
594
|
document(room, path) {
|
|
420
595
|
const row = rows.get(documentKey(room, path));
|
|
@@ -423,6 +598,8 @@ export function createReadSide() {
|
|
|
423
598
|
close() {
|
|
424
599
|
for (const entry of shared.values()) {
|
|
425
600
|
entry.listeners.clear();
|
|
601
|
+
entry.fresh.clear();
|
|
602
|
+
entry.ready.clear();
|
|
426
603
|
entry.subscription?.unsubscribe();
|
|
427
604
|
entry.built.dispose();
|
|
428
605
|
}
|
|
@@ -431,3 +608,32 @@ export function createReadSide() {
|
|
|
431
608
|
},
|
|
432
609
|
};
|
|
433
610
|
}
|
|
611
|
+
function changedFrom(previous, next) {
|
|
612
|
+
const before = previous.result;
|
|
613
|
+
const after = next.result;
|
|
614
|
+
if ('pending' in before || 'pending' in after)
|
|
615
|
+
return deepEquals(before, after) ? null : next;
|
|
616
|
+
const earlier = 'groups' in before ? before.groups : before.documents;
|
|
617
|
+
const held = new Map(previous.keys.map((key, index) => [key, earlier[index]]));
|
|
618
|
+
const later = 'groups' in after ? after.groups : after.documents;
|
|
619
|
+
const changed = [];
|
|
620
|
+
next.keys.forEach((key, index) => {
|
|
621
|
+
if (held.get(key) !== later[index])
|
|
622
|
+
changed.push([key, later[index]]);
|
|
623
|
+
});
|
|
624
|
+
const present = new Set(next.keys);
|
|
625
|
+
const removed = previous.keys.filter((key) => !present.has(key));
|
|
626
|
+
const moved = reordered(previous.keys, next.keys, present);
|
|
627
|
+
const covered = !deepEquals(before.coverage, after.coverage);
|
|
628
|
+
if (changed.length === 0 && removed.length === 0 && !moved && !covered)
|
|
629
|
+
return null;
|
|
630
|
+
return {
|
|
631
|
+
changed,
|
|
632
|
+
removed,
|
|
633
|
+
order: moved ? next.keys : null,
|
|
634
|
+
...(covered ? { coverage: after.coverage } : {}),
|
|
635
|
+
};
|
|
636
|
+
}
|
|
637
|
+
function rowAt(rows, index) {
|
|
638
|
+
return 'groups' in rows ? rows.groups[index] : rows.documents[index];
|
|
639
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export type Attempted = 'done' | 'again' | {
|
|
2
|
+
readonly at: number;
|
|
3
|
+
};
|
|
4
|
+
export type Attempt = (signal: AbortSignal) => Promise<Attempted>;
|
|
5
|
+
export type AttemptOptions = {
|
|
6
|
+
readonly at?: number;
|
|
7
|
+
readonly again?: boolean;
|
|
8
|
+
};
|
|
9
|
+
export type RecoveryOptions = {
|
|
10
|
+
readonly firstMs?: number;
|
|
11
|
+
readonly ceilingMs?: number;
|
|
12
|
+
readonly attempts?: number;
|
|
13
|
+
readonly inFlight?: number;
|
|
14
|
+
};
|
|
15
|
+
export type Recovery = {
|
|
16
|
+
attempt(intent: string, run: Attempt, options?: AttemptOptions): Promise<boolean>;
|
|
17
|
+
pending(intent: string): boolean;
|
|
18
|
+
resume(): void;
|
|
19
|
+
cancel(intent: string): void;
|
|
20
|
+
scope(inFlight?: number): Recovery;
|
|
21
|
+
retire(): Promise<void>;
|
|
22
|
+
};
|
|
23
|
+
export declare function retryDelay(tries: number, firstMs?: number, ceilingMs?: number): number;
|
|
24
|
+
export declare function createRecovery(options?: RecoveryOptions): Recovery;
|
|
25
|
+
//# sourceMappingURL=recovery.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recovery.d.ts","sourceRoot":"","sources":["../src/recovery.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,OAAO,GAAG;IAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnE,MAAM,MAAM,OAAO,GAAG,CAAC,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC,SAAS,CAAC,CAAC;AAElE,MAAM,MAAM,cAAc,GAAG;IAAE,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAEhF,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG;IACrB,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAClF,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;IACjC,MAAM,IAAI,IAAI,CAAC;IACf,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,KAAK,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC;IACnC,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACzB,CAAC;AAsBF,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,SAAW,EAAE,SAAS,SAAa,GAAG,MAAM,CAG5F;AAuKD,wBAAgB,cAAc,CAAC,OAAO,GAAE,eAAoB,GAAG,QAAQ,CAStE"}
|