@mengine/medeo-tool 1.2.1-alpha.9 → 1.3.1-alpha.8

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,5 +1,5 @@
1
- import { i as createRelationId, n as EntitySandbox, r as createEntityId, t as EditSandboxSession } from "./script-session-CHyIUBkO.mjs";
2
- import { EntityTimelineEditor } from "@mengine/medeo-client";
1
+ import { a as createRelationId, i as createEntityId, n as EntitySandbox, t as EditSandboxSession } from "./script-session-C2uQHYt4.mjs";
2
+ import { EntityTimelineEditor, assertCanonicalEditorResources, assertMediaAssetWritePolicy } from "@mengine/medeo-client";
3
3
  import { parentPort, workerData } from "node:worker_threads";
4
4
  import { randomUUID } from "node:crypto";
5
5
  import vm from "node:vm";
@@ -21,6 +21,7 @@ var EntityEditSandboxSession = class {
21
21
  document;
22
22
  entitySandbox;
23
23
  entityRevision;
24
+ baseRows;
24
25
  domainIdFactory;
25
26
  logs = [];
26
27
  onLog;
@@ -36,6 +37,12 @@ var EntityEditSandboxSession = class {
36
37
  constructor(document, options) {
37
38
  this.document = structuredClone(document);
38
39
  this.entityRevision = options?.entityState?.revision ?? 0;
40
+ this.baseRows = toDslRows(options?.entityState ?? {
41
+ revision: 0,
42
+ audioScriptEntityId: null,
43
+ entities: [],
44
+ relations: []
45
+ });
39
46
  this.domainIdFactory = options?.domainIdFactory ?? (() => {
40
47
  throw new Error("Entity id factory is unavailable in this sandbox host");
41
48
  });
@@ -56,6 +63,8 @@ var EntityEditSandboxSession = class {
56
63
  }
57
64
  buildPlan(baseVersion) {
58
65
  const entityPlan = this.entitySandbox.buildPlan();
66
+ assertCanonicalEditorResources(toDslRows(entityPlan.rows));
67
+ assertMediaAssetWritePolicy(this.baseRows, toDslRows(entityPlan.rows));
59
68
  return {
60
69
  plan_kind: "entities",
61
70
  doc_id: this.document.meta.draft_id ?? "",
@@ -75,6 +84,7 @@ var EntityEditSandboxSession = class {
75
84
  }
76
85
  buildEditFacade() {
77
86
  return {
87
+ setDocumentAudioScript: (entityId) => this.entitySandbox.setDocumentAudioScript(entityId),
78
88
  insertClip: (input) => this.runNativeEdit((editor) => editor.insertClip(input)),
79
89
  insertPlacedClip: (input) => this.runNativeEdit((editor) => editor.insertPlacedClip(input)),
80
90
  updateClipMarker: (input) => this.runNativeEdit((editor) => editor.updateClipMarker(input)),
@@ -99,7 +109,8 @@ var EntityEditSandboxSession = class {
99
109
  setBgm: (input) => this.runNativeEdit((editor) => editor.setBgm(input)),
100
110
  deleteBgm: (input) => this.runNativeEdit((editor) => editor.deleteBgm(input)),
101
111
  setCaptionVisibility: (input) => this.runNativeEdit((editor) => editor.setCaptionVisibility(input)),
102
- patchCaptionStyle: (input) => this.runNativeEdit((editor) => editor.patchCaptionStyle(input))
112
+ patchCaptionStyle: (input) => this.runNativeEdit((editor) => editor.patchCaptionStyle(input)),
113
+ insertCaptionClip: (input) => this.runNativeEdit((editor) => editor.insertCaptionClip(input))
103
114
  };
104
115
  }
105
116
  runNativeEdit(mutate) {
@@ -108,7 +119,7 @@ var EntityEditSandboxSession = class {
108
119
  const before = this.entitySandbox.buildPlan().rows;
109
120
  const editor = new EntityTimelineEditor(toDslRows(before), this.domainIdFactory);
110
121
  const result = mutate(editor);
111
- const expected = fromDslRows(editor.rows(), before.revision);
122
+ const expected = fromDslRows(editor.rows(), before.revision, before.audioScriptEntityId);
112
123
  applyGraphDiff(this.entitySandbox, before, expected);
113
124
  const applied = this.entitySandbox.buildPlan().rows;
114
125
  if (!graphRowsEqual(applied, expected)) throw new Error("Entity timeline command diff did not reproduce the editor result");
@@ -121,6 +132,7 @@ var EntityEditSandboxSession = class {
121
132
  snapshot() {
122
133
  return {
123
134
  revision: this.entityRevision,
135
+ audioScriptEntityId: this.entitySandbox.audioScriptEntityId,
124
136
  entities: this.entitySandbox.entities.list(),
125
137
  relations: this.entitySandbox.relations.list()
126
138
  };
@@ -175,7 +187,7 @@ function applyGraphDiff(sandbox, before, after) {
175
187
  const previous = beforeEntities.get(entity.entity_id);
176
188
  return previous != null && !jsonEqual(previous.payload, entity.payload);
177
189
  }).sort((left, right) => left.entity_id.localeCompare(right.entity_id));
178
- for (const entity of entitiesToUpdate) sandbox.entities.update({
190
+ for (const entity of entitiesToUpdate) sandbox.replaceOwnedPayload({
179
191
  entity_id: entity.entity_id,
180
192
  payload: entity.payload
181
193
  });
@@ -201,11 +213,22 @@ function linkRelation(sandbox, relation) {
201
213
  });
202
214
  return;
203
215
  }
204
- if (relation.relation_kind === "audio-script-render") {
205
- sandbox.relations.linkAudioScriptRender({
216
+ if (relation.relation_kind === "phonetic-script-render") {
217
+ const firstIsVoice = sandbox.entities.get(relation.endpoint_0_entity_id)?.entity_kind === "voice";
218
+ sandbox.relations.linkPhoneticScriptRender({
206
219
  relation_id: relation.relation_id,
207
- output_entity_id: relation.endpoint_0_entity_id,
208
- script_entity_id: relation.endpoint_1_entity_id,
220
+ output_entity_id: firstIsVoice ? relation.endpoint_0_entity_id : relation.endpoint_1_entity_id,
221
+ phonetic_script_entity_id: firstIsVoice ? relation.endpoint_1_entity_id : relation.endpoint_0_entity_id,
222
+ trace: relation.trace
223
+ });
224
+ return;
225
+ }
226
+ if (relation.relation_kind === "audio-script-source") {
227
+ const firstIsScript = sandbox.entities.get(relation.endpoint_0_entity_id)?.entity_kind === "audio-script";
228
+ sandbox.relations.linkAudioScriptSource({
229
+ relation_id: relation.relation_id,
230
+ script_entity_id: firstIsScript ? relation.endpoint_0_entity_id : relation.endpoint_1_entity_id,
231
+ source_entity_id: firstIsScript ? relation.endpoint_1_entity_id : relation.endpoint_0_entity_id,
209
232
  trace: relation.trace
210
233
  });
211
234
  return;
@@ -236,9 +259,10 @@ function toDslRows(snapshot) {
236
259
  }))
237
260
  };
238
261
  }
239
- function fromDslRows(rows, revision) {
262
+ function fromDslRows(rows, revision, audioScriptEntityId) {
240
263
  return {
241
264
  revision,
265
+ audioScriptEntityId,
242
266
  entities: rows.entities.map((entity) => ({
243
267
  entity_id: entity.entityId,
244
268
  entity_kind: entity.entityKind,
@@ -263,7 +287,7 @@ function jsonEqual(left, right) {
263
287
  return leftKeys.length === rightKeys.length && leftKeys.every((key, index) => key === rightKeys[index] && jsonEqual(left[key], right[key]));
264
288
  }
265
289
  function graphRowsEqual(left, right) {
266
- if (left.revision !== right.revision || left.entities.length !== right.entities.length || left.relations.length !== right.relations.length) return false;
290
+ if (left.revision !== right.revision || left.audioScriptEntityId !== right.audioScriptEntityId || left.entities.length !== right.entities.length || left.relations.length !== right.relations.length) return false;
267
291
  const rightEntities = new Map(right.entities.map((entity) => [entity.entity_id, entity]));
268
292
  const rightRelations = new Map(right.relations.map((relation) => [relation.relation_id, relation]));
269
293
  return left.entities.every((entity) => jsonEqual(entity, rightEntities.get(entity.entity_id))) && left.relations.every((relation) => jsonEqual(relation, rightRelations.get(relation.relation_id)));
@@ -1 +1 @@
1
- {"version":3,"file":"worker-entry.mjs","names":[],"sources":["../src/sandbox/entity-script-session.ts","../src/sandbox/worker-entry.ts"],"sourcesContent":["import {\n EntityTimelineEditor,\n type ClipEntityId,\n type DeleteBgmInput,\n type DeleteClipInput,\n type DeleteClipTreeInput,\n type DeleteVoiceoverInput,\n type InsertClipInput,\n type InsertMediaClipInput,\n type InsertMediaClipsInput,\n type InsertPlacedClipInput,\n type MoveClipInput,\n type MoveClipsToStartsInput,\n type MoveSequentialClipsInput,\n type MoveVoiceoverInput,\n type PatchCaptionStyleInput,\n type ReplaceMediaClipInput,\n type ReplaceSequentialClipsInput,\n type ReplaceClipContentInput,\n type SetBgmInput,\n type SetCaptionVisibilityInput,\n type SetClipPlacementInput,\n type SetClipSpeedInput,\n type SetClipVolumeInput,\n type TrimClipInput,\n type UpdateClipInput,\n type UpdateClipMarkerInput,\n type VideoDocument,\n type VoiceoverTakeInput,\n type VoiceoverTakeResult,\n} from '@mengine/medeo-client';\nimport {\n createEntityId,\n createRelationId,\n type EntityRelationRows,\n type EntityRow,\n type RelationRow,\n} from '@mengine/medeo-dsl';\n\nimport type {\n CreateEntityInput,\n EntityFacade,\n EntityStoreSnapshot,\n LinkRelationInput,\n RelationFacade,\n SandboxEntity,\n SandboxRelation,\n} from '../entity/entity-contract.ts';\nimport { EntitySandbox, type DomainIdFactory } from '../entity/entity-sandbox.ts';\nimport type { ChangePlan, ConsoleShim, EditSandboxSessionOptions, SandboxCheckpoint } from './script-session.ts';\n\nconst LOG_LINE_MAX = 2000;\nconst LOG_LINE_CAP = 1000;\nconst LOG_BYTE_CAP = 64 * 1024;\nconst TRUNCATE_MARK = '[truncated]';\nconst LOG_TRUNCATED = '[log truncated]';\n\n/** Model-facing timeline mutations whose source of truth is the Medeo Entity graph. */\nexport interface EntityEditFacade {\n insertClip(input: InsertClipInput): ClipEntityId;\n insertPlacedClip(input: InsertPlacedClipInput): ClipEntityId;\n updateClipMarker(input: UpdateClipMarkerInput): void;\n setClipPlacement(input: SetClipPlacementInput): void;\n moveSequentialClips(input: MoveSequentialClipsInput): void;\n moveClip(input: MoveClipInput): void;\n replaceClipContent(input: ReplaceClipContentInput): void;\n insertMediaClip(input: InsertMediaClipInput): ClipEntityId;\n insertMediaClips(input: InsertMediaClipsInput): readonly ClipEntityId[];\n replaceMediaClip(input: ReplaceMediaClipInput): void;\n setClipVolume(input: SetClipVolumeInput): void;\n setClipSpeed(input: SetClipSpeedInput): void;\n trimClip(input: TrimClipInput): void;\n replaceSequentialClips(input: ReplaceSequentialClipsInput): readonly ClipEntityId[];\n deleteClip(input: DeleteClipInput): void;\n deleteClipTree(input: DeleteClipTreeInput): void;\n updateClip(input: UpdateClipInput): void;\n upsertVoiceoverTake(input: VoiceoverTakeInput): VoiceoverTakeResult;\n moveVoiceover(input: MoveVoiceoverInput): void;\n moveClipsToStarts(input: MoveClipsToStartsInput): void;\n deleteVoiceover(input: DeleteVoiceoverInput): void;\n setBgm(input: SetBgmInput): ClipEntityId;\n deleteBgm(input: DeleteBgmInput): void;\n setCaptionVisibility(input: SetCaptionVisibilityInput): void;\n patchCaptionStyle(input: PatchCaptionStyleInput): void;\n}\n\nexport interface EntityTimelineFacade {\n /** Return the current graph draft, including uncommitted commands. */\n snapshot(): EntityStoreSnapshot;\n}\n\n/**\n * Entity-only sandbox session used by the production model path.\n *\n * Native timeline operations execute against a detached graph editor and are\n * then journaled as ordinary EntitySandbox commands. VideoDocument is retained\n * only for the request's document identity; it is never edited or projected\n * back into the graph.\n */\nexport class EntityEditSandboxSession {\n private readonly document: VideoDocument;\n private readonly entitySandbox: EntitySandbox;\n private readonly entityRevision: number;\n private readonly domainIdFactory: DomainIdFactory;\n private readonly logs: string[] = [];\n private readonly onLog: ((line: string) => void) | undefined;\n private logBytes = 0;\n private logCapped = false;\n\n readonly edit: EntityEditFacade;\n readonly timeline: EntityTimelineFacade;\n readonly entities: EntityFacade;\n readonly relations: RelationFacade;\n readonly console: ConsoleShim;\n readonly checkpoint: () => SandboxCheckpoint;\n readonly rollbackTo: (cp: SandboxCheckpoint) => void;\n\n constructor(document: VideoDocument, options?: EditSandboxSessionOptions) {\n this.document = structuredClone(document);\n this.entityRevision = options?.entityState?.revision ?? 0;\n this.domainIdFactory =\n options?.domainIdFactory ??\n (() => {\n throw new Error('Entity id factory is unavailable in this sandbox host');\n });\n this.onLog = options?.onLog;\n this.entitySandbox = new EntitySandbox({\n state: options?.entityState,\n idFactory: this.domainIdFactory,\n onCommand: options?.onEntityCommand,\n onTruncate: options?.onEntityTruncate,\n });\n\n this.edit = this.buildEditFacade();\n this.timeline = { snapshot: () => this.snapshot() };\n this.entities = this.entitySandbox.entities;\n this.relations = this.entitySandbox.relations;\n this.console = this.buildConsoleShim();\n this.checkpoint = () => ({ index: this.entitySandbox.commandCount });\n this.rollbackTo = (cp) => this.entitySandbox.rollbackTo(cp.index);\n }\n\n buildPlan(baseVersion: string): ChangePlan {\n const entityPlan = this.entitySandbox.buildPlan();\n return {\n plan_kind: 'entities',\n doc_id: this.document.meta.draft_id ?? '',\n base_version: baseVersion,\n ops: [],\n entity_base_revision: entityPlan.base_revision,\n entity_commands: entityPlan.commands,\n entity_rows: entityPlan.rows,\n deleted_entity_ids: entityPlan.deleted_entity_ids,\n deleted_relation_ids: entityPlan.deleted_relation_ids,\n preview: this.entitySandbox.renderPreview(),\n logs: this.logs.slice(),\n };\n }\n\n getLogs(): readonly string[] {\n return this.logs;\n }\n\n private buildEditFacade(): EntityEditFacade {\n return {\n insertClip: (input) => this.runNativeEdit((editor) => editor.insertClip(input)),\n insertPlacedClip: (input) => this.runNativeEdit((editor) => editor.insertPlacedClip(input)),\n updateClipMarker: (input) => this.runNativeEdit((editor) => editor.updateClipMarker(input)),\n setClipPlacement: (input) => this.runNativeEdit((editor) => editor.setClipPlacement(input)),\n moveSequentialClips: (input) => this.runNativeEdit((editor) => editor.moveSequentialClips(input)),\n moveClip: (input) => this.runNativeEdit((editor) => editor.moveClip(input)),\n replaceClipContent: (input) => this.runNativeEdit((editor) => editor.replaceClipContent(input)),\n insertMediaClip: (input) => this.runNativeEdit((editor) => editor.insertMediaClip(input)),\n insertMediaClips: (input) => this.runNativeEdit((editor) => editor.insertMediaClips(input)),\n replaceMediaClip: (input) => this.runNativeEdit((editor) => editor.replaceMediaClip(input)),\n setClipVolume: (input) => this.runNativeEdit((editor) => editor.setClipVolume(input)),\n setClipSpeed: (input) => this.runNativeEdit((editor) => editor.setClipSpeed(input)),\n trimClip: (input) => this.runNativeEdit((editor) => editor.trimClip(input)),\n replaceSequentialClips: (input) => this.runNativeEdit((editor) => editor.replaceSequentialClips(input)),\n deleteClip: (input) => this.runNativeEdit((editor) => editor.deleteClip(input)),\n deleteClipTree: (input) => this.runNativeEdit((editor) => editor.deleteClipTree(input)),\n updateClip: (input) => this.runNativeEdit((editor) => editor.updateClip(input)),\n upsertVoiceoverTake: (input) => this.runNativeEdit((editor) => editor.upsertVoiceoverTake(input)),\n moveVoiceover: (input) => this.runNativeEdit((editor) => editor.moveVoiceover(input)),\n moveClipsToStarts: (input) => this.runNativeEdit((editor) => editor.moveClipsToStarts(input)),\n deleteVoiceover: (input) => this.runNativeEdit((editor) => editor.deleteVoiceover(input)),\n setBgm: (input) => this.runNativeEdit((editor) => editor.setBgm(input)),\n deleteBgm: (input) => this.runNativeEdit((editor) => editor.deleteBgm(input)),\n setCaptionVisibility: (input) => this.runNativeEdit((editor) => editor.setCaptionVisibility(input)),\n patchCaptionStyle: (input) => this.runNativeEdit((editor) => editor.patchCaptionStyle(input)),\n };\n }\n\n private runNativeEdit<T>(mutate: (editor: EntityTimelineEditor) => T): T {\n const checkpoint = this.entitySandbox.commandCount;\n try {\n const before = this.entitySandbox.buildPlan().rows;\n const editor = new EntityTimelineEditor(toDslRows(before), this.domainIdFactory);\n const result = mutate(editor);\n const expected = fromDslRows(editor.rows(), before.revision);\n applyGraphDiff(this.entitySandbox, before, expected);\n const applied = this.entitySandbox.buildPlan().rows;\n if (!graphRowsEqual(applied, expected)) {\n throw new Error('Entity timeline command diff did not reproduce the editor result');\n }\n return result;\n } catch (error) {\n this.entitySandbox.rollbackTo(checkpoint);\n throw error;\n }\n }\n\n private snapshot(): EntityStoreSnapshot {\n return {\n revision: this.entityRevision,\n entities: this.entitySandbox.entities.list(),\n relations: this.entitySandbox.relations.list(),\n };\n }\n\n private appendLog(line: string): void {\n if (this.logCapped) return;\n if (this.logs.length >= LOG_LINE_CAP || this.logBytes >= LOG_BYTE_CAP) {\n this.logs.push(LOG_TRUNCATED);\n this.logCapped = true;\n this.onLog?.(LOG_TRUNCATED);\n return;\n }\n const out =\n line.length > LOG_LINE_MAX ? `${line.slice(0, LOG_LINE_MAX - TRUNCATE_MARK.length)}${TRUNCATE_MARK}` : line;\n this.logs.push(out);\n this.logBytes += out.length;\n this.onLog?.(out);\n }\n\n private buildConsoleShim(): ConsoleShim {\n const write = (...args: unknown[]) => this.appendLog(args.map(formatLogArg).join(' '));\n return { log: write, info: write, warn: write, error: write };\n }\n}\n\nfunction applyGraphDiff(sandbox: EntitySandbox, before: EntityStoreSnapshot, after: EntityStoreSnapshot): void {\n const beforeEntities = new Map(before.entities.map((entity) => [entity.entity_id, entity]));\n const afterEntities = new Map(after.entities.map((entity) => [entity.entity_id, entity]));\n const beforeRelations = new Map(before.relations.map((relation) => [relation.relation_id, relation]));\n const afterRelations = new Map(after.relations.map((relation) => [relation.relation_id, relation]));\n\n for (const [entityId, previous] of beforeEntities) {\n const next = afterEntities.get(entityId);\n if (next != null && next.entity_kind !== previous.entity_kind) {\n throw new Error(\n `Entity id \"${entityId}\" cannot change kind from \"${previous.entity_kind}\" to \"${next.entity_kind}\"`,\n );\n }\n }\n for (const [relationId, previous] of beforeRelations) {\n const next = afterRelations.get(relationId);\n if (\n next != null &&\n (next.relation_kind !== previous.relation_kind ||\n next.endpoint_0_entity_id !== previous.endpoint_0_entity_id ||\n next.endpoint_1_entity_id !== previous.endpoint_1_entity_id)\n ) {\n throw new Error(`Relation id \"${relationId}\" cannot change kind or persisted endpoint positions`);\n }\n }\n\n const relationIdsToReplace = new Set(\n [...beforeRelations]\n .filter(([relationId, previous]) => {\n const next = afterRelations.get(relationId);\n return next != null && (!jsonEqual(previous.metadata, next.metadata) || !jsonEqual(previous.trace, next.trace));\n })\n .map(([relationId]) => relationId),\n );\n const relationIdsToUnlink = [...beforeRelations.keys()]\n .filter((relationId) => !afterRelations.has(relationId) || relationIdsToReplace.has(relationId))\n .sort();\n for (const relationId of relationIdsToUnlink) sandbox.relations.unlink({ relation_id: relationId });\n\n const entityIdsToDelete = [...beforeEntities.keys()].filter((entityId) => !afterEntities.has(entityId)).sort();\n for (const entityId of entityIdsToDelete) sandbox.entities.delete({ entity_id: entityId });\n\n const entitiesToCreate = [...afterEntities.values()]\n .filter((entity) => !beforeEntities.has(entity.entity_id))\n .sort((left, right) => left.entity_id.localeCompare(right.entity_id));\n for (const entity of entitiesToCreate) sandbox.entities.create(entity as CreateEntityInput);\n\n const entitiesToUpdate = [...afterEntities.values()]\n .filter((entity) => {\n const previous = beforeEntities.get(entity.entity_id);\n return previous != null && !jsonEqual(previous.payload, entity.payload);\n })\n .sort((left, right) => left.entity_id.localeCompare(right.entity_id));\n for (const entity of entitiesToUpdate) {\n sandbox.entities.update({ entity_id: entity.entity_id, payload: entity.payload });\n }\n\n const relationsToLink = [...afterRelations.values()]\n .filter((relation) => !beforeRelations.has(relation.relation_id) || relationIdsToReplace.has(relation.relation_id))\n .sort((left, right) => left.relation_id.localeCompare(right.relation_id));\n for (const relation of relationsToLink) linkRelation(sandbox, relation);\n}\n\nfunction linkRelation(sandbox: EntitySandbox, relation: SandboxRelation): void {\n if (relation.relation_kind === 'generated') {\n sandbox.relations.linkGenerated({\n relation_id: relation.relation_id,\n output_entity_id: relation.endpoint_0_entity_id,\n input_entity_id: relation.endpoint_1_entity_id,\n trace: relation.trace,\n });\n return;\n }\n if (relation.relation_kind === 'clip-anchor') {\n sandbox.relations.linkClipAnchor({\n relation_id: relation.relation_id,\n child_clip_entity_id: relation.endpoint_0_entity_id,\n host_clip_entity_id: relation.endpoint_1_entity_id,\n trace: relation.trace,\n });\n return;\n }\n if (relation.relation_kind === 'audio-script-render') {\n sandbox.relations.linkAudioScriptRender({\n relation_id: relation.relation_id,\n output_entity_id: relation.endpoint_0_entity_id,\n script_entity_id: relation.endpoint_1_entity_id,\n trace: relation.trace,\n });\n return;\n }\n sandbox.relations.link({\n relation_id: relation.relation_id,\n relation_kind: relation.relation_kind,\n endpoint_0_entity_id: relation.endpoint_0_entity_id,\n endpoint_1_entity_id: relation.endpoint_1_entity_id,\n metadata: relation.metadata,\n trace: relation.trace,\n } as LinkRelationInput);\n}\n\nfunction toDslRows(snapshot: EntityStoreSnapshot): EntityRelationRows {\n return {\n entities: snapshot.entities.map((entity) => ({\n entityId: createEntityId(entity.entity_id),\n entityKind: entity.entity_kind,\n payload: structuredClone(entity.payload),\n })) as EntityRow[],\n relations: snapshot.relations.map((relation) => ({\n relationId: createRelationId(relation.relation_id),\n relationKind: relation.relation_kind,\n endpoint0EntityId: createEntityId(relation.endpoint_0_entity_id),\n endpoint1EntityId: createEntityId(relation.endpoint_1_entity_id),\n metadata: structuredClone(relation.metadata),\n trace: structuredClone(relation.trace),\n })) as RelationRow[],\n };\n}\n\nfunction fromDslRows(rows: EntityRelationRows, revision: number): EntityStoreSnapshot {\n return {\n revision,\n entities: rows.entities.map(\n (entity) =>\n ({\n entity_id: entity.entityId,\n entity_kind: entity.entityKind,\n payload: structuredClone(entity.payload),\n }) as SandboxEntity,\n ),\n relations: rows.relations.map(\n (relation) =>\n ({\n relation_id: relation.relationId,\n relation_kind: relation.relationKind,\n endpoint_0_entity_id: relation.endpoint0EntityId,\n endpoint_1_entity_id: relation.endpoint1EntityId,\n metadata: structuredClone(relation.metadata),\n trace: structuredClone(relation.trace),\n }) as SandboxRelation,\n ),\n };\n}\n\nfunction jsonEqual(left: unknown, right: unknown): boolean {\n if (Object.is(left, right)) return true;\n if (Array.isArray(left) || Array.isArray(right)) {\n return (\n Array.isArray(left) &&\n Array.isArray(right) &&\n left.length === right.length &&\n left.every((value, index) => jsonEqual(value, right[index]))\n );\n }\n if (!isRecord(left) || !isRecord(right)) return false;\n const leftKeys = Object.keys(left).sort();\n const rightKeys = Object.keys(right).sort();\n return (\n leftKeys.length === rightKeys.length &&\n leftKeys.every((key, index) => key === rightKeys[index] && jsonEqual(left[key], right[key]))\n );\n}\n\nfunction graphRowsEqual(left: EntityStoreSnapshot, right: EntityStoreSnapshot): boolean {\n if (\n left.revision !== right.revision ||\n left.entities.length !== right.entities.length ||\n left.relations.length !== right.relations.length\n ) {\n return false;\n }\n const rightEntities = new Map(right.entities.map((entity) => [entity.entity_id, entity]));\n const rightRelations = new Map(right.relations.map((relation) => [relation.relation_id, relation]));\n return (\n left.entities.every((entity) => jsonEqual(entity, rightEntities.get(entity.entity_id))) &&\n left.relations.every((relation) => jsonEqual(relation, rightRelations.get(relation.relation_id)))\n );\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value);\n}\n\nfunction formatLogArg(value: unknown): string {\n if (typeof value === 'string') return value;\n if (typeof value === 'number' || typeof value === 'boolean' || value === null || value === undefined) {\n return String(value);\n }\n try {\n return JSON.stringify(value);\n } catch {\n return '[unstringifiable]';\n }\n}\n","/// <reference types=\"node\" />\n\nimport { randomUUID } from 'node:crypto';\nimport vm from 'node:vm';\nimport { parentPort, workerData } from 'node:worker_threads';\n\nimport type { JournalEntry, PartIdFactory, VideoDocument } from '@mengine/medeo-client';\n\nimport type { EntityCommand, EntityStoreSnapshot } from '../entity/entity-contract.ts';\nimport type { DomainIdFactory } from '../entity/entity-sandbox.ts';\nimport { EntityEditSandboxSession } from './entity-script-session.ts';\nimport { EditSandboxSession, type EditSandboxSessionOptions } from './script-session.ts';\n\n/**\n * Node worker entry for trusted edit scripts.\n *\n * Spawns the requested sandbox session, runs the agent script in a bare `vm`\n * context (no fetch/process/setTimeout), and streams journals + logs to the\n * host so hard timeout / OOM termination still preserves partial products.\n */\n\nexport interface WorkerData {\n document: VideoDocument;\n script: string;\n inputs?: Record<string, unknown>;\n entityState?: EntityStoreSnapshot;\n idLabel?: string;\n entityOnly?: boolean;\n}\n\ntype HostMessage =\n | { t: 'ready' }\n | { t: 'entry'; entry: JournalEntry }\n | { t: 'entity-entry'; command: EntityCommand }\n | { t: 'log'; line: string }\n | { t: 'truncate'; index: number }\n | { t: 'entity-truncate'; index: number }\n | {\n t: 'done';\n preview: string;\n opsCount: number;\n entityCommandsCount: number;\n entityBaseRevision: number;\n entityRows?: EntityStoreSnapshot;\n deletedEntityIds: readonly string[];\n deletedRelationIds: readonly string[];\n planKind: 'timeline' | 'entities';\n }\n | {\n t: 'fail';\n phase: 'parse' | 'runtime';\n error: { message: string; line?: number; column?: number; stack?: string };\n };\n\nconst data = workerData as WorkerData;\nif (parentPort == null) {\n throw new Error('worker-entry must run inside a worker_threads Worker');\n}\nconst port = parentPort;\n\nfunction post(message: HostMessage): void {\n port.postMessage(message);\n}\n\nfunction countingFactory(label: string): PartIdFactory {\n let n = 0;\n return (prefix) => `${prefix}_${label}${++n}`;\n}\n\nfunction domainIdFactory(label?: string): DomainIdFactory {\n let n = 0;\n return (prefix) => `${prefix}_${label == null ? randomUUID() : `${label}${++n}`}`;\n}\n\n/** Extract script line/column from the first `agent-script.js` stack frame. */\nfunction positionFromError(\n error: unknown,\n script?: string,\n phase?: 'parse' | 'runtime',\n): { line?: number; column?: number; stack?: string; message: string } {\n // Duck-type: vm SyntaxError in a worker may fail `instanceof Error` across realms.\n const obj = error != null && typeof error === 'object' ? (error as Record<string, unknown>) : null;\n const message =\n obj != null && typeof obj.message === 'string'\n ? obj.message\n : error instanceof Error\n ? error.message\n : String(error);\n const stack = obj != null && typeof obj.stack === 'string' ? obj.stack : undefined;\n\n let line = typeof obj?.lineNumber === 'number' ? obj.lineNumber : undefined;\n let column = typeof obj?.columnNumber === 'number' ? obj.columnNumber : undefined;\n\n if (stack != null) {\n // Prefer the header form `agent-script.js:N` (SyntaxError) or `agent-script.js:N:M`.\n const match = /agent-script\\.js:(\\d+)(?::(\\d+))?/.exec(stack);\n if (match != null) {\n line = Number(match[1]);\n if (match[2] != null) column = Number(match[2]);\n }\n }\n\n // Parse-phase refinement: V8 often points at the token after an unclosed\n // `{`/`(`/`[`; walk back one line when the previous line ends that way so\n // the reported line matches the agent-authored incomplete construct.\n if (phase === 'parse' && script != null && line != null && line >= 2) {\n const lines = script.split('\\n');\n const prev = lines[line - 2];\n if (prev != null && /[{([]\\s*$/.test(prev)) {\n line = line - 1;\n column = prev.length;\n }\n }\n\n return { message, line, column, stack };\n}\n\nasync function main(): Promise<void> {\n const idFactory = data.idLabel != null ? countingFactory(data.idLabel) : undefined;\n const options: EditSandboxSessionOptions = {\n idFactory,\n entityState: data.entityState,\n domainIdFactory: domainIdFactory(data.idLabel),\n onEntry: (entry) => post({ t: 'entry', entry }),\n onEntityCommand: (command) => post({ t: 'entity-entry', command }),\n onLog: (line) => post({ t: 'log', line }),\n onTruncate: (index) => post({ t: 'truncate', index }),\n onEntityTruncate: (index) => post({ t: 'entity-truncate', index }),\n };\n const session = data.entityOnly\n ? new EntityEditSandboxSession(data.document, options)\n : new EditSandboxSession(data.document, options);\n\n // Prelude stays on the same physical line as script line 1 so stack line\n // numbers map 1:1 onto the agent script (no leading newline).\n const wrapped = `(async (edit, timeline, entities, relations, checkpoint, rollbackTo, inputs, console) => {${data.script}\\n})`;\n\n const ctx = vm.createContext(Object.create(null) as Record<string, unknown>);\n\n let run: unknown;\n try {\n run = vm.runInContext(wrapped, ctx, { filename: 'agent-script.js' });\n } catch (error) {\n const pos = positionFromError(error, data.script, 'parse');\n post({ t: 'fail', phase: 'parse', error: pos });\n return;\n }\n\n if (typeof run !== 'function') {\n post({\n t: 'fail',\n phase: 'runtime',\n error: { message: 'agent script wrapper did not evaluate to a function' },\n });\n return;\n }\n\n try {\n const invoke = run as (\n edit: typeof session.edit,\n timeline: typeof session.timeline,\n entities: typeof session.entities,\n relations: typeof session.relations,\n checkpoint: typeof session.checkpoint,\n rollbackTo: typeof session.rollbackTo,\n inputs: Record<string, unknown>,\n console: typeof session.console,\n ) => Promise<unknown>;\n // Signal host that cold start is done; timeout wall-clock starts here.\n post({ t: 'ready' });\n await invoke(\n session.edit,\n session.timeline,\n session.entities,\n session.relations,\n session.checkpoint,\n session.rollbackTo,\n data.inputs ?? {},\n session.console,\n );\n } catch (error) {\n const pos = positionFromError(error, data.script, 'runtime');\n post({ t: 'fail', phase: 'runtime', error: pos });\n return;\n }\n\n const plan = session.buildPlan('');\n post({\n t: 'done',\n preview: plan.preview,\n opsCount: plan.ops.length,\n entityCommandsCount: plan.entity_commands.length,\n entityBaseRevision: plan.entity_base_revision,\n ...(plan.entity_rows !== undefined ? { entityRows: plan.entity_rows } : {}),\n deletedEntityIds: plan.deleted_entity_ids ?? [],\n deletedRelationIds: plan.deleted_relation_ids ?? [],\n planKind: plan.plan_kind,\n });\n}\n\nmain().catch((error: unknown) => {\n const pos = positionFromError(error);\n post({ t: 'fail', phase: 'runtime', error: pos });\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"worker-entry.mjs","names":[],"sources":["../src/sandbox/entity-script-session.ts","../src/sandbox/worker-entry.ts"],"sourcesContent":["import {\n EntityTimelineEditor,\n assertCanonicalEditorResources,\n assertMediaAssetWritePolicy,\n type ClipEntityId,\n type DeleteBgmInput,\n type DeleteClipInput,\n type DeleteClipTreeInput,\n type DeleteVoiceoverInput,\n type InsertCaptionClipInput,\n type InsertClipInput,\n type InsertMediaClipInput,\n type InsertMediaClipsInput,\n type InsertPlacedClipInput,\n type MoveClipInput,\n type MoveClipsToStartsInput,\n type MoveSequentialClipsInput,\n type MoveVoiceoverInput,\n type PatchCaptionStyleInput,\n type ReplaceMediaClipInput,\n type ReplaceSequentialClipsInput,\n type ReplaceClipContentInput,\n type SetBgmInput,\n type SetCaptionVisibilityInput,\n type SetClipPlacementInput,\n type SetClipSpeedInput,\n type SetClipVolumeInput,\n type TrimClipInput,\n type UpdateClipInput,\n type UpdateClipMarkerInput,\n type VideoDocument,\n type VoiceoverTakeInput,\n type VoiceoverTakeResult,\n} from '@mengine/medeo-client';\nimport {\n createEntityId,\n createRelationId,\n type EntityRelationRows,\n type EntityRow,\n type RelationRow,\n} from '@mengine/medeo-dsl';\n\nimport type {\n CreateEntityInput,\n EntityFacade,\n EntityStoreSnapshot,\n LinkRelationInput,\n RelationFacade,\n SandboxEntity,\n SandboxRelation,\n} from '../entity/entity-contract.ts';\nimport { EntitySandbox, type DomainIdFactory } from '../entity/entity-sandbox.ts';\nimport type { ChangePlan, ConsoleShim, EditSandboxSessionOptions, SandboxCheckpoint } from './script-session.ts';\n\nconst LOG_LINE_MAX = 2000;\nconst LOG_LINE_CAP = 1000;\nconst LOG_BYTE_CAP = 64 * 1024;\nconst TRUNCATE_MARK = '[truncated]';\nconst LOG_TRUNCATED = '[log truncated]';\n\n/** Model-facing timeline mutations whose source of truth is the Medeo Entity graph. */\nexport interface EntityEditFacade {\n /** Select the one complete AudioScript exposed by this VideoDocument; null explicitly clears it. */\n setDocumentAudioScript(entityId: string | null): void;\n insertClip(input: InsertClipInput): ClipEntityId;\n insertPlacedClip(input: InsertPlacedClipInput): ClipEntityId;\n updateClipMarker(input: UpdateClipMarkerInput): void;\n setClipPlacement(input: SetClipPlacementInput): void;\n moveSequentialClips(input: MoveSequentialClipsInput): void;\n moveClip(input: MoveClipInput): void;\n replaceClipContent(input: ReplaceClipContentInput): void;\n insertMediaClip(input: InsertMediaClipInput): ClipEntityId;\n insertMediaClips(input: InsertMediaClipsInput): readonly ClipEntityId[];\n replaceMediaClip(input: ReplaceMediaClipInput): void;\n setClipVolume(input: SetClipVolumeInput): void;\n setClipSpeed(input: SetClipSpeedInput): void;\n trimClip(input: TrimClipInput): void;\n replaceSequentialClips(input: ReplaceSequentialClipsInput): readonly ClipEntityId[];\n deleteClip(input: DeleteClipInput): void;\n deleteClipTree(input: DeleteClipTreeInput): void;\n updateClip(input: UpdateClipInput): void;\n upsertVoiceoverTake(input: VoiceoverTakeInput): VoiceoverTakeResult;\n moveVoiceover(input: MoveVoiceoverInput): void;\n moveClipsToStarts(input: MoveClipsToStartsInput): void;\n deleteVoiceover(input: DeleteVoiceoverInput): void;\n setBgm(input: SetBgmInput): ClipEntityId;\n deleteBgm(input: DeleteBgmInput): void;\n setCaptionVisibility(input: SetCaptionVisibilityInput): void;\n patchCaptionStyle(input: PatchCaptionStyleInput): void;\n insertCaptionClip(input: InsertCaptionClipInput): ClipEntityId;\n}\n\nexport interface EntityTimelineFacade {\n /** Return the current graph draft, including uncommitted commands. */\n snapshot(): EntityStoreSnapshot;\n}\n\n/**\n * Entity-only sandbox session used by the production model path.\n *\n * Native timeline operations execute against a detached graph editor and are\n * then journaled as ordinary EntitySandbox commands. VideoDocument is retained\n * only for the request's document identity; it is never edited or projected\n * back into the graph.\n */\nexport class EntityEditSandboxSession {\n private readonly document: VideoDocument;\n private readonly entitySandbox: EntitySandbox;\n private readonly entityRevision: number;\n private readonly baseRows: EntityRelationRows;\n private readonly domainIdFactory: DomainIdFactory;\n private readonly logs: string[] = [];\n private readonly onLog: ((line: string) => void) | undefined;\n private logBytes = 0;\n private logCapped = false;\n\n readonly edit: EntityEditFacade;\n readonly timeline: EntityTimelineFacade;\n readonly entities: EntityFacade;\n readonly relations: RelationFacade;\n readonly console: ConsoleShim;\n readonly checkpoint: () => SandboxCheckpoint;\n readonly rollbackTo: (cp: SandboxCheckpoint) => void;\n\n constructor(document: VideoDocument, options?: EditSandboxSessionOptions) {\n this.document = structuredClone(document);\n this.entityRevision = options?.entityState?.revision ?? 0;\n this.baseRows = toDslRows(\n options?.entityState ?? { revision: 0, audioScriptEntityId: null, entities: [], relations: [] },\n );\n this.domainIdFactory =\n options?.domainIdFactory ??\n (() => {\n throw new Error('Entity id factory is unavailable in this sandbox host');\n });\n this.onLog = options?.onLog;\n this.entitySandbox = new EntitySandbox({\n state: options?.entityState,\n idFactory: this.domainIdFactory,\n onCommand: options?.onEntityCommand,\n onTruncate: options?.onEntityTruncate,\n });\n\n this.edit = this.buildEditFacade();\n this.timeline = { snapshot: () => this.snapshot() };\n this.entities = this.entitySandbox.entities;\n this.relations = this.entitySandbox.relations;\n this.console = this.buildConsoleShim();\n this.checkpoint = () => ({ index: this.entitySandbox.commandCount });\n this.rollbackTo = (cp) => this.entitySandbox.rollbackTo(cp.index);\n }\n\n buildPlan(baseVersion: string): ChangePlan {\n const entityPlan = this.entitySandbox.buildPlan();\n assertCanonicalEditorResources(toDslRows(entityPlan.rows));\n assertMediaAssetWritePolicy(this.baseRows, toDslRows(entityPlan.rows));\n return {\n plan_kind: 'entities',\n doc_id: this.document.meta.draft_id ?? '',\n base_version: baseVersion,\n ops: [],\n entity_base_revision: entityPlan.base_revision,\n entity_commands: entityPlan.commands,\n entity_rows: entityPlan.rows,\n deleted_entity_ids: entityPlan.deleted_entity_ids,\n deleted_relation_ids: entityPlan.deleted_relation_ids,\n preview: this.entitySandbox.renderPreview(),\n logs: this.logs.slice(),\n };\n }\n\n getLogs(): readonly string[] {\n return this.logs;\n }\n\n private buildEditFacade(): EntityEditFacade {\n return {\n setDocumentAudioScript: (entityId) => this.entitySandbox.setDocumentAudioScript(entityId),\n insertClip: (input) => this.runNativeEdit((editor) => editor.insertClip(input)),\n insertPlacedClip: (input) => this.runNativeEdit((editor) => editor.insertPlacedClip(input)),\n updateClipMarker: (input) => this.runNativeEdit((editor) => editor.updateClipMarker(input)),\n setClipPlacement: (input) => this.runNativeEdit((editor) => editor.setClipPlacement(input)),\n moveSequentialClips: (input) => this.runNativeEdit((editor) => editor.moveSequentialClips(input)),\n moveClip: (input) => this.runNativeEdit((editor) => editor.moveClip(input)),\n replaceClipContent: (input) => this.runNativeEdit((editor) => editor.replaceClipContent(input)),\n insertMediaClip: (input) => this.runNativeEdit((editor) => editor.insertMediaClip(input)),\n insertMediaClips: (input) => this.runNativeEdit((editor) => editor.insertMediaClips(input)),\n replaceMediaClip: (input) => this.runNativeEdit((editor) => editor.replaceMediaClip(input)),\n setClipVolume: (input) => this.runNativeEdit((editor) => editor.setClipVolume(input)),\n setClipSpeed: (input) => this.runNativeEdit((editor) => editor.setClipSpeed(input)),\n trimClip: (input) => this.runNativeEdit((editor) => editor.trimClip(input)),\n replaceSequentialClips: (input) => this.runNativeEdit((editor) => editor.replaceSequentialClips(input)),\n deleteClip: (input) => this.runNativeEdit((editor) => editor.deleteClip(input)),\n deleteClipTree: (input) => this.runNativeEdit((editor) => editor.deleteClipTree(input)),\n updateClip: (input) => this.runNativeEdit((editor) => editor.updateClip(input)),\n upsertVoiceoverTake: (input) => this.runNativeEdit((editor) => editor.upsertVoiceoverTake(input)),\n moveVoiceover: (input) => this.runNativeEdit((editor) => editor.moveVoiceover(input)),\n moveClipsToStarts: (input) => this.runNativeEdit((editor) => editor.moveClipsToStarts(input)),\n deleteVoiceover: (input) => this.runNativeEdit((editor) => editor.deleteVoiceover(input)),\n setBgm: (input) => this.runNativeEdit((editor) => editor.setBgm(input)),\n deleteBgm: (input) => this.runNativeEdit((editor) => editor.deleteBgm(input)),\n setCaptionVisibility: (input) => this.runNativeEdit((editor) => editor.setCaptionVisibility(input)),\n patchCaptionStyle: (input) => this.runNativeEdit((editor) => editor.patchCaptionStyle(input)),\n insertCaptionClip: (input) => this.runNativeEdit((editor) => editor.insertCaptionClip(input)),\n };\n }\n\n private runNativeEdit<T>(mutate: (editor: EntityTimelineEditor) => T): T {\n const checkpoint = this.entitySandbox.commandCount;\n try {\n const before = this.entitySandbox.buildPlan().rows;\n const editor = new EntityTimelineEditor(toDslRows(before), this.domainIdFactory);\n const result = mutate(editor);\n const expected = fromDslRows(editor.rows(), before.revision, before.audioScriptEntityId);\n applyGraphDiff(this.entitySandbox, before, expected);\n const applied = this.entitySandbox.buildPlan().rows;\n if (!graphRowsEqual(applied, expected)) {\n throw new Error('Entity timeline command diff did not reproduce the editor result');\n }\n return result;\n } catch (error) {\n this.entitySandbox.rollbackTo(checkpoint);\n throw error;\n }\n }\n\n private snapshot(): EntityStoreSnapshot {\n return {\n revision: this.entityRevision,\n audioScriptEntityId: this.entitySandbox.audioScriptEntityId,\n entities: this.entitySandbox.entities.list(),\n relations: this.entitySandbox.relations.list(),\n };\n }\n\n private appendLog(line: string): void {\n if (this.logCapped) return;\n if (this.logs.length >= LOG_LINE_CAP || this.logBytes >= LOG_BYTE_CAP) {\n this.logs.push(LOG_TRUNCATED);\n this.logCapped = true;\n this.onLog?.(LOG_TRUNCATED);\n return;\n }\n const out =\n line.length > LOG_LINE_MAX ? `${line.slice(0, LOG_LINE_MAX - TRUNCATE_MARK.length)}${TRUNCATE_MARK}` : line;\n this.logs.push(out);\n this.logBytes += out.length;\n this.onLog?.(out);\n }\n\n private buildConsoleShim(): ConsoleShim {\n const write = (...args: unknown[]) => this.appendLog(args.map(formatLogArg).join(' '));\n return { log: write, info: write, warn: write, error: write };\n }\n}\n\nfunction applyGraphDiff(sandbox: EntitySandbox, before: EntityStoreSnapshot, after: EntityStoreSnapshot): void {\n const beforeEntities = new Map(before.entities.map((entity) => [entity.entity_id, entity]));\n const afterEntities = new Map(after.entities.map((entity) => [entity.entity_id, entity]));\n const beforeRelations = new Map(before.relations.map((relation) => [relation.relation_id, relation]));\n const afterRelations = new Map(after.relations.map((relation) => [relation.relation_id, relation]));\n\n for (const [entityId, previous] of beforeEntities) {\n const next = afterEntities.get(entityId);\n if (next != null && next.entity_kind !== previous.entity_kind) {\n throw new Error(\n `Entity id \"${entityId}\" cannot change kind from \"${previous.entity_kind}\" to \"${next.entity_kind}\"`,\n );\n }\n }\n for (const [relationId, previous] of beforeRelations) {\n const next = afterRelations.get(relationId);\n if (\n next != null &&\n (next.relation_kind !== previous.relation_kind ||\n next.endpoint_0_entity_id !== previous.endpoint_0_entity_id ||\n next.endpoint_1_entity_id !== previous.endpoint_1_entity_id)\n ) {\n throw new Error(`Relation id \"${relationId}\" cannot change kind or persisted endpoint positions`);\n }\n }\n\n const relationIdsToReplace = new Set(\n [...beforeRelations]\n .filter(([relationId, previous]) => {\n const next = afterRelations.get(relationId);\n return next != null && (!jsonEqual(previous.metadata, next.metadata) || !jsonEqual(previous.trace, next.trace));\n })\n .map(([relationId]) => relationId),\n );\n const relationIdsToUnlink = [...beforeRelations.keys()]\n .filter((relationId) => !afterRelations.has(relationId) || relationIdsToReplace.has(relationId))\n .sort();\n for (const relationId of relationIdsToUnlink) sandbox.relations.unlink({ relation_id: relationId });\n\n const entityIdsToDelete = [...beforeEntities.keys()].filter((entityId) => !afterEntities.has(entityId)).sort();\n for (const entityId of entityIdsToDelete) sandbox.entities.delete({ entity_id: entityId });\n\n const entitiesToCreate = [...afterEntities.values()]\n .filter((entity) => !beforeEntities.has(entity.entity_id))\n .sort((left, right) => left.entity_id.localeCompare(right.entity_id));\n for (const entity of entitiesToCreate) sandbox.entities.create(entity as CreateEntityInput);\n\n const entitiesToUpdate = [...afterEntities.values()]\n .filter((entity) => {\n const previous = beforeEntities.get(entity.entity_id);\n return previous != null && !jsonEqual(previous.payload, entity.payload);\n })\n .sort((left, right) => left.entity_id.localeCompare(right.entity_id));\n for (const entity of entitiesToUpdate) {\n sandbox.replaceOwnedPayload({ entity_id: entity.entity_id, payload: entity.payload });\n }\n\n const relationsToLink = [...afterRelations.values()]\n .filter((relation) => !beforeRelations.has(relation.relation_id) || relationIdsToReplace.has(relation.relation_id))\n .sort((left, right) => left.relation_id.localeCompare(right.relation_id));\n for (const relation of relationsToLink) linkRelation(sandbox, relation);\n}\n\nfunction linkRelation(sandbox: EntitySandbox, relation: SandboxRelation): void {\n if (relation.relation_kind === 'generated') {\n sandbox.relations.linkGenerated({\n relation_id: relation.relation_id,\n output_entity_id: relation.endpoint_0_entity_id,\n input_entity_id: relation.endpoint_1_entity_id,\n trace: relation.trace,\n });\n return;\n }\n if (relation.relation_kind === 'clip-anchor') {\n sandbox.relations.linkClipAnchor({\n relation_id: relation.relation_id,\n child_clip_entity_id: relation.endpoint_0_entity_id,\n host_clip_entity_id: relation.endpoint_1_entity_id,\n trace: relation.trace,\n });\n return;\n }\n if (relation.relation_kind === 'phonetic-script-render') {\n const firstIsVoice = sandbox.entities.get(relation.endpoint_0_entity_id)?.entity_kind === 'voice';\n sandbox.relations.linkPhoneticScriptRender({\n relation_id: relation.relation_id,\n output_entity_id: firstIsVoice ? relation.endpoint_0_entity_id : relation.endpoint_1_entity_id,\n phonetic_script_entity_id: firstIsVoice ? relation.endpoint_1_entity_id : relation.endpoint_0_entity_id,\n trace: relation.trace,\n });\n return;\n }\n if (relation.relation_kind === 'audio-script-source') {\n const firstIsScript = sandbox.entities.get(relation.endpoint_0_entity_id)?.entity_kind === 'audio-script';\n sandbox.relations.linkAudioScriptSource({\n relation_id: relation.relation_id,\n script_entity_id: firstIsScript ? relation.endpoint_0_entity_id : relation.endpoint_1_entity_id,\n source_entity_id: firstIsScript ? relation.endpoint_1_entity_id : relation.endpoint_0_entity_id,\n trace: relation.trace,\n });\n return;\n }\n sandbox.relations.link({\n relation_id: relation.relation_id,\n relation_kind: relation.relation_kind,\n endpoint_0_entity_id: relation.endpoint_0_entity_id,\n endpoint_1_entity_id: relation.endpoint_1_entity_id,\n metadata: relation.metadata,\n trace: relation.trace,\n } as LinkRelationInput);\n}\n\nfunction toDslRows(snapshot: EntityStoreSnapshot): EntityRelationRows {\n return {\n entities: snapshot.entities.map((entity) => ({\n entityId: createEntityId(entity.entity_id),\n entityKind: entity.entity_kind,\n payload: structuredClone(entity.payload),\n })) as EntityRow[],\n relations: snapshot.relations.map((relation) => ({\n relationId: createRelationId(relation.relation_id),\n relationKind: relation.relation_kind,\n endpoint0EntityId: createEntityId(relation.endpoint_0_entity_id),\n endpoint1EntityId: createEntityId(relation.endpoint_1_entity_id),\n metadata: structuredClone(relation.metadata),\n trace: structuredClone(relation.trace),\n })) as RelationRow[],\n };\n}\n\nfunction fromDslRows(\n rows: EntityRelationRows,\n revision: number,\n audioScriptEntityId: string | null,\n): EntityStoreSnapshot {\n return {\n revision,\n audioScriptEntityId,\n entities: rows.entities.map(\n (entity) =>\n ({\n entity_id: entity.entityId,\n entity_kind: entity.entityKind,\n payload: structuredClone(entity.payload),\n }) as SandboxEntity,\n ),\n relations: rows.relations.map(\n (relation) =>\n ({\n relation_id: relation.relationId,\n relation_kind: relation.relationKind,\n endpoint_0_entity_id: relation.endpoint0EntityId,\n endpoint_1_entity_id: relation.endpoint1EntityId,\n metadata: structuredClone(relation.metadata),\n trace: structuredClone(relation.trace),\n }) as SandboxRelation,\n ),\n };\n}\n\nfunction jsonEqual(left: unknown, right: unknown): boolean {\n if (Object.is(left, right)) return true;\n if (Array.isArray(left) || Array.isArray(right)) {\n return (\n Array.isArray(left) &&\n Array.isArray(right) &&\n left.length === right.length &&\n left.every((value, index) => jsonEqual(value, right[index]))\n );\n }\n if (!isRecord(left) || !isRecord(right)) return false;\n const leftKeys = Object.keys(left).sort();\n const rightKeys = Object.keys(right).sort();\n return (\n leftKeys.length === rightKeys.length &&\n leftKeys.every((key, index) => key === rightKeys[index] && jsonEqual(left[key], right[key]))\n );\n}\n\nfunction graphRowsEqual(left: EntityStoreSnapshot, right: EntityStoreSnapshot): boolean {\n if (\n left.revision !== right.revision ||\n left.audioScriptEntityId !== right.audioScriptEntityId ||\n left.entities.length !== right.entities.length ||\n left.relations.length !== right.relations.length\n ) {\n return false;\n }\n const rightEntities = new Map(right.entities.map((entity) => [entity.entity_id, entity]));\n const rightRelations = new Map(right.relations.map((relation) => [relation.relation_id, relation]));\n return (\n left.entities.every((entity) => jsonEqual(entity, rightEntities.get(entity.entity_id))) &&\n left.relations.every((relation) => jsonEqual(relation, rightRelations.get(relation.relation_id)))\n );\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value);\n}\n\nfunction formatLogArg(value: unknown): string {\n if (typeof value === 'string') return value;\n if (typeof value === 'number' || typeof value === 'boolean' || value === null || value === undefined) {\n return String(value);\n }\n try {\n return JSON.stringify(value);\n } catch {\n return '[unstringifiable]';\n }\n}\n","/// <reference types=\"node\" />\n\nimport { randomUUID } from 'node:crypto';\nimport vm from 'node:vm';\nimport { parentPort, workerData } from 'node:worker_threads';\n\nimport type { JournalEntry, PartIdFactory, VideoDocument } from '@mengine/medeo-client';\n\nimport type { EntityCommand, EntityStoreSnapshot } from '../entity/entity-contract.ts';\nimport type { DomainIdFactory } from '../entity/entity-sandbox.ts';\nimport { EntityEditSandboxSession } from './entity-script-session.ts';\nimport { EditSandboxSession, type EditSandboxSessionOptions } from './script-session.ts';\n\n/**\n * Node worker entry for trusted edit scripts.\n *\n * Spawns the requested sandbox session, runs the agent script in a bare `vm`\n * context (no fetch/process/setTimeout), and streams journals + logs to the\n * host so hard timeout / OOM termination still preserves partial products.\n */\n\nexport interface WorkerData {\n document: VideoDocument;\n script: string;\n inputs?: Record<string, unknown>;\n entityState?: EntityStoreSnapshot;\n idLabel?: string;\n entityOnly?: boolean;\n}\n\ntype HostMessage =\n | { t: 'ready' }\n | { t: 'entry'; entry: JournalEntry }\n | { t: 'entity-entry'; command: EntityCommand }\n | { t: 'log'; line: string }\n | { t: 'truncate'; index: number }\n | { t: 'entity-truncate'; index: number }\n | {\n t: 'done';\n preview: string;\n opsCount: number;\n entityCommandsCount: number;\n entityBaseRevision: number;\n entityRows?: EntityStoreSnapshot;\n deletedEntityIds: readonly string[];\n deletedRelationIds: readonly string[];\n planKind: 'timeline' | 'entities';\n }\n | {\n t: 'fail';\n phase: 'parse' | 'runtime';\n error: { message: string; line?: number; column?: number; stack?: string };\n };\n\nconst data = workerData as WorkerData;\nif (parentPort == null) {\n throw new Error('worker-entry must run inside a worker_threads Worker');\n}\nconst port = parentPort;\n\nfunction post(message: HostMessage): void {\n port.postMessage(message);\n}\n\nfunction countingFactory(label: string): PartIdFactory {\n let n = 0;\n return (prefix) => `${prefix}_${label}${++n}`;\n}\n\nfunction domainIdFactory(label?: string): DomainIdFactory {\n let n = 0;\n return (prefix) => `${prefix}_${label == null ? randomUUID() : `${label}${++n}`}`;\n}\n\n/** Extract script line/column from the first `agent-script.js` stack frame. */\nfunction positionFromError(\n error: unknown,\n script?: string,\n phase?: 'parse' | 'runtime',\n): { line?: number; column?: number; stack?: string; message: string } {\n // Duck-type: vm SyntaxError in a worker may fail `instanceof Error` across realms.\n const obj = error != null && typeof error === 'object' ? (error as Record<string, unknown>) : null;\n const message =\n obj != null && typeof obj.message === 'string'\n ? obj.message\n : error instanceof Error\n ? error.message\n : String(error);\n const stack = obj != null && typeof obj.stack === 'string' ? obj.stack : undefined;\n\n let line = typeof obj?.lineNumber === 'number' ? obj.lineNumber : undefined;\n let column = typeof obj?.columnNumber === 'number' ? obj.columnNumber : undefined;\n\n if (stack != null) {\n // Prefer the header form `agent-script.js:N` (SyntaxError) or `agent-script.js:N:M`.\n const match = /agent-script\\.js:(\\d+)(?::(\\d+))?/.exec(stack);\n if (match != null) {\n line = Number(match[1]);\n if (match[2] != null) column = Number(match[2]);\n }\n }\n\n // Parse-phase refinement: V8 often points at the token after an unclosed\n // `{`/`(`/`[`; walk back one line when the previous line ends that way so\n // the reported line matches the agent-authored incomplete construct.\n if (phase === 'parse' && script != null && line != null && line >= 2) {\n const lines = script.split('\\n');\n const prev = lines[line - 2];\n if (prev != null && /[{([]\\s*$/.test(prev)) {\n line = line - 1;\n column = prev.length;\n }\n }\n\n return { message, line, column, stack };\n}\n\nasync function main(): Promise<void> {\n const idFactory = data.idLabel != null ? countingFactory(data.idLabel) : undefined;\n const options: EditSandboxSessionOptions = {\n idFactory,\n entityState: data.entityState,\n domainIdFactory: domainIdFactory(data.idLabel),\n onEntry: (entry) => post({ t: 'entry', entry }),\n onEntityCommand: (command) => post({ t: 'entity-entry', command }),\n onLog: (line) => post({ t: 'log', line }),\n onTruncate: (index) => post({ t: 'truncate', index }),\n onEntityTruncate: (index) => post({ t: 'entity-truncate', index }),\n };\n const session = data.entityOnly\n ? new EntityEditSandboxSession(data.document, options)\n : new EditSandboxSession(data.document, options);\n\n // Prelude stays on the same physical line as script line 1 so stack line\n // numbers map 1:1 onto the agent script (no leading newline).\n const wrapped = `(async (edit, timeline, entities, relations, checkpoint, rollbackTo, inputs, console) => {${data.script}\\n})`;\n\n const ctx = vm.createContext(Object.create(null) as Record<string, unknown>);\n\n let run: unknown;\n try {\n run = vm.runInContext(wrapped, ctx, { filename: 'agent-script.js' });\n } catch (error) {\n const pos = positionFromError(error, data.script, 'parse');\n post({ t: 'fail', phase: 'parse', error: pos });\n return;\n }\n\n if (typeof run !== 'function') {\n post({\n t: 'fail',\n phase: 'runtime',\n error: { message: 'agent script wrapper did not evaluate to a function' },\n });\n return;\n }\n\n try {\n const invoke = run as (\n edit: typeof session.edit,\n timeline: typeof session.timeline,\n entities: typeof session.entities,\n relations: typeof session.relations,\n checkpoint: typeof session.checkpoint,\n rollbackTo: typeof session.rollbackTo,\n inputs: Record<string, unknown>,\n console: typeof session.console,\n ) => Promise<unknown>;\n // Signal host that cold start is done; timeout wall-clock starts here.\n post({ t: 'ready' });\n await invoke(\n session.edit,\n session.timeline,\n session.entities,\n session.relations,\n session.checkpoint,\n session.rollbackTo,\n data.inputs ?? {},\n session.console,\n );\n } catch (error) {\n const pos = positionFromError(error, data.script, 'runtime');\n post({ t: 'fail', phase: 'runtime', error: pos });\n return;\n }\n\n const plan = session.buildPlan('');\n post({\n t: 'done',\n preview: plan.preview,\n opsCount: plan.ops.length,\n entityCommandsCount: plan.entity_commands.length,\n entityBaseRevision: plan.entity_base_revision,\n ...(plan.entity_rows !== undefined ? { entityRows: plan.entity_rows } : {}),\n deletedEntityIds: plan.deleted_entity_ids ?? [],\n deletedRelationIds: plan.deleted_relation_ids ?? [],\n planKind: plan.plan_kind,\n });\n}\n\nmain().catch((error: unknown) => {\n const pos = positionFromError(error);\n post({ t: 'fail', phase: 'runtime', error: pos });\n});\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mengine/medeo-tool",
3
- "version": "1.2.1-alpha.9",
3
+ "version": "1.3.1-alpha.8",
4
4
  "license": "UNLICENSED",
5
5
  "repository": {
6
6
  "type": "git",
@@ -24,7 +24,7 @@
24
24
  "registry": "https://registry.npmjs.org/"
25
25
  },
26
26
  "dependencies": {
27
- "@mengine/medeo-client": "1.2.1-alpha.9"
27
+ "@mengine/medeo-client": "1.3.1-alpha.8"
28
28
  },
29
29
  "devDependencies": {
30
30
  "@types/node": "^25.9.1",