@agentshouse/mdruntime 0.1.0-alpha.9 → 0.1.0-c009335e08279

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.
Files changed (124) hide show
  1. package/AGENTS.md +208 -0
  2. package/README.md +44 -0
  3. package/dist/adapter.d.ts +147 -12
  4. package/dist/adapter.d.ts.map +1 -1
  5. package/dist/adapter.js +2 -3
  6. package/dist/attachment.d.ts +3 -0
  7. package/dist/attachment.d.ts.map +1 -0
  8. package/dist/attachment.js +8 -0
  9. package/dist/bootstrap.d.ts +3 -7
  10. package/dist/bootstrap.d.ts.map +1 -1
  11. package/dist/bootstrap.js +28 -27
  12. package/dist/change-set.d.ts +33 -0
  13. package/dist/change-set.d.ts.map +1 -0
  14. package/dist/change-set.js +83 -0
  15. package/dist/change.d.ts +9 -0
  16. package/dist/change.d.ts.map +1 -1
  17. package/dist/change.js +6 -5
  18. package/dist/client.d.ts +38 -32
  19. package/dist/client.d.ts.map +1 -1
  20. package/dist/client.js +115 -177
  21. package/dist/collection.d.ts +13 -16
  22. package/dist/collection.d.ts.map +1 -1
  23. package/dist/collection.js +45 -88
  24. package/dist/connection.d.ts +46 -39
  25. package/dist/connection.d.ts.map +1 -1
  26. package/dist/connection.js +1376 -975
  27. package/dist/conversation.d.ts +41 -19
  28. package/dist/conversation.d.ts.map +1 -1
  29. package/dist/conversation.js +483 -327
  30. package/dist/durability.js +6 -6
  31. package/dist/file.d.ts +2 -2
  32. package/dist/file.d.ts.map +1 -1
  33. package/dist/file.js +48 -71
  34. package/dist/host.d.ts +6 -2
  35. package/dist/host.d.ts.map +1 -1
  36. package/dist/host.js +83 -108
  37. package/dist/identity.d.ts +1 -0
  38. package/dist/identity.d.ts.map +1 -1
  39. package/dist/identity.js +10 -9
  40. package/dist/index.d.ts +12 -11
  41. package/dist/index.d.ts.map +1 -1
  42. package/dist/index.js +1 -3
  43. package/dist/log.js +5 -6
  44. package/dist/memory.d.ts +6 -3
  45. package/dist/memory.d.ts.map +1 -1
  46. package/dist/memory.js +205 -210
  47. package/dist/model.d.ts +10 -25
  48. package/dist/model.d.ts.map +1 -1
  49. package/dist/model.js +18 -21
  50. package/dist/observation.d.ts +25 -0
  51. package/dist/observation.d.ts.map +1 -0
  52. package/dist/observation.js +85 -0
  53. package/dist/outcome.d.ts +10 -29
  54. package/dist/outcome.d.ts.map +1 -1
  55. package/dist/outcome.js +1 -23
  56. package/dist/overlay.d.ts +9 -2
  57. package/dist/overlay.d.ts.map +1 -1
  58. package/dist/overlay.js +187 -43
  59. package/dist/paths.d.ts +0 -1
  60. package/dist/paths.d.ts.map +1 -1
  61. package/dist/paths.js +12 -19
  62. package/dist/query.d.ts +210 -10
  63. package/dist/query.d.ts.map +1 -1
  64. package/dist/query.js +420 -15
  65. package/dist/read-side.d.ts +14 -0
  66. package/dist/read-side.d.ts.map +1 -0
  67. package/dist/read-side.js +371 -0
  68. package/dist/refresh.d.ts +4 -5
  69. package/dist/refresh.d.ts.map +1 -1
  70. package/dist/refresh.js +45 -30
  71. package/dist/replica.d.ts +25 -5
  72. package/dist/replica.d.ts.map +1 -1
  73. package/dist/replica.js +228 -38
  74. package/dist/room-draft.d.ts +124 -0
  75. package/dist/room-draft.d.ts.map +1 -0
  76. package/dist/room-draft.js +327 -0
  77. package/dist/rows.d.ts +41 -0
  78. package/dist/rows.d.ts.map +1 -0
  79. package/dist/rows.js +100 -0
  80. package/dist/save.d.ts +8 -4
  81. package/dist/save.d.ts.map +1 -1
  82. package/dist/save.js +264 -350
  83. package/dist/search.d.ts +61 -0
  84. package/dist/search.d.ts.map +1 -0
  85. package/dist/search.js +125 -0
  86. package/dist/status.d.ts +4 -6
  87. package/dist/status.d.ts.map +1 -1
  88. package/dist/status.js +9 -13
  89. package/dist/store.d.ts +59 -31
  90. package/dist/store.d.ts.map +1 -1
  91. package/dist/store.js +338 -134
  92. package/dist/transfer.d.ts +5 -0
  93. package/dist/transfer.d.ts.map +1 -1
  94. package/dist/transfer.js +1 -5
  95. package/dist/wire.d.ts +4 -3
  96. package/dist/wire.d.ts.map +1 -1
  97. package/dist/wire.js +47 -68
  98. package/package.json +6 -12
  99. package/dist/adapter.js.map +0 -1
  100. package/dist/bootstrap.js.map +0 -1
  101. package/dist/change.js.map +0 -1
  102. package/dist/client.js.map +0 -1
  103. package/dist/collection.js.map +0 -1
  104. package/dist/connection.js.map +0 -1
  105. package/dist/conversation.js.map +0 -1
  106. package/dist/durability.js.map +0 -1
  107. package/dist/file.js.map +0 -1
  108. package/dist/host.js.map +0 -1
  109. package/dist/identity.js.map +0 -1
  110. package/dist/index.js.map +0 -1
  111. package/dist/log.js.map +0 -1
  112. package/dist/memory.js.map +0 -1
  113. package/dist/model.js.map +0 -1
  114. package/dist/outcome.js.map +0 -1
  115. package/dist/overlay.js.map +0 -1
  116. package/dist/paths.js.map +0 -1
  117. package/dist/query.js.map +0 -1
  118. package/dist/refresh.js.map +0 -1
  119. package/dist/replica.js.map +0 -1
  120. package/dist/save.js.map +0 -1
  121. package/dist/status.js.map +0 -1
  122. package/dist/store.js.map +0 -1
  123. package/dist/transfer.js.map +0 -1
  124. package/dist/wire.js.map +0 -1
