@agentshouse/mdruntime 0.1.0-c967d1ca66fee → 0.1.0-c96e80d38e5f0

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 (175) hide show
  1. package/README.md +22 -9
  2. package/dist/adapter.d.ts +172 -49
  3. package/dist/adapter.d.ts.map +1 -1
  4. package/dist/attached-model.d.ts +5 -1
  5. package/dist/attached-model.d.ts.map +1 -1
  6. package/dist/attached-model.js +38 -4
  7. package/dist/attempt.d.ts +16 -0
  8. package/dist/attempt.d.ts.map +1 -0
  9. package/dist/attempt.js +70 -0
  10. package/dist/binary.d.ts +18 -0
  11. package/dist/binary.d.ts.map +1 -0
  12. package/dist/binary.js +8 -0
  13. package/dist/bootstrap.d.ts +27 -11
  14. package/dist/bootstrap.d.ts.map +1 -1
  15. package/dist/bootstrap.js +184 -84
  16. package/dist/chain.d.ts +11 -0
  17. package/dist/chain.d.ts.map +1 -0
  18. package/dist/chain.js +64 -0
  19. package/dist/change-set.d.ts +9 -14
  20. package/dist/change-set.d.ts.map +1 -1
  21. package/dist/change-set.js +11 -62
  22. package/dist/change.d.ts +41 -0
  23. package/dist/change.d.ts.map +1 -1
  24. package/dist/change.js +34 -0
  25. package/dist/client.d.ts +34 -15
  26. package/dist/client.d.ts.map +1 -1
  27. package/dist/client.js +104 -8
  28. package/dist/collection.d.ts +10 -7
  29. package/dist/collection.d.ts.map +1 -1
  30. package/dist/collection.js +38 -79
  31. package/dist/compile.d.ts +16 -0
  32. package/dist/compile.d.ts.map +1 -0
  33. package/dist/compile.js +789 -0
  34. package/dist/connection.d.ts +51 -17
  35. package/dist/connection.d.ts.map +1 -1
  36. package/dist/connection.js +3951 -907
  37. package/dist/conversation.d.ts +48 -19
  38. package/dist/conversation.d.ts.map +1 -1
  39. package/dist/conversation.js +726 -240
  40. package/dist/digest.d.ts +7 -0
  41. package/dist/digest.d.ts.map +1 -0
  42. package/dist/digest.js +113 -0
  43. package/dist/durability.d.ts +4 -1
  44. package/dist/durability.d.ts.map +1 -1
  45. package/dist/durability.js +5 -0
  46. package/dist/entry.d.ts +20 -0
  47. package/dist/entry.d.ts.map +1 -0
  48. package/dist/entry.js +152 -0
  49. package/dist/expectation.d.ts +21 -0
  50. package/dist/expectation.d.ts.map +1 -0
  51. package/dist/expectation.js +70 -0
  52. package/dist/fence.d.ts +6 -0
  53. package/dist/fence.d.ts.map +1 -0
  54. package/dist/fence.js +10 -0
  55. package/dist/file.d.ts +2 -19
  56. package/dist/file.d.ts.map +1 -1
  57. package/dist/file.js +7 -122
  58. package/dist/host.d.ts +12 -3
  59. package/dist/host.d.ts.map +1 -1
  60. package/dist/host.js +125 -18
  61. package/dist/identity.d.ts +3 -0
  62. package/dist/identity.d.ts.map +1 -1
  63. package/dist/identity.js +9 -0
  64. package/dist/index.d.ts +19 -9
  65. package/dist/index.d.ts.map +1 -1
  66. package/dist/index.js +9 -0
  67. package/dist/live.d.ts +22 -0
  68. package/dist/live.d.ts.map +1 -0
  69. package/dist/live.js +123 -0
  70. package/dist/media.d.ts +8 -0
  71. package/dist/media.d.ts.map +1 -0
  72. package/dist/media.js +218 -0
  73. package/dist/memory.d.ts +18 -7
  74. package/dist/memory.d.ts.map +1 -1
  75. package/dist/memory.js +231 -91
  76. package/dist/messages.d.ts +28 -0
  77. package/dist/messages.d.ts.map +1 -0
  78. package/dist/messages.js +89 -0
  79. package/dist/model.d.ts +9 -2
  80. package/dist/model.d.ts.map +1 -1
  81. package/dist/model.js +8 -2
  82. package/dist/name.d.ts +4 -0
  83. package/dist/name.d.ts.map +1 -0
  84. package/dist/name.js +122 -0
  85. package/dist/observation.d.ts +20 -2
  86. package/dist/observation.d.ts.map +1 -1
  87. package/dist/observation.js +113 -12
  88. package/dist/opened.d.ts +22 -0
  89. package/dist/opened.d.ts.map +1 -0
  90. package/dist/opened.js +107 -0
  91. package/dist/outcome.d.ts +52 -4
  92. package/dist/outcome.d.ts.map +1 -1
  93. package/dist/outcome.js +46 -0
  94. package/dist/overlay.d.ts +15 -5
  95. package/dist/overlay.d.ts.map +1 -1
  96. package/dist/overlay.js +129 -177
  97. package/dist/paths.d.ts +1 -0
  98. package/dist/paths.d.ts.map +1 -1
  99. package/dist/paths.js +4 -0
  100. package/dist/phrase.d.ts +3 -0
  101. package/dist/phrase.d.ts.map +1 -0
  102. package/dist/phrase.js +8 -0
  103. package/dist/query.d.ts +72 -4
  104. package/dist/query.d.ts.map +1 -1
  105. package/dist/query.js +67 -7
  106. package/dist/reach.d.ts +16 -2
  107. package/dist/reach.d.ts.map +1 -1
  108. package/dist/reach.js +222 -56
  109. package/dist/react.d.ts +11 -7
  110. package/dist/react.d.ts.map +1 -1
  111. package/dist/react.js +7 -17
  112. package/dist/readiness.d.ts +50 -0
  113. package/dist/readiness.d.ts.map +1 -0
  114. package/dist/readiness.js +27 -0
  115. package/dist/recovery.d.ts +26 -0
  116. package/dist/recovery.d.ts.map +1 -0
  117. package/dist/recovery.js +224 -0
  118. package/dist/refresh.d.ts +17 -14
  119. package/dist/refresh.d.ts.map +1 -1
  120. package/dist/refresh.js +155 -56
  121. package/dist/replica.d.ts +58 -33
  122. package/dist/replica.d.ts.map +1 -1
  123. package/dist/replica.js +310 -159
  124. package/dist/room-draft.d.ts +52 -5
  125. package/dist/room-draft.d.ts.map +1 -1
  126. package/dist/room-draft.js +261 -56
  127. package/dist/rows.d.ts +38 -35
  128. package/dist/rows.d.ts.map +1 -1
  129. package/dist/rows.js +178 -102
  130. package/dist/save.d.ts +70 -3
  131. package/dist/save.d.ts.map +1 -1
  132. package/dist/save.js +805 -147
  133. package/dist/search.d.ts +15 -55
  134. package/dist/search.d.ts.map +1 -1
  135. package/dist/search.js +10 -121
  136. package/dist/seed.d.ts +16 -0
  137. package/dist/seed.d.ts.map +1 -0
  138. package/dist/seed.js +75 -0
  139. package/dist/shared.d.ts +15 -0
  140. package/dist/shared.d.ts.map +1 -0
  141. package/dist/shared.js +421 -0
  142. package/dist/status.d.ts +5 -0
  143. package/dist/status.d.ts.map +1 -1
  144. package/dist/status.js +3 -1
  145. package/dist/store.d.ts +116 -80
  146. package/dist/store.d.ts.map +1 -1
  147. package/dist/store.js +355 -461
  148. package/dist/stored.d.ts +162 -0
  149. package/dist/stored.d.ts.map +1 -0
  150. package/dist/stored.js +549 -0
  151. package/dist/tables.d.ts +353 -0
  152. package/dist/tables.d.ts.map +1 -0
  153. package/dist/tables.js +585 -0
  154. package/dist/transfer.d.ts +0 -5
  155. package/dist/transfer.d.ts.map +1 -1
  156. package/dist/turn.d.ts +9 -0
  157. package/dist/turn.d.ts.map +1 -0
  158. package/dist/turn.js +75 -0
  159. package/dist/validation.d.ts +29 -0
  160. package/dist/validation.d.ts.map +1 -0
  161. package/dist/validation.js +101 -0
  162. package/dist/windows.d.ts +22 -0
  163. package/dist/windows.d.ts.map +1 -0
  164. package/dist/windows.js +89 -0
  165. package/dist/wire.d.ts +166 -30
  166. package/dist/wire.d.ts.map +1 -1
  167. package/dist/wire.js +57 -29
  168. package/package.json +26 -15
  169. package/AGENTS.md +0 -269
  170. package/dist/attachment.d.ts +0 -3
  171. package/dist/attachment.d.ts.map +0 -1
  172. package/dist/attachment.js +0 -8
  173. package/dist/read-side.d.ts +0 -18
  174. package/dist/read-side.d.ts.map +0 -1
  175. package/dist/read-side.js +0 -433
