@mengine/medeo-client 2.0.1-alpha.11 → 2.0.1-alpha.13

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.
@@ -1462,8 +1462,9 @@ function emptyLaneTracks() {
1462
1462
  * `Voice` declares no `Sequence` — it is a timbre identity, not playable
1463
1463
  * content; a rendered voiceover is an `audio` entity.
1464
1464
  *
1465
- * No declaration says anything about resources: whether an entity has one, and
1466
- * which, is the `from-asset` Relation's answer alone.
1465
+ * `Asset` says only that an entity of that kind may be bound to stored bytes,
1466
+ * and asks nothing of its payload. Which bytes, and which way the content
1467
+ * flowed, is the `from-asset` / `to-asset` Relation's answer alone.
1467
1468
  */
1468
1469
  const ENTITY_KINDS = Object.freeze({
1469
1470
  axvideo: Object.freeze([
@@ -1480,27 +1481,27 @@ const ENTITY_KINDS = Object.freeze({
1480
1481
  "Sequence",
1481
1482
  "Visual",
1482
1483
  "Audible",
1483
- "FromAsset"
1484
+ "Asset"
1484
1485
  ]),
1485
1486
  audio: Object.freeze([
1486
1487
  "Sequence",
1487
1488
  "Audible",
1488
- "FromAsset"
1489
+ "Asset"
1489
1490
  ]),
1490
1491
  image: Object.freeze([
1491
1492
  "Sequence",
1492
1493
  "Visual",
1493
- "FromAsset"
1494
+ "Asset"
1494
1495
  ]),
1495
1496
  voice: Object.freeze(["Container", "IPBound"]),
1496
1497
  "sequence-marker": Object.freeze([]),
1497
1498
  viewport: Object.freeze([]),
1498
- "audio-script": Object.freeze(["SegmentText", "FromAsset"]),
1499
- "phonetic-script": Object.freeze(["SegmentText"]),
1499
+ "audio-script": Object.freeze(["SegmentText", "Asset"]),
1500
+ "phonetic-script": Object.freeze(["SegmentText", "Asset"]),
1500
1501
  caption: Object.freeze([
1501
1502
  "SegmentText",
1502
1503
  "Sequence",
1503
- "FromAsset"
1504
+ "Asset"
1504
1505
  ])
1505
1506
  });
1506
1507
  /** What a known kind declares; extension kinds declare nothing through this table. */
@@ -1798,15 +1799,6 @@ function entityToRow(entity) {
1798
1799
  //#endregion
1799
1800
  //#region ../medeo-dsl/src/invariants.ts
1800
1801
  /** An entity is made from at most one Asset; two would leave its bytes ambiguous. */
1801
- function validateAssetSource(entity, index) {
1802
- if (entity.current().entityKind === "asset") return [];
1803
- if ([...index.relationsOf(entity)].filter((relation) => relation.kind === "from-asset").length <= 1) return [];
1804
- return [{
1805
- code: "asset_source_cardinality",
1806
- entityId: entity.entityId,
1807
- message: `Entity "${entity.entityId}" is made from more than one Asset`
1808
- }];
1809
- }
1810
1802
  /** Validates one complete set of entities and its authoritative Relation rows. */
1811
1803
  function validateEntityRelationSet(entityRefs, index, options) {
1812
1804
  const { entities, issues } = collectRelatedEntities(entityRefs, index);
@@ -1828,7 +1820,6 @@ function validateEntityRelationSet(entityRefs, index, options) {
1828
1820
  const current = entity.current();
1829
1821
  const entityIssues = validateEntity(entity, entityIds);
1830
1822
  issues.push(...entityIssues);
1831
- issues.push(...validateAssetSource(entity, index));
1832
1823
  if (entityIssues.some((issue) => issue.code === "invalid_entity_payload")) continue;
1833
1824
  if (current.entityKind === "sequence-marker") {
1834
1825
  const marker = entity;
@@ -2472,10 +2463,10 @@ const markerContentRelationSpec = Object.freeze({
2472
2463
  /**
2473
2464
  * `from-asset(entity, asset)` — the entity was made from that stored resource.
2474
2465
  *
2475
- * Eligibility is declared: the non-Asset endpoint must carry the `FromAsset`
2476
- * kind, which says an entity of that kind can be made from stored bytes and
2477
- * asks nothing of its payload. The bytes stay named in exactly one place, so
2478
- * no entity copies the locator into its own row and one Asset can back several
2466
+ * Eligibility is declared: the non-Asset endpoint must carry the `Asset` kind,
2467
+ * which says an entity of that kind can be bound to stored bytes and asks
2468
+ * nothing of its payload. The bytes stay named in exactly one place, so no
2469
+ * entity copies the locator into its own row and one Asset can back several
2479
2470
  * entities.
2480
2471
  */
2481
2472
  const fromAssetRelationSpec = Object.freeze({
@@ -2483,6 +2474,26 @@ const fromAssetRelationSpec = Object.freeze({
2483
2474
  validateEndpoints: (endpoints) => hasExactlyOneAsset(endpoints),
2484
2475
  validateMetadata: isAssetBinding
2485
2476
  });
2477
+ /**
2478
+ * `to-asset(entity, asset)` — the entity's content was written out to that
2479
+ * stored resource.
2480
+ *
2481
+ * The mirror of `from-asset`, and deliberately a separate relation kind rather
2482
+ * than a second declared kind: eligibility is the same either way, but which
2483
+ * way the content flowed is what says whether an entity may still be edited.
2484
+ * An entity reached by `from-asset` was produced from bytes it does not own,
2485
+ * so changing it would contradict them. An entity with a `to-asset` owns its
2486
+ * content and the resource is a snapshot of it, which is what goes stale and
2487
+ * gets written again. A transcript that is later edited carries both at once,
2488
+ * and only the distinct relation kinds keep them apart.
2489
+ *
2490
+ * Writing a snapshot is host assembly; nothing a script authors creates one.
2491
+ */
2492
+ const toAssetRelationSpec = Object.freeze({
2493
+ kind: "to-asset",
2494
+ validateEndpoints: (endpoints) => hasExactlyOneAsset(endpoints),
2495
+ validateMetadata: isAssetBinding
2496
+ });
2486
2497
  /** `generated(output, input)` means endpoint 0 was generated from endpoint 1. */
2487
2498
  const generatedRelationSpec = Object.freeze({
2488
2499
  kind: "generated",
@@ -2545,6 +2556,7 @@ const builtInRelationSpecs = Object.freeze([
2545
2556
  axVideoMarkerRelationSpec,
2546
2557
  markerTimelineRelationSpec,
2547
2558
  fromAssetRelationSpec,
2559
+ toAssetRelationSpec,
2548
2560
  generatedRelationSpec,
2549
2561
  captionAlignmentRelationSpec,
2550
2562
  clipAnchorRelationSpec,
@@ -2573,12 +2585,12 @@ function hasMarkerAndSequence(endpoints) {
2573
2585
  const second = endpoints[1].current();
2574
2586
  return first.entityKind === "sequence-marker" && hasSequence(second) || second.entityKind === "sequence-marker" && hasSequence(first);
2575
2587
  }
2576
- /** Exactly one end is the Asset, so the other end is unambiguously the maker. */
2588
+ /** Exactly one end is the Asset, so the other end is unambiguously the bound entity. */
2577
2589
  function hasExactlyOneAsset(endpoints) {
2578
2590
  const kinds = endpoints.map((endpoint) => endpoint.current().entityKind);
2579
2591
  const assets = kinds.map((kind) => kind === "asset");
2580
2592
  if (assets[0] === assets[1]) return false;
2581
- return declaresKind(assets[0] ? kinds[1] : kinds[0], "FromAsset");
2593
+ return declaresKind(assets[0] ? kinds[1] : kinds[0], "Asset");
2582
2594
  }
2583
2595
  function isGeneratedMedia(entity) {
2584
2596
  return entity.entityKind === "video" || entity.entityKind === "image" || entity.entityKind === "audio";
@@ -3608,12 +3620,23 @@ function audioScriptAssetHash(payload) {
3608
3620
  return bytesToHex(sha256(new TextEncoder().encode(canonicalJson(audioScriptAssetContent(payload)))));
3609
3621
  }
3610
3622
  /**
3611
- * The Asset a script was written out to, read from the graph rather than the
3612
- * script's own row: like every other entity, a script names its bytes through
3613
- * a `from-asset` Relation and stores no locator itself.
3623
+ * The Asset a script was written out to. It is a snapshot the script owns, so
3624
+ * it is reached by `to-asset` — not `from-asset`, which would say the script
3625
+ * was produced from bytes it cannot change.
3614
3626
  */
3615
3627
  function audioScriptAssetOf(rows, entityId) {
3616
- const link = rows.relations.find((relation) => relation.relationKind === "from-asset" && (String(relation.endpoint0EntityId) === entityId || String(relation.endpoint1EntityId) === entityId));
3628
+ return boundAsset(rows, entityId, "to-asset");
3629
+ }
3630
+ /**
3631
+ * The Asset a script was made from — a transcript it does not own. A script
3632
+ * that has one never writes a snapshot of its own: the bytes it would describe
3633
+ * are already named, and rewriting them would contradict their source.
3634
+ */
3635
+ function scriptSourceAssetOf(rows, entityId) {
3636
+ return boundAsset(rows, entityId, "from-asset");
3637
+ }
3638
+ function boundAsset(rows, entityId, relationKind) {
3639
+ const link = rows.relations.find((relation) => relation.relationKind === relationKind && (String(relation.endpoint0EntityId) === entityId || String(relation.endpoint1EntityId) === entityId));
3617
3640
  if (link === void 0) return void 0;
3618
3641
  const otherId = String(link.endpoint0EntityId) === entityId ? link.endpoint1EntityId : link.endpoint0EntityId;
3619
3642
  return rows.entities.find((row) => String(row.entityId) === String(otherId) && row.entityKind === "asset");
@@ -3622,6 +3645,33 @@ function audioScriptAssetOf(rows, entityId) {
3622
3645
  function audioScriptAssetFields(payload) {
3623
3646
  return { assetContentHash: audioScriptAssetHash(payload) };
3624
3647
  }
3648
+ /**
3649
+ * What a PhoneticScript hands to synthesis: the base AudioScript's text as the
3650
+ * variant pronounces it, plus the variant's own phoneme and prosody control.
3651
+ *
3652
+ * The variant's content is written by a model — deciding how words are said is
3653
+ * text work, not a mechanical copy — but the bytes a synthesizer reads have to
3654
+ * leave the entity graph to reach it, because synthesis does not handle
3655
+ * entities. Writing this resource down is that crossing, and it is why speech
3656
+ * can only come from a PhoneticScript.
3657
+ */
3658
+ function phoneticScriptAssetContent(rows, entityId) {
3659
+ const assembled = assemblePhoneticScriptContent(rows, createEntityId(entityId));
3660
+ const own = assembled.phoneticScript.payload;
3661
+ return {
3662
+ text: assembled.text,
3663
+ segments: structuredClone(assembled.segments),
3664
+ ...typeof own.phonemeScript === "string" ? { phonemeScript: own.phonemeScript } : {},
3665
+ ...isJsonObject(own.prosody) ? { prosody: structuredClone(own.prosody) } : {}
3666
+ };
3667
+ }
3668
+ function phoneticScriptAssetHash(rows, entityId) {
3669
+ return bytesToHex(sha256(new TextEncoder().encode(canonicalJson(phoneticScriptAssetContent(rows, entityId)))));
3670
+ }
3671
+ /** The Asset a PhoneticScript was written out to, read from the graph. */
3672
+ function phoneticScriptAssetOf(rows, entityId) {
3673
+ return audioScriptAssetOf(rows, entityId);
3674
+ }
3625
3675
  //#endregion
3626
3676
  //#region src/entity-crdt/ordering.ts
3627
3677
  /** Domain order is scoped by membership; relation storage has no global order. */
@@ -3925,8 +3975,10 @@ var LoroEntityDocument = class LoroEntityDocument {
3925
3975
  /**
3926
3976
  * Bind a saved snapshot without rewriting text operations or resolving
3927
3977
  * selection conflicts. The script names the bytes the same way everything
3928
- * else does — an Asset entity plus a `from-asset` Relation — and keeps only
3929
- * the fingerprint that tells a stale snapshot from a current one.
3978
+ * else does — an Asset entity plus a Relation — and keeps only the
3979
+ * fingerprint that tells a stale snapshot from a current one. The Relation is
3980
+ * `to-asset`: these bytes are the script's own content written out, not a
3981
+ * source it was made from.
3930
3982
  */
3931
3983
  bindAudioScriptAsset(entityId, assetId, expectedContentHash) {
3932
3984
  const key = family(this.doc, entityId);
@@ -3949,10 +4001,10 @@ var LoroEntityDocument = class LoroEntityDocument {
3949
4001
  this.transact((draft) => {
3950
4002
  const current = readEntityDocument(this.doc, true).rows;
3951
4003
  if (audioScriptAssetOf(current, entityId)?.entityId !== assetEntityId) {
3952
- for (const relation of current.relations) if (relation.relationKind === "from-asset" && (String(relation.endpoint0EntityId) === String(entityId) || String(relation.endpoint1EntityId) === String(entityId))) draft.unlink(String(relation.relationId));
4004
+ for (const relation of current.relations) if (relation.relationKind === "to-asset" && (String(relation.endpoint0EntityId) === String(entityId) || String(relation.endpoint1EntityId) === String(entityId))) draft.unlink(String(relation.relationId));
3953
4005
  draft.link({
3954
- relationId: createRelationId(`relation_from-asset_${entityId}_${assetId}`),
3955
- relationKind: "from-asset",
4006
+ relationId: createRelationId(`relation_to-asset_${entityId}_${assetId}`),
4007
+ relationKind: "to-asset",
3956
4008
  endpoint0EntityId: createEntityId(entityId),
3957
4009
  endpoint1EntityId: assetEntityId,
3958
4010
  metadata: {},
@@ -4663,4 +4715,4 @@ function createPlainMemoryAdapter(document, options) {
4663
4715
  return new PlainMemoryAdapter(document, options);
4664
4716
  }
4665
4717
  //#endregion
4666
- export { findLaneTrack as $, assemblePhoneticScriptContent as A, isMediaAssetVariantKind as B, EntityProjectionGraph as C, ScriptCompositionError as D, decodeEntityRelationRows as E, variantBaseEntityIds as F, toVideoDocument as G, buildSpeechHostMap as H, isJsonObject as I, validateVideoDocument as J, VideoDocumentValidationError as K, createEntityId as L, findComposedAudioScript as M, selectAudioScriptSegment as N, assembleCaptionContent as O, updateEntityFields as P, ensureLaneTrack as Q, createRelationId as R, projectEntityTimeline as S, bytesToBase64 as St, EntityTimelineProjectionError as T, derivePositionFromAbs as U, buildInitialVideoDocument as V, fromVideoDocument as W, videoDocumentSchema as X, partUnionSchema as Y, LANE_KINDS_IN_STACK_ORDER as Z, audioScriptAssetOf as _, speedOf as _t, createMirrorVideoDocument as a, fillMainTrackTimeGaps as at, assertFieldChanges as b, videoDocumentMirrorSchema as bt, DocumentMutationGuard as c, resolveAllSpeechOverlaps as ct, LoroEntityDraft as d, TIMELINE_SKELETON_DURATION_MS as dt, hasResolvedPlacement as et, readEntityDocument as f, isEmptyVideoClip as ft, audioScriptAssetHash as g, effectiveVideoClipDurationMs as gt, audioScriptAssetFields as h, DEFAULT_UNIT_TIME_MS as ht, MirrorVideoDocumentAdapter as i, arrangeMainTrackSeamlessly as it, assembleScriptText as j, assembleEntityContent as k, LORO_ENTITY_SCHEMA as l, resolveSpeechOverlapByShiftingVideos as lt, audioScriptAssetContent as m, safeDurationMs as mt, createPlainMemoryAdapter as n, solveVideoDocument as nt, createMirrorVideoDocumentAdapter as o, reassignSpeechesToVideoClipsByTime as ot, entityOrderGroups as p, partDurationMs as pt, assertValidVideoDocument as q, generatePartId as r, cascadeAfterVideoClipChanges as rt, readVideoDocumentFromDraft as s, recalculateTimelineDuration as st, PlainMemoryAdapter as t, laneTrackId as tt, LoroEntityDocument as u, syncAggregatedClipsTimePosition as ut, equalJson as v, partUnionToDraft as vt, resolveEntityTimelineLayout as w, resolveFieldPath as x, base64ToBytes as xt, applyFieldChanges as y, recordEntries as yt, hasSequence as z };
4718
+ export { partUnionSchema as $, decodeEntityRelationRows as A, isJsonObject as B, applyFieldChanges as C, recordEntries as Ct, EntityProjectionGraph as D, projectEntityTimeline as E, bytesToBase64 as Et, assembleScriptText as F, buildInitialVideoDocument as G, createRelationId as H, findComposedAudioScript as I, fromVideoDocument as J, buildSpeechHostMap as K, selectAudioScriptSegment as L, assembleCaptionContent as M, assembleEntityContent as N, resolveEntityTimelineLayout as O, assemblePhoneticScriptContent as P, validateVideoDocument as Q, updateEntityFields as R, equalJson as S, partUnionToDraft as St, resolveFieldPath as T, base64ToBytes as Tt, hasSequence as U, createEntityId as V, isMediaAssetVariantKind as W, VideoDocumentValidationError as X, toVideoDocument as Y, assertValidVideoDocument as Z, audioScriptAssetOf as _, partDurationMs as _t, createMirrorVideoDocument as a, laneTrackId as at, phoneticScriptAssetOf as b, effectiveVideoClipDurationMs as bt, DocumentMutationGuard as c, arrangeMainTrackSeamlessly as ct, LoroEntityDraft as d, recalculateTimelineDuration as dt, videoDocumentSchema as et, readEntityDocument as f, resolveAllSpeechOverlaps as ft, audioScriptAssetHash as g, isEmptyVideoClip as gt, audioScriptAssetFields as h, TIMELINE_SKELETON_DURATION_MS as ht, MirrorVideoDocumentAdapter as i, hasResolvedPlacement as it, ScriptCompositionError as j, EntityTimelineProjectionError as k, LORO_ENTITY_SCHEMA as l, fillMainTrackTimeGaps as lt, audioScriptAssetContent as m, syncAggregatedClipsTimePosition as mt, createPlainMemoryAdapter as n, ensureLaneTrack as nt, createMirrorVideoDocumentAdapter as o, solveVideoDocument as ot, entityOrderGroups as p, resolveSpeechOverlapByShiftingVideos as pt, derivePositionFromAbs as q, generatePartId as r, findLaneTrack as rt, readVideoDocumentFromDraft as s, cascadeAfterVideoClipChanges as st, PlainMemoryAdapter as t, LANE_KINDS_IN_STACK_ORDER as tt, LoroEntityDocument as u, reassignSpeechesToVideoClipsByTime as ut, phoneticScriptAssetContent as v, safeDurationMs as vt, assertFieldChanges as w, videoDocumentMirrorSchema as wt, scriptSourceAssetOf as x, speedOf as xt, phoneticScriptAssetHash as y, DEFAULT_UNIT_TIME_MS as yt, variantBaseEntityIds as z };
@@ -1104,7 +1104,7 @@ type CaptionSegmentSelection = JsonObject & {
1104
1104
  };
1105
1105
  //#endregion
1106
1106
  //#region ../medeo-dsl/src/relations.d.ts
1107
- type KnownRelationKind = 'timeline-track' | 'track-clip' | 'clip-marker' | 'marker-content' | 'axvideo-marker' | 'marker-timeline' | 'from-asset' | 'generated' | 'caption-alignment' | 'clip-anchor' | 'phonetic-script-render' | 'audio-script-source' | 'audio-script-marker';
1107
+ type KnownRelationKind = 'timeline-track' | 'track-clip' | 'clip-marker' | 'marker-content' | 'axvideo-marker' | 'marker-timeline' | 'from-asset' | 'to-asset' | 'generated' | 'caption-alignment' | 'clip-anchor' | 'phonetic-script-render' | 'audio-script-source' | 'audio-script-marker';
1108
1108
  type RelationKind = KnownRelationKind | (string & {});
1109
1109
  type RelationTrace = JsonObject;
1110
1110
  /**
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { t as index_d_exports } from "./index-CMa6ZCtX.js";
2
- import { $ as SpeechHostMap, A as assertValidVideoDocument, At as VideoDocumentValidationIssueCode, B as EntityRow, Bt as SpeedShift, C as isImplementedSemanticOpKind, Ct as Timeline, D as PartIdFactory, Dt as VideoClipPart, E as ValidationError, Et as TrackItemTimePosition, F as ResolvedEntityTrack, Ft as speedOf, G as SequenceDuration, H as CaptionSegmentSelection, Ht as Track$1, I as resolveEntityTimelineLayout, It as Attachment, J as JsonObject, K as SequenceRange, L as projectEntityTimeline, Lt as CaptionPart$1, M as EntityTimelineTrackRole, Mt as VideoDraftContent, N as ResolvedEntityClipPlacement, Nt as VideoDraftPartUnion, O as generatePartId, Ot as VideoDocument, P as ResolvedEntityTimelineLayout, Pt as effectiveVideoClipDurationMs, Q as DerivedItemPosition, R as EntityTimelineProjectionError, Rt as CaptionStyle, S as SemanticOpKind, St as SpeechPart, T as SnapshotReadable, Tt as TrackItem, U as CaptionStyleFields, Ut as TrackItem$1, V as RelationRow, Vt as Timeline$1, W as ScriptTextSegment, X as EntityId, Y as JsonValue, Z as buildInitialVideoDocument, _ as SemanticOpName, _t as CaptionDisplayCue, a as PlainMemoryAdapter, at as LaneKind, b as ImplementedSemanticOpKind, bt as PartKind, c as MirrorVideoDocumentAdapter, ct as findLaneTrack, d as createMirrorVideoDocumentAdapter, dt as TrackDraft, et as buildSpeechHostMap, f as CommitOptions, ft as TrackItemDraft, g as SemanticOpInput, gt as BgmPart, h as SemanticEditor, ht as videoDocumentMirrorSchema, i as JournalEntry, it as LANE_KINDS_IN_STACK_ORDER, j as validateVideoDocument, jt as VideoDraft, k as VideoDocumentValidationError, kt as VideoDocumentValidationIssue, l as MirrorVideoDocumentOptions, lt as laneTrackId, m as SemanticDocumentAdapter, mt as VideoDocumentMirrorSchema, n as videoDocumentSchema, nt as fromVideoDocument, o as PlainMemoryAdapterOptions, ot as SolvedVideoDocument, p as OpActor, pt as VideoDocumentDraft, q as VoiceDescriptor, r as readVideoDocumentFromDraft, rt as toVideoDocument, s as createPlainMemoryAdapter, st as ensureLaneTrack, t as partUnionSchema, tt as derivePositionFromAbs, u as createMirrorVideoDocument, ut as solveVideoDocument, v as TransactAudit, vt as CaptionPart, w as SchemaValidator, wt as Track, x as PlannedSemanticOpKind, xt as PartUnion, y as IMPLEMENTED_SEMANTIC_OP_KINDS, yt as DEFAULT_UNIT_TIME_MS, z as EntityRelationRows, zt as PartAggregation } from "./index-qAoWdqvp.js";
2
+ import { $ as SpeechHostMap, A as assertValidVideoDocument, At as VideoDocumentValidationIssueCode, B as EntityRow, Bt as SpeedShift, C as isImplementedSemanticOpKind, Ct as Timeline, D as PartIdFactory, Dt as VideoClipPart, E as ValidationError, Et as TrackItemTimePosition, F as ResolvedEntityTrack, Ft as speedOf, G as SequenceDuration, H as CaptionSegmentSelection, Ht as Track$1, I as resolveEntityTimelineLayout, It as Attachment, J as JsonObject, K as SequenceRange, L as projectEntityTimeline, Lt as CaptionPart$1, M as EntityTimelineTrackRole, Mt as VideoDraftContent, N as ResolvedEntityClipPlacement, Nt as VideoDraftPartUnion, O as generatePartId, Ot as VideoDocument, P as ResolvedEntityTimelineLayout, Pt as effectiveVideoClipDurationMs, Q as DerivedItemPosition, R as EntityTimelineProjectionError, Rt as CaptionStyle, S as SemanticOpKind, St as SpeechPart, T as SnapshotReadable, Tt as TrackItem, U as CaptionStyleFields, Ut as TrackItem$1, V as RelationRow, Vt as Timeline$1, W as ScriptTextSegment, X as EntityId, Y as JsonValue, Z as buildInitialVideoDocument, _ as SemanticOpName, _t as CaptionDisplayCue, a as PlainMemoryAdapter, at as LaneKind, b as ImplementedSemanticOpKind, bt as PartKind, c as MirrorVideoDocumentAdapter, ct as findLaneTrack, d as createMirrorVideoDocumentAdapter, dt as TrackDraft, et as buildSpeechHostMap, f as CommitOptions, ft as TrackItemDraft, g as SemanticOpInput, gt as BgmPart, h as SemanticEditor, ht as videoDocumentMirrorSchema, i as JournalEntry, it as LANE_KINDS_IN_STACK_ORDER, j as validateVideoDocument, jt as VideoDraft, k as VideoDocumentValidationError, kt as VideoDocumentValidationIssue, l as MirrorVideoDocumentOptions, lt as laneTrackId, m as SemanticDocumentAdapter, mt as VideoDocumentMirrorSchema, n as videoDocumentSchema, nt as fromVideoDocument, o as PlainMemoryAdapterOptions, ot as SolvedVideoDocument, p as OpActor, pt as VideoDocumentDraft, q as VoiceDescriptor, r as readVideoDocumentFromDraft, rt as toVideoDocument, s as createPlainMemoryAdapter, st as ensureLaneTrack, t as partUnionSchema, tt as derivePositionFromAbs, u as createMirrorVideoDocument, ut as solveVideoDocument, v as TransactAudit, vt as CaptionPart, w as SchemaValidator, wt as Track, x as PlannedSemanticOpKind, xt as PartUnion, y as IMPLEMENTED_SEMANTIC_OP_KINDS, yt as DEFAULT_UNIT_TIME_MS, z as EntityRelationRows, zt as PartAggregation } from "./index-BZtSciyB.js";
3
3
  import { LoroDoc, PeerID } from "loro-crdt";
4
4
  import { DocState } from "@mengine/sync";
5
5
  import { BaseDocStorage, Connection, DocDiff, DocPushReceipt, DocSnapshotRecord, DocStorage, DocStorageOptions, DocUpdate, DocUpdateRecord } from "@mengine/storage";
@@ -232,8 +232,8 @@ declare function selectAudioScriptSegment(script: EntityRow<'audio-script'>, sel
232
232
  //#region src/entity-editor/entity-graph-http-client.d.ts
233
233
  /** One authenticated revision of the authoritative Medeo Entity graph. */
234
234
  interface EntityGraphState {
235
- /** Current AudioScript content version attached to the project. */
236
- readonly audioScriptEntityId: string;
235
+ /** Current AudioScript attached to the project, or null until one is written. */
236
+ readonly audioScriptEntityId: string | null;
237
237
  readonly revision: number;
238
238
  readonly loroSnapshot: string;
239
239
  readonly rows: EntityRelationRows;
@@ -614,7 +614,7 @@ interface EditorFoundation {
614
614
  readonly timelineEntityId: string;
615
615
  readonly trackEntityIds: Readonly<Record<EditorTrackRole, string>>;
616
616
  /** Initial or current AudioScript content ID selected by the foundation. */
617
- readonly audioScriptEntityId: string;
617
+ readonly audioScriptEntityId: string | null;
618
618
  }
619
619
  /**
620
620
  * MEngine editor policy, not a cardinality restriction on the general-purpose DSL.
@@ -688,7 +688,7 @@ interface DocumentAudioScript {
688
688
  /** State exposing the current AudioScript content version attached to the project. */
689
689
  interface DocumentAudioScriptState {
690
690
  readonly rows: EntityRelationRows;
691
- /** Current attachment; initialized projects point to a real script, including an empty one. */
691
+ /** Current attachment, or null until a script is transcribed or written. */
692
692
  readonly audioScriptEntityId: string | null;
693
693
  }
694
694
  /** Read only the attached version and preserve every segment; never aggregate other scripts. */
@@ -817,8 +817,10 @@ declare class LoroEntityDocument {
817
817
  /**
818
818
  * Bind a saved snapshot without rewriting text operations or resolving
819
819
  * selection conflicts. The script names the bytes the same way everything
820
- * else does — an Asset entity plus a `from-asset` Relation — and keeps only
821
- * the fingerprint that tells a stale snapshot from a current one.
820
+ * else does — an Asset entity plus a Relation — and keeps only the
821
+ * fingerprint that tells a stale snapshot from a current one. The Relation is
822
+ * `to-asset`: these bytes are the script's own content written out, not a
823
+ * source it was made from.
822
824
  */
823
825
  bindAudioScriptAsset(entityId: string, assetId: string, expectedContentHash: string): Uint8Array;
824
826
  canUndo(): boolean;
@@ -1735,12 +1737,32 @@ declare function relativePositionForAbs(ranges: MainClipRange[], absMs: number):
1735
1737
  declare function audioScriptAssetContent(payload: JsonObject): JsonObject;
1736
1738
  declare function audioScriptAssetHash(payload: JsonObject): string;
1737
1739
  /**
1738
- * The Asset a script was written out to, read from the graph rather than the
1739
- * script's own row: like every other entity, a script names its bytes through
1740
- * a `from-asset` Relation and stores no locator itself.
1740
+ * The Asset a script was written out to. It is a snapshot the script owns, so
1741
+ * it is reached by `to-asset` — not `from-asset`, which would say the script
1742
+ * was produced from bytes it cannot change.
1741
1743
  */
1742
1744
  declare function audioScriptAssetOf(rows: EntityRelationRows, entityId: string): EntityRow | undefined;
1745
+ /**
1746
+ * The Asset a script was made from — a transcript it does not own. A script
1747
+ * that has one never writes a snapshot of its own: the bytes it would describe
1748
+ * are already named, and rewriting them would contradict their source.
1749
+ */
1750
+ declare function scriptSourceAssetOf(rows: EntityRelationRows, entityId: string): EntityRow | undefined;
1743
1751
  /** Internal fingerprint prevents a resource from silently describing an older text revision. */
1744
1752
  declare function audioScriptAssetFields(payload: JsonObject): JsonObject;
1753
+ /**
1754
+ * What a PhoneticScript hands to synthesis: the base AudioScript's text as the
1755
+ * variant pronounces it, plus the variant's own phoneme and prosody control.
1756
+ *
1757
+ * The variant's content is written by a model — deciding how words are said is
1758
+ * text work, not a mechanical copy — but the bytes a synthesizer reads have to
1759
+ * leave the entity graph to reach it, because synthesis does not handle
1760
+ * entities. Writing this resource down is that crossing, and it is why speech
1761
+ * can only come from a PhoneticScript.
1762
+ */
1763
+ declare function phoneticScriptAssetContent(rows: EntityRelationRows, entityId: string): JsonObject;
1764
+ declare function phoneticScriptAssetHash(rows: EntityRelationRows, entityId: string): string;
1765
+ /** The Asset a PhoneticScript was written out to, read from the graph. */
1766
+ declare function phoneticScriptAssetOf(rows: EntityRelationRows, entityId: string): EntityRow | undefined;
1745
1767
  //#endregion
1746
- export { type Aggregation, type AssembledCaptionContent, type AssembledPhoneticScriptContent, type Attachment, type AudioMediaAssetFact, type BgmPart, type CaptionContentInput, type CaptionDisplayCue, type CaptionPart, type CaptionSegmentSelection, type CaptionStyle, type ClipEntityId, type ClipPlacement, type CommitOptions, DEFAULT_UNIT_TIME_MS, type DeleteBgmInput, type DeleteClipInput, type DeleteClipTreeInput, type DeleteVoiceoverInput, type DerivedItemPosition, type DocStorageLike, type DocVersionMark, type DocumentAudioScript, type DocumentAudioScriptState, type EditorFoundation, EntityDocumentState, type EntityGraphCommitOptions, EntityGraphHttpClient, type EntityGraphState, EntityTimelineEditor, type EntityTimelineIdFactory, EntityTimelineProjectionError, type EntityTimelineTrackRole, type FieldChange, type FieldPath, IMPLEMENTED_SEMANTIC_OP_KINDS, type ImageMediaAssetFact, type ImplementedSemanticOpKind, type ImportedMediaAsset, type InsertCaptionClipInput, type InsertClipInput, type InsertMediaClipInput, type InsertMediaClipsInput, type InsertPlacedClipInput, type JournalEntry, LANE_KINDS_IN_STACK_ORDER, LORO_ENTITY_SCHEMA, type LaneKind, type LinearClipSpeed, LoroEntityDocument, LoroEntityDraft, type MainClipRange, type MakeEmptyPart, ManualSyncDoc, type ManualSyncDocOptions, MedeoHttpDocStorage, type MedeoHttpDocStorageOptions, type MediaAssetFact, type MediaClipInsertion, MemoryDocStorage, MengineAckFailedError, type MengineAuditEntry, type MengineAuditResponse, MengineDocSession, type MengineDocSessionOptions, type MengineDocSessionUpdateEvent, type MengineDocSyncState, type MengineDocumentVersion, type MengineEventStreamOptions, MengineHttpClient, type MengineHttpClientOptions, MengineHttpRequestError, MenginePushRejectedError, type MenginePushResponse, type MenginePushUpdateResponse, type MengineRejectedResponse, type MengineSnapshotResponse, type MengineSseUpdateEvent, type MengineSyncResponse, type MengineUndoState, type MengineUpdateMeta, MirrorVideoDocumentAdapter, type MirrorVideoDocumentOptions, type MoveClipInput, type MoveClipsToStartsInput, type MoveSequentialClipsInput, type MoveVoiceoverInput, type OpActor, type PartAggregation, type PartIdFactory, type PartKind, type PartUnion, type PatchCaptionStyleInput, PlainMemoryAdapter, type PlainMemoryAdapterOptions, type PlannedSemanticOpKind, type PullFailureReason, type PullResult, type PushOutcome, type PushOutcomeKind, type PushResult, type PushResultKind, type ReplaceClipContentInput, type ReplaceMediaClipInput, type ReplaceSequentialClipsInput, type ReplacementMediaClipInput, type ResolvedEntityClipPlacement, type ResolvedEntityTimelineLayout, type ResolvedEntityTrack, SchemaValidator, ScriptCompositionError, type SemanticDocumentAdapter, SemanticEditor, type SemanticOpInput, type SemanticOpKind, type SemanticOpName, type SequentialClipAnchor, type SetBgmInput, type SetCaptionVisibilityInput, type SetClipPlacementInput, type SetClipSpeedInput, type SetClipVolumeInput, type SnapshotReadable, type SolvedVideoDocument, type SpeechHostMap, type SpeechPart, type SpeedShift, TIMELINE_SKELETON_DURATION_MS, type Timeline, type TimelineDoc, type TimelineItem, type Track, type TrackDraft, type TrackItem, type TrackItemDraft, type TrackItemTimePosition, type TransactAudit, type TrimClipInput, type UpdateClipInput, type UpdateClipMarkerInput, ValidationError, type VideoClipPart, type VideoDocument, type VideoDocumentDraft, type VideoDocumentMirrorSchema, VideoDocumentValidationError, type VideoDocumentValidationIssue, type VideoDocumentValidationIssueCode, type VideoDraft, type CaptionPart$1 as VideoDraftCaptionPart, type VideoDraftContent, type VideoDraftPartUnion, type Timeline$1 as VideoDraftTimeline, type Track$1 as VideoDraftTrack, type TrackItem$1 as VideoDraftTrackItem, type VideoMediaAssetFact, type VisualMediaAssetFact, type VoiceoverCaptionFact, type VoiceoverMediaAssetFact, type VoiceoverTakeInput, type VoiceoverTakeResult, type WaitForServerAckOptions, applyEntityRows, applyFieldChanges, arrangeMainTrackSeamlessly, assembleCaptionContent, assembleEntityContent, assemblePhoneticScriptContent, assembleScriptText, assertCanonicalEditorResources, assertEntityProjectionPreservesLegacy, assertFieldChanges, assertMediaAssetWritePolicy, assertValidVideoDocument, audioScriptAssetContent, audioScriptAssetFields, audioScriptAssetHash, audioScriptAssetOf, base64ToBytes, buildInitialVideoDocument, buildSpeechHostMap, bytesToBase64, cascadeAfterVideoClipChanges, compileEntityRows, createEditSandbox, createMirrorVideoDocument, createMirrorVideoDocumentAdapter, createPlainMemoryAdapter, decodeDocVersionMark, derivePositionFromAbs, effectiveVideoClipDurationMs, encodeDocVersionMark, ensureEditorFoundation, ensureLaneTrack, fillMainTrackTimeGaps, findComposedAudioScript, findLaneTrack, fromVideoDocument, generatePartId, getAt, hostForAbsMs, importMediaAsset, isEmptyVideoClip, isImplementedSemanticOpKind, isMap, laneTrackId, mainTrackRanges, migrateLegacyTimelineToEntities, partDurationMs, partUnionSchema, prepareCaptionContent, projectEntityTimeline, readDocumentAudioScript, readEntityDocument, readMainTrackItems, readMengineEventStream, readPart, readPartDurationMs, readVideoDocumentFromDraft, reassignSpeechesToVideoClipsByTime, recalculateTimelineDuration, relativePositionForAbs, replayJournal, resolveAllSpeechOverlaps, resolveEntityTimelineLayout, resolveFieldPath, resolveSpeechOverlapByShiftingVideos, safeDurationMs, index_d_exports as schemas, selectAudioScriptSegment, snapshotToPlain, solveVideoDocument, speedOf, syncAggregatedClipsTimePosition, toVideoDocument, validateVideoDocument, videoDocumentMirrorSchema, videoDocumentSchema };
1768
+ export { type Aggregation, type AssembledCaptionContent, type AssembledPhoneticScriptContent, type Attachment, type AudioMediaAssetFact, type BgmPart, type CaptionContentInput, type CaptionDisplayCue, type CaptionPart, type CaptionSegmentSelection, type CaptionStyle, type ClipEntityId, type ClipPlacement, type CommitOptions, DEFAULT_UNIT_TIME_MS, type DeleteBgmInput, type DeleteClipInput, type DeleteClipTreeInput, type DeleteVoiceoverInput, type DerivedItemPosition, type DocStorageLike, type DocVersionMark, type DocumentAudioScript, type DocumentAudioScriptState, type EditorFoundation, EntityDocumentState, type EntityGraphCommitOptions, EntityGraphHttpClient, type EntityGraphState, EntityTimelineEditor, type EntityTimelineIdFactory, EntityTimelineProjectionError, type EntityTimelineTrackRole, type FieldChange, type FieldPath, IMPLEMENTED_SEMANTIC_OP_KINDS, type ImageMediaAssetFact, type ImplementedSemanticOpKind, type ImportedMediaAsset, type InsertCaptionClipInput, type InsertClipInput, type InsertMediaClipInput, type InsertMediaClipsInput, type InsertPlacedClipInput, type JournalEntry, LANE_KINDS_IN_STACK_ORDER, LORO_ENTITY_SCHEMA, type LaneKind, type LinearClipSpeed, LoroEntityDocument, LoroEntityDraft, type MainClipRange, type MakeEmptyPart, ManualSyncDoc, type ManualSyncDocOptions, MedeoHttpDocStorage, type MedeoHttpDocStorageOptions, type MediaAssetFact, type MediaClipInsertion, MemoryDocStorage, MengineAckFailedError, type MengineAuditEntry, type MengineAuditResponse, MengineDocSession, type MengineDocSessionOptions, type MengineDocSessionUpdateEvent, type MengineDocSyncState, type MengineDocumentVersion, type MengineEventStreamOptions, MengineHttpClient, type MengineHttpClientOptions, MengineHttpRequestError, MenginePushRejectedError, type MenginePushResponse, type MenginePushUpdateResponse, type MengineRejectedResponse, type MengineSnapshotResponse, type MengineSseUpdateEvent, type MengineSyncResponse, type MengineUndoState, type MengineUpdateMeta, MirrorVideoDocumentAdapter, type MirrorVideoDocumentOptions, type MoveClipInput, type MoveClipsToStartsInput, type MoveSequentialClipsInput, type MoveVoiceoverInput, type OpActor, type PartAggregation, type PartIdFactory, type PartKind, type PartUnion, type PatchCaptionStyleInput, PlainMemoryAdapter, type PlainMemoryAdapterOptions, type PlannedSemanticOpKind, type PullFailureReason, type PullResult, type PushOutcome, type PushOutcomeKind, type PushResult, type PushResultKind, type ReplaceClipContentInput, type ReplaceMediaClipInput, type ReplaceSequentialClipsInput, type ReplacementMediaClipInput, type ResolvedEntityClipPlacement, type ResolvedEntityTimelineLayout, type ResolvedEntityTrack, SchemaValidator, ScriptCompositionError, type SemanticDocumentAdapter, SemanticEditor, type SemanticOpInput, type SemanticOpKind, type SemanticOpName, type SequentialClipAnchor, type SetBgmInput, type SetCaptionVisibilityInput, type SetClipPlacementInput, type SetClipSpeedInput, type SetClipVolumeInput, type SnapshotReadable, type SolvedVideoDocument, type SpeechHostMap, type SpeechPart, type SpeedShift, TIMELINE_SKELETON_DURATION_MS, type Timeline, type TimelineDoc, type TimelineItem, type Track, type TrackDraft, type TrackItem, type TrackItemDraft, type TrackItemTimePosition, type TransactAudit, type TrimClipInput, type UpdateClipInput, type UpdateClipMarkerInput, ValidationError, type VideoClipPart, type VideoDocument, type VideoDocumentDraft, type VideoDocumentMirrorSchema, VideoDocumentValidationError, type VideoDocumentValidationIssue, type VideoDocumentValidationIssueCode, type VideoDraft, type CaptionPart$1 as VideoDraftCaptionPart, type VideoDraftContent, type VideoDraftPartUnion, type Timeline$1 as VideoDraftTimeline, type Track$1 as VideoDraftTrack, type TrackItem$1 as VideoDraftTrackItem, type VideoMediaAssetFact, type VisualMediaAssetFact, type VoiceoverCaptionFact, type VoiceoverMediaAssetFact, type VoiceoverTakeInput, type VoiceoverTakeResult, type WaitForServerAckOptions, applyEntityRows, applyFieldChanges, arrangeMainTrackSeamlessly, assembleCaptionContent, assembleEntityContent, assemblePhoneticScriptContent, assembleScriptText, assertCanonicalEditorResources, assertEntityProjectionPreservesLegacy, assertFieldChanges, assertMediaAssetWritePolicy, assertValidVideoDocument, audioScriptAssetContent, audioScriptAssetFields, audioScriptAssetHash, audioScriptAssetOf, base64ToBytes, buildInitialVideoDocument, buildSpeechHostMap, bytesToBase64, cascadeAfterVideoClipChanges, compileEntityRows, createEditSandbox, createMirrorVideoDocument, createMirrorVideoDocumentAdapter, createPlainMemoryAdapter, decodeDocVersionMark, derivePositionFromAbs, effectiveVideoClipDurationMs, encodeDocVersionMark, ensureEditorFoundation, ensureLaneTrack, fillMainTrackTimeGaps, findComposedAudioScript, findLaneTrack, fromVideoDocument, generatePartId, getAt, hostForAbsMs, importMediaAsset, isEmptyVideoClip, isImplementedSemanticOpKind, isMap, laneTrackId, mainTrackRanges, migrateLegacyTimelineToEntities, partDurationMs, partUnionSchema, phoneticScriptAssetContent, phoneticScriptAssetHash, phoneticScriptAssetOf, prepareCaptionContent, projectEntityTimeline, readDocumentAudioScript, readEntityDocument, readMainTrackItems, readMengineEventStream, readPart, readPartDurationMs, readVideoDocumentFromDraft, reassignSpeechesToVideoClipsByTime, recalculateTimelineDuration, relativePositionForAbs, replayJournal, resolveAllSpeechOverlaps, resolveEntityTimelineLayout, resolveFieldPath, resolveSpeechOverlapByShiftingVideos, safeDurationMs, index_d_exports as schemas, scriptSourceAssetOf, selectAudioScriptSegment, snapshotToPlain, solveVideoDocument, speedOf, syncAggregatedClipsTimePosition, toVideoDocument, validateVideoDocument, videoDocumentMirrorSchema, videoDocumentSchema };
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { $ as findLaneTrack, A as assemblePhoneticScriptContent, B as isMediaAssetVariantKind, C as EntityProjectionGraph, D as ScriptCompositionError, E as decodeEntityRelationRows, F as variantBaseEntityIds, G as toVideoDocument, H as buildSpeechHostMap, I as isJsonObject, J as validateVideoDocument, K as VideoDocumentValidationError, L as createEntityId, M as findComposedAudioScript, N as selectAudioScriptSegment, O as assembleCaptionContent, P as updateEntityFields, Q as ensureLaneTrack, R as createRelationId, S as projectEntityTimeline, St as bytesToBase64, T as EntityTimelineProjectionError, U as derivePositionFromAbs, V as buildInitialVideoDocument, W as fromVideoDocument, X as videoDocumentSchema, Y as partUnionSchema, Z as LANE_KINDS_IN_STACK_ORDER, _ as audioScriptAssetOf, _t as speedOf, a as createMirrorVideoDocument, at as fillMainTrackTimeGaps, b as assertFieldChanges, bt as videoDocumentMirrorSchema, c as DocumentMutationGuard, ct as resolveAllSpeechOverlaps, d as LoroEntityDraft, dt as TIMELINE_SKELETON_DURATION_MS, et as hasResolvedPlacement, f as readEntityDocument, ft as isEmptyVideoClip, g as audioScriptAssetHash, gt as effectiveVideoClipDurationMs, h as audioScriptAssetFields, ht as DEFAULT_UNIT_TIME_MS, i as MirrorVideoDocumentAdapter, it as arrangeMainTrackSeamlessly, j as assembleScriptText, k as assembleEntityContent, l as LORO_ENTITY_SCHEMA, lt as resolveSpeechOverlapByShiftingVideos, m as audioScriptAssetContent, mt as safeDurationMs, n as createPlainMemoryAdapter, nt as solveVideoDocument, o as createMirrorVideoDocumentAdapter, ot as reassignSpeechesToVideoClipsByTime, p as entityOrderGroups, pt as partDurationMs, q as assertValidVideoDocument, r as generatePartId, rt as cascadeAfterVideoClipChanges, s as readVideoDocumentFromDraft, st as recalculateTimelineDuration, t as PlainMemoryAdapter, tt as laneTrackId, u as LoroEntityDocument, ut as syncAggregatedClipsTimePosition, v as equalJson, vt as partUnionToDraft, w as resolveEntityTimelineLayout, x as resolveFieldPath, xt as base64ToBytes, y as applyFieldChanges, yt as recordEntries, z as hasSequence } from "./document-D631gqZV.js";
1
+ import { $ as partUnionSchema, A as decodeEntityRelationRows, B as isJsonObject, C as applyFieldChanges, Ct as recordEntries, D as EntityProjectionGraph, E as projectEntityTimeline, Et as bytesToBase64, F as assembleScriptText, G as buildInitialVideoDocument, H as createRelationId, I as findComposedAudioScript, J as fromVideoDocument, K as buildSpeechHostMap, L as selectAudioScriptSegment, M as assembleCaptionContent, N as assembleEntityContent, O as resolveEntityTimelineLayout, P as assemblePhoneticScriptContent, Q as validateVideoDocument, R as updateEntityFields, S as equalJson, St as partUnionToDraft, T as resolveFieldPath, Tt as base64ToBytes, U as hasSequence, V as createEntityId, W as isMediaAssetVariantKind, X as VideoDocumentValidationError, Y as toVideoDocument, Z as assertValidVideoDocument, _ as audioScriptAssetOf, _t as partDurationMs, a as createMirrorVideoDocument, at as laneTrackId, b as phoneticScriptAssetOf, bt as effectiveVideoClipDurationMs, c as DocumentMutationGuard, ct as arrangeMainTrackSeamlessly, d as LoroEntityDraft, dt as recalculateTimelineDuration, et as videoDocumentSchema, f as readEntityDocument, ft as resolveAllSpeechOverlaps, g as audioScriptAssetHash, gt as isEmptyVideoClip, h as audioScriptAssetFields, ht as TIMELINE_SKELETON_DURATION_MS, i as MirrorVideoDocumentAdapter, it as hasResolvedPlacement, j as ScriptCompositionError, k as EntityTimelineProjectionError, l as LORO_ENTITY_SCHEMA, lt as fillMainTrackTimeGaps, m as audioScriptAssetContent, mt as syncAggregatedClipsTimePosition, n as createPlainMemoryAdapter, nt as ensureLaneTrack, o as createMirrorVideoDocumentAdapter, ot as solveVideoDocument, p as entityOrderGroups, pt as resolveSpeechOverlapByShiftingVideos, q as derivePositionFromAbs, r as generatePartId, rt as findLaneTrack, s as readVideoDocumentFromDraft, st as cascadeAfterVideoClipChanges, t as PlainMemoryAdapter, tt as LANE_KINDS_IN_STACK_ORDER, u as LoroEntityDocument, ut as reassignSpeechesToVideoClipsByTime, v as phoneticScriptAssetContent, vt as safeDurationMs, w as assertFieldChanges, wt as videoDocumentMirrorSchema, x as scriptSourceAssetOf, xt as speedOf, y as phoneticScriptAssetHash, yt as DEFAULT_UNIT_TIME_MS, z as variantBaseEntityIds } from "./document-CAZ_A9R8.js";
2
2
  import { addSpeechesInputSchema, addVideoClipsInputSchema, adjustBgmVolumeInputSchema, adjustSpeechVolumeInputSchema, adjustVideoClipDurationInputSchema, adjustVideoClipVolumeInputSchema, changeSpeechScriptInputSchema, changeSpeechVoiceInputSchema, deleteBgmInputSchema, deleteSpeechesInputSchema, deleteVideoClipsInputSchema, moveSpeechesInputSchema, moveVideoClipsByAnchorInputSchema, moveVideoClipsInputSchema, replaceVideoClipContentInputSchema, replaceVideoClipSequenceInputSchema, setBgmInputSchema, setCaptionStyleInputSchema, setCaptionVisibilityInputSchema, setVideoClipSpeedShiftInputSchema, t as schemas_exports } from "./schemas.js";
3
3
  import { LoroDoc, UndoManager, VersionVector } from "loro-crdt";
4
4
  import { ClientServerSynchronizer, DocManager } from "@mengine/sync";
@@ -221,7 +221,8 @@ function compileEntityRows(snapshot, rows, validate) {
221
221
  }
222
222
  /** Compile an edit on an existing peer, retaining its native local undo history. */
223
223
  function applyEntityRows(editor, rows) {
224
- const before = editor.snapshot().rows;
224
+ const baseline = editor.snapshot();
225
+ const before = baseline.rows;
225
226
  const oldEntities = new Map(before.entities.map((row) => [row.entityId, row]));
226
227
  const newEntities = new Map(rows.entities.map((row) => [row.entityId, row]));
227
228
  const oldRelations = new Map(before.relations.map((row) => [row.relationId, row]));
@@ -237,10 +238,16 @@ function applyEntityRows(editor, rows) {
237
238
  if (!equalJson(row.metadata, next.metadata) || !equalJson(row.trace, next.trace)) draft.patchRelation(row.relationId, next.metadata, next.trace);
238
239
  }
239
240
  }
241
+ let attached = baseline.project.audioScriptEntityId !== void 0;
240
242
  for (const row of rows.entities) {
241
243
  const previous = oldEntities.get(row.entityId);
242
- if (!previous) draft.create(row);
243
- else {
244
+ if (!previous) {
245
+ draft.create(row);
246
+ if (!attached && row.entityKind === "audio-script") {
247
+ draft.attach("audioScriptEntityId", String(row.entityId));
248
+ attached = true;
249
+ }
250
+ } else {
244
251
  if (previous.entityKind !== row.entityKind) throw new Error("Entity kind cannot change");
245
252
  if (!equalJson(previous.payload, row.payload)) draft.replaceOwned(row.entityId, row.payload);
246
253
  }
@@ -350,23 +357,14 @@ function memotaLocator(value) {
350
357
  * explicit project attachment, multiple candidates are ambiguous. Existing
351
358
  * content IDs are reused here; Loro editing advances their immutable versions.
352
359
  */
353
- function ensureDocumentAudioScript(entities, idFactory, selectedEntityId) {
360
+ function ensureDocumentAudioScript(entities, selectedEntityId) {
354
361
  if (selectedEntityId != null) {
355
362
  if (!entities.some((row) => row.entityKind === "audio-script" && row.entityId === selectedEntityId)) throw new EntityTimelineProjectionError(`Selected AudioScript ${selectedEntityId} does not exist`);
356
363
  return selectedEntityId;
357
364
  }
358
365
  const scripts = entities.filter((row) => row.entityKind === "audio-script");
359
366
  if (scripts.length > 1) throw new EntityTimelineProjectionError("Select an AudioScript for the editor panel when multiple scripts exist");
360
- const existing = scripts[0];
361
- if (existing !== void 0) return existing.entityId;
362
- const id = createEntityId(idFactory("entity"));
363
- if (entities.some((row) => row.entityId === id)) throw new Error(`Duplicate entity id ${id}`);
364
- entities.push({
365
- entityId: id,
366
- entityKind: "audio-script",
367
- payload: { segments: [] }
368
- });
369
- return id;
367
+ return scripts[0]?.entityId ?? null;
370
368
  }
371
369
  /** Add only missing editor structure; existing identities and owned settings are never replaced. */
372
370
  function ensureEditorFoundation(initial, idFactory = (prefix) => `${prefix}_${globalThis.crypto.randomUUID()}`, timelinePayload = {}, selectedAudioScriptEntityId) {
@@ -420,7 +418,7 @@ function ensureEditorFoundation(initial, idFactory = (prefix) => `${prefix}_${gl
420
418
  }
421
419
  trackEntityIds[role] = track.entityId;
422
420
  }
423
- const audioScriptEntityId = ensureDocumentAudioScript(entities, idFactory, selectedAudioScriptEntityId);
421
+ const audioScriptEntityId = ensureDocumentAudioScript(entities, selectedAudioScriptEntityId);
424
422
  return {
425
423
  rows: {
426
424
  entities,
@@ -488,15 +486,16 @@ function parseWireState(value, expectedDocId) {
488
486
  if (value.doc_id !== expectedDocId) throw new Error(`Entity-state response doc_id mismatch: expected "${expectedDocId}"`);
489
487
  const rows = parseWireRows(value.rows);
490
488
  decodeEntityRelationRows(rows, numericMarkerValidation$1);
491
- if (typeof value.audio_script_entity_id !== "string") throw new Error("Document AudioScript is not initialized");
489
+ const attached = value.audio_script_entity_id;
490
+ if (attached !== null && typeof attached !== "string") throw new Error("Invalid document AudioScript identity");
492
491
  if (typeof value.loro_snapshot !== "string") throw new Error("Missing causal Loro snapshot");
493
492
  const state = {
494
493
  revision: value.revision,
495
494
  loroSnapshot: value.loro_snapshot,
496
495
  rows,
497
- audioScriptEntityId: value.audio_script_entity_id
496
+ audioScriptEntityId: attached
498
497
  };
499
- readDocumentAudioScript(state);
498
+ if (attached !== null) readDocumentAudioScript(state);
500
499
  return state;
501
500
  }
502
501
  function parseWireRows(value) {
@@ -2035,7 +2034,15 @@ function migrateLegacyTimelineToEntities(legacy, assetFacts, initial = {
2035
2034
  const normalizedMainRanges = overlapNormalizedMainRanges(legacy);
2036
2035
  let entities = structuredClone([...initial.entities]);
2037
2036
  let relations = structuredClone([...initial.relations]);
2038
- const documentAudioScriptEntityId = ensureDocumentAudioScript(entities, idFactory);
2037
+ const documentAudioScriptEntityId = ensureDocumentAudioScript(entities) ?? (() => {
2038
+ const id = createEntityId(idFactory("entity"));
2039
+ entities.push({
2040
+ entityId: id,
2041
+ entityKind: "audio-script",
2042
+ payload: { segments: [] }
2043
+ });
2044
+ return String(id);
2045
+ })();
2039
2046
  const addEntity = (kind, payload, existingId) => {
2040
2047
  const entityId = createEntityId(existingId ?? idFactory("entity"));
2041
2048
  if (entities.some((row) => row.entityId === entityId)) fail(`Migration entity identity collision: ${entityId}`);
@@ -5138,4 +5145,4 @@ function serverCovers(serverVV, target) {
5138
5145
  return covers(server, target);
5139
5146
  }
5140
5147
  //#endregion
5141
- export { DEFAULT_UNIT_TIME_MS, EntityGraphHttpClient, EntityTimelineEditor, EntityTimelineProjectionError, IMPLEMENTED_SEMANTIC_OP_KINDS, LANE_KINDS_IN_STACK_ORDER, LORO_ENTITY_SCHEMA, LoroEntityDocument, LoroEntityDraft, ManualSyncDoc, MedeoHttpDocStorage, MemoryDocStorage, MengineAckFailedError, MengineDocSession, MengineHttpClient, MengineHttpRequestError, MenginePushRejectedError, MirrorVideoDocumentAdapter, PlainMemoryAdapter, SchemaValidator, ScriptCompositionError, SemanticEditor, TIMELINE_SKELETON_DURATION_MS, ValidationError, VideoDocumentValidationError, applyEntityRows, applyFieldChanges, arrangeMainTrackSeamlessly, assembleCaptionContent, assembleEntityContent, assemblePhoneticScriptContent, assembleScriptText, assertCanonicalEditorResources, assertEntityProjectionPreservesLegacy, assertFieldChanges, assertMediaAssetWritePolicy, assertValidVideoDocument, audioScriptAssetContent, audioScriptAssetFields, audioScriptAssetHash, audioScriptAssetOf, base64ToBytes, buildInitialVideoDocument, buildSpeechHostMap, bytesToBase64, cascadeAfterVideoClipChanges, compileEntityRows, createEditSandbox, createMirrorVideoDocument, createMirrorVideoDocumentAdapter, createPlainMemoryAdapter, decodeDocVersionMark, derivePositionFromAbs, effectiveVideoClipDurationMs, encodeDocVersionMark, ensureEditorFoundation, ensureLaneTrack, fillMainTrackTimeGaps, findComposedAudioScript, findLaneTrack, fromVideoDocument, generatePartId, getAt, hostForAbsMs, importMediaAsset, isEmptyVideoClip, isImplementedSemanticOpKind, isMap, laneTrackId, mainTrackRanges, migrateLegacyTimelineToEntities, partDurationMs, partUnionSchema, prepareCaptionContent, projectEntityTimeline, readDocumentAudioScript, readEntityDocument, readMainTrackItems, readMengineEventStream, readPart, readPartDurationMs, readVideoDocumentFromDraft, reassignSpeechesToVideoClipsByTime, recalculateTimelineDuration, relativePositionForAbs, replayJournal, resolveAllSpeechOverlaps, resolveEntityTimelineLayout, resolveFieldPath, resolveSpeechOverlapByShiftingVideos, safeDurationMs, schemas_exports as schemas, selectAudioScriptSegment, snapshotToPlain, solveVideoDocument, speedOf, syncAggregatedClipsTimePosition, toVideoDocument, validateVideoDocument, videoDocumentMirrorSchema, videoDocumentSchema };
5148
+ export { DEFAULT_UNIT_TIME_MS, EntityGraphHttpClient, EntityTimelineEditor, EntityTimelineProjectionError, IMPLEMENTED_SEMANTIC_OP_KINDS, LANE_KINDS_IN_STACK_ORDER, LORO_ENTITY_SCHEMA, LoroEntityDocument, LoroEntityDraft, ManualSyncDoc, MedeoHttpDocStorage, MemoryDocStorage, MengineAckFailedError, MengineDocSession, MengineHttpClient, MengineHttpRequestError, MenginePushRejectedError, MirrorVideoDocumentAdapter, PlainMemoryAdapter, SchemaValidator, ScriptCompositionError, SemanticEditor, TIMELINE_SKELETON_DURATION_MS, ValidationError, VideoDocumentValidationError, applyEntityRows, applyFieldChanges, arrangeMainTrackSeamlessly, assembleCaptionContent, assembleEntityContent, assemblePhoneticScriptContent, assembleScriptText, assertCanonicalEditorResources, assertEntityProjectionPreservesLegacy, assertFieldChanges, assertMediaAssetWritePolicy, assertValidVideoDocument, audioScriptAssetContent, audioScriptAssetFields, audioScriptAssetHash, audioScriptAssetOf, base64ToBytes, buildInitialVideoDocument, buildSpeechHostMap, bytesToBase64, cascadeAfterVideoClipChanges, compileEntityRows, createEditSandbox, createMirrorVideoDocument, createMirrorVideoDocumentAdapter, createPlainMemoryAdapter, decodeDocVersionMark, derivePositionFromAbs, effectiveVideoClipDurationMs, encodeDocVersionMark, ensureEditorFoundation, ensureLaneTrack, fillMainTrackTimeGaps, findComposedAudioScript, findLaneTrack, fromVideoDocument, generatePartId, getAt, hostForAbsMs, importMediaAsset, isEmptyVideoClip, isImplementedSemanticOpKind, isMap, laneTrackId, mainTrackRanges, migrateLegacyTimelineToEntities, partDurationMs, partUnionSchema, phoneticScriptAssetContent, phoneticScriptAssetHash, phoneticScriptAssetOf, prepareCaptionContent, projectEntityTimeline, readDocumentAudioScript, readEntityDocument, readMainTrackItems, readMengineEventStream, readPart, readPartDurationMs, readVideoDocumentFromDraft, reassignSpeechesToVideoClipsByTime, recalculateTimelineDuration, relativePositionForAbs, replayJournal, resolveAllSpeechOverlaps, resolveEntityTimelineLayout, resolveFieldPath, resolveSpeechOverlapByShiftingVideos, safeDurationMs, schemas_exports as schemas, scriptSourceAssetOf, selectAudioScriptSegment, snapshotToPlain, solveVideoDocument, speedOf, syncAggregatedClipsTimePosition, toVideoDocument, validateVideoDocument, videoDocumentMirrorSchema, videoDocumentSchema };
package/dist/testing.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { c as MirrorVideoDocumentAdapter, jt as VideoDraft } from "./index-qAoWdqvp.js";
1
+ import { c as MirrorVideoDocumentAdapter, jt as VideoDraft } from "./index-BZtSciyB.js";
2
2
 
3
3
  //#region src/testing/in-memory-mengine-server.d.ts
4
4
  /**
package/dist/testing.js CHANGED
@@ -1,4 +1,4 @@
1
- import { St as bytesToBase64, o as createMirrorVideoDocumentAdapter, xt as base64ToBytes } from "./document-D631gqZV.js";
1
+ import { Et as bytesToBase64, Tt as base64ToBytes, o as createMirrorVideoDocumentAdapter } from "./document-CAZ_A9R8.js";
2
2
  import { t as classifyUpdate } from "./loro-relay-doc-cJSY-uau.js";
3
3
  import { LoroDoc, VersionVector, encodeFrontiers } from "loro-crdt";
4
4
  //#region src/testing/in-memory-mengine-server.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mengine/medeo-client",
3
- "version": "2.0.1-alpha.11",
3
+ "version": "2.0.1-alpha.13",
4
4
  "license": "UNLICENSED",
5
5
  "repository": {
6
6
  "type": "git",
@@ -28,9 +28,9 @@
28
28
  "immer": "^10.2.0",
29
29
  "loro-mirror": "^2.3.3",
30
30
  "zod": "^4.4.3",
31
- "@mengine/storage": "2.0.1-alpha.11",
32
- "@mengine/sync": "2.0.1-alpha.11",
33
- "@mengine/utils": "2.0.1-alpha.11"
31
+ "@mengine/utils": "2.0.1-alpha.13",
32
+ "@mengine/storage": "2.0.1-alpha.13",
33
+ "@mengine/sync": "2.0.1-alpha.13"
34
34
  },
35
35
  "devDependencies": {
36
36
  "@types/node": "^25.9.1",