@agentshouse/mdruntime 0.1.0-alpha.5 → 0.1.0-alpha.50

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 (129) hide show
  1. package/AGENTS.md +210 -0
  2. package/README.md +44 -0
  3. package/dist/adapter.d.ts +253 -19
  4. package/dist/adapter.d.ts.map +1 -1
  5. package/dist/adapter.js +2 -1
  6. package/dist/adapter.js.map +1 -1
  7. package/dist/attachment.d.ts +3 -0
  8. package/dist/attachment.d.ts.map +1 -0
  9. package/dist/attachment.js +11 -0
  10. package/dist/attachment.js.map +1 -0
  11. package/dist/bootstrap.d.ts +7 -6
  12. package/dist/bootstrap.d.ts.map +1 -1
  13. package/dist/bootstrap.js +30 -10
  14. package/dist/bootstrap.js.map +1 -1
  15. package/dist/change-set.d.ts +33 -0
  16. package/dist/change-set.d.ts.map +1 -0
  17. package/dist/change-set.js +95 -0
  18. package/dist/change-set.js.map +1 -0
  19. package/dist/change.d.ts +10 -0
  20. package/dist/change.d.ts.map +1 -1
  21. package/dist/change.js.map +1 -1
  22. package/dist/client.d.ts +75 -0
  23. package/dist/client.d.ts.map +1 -0
  24. package/dist/client.js +237 -0
  25. package/dist/client.js.map +1 -0
  26. package/dist/collection.d.ts +26 -12
  27. package/dist/collection.d.ts.map +1 -1
  28. package/dist/collection.js +78 -31
  29. package/dist/collection.js.map +1 -1
  30. package/dist/connection.d.ts +85 -28
  31. package/dist/connection.d.ts.map +1 -1
  32. package/dist/connection.js +1756 -510
  33. package/dist/connection.js.map +1 -1
  34. package/dist/conversation.d.ts +79 -0
  35. package/dist/conversation.d.ts.map +1 -0
  36. package/dist/conversation.js +635 -0
  37. package/dist/conversation.js.map +1 -0
  38. package/dist/durability.d.ts +8 -3
  39. package/dist/durability.d.ts.map +1 -1
  40. package/dist/durability.js +8 -62
  41. package/dist/durability.js.map +1 -1
  42. package/dist/file.d.ts +20 -0
  43. package/dist/file.d.ts.map +1 -0
  44. package/dist/file.js +149 -0
  45. package/dist/file.js.map +1 -0
  46. package/dist/host.d.ts +14 -0
  47. package/dist/host.d.ts.map +1 -0
  48. package/dist/host.js +213 -0
  49. package/dist/host.js.map +1 -0
  50. package/dist/identity.d.ts +3 -0
  51. package/dist/identity.d.ts.map +1 -0
  52. package/dist/identity.js +23 -0
  53. package/dist/identity.js.map +1 -0
  54. package/dist/index.d.ts +15 -7
  55. package/dist/index.d.ts.map +1 -1
  56. package/dist/index.js +1 -0
  57. package/dist/index.js.map +1 -1
  58. package/dist/memory.d.ts +19 -2
  59. package/dist/memory.d.ts.map +1 -1
  60. package/dist/memory.js +283 -24
  61. package/dist/memory.js.map +1 -1
  62. package/dist/model.d.ts +55 -0
  63. package/dist/model.d.ts.map +1 -0
  64. package/dist/model.js +36 -0
  65. package/dist/model.js.map +1 -0
  66. package/dist/observation.d.ts +25 -0
  67. package/dist/observation.d.ts.map +1 -0
  68. package/dist/observation.js +92 -0
  69. package/dist/observation.js.map +1 -0
  70. package/dist/outcome.d.ts +22 -18
  71. package/dist/outcome.d.ts.map +1 -1
  72. package/dist/outcome.js +1 -11
  73. package/dist/outcome.js.map +1 -1
  74. package/dist/overlay.d.ts +9 -2
  75. package/dist/overlay.d.ts.map +1 -1
  76. package/dist/overlay.js +145 -6
  77. package/dist/overlay.js.map +1 -1
  78. package/dist/paths.d.ts +0 -1
  79. package/dist/paths.d.ts.map +1 -1
  80. package/dist/paths.js +0 -4
  81. package/dist/paths.js.map +1 -1
  82. package/dist/query.d.ts +213 -0
  83. package/dist/query.d.ts.map +1 -0
  84. package/dist/query.js +470 -0
  85. package/dist/query.js.map +1 -0
  86. package/dist/read-side.d.ts +14 -0
  87. package/dist/read-side.d.ts.map +1 -0
  88. package/dist/read-side.js +457 -0
  89. package/dist/read-side.js.map +1 -0
  90. package/dist/refresh.d.ts +4 -4
  91. package/dist/refresh.d.ts.map +1 -1
  92. package/dist/refresh.js +40 -10
  93. package/dist/refresh.js.map +1 -1
  94. package/dist/replica.d.ts +27 -4
  95. package/dist/replica.d.ts.map +1 -1
  96. package/dist/replica.js +255 -13
  97. package/dist/replica.js.map +1 -1
  98. package/dist/room-draft.d.ts +124 -0
  99. package/dist/room-draft.d.ts.map +1 -0
  100. package/dist/room-draft.js +406 -0
  101. package/dist/room-draft.js.map +1 -0
  102. package/dist/rows.d.ts +41 -0
  103. package/dist/rows.d.ts.map +1 -0
  104. package/dist/rows.js +102 -0
  105. package/dist/rows.js.map +1 -0
  106. package/dist/save.d.ts +11 -2
  107. package/dist/save.d.ts.map +1 -1
  108. package/dist/save.js +116 -128
  109. package/dist/save.js.map +1 -1
  110. package/dist/search.d.ts +61 -0
  111. package/dist/search.d.ts.map +1 -0
  112. package/dist/search.js +155 -0
  113. package/dist/search.js.map +1 -0
  114. package/dist/status.d.ts +9 -2
  115. package/dist/status.d.ts.map +1 -1
  116. package/dist/status.js +5 -4
  117. package/dist/status.js.map +1 -1
  118. package/dist/store.d.ts +90 -18
  119. package/dist/store.d.ts.map +1 -1
  120. package/dist/store.js +492 -67
  121. package/dist/store.js.map +1 -1
  122. package/dist/transfer.d.ts +5 -0
  123. package/dist/transfer.d.ts.map +1 -1
  124. package/dist/transfer.js.map +1 -1
  125. package/dist/wire.d.ts +64 -0
  126. package/dist/wire.d.ts.map +1 -0
  127. package/dist/wire.js +145 -0
  128. package/dist/wire.js.map +1 -0
  129. package/package.json +15 -13
