@agentshouse/mdruntime 0.1.0-cacb4c3f6734e → 0.1.0-caee7332d2235
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 +277 -222
- package/README.md +20 -10
- package/dist/adapter.d.ts +95 -20
- 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 +18 -5
- package/dist/bootstrap.d.ts.map +1 -1
- package/dist/bootstrap.js +113 -37
- package/dist/change-set.d.ts +7 -2
- package/dist/change-set.d.ts.map +1 -1
- package/dist/change-set.js +54 -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/earlier.d.ts +10 -0
- package/dist/chat/earlier.d.ts.map +1 -0
- package/dist/chat/earlier.js +54 -0
- package/dist/chat/input.d.ts +9 -0
- package/dist/chat/input.d.ts.map +1 -0
- package/dist/chat/input.js +99 -0
- package/dist/chat/kit.d.ts +61 -0
- package/dist/chat/kit.d.ts.map +1 -0
- package/dist/chat/kit.js +123 -0
- package/dist/chat/lasting.d.ts +6 -0
- package/dist/chat/lasting.d.ts.map +1 -0
- package/dist/chat/lasting.js +19 -0
- package/dist/chat/list.d.ts +27 -0
- package/dist/chat/list.d.ts.map +1 -0
- package/dist/chat/list.js +99 -0
- package/dist/chat/markdown.d.ts +21 -0
- package/dist/chat/markdown.d.ts.map +1 -0
- package/dist/chat/markdown.js +246 -0
- package/dist/chat/message.d.ts +6 -0
- package/dist/chat/message.d.ts.map +1 -0
- package/dist/chat/message.js +192 -0
- package/dist/chat/messages.d.ts +22 -0
- package/dist/chat/messages.d.ts.map +1 -0
- package/dist/chat/messages.js +171 -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/pieces.d.ts +62 -0
- package/dist/chat/pieces.d.ts.map +1 -0
- package/dist/chat/pieces.js +1110 -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 +630 -0
- package/dist/chat/question.d.ts +9 -0
- package/dist/chat/question.d.ts.map +1 -0
- package/dist/chat/question.js +69 -0
- package/dist/chat/questions.d.ts +31 -0
- package/dist/chat/questions.d.ts.map +1 -0
- package/dist/chat/questions.js +111 -0
- package/dist/chat/read.d.ts +5 -0
- package/dist/chat/read.d.ts.map +1 -0
- package/dist/chat/read.js +13 -0
- package/dist/chat/ready.d.ts +34 -0
- package/dist/chat/ready.d.ts.map +1 -0
- package/dist/chat/ready.js +91 -0
- package/dist/chat/steady.d.ts +3 -0
- package/dist/chat/steady.d.ts.map +1 -0
- package/dist/chat/steady.js +26 -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 +30 -13
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +79 -16
- package/dist/collection.d.ts +23 -13
- package/dist/collection.d.ts.map +1 -1
- package/dist/collection.js +349 -36
- package/dist/connection.d.ts +50 -16
- package/dist/connection.d.ts.map +1 -1
- package/dist/connection.js +1968 -424
- package/dist/conversation.d.ts +31 -10
- package/dist/conversation.d.ts.map +1 -1
- package/dist/conversation.js +521 -170
- package/dist/durability.d.ts +7 -1
- package/dist/durability.d.ts.map +1 -1
- package/dist/entry.d.ts +17 -0
- package/dist/entry.d.ts.map +1 -0
- package/dist/entry.js +157 -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 +15 -2
- package/dist/host.d.ts.map +1 -1
- package/dist/host.js +102 -19
- package/dist/identity.d.ts +5 -0
- package/dist/identity.d.ts.map +1 -1
- package/dist/identity.js +19 -1
- package/dist/index.d.ts +16 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -0
- package/dist/memory.d.ts +11 -4
- package/dist/memory.d.ts.map +1 -1
- package/dist/memory.js +91 -24
- package/dist/model.d.ts +14 -4
- package/dist/model.d.ts.map +1 -1
- package/dist/model.js +12 -1
- package/dist/observation.d.ts +7 -2
- package/dist/observation.d.ts.map +1 -1
- package/dist/observation.js +29 -12
- 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 +38 -3
- package/dist/outcome.d.ts.map +1 -1
- package/dist/outcome.js +45 -1
- package/dist/overlay.d.ts +18 -5
- package/dist/overlay.d.ts.map +1 -1
- package/dist/overlay.js +247 -165
- package/dist/query.d.ts +60 -4
- package/dist/query.d.ts.map +1 -1
- package/dist/query.js +41 -38
- package/dist/reach.d.ts +8 -3
- package/dist/reach.d.ts.map +1 -1
- package/dist/reach.js +73 -24
- package/dist/react.d.ts +31 -20
- package/dist/react.d.ts.map +1 -1
- package/dist/react.js +13 -21
- package/dist/read-side.d.ts +16 -7
- package/dist/read-side.d.ts.map +1 -1
- package/dist/read-side.js +495 -102
- package/dist/readiness.d.ts +53 -0
- package/dist/readiness.d.ts.map +1 -0
- package/dist/readiness.js +33 -0
- package/dist/reads.d.ts +11 -0
- package/dist/reads.d.ts.map +1 -0
- package/dist/reads.js +98 -0
- package/dist/recovery.d.ts +25 -0
- package/dist/recovery.d.ts.map +1 -0
- package/dist/recovery.js +197 -0
- package/dist/refresh.d.ts +13 -3
- package/dist/refresh.d.ts.map +1 -1
- package/dist/refresh.js +72 -42
- package/dist/replica.d.ts +17 -8
- package/dist/replica.d.ts.map +1 -1
- package/dist/replica.js +165 -79
- package/dist/room-draft.d.ts +38 -9
- package/dist/room-draft.d.ts.map +1 -1
- package/dist/room-draft.js +141 -33
- package/dist/rows.d.ts +10 -13
- package/dist/rows.d.ts.map +1 -1
- package/dist/rows.js +19 -14
- package/dist/save.d.ts +35 -3
- package/dist/save.d.ts.map +1 -1
- package/dist/save.js +522 -107
- package/dist/search.d.ts +52 -8
- package/dist/search.d.ts.map +1 -1
- package/dist/search.js +192 -47
- 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 +15 -0
- package/dist/shared.d.ts.map +1 -0
- package/dist/shared.js +398 -0
- package/dist/status.d.ts +6 -2
- package/dist/status.d.ts.map +1 -1
- package/dist/status.js +0 -8
- package/dist/store.d.ts +91 -18
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +704 -283
- package/dist/turn.d.ts +9 -0
- package/dist/turn.d.ts.map +1 -0
- package/dist/turn.js +64 -0
- package/dist/windows.d.ts +26 -0
- package/dist/windows.d.ts.map +1 -0
- package/dist/windows.js +93 -0
- package/dist/wire.d.ts +157 -33
- package/dist/wire.d.ts.map +1 -1
- package/dist/wire.js +65 -31
- 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/overlay.js
CHANGED
|
@@ -1,4 +1,20 @@
|
|
|
1
|
-
import { apply, parse, serialize } from '@agentshouse/mdmodel';
|
|
1
|
+
import { apply, frontmatterValue, parse, serialize, } from '@agentshouse/mdmodel';
|
|
2
|
+
import { differences, drafted, patching, settling } from './shared.js';
|
|
3
|
+
import { ROW_WEIGHT } from './turn.js';
|
|
4
|
+
export function acceptedBinaries(files) {
|
|
5
|
+
return Object.fromEntries(Object.entries(files).map(([path, file]) => [path, { state: 'accepted', ...file }]));
|
|
6
|
+
}
|
|
7
|
+
export function sameBinary(left, right) {
|
|
8
|
+
if (left === undefined || right === undefined)
|
|
9
|
+
return left === right;
|
|
10
|
+
return (left.state === right.state &&
|
|
11
|
+
left.byteLength === right.byteLength &&
|
|
12
|
+
left.mediaType === right.mediaType &&
|
|
13
|
+
left.sha256 === right.sha256 &&
|
|
14
|
+
(left.state === 'accepted'
|
|
15
|
+
? right.state === 'accepted' && left.fileRef === right.fileRef
|
|
16
|
+
: right.state === 'pending' && left.localId === right.localId));
|
|
17
|
+
}
|
|
2
18
|
export function sameChange(left, right) {
|
|
3
19
|
if (left === undefined || right === undefined)
|
|
4
20
|
return left === right;
|
|
@@ -8,10 +24,13 @@ export function sameChange(left, right) {
|
|
|
8
24
|
left.author?.name === right.author?.name);
|
|
9
25
|
}
|
|
10
26
|
const EMPTY_FRONTMATTER = '---\n---\n';
|
|
27
|
+
function isPart(change) {
|
|
28
|
+
return change.kind === 'field' || change.kind === 'section' || change.kind === 'preamble';
|
|
29
|
+
}
|
|
11
30
|
function at(path, name) {
|
|
12
31
|
return `${path} ${name}`;
|
|
13
32
|
}
|
|
14
|
-
function priorsOf(preconditions) {
|
|
33
|
+
function* priorsOf(preconditions) {
|
|
15
34
|
const fields = new Map();
|
|
16
35
|
const sections = new Map();
|
|
17
36
|
const preambles = new Map();
|
|
@@ -25,6 +44,7 @@ function priorsOf(preconditions) {
|
|
|
25
44
|
if (precondition.kind === 'preamble') {
|
|
26
45
|
preambles.set(precondition.path, precondition.value);
|
|
27
46
|
}
|
|
47
|
+
yield ROW_WEIGHT;
|
|
28
48
|
}
|
|
29
49
|
return {
|
|
30
50
|
field: (path, name) => fields.get(at(path, name)),
|
|
@@ -40,49 +60,50 @@ function compose(fields, sections) {
|
|
|
40
60
|
const opened = parse(skeleton);
|
|
41
61
|
if (!opened.ok)
|
|
42
62
|
return skeleton;
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
const next = apply(document, { kind: 'field', name, value, prior: undefined });
|
|
46
|
-
if (next.outcome === 'applied')
|
|
47
|
-
document = next.document;
|
|
48
|
-
}
|
|
49
|
-
return serialize(document);
|
|
63
|
+
const next = apply(opened.document, Object.entries(fields).flatMap(([name, value]) => frontmatterValue(value) ? [{ kind: 'field', name, value, prior: undefined }] : []));
|
|
64
|
+
return serialize(next.outcome === 'applied' ? next.document : opened.document);
|
|
50
65
|
}
|
|
51
|
-
function edited(
|
|
52
|
-
if (change.kind === 'field')
|
|
53
|
-
return
|
|
66
|
+
function edited(change, priors) {
|
|
67
|
+
if (change.kind === 'field')
|
|
68
|
+
return {
|
|
54
69
|
kind: 'field',
|
|
55
70
|
name: change.name,
|
|
56
71
|
value: change.value,
|
|
57
72
|
prior: priors.field(change.path, change.name),
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
kind: 'preamble',
|
|
63
|
-
value: change.value,
|
|
64
|
-
prior: priors.preamble(change.path),
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
if (change.kind !== 'section')
|
|
68
|
-
return null;
|
|
69
|
-
return apply(document, {
|
|
73
|
+
};
|
|
74
|
+
if (change.kind === 'preamble')
|
|
75
|
+
return { kind: 'preamble', value: change.value, prior: priors.preamble(change.path) };
|
|
76
|
+
return {
|
|
70
77
|
kind: 'section',
|
|
71
78
|
name: change.name,
|
|
72
79
|
value: change.value,
|
|
73
80
|
prior: priors.section(change.path, change.name),
|
|
74
|
-
}
|
|
81
|
+
};
|
|
75
82
|
}
|
|
76
|
-
function edit(staged,
|
|
77
|
-
const
|
|
83
|
+
function edit(staged, changes, priors) {
|
|
84
|
+
const path = changes[0].path;
|
|
85
|
+
delete staged.revisions[path];
|
|
86
|
+
const text = staged.documents[path];
|
|
78
87
|
if (text === undefined)
|
|
79
|
-
return;
|
|
80
|
-
const parsed = parse(text,
|
|
88
|
+
return changes.length;
|
|
89
|
+
const parsed = parse(text, path);
|
|
81
90
|
if (!parsed.ok)
|
|
82
|
-
return;
|
|
83
|
-
const
|
|
84
|
-
|
|
85
|
-
|
|
91
|
+
return changes.length;
|
|
92
|
+
const wanted = changes.map((change) => edited(change, priors));
|
|
93
|
+
const first = apply(parsed.document, wanted);
|
|
94
|
+
if (first.outcome === 'refuse')
|
|
95
|
+
return changes.length;
|
|
96
|
+
if (first.outcome === 'applied') {
|
|
97
|
+
staged.documents[path] = serialize(first.document);
|
|
98
|
+
return 0;
|
|
99
|
+
}
|
|
100
|
+
const stale = new Set(first.stale);
|
|
101
|
+
const kept = wanted.filter((_, at) => !stale.has(at));
|
|
102
|
+
const rest = apply(parsed.document, kept);
|
|
103
|
+
if (rest.outcome !== 'applied')
|
|
104
|
+
return changes.length;
|
|
105
|
+
staged.documents[path] = serialize(rest.document);
|
|
106
|
+
return first.stale.length;
|
|
86
107
|
}
|
|
87
108
|
function relocate(staged, from, to) {
|
|
88
109
|
const text = staged.documents[from];
|
|
@@ -90,194 +111,255 @@ function relocate(staged, from, to) {
|
|
|
90
111
|
delete staged.documents[from];
|
|
91
112
|
staged.documents[to] = text;
|
|
92
113
|
}
|
|
93
|
-
else if (staged.
|
|
94
|
-
staged.
|
|
114
|
+
else if (staged.binaries[from] !== undefined) {
|
|
115
|
+
staged.binaries[to] = staged.binaries[from];
|
|
116
|
+
delete staged.binaries[from];
|
|
95
117
|
}
|
|
96
118
|
else {
|
|
97
|
-
return;
|
|
119
|
+
return false;
|
|
98
120
|
}
|
|
99
121
|
moveHead(staged, from, to);
|
|
122
|
+
return true;
|
|
100
123
|
}
|
|
101
124
|
function moveHead(heads, from, to) {
|
|
102
125
|
const revision = heads.revisions[from];
|
|
126
|
+
const fileId = heads.fileIds[from];
|
|
103
127
|
const change = heads.changes[from];
|
|
104
128
|
delete heads.revisions[from];
|
|
129
|
+
delete heads.fileIds[from];
|
|
105
130
|
delete heads.changes[from];
|
|
131
|
+
delete heads.fileIds[to];
|
|
106
132
|
delete heads.changes[to];
|
|
107
133
|
if (revision !== undefined)
|
|
108
134
|
heads.revisions[to] = revision;
|
|
135
|
+
if (fileId !== undefined)
|
|
136
|
+
heads.fileIds[to] = fileId;
|
|
109
137
|
if (change !== undefined)
|
|
110
138
|
heads.changes[to] = change;
|
|
111
139
|
}
|
|
112
140
|
function erase(staged, path) {
|
|
113
141
|
delete staged.documents[path];
|
|
114
142
|
delete staged.revisions[path];
|
|
143
|
+
delete staged.fileIds[path];
|
|
115
144
|
delete staged.changes[path];
|
|
116
|
-
staged.
|
|
145
|
+
delete staged.binaries[path];
|
|
117
146
|
}
|
|
118
|
-
function stage(staged, change
|
|
119
|
-
if (change.kind === 'field' || change.kind === 'section' || change.kind === 'preamble') {
|
|
120
|
-
edit(staged, change, priors);
|
|
121
|
-
return;
|
|
122
|
-
}
|
|
147
|
+
function stage(staged, change) {
|
|
123
148
|
if (change.kind === 'create') {
|
|
124
149
|
staged.documents[change.path] =
|
|
125
150
|
'content' in change ? change.content : compose(change.fields, change.sections);
|
|
151
|
+
delete staged.fileIds[change.path];
|
|
126
152
|
delete staged.changes[change.path];
|
|
127
|
-
return;
|
|
153
|
+
return true;
|
|
128
154
|
}
|
|
129
155
|
if (change.kind === 'replace') {
|
|
156
|
+
delete staged.revisions[change.path];
|
|
130
157
|
if (staged.documents[change.path] === undefined)
|
|
131
|
-
return;
|
|
158
|
+
return false;
|
|
132
159
|
staged.documents[change.path] = change.content;
|
|
133
|
-
return;
|
|
160
|
+
return true;
|
|
161
|
+
}
|
|
162
|
+
if (change.kind === 'binary') {
|
|
163
|
+
if (staged.documents[change.path] !== undefined)
|
|
164
|
+
return false;
|
|
165
|
+
staged.binaries[change.path] = {
|
|
166
|
+
state: 'pending',
|
|
167
|
+
localId: change.localId,
|
|
168
|
+
byteLength: change.byteLength,
|
|
169
|
+
mediaType: change.mediaType,
|
|
170
|
+
sha256: change.sha256,
|
|
171
|
+
};
|
|
172
|
+
delete staged.revisions[change.path];
|
|
173
|
+
delete staged.changes[change.path];
|
|
174
|
+
return true;
|
|
134
175
|
}
|
|
135
176
|
if (change.kind === 'move') {
|
|
136
|
-
relocate(staged, change.path, change.to);
|
|
137
|
-
return;
|
|
177
|
+
return relocate(staged, change.path, change.to);
|
|
138
178
|
}
|
|
139
179
|
erase(staged, change.path);
|
|
180
|
+
return true;
|
|
140
181
|
}
|
|
141
|
-
export function
|
|
182
|
+
export function* overlaying(base, queue, unapplied) {
|
|
142
183
|
const staged = {
|
|
143
|
-
documents:
|
|
144
|
-
|
|
145
|
-
revisions:
|
|
146
|
-
|
|
184
|
+
documents: drafted(base.documents),
|
|
185
|
+
binaries: drafted(base.binaries),
|
|
186
|
+
revisions: drafted(base.revisions),
|
|
187
|
+
fileIds: drafted(base.fileIds),
|
|
188
|
+
changes: drafted(base.changes),
|
|
147
189
|
};
|
|
148
190
|
for (const batch of queue) {
|
|
149
|
-
const priors = priorsOf(batch.preconditions);
|
|
150
|
-
for (
|
|
151
|
-
|
|
191
|
+
const priors = yield* priorsOf(batch.preconditions);
|
|
192
|
+
for (let index = 0; index < batch.changes.length; index += 1) {
|
|
193
|
+
const change = batch.changes[index];
|
|
194
|
+
if (!isPart(change)) {
|
|
195
|
+
if (!stage(staged, change))
|
|
196
|
+
unapplied?.();
|
|
197
|
+
yield ROW_WEIGHT;
|
|
198
|
+
continue;
|
|
199
|
+
}
|
|
200
|
+
const run = [change];
|
|
201
|
+
while (index + 1 < batch.changes.length) {
|
|
202
|
+
const next = batch.changes[index + 1];
|
|
203
|
+
if (!isPart(next) || next.path !== change.path)
|
|
204
|
+
break;
|
|
205
|
+
run.push(next);
|
|
206
|
+
index += 1;
|
|
207
|
+
}
|
|
208
|
+
const text = staged.documents[change.path] ?? '';
|
|
209
|
+
for (let left = edit(staged, run, priors); left > 0; left -= 1)
|
|
210
|
+
unapplied?.();
|
|
211
|
+
yield ROW_WEIGHT + text.length;
|
|
212
|
+
}
|
|
152
213
|
}
|
|
153
214
|
return {
|
|
154
|
-
documents: staged.documents,
|
|
155
|
-
|
|
156
|
-
revisions: staged.revisions,
|
|
157
|
-
|
|
215
|
+
documents: yield* settling(staged.documents),
|
|
216
|
+
binaries: yield* settling(staged.binaries),
|
|
217
|
+
revisions: yield* settling(staged.revisions),
|
|
218
|
+
fileIds: yield* settling(staged.fileIds),
|
|
219
|
+
changes: yield* settling(staged.changes),
|
|
158
220
|
};
|
|
159
221
|
}
|
|
160
|
-
function pathsOf(batch) {
|
|
161
|
-
|
|
222
|
+
function* pathsOf(batch) {
|
|
223
|
+
const paths = new Set();
|
|
224
|
+
for (const change of batch.changes) {
|
|
225
|
+
paths.add(change.path);
|
|
226
|
+
if (change.kind === 'move')
|
|
227
|
+
paths.add(change.to);
|
|
228
|
+
yield ROW_WEIGHT;
|
|
229
|
+
}
|
|
230
|
+
return paths;
|
|
162
231
|
}
|
|
163
|
-
export function
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
paths.every((path) => left.documents[path] === right.documents[path]) &&
|
|
167
|
-
left.binaryTargets.length === right.binaryTargets.length &&
|
|
168
|
-
left.binaryTargets.every((path) => right.binaryTargets.includes(path)));
|
|
232
|
+
export function* sameText(left, right) {
|
|
233
|
+
return ((yield* differences(left.documents, right.documents)).size === 0 &&
|
|
234
|
+
(yield* differences(left.binaries, right.binaries, sameBinary)).size === 0);
|
|
169
235
|
}
|
|
170
|
-
function
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
236
|
+
export function* changedPaths(left, right) {
|
|
237
|
+
return new Set([
|
|
238
|
+
...(yield* differences(left.documents, right.documents)),
|
|
239
|
+
...(yield* differences(left.revisions, right.revisions)),
|
|
240
|
+
...(yield* differences(left.fileIds, right.fileIds)),
|
|
241
|
+
...(yield* differences(left.changes, right.changes, sameChange)),
|
|
242
|
+
...(yield* differences(left.binaries, right.binaries, sameBinary)),
|
|
243
|
+
]);
|
|
244
|
+
}
|
|
245
|
+
function* sameItems(left, right) {
|
|
246
|
+
if (left.length !== right.length)
|
|
247
|
+
return false;
|
|
248
|
+
for (let index = 0; index < left.length; index += 1) {
|
|
249
|
+
const item = JSON.stringify(left[index]);
|
|
250
|
+
if (item !== JSON.stringify(right[index]))
|
|
251
|
+
return false;
|
|
252
|
+
yield ROW_WEIGHT + item.length;
|
|
253
|
+
}
|
|
254
|
+
return true;
|
|
255
|
+
}
|
|
256
|
+
function* sameBatch(left, right) {
|
|
257
|
+
if (left === right)
|
|
258
|
+
return true;
|
|
259
|
+
const { changes, preconditions, ...rest } = left;
|
|
260
|
+
const { changes: others, preconditions: priors, ...held } = right;
|
|
261
|
+
return (JSON.stringify(rest) === JSON.stringify(held) &&
|
|
262
|
+
(yield* sameItems(changes, others)) &&
|
|
263
|
+
(yield* sameItems(preconditions, priors)));
|
|
264
|
+
}
|
|
265
|
+
function* replayHeads(base, batch) {
|
|
266
|
+
const heads = {
|
|
267
|
+
revisions: drafted(base.revisions),
|
|
268
|
+
fileIds: drafted(base.fileIds),
|
|
269
|
+
changes: drafted(base.changes),
|
|
270
|
+
};
|
|
271
|
+
for (const change of batch.changes) {
|
|
272
|
+
if (change.kind === 'remove') {
|
|
273
|
+
delete heads.revisions[change.path];
|
|
274
|
+
delete heads.fileIds[change.path];
|
|
275
|
+
delete heads.changes[change.path];
|
|
184
276
|
}
|
|
277
|
+
else if (change.kind === 'create') {
|
|
278
|
+
delete heads.fileIds[change.path];
|
|
279
|
+
delete heads.changes[change.path];
|
|
280
|
+
}
|
|
281
|
+
else if (change.kind === 'replace' ||
|
|
282
|
+
change.kind === 'field' ||
|
|
283
|
+
change.kind === 'section' ||
|
|
284
|
+
change.kind === 'preamble') {
|
|
285
|
+
delete heads.revisions[change.path];
|
|
286
|
+
}
|
|
287
|
+
else if (change.kind === 'binary') {
|
|
288
|
+
delete heads.revisions[change.path];
|
|
289
|
+
delete heads.changes[change.path];
|
|
290
|
+
}
|
|
291
|
+
else if (change.kind === 'move') {
|
|
292
|
+
moveHead(heads, change.path, change.to);
|
|
293
|
+
}
|
|
294
|
+
yield ROW_WEIGHT;
|
|
185
295
|
}
|
|
186
|
-
return
|
|
296
|
+
return {
|
|
297
|
+
revisions: yield* settling(heads.revisions),
|
|
298
|
+
fileIds: yield* settling(heads.fileIds),
|
|
299
|
+
changes: yield* settling(heads.changes),
|
|
300
|
+
};
|
|
187
301
|
}
|
|
188
|
-
|
|
189
|
-
const
|
|
190
|
-
const
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
302
|
+
function* repatched(held, paths, value) {
|
|
303
|
+
const set = [];
|
|
304
|
+
const removed = [];
|
|
305
|
+
for (const path of paths) {
|
|
306
|
+
const found = value(path);
|
|
307
|
+
if (found === undefined)
|
|
308
|
+
removed.push(path);
|
|
309
|
+
else
|
|
310
|
+
set.push([path, found]);
|
|
311
|
+
yield ROW_WEIGHT;
|
|
312
|
+
}
|
|
313
|
+
return yield* patching(held, set, removed);
|
|
314
|
+
}
|
|
315
|
+
export function* overlayChanged(base, batch, previousBase, previousBatch, previousVisible) {
|
|
316
|
+
const same = yield* sameBatch(batch, previousBatch);
|
|
317
|
+
if (same && (yield* sameText(base, previousBase))) {
|
|
194
318
|
return {
|
|
195
319
|
documents: previousVisible.documents,
|
|
196
|
-
|
|
197
|
-
...replayHeads(base,
|
|
320
|
+
binaries: previousVisible.binaries,
|
|
321
|
+
...(yield* replayHeads(base, batch)),
|
|
198
322
|
};
|
|
199
323
|
}
|
|
200
|
-
const affected = new Set();
|
|
201
|
-
const
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
...Object.keys(previousBase.revisions),
|
|
206
|
-
...Object.keys(base.changes),
|
|
207
|
-
...Object.keys(previousBase.changes),
|
|
208
|
-
...base.binaryTargets,
|
|
209
|
-
...previousBase.binaryTargets,
|
|
210
|
-
]);
|
|
211
|
-
for (const path of paths) {
|
|
212
|
-
if (base.documents[path] !== previousBase.documents[path] ||
|
|
213
|
-
base.revisions[path] !== previousBase.revisions[path] ||
|
|
214
|
-
!sameChange(base.changes[path], previousBase.changes[path]) ||
|
|
215
|
-
base.binaryTargets.includes(path) !== previousBase.binaryTargets.includes(path))
|
|
324
|
+
const affected = new Set(yield* changedPaths(base, previousBase));
|
|
325
|
+
const touched = yield* pathsOf(batch);
|
|
326
|
+
let replayed = !same;
|
|
327
|
+
if (replayed)
|
|
328
|
+
for (const path of yield* pathsOf(previousBatch))
|
|
216
329
|
affected.add(path);
|
|
330
|
+
for (const path of touched) {
|
|
331
|
+
if (affected.has(path))
|
|
332
|
+
replayed = true;
|
|
333
|
+
yield ROW_WEIGHT;
|
|
217
334
|
}
|
|
218
|
-
const
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
}
|
|
225
|
-
for (const
|
|
226
|
-
|
|
227
|
-
for (const path of pathsOf(batch))
|
|
228
|
-
affected.add(path);
|
|
229
|
-
}
|
|
230
|
-
let expanded = true;
|
|
231
|
-
while (expanded) {
|
|
232
|
-
expanded = false;
|
|
233
|
-
for (const batch of queue) {
|
|
234
|
-
const touched = pathsOf(batch);
|
|
235
|
-
if (!touched.some((path) => affected.has(path)))
|
|
236
|
-
continue;
|
|
237
|
-
for (const path of touched) {
|
|
238
|
-
if (affected.has(path))
|
|
239
|
-
continue;
|
|
240
|
-
affected.add(path);
|
|
241
|
-
expanded = true;
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
const documents = {};
|
|
246
|
-
const revisions = {};
|
|
247
|
-
const changes = {};
|
|
248
|
-
for (const path of affected) {
|
|
335
|
+
const restricted = {
|
|
336
|
+
documents: {},
|
|
337
|
+
revisions: {},
|
|
338
|
+
fileIds: {},
|
|
339
|
+
changes: {},
|
|
340
|
+
binaries: {},
|
|
341
|
+
};
|
|
342
|
+
for (const path of replayed ? touched : []) {
|
|
343
|
+
affected.add(path);
|
|
249
344
|
if (base.documents[path] !== undefined)
|
|
250
|
-
documents[path] = base.documents[path];
|
|
345
|
+
restricted.documents[path] = base.documents[path];
|
|
251
346
|
if (base.revisions[path] !== undefined)
|
|
252
|
-
revisions[path] = base.revisions[path];
|
|
347
|
+
restricted.revisions[path] = base.revisions[path];
|
|
348
|
+
if (base.fileIds[path] !== undefined)
|
|
349
|
+
restricted.fileIds[path] = base.fileIds[path];
|
|
253
350
|
if (base.changes[path] !== undefined)
|
|
254
|
-
changes[path] = base.changes[path];
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
revisions,
|
|
259
|
-
changes,
|
|
260
|
-
binaryTargets: base.binaryTargets.filter((path) => affected.has(path)),
|
|
261
|
-
}, queue.filter((batch) => pathsOf(batch).some((path) => affected.has(path))));
|
|
262
|
-
const mergedDocuments = { ...previousVisible.documents };
|
|
263
|
-
const mergedRevisions = { ...previousVisible.revisions };
|
|
264
|
-
const mergedChanges = { ...previousVisible.changes };
|
|
265
|
-
const mergedTargets = new Set(previousVisible.binaryTargets);
|
|
266
|
-
for (const path of affected) {
|
|
267
|
-
delete mergedDocuments[path];
|
|
268
|
-
delete mergedRevisions[path];
|
|
269
|
-
delete mergedChanges[path];
|
|
270
|
-
mergedTargets.delete(path);
|
|
351
|
+
restricted.changes[path] = base.changes[path];
|
|
352
|
+
if (base.binaries[path] !== undefined)
|
|
353
|
+
restricted.binaries[path] = base.binaries[path];
|
|
354
|
+
yield ROW_WEIGHT;
|
|
271
355
|
}
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
Object.assign(mergedChanges, staged.changes);
|
|
275
|
-
for (const path of staged.binaryTargets)
|
|
276
|
-
mergedTargets.add(path);
|
|
356
|
+
const staged = replayed ? yield* overlaying(restricted, [batch]) : base;
|
|
357
|
+
const from = (path) => (touched.has(path) ? staged : base);
|
|
277
358
|
return {
|
|
278
|
-
documents:
|
|
279
|
-
revisions:
|
|
280
|
-
|
|
281
|
-
|
|
359
|
+
documents: yield* repatched(previousVisible.documents, affected, (path) => from(path).documents[path]),
|
|
360
|
+
revisions: yield* repatched(previousVisible.revisions, affected, (path) => from(path).revisions[path]),
|
|
361
|
+
fileIds: yield* repatched(previousVisible.fileIds, affected, (path) => from(path).fileIds[path]),
|
|
362
|
+
changes: yield* repatched(previousVisible.changes, affected, (path) => from(path).changes[path]),
|
|
363
|
+
binaries: yield* repatched(previousVisible.binaries, affected, (path) => from(path).binaries[path]),
|
|
282
364
|
};
|
|
283
365
|
}
|
package/dist/query.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { type Definition } from '@agentshouse/mdmodel';
|
|
2
2
|
import type { HeadChange } from './adapter.js';
|
|
3
|
+
import type { BinaryFileRecord } from './binary.js';
|
|
4
|
+
import type { Open } from './open.js';
|
|
3
5
|
export type Value = string | number | boolean | null;
|
|
4
6
|
export type Predicate = Value | {
|
|
5
7
|
$eq: Value;
|
|
@@ -36,6 +38,8 @@ export type Filter = {
|
|
|
36
38
|
types?: readonly string[];
|
|
37
39
|
where?: Where;
|
|
38
40
|
pathPrefix?: string;
|
|
41
|
+
folder?: string;
|
|
42
|
+
paths?: readonly string[];
|
|
39
43
|
hop?: Related & {
|
|
40
44
|
field: string;
|
|
41
45
|
};
|
|
@@ -43,7 +47,7 @@ export type Filter = {
|
|
|
43
47
|
field?: string;
|
|
44
48
|
};
|
|
45
49
|
};
|
|
46
|
-
export type Key = 'room' | 'path' | 'type' | {
|
|
50
|
+
export type Key = 'room' | 'path' | 'type' | 'folder' | {
|
|
47
51
|
field: string;
|
|
48
52
|
};
|
|
49
53
|
export type Select = 'all' | {
|
|
@@ -53,6 +57,7 @@ export type Select = 'all' | {
|
|
|
53
57
|
markdown?: true;
|
|
54
58
|
backlinks?: true;
|
|
55
59
|
change?: true;
|
|
60
|
+
fileId?: true;
|
|
56
61
|
};
|
|
57
62
|
export type OrderOptions = {
|
|
58
63
|
nulls?: 'first' | 'last';
|
|
@@ -68,6 +73,8 @@ export type DocumentQuery = Filter & {
|
|
|
68
73
|
direction?: Direction;
|
|
69
74
|
} & OrderOptions)[];
|
|
70
75
|
limit?: number;
|
|
76
|
+
after?: string;
|
|
77
|
+
total?: true;
|
|
71
78
|
};
|
|
72
79
|
export type GroupQuery = Filter & {
|
|
73
80
|
groupBy: readonly Exclude<Key, 'path'>[];
|
|
@@ -76,6 +83,8 @@ export type GroupQuery = Filter & {
|
|
|
76
83
|
direction?: Direction;
|
|
77
84
|
}[];
|
|
78
85
|
limit?: number;
|
|
86
|
+
after?: string;
|
|
87
|
+
total?: true;
|
|
79
88
|
};
|
|
80
89
|
export type LocalQuery = DocumentQuery | GroupQuery;
|
|
81
90
|
export type Backlink = {
|
|
@@ -93,18 +102,49 @@ export type QueryDocument = {
|
|
|
93
102
|
markdown?: string;
|
|
94
103
|
backlinks?: readonly Backlink[];
|
|
95
104
|
change?: HeadChange | null;
|
|
105
|
+
fileId?: string | null;
|
|
106
|
+
binaryFile?: BinaryFileRecord;
|
|
96
107
|
};
|
|
97
108
|
export type QueryGroup = {
|
|
98
109
|
key: readonly unknown[];
|
|
99
110
|
count: number;
|
|
100
111
|
};
|
|
101
|
-
export type
|
|
112
|
+
export type CoveredRoom = {
|
|
113
|
+
room: string;
|
|
114
|
+
generation: string;
|
|
115
|
+
current: boolean;
|
|
116
|
+
};
|
|
117
|
+
export type QueryCoverage = {
|
|
118
|
+
rooms: readonly CoveredRoom[];
|
|
119
|
+
indexes: readonly string[];
|
|
120
|
+
overlay: readonly string[];
|
|
121
|
+
};
|
|
122
|
+
export type Awaits = Open<'acquisition' | 'preparation' | 'index'>;
|
|
123
|
+
export type PendingRoom = {
|
|
124
|
+
room: string;
|
|
125
|
+
awaits: Awaits;
|
|
126
|
+
};
|
|
127
|
+
export type PendingResult = {
|
|
128
|
+
pending: readonly PendingRoom[];
|
|
129
|
+
};
|
|
130
|
+
export type DocumentRows = {
|
|
102
131
|
documents: readonly QueryDocument[];
|
|
132
|
+
next?: string;
|
|
133
|
+
total?: number;
|
|
103
134
|
};
|
|
104
|
-
export type
|
|
135
|
+
export type GroupRows = {
|
|
105
136
|
groups: readonly QueryGroup[];
|
|
137
|
+
next?: string;
|
|
138
|
+
total?: number;
|
|
139
|
+
};
|
|
140
|
+
export type QueryRows = DocumentRows | GroupRows;
|
|
141
|
+
export type DocumentResult = DocumentRows & {
|
|
142
|
+
coverage: QueryCoverage;
|
|
143
|
+
};
|
|
144
|
+
export type GroupResult = GroupRows & {
|
|
145
|
+
coverage: QueryCoverage;
|
|
106
146
|
};
|
|
107
|
-
export type QueryResult = DocumentResult | GroupResult;
|
|
147
|
+
export type QueryResult = DocumentResult | GroupResult | PendingResult;
|
|
108
148
|
export type QueryErrorCode = 'invalid-query' | 'unknown-type' | 'unknown-field' | 'wrong-kind';
|
|
109
149
|
export type RoomFacts = {
|
|
110
150
|
locator: string;
|
|
@@ -159,6 +199,8 @@ export type KeyPlan = {
|
|
|
159
199
|
of: 'path';
|
|
160
200
|
} | {
|
|
161
201
|
of: 'type';
|
|
202
|
+
} | {
|
|
203
|
+
of: 'folder';
|
|
162
204
|
} | {
|
|
163
205
|
of: 'field';
|
|
164
206
|
field: string;
|
|
@@ -171,6 +213,7 @@ export type DocumentShape = {
|
|
|
171
213
|
markdown: boolean;
|
|
172
214
|
backlinks: boolean;
|
|
173
215
|
change: boolean;
|
|
216
|
+
fileId: boolean;
|
|
174
217
|
orderBy: readonly {
|
|
175
218
|
key: KeyPlan;
|
|
176
219
|
options: OrderOptions & {
|
|
@@ -190,10 +233,17 @@ export type PlanReach = {
|
|
|
190
233
|
rooms: readonly string[];
|
|
191
234
|
documents: readonly string[];
|
|
192
235
|
};
|
|
236
|
+
export type Continuation = {
|
|
237
|
+
text: string;
|
|
238
|
+
values: readonly unknown[] | null;
|
|
239
|
+
};
|
|
193
240
|
export type Plan = {
|
|
241
|
+
key: string;
|
|
194
242
|
rooms: readonly string[] | null;
|
|
195
243
|
reach: PlanReach | null;
|
|
196
244
|
root: Scope;
|
|
245
|
+
folder: string | null;
|
|
246
|
+
paths: readonly string[] | null;
|
|
197
247
|
hop: (Scope & {
|
|
198
248
|
field: string;
|
|
199
249
|
}) | null;
|
|
@@ -202,17 +252,23 @@ export type Plan = {
|
|
|
202
252
|
}) | null;
|
|
203
253
|
shape: DocumentShape | GroupShape;
|
|
204
254
|
limit: number | null;
|
|
255
|
+
after: Continuation | null;
|
|
256
|
+
total: boolean;
|
|
205
257
|
};
|
|
206
258
|
export declare class QueryError extends Error {
|
|
259
|
+
readonly code: QueryErrorCode;
|
|
260
|
+
readonly retryable = false;
|
|
207
261
|
constructor(code: QueryErrorCode, at: string, problem: string);
|
|
208
262
|
}
|
|
209
263
|
type Entries = Readonly<Record<string, unknown>>;
|
|
210
264
|
export declare function invalid(at: string, problem: string): never;
|
|
211
265
|
export declare function plain(value: unknown): value is Entries;
|
|
212
266
|
export declare function known(value: Entries, allowed: readonly string[], at: string): void;
|
|
267
|
+
export declare function flag(input: unknown, at: string): boolean;
|
|
213
268
|
export declare function planOf(input: unknown, facts: HeldRooms, reach?: PlanReach | null): Plan;
|
|
214
269
|
export declare function limitOf(input: unknown): number | null;
|
|
215
270
|
export declare function filterOf(input: unknown, facts: HeldRooms, reach?: PlanReach | null): Plan;
|
|
271
|
+
export declare function queryKey(query: unknown): string;
|
|
216
272
|
export declare function identityOf(plan: Plan): string;
|
|
217
273
|
export {};
|
|
218
274
|
//# sourceMappingURL=query.d.ts.map
|