@agentshouse/mdruntime 0.1.0-c99e5271060cd → 0.1.0-c9b1e59e5baeb
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 +274 -244
- package/README.md +18 -8
- package/dist/adapter.d.ts +98 -20
- package/dist/adapter.d.ts.map +1 -1
- 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 +3 -2
- package/dist/bootstrap.d.ts.map +1 -1
- package/dist/bootstrap.js +38 -15
- package/dist/change-set.d.ts +7 -2
- package/dist/change-set.d.ts.map +1 -1
- package/dist/change-set.js +45 -13
- package/dist/change.d.ts +11 -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 +28 -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 +199 -0
- package/dist/chat/messages.d.ts +22 -0
- package/dist/chat/messages.d.ts.map +1 -0
- package/dist/chat/messages.js +175 -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 +32 -0
- package/dist/chat/overlay.d.ts.map +1 -0
- package/dist/chat/overlay.js +107 -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 +64 -0
- package/dist/chat/provider.d.ts.map +1 -0
- package/dist/chat/provider.js +637 -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 +26 -11
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +27 -4
- package/dist/collection.d.ts +20 -5
- package/dist/collection.d.ts.map +1 -1
- package/dist/collection.js +309 -33
- package/dist/connection.d.ts +41 -13
- package/dist/connection.d.ts.map +1 -1
- package/dist/connection.js +1819 -407
- package/dist/conversation.d.ts +34 -9
- package/dist/conversation.d.ts.map +1 -1
- package/dist/conversation.js +552 -168
- 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/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 -3
- package/dist/host.d.ts.map +1 -1
- package/dist/host.js +99 -13
- package/dist/identity.d.ts +4 -0
- package/dist/identity.d.ts.map +1 -1
- package/dist/identity.js +12 -0
- package/dist/index.d.ts +15 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -0
- package/dist/memory.d.ts +10 -4
- package/dist/memory.d.ts.map +1 -1
- package/dist/memory.js +64 -17
- package/dist/model.d.ts +4 -2
- package/dist/model.d.ts.map +1 -1
- package/dist/model.js +10 -1
- package/dist/observation.d.ts +7 -2
- package/dist/observation.d.ts.map +1 -1
- package/dist/observation.js +29 -12
- package/dist/outcome.d.ts +17 -1
- package/dist/outcome.d.ts.map +1 -1
- package/dist/outcome.js +10 -0
- package/dist/overlay.d.ts +18 -5
- package/dist/overlay.d.ts.map +1 -1
- package/dist/overlay.js +238 -160
- package/dist/query.d.ts +58 -4
- package/dist/query.d.ts.map +1 -1
- package/dist/query.js +36 -7
- package/dist/reach.d.ts +8 -3
- package/dist/reach.d.ts.map +1 -1
- package/dist/reach.js +55 -8
- package/dist/react.d.ts +10 -7
- package/dist/react.d.ts.map +1 -1
- package/dist/react.js +7 -17
- 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 +4 -4
- package/dist/refresh.d.ts.map +1 -1
- package/dist/refresh.js +51 -30
- package/dist/replica.d.ts +15 -6
- package/dist/replica.d.ts.map +1 -1
- package/dist/replica.js +137 -66
- package/dist/room-draft.d.ts +32 -3
- package/dist/room-draft.d.ts.map +1 -1
- package/dist/room-draft.js +129 -12
- package/dist/rows.d.ts +8 -13
- package/dist/rows.d.ts.map +1 -1
- package/dist/rows.js +12 -13
- package/dist/save.d.ts +32 -2
- package/dist/save.d.ts.map +1 -1
- package/dist/save.js +495 -97
- package/dist/search.d.ts +49 -6
- 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 +4 -1
- package/dist/status.d.ts.map +1 -1
- package/dist/status.js +0 -8
- package/dist/store.d.ts +71 -21
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +625 -320
- 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 +153 -30
- package/dist/wire.d.ts.map +1 -1
- package/dist/wire.js +53 -29
- 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,51 +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
|
-
|
|
86
|
-
|
|
87
|
-
|
|
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;
|
|
88
107
|
}
|
|
89
108
|
function relocate(staged, from, to) {
|
|
90
109
|
const text = staged.documents[from];
|
|
@@ -92,8 +111,9 @@ function relocate(staged, from, to) {
|
|
|
92
111
|
delete staged.documents[from];
|
|
93
112
|
staged.documents[to] = text;
|
|
94
113
|
}
|
|
95
|
-
else if (staged.
|
|
96
|
-
staged.
|
|
114
|
+
else if (staged.binaries[from] !== undefined) {
|
|
115
|
+
staged.binaries[to] = staged.binaries[from];
|
|
116
|
+
delete staged.binaries[from];
|
|
97
117
|
}
|
|
98
118
|
else {
|
|
99
119
|
return false;
|
|
@@ -103,185 +123,243 @@ function relocate(staged, from, to) {
|
|
|
103
123
|
}
|
|
104
124
|
function moveHead(heads, from, to) {
|
|
105
125
|
const revision = heads.revisions[from];
|
|
126
|
+
const fileId = heads.fileIds[from];
|
|
106
127
|
const change = heads.changes[from];
|
|
107
128
|
delete heads.revisions[from];
|
|
129
|
+
delete heads.fileIds[from];
|
|
108
130
|
delete heads.changes[from];
|
|
131
|
+
delete heads.fileIds[to];
|
|
109
132
|
delete heads.changes[to];
|
|
110
133
|
if (revision !== undefined)
|
|
111
134
|
heads.revisions[to] = revision;
|
|
135
|
+
if (fileId !== undefined)
|
|
136
|
+
heads.fileIds[to] = fileId;
|
|
112
137
|
if (change !== undefined)
|
|
113
138
|
heads.changes[to] = change;
|
|
114
139
|
}
|
|
115
140
|
function erase(staged, path) {
|
|
116
141
|
delete staged.documents[path];
|
|
117
142
|
delete staged.revisions[path];
|
|
143
|
+
delete staged.fileIds[path];
|
|
118
144
|
delete staged.changes[path];
|
|
119
|
-
staged.
|
|
145
|
+
delete staged.binaries[path];
|
|
120
146
|
}
|
|
121
|
-
function stage(staged, change
|
|
122
|
-
if (change.kind === 'field' || change.kind === 'section' || change.kind === 'preamble') {
|
|
123
|
-
return edit(staged, change, priors);
|
|
124
|
-
}
|
|
147
|
+
function stage(staged, change) {
|
|
125
148
|
if (change.kind === 'create') {
|
|
126
149
|
staged.documents[change.path] =
|
|
127
150
|
'content' in change ? change.content : compose(change.fields, change.sections);
|
|
151
|
+
delete staged.fileIds[change.path];
|
|
128
152
|
delete staged.changes[change.path];
|
|
129
153
|
return true;
|
|
130
154
|
}
|
|
131
155
|
if (change.kind === 'replace') {
|
|
156
|
+
delete staged.revisions[change.path];
|
|
132
157
|
if (staged.documents[change.path] === undefined)
|
|
133
158
|
return false;
|
|
134
159
|
staged.documents[change.path] = change.content;
|
|
135
160
|
return true;
|
|
136
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;
|
|
175
|
+
}
|
|
137
176
|
if (change.kind === 'move') {
|
|
138
177
|
return relocate(staged, change.path, change.to);
|
|
139
178
|
}
|
|
140
179
|
erase(staged, change.path);
|
|
141
180
|
return true;
|
|
142
181
|
}
|
|
143
|
-
export function
|
|
182
|
+
export function* overlaying(base, queue, unapplied) {
|
|
144
183
|
const staged = {
|
|
145
|
-
documents:
|
|
146
|
-
|
|
147
|
-
revisions:
|
|
148
|
-
|
|
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),
|
|
149
189
|
};
|
|
150
190
|
for (const batch of queue) {
|
|
151
|
-
const priors = priorsOf(batch.preconditions);
|
|
152
|
-
for (
|
|
153
|
-
|
|
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)
|
|
154
210
|
unapplied?.();
|
|
211
|
+
yield ROW_WEIGHT + text.length;
|
|
155
212
|
}
|
|
156
213
|
}
|
|
157
214
|
return {
|
|
158
|
-
documents: staged.documents,
|
|
159
|
-
|
|
160
|
-
revisions: staged.revisions,
|
|
161
|
-
|
|
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),
|
|
162
220
|
};
|
|
163
221
|
}
|
|
164
|
-
function pathsOf(batch) {
|
|
165
|
-
|
|
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;
|
|
166
231
|
}
|
|
167
|
-
export function
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
paths.every((path) => left.documents[path] === right.documents[path]) &&
|
|
171
|
-
left.binaryTargets.length === right.binaryTargets.length &&
|
|
172
|
-
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);
|
|
173
235
|
}
|
|
174
|
-
function
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
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];
|
|
276
|
+
}
|
|
277
|
+
else if (change.kind === 'create') {
|
|
278
|
+
delete heads.fileIds[change.path];
|
|
279
|
+
delete heads.changes[change.path];
|
|
188
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;
|
|
189
295
|
}
|
|
190
|
-
return
|
|
296
|
+
return {
|
|
297
|
+
revisions: yield* settling(heads.revisions),
|
|
298
|
+
fileIds: yield* settling(heads.fileIds),
|
|
299
|
+
changes: yield* settling(heads.changes),
|
|
300
|
+
};
|
|
301
|
+
}
|
|
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);
|
|
191
314
|
}
|
|
192
|
-
export function overlayChanged(base,
|
|
193
|
-
const
|
|
194
|
-
|
|
195
|
-
if (before.length === after.length &&
|
|
196
|
-
before.every((id, index) => id === after[index]) &&
|
|
197
|
-
sameLayerText(base, previousBase)) {
|
|
315
|
+
export function* overlayChanged(base, batch, previousBase, previousBatch, previousVisible) {
|
|
316
|
+
const same = yield* sameBatch(batch, previousBatch);
|
|
317
|
+
if (same && (yield* sameText(base, previousBase))) {
|
|
198
318
|
return {
|
|
199
319
|
documents: previousVisible.documents,
|
|
200
|
-
|
|
201
|
-
...replayHeads(base,
|
|
320
|
+
binaries: previousVisible.binaries,
|
|
321
|
+
...(yield* replayHeads(base, batch)),
|
|
202
322
|
};
|
|
203
323
|
}
|
|
204
|
-
const affected = new Set();
|
|
205
|
-
const
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
...Object.keys(previousBase.revisions),
|
|
210
|
-
...Object.keys(base.changes),
|
|
211
|
-
...Object.keys(previousBase.changes),
|
|
212
|
-
...base.binaryTargets,
|
|
213
|
-
...previousBase.binaryTargets,
|
|
214
|
-
]);
|
|
215
|
-
for (const path of paths) {
|
|
216
|
-
if (base.documents[path] !== previousBase.documents[path] ||
|
|
217
|
-
base.revisions[path] !== previousBase.revisions[path] ||
|
|
218
|
-
!sameChange(base.changes[path], previousBase.changes[path]) ||
|
|
219
|
-
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))
|
|
220
329
|
affected.add(path);
|
|
330
|
+
for (const path of touched) {
|
|
331
|
+
if (affected.has(path))
|
|
332
|
+
replayed = true;
|
|
333
|
+
yield ROW_WEIGHT;
|
|
221
334
|
}
|
|
222
|
-
const
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
}
|
|
229
|
-
for (const
|
|
230
|
-
|
|
231
|
-
for (const path of pathsOf(batch))
|
|
232
|
-
affected.add(path);
|
|
233
|
-
}
|
|
234
|
-
let expanded = true;
|
|
235
|
-
while (expanded) {
|
|
236
|
-
expanded = false;
|
|
237
|
-
for (const batch of queue) {
|
|
238
|
-
const touched = pathsOf(batch);
|
|
239
|
-
if (!touched.some((path) => affected.has(path)))
|
|
240
|
-
continue;
|
|
241
|
-
for (const path of touched) {
|
|
242
|
-
if (affected.has(path))
|
|
243
|
-
continue;
|
|
244
|
-
affected.add(path);
|
|
245
|
-
expanded = true;
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
const documents = {};
|
|
250
|
-
const revisions = {};
|
|
251
|
-
const changes = {};
|
|
252
|
-
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);
|
|
253
344
|
if (base.documents[path] !== undefined)
|
|
254
|
-
documents[path] = base.documents[path];
|
|
345
|
+
restricted.documents[path] = base.documents[path];
|
|
255
346
|
if (base.revisions[path] !== undefined)
|
|
256
|
-
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];
|
|
257
350
|
if (base.changes[path] !== undefined)
|
|
258
|
-
changes[path] = base.changes[path];
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
revisions,
|
|
263
|
-
changes,
|
|
264
|
-
binaryTargets: base.binaryTargets.filter((path) => affected.has(path)),
|
|
265
|
-
}, queue.filter((batch) => pathsOf(batch).some((path) => affected.has(path))));
|
|
266
|
-
const mergedDocuments = { ...previousVisible.documents };
|
|
267
|
-
const mergedRevisions = { ...previousVisible.revisions };
|
|
268
|
-
const mergedChanges = { ...previousVisible.changes };
|
|
269
|
-
const mergedTargets = new Set(previousVisible.binaryTargets);
|
|
270
|
-
for (const path of affected) {
|
|
271
|
-
delete mergedDocuments[path];
|
|
272
|
-
delete mergedRevisions[path];
|
|
273
|
-
delete mergedChanges[path];
|
|
274
|
-
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;
|
|
275
355
|
}
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
Object.assign(mergedChanges, staged.changes);
|
|
279
|
-
for (const path of staged.binaryTargets)
|
|
280
|
-
mergedTargets.add(path);
|
|
356
|
+
const staged = replayed ? yield* overlaying(restricted, [batch]) : base;
|
|
357
|
+
const from = (path) => (touched.has(path) ? staged : base);
|
|
281
358
|
return {
|
|
282
|
-
documents:
|
|
283
|
-
revisions:
|
|
284
|
-
|
|
285
|
-
|
|
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]),
|
|
286
364
|
};
|
|
287
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,6 +252,8 @@ 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 {
|
|
207
259
|
readonly code: QueryErrorCode;
|
|
@@ -212,9 +264,11 @@ type Entries = Readonly<Record<string, unknown>>;
|
|
|
212
264
|
export declare function invalid(at: string, problem: string): never;
|
|
213
265
|
export declare function plain(value: unknown): value is Entries;
|
|
214
266
|
export declare function known(value: Entries, allowed: readonly string[], at: string): void;
|
|
267
|
+
export declare function flag(input: unknown, at: string): boolean;
|
|
215
268
|
export declare function planOf(input: unknown, facts: HeldRooms, reach?: PlanReach | null): Plan;
|
|
216
269
|
export declare function limitOf(input: unknown): number | null;
|
|
217
270
|
export declare function filterOf(input: unknown, facts: HeldRooms, reach?: PlanReach | null): Plan;
|
|
271
|
+
export declare function queryKey(query: unknown): string;
|
|
218
272
|
export declare function identityOf(plan: Plan): string;
|
|
219
273
|
export {};
|
|
220
274
|
//# sourceMappingURL=query.d.ts.map
|