@agentshouse/mdruntime 0.1.0-alpha.20 → 0.1.0-alpha.21

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.
@@ -1 +1 @@
1
- {"version":3,"file":"host.d.ts","sourceRoot":"","sources":["../src/host.ts"],"names":[],"mappings":"AAEA,OAAO,EAIL,KAAK,gBAAgB,EACtB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAML,KAAK,WAAW,EAKjB,MAAM,WAAW,CAAC;AAEnB,MAAM,MAAM,oBAAoB,GAAG,gBAAgB,GAAG;IAAE,eAAe,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAEpF,MAAM,MAAM,aAAa,GAAG;IAC1B,sBAAsB,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;IAC7C,MAAM,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,IAAI,CAAC;IACrE,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACnC,CAAC;AAkHF,wBAAgB,cAAc,CAAC,OAAO,EAAE,oBAAoB,GAAG,aAAa,CAiH3E;AAED,YAAY,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"host.d.ts","sourceRoot":"","sources":["../src/host.ts"],"names":[],"mappings":"AAEA,OAAO,EAIL,KAAK,gBAAgB,EACtB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAML,KAAK,WAAW,EAKjB,MAAM,WAAW,CAAC;AAEnB,MAAM,MAAM,oBAAoB,GAAG,gBAAgB,GAAG;IAAE,eAAe,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAEpF,MAAM,MAAM,aAAa,GAAG;IAC1B,sBAAsB,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;IAC7C,MAAM,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,IAAI,CAAC;IACrE,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACnC,CAAC;AAkHF,wBAAgB,cAAc,CAAC,OAAO,EAAE,oBAAoB,GAAG,aAAa,CAkH3E;AAED,YAAY,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC"}
package/dist/host.js CHANGED
@@ -143,6 +143,7 @@ export function serveMdRuntime(options) {
143
143
  return;
144
144
  }
145
145
  try {
146
+ if (message.kind !== 'observe' || message.topic !== 'drafts') await md.loaded();
146
147
  if (message.kind === 'observe') {
147
148
  subscriptions.set(message.id, message.topic === 'deployment-facts' ? observeFacts((value)=>{
148
149
  if (serving) send({
package/dist/host.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["/workspace/packages/mdruntime/src/host.ts"],"sourcesContent":["import type { QueryOptions } from '@agentshouse/query';\nimport type { Change, WrittenBy } from './change.js';\nimport {\n createMdRuntime,\n type HistoryQuery,\n type MdRuntime,\n type MdRuntimeOptions,\n} from './connection.js';\nimport type { UnsentInstruction } from './conversation.js';\nimport { removeRuntimeStore } from './store.js';\nimport {\n AUTHORIZATION_ENDED,\n carried,\n envelope,\n PROTOCOL_MISMATCH,\n request,\n type RuntimePort,\n type WireAnswer,\n type WireMember,\n type WireRequest,\n type WireTopic,\n} from './wire.js';\n\nexport type MdRuntimeHostOptions = MdRuntimeOptions & { deploymentFacts?: unknown };\n\nexport type MdRuntimeHost = {\n replaceDeploymentFacts(value: unknown): void;\n attach(port: RuntimePort, app: string, release?: string): () => void;\n endAuthorization(): Promise<void>;\n};\n\nfunction answered(\n md: MdRuntime,\n app: string,\n writtenBy: WrittenBy | undefined,\n member: WireMember,\n input: readonly unknown[],\n deploymentFacts: unknown,\n): unknown {\n switch (member) {\n case 'rooms':\n return md.rooms();\n case 'slots':\n return md.slots();\n case 'query':\n return md.query(input[0] as QueryOptions | undefined);\n case 'types':\n return md.types(input[0] as string);\n case 'syncStatus':\n return md.syncStatus();\n case 'save':\n return md.save(\n input[0] as string,\n input[1] as readonly Change[],\n input[2] as string | undefined,\n writtenBy,\n );\n case 'outcome':\n return md.outcome(input[0] as string);\n case 'history':\n return md.history(input[0] as string, input[1] as string, input[2] as HistoryQuery);\n case 'call':\n return md.call(input[0] as string, input[1]);\n case 'log':\n return md.log();\n case 'storageLoss':\n return md.storageLoss();\n case 'deploymentFacts':\n return structuredClone(deploymentFacts);\n case 'persistence':\n return md.persistence();\n case 'reauthorize':\n return md.reauthorize();\n case 'draft.list':\n return md.draft.list();\n case 'draft.read':\n return md.draft.read(input[0] as string, input[1] as string);\n case 'draft.replace':\n return md.draft.replace(input[0] as string, input[1] as string, input[2]);\n case 'draft.discard':\n return md.draft.discard(input[0] as string, input[1] as string);\n case 'queue.discard':\n return md.queue.discard(input[0] as string, input[1] as string);\n case 'presentation.read':\n return md.presentation.read(app);\n case 'presentation.write':\n return md.presentation.write(app, input[0]);\n case 'conversation.list':\n return md.conversation.list();\n case 'conversation.read':\n return md.conversation.read(input[0] as string);\n case 'conversation.older':\n return md.conversation.older(input[0] as string);\n case 'conversation.compose':\n return md.conversation.compose(input[0] as string, input[1] as UnsentInstruction);\n case 'conversation.discard':\n return md.conversation.discard(input[0] as string);\n case 'conversation.create':\n return md.conversation.create(input[0]);\n case 'conversation.send':\n return md.conversation.send(input[0] as string);\n case 'conversation.answer':\n return md.conversation.answer(input[0] as string, input[1]);\n case 'conversation.interrupt':\n return md.conversation.interrupt(input[0] as string);\n case 'conversation.kill':\n return md.conversation.kill(input[0] as string);\n case 'conversation.cancel':\n return md.conversation.cancel(input[0] as string, input[1] as string);\n case 'conversation.delete':\n return md.conversation.delete(input[0] as string);\n }\n}\n\nfunction subscribed(\n md: MdRuntime,\n app: string,\n topic: Exclude<WireTopic, 'deployment-facts'>,\n input: readonly unknown[],\n deliver: (value: unknown) => void,\n): () => void {\n switch (topic) {\n case 'rooms':\n return md.observe('rooms', deliver);\n case 'connection-refusal':\n return md.observe('connection-refusal', deliver);\n case 'storage-loss':\n return md.observe('storage-loss', deliver);\n case 'sync-status':\n return md.observe('sync-status', deliver);\n case 'drafts':\n return md.observe('drafts', deliver);\n case 'queue':\n return md.observe('queue', input[0] as string, deliver);\n case 'query':\n return md.observe('query', input[0] as QueryOptions, deliver);\n case 'presentation':\n return md.observe('presentation', app, deliver);\n case 'conversation':\n return md.observe('conversation', input[0] as string, deliver);\n }\n}\n\nexport function serveMdRuntime(options: MdRuntimeHostOptions): MdRuntimeHost {\n let deploymentFacts = structuredClone(options.deploymentFacts);\n const stopping = new AbortController();\n const stop = () => {\n stopping.abort();\n };\n options.signal?.addEventListener('abort', stop, { once: true });\n if (options.signal?.aborted === true) stop();\n const md = createMdRuntime({ ...options, signal: stopping.signal });\n const attachments = new Map<() => void, (message: WireAnswer) => void>();\n let authorized = true;\n const factsObservers = new Set<(value: unknown) => void>();\n const observeFacts = (deliver: (value: unknown) => void) => {\n factsObservers.add(deliver);\n deliver(structuredClone(deploymentFacts));\n return () => {\n factsObservers.delete(deliver);\n };\n };\n\n function attach(port: RuntimePort, app: string, release?: string): () => void {\n if (!authorized) throw new Error(AUTHORIZATION_ENDED);\n const writtenBy = release === undefined ? undefined : { app, release };\n const subscriptions = new Map<number, () => void>();\n let serving = true;\n const send = (message: WireAnswer) => {\n port.postMessage(envelope(message));\n };\n const detach = () => {\n if (!serving) return;\n serving = false;\n for (const end of subscriptions.values()) end();\n subscriptions.clear();\n attachments.delete(detach);\n };\n const serve = async (message: WireRequest) => {\n if (message.kind === 'hello') return;\n if (message.kind === 'stop') {\n subscriptions.get(message.id)?.();\n subscriptions.delete(message.id);\n return;\n }\n try {\n if (message.kind === 'observe') {\n subscriptions.set(\n message.id,\n message.topic === 'deployment-facts'\n ? observeFacts((value) => {\n if (serving) send({ kind: 'event', id: message.id, value });\n })\n : subscribed(md, app, message.topic, message.input, (value) => {\n if (serving) send({ kind: 'event', id: message.id, value });\n }),\n );\n if (serving) send({ kind: 'result', id: message.id, value: null });\n return;\n }\n const value = await answered(\n md,\n app,\n writtenBy,\n message.member,\n message.input,\n deploymentFacts,\n );\n if (serving) send({ kind: 'result', id: message.id, value });\n } catch (error) {\n if (serving) {\n send({\n kind: 'failure',\n id: message.id,\n message: error instanceof Error ? error.message : String(error),\n });\n }\n }\n };\n port.addEventListener('message', (event) => {\n if (!serving) return;\n const wire = carried(event.data);\n if (wire === null) return;\n if (!wire.matching) {\n send({ kind: 'refusal', refusal: PROTOCOL_MISMATCH });\n detach();\n return;\n }\n const message = request(wire.message);\n if (message === null) return;\n void serve(message);\n });\n port.addEventListener('close', detach);\n port.start();\n attachments.set(detach, send);\n return detach;\n }\n\n return {\n attach,\n replaceDeploymentFacts(value) {\n if (!authorized) throw new Error(AUTHORIZATION_ENDED);\n deploymentFacts = structuredClone(value);\n for (const deliver of factsObservers) deliver(structuredClone(deploymentFacts));\n },\n async endAuthorization() {\n authorized = false;\n for (const [detach, send] of [...attachments]) {\n send({ kind: 'ended' });\n detach();\n }\n stop();\n await removeRuntimeStore();\n await options.shell.dropGeneration();\n },\n };\n}\n\nexport type { RuntimePort } from './wire.js';\n"],"names":["createMdRuntime","removeRuntimeStore","AUTHORIZATION_ENDED","carried","envelope","PROTOCOL_MISMATCH","request","answered","md","app","writtenBy","member","input","deploymentFacts","rooms","slots","query","types","syncStatus","save","outcome","history","call","log","storageLoss","structuredClone","persistence","reauthorize","draft","list","read","replace","discard","queue","presentation","write","conversation","older","compose","create","send","answer","interrupt","kill","cancel","delete","subscribed","topic","deliver","observe","serveMdRuntime","options","stopping","AbortController","stop","abort","signal","addEventListener","once","aborted","attachments","Map","authorized","factsObservers","Set","observeFacts","add","attach","port","release","Error","undefined","subscriptions","serving","message","postMessage","detach","end","values","clear","serve","kind","get","id","set","value","error","String","event","wire","data","matching","refusal","start","replaceDeploymentFacts","endAuthorization","shell","dropGeneration"],"mappings":"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"}
1
+ {"version":3,"sources":["/workspace/packages/mdruntime/src/host.ts"],"sourcesContent":["import type { QueryOptions } from '@agentshouse/query';\nimport type { Change, WrittenBy } from './change.js';\nimport {\n createMdRuntime,\n type HistoryQuery,\n type MdRuntime,\n type MdRuntimeOptions,\n} from './connection.js';\nimport type { UnsentInstruction } from './conversation.js';\nimport { removeRuntimeStore } from './store.js';\nimport {\n AUTHORIZATION_ENDED,\n carried,\n envelope,\n PROTOCOL_MISMATCH,\n request,\n type RuntimePort,\n type WireAnswer,\n type WireMember,\n type WireRequest,\n type WireTopic,\n} from './wire.js';\n\nexport type MdRuntimeHostOptions = MdRuntimeOptions & { deploymentFacts?: unknown };\n\nexport type MdRuntimeHost = {\n replaceDeploymentFacts(value: unknown): void;\n attach(port: RuntimePort, app: string, release?: string): () => void;\n endAuthorization(): Promise<void>;\n};\n\nfunction answered(\n md: MdRuntime,\n app: string,\n writtenBy: WrittenBy | undefined,\n member: WireMember,\n input: readonly unknown[],\n deploymentFacts: unknown,\n): unknown {\n switch (member) {\n case 'rooms':\n return md.rooms();\n case 'slots':\n return md.slots();\n case 'query':\n return md.query(input[0] as QueryOptions | undefined);\n case 'types':\n return md.types(input[0] as string);\n case 'syncStatus':\n return md.syncStatus();\n case 'save':\n return md.save(\n input[0] as string,\n input[1] as readonly Change[],\n input[2] as string | undefined,\n writtenBy,\n );\n case 'outcome':\n return md.outcome(input[0] as string);\n case 'history':\n return md.history(input[0] as string, input[1] as string, input[2] as HistoryQuery);\n case 'call':\n return md.call(input[0] as string, input[1]);\n case 'log':\n return md.log();\n case 'storageLoss':\n return md.storageLoss();\n case 'deploymentFacts':\n return structuredClone(deploymentFacts);\n case 'persistence':\n return md.persistence();\n case 'reauthorize':\n return md.reauthorize();\n case 'draft.list':\n return md.draft.list();\n case 'draft.read':\n return md.draft.read(input[0] as string, input[1] as string);\n case 'draft.replace':\n return md.draft.replace(input[0] as string, input[1] as string, input[2]);\n case 'draft.discard':\n return md.draft.discard(input[0] as string, input[1] as string);\n case 'queue.discard':\n return md.queue.discard(input[0] as string, input[1] as string);\n case 'presentation.read':\n return md.presentation.read(app);\n case 'presentation.write':\n return md.presentation.write(app, input[0]);\n case 'conversation.list':\n return md.conversation.list();\n case 'conversation.read':\n return md.conversation.read(input[0] as string);\n case 'conversation.older':\n return md.conversation.older(input[0] as string);\n case 'conversation.compose':\n return md.conversation.compose(input[0] as string, input[1] as UnsentInstruction);\n case 'conversation.discard':\n return md.conversation.discard(input[0] as string);\n case 'conversation.create':\n return md.conversation.create(input[0]);\n case 'conversation.send':\n return md.conversation.send(input[0] as string);\n case 'conversation.answer':\n return md.conversation.answer(input[0] as string, input[1]);\n case 'conversation.interrupt':\n return md.conversation.interrupt(input[0] as string);\n case 'conversation.kill':\n return md.conversation.kill(input[0] as string);\n case 'conversation.cancel':\n return md.conversation.cancel(input[0] as string, input[1] as string);\n case 'conversation.delete':\n return md.conversation.delete(input[0] as string);\n }\n}\n\nfunction subscribed(\n md: MdRuntime,\n app: string,\n topic: Exclude<WireTopic, 'deployment-facts'>,\n input: readonly unknown[],\n deliver: (value: unknown) => void,\n): () => void {\n switch (topic) {\n case 'rooms':\n return md.observe('rooms', deliver);\n case 'connection-refusal':\n return md.observe('connection-refusal', deliver);\n case 'storage-loss':\n return md.observe('storage-loss', deliver);\n case 'sync-status':\n return md.observe('sync-status', deliver);\n case 'drafts':\n return md.observe('drafts', deliver);\n case 'queue':\n return md.observe('queue', input[0] as string, deliver);\n case 'query':\n return md.observe('query', input[0] as QueryOptions, deliver);\n case 'presentation':\n return md.observe('presentation', app, deliver);\n case 'conversation':\n return md.observe('conversation', input[0] as string, deliver);\n }\n}\n\nexport function serveMdRuntime(options: MdRuntimeHostOptions): MdRuntimeHost {\n let deploymentFacts = structuredClone(options.deploymentFacts);\n const stopping = new AbortController();\n const stop = () => {\n stopping.abort();\n };\n options.signal?.addEventListener('abort', stop, { once: true });\n if (options.signal?.aborted === true) stop();\n const md = createMdRuntime({ ...options, signal: stopping.signal });\n const attachments = new Map<() => void, (message: WireAnswer) => void>();\n let authorized = true;\n const factsObservers = new Set<(value: unknown) => void>();\n const observeFacts = (deliver: (value: unknown) => void) => {\n factsObservers.add(deliver);\n deliver(structuredClone(deploymentFacts));\n return () => {\n factsObservers.delete(deliver);\n };\n };\n\n function attach(port: RuntimePort, app: string, release?: string): () => void {\n if (!authorized) throw new Error(AUTHORIZATION_ENDED);\n const writtenBy = release === undefined ? undefined : { app, release };\n const subscriptions = new Map<number, () => void>();\n let serving = true;\n const send = (message: WireAnswer) => {\n port.postMessage(envelope(message));\n };\n const detach = () => {\n if (!serving) return;\n serving = false;\n for (const end of subscriptions.values()) end();\n subscriptions.clear();\n attachments.delete(detach);\n };\n const serve = async (message: WireRequest) => {\n if (message.kind === 'hello') return;\n if (message.kind === 'stop') {\n subscriptions.get(message.id)?.();\n subscriptions.delete(message.id);\n return;\n }\n try {\n if (message.kind !== 'observe' || message.topic !== 'drafts') await md.loaded();\n if (message.kind === 'observe') {\n subscriptions.set(\n message.id,\n message.topic === 'deployment-facts'\n ? observeFacts((value) => {\n if (serving) send({ kind: 'event', id: message.id, value });\n })\n : subscribed(md, app, message.topic, message.input, (value) => {\n if (serving) send({ kind: 'event', id: message.id, value });\n }),\n );\n if (serving) send({ kind: 'result', id: message.id, value: null });\n return;\n }\n const value = await answered(\n md,\n app,\n writtenBy,\n message.member,\n message.input,\n deploymentFacts,\n );\n if (serving) send({ kind: 'result', id: message.id, value });\n } catch (error) {\n if (serving) {\n send({\n kind: 'failure',\n id: message.id,\n message: error instanceof Error ? error.message : String(error),\n });\n }\n }\n };\n port.addEventListener('message', (event) => {\n if (!serving) return;\n const wire = carried(event.data);\n if (wire === null) return;\n if (!wire.matching) {\n send({ kind: 'refusal', refusal: PROTOCOL_MISMATCH });\n detach();\n return;\n }\n const message = request(wire.message);\n if (message === null) return;\n void serve(message);\n });\n port.addEventListener('close', detach);\n port.start();\n attachments.set(detach, send);\n return detach;\n }\n\n return {\n attach,\n replaceDeploymentFacts(value) {\n if (!authorized) throw new Error(AUTHORIZATION_ENDED);\n deploymentFacts = structuredClone(value);\n for (const deliver of factsObservers) deliver(structuredClone(deploymentFacts));\n },\n async endAuthorization() {\n authorized = false;\n for (const [detach, send] of [...attachments]) {\n send({ kind: 'ended' });\n detach();\n }\n stop();\n await removeRuntimeStore();\n await options.shell.dropGeneration();\n },\n };\n}\n\nexport type { RuntimePort } from './wire.js';\n"],"names":["createMdRuntime","removeRuntimeStore","AUTHORIZATION_ENDED","carried","envelope","PROTOCOL_MISMATCH","request","answered","md","app","writtenBy","member","input","deploymentFacts","rooms","slots","query","types","syncStatus","save","outcome","history","call","log","storageLoss","structuredClone","persistence","reauthorize","draft","list","read","replace","discard","queue","presentation","write","conversation","older","compose","create","send","answer","interrupt","kill","cancel","delete","subscribed","topic","deliver","observe","serveMdRuntime","options","stopping","AbortController","stop","abort","signal","addEventListener","once","aborted","attachments","Map","authorized","factsObservers","Set","observeFacts","add","attach","port","release","Error","undefined","subscriptions","serving","message","postMessage","detach","end","values","clear","serve","kind","get","id","loaded","set","value","error","String","event","wire","data","matching","refusal","start","replaceDeploymentFacts","endAuthorization","shell","dropGeneration"],"mappings":"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"}
package/dist/overlay.d.ts CHANGED
@@ -5,4 +5,6 @@ export type Layer = {
5
5
  revisions: Readonly<Record<string, string>>;
6
6
  };
7
7
  export declare function overlay(base: Layer, queue: readonly ChangeBatch[]): Layer;
8
+ export declare function sameLayerText(left: Layer, right: Layer): boolean;
9
+ export declare function overlayChanged(base: Layer, queue: readonly ChangeBatch[], previousBase: Layer, previousQueue: readonly ChangeBatch[], previousVisible: Layer): Layer;
8
10
  //# sourceMappingURL=overlay.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"overlay.d.ts","sourceRoot":"","sources":["../src/overlay.ts"],"names":[],"mappings":"AACA,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,aAAa,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CAC7C,CAAC;AAyIF,wBAAgB,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,WAAW,EAAE,GAAG,KAAK,CAezE"}
1
+ {"version":3,"file":"overlay.d.ts","sourceRoot":"","sources":["../src/overlay.ts"],"names":[],"mappings":"AACA,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,aAAa,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CAC7C,CAAC;AAyIF,wBAAgB,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,WAAW,EAAE,GAAG,KAAK,CAezE;AAQD,wBAAgB,aAAa,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAQhE;AAqBD,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,CAkFP"}
package/dist/overlay.js CHANGED
@@ -135,5 +135,111 @@ export function overlay(base, queue) {
135
135
  revisions: staged.revisions
136
136
  };
137
137
  }
138
+ function pathsOf(batch) {
139
+ return batch.changes.flatMap((change)=>change.kind === 'move' ? [
140
+ change.path,
141
+ change.to
142
+ ] : [
143
+ change.path
144
+ ]);
145
+ }
146
+ export function sameLayerText(left, right) {
147
+ const paths = Object.keys(left.documents);
148
+ return paths.length === Object.keys(right.documents).length && paths.every((path)=>left.documents[path] === right.documents[path]) && left.binaryTargets.length === right.binaryTargets.length && left.binaryTargets.every((path)=>right.binaryTargets.includes(path));
149
+ }
150
+ function replayRevisions(base, queue) {
151
+ const revisions = {
152
+ ...base
153
+ };
154
+ for (const batch of queue){
155
+ for (const change of batch.changes){
156
+ if (change.kind === 'remove') {
157
+ delete revisions[change.path];
158
+ } else if (change.kind === 'move') {
159
+ const revision = revisions[change.path];
160
+ delete revisions[change.path];
161
+ if (revision !== undefined) revisions[change.to] = revision;
162
+ }
163
+ }
164
+ }
165
+ return revisions;
166
+ }
167
+ export function overlayChanged(base, queue, previousBase, previousQueue, previousVisible) {
168
+ const before = previousQueue.map((batch)=>JSON.stringify(batch));
169
+ const after = queue.map((batch)=>JSON.stringify(batch));
170
+ if (before.length === after.length && before.every((id, index)=>id === after[index]) && sameLayerText(base, previousBase)) {
171
+ return {
172
+ documents: previousVisible.documents,
173
+ binaryTargets: previousVisible.binaryTargets,
174
+ revisions: replayRevisions(base.revisions, queue)
175
+ };
176
+ }
177
+ const affected = new Set();
178
+ const paths = new Set([
179
+ ...Object.keys(base.documents),
180
+ ...Object.keys(previousBase.documents),
181
+ ...Object.keys(base.revisions),
182
+ ...Object.keys(previousBase.revisions),
183
+ ...base.binaryTargets,
184
+ ...previousBase.binaryTargets
185
+ ]);
186
+ for (const path of paths){
187
+ if (base.documents[path] !== previousBase.documents[path] || base.revisions[path] !== previousBase.revisions[path] || base.binaryTargets.includes(path) !== previousBase.binaryTargets.includes(path)) affected.add(path);
188
+ }
189
+ const oldIds = new Set(before);
190
+ const newIds = new Set(after);
191
+ for (const batch of previousQueue){
192
+ if (!newIds.has(JSON.stringify(batch))) for (const path of pathsOf(batch))affected.add(path);
193
+ }
194
+ for (const batch of queue){
195
+ if (!oldIds.has(JSON.stringify(batch))) for (const path of pathsOf(batch))affected.add(path);
196
+ }
197
+ let expanded = true;
198
+ while(expanded){
199
+ expanded = false;
200
+ for (const batch of queue){
201
+ const touched = pathsOf(batch);
202
+ if (!touched.some((path)=>affected.has(path))) continue;
203
+ for (const path of touched){
204
+ if (affected.has(path)) continue;
205
+ affected.add(path);
206
+ expanded = true;
207
+ }
208
+ }
209
+ }
210
+ const documents = {};
211
+ const revisions = {};
212
+ for (const path of affected){
213
+ if (base.documents[path] !== undefined) documents[path] = base.documents[path];
214
+ if (base.revisions[path] !== undefined) revisions[path] = base.revisions[path];
215
+ }
216
+ const staged = overlay({
217
+ documents,
218
+ revisions,
219
+ binaryTargets: base.binaryTargets.filter((path)=>affected.has(path))
220
+ }, queue.filter((batch)=>pathsOf(batch).some((path)=>affected.has(path))));
221
+ const mergedDocuments = {
222
+ ...previousVisible.documents
223
+ };
224
+ const mergedRevisions = {
225
+ ...previousVisible.revisions
226
+ };
227
+ const mergedTargets = new Set(previousVisible.binaryTargets);
228
+ for (const path of affected){
229
+ delete mergedDocuments[path];
230
+ delete mergedRevisions[path];
231
+ mergedTargets.delete(path);
232
+ }
233
+ Object.assign(mergedDocuments, staged.documents);
234
+ Object.assign(mergedRevisions, staged.revisions);
235
+ for (const path of staged.binaryTargets)mergedTargets.add(path);
236
+ return {
237
+ documents: mergedDocuments,
238
+ revisions: mergedRevisions,
239
+ binaryTargets: [
240
+ ...mergedTargets
241
+ ].sort()
242
+ };
243
+ }
138
244
 
139
245
  //# sourceMappingURL=overlay.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["/workspace/packages/mdruntime/src/overlay.ts"],"sourcesContent":["import { apply, parse, serialize, type Document } from '@agentshouse/mdmodel';\nimport type { Change, ChangeBatch, Precondition } from './change.js';\n\nexport type Layer = {\n documents: Readonly<Record<string, string>>;\n binaryTargets: readonly string[];\n revisions: Readonly<Record<string, string>>;\n};\n\ntype Staged = {\n documents: Record<string, string>;\n binaryTargets: Set<string>;\n revisions: Record<string, string>;\n};\n\ntype Priors = {\n field(path: string, name: string): unknown;\n section(path: string, name: string): string;\n preamble(path: string): string;\n};\n\nconst EMPTY_FRONTMATTER = '---\\n---\\n';\n\nfunction at(path: string, name: string) {\n return `${path} ${name}`;\n}\n\nfunction priorsOf(preconditions: readonly Precondition[]): Priors {\n const fields = new Map<string, unknown>();\n const sections = new Map<string, string>();\n const preambles = new Map<string, string>();\n for (const precondition of preconditions) {\n if (precondition.kind === 'field') {\n fields.set(at(precondition.path, precondition.name), precondition.value);\n }\n if (precondition.kind === 'section') {\n sections.set(at(precondition.path, precondition.name), precondition.value);\n }\n if (precondition.kind === 'preamble') {\n preambles.set(precondition.path, precondition.value);\n }\n }\n return {\n field: (path, name) => fields.get(at(path, name)),\n section: (path, name) => sections.get(at(path, name)) ?? '',\n preamble: (path) => preambles.get(path) ?? '',\n };\n}\n\nfunction compose(\n fields: Readonly<Record<string, unknown>>,\n sections: Readonly<Record<string, string>>,\n): string {\n const body = Object.entries(sections)\n .map(([name, value]) => `\\n## ${name}\\n${value}`)\n .join('');\n const skeleton = `${EMPTY_FRONTMATTER}${body}`;\n const opened = parse(skeleton);\n if (!opened.ok) return skeleton;\n let document: Document = opened.document;\n for (const [name, value] of Object.entries(fields)) {\n const next = apply(document, { kind: 'field', name, value, prior: undefined });\n if (next.outcome === 'applied') document = next.document;\n }\n return serialize(document);\n}\n\nfunction edited(document: Document, change: Change, priors: Priors) {\n if (change.kind === 'field') {\n return apply(document, {\n kind: 'field',\n name: change.name,\n value: change.value,\n prior: priors.field(change.path, change.name),\n });\n }\n if (change.kind === 'preamble') {\n return apply(document, {\n kind: 'preamble',\n value: change.value,\n prior: priors.preamble(change.path),\n });\n }\n if (change.kind !== 'section') return null;\n return apply(document, {\n kind: 'section',\n name: change.name,\n value: change.value,\n prior: priors.section(change.path, change.name),\n });\n}\n\nfunction edit(staged: Staged, change: Change, priors: Priors) {\n const text = staged.documents[change.path];\n if (text === undefined) return;\n const parsed = parse(text, change.path);\n if (!parsed.ok) return;\n const next = edited(parsed.document, change, priors);\n if (next?.outcome === 'applied') staged.documents[change.path] = serialize(next.document);\n}\n\nfunction relocate(staged: Staged, from: string, to: string) {\n const text = staged.documents[from];\n if (text !== undefined) {\n delete staged.documents[from];\n staged.documents[to] = text;\n } else if (staged.binaryTargets.delete(from)) {\n staged.binaryTargets.add(to);\n } else {\n return;\n }\n const revision = staged.revisions[from];\n if (revision === undefined) return;\n delete staged.revisions[from];\n staged.revisions[to] = revision;\n}\n\nfunction erase(staged: Staged, path: string) {\n delete staged.documents[path];\n delete staged.revisions[path];\n staged.binaryTargets.delete(path);\n}\n\nfunction stage(staged: Staged, change: Change, priors: Priors) {\n if (change.kind === 'field' || change.kind === 'section' || change.kind === 'preamble') {\n edit(staged, change, priors);\n return;\n }\n if (change.kind === 'create') {\n staged.documents[change.path] = compose(change.fields, change.sections);\n return;\n }\n if (change.kind === 'replace') {\n if (staged.documents[change.path] === undefined) return;\n staged.documents[change.path] = change.content;\n return;\n }\n if (change.kind === 'move') {\n relocate(staged, change.path, change.to);\n return;\n }\n erase(staged, change.path);\n}\n\nexport function overlay(base: Layer, queue: readonly ChangeBatch[]): Layer {\n const staged: Staged = {\n documents: { ...base.documents },\n binaryTargets: new Set(base.binaryTargets),\n revisions: { ...base.revisions },\n };\n for (const batch of queue) {\n const priors = priorsOf(batch.preconditions);\n for (const change of batch.changes) stage(staged, change, priors);\n }\n return {\n documents: staged.documents,\n binaryTargets: [...staged.binaryTargets].sort(),\n revisions: staged.revisions,\n };\n}\n"],"names":["apply","parse","serialize","EMPTY_FRONTMATTER","at","path","name","priorsOf","preconditions","fields","Map","sections","preambles","precondition","kind","set","value","field","get","section","preamble","compose","body","Object","entries","map","join","skeleton","opened","ok","document","next","prior","undefined","outcome","edited","change","priors","edit","staged","text","documents","parsed","relocate","from","to","binaryTargets","delete","add","revision","revisions","erase","stage","content","overlay","base","queue","Set","batch","changes","sort"],"mappings":"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"}
1
+ {"version":3,"sources":["/workspace/packages/mdruntime/src/overlay.ts"],"sourcesContent":["import { apply, parse, serialize, type Document } from '@agentshouse/mdmodel';\nimport type { Change, ChangeBatch, Precondition } from './change.js';\n\nexport type Layer = {\n documents: Readonly<Record<string, string>>;\n binaryTargets: readonly string[];\n revisions: Readonly<Record<string, string>>;\n};\n\ntype Staged = {\n documents: Record<string, string>;\n binaryTargets: Set<string>;\n revisions: Record<string, string>;\n};\n\ntype Priors = {\n field(path: string, name: string): unknown;\n section(path: string, name: string): string;\n preamble(path: string): string;\n};\n\nconst EMPTY_FRONTMATTER = '---\\n---\\n';\n\nfunction at(path: string, name: string) {\n return `${path} ${name}`;\n}\n\nfunction priorsOf(preconditions: readonly Precondition[]): Priors {\n const fields = new Map<string, unknown>();\n const sections = new Map<string, string>();\n const preambles = new Map<string, string>();\n for (const precondition of preconditions) {\n if (precondition.kind === 'field') {\n fields.set(at(precondition.path, precondition.name), precondition.value);\n }\n if (precondition.kind === 'section') {\n sections.set(at(precondition.path, precondition.name), precondition.value);\n }\n if (precondition.kind === 'preamble') {\n preambles.set(precondition.path, precondition.value);\n }\n }\n return {\n field: (path, name) => fields.get(at(path, name)),\n section: (path, name) => sections.get(at(path, name)) ?? '',\n preamble: (path) => preambles.get(path) ?? '',\n };\n}\n\nfunction compose(\n fields: Readonly<Record<string, unknown>>,\n sections: Readonly<Record<string, string>>,\n): string {\n const body = Object.entries(sections)\n .map(([name, value]) => `\\n## ${name}\\n${value}`)\n .join('');\n const skeleton = `${EMPTY_FRONTMATTER}${body}`;\n const opened = parse(skeleton);\n if (!opened.ok) return skeleton;\n let document: Document = opened.document;\n for (const [name, value] of Object.entries(fields)) {\n const next = apply(document, { kind: 'field', name, value, prior: undefined });\n if (next.outcome === 'applied') document = next.document;\n }\n return serialize(document);\n}\n\nfunction edited(document: Document, change: Change, priors: Priors) {\n if (change.kind === 'field') {\n return apply(document, {\n kind: 'field',\n name: change.name,\n value: change.value,\n prior: priors.field(change.path, change.name),\n });\n }\n if (change.kind === 'preamble') {\n return apply(document, {\n kind: 'preamble',\n value: change.value,\n prior: priors.preamble(change.path),\n });\n }\n if (change.kind !== 'section') return null;\n return apply(document, {\n kind: 'section',\n name: change.name,\n value: change.value,\n prior: priors.section(change.path, change.name),\n });\n}\n\nfunction edit(staged: Staged, change: Change, priors: Priors) {\n const text = staged.documents[change.path];\n if (text === undefined) return;\n const parsed = parse(text, change.path);\n if (!parsed.ok) return;\n const next = edited(parsed.document, change, priors);\n if (next?.outcome === 'applied') staged.documents[change.path] = serialize(next.document);\n}\n\nfunction relocate(staged: Staged, from: string, to: string) {\n const text = staged.documents[from];\n if (text !== undefined) {\n delete staged.documents[from];\n staged.documents[to] = text;\n } else if (staged.binaryTargets.delete(from)) {\n staged.binaryTargets.add(to);\n } else {\n return;\n }\n const revision = staged.revisions[from];\n if (revision === undefined) return;\n delete staged.revisions[from];\n staged.revisions[to] = revision;\n}\n\nfunction erase(staged: Staged, path: string) {\n delete staged.documents[path];\n delete staged.revisions[path];\n staged.binaryTargets.delete(path);\n}\n\nfunction stage(staged: Staged, change: Change, priors: Priors) {\n if (change.kind === 'field' || change.kind === 'section' || change.kind === 'preamble') {\n edit(staged, change, priors);\n return;\n }\n if (change.kind === 'create') {\n staged.documents[change.path] = compose(change.fields, change.sections);\n return;\n }\n if (change.kind === 'replace') {\n if (staged.documents[change.path] === undefined) return;\n staged.documents[change.path] = change.content;\n return;\n }\n if (change.kind === 'move') {\n relocate(staged, change.path, change.to);\n return;\n }\n erase(staged, change.path);\n}\n\nexport function overlay(base: Layer, queue: readonly ChangeBatch[]): Layer {\n const staged: Staged = {\n documents: { ...base.documents },\n binaryTargets: new Set(base.binaryTargets),\n revisions: { ...base.revisions },\n };\n for (const batch of queue) {\n const priors = priorsOf(batch.preconditions);\n for (const change of batch.changes) stage(staged, change, priors);\n }\n return {\n documents: staged.documents,\n binaryTargets: [...staged.binaryTargets].sort(),\n revisions: staged.revisions,\n };\n}\n\nfunction pathsOf(batch: ChangeBatch): readonly string[] {\n return batch.changes.flatMap((change) =>\n change.kind === 'move' ? [change.path, change.to] : [change.path],\n );\n}\n\nexport function sameLayerText(left: Layer, right: Layer): boolean {\n const paths = Object.keys(left.documents);\n return (\n paths.length === Object.keys(right.documents).length &&\n paths.every((path) => left.documents[path] === right.documents[path]) &&\n left.binaryTargets.length === right.binaryTargets.length &&\n left.binaryTargets.every((path) => right.binaryTargets.includes(path))\n );\n}\n\nfunction replayRevisions(\n base: Readonly<Record<string, string>>,\n queue: readonly ChangeBatch[],\n): Readonly<Record<string, string>> {\n const revisions = { ...base };\n for (const batch of queue) {\n for (const change of batch.changes) {\n if (change.kind === 'remove') {\n delete revisions[change.path];\n } else if (change.kind === 'move') {\n const revision = revisions[change.path];\n delete revisions[change.path];\n if (revision !== undefined) revisions[change.to] = revision;\n }\n }\n }\n return revisions;\n}\n\nexport function overlayChanged(\n base: Layer,\n queue: readonly ChangeBatch[],\n previousBase: Layer,\n previousQueue: readonly ChangeBatch[],\n previousVisible: Layer,\n): Layer {\n const before = previousQueue.map((batch) => JSON.stringify(batch));\n const after = queue.map((batch) => JSON.stringify(batch));\n if (\n before.length === after.length &&\n before.every((id, index) => id === after[index]) &&\n sameLayerText(base, previousBase)\n ) {\n return {\n documents: previousVisible.documents,\n binaryTargets: previousVisible.binaryTargets,\n revisions: replayRevisions(base.revisions, queue),\n };\n }\n const affected = new Set<string>();\n const paths = new Set([\n ...Object.keys(base.documents),\n ...Object.keys(previousBase.documents),\n ...Object.keys(base.revisions),\n ...Object.keys(previousBase.revisions),\n ...base.binaryTargets,\n ...previousBase.binaryTargets,\n ]);\n for (const path of paths) {\n if (\n base.documents[path] !== previousBase.documents[path] ||\n base.revisions[path] !== previousBase.revisions[path] ||\n base.binaryTargets.includes(path) !== previousBase.binaryTargets.includes(path)\n )\n affected.add(path);\n }\n const oldIds = new Set(before);\n const newIds = new Set(after);\n for (const batch of previousQueue) {\n if (!newIds.has(JSON.stringify(batch))) for (const path of pathsOf(batch)) affected.add(path);\n }\n for (const batch of queue) {\n if (!oldIds.has(JSON.stringify(batch))) for (const path of pathsOf(batch)) affected.add(path);\n }\n let expanded = true;\n while (expanded) {\n expanded = false;\n for (const batch of queue) {\n const touched = pathsOf(batch);\n if (!touched.some((path) => affected.has(path))) continue;\n for (const path of touched) {\n if (affected.has(path)) continue;\n affected.add(path);\n expanded = true;\n }\n }\n }\n const documents: Record<string, string> = {};\n const revisions: Record<string, string> = {};\n for (const path of affected) {\n if (base.documents[path] !== undefined) documents[path] = base.documents[path];\n if (base.revisions[path] !== undefined) revisions[path] = base.revisions[path];\n }\n const staged = overlay(\n {\n documents,\n revisions,\n binaryTargets: base.binaryTargets.filter((path) => affected.has(path)),\n },\n queue.filter((batch) => pathsOf(batch).some((path) => affected.has(path))),\n );\n const mergedDocuments = { ...previousVisible.documents };\n const mergedRevisions = { ...previousVisible.revisions };\n const mergedTargets = new Set(previousVisible.binaryTargets);\n for (const path of affected) {\n delete mergedDocuments[path];\n delete mergedRevisions[path];\n mergedTargets.delete(path);\n }\n Object.assign(mergedDocuments, staged.documents);\n Object.assign(mergedRevisions, staged.revisions);\n for (const path of staged.binaryTargets) mergedTargets.add(path);\n return {\n documents: mergedDocuments,\n revisions: mergedRevisions,\n binaryTargets: [...mergedTargets].sort(),\n };\n}\n"],"names":["apply","parse","serialize","EMPTY_FRONTMATTER","at","path","name","priorsOf","preconditions","fields","Map","sections","preambles","precondition","kind","set","value","field","get","section","preamble","compose","body","Object","entries","map","join","skeleton","opened","ok","document","next","prior","undefined","outcome","edited","change","priors","edit","staged","text","documents","parsed","relocate","from","to","binaryTargets","delete","add","revision","revisions","erase","stage","content","overlay","base","queue","Set","batch","changes","sort","pathsOf","flatMap","sameLayerText","left","right","paths","keys","length","every","includes","replayRevisions","overlayChanged","previousBase","previousQueue","previousVisible","before","JSON","stringify","after","id","index","affected","oldIds","newIds","has","expanded","touched","some","filter","mergedDocuments","mergedRevisions","mergedTargets","assign"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"refresh.d.ts","sourceRoot":"","sources":["../src/refresh.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AACvD,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,aAAa,EAAe,MAAM,cAAc,CAAC;AACxF,OAAO,EAAc,KAAK,cAAc,EAAE,MAAM,cAAc,CAAC;AAC/D,OAAO,EAAe,KAAK,WAAW,EAAE,MAAM,eAAe,CAAC;AAE9D,MAAM,MAAM,cAAc,GACtB;IAAE,IAAI,EAAE,eAAe,CAAA;CAAE,GACzB;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,SAAS,EAAE,cAAc,CAAA;CAAE,GAC/C;IAAE,IAAI,EAAE,gBAAgB,CAAA;CAAE,GAC1B,WAAW,GACX,cAAc,CAAC;AAEnB,wBAAsB,WAAW,CAC/B,OAAO,EAAE,OAAO,EAChB,aAAa,EAAE,aAAa,EAC5B,SAAS,EAAE,cAAc,EACzB,OAAO,EAAE,oBAAoB,GAAG,IAAI,GACnC,OAAO,CAAC,cAAc,CAAC,CAsDzB"}
1
+ {"version":3,"file":"refresh.d.ts","sourceRoot":"","sources":["../src/refresh.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AACvD,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,aAAa,EAAe,MAAM,cAAc,CAAC;AACxF,OAAO,EAAc,KAAK,cAAc,EAAE,MAAM,cAAc,CAAC;AAC/D,OAAO,EAAe,KAAK,WAAW,EAAE,MAAM,eAAe,CAAC;AAE9D,MAAM,MAAM,cAAc,GACtB;IAAE,IAAI,EAAE,eAAe,CAAA;CAAE,GACzB;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,SAAS,EAAE,cAAc,CAAA;CAAE,GAC/C;IAAE,IAAI,EAAE,gBAAgB,CAAA;CAAE,GAC1B,WAAW,GACX,cAAc,CAAC;AAEnB,wBAAsB,WAAW,CAC/B,OAAO,EAAE,OAAO,EAChB,aAAa,EAAE,aAAa,EAC5B,SAAS,EAAE,cAAc,EACzB,OAAO,EAAE,oBAAoB,GAAG,IAAI,GACnC,OAAO,CAAC,cAAc,CAAC,CAuDzB"}
package/dist/refresh.js CHANGED
@@ -55,7 +55,7 @@ export async function refreshRoom(adapter, authorization, confirmed, binding) {
55
55
  ...binaryTargets
56
56
  ].sort(),
57
57
  revisions
58
- }, binding);
58
+ }, binding, confirmed);
59
59
  return advanced === null ? unconfirmed : {
60
60
  kind: 'advanced',
61
61
  confirmed: advanced
@@ -1 +1 @@
1
- {"version":3,"sources":["/workspace/packages/mdruntime/src/refresh.ts"],"sourcesContent":["import type { AttachedModelBinding } from './model.js';\nimport type { Adapter, AdapterFailure, Authorization, RefreshPage } from './adapter.js';\nimport { readStaged, type ConfirmedLayer } from './replica.js';\nimport { unconfirmed, type Unconfirmed } from './transfer.js';\n\nexport type RefreshOutcome =\n | { kind: 'still-current' }\n | { kind: 'advanced'; confirmed: ConfirmedLayer }\n | { kind: 'beyond-horizon' }\n | Unconfirmed\n | AdapterFailure;\n\nexport async function refreshRoom(\n adapter: Adapter,\n authorization: Authorization,\n confirmed: ConfirmedLayer,\n binding: AttachedModelBinding | null,\n): Promise<RefreshOutcome> {\n const locator = confirmed.record.locator;\n const fromRoomVersion = confirmed.record.roomVersion;\n const first = await adapter.refresh(authorization, {\n locator,\n selection: confirmed.record.replica.selection,\n fromRoomVersion,\n });\n if (first.kind !== 'net-advancement') return first;\n const roomVersion = first.roomVersion;\n const documents: Record<string, string> = { ...confirmed.record.documents };\n const revisions: Record<string, string> = { ...confirmed.record.revisions };\n const binaryTargets = new Set(confirmed.record.binaryTargets);\n const stage = (page: RefreshPage) => {\n Object.assign(documents, page.documents);\n Object.assign(revisions, page.revisions);\n for (const path of Object.keys(page.documents)) binaryTargets.delete(path);\n for (const target of page.binaryTargets) {\n delete documents[target];\n delete revisions[target];\n binaryTargets.add(target);\n }\n for (const path of page.removals) {\n delete documents[path];\n delete revisions[path];\n binaryTargets.delete(path);\n }\n };\n stage(first);\n let pageToken = first.pageToken;\n while (pageToken !== undefined) {\n const page = await adapter.refresh(authorization, {\n locator,\n selection: confirmed.record.replica.selection,\n fromRoomVersion,\n pageToken,\n });\n if (page.kind === 'still-current' || page.kind === 'beyond-horizon') return unconfirmed;\n if (page.kind !== 'net-advancement') return page;\n if (page.roomVersion !== roomVersion) return unconfirmed;\n stage(page);\n pageToken = page.pageToken;\n }\n const advanced = readStaged(\n {\n ...confirmed.record,\n roomVersion,\n documents,\n binaryTargets: [...binaryTargets].sort(),\n revisions,\n },\n binding,\n );\n return advanced === null ? unconfirmed : { kind: 'advanced', confirmed: advanced };\n}\n"],"names":["readStaged","unconfirmed","refreshRoom","adapter","authorization","confirmed","binding","locator","record","fromRoomVersion","roomVersion","first","refresh","selection","replica","kind","documents","revisions","binaryTargets","Set","stage","page","Object","assign","path","keys","delete","target","add","removals","pageToken","undefined","advanced","sort"],"mappings":"AAEA,SAASA,UAAU,QAA6B,eAAe;AAC/D,SAASC,WAAW,QAA0B,gBAAgB;AAS9D,OAAO,eAAeC,YACpBC,OAAgB,EAChBC,aAA4B,EAC5BC,SAAyB,EACzBC,OAAoC;IAEpC,MAAMC,UAAUF,UAAUG,MAAM,CAACD,OAAO;IACxC,MAAME,kBAAkBJ,UAAUG,MAAM,CAACE,WAAW;IACpD,MAAMC,QAAQ,MAAMR,QAAQS,OAAO,CAACR,eAAe;QACjDG;QACAM,WAAWR,UAAUG,MAAM,CAACM,OAAO,CAACD,SAAS;QAC7CJ;IACF;IACA,IAAIE,MAAMI,IAAI,KAAK,mBAAmB,OAAOJ;IAC7C,MAAMD,cAAcC,MAAMD,WAAW;IACrC,MAAMM,YAAoC;QAAE,GAAGX,UAAUG,MAAM,CAACQ,SAAS;IAAC;IAC1E,MAAMC,YAAoC;QAAE,GAAGZ,UAAUG,MAAM,CAACS,SAAS;IAAC;IAC1E,MAAMC,gBAAgB,IAAIC,IAAId,UAAUG,MAAM,CAACU,aAAa;IAC5D,MAAME,QAAQ,CAACC;QACbC,OAAOC,MAAM,CAACP,WAAWK,KAAKL,SAAS;QACvCM,OAAOC,MAAM,CAACN,WAAWI,KAAKJ,SAAS;QACvC,KAAK,MAAMO,QAAQF,OAAOG,IAAI,CAACJ,KAAKL,SAAS,EAAGE,cAAcQ,MAAM,CAACF;QACrE,KAAK,MAAMG,UAAUN,KAAKH,aAAa,CAAE;YACvC,OAAOF,SAAS,CAACW,OAAO;YACxB,OAAOV,SAAS,CAACU,OAAO;YACxBT,cAAcU,GAAG,CAACD;QACpB;QACA,KAAK,MAAMH,QAAQH,KAAKQ,QAAQ,CAAE;YAChC,OAAOb,SAAS,CAACQ,KAAK;YACtB,OAAOP,SAAS,CAACO,KAAK;YACtBN,cAAcQ,MAAM,CAACF;QACvB;IACF;IACAJ,MAAMT;IACN,IAAImB,YAAYnB,MAAMmB,SAAS;IAC/B,MAAOA,cAAcC,UAAW;QAC9B,MAAMV,OAAO,MAAMlB,QAAQS,OAAO,CAACR,eAAe;YAChDG;YACAM,WAAWR,UAAUG,MAAM,CAACM,OAAO,CAACD,SAAS;YAC7CJ;YACAqB;QACF;QACA,IAAIT,KAAKN,IAAI,KAAK,mBAAmBM,KAAKN,IAAI,KAAK,kBAAkB,OAAOd;QAC5E,IAAIoB,KAAKN,IAAI,KAAK,mBAAmB,OAAOM;QAC5C,IAAIA,KAAKX,WAAW,KAAKA,aAAa,OAAOT;QAC7CmB,MAAMC;QACNS,YAAYT,KAAKS,SAAS;IAC5B;IACA,MAAME,WAAWhC,WACf;QACE,GAAGK,UAAUG,MAAM;QACnBE;QACAM;QACAE,eAAe;eAAIA;SAAc,CAACe,IAAI;QACtChB;IACF,GACAX;IAEF,OAAO0B,aAAa,OAAO/B,cAAc;QAAEc,MAAM;QAAYV,WAAW2B;IAAS;AACnF"}
1
+ {"version":3,"sources":["/workspace/packages/mdruntime/src/refresh.ts"],"sourcesContent":["import type { AttachedModelBinding } from './model.js';\nimport type { Adapter, AdapterFailure, Authorization, RefreshPage } from './adapter.js';\nimport { readStaged, type ConfirmedLayer } from './replica.js';\nimport { unconfirmed, type Unconfirmed } from './transfer.js';\n\nexport type RefreshOutcome =\n | { kind: 'still-current' }\n | { kind: 'advanced'; confirmed: ConfirmedLayer }\n | { kind: 'beyond-horizon' }\n | Unconfirmed\n | AdapterFailure;\n\nexport async function refreshRoom(\n adapter: Adapter,\n authorization: Authorization,\n confirmed: ConfirmedLayer,\n binding: AttachedModelBinding | null,\n): Promise<RefreshOutcome> {\n const locator = confirmed.record.locator;\n const fromRoomVersion = confirmed.record.roomVersion;\n const first = await adapter.refresh(authorization, {\n locator,\n selection: confirmed.record.replica.selection,\n fromRoomVersion,\n });\n if (first.kind !== 'net-advancement') return first;\n const roomVersion = first.roomVersion;\n const documents: Record<string, string> = { ...confirmed.record.documents };\n const revisions: Record<string, string> = { ...confirmed.record.revisions };\n const binaryTargets = new Set(confirmed.record.binaryTargets);\n const stage = (page: RefreshPage) => {\n Object.assign(documents, page.documents);\n Object.assign(revisions, page.revisions);\n for (const path of Object.keys(page.documents)) binaryTargets.delete(path);\n for (const target of page.binaryTargets) {\n delete documents[target];\n delete revisions[target];\n binaryTargets.add(target);\n }\n for (const path of page.removals) {\n delete documents[path];\n delete revisions[path];\n binaryTargets.delete(path);\n }\n };\n stage(first);\n let pageToken = first.pageToken;\n while (pageToken !== undefined) {\n const page = await adapter.refresh(authorization, {\n locator,\n selection: confirmed.record.replica.selection,\n fromRoomVersion,\n pageToken,\n });\n if (page.kind === 'still-current' || page.kind === 'beyond-horizon') return unconfirmed;\n if (page.kind !== 'net-advancement') return page;\n if (page.roomVersion !== roomVersion) return unconfirmed;\n stage(page);\n pageToken = page.pageToken;\n }\n const advanced = readStaged(\n {\n ...confirmed.record,\n roomVersion,\n documents,\n binaryTargets: [...binaryTargets].sort(),\n revisions,\n },\n binding,\n confirmed,\n );\n return advanced === null ? unconfirmed : { kind: 'advanced', confirmed: advanced };\n}\n"],"names":["readStaged","unconfirmed","refreshRoom","adapter","authorization","confirmed","binding","locator","record","fromRoomVersion","roomVersion","first","refresh","selection","replica","kind","documents","revisions","binaryTargets","Set","stage","page","Object","assign","path","keys","delete","target","add","removals","pageToken","undefined","advanced","sort"],"mappings":"AAEA,SAASA,UAAU,QAA6B,eAAe;AAC/D,SAASC,WAAW,QAA0B,gBAAgB;AAS9D,OAAO,eAAeC,YACpBC,OAAgB,EAChBC,aAA4B,EAC5BC,SAAyB,EACzBC,OAAoC;IAEpC,MAAMC,UAAUF,UAAUG,MAAM,CAACD,OAAO;IACxC,MAAME,kBAAkBJ,UAAUG,MAAM,CAACE,WAAW;IACpD,MAAMC,QAAQ,MAAMR,QAAQS,OAAO,CAACR,eAAe;QACjDG;QACAM,WAAWR,UAAUG,MAAM,CAACM,OAAO,CAACD,SAAS;QAC7CJ;IACF;IACA,IAAIE,MAAMI,IAAI,KAAK,mBAAmB,OAAOJ;IAC7C,MAAMD,cAAcC,MAAMD,WAAW;IACrC,MAAMM,YAAoC;QAAE,GAAGX,UAAUG,MAAM,CAACQ,SAAS;IAAC;IAC1E,MAAMC,YAAoC;QAAE,GAAGZ,UAAUG,MAAM,CAACS,SAAS;IAAC;IAC1E,MAAMC,gBAAgB,IAAIC,IAAId,UAAUG,MAAM,CAACU,aAAa;IAC5D,MAAME,QAAQ,CAACC;QACbC,OAAOC,MAAM,CAACP,WAAWK,KAAKL,SAAS;QACvCM,OAAOC,MAAM,CAACN,WAAWI,KAAKJ,SAAS;QACvC,KAAK,MAAMO,QAAQF,OAAOG,IAAI,CAACJ,KAAKL,SAAS,EAAGE,cAAcQ,MAAM,CAACF;QACrE,KAAK,MAAMG,UAAUN,KAAKH,aAAa,CAAE;YACvC,OAAOF,SAAS,CAACW,OAAO;YACxB,OAAOV,SAAS,CAACU,OAAO;YACxBT,cAAcU,GAAG,CAACD;QACpB;QACA,KAAK,MAAMH,QAAQH,KAAKQ,QAAQ,CAAE;YAChC,OAAOb,SAAS,CAACQ,KAAK;YACtB,OAAOP,SAAS,CAACO,KAAK;YACtBN,cAAcQ,MAAM,CAACF;QACvB;IACF;IACAJ,MAAMT;IACN,IAAImB,YAAYnB,MAAMmB,SAAS;IAC/B,MAAOA,cAAcC,UAAW;QAC9B,MAAMV,OAAO,MAAMlB,QAAQS,OAAO,CAACR,eAAe;YAChDG;YACAM,WAAWR,UAAUG,MAAM,CAACM,OAAO,CAACD,SAAS;YAC7CJ;YACAqB;QACF;QACA,IAAIT,KAAKN,IAAI,KAAK,mBAAmBM,KAAKN,IAAI,KAAK,kBAAkB,OAAOd;QAC5E,IAAIoB,KAAKN,IAAI,KAAK,mBAAmB,OAAOM;QAC5C,IAAIA,KAAKX,WAAW,KAAKA,aAAa,OAAOT;QAC7CmB,MAAMC;QACNS,YAAYT,KAAKS,SAAS;IAC5B;IACA,MAAME,WAAWhC,WACf;QACE,GAAGK,UAAUG,MAAM;QACnBE;QACAM;QACAE,eAAe;eAAIA;SAAc,CAACe,IAAI;QACtChB;IACF,GACAX,SACAD;IAEF,OAAO2B,aAAa,OAAO/B,cAAc;QAAEc,MAAM;QAAYV,WAAW2B;IAAS;AACnF"}
package/dist/replica.d.ts CHANGED
@@ -15,10 +15,19 @@ export type Replica = {
15
15
  confirmed: ConfirmedLayer;
16
16
  queue: readonly ChangeBatch[];
17
17
  visible: VisibleLayer;
18
+ replay: readonly ReplayStep[];
19
+ };
20
+ type ReplayStep = {
21
+ id: string;
22
+ before: Layer;
23
+ after: Layer;
24
+ effective: ChangeBatch;
25
+ collection?: Collection;
18
26
  };
19
27
  export declare function compositionOf(record: ReplicaRecord): Composition;
20
- export declare function readConfirmed(record: ReplicaRecord): ConfirmedLayer | null;
21
- export declare function readStaged(record: ReplicaRecord, binding: AttachedModelBinding | null): ConfirmedLayer | null;
28
+ export declare function readConfirmed(record: ReplicaRecord, previous?: ConfirmedLayer): ConfirmedLayer | null;
29
+ export declare function readStaged(record: ReplicaRecord, binding: AttachedModelBinding | null, previous?: ConfirmedLayer): ConfirmedLayer | null;
22
30
  export declare function applyReturned(confirmed: ConfirmedLayer, documents: Readonly<Record<string, string>>, revisions: Readonly<Record<string, string>>, removals: readonly string[], roomVersion: string, binding: AttachedModelBinding | null): ConfirmedLayer | null;
23
- export declare function replicaOf(confirmed: ConfirmedLayer, queue: readonly ChangeBatch[], rewriting: Rewriting): Replica;
31
+ export declare function replicaOf(confirmed: ConfirmedLayer, queue: readonly ChangeBatch[], rewriting: Rewriting, previous?: Replica): Replica;
32
+ export {};
24
33
  //# sourceMappingURL=replica.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"replica.d.ts","sourceRoot":"","sources":["../src/replica.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AACvD,OAAO,EAAa,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1D,OAAO,EAIL,KAAK,UAAU,EACf,KAAK,WAAW,EACjB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAW,KAAK,KAAK,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAqB,KAAK,SAAS,EAAE,MAAM,WAAW,CAAC;AAC9D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,MAAM,MAAM,cAAc,GAAG;IAC3B,MAAM,EAAE,aAAa,CAAC;IACtB,UAAU,EAAE,UAAU,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,KAAK,GAAG;IACjC,UAAU,EAAE,UAAU,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,OAAO,GAAG;IACpB,SAAS,EAAE,cAAc,CAAC;IAC1B,KAAK,EAAE,SAAS,WAAW,EAAE,CAAC;IAC9B,OAAO,EAAE,YAAY,CAAC;CACvB,CAAC;AAEF,wBAAgB,aAAa,CAAC,MAAM,EAAE,aAAa,GAAG,WAAW,CAShE;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,aAAa,GAAG,cAAc,GAAG,IAAI,CAG1E;AAED,wBAAgB,UAAU,CACxB,MAAM,EAAE,aAAa,EACrB,OAAO,EAAE,oBAAoB,GAAG,IAAI,GACnC,cAAc,GAAG,IAAI,CAcvB;AAED,wBAAgB,aAAa,CAC3B,SAAS,EAAE,cAAc,EACzB,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EAC3C,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EAC3C,QAAQ,EAAE,SAAS,MAAM,EAAE,EAC3B,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,oBAAoB,GAAG,IAAI,GACnC,cAAc,GAAG,IAAI,CAmBvB;AAgBD,wBAAgB,SAAS,CACvB,SAAS,EAAE,cAAc,EACzB,KAAK,EAAE,SAAS,WAAW,EAAE,EAC7B,SAAS,EAAE,SAAS,GACnB,OAAO,CAwBT"}
1
+ {"version":3,"file":"replica.d.ts","sourceRoot":"","sources":["../src/replica.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AACvD,OAAO,EAAa,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1D,OAAO,EAIL,KAAK,UAAU,EACf,KAAK,WAAW,EACjB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAA0C,KAAK,KAAK,EAAE,MAAM,cAAc,CAAC;AAClF,OAAO,EAAqB,KAAK,SAAS,EAAE,MAAM,WAAW,CAAC;AAC9D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,MAAM,MAAM,cAAc,GAAG;IAC3B,MAAM,EAAE,aAAa,CAAC;IACtB,UAAU,EAAE,UAAU,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,KAAK,GAAG;IACjC,UAAU,EAAE,UAAU,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,OAAO,GAAG;IACpB,SAAS,EAAE,cAAc,CAAC;IAC1B,KAAK,EAAE,SAAS,WAAW,EAAE,CAAC;IAC9B,OAAO,EAAE,YAAY,CAAC;IACtB,MAAM,EAAE,SAAS,UAAU,EAAE,CAAC;CAC/B,CAAC;AAEF,KAAK,UAAU,GAAG;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,KAAK,CAAC;IACd,KAAK,EAAE,KAAK,CAAC;IACb,SAAS,EAAE,WAAW,CAAC;IACvB,UAAU,CAAC,EAAE,UAAU,CAAC;CACzB,CAAC;AAEF,wBAAgB,aAAa,CAAC,MAAM,EAAE,aAAa,GAAG,WAAW,CAShE;AAED,wBAAgB,aAAa,CAC3B,MAAM,EAAE,aAAa,EACrB,QAAQ,CAAC,EAAE,cAAc,GACxB,cAAc,GAAG,IAAI,CASvB;AAED,wBAAgB,UAAU,CACxB,MAAM,EAAE,aAAa,EACrB,OAAO,EAAE,oBAAoB,GAAG,IAAI,EACpC,QAAQ,CAAC,EAAE,cAAc,GACxB,cAAc,GAAG,IAAI,CAkBvB;AAED,wBAAgB,aAAa,CAC3B,SAAS,EAAE,cAAc,EACzB,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EAC3C,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EAC3C,QAAQ,EAAE,SAAS,MAAM,EAAE,EAC3B,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,oBAAoB,GAAG,IAAI,GACnC,cAAc,GAAG,IAAI,CAoBvB;AAuDD,wBAAgB,SAAS,CACvB,SAAS,EAAE,cAAc,EACzB,KAAK,EAAE,SAAS,WAAW,EAAE,EAC7B,SAAS,EAAE,SAAS,EACpB,QAAQ,CAAC,EAAE,OAAO,GACjB,OAAO,CA2CT"}
package/dist/replica.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { immutable } from './change.js';
2
2
  import { parseCollection, readCollection, validateCollection } from './collection.js';
3
- import { overlay } from './overlay.js';
3
+ import { overlay, overlayChanged, sameLayerText } from './overlay.js';
4
4
  import { providerRewritten } from './save.js';
5
5
  export function compositionOf(record) {
6
6
  return {
@@ -12,19 +12,22 @@ export function compositionOf(record) {
12
12
  }
13
13
  };
14
14
  }
15
- export function readConfirmed(record) {
16
- const collection = readCollection(record.documents, compositionOf(record));
15
+ export function readConfirmed(record, previous) {
16
+ const collection = readCollection(record.documents, compositionOf(record), previous === undefined ? undefined : {
17
+ text: previous.record.documents,
18
+ collection: previous.collection
19
+ });
17
20
  return collection === null ? null : {
18
21
  record,
19
22
  collection
20
23
  };
21
24
  }
22
- export function readStaged(record, binding) {
23
- if (binding !== null && (record.model.status === 'current' || record.selectionModel.status === 'current')) {
25
+ export function readStaged(record, binding, previous) {
26
+ if (binding !== null && (record.model.status === 'current' || record.selectionModel.status === 'current') && (previous === undefined || !sameLayerText(record, previous.record) || record.model !== previous.record.model || record.selectionModel !== previous.record.selectionModel)) {
24
27
  const verdict = validateCollection(record.documents, record.binaryTargets, compositionOf(record), binding);
25
28
  if (verdict.verdict === 'refuse' && verdict.rule !== 'model-unavailable') return null;
26
29
  }
27
- return readConfirmed(record);
30
+ return readConfirmed(record, previous);
28
31
  }
29
32
  export function applyReturned(confirmed, documents, revisions, removals, roomVersion, binding) {
30
33
  const nextDocuments = {
@@ -49,29 +52,55 @@ export function applyReturned(confirmed, documents, revisions, removals, roomVer
49
52
  binaryTargets: [
50
53
  ...binaryTargets
51
54
  ].sort()
52
- }, binding);
55
+ }, binding, confirmed);
53
56
  }
54
- function predicted(confirmed, batches) {
57
+ function predicted(confirmed, batches, previous) {
55
58
  const composition = compositionOf(confirmed.record);
56
59
  let layer = confirmed.record;
60
+ const replay = [];
61
+ const prior = new Map(previous?.replay.map((step)=>[
62
+ step.id,
63
+ step
64
+ ]) ?? []);
57
65
  for (const batch of batches){
58
- if (!batch.changes.some((change)=>change.kind === 'move')) {
59
- layer = overlay(layer, [
60
- batch
61
- ]);
62
- continue;
63
- }
64
- const visible = {
65
- ...layer,
66
- collection: parseCollection(layer.documents, composition)
67
- };
68
- layer = overlay(layer, [
69
- providerRewritten(batch, visible)
70
- ]);
66
+ const before = layer;
67
+ const old = prior.get(batch.id);
68
+ const hasMove = batch.changes.some((change)=>change.kind === 'move');
69
+ const reuseRewrite = old?.collection !== undefined && sameLayerText(before, old.before) && old.collection.composition.collectionRoot === composition.collectionRoot && old.collection.composition.model === composition.model && old.collection.composition.selection?.model === composition.selection?.model && JSON.stringify(old.collection.composition.selection?.roots) === JSON.stringify(composition.selection?.roots);
70
+ const collection = hasMove ? reuseRewrite ? old.collection : parseCollection(before.documents, composition, old?.collection === undefined ? {
71
+ text: confirmed.record.documents,
72
+ collection: confirmed.collection
73
+ } : {
74
+ text: old.before.documents,
75
+ collection: old.collection
76
+ }) : undefined;
77
+ const effective = collection === undefined ? batch : reuseRewrite ? old.effective : providerRewritten(batch, {
78
+ ...before,
79
+ collection
80
+ });
81
+ layer = old === undefined ? overlay(before, [
82
+ effective
83
+ ]) : overlayChanged(before, [
84
+ effective
85
+ ], old.before, [
86
+ old.effective
87
+ ], old.after);
88
+ replay.push({
89
+ id: batch.id,
90
+ before,
91
+ after: layer,
92
+ effective,
93
+ ...collection === undefined ? {} : {
94
+ collection
95
+ }
96
+ });
71
97
  }
72
- return layer;
98
+ return {
99
+ layer,
100
+ replay
101
+ };
73
102
  }
74
- export function replicaOf(confirmed, queue, rewriting) {
103
+ export function replicaOf(confirmed, queue, rewriting, previous) {
75
104
  const batches = Object.freeze(queue.map(immutable));
76
105
  if (batches.length === 0) {
77
106
  return {
@@ -82,16 +111,22 @@ export function replicaOf(confirmed, queue, rewriting) {
82
111
  binaryTargets: confirmed.record.binaryTargets,
83
112
  revisions: confirmed.record.revisions,
84
113
  collection: confirmed.collection
85
- }
114
+ },
115
+ replay: []
86
116
  };
87
117
  }
88
- const layer = rewriting === 'provider' ? predicted(confirmed, batches) : overlay(confirmed.record, batches);
118
+ const predictedState = rewriting === 'provider' ? predicted(confirmed, batches, previous) : null;
119
+ const layer = rewriting === 'provider' ? predictedState.layer : previous === undefined ? overlay(confirmed.record, batches) : overlayChanged(confirmed.record, batches, previous.confirmed.record, previous.queue, previous.visible);
89
120
  return {
90
121
  confirmed,
91
122
  queue: batches,
123
+ replay: predictedState?.replay ?? [],
92
124
  visible: {
93
125
  ...layer,
94
- collection: parseCollection(layer.documents, compositionOf(confirmed.record))
126
+ collection: parseCollection(layer.documents, compositionOf(confirmed.record), previous === undefined ? undefined : {
127
+ text: previous.visible.documents,
128
+ collection: previous.visible.collection
129
+ })
95
130
  }
96
131
  };
97
132
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["/workspace/packages/mdruntime/src/replica.ts"],"sourcesContent":["import type { AttachedModelBinding } from './model.js';\nimport { immutable, type ChangeBatch } from './change.js';\nimport {\n parseCollection,\n readCollection,\n validateCollection,\n type Collection,\n type Composition,\n} from './collection.js';\nimport { overlay, type Layer } from './overlay.js';\nimport { providerRewritten, type Rewriting } from './save.js';\nimport type { ReplicaRecord } from './store.js';\n\nexport type ConfirmedLayer = {\n record: ReplicaRecord;\n collection: Collection;\n};\n\nexport type VisibleLayer = Layer & {\n collection: Collection;\n};\n\nexport type Replica = {\n confirmed: ConfirmedLayer;\n queue: readonly ChangeBatch[];\n visible: VisibleLayer;\n};\n\nexport function compositionOf(record: ReplicaRecord): Composition {\n return {\n collectionRoot: record.collectionRoot,\n model: record.model,\n selection:\n record.typedSelection === null\n ? null\n : { roots: record.typedSelection.roots, model: record.selectionModel },\n };\n}\n\nexport function readConfirmed(record: ReplicaRecord): ConfirmedLayer | null {\n const collection = readCollection(record.documents, compositionOf(record));\n return collection === null ? null : { record, collection };\n}\n\nexport function readStaged(\n record: ReplicaRecord,\n binding: AttachedModelBinding | null,\n): ConfirmedLayer | null {\n if (\n binding !== null &&\n (record.model.status === 'current' || record.selectionModel.status === 'current')\n ) {\n const verdict = validateCollection(\n record.documents,\n record.binaryTargets,\n compositionOf(record),\n binding,\n );\n if (verdict.verdict === 'refuse' && verdict.rule !== 'model-unavailable') return null;\n }\n return readConfirmed(record);\n}\n\nexport function applyReturned(\n confirmed: ConfirmedLayer,\n documents: Readonly<Record<string, string>>,\n revisions: Readonly<Record<string, string>>,\n removals: readonly string[],\n roomVersion: string,\n binding: AttachedModelBinding | null,\n): ConfirmedLayer | null {\n const nextDocuments = { ...confirmed.record.documents, ...documents };\n const nextRevisions = { ...confirmed.record.revisions, ...revisions };\n const binaryTargets = new Set(confirmed.record.binaryTargets);\n for (const path of removals) {\n delete nextDocuments[path];\n delete nextRevisions[path];\n binaryTargets.delete(path);\n }\n return readStaged(\n {\n ...confirmed.record,\n roomVersion,\n documents: nextDocuments,\n revisions: nextRevisions,\n binaryTargets: [...binaryTargets].sort(),\n },\n binding,\n );\n}\n\nfunction predicted(confirmed: ConfirmedLayer, batches: readonly ChangeBatch[]): Layer {\n const composition = compositionOf(confirmed.record);\n let layer: Layer = confirmed.record;\n for (const batch of batches) {\n if (!batch.changes.some((change) => change.kind === 'move')) {\n layer = overlay(layer, [batch]);\n continue;\n }\n const visible = { ...layer, collection: parseCollection(layer.documents, composition) };\n layer = overlay(layer, [providerRewritten(batch, visible)]);\n }\n return layer;\n}\n\nexport function replicaOf(\n confirmed: ConfirmedLayer,\n queue: readonly ChangeBatch[],\n rewriting: Rewriting,\n): Replica {\n const batches = Object.freeze(queue.map(immutable));\n if (batches.length === 0) {\n return {\n confirmed,\n queue: batches,\n visible: {\n documents: confirmed.record.documents,\n binaryTargets: confirmed.record.binaryTargets,\n revisions: confirmed.record.revisions,\n collection: confirmed.collection,\n },\n };\n }\n const layer =\n rewriting === 'provider' ? predicted(confirmed, batches) : overlay(confirmed.record, batches);\n return {\n confirmed,\n queue: batches,\n visible: {\n ...layer,\n collection: parseCollection(layer.documents, compositionOf(confirmed.record)),\n },\n };\n}\n"],"names":["immutable","parseCollection","readCollection","validateCollection","overlay","providerRewritten","compositionOf","record","collectionRoot","model","selection","typedSelection","roots","selectionModel","readConfirmed","collection","documents","readStaged","binding","status","verdict","binaryTargets","rule","applyReturned","confirmed","revisions","removals","roomVersion","nextDocuments","nextRevisions","Set","path","delete","sort","predicted","batches","composition","layer","batch","changes","some","change","kind","visible","replicaOf","queue","rewriting","Object","freeze","map","length"],"mappings":"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"}
1
+ {"version":3,"sources":["/workspace/packages/mdruntime/src/replica.ts"],"sourcesContent":["import type { AttachedModelBinding } from './model.js';\nimport { immutable, type ChangeBatch } from './change.js';\nimport {\n parseCollection,\n readCollection,\n validateCollection,\n type Collection,\n type Composition,\n} from './collection.js';\nimport { overlay, overlayChanged, sameLayerText, type Layer } from './overlay.js';\nimport { providerRewritten, type Rewriting } from './save.js';\nimport type { ReplicaRecord } from './store.js';\n\nexport type ConfirmedLayer = {\n record: ReplicaRecord;\n collection: Collection;\n};\n\nexport type VisibleLayer = Layer & {\n collection: Collection;\n};\n\nexport type Replica = {\n confirmed: ConfirmedLayer;\n queue: readonly ChangeBatch[];\n visible: VisibleLayer;\n replay: readonly ReplayStep[];\n};\n\ntype ReplayStep = {\n id: string;\n before: Layer;\n after: Layer;\n effective: ChangeBatch;\n collection?: Collection;\n};\n\nexport function compositionOf(record: ReplicaRecord): Composition {\n return {\n collectionRoot: record.collectionRoot,\n model: record.model,\n selection:\n record.typedSelection === null\n ? null\n : { roots: record.typedSelection.roots, model: record.selectionModel },\n };\n}\n\nexport function readConfirmed(\n record: ReplicaRecord,\n previous?: ConfirmedLayer,\n): ConfirmedLayer | null {\n const collection = readCollection(\n record.documents,\n compositionOf(record),\n previous === undefined\n ? undefined\n : { text: previous.record.documents, collection: previous.collection },\n );\n return collection === null ? null : { record, collection };\n}\n\nexport function readStaged(\n record: ReplicaRecord,\n binding: AttachedModelBinding | null,\n previous?: ConfirmedLayer,\n): ConfirmedLayer | null {\n if (\n binding !== null &&\n (record.model.status === 'current' || record.selectionModel.status === 'current') &&\n (previous === undefined ||\n !sameLayerText(record, previous.record) ||\n record.model !== previous.record.model ||\n record.selectionModel !== previous.record.selectionModel)\n ) {\n const verdict = validateCollection(\n record.documents,\n record.binaryTargets,\n compositionOf(record),\n binding,\n );\n if (verdict.verdict === 'refuse' && verdict.rule !== 'model-unavailable') return null;\n }\n return readConfirmed(record, previous);\n}\n\nexport function applyReturned(\n confirmed: ConfirmedLayer,\n documents: Readonly<Record<string, string>>,\n revisions: Readonly<Record<string, string>>,\n removals: readonly string[],\n roomVersion: string,\n binding: AttachedModelBinding | null,\n): ConfirmedLayer | null {\n const nextDocuments = { ...confirmed.record.documents, ...documents };\n const nextRevisions = { ...confirmed.record.revisions, ...revisions };\n const binaryTargets = new Set(confirmed.record.binaryTargets);\n for (const path of removals) {\n delete nextDocuments[path];\n delete nextRevisions[path];\n binaryTargets.delete(path);\n }\n return readStaged(\n {\n ...confirmed.record,\n roomVersion,\n documents: nextDocuments,\n revisions: nextRevisions,\n binaryTargets: [...binaryTargets].sort(),\n },\n binding,\n confirmed,\n );\n}\n\nfunction predicted(\n confirmed: ConfirmedLayer,\n batches: readonly ChangeBatch[],\n previous?: Replica,\n): { layer: Layer; replay: readonly ReplayStep[] } {\n const composition = compositionOf(confirmed.record);\n let layer: Layer = confirmed.record;\n const replay: ReplayStep[] = [];\n const prior = new Map(previous?.replay.map((step) => [step.id, step]) ?? []);\n for (const batch of batches) {\n const before = layer;\n const old = prior.get(batch.id);\n const hasMove = batch.changes.some((change) => change.kind === 'move');\n const reuseRewrite =\n old?.collection !== undefined &&\n sameLayerText(before, old.before) &&\n old.collection.composition.collectionRoot === composition.collectionRoot &&\n old.collection.composition.model === composition.model &&\n old.collection.composition.selection?.model === composition.selection?.model &&\n JSON.stringify(old.collection.composition.selection?.roots) ===\n JSON.stringify(composition.selection?.roots);\n const collection = hasMove\n ? reuseRewrite\n ? old.collection\n : parseCollection(\n before.documents,\n composition,\n old?.collection === undefined\n ? { text: confirmed.record.documents, collection: confirmed.collection }\n : { text: old.before.documents, collection: old.collection },\n )\n : undefined;\n const effective =\n collection === undefined\n ? batch\n : reuseRewrite\n ? old.effective\n : providerRewritten(batch, { ...before, collection });\n layer =\n old === undefined\n ? overlay(before, [effective])\n : overlayChanged(before, [effective], old.before, [old.effective], old.after);\n replay.push({\n id: batch.id,\n before,\n after: layer,\n effective,\n ...(collection === undefined ? {} : { collection }),\n });\n }\n return { layer, replay };\n}\n\nexport function replicaOf(\n confirmed: ConfirmedLayer,\n queue: readonly ChangeBatch[],\n rewriting: Rewriting,\n previous?: Replica,\n): Replica {\n const batches = Object.freeze(queue.map(immutable));\n if (batches.length === 0) {\n return {\n confirmed,\n queue: batches,\n visible: {\n documents: confirmed.record.documents,\n binaryTargets: confirmed.record.binaryTargets,\n revisions: confirmed.record.revisions,\n collection: confirmed.collection,\n },\n replay: [],\n };\n }\n const predictedState = rewriting === 'provider' ? predicted(confirmed, batches, previous) : null;\n const layer =\n rewriting === 'provider'\n ? predictedState!.layer\n : previous === undefined\n ? overlay(confirmed.record, batches)\n : overlayChanged(\n confirmed.record,\n batches,\n previous.confirmed.record,\n previous.queue,\n previous.visible,\n );\n return {\n confirmed,\n queue: batches,\n replay: predictedState?.replay ?? [],\n visible: {\n ...layer,\n collection: parseCollection(\n layer.documents,\n compositionOf(confirmed.record),\n previous === undefined\n ? undefined\n : { text: previous.visible.documents, collection: previous.visible.collection },\n ),\n },\n };\n}\n"],"names":["immutable","parseCollection","readCollection","validateCollection","overlay","overlayChanged","sameLayerText","providerRewritten","compositionOf","record","collectionRoot","model","selection","typedSelection","roots","selectionModel","readConfirmed","previous","collection","documents","undefined","text","readStaged","binding","status","verdict","binaryTargets","rule","applyReturned","confirmed","revisions","removals","roomVersion","nextDocuments","nextRevisions","Set","path","delete","sort","predicted","batches","composition","layer","replay","prior","Map","map","step","id","batch","before","old","get","hasMove","changes","some","change","kind","reuseRewrite","JSON","stringify","effective","after","push","replicaOf","queue","rewriting","Object","freeze","length","visible","predictedState"],"mappings":"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"}
package/dist/store.d.ts CHANGED
@@ -3,7 +3,7 @@ import type { Capability, Discovery, OperationScopes, ProviderLimit, ReplicaAdmi
3
3
  import type { ConversationMessage } from './adapter.js';
4
4
  import type { ChangeBatch } from './change.js';
5
5
  import type { InstructionFile } from './file.js';
6
- import type { QueueOutcome } from './outcome.js';
6
+ import type { SubmissionOutcome } from './outcome.js';
7
7
  export type ReplicaRecord = {
8
8
  collectionRoot: string;
9
9
  locator: string;
@@ -20,10 +20,14 @@ export type ReplicaRecord = {
20
20
  binaryTargets: readonly string[];
21
21
  revisions: Readonly<Record<string, string>>;
22
22
  };
23
+ export type OutcomeRecord = {
24
+ locator: string;
25
+ id: string;
26
+ outcome: SubmissionOutcome;
27
+ };
23
28
  export type QueueRecord = {
24
29
  locator: string;
25
30
  batches: readonly ChangeBatch[];
26
- outcomes: Readonly<Record<string, QueueOutcome>>;
27
31
  };
28
32
  export type DraftRecord = {
29
33
  locator: string;
@@ -46,9 +50,24 @@ export type InstructionRecord = {
46
50
  files: readonly InstructionFile[];
47
51
  turn: string | null;
48
52
  };
53
+ export type RecordWrite = {
54
+ next: ReplicaRecord;
55
+ previous: ReplicaRecord | null;
56
+ queue: readonly ChangeBatch[];
57
+ previousQueue?: readonly ChangeBatch[];
58
+ outcomes?: readonly {
59
+ id: string;
60
+ outcome: SubmissionOutcome | null;
61
+ }[];
62
+ consumedDrafts?: readonly string[];
63
+ };
49
64
  export type RuntimeStore = {
50
65
  all(): Promise<readonly ReplicaRecord[]>;
51
- publish(record: ReplicaRecord): Promise<void>;
66
+ write(input: RecordWrite): Promise<void>;
67
+ revokeModels(records: readonly {
68
+ record: ReplicaRecord;
69
+ queue: readonly ChangeBatch[];
70
+ }[]): Promise<void>;
52
71
  lastCompleted(): Promise<string | null>;
53
72
  complete(at: string): Promise<void>;
54
73
  providerLimits(): Promise<readonly ProviderLimit[]>;
@@ -56,6 +75,8 @@ export type RuntimeStore = {
56
75
  slots(): Promise<NonNullable<Discovery['slots']>>;
57
76
  declare(limits: readonly ProviderLimit[], capabilities: readonly Capability[], slots: NonNullable<Discovery['slots']>): Promise<void>;
58
77
  queues(): Promise<readonly QueueRecord[]>;
78
+ outcomes(): Promise<readonly OutcomeRecord[]>;
79
+ markSubmitted(locator: string, id: string): Promise<boolean>;
59
80
  drafts(): Promise<readonly DraftRecord[]>;
60
81
  presentation(): Promise<readonly PresentationRecord[]>;
61
82
  present(record: PresentationRecord): Promise<void>;
@@ -67,8 +88,6 @@ export type RuntimeStore = {
67
88
  dropInstruction(conversation: string): Promise<void>;
68
89
  keep(draft: DraftRecord): Promise<void>;
69
90
  discard(locator: string, path: string): Promise<void>;
70
- append(queue: QueueRecord, consumed: readonly string[]): Promise<void>;
71
- writeQueue(queue: QueueRecord): Promise<void>;
72
91
  dropRooms(locators: readonly string[]): Promise<void>;
73
92
  generation(): Promise<string | null>;
74
93
  rememberGeneration(value: string): Promise<void>;