package/dist/overlay.d.ts CHANGED
@@ -1,15 +1,25 @@
1
- import type { HeadChange } from './adapter.js';
1
+ import type { BinaryFile, HeadChange } from './adapter.js';
2
2
  import type { ChangeBatch } from './change.js';
3
3
  export type Heads = {
4
4
  revisions: Readonly<Record<string, string>>;
5
+ fileIds: Readonly<Record<string, string>>;
5
6
  changes: Readonly<Record<string, HeadChange>>;
6
7
  };
8
+ export type HeldBinary = ({
9
+ readonly state: 'accepted';
10
+ } & BinaryFile) | {
11
+ readonly state: 'pending';
12
+ readonly localId: string;
13
+ readonly byteLength: number;
14
+ readonly mediaType: string;
15
+ readonly sha256: string;
16
+ };
7
17
  export type Layer = Heads & {
8
18
  documents: Readonly<Record<string, string>>;
9
- binaryTargets: readonly string[];
19
+ binaries: Readonly<Record<string, HeldBinary>>;
10
20
  };
21
+ export declare function acceptedBinaries(files: Readonly<Record<string, BinaryFile>>): Generator<readonly [string, HeldBinary]>;
22
+ export declare function sameBinary(left: HeldBinary | undefined, right: HeldBinary | undefined): boolean;
11
23
  export declare function sameChange(left: HeadChange | undefined, right: HeadChange | undefined): boolean;
