@agentshouse/mdruntime 0.1.0-c3903a68dcbbf → 0.1.0-c3c7796382e28

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 (186) hide show
  1. package/README.md +25 -12
  2. package/dist/adapter.d.ts +216 -74
  3. package/dist/adapter.d.ts.map +1 -1
  4. package/dist/adapter.js +1 -9
  5. package/dist/attached-model.d.ts +15 -0
  6. package/dist/attached-model.d.ts.map +1 -0
  7. package/dist/attached-model.js +64 -0
  8. package/dist/attempt.d.ts +16 -0
  9. package/dist/attempt.d.ts.map +1 -0
  10. package/dist/attempt.js +70 -0
  11. package/dist/binary.d.ts +18 -0
  12. package/dist/binary.d.ts.map +1 -0
  13. package/dist/binary.js +8 -0
  14. package/dist/bootstrap.d.ts +44 -7
  15. package/dist/bootstrap.d.ts.map +1 -1
  16. package/dist/bootstrap.js +224 -46
  17. package/dist/chain.d.ts +11 -0
  18. package/dist/chain.d.ts.map +1 -0
  19. package/dist/chain.js +64 -0
  20. package/dist/change-set.d.ts +9 -14
  21. package/dist/change-set.d.ts.map +1 -1
  22. package/dist/change-set.js +11 -60
  23. package/dist/change.d.ts +45 -0
  24. package/dist/change.d.ts.map +1 -1
  25. package/dist/change.js +34 -0
  26. package/dist/client.d.ts +37 -21
  27. package/dist/client.d.ts.map +1 -1
  28. package/dist/client.js +159 -35
  29. package/dist/collection.d.ts +14 -15
  30. package/dist/collection.d.ts.map +1 -1
  31. package/dist/collection.js +65 -63
  32. package/dist/compile.d.ts +16 -0
  33. package/dist/compile.d.ts.map +1 -0
  34. package/dist/compile.js +765 -0
  35. package/dist/connection.d.ts +67 -42
  36. package/dist/connection.d.ts.map +1 -1
  37. package/dist/connection.js +4006 -1085
  38. package/dist/conversation.d.ts +59 -21
  39. package/dist/conversation.d.ts.map +1 -1
  40. package/dist/conversation.js +786 -243
  41. package/dist/digest.d.ts +7 -0
  42. package/dist/digest.d.ts.map +1 -0
  43. package/dist/digest.js +113 -0
  44. package/dist/durability.d.ts +5 -1
  45. package/dist/durability.d.ts.map +1 -1
  46. package/dist/durability.js +5 -0
  47. package/dist/entry.d.ts +19 -0
  48. package/dist/entry.d.ts.map +1 -0
  49. package/dist/entry.js +151 -0
  50. package/dist/expectation.d.ts +21 -0
  51. package/dist/expectation.d.ts.map +1 -0
  52. package/dist/expectation.js +70 -0
  53. package/dist/failure.d.ts +13 -0
  54. package/dist/failure.d.ts.map +1 -0
  55. package/dist/failure.js +19 -0
  56. package/dist/fence.d.ts +6 -0
  57. package/dist/fence.d.ts.map +1 -0
  58. package/dist/fence.js +10 -0
  59. package/dist/file.d.ts +2 -19
  60. package/dist/file.d.ts.map +1 -1
  61. package/dist/file.js +7 -122
  62. package/dist/fulltext.d.ts +27 -0
  63. package/dist/fulltext.d.ts.map +1 -0
  64. package/dist/fulltext.js +368 -0
  65. package/dist/host.d.ts +21 -3
  66. package/dist/host.d.ts.map +1 -1
  67. package/dist/host.js +165 -72
  68. package/dist/identity.d.ts +4 -0
  69. package/dist/identity.d.ts.map +1 -1
  70. package/dist/identity.js +16 -1
  71. package/dist/index.d.ts +19 -10
  72. package/dist/index.d.ts.map +1 -1
  73. package/dist/index.js +8 -1
  74. package/dist/live.d.ts +22 -0
  75. package/dist/live.d.ts.map +1 -0
  76. package/dist/live.js +124 -0
  77. package/dist/media.d.ts +8 -0
  78. package/dist/media.d.ts.map +1 -0
  79. package/dist/media.js +208 -0
  80. package/dist/memory.d.ts +22 -8
  81. package/dist/memory.d.ts.map +1 -1
  82. package/dist/memory.js +207 -48
  83. package/dist/messages.d.ts +28 -0
  84. package/dist/messages.d.ts.map +1 -0
  85. package/dist/messages.js +90 -0
  86. package/dist/model.d.ts +23 -14
  87. package/dist/model.d.ts.map +1 -1
  88. package/dist/model.js +22 -4
  89. package/dist/name.d.ts +4 -0
  90. package/dist/name.d.ts.map +1 -0
  91. package/dist/name.js +122 -0
  92. package/dist/observation.d.ts +21 -1
  93. package/dist/observation.d.ts.map +1 -1
  94. package/dist/observation.js +128 -17
  95. package/dist/open.d.ts +2 -0
  96. package/dist/open.d.ts.map +1 -0
  97. package/dist/open.js +1 -0
  98. package/dist/opened.d.ts +22 -0
  99. package/dist/opened.d.ts.map +1 -0
  100. package/dist/opened.js +107 -0
  101. package/dist/outcome.d.ts +75 -21
  102. package/dist/outcome.d.ts.map +1 -1
  103. package/dist/outcome.js +81 -1
  104. package/dist/overlay.d.ts +15 -5
  105. package/dist/overlay.d.ts.map +1 -1
  106. package/dist/overlay.js +136 -180
  107. package/dist/paths.d.ts +0 -1
  108. package/dist/paths.d.ts.map +1 -1
  109. package/dist/paths.js +0 -16
  110. package/dist/query.d.ts +78 -7
  111. package/dist/query.d.ts.map +1 -1
  112. package/dist/query.js +126 -43
  113. package/dist/reach.d.ts +53 -0
  114. package/dist/reach.d.ts.map +1 -0
  115. package/dist/reach.js +448 -0
  116. package/dist/react.d.ts +43 -0
  117. package/dist/react.d.ts.map +1 -0
  118. package/dist/react.js +54 -0
  119. package/dist/readiness.d.ts +64 -0
  120. package/dist/readiness.d.ts.map +1 -0
  121. package/dist/readiness.js +33 -0
  122. package/dist/reads.d.ts +11 -0
  123. package/dist/reads.d.ts.map +1 -0
  124. package/dist/reads.js +100 -0
  125. package/dist/recovery.d.ts +25 -0
  126. package/dist/recovery.d.ts.map +1 -0
  127. package/dist/recovery.js +198 -0
  128. package/dist/refresh.d.ts +19 -7
  129. package/dist/refresh.d.ts.map +1 -1
  130. package/dist/refresh.js +125 -53
  131. package/dist/replica.d.ts +59 -33
  132. package/dist/replica.d.ts.map +1 -1
  133. package/dist/replica.js +324 -162
  134. package/dist/room-draft.d.ts +44 -9
  135. package/dist/room-draft.d.ts.map +1 -1
  136. package/dist/room-draft.js +191 -40
  137. package/dist/rows.d.ts +39 -34
  138. package/dist/rows.d.ts.map +1 -1
  139. package/dist/rows.js +195 -81
  140. package/dist/save.d.ts +72 -6
  141. package/dist/save.d.ts.map +1 -1
  142. package/dist/save.js +889 -179
  143. package/dist/search.d.ts +41 -29
  144. package/dist/search.d.ts.map +1 -1
  145. package/dist/search.js +37 -105
  146. package/dist/seed.d.ts +16 -0
  147. package/dist/seed.d.ts.map +1 -0
  148. package/dist/seed.js +75 -0
  149. package/dist/shared.d.ts +16 -0
  150. package/dist/shared.d.ts.map +1 -0
  151. package/dist/shared.js +431 -0
  152. package/dist/status.d.ts +6 -2
  153. package/dist/status.d.ts.map +1 -1
  154. package/dist/status.js +0 -8
  155. package/dist/store.d.ts +129 -70
  156. package/dist/store.d.ts.map +1 -1
  157. package/dist/store.js +373 -365
  158. package/dist/stored.d.ts +152 -0
  159. package/dist/stored.d.ts.map +1 -0
  160. package/dist/stored.js +571 -0
  161. package/dist/tables.d.ts +354 -0
  162. package/dist/tables.d.ts.map +1 -0
  163. package/dist/tables.js +624 -0
  164. package/dist/turn.d.ts +9 -0
  165. package/dist/turn.d.ts.map +1 -0
  166. package/dist/turn.js +75 -0
  167. package/dist/validation.d.ts +30 -0
  168. package/dist/validation.d.ts.map +1 -0
  169. package/dist/validation.js +162 -0
  170. package/dist/windows.d.ts +22 -0
  171. package/dist/windows.d.ts.map +1 -0
  172. package/dist/windows.js +89 -0
  173. package/dist/wire.d.ts +194 -19
  174. package/dist/wire.d.ts.map +1 -1
  175. package/dist/wire.js +90 -67
  176. package/dist/words.d.ts +19 -0
  177. package/dist/words.d.ts.map +1 -0
  178. package/dist/words.js +150 -0
  179. package/package.json +33 -10
  180. package/AGENTS.md +0 -210
  181. package/dist/attachment.d.ts +0 -3
  182. package/dist/attachment.d.ts.map +0 -1
  183. package/dist/attachment.js +0 -8
  184. package/dist/read-side.d.ts +0 -14
  185. package/dist/read-side.d.ts.map +0 -1
  186. package/dist/read-side.js +0 -371