@@ -0,0 +1,327 @@
1
+ import { apply, parse, serialize } from '@agentshouse/mdmodel';
2
+ import { normalize } from './paths.js';
3
+ function malformed() {
4
+ throw new Error('room-draft-malformed');
5
+ }
6
+ function plain(value) {
7
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
8
+ }
9
+ function frontmatterValue(value) {
10
+ if (Array.isArray(value))
11
+ return value.every(frontmatterValue);
12
+ return (value === null ||
13
+ typeof value === 'string' ||
14
+ typeof value === 'boolean' ||
15
+ (typeof value === 'number' && Number.isFinite(value)));
16
+ }
17
+ function text(value) {
18
+ return typeof value === 'string' ? value : malformed();
19
+ }
20
+ function optionalText(value) {
21
+ return value === undefined ? undefined : text(value);
22
+ }
23
+ function markdownBase(value) {
24
+ return value === null ? null : optionalText(value);
25
+ }
26
+ function entries(value, each) {
27
+ if (!plain(value))
28
+ malformed();
29
+ const read = {};
30
+ for (const [name, item] of Object.entries(value))
31
+ read[name] = each(item);
32
+ return read;
33
+ }
34
+ function fieldValue(value) {
35
+ if (value === null)
36
+ return null;
37
+ if (!plain(value) || !Object.hasOwn(value, 'value') || !frontmatterValue(value.value)) {
38
+ malformed();
39
+ }
40
+ return { value: value.value };
41
+ }
42
+ function textPart(value) {
43
+ if (!plain(value))
44
+ malformed();
45
+ const base = optionalText(value.base);
46
+ return { value: text(value.value), ...(base === undefined ? {} : { base }) };
47
+ }
48
+ function creationOf(value) {
49
+ if (!plain(value))
50
+ malformed();
51
+ if (Object.hasOwn(value, 'markdown'))
52
+ return { markdown: text(value.markdown) };
53
+ const fields = entries(value.fields, (item) => (frontmatterValue(item) ? item : malformed()));
54
+ return { type: text(value.type), fields, sections: entries(value.sections, text) };
55
+ }
56
+ const PART_NAMES = new Set([
57
+ 'fields',
58
+ 'sections',
59
+ 'preamble',
60
+ 'markdown',
61
+ 'creation',
62
+ 'move',
63
+ 'removal',
64
+ ]);
65
+ export function readParts(value) {
66
+ if (!plain(value) || Object.keys(value).some((name) => !PART_NAMES.has(name)))
67
+ malformed();
68
+ const parts = {};
69
+ if (value.fields !== undefined) {
70
+ parts.fields = entries(value.fields, (item) => {
71
+ if (!plain(item) || !Object.hasOwn(item, 'value') || !frontmatterValue(item.value)) {
72
+ malformed();
73
+ }
74
+ return item.base === undefined
75
+ ? { value: item.value }
76
+ : { value: item.value, base: fieldValue(item.base) };
77
+ });
78
+ }
79
+ if (value.sections !== undefined)
80
+ parts.sections = entries(value.sections, textPart);
81
+ if (value.preamble !== undefined)
82
+ parts.preamble = textPart(value.preamble);
83
+ if (value.markdown !== undefined)
84
+ parts.markdown = textPart(value.markdown);
85
+ if (value.creation !== undefined)
86
+ parts.creation = creationOf(value.creation);
87
+ if (value.move !== undefined) {
88
+ if (!plain(value.move))
89
+ malformed();
90
+ const base = markdownBase(value.move.base);
91
+ parts.move = { to: text(value.move.to), ...(base === undefined ? {} : { base }) };
92
+ }
93
+ if (value.removal !== undefined) {
94
+ if (!plain(value.removal))
95
+ malformed();
96
+ const base = markdownBase(value.removal.base);
97
+ parts.removal = base === undefined ? {} : { base };
98
+ }
99
+ return parts;
100
+ }
101
+ function named(record) {
102
+ return Object.entries(record ?? {});
103
+ }
104
+ function own(record, name) {
105
+ return record !== undefined && Object.hasOwn(record, name) ? record[name] : undefined;
106
+ }
107
+ function kept(prior, base) {
108
+ if (prior !== undefined)
109
+ return prior.base;
110
+ if (base === undefined)
111
+ throw new Error('room-draft-base-missing');
112
+ return base;
113
+ }
114
+ function editsText(parts) {
115
+ return (parts.preamble !== undefined ||
116
+ named(parts.fields).length > 0 ||
117
+ named(parts.sections).length > 0);
118
+ }
119
+ export function held(current, parts) {
120
+ if (parts.markdown !== undefined && editsText(parts)) {
121
+ throw new Error('room-draft-markdown-exclusive');
122
+ }
123
+ const next = {};
124
+ const fields = named(parts.fields);
125
+ if (fields.length > 0) {
126
+ next.fields = Object.fromEntries(fields.map(([name, part]) => [
127
+ name,
128
+ { value: part.value, base: kept(own(current?.fields, name), part.base) },
129
+ ]));
130
+ }
131
+ const sections = named(parts.sections);
132
+ if (sections.length > 0) {
133
+ next.sections = Object.fromEntries(sections.map(([name, part]) => [
134
+ name,
135
+ { value: part.value, base: kept(own(current?.sections, name), part.base) },
136
+ ]));
137
+ }
138
+ if (parts.preamble !== undefined) {
139
+ next.preamble = {
140
+ value: parts.preamble.value,
141
+ base: kept(current?.preamble, parts.preamble.base),
142
+ };
143
+ }
144
+ if (parts.markdown !== undefined) {
145
+ next.markdown = {
146
+ value: parts.markdown.value,
147
+ base: kept(current?.markdown, parts.markdown.base),
148
+ };
149
+ }
150
+ if (parts.creation !== undefined)
151
+ next.creation = parts.creation;
152
+ if (parts.move !== undefined) {
153
+ next.move = { to: parts.move.to, base: kept(current?.move, parts.move.base) };
154
+ }
155
+ if (parts.removal !== undefined) {
156
+ next.removal = { base: kept(current?.removal, parts.removal.base) };
157
+ }
158
+ if (Object.keys(next).length === 0)
159
+ throw new Error('room-draft-empty');
160
+ return next;
161
+ }
162
+ export function equalValue(left, right) {
163
+ if (left === right)
164
+ return true;
165
+ return (Array.isArray(left) &&
166
+ Array.isArray(right) &&
167
+ left.length === right.length &&
168
+ left.every((item, index) => equalValue(item, right[index])));
169
+ }
170
+ function sameField(left, right) {
171
+ if (left === null || right === null)
172
+ return left === right;
173
+ return equalValue(left.value, right.value);
174
+ }
175
+ export function underneath(parts, path, visible) {
176
+ const markdown = visible?.documents[path] ?? null;
177
+ const document = visible?.collection.documents[path];
178
+ const report = {};
179
+ const fields = {};
180
+ for (const [name, part] of named(parts.fields)) {
181
+ const current = document !== undefined && Object.hasOwn(document.fields, name)
182
+ ? { value: document.fields[name] }
183
+ : null;
184
+ if (!sameField(part.base, current))
185
+ fields[name] = current;
186
+ }
187
+ if (Object.keys(fields).length > 0)
188
+ report.fields = fields;
189
+ const sections = {};
190
+ for (const [name, part] of named(parts.sections)) {
191
+ const current = document !== undefined && Object.hasOwn(document.sections, name)
192
+ ? document.sections[name]
193
+ : null;
194
+ if (current !== part.base)
195
+ sections[name] = current;
196
+ }
197
+ if (Object.keys(sections).length > 0)
198
+ report.sections = sections;
199
+ const preamble = document?.preamble ?? null;
200
+ if (parts.preamble !== undefined && preamble !== parts.preamble.base)
201
+ report.preamble = preamble;
202
+ if (parts.markdown !== undefined && markdown !== parts.markdown.base)
203
+ report.markdown = markdown;
204
+ if (parts.creation !== undefined && markdown !== null)
205
+ report.creation = markdown;
206
+ if (parts.move !== undefined && markdown !== parts.move.base)
207
+ report.move = markdown;
208
+ if (parts.removal !== undefined && markdown !== parts.removal.base)
209
+ report.removal = markdown;
210
+ return report;
211
+ }
212
+ export function changedParts(path, report) {
213
+ return [
214
+ ...(report.creation === undefined ? [] : [{ path, part: 'creation' }]),
215
+ ...named(report.fields).map(([name]) => ({ path, part: 'field', name })),
216
+ ...named(report.sections).map(([name]) => ({ path, part: 'section', name })),
217
+ ...(report.preamble === undefined ? [] : [{ path, part: 'preamble' }]),
218
+ ...(report.markdown === undefined ? [] : [{ path, part: 'markdown' }]),
219
+ ...(report.move === undefined ? [] : [{ path, part: 'move' }]),
220
+ ...(report.removal === undefined ? [] : [{ path, part: 'removal' }]),
221
+ ];
222
+ }
223
+ function joined(existing, returned) {
224
+ const merged = { ...existing };
225
+ for (const [name, part] of named(returned))
226
+ if (!Object.hasOwn(merged, name))
227
+ merged[name] = part;
228
+ return Object.keys(merged).length === 0 ? undefined : merged;
229
+ }
230
+ function ended(text) {
231
+ return text === '' || text.endsWith('\n') ? text : `${text}\n`;
232
+ }
233
+ function frontmatterOf(fields) {
234
+ const opened = parse('---\n---\n');
235
+ if (!opened.ok)
236
+ return malformed();
237
+ let document = opened.document;
238
+ for (const [name, part] of fields) {
239
+ const next = apply(document, { kind: 'field', name, value: part.value, prior: undefined });
240
+ if (next.outcome !== 'applied')
241
+ return malformed();
242
+ document = next.document;
243
+ }
244
+ return serialize(document);
245
+ }
246
+ function concatenated(markdown, parts) {
247
+ const fields = named(parts.fields);
248
+ const pieces = [
249
+ ...(fields.length === 0 ? [] : [frontmatterOf(fields)]),
250
+ ...(parts.preamble === undefined ? [] : [parts.preamble.value]),
251
+ ...named(parts.sections).map(([name, part]) => `## ${name}\n${part.value}`),
252
+ ];
253
+ if (pieces.length === 0)
254
+ return markdown;
255
+ return `${ended(markdown)}\n${pieces.map(ended).join('')}`;
256
+ }
257
+ export function returnedInto(existing, returned) {
258
+ if (existing === undefined)
259
+ return returned;
260
+ const next = { ...existing };
261
+ const whole = existing.markdown ?? returned.markdown;
262
+ if (whole === undefined) {
263
+ const fields = joined(existing.fields, returned.fields);
264
+ const sections = joined(existing.sections, returned.sections);
265
+ if (fields !== undefined)
266
+ next.fields = fields;
267
+ if (sections !== undefined)
268
+ next.sections = sections;
269
+ const preamble = existing.preamble ?? returned.preamble;
270
+ if (preamble !== undefined)
271
+ next.preamble = preamble;
272
+ }
273
+ else {
274
+ delete next.fields;
275
+ delete next.sections;
276
+ delete next.preamble;
277
+ const value = concatenated(whole.value, existing.markdown === undefined ? existing : returned);
278
+ next.markdown = { value, base: whole.base };
279
+ }
280
+ const creation = existing.creation ?? returned.creation;
281
+ const move = existing.move ?? returned.move;
282
+ const removal = existing.removal ?? returned.removal;
283
+ if (creation !== undefined)
284
+ next.creation = creation;
285
+ if (move !== undefined)
286
+ next.move = move;
287
+ if (removal !== undefined)
288
+ next.removal = removal;
289
+ return next;
290
+ }
291
+ export function changesOf(path, parts) {
292
+ const changes = [];
293
+ const bases = [];
294
+ const creation = parts.creation;
295
+ if (creation !== undefined) {
296
+ changes.push('markdown' in creation
297
+ ? { kind: 'create', path, content: creation.markdown }
298
+ : {
299
+ kind: 'create',
300
+ path,
301
+ fields: { type: creation.type, ...creation.fields },
302
+ sections: creation.sections,
303
+ });
304
+ }
305
+ for (const [name, part] of named(parts.fields)) {
306
+ changes.push({ kind: 'field', path, name, value: part.value });
307
+ bases.push({ kind: 'field', path, name, value: part.base?.value });
308
+ }
309
+ for (const [name, part] of named(parts.sections)) {
310
+ changes.push({ kind: 'section', path, name, value: part.value });
311
+ bases.push({ kind: 'section', path, name, value: part.base });
312
+ }
313
+ if (parts.preamble !== undefined) {
314
+ changes.push({ kind: 'preamble', path, value: parts.preamble.value });
315
+ bases.push({ kind: 'preamble', path, value: parts.preamble.base });
316
+ }
317
+ if (parts.markdown !== undefined) {
318
+ changes.push({ kind: 'replace', path, content: parts.markdown.value });
319
+ }
320
+ if (parts.move !== undefined) {
321
+ const to = normalize(parts.move.to);
322
+ changes.push({ kind: 'move', path, to: to === null || to === '' ? parts.move.to : to });
323
+ }
324
+ if (parts.removal !== undefined)
325
+ changes.push({ kind: 'remove', path });
326
+ return { changes, bases };
327
+ }
package/dist/rows.d.ts ADDED
@@ -0,0 +1,41 @@
1
+ import { type Document } from '@agentshouse/mdmodel';
2
+ import type { HeadChange } from './adapter.js';
3
+ import { type Composition } from './collection.js';
4
+ type Fields = Readonly<Record<string, unknown>>;
5
+ export type DocumentRow = {
6
+ key: string;
7
+ kind: 'document';
8
+ room: string;
9
+ path: string;
10
+ type: string | null;
11
+ fields: Fields;
12
+ values: Fields;
13
+ sizes: Readonly<Record<string, number>>;
14
+ directories: readonly string[];
15
+ body: string;
16
+ change: HeadChange | null;
17
+ };
18
+ export type BodyRow = {
19
+ key: string;
20
+ kind: 'body';
21
+ room: string;
22
+ path: string;
23
+ preamble: string;
24
+ sections: Readonly<Record<string, string>>;
25
+ markdown: string;
26
+ };
27
+ export type ReferenceRow = {
28
+ key: string;
29
+ kind: 'reference';
30
+ room: string;
31
+ source: string;
32
+ target: string;
33
+ field: string;
34
+ path: string;
35
+ type: string;
36
+ };
37
+ export type Row = DocumentRow | BodyRow | ReferenceRow;
38
+ export declare function documentKey(room: string, path: string): string;
39
+ export declare function rowsOf(room: string, path: string, document: Document | null, composition: Composition, change: HeadChange | null): readonly Row[];
40
+ export {};
41
+ //# sourceMappingURL=rows.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rows.d.ts","sourceRoot":"","sources":["../src/rows.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,KAAK,QAAQ,EAAkB,MAAM,sBAAsB,CAAC;AAC7E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAa,KAAK,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAG9D,KAAK,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAEhD,MAAM,MAAM,WAAW,GAAG;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,UAAU,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACxC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,UAAU,GAAG,IAAI,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,OAAO,GAAG;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC3C,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,WAAW,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,GAAG,GAAG,WAAW,GAAG,OAAO,GAAG,YAAY,CAAC;AAMvD,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAE9D;AAqBD,wBAAgB,MAAM,CACpB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,QAAQ,GAAG,IAAI,EACzB,WAAW,EAAE,WAAW,EACxB,MAAM,EAAE,UAAU,GAAG,IAAI,GACxB,SAAS,GAAG,EAAE,CAsEhB"}
package/dist/rows.js ADDED
@@ -0,0 +1,100 @@
1
+ import { target } from '@agentshouse/mdmodel';
2
+ import { governing } from './collection.js';
3
+ import { definitionOf } from './model.js';
4
+ function keyOf(...parts) {
5
+ return `${parts.join('\u0000')}\u0000`;
6
+ }
7
+ export function documentKey(room, path) {
8
+ return keyOf('d', room, path);
9
+ }
10
+ function referenceField(spec) {
11
+ return spec?.kind === 'reference' || (spec?.kind === 'list' && spec.of.kind === 'reference');
12
+ }
13
+ function targetOf(path, value) {
14
+ return typeof value === 'string' ? target(path, value) : null;
15
+ }
16
+ function resolved(path, value) {
17
+ if (value === null)
18
+ return null;
19
+ if (!Array.isArray(value))
20
+ return targetOf(path, value) ?? undefined;
21
+ return value.map((item) => targetOf(path, item)).filter((item) => item !== null);
22
+ }
23
+ function directoriesOf(path) {
24
+ const parts = path.split('/').slice(0, -1);
25
+ return ['', ...parts.map((_, index) => parts.slice(0, index + 1).join('/'))];
26
+ }
27
+ export function rowsOf(room, path, document, composition, change) {
28
+ const key = documentKey(room, path);
29
+ const body = keyOf('b', room, path);
30
+ if (document === null || !path.endsWith('.md')) {
31
+ return [
32
+ {
33
+ key,
34
+ kind: 'document',
35
+ room,
36
+ path,
37
+ type: null,
38
+ fields: {},
39
+ values: {},
40
+ sizes: {},
41
+ directories: directoriesOf(path),
42
+ body,
43
+ change,
44
+ },
45
+ ];
46
+ }
47
+ const type = document.type ?? 'any';
48
+ const definition = definitionOf(governing(composition, path), document.type);
49
+ const values = {};
50
+ const sizes = {};
51
+ const references = [];
52
+ for (const [name, value] of Object.entries(document.fields)) {
53
+ const reference = referenceField(definition?.fields[name]);
54
+ const compared = reference ? resolved(path, value) : value;
55
+ if (compared !== undefined)
56
+ values[name] = compared;
57
+ if (Array.isArray(value))
58
+ sizes[name] = value.length;
59
+ if (!reference)
60
+ continue;
61
+ const targets = [compared].flat().filter((found) => typeof found === 'string');
62
+ for (const found of new Set(targets)) {
63
+ references.push({
64
+ key: keyOf('r', room, path, name, found),
65
+ kind: 'reference',
66
+ room,
67
+ source: key,
68
+ target: documentKey(room, found),
69
+ field: name,
70
+ path,
71
+ type,
72
+ });
73
+ }
74
+ }
75
+ return [
76
+ {
77
+ key,
78
+ kind: 'document',
79
+ room,
80
+ path,
81
+ type,
82
+ fields: document.fields,
83
+ values,
84
+ sizes,
85
+ directories: directoriesOf(path),
86
+ body,
87
+ change,
88
+ },
89
+ {
90
+ key: body,
91
+ kind: 'body',
92
+ room,
93
+ path,
94
+ preamble: document.preamble,
95
+ sections: document.sections,
96
+ markdown: document.content,
97
+ },
98
+ ...references,
99
+ ];
100
+ }
package/dist/save.d.ts CHANGED
@@ -1,24 +1,27 @@
1
- import type { AttachedModelBinding } from './model.js';
2
1
  import type { ProviderLimit } from './adapter.js';