package/dist/client.js ADDED
@@ -0,0 +1,237 @@
1
+ import { observed } from './observation.js';
2
+ import { answer, AUTHORIZATION_ENDED, carried, envelope, PORT_CLOSED, PROTOCOL_MISMATCH } from './wire.js';
3
+ export function connectMdRuntime(port) {
4
+ let sequence = 0;
5
+ let refusal = null;
6
+ let ended = null;
7
+ const calls = new Map();
8
+ const opening = new Map();
9
+ const observations = new Map();
10
+ const send = (message)=>{
11
+ port.postMessage(envelope(message));
12
+ };
13
+ function begin(id, topic, first) {
14
+ const handle = observed(first, ()=>{
15
+ observations.delete(id);
16
+ if (refusal === null) send({
17
+ kind: 'stop',
18
+ id
19
+ });
20
+ }, topic === 'query');
21
+ observations.set(id, {
22
+ topic,
23
+ handle
24
+ });
25
+ return handle.observation;
26
+ }
27
+ function refuse(reported) {
28
+ refusal = reported;
29
+ for (const { topic, handle } of observations.values()){
30
+ if (topic === 'connection-refusal') handle.receive(reported);
31
+ }
32
+ const failure = new Error(reported.reason);
33
+ for (const [id, waiting] of opening){
34
+ if (waiting.topic === 'connection-refusal') waiting.settle(begin(id, waiting.topic, reported));
35
+ else waiting.fail(failure);
36
+ }
37
+ opening.clear();
38
+ for (const waiting of calls.values())waiting.fail(failure);
39
+ calls.clear();
40
+ }
41
+ function end(reason) {
42
+ if (ended !== null) return;
43
+ ended = reason;
44
+ const failure = new Error(reason);
45
+ for (const waiting of opening.values())waiting.fail(failure);
46
+ opening.clear();
47
+ for (const waiting of calls.values())waiting.fail(failure);
48
+ calls.clear();
49
+ for (const { handle } of observations.values())handle.end();
50
+ observations.clear();
51
+ }
52
+ port.addEventListener('message', (event)=>{
53
+ const wire = carried(event.data);
54
+ if (wire === null) return;
55
+ if (!wire.matching) {
56
+ refuse(PROTOCOL_MISMATCH);
57
+ return;
58
+ }
59
+ const message = answer(wire.message);
60
+ if (message === null) return;
61
+ if (message.kind === 'refusal') {
62
+ refuse(message.refusal);
63
+ return;
64
+ }
65
+ if (message.kind === 'ended') {
66
+ end(AUTHORIZATION_ENDED);
67
+ return;
68
+ }
69
+ if (message.kind === 'event') {
70
+ observations.get(message.id)?.handle.receive(message.value);
71
+ return;
72
+ }
73
+ const waiting = opening.get(message.id);
74
+ if (waiting !== undefined) {
75
+ opening.delete(message.id);
76
+ if (message.kind === 'failure') waiting.fail(new Error(message.message));
77
+ else waiting.settle(begin(message.id, waiting.topic, message.value));
78
+ return;
79
+ }
80
+ const called = calls.get(message.id);
81
+ if (called === undefined) return;
82
+ calls.delete(message.id);
83
+ if (message.kind === 'failure') called.fail(new Error(message.message));
84
+ else called.settle(message.value);
85
+ });
86
+ port.addEventListener('close', ()=>{
87
+ end(PORT_CLOSED);
88
+ });
89
+ port.start();
90
+ send({
91
+ kind: 'hello'
92
+ });
93
+ function ask(member, input) {
94
+ if (ended !== null) return Promise.reject(new Error(ended));
95
+ if (refusal !== null) return Promise.reject(new Error(refusal.reason));
96
+ const id = sequence += 1;
97
+ return new Promise((settle, fail)=>{
98
+ calls.set(id, {
99
+ settle: settle,
100
+ fail
101
+ });
102
+ send({
103
+ kind: 'call',
104
+ id,
105
+ member,
106
+ input
107
+ });
108
+ });
109
+ }
110
+ function watch(topic, input) {
111
+ if (ended !== null) return Promise.reject(new Error(ended));
112
+ const id = sequence += 1;
113
+ if (refusal !== null) {
114
+ return topic === 'connection-refusal' ? Promise.resolve(begin(id, topic, refusal)) : Promise.reject(new Error(refusal.reason));
115
+ }
116
+ return new Promise((settle, fail)=>{
117
+ opening.set(id, {
118
+ topic,
119
+ settle,
120
+ fail
121
+ });
122
+ send({
123
+ kind: 'observe',
124
+ id,
125
+ topic,
126
+ input
127
+ });
128
+ });
129
+ }
130
+ return {
131
+ rooms: ()=>ask('rooms', []),
132
+ slots: ()=>ask('slots', []),
133
+ query: (query)=>ask('query', [
134
+ query
135
+ ]),
136
+ search: (request)=>ask('search', [
137
+ request
138
+ ]),
139
+ types: (locator)=>ask('types', [
140
+ locator
141
+ ]),
142
+ syncStatus: ()=>ask('syncStatus', []),
143
+ serviceMode: ()=>ask('serviceMode', []),
144
+ roomDraft: {
145
+ list: ()=>ask('roomDraft.list', []),
146
+ read: (room, path)=>ask('roomDraft.read', [
147
+ room,
148
+ path
149
+ ]),
150
+ write: (room, path, revision, parts)=>ask('roomDraft.write', [
151
+ room,
152
+ path,
153
+ revision,
154
+ parts
155
+ ]),
156
+ discard: (room, path, revision)=>ask('roomDraft.discard', [
157
+ room,
158
+ path,
159
+ revision
160
+ ])
161
+ },
162
+ save: (room, roomDrafts)=>ask('save', [
163
+ room,
164
+ roomDrafts
165
+ ]),
166
+ outcome: (identifier)=>ask('outcome', [
167
+ identifier
168
+ ]),
169
+ presentation: {
170
+ read: ()=>ask('presentation.read', []),
171
+ write: (value)=>ask('presentation.write', [
172
+ value
173
+ ])
174
+ },
175
+ conversation: {
176
+ list: ()=>ask('conversation.list', []),
177
+ read: (conversation, options)=>ask('conversation.read', [
178
+ conversation,
179
+ options
180
+ ]),
181
+ create: (input)=>ask('conversation.create', [
182
+ input
183
+ ]),
184
+ send: (conversation)=>ask('conversation.send', [
185
+ conversation
186
+ ]),
187
+ answer: (conversation, answer)=>ask('conversation.answer', [
188
+ conversation,
189
+ answer
190
+ ]),
191
+ interrupt: (conversation)=>ask('conversation.interrupt', [
192
+ conversation
193
+ ]),
194
+ kill: (conversation)=>ask('conversation.kill', [
195
+ conversation
196
+ ]),
197
+ cancel: (conversation, turn)=>ask('conversation.cancel', [
198
+ conversation,
199
+ turn
200
+ ]),
201
+ delete: (conversation)=>ask('conversation.delete', [
202
+ conversation
203
+ ])
204
+ },
205
+ chatDraft: {
206
+ write: (conversation, draft)=>ask('chatDraft.write', [
207
+ conversation,
208
+ draft
209
+ ]),
210
+ discard: (conversation)=>ask('chatDraft.discard', [
211
+ conversation
212
+ ])
213
+ },
214
+ history: (locator, path, query)=>ask('history', [
215
+ locator,
216
+ path,
217
+ query
218
+ ]),
219
+ call: (name, input)=>ask('call', [
220
+ name,
221
+ input
222
+ ]),
223
+ reached: (locator, roomVersion, path)=>ask('reached', [
224
+ locator,
225
+ roomVersion,
226
+ path
227
+ ]),
228
+ log: ()=>ask('log', []),
229
+ storageLoss: ()=>ask('storageLoss', []),
230
+ persistence: ()=>ask('persistence', []),
231
+ deploymentFacts: ()=>ask('deploymentFacts', []),
232
+ observe: (topic, ...input)=>watch(topic, input),
233
+ reauthorize: ()=>ask('reauthorize', [])
234
+ };
235
+ }
236
+
237
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/workspace/packages/mdruntime/src/client.ts"],"sourcesContent":["import type {\n AppRoom,\n AppSlot,\n ConnectionRefusal,\n HistoryQuery,\n RoomTypes,\n SavedRoomDraft,\n SaveResult,\n} from './connection.js';\nimport type { HistoryResult, ServiceMode } from './adapter.js';\nimport type {\n ChatDraft,\n ConversationEntry,\n ConversationOptions,\n ConversationView,\n} from './conversation.js';\nimport { observed, type Observation, type Observed } from './observation.js';\nimport type { CallResult, QueueEntry, SubmissionOutcome } from './outcome.js';\nimport type { DocumentQuery, DocumentResult, GroupQuery, GroupResult } from './query.js';\nimport type { RoomDraft, RoomDraftParts, RoomDraftWrite } from './room-draft.js';\nimport type { SearchRequest, SearchResult } from './search.js';\nimport type { SyncStatus } from './status.js';\nimport {\n answer,\n AUTHORIZATION_ENDED,\n carried,\n envelope,\n PORT_CLOSED,\n PROTOCOL_MISMATCH,\n type RuntimePort,\n type WireMember,\n type WireRequest,\n type WireTopic,\n} from './wire.js';\n\nexport type MdRuntimeClient = {\n rooms(): Promise<readonly AppRoom[]>;\n slots(): Promise<readonly AppSlot[]>;\n query: {\n (query: DocumentQuery): Promise<DocumentResult>;\n (query: GroupQuery): Promise<GroupResult>;\n };\n search(request: SearchRequest): Promise<SearchResult>;\n types(locator: string): Promise<RoomTypes>;\n syncStatus(): Promise<SyncStatus>;\n serviceMode(): Promise<ServiceMode>;\n roomDraft: {\n list(): Promise<readonly RoomDraft[]>;\n read(room: string, path: string): Promise<RoomDraft | null>;\n write(\n room: string,\n path: string,\n revision: string | null,\n parts: RoomDraftParts,\n ): Promise<RoomDraftWrite>;\n discard(room: string, path: string, revision: string): Promise<RoomDraftWrite>;\n };\n save(room: string, roomDrafts: readonly SavedRoomDraft[]): Promise<SaveResult>;\n outcome(identifier: string): Promise<SubmissionOutcome | null>;\n presentation: {\n read(): Promise<unknown>;\n write(value: unknown): Promise<void>;\n };\n conversation: {\n list(): Promise<readonly ConversationEntry[]>;\n read(conversation: string, options?: ConversationOptions): Promise<ConversationView>;\n create(input: unknown): Promise<CallResult>;\n send(conversation: string): Promise<CallResult>;\n answer(conversation: string, answer: unknown): Promise<CallResult>;\n interrupt(conversation: string): Promise<CallResult>;\n kill(conversation: string): Promise<CallResult>;\n cancel(conversation: string, turn: string): Promise<CallResult>;\n delete(conversation: string): Promise<CallResult>;\n };\n chatDraft: {\n write(conversation: string, draft: ChatDraft): Promise<void>;\n discard(conversation: string): Promise<void>;\n };\n history(locator: string, path: string, query?: HistoryQuery): Promise<HistoryResult>;\n call(name: string, input: unknown): Promise<CallResult>;\n reached(locator: string, roomVersion: string, path?: string): Promise<boolean>;\n log(): Promise<string>;\n storageLoss(): Promise<string | null>;\n persistence(): Promise<boolean>;\n deploymentFacts(): Promise<unknown>;\n observe: {\n (topic: 'deployment-facts'): Promise<Observation<unknown>>;\n (topic: 'rooms'): Promise<Observation<readonly AppRoom[]>>;\n (topic: 'connection-refusal'): Promise<Observation<ConnectionRefusal | null>>;\n (topic: 'storage-loss'): Promise<Observation<string | null>>;\n (topic: 'sync-status'): Promise<Observation<SyncStatus>>;\n (topic: 'service-mode'): Promise<Observation<ServiceMode>>;\n (topic: 'query', query: DocumentQuery): Promise<Observation<DocumentResult>>;\n (topic: 'query', query: GroupQuery): Promise<Observation<GroupResult>>;\n (topic: 'queue', locator: string): Promise<Observation<readonly QueueEntry[]>>;\n (topic: 'room-drafts'): Promise<Observation<readonly RoomDraft[]>>;\n (topic: 'presentation'): Promise<Observation<unknown>>;\n (\n topic: 'conversation',\n conversation: string,\n options: ConversationOptions,\n ): Promise<Observation<ConversationView>>;\n };\n reauthorize(): Promise<void>;\n};\n\nexport function connectMdRuntime(port: RuntimePort): MdRuntimeClient {\n let sequence = 0;\n let refusal: ConnectionRefusal | null = null;\n let ended: string | null = null;\n const calls = new Map<\n number,\n { settle: (value: unknown) => void; fail: (error: Error) => void }\n >();\n const opening = new Map<\n number,\n {\n topic: WireTopic;\n settle: (observation: Observation<unknown>) => void;\n fail: (error: Error) => void;\n }\n >();\n const observations = new Map<number, { topic: WireTopic; handle: Observed }>();\n\n const send = (message: WireRequest) => {\n port.postMessage(envelope(message));\n };\n\n function begin(id: number, topic: WireTopic, first: unknown): Observation<unknown> {\n const handle = observed(\n first,\n () => {\n observations.delete(id);\n if (refusal === null) send({ kind: 'stop', id });\n },\n topic === 'query',\n );\n observations.set(id, { topic, handle });\n return handle.observation;\n }\n\n function refuse(reported: ConnectionRefusal) {\n refusal = reported;\n for (const { topic, handle } of observations.values()) {\n if (topic === 'connection-refusal') handle.receive(reported);\n }\n const failure = new Error(reported.reason);\n for (const [id, waiting] of opening) {\n if (waiting.topic === 'connection-refusal')\n waiting.settle(begin(id, waiting.topic, reported));\n else waiting.fail(failure);\n }\n opening.clear();\n for (const waiting of calls.values()) waiting.fail(failure);\n calls.clear();\n }\n\n function end(reason: string) {\n if (ended !== null) return;\n ended = reason;\n const failure = new Error(reason);\n for (const waiting of opening.values()) waiting.fail(failure);\n opening.clear();\n for (const waiting of calls.values()) waiting.fail(failure);\n calls.clear();\n for (const { handle } of observations.values()) handle.end();\n observations.clear();\n }\n\n port.addEventListener('message', (event) => {\n const wire = carried(event.data);\n if (wire === null) return;\n if (!wire.matching) {\n refuse(PROTOCOL_MISMATCH);\n return;\n }\n const message = answer(wire.message);\n if (message === null) return;\n if (message.kind === 'refusal') {\n refuse(message.refusal);\n return;\n }\n if (message.kind === 'ended') {\n end(AUTHORIZATION_ENDED);\n return;\n }\n if (message.kind === 'event') {\n observations.get(message.id)?.handle.receive(message.value);\n return;\n }\n const waiting = opening.get(message.id);\n if (waiting !== undefined) {\n opening.delete(message.id);\n if (message.kind === 'failure') waiting.fail(new Error(message.message));\n else waiting.settle(begin(message.id, waiting.topic, message.value));\n return;\n }\n const called = calls.get(message.id);\n if (called === undefined) return;\n calls.delete(message.id);\n if (message.kind === 'failure') called.fail(new Error(message.message));\n else called.settle(message.value);\n });\n port.addEventListener('close', () => {\n end(PORT_CLOSED);\n });\n port.start();\n send({ kind: 'hello' });\n\n function ask<T>(member: WireMember, input: readonly unknown[]): Promise<T> {\n if (ended !== null) return Promise.reject(new Error(ended));\n if (refusal !== null) return Promise.reject(new Error(refusal.reason));\n const id = (sequence += 1);\n return new Promise<T>((settle, fail) => {\n calls.set(id, { settle: settle as (value: unknown) => void, fail });\n send({ kind: 'call', id, member, input });\n });\n }\n\n function watch(topic: WireTopic, input: readonly unknown[]): Promise<Observation<unknown>> {\n if (ended !== null) return Promise.reject(new Error(ended));\n const id = (sequence += 1);\n if (refusal !== null) {\n return topic === 'connection-refusal'\n ? Promise.resolve(begin(id, topic, refusal))\n : Promise.reject(new Error(refusal.reason));\n }\n return new Promise((settle, fail) => {\n opening.set(id, { topic, settle, fail });\n send({ kind: 'observe', id, topic, input });\n });\n }\n\n return {\n rooms: () => ask<readonly AppRoom[]>('rooms', []),\n slots: () => ask<readonly AppSlot[]>('slots', []),\n query: ((query: DocumentQuery | GroupQuery) =>\n ask('query', [query])) as MdRuntimeClient['query'],\n search: (request: SearchRequest) => ask<SearchResult>('search', [request]),\n types: (locator: string) => ask<RoomTypes>('types', [locator]),\n syncStatus: () => ask<SyncStatus>('syncStatus', []),\n serviceMode: () => ask<ServiceMode>('serviceMode', []),\n roomDraft: {\n list: () => ask<readonly RoomDraft[]>('roomDraft.list', []),\n read: (room: string, path: string) => ask<RoomDraft | null>('roomDraft.read', [room, path]),\n write: (room: string, path: string, revision: string | null, parts: RoomDraftParts) =>\n ask<RoomDraftWrite>('roomDraft.write', [room, path, revision, parts]),\n discard: (room: string, path: string, revision: string) =>\n ask<RoomDraftWrite>('roomDraft.discard', [room, path, revision]),\n },\n save: (room: string, roomDrafts: readonly SavedRoomDraft[]) =>\n ask<SaveResult>('save', [room, roomDrafts]),\n outcome: (identifier: string) => ask<SubmissionOutcome | null>('outcome', [identifier]),\n presentation: {\n read: () => ask<unknown>('presentation.read', []),\n write: (value: unknown) => ask<void>('presentation.write', [value]),\n },\n conversation: {\n list: () => ask<readonly ConversationEntry[]>('conversation.list', []),\n read: (conversation: string, options?: ConversationOptions) =>\n ask<ConversationView>('conversation.read', [conversation, options]),\n create: (input: unknown) => ask<CallResult>('conversation.create', [input]),\n send: (conversation: string) => ask<CallResult>('conversation.send', [conversation]),\n answer: (conversation: string, answer: unknown) =>\n ask<CallResult>('conversation.answer', [conversation, answer]),\n interrupt: (conversation: string) =>\n ask<CallResult>('conversation.interrupt', [conversation]),\n kill: (conversation: string) => ask<CallResult>('conversation.kill', [conversation]),\n cancel: (conversation: string, turn: string) =>\n ask<CallResult>('conversation.cancel', [conversation, turn]),\n delete: (conversation: string) => ask<CallResult>('conversation.delete', [conversation]),\n },\n chatDraft: {\n write: (conversation: string, draft: ChatDraft) =>\n ask<void>('chatDraft.write', [conversation, draft]),\n discard: (conversation: string) => ask<void>('chatDraft.discard', [conversation]),\n },\n history: (locator: string, path: string, query?: HistoryQuery) =>\n ask<HistoryResult>('history', [locator, path, query]),\n call: (name: string, input: unknown) => ask<CallResult>('call', [name, input]),\n reached: (locator: string, roomVersion: string, path?: string) =>\n ask<boolean>('reached', [locator, roomVersion, path]),\n log: () => ask<string>('log', []),\n storageLoss: () => ask<string | null>('storageLoss', []),\n persistence: () => ask<boolean>('persistence', []),\n deploymentFacts: () => ask<unknown>('deploymentFacts', []),\n observe: ((topic: WireTopic, ...input: unknown[]) =>\n watch(topic, input)) as MdRuntimeClient['observe'],\n reauthorize: () => ask<void>('reauthorize', []),\n };\n}\n\nexport type { Observation } from './observation.js';\nexport type { RuntimePort } from './wire.js';\n"],"names":["observed","answer","AUTHORIZATION_ENDED","carried","envelope","PORT_CLOSED","PROTOCOL_MISMATCH","connectMdRuntime","port","sequence","refusal","ended","calls","Map","opening","observations","send","message","postMessage","begin","id","topic","first","handle","delete","kind","set","observation","refuse","reported","values","receive","failure","Error","reason","waiting","settle","fail","clear","end","addEventListener","event","wire","data","matching","get","value","undefined","called","start","ask","member","input","Promise","reject","watch","resolve","rooms","slots","query","search","request","types","locator","syncStatus","serviceMode","roomDraft","list","read","room","path","write","revision","parts","discard","save","roomDrafts","outcome","identifier","presentation","conversation","options","create","interrupt","kill","cancel","turn","chatDraft","draft","history","call","name","reached","roomVersion","log","storageLoss","persistence","deploymentFacts","observe","reauthorize"],"mappings":"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"}
@@ -1,18 +1,32 @@
1
- import { type Document } from '@agentshouse/mdmodel';
2
- import type { Selector } from '@agentshouse/query';
1
+ import { type Document, type Validation } from '@agentshouse/mdmodel';
2
+ import type { ModelState } from './model.js';
3
3
  import type { MdModelIdentity } from './adapter.js';