package/dist/client.js CHANGED
@@ -1,5 +1,28 @@
1
+ import { shownBy } from './media.js';
1
2
  import { observed } from './observation.js';
2
- import { answer, AUTHORIZATION_ENDED, carried, envelope, PORT_CLOSED, PROTOCOL_MISMATCH, } from './wire.js';
3
+ import { runtimeError } from './failure.js';
4
+ import { answer, AUTHORIZATION_ENDED, PORT_CLOSED, } from './wire.js';
5
+ // React renders an arrived value in a later task and opens what that render observes as it commits, so this many frames opening nothing mean the page drew what it observes.
6
+ const SETTLED_FRAMES = 2;
7
+ // A browser reads a download's address only after the click that hands it returns, so a copy's address is released a minute later.
8
+ const HANDED_COPY_MS = 60_000;
9
+ const PAGE = /\.html?$/iu;
10
+ const STARTED = { kind: 'started' };
11
+ const BLOCKED = {
12
+ kind: 'blocked',
13
+ code: 'popup-blocked',
14
+ fields: {},
15
+ retryable: true,
16
+ };
17
+ function handed(url, name) {
18
+ const anchor = document.createElement('a');
19
+ anchor.href = url;
20
+ anchor.download = name;
21
+ anchor.click();
22
+ }
23
+ function refused(refusal) {
24
+ return runtimeError(refusal.code, refusal.code, refusal.retryable);
25
+ }
3
26
  export function connectMdRuntime(port) {
4
27
  let sequence = 0;
5
28
  let refusal = null;
@@ -7,8 +30,10 @@ export function connectMdRuntime(port) {
7
30
  const calls = new Map();
8
31
  const opening = new Map();
9
32
  const observations = new Map();
33
+ let drawing = null;
34
+ let settling = null;
10
35
  const send = (message) => {
11
- port.postMessage(envelope(message));
36
+ port.postMessage(message);
12
37
  };
13
38
  function begin(id, topic, first) {
14
39
  const handle = observed(first, () => {
@@ -25,7 +50,7 @@ export function connectMdRuntime(port) {
25
50
  if (topic === 'connection-refusal')
26
51
  handle.receive(reported);
27
52
  }
28
- const failure = new Error(reported.reason);
53
+ const failure = refused(reported);
29
54
  for (const [id, waiting] of opening) {
30
55
  if (waiting.topic === 'connection-refusal')
31
56
  waiting.settle(begin(id, waiting.topic, reported));
@@ -36,12 +61,12 @@ export function connectMdRuntime(port) {
36
61
  for (const waiting of calls.values())
37
62
  waiting.fail(failure);
38
63
  calls.clear();
64
+ drawing?.();
39
65
  }
40
- function end(reason) {
66
+ function end(failure) {
41
67
  if (ended !== null)
42
68
  return;
43
- ended = reason;
44
- const failure = new Error(reason);
69
+ ended = failure;
45
70
  for (const waiting of opening.values())
46
71
  waiting.fail(failure);
47
72
  opening.clear();
@@ -51,16 +76,10 @@ export function connectMdRuntime(port) {
51
76
  for (const { handle } of observations.values())
52
77
  handle.end();
53
78
  observations.clear();
79
+ drawing?.();
54
80
  }
55
81
  port.addEventListener('message', (event) => {
56
- const wire = carried(event.data);
57
- if (wire === null)
58
- return;
59
- if (!wire.matching) {
60
- refuse(PROTOCOL_MISMATCH);
61
- return;
62
- }
63
- const message = answer(wire.message);
82
+ const message = answer(event.data);
64
83
  if (message === null)
65
84
  return;
66
85
  if (message.kind === 'refusal') {
@@ -68,7 +87,11 @@ export function connectMdRuntime(port) {
68
87
  return;
69
88
  }
70
89
  if (message.kind === 'ended') {
71
- end(AUTHORIZATION_ENDED);
90
+ for (const { topic, handle } of observations.values()) {
91
+ if (topic === 'member')
92
+ handle.receive(null);
93
+ }
94
+ end(runtimeError('authorization-ended', AUTHORIZATION_ENDED));
72
95
  return;
73
96
  }
74
97
  if (message.kind === 'event') {
@@ -78,31 +101,34 @@ export function connectMdRuntime(port) {
78
101
  const waiting = opening.get(message.id);
79
102
  if (waiting !== undefined) {
80
103
  opening.delete(message.id);
81
- if (message.kind === 'failure')
82
- waiting.fail(new Error(message.message));
104
+ if (message.kind === 'failure') {
105
+ waiting.fail(runtimeError(message.code, message.message, message.retryable));
106
+ }
83
107
  else
84
108
  waiting.settle(begin(message.id, waiting.topic, message.value));
109
+ drawing?.();
85
110
  return;
86
111
  }
87
112
  const called = calls.get(message.id);
88
113
  if (called === undefined)
89
114
  return;
90
115
  calls.delete(message.id);
91
- if (message.kind === 'failure')
92
- called.fail(new Error(message.message));
116
+ if (message.kind === 'failure') {
117
+ called.fail(runtimeError(message.code, message.message, message.retryable));
118
+ }
93
119
  else
94
120
  called.settle(message.value);
95
121
  });
96
122
  port.addEventListener('close', () => {
97
- end(PORT_CLOSED);
123
+ end(runtimeError('port-closed', PORT_CLOSED));
98
124
  });
99
125
  port.start();
100
126
  send({ kind: 'hello' });
101
127
  function ask(member, input) {
102
128
  if (ended !== null)
103
- return Promise.reject(new Error(ended));
129
+ return Promise.reject(ended);
104
130
  if (refusal !== null)
105
- return Promise.reject(new Error(refusal.reason));
131
+ return Promise.reject(refused(refusal));
106
132
  const id = (sequence += 1);
107
133
  return new Promise((settle, fail) => {
108
134
  calls.set(id, { settle: settle, fail });
@@ -111,43 +137,123 @@ export function connectMdRuntime(port) {
111
137
  }
112
138
  function watch(topic, input) {
113
139
  if (ended !== null)
114
- return Promise.reject(new Error(ended));
140
+ return Promise.reject(ended);
115
141
  const id = (sequence += 1);
116
142
  if (refusal !== null) {
117
143
  return topic === 'connection-refusal'
118
144
  ? Promise.resolve(begin(id, topic, refusal))
119
- : Promise.reject(new Error(refusal.reason));
145
+ : Promise.reject(refused(refusal));
120
146
  }
121
147
  return new Promise((settle, fail) => {
122
148
  opening.set(id, { topic, settle, fail });
123
149
  send({ kind: 'observe', id, topic, input });
150
+ drawing?.();
151
+ });
152
+ }
153
+ function streamed(answer) {
154
+ if (answer.kind !== 'binary')
155
+ return answer;
156
+ const { file, byteLength, mediaType } = answer;
157
+ let part = 0;
158
+ let received = 0;
159
+ const stream = new ReadableStream({
160
+ async pull(controller) {
161
+ const bytes = await ask('binaryFile.part', [file, part]);
162
+ if (bytes === null) {
163
+ if (received === byteLength)
164
+ controller.close();
165
+ else
166
+ controller.error(runtimeError('binary-file-absent', 'The file ended early'));
167
+ return;
168
+ }
169
+ part += 1;
170
+ received += bytes.byteLength;
171
+ controller.enqueue(bytes);
172
+ },
173
+ }, { highWaterMark: 0 });
174
+ return { kind: 'binary', stream, byteLength, mediaType };
175
+ }
176
+ async function download(room, path, revision) {
177
+ const tab = PAGE.test(path) ? globalThis.open('', '_blank') : null;
178
+ const linked = await ask('binaryFile.link', [room, path, revision]);
179
+ if (linked.kind === 'link' && PAGE.test(linked.name)) {
180
+ const away = tab ?? globalThis.open('', '_blank');
181
+ if (away === null)
182
+ return BLOCKED;
183
+ away.location.replace(linked.url);
184
+ return STARTED;
185
+ }
186
+ tab?.close();
187
+ if (linked.kind === 'link') {
188
+ handed(linked.url, linked.name);
189
+ return STARTED;
190
+ }
191
+ if (linked.kind !== 'absent')
192
+ return linked;
193
+ const read = streamed(await ask('binaryFile.read', [room, path, revision]));
194
+ if (read.kind !== 'binary')
195
+ return read;
196
+ const copy = await new Response(read.stream, {
197
+ headers: { 'content-type': read.mediaType },
198
+ }).blob();
199
+ const url = URL.createObjectURL(copy);
200
+ handed(url, path.slice(path.lastIndexOf('/') + 1));
201
+ setTimeout(() => URL.revokeObjectURL(url), HANDED_COPY_MS);
202
+ return STARTED;
203
+ }
204
+ function settled() {
205
+ if (settling !== null)
206
+ return settling;
207
+ settling = new Promise((resolve) => {
208
+ let moved = 0;
209
+ const check = () => {
210
+ moved += 1;
211
+ if (opening.size > 0)
212
+ return;
213
+ const at = moved;
214
+ const waited = (frames) => {
215
+ requestAnimationFrame(() => {
216
+ if (frames < SETTLED_FRAMES) {
217
+ waited(frames + 1);
218
+ return;
219
+ }
220
+ if (moved !== at || opening.size > 0)
221
+ return;
222
+ drawing = null;
223
+ resolve();
224
+ });
225
+ };
226
+ waited(1);
227
+ };
228
+ drawing = check;
229
+ check();
124
230
  });
231
+ return settling;
125
232
  }
126
- return {
233
+ const show = (room, path, revision) => ask('binaryFile.show', [room, path, revision]).then((shown) => streamed(shown));
234
+ return shownBy(show, {
127
235
  rooms: () => ask('rooms', []),
128
- slots: () => ask('slots', []),
129
236
  query: ((query) => ask('query', [query])),
130
237
  search: (request) => ask('search', [request]),
131
238
  types: (locator) => ask('types', [locator]),
132
- syncStatus: () => ask('syncStatus', []),
133
- serviceMode: () => ask('serviceMode', []),
134
239
  roomDraft: {
135
240
  list: () => ask('roomDraft.list', []),
136
241
  read: (room, path) => ask('roomDraft.read', [room, path]),
137
- write: (room, path, revision, parts) => ask('roomDraft.write', [room, path, revision, parts]),
242
+ write: (room, path, revision, parts, next) => ask('roomDraft.write', next === undefined ? [room, path, revision, parts] : [room, path, revision, parts, next]),
138
243
  discard: (room, path, revision) => ask('roomDraft.discard', [room, path, revision]),
139
244
  },
140
245
  save: (room, roomDrafts) => ask('save', [room, roomDrafts]),
141
- outcome: (identifier) => ask('outcome', [identifier]),
246
+ saveParts: (room, parts) => ask('saveParts', [room, parts]),
142
247
  presentation: {
143
248
  read: () => ask('presentation.read', []),
144
249
  write: (value) => ask('presentation.write', [value]),
250
+ edit: (members) => ask('presentation.edit', [members]),
145
251
  },
146
252
  conversation: {
147
253
  list: () => ask('conversation.list', []),
148
254
  read: (conversation, options) => ask('conversation.read', [conversation, options]),
149
255
  create: (input) => ask('conversation.create', [input]),
150
- send: (conversation) => ask('conversation.send', [conversation]),
256
+ send: (conversation, operation, draft) => ask('conversation.send', [conversation, operation, draft]),
151
257
  answer: (conversation, answer) => ask('conversation.answer', [conversation, answer]),
152
258
  interrupt: (conversation) => ask('conversation.interrupt', [conversation]),
153
259
  kill: (conversation) => ask('conversation.kill', [conversation]),
@@ -155,17 +261,35 @@ export function connectMdRuntime(port) {
155
261
  delete: (conversation) => ask('conversation.delete', [conversation]),
156
262
  },
157
263
  chatDraft: {
158
- write: (conversation, draft) => ask('chatDraft.write', [conversation, draft]),
264
+ write: (conversation, draft, revision) => ask('chatDraft.write', [conversation, draft, revision]),
265
+ prepend: (conversation, draft) => ask('chatDraft.prepend', [conversation, draft]),
159
266
  discard: (conversation) => ask('chatDraft.discard', [conversation]),
160
267
  },
161
268
  history: (locator, path, query) => ask('history', [locator, path, query]),
269
+ resolve: (room, path, destination) => ask('resolve', [room, path, destination]),
270
+ binaryFile: {
271
+ read: (room, path, revision) => ask('binaryFile.read', [room, path, revision]).then((read) => streamed(read)),
272
+ attach: (room, file) => ask('binaryFile.attach', [room, file]),
273
+ download,
274
+ },
162
275
  call: (name, input) => ask('call', [name, input]),
163
276
  reached: (locator, roomVersion, path) => ask('reached', [locator, roomVersion, path]),
164
277
  log: () => ask('log', []),
165
- storageLoss: () => ask('storageLoss', []),
166
278
  persistence: () => ask('persistence', []),
167
- deploymentFacts: () => ask('deploymentFacts', []),
279
+ retry: () => ask('retry', []),
280
+ cleanUp: () => ask('cleanUp', []),
168
281
  observe: ((topic, ...input) => watch(topic, input)),
169
282
  reauthorize: () => ask('reauthorize', []),
170
- };
283
+ settled,
284
+ });
285
+ }
286
+ const turns = new WeakMap();
287
+ export function inTurn(client, work) {
288
+ const turn = (turns.get(client) ?? Promise.resolve()).then(work);
289
+ turns.set(client, turn.then(() => undefined, () => undefined));
290
+ return turn;
171
291
  }
292
+ export { chainedWindows } from './chain.js';
293
+ export { roomDraftRevision } from './identity.js';
294
+ export { defineRoomMedia, ROOM_MEDIA } from './media.js';
295
+ export { unanswered } from './wire.js';
@@ -1,11 +1,13 @@
1
- import { type Document, type Validation } from '@agentshouse/mdmodel';
1
+ import { type Document } from '@agentshouse/mdmodel';
2
2
  import type { ModelState } from './model.js';
3
3
  import type { MdModelIdentity } from './adapter.js';
4
+ import { type Paths } from './shared.js';
4
5
  import type { Refused } from './transfer.js';
5
6
  export declare const MD_MODEL: MdModelIdentity;
6
7
  export type Collection = {
7
- documents: Readonly<Record<string, Document>>;
8
+ text: Readonly<Record<string, string>>;
8
9
  composition: Composition;
10
+ document(path: string): Document | undefined;
9
11
  };
10
12
  export type Composition = {
11
13
  model: ModelState;
@@ -13,20 +15,17 @@ export type Composition = {
13
15
  roots: readonly string[];
14
16
  model: ModelState;
15
17
  } | null;
16
- untypedFolders: readonly string[];
17
18
  };
18
- export declare function untyped(roots: readonly string[], path: string): boolean;
19
- export declare function governing(composition: Composition, path: string): ModelState;
20
- type Previous = {
21
- text: Readonly<Record<string, string>>;
22
- collection: Collection;
19
+ export type Composed = {
20
+ readonly composition: Composition;
21
+ readonly fingerprint: string;
23
22
  };
24
- export declare function parseCollection(text: Readonly<Record<string, string>>, composition: Composition, previous?: Previous): Collection;
25
- export declare function readCollection(text: Readonly<Record<string, string>>, composition: Composition, previous?: Previous): {
26
- kind: 'read';
27
- collection: Collection;
28
- } | Refused;
23
+ export declare function composedOf(composition: Composition): Composed;
24
+ export declare function selected(composition: Composition, path: string): boolean;
25
+ export declare function governing(composition: Composition, path: string): ModelState;
26
+ export declare function collectionOf(text: Readonly<Record<string, string>>, composition: Composition): Collection;
27
+ export declare function documentsOf(collection: Collection): Generator<number, Iterable<readonly [string, Document]>, void>;
28
+ export declare function unreadable(text: Paths<string>, paths?: Iterable<string> | null): Generator<number, Refused | null, void>;
29
29
  export declare function validRoot(root: unknown): root is string;
30
- export declare function validateCollection(text: Readonly<Record<string, string>>, binaryTargets: readonly string[], composition: Composition): Validation;
31
- export {};
30
+ export declare function available(composition: Composition): boolean;
32
31
  //# sourceMappingURL=collection.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"collection.d.ts","sourceRoot":"","sources":["../src/collection.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,QAAQ,EAEb,KAAK,UAAU,EAEhB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAE7C,eAAO,MAAM,QAAQ,EAAE,eAAwE,CAAC;AAIhG,MAAM,MAAM,UAAU,GAAG;IACvB,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;IAC9C,WAAW,EAAE,WAAW,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,KAAK,EAAE,UAAU,CAAC;IAClB,SAAS,EAAE;QAAE,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;QAAC,KAAK,EAAE,UAAU,CAAA;KAAE,GAAG,IAAI,CAAC;IAClE,cAAc,EAAE,SAAS,MAAM,EAAE,CAAC;CACnC,CAAC;AASF,wBAAgB,OAAO,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAEvE;AAED,wBAAgB,SAAS,CAAC,WAAW,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,GAAG,UAAU,CAI5E;AAED,KAAK,QAAQ,GAAG;IAAE,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAAC,UAAU,EAAE,UAAU,CAAA;CAAE,CAAC;AAanF,wBAAgB,eAAe,CAC7B,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EACtC,WAAW,EAAE,WAAW,EACxB,QAAQ,CAAC,EAAE,QAAQ,GAClB,UAAU,CAQZ;AAED,wBAAgB,cAAc,CAC5B,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EACtC,WAAW,EAAE,WAAW,EACxB,QAAQ,CAAC,EAAE,QAAQ,GAClB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,UAAU,CAAA;CAAE,GAAG,OAAO,CASpD;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,IAAI,MAAM,CAEvD;AAwBD,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EACtC,aAAa,EAAE,SAAS,MAAM,EAAE,EAChC,WAAW,EAAE,WAAW,GACvB,UAAU,CA4BZ"}
1
+ {"version":3,"file":"collection.d.ts","sourceRoot":"","sources":["../src/collection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,KAAK,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAErE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAEpD,OAAO,EAAsB,KAAK,KAAK,EAAE,MAAM,aAAa,CAAC;AAC7D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAG7C,eAAO,MAAM,QAAQ,EAAE,eAAwE,CAAC;AAEhG,MAAM,MAAM,UAAU,GAAG;IACvB,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACvC,WAAW,EAAE,WAAW,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS,CAAC;CAC9C,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,KAAK,EAAE,UAAU,CAAC;IAClB,SAAS,EAAE;QAAE,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;QAAC,KAAK,EAAE,UAAU,CAAA;KAAE,GAAG,IAAI,CAAC;CACnE,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG;IAAE,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC;IAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAAC;AAc3F,wBAAgB,UAAU,CAAC,WAAW,EAAE,WAAW,GAAG,QAAQ,CAS7D;AAED,wBAAgB,QAAQ,CAAC,WAAW,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAKxE;AAED,wBAAgB,SAAS,CAAC,WAAW,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,GAAG,UAAU,CAI5E;AAED,wBAAgB,YAAY,CAC1B,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EACtC,WAAW,EAAE,WAAW,GACvB,UAAU,CAcZ;AAED,wBAAiB,WAAW,CAC1B,UAAU,EAAE,UAAU,GACrB,SAAS,CAAC,MAAM,EAAE,QAAQ,CAAC,SAAS,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,EAAE,IAAI,CAAC,CAQhE;AAED,wBAAiB,UAAU,CACzB,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,EACnB,KAAK,GAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,IAAW,GACpC,SAAS,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,EAAE,IAAI,CAAC,CAazC;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,IAAI,MAAM,CAEvD;AAED,wBAAgB,SAAS,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,CAE3D"}
@@ -1,82 +1,84 @@
1
- import { parse, validate, VERSION, } from '@agentshouse/mdmodel';
1
+ import { parse, VERSION } from '@agentshouse/mdmodel';
2
2
  import { beneath, normalize } from './paths.js';
3
+ import { hashed } from './observation.js';
4
+ import { keysIn, sortedKeys } from './shared.js';
5
+ import { ROW_WEIGHT } from './turn.js';
3
6
  export const MD_MODEL = { identity: '@agentshouse/mdmodel', version: VERSION };
4
- const NO_TYPES = { types: {} };
5
- function selected(composition, path) {
7
+ const typesPrinted = new WeakMap();
8
+ function typesPrint(model) {
9
+ if (model.status === 'unavailable')
10
+ return '';
11
+ let print = typesPrinted.get(model.types);
12
+ if (print === undefined) {
13
+ print = hashed(JSON.stringify(model.types)).toString(36);
14
+ typesPrinted.set(model.types, print);
15
+ }
16
+ return print;
17
+ }
18
+ export function composedOf(composition) {
19
+ const { model, selection } = composition;
20
+ return {
21
+ composition,
22
+ fingerprint: JSON.stringify([
23
+ typesPrint(model),
24
+ selection === null ? null : [selection.roots, typesPrint(selection.model)],
25
+ ]),
26
+ };
27
+ }
28
+ export function selected(composition, path) {
6
29
  return (composition.selection !== null &&
7
30
  composition.selection.roots.some((root) => beneath(root, path)));
8
31
  }
9
- export function untyped(roots, path) {
10
- return roots.some((root) => beneath(root, path));
11
- }
12
32
  export function governing(composition, path) {
13
33
  return composition.selection !== null && selected(composition, path)
14
34
  ? composition.selection.model
15
35
  : composition.model;
16
36
  }
17
- function parsedAt(text, path, previous) {
18
- const retained = previous?.collection.documents[path];
19
- return retained !== undefined && previous?.text[path] === text[path]
20
- ? { ok: true, document: retained }
21
- : parse(text[path], path);
37
+ export function collectionOf(text, composition) {
38
+ const parsed = new Map();
39
+ return {
40
+ text,
41
+ composition,
42
+ document(path) {
43
+ if (parsed.has(path))
44
+ return parsed.get(path) ?? undefined;
45
+ const content = text[path];
46
+ if (content === undefined)
47
+ return undefined;
48
+ const read = parse(content, path);
49
+ parsed.set(path, read.ok ? read.document : null);
50
+ return read.ok ? read.document : undefined;
51
+ },
52
+ };
22
53
  }
23
- export function parseCollection(text, composition, previous) {
24
- const documents = {};
25
- for (const path of Object.keys(text).sort()) {
26
- if (untyped(composition.untypedFolders, path))
27
- continue;
28
- const parsed = parsedAt(text, path, previous);
29
- if (parsed.ok)
30
- documents[path] = parsed.document;
31
- }
32
- return { documents, composition };
54
+ export function* documentsOf(collection) {
55
+ const paths = yield* sortedKeys(collection.text);
56
+ return (function* () {
57
+ for (const path of paths) {
58
+ const document = collection.document(path);
59
+ if (document !== undefined)
60
+ yield [path, document];
61
+ }
62
+ })();
33
63
  }
34
- export function readCollection(text, composition, previous) {
35
- const documents = {};
36
- for (const path of Object.keys(text).sort()) {
37
- if (untyped(composition.untypedFolders, path))
64
+ export function* unreadable(text, paths = null) {
65
+ const named = paths ?? (yield* keysIn(text));
66
+ let least = null;
67
+ for (const path of named) {
68
+ const content = Object.hasOwn(text, path) ? text[path] : undefined;
69
+ if (content === undefined)
38
70
  continue;
39
- const parsed = parsedAt(text, path, previous);
40
- if (!parsed.ok)
41
- return { kind: 'refused', refusal: parsed.refusal };
42
- documents[path] = parsed.document;
71
+ const read = parse(content, path);
72
+ if (!read.ok && (least === null || path < least.path)) {
73
+ least = { path, refused: { kind: 'refused', refusal: read.refusal } };
74
+ }
75
+ yield ROW_WEIGHT + content.length;
43
76
  }
44
- return { kind: 'read', collection: { documents, composition } };
77
+ return least?.refused ?? null;
45
78
  }
46
79
  export function validRoot(root) {
47
80
  return typeof root === 'string' && normalize(root) === root;
48
81
  }
49
- function validateAgainst(documents, binaryTargets, model) {
50
- if (model.status === 'unavailable') {
51
- const typed = Object.entries(documents).find(([, content]) => {
52
- const parsed = parse(content);
53
- return parsed.ok && parsed.document.type !== undefined && parsed.document.type !== 'any';
54
- });
55
- if (typed !== undefined)
56
- return { verdict: 'refuse', rule: 'model-unavailable', file: typed[0] };
57
- }
58
- return validate(documents, { binaryTargets }, model.status === 'unavailable' ? NO_TYPES : { types: model.types });
59
- }
60
- export function validateCollection(text, binaryTargets, composition) {
61
- const collection = {};
62
- const selection = {};
63
- for (const [path, content] of Object.entries(text)) {
64
- if (untyped(composition.untypedFolders, path))
65
- continue;
66
- if (selected(composition, path))
67
- selection[path] = content;
68
- else
69
- collection[path] = content;
70
- }
71
- const linked = binaryTargets.filter((path) => !untyped(composition.untypedFolders, path));
72
- const verdicts = [
73
- validateAgainst(collection, linked.filter((path) => !selected(composition, path)), composition.model),
74
- ];
75
- if (composition.selection !== null) {
76
- verdicts.push(validateAgainst(selection, linked.filter((path) => selected(composition, path)), composition.selection.model));
77
- }
78
- const refusals = verdicts.filter((verdict) => verdict.verdict === 'refuse');
79
- if (refusals.length === 0)
80
- return verdicts[0];
81
- return refusals.find((refusal) => refusal.rule !== 'model-unavailable') ?? refusals[0];
82
+ export function available(composition) {
83
+ return composition.model.status !== 'unavailable';
82
84
  }
@@ -0,0 +1,16 @@
1
+ import type { Plan, QueryRows } from './query.js';
2
+ import type { Connection, Value } from './tables.js';
3
+ export type QueryRoom = {
4
+ readonly locator: string;
5
+ readonly key: number;
6
+ };
7
+ export type Fragment = {
8
+ readonly sql: string;
9
+ readonly bind: readonly Value[];
10
+ };
11
+ export type QueryAnswer = QueryRows & {
12
+ readonly more?: string;
13
+ };
14
+ export declare function selected(connection: Connection, plan: Plan, rooms: readonly QueryRoom[]): Fragment;
15
+ export declare function answerQuery(connection: Connection, plan: Plan, rooms: readonly QueryRoom[], budget?: number | null): QueryAnswer;
16
+ //# sourceMappingURL=compile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compile.d.ts","sourceRoot":"","sources":["../src/compile.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAOV,IAAI,EAGJ,SAAS,EAIV,MAAM,YAAY,CAAC;AAEpB,OAAO,KAAK,EAAE,UAAU,EAAO,KAAK,EAAE,MAAM,aAAa,CAAC;AAU1D,MAAM,MAAM,SAAS,GAAG;IAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC;AAE3E,MAAM,MAAM,QAAQ,GAAG;IAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,SAAS,KAAK,EAAE,CAAA;CAAE,CAAC;AAwrBjF,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG;IAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AA4TjE,wBAAgB,QAAQ,CACtB,UAAU,EAAE,UAAU,EACtB,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,SAAS,SAAS,EAAE,GAC1B,QAAQ,CAEV;AAED,wBAAgB,WAAW,CACzB,UAAU,EAAE,UAAU,EACtB,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,SAAS,SAAS,EAAE,EAC3B,MAAM,GAAE,MAAM,GAAG,IAAW,GAC3B,WAAW,CAUb"}