3
- import { type Change, type ChangeBatch } from './change.js';
2
+ import { type Change, type ChangeBatch, type Precondition, type WrittenBy } from './change.js';
4
3
  import { type Composition } from './collection.js';
5
4
  import type { VisibleLayer } from './replica.js';
5
+ import type { ChangedPart } from './room-draft.js';
6
6
  export type SaveRefusal = {
7
- source?: 'model';
8
7
  rule: string;
9
8
  file?: string;
10
9
  location?: string;
11
10
  referrers?: readonly string[];
11
+ parts?: readonly ChangedPart[];
12
12
  };
13
+ export type Rewriting = 'runtime' | 'provider';
13
14
  export type SaveInput = {
14
15
  composition: Composition;
16
+ rewriting: Rewriting;
15
17
  baseRoomVersion: string;
16
18
  operations: import('./adapter.js').OperationScopes;
17
- binding: AttachedModelBinding | null;
18
19
  providerOwnedPaths: readonly string[];
19
20
  providerLimits: readonly ProviderLimit[];
20
21
  visible: VisibleLayer;
21
22
  changes: readonly Change[];
23
+ bases: readonly Precondition[];
24
+ writtenBy?: WrittenBy;
22
25
  };
23
26
  export type BatchResult = {
24
27
  kind: 'batch';
@@ -27,5 +30,6 @@ export type BatchResult = {
27
30
  kind: 'refused';
28
31
  refusal: SaveRefusal;
29
32
  };
33
+ export declare function providerRewritten(batch: ChangeBatch, visible: VisibleLayer): ChangeBatch;
30
34
  export declare function buildBatch(input: SaveInput): BatchResult;
31
35
  //# sourceMappingURL=save.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"save.d.ts","sourceRoot":"","sources":["../src/save.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAc,MAAM,YAAY,CAAC;AAEnE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,EAAa,KAAK,MAAM,EAAE,KAAK,WAAW,EAAqB,MAAM,aAAa,CAAC;AAC1F,OAAO,EAML,KAAK,WAAW,EAEjB,MAAM,iBAAiB,CAAC;AAIzB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEjD,MAAM,MAAM,WAAW,GAAG;IACxB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC/B,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG;IACtB,WAAW,EAAE,WAAW,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,OAAO,cAAc,EAAE,eAAe,CAAC;IACnD,OAAO,EAAE,oBAAoB,GAAG,IAAI,CAAC;IACrC,kBAAkB,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,cAAc,EAAE,SAAS,aAAa,EAAE,CAAC;IACzC,OAAO,EAAE,YAAY,CAAC;IACtB,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,WAAW,GACnB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,WAAW,CAAA;CAAE,GACrC;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,WAAW,CAAA;CAAE,CAAC;AA2Y9C,wBAAgB,UAAU,CAAC,KAAK,EAAE,SAAS,GAAG,WAAW,CAmGxD"}
1
+ {"version":3,"file":"save.d.ts","sourceRoot":"","sources":["../src/save.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,EAEL,KAAK,MAAM,EACX,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,SAAS,EACf,MAAM,aAAa,CAAC;AACrB,OAAO,EAKL,KAAK,WAAW,EACjB,MAAM,iBAAiB,CAAC;AAIzB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAEnD,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9B,KAAK,CAAC,EAAE,SAAS,WAAW,EAAE,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG,SAAS,GAAG,UAAU,CAAC;AAE/C,MAAM,MAAM,SAAS,GAAG;IACtB,WAAW,EAAE,WAAW,CAAC;IACzB,SAAS,EAAE,SAAS,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,OAAO,cAAc,EAAE,eAAe,CAAC;IACnD,kBAAkB,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,cAAc,EAAE,SAAS,aAAa,EAAE,CAAC;IACzC,OAAO,EAAE,YAAY,CAAC;IACtB,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,KAAK,EAAE,SAAS,YAAY,EAAE,CAAC;IAC/B,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,WAAW,GACnB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,WAAW,CAAA;CAAE,GACrC;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,WAAW,CAAA;CAAE,CAAC;AAwK9C,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,YAAY,GAAG,WAAW,CAOxF;AA2MD,wBAAgB,UAAU,CAAC,KAAK,EAAE,SAAS,GAAG,WAAW,CA8FxD"}