@mengine/medeo-tool 1.2.1-alpha.7 → 1.2.1-alpha.9
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.
- package/README.md +71 -16
- package/dist/{entity-contract-B3txrzTt.d.mts → entity-contract-DycLxdQ5.d.mts} +49 -3
- package/dist/index.d.mts +192 -13
- package/dist/index.mjs +1030 -923
- package/dist/index.mjs.map +1 -1
- package/dist/sandbox-api.d.mts +397 -818
- package/dist/{script-session-BF44uKv_.mjs → script-session-CHyIUBkO.mjs} +366 -26
- package/dist/script-session-CHyIUBkO.mjs.map +1 -0
- package/dist/worker-entry.d.mts +5 -4
- package/dist/worker-entry.mjs +286 -5
- package/dist/worker-entry.mjs.map +1 -1
- package/package.json +2 -2
- package/dist/script-session-BF44uKv_.mjs.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"script-session-CHyIUBkO.mjs","names":["isRecord"],"sources":["../src/document/compact-projection.ts","../src/sandbox/preview.ts","../../medeo-dsl/src/entities.ts","../../medeo-dsl/src/ids.ts","../../medeo-dsl/src/invariants.ts","../../medeo-dsl/src/json-values.ts","../../medeo-dsl/src/relation-specs.ts","../../medeo-dsl/src/relations.ts","../../medeo-dsl/src/relation-index.ts","../../medeo-dsl/src/entity-relation-rows.ts","../../medeo-dsl/src/rows.ts","../src/entity/entity-sandbox.ts","../src/sandbox/script-session.ts"],"sourcesContent":["import {\n effectiveVideoClipDurationMs,\n solveVideoDocument,\n speedOf,\n type PartKind,\n type PartUnion,\n type SpeedShift,\n type TrackItem,\n type TrackItemTimePosition,\n type VideoClipPart,\n type VideoDocument,\n} from '@mengine/medeo-client';\n\n/**\n * Compact text projection of a `VideoDocument` for sandbox ChangePlan\n * `preview` (and pipeline dry-run preview). Pure, runtime-neutral: solves\n * via `solveVideoDocument`, emits one header line plus one row per timeline\n * item (library orphans are never rendered). Row intervals and per-kind\n * effective durations align with `toReadViewPartLibrary` /\n * `fromVideoDocument`.\n */\n\nexport interface CompactProjectionOptions {\n /** Only render these parts (header still reports the full timeline total). Default = all. */\n onlyPartIds?: ReadonlySet<string>;\n /** Caption text preview truncation length. Default 24. */\n textPreviewLength?: number;\n}\n\nconst DEFAULT_TEXT_PREVIEW_LENGTH = 24;\n\n/** Kind tag shown in the first column (`video_clip` → `clip`). */\nfunction kindTag(kind: PartKind): string {\n return kind === 'video_clip' ? 'clip' : kind;\n}\n\n/** Lane label: `video_clip` tracks display as `main`, otherwise `parts_kind`. */\nfunction laneLabel(partsKind: PartKind): string {\n return partsKind === 'video_clip' ? 'main' : partsKind;\n}\n\n/** Speed token: absent → `1`; linear → numeric multiplier; anything else → `custom`. */\nfunction speedToken(speedShift: SpeedShift | undefined): string {\n if (speedShift == null) return '1';\n if (speedShift.category === 'linear') return String(speedOf(speedShift));\n return 'custom';\n}\n\nfunction effectiveDurationMs(part: PartUnion, timelineDurationMs: number): number {\n if (part.video_clip != null) return effectiveVideoClipDurationMs(part.video_clip);\n if (part.speech != null) return part.speech.media_duration_ms ?? 0;\n if (part.caption != null) return part.caption.initial_duration_ms ?? 0;\n if (part.bgm != null) return timelineDurationMs;\n return 0;\n}\n\nfunction truncateText(text: string, budget: number): string {\n if (text.length <= budget) return text;\n return `${text.slice(0, budget)}…`;\n}\n\nfunction anchorToken(timePosition: TrackItemTimePosition): string {\n if (timePosition.mode === 'anchored') {\n return `anchor=${timePosition.anchorPartId}+${timePosition.offsetMs}`;\n }\n if (timePosition.mode === 'absolute') return 'anchor=abs';\n return 'anchor=abs';\n}\n\nfunction clipAttrs(clip: VideoClipPart): string {\n const playIn = clip.play_in ?? 0;\n const playOut = clip.play_out ?? 0;\n return `media=${clip.origin_media_id ?? ''} trim=${playIn}-${playOut} speed=${speedToken(clip.speed_shift)} vol=${clip.volume ?? 0}`;\n}\n\nfunction partAttrs(part: PartUnion, item: TrackItem, textPreviewLength: number): string {\n if (part.video_clip != null) return clipAttrs(part.video_clip);\n if (part.speech != null) {\n return `${anchorToken(item.time_position)} dur=${part.speech.media_duration_ms ?? 0}`;\n }\n if (part.caption != null) {\n const preview = truncateText(part.caption.text ?? '', textPreviewLength);\n return `${anchorToken(item.time_position)} text=\"${preview}\"`;\n }\n if (part.bgm != null) return `vol=${part.bgm.volume ?? 0}`;\n return '';\n}\n\n/**\n * Render a `VideoDocument` as compact text: one header line plus one row per\n * timeline part (optionally filtered by `onlyPartIds`). Deterministic and\n * side-effect free — same document always yields the same string.\n */\nexport function renderCompactProjection(document: VideoDocument, options?: CompactProjectionOptions): string {\n const onlyPartIds = options?.onlyPartIds;\n const textPreviewLength = options?.textPreviewLength ?? DEFAULT_TEXT_PREVIEW_LENGTH;\n\n const solved = solveVideoDocument(document);\n const library = document.part_library ?? {};\n const tracks = document.tracks ?? [];\n\n let totalParts = 0;\n const rows: string[] = [];\n\n for (const track of tracks) {\n const partsKind = track.parts_kind;\n if (partsKind == null) continue;\n const lane = laneLabel(partsKind);\n const tag = kindTag(partsKind);\n\n for (const item of track.items ?? []) {\n totalParts += 1;\n const partId = item.part_id;\n if (onlyPartIds != null && !onlyPartIds.has(partId)) continue;\n\n const part = library[partId];\n if (part == null) continue;\n\n const abs = solved.absByPartId.get(partId) ?? 0;\n const dur = effectiveDurationMs(part, solved.durationMs);\n const attrs = partAttrs(part, item, textPreviewLength);\n rows.push(`${tag} ${partId} ${lane} [${abs},${abs + dur}) ${attrs}`);\n }\n }\n\n const header = `# draft=${document.meta.draft_id ?? ''} v=${document.meta.version ?? 0} duration=${solved.durationMs} parts=${totalParts} shown=${rows.length}`;\n return [header, ...rows].join('\\n');\n}\n","import type { JournalEntry, VideoDocument } from '@mengine/medeo-client';\n\nimport { renderCompactProjection } from '../document/compact-projection.ts';\n\n/**\n * Collect part ids referenced by a journal for compact preview filtering.\n * Walks known id-shaped payload keys (宁多勿少) and unions `generated_ids`.\n */\nconst PART_ID_KEYS = new Set([\n 'clip_id',\n 'clip_ids',\n 'before_clip_id',\n 'after_clip_id',\n 'speech_id',\n 'speech_ids',\n 'speech_part_id',\n 'caption_id',\n 'caption_ids',\n 'bgm_id',\n 'anchor_part_id',\n 'part_id',\n 'body_part_id',\n]);\n\n/** Extract every part id a journal entry touches (payload refs + minted ids). */\nexport function collectAffectedPartIds(journal: readonly JournalEntry[]): Set<string> {\n const ids = new Set<string>();\n for (const entry of journal) {\n for (const generated of entry.generated_ids ?? []) {\n if (generated.length > 0) ids.add(generated);\n }\n collectFromValue(entry.payload, ids);\n }\n return ids;\n}\n\nfunction collectFromValue(value: unknown, ids: Set<string>): void {\n if (value == null) return;\n if (Array.isArray(value)) {\n for (const item of value) collectFromValue(item, ids);\n return;\n }\n if (typeof value !== 'object') return;\n for (const [key, child] of Object.entries(value as Record<string, unknown>)) {\n if (PART_ID_KEYS.has(key)) {\n if (typeof child === 'string' && child.length > 0) ids.add(child);\n else if (Array.isArray(child)) {\n for (const item of child) {\n if (typeof item === 'string' && item.length > 0) ids.add(item);\n }\n }\n }\n collectFromValue(child, ids);\n }\n}\n\n/**\n * Render a ChangePlan preview: header + rows for journal-affected parts only.\n * Empty journal → empty `onlyPartIds` (header alone), matching the T2 contract.\n */\nexport function renderPreview(document: VideoDocument, journal: readonly JournalEntry[]): string {\n const onlyPartIds = journal.length === 0 ? new Set<string>() : collectAffectedPartIds(journal);\n return renderCompactProjection(document, { onlyPartIds });\n}\n","import type { EntityId } from './ids.ts';\n\nexport type KnownEntityKind =\n | 'axvideo'\n | 'timeline'\n | 'track'\n | 'clip'\n | 'asset'\n | 'video'\n | 'audio'\n | 'voice'\n | 'image'\n | 'sequence-marker'\n | 'viewport'\n | 'audio-script'\n | 'phonetic-script'\n | 'caption';\n\nexport type KnownSequenceEntityKind = 'video' | 'audio' | 'voice' | 'image' | 'caption' | 'axvideo';\ndeclare const extensionEntityKindBrand: unique symbol;\nexport type ExtensionEntityKind = string & { readonly [extensionEntityKindBrand]: 'ExtensionEntityKind' };\n\n/** Extensions require explicit branding so removed or reserved domain kinds cannot reappear accidentally. */\nexport type EntityKind = KnownEntityKind | ExtensionEntityKind;\n\nexport type EntityLifecycle = Readonly<Record<string, unknown>>;\n\n/** One independently identified Medeo domain object. Peer associations belong in Relation rows. */\nexport interface MedeoEntity<K extends EntityKind = EntityKind> {\n readonly entityId: EntityId;\n readonly entityKind: K;\n readonly lifecycle?: EntityLifecycle;\n}\n\nexport type SequenceExtent<Point> =\n | { readonly kind: 'bounded'; readonly start: Point; readonly end: Point }\n | { readonly kind: 'unbounded'; readonly start: Point };\n\nexport type SequenceSampling = 'native' | 'constant' | 'derived';\n\n/**\n * Shared value shape for an entity's own ordered content domain.\n *\n * This is shared structural vocabulary, not a separately identified object.\n * Video and the other sequence entities own these fields directly.\n */\nexport interface SequenceFields<Point = unknown, CoordinateSpace = unknown> {\n readonly extent: SequenceExtent<Point>;\n readonly sampling: SequenceSampling;\n readonly coordinateSpace: CoordinateSpace;\n}\n\nexport interface SequenceRange<Point = unknown> {\n readonly start: Point;\n readonly end: Point;\n}\n\nexport type SequenceDuration<Span = unknown> =\n | { readonly mode: 'from-source' }\n | { readonly mode: 'fixed'; readonly value: Span };\n\nexport interface ScriptTextSegment {\n readonly segmentId: string;\n readonly text: string;\n readonly language?: string;\n}\n\nexport interface ScriptTextFields<Segment extends ScriptTextSegment = ScriptTextSegment> {\n readonly segments: readonly Segment[];\n}\n\nexport interface ExternalAssetLocator {\n readonly system: 'memota' | 'memota-speech';\n readonly key: string;\n}\n\nexport interface InlineTextAsset {\n readonly mediaType: 'text/plain';\n readonly text: string;\n}\n\nexport interface VoiceDescriptor {\n readonly system: 'voice-library';\n readonly key: string;\n readonly name?: string;\n}\n\nexport interface CaptionFontDescriptor {\n readonly system: 'font-library';\n readonly key: string;\n}\n\nexport interface CaptionStyleFields {\n readonly font?: CaptionFontDescriptor;\n readonly fontSize?: number;\n readonly fontColor?: string;\n readonly fontWeight?: number;\n readonly entranceAnimation?: string;\n readonly entranceAnimationDurationMs?: number;\n readonly strokeColor?: string;\n readonly strokeWidth?: number;\n readonly positionX?: number;\n readonly positionY?: number;\n}\n\nexport type EmptyFields = Readonly<Record<never, never>>;\n\nexport type Timeline = MedeoEntity<'timeline'>;\n\nexport type Track = MedeoEntity<'track'> & {\n readonly hidden?: boolean;\n /** The vocabulary remains deliberately open in Review v8. */\n readonly role?: string;\n /** Stable stacking order among sibling Tracks. */\n readonly order?: number;\n};\n\nexport type Clip = MedeoEntity<'clip'> & {\n /** Stable flow order for a sequential Clip. */\n readonly order?: number;\n /** Playback gain in decibels. */\n readonly volume?: number;\n};\nexport type Asset = MedeoEntity<'asset'> & {\n readonly external?: ExternalAssetLocator;\n readonly storageKey?: string;\n readonly inline?: InlineTextAsset;\n};\nexport type Viewport = MedeoEntity<'viewport'>;\n\nexport type Video<Point = unknown, CoordinateSpace = unknown> = MedeoEntity<'video'> &\n SequenceFields<Point, CoordinateSpace> & {\n readonly extent: Extract<SequenceFields<Point, CoordinateSpace>['extent'], { kind: 'bounded' }>;\n readonly sampling: 'native';\n };\n\nexport type Audio<Point = unknown, CoordinateSpace = unknown> = MedeoEntity<'audio'> &\n SequenceFields<Point, CoordinateSpace> & {\n readonly extent: Extract<SequenceFields<Point, CoordinateSpace>['extent'], { kind: 'bounded' }>;\n readonly sampling: 'native';\n };\n\nexport type Voice<Point = unknown, CoordinateSpace = unknown> = MedeoEntity<'voice'> &\n SequenceFields<Point, CoordinateSpace> & {\n readonly extent: Extract<SequenceFields<Point, CoordinateSpace>['extent'], { kind: 'bounded' }>;\n readonly sampling: 'native';\n readonly voice?: VoiceDescriptor;\n };\n\nexport type Image<Point = unknown, CoordinateSpace = unknown> = MedeoEntity<'image'> &\n SequenceFields<Point, CoordinateSpace> & {\n readonly extent: Extract<SequenceFields<Point, CoordinateSpace>['extent'], { kind: 'unbounded' }>;\n readonly sampling: 'constant';\n };\n\nexport type Caption<Point = unknown, CoordinateSpace = unknown> = MedeoEntity<'caption'> &\n SequenceFields<Point, CoordinateSpace> & {\n readonly extent: Extract<SequenceFields<Point, CoordinateSpace>['extent'], { kind: 'bounded' }>;\n readonly sampling: 'native';\n readonly text?: string;\n readonly style?: CaptionStyleFields;\n };\n\nexport type AXVideo<Point = unknown, CoordinateSpace = unknown> = MedeoEntity<'axvideo'> &\n SequenceFields<Point, CoordinateSpace> & {\n readonly extent: Extract<SequenceFields<Point, CoordinateSpace>['extent'], { kind: 'bounded' }>;\n readonly sampling: 'derived';\n };\n\nexport type AudioScript<Segment extends ScriptTextSegment = ScriptTextSegment> = MedeoEntity<'audio-script'> &\n ScriptTextFields<Segment>;\n\nexport type PhoneticScript<Segment extends ScriptTextSegment = ScriptTextSegment> = MedeoEntity<'phonetic-script'> &\n ScriptTextFields<Segment>;\n\nexport type SequenceMarker<\n SourcePoint = unknown,\n TargetPoint = SourcePoint,\n Span = unknown,\n Remapping = unknown,\n> = MedeoEntity<'sequence-marker'> & {\n readonly sourceRange: SequenceRange<SourcePoint>;\n readonly targetRange?: SequenceRange<TargetPoint>;\n readonly duration: SequenceDuration<Span>;\n readonly timeRemapping?: Remapping;\n /** Offset from the host Clip selected by an ordered clip-anchor Relation. */\n readonly anchorOffset?: Span;\n /** Dynamic playback behavior. The source duration remains authoritative. */\n readonly durationPolicy?: 'timeline';\n};\n\n/** Capability constraint, intentionally open to future entity kinds. */\nexport type SequenceEntity<\n K extends KnownSequenceEntityKind | ExtensionEntityKind = KnownSequenceEntityKind | ExtensionEntityKind,\n> = MedeoEntity<K> & SequenceFields;\n\nexport function createExtensionEntityKind(value: string): ExtensionEntityKind {\n if (value.length === 0 || value.trim() !== value) {\n throw new Error('ExtensionEntityKind must be a non-empty trimmed string');\n }\n if (isKnownEntityKind(value) || isReservedEntityKind(value)) {\n throw new Error(`Entity kind \"${value}\" is known or reserved and cannot be registered as an extension`);\n }\n return value as ExtensionEntityKind;\n}\n\nexport function hasSequence(entity: MedeoEntity): entity is SequenceEntity {\n if (isKnownNonSequenceKind(entity.entityKind) || isReservedEntityKind(entity.entityKind)) return false;\n return isSequenceFields(entity);\n}\n\nexport function isSequenceFields(value: unknown): value is SequenceFields {\n if (!isRecord(value)) return false;\n const extent = value.extent;\n if (!isRecord(extent) || !('start' in extent) || extent.start === undefined) return false;\n if (extent.kind === 'bounded' && (!('end' in extent) || extent.end === undefined)) return false;\n if (extent.kind === 'unbounded' && 'end' in extent) return false;\n if (extent.kind !== 'bounded' && extent.kind !== 'unbounded') return false;\n if (value.sampling !== 'native' && value.sampling !== 'constant' && value.sampling !== 'derived') return false;\n return 'coordinateSpace' in value && value.coordinateSpace !== undefined;\n}\n\nexport function isKnownSequenceKind(kind: string): kind is KnownSequenceEntityKind {\n return (\n kind === 'video' ||\n kind === 'audio' ||\n kind === 'voice' ||\n kind === 'image' ||\n kind === 'caption' ||\n kind === 'axvideo'\n );\n}\n\nexport function isKnownEntityKind(kind: string): kind is KnownEntityKind {\n return isKnownSequenceKind(kind) || isKnownNonSequenceKind(kind);\n}\n\nexport function isReservedEntityKind(kind: string): boolean {\n const normalized = kind.toLowerCase().replaceAll('-', '').replaceAll('_', '');\n return normalized === 'speech' || normalized === 'videodocument';\n}\n\nexport function isKnownNonSequenceKind(kind: string): boolean {\n return (\n kind === 'timeline' ||\n kind === 'track' ||\n kind === 'clip' ||\n kind === 'asset' ||\n kind === 'sequence-marker' ||\n kind === 'viewport' ||\n kind === 'audio-script' ||\n kind === 'phonetic-script'\n );\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value != null && !Array.isArray(value);\n}\n","declare const entityIdBrand: unique symbol;\ndeclare const relationIdBrand: unique symbol;\n\nexport type EntityId = string & { readonly [entityIdBrand]: 'EntityId' };\nexport type RelationId = string & { readonly [relationIdBrand]: 'RelationId' };\n\nexport function createEntityId(value: string): EntityId {\n return createId(value, 'EntityId') as EntityId;\n}\n\nexport function createRelationId(value: string): RelationId {\n return createId(value, 'RelationId') as RelationId;\n}\n\nfunction createId(value: string, label: string): string {\n if (value.length === 0 || value.trim() !== value) throw new Error(`${label} must be a non-empty trimmed string`);\n return value;\n}\n","import {\n hasSequence,\n isReservedEntityKind,\n type AXVideo,\n type Caption,\n type Clip,\n type MedeoEntity,\n type SequenceMarker,\n} from './entities.ts';\nimport type { EntityId } from './ids.ts';\nimport type { BiRelationIndex } from './relation-index.ts';\nimport type { EntityRef, RelationAny } from './relations.ts';\n\nexport type EntityRelationIssueCode =\n | 'invalid_sequence_composition'\n | 'marker_container_xor'\n | 'marker_content_xor'\n | 'marker_pair_mismatch'\n | 'marker_source_range_empty'\n | 'marker_target_range_empty'\n | 'marker_source_out_of_bounds'\n | 'clip_marker_cardinality'\n | 'clip_content_cardinality'\n | 'clip_content_not_sequence'\n | 'axvideo_marker_cardinality'\n | 'caption_asset_required'\n | 'caption_inline_asset_mismatch'\n | 'clip_anchor_cardinality'\n | 'clip_anchor_cycle'\n | 'clip_placement_invalid'\n | 'timeline_duration_policy_invalid'\n | 'forbidden_entity_kind'\n | 'invalid_entity_payload'\n | 'peer_entity_id_field'\n | 'duplicate_entity_id';\n\nexport interface EntityRelationIssue {\n readonly code: EntityRelationIssueCode;\n readonly entityId: EntityId;\n readonly message: string;\n}\n\nexport interface MarkerRangeComparators<SourcePoint = unknown, TargetPoint = unknown> {\n readonly source: (left: SourcePoint, right: SourcePoint) => number;\n readonly target: (left: TargetPoint, right: TargetPoint) => number;\n}\n\nexport interface EntityRelationValidationOptions {\n readonly compareMarkerPoints: (\n marker: EntityRef<SequenceMarker>,\n range: 'source' | 'target',\n left: unknown,\n right: unknown,\n ) => number;\n}\n\n/** Validates one complete set of entities and its authoritative Relation rows. */\nexport function validateEntityRelationSet(\n entityRefs: readonly EntityRef[],\n index: BiRelationIndex,\n options: EntityRelationValidationOptions,\n): EntityRelationIssue[] {\n const { entities, issues } = collectRelatedEntities(entityRefs, index);\n const entityIds = new Set(entities.map((entity) => entity.entityId));\n for (const entity of entities) {\n const current = entity.current();\n const entityIssues = validateEntity(entity, entityIds);\n issues.push(...entityIssues);\n if (entityIssues.some((issue) => issue.code === 'invalid_entity_payload')) continue;\n if (current.entityKind === 'sequence-marker') {\n const marker = entity as EntityRef<SequenceMarker>;\n issues.push(...validateMarkerUse(entity as EntityRef<SequenceMarker>, index));\n issues.push(\n ...validateMarkerRanges(marker, {\n source: (left, right) => options.compareMarkerPoints(marker, 'source', left, right),\n target: (left, right) => options.compareMarkerPoints(marker, 'target', left, right),\n }),\n );\n issues.push(\n ...validateMarkerSourceBounds(marker, index, (left, right) =>\n options.compareMarkerPoints(marker, 'source', left, right),\n ),\n );\n }\n if (current.entityKind === 'clip') {\n issues.push(...validateClipAdmission(entity as EntityRef<Clip>, index));\n issues.push(...validateClipPlacement(entity as EntityRef<Clip>, index));\n }\n if (current.entityKind === 'axvideo') issues.push(...validateAXVideoAdmission(entity as EntityRef<AXVideo>, index));\n if (current.entityKind === 'caption') issues.push(...validateCaptionAsset(entity as EntityRef<Caption>, index));\n issues.push(...validateSequenceComposition(entity));\n }\n issues.push(...validateClipAnchorCycles(entities, index));\n return issues;\n}\n\nexport function validateMarkerUse(marker: EntityRef<SequenceMarker>, index: BiRelationIndex): EntityRelationIssue[] {\n const relations = [...index.relationsOf(marker)];\n const clipEdges = ofKind(relations, 'clip-marker');\n const axVideoEdges = ofKind(relations, 'axvideo-marker');\n const contentEdges = ofKind(relations, 'marker-content');\n const timelineEdges = ofKind(relations, 'marker-timeline');\n const issues: EntityRelationIssue[] = [];\n\n if (clipEdges.length + axVideoEdges.length !== 1) {\n issues.push({\n code: 'marker_container_xor',\n entityId: marker.entityId,\n message: 'Sequence Marker must have exactly one Clip XOR AXVideo container relation',\n });\n }\n if (contentEdges.length + timelineEdges.length !== 1) {\n issues.push({\n code: 'marker_content_xor',\n entityId: marker.entityId,\n message: 'Sequence Marker must have exactly one Sequence content XOR Timeline relation',\n });\n }\n if (\n (clipEdges.length === 1 && timelineEdges.length === 1) ||\n (axVideoEdges.length === 1 && contentEdges.length === 1)\n ) {\n issues.push({\n code: 'marker_pair_mismatch',\n entityId: marker.entityId,\n message: 'Only Clip+Content or AXVideo+Timeline Marker relation pairs are valid',\n });\n }\n return issues;\n}\n\nexport function validateClipAdmission(clip: EntityRef<Clip>, index: BiRelationIndex): EntityRelationIssue[] {\n const markerEdges = ofKind([...index.relationsOf(clip)], 'clip-marker');\n if (markerEdges.length !== 1) {\n return [\n {\n code: 'clip_marker_cardinality',\n entityId: clip.entityId,\n message: 'Clip must have exactly one authoritative Clip-Marker Relation',\n },\n ];\n }\n\n const marker = markerEdges[0]?.other(clip)?.deref();\n if (marker == null) {\n return [\n {\n code: 'clip_content_cardinality',\n entityId: clip.entityId,\n message: 'Clip must resolve one live Sequence Marker and one content Relation',\n },\n ];\n }\n const contentEdges = ofKind([...index.relationsOf(marker)], 'marker-content');\n if (contentEdges.length !== 1) {\n return [\n {\n code: 'clip_content_cardinality',\n entityId: clip.entityId,\n message: 'Clip Marker must resolve exactly one content Relation',\n },\n ];\n }\n const content = contentEdges[0]?.other(marker)?.deref()?.current();\n if (content == null) {\n return [\n {\n code: 'clip_content_cardinality',\n entityId: clip.entityId,\n message: 'Clip Marker content Relation must resolve one live entity',\n },\n ];\n }\n if (!hasSequence(content)) {\n return [\n {\n code: 'clip_content_not_sequence',\n entityId: clip.entityId,\n message: `Clip Marker resolves to non-Sequence entity \"${content.entityId}\"`,\n },\n ];\n }\n return [];\n}\n\nexport function validateAXVideoAdmission(axVideo: EntityRef<AXVideo>, index: BiRelationIndex): EntityRelationIssue[] {\n const markerEdges = ofKind([...index.relationsOf(axVideo)], 'axvideo-marker');\n if (markerEdges.length === 1 && markerEdges[0]?.other(axVideo)?.deref() != null) return [];\n return [\n {\n code: 'axvideo_marker_cardinality',\n entityId: axVideo.entityId,\n message: 'AXVideo must have exactly one live AXVideo-Marker Relation',\n },\n ];\n}\n\nexport function validateCaptionAsset(caption: EntityRef<Caption>, index: BiRelationIndex): EntityRelationIssue[] {\n const assetEdges = ofKind([...index.relationsOf(caption)], 'physical-asset');\n const assets = assetEdges\n .map((relation) => relation.other(caption)?.deref()?.current())\n .filter((entity): entity is MedeoEntity<'asset'> => entity?.entityKind === 'asset');\n if (assets.length > 0) {\n const captionText = caption.current().text;\n const mismatched = assets.some((asset) => {\n const inline = (asset as unknown as Readonly<Record<string, unknown>>).inline;\n return isRecord(inline) && inline.mediaType === 'text/plain' && inline.text !== captionText;\n });\n if (!mismatched) return [];\n return [\n {\n code: 'caption_inline_asset_mismatch',\n entityId: caption.entityId,\n message: 'Caption text must match the text/plain inline Physical Asset',\n },\n ];\n }\n return [\n {\n code: 'caption_asset_required',\n entityId: caption.entityId,\n message: 'Caption must have a Physical Asset Relation',\n },\n ];\n}\n\nexport function validateClipPlacement(clip: EntityRef<Clip>, index: BiRelationIndex): EntityRelationIssue[] {\n const markerEdge = ofKind([...index.relationsOf(clip)], 'clip-marker')[0];\n const marker = markerEdge?.other(clip)?.deref();\n if (marker?.current().entityKind !== 'sequence-marker') return [];\n const markerValue = marker.current() as SequenceMarker;\n const anchors = ofKind([...index.relationsOf(clip)], 'clip-anchor').filter(\n (relation) => relation.endpoints[0].deref() === clip,\n );\n const hasOrder = clip.current().order !== undefined;\n const hasTarget = markerValue.targetRange !== undefined;\n const hasAnchorOffset = markerValue.anchorOffset !== undefined;\n const issues: EntityRelationIssue[] = [];\n if (anchors.length > 1) {\n issues.push({\n code: 'clip_anchor_cardinality',\n entityId: clip.entityId,\n message: 'A Clip may follow at most one host Clip',\n });\n }\n const hasAnchor = anchors.length === 1;\n if (\n (hasAnchor && (!hasAnchorOffset || hasOrder || hasTarget)) ||\n (!hasAnchor && (hasAnchorOffset || Number(hasOrder) + Number(hasTarget) !== 1))\n ) {\n issues.push({\n code: 'clip_placement_invalid',\n entityId: clip.entityId,\n message:\n 'Clip placement must be exactly one of Clip.order, Marker.targetRange, or clip-anchor with Marker.anchorOffset',\n });\n }\n if (markerValue.durationPolicy === 'timeline') {\n const content = ofKind([...index.relationsOf(marker)], 'marker-content')[0]\n ?.other(marker)\n ?.deref()\n ?.current();\n const track = ofKind([...index.relationsOf(clip)], 'track-clip')[0]\n ?.other(clip)\n ?.deref()\n ?.current();\n const trackRole =\n track?.entityKind === 'track' ? (track as unknown as Readonly<Record<string, unknown>>).role : undefined;\n if (content?.entityKind !== 'audio' || trackRole !== 'bgm' || !hasOrder) {\n issues.push({\n code: 'timeline_duration_policy_invalid',\n entityId: marker.entityId,\n message: 'Marker durationPolicy \"timeline\" is only valid for ordered Audio Clips on the bgm Track',\n });\n }\n }\n return issues;\n}\n\nfunction validateClipAnchorCycles(entities: readonly EntityRef[], index: BiRelationIndex): EntityRelationIssue[] {\n const hostByChild = new Map<EntityId, EntityId>();\n for (const entity of entities) {\n if (entity.current().entityKind !== 'clip') continue;\n for (const relation of ofKind([...index.relationsOf(entity)], 'clip-anchor')) {\n if (relation.endpoints[0].deref() !== entity) continue;\n const host = relation.endpoints[1].deref();\n if (host != null) hostByChild.set(entity.entityId, host.entityId);\n }\n }\n const issues: EntityRelationIssue[] = [];\n for (const child of hostByChild.keys()) {\n const seen = new Set<EntityId>();\n let current: EntityId | undefined = child;\n while (current !== undefined && !seen.has(current)) {\n seen.add(current);\n current = hostByChild.get(current);\n }\n if (current === undefined) continue;\n issues.push({\n code: 'clip_anchor_cycle',\n entityId: child,\n message: 'clip-anchor Relations must form an acyclic dependency graph',\n });\n }\n return issues;\n}\n\nexport function validateMarkerRanges<SourcePoint, TargetPoint>(\n marker: EntityRef<SequenceMarker<SourcePoint, TargetPoint>>,\n compare: MarkerRangeComparators<SourcePoint, TargetPoint>,\n): EntityRelationIssue[] {\n const current = marker.current();\n const issues: EntityRelationIssue[] = [];\n if (!(compare.source(current.sourceRange.start, current.sourceRange.end) < 0)) {\n issues.push({\n code: 'marker_source_range_empty',\n entityId: marker.entityId,\n message: 'Sequence Marker sourceRange must be a non-empty half-open interval',\n });\n }\n if (current.targetRange != null && !(compare.target(current.targetRange.start, current.targetRange.end) < 0)) {\n issues.push({\n code: 'marker_target_range_empty',\n entityId: marker.entityId,\n message: 'Sequence Marker targetRange must be a non-empty half-open interval',\n });\n }\n return issues;\n}\n\nexport function validateMarkerSourceBounds(\n marker: EntityRef<SequenceMarker>,\n index: BiRelationIndex,\n compare: (left: unknown, right: unknown) => number,\n): EntityRelationIssue[] {\n const contentEdges = ofKind([...index.relationsOf(marker)], 'marker-content');\n if (contentEdges.length !== 1) return [];\n const content = contentEdges[0]?.other(marker)?.deref()?.current();\n if (content == null || !hasSequence(content)) return [];\n\n const sourceRange = marker.current().sourceRange;\n const startVsExtent = compare(sourceRange.start, content.extent.start);\n const endVsExtent = content.extent.kind === 'bounded' ? compare(sourceRange.end, content.extent.end) : undefined;\n if (\n !Number.isNaN(startVsExtent) &&\n startVsExtent >= 0 &&\n (endVsExtent == null || (!Number.isNaN(endVsExtent) && endVsExtent <= 0))\n ) {\n return [];\n }\n return [\n {\n code: 'marker_source_out_of_bounds',\n entityId: marker.entityId,\n message: `Sequence Marker sourceRange must stay within content \"${content.entityId}\" extent`,\n },\n ];\n}\n\nexport function validateSequenceComposition(entity: EntityRef): EntityRelationIssue[] {\n const current = entity.current();\n const expected = expectedSequenceShape(current.entityKind);\n if (expected == null) return [];\n if (hasSequence(current) && current.extent.kind === expected.extent && current.sampling === expected.sampling) {\n return [];\n }\n return [\n {\n code: 'invalid_sequence_composition',\n entityId: current.entityId,\n message: `${current.entityKind} must compose ${expected.extent} / ${expected.sampling} Sequence semantics`,\n },\n ];\n}\n\nexport function validateEntity(entity: EntityRef, entityIds: ReadonlySet<EntityId> = new Set()): EntityRelationIssue[] {\n const current = entity.current();\n const issues: EntityRelationIssue[] = [];\n if (isReservedEntityKind(current.entityKind)) {\n issues.push({\n code: 'forbidden_entity_kind',\n entityId: current.entityId,\n message: `Entity kind \"${current.entityKind}\" is explicitly outside the Medeo DSL`,\n });\n }\n\n for (const problem of validateKnownEntityPayload(current)) {\n issues.push({\n code: 'invalid_entity_payload',\n entityId: current.entityId,\n message: `Entity \"${current.entityKind}\" ${problem}`,\n });\n }\n\n const peerIdPaths = [\n ...collectPeerEntityIdPaths(current, current.entityKind),\n ...collectPeerEntityValuePaths(current, current.entityKind, current.entityId, entityIds),\n ];\n const uniquePeerIdPaths = [...new Set(peerIdPaths)].sort();\n if (uniquePeerIdPaths.length > 0) {\n issues.push({\n code: 'peer_entity_id_field',\n entityId: current.entityId,\n message: `Entity embeds forbidden peer-ID field/value path(s): ${uniquePeerIdPaths.join(', ')}`,\n });\n }\n\n return issues;\n}\n\nfunction validateKnownEntityPayload(entity: MedeoEntity): readonly string[] {\n const value = entity as unknown as Readonly<Record<string, unknown>>;\n const problems: string[] = [];\n\n if (value.lifecycle !== undefined && !isRecord(value.lifecycle)) {\n problems.push('lifecycle must be an object when present');\n }\n\n switch (entity.entityKind) {\n case 'track':\n validateOptionalField(value, 'hidden', 'boolean', problems);\n validateOptionalField(value, 'role', 'string', problems);\n validateOptionalFiniteNumber(value, 'order', problems);\n break;\n case 'video':\n case 'audio':\n case 'voice':\n case 'caption':\n validateSequencePayload(value, 'bounded', 'native', problems);\n if (entity.entityKind === 'voice') validateVoicePayload(value, problems);\n if (entity.entityKind === 'caption') validateCaptionPayload(value, problems);\n break;\n case 'image':\n validateSequencePayload(value, 'unbounded', 'constant', problems);\n break;\n case 'axvideo':\n validateSequencePayload(value, 'bounded', 'derived', problems);\n break;\n case 'sequence-marker':\n validateMarkerPayload(value, problems);\n break;\n case 'audio-script':\n case 'phonetic-script':\n validateScriptPayload(value, problems);\n break;\n case 'timeline':\n case 'viewport':\n break;\n case 'clip':\n validateOptionalFiniteNumber(value, 'order', problems);\n validateOptionalFiniteNumber(value, 'volume', problems);\n if (typeof value.volume === 'number' && (value.volume < -60 || value.volume > 20)) {\n problems.push('volume must be decibels between -60 and 20');\n }\n break;\n case 'asset':\n validateAssetPayload(value, problems);\n break;\n default:\n break;\n }\n\n return problems;\n}\n\nfunction validateSequencePayload(\n value: Readonly<Record<string, unknown>>,\n expectedExtent: 'bounded' | 'unbounded',\n expectedSampling: 'native' | 'constant' | 'derived',\n problems: string[],\n): void {\n const extent = value.extent;\n if (!isRecord(extent)) {\n problems.push('extent must be an object');\n } else {\n if (extent.kind !== expectedExtent) problems.push(`extent.kind must be \"${expectedExtent}\"`);\n if (!Object.hasOwn(extent, 'start') || extent.start === undefined) {\n problems.push('extent.start is required');\n }\n if (expectedExtent === 'bounded' && (!Object.hasOwn(extent, 'end') || extent.end === undefined)) {\n problems.push('extent.end is required for bounded sequences');\n }\n if (expectedExtent === 'unbounded' && Object.hasOwn(extent, 'end')) {\n problems.push('extent.end is forbidden for unbounded sequences');\n }\n }\n if (value.sampling !== expectedSampling) problems.push(`sampling must be \"${expectedSampling}\"`);\n if (!Object.hasOwn(value, 'coordinateSpace') || value.coordinateSpace === undefined) {\n problems.push('coordinateSpace is required');\n }\n}\n\nfunction validateMarkerPayload(value: Readonly<Record<string, unknown>>, problems: string[]): void {\n validateRange(value.sourceRange, 'sourceRange', true, problems);\n if (Object.hasOwn(value, 'targetRange') && value.targetRange !== undefined) {\n validateRange(value.targetRange, 'targetRange', true, problems);\n }\n\n const duration = value.duration;\n if (!isRecord(duration)) {\n problems.push('duration must be an object');\n } else if (duration.mode === 'fixed') {\n if (!Object.hasOwn(duration, 'value') || duration.value === undefined) {\n problems.push('duration.value is required when duration.mode is \"fixed\"');\n }\n } else if (duration.mode !== 'from-source') {\n problems.push('duration.mode must be \"from-source\" or \"fixed\"');\n }\n if (value.anchorOffset === undefined && Object.hasOwn(value, 'anchorOffset')) {\n problems.push('anchorOffset cannot be undefined when present');\n }\n if (value.durationPolicy !== undefined && value.durationPolicy !== 'timeline') {\n problems.push('durationPolicy must be \"timeline\" when present');\n }\n}\n\nfunction validateAssetPayload(value: Readonly<Record<string, unknown>>, problems: string[]): void {\n const external = value.external;\n if (external !== undefined) {\n if (!isRecord(external)) {\n problems.push('external must be an object when present');\n } else {\n if (external.system !== 'memota' && external.system !== 'memota-speech') {\n problems.push('external.system must be \"memota\" or \"memota-speech\"');\n }\n if (typeof external.key !== 'string' || external.key.trim() === '') {\n problems.push('external.key must be a non-empty string');\n }\n }\n }\n if (value.storageKey !== undefined && (typeof value.storageKey !== 'string' || value.storageKey.trim() === '')) {\n problems.push('storageKey must be a non-empty string when present');\n }\n const inline = value.inline;\n if (inline !== undefined) {\n if (!isRecord(inline)) {\n problems.push('inline must be an object when present');\n } else {\n if (inline.mediaType !== 'text/plain') problems.push('inline.mediaType must be \"text/plain\"');\n if (typeof inline.text !== 'string') problems.push('inline.text must be a string');\n }\n }\n if (external !== undefined && inline !== undefined) {\n problems.push('Asset must not combine external and inline physical locations');\n }\n}\n\nfunction validateVoicePayload(value: Readonly<Record<string, unknown>>, problems: string[]): void {\n const voice = value.voice;\n if (voice === undefined) return;\n if (!isRecord(voice)) {\n problems.push('voice must be an object when present');\n return;\n }\n if (voice.system !== 'voice-library') problems.push('voice.system must be \"voice-library\"');\n if (typeof voice.key !== 'string' || voice.key.trim() === '') problems.push('voice.key must be a non-empty string');\n if (voice.name !== undefined && typeof voice.name !== 'string')\n problems.push('voice.name must be a string when present');\n}\n\nfunction validateCaptionPayload(value: Readonly<Record<string, unknown>>, problems: string[]): void {\n if (value.text !== undefined && typeof value.text !== 'string') problems.push('text must be a string when present');\n const style = value.style;\n if (style === undefined) return;\n if (!isRecord(style)) {\n problems.push('style must be an object when present');\n return;\n }\n const font = style.font;\n if (font !== undefined) {\n if (!isRecord(font)) {\n problems.push('style.font must be an object when present');\n } else {\n if (font.system !== 'font-library') problems.push('style.font.system must be \"font-library\"');\n if (typeof font.key !== 'string' || font.key.trim() === '') {\n problems.push('style.font.key must be a non-empty string');\n }\n }\n }\n for (const key of [\n 'fontSize',\n 'fontWeight',\n 'entranceAnimationDurationMs',\n 'strokeWidth',\n 'positionX',\n 'positionY',\n ]) {\n validateOptionalFiniteNumber(style, key, problems, `style.${key}`);\n }\n for (const key of ['fontColor', 'entranceAnimation', 'strokeColor']) {\n if (style[key] !== undefined && typeof style[key] !== 'string') problems.push(`style.${key} must be a string`);\n }\n}\n\nfunction validateRange(value: unknown, path: string, required: boolean, problems: string[]): void {\n if (!isRecord(value)) {\n if (required) problems.push(`${path} must be an object`);\n return;\n }\n if (!Object.hasOwn(value, 'start') || value.start === undefined) problems.push(`${path}.start is required`);\n if (!Object.hasOwn(value, 'end') || value.end === undefined) problems.push(`${path}.end is required`);\n}\n\nfunction validateScriptPayload(value: Readonly<Record<string, unknown>>, problems: string[]): void {\n if (!Array.isArray(value.segments)) {\n problems.push('segments must be an array');\n return;\n }\n for (const [index, segment] of value.segments.entries()) {\n if (!isRecord(segment)) {\n problems.push(`segments[${index}] must be an object`);\n continue;\n }\n if (typeof segment.segmentId !== 'string') problems.push(`segments[${index}].segmentId must be a string`);\n if (typeof segment.text !== 'string') problems.push(`segments[${index}].text must be a string`);\n if (segment.language !== undefined && typeof segment.language !== 'string') {\n problems.push(`segments[${index}].language must be a string when present`);\n }\n }\n}\n\nfunction validateOptionalField(\n value: Readonly<Record<string, unknown>>,\n key: string,\n expectedType: 'boolean' | 'string',\n problems: string[],\n): void {\n if (value[key] !== undefined && typeof value[key] !== expectedType) {\n problems.push(`${key} must be a ${expectedType} when present`);\n }\n}\n\nfunction validateOptionalFiniteNumber(\n value: Readonly<Record<string, unknown>>,\n key: string,\n problems: string[],\n label: string = key,\n): void {\n if (value[key] !== undefined && (typeof value[key] !== 'number' || !Number.isFinite(value[key]))) {\n problems.push(`${label} must be a finite number when present`);\n }\n}\n\nfunction collectPeerEntityIdPaths(value: unknown, entityKind: string): readonly string[] {\n const paths: string[] = [];\n visitPeerEntityIdPaths(value, entityKind, '', new Set(), paths);\n return paths;\n}\n\nfunction visitPeerEntityIdPaths(\n value: unknown,\n entityKind: string,\n parentPath: string,\n ancestors: Set<object>,\n paths: string[],\n): void {\n if (typeof value !== 'object' || value == null) return;\n if (ancestors.has(value)) return;\n\n ancestors.add(value);\n if (Array.isArray(value)) {\n for (const [index, item] of value.entries()) {\n visitPeerEntityIdPaths(item, entityKind, `${parentPath}[${index}]`, ancestors, paths);\n }\n } else {\n for (const [key, child] of Object.entries(value)) {\n const path = parentPath.length === 0 ? key : `${parentPath}.${key}`;\n const isOwnEntityId = parentPath.length === 0 && key === 'entityId';\n if (!isOwnEntityId && !isOwnedLocalIdPath(entityKind, path) && isEntityIdFieldName(key)) paths.push(path);\n visitPeerEntityIdPaths(child, entityKind, path, ancestors, paths);\n }\n }\n ancestors.delete(value);\n}\n\nfunction collectPeerEntityValuePaths(\n value: unknown,\n entityKind: string,\n ownEntityId: EntityId,\n entityIds: ReadonlySet<EntityId>,\n): readonly string[] {\n const paths: string[] = [];\n visitPeerEntityValues(value, entityKind, ownEntityId, entityIds, '', new Set(), paths);\n return paths;\n}\n\nfunction visitPeerEntityValues(\n value: unknown,\n entityKind: string,\n ownEntityId: EntityId,\n entityIds: ReadonlySet<EntityId>,\n path: string,\n ancestors: Set<object>,\n paths: string[],\n): void {\n if (typeof value === 'string') {\n if (value !== ownEntityId && entityIds.has(value as EntityId) && !isOwnedLocalEntityValuePath(entityKind, path))\n paths.push(path);\n return;\n }\n if (typeof value !== 'object' || value == null || ancestors.has(value)) return;\n\n ancestors.add(value);\n if (Array.isArray(value)) {\n for (const [index, item] of value.entries()) {\n visitPeerEntityValues(item, entityKind, ownEntityId, entityIds, `${path}[${index}]`, ancestors, paths);\n }\n } else {\n for (const [key, child] of Object.entries(value)) {\n if (path.length === 0 && (key === 'entityId' || key === 'entityKind')) continue;\n visitPeerEntityValues(\n child,\n entityKind,\n ownEntityId,\n entityIds,\n path.length === 0 ? key : `${path}.${key}`,\n ancestors,\n paths,\n );\n }\n }\n ancestors.delete(value);\n}\n\nfunction isOwnedLocalEntityValuePath(entityKind: string, path: string): boolean {\n if (entityKind === 'track' && path === 'role') return true;\n if (\n ['video', 'audio', 'voice', 'image', 'caption', 'axvideo'].includes(entityKind) &&\n /^(?:sampling|coordinateSpace|coordinateSpace\\.unit|extent\\.kind)$/.test(path)\n )\n return true;\n if (entityKind === 'sequence-marker' && /^(?:durationPolicy|duration\\.mode|timeRemapping\\.(?:kind|mode))$/.test(path))\n return true;\n if (entityKind === 'asset' && /^(?:external\\.(?:system|key)|storageKey|inline\\.(?:mediaType|text))$/.test(path))\n return true;\n if (entityKind === 'voice' && /^voice\\.(?:system|key|name)$/.test(path)) return true;\n if (entityKind === 'caption' && (path === 'text' || path.startsWith('style.'))) return true;\n if (\n (entityKind === 'audio-script' || entityKind === 'phonetic-script') &&\n /^segments\\[\\d+\\]\\.(?:segmentId|text|language)$/.test(path)\n )\n return true;\n return false;\n}\n\nfunction isOwnedLocalIdPath(entityKind: string, path: string): boolean {\n if (path === 'lifecycle.actorId') return true;\n if (\n (entityKind === 'audio-script' || entityKind === 'phonetic-script') &&\n /^segments\\[\\d+\\]\\.segmentId$/.test(path)\n ) {\n return true;\n }\n if (entityKind === 'asset' && /^(?:tracks\\[\\d+\\]\\.trackId|renditions\\[\\d+\\]\\.renditionId)$/.test(path)) {\n return true;\n }\n return false;\n}\n\nfunction isEntityIdFieldName(key: string): boolean {\n return key.endsWith('Id') || key.endsWith('Ids') || key.endsWith('ID') || key.endsWith('IDs') || /_ids?$/i.test(key);\n}\n\nfunction isRecord(value: unknown): value is Readonly<Record<string, unknown>> {\n return typeof value === 'object' && value != null && !Array.isArray(value);\n}\n\nfunction collectRelatedEntities(\n entityRefs: readonly EntityRef[],\n index: BiRelationIndex,\n): { readonly entities: readonly EntityRef[]; readonly issues: EntityRelationIssue[] } {\n const byId = new Map<EntityId, EntityRef>();\n const queue = [...entityRefs];\n const issues: EntityRelationIssue[] = [];\n while (queue.length > 0) {\n const entity = queue.shift();\n if (entity == null) continue;\n const existing = byId.get(entity.entityId);\n if (existing != null) {\n if (existing !== entity) {\n issues.push({\n code: 'duplicate_entity_id',\n entityId: entity.entityId,\n message: `Entity id \"${entity.entityId}\" has more than one live EntityRef`,\n });\n }\n continue;\n }\n byId.set(entity.entityId, entity);\n for (const relation of index.relationsOf(entity)) {\n for (const endpoint of relation.endpoints) {\n const ref = endpoint.deref();\n if (ref != null && !byId.has(ref.entityId)) queue.push(ref);\n }\n }\n }\n return { entities: [...byId.values()], issues };\n}\n\nfunction expectedSequenceShape(\n kind: string,\n): { readonly extent: 'bounded' | 'unbounded'; readonly sampling: 'native' | 'constant' | 'derived' } | undefined {\n if (kind === 'video' || kind === 'audio' || kind === 'voice' || kind === 'caption') {\n return { extent: 'bounded', sampling: 'native' };\n }\n if (kind === 'image') return { extent: 'unbounded', sampling: 'constant' };\n if (kind === 'axvideo') return { extent: 'bounded', sampling: 'derived' };\n return undefined;\n}\n\nfunction ofKind(relations: readonly RelationAny[], kind: string): RelationAny[] {\n return relations.filter((relation) => relation.kind === kind);\n}\n","export type JsonPrimitive = string | number | boolean | null;\nexport type JsonValue = JsonPrimitive | JsonObject | readonly JsonValue[];\nexport type JsonObject = { readonly [key: string]: JsonValue };\n\nconst nativeObjectConstructorSource = Function.prototype.toString.call(Object);\n\nexport function isJsonObject(value: unknown): value is JsonObject {\n return isJsonValue(value, new Set()) && !Array.isArray(value) && value !== null;\n}\n\nfunction isJsonValue(value: unknown, ancestors: Set<object>): value is JsonValue {\n if (value === null || typeof value === 'string' || typeof value === 'boolean') return true;\n if (typeof value === 'number') return Number.isFinite(value);\n if (typeof value !== 'object') return false;\n\n if (!Array.isArray(value) && !isPlainObject(value)) return false;\n if (ancestors.has(value)) return false;\n\n ancestors.add(value);\n const valid = Array.isArray(value)\n ? value.every((item) => isJsonValue(item, ancestors))\n : Object.values(value).every((item) => isJsonValue(item, ancestors));\n ancestors.delete(value);\n return valid;\n}\n\n/** Recognize an ordinary object from any VM realm without admitting class instances. */\nfunction isPlainObject(value: object): boolean {\n try {\n const prototype = Object.getPrototypeOf(value);\n if (prototype === null) return true;\n if (Object.getPrototypeOf(prototype) !== null) return false;\n const constructor = Object.getOwnPropertyDescriptor(prototype, 'constructor')?.value;\n return (\n typeof constructor === 'function' &&\n constructor.prototype === prototype &&\n Function.prototype.toString.call(constructor) === nativeObjectConstructorSource\n );\n } catch {\n return false;\n }\n}\n","import type {\n Asset,\n Audio,\n AudioScript,\n AXVideo,\n Caption,\n Clip,\n EntityKind,\n Image,\n MedeoEntity,\n PhoneticScript,\n SequenceEntity,\n SequenceMarker,\n Timeline,\n Track,\n Video,\n Voice,\n} from './entities.ts';\nimport { hasSequence } from './entities.ts';\nimport { isJsonObject, type JsonObject, type JsonValue } from './json-values.ts';\nimport type { EmptyMetadata, EntityRef, RelationEndpoints, RelationKindSpec } from './relations.ts';\n\nexport type AssetBinding = JsonObject;\nexport type GeneratedMedia = Video | Image | Audio | Voice;\nexport type GeneratedMetadata = EmptyMetadata;\nexport type AudioScriptRenderOutput = Audio | Voice;\n\nexport interface SegmentAlignmentMetadata extends JsonObject {\n readonly segmentAlignment: JsonValue;\n}\n\nexport interface CaptionAlignmentMetadata extends JsonObject {\n readonly alignment: JsonValue;\n}\n\nexport const timelineTrackRelationSpec = emptySpec<'timeline-track', Timeline, Track>(\n 'timeline-track',\n 'timeline',\n 'track',\n);\nexport const trackClipRelationSpec = emptySpec<'track-clip', Track, Clip>('track-clip', 'track', 'clip');\nexport const clipMarkerRelationSpec = emptySpec<'clip-marker', Clip, SequenceMarker>(\n 'clip-marker',\n 'clip',\n 'sequence-marker',\n);\nexport const axVideoMarkerRelationSpec = emptySpec<'axvideo-marker', AXVideo, SequenceMarker>(\n 'axvideo-marker',\n 'axvideo',\n 'sequence-marker',\n);\nexport const markerTimelineRelationSpec = emptySpec<'marker-timeline', SequenceMarker, Timeline>(\n 'marker-timeline',\n 'sequence-marker',\n 'timeline',\n);\n\nexport const markerContentRelationSpec: RelationKindSpec<\n 'marker-content',\n SequenceMarker,\n SequenceEntity,\n EmptyMetadata\n> = Object.freeze({\n kind: 'marker-content',\n validateEndpoints: (\n endpoints: RelationEndpoints<EntityRef, EntityRef>,\n ): endpoints is RelationEndpoints<EntityRef<SequenceMarker>, EntityRef<SequenceEntity>> =>\n hasMarkerAndSequence(endpoints),\n validateMetadata: isEmptyMetadata,\n});\n\nexport const physicalAssetRelationSpec: RelationKindSpec<'physical-asset', SequenceEntity, Asset, AssetBinding> =\n Object.freeze({\n kind: 'physical-asset',\n validateEndpoints: (\n endpoints: RelationEndpoints<EntityRef, EntityRef>,\n ): endpoints is RelationEndpoints<EntityRef<SequenceEntity>, EntityRef<Asset>> => hasAssetAndSequence(endpoints),\n validateMetadata: isAssetBinding,\n });\n\n/** `generated(output, input)` means endpoint 0 was generated from endpoint 1. */\nexport const generatedRelationSpec: RelationKindSpec<'generated', GeneratedMedia, GeneratedMedia, GeneratedMetadata> =\n Object.freeze({\n kind: 'generated',\n validateEndpoints: (\n endpoints: RelationEndpoints<EntityRef, EntityRef>,\n ): endpoints is RelationEndpoints<EntityRef<GeneratedMedia>, EntityRef<GeneratedMedia>> =>\n endpoints.every((endpoint) => isGeneratedMedia(endpoint.current())),\n validateMetadata: isEmptyMetadata,\n });\n\nexport const phoneticScriptProvenanceRelationSpec = metadataSpec<\n 'phonetic-script-provenance',\n PhoneticScript,\n AudioScript,\n SegmentAlignmentMetadata\n>('phonetic-script-provenance', 'phonetic-script', 'audio-script', isSegmentAlignmentMetadata);\n\nexport const captionProvenanceRelationSpec = metadataSpec<\n 'caption-provenance',\n Caption,\n AudioScript,\n SegmentAlignmentMetadata\n>('caption-provenance', 'caption', 'audio-script', isSegmentAlignmentMetadata);\n\nexport const captionAlignmentRelationSpec: RelationKindSpec<\n 'caption-alignment',\n Caption,\n Audio | Voice,\n CaptionAlignmentMetadata\n> = Object.freeze({\n kind: 'caption-alignment',\n validateEndpoints: (\n endpoints: RelationEndpoints<EntityRef, EntityRef>,\n ): endpoints is RelationEndpoints<EntityRef<Caption>, EntityRef<Audio | Voice>> =>\n hasKinds(endpoints, new Set(['caption']), new Set(['audio', 'voice'])),\n validateMetadata: isCaptionAlignmentMetadata,\n});\n\n/** `clip-anchor(child, host)` means endpoint 0 follows endpoint 1. */\nexport const clipAnchorRelationSpec: RelationKindSpec<'clip-anchor', Clip, Clip, EmptyMetadata> = Object.freeze({\n kind: 'clip-anchor',\n validateEndpoints: (\n endpoints: RelationEndpoints<EntityRef, EntityRef>,\n ): endpoints is RelationEndpoints<EntityRef<Clip>, EntityRef<Clip>> =>\n endpoints[0].current().entityKind === 'clip' && endpoints[1].current().entityKind === 'clip',\n validateMetadata: isEmptyMetadata,\n});\n\n/** `audio-script-render(output, script)` means endpoint 0 was rendered from endpoint 1. */\nexport const audioScriptRenderRelationSpec: RelationKindSpec<\n 'audio-script-render',\n AudioScriptRenderOutput,\n AudioScript,\n EmptyMetadata\n> = Object.freeze({\n kind: 'audio-script-render',\n validateEndpoints: (\n endpoints: RelationEndpoints<EntityRef, EntityRef>,\n ): endpoints is RelationEndpoints<EntityRef<AudioScriptRenderOutput>, EntityRef<AudioScript>> => {\n const outputKind = endpoints[0].current().entityKind;\n return (outputKind === 'audio' || outputKind === 'voice') && endpoints[1].current().entityKind === 'audio-script';\n },\n validateMetadata: isEmptyMetadata,\n});\n\n/** Built-in kinds are reserved; callers may add specs only under new names. */\nexport const builtInRelationSpecs = Object.freeze([\n timelineTrackRelationSpec,\n trackClipRelationSpec,\n clipMarkerRelationSpec,\n markerContentRelationSpec,\n axVideoMarkerRelationSpec,\n markerTimelineRelationSpec,\n physicalAssetRelationSpec,\n generatedRelationSpec,\n phoneticScriptProvenanceRelationSpec,\n captionProvenanceRelationSpec,\n captionAlignmentRelationSpec,\n clipAnchorRelationSpec,\n audioScriptRenderRelationSpec,\n]);\n\nfunction emptySpec<K extends string, A extends MedeoEntity<EntityKind>, B extends MedeoEntity<EntityKind>>(\n kind: K,\n a: A['entityKind'],\n b: B['entityKind'],\n): RelationKindSpec<K, A, B, EmptyMetadata> {\n return metadataSpec(kind, a, b, isEmptyMetadata);\n}\n\nfunction metadataSpec<\n K extends string,\n A extends MedeoEntity<EntityKind>,\n B extends MedeoEntity<EntityKind>,\n Metadata extends JsonObject,\n>(\n kind: K,\n a: A['entityKind'],\n b: B['entityKind'],\n validateMetadata: (value: unknown) => value is Metadata,\n): RelationKindSpec<K, A, B, Metadata> {\n return Object.freeze({\n kind,\n validateEndpoints: (\n endpoints: RelationEndpoints<EntityRef, EntityRef>,\n ): endpoints is RelationEndpoints<EntityRef<A>, EntityRef<B>> => hasKinds(endpoints, new Set([a]), new Set([b])),\n validateMetadata,\n });\n}\n\nfunction hasKinds(\n endpoints: RelationEndpoints<EntityRef, EntityRef>,\n aKinds: ReadonlySet<string>,\n bKinds: ReadonlySet<string>,\n): boolean {\n const first = endpoints[0].current().entityKind;\n const second = endpoints[1].current().entityKind;\n return (aKinds.has(first) && bKinds.has(second)) || (aKinds.has(second) && bKinds.has(first));\n}\n\nfunction hasMarkerAndSequence(endpoints: RelationEndpoints<EntityRef, EntityRef>): boolean {\n const first = endpoints[0].current();\n const second = endpoints[1].current();\n return (\n (first.entityKind === 'sequence-marker' && hasSequence(second)) ||\n (second.entityKind === 'sequence-marker' && hasSequence(first))\n );\n}\n\nfunction hasAssetAndSequence(endpoints: RelationEndpoints<EntityRef, EntityRef>): boolean {\n const first = endpoints[0].current();\n const second = endpoints[1].current();\n return (first.entityKind === 'asset' && hasSequence(second)) || (second.entityKind === 'asset' && hasSequence(first));\n}\n\nfunction isGeneratedMedia(entity: MedeoEntity): entity is GeneratedMedia {\n return (\n entity.entityKind === 'video' ||\n entity.entityKind === 'image' ||\n entity.entityKind === 'audio' ||\n entity.entityKind === 'voice'\n );\n}\n\nfunction isEmptyMetadata(value: unknown): value is EmptyMetadata {\n return isJsonObject(value) && Object.keys(value).length === 0;\n}\n\nfunction isAssetBinding(value: unknown): value is AssetBinding {\n if (!isJsonObject(value)) return false;\n const orderingKey = /(order|ordinal|position|rank|index|z[_-]?index)/i;\n return Object.keys(value).every((key) => !orderingKey.test(key));\n}\n\nfunction isSegmentAlignmentMetadata(value: unknown): value is SegmentAlignmentMetadata {\n return isJsonObject(value) && Object.hasOwn(value, 'segmentAlignment');\n}\n\nfunction isCaptionAlignmentMetadata(value: unknown): value is CaptionAlignmentMetadata {\n return isJsonObject(value) && Object.hasOwn(value, 'alignment');\n}\n","import type { EntityKind, MedeoEntity } from './entities.ts';\nimport type { EntityId, RelationId } from './ids.ts';\nimport type { JsonObject } from './json-values.ts';\n\nexport type KnownRelationKind =\n | 'timeline-track'\n | 'track-clip'\n | 'clip-marker'\n | 'marker-content'\n | 'axvideo-marker'\n | 'marker-timeline'\n | 'physical-asset'\n | 'generated'\n | 'phonetic-script-provenance'\n | 'caption-provenance'\n | 'caption-alignment'\n | 'clip-anchor'\n | 'audio-script-render';\n\nexport type RelationKind = KnownRelationKind | (string & {});\nexport type RelationTrace = JsonObject;\nexport type EmptyMetadata = Readonly<Record<string, never>>;\n\n/** Two persisted endpoint positions. Their meaning belongs to the Relation kind. */\nexport type RelationEndpoints<A, B> = readonly [A, B] | readonly [B, A];\n\n/**\n * Authoritative persisted relation value.\n *\n * A kind may assign semantic roles to endpoint 0 and endpoint 1. Callers and\n * storage adapters must preserve the submitted positions; kinds whose\n * semantics are unordered simply do not interpret those positions.\n */\nexport interface RelationRow<K extends RelationKind = RelationKind, Metadata extends JsonObject = JsonObject> {\n readonly relationId: RelationId;\n readonly endpoint0EntityId: EntityId;\n readonly endpoint1EntityId: EntityId;\n readonly relationKind: K;\n readonly metadata: Metadata;\n readonly trace: RelationTrace;\n}\n\nexport interface EntityRef<T extends MedeoEntity<EntityKind> = MedeoEntity<EntityKind>> {\n readonly entityId: EntityId;\n current(): T;\n}\n\nexport interface Relation<\n K extends RelationKind = RelationKind,\n A extends MedeoEntity<EntityKind> = MedeoEntity<EntityKind>,\n B extends MedeoEntity<EntityKind> = MedeoEntity<EntityKind>,\n Metadata extends JsonObject = JsonObject,\n> {\n readonly relationId: RelationId;\n readonly kind: K;\n readonly endpoints: RelationEndpoints<WeakRef<EntityRef<A>>, WeakRef<EntityRef<B>>>;\n readonly metadata: Metadata;\n readonly trace: RelationTrace;\n other(entity: EntityRef<A | B>): WeakRef<EntityRef<A | B>> | undefined;\n toRow(): RelationRow<K, Metadata> | undefined;\n}\n\nexport type RelationAny = Relation<RelationKind, MedeoEntity<EntityKind>, MedeoEntity<EntityKind>, JsonObject>;\n\n/** Type-erased validation contract used when decoding persisted relation rows. */\nexport interface RuntimeRelationKindSpec {\n readonly kind: RelationKind;\n validateEndpoints(endpoints: RelationEndpoints<EntityRef, EntityRef>): boolean;\n validateMetadata(value: unknown): value is JsonObject;\n}\n\nexport interface RelationKindSpec<\n K extends RelationKind,\n A extends MedeoEntity<EntityKind>,\n B extends MedeoEntity<EntityKind>,\n Metadata extends JsonObject,\n> extends RuntimeRelationKindSpec {\n readonly kind: K;\n validateEndpoints(\n endpoints: RelationEndpoints<EntityRef, EntityRef>,\n ): endpoints is RelationEndpoints<EntityRef<A>, EntityRef<B>>;\n validateMetadata(value: unknown): value is Metadata;\n}\n\nexport function createEntityRef<T extends MedeoEntity<EntityKind>>(entity: T): EntityRef<T> {\n return { entityId: entity.entityId, current: () => entity };\n}\n","import {\n hasSequence,\n type Audio,\n type AudioScript,\n type Clip,\n type EntityKind,\n type MedeoEntity,\n type Voice,\n} from './entities.ts';\nimport type { RelationId } from './ids.ts';\nimport type { JsonObject } from './json-values.ts';\nimport {\n audioScriptRenderRelationSpec,\n builtInRelationSpecs,\n clipAnchorRelationSpec,\n generatedRelationSpec,\n type GeneratedMedia,\n type GeneratedMetadata,\n} from './relation-specs.ts';\nimport {\n type EntityRef,\n type EmptyMetadata,\n type Relation,\n type RelationAny,\n type RelationEndpoints,\n type RelationKind,\n type RelationKindSpec,\n type RelationRow,\n type RelationTrace,\n type RuntimeRelationKindSpec,\n} from './relations.ts';\n\nclass RelationEdge<\n K extends RelationKind,\n A extends MedeoEntity<EntityKind>,\n B extends MedeoEntity<EntityKind>,\n Metadata extends JsonObject,\n> implements Relation<K, A, B, Metadata> {\n readonly endpoints: RelationEndpoints<WeakRef<EntityRef<A>>, WeakRef<EntityRef<B>>>;\n\n constructor(\n readonly relationId: RelationId,\n readonly kind: K,\n endpoints: RelationEndpoints<EntityRef<A>, EntityRef<B>>,\n readonly metadata: Metadata,\n readonly trace: RelationTrace,\n ) {\n this.endpoints = [\n new WeakRef(endpoints[0] as EntityRef<A | B>),\n new WeakRef(endpoints[1] as EntityRef<A | B>),\n ] as unknown as RelationEndpoints<WeakRef<EntityRef<A>>, WeakRef<EntityRef<B>>>;\n }\n\n other(entity: EntityRef<A | B>): WeakRef<EntityRef<A | B>> | undefined {\n const first = this.endpoints[0].deref();\n const second = this.endpoints[1].deref();\n if (first === entity) return this.endpoints[1] as WeakRef<EntityRef<A | B>>;\n if (second === entity) return this.endpoints[0] as WeakRef<EntityRef<A | B>>;\n return undefined;\n }\n\n toRow(): RelationRow<K, Metadata> | undefined {\n const first = this.endpoints[0].deref();\n const second = this.endpoints[1].deref();\n if (first == null || second == null) return undefined;\n return {\n relationId: this.relationId,\n endpoint0EntityId: first.entityId,\n endpoint1EntityId: second.entityId,\n relationKind: this.kind,\n metadata: this.metadata,\n trace: this.trace,\n };\n }\n\n isStale(): boolean {\n return this.endpoints[0].deref() == null || this.endpoints[1].deref() == null;\n }\n}\n\nexport interface LinkRelationInput<\n K extends RelationKind,\n A extends MedeoEntity<EntityKind>,\n B extends MedeoEntity<EntityKind>,\n Metadata extends JsonObject,\n> {\n readonly relationId: RelationId;\n readonly spec: RelationKindSpec<K, A, B, Metadata>;\n readonly endpoints: RelationEndpoints<EntityRef<A>, EntityRef<B>>;\n readonly metadata: Metadata;\n readonly trace?: RelationTrace;\n}\n\nexport interface LinkRuntimeRelationInput {\n readonly relationId: RelationId;\n readonly spec: RuntimeRelationKindSpec;\n readonly endpoints: RelationEndpoints<EntityRef, EntityRef>;\n readonly metadata: unknown;\n readonly trace?: RelationTrace;\n}\n\nexport interface LinkGeneratedRelationInput {\n readonly relationId: RelationId;\n readonly output: EntityRef<GeneratedMedia>;\n readonly input: EntityRef<GeneratedMedia>;\n readonly trace?: RelationTrace;\n}\n\nexport interface LinkClipAnchorRelationInput {\n readonly relationId: RelationId;\n readonly child: EntityRef<Clip>;\n readonly host: EntityRef<Clip>;\n readonly trace?: RelationTrace;\n}\n\nexport interface LinkAudioScriptRenderRelationInput {\n readonly relationId: RelationId;\n readonly output: EntityRef<Audio | Voice>;\n readonly script: EntityRef<AudioScript>;\n readonly trace?: RelationTrace;\n}\n\n/** Endpoint-agnostic secondary index. Relation rows remain the persistence authority. */\nexport class BiRelationIndex {\n private readonly byEntity = new WeakMap<EntityRef, Set<RelationAny>>();\n private readonly canonicalRefs = new Map<string, WeakRef<EntityRef>>();\n private readonly byRelationId = new Map<RelationId, WeakRef<RelationAny>>();\n\n link<\n K extends RelationKind,\n A extends MedeoEntity<EntityKind>,\n B extends MedeoEntity<EntityKind>,\n Metadata extends JsonObject,\n >(input: LinkRelationInput<K, A, B, Metadata>): Relation<K, A, B, Metadata> {\n if (input.spec.kind === 'generated')\n throw new Error('Author generated Relations with linkGenerated({ output, input })');\n if (input.spec.kind === 'clip-anchor' || input.spec.kind === 'audio-script-render')\n throw new Error(`Author ordered ${input.spec.kind} Relations with the dedicated role-named method`);\n return this.linkValidated(input) as Relation<K, A, B, Metadata>;\n }\n\n /** Author `generated(output, input)` without exposing positional arguments. */\n linkGenerated(\n input: LinkGeneratedRelationInput,\n ): Relation<'generated', GeneratedMedia, GeneratedMedia, GeneratedMetadata> {\n return this.linkValidated({\n relationId: input.relationId,\n spec: generatedRelationSpec,\n endpoints: [input.output, input.input],\n metadata: {},\n trace: input.trace,\n }) as Relation<'generated', GeneratedMedia, GeneratedMedia, GeneratedMetadata>;\n }\n\n /** Author `clip-anchor(child, host)` without exposing positional arguments. */\n linkClipAnchor(input: LinkClipAnchorRelationInput): Relation<'clip-anchor', Clip, Clip, EmptyMetadata> {\n return this.linkValidated({\n relationId: input.relationId,\n spec: clipAnchorRelationSpec,\n endpoints: [input.child, input.host],\n metadata: {},\n trace: input.trace,\n }) as Relation<'clip-anchor', Clip, Clip, EmptyMetadata>;\n }\n\n /** Author `audio-script-render(output, script)` without exposing positional arguments. */\n linkAudioScriptRender(\n input: LinkAudioScriptRenderRelationInput,\n ): Relation<'audio-script-render', Audio | Voice, AudioScript, EmptyMetadata> {\n return this.linkValidated({\n relationId: input.relationId,\n spec: audioScriptRenderRelationSpec,\n endpoints: [input.output, input.script],\n metadata: {},\n trace: input.trace,\n }) as Relation<'audio-script-render', Audio | Voice, AudioScript, EmptyMetadata>;\n }\n\n /**\n * Rehydrate a persisted row after resolving its spec and endpoint refs.\n *\n * This is a storage-boundary escape hatch, not an authoring API: persisted\n * positions already are the semantic assertion made by their relation kind.\n */\n linkRuntime(input: LinkRuntimeRelationInput): RelationAny {\n return this.linkValidated(input);\n }\n\n private linkValidated(input: LinkRuntimeRelationInput): RelationAny {\n const [first, second] = input.endpoints;\n if (first.entityId === second.entityId) throw new Error('A Relation cannot connect an entity to itself');\n this.assertRelationIdAvailable(input.relationId);\n const builtInSpec = builtInSpecByKind.get(input.spec.kind);\n if (builtInSpec != null && builtInSpec !== input.spec) {\n throw new Error(`Relation kind \"${input.spec.kind}\" must use its built-in specification`);\n }\n if (isForbiddenAuthoritativeRelation(input.spec.kind, input.endpoints)) {\n throw new Error('A direct Clip-Content Relation is derived-only and cannot be authoritative');\n }\n if (!input.spec.validateEndpoints(input.endpoints)) {\n throw new Error(`Relation \"${input.spec.kind}\" received invalid endpoints`);\n }\n if (!input.spec.validateMetadata(input.metadata)) {\n throw new Error(`Relation \"${input.spec.kind}\" received invalid metadata`);\n }\n this.assertCanonicalRefAvailable(first);\n this.assertCanonicalRefAvailable(second);\n\n const relation = new RelationEdge<RelationKind, MedeoEntity<EntityKind>, MedeoEntity<EntityKind>, JsonObject>(\n input.relationId,\n input.spec.kind,\n input.endpoints,\n input.metadata,\n input.trace ?? {},\n );\n this.rememberCanonicalRef(first);\n this.rememberCanonicalRef(second);\n this.add(first, relation);\n this.add(second, relation);\n this.byRelationId.set(input.relationId, new WeakRef(relation));\n return relation;\n }\n\n relationsOf(entity: EntityRef): ReadonlySet<RelationAny> {\n this.registerCanonicalRef(entity);\n const relations = this.byEntity.get(entity);\n if (relations == null) return new Set();\n for (const relation of relations) {\n if (relation instanceof RelationEdge && relation.isStale()) this.unlink(relation);\n }\n return new Set(relations);\n }\n\n unlink(relation: RelationAny): void {\n for (const endpoint of relation.endpoints) {\n const ref = endpoint.deref();\n if (ref != null) this.byEntity.get(ref)?.delete(relation);\n }\n if (this.byRelationId.get(relation.relationId)?.deref() === relation) {\n this.byRelationId.delete(relation.relationId);\n }\n }\n\n private add(entity: EntityRef, relation: RelationAny): void {\n const relations = this.byEntity.get(entity) ?? new Set<RelationAny>();\n relations.add(relation);\n this.byEntity.set(entity, relations);\n }\n\n private registerCanonicalRef(entity: EntityRef): void {\n this.assertCanonicalRefAvailable(entity);\n this.rememberCanonicalRef(entity);\n }\n\n private assertCanonicalRefAvailable(entity: EntityRef): void {\n const existing = this.canonicalRefs.get(entity.entityId)?.deref();\n if (existing != null && existing !== entity) {\n throw new Error(`Entity \"${entity.entityId}\" already has a live canonical EntityRef`);\n }\n }\n\n private rememberCanonicalRef(entity: EntityRef): void {\n this.canonicalRefs.set(entity.entityId, new WeakRef(entity));\n }\n\n private assertRelationIdAvailable(relationId: RelationId): void {\n const existing = this.byRelationId.get(relationId)?.deref();\n if (existing != null) throw new Error(`Relation id \"${relationId}\" already exists`);\n this.byRelationId.delete(relationId);\n }\n}\n\nconst builtInSpecByKind: ReadonlyMap<string, object> = new Map(builtInRelationSpecs.map((spec) => [spec.kind, spec]));\n\nfunction isForbiddenAuthoritativeRelation(\n kind: RelationKind,\n endpoints: RelationEndpoints<EntityRef, EntityRef>,\n): boolean {\n if (kind === 'clip-content') return true;\n const first = endpoints[0].current();\n const second = endpoints[1].current();\n return (first.entityKind === 'clip' && hasSequence(second)) || (second.entityKind === 'clip' && hasSequence(first));\n}\n","import {\n isKnownEntityKind,\n isReservedEntityKind,\n type EntityKind,\n type ExtensionEntityKind,\n type MedeoEntity,\n} from './entities.ts';\nimport { createEntityId, createRelationId, type EntityId, type RelationId } from './ids.ts';\nimport { validateEntityRelationSet, type EntityRelationValidationOptions } from './invariants.ts';\nimport { isJsonObject } from './json-values.ts';\nimport { BiRelationIndex } from './relation-index.ts';\nimport { builtInRelationSpecs } from './relation-specs.ts';\nimport { createEntityRef, type EntityRef, type RelationAny, type RuntimeRelationKindSpec } from './relations.ts';\nimport type { EntityRelationRows, EntityRow } from './rows.ts';\n\nexport interface DecodeEntityRelationRowsOptions extends EntityRelationValidationOptions {\n /** Extension entity kinds must be explicitly registered; the 14 built-ins are always available. */\n readonly entityKinds?: readonly ExtensionEntityKind[];\n /** Specs for extension relation kinds. Built-in names cannot be replaced. */\n readonly relationSpecs?: readonly RuntimeRelationKindSpec[];\n}\n\nexport interface DecodedEntityRelationSet {\n readonly entitiesById: ReadonlyMap<EntityId, EntityRef>;\n readonly relationIndex: BiRelationIndex;\n readonly relations: readonly RelationAny[];\n}\n\nexport class InvalidEntityRelationRowsError extends Error {\n constructor(readonly issues: readonly string[]) {\n super(`Invalid Medeo entity/relation rows:\\n- ${issues.join('\\n- ')}`);\n this.name = 'InvalidEntityRelationRowsError';\n }\n}\n\n/** Decodes database rows into flat entities and validates the complete relation set. */\nexport function decodeEntityRelationRows(\n rows: EntityRelationRows,\n options: DecodeEntityRelationRowsOptions,\n): DecodedEntityRelationSet {\n const issues: string[] = [];\n const entitiesById = new Map<EntityId, EntityRef>();\n const extensionEntityKinds = new Set<string>(options.entityKinds ?? []);\n\n for (const row of rows.entities) {\n const entity = decodeEntityRow(row, extensionEntityKinds, issues);\n if (entity == null) continue;\n const ref = createEntityRef(entity);\n if (entitiesById.has(ref.entityId)) {\n issues.push(`duplicate entity id \"${ref.entityId}\"`);\n continue;\n }\n entitiesById.set(ref.entityId, ref);\n }\n\n const specsByKind = collectRelationSpecs(options.relationSpecs ?? [], issues);\n const relationIndex = new BiRelationIndex();\n const relations: RelationAny[] = [];\n const relationIds = new Set<string>();\n\n for (const row of rows.relations) {\n let relationId: RelationId;\n try {\n relationId = createRelationId(row.relationId);\n } catch (error) {\n issues.push(errorMessage(error));\n continue;\n }\n if (relationIds.has(relationId)) {\n issues.push(`duplicate relation id \"${relationId}\"`);\n continue;\n }\n relationIds.add(relationId);\n\n if (!isTrimmedNonEmpty(row.relationKind)) {\n issues.push(`relation \"${relationId}\" has an empty or untrimmed kind`);\n continue;\n }\n const spec = specsByKind.get(row.relationKind);\n if (spec == null) {\n issues.push(`relation \"${relationId}\" has no registered spec for kind \"${row.relationKind}\"`);\n continue;\n }\n\n let endpoint0EntityId: EntityId;\n let endpoint1EntityId: EntityId;\n try {\n endpoint0EntityId = createEntityId(row.endpoint0EntityId);\n endpoint1EntityId = createEntityId(row.endpoint1EntityId);\n } catch (error) {\n issues.push(errorMessage(error));\n continue;\n }\n const endpoint0 = entitiesById.get(endpoint0EntityId);\n const endpoint1 = entitiesById.get(endpoint1EntityId);\n if (endpoint0 == null || endpoint1 == null) {\n const missing = [\n endpoint0 == null ? endpoint0EntityId : undefined,\n endpoint1 == null ? endpoint1EntityId : undefined,\n ]\n .filter((value) => value != null)\n .join(', ');\n issues.push(`relation \"${relationId}\" references missing entity id(s): ${missing}`);\n continue;\n }\n if (!isJsonObject(row.metadata) || !isJsonObject(row.trace)) {\n issues.push(`relation \"${relationId}\" metadata and trace must contain only JSON values`);\n continue;\n }\n\n try {\n relations.push(\n relationIndex.linkRuntime({\n relationId,\n spec,\n endpoints: [endpoint0, endpoint1],\n metadata: row.metadata,\n trace: row.trace,\n }),\n );\n } catch (error) {\n issues.push(errorMessage(error));\n }\n }\n\n if (issues.length === 0) {\n for (const issue of validateEntityRelationSet([...entitiesById.values()], relationIndex, options)) {\n issues.push(`${issue.code}: ${issue.message}`);\n }\n }\n if (issues.length > 0) throw new InvalidEntityRelationRowsError(issues);\n\n return { entitiesById, relationIndex, relations };\n}\n\nfunction decodeEntityRow(\n row: EntityRow,\n extensionEntityKinds: ReadonlySet<string>,\n issues: string[],\n): MedeoEntity | undefined {\n let entityId: EntityId;\n try {\n entityId = createEntityId(row.entityId);\n } catch (error) {\n issues.push(errorMessage(error));\n return undefined;\n }\n if (!isTrimmedNonEmpty(row.entityKind)) {\n issues.push(`entity \"${entityId}\" has an empty or untrimmed kind`);\n return undefined;\n }\n if (isReservedEntityKind(row.entityKind)) {\n issues.push(`entity \"${entityId}\" uses reserved kind \"${row.entityKind}\"`);\n return undefined;\n }\n if (!isKnownEntityKind(row.entityKind) && !extensionEntityKinds.has(row.entityKind)) {\n issues.push(`entity \"${entityId}\" has unregistered extension kind \"${row.entityKind}\"`);\n return undefined;\n }\n if (!isJsonObject(row.payload)) {\n issues.push(`entity \"${entityId}\" payload must contain only JSON values`);\n return undefined;\n }\n const reserved = ['entityId', 'entityKind'].filter((key) => Object.hasOwn(row.payload, key));\n if (reserved.length > 0) {\n issues.push(`entity \"${entityId}\" payload contains reserved field(s): ${reserved.join(', ')}`);\n return undefined;\n }\n return { ...row.payload, entityId, entityKind: row.entityKind as EntityKind } as MedeoEntity;\n}\n\nfunction collectRelationSpecs(\n extensionSpecs: readonly RuntimeRelationKindSpec[],\n issues: string[],\n): ReadonlyMap<string, RuntimeRelationKindSpec> {\n const specs = new Map<string, RuntimeRelationKindSpec>();\n for (const spec of builtInRelationSpecs) specs.set(spec.kind, spec);\n for (const spec of extensionSpecs) {\n if (!isTrimmedNonEmpty(spec.kind)) {\n issues.push('extension relation spec has an empty or untrimmed kind');\n continue;\n }\n if (specs.has(spec.kind)) {\n issues.push(`relation spec kind \"${spec.kind}\" is already registered`);\n continue;\n }\n specs.set(spec.kind, spec);\n }\n return specs;\n}\n\nfunction isTrimmedNonEmpty(value: string): boolean {\n return value.length > 0 && value.trim() === value;\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n","import type { EntityKind, MedeoEntity } from './entities.ts';\nimport type { EntityId } from './ids.ts';\nimport { isJsonObject, type JsonObject } from './json-values.ts';\nimport type { RelationRow } from './relations.ts';\n\n/** One persisted first-class entity. Its owned fields live directly in payload. */\nexport interface EntityRow<K extends EntityKind = EntityKind> {\n readonly entityId: EntityId;\n readonly entityKind: K;\n readonly payload: JsonObject;\n}\n\n/** Complete persistence value for an entity set and its authoritative relations. */\nexport interface EntityRelationRows {\n readonly entities: readonly EntityRow[];\n readonly relations: readonly RelationRow[];\n}\n\nexport function entityToRow<K extends EntityKind>(entity: MedeoEntity<K>): EntityRow<K> {\n const { entityId, entityKind, ...payload } = entity;\n if (!isJsonObject(payload)) {\n throw new Error(`Entity \"${entityId}\" payload must contain only JSON values`);\n }\n return { entityId, entityKind, payload };\n}\n","import {\n BiRelationIndex,\n builtInRelationSpecs,\n createEntityId,\n createEntityRef,\n createRelationId,\n decodeEntityRelationRows,\n entityToRow,\n isJsonObject,\n isKnownEntityKind,\n type Audio,\n type AudioScript,\n type Clip,\n type EntityRef,\n type EntityRelationRows,\n type GeneratedMedia,\n type JsonObject as DslJsonObject,\n type MedeoEntity,\n type RelationKindSpec,\n type Voice,\n} from '@mengine/medeo-dsl';\n\nimport type {\n AuthorableRelationKind,\n CreateEntityInput,\n DeleteEntityInput,\n EntityCommand,\n EntityFacade,\n EntityPlanState,\n EntityStoreSnapshot,\n ImportAssetInput,\n LinkAudioScriptRenderRelationInput,\n LinkClipAnchorRelationInput,\n JsonObject,\n LinkGeneratedRelationInput,\n LinkRelationInput,\n RelationFacade,\n SandboxEntity,\n SandboxRelation,\n UnlinkRelationInput,\n UpdateEntityInput,\n} from './entity-contract.ts';\n\nexport type DomainIdFactory = (prefix: 'entity' | 'relation') => string;\n\nexport interface EntitySandboxOptions {\n state?: EntityStoreSnapshot;\n idFactory: DomainIdFactory;\n onCommand?: (command: EntityCommand) => void;\n onTruncate?: (index: number) => void;\n}\n\nconst ASSET_SOURCE_KEY = 'external';\nconst MEMOTA_SYSTEM = 'memota';\n\n/** Mutable entity/relation draft whose only durable product is an explicit command plan. */\nexport class EntitySandbox {\n private readonly original: EntityStoreSnapshot;\n private readonly idFactory: DomainIdFactory;\n private readonly onCommand: ((command: EntityCommand) => void) | undefined;\n private readonly onTruncate: ((index: number) => void) | undefined;\n private state: EntityStoreSnapshot;\n private readonly commands: EntityCommand[] = [];\n\n readonly entities: EntityFacade;\n readonly relations: RelationFacade;\n\n constructor(options: EntitySandboxOptions) {\n this.original = cloneSnapshot(options.state ?? { revision: 0, entities: [], relations: [] });\n this.state = cloneSnapshot(this.original);\n this.idFactory = options.idFactory;\n this.onCommand = options.onCommand;\n this.onTruncate = options.onTruncate;\n this.entities = this.buildEntityFacade();\n this.relations = this.buildRelationFacade();\n }\n\n get commandCount(): number {\n return this.commands.length;\n }\n\n getCommands(): readonly EntityCommand[] {\n return this.commands;\n }\n\n rollbackTo(index: number): void {\n if (!Number.isInteger(index) || index < 0 || index > this.commands.length) {\n throw new Error(`rollbackTo: entity checkpoint index ${index} is past journal length ${this.commands.length}`);\n }\n const prefix = this.commands.slice(0, index);\n this.state = cloneSnapshot(this.original);\n for (const command of prefix) this.apply(command, false);\n this.commands.length = 0;\n this.commands.push(...prefix);\n this.onTruncate?.(index);\n }\n\n buildPlan(): EntityPlanState {\n const rows = toDslRows(this.state);\n decodeEntityRelationRows(rows, numericMarkerComparators);\n const currentEntityIds = new Set(this.state.entities.map((entity) => entity.entity_id));\n const currentRelationIds = new Set(this.state.relations.map((relation) => relation.relation_id));\n return {\n base_revision: this.original.revision,\n commands: this.commands.slice(),\n rows: cloneSnapshot(this.state),\n deleted_entity_ids: this.original.entities\n .map((entity) => entity.entity_id)\n .filter((entityId) => !currentEntityIds.has(entityId))\n .sort(),\n deleted_relation_ids: this.original.relations\n .map((relation) => relation.relation_id)\n .filter((relationId) => !currentRelationIds.has(relationId))\n .sort(),\n };\n }\n\n renderPreview(): string {\n const lines = [\n `Entity plan: base_revision=${this.original.revision} commands=${this.commands.length} entities=${this.state.entities.length} relations=${this.state.relations.length}`,\n ];\n for (const command of this.commands) {\n switch (command.kind) {\n case 'create-entity':\n lines.push(`+ entity ${command.entity.entity_id} kind=${command.entity.entity_kind}`);\n break;\n case 'update-entity':\n lines.push(`~ entity ${command.entity_id} payload`);\n break;\n case 'delete-entity':\n lines.push(`- entity ${command.entity_id}`);\n break;\n case 'unlink-relation':\n lines.push(`- relation ${command.relation_id}`);\n break;\n case 'link-relation':\n if (command.relation.relation_kind === 'generated') {\n lines.push(\n `+ relation ${command.relation.relation_id} generated(output=${command.relation.endpoint_0_entity_id}, input=${command.relation.endpoint_1_entity_id})`,\n );\n } else {\n lines.push(\n `+ relation ${command.relation.relation_id} kind=${command.relation.relation_kind} endpoints=${command.relation.endpoint_0_entity_id},${command.relation.endpoint_1_entity_id}`,\n );\n }\n break;\n }\n }\n return lines.join('\\n');\n }\n\n private buildEntityFacade(): EntityFacade {\n return {\n list: () => clone(this.state.entities),\n get: (entityId) => {\n const entity = this.state.entities.find((candidate) => candidate.entity_id === entityId);\n return entity == null ? null : clone(entity);\n },\n findByAssetId: (assetId) => {\n assertTrimmed(assetId, 'assetId');\n return clone(\n this.state.entities.filter(\n (entity): entity is SandboxEntity<'asset'> =>\n entity.entity_kind === 'asset' && isImportedMemotaAsset(entity.payload, assetId),\n ),\n );\n },\n create: (input) => this.createEntity(input),\n update: (input) => this.updateEntity(input),\n delete: (input) => this.deleteEntity(input),\n importAsset: (input) => this.importAsset(input),\n };\n }\n\n private buildRelationFacade(): RelationFacade {\n return {\n list: () => clone(this.state.relations),\n of: (entityId, relationKind) => {\n assertTrimmed(entityId, 'entityId');\n if (relationKind !== undefined && !builtInRelationSpecs.some((spec) => spec.kind === relationKind)) {\n throw new Error(`Unknown Relation kind \"${relationKind}\"`);\n }\n return clone(\n this.state.relations.filter(\n (relation) =>\n (relation.endpoint_0_entity_id === entityId || relation.endpoint_1_entity_id === entityId) &&\n (relationKind === undefined || relation.relation_kind === relationKind),\n ),\n );\n },\n link: (input) => this.link(input),\n linkGenerated: (input) => this.linkGenerated(input),\n linkClipAnchor: (input) => this.linkClipAnchor(input),\n linkAudioScriptRender: (input) => this.linkAudioScriptRender(input),\n unlink: (input) => this.unlinkRelation(input),\n };\n }\n\n private createEntity(input: CreateEntityInput): string {\n if (!isKnownEntityKind(input.entity_kind)) {\n throw new Error(`Unknown or extension Entity kind \"${String(input.entity_kind)}\"`);\n }\n const payload = clone(input.payload);\n if (!isJsonObject(payload)) throw new Error('Entity payload must contain only JSON values');\n const entityId = input.entity_id ?? this.idFactory('entity');\n assertTrimmed(entityId, 'entity_id');\n const entity: SandboxEntity = {\n entity_id: entityId,\n entity_kind: input.entity_kind,\n payload,\n };\n const decoded = {\n ...entity.payload,\n entityId: createEntityId(entityId),\n entityKind: entity.entity_kind,\n } as MedeoEntity;\n entityToRow(decoded);\n this.record({ kind: 'create-entity', entity });\n return entityId;\n }\n\n private updateEntity(input: UpdateEntityInput): void {\n assertTrimmed(input.entity_id, 'entity_id');\n const payload = clone(input.payload);\n if (!isJsonObject(payload)) throw new Error('Entity payload must contain only JSON values');\n this.record({ kind: 'update-entity', entity_id: input.entity_id, payload });\n }\n\n private deleteEntity(input: DeleteEntityInput): void {\n assertTrimmed(input.entity_id, 'entity_id');\n this.record({ kind: 'delete-entity', entity_id: input.entity_id });\n }\n\n private importAsset(input: ImportAssetInput): string {\n assertTrimmed(input.asset_id, 'asset_id');\n const payload = input.payload === undefined ? {} : clone(input.payload);\n if (!isJsonObject(payload)) {\n throw new Error('Asset payload must contain only JSON values');\n }\n return this.createEntity({\n ...(input.entity_id !== undefined ? { entity_id: input.entity_id } : {}),\n entity_kind: 'asset',\n payload: {\n ...payload,\n [ASSET_SOURCE_KEY]: { system: MEMOTA_SYSTEM, key: input.asset_id },\n },\n });\n }\n\n private link(input: LinkRelationInput): string {\n if ((input.relation_kind as string) === 'generated') {\n throw new Error('Author generated Relations with relations.linkGenerated({ output_entity_id, input_entity_id })');\n }\n const spec = builtInRelationSpecs.find((candidate) => candidate.kind === input.relation_kind);\n if (spec == null) throw new Error(`Unknown Relation kind \"${String(input.relation_kind)}\"`);\n const relation = this.relationFromInput(input, input.relation_kind);\n const [first, second] = this.refsFor(relation);\n new BiRelationIndex().link({\n relationId: createRelationId(relation.relation_id),\n spec: spec as unknown as RelationKindSpec<AuthorableRelationKind, MedeoEntity, MedeoEntity, DslJsonObject>,\n endpoints: [first, second],\n metadata: relation.metadata,\n trace: relation.trace,\n });\n this.record({ kind: 'link-relation', relation });\n return relation.relation_id;\n }\n\n private linkGenerated(input: LinkGeneratedRelationInput): string {\n const relation = this.relationFromInput(\n {\n ...(input.relation_id !== undefined ? { relation_id: input.relation_id } : {}),\n endpoint_0_entity_id: input.output_entity_id,\n endpoint_1_entity_id: input.input_entity_id,\n metadata: {},\n ...(input.trace !== undefined ? { trace: input.trace } : {}),\n },\n 'generated',\n );\n const [output, source] = this.refsFor(relation);\n new BiRelationIndex().linkGenerated({\n relationId: createRelationId(relation.relation_id),\n output: output as EntityRef<GeneratedMedia>,\n input: source as EntityRef<GeneratedMedia>,\n trace: relation.trace,\n });\n this.record({ kind: 'link-relation', relation });\n return relation.relation_id;\n }\n\n private linkClipAnchor(input: LinkClipAnchorRelationInput): string {\n const relation = this.relationFromInput(\n {\n ...(input.relation_id !== undefined ? { relation_id: input.relation_id } : {}),\n endpoint_0_entity_id: input.child_clip_entity_id,\n endpoint_1_entity_id: input.host_clip_entity_id,\n metadata: {},\n ...(input.trace !== undefined ? { trace: input.trace } : {}),\n },\n 'clip-anchor',\n );\n const [child, host] = this.refsFor(relation);\n new BiRelationIndex().linkClipAnchor({\n relationId: createRelationId(relation.relation_id),\n child: child as EntityRef<Clip>,\n host: host as EntityRef<Clip>,\n trace: relation.trace,\n });\n this.record({ kind: 'link-relation', relation });\n return relation.relation_id;\n }\n\n private linkAudioScriptRender(input: LinkAudioScriptRenderRelationInput): string {\n const relation = this.relationFromInput(\n {\n ...(input.relation_id !== undefined ? { relation_id: input.relation_id } : {}),\n endpoint_0_entity_id: input.output_entity_id,\n endpoint_1_entity_id: input.script_entity_id,\n metadata: {},\n ...(input.trace !== undefined ? { trace: input.trace } : {}),\n },\n 'audio-script-render',\n );\n const [output, script] = this.refsFor(relation);\n new BiRelationIndex().linkAudioScriptRender({\n relationId: createRelationId(relation.relation_id),\n output: output as EntityRef<Audio | Voice>,\n script: script as EntityRef<AudioScript>,\n trace: relation.trace,\n });\n this.record({ kind: 'link-relation', relation });\n return relation.relation_id;\n }\n\n private unlinkRelation(input: UnlinkRelationInput): void {\n assertTrimmed(input.relation_id, 'relation_id');\n this.record({ kind: 'unlink-relation', relation_id: input.relation_id });\n }\n\n private relationFromInput(\n input: {\n relation_id?: string;\n endpoint_0_entity_id: string;\n endpoint_1_entity_id: string;\n metadata?: JsonObject;\n trace?: JsonObject;\n },\n relationKind: SandboxRelation['relation_kind'],\n ): SandboxRelation {\n const relationId = input.relation_id ?? this.idFactory('relation');\n assertTrimmed(relationId, 'relation_id');\n assertTrimmed(input.endpoint_0_entity_id, 'endpoint_0_entity_id');\n assertTrimmed(input.endpoint_1_entity_id, 'endpoint_1_entity_id');\n const metadata = clone(input.metadata ?? {});\n const trace = clone(input.trace ?? {});\n if (!isJsonObject(metadata) || !isJsonObject(trace)) {\n throw new Error('Relation metadata and trace must contain only JSON values');\n }\n return {\n relation_id: relationId,\n relation_kind: relationKind,\n endpoint_0_entity_id: input.endpoint_0_entity_id,\n endpoint_1_entity_id: input.endpoint_1_entity_id,\n metadata,\n trace,\n };\n }\n\n private refsFor(relation: SandboxRelation): readonly [EntityRef, EntityRef] {\n const first = this.state.entities.find((entity) => entity.entity_id === relation.endpoint_0_entity_id);\n const second = this.state.entities.find((entity) => entity.entity_id === relation.endpoint_1_entity_id);\n if (first == null || second == null) {\n const missing = [\n first == null ? relation.endpoint_0_entity_id : null,\n second == null ? relation.endpoint_1_entity_id : null,\n ]\n .filter((value) => value != null)\n .join(', ');\n throw new Error(`Relation references missing Entity id(s): ${missing}`);\n }\n return [createEntityRef(toDslEntity(first)), createEntityRef(toDslEntity(second))];\n }\n\n private record(command: EntityCommand): void {\n this.apply(command, true);\n this.commands.push(clone(command));\n this.onCommand?.(clone(command));\n }\n\n private apply(command: EntityCommand, enforceIdentity: boolean): void {\n switch (command.kind) {\n case 'create-entity': {\n if (enforceIdentity && this.state.entities.some((entity) => entity.entity_id === command.entity.entity_id)) {\n throw new Error(`Entity id \"${command.entity.entity_id}\" already exists`);\n }\n const original = this.original.entities.find((entity) => entity.entity_id === command.entity.entity_id);\n if (enforceIdentity && original != null && original.entity_kind !== command.entity.entity_kind) {\n throw new Error(\n `Entity id \"${command.entity.entity_id}\" was originally kind \"${original.entity_kind}\" and cannot be recreated as \"${command.entity.entity_kind}\"`,\n );\n }\n this.state.entities.push(clone(command.entity));\n return;\n }\n case 'update-entity': {\n const index = this.state.entities.findIndex((entity) => entity.entity_id === command.entity_id);\n if (index < 0) throw new Error(`Entity id \"${command.entity_id}\" does not exist`);\n const current = this.state.entities[index];\n if (current == null) throw new Error(`Entity id \"${command.entity_id}\" does not exist`);\n this.state.entities[index] = { ...current, payload: clone(command.payload) };\n return;\n }\n case 'delete-entity': {\n const index = this.state.entities.findIndex((entity) => entity.entity_id === command.entity_id);\n if (index < 0) throw new Error(`Entity id \"${command.entity_id}\" does not exist`);\n const incidentRelationIds = this.state.relations\n .filter(\n (relation) =>\n relation.endpoint_0_entity_id === command.entity_id ||\n relation.endpoint_1_entity_id === command.entity_id,\n )\n .map((relation) => relation.relation_id)\n .sort();\n if (incidentRelationIds.length > 0) {\n throw new Error(\n `Entity id \"${command.entity_id}\" still has incident Relation id(s): ${incidentRelationIds.join(', ')}`,\n );\n }\n this.state.entities.splice(index, 1);\n return;\n }\n case 'link-relation':\n if (\n enforceIdentity &&\n this.state.relations.some((relation) => relation.relation_id === command.relation.relation_id)\n ) {\n throw new Error(`Relation id \"${command.relation.relation_id}\" already exists`);\n }\n if (enforceIdentity) {\n const original = this.original.relations.find(\n (relation) => relation.relation_id === command.relation.relation_id,\n );\n if (\n original != null &&\n (original.relation_kind !== command.relation.relation_kind ||\n original.endpoint_0_entity_id !== command.relation.endpoint_0_entity_id ||\n original.endpoint_1_entity_id !== command.relation.endpoint_1_entity_id)\n ) {\n throw new Error(\n `Relation id \"${command.relation.relation_id}\" cannot change its kind or persisted endpoint positions`,\n );\n }\n }\n this.state.relations.push(clone(command.relation));\n return;\n case 'unlink-relation': {\n const index = this.state.relations.findIndex((relation) => relation.relation_id === command.relation_id);\n if (index < 0) throw new Error(`Relation id \"${command.relation_id}\" does not exist`);\n this.state.relations.splice(index, 1);\n return;\n }\n }\n }\n}\n\nfunction isImportedMemotaAsset(payload: JsonObject, assetId: string): boolean {\n const external = payload[ASSET_SOURCE_KEY];\n return (\n external != null &&\n !Array.isArray(external) &&\n typeof external === 'object' &&\n external.system === MEMOTA_SYSTEM &&\n external.key === assetId\n );\n}\n\nfunction toDslEntity(entity: SandboxEntity): MedeoEntity {\n return {\n ...clone(entity.payload),\n entityId: createEntityId(entity.entity_id),\n entityKind: entity.entity_kind,\n } as MedeoEntity;\n}\n\nfunction toDslRows(state: EntityStoreSnapshot): EntityRelationRows {\n return {\n entities: state.entities.map((entity) => ({\n entityId: createEntityId(entity.entity_id),\n entityKind: entity.entity_kind,\n payload: clone(entity.payload),\n })),\n relations: state.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: clone(relation.metadata),\n trace: clone(relation.trace),\n })),\n };\n}\n\nfunction cloneSnapshot(state: EntityStoreSnapshot): EntityStoreSnapshot {\n return clone(state);\n}\n\nfunction clone<T>(value: T): T {\n return structuredClone(value);\n}\n\nfunction assertTrimmed(value: string, label: string): void {\n if (typeof value !== 'string' || value.length === 0 || value.trim() !== value) {\n throw new Error(`${label} must be a non-empty trimmed string`);\n }\n}\n\nconst numericMarkerComparators = {\n compareMarkerPoints: (_marker: unknown, _range: 'source' | 'target', left: unknown, right: unknown) => {\n if (typeof left !== 'number' || !Number.isFinite(left) || typeof right !== 'number' || !Number.isFinite(right)) {\n throw new Error('Sequence Marker points require finite numeric coordinates in the entity sandbox');\n }\n return left - right;\n },\n};\n","import {\n createEditSandbox,\n effectiveVideoClipDurationMs,\n fromVideoDocument,\n SchemaValidator,\n SemanticEditor,\n solveVideoDocument,\n type JournalEntry,\n type PartIdFactory,\n type PlainMemoryAdapter,\n type VideoDocument,\n} from '@mengine/medeo-client';\nimport type {\n AddSpeechesInput,\n AddVideoClipsInput,\n AdjustBgmVolumeInput,\n AdjustSpeechVolumeInput,\n AdjustVideoClipDurationInput,\n AdjustVideoClipVolumeInput,\n ChangeSpeechScriptInput,\n ChangeSpeechVoiceInput,\n DeleteBgmInput,\n DeleteSpeechesInput,\n DeleteVideoClipsInput,\n MoveSpeechesInput,\n MoveVideoClipsByAnchorInput,\n MoveVideoClipsInput,\n ReplaceVideoClipContentInput,\n ReplaceVideoClipSequenceInput,\n SetBgmInput,\n SetCaptionStyleInput,\n SetCaptionVisibilityInput,\n SetVideoClipSpeedShiftInput,\n} from '@mengine/medeo-client/schemas';\n\nimport type { EntityCommand, EntityFacade, EntityStoreSnapshot, RelationFacade } from '../entity/entity-contract.ts';\nimport { EntitySandbox, type DomainIdFactory } from '../entity/entity-sandbox.ts';\nimport { renderPreview } from './preview.ts';\n\n/**\n * Runtime-neutral edit-sandbox session: `edit.*` / `timeline.*` / checkpoint\n * facade over a forked `VideoDocument`, self-maintained journal, and console\n * log buffer. No `node:*` imports — host/worker layers inject this into vm.\n *\n * Known gap (not solved here): `Math.random` / `Date.now` remain reachable in\n * the vm; purity is by convention.\n */\n\nexport interface SandboxCheckpoint {\n readonly index: number;\n}\n\nexport interface ChangePlan {\n readonly plan_kind: 'timeline' | 'entities';\n doc_id: string;\n base_version: string;\n ops: readonly JournalEntry[];\n entity_base_revision: number;\n entity_commands: readonly EntityCommand[];\n entity_rows?: EntityStoreSnapshot;\n deleted_entity_ids?: readonly string[];\n deleted_relation_ids?: readonly string[];\n preview: string;\n logs: string[];\n}\n\nexport interface EditSandboxSessionOptions {\n idFactory?: PartIdFactory;\n onEntry?: (entry: JournalEntry) => void;\n onLog?: (line: string) => void;\n /** Notify host that the streamed journal was truncated to `index` (rollback). */\n onTruncate?: (index: number) => void;\n entityState?: EntityStoreSnapshot;\n domainIdFactory?: DomainIdFactory;\n onEntityCommand?: (command: EntityCommand) => void;\n onEntityTruncate?: (index: number) => void;\n}\n\nexport interface TimelineClipDescriptor {\n id: string;\n start_ms: number;\n end_ms: number;\n duration_ms: number;\n speed_shift: unknown;\n volume: number | undefined;\n media_id: string | undefined;\n}\n\nexport interface TimelinePartDescriptor {\n id: string;\n kind: string;\n lane: string;\n start_ms: number;\n end_ms: number;\n duration_ms: number;\n part: unknown;\n}\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\ninterface SandboxRef {\n adapter: PlainMemoryAdapter;\n editor: SemanticEditor;\n}\n\nconst ENTITY_CHECKPOINT_INDEX = Symbol('entityCheckpointIndex');\n\n/** Session core for one forked document; globals stay identity-stable across rollback. */\nexport class EditSandboxSession {\n private readonly original: VideoDocument;\n private readonly idFactory: PartIdFactory | undefined;\n private readonly onEntry: ((entry: JournalEntry) => void) | undefined;\n private readonly onLog: ((line: string) => void) | undefined;\n private readonly onTruncate: ((index: number) => void) | undefined;\n private readonly entitySandbox: EntitySandbox;\n\n private current: SandboxRef;\n /** Adapter journal length already accounted for — new slices are real commits. */\n private adapterJournalSeen = 0;\n private readonly entries: JournalEntry[] = [];\n private readonly logs: string[] = [];\n private logBytes = 0;\n private logCapped = false;\n\n readonly edit: EditFacade;\n readonly timeline: TimelineFacade;\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.original = structuredClone(document);\n this.idFactory = options?.idFactory;\n this.onEntry = options?.onEntry;\n this.onLog = options?.onLog;\n this.onTruncate = options?.onTruncate;\n this.entitySandbox = new EntitySandbox({\n state: options?.entityState,\n idFactory:\n options?.domainIdFactory ??\n (() => {\n throw new Error('Entity id factory is unavailable in this sandbox host');\n }),\n onCommand: options?.onEntityCommand,\n onTruncate: options?.onEntityTruncate,\n });\n\n this.current = this.boot(structuredClone(this.original));\n this.adapterJournalSeen = this.current.adapter.journal.length;\n\n this.edit = this.buildEditFacade();\n this.timeline = this.buildTimelineFacade();\n this.entities = this.entitySandbox.entities;\n this.relations = this.entitySandbox.relations;\n this.console = this.buildConsoleShim();\n this.checkpoint = () => {\n const checkpoint = { index: this.entries.length };\n Object.defineProperty(checkpoint, ENTITY_CHECKPOINT_INDEX, {\n value: this.entitySandbox.commandCount,\n enumerable: false,\n });\n return checkpoint;\n };\n this.rollbackTo = (cp) => this.doRollbackTo(cp);\n }\n\n /** Assemble a ChangePlan from the self-maintained journal + current preview. */\n buildPlan(baseVersion: string): ChangePlan {\n const entityCommands = this.entitySandbox.getCommands();\n if (this.entries.length > 0 && entityCommands.length > 0) {\n throw new Error('A sandbox plan cannot mix timeline and entity mutations; run and commit them as separate plans');\n }\n const entityPlan = this.entitySandbox.buildPlan();\n const planKind = entityCommands.length > 0 ? 'entities' : 'timeline';\n return {\n plan_kind: planKind,\n doc_id: this.original.meta.draft_id ?? '',\n base_version: baseVersion,\n ops: this.entries.slice(),\n entity_base_revision: entityPlan.base_revision,\n entity_commands: entityPlan.commands,\n ...(planKind === 'entities' ? { entity_rows: entityPlan.rows } : {}),\n ...(planKind === 'entities'\n ? {\n deleted_entity_ids: entityPlan.deleted_entity_ids,\n deleted_relation_ids: entityPlan.deleted_relation_ids,\n }\n : {}),\n preview:\n planKind === 'entities'\n ? this.entitySandbox.renderPreview()\n : renderPreview(this.current.adapter.snapshot(), this.entries),\n logs: this.logs.slice(),\n };\n }\n\n getEntries(): readonly JournalEntry[] {\n return this.entries;\n }\n\n getLogs(): readonly string[] {\n return this.logs;\n }\n\n private boot(document: VideoDocument): SandboxRef {\n const sandbox = createEditSandbox(document, this.idFactory != null ? { idFactory: this.idFactory } : undefined);\n return { adapter: sandbox.adapter, editor: sandbox.editor };\n }\n\n private doRollbackTo(cp: SandboxCheckpoint): void {\n if (cp.index > this.entries.length) {\n throw new Error(`rollbackTo: checkpoint index ${cp.index} is past journal length ${this.entries.length}`);\n }\n const prefix = this.entries.slice(0, cp.index);\n const next = this.boot(structuredClone(this.original));\n // Sync replay: editor methods finish mutations before returning a Promise.\n // Must not use async `replayJournal` — agent scripts call rollbackTo without await.\n replayJournalSync(next.adapter, prefix);\n this.entries.length = 0;\n this.entries.push(...prefix);\n this.current = next;\n this.adapterJournalSeen = next.adapter.journal.length;\n // Host streams entries eagerly; tell it to drop the rolled-back suffix.\n this.onTruncate?.(prefix.length);\n const entityIndex = (cp as SandboxCheckpoint & { [ENTITY_CHECKPOINT_INDEX]?: number })[ENTITY_CHECKPOINT_INDEX];\n if (entityIndex !== undefined) this.entitySandbox.rollbackTo(entityIndex);\n }\n\n private captureNewEntries(): void {\n const journal = this.current.adapter.journal;\n if (journal.length <= this.adapterJournalSeen) return;\n const fresh = journal.slice(this.adapterJournalSeen);\n this.adapterJournalSeen = journal.length;\n for (const entry of fresh) {\n this.entries.push(entry);\n this.onEntry?.(entry);\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 let out = line;\n if (out.length > LOG_LINE_MAX) {\n out = `${out.slice(0, LOG_LINE_MAX - TRUNCATE_MARK.length)}${TRUNCATE_MARK}`;\n }\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[]) => {\n this.appendLog(args.map(formatLogArg).join(' '));\n };\n return {\n log: write,\n info: write,\n warn: write,\n error: write,\n };\n }\n\n private buildEditFacade(): EditFacade {\n const wrap =\n <I>(method: (editor: SemanticEditor, input: I) => Promise<void>) =>\n async (input: I): Promise<void> => {\n await method(this.current.editor, input);\n this.captureNewEntries();\n };\n\n return {\n addSpeeches: wrap((e, i: AddSpeechesInput) => e.addSpeeches(i)),\n addVideoClips: async (input: AddVideoClipsInput): Promise<void> => {\n // Schema requires start_ms without before/after, but SemanticEditor\n // treats a missing start_ms as \"append\". Fill duration so agent scripts\n // that omit it (and the host-spec id-factory case) still validate.\n const needsAppend =\n input.before_clip_id == null &&\n input.after_clip_id == null &&\n input.clips.some((clip) => clip.start_ms == null);\n const appendAt = this.timeline.snapshot().timeline?.duration_ms ?? 0;\n const normalized: AddVideoClipsInput = needsAppend\n ? {\n ...input,\n clips: input.clips.map((clip) => (clip.start_ms == null ? { ...clip, start_ms: appendAt } : clip)),\n }\n : input;\n await this.current.editor.addVideoClips(normalized);\n this.captureNewEntries();\n },\n adjustBgmVolume: wrap((e, i: AdjustBgmVolumeInput) => e.adjustBgmVolume(i)),\n adjustSpeechVolume: wrap((e, i: AdjustSpeechVolumeInput) => e.adjustSpeechVolume(i)),\n adjustVideoClipDuration: wrap((e, i: AdjustVideoClipDurationInput) => e.adjustVideoClipDuration(i)),\n adjustVideoClipVolume: wrap((e, i: AdjustVideoClipVolumeInput) => e.adjustVideoClipVolume(i)),\n changeSpeechScript: wrap((e, i: ChangeSpeechScriptInput) => e.changeSpeechScript(i)),\n changeSpeechVoice: wrap((e, i: ChangeSpeechVoiceInput) => e.changeSpeechVoice(i)),\n deleteBgm: wrap((e, i: DeleteBgmInput) => e.deleteBgm(i)),\n deleteSpeeches: wrap((e, i: DeleteSpeechesInput) => e.deleteSpeeches(i)),\n deleteVideoClips: wrap((e, i: DeleteVideoClipsInput) => e.deleteVideoClips(i)),\n moveSpeeches: wrap((e, i: MoveSpeechesInput) => e.moveSpeeches(i)),\n moveVideoClips: wrap((e, i: MoveVideoClipsInput) => e.moveVideoClips(i)),\n moveVideoClipsByAnchor: wrap((e, i: MoveVideoClipsByAnchorInput) => e.moveVideoClipsByAnchor(i)),\n replaceVideoClipContent: wrap((e, i: ReplaceVideoClipContentInput) => e.replaceVideoClipContent(i)),\n replaceVideoClipSequence: wrap((e, i: ReplaceVideoClipSequenceInput) => e.replaceVideoClipSequence(i)),\n setBgm: wrap((e, i: SetBgmInput) => e.setBgm(i)),\n setCaptionStyle: wrap((e, i: SetCaptionStyleInput) => e.setCaptionStyle(i)),\n setCaptionVisibility: wrap((e, i: SetCaptionVisibilityInput) => e.setCaptionVisibility(i)),\n setVideoClipSpeedShift: wrap((e, i: SetVideoClipSpeedShiftInput) => e.setVideoClipSpeedShift(i)),\n };\n }\n\n private buildTimelineFacade(): TimelineFacade {\n return {\n snapshot: () => fromVideoDocument(this.current.adapter.snapshot()),\n clipsInRange: (startMs, endMs) => this.clipsInRange(startMs, endMs),\n part: (id) => this.part(id),\n };\n }\n\n private clipsInRange(startMs: number, endMs: number): TimelineClipDescriptor[] {\n const document = this.current.adapter.snapshot();\n const solved = solveVideoDocument(document);\n const library = document.part_library ?? {};\n const main = document.tracks?.find((track) => track.parts_kind === 'video_clip');\n const out: TimelineClipDescriptor[] = [];\n for (const item of main?.items ?? []) {\n const id = item.part_id;\n if (id == null) continue;\n const part = library[id];\n const clip = part?.video_clip;\n if (clip == null) continue;\n const start = solved.absByPartId.get(id) ?? 0;\n const duration = effectiveVideoClipDurationMs(clip);\n const end = start + duration;\n // Include clips whose midpoint falls in [startMs, endMs). Standard\n // interval overlap would also pull in a clip that only barely crosses\n // the window edge (e.g. clip_b@[4000,8000) vs query [0,5000)); the\n // midpoint rule matches the T2 host-spec pin for that fixture.\n const mid = start + duration / 2;\n if (!(mid >= startMs && mid < endMs)) continue;\n out.push({\n id,\n start_ms: start,\n end_ms: end,\n duration_ms: duration,\n speed_shift: clip.speed_shift,\n volume: clip.volume,\n media_id: clip.origin_media_id,\n });\n }\n return out;\n }\n\n private part(id: string): TimelinePartDescriptor | null {\n const document = this.current.adapter.snapshot();\n const library = document.part_library ?? {};\n const part = library[id];\n if (part == null) return null;\n\n let lane = 'main';\n let kind = 'video_clip';\n for (const track of document.tracks ?? []) {\n const hit = (track.items ?? []).some((item) => item.part_id === id);\n if (!hit) continue;\n const partsKind = track.parts_kind ?? 'video_clip';\n kind = partsKind;\n lane = partsKind === 'video_clip' ? 'main' : partsKind;\n break;\n }\n\n const solved = solveVideoDocument(document);\n const start = solved.absByPartId.get(id) ?? 0;\n let duration = 0;\n if (part.video_clip != null) duration = effectiveVideoClipDurationMs(part.video_clip);\n else if (part.speech != null) duration = part.speech.media_duration_ms ?? 0;\n else if (part.caption != null) duration = part.caption.initial_duration_ms ?? 0;\n else if (part.bgm != null) duration = solved.durationMs;\n\n return {\n id,\n kind,\n lane,\n start_ms: start,\n end_ms: start + duration,\n duration_ms: duration,\n part,\n };\n }\n}\n\nexport interface EditFacade {\n addSpeeches: (input: AddSpeechesInput) => Promise<void>;\n addVideoClips: (input: AddVideoClipsInput) => Promise<void>;\n adjustBgmVolume: (input: AdjustBgmVolumeInput) => Promise<void>;\n adjustSpeechVolume: (input: AdjustSpeechVolumeInput) => Promise<void>;\n adjustVideoClipDuration: (input: AdjustVideoClipDurationInput) => Promise<void>;\n adjustVideoClipVolume: (input: AdjustVideoClipVolumeInput) => Promise<void>;\n changeSpeechScript: (input: ChangeSpeechScriptInput) => Promise<void>;\n changeSpeechVoice: (input: ChangeSpeechVoiceInput) => Promise<void>;\n deleteBgm: (input: DeleteBgmInput) => Promise<void>;\n deleteSpeeches: (input: DeleteSpeechesInput) => Promise<void>;\n deleteVideoClips: (input: DeleteVideoClipsInput) => Promise<void>;\n moveSpeeches: (input: MoveSpeechesInput) => Promise<void>;\n moveVideoClips: (input: MoveVideoClipsInput) => Promise<void>;\n moveVideoClipsByAnchor: (input: MoveVideoClipsByAnchorInput) => Promise<void>;\n replaceVideoClipContent: (input: ReplaceVideoClipContentInput) => Promise<void>;\n replaceVideoClipSequence: (input: ReplaceVideoClipSequenceInput) => Promise<void>;\n setBgm: (input: SetBgmInput) => Promise<void>;\n setCaptionStyle: (input: SetCaptionStyleInput) => Promise<void>;\n setCaptionVisibility: (input: SetCaptionVisibilityInput) => Promise<void>;\n setVideoClipSpeedShift: (input: SetVideoClipSpeedShiftInput) => Promise<void>;\n}\n\nexport interface TimelineFacade {\n snapshot: () => ReturnType<typeof fromVideoDocument>;\n clipsInRange: (startMs: number, endMs: number) => TimelineClipDescriptor[];\n part: (id: string) => TimelinePartDescriptor | null;\n}\n\nexport interface ConsoleShim {\n log: (...args: unknown[]) => void;\n info: (...args: unknown[]) => void;\n warn: (...args: unknown[]) => void;\n error: (...args: unknown[]) => void;\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\n/**\n * Synchronous journal replay for rollback. Editor methods are `async` only for\n * interface uniformity — their bodies complete before the Promise is returned,\n * so voiding the call applies mutations in-order without yielding.\n */\nfunction replayJournalSync(adapter: PlainMemoryAdapter, journal: readonly JournalEntry[]): void {\n const queue: string[] = [];\n const idFactory: PartIdFactory = (_prefix) => {\n const id = queue.shift();\n if (id == null) throw new Error('unrecorded id');\n return id;\n };\n const editor = new SemanticEditor(adapter, new SchemaValidator(), idFactory);\n\n for (const entry of journal) {\n queue.push(...(entry.generated_ids ?? []));\n const payload = entry.payload;\n switch (entry.kind) {\n case 'MoveVideoClips':\n void editor.moveVideoClips(payload as MoveVideoClipsInput);\n break;\n case 'MoveVideoClipsByAnchor':\n void editor.moveVideoClipsByAnchor(payload as MoveVideoClipsByAnchorInput);\n break;\n case 'DeleteVideoClips':\n void editor.deleteVideoClips(payload as DeleteVideoClipsInput);\n break;\n case 'AddVideoClips':\n void editor.addVideoClips(payload as AddVideoClipsInput);\n break;\n case 'AdjustVideoClipVolume':\n void editor.adjustVideoClipVolume(payload as AdjustVideoClipVolumeInput);\n break;\n case 'SetVideoClipSpeedShift':\n void editor.setVideoClipSpeedShift(payload as SetVideoClipSpeedShiftInput);\n break;\n case 'ReplaceVideoClipContent':\n void editor.replaceVideoClipContent(payload as ReplaceVideoClipContentInput);\n break;\n case 'ReplaceVideoClipSequence':\n void editor.replaceVideoClipSequence(payload as ReplaceVideoClipSequenceInput);\n break;\n case 'AdjustVideoClipDuration':\n void editor.adjustVideoClipDuration(payload as AdjustVideoClipDurationInput);\n break;\n case 'AddSpeeches':\n void editor.addSpeeches(payload as AddSpeechesInput);\n break;\n case 'DeleteSpeeches':\n void editor.deleteSpeeches(payload as DeleteSpeechesInput);\n break;\n case 'MoveSpeeches':\n void editor.moveSpeeches(payload as MoveSpeechesInput);\n break;\n case 'ChangeSpeechScript':\n void editor.changeSpeechScript(payload as ChangeSpeechScriptInput);\n break;\n case 'ChangeSpeechVoice':\n void editor.changeSpeechVoice(payload as ChangeSpeechVoiceInput);\n break;\n case 'AdjustSpeechVolume':\n void editor.adjustSpeechVolume(payload as AdjustSpeechVolumeInput);\n break;\n case 'SetCaptionVisibility':\n void editor.setCaptionVisibility(payload as SetCaptionVisibilityInput);\n break;\n case 'SetCaptionStyle':\n void editor.setCaptionStyle(payload as SetCaptionStyleInput);\n break;\n case 'SetBgm':\n void editor.setBgm(payload as SetBgmInput);\n break;\n case 'DeleteBgm':\n void editor.deleteBgm(payload as DeleteBgmInput);\n break;\n case 'AdjustBgmVolume':\n void editor.adjustBgmVolume(payload as AdjustBgmVolumeInput);\n break;\n default: {\n const _exhaustive: never = entry.kind;\n throw new Error(`replayJournalSync: unsupported kind ${String(_exhaustive)}`);\n }\n }\n if (queue.length > 0) throw new Error('unconsumed ids');\n }\n}\n"],"mappings":"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"}
|
package/dist/worker-entry.d.mts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { s as EntityStoreSnapshot } from "./entity-contract-DycLxdQ5.mjs";
|
|
2
2
|
import { VideoDocument } from "@mengine/medeo-client";
|
|
3
3
|
|
|
4
4
|
//#region src/sandbox/worker-entry.d.ts
|
|
5
5
|
/**
|
|
6
6
|
* Node worker entry for trusted edit scripts.
|
|
7
7
|
*
|
|
8
|
-
* Spawns
|
|
9
|
-
* (no fetch/process/setTimeout), and streams
|
|
10
|
-
* so hard timeout / OOM termination still preserves partial products.
|
|
8
|
+
* Spawns the requested sandbox session, runs the agent script in a bare `vm`
|
|
9
|
+
* context (no fetch/process/setTimeout), and streams journals + logs to the
|
|
10
|
+
* host so hard timeout / OOM termination still preserves partial products.
|
|
11
11
|
*/
|
|
12
12
|
interface WorkerData {
|
|
13
13
|
document: VideoDocument;
|
|
@@ -15,6 +15,7 @@ interface WorkerData {
|
|
|
15
15
|
inputs?: Record<string, unknown>;
|
|
16
16
|
entityState?: EntityStoreSnapshot;
|
|
17
17
|
idLabel?: string;
|
|
18
|
+
entityOnly?: boolean;
|
|
18
19
|
}
|
|
19
20
|
//#endregion
|
|
20
21
|
export { WorkerData };
|