4
+ import type { Refused } from './transfer.js';
4
5
  export declare const MD_MODEL: MdModelIdentity;
5
- export declare const PRESENTED: Selector;
6
- export type MdType = {
7
- name: string;
8
- path: string;
9
- fields: Readonly<Record<string, unknown>>;
10
- sections: Readonly<Record<string, unknown>>;
11
- };
12
6
  export type Collection = {
13
7
  documents: Readonly<Record<string, Document>>;
14
- types: readonly MdType[];
8
+ composition: Composition;
9
+ };
10
+ export type Composition = {
11
+ model: ModelState;
12
+ selection: {
13
+ roots: readonly string[];
14
+ model: ModelState;
15
+ } | null;
16
+ untypedFolders: readonly string[];
17
+ };
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;
15
23
  };
16
- export declare function parseCollection(text: Readonly<Record<string, string>>): Collection;
17
- export declare function readCollection(text: Readonly<Record<string, string>>, binaryTargets: readonly string[]): Collection | null;
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;
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 {};
18
32
  //# sourceMappingURL=collection.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"collection.d.ts","sourceRoot":"","sources":["../src/collection.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,KAAK,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAC/E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAKpD,eAAO,MAAM,QAAQ,EAAE,eAAwE,CAAC;AAEhG,eAAO,MAAM,SAAS,EAAE,QAAyC,CAAC;AAElE,MAAM,MAAM,MAAM,GAAG;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAC1C,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CAC7C,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;IAC9C,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;CAC1B,CAAC;AAmBF,wBAAgB,eAAe,CAAC,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,UAAU,CAYlF;AAED,wBAAgB,cAAc,CAC5B,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EACtC,aAAa,EAAE,SAAS,MAAM,EAAE,GAC/B,UAAU,GAAG,IAAI,CAKnB"}
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,52 +1,99 @@
1
1
  import { parse, validate, VERSION } from '@agentshouse/mdmodel';