12
- export declare function overlay(base: Layer, queue: readonly ChangeBatch[], unapplied?: () => void): Layer;
13
- export declare function sameLayerText(left: Layer, right: Layer): boolean;
14
- export declare function overlayChanged(base: Layer, queue: readonly ChangeBatch[], previousBase: Layer, previousQueue: readonly ChangeBatch[], previousVisible: Layer): Layer;
24
+ export declare function overlaying(base: Layer, queue: readonly ChangeBatch[], unapplied?: () => void): Generator<number, Layer, void>;
15
25
  //# sourceMappingURL=overlay.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"overlay.d.ts","sourceRoot":"","sources":["../src/overlay.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,KAAK,EAAU,WAAW,EAAgB,MAAM,aAAa,CAAC;AAErE,MAAM,MAAM,KAAK,GAAG;IAClB,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC5C,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC;CAC/C,CAAC;AAEF,MAAM,MAAM,KAAK,GAAG,KAAK,GAAG;IAC1B,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC5C,aAAa,EAAE,SAAS,MAAM,EAAE,CAAC;CAClC,CAAC;AAEF,wBAAgB,UAAU,CAAC,IAAI,EAAE,UAAU,GAAG,SAAS,EAAE,KAAK,EAAE,UAAU,GAAG,SAAS,GAAG,OAAO,CAQ/F;AAsJD,wBAAgB,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,WAAW,EAAE,EAAE,SAAS,CAAC,EAAE,MAAM,IAAI,GAAG,KAAK,CAmBjG;AAQD,wBAAgB,aAAa,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAQhE;AAmBD,wBAAgB,cAAc,CAC5B,IAAI,EAAE,KAAK,EACX,KAAK,EAAE,SAAS,WAAW,EAAE,EAC7B,YAAY,EAAE,KAAK,EACnB,aAAa,EAAE,SAAS,WAAW,EAAE,EACrC,eAAe,EAAE,KAAK,GACrB,KAAK,CA4FP"}
