@agentshouse/mdmodel 0.1.0-ccf1367190878 → 0.1.0-cdbd463e01dc2
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/API.md +197 -178
- package/README.md +21 -22
- package/dist/blocks.d.ts.map +1 -1
- package/dist/blocks.js +35 -20
- package/dist/definition.d.ts +3 -1
- package/dist/definition.d.ts.map +1 -1
- package/dist/definition.js +112 -24
- package/dist/divide.d.ts.map +1 -1
- package/dist/divide.js +27 -17
- package/dist/document.d.ts +5 -5
- package/dist/document.d.ts.map +1 -1
- package/dist/document.js +304 -187
- package/dist/event.d.ts +78 -0
- package/dist/event.d.ts.map +1 -0
- package/dist/event.js +230 -0
- package/dist/facts.d.ts +15 -0
- package/dist/facts.d.ts.map +1 -0
- package/dist/facts.js +39 -0
- package/dist/index.d.ts +22 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +13 -6
- package/dist/kinds.d.ts +19 -0
- package/dist/kinds.d.ts.map +1 -0
- package/dist/kinds.js +161 -0
- package/dist/links.d.ts +2 -0
- package/dist/links.d.ts.map +1 -1
- package/dist/links.js +107 -50
- package/dist/paths.d.ts +9 -1
- package/dist/paths.d.ts.map +1 -1
- package/dist/paths.js +28 -2
- package/dist/pattern.d.ts +10 -0
- package/dist/pattern.d.ts.map +1 -0
- package/dist/pattern.js +355 -0
- package/dist/project.d.ts +1 -0
- package/dist/project.d.ts.map +1 -1
- package/dist/project.js +38 -15
- package/dist/query/language.d.ts +223 -0
- package/dist/query/language.d.ts.map +1 -0
- package/dist/query/language.js +565 -0
- package/dist/query/match.d.ts +14 -0
- package/dist/query/match.d.ts.map +1 -0
- package/dist/query/match.js +121 -0
- package/dist/query/rows.d.ts +32 -0
- package/dist/query/rows.d.ts.map +1 -0
- package/dist/query/rows.js +161 -0
- package/dist/query/sql.d.ts +39 -0
- package/dist/query/sql.d.ts.map +1 -0
- package/dist/query/sql.js +279 -0
- package/dist/references.d.ts.map +1 -1
- package/dist/references.js +6 -1
- package/dist/reserved.d.ts +5 -0
- package/dist/reserved.d.ts.map +1 -0
- package/dist/reserved.js +20 -0
- package/dist/schema.d.ts +1 -0
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +55 -4
- package/dist/types.d.ts +35 -4
- package/dist/types.d.ts.map +1 -1
- package/dist/validate.d.ts +29 -4
- package/dist/validate.d.ts.map +1 -1
- package/dist/validate.js +301 -85
- package/dist/yaml.d.ts.map +1 -1
- package/dist/yaml.js +36 -3
- package/fixtures/README.md +26 -6
- package/fixtures/cases/conditional-section/context.json +1 -0
- package/fixtures/cases/conditional-section/expected.json +6 -0
- package/fixtures/cases/conditional-section/library/questions/hosting.md +9 -0
- package/fixtures/cases/conditional-section/library/questions/payments.md +12 -0
- package/fixtures/cases/conditional-section/schema.yaml +14 -0
- package/fixtures/cases/cross-room-link/context.json +1 -0
- package/fixtures/cases/cross-room-link/expected.json +1 -0
- package/fixtures/cases/cross-room-link/library/clients/acme.md +6 -0
- package/fixtures/cases/cross-room-link/schema.yaml +3 -0
- package/fixtures/cases/cross-room-reference/context.json +1 -0
- package/fixtures/cases/cross-room-reference/expected.json +1 -0
- package/fixtures/cases/cross-room-reference/library/clients/acme.md +9 -0
- package/fixtures/cases/cross-room-reference/schema.yaml +9 -0
- package/fixtures/cases/link-into-a-reserved-name/context.json +1 -0
- package/fixtures/cases/link-into-a-reserved-name/expected.json +5 -0
- package/fixtures/cases/link-into-a-reserved-name/library/notes/a.md +6 -0
- package/fixtures/cases/link-into-a-reserved-name/schema.yaml +3 -0
- package/fixtures/cases/link-into-a-reserved-name-from-an-untyped-document/context.json +1 -0
- package/fixtures/cases/link-into-a-reserved-name-from-an-untyped-document/expected.json +5 -0
- package/fixtures/cases/link-into-a-reserved-name-from-an-untyped-document/library/notes/b.md +5 -0
- package/fixtures/cases/member-on-an-untyped-document/context.json +1 -0
- package/fixtures/cases/member-on-an-untyped-document/expected.json +6 -0
- package/fixtures/cases/member-on-an-untyped-document/library/note.md +4 -0
- package/fixtures/cases/member-on-another-type/context.json +1 -0
- package/fixtures/cases/member-on-another-type/expected.json +6 -0
- package/fixtures/cases/member-on-another-type/library/note.md +4 -0
- package/fixtures/cases/member-on-another-type/schema.yaml +7 -0
- package/fixtures/cases/reference-into-a-reserved-name/context.json +1 -0
- package/fixtures/cases/reference-into-a-reserved-name/expected.json +6 -0
- package/fixtures/cases/reference-into-a-reserved-name/library/notes/a.md +4 -0
- package/fixtures/cases/reference-into-a-reserved-name/library/settings/brief.md +1 -0
- package/fixtures/cases/reference-into-a-reserved-name/schema.yaml +3 -0
- package/fixtures/cases/room-md-declares-a-type/context.json +1 -0
- package/fixtures/cases/room-md-declares-a-type/expected.json +6 -0
- package/fixtures/cases/room-md-declares-a-type/library/ROOM.md +5 -0
- package/fixtures/cases/typed-path-names-another-type/context.json +11 -0
- package/fixtures/cases/typed-path-names-another-type/expected.json +6 -0
- package/fixtures/cases/typed-path-names-another-type/library/settings/prefs/one.md +3 -0
- package/fixtures/cases/typed-path-names-another-type/schema.yaml +6 -0
- package/fixtures/cases/typed-path-names-its-type/context.json +11 -0
- package/fixtures/cases/typed-path-names-its-type/expected.json +3 -0
- package/fixtures/cases/typed-path-names-its-type/library/settings/prefs/deeper/two.md +1 -0
- package/fixtures/cases/typed-path-names-its-type/library/settings/prefs/one.md +4 -0
- package/fixtures/cases/typed-path-names-its-type/schema.yaml +6 -0
- package/fixtures/cases/typed-path-names-no-type/context.json +11 -0
- package/fixtures/cases/typed-path-names-no-type/expected.json +6 -0
- package/fixtures/cases/typed-path-names-no-type/library/settings/prefs/one.md +1 -0
- package/fixtures/cases/typed-path-names-no-type/schema.yaml +6 -0
- package/fixtures/cases/unnamed-typed-path-checks-its-fields/context.json +11 -0
- package/fixtures/cases/unnamed-typed-path-checks-its-fields/expected.json +6 -0
- package/fixtures/cases/unnamed-typed-path-checks-its-fields/library/rooms/team/tasks/plan.md +4 -0
- package/fixtures/cases/unnamed-typed-path-checks-its-fields/schema.yaml +5 -0
- package/fixtures/cases/unnamed-typed-path-names-a-type/context.json +11 -0
- package/fixtures/cases/unnamed-typed-path-names-a-type/expected.json +6 -0
- package/fixtures/cases/unnamed-typed-path-names-a-type/library/rooms/team/tasks/plan.md +6 -0
- package/fixtures/cases/unnamed-typed-path-names-a-type/schema.yaml +5 -0
- package/fixtures/cases/unnamed-typed-path-reads-its-type/context.json +11 -0
- package/fixtures/cases/unnamed-typed-path-reads-its-type/expected.json +3 -0
- package/fixtures/cases/unnamed-typed-path-reads-its-type/library/rooms/team/plan.md +1 -0
- package/fixtures/cases/unnamed-typed-path-reads-its-type/library/rooms/team/tasks/plan.md +5 -0
- package/fixtures/cases/unnamed-typed-path-reads-its-type/schema.yaml +5 -0
- package/fixtures/cases/unnamed-typed-path-without-a-body/context.json +11 -0
- package/fixtures/cases/unnamed-typed-path-without-a-body/expected.json +5 -0
- package/fixtures/cases/unnamed-typed-path-without-a-body/library/rooms/team/tasks/plan.md +5 -0
- package/fixtures/cases/unnamed-typed-path-without-a-body/schema.yaml +5 -0
- package/fixtures/division.json +26 -26
- package/fixtures/queries.json +913 -0
- package/package.json +7 -2
- package/dist/condition.d.ts +0 -149
- package/dist/condition.d.ts.map +0 -1
- package/dist/condition.js +0 -500
package/dist/document.js
CHANGED
|
@@ -1,24 +1,35 @@
|
|
|
1
1
|
import { ARRAY_INDEX, pointerSegments } from './definition.js';
|
|
2
|
-
import { hrefOccurrences } from './links.js';
|
|
3
|
-
import { destinationPath, relative, retarget, SHELL_ROOMS, shellTarget, target } from './paths.js';
|
|
2
|
+
import { destinations, hrefOccurrences, linkInventory, } from './links.js';
|
|
3
|
+
import { destinationPath, relative, retarget, roomPath, roomTarget, SHELL_ROOMS, shellTarget, target, } from './paths.js';
|
|
4
4
|
import { references } from './references.js';
|
|
5
5
|
import { headingSpans, sectionsRecord } from './sections.js';
|
|
6
6
|
import { refusal } from './refuse.js';
|
|
7
7
|
import { bodyStartAfterYaml, bodyStartOf, equalValue, extractFrontmatter, frontmatterValue, jsValue, lineEnding, mapEntry, parseYamlMapping, serializeJs, serializeKey, YamlError, } from './yaml.js';
|
|
8
|
-
const
|
|
8
|
+
const HELD = Symbol('held');
|
|
9
|
+
function heldOf(document) {
|
|
10
|
+
return document[HELD];
|
|
11
|
+
}
|
|
12
|
+
export function inventoryOf(document) {
|
|
13
|
+
const held = heldOf(document);
|
|
14
|
+
if (held?.inventory !== undefined)
|
|
15
|
+
return held.inventory;
|
|
16
|
+
const inventory = linkInventory(document.content.slice(bodyStartOf(document.content)));
|
|
17
|
+
if (held !== undefined)
|
|
18
|
+
held.inventory = inventory;
|
|
19
|
+
return inventory;
|
|
20
|
+
}
|
|
9
21
|
function refuse(file, rule, location) {
|
|
10
22
|
return location === undefined ? refusal(file, rule) : refusal(file, rule, { location });
|
|
11
23
|
}
|
|
12
24
|
function freezeDocument(content, type, fields, preamble, sections, internal) {
|
|
13
|
-
const
|
|
25
|
+
const held = { internal, inventory: undefined };
|
|
26
|
+
return Object.freeze(Object.defineProperty({
|
|
14
27
|
content,
|
|
15
28
|
type,
|
|
16
29
|
fields: Object.freeze(fields),
|
|
17
30
|
preamble,
|
|
18
31
|
sections: Object.freeze(sections),
|
|
19
|
-
});
|
|
20
|
-
internals.set(document, internal);
|
|
21
|
-
return document;
|
|
32
|
+
}, HELD, { value: held }));
|
|
22
33
|
}
|
|
23
34
|
function declaredType(fields) {
|
|
24
35
|
const value = fields.type;
|
|
@@ -72,86 +83,6 @@ export function parse(content, file = '') {
|
|
|
72
83
|
document: freezeDocument(content, declaredType(read.fields), read.fields, content.slice(bodyStart, spans[0]?.headingStart), sectionsRecord(spans, content), { root: read.root, yamlEnd: read.yamlEnd, bodyStart }),
|
|
73
84
|
};
|
|
74
85
|
}
|
|
75
|
-
function splice(content, start, end, insert) {
|
|
76
|
-
return content.slice(0, start) + insert + content.slice(end);
|
|
77
|
-
}
|
|
78
|
-
function applyField(document, name, value, prior) {
|
|
79
|
-
const internal = internals.get(document);
|
|
80
|
-
if (internal === undefined || internal.root === null) {
|
|
81
|
-
return { outcome: 'refuse', refusal: refuse('', 'frontmatter-fence', name) };
|
|
82
|
-
}
|
|
83
|
-
if (!equalValue(document.fields[name], prior)) {
|
|
84
|
-
return { outcome: 'stale', document };
|
|
85
|
-
}
|
|
86
|
-
if (!frontmatterValue(value)) {
|
|
87
|
-
return { outcome: 'refuse', refusal: refuse('', 'frontmatter-fence', name) };
|
|
88
|
-
}
|
|
89
|
-
let nextContent;
|
|
90
|
-
const existing = mapEntry(internal.root, name);
|
|
91
|
-
if (existing !== undefined) {
|
|
92
|
-
const held = existing.value;
|
|
93
|
-
const inline = held.start > existing.after &&
|
|
94
|
-
!/[\r\n]/.test(document.content.slice(existing.after, held.start));
|
|
95
|
-
nextContent = inline
|
|
96
|
-
? splice(document.content, held.start, held.end, serializeJs(value))
|
|
97
|
-
: splice(document.content, existing.after, held.end, ` ${serializeJs(value)}`);
|
|
98
|
-
}
|
|
99
|
-
else if (document.content[internal.root.start] === '{') {
|
|
100
|
-
nextContent = splice(document.content, internal.root.end - 1, internal.root.end - 1, `${internal.root.entries.length === 0 ? '' : ', '}${serializeKey(name)}: ${serializeJs(value)}`);
|
|
101
|
-
}
|
|
102
|
-
else {
|
|
103
|
-
const nl = lineEnding(document.content);
|
|
104
|
-
const lineStart = document.content.lastIndexOf('\n', internal.root.start - 1) + 1;
|
|
105
|
-
const indent = document.content.slice(lineStart, internal.root.start);
|
|
106
|
-
const line = `${indent}${serializeKey(name)}: ${serializeJs(value)}${nl}`;
|
|
107
|
-
const before = document.content.slice(0, internal.yamlEnd);
|
|
108
|
-
const prefix = before.endsWith('\n') || before.endsWith('\r\n') ? '' : nl;
|
|
109
|
-
nextContent = splice(document.content, internal.yamlEnd, internal.yamlEnd, `${prefix}${line}`);
|
|
110
|
-
}
|
|
111
|
-
const parsed = parse(nextContent);
|
|
112
|
-
if (!parsed.ok)
|
|
113
|
-
return { outcome: 'refuse', refusal: parsed.refusal };
|
|
114
|
-
return { outcome: 'applied', document: parsed.document };
|
|
115
|
-
}
|
|
116
|
-
function applySection(document, name, value, prior) {
|
|
117
|
-
const internal = internals.get(document);
|
|
118
|
-
if (internal === undefined)
|
|
119
|
-
return { outcome: 'refuse', refusal: refuse('', 'required-section', name) };
|
|
120
|
-
const spans = headingSpans(document.content, internal.bodyStart);
|
|
121
|
-
const span = spans.find((item) => item.name === name);
|
|
122
|
-
if (span === undefined)
|
|
123
|
-
return { outcome: 'refuse', refusal: refuse('', 'required-section', name) };
|
|
124
|
-
const current = document.content.slice(span.bodyStart, span.bodyEnd);
|
|
125
|
-
if (current !== prior)
|
|
126
|
-
return { outcome: 'stale', document };
|
|
127
|
-
return replaced(document, internal.bodyStart, span.bodyStart, span.bodyEnd, value);
|
|
128
|
-
}
|
|
129
|
-
function applyPreamble(document, value, prior) {
|
|
130
|
-
if (document.preamble !== prior)
|
|
131
|
-
return { outcome: 'stale', document };
|
|
132
|
-
const start = bodyStartOf(document.content);
|
|
133
|
-
return replaced(document, start, start, start + document.preamble.length, value);
|
|
134
|
-
}
|
|
135
|
-
function firstHeadings(content, bodyStart) {
|
|
136
|
-
const first = new Map();
|
|
137
|
-
for (const span of headingSpans(content, bodyStart)) {
|
|
138
|
-
if (!first.has(span.name))
|
|
139
|
-
first.set(span.name, span.headingStart);
|
|
140
|
-
}
|
|
141
|
-
return first;
|
|
142
|
-
}
|
|
143
|
-
function replaced(document, bodyStart, start, end, value) {
|
|
144
|
-
const content = splice(document.content, start, end, value);
|
|
145
|
-
const after = firstHeadings(content, bodyStartOf(content));
|
|
146
|
-
for (const [name, at] of firstHeadings(document.content, bodyStart)) {
|
|
147
|
-
if (after.get(name) !== (at < start ? at : at + value.length - (end - start)))
|
|
148
|
-
return { outcome: 'refuse', refusal: refuse('', 'overlapping-section', name) };
|
|
149
|
-
}
|
|
150
|
-
const parsed = parse(content);
|
|
151
|
-
if (!parsed.ok)
|
|
152
|
-
return { outcome: 'refuse', refusal: parsed.refusal };
|
|
153
|
-
return { outcome: 'applied', document: parsed.document };
|
|
154
|
-
}
|
|
155
86
|
function fitsBare(to) {
|
|
156
87
|
if (to === '' || to.startsWith('<'))
|
|
157
88
|
return false;
|
|
@@ -179,58 +110,34 @@ function destinationText(to, bracketed) {
|
|
|
179
110
|
return `<${to}>`;
|
|
180
111
|
return null;
|
|
181
112
|
}
|
|
182
|
-
function
|
|
183
|
-
const
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
for (const match of hrefOccurrences(content.slice(bodyStart))) {
|
|
187
|
-
if (match.href !== href)
|
|
188
|
-
continue;
|
|
189
|
-
const text = destinationText(written, match.bracketed);
|
|
190
|
-
if (text === null)
|
|
191
|
-
return refuse('', 'unwritable-link', written);
|
|
192
|
-
rewritten += content.slice(cursor, bodyStart + match.start);
|
|
193
|
-
rewritten += text;
|
|
194
|
-
cursor = bodyStart + match.end;
|
|
195
|
-
}
|
|
196
|
-
return rewritten + content.slice(cursor);
|
|
197
|
-
}
|
|
198
|
-
function shellRelinked(content, bodyStart, file, handle) {
|
|
199
|
-
const hrefs = new Set(hrefOccurrences(content.slice(bodyStart)).map(({ href }) => href));
|
|
200
|
-
let held = content;
|
|
201
|
-
for (const href of hrefs) {
|
|
113
|
+
function shellRelinked(body, file, handle) {
|
|
114
|
+
const occurrences = hrefOccurrences(body);
|
|
115
|
+
const written = new Map();
|
|
116
|
+
for (const href of new Set(occurrences.map((occurrence) => occurrence.href))) {
|
|
202
117
|
const path = shellTarget(href, handle);
|
|
203
118
|
if (path === null)
|
|
204
119
|
continue;
|
|
205
|
-
const
|
|
206
|
-
if (
|
|
207
|
-
return
|
|
208
|
-
|
|
120
|
+
const to = retarget(href, relative(file, path));
|
|
121
|
+
if (destinationText(to, false) === null)
|
|
122
|
+
return refuse('', 'unwritable-link', to);
|
|
123
|
+
written.set(href, to);
|
|
209
124
|
}
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
return { outcome: 'applied', document: parsed.document };
|
|
221
|
-
}
|
|
222
|
-
function applyLink(document, href, to) {
|
|
223
|
-
const content = document.content;
|
|
224
|
-
const bodyStart = bodyStartOf(content);
|
|
225
|
-
if (!hrefOccurrences(content.slice(bodyStart)).some((occurrence) => occurrence.href === href))
|
|
226
|
-
return { outcome: 'stale', document };
|
|
227
|
-
return reparsed(document, relinked(content, bodyStart, href, to));
|
|
125
|
+
let rewritten = '';
|
|
126
|
+
let cursor = 0;
|
|
127
|
+
for (const match of occurrences) {
|
|
128
|
+
const to = written.get(match.href);
|
|
129
|
+
if (to === undefined)
|
|
130
|
+
continue;
|
|
131
|
+
rewritten += body.slice(cursor, match.start) + destinationText(to, match.bracketed);
|
|
132
|
+
cursor = match.end;
|
|
133
|
+
}
|
|
134
|
+
return rewritten + body.slice(cursor);
|
|
228
135
|
}
|
|
229
|
-
function nodeAt(root, pointer) {
|
|
136
|
+
function nodeAt(root, pointer, entryOf = mapEntry) {
|
|
230
137
|
let node = root;
|
|
231
138
|
for (const key of pointerSegments(pointer)) {
|
|
232
139
|
if (node?.kind === 'map')
|
|
233
|
-
node =
|
|
140
|
+
node = entryOf(node, key)?.value;
|
|
234
141
|
else if (node?.kind === 'seq' && ARRAY_INDEX.test(key))
|
|
235
142
|
node = node.items[Number(key)];
|
|
236
143
|
else
|
|
@@ -245,37 +152,36 @@ function scalarText(source, value) {
|
|
|
245
152
|
return JSON.stringify(value);
|
|
246
153
|
return serializeJs(value);
|
|
247
154
|
}
|
|
248
|
-
function
|
|
249
|
-
const
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
const
|
|
254
|
-
const parsed = parse(splice(document.content, node.start, node.end, text));
|
|
255
|
-
if (!parsed.ok)
|
|
256
|
-
return { outcome: 'refuse', refusal: parsed.refusal };
|
|
257
|
-
return { outcome: 'applied', document: parsed.document };
|
|
258
|
-
}
|
|
259
|
-
export function relativize(document, file, handle, definition) {
|
|
260
|
-
let held = document;
|
|
155
|
+
export function relativize(document, file, handle, definition, kept = new Set()) {
|
|
156
|
+
const relativized = (href) => {
|
|
157
|
+
const path = shellTarget(href, handle);
|
|
158
|
+
return path === null || kept.has(`${SHELL_ROOMS}${handle}/${path}`) ? null : path;
|
|
159
|
+
};
|
|
160
|
+
const changes = [];
|
|
261
161
|
for (const { pointer, value } of definition === undefined
|
|
262
162
|
? []
|
|
263
163
|
: references(document, definition)) {
|
|
264
|
-
const path =
|
|
265
|
-
if (path
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
164
|
+
const path = relativized(value);
|
|
165
|
+
if (path !== null)
|
|
166
|
+
changes.push({
|
|
167
|
+
kind: 'reference',
|
|
168
|
+
pointer,
|
|
169
|
+
value: retarget(value, relative(file, path)),
|
|
170
|
+
prior: value,
|
|
171
|
+
});
|
|
271
172
|
}
|
|
272
|
-
|
|
173
|
+
for (const href of new Set(destinations(inventoryOf(document)).map(({ href }) => href))) {
|
|
174
|
+
const path = relativized(href);
|
|
175
|
+
if (path !== null)
|
|
176
|
+
changes.push({ kind: 'link', href, to: relative(file, path) });
|
|
177
|
+
}
|
|
178
|
+
return apply(document, changes);
|
|
273
179
|
}
|
|
274
180
|
export function relativizeBody(body, file, handle) {
|
|
275
|
-
const relinkedBody = shellRelinked(body,
|
|
181
|
+
const relinkedBody = shellRelinked(body, file, handle);
|
|
276
182
|
if (typeof relinkedBody !== 'string')
|
|
277
183
|
return { outcome: 'refuse', refusal: relinkedBody };
|
|
278
|
-
const elsewhere = hrefOccurrences(relinkedBody).find(({ href }) => destinationPath(href)?.startsWith(SHELL_ROOMS) === true);
|
|
184
|
+
const elsewhere = hrefOccurrences(relinkedBody).find(({ href }) => destinationPath(href)?.startsWith(SHELL_ROOMS) === true && roomTarget(href) === null);
|
|
279
185
|
if (elsewhere !== undefined)
|
|
280
186
|
return { outcome: 'refuse', refusal: refuse(file, 'unresolved-link', elsewhere.href) };
|
|
281
187
|
return { outcome: 'applied', body: relinkedBody };
|
|
@@ -284,11 +190,11 @@ export function relinkBody(body, file, moves) {
|
|
|
284
190
|
let rewritten = '';
|
|
285
191
|
let cursor = 0;
|
|
286
192
|
for (const match of hrefOccurrences(body)) {
|
|
287
|
-
const from = target(file, match.href);
|
|
193
|
+
const from = target(file, match.href) ?? roomPath(match.href);
|
|
288
194
|
const to = from === null ? undefined : moves.get(from);
|
|
289
195
|
if (to === undefined)
|
|
290
196
|
continue;
|
|
291
|
-
const written = retarget(match.href, relative(file, to));
|
|
197
|
+
const written = retarget(match.href, from.startsWith(SHELL_ROOMS) || to.startsWith(SHELL_ROOMS) ? to : relative(file, to));
|
|
292
198
|
const text = destinationText(written, match.bracketed);
|
|
293
199
|
if (text === null)
|
|
294
200
|
return { outcome: 'refuse', refusal: refuse(file, 'unwritable-link', written) };
|
|
@@ -297,54 +203,265 @@ export function relinkBody(body, file, moves) {
|
|
|
297
203
|
}
|
|
298
204
|
return { outcome: 'applied', body: rewritten + body.slice(cursor) };
|
|
299
205
|
}
|
|
300
|
-
function
|
|
301
|
-
const found = [];
|
|
302
|
-
for (const occurrence of hrefOccurrences(text)) {
|
|
303
|
-
const resolved = target(file, occurrence.href);
|
|
304
|
-
if (resolved !== null)
|
|
305
|
-
found.push({ href: occurrence.href, target: resolved, start: offset + occurrence.start });
|
|
306
|
-
}
|
|
307
|
-
return found;
|
|
308
|
-
}
|
|
309
|
-
function linksIn(text, file) {
|
|
206
|
+
function linksIn(occurrences, file) {
|
|
310
207
|
const found = [];
|
|
311
208
|
const seen = new Set();
|
|
312
|
-
for (const occurrence of
|
|
209
|
+
for (const occurrence of occurrences) {
|
|
313
210
|
if (seen.has(occurrence.href))
|
|
314
211
|
continue;
|
|
212
|
+
const resolved = target(file, occurrence.href);
|
|
213
|
+
if (resolved === null)
|
|
214
|
+
continue;
|
|
315
215
|
seen.add(occurrence.href);
|
|
316
|
-
found.push({ href: occurrence.href, target:
|
|
216
|
+
found.push({ href: occurrence.href, target: resolved });
|
|
317
217
|
}
|
|
318
218
|
return found;
|
|
319
219
|
}
|
|
320
220
|
export function links(document, file) {
|
|
321
|
-
return linksIn(
|
|
322
|
-
}
|
|
323
|
-
export function linkOccurrences(document, file) {
|
|
324
|
-
const bodyStart = bodyStartOf(document.content);
|
|
325
|
-
return occurrencesIn(document.content.slice(bodyStart), file, bodyStart);
|
|
221
|
+
return linksIn(destinations(inventoryOf(document)), file);
|
|
326
222
|
}
|
|
327
223
|
export function bodyLinks(body, file) {
|
|
328
|
-
return linksIn(body, file);
|
|
224
|
+
return linksIn(hrefOccurrences(body), file);
|
|
329
225
|
}
|
|
330
|
-
|
|
226
|
+
function internalOf(document) {
|
|
227
|
+
const held = heldOf(document);
|
|
228
|
+
if (held !== undefined)
|
|
229
|
+
return held.internal;
|
|
230
|
+
const read = opened(document.content, '');
|
|
231
|
+
if (!read.ok)
|
|
232
|
+
return read.refusal;
|
|
233
|
+
return {
|
|
234
|
+
root: read.root,
|
|
235
|
+
yamlEnd: read.yamlEnd,
|
|
236
|
+
bodyStart: read.root === null ? 0 : bodyStartAfterYaml(document.content, read.yamlEnd),
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
function partOf(change) {
|
|
240
|
+
if (change.kind === 'field' || change.kind === 'section')
|
|
241
|
+
return `${change.kind} ${change.name}`;
|
|
331
242
|
if (change.kind === 'link')
|
|
332
|
-
return
|
|
243
|
+
return `link ${change.href}`;
|
|
333
244
|
if (change.kind === 'reference')
|
|
334
|
-
return
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
245
|
+
return `reference ${change.pointer}`;
|
|
246
|
+
return 'preamble';
|
|
247
|
+
}
|
|
248
|
+
function planner(document, internal) {
|
|
249
|
+
const content = document.content;
|
|
250
|
+
const keyed = new Map();
|
|
251
|
+
let spans;
|
|
252
|
+
let occurrences;
|
|
253
|
+
let ending;
|
|
254
|
+
let added = 0;
|
|
255
|
+
const entryOf = (map, key) => {
|
|
256
|
+
let index = keyed.get(map);
|
|
257
|
+
if (index === undefined) {
|
|
258
|
+
index = new Map();
|
|
259
|
+
for (const entry of map.entries)
|
|
260
|
+
if (!index.has(entry.key))
|
|
261
|
+
index.set(entry.key, entry);
|
|
262
|
+
keyed.set(map, index);
|
|
263
|
+
}
|
|
264
|
+
return index.get(key);
|
|
265
|
+
};
|
|
266
|
+
const field = (name, value, prior, at) => {
|
|
267
|
+
const root = internal.root;
|
|
268
|
+
if (root === null)
|
|
269
|
+
return refuse('', 'frontmatter-fence', name);
|
|
270
|
+
if (!equalValue(document.fields[name], prior))
|
|
271
|
+
return 'stale';
|
|
272
|
+
if (!frontmatterValue(value))
|
|
273
|
+
return refuse('', 'frontmatter-fence', name);
|
|
274
|
+
const existing = entryOf(root, name);
|
|
275
|
+
if (existing !== undefined) {
|
|
276
|
+
const held = existing.value;
|
|
277
|
+
const inline = held.start > existing.after && !/[\r\n]/.test(content.slice(existing.after, held.start));
|
|
278
|
+
return inline
|
|
279
|
+
? [{ start: held.start, end: held.end, text: serializeJs(value), at }]
|
|
280
|
+
: [{ start: existing.after, end: held.end, text: ` ${serializeJs(value)}`, at }];
|
|
281
|
+
}
|
|
282
|
+
const entry = `${serializeKey(name)}: ${serializeJs(value)}`;
|
|
283
|
+
added += 1;
|
|
284
|
+
if (content[root.start] === '{') {
|
|
285
|
+
const separator = root.entries.length === 0 && added === 1 ? '' : ', ';
|
|
286
|
+
return [{ start: root.end - 1, end: root.end - 1, text: `${separator}${entry}`, at }];
|
|
287
|
+
}
|
|
288
|
+
const lineStart = content.lastIndexOf('\n', root.start - 1) + 1;
|
|
289
|
+
ending ??= lineEnding(content);
|
|
290
|
+
const line = `${content.slice(lineStart, root.start)}${entry}${ending}`;
|
|
291
|
+
return [{ start: internal.yamlEnd, end: internal.yamlEnd, text: line, at, entry: true }];
|
|
292
|
+
};
|
|
293
|
+
const section = (name, value, prior, at) => {
|
|
294
|
+
if (spans === undefined) {
|
|
295
|
+
spans = new Map();
|
|
296
|
+
for (const span of headingSpans(content, internal.bodyStart))
|
|
297
|
+
if (!spans.has(span.name))
|
|
298
|
+
spans.set(span.name, span);
|
|
299
|
+
}
|
|
300
|
+
const span = spans.get(name);
|
|
301
|
+
if (span === undefined)
|
|
302
|
+
return refuse('', 'required-section', name);
|
|
303
|
+
if (content.slice(span.bodyStart, span.bodyEnd) !== prior)
|
|
304
|
+
return 'stale';
|
|
305
|
+
return [{ start: span.bodyStart, end: span.bodyEnd, text: value, at }];
|
|
306
|
+
};
|
|
307
|
+
const link = (href, to, at) => {
|
|
308
|
+
if (occurrences === undefined) {
|
|
309
|
+
occurrences = new Map();
|
|
310
|
+
for (const occurrence of destinations(inventoryOf(document))) {
|
|
311
|
+
const same = occurrences.get(occurrence.href);
|
|
312
|
+
if (same === undefined)
|
|
313
|
+
occurrences.set(occurrence.href, [occurrence]);
|
|
314
|
+
else
|
|
315
|
+
same.push(occurrence);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
const found = occurrences.get(href);
|
|
319
|
+
if (found === undefined)
|
|
320
|
+
return 'stale';
|
|
321
|
+
const written = retarget(href, to);
|
|
322
|
+
if (destinationText(written, false) === null)
|
|
323
|
+
return refuse('', 'unwritable-link', written);
|
|
324
|
+
return found.map((occurrence) => ({
|
|
325
|
+
start: internal.bodyStart + occurrence.start,
|
|
326
|
+
end: internal.bodyStart + occurrence.end,
|
|
327
|
+
text: destinationText(written, occurrence.bracketed),
|
|
328
|
+
at,
|
|
329
|
+
}));
|
|
330
|
+
};
|
|
331
|
+
const reference = (pointer, value, prior, at) => {
|
|
332
|
+
const node = internal.root === null ? undefined : nodeAt(internal.root, pointer, entryOf);
|
|
333
|
+
if (node?.kind !== 'scalar' || node.value !== prior)
|
|
334
|
+
return 'stale';
|
|
335
|
+
return [
|
|
336
|
+
{ start: node.start, end: node.end, text: scalarText(content[node.start], value), at },
|
|
337
|
+
];
|
|
338
|
+
};
|
|
339
|
+
return (change, at) => {
|
|
340
|
+
if (change.kind === 'field')
|
|
341
|
+
return field(change.name, change.value, change.prior, at);
|
|
342
|
+
if (change.kind === 'section')
|
|
343
|
+
return section(change.name, change.value, change.prior, at);
|
|
344
|
+
if (change.kind === 'link')
|
|
345
|
+
return link(change.href, change.to, at);
|
|
346
|
+
if (change.kind === 'reference')
|
|
347
|
+
return reference(change.pointer, change.value, change.prior, at);
|
|
348
|
+
if (document.preamble !== change.prior)
|
|
349
|
+
return 'stale';
|
|
350
|
+
const start = internal.bodyStart;
|
|
351
|
+
return [{ start, end: start + document.preamble.length, text: change.value, at }];
|
|
352
|
+
};
|
|
353
|
+
}
|
|
354
|
+
function overlapping(edits, stale) {
|
|
355
|
+
let reach = -1;
|
|
356
|
+
let owner = -1;
|
|
357
|
+
for (const edit of edits) {
|
|
358
|
+
if (edit.start < reach)
|
|
359
|
+
stale.add(Math.max(edit.at, owner));
|
|
360
|
+
if (edit.end > reach) {
|
|
361
|
+
reach = edit.end;
|
|
362
|
+
owner = edit.at;
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
function firstHeadings(content, bodyStart) {
|
|
367
|
+
const first = new Map();
|
|
368
|
+
for (const span of headingSpans(content, bodyStart)) {
|
|
369
|
+
if (!first.has(span.name))
|
|
370
|
+
first.set(span.name, span.headingStart);
|
|
371
|
+
}
|
|
372
|
+
return first;
|
|
373
|
+
}
|
|
374
|
+
function hidden(before, bodyStart, after, shifts) {
|
|
375
|
+
const placed = firstHeadings(after, bodyStartOf(after));
|
|
376
|
+
let shift = 0;
|
|
377
|
+
let index = 0;
|
|
378
|
+
for (const [name, at] of firstHeadings(before, bodyStart)) {
|
|
379
|
+
while (index < shifts.length && shifts[index][0] <= at) {
|
|
380
|
+
shift += shifts[index][1];
|
|
381
|
+
index += 1;
|
|
382
|
+
}
|
|
383
|
+
if (placed.get(name) !== at + shift)
|
|
384
|
+
return name;
|
|
385
|
+
}
|
|
386
|
+
return undefined;
|
|
387
|
+
}
|
|
388
|
+
function spliced(source, edits) {
|
|
389
|
+
const shifts = [];
|
|
390
|
+
const pieces = [];
|
|
391
|
+
let cursor = 0;
|
|
392
|
+
let entered = false;
|
|
393
|
+
let ended = false;
|
|
394
|
+
for (const edit of edits) {
|
|
395
|
+
const kept = source.slice(cursor, edit.start);
|
|
396
|
+
pieces.push(kept);
|
|
397
|
+
if (kept !== '')
|
|
398
|
+
ended = kept.endsWith('\n');
|
|
399
|
+
let text = edit.text;
|
|
400
|
+
if (edit.entry === true && !entered) {
|
|
401
|
+
entered = true;
|
|
402
|
+
if (!ended)
|
|
403
|
+
text = `${lineEnding(source)}${text}`;
|
|
404
|
+
}
|
|
405
|
+
pieces.push(text);
|
|
406
|
+
if (text !== '')
|
|
407
|
+
ended = text.endsWith('\n');
|
|
408
|
+
shifts.push([edit.start, text.length - (edit.end - edit.start)]);
|
|
409
|
+
cursor = edit.end;
|
|
410
|
+
}
|
|
411
|
+
pieces.push(source.slice(cursor));
|
|
412
|
+
return { content: pieces.join(''), shifts };
|
|
413
|
+
}
|
|
414
|
+
export function apply(document, changes) {
|
|
415
|
+
const internal = internalOf(document);
|
|
416
|
+
if (!('bodyStart' in internal))
|
|
417
|
+
return { outcome: 'refuse', refusal: internal };
|
|
418
|
+
const plan = planner(document, internal);
|
|
419
|
+
const edits = [];
|
|
420
|
+
const stale = new Set();
|
|
421
|
+
const named = new Set();
|
|
422
|
+
for (const [at, change] of changes.entries()) {
|
|
423
|
+
const planned = plan(change, at);
|
|
424
|
+
if (planned === 'stale') {
|
|
425
|
+
stale.add(at);
|
|
426
|
+
continue;
|
|
427
|
+
}
|
|
428
|
+
if (!Array.isArray(planned))
|
|
429
|
+
return { outcome: 'refuse', refusal: planned };
|
|
430
|
+
const part = partOf(change);
|
|
431
|
+
if (named.has(part)) {
|
|
432
|
+
stale.add(at);
|
|
433
|
+
continue;
|
|
434
|
+
}
|
|
435
|
+
named.add(part);
|
|
436
|
+
for (const edit of planned)
|
|
437
|
+
edits.push(edit);
|
|
438
|
+
}
|
|
439
|
+
edits.sort((left, right) => left.start - right.start || left.end - right.end || left.at - right.at);
|
|
440
|
+
overlapping(edits, stale);
|
|
441
|
+
if (stale.size > 0)
|
|
442
|
+
return { outcome: 'stale', document, stale: [...stale].sort((left, right) => left - right) };
|
|
443
|
+
const source = document.content;
|
|
444
|
+
const { content } = spliced(source, edits);
|
|
445
|
+
if (content === source)
|
|
446
|
+
return { outcome: 'applied', document };
|
|
447
|
+
const replaced = edits.filter((edit) => {
|
|
448
|
+
const kind = changes[edit.at].kind;
|
|
449
|
+
return kind === 'section' || kind === 'preamble';
|
|
450
|
+
});
|
|
451
|
+
if (replaced.length > 0) {
|
|
452
|
+
const checked = spliced(source, replaced);
|
|
453
|
+
const name = hidden(source, internal.bodyStart, checked.content, checked.shifts);
|
|
454
|
+
if (name !== undefined)
|
|
455
|
+
return { outcome: 'refuse', refusal: refuse('', 'overlapping-section', name) };
|
|
456
|
+
}
|
|
457
|
+
const parsed = parse(content);
|
|
458
|
+
if (!parsed.ok)
|
|
459
|
+
return { outcome: 'refuse', refusal: parsed.refusal };
|
|
460
|
+
return { outcome: 'applied', document: parsed.document };
|
|
340
461
|
}
|
|
341
462
|
export function serialize(document) {
|
|
342
463
|
return document.content;
|
|
343
464
|
}
|
|
344
|
-
export function fieldStart(document, pointer) {
|
|
345
|
-
const root = internals.get(document)?.root;
|
|
346
|
-
return root === null || root === undefined ? undefined : nodeAt(root, pointer)?.start;
|
|
347
|
-
}
|
|
348
465
|
export function frontmatter(document) {
|
|
349
|
-
return
|
|
466
|
+
return heldOf(document)?.internal.root ?? null;
|
|
350
467
|
}
|
package/dist/event.d.ts
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { type Definition } from './definition.js';
|
|
2
|
+
import type { Candidate } from './query/match.js';
|
|
3
|
+
import type { Document, VerifiedModel } from './types.js';
|
|
4
|
+
export type FactKind = 'string' | 'number' | 'boolean' | 'date' | 'time' | 'enum' | 'reference';
|
|
5
|
+
type Scalar = string | number | boolean;
|
|
6
|
+
export type Fact = {
|
|
7
|
+
readonly kind: FactKind;
|
|
8
|
+
readonly value: Scalar;
|
|
9
|
+
readonly member?: string;
|
|
10
|
+
} | {
|
|
11
|
+
readonly kind: 'prose';
|
|
12
|
+
} | {
|
|
13
|
+
readonly kind: 'null';
|
|
14
|
+
} | {
|
|
15
|
+
readonly kind: 'unreadable';
|
|
16
|
+
} | {
|
|
17
|
+
readonly kind: 'list';
|
|
18
|
+
readonly items: readonly Fact[];
|
|
19
|
+
} | {
|
|
20
|
+
readonly kind: 'object';
|
|
21
|
+
readonly fields: Readonly<Record<string, Fact>>;
|
|
22
|
+
};
|
|
23
|
+
export type DocumentFacts = {
|
|
24
|
+
readonly id: string;
|
|
25
|
+
readonly path: string;
|
|
26
|
+
readonly type: string | null;
|
|
27
|
+
readonly fields: Readonly<Record<string, Fact>>;
|
|
28
|
+
readonly sections: readonly string[];
|
|
29
|
+
};
|
|
30
|
+
export declare const TEXT_FIELD = "/text";
|
|
31
|
+
export declare const WRITE_DOORS: readonly ['browser', 'agent', 'client', 'function'];
|
|
32
|
+
export type WriteDoor = (typeof WRITE_DOORS)[number];
|
|
33
|
+
export type Actor = {
|
|
34
|
+
readonly user?: string;
|
|
35
|
+
readonly site?: string;
|
|
36
|
+
readonly app?: string;
|
|
37
|
+
readonly door?: WriteDoor;
|
|
38
|
+
};
|
|
39
|
+
export type DocumentEvent = {
|
|
40
|
+
readonly before: DocumentFacts | null;
|
|
41
|
+
readonly after: DocumentFacts | null;
|
|
42
|
+
readonly changed: readonly string[];
|
|
43
|
+
readonly by: Actor;
|
|
44
|
+
readonly moved_between_rooms: boolean;
|
|
45
|
+
};
|
|
46
|
+
export type ItemFacts = {
|
|
47
|
+
readonly delivery: string;
|
|
48
|
+
readonly source: string | null;
|
|
49
|
+
readonly address: string | null;
|
|
50
|
+
readonly container: string | null;
|
|
51
|
+
readonly author: string | null;
|
|
52
|
+
readonly headers: Readonly<Record<string, string>>;
|
|
53
|
+
readonly json: {
|
|
54
|
+
readonly value: unknown;
|
|
55
|
+
} | null;
|
|
56
|
+
};
|
|
57
|
+
export type MessageFacts = {
|
|
58
|
+
readonly sender: string;
|
|
59
|
+
readonly agent_function: string | null;
|
|
60
|
+
readonly path: string | null;
|
|
61
|
+
};
|
|
62
|
+
export type Resolved = {
|
|
63
|
+
readonly id: string;
|
|
64
|
+
readonly member?: string;
|
|
65
|
+
};
|
|
66
|
+
export declare function facts(document: Pick<Document, 'type' | 'fields' | 'sections'>, at: {
|
|
67
|
+
readonly id: string;
|
|
68
|
+
readonly path: string;
|
|
69
|
+
}, model: VerifiedModel, resolve: (target: string) => Resolved | undefined): DocumentFacts;
|
|
70
|
+
export declare function prosePaths(facts: DocumentFacts): string[];
|
|
71
|
+
export declare function members(document: DocumentFacts, path: string): readonly string[];
|
|
72
|
+
export declare function pointed(value: unknown, pointer: string): unknown;
|
|
73
|
+
export declare function valuedChange(definition: Definition, pointer: string): boolean;
|
|
74
|
+
export declare function datePointers(definition: Definition): string[];
|
|
75
|
+
export declare function memberPointers(definition: Definition, memberType: string): string[];
|
|
76
|
+
export declare function candidateOf(document: DocumentFacts): Candidate;
|
|
77
|
+
export {};
|
|
78
|
+
//# sourceMappingURL=event.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event.d.ts","sourceRoot":"","sources":["../src/event.ts"],"names":[],"mappings":"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"}
|