2
- const MARKDOWN = '.md';
3
- const DEFINITION = 'definition';
2
+ import { beneath, normalize } from './paths.js';
4
3
  export const MD_MODEL = {
5
4
  identity: '@agentshouse/mdmodel',
6
5
  version: VERSION
7
6
  };
8
- export const PRESENTED = {
9
- path: {
10
- $regex: '\\.md$'
11
- }
7
+ const NO_TYPES = {
8
+ types: {}
12
9
  };
13
- function isMarkdown(path) {
14
- return path.endsWith(MARKDOWN);
10
+ function selected(composition, path) {
11
+ return composition.selection !== null && composition.selection.roots.some((root)=>beneath(root, path));
15
12
  }
16
- function declaredIn(document, part) {
17
- return document.fields[part] ?? {};
13
+ export function untyped(roots, path) {
14
+ return roots.some((root)=>beneath(root, path));
18
15
  }
19
- function mdType(path, document) {
20
- return {
21
- name: path.slice(path.lastIndexOf('/') + 1, -MARKDOWN.length),
22
- path,
23
- fields: declaredIn(document, 'fields'),
24
- sections: declaredIn(document, 'sections')
25
- };
16
+ export function governing(composition, path) {
17
+ return composition.selection !== null && selected(composition, path) ? composition.selection.model : composition.model;
18
+ }
19
+ function parsedAt(text, path, previous) {
20
+ const retained = previous?.collection.documents[path];
21
+ return retained !== undefined && previous?.text[path] === text[path] ? {
22
+ ok: true,
23
+ document: retained
24
+ } : parse(text[path], path);
26
25
  }
27
- export function parseCollection(text) {
26
+ export function parseCollection(text, composition, previous) {
28
27
  const documents = {};
29
28
  for (const path of Object.keys(text).sort()){
30
- const parsed = parse(text[path], path);
29
+ if (untyped(composition.untypedFolders, path)) continue;
30
+ const parsed = parsedAt(text, path, previous);
31
31
  if (parsed.ok) documents[path] = parsed.document;
32
32
  }
33
- const types = [];
34
- for (const [path, document] of Object.entries(documents)){
35
- if (!isMarkdown(path) || document.type !== DEFINITION) continue;
36
- types.push(mdType(path, document));
37
- }
38
33
  return {
39
34
  documents,
40
- types
35
+ composition
36
+ };
37
+ }
38
+ export function readCollection(text, composition, previous) {
39
+ const documents = {};
40
+ for (const path of Object.keys(text).sort()){
41
+ if (untyped(composition.untypedFolders, path)) continue;
42
+ const parsed = parsedAt(text, path, previous);
43
+ if (!parsed.ok) return {
44
+ kind: 'refused',
45
+ refusal: parsed.refusal
46
+ };
47
+ documents[path] = parsed.document;
48
+ }
49
+ return {
50
+ kind: 'read',
51
+ collection: {
52
+ documents,
53
+ composition
54
+ }
41
55
  };
42
56
  }
43
- export function readCollection(text, binaryTargets) {
44
- const collection = parseCollection(text);
45
- if (Object.keys(collection.documents).length !== Object.keys(text).length) return null;
46
- if (validate(text, {
57
+ export function validRoot(root) {
58
+ return typeof root === 'string' && normalize(root) === root;
59
+ }
60
+ function validateAgainst(documents, binaryTargets, model) {
61
+ if (model.status === 'unavailable') {
62
+ const typed = Object.entries(documents).find(([, content])=>{
63
+ const parsed = parse(content);
64
+ return parsed.ok && parsed.document.type !== undefined && parsed.document.type !== 'any';
65
+ });
66
+ if (typed !== undefined) return {
67
+ verdict: 'refuse',
68
+ rule: 'model-unavailable',
69
+ file: typed[0],
70
+ version: VERSION
71
+ };
72
+ }
73
+ return validate(documents, {
47
74
  binaryTargets
48
- }).verdict === 'refuse') return null;
49
- return collection;
75
+ }, model.status === 'unavailable' ? NO_TYPES : {
76
+ types: model.types
77
+ });
78
+ }
79
+ export function validateCollection(text, binaryTargets, composition) {
80
+ const collection = {};
81
+ const selection = {};
82
+ for (const [path, content] of Object.entries(text)){
83
+ if (untyped(composition.untypedFolders, path)) continue;
84
+ if (selected(composition, path)) selection[path] = content;
85
+ else collection[path] = content;
86
+ }
87
+ const linked = binaryTargets.filter((path)=>!untyped(composition.untypedFolders, path));
88
+ const verdicts = [
89
+ validateAgainst(collection, linked.filter((path)=>!selected(composition, path)), composition.model)
90
+ ];
91
+ if (composition.selection !== null) {
92
+ verdicts.push(validateAgainst(selection, linked.filter((path)=>selected(composition, path)), composition.selection.model));
93
+ }
94
+ const refusals = verdicts.filter((verdict)=>verdict.verdict === 'refuse');
95
+ if (refusals.length === 0) return verdicts[0];
96
+ return refusals.find((refusal)=>refusal.rule !== 'model-unavailable') ?? refusals[0];
50
97
  }
51
98
 
52
99
  //# sourceMappingURL=collection.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["/workspace/packages/mdruntime/src/collection.ts"],"sourcesContent":["import { parse, validate, VERSION, type Document } from '@agentshouse/mdmodel';\nimport type { Selector } from '@agentshouse/query';\nimport type { MdModelIdentity } from './adapter.js';\n\nconst MARKDOWN = '.md';\nconst DEFINITION = 'definition';\n\nexport const MD_MODEL: MdModelIdentity = { identity: '@agentshouse/mdmodel', version: VERSION };\n\nexport const PRESENTED: Selector = { path: { $regex: '\\\\.md$' } };\n\nexport type MdType = {\n name: string;\n path: string;\n fields: Readonly<Record<string, unknown>>;\n sections: Readonly<Record<string, unknown>>;\n};\n\nexport type Collection = {\n documents: Readonly<Record<string, Document>>;\n types: readonly MdType[];\n};\n\nfunction isMarkdown(path: string) {\n return path.endsWith(MARKDOWN);\n}\n\nfunction declaredIn(document: Document, part: 'fields' | 'sections') {\n return (document.fields[part] ?? {}) as Readonly<Record<string, unknown>>;\n}\n\nfunction mdType(path: string, document: Document): MdType {\n return {\n name: path.slice(path.lastIndexOf('/') + 1, -MARKDOWN.length),\n path,\n fields: declaredIn(document, 'fields'),\n sections: declaredIn(document, 'sections'),\n };\n}\n\nexport function parseCollection(text: Readonly<Record<string, string>>): Collection {\n const documents: Record<string, Document> = {};\n for (const path of Object.keys(text).sort()) {\n const parsed = parse(text[path], path);\n if (parsed.ok) documents[path] = parsed.document;\n }\n const types: MdType[] = [];\n for (const [path, document] of Object.entries(documents)) {\n if (!isMarkdown(path) || document.type !== DEFINITION) continue;\n types.push(mdType(path, document));\n }\n return { documents, types };\n}\n\nexport function readCollection(\n text: Readonly<Record<string, string>>,\n binaryTargets: readonly string[],\n): Collection | null {\n const collection = parseCollection(text);\n if (Object.keys(collection.documents).length !== Object.keys(text).length) return null;\n if (validate(text, { binaryTargets }).verdict === 'refuse') return null;\n return collection;\n}\n"],"names":["parse","validate","VERSION","MARKDOWN","DEFINITION","MD_MODEL","identity","version","PRESENTED","path","$regex","isMarkdown","endsWith","declaredIn","document","part","fields","mdType","name","slice","lastIndexOf","length","sections","parseCollection","text","documents","Object","keys","sort","parsed","ok","types","entries","type","push","readCollection","binaryTargets","collection","verdict"],"mappings":"AAAA,SAASA,KAAK,EAAEC,QAAQ,EAAEC,OAAO,QAAuB,uBAAuB;AAI/E,MAAMC,WAAW;AACjB,MAAMC,aAAa;AAEnB,OAAO,MAAMC,WAA4B;IAAEC,UAAU;IAAwBC,SAASL;AAAQ,EAAE;AAEhG,OAAO,MAAMM,YAAsB;IAAEC,MAAM;QAAEC,QAAQ;IAAS;AAAE,EAAE;AAclE,SAASC,WAAWF,IAAY;IAC9B,OAAOA,KAAKG,QAAQ,CAACT;AACvB;AAEA,SAASU,WAAWC,QAAkB,EAAEC,IAA2B;IACjE,OAAQD,SAASE,MAAM,CAACD,KAAK,IAAI,CAAC;AACpC;AAEA,SAASE,OAAOR,IAAY,EAAEK,QAAkB;IAC9C,OAAO;QACLI,MAAMT,KAAKU,KAAK,CAACV,KAAKW,WAAW,CAAC,OAAO,GAAG,CAACjB,SAASkB,MAAM;QAC5DZ;QACAO,QAAQH,WAAWC,UAAU;QAC7BQ,UAAUT,WAAWC,UAAU;IACjC;AACF;AAEA,OAAO,SAASS,gBAAgBC,IAAsC;IACpE,MAAMC,YAAsC,CAAC;IAC7C,KAAK,MAAMhB,QAAQiB,OAAOC,IAAI,CAACH,MAAMI,IAAI,GAAI;QAC3C,MAAMC,SAAS7B,MAAMwB,IAAI,CAACf,KAAK,EAAEA;QACjC,IAAIoB,OAAOC,EAAE,EAAEL,SAAS,CAAChB,KAAK,GAAGoB,OAAOf,QAAQ;IAClD;IACA,MAAMiB,QAAkB,EAAE;IAC1B,KAAK,MAAM,CAACtB,MAAMK,SAAS,IAAIY,OAAOM,OAAO,CAACP,WAAY;QACxD,IAAI,CAACd,WAAWF,SAASK,SAASmB,IAAI,KAAK7B,YAAY;QACvD2B,MAAMG,IAAI,CAACjB,OAAOR,MAAMK;IAC1B;IACA,OAAO;QAAEW;QAAWM;IAAM;AAC5B;AAEA,OAAO,SAASI,eACdX,IAAsC,EACtCY,aAAgC;IAEhC,MAAMC,aAAad,gBAAgBC;IACnC,IAAIE,OAAOC,IAAI,CAACU,WAAWZ,SAAS,EAAEJ,MAAM,KAAKK,OAAOC,IAAI,CAACH,MAAMH,MAAM,EAAE,OAAO;IAClF,IAAIpB,SAASuB,MAAM;QAAEY;IAAc,GAAGE,OAAO,KAAK,UAAU,OAAO;IACnE,OAAOD;AACT"}
1
+ {"version":3,"sources":["/workspace/packages/mdruntime/src/collection.ts"],"sourcesContent":["import {\n parse,\n validate,\n VERSION,\n type Document,\n type ParseResult,\n type Validation,\n type VerifiedModel,\n} from '@agentshouse/mdmodel';\nimport { beneath, normalize } from './paths.js';\nimport type { ModelState } from './model.js';\nimport type { MdModelIdentity } from './adapter.js';\nimport type { Refused } from './transfer.js';\n\nexport const MD_MODEL: MdModelIdentity = { identity: '@agentshouse/mdmodel', version: VERSION };\n\nconst NO_TYPES: VerifiedModel = { types: {} };\n\nexport type Collection = {\n documents: Readonly<Record<string, Document>>;\n composition: Composition;\n};\n\nexport type Composition = {\n model: ModelState;\n selection: { roots: readonly string[]; model: ModelState } | null;\n untypedFolders: readonly string[];\n};\n\nfunction selected(composition: Composition, path: string): boolean {\n return (\n composition.selection !== null &&\n composition.selection.roots.some((root) => beneath(root, path))\n );\n}\n\nexport function untyped(roots: readonly string[], path: string): boolean {\n return roots.some((root) => beneath(root, path));\n}\n\nexport function governing(composition: Composition, path: string): ModelState {\n return composition.selection !== null && selected(composition, path)\n ? composition.selection.model\n : composition.model;\n}\n\ntype Previous = { text: Readonly<Record<string, string>>; collection: Collection };\n\nfunction parsedAt(\n text: Readonly<Record<string, string>>,\n path: string,\n previous: Previous | undefined,\n): ParseResult {\n const retained = previous?.collection.documents[path];\n return retained !== undefined && previous?.text[path] === text[path]\n ? { ok: true, document: retained }\n : parse(text[path], path);\n}\n\nexport function parseCollection(\n text: Readonly<Record<string, string>>,\n composition: Composition,\n previous?: Previous,\n): Collection {\n const documents: Record<string, Document> = {};\n for (const path of Object.keys(text).sort()) {\n if (untyped(composition.untypedFolders, path)) continue;\n const parsed = parsedAt(text, path, previous);\n if (parsed.ok) documents[path] = parsed.document;\n }\n return { documents, composition };\n}\n\nexport function readCollection(\n text: Readonly<Record<string, string>>,\n composition: Composition,\n previous?: Previous,\n): { kind: 'read'; collection: Collection } | Refused {\n const documents: Record<string, Document> = {};\n for (const path of Object.keys(text).sort()) {\n if (untyped(composition.untypedFolders, path)) continue;\n const parsed = parsedAt(text, path, previous);\n if (!parsed.ok) return { kind: 'refused', refusal: parsed.refusal };\n documents[path] = parsed.document;\n }\n return { kind: 'read', collection: { documents, composition } };\n}\n\nexport function validRoot(root: unknown): root is string {\n return typeof root === 'string' && normalize(root) === root;\n}\n\ntype Refusal = Extract<Validation, { verdict: 'refuse' }>;\n\nfunction validateAgainst(\n documents: Readonly<Record<string, string>>,\n binaryTargets: readonly string[],\n model: ModelState,\n): Validation {\n if (model.status === 'unavailable') {\n const typed = Object.entries(documents).find(([, content]) => {\n const parsed = parse(content);\n return parsed.ok && parsed.document.type !== undefined && parsed.document.type !== 'any';\n });\n if (typed !== undefined)\n return { verdict: 'refuse', rule: 'model-unavailable', file: typed[0], version: VERSION };\n }\n return validate(\n documents,\n { binaryTargets },\n model.status === 'unavailable' ? NO_TYPES : { types: model.types },\n );\n}\n\nexport function validateCollection(\n text: Readonly<Record<string, string>>,\n binaryTargets: readonly string[],\n composition: Composition,\n): Validation {\n const collection: Record<string, string> = {};\n const selection: Record<string, string> = {};\n for (const [path, content] of Object.entries(text)) {\n if (untyped(composition.untypedFolders, path)) continue;\n if (selected(composition, path)) selection[path] = content;\n else collection[path] = content;\n }\n const linked = binaryTargets.filter((path) => !untyped(composition.untypedFolders, path));\n const verdicts = [\n validateAgainst(\n collection,\n linked.filter((path) => !selected(composition, path)),\n composition.model,\n ),\n ];\n if (composition.selection !== null) {\n verdicts.push(\n validateAgainst(\n selection,\n linked.filter((path) => selected(composition, path)),\n composition.selection.model,\n ),\n );\n }\n const refusals = verdicts.filter((verdict): verdict is Refusal => verdict.verdict === 'refuse');\n if (refusals.length === 0) return verdicts[0];\n return refusals.find((refusal) => refusal.rule !== 'model-unavailable') ?? refusals[0];\n}\n"],"names":["parse","validate","VERSION","beneath","normalize","MD_MODEL","identity","version","NO_TYPES","types","selected","composition","path","selection","roots","some","root","untyped","governing","model","parsedAt","text","previous","retained","collection","documents","undefined","ok","document","parseCollection","Object","keys","sort","untypedFolders","parsed","readCollection","kind","refusal","validRoot","validateAgainst","binaryTargets","status","typed","entries","find","content","type","verdict","rule","file","validateCollection","linked","filter","verdicts","push","refusals","length"],"mappings":"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"}