1
+ {"version":3,"file":"overlay.d.ts","sourceRoot":"","sources":["../src/overlay.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC3D,OAAO,KAAK,EAAU,WAAW,EAAgB,MAAM,aAAa,CAAC;AAIrE,MAAM,MAAM,KAAK,GAAG;IAClB,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC5C,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC1C,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC;CAC/C,CAAC;AAEF,MAAM,MAAM,UAAU,GAClB,CAAC;IAAE,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAA;CAAE,GAAG,UAAU,CAAC,GAC7C;IACE,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB,CAAC;AAEN,MAAM,MAAM,KAAK,GAAG,KAAK,GAAG;IAC1B,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC5C,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC;CAChD,CAAC;AAEF,wBAAiB,gBAAgB,CAC/B,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,GAC1C,SAAS,CAAC,SAAS,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAE1C;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,UAAU,GAAG,SAAS,EAAE,KAAK,EAAE,UAAU,GAAG,SAAS,GAAG,OAAO,CAW/F;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,UAAU,GAAG,SAAS,EAAE,KAAK,EAAE,UAAU,GAAG,SAAS,GAAG,OAAO,CAQ/F;AAqMD,wBAAiB,UAAU,CACzB,IAAI,EAAE,KAAK,EACX,KAAK,EAAE,SAAS,WAAW,EAAE,EAC7B,SAAS,CAAC,EAAE,MAAM,IAAI,GACrB,SAAS,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,CAoChC"}
package/dist/overlay.js CHANGED
@@ -1,4 +1,21 @@
1
- import { apply, parse, serialize } from '@agentshouse/mdmodel';
1
+ import { apply, frontmatterValue, parse, serialize, } from '@agentshouse/mdmodel';
2
+ import { drafted, entriesIn, settling } from './shared.js';
3
+ import { ROW_WEIGHT } from './turn.js';
4
+ export function* acceptedBinaries(files) {
5
+ for (const [path, file] of entriesIn(files))
6
+ yield [path, { state: 'accepted', ...file }];
7
+ }
8
+ export function sameBinary(left, right) {
9
+ if (left === undefined || right === undefined)
10
+ return left === right;
11
+ return (left.state === right.state &&
12
+ left.byteLength === right.byteLength &&
13
+ left.mediaType === right.mediaType &&
14
+ left.sha256 === right.sha256 &&
15
+ (left.state === 'accepted'
16
+ ? right.state === 'accepted'
17
+ : right.state === 'pending' && left.localId === right.localId));
18
+ }
2
19
  export function sameChange(left, right) {
3
20
  if (left === undefined || right === undefined)
4
21
  return left === right;
@@ -8,10 +25,13 @@ export function sameChange(left, right) {
8
25
  left.author?.name === right.author?.name);
9
26
  }
10
27
  const EMPTY_FRONTMATTER = '---\n---\n';
28
+ function isPart(change) {
29
+ return change.kind === 'field' || change.kind === 'section' || change.kind === 'preamble';
30
+ }
11
31
  function at(path, name) {
12
32
  return `${path} ${name}`;
13
33
  }
14
- function priorsOf(preconditions) {
34
+ function* priorsOf(preconditions) {
15
35
  const fields = new Map();
16
36
  const sections = new Map();
17
37
  const preambles = new Map();
@@ -25,6 +45,7 @@ function priorsOf(preconditions) {
25
45
  if (precondition.kind === 'preamble') {
26
46
  preambles.set(precondition.path, precondition.value);
27
47
  }
48
+ yield ROW_WEIGHT;
28
49
  }
29
50
  return {
30
51
  field: (path, name) => fields.get(at(path, name)),
@@ -40,51 +61,50 @@ function compose(fields, sections) {
40
61
  const opened = parse(skeleton);
41
62
  if (!opened.ok)
42
63
  return skeleton;
43
- let document = opened.document;
44
- for (const [name, value] of Object.entries(fields)) {
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);
64
+ const next = apply(opened.document, Object.entries(fields).flatMap(([name, value]) => frontmatterValue(value) ? [{ kind: 'field', name, value, prior: undefined }] : []));
65
+ return serialize(next.outcome === 'applied' ? next.document : opened.document);
50
66
  }
51
- function edited(document, change, priors) {
52
- if (change.kind === 'field') {
53
- return apply(document, {
67
+ function edited(change, priors) {
68
+ if (change.kind === 'field')
69
+ return {
54
70
  kind: 'field',
55
71
  name: change.name,
56
72
  value: change.value,
57
73
  prior: priors.field(change.path, change.name),
58
- });
59
- }
60
- if (change.kind === 'preamble') {
61
- return apply(document, {
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, {
74
+ };
75
+ if (change.kind === 'preamble')
76
+ return { kind: 'preamble', value: change.value, prior: priors.preamble(change.path) };
77
+ return {
70
78
  kind: 'section',
71
79
  name: change.name,
72
80
  value: change.value,
73
81
  prior: priors.section(change.path, change.name),
74
- });
82
+ };
75
83
  }
76
- function edit(staged, change, priors) {
77
- const text = staged.documents[change.path];
84
+ function edit(staged, changes, priors) {
85
+ const path = changes[0].path;
86
+ delete staged.revisions[path];
87
+ const text = staged.documents[path];
78
88
  if (text === undefined)
79
- return false;
80
- const parsed = parse(text, change.path);
89
+ return changes.length;
90
+ const parsed = parse(text, path);
81
91
  if (!parsed.ok)
82
- return false;
83
- const next = edited(parsed.document, change, priors);
84
- if (next?.outcome !== 'applied')
85
- return false;
86
- staged.documents[change.path] = serialize(next.document);
87
- return true;
92
+ return changes.length;
93
+ const wanted = changes.map((change) => edited(change, priors));
94
+ const first = apply(parsed.document, wanted);
95
+ if (first.outcome === 'refuse')
96
+ return changes.length;
97
+ if (first.outcome === 'applied') {
98
+ staged.documents[path] = serialize(first.document);
99
+ return 0;
100
+ }
101
+ const stale = new Set(first.stale);
102
+ const kept = wanted.filter((_, at) => !stale.has(at));
103
+ const rest = apply(parsed.document, kept);
104
+ if (rest.outcome !== 'applied')
105
+ return changes.length;
106
+ staged.documents[path] = serialize(rest.document);
107
+ return first.stale.length;
88
108
  }
89
109
  function relocate(staged, from, to) {
90
110
  const text = staged.documents[from];
@@ -92,8 +112,9 @@ function relocate(staged, from, to) {
92
112
  delete staged.documents[from];
93
113
  staged.documents[to] = text;
94
114
  }
95
- else if (staged.binaryTargets.delete(from)) {
96
- staged.binaryTargets.add(to);
115
+ else if (staged.binaries[from] !== undefined) {
116
+ staged.binaries[to] = staged.binaries[from];
117
+ delete staged.binaries[from];
97
118
  }
98
119
  else {
99
120
  return false;
@@ -103,185 +124,116 @@ function relocate(staged, from, to) {
103
124
  }
104
125
  function moveHead(heads, from, to) {
105
126
  const revision = heads.revisions[from];
127
+ const fileId = heads.fileIds[from];
106
128
  const change = heads.changes[from];
107
129
  delete heads.revisions[from];
130
+ delete heads.fileIds[from];
108
131
  delete heads.changes[from];
132
+ delete heads.fileIds[to];
109
133
  delete heads.changes[to];
110
134
  if (revision !== undefined)
111
135
  heads.revisions[to] = revision;
136
+ if (fileId !== undefined)
137
+ heads.fileIds[to] = fileId;
112
138
  if (change !== undefined)
113
139
  heads.changes[to] = change;
114
140
  }
115
141
  function erase(staged, path) {
116
142
  delete staged.documents[path];
117
143
  delete staged.revisions[path];
144
+ delete staged.fileIds[path];
118
145
  delete staged.changes[path];
119
- staged.binaryTargets.delete(path);
146
+ delete staged.binaries[path];
120
147
  }
121
- function stage(staged, change, priors) {
122
- if (change.kind === 'field' || change.kind === 'section' || change.kind === 'preamble') {
123
- return edit(staged, change, priors);
124
- }
148
+ function stage(staged, change) {
125
149
  if (change.kind === 'create') {
126
150
  staged.documents[change.path] =
127
151
  'content' in change ? change.content : compose(change.fields, change.sections);
152
+ delete staged.fileIds[change.path];
128
153
  delete staged.changes[change.path];
129
154
  return true;
130
155
  }
131
156
  if (change.kind === 'replace') {
157
+ delete staged.revisions[change.path];
132
158
  if (staged.documents[change.path] === undefined)
133
159
  return false;
134
160
  staged.documents[change.path] = change.content;
135
161
  return true;
136
162
  }
163
+ if (change.kind === 'binary') {
164
+ if (staged.documents[change.path] !== undefined)
165
+ return false;
166
+ staged.binaries[change.path] = {
167
+ state: 'pending',
168
+ localId: change.localId,
169
+ byteLength: change.byteLength,
170
+ mediaType: change.mediaType,
171
+ sha256: change.sha256,
172
+ };
173
+ delete staged.revisions[change.path];
174
+ delete staged.changes[change.path];
175
+ return true;
176
+ }
137
177
  if (change.kind === 'move') {
138
178
  return relocate(staged, change.path, change.to);
139
179
  }
180
+ if (change.kind === 'arrival') {
181
+ erase(staged, change.path);
182
+ if ('content' in change)
183
+ staged.documents[change.path] = change.content;
184
+ else
185
+ staged.binaries[change.path] = { state: 'accepted', ...change.binary };
186
+ arrive(staged, change);
187
+ return true;
188
+ }
140
189
  erase(staged, change.path);
141
190
  return true;
142
191
  }
143
- export function overlay(base, queue, unapplied) {
192
+ function arrive(heads, change) {
193
+ if (change.revision !== undefined)
194
+ heads.revisions[change.path] = change.revision;
195
+ if (change.fileId !== undefined)
196
+ heads.fileIds[change.path] = change.fileId;
197
+ if (change.change !== undefined)
198
+ heads.changes[change.path] = change.change;
199
+ }
200
+ export function* overlaying(base, queue, unapplied) {
144
201
  const staged = {
145
- documents: { ...base.documents },
146
- binaryTargets: new Set(base.binaryTargets),
147
- revisions: { ...base.revisions },
148
- changes: { ...base.changes },
202
+ documents: drafted(base.documents),
203
+ binaries: drafted(base.binaries),
204
+ revisions: drafted(base.revisions),
205
+ fileIds: drafted(base.fileIds),
206
+ changes: drafted(base.changes),
149
207
  };
150
208
  for (const batch of queue) {
151
- const priors = priorsOf(batch.preconditions);
152
- for (const change of batch.changes) {
153
- if (!stage(staged, change, priors))
154
- unapplied?.();
155
- }
156
- }
157
- return {
158
- documents: staged.documents,
159
- binaryTargets: [...staged.binaryTargets].sort(),
160
- revisions: staged.revisions,
161
- changes: staged.changes,
162
- };
163
- }
164
- function pathsOf(batch) {
165
- return batch.changes.flatMap((change) => change.kind === 'move' ? [change.path, change.to] : [change.path]);
166
- }
167
- export function sameLayerText(left, right) {
168
- const paths = Object.keys(left.documents);
169
- return (paths.length === Object.keys(right.documents).length &&
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)));
173
- }
174
- function replayHeads(base, queue) {
175
- const heads = { revisions: { ...base.revisions }, changes: { ...base.changes } };
176
- for (const batch of queue) {
177
- for (const change of batch.changes) {
178
- if (change.kind === 'remove') {
179
- delete heads.revisions[change.path];
180
- delete heads.changes[change.path];
181
- }
182
- else if (change.kind === 'create') {
183
- delete heads.changes[change.path];
184
- }
185
- else if (change.kind === 'move') {
186
- moveHead(heads, change.path, change.to);
187
- }
188
- }
189
- }
190
- return heads;
191
- }
192
- export function overlayChanged(base, queue, previousBase, previousQueue, previousVisible) {
193
- const before = previousQueue.map((batch) => JSON.stringify(batch));
194
- const after = queue.map((batch) => JSON.stringify(batch));
195
- if (before.length === after.length &&
196
- before.every((id, index) => id === after[index]) &&
197
- sameLayerText(base, previousBase)) {
198
- return {
199
- documents: previousVisible.documents,
200
- binaryTargets: previousVisible.binaryTargets,
201
- ...replayHeads(base, queue),
202
- };
203
- }
204
- const affected = new Set();
205
- const paths = new Set([
206
- ...Object.keys(base.documents),
207
- ...Object.keys(previousBase.documents),
208
- ...Object.keys(base.revisions),
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))
220
- affected.add(path);
221
- }
222
- const oldIds = new Set(before);
223
- const newIds = new Set(after);
224
- for (const batch of previousQueue) {
225
- if (!newIds.has(JSON.stringify(batch)))
226
- for (const path of pathsOf(batch))
227
- affected.add(path);
228
- }
229
- for (const batch of queue) {
230
- if (!oldIds.has(JSON.stringify(batch)))
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)))
209
+ const priors = yield* priorsOf(batch.preconditions);
210
+ for (let index = 0; index < batch.changes.length; index += 1) {
211
+ const change = batch.changes[index];
212
+ if (!isPart(change)) {
213
+ if (!stage(staged, change))
214
+ unapplied?.();
215
+ yield ROW_WEIGHT;
240
216
  continue;
241
- for (const path of touched) {
242
- if (affected.has(path))
243
- continue;
244
- affected.add(path);
245
- expanded = true;
246
217
  }
218
+ const run = [change];
219
+ while (index + 1 < batch.changes.length) {
220
+ const next = batch.changes[index + 1];
221
+ if (!isPart(next) || next.path !== change.path)
222
+ break;
223
+ run.push(next);
224
+ index += 1;
225
+ }
226
+ const text = staged.documents[change.path] ?? '';
227
+ for (let left = edit(staged, run, priors); left > 0; left -= 1)
228
+ unapplied?.();
229
+ yield ROW_WEIGHT + text.length;
247
230
  }
248
231
  }
249
- const documents = {};
250
- const revisions = {};
251
- const changes = {};
252
- for (const path of affected) {
253
- if (base.documents[path] !== undefined)
254
- documents[path] = base.documents[path];
255
- if (base.revisions[path] !== undefined)
256
- revisions[path] = base.revisions[path];
257
- if (base.changes[path] !== undefined)
258
- changes[path] = base.changes[path];
259
- }
260
- const staged = overlay({
261
- documents,
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);
275
- }
276
- Object.assign(mergedDocuments, staged.documents);
277
- Object.assign(mergedRevisions, staged.revisions);
278
- Object.assign(mergedChanges, staged.changes);
279
- for (const path of staged.binaryTargets)
280
- mergedTargets.add(path);
281
232
  return {
282
- documents: mergedDocuments,
283
- revisions: mergedRevisions,
284
- changes: mergedChanges,
285
- binaryTargets: [...mergedTargets].sort(),
233
+ documents: yield* settling(staged.documents),
234
+ binaries: yield* settling(staged.binaries),
235
+ revisions: yield* settling(staged.revisions),
236
+ fileIds: yield* settling(staged.fileIds),
237
+ changes: yield* settling(staged.changes),
286
238
  };
287
239
  }
package/dist/paths.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export declare function normalize(path: string): string | null;
2
2
  export declare function beneath(prefix: string, path: string): boolean;
3
3
  export declare function covered(prefixes: readonly string[], path: string): boolean;
4
+ export declare function ancestors(path: string): readonly string[];
4
5
  //# sourceMappingURL=paths.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"AAAA,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAYrD;AAED,wBAAgB,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAE7D;AAED,wBAAgB,OAAO,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAK1E"}
1
+ {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"AAAA,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAYrD;AAED,wBAAgB,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAE7D;AAED,wBAAgB,OAAO,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAK1E;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAGzD"}
package/dist/paths.js CHANGED
@@ -22,3 +22,7 @@ export function covered(prefixes, path) {
22
22
  return normalized !== null && (normalized === '' || beneath(normalized, path));
23
23
  });
24
24
  }
25
+ export function ancestors(path) {
26
+ const parts = path.split('/');
27
+ return parts.slice(1).map((_, at) => parts.slice(0, at + 1).join('/'));
28
+ }
@@ -0,0 +1,3 @@
1
+ export declare const HOLDS_PHRASE = "holds_phrase";
2
+ export declare function holdsPhrase(_context: number, text: unknown, phrase: unknown): number;
3
+ //# sourceMappingURL=phrase.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"phrase.d.ts","sourceRoot":"","sources":["../src/phrase.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,YAAY,iBAAiB,CAAC;AAE3C,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,GAAG,MAAM,CAMpF"}
package/dist/phrase.js ADDED
@@ -0,0 +1,8 @@
1
+ export const HOLDS_PHRASE = 'holds_phrase';
2
+ export function holdsPhrase(_context, text, phrase) {
3
+ return typeof text === 'string' &&
4
+ typeof phrase === 'string' &&
5
+ text.toLowerCase().includes(phrase)
6
+ ? 1
7
+ : 0;
8
+ }
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,14 +38,17 @@ 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
  };
42
46
  backlinks?: Related & {
43
47
  field?: string;
44
48
  };
49
+ text?: string;
45
50
  };
46
- export type Key = 'room' | 'path' | 'type' | {
51
+ export type Key = 'room' | 'path' | 'type' | 'folder' | {
47
52
  field: string;
48
53
  };
49
54
  export type Select = 'all' | {
@@ -53,6 +58,8 @@ export type Select = 'all' | {
53
58
  markdown?: true;
54
59
  backlinks?: true;
55
60
  change?: true;
61
+ fileId?: true;
62
+ revision?: true;
56
63
  };
57
64
  export type OrderOptions = {
58
65
  nulls?: 'first' | 'last';
@@ -68,6 +75,8 @@ export type DocumentQuery = Filter & {
68
75
  direction?: Direction;
69
76
  } & OrderOptions)[];
70
77
  limit?: number;
78
+ after?: string;
79
+ total?: true;
71
80
  };
72
81
  export type GroupQuery = Filter & {
73
82
  groupBy: readonly Exclude<Key, 'path'>[];
@@ -76,6 +85,8 @@ export type GroupQuery = Filter & {
76
85
  direction?: Direction;
77
86
  }[];
78
87
  limit?: number;
88
+ after?: string;
89
+ total?: true;
79
90
  };
80
91
  export type LocalQuery = DocumentQuery | GroupQuery;
81
92
  export type Backlink = {
@@ -91,20 +102,53 @@ export type QueryDocument = {
91
102
  sections?: Readonly<Record<string, string>>;
92
103
  preamble?: string;
93
104
  markdown?: string;
105
+ textHeld?: false;
94
106
  backlinks?: readonly Backlink[];
95
107
  change?: HeadChange | null;
108
+ fileId?: string | null;
109
+ revision?: string | null;
110
+ binaryFile?: BinaryFileRecord;
96
111
  };
97
112
  export type QueryGroup = {
98
113
  key: readonly unknown[];
99
114
  count: number;
100
115
  };
101
- export type DocumentResult = {
116
+ export type CoveredRoom = {
117
+ room: string;
118
+ generation: string;
119
+ current: boolean;
120
+ };
121
+ export type QueryCoverage = {
122
+ rooms: readonly CoveredRoom[];
123
+ indexes: readonly string[];
124
+ overlay: readonly string[];
125
+ };
126
+ export type Awaits = Open<'acquisition' | 'preparation' | 'unlock'>;
127
+ export type PendingRoom = {
128
+ room: string;
129
+ awaits: Awaits;
130
+ };
131
+ export type PendingResult = {
132
+ pending: readonly PendingRoom[];
133
+ };
134
+ export type DocumentRows = {
102
135
  documents: readonly QueryDocument[];
136
+ next?: string;
137
+ total?: number;
103
138
  };
104
- export type GroupResult = {
139
+ export type GroupRows = {
105
140
  groups: readonly QueryGroup[];
141
+ next?: string;
142
+ total?: number;
143
+ };
144
+ export type QueryRows = DocumentRows | GroupRows;
145
+ export type DocumentResult = DocumentRows & {
146
+ coverage: QueryCoverage;
106
147
  };
107
- export type QueryResult = DocumentResult | GroupResult;
148
+ export type GroupResult = GroupRows & {
149
+ coverage: QueryCoverage;
150
+ };
151
+ export type QueryResult = DocumentResult | GroupResult | PendingResult;
108
152
  export type QueryErrorCode = 'invalid-query' | 'unknown-type' | 'unknown-field' | 'wrong-kind';
109
153
  export type RoomFacts = {
110
154
  locator: string;
@@ -159,6 +203,8 @@ export type KeyPlan = {
159
203
  of: 'path';
160
204
  } | {
161
205
  of: 'type';
206
+ } | {
207
+ of: 'folder';
162
208
  } | {
163
209
  of: 'field';
164
210
  field: string;
@@ -171,6 +217,8 @@ export type DocumentShape = {
171
217
  markdown: boolean;
172
218
  backlinks: boolean;
173
219
  change: boolean;
220
+ fileId: boolean;
221
+ revision: boolean;
174
222
  orderBy: readonly {
175
223
  key: KeyPlan;
176
224
  options: OrderOptions & {
@@ -178,6 +226,7 @@ export type DocumentShape = {
178
226
  };
179
227
  }[];
180
228
  };
229
+ export declare function bodied(shape: DocumentShape): boolean;
181
230
  export type GroupShape = {
182
231
  kind: 'groups';
183
232
  groupBy: readonly KeyPlan[];
@@ -186,22 +235,39 @@ export type GroupShape = {
186
235
  direction: Direction;
187
236
  }[];
188
237
  };
238
+ export type PlanArea = {
239
+ room: string;
240
+ path: string;
241
+ open: readonly string[];
242
+ };
189
243
  export type PlanReach = {
190
244
  rooms: readonly string[];
191
245
  documents: readonly string[];
246
+ areas: readonly PlanArea[];
247
+ };
248
+ export type Continuation = {
249
+ text: string;
250
+ values: readonly unknown[] | null;
192
251
  };
193
252
  export type Plan = {
253
+ key: string;
194
254
  rooms: readonly string[] | null;
195
255
  reach: PlanReach | null;
256
+ locked: readonly string[];
196
257
  root: Scope;
258
+ folder: string | null;
259
+ paths: readonly string[] | null;
197
260
  hop: (Scope & {
198
261
  field: string;
199
262
  }) | null;
200
263
  backlinks: (Scope & {
201
264
  field: string | null;
202
265
  }) | null;
266
+ text: string | null;
203
267
  shape: DocumentShape | GroupShape;
204
268
  limit: number | null;
269
+ after: Continuation | null;
270
+ total: boolean;
205
271
  };
206
272
  export declare class QueryError extends Error {
207
273
  readonly code: QueryErrorCode;
@@ -212,9 +278,11 @@ type Entries = Readonly<Record<string, unknown>>;
212
278
  export declare function invalid(at: string, problem: string): never;
213
279
  export declare function plain(value: unknown): value is Entries;
214
280
  export declare function known(value: Entries, allowed: readonly string[], at: string): void;
281
+ export declare function flag(input: unknown, at: string): boolean;
215
282
  export declare function planOf(input: unknown, facts: HeldRooms, reach?: PlanReach | null): Plan;
216
283
  export declare function limitOf(input: unknown): number | null;
217
284
  export declare function filterOf(input: unknown, facts: HeldRooms, reach?: PlanReach | null): Plan;
285
+ export declare function queryKey(query: unknown): string;
218
286
  export declare function identityOf(plan: Plan): string;
219
287
  export {};
220
288
  //# sourceMappingURL=query.d.ts.map