@mengine/medeo-client 1.3.1-alpha.9 → 1.4.1-alpha.0

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.
@@ -1682,10 +1682,10 @@ declare const videoDocumentSchema: z.ZodObject<{
1682
1682
  tracks: z.ZodOptional<z.ZodArray<z.ZodObject<{
1683
1683
  id: z.ZodOptional<z.ZodString>;
1684
1684
  parts_kind: z.ZodOptional<z.ZodEnum<{
1685
+ video_clip: "video_clip";
1685
1686
  speech: "speech";
1686
1687
  caption: "caption";
1687
1688
  bgm: "bgm";
1688
- video_clip: "video_clip";
1689
1689
  }>>;
1690
1690
  is_hidden: z.ZodOptional<z.ZodBoolean>;
1691
1691
  items: z.ZodOptional<z.ZodArray<z.ZodObject<{
@@ -1767,4 +1767,4 @@ declare const videoDocumentSchema: z.ZodObject<{
1767
1767
  }, z.core.$loose>]>>>;
1768
1768
  }, z.core.$loose>;
1769
1769
  //#endregion
1770
- export { VoiceDescriptor as $, generatePartId as A, effectiveVideoClipDurationMs as At, ResolvedEntityClipPlacement as B, PlannedSemanticOpKind as C, VideoClipPart as Ct, SnapshotReadable as D, VideoDocumentValidationIssueCode as Dt, SchemaValidator as E, VideoDocumentValidationIssue as Et, videoDocumentMirrorSchema as F, PartAggregation as Ft, EntityTimelineProjectionError as G, ResolvedEntityTrack as H, VideoDocumentValidationError as I, SpeedShift as It, CaptionSegmentSelection as J, EntityRelationRows as K, assertValidVideoDocument as L, Timeline$1 as Lt, TrackItemDraft as M, Attachment as Mt, VideoDocumentDraft as N, CaptionPart$1 as Nt, ValidationError as O, VideoDraft as Ot, VideoDocumentMirrorSchema as P, CaptionStyle as Pt, SequenceRange as Q, validateVideoDocument as R, Track$1 as Rt, ImplementedSemanticOpKind as S, VIDEO_DOCUMENT_SCHEMA_VERSION as St, isImplementedSemanticOpKind as T, VideoDocumentSchemaVersion as Tt, resolveEntityTimelineLayout as U, ResolvedEntityTimelineLayout as V, projectEntityTimeline as W, ScriptTextSegment as X, CaptionStyleFields as Y, SequenceDuration as Z, SemanticEditor as _, SpeechPart as _t, PlainMemoryAdapter as a, DerivedItemPosition as at, TransactAudit as b, TrackItem as bt, MirrorVideoDocumentAdapter as c, derivePositionFromAbs as ct, createMirrorVideoDocument as d, BgmPart as dt, JsonObject as et, createMirrorVideoDocumentAdapter as f, CaptionPart as ft, SemanticDocumentAdapter as g, PartUnion as gt, OpActor as h, PartKind as ht, JournalEntry as i, buildInitialVideoDocument as it, TrackDraft as j, speedOf as jt, PartIdFactory as k, VideoDraftPartUnion as kt, MirrorVideoDocumentOptions as l, fromVideoDocument as lt, CommitOptions as m, ENTITY_TIMELINE_PROJECTION_SCHEMA_VERSION as mt, videoDocumentSchema as n, EntityId as nt, PlainMemoryAdapterOptions as o, SpeechHostMap as ot, writeVideoDocumentToDraft as p, DEFAULT_UNIT_TIME_MS as pt, EntityRow as q, readVideoDocumentFromDraft as r, InitialDocumentFacts as rt, createPlainMemoryAdapter as s, buildSpeechHostMap as st, partUnionSchema as t, JsonValue as tt, applyEntityTimelineProjection as u, toVideoDocument as ut, SemanticOpInput as v, Timeline as vt, SemanticOpKind as w, VideoDocument as wt, IMPLEMENTED_SEMANTIC_OP_KINDS as x, TrackItemTimePosition as xt, SemanticOpName as y, Track as yt, EntityTimelineTrackRole as z, TrackItem$1 as zt };
1770
+ export { SequenceRange as $, generatePartId as A, VideoDraftPartUnion as At, ResolvedEntityClipPlacement as B, TrackItem$1 as Bt, PlannedSemanticOpKind as C, VIDEO_DOCUMENT_SCHEMA_VERSION as Ct, SnapshotReadable as D, VideoDocumentValidationIssue as Dt, SchemaValidator as E, VideoDocumentSchemaVersion as Et, videoDocumentMirrorSchema as F, CaptionStyle as Ft, EntityTimelineProjectionError as G, ResolvedEntityTrack as H, VideoDocumentValidationError as I, PartAggregation as It, RelationRow as J, EntityRelationRows as K, assertValidVideoDocument as L, SpeedShift as Lt, TrackItemDraft as M, speedOf as Mt, VideoDocumentDraft as N, Attachment as Nt, ValidationError as O, VideoDocumentValidationIssueCode as Ot, VideoDocumentMirrorSchema as P, CaptionPart$1 as Pt, SequenceDuration as Q, validateVideoDocument as R, Timeline$1 as Rt, ImplementedSemanticOpKind as S, TrackItemTimePosition as St, isImplementedSemanticOpKind as T, VideoDocument as Tt, resolveEntityTimelineLayout as U, ResolvedEntityTimelineLayout as V, projectEntityTimeline as W, CaptionStyleFields as X, CaptionSegmentSelection as Y, ScriptTextSegment as Z, SemanticEditor as _, PartUnion as _t, PlainMemoryAdapter as a, buildInitialVideoDocument as at, TransactAudit as b, Track as bt, MirrorVideoDocumentAdapter as c, buildSpeechHostMap as ct, createMirrorVideoDocument as d, toVideoDocument as dt, VoiceDescriptor as et, createMirrorVideoDocumentAdapter as f, BgmPart as ft, SemanticDocumentAdapter as g, PartKind as gt, OpActor as h, ENTITY_TIMELINE_PROJECTION_SCHEMA_VERSION as ht, JournalEntry as i, InitialDocumentFacts as it, TrackDraft as j, effectiveVideoClipDurationMs as jt, PartIdFactory as k, VideoDraft as kt, MirrorVideoDocumentOptions as l, derivePositionFromAbs as lt, CommitOptions as m, DEFAULT_UNIT_TIME_MS as mt, videoDocumentSchema as n, JsonValue as nt, PlainMemoryAdapterOptions as o, DerivedItemPosition as ot, writeVideoDocumentToDraft as p, CaptionPart as pt, EntityRow as q, readVideoDocumentFromDraft as r, EntityId as rt, createPlainMemoryAdapter as s, SpeechHostMap as st, partUnionSchema as t, JsonObject as tt, applyEntityTimelineProjection as u, fromVideoDocument as ut, SemanticOpInput as v, SpeechPart as vt, SemanticOpKind as w, VideoClipPart as wt, IMPLEMENTED_SEMANTIC_OP_KINDS as x, TrackItem as xt, SemanticOpName as y, Timeline as yt, EntityTimelineTrackRole as z, Track$1 as zt };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { t as index_d_exports } from "./index-CMa6ZCtX.js";
2
- import { $ as VoiceDescriptor, A as generatePartId, At as effectiveVideoClipDurationMs, B as ResolvedEntityClipPlacement, C as PlannedSemanticOpKind, Ct as VideoClipPart, D as SnapshotReadable, Dt as VideoDocumentValidationIssueCode, E as SchemaValidator, Et as VideoDocumentValidationIssue, F as videoDocumentMirrorSchema, Ft as PartAggregation, G as EntityTimelineProjectionError, H as ResolvedEntityTrack, I as VideoDocumentValidationError, It as SpeedShift, J as CaptionSegmentSelection, K as EntityRelationRows, L as assertValidVideoDocument, Lt as Timeline$1, M as TrackItemDraft, Mt as Attachment, N as VideoDocumentDraft, Nt as CaptionPart$1, O as ValidationError, Ot as VideoDraft, P as VideoDocumentMirrorSchema, Pt as CaptionStyle, Q as SequenceRange, R as validateVideoDocument, Rt as Track$1, S as ImplementedSemanticOpKind, St as VIDEO_DOCUMENT_SCHEMA_VERSION, T as isImplementedSemanticOpKind, Tt as VideoDocumentSchemaVersion, U as resolveEntityTimelineLayout, V as ResolvedEntityTimelineLayout, W as projectEntityTimeline, X as ScriptTextSegment, Y as CaptionStyleFields, Z as SequenceDuration, _ as SemanticEditor, _t as SpeechPart, a as PlainMemoryAdapter, at as DerivedItemPosition, b as TransactAudit, bt as TrackItem, c as MirrorVideoDocumentAdapter, ct as derivePositionFromAbs, d as createMirrorVideoDocument, dt as BgmPart, et as JsonObject, f as createMirrorVideoDocumentAdapter, ft as CaptionPart, g as SemanticDocumentAdapter, gt as PartUnion, h as OpActor, ht as PartKind, i as JournalEntry, it as buildInitialVideoDocument, j as TrackDraft, jt as speedOf, k as PartIdFactory, kt as VideoDraftPartUnion, l as MirrorVideoDocumentOptions, lt as fromVideoDocument, m as CommitOptions, mt as ENTITY_TIMELINE_PROJECTION_SCHEMA_VERSION, n as videoDocumentSchema, nt as EntityId, o as PlainMemoryAdapterOptions, ot as SpeechHostMap, p as writeVideoDocumentToDraft, pt as DEFAULT_UNIT_TIME_MS, q as EntityRow, r as readVideoDocumentFromDraft, rt as InitialDocumentFacts, s as createPlainMemoryAdapter, st as buildSpeechHostMap, t as partUnionSchema, tt as JsonValue, u as applyEntityTimelineProjection, ut as toVideoDocument, v as SemanticOpInput, vt as Timeline, w as SemanticOpKind, wt as VideoDocument, x as IMPLEMENTED_SEMANTIC_OP_KINDS, xt as TrackItemTimePosition, y as SemanticOpName, yt as Track, z as EntityTimelineTrackRole, zt as TrackItem$1 } from "./index-BUkDsU7c.js";
3
- import { PeerID } from "loro-crdt";
2
+ import { $ as SequenceRange, A as generatePartId, At as VideoDraftPartUnion, B as ResolvedEntityClipPlacement, Bt as TrackItem$1, C as PlannedSemanticOpKind, Ct as VIDEO_DOCUMENT_SCHEMA_VERSION, D as SnapshotReadable, Dt as VideoDocumentValidationIssue, E as SchemaValidator, Et as VideoDocumentSchemaVersion, F as videoDocumentMirrorSchema, Ft as CaptionStyle, G as EntityTimelineProjectionError, H as ResolvedEntityTrack, I as VideoDocumentValidationError, It as PartAggregation, J as RelationRow, K as EntityRelationRows, L as assertValidVideoDocument, Lt as SpeedShift, M as TrackItemDraft, Mt as speedOf, N as VideoDocumentDraft, Nt as Attachment, O as ValidationError, Ot as VideoDocumentValidationIssueCode, P as VideoDocumentMirrorSchema, Pt as CaptionPart$1, Q as SequenceDuration, R as validateVideoDocument, Rt as Timeline$1, S as ImplementedSemanticOpKind, St as TrackItemTimePosition, T as isImplementedSemanticOpKind, Tt as VideoDocument, U as resolveEntityTimelineLayout, V as ResolvedEntityTimelineLayout, W as projectEntityTimeline, X as CaptionStyleFields, Y as CaptionSegmentSelection, Z as ScriptTextSegment, _ as SemanticEditor, _t as PartUnion, a as PlainMemoryAdapter, at as buildInitialVideoDocument, b as TransactAudit, bt as Track, c as MirrorVideoDocumentAdapter, ct as buildSpeechHostMap, d as createMirrorVideoDocument, dt as toVideoDocument, et as VoiceDescriptor, f as createMirrorVideoDocumentAdapter, ft as BgmPart, g as SemanticDocumentAdapter, gt as PartKind, h as OpActor, ht as ENTITY_TIMELINE_PROJECTION_SCHEMA_VERSION, i as JournalEntry, it as InitialDocumentFacts, j as TrackDraft, jt as effectiveVideoClipDurationMs, k as PartIdFactory, kt as VideoDraft, l as MirrorVideoDocumentOptions, lt as derivePositionFromAbs, m as CommitOptions, mt as DEFAULT_UNIT_TIME_MS, n as videoDocumentSchema, nt as JsonValue, o as PlainMemoryAdapterOptions, ot as DerivedItemPosition, p as writeVideoDocumentToDraft, pt as CaptionPart, q as EntityRow, r as readVideoDocumentFromDraft, rt as EntityId, s as createPlainMemoryAdapter, st as SpeechHostMap, t as partUnionSchema, tt as JsonObject, u as applyEntityTimelineProjection, ut as fromVideoDocument, v as SemanticOpInput, vt as SpeechPart, w as SemanticOpKind, wt as VideoClipPart, x as IMPLEMENTED_SEMANTIC_OP_KINDS, xt as TrackItem, y as SemanticOpName, yt as Timeline, z as EntityTimelineTrackRole, zt as Track$1 } from "./index-Bs60N9Hl.js";
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";
6
6
 
@@ -221,16 +221,17 @@ declare function selectAudioScriptSegments(script: EntityRow<'audio-script'>, se
221
221
  //#region src/entity-editor/entity-graph-http-client.d.ts
222
222
  /** One authenticated revision of the authoritative Medeo Entity graph. */
223
223
  interface EntityGraphState {
224
- /** Fixed identity of the project's one AudioScript; present in every readable state. */
224
+ /** Current AudioScript content version attached to the project. */
225
225
  readonly audioScriptEntityId: string;
226
226
  readonly revision: number;
227
+ readonly loroSnapshot: string;
227
228
  readonly rows: EntityRelationRows;
228
229
  }
229
230
  interface EntityGraphCommitOptions {
230
231
  /** Server version vector proving the explicit legacy-to-Entity migration baseline. */
231
232
  readonly migrationBaseVv?: string;
232
233
  }
233
- /** Browser-safe authenticated CAS client for a document's Entity graph. */
234
+ /** Browser-safe authenticated Loro client for a document's Entity graph. */
234
235
  declare class EntityGraphHttpClient {
235
236
  private readonly options;
236
237
  private readonly transport;
@@ -238,13 +239,15 @@ declare class EntityGraphHttpClient {
238
239
  constructor(options: MengineHttpClientOptions);
239
240
  fetchState(): Promise<EntityGraphState>;
240
241
  /**
241
- * Replace the complete Entity graph under the baseline revision.
242
+ * Compile edits against the original causal snapshot and publish native Loro operations.
242
243
  *
243
244
  * Deletion intent is derived from baseline IDs omitted from `nextRows`, so a
244
245
  * transient create-then-remove never becomes a request to delete unknown
245
246
  * persisted data.
246
247
  */
247
- commit(baseState: Pick<EntityGraphState, 'revision' | 'rows'>, nextRows: EntityRelationRows, options?: EntityGraphCommitOptions): Promise<EntityGraphState>;
248
+ commit(baseState: Pick<EntityGraphState, 'revision' | 'rows' | 'loroSnapshot'>, nextRows: EntityRelationRows, options?: EntityGraphCommitOptions): Promise<EntityGraphState>;
249
+ /** Send the same prepared bytes on retry; never recompile an unconfirmed edit. */
250
+ commitUpdate(update: string): Promise<EntityGraphState>;
248
251
  private request;
249
252
  }
250
253
  //#endregion
@@ -451,6 +454,8 @@ interface PatchCaptionStyleInput {
451
454
  }
452
455
  interface InsertCaptionClipInput {
453
456
  readonly timelineEntityId: string;
457
+ /** Existing generation identity for newly materialized Caption content, distinct from its Clip. */
458
+ readonly captionEntityId?: string;
454
459
  /** Stable placed caption identity, distinct from the Caption content identity. */
455
460
  readonly captionClipEntityId?: string;
456
461
  /** Existing bases composed by this variant; includes an AudioScript text owner. */
@@ -589,7 +594,7 @@ interface EditorFoundation {
589
594
  readonly rows: EntityRelationRows;
590
595
  readonly timelineEntityId: string;
591
596
  readonly trackEntityIds: Readonly<Record<EditorTrackRole, string>>;
592
- /** Fixed identity of the project's one AudioScript, minted here when missing. */
597
+ /** Initial or current AudioScript content ID selected by the foundation. */
593
598
  readonly audioScriptEntityId: string;
594
599
  }
595
600
  /**
@@ -599,7 +604,7 @@ interface EditorFoundation {
599
604
  * Image/Video/Audio/Voice Entity must carry its own external locator, every
600
605
  * external asset id has exactly one claimant, and no media variant may be
601
606
  * bound through a legacy `physical-asset` Relation. Dual-entity media graphs
602
- * are rejected, not migrated. Caption composes AudioScript text and has no physical text Asset.
607
+ * are rejected, not migrated. Caption composes AudioScript text and may associate with a physical text Asset.
603
608
  */
604
609
  declare function assertCanonicalEditorResources(rows: EntityRelationRows): void;
605
610
  /**
@@ -610,7 +615,7 @@ declare function assertCanonicalEditorResources(rows: EntityRelationRows): void;
610
615
  *
611
616
  * 1. every Image/Video/Audio/Voice Entity carries its own Asset `external`
612
617
  * identity;
613
- * 2. no `physical-asset` Relation may bind a media variant or Caption;
618
+ * 2. no `physical-asset` Relation may bind a media variant;
614
619
  * 3. a self-carried media identity is immutable — it cannot be rewritten to
615
620
  * another asset id.
616
621
  *
@@ -662,23 +667,123 @@ interface DocumentAudioScript {
662
667
  readonly entityId: string;
663
668
  readonly segments: readonly (ScriptTextSegment & Readonly<Record<string, unknown>>)[];
664
669
  }
665
- /** Any state that carries the fixed document AudioScript identity outlet. */
670
+ /** State exposing the current AudioScript content version attached to the project. */
666
671
  interface DocumentAudioScriptState {
667
672
  readonly rows: EntityRelationRows;
668
- /**
669
- * Fixed identity minted atomically at project initialization. `null` is only
670
- * the internal revision-0 "not yet initialized" representation; normal
671
- * projects never carry the legacy null association.
672
- */
673
+ /** Current attachment; initialized projects point to a real script, including an empty one. */
673
674
  readonly audioScriptEntityId: string | null;
674
675
  }
675
- /**
676
- * Strict read of the project's one fixed AudioScript. The identity is immutable
677
- * for the project's lifetime; this never selects, clears, or switches a
678
- * script. Uninitialized or dangling identities are projection errors.
679
- */
676
+ /** Read only the attached version and preserve every segment; never aggregate other scripts. */
680
677
  declare function readDocumentAudioScript(state: DocumentAudioScriptState): DocumentAudioScript;
681
678
  //#endregion
679
+ //#region src/entity-crdt/entity-document.d.ts
680
+ declare const LORO_ENTITY_SCHEMA = "medeo.entities.loro.v1";
681
+ interface EntityDocumentState {
682
+ readonly rows: EntityRelationRows;
683
+ readonly project: Readonly<Record<string, string>>;
684
+ }
685
+ type Command = {
686
+ type: 'create';
687
+ row: EntityRow;
688
+ } | {
689
+ type: 'selection-baseline';
690
+ root: string;
691
+ fingerprint: string;
692
+ } | {
693
+ type: 'order';
694
+ group: string;
695
+ roots: string[];
696
+ token: string;
697
+ } | {
698
+ type: 'write';
699
+ root: string;
700
+ payload: JsonObject;
701
+ token: string;
702
+ } | {
703
+ type: 'text';
704
+ root: string;
705
+ path: readonly (string | number)[];
706
+ start: number;
707
+ deleteCount: number;
708
+ text: string;
709
+ token: string;
710
+ } | {
711
+ type: 'delete';
712
+ root: string;
713
+ } | {
714
+ type: 'relation';
715
+ row: RelationRow;
716
+ } | {
717
+ type: 'relation-fields';
718
+ root: string;
719
+ metadata: JsonObject;
720
+ trace: JsonObject;
721
+ } | {
722
+ type: 'unlink';
723
+ root: string;
724
+ } | {
725
+ type: 'attach';
726
+ slot: string;
727
+ entityId: string;
728
+ };
729
+ /** Plain domain objects assembled from native Loro state, never a second writable authority. */
730
+ declare function readEntityDocument(doc: LoroDoc, allowSelectionConflicts?: boolean): EntityDocumentState;
731
+ /** Native editing containers survive domain version changes and merge independently. */
732
+ declare class LoroEntityDocument {
733
+ readonly doc: LoroDoc;
734
+ private readonly validate?;
735
+ private readonly undoManager;
736
+ constructor(doc: LoroDoc, validate?: ((state: EntityDocumentState) => void) | undefined);
737
+ /** Open a causal snapshot using the same Loro runtime as the compiler. */
738
+ static fromSnapshot(snapshot: Uint8Array, validate?: (state: EntityDocumentState) => void): LoroEntityDocument;
739
+ static create(rows: EntityRelationRows, project?: Readonly<Record<string, string>>, peerId?: PeerID): LoroEntityDocument;
740
+ snapshot(): EntityDocumentState;
741
+ relationsOf(entityId: string): readonly RelationRow[];
742
+ getVersion(id: string): EntityRow | undefined;
743
+ /** The callback and every domain validation execute on a causally complete fork first. */
744
+ transact(edit: (draft: LoroEntityDraft) => void): Uint8Array;
745
+ /** Import preserves native operation identities; projection errors never discard remote operations. */
746
+ import(update: Uint8Array): void;
747
+ canUndo(): boolean;
748
+ canRedo(): boolean;
749
+ undo(): boolean;
750
+ redo(): boolean;
751
+ private historyEdit;
752
+ }
753
+ declare class LoroEntityDraft {
754
+ private readonly doc;
755
+ readonly commands: Command[];
756
+ private readonly selectedRoots;
757
+ constructor(doc: LoroDoc);
758
+ snapshot(): EntityDocumentState;
759
+ order(groupId: string, entityIds: readonly string[]): void;
760
+ create(row: EntityRow): void;
761
+ delete(entityId: string): void;
762
+ attach(slot: string, entityId: string): void;
763
+ link(row: RelationRow): void;
764
+ patchRelation(relationId: string, metadata: JsonObject, trace: JsonObject): void;
765
+ unlink(relationId: string): void;
766
+ private relationRoot;
767
+ update(entityId: string, fields: JsonObject): void;
768
+ declare(entityId: string, fields: JsonObject): void;
769
+ replaceOwned(entityId: string, payload: JsonObject): void;
770
+ editText(entityId: string, path: readonly (string | number)[], start: number, deleteCount: number, text: string): void;
771
+ captureSelectionBaselines(): void;
772
+ private record;
773
+ }
774
+ //#endregion
775
+ //#region src/entity-crdt/compile-rows.d.ts
776
+ /** Lower a detached ordinary-object edit against its actual causal Loro baseline. */
777
+ declare function compileEntityRows(snapshot: Uint8Array, rows: EntityRelationRows, validate?: (state: EntityDocumentState) => void): {
778
+ update: Uint8Array;
779
+ state: EntityDocumentState;
780
+ };
781
+ /** Compile an edit on an existing peer, retaining its native local undo history. */
782
+ declare function applyEntityRows(editor: LoroEntityDocument, rows: EntityRelationRows): {
783
+ update: Uint8Array;
784
+ state: EntityDocumentState;
785
+ };
786
+ //#endregion
682
787
  //#region src/editor/journal.d.ts
683
788
  /**
684
789
  * Wire a plain-memory adapter + editor that share a recording id factory, so
@@ -1583,4 +1688,4 @@ declare function hostForAbsMs(ranges: MainClipRange[], absMs: number): MainClipR
1583
1688
  */
1584
1689
  declare function relativePositionForAbs(ranges: MainClipRange[], absMs: number): TrackItemTimePosition;
1585
1690
  //#endregion
1586
- export { type Aggregation, type AssembledCaptionContent, type AssembledPhoneticScriptContent, type Attachment, type AudioMediaAssetFact, type BgmPart, type CaptionContentInput, 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, ENTITY_TIMELINE_PROJECTION_SCHEMA_VERSION, type EditorFoundation, type EntityGraphCommitOptions, EntityGraphHttpClient, type EntityGraphState, EntityTimelineEditor, type EntityTimelineIdFactory, EntityTimelineProjectionError, type EntityTimelineTrackRole, IMPLEMENTED_SEMANTIC_OP_KINDS, type ImageMediaAssetFact, type ImplementedSemanticOpKind, type ImportedMediaAsset, type InitialDocumentFacts, type InsertCaptionClipInput, type InsertClipInput, type InsertMediaClipInput, type InsertMediaClipsInput, type InsertPlacedClipInput, type JournalEntry, LANE_KINDS_IN_STACK_ORDER, type LaneKind, type LinearClipSpeed, 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 MengineDocumentVersion, type MengineEventStreamOptions, MengineHttpClient, type MengineHttpClientOptions, MengineHttpRequestError, MenginePushRejectedError, type MenginePushResponse, type MenginePushUpdateResponse, type MengineRejectedResponse, type MengineSnapshotResponse, type MengineSseUpdateEvent, type MengineSyncResponse, 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, VIDEO_DOCUMENT_SCHEMA_VERSION, ValidationError, type VideoClipPart, type VideoDocument, type VideoDocumentDraft, type VideoDocumentMirrorSchema, type VideoDocumentSchemaVersion, VideoDocumentValidationError, type VideoDocumentValidationIssue, type VideoDocumentValidationIssueCode, type VideoDraft, type CaptionPart$1 as VideoDraftCaptionPart, type VideoDraftPartUnion, type Timeline$1 as VideoDraftTimeline, type Track$1 as VideoDraftTrack, type TrackItem$1 as VideoDraftTrackItem, type VideoMediaAssetFact, type VisualMediaAssetFact, type VoiceMediaAssetFact, type VoiceoverCaptionFact, type VoiceoverTakeInput, type VoiceoverTakeResult, type WaitForServerAckOptions, applyEntityTimelineProjection, arrangeMainTrackSeamlessly, assembleCaptionContent, assembleEntityContent, assemblePhoneticScriptContent, assembleScriptText, assertCanonicalEditorResources, assertEntityProjectionPreservesLegacy, assertMediaAssetWritePolicy, assertValidVideoDocument, base64ToBytes, buildInitialVideoDocument, buildSpeechHostMap, bytesToBase64, cascadeAfterVideoClipChanges, 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, readMainTrackItems, readMengineEventStream, readPart, readPartDurationMs, readVideoDocumentFromDraft, reassignSpeechesToVideoClipsByTime, recalculateTimelineDuration, relativePositionForAbs, replayJournal, resolveAllSpeechOverlaps, resolveEntityTimelineLayout, resolveSpeechOverlapByShiftingVideos, safeDurationMs, index_d_exports as schemas, selectAudioScriptSegments, snapshotToPlain, solveVideoDocument, speedOf, syncAggregatedClipsTimePosition, toVideoDocument, validateVideoDocument, videoDocumentMirrorSchema, videoDocumentSchema, writeVideoDocumentToDraft };
1691
+ export { type Aggregation, type AssembledCaptionContent, type AssembledPhoneticScriptContent, type Attachment, type AudioMediaAssetFact, type BgmPart, type CaptionContentInput, 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, ENTITY_TIMELINE_PROJECTION_SCHEMA_VERSION, type EditorFoundation, EntityDocumentState, type EntityGraphCommitOptions, EntityGraphHttpClient, type EntityGraphState, EntityTimelineEditor, type EntityTimelineIdFactory, EntityTimelineProjectionError, type EntityTimelineTrackRole, IMPLEMENTED_SEMANTIC_OP_KINDS, type ImageMediaAssetFact, type ImplementedSemanticOpKind, type ImportedMediaAsset, type InitialDocumentFacts, 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 MengineDocumentVersion, type MengineEventStreamOptions, MengineHttpClient, type MengineHttpClientOptions, MengineHttpRequestError, MenginePushRejectedError, type MenginePushResponse, type MenginePushUpdateResponse, type MengineRejectedResponse, type MengineSnapshotResponse, type MengineSseUpdateEvent, type MengineSyncResponse, 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, VIDEO_DOCUMENT_SCHEMA_VERSION, ValidationError, type VideoClipPart, type VideoDocument, type VideoDocumentDraft, type VideoDocumentMirrorSchema, type VideoDocumentSchemaVersion, VideoDocumentValidationError, type VideoDocumentValidationIssue, type VideoDocumentValidationIssueCode, type VideoDraft, type CaptionPart$1 as VideoDraftCaptionPart, type VideoDraftPartUnion, type Timeline$1 as VideoDraftTimeline, type Track$1 as VideoDraftTrack, type TrackItem$1 as VideoDraftTrackItem, type VideoMediaAssetFact, type VisualMediaAssetFact, type VoiceMediaAssetFact, type VoiceoverCaptionFact, type VoiceoverTakeInput, type VoiceoverTakeResult, type WaitForServerAckOptions, applyEntityRows, applyEntityTimelineProjection, arrangeMainTrackSeamlessly, assembleCaptionContent, assembleEntityContent, assemblePhoneticScriptContent, assembleScriptText, assertCanonicalEditorResources, assertEntityProjectionPreservesLegacy, assertMediaAssetWritePolicy, assertValidVideoDocument, 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, resolveSpeechOverlapByShiftingVideos, safeDurationMs, index_d_exports as schemas, selectAudioScriptSegments, snapshotToPlain, solveVideoDocument, speedOf, syncAggregatedClipsTimePosition, toVideoDocument, validateVideoDocument, videoDocumentMirrorSchema, videoDocumentSchema, writeVideoDocumentToDraft };
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { $ as isEmptyVideoClip, A as buildSpeechHostMap, B as ensureLaneTrack, C as variantBaseEntityIds, D as hasSequence, E as createRelationId, F as assertValidVideoDocument, G as arrangeMainTrackSeamlessly, H as laneTrackId, I as validateVideoDocument, J as recalculateTimelineDuration, K as fillMainTrackTimeGaps, L as partUnionSchema, M as fromVideoDocument, N as toVideoDocument, O as isMediaAssetVariantKind, P as VideoDocumentValidationError, Q as TIMELINE_SKELETON_DURATION_MS, R as videoDocumentSchema, S as updateEntityFields, T as createEntityId, U as solveVideoDocument, V as findLaneTrack, W as cascadeAfterVideoClipChanges, X as resolveSpeechOverlapByShiftingVideos, Y as resolveAllSpeechOverlaps, Z as syncAggregatedClipsTimePosition, _ as assembleEntityContent, a as applyEntityTimelineProjection, at as effectiveVideoClipDurationMs, b as findComposedAudioScript, c as writeVideoDocumentToDraft, ct as recordEntries, d as EntityProjectionGraph, dt as bytesToBase64, et as partDurationMs, f as resolveEntityTimelineLayout, g as assembleCaptionContent, h as ScriptCompositionError, i as MirrorVideoDocumentAdapter, it as VIDEO_DOCUMENT_SCHEMA_VERSION, j as derivePositionFromAbs, k as buildInitialVideoDocument, l as readVideoDocumentFromDraft, lt as videoDocumentMirrorSchema, m as decodeEntityRelationRows, n as createPlainMemoryAdapter, nt as DEFAULT_UNIT_TIME_MS, o as createMirrorVideoDocument, ot as speedOf, p as EntityTimelineProjectionError, q as reassignSpeechesToVideoClipsByTime, r as generatePartId, rt as ENTITY_TIMELINE_PROJECTION_SCHEMA_VERSION, s as createMirrorVideoDocumentAdapter, st as partUnionToDraft, t as PlainMemoryAdapter, tt as safeDurationMs, u as projectEntityTimeline, ut as base64ToBytes, v as assemblePhoneticScriptContent, w as isJsonObject, x as selectAudioScriptSegments, y as assembleScriptText, z as LANE_KINDS_IN_STACK_ORDER } from "./document-BLYcbv8E.js";
1
+ import { $ as reassignSpeechesToVideoClipsByTime, A as isJsonObject, B as VideoDocumentValidationError, C as assembleEntityContent, D as selectAudioScriptSegments, E as findComposedAudioScript, F as buildInitialVideoDocument, G as LANE_KINDS_IN_STACK_ORDER, H as validateVideoDocument, I as buildSpeechHostMap, J as laneTrackId, K as ensureLaneTrack, L as derivePositionFromAbs, M as createRelationId, N as hasSequence, O as updateEntityFields, P as isMediaAssetVariantKind, Q as fillMainTrackTimeGaps, R as fromVideoDocument, S as assembleCaptionContent, T as assembleScriptText, U as partUnionSchema, V as assertValidVideoDocument, W as videoDocumentSchema, X as cascadeAfterVideoClipChanges, Y as solveVideoDocument, Z as arrangeMainTrackSeamlessly, _ as EntityProjectionGraph, _t as bytesToBase64, a as applyEntityTimelineProjection, at as isEmptyVideoClip, b as decodeEntityRelationRows, c as writeVideoDocumentToDraft, ct as DEFAULT_UNIT_TIME_MS, d as LoroEntityDocument, dt as effectiveVideoClipDurationMs, et as recalculateTimelineDuration, f as LoroEntityDraft, ft as speedOf, g as projectEntityTimeline, gt as base64ToBytes, h as equalJson, ht as videoDocumentMirrorSchema, i as MirrorVideoDocumentAdapter, it as TIMELINE_SKELETON_DURATION_MS, j as createEntityId, k as variantBaseEntityIds, l as readVideoDocumentFromDraft, lt as ENTITY_TIMELINE_PROJECTION_SCHEMA_VERSION, m as entityOrderGroups, mt as recordEntries, n as createPlainMemoryAdapter, nt as resolveSpeechOverlapByShiftingVideos, o as createMirrorVideoDocument, ot as partDurationMs, p as readEntityDocument, pt as partUnionToDraft, q as findLaneTrack, r as generatePartId, rt as syncAggregatedClipsTimePosition, s as createMirrorVideoDocumentAdapter, st as safeDurationMs, t as PlainMemoryAdapter, tt as resolveAllSpeechOverlaps, u as LORO_ENTITY_SCHEMA, ut as VIDEO_DOCUMENT_SCHEMA_VERSION, v as resolveEntityTimelineLayout, w as assemblePhoneticScriptContent, x as ScriptCompositionError, y as EntityTimelineProjectionError, z as toVideoDocument } from "./document-CF-q_mRy.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, VersionVector } from "loro-crdt";
4
4
  import { ClientServerSynchronizer, DocManager } from "@mengine/sync";
@@ -217,17 +217,57 @@ function findSseFrameBoundary(buffer) {
217
217
  return Math.min(lf, crlf);
218
218
  }
219
219
  //#endregion
220
+ //#region src/entity-crdt/compile-rows.ts
221
+ /** Lower a detached ordinary-object edit against its actual causal Loro baseline. */
222
+ function compileEntityRows(snapshot, rows, validate) {
223
+ const doc = new LoroDoc();
224
+ doc.import(snapshot);
225
+ return applyEntityRows(new LoroEntityDocument(doc, validate), rows);
226
+ }
227
+ /** Compile an edit on an existing peer, retaining its native local undo history. */
228
+ function applyEntityRows(editor, rows) {
229
+ const before = editor.snapshot().rows;
230
+ const oldEntities = new Map(before.entities.map((row) => [row.entityId, row]));
231
+ const newEntities = new Map(rows.entities.map((row) => [row.entityId, row]));
232
+ const oldRelations = new Map(before.relations.map((row) => [row.relationId, row]));
233
+ const newRelations = new Map(rows.relations.map((row) => [row.relationId, row]));
234
+ if (newEntities.size !== rows.entities.length || newRelations.size !== rows.relations.length) throw new Error("Duplicate domain identity");
235
+ return {
236
+ update: editor.transact((draft) => {
237
+ for (const row of before.relations) {
238
+ const next = newRelations.get(row.relationId);
239
+ if (!next) draft.unlink(row.relationId);
240
+ else {
241
+ if (next.relationKind !== row.relationKind || next.endpoint0EntityId !== row.endpoint0EntityId || next.endpoint1EntityId !== row.endpoint1EntityId) throw new Error("Relation identity cannot change kind or endpoint positions");
242
+ if (!equalJson(row.metadata, next.metadata) || !equalJson(row.trace, next.trace)) draft.patchRelation(row.relationId, next.metadata, next.trace);
243
+ }
244
+ }
245
+ for (const row of rows.entities) {
246
+ const previous = oldEntities.get(row.entityId);
247
+ if (!previous) draft.create(row);
248
+ else {
249
+ if (previous.entityKind !== row.entityKind) throw new Error("Entity kind cannot change");
250
+ if (!equalJson(previous.payload, row.payload)) draft.replaceOwned(row.entityId, row.payload);
251
+ }
252
+ }
253
+ for (const row of rows.relations) if (!oldRelations.has(row.relationId)) draft.link(row);
254
+ const beforeOrder = entityOrderGroups(before), afterOrder = entityOrderGroups(rows);
255
+ for (const group of new Set([...beforeOrder.keys(), ...afterOrder.keys()])) {
256
+ const next = afterOrder.get(group) ?? [];
257
+ if (!equalJson(beforeOrder.get(group) ?? [], next)) draft.order(group, next);
258
+ }
259
+ for (const row of before.entities) if (!newEntities.has(row.entityId)) draft.delete(row.entityId);
260
+ }),
261
+ state: editor.snapshot()
262
+ };
263
+ }
264
+ //#endregion
220
265
  //#region src/entity-editor/document-audio-script.ts
221
- /**
222
- * Strict read of the project's one fixed AudioScript. The identity is immutable
223
- * for the project's lifetime; this never selects, clears, or switches a
224
- * script. Uninitialized or dangling identities are projection errors.
225
- */
266
+ /** Read only the attached version and preserve every segment; never aggregate other scripts. */
226
267
  function readDocumentAudioScript(state) {
227
268
  const id = state.audioScriptEntityId;
228
269
  if (id === null) throw new EntityTimelineProjectionError("Document AudioScript is not initialized");
229
270
  if (typeof id !== "string" || id.trim() !== id || !id) throw new EntityTimelineProjectionError("Invalid document AudioScript identity");
230
- if (state.rows.entities.filter((row) => row.entityKind === "audio-script").length !== 1) throw new EntityTimelineProjectionError("Editor requires exactly one AudioScript");
231
271
  const entity = state.rows.entities.find((row) => row.entityId === id);
232
272
  if (!entity || entity.entityKind !== "audio-script") throw new EntityTimelineProjectionError(`Document AudioScript ${id} must name the project AudioScript`);
233
273
  const content = assembleEntityContent(state.rows, createEntityId(id));
@@ -252,11 +292,10 @@ const roleOrder$1 = {
252
292
  * Image/Video/Audio/Voice Entity must carry its own external locator, every
253
293
  * external asset id has exactly one claimant, and no media variant may be
254
294
  * bound through a legacy `physical-asset` Relation. Dual-entity media graphs
255
- * are rejected, not migrated. Caption composes AudioScript text and has no physical text Asset.
295
+ * are rejected, not migrated. Caption composes AudioScript text and may associate with a physical text Asset.
256
296
  */
257
297
  function assertCanonicalEditorResources(rows) {
258
298
  if (rows.entities.filter((row) => row.entityKind === "timeline").length > 1) throw new EntityTimelineProjectionError("Editor requires exactly one Timeline");
259
- if (rows.entities.filter((row) => row.entityKind === "audio-script").length !== 1) throw new EntityTimelineProjectionError("Editor requires exactly one AudioScript");
260
299
  for (const role of Object.keys(roleOrder$1)) if (rows.entities.filter((row) => row.entityKind === "track" && row.payload.role === role).length > 1) throw new EntityTimelineProjectionError(`Editor has multiple ${role} Tracks`);
261
300
  const identityByAssetKey = /* @__PURE__ */ new Map();
262
301
  const kinds = new Map(rows.entities.map((row) => [String(row.entityId), row.entityKind]));
@@ -284,7 +323,7 @@ function assertCanonicalEditorResources(rows) {
284
323
  *
285
324
  * 1. every Image/Video/Audio/Voice Entity carries its own Asset `external`
286
325
  * identity;
287
- * 2. no `physical-asset` Relation may bind a media variant or Caption;
326
+ * 2. no `physical-asset` Relation may bind a media variant;
288
327
  * 3. a self-carried media identity is immutable — it cannot be rewritten to
289
328
  * another asset id.
290
329
  *
@@ -319,10 +358,9 @@ function memotaLocator(value) {
319
358
  };
320
359
  }
321
360
  /**
322
- * The project AudioScript is a fixed structure identity, like the Timeline: at
323
- * most one may exist, and a missing one is minted atomically with empty
324
- * segments. Project initialization and legacy migration share this single
325
- * path, so both produce the same canonical structure.
361
+ * Bootstrap an empty script when the foundation has no candidate. Without an
362
+ * explicit project attachment, multiple candidates are ambiguous. Existing
363
+ * content IDs are reused here; Loro editing advances their immutable versions.
326
364
  */
327
365
  function ensureDocumentAudioScript(entities, idFactory) {
328
366
  const scripts = entities.filter((row) => row.entityKind === "audio-script");
@@ -408,7 +446,7 @@ const numericMarkerValidation$1 = { compareMarkerPoints: (_marker, _range, left,
408
446
  if (typeof left !== "number" || !Number.isFinite(left) || typeof right !== "number" || !Number.isFinite(right)) throw new Error("entity-state requires finite numeric Marker coordinates");
409
447
  return left < right ? -1 : left > right ? 1 : 0;
410
448
  } };
411
- /** Browser-safe authenticated CAS client for a document's Entity graph. */
449
+ /** Browser-safe authenticated Loro client for a document's Entity graph. */
412
450
  var EntityGraphHttpClient = class {
413
451
  options;
414
452
  transport;
@@ -423,36 +461,24 @@ var EntityGraphHttpClient = class {
423
461
  return this.request({ method: "GET" });
424
462
  }
425
463
  /**
426
- * Replace the complete Entity graph under the baseline revision.
464
+ * Compile edits against the original causal snapshot and publish native Loro operations.
427
465
  *
428
466
  * Deletion intent is derived from baseline IDs omitted from `nextRows`, so a
429
467
  * transient create-then-remove never becomes a request to delete unknown
430
468
  * persisted data.
431
469
  */
432
470
  async commit(baseState, nextRows, options = {}) {
433
- if (!isNonNegativeSafeInteger(baseState.revision)) throw new Error("Entity graph revision must be a non-negative safe integer");
434
- const baseRows = cloneAndValidateRows(baseState.rows);
471
+ if (options.migrationBaseVv !== void 0) throw new Error("Legacy entity migration is not supported by the Loro contract");
435
472
  const next = cloneAndValidateRows(nextRows);
436
- assertMediaAssetWritePolicy(baseRows, next);
437
- const scriptRows = next.entities.filter((row) => row.entityKind === "audio-script");
438
- if (scriptRows.length !== 1) throw new EntityTimelineProjectionError("Editor requires exactly one AudioScript");
439
- readDocumentAudioScript({
440
- rows: next,
441
- audioScriptEntityId: scriptRows[0].entityId
442
- });
443
- const nextEntityIds = new Set(next.entities.map((row) => row.entityId));
444
- const nextRelationIds = new Set(next.relations.map((row) => row.relationId));
445
- const deletedEntityIds = baseRows.entities.map((row) => row.entityId).filter((entityId) => !nextEntityIds.has(entityId)).sort();
446
- const deletedRelationIds = baseRows.relations.map((row) => row.relationId).filter((relationId) => !nextRelationIds.has(relationId)).sort();
473
+ assertMediaAssetWritePolicy(baseState.rows, next);
474
+ const compiled = compileEntityRows(base64ToBytes(baseState.loroSnapshot), next);
475
+ return this.commitUpdate(bytesToBase64(compiled.update));
476
+ }
477
+ /** Send the same prepared bytes on retry; never recompile an unconfirmed edit. */
478
+ async commitUpdate(update) {
447
479
  return this.request({
448
480
  method: "POST",
449
- body: JSON.stringify({
450
- expected_revision: baseState.revision,
451
- rows: toWireRows(next),
452
- deleted_entity_ids: deletedEntityIds,
453
- deleted_relation_ids: deletedRelationIds,
454
- ...options.migrationBaseVv === void 0 ? {} : { migration_base_vv: options.migrationBaseVv }
455
- })
481
+ body: JSON.stringify({ update })
456
482
  });
457
483
  }
458
484
  async request(init) {
@@ -471,8 +497,10 @@ function parseWireState(value, expectedDocId) {
471
497
  const rows = parseWireRows(value.rows);
472
498
  decodeEntityRelationRows(rows, numericMarkerValidation$1);
473
499
  if (typeof value.audio_script_entity_id !== "string") throw new Error("Document AudioScript is not initialized");
500
+ if (typeof value.loro_snapshot !== "string") throw new Error("Missing causal Loro snapshot");
474
501
  const state = {
475
502
  revision: value.revision,
503
+ loroSnapshot: value.loro_snapshot,
476
504
  rows,
477
505
  audioScriptEntityId: value.audio_script_entity_id
478
506
  };
@@ -510,23 +538,6 @@ function cloneAndValidateRows(rows) {
510
538
  decodeEntityRelationRows(clone, numericMarkerValidation$1);
511
539
  return clone;
512
540
  }
513
- function toWireRows(rows) {
514
- return {
515
- entities: rows.entities.map((row) => ({
516
- entity_id: row.entityId,
517
- entity_kind: row.entityKind,
518
- payload: row.payload
519
- })),
520
- relations: rows.relations.map((row) => ({
521
- relation_id: row.relationId,
522
- relation_kind: row.relationKind,
523
- endpoint_0_entity_id: row.endpoint0EntityId,
524
- endpoint_1_entity_id: row.endpoint1EntityId,
525
- metadata: row.metadata,
526
- trace: row.trace
527
- }))
528
- };
529
- }
530
541
  function requiredString(value, field) {
531
542
  if (typeof value !== "string" || value.length === 0 || value.trim() !== value) throw new Error(`Invalid ${field} in entity-state response`);
532
543
  return value;
@@ -1365,7 +1376,7 @@ var EntityTimelineEditor = class {
1365
1376
  const selections = captionSelections(input.selections);
1366
1377
  const track = this.ensureRoleTrack(draft, input.timelineEntityId, "caption");
1367
1378
  const content = {
1368
- entityId: this.mintEntityId(draft),
1379
+ entityId: input.captionEntityId === void 0 ? this.mintEntityId(draft) : requireAvailableEntityId(draft, input.captionEntityId),
1369
1380
  entityKind: "caption",
1370
1381
  payload: {
1371
1382
  extent: {
@@ -4837,4 +4848,4 @@ function serverCovers(serverVV, target) {
4837
4848
  return covers(server, target);
4838
4849
  }
4839
4850
  //#endregion
4840
- export { DEFAULT_UNIT_TIME_MS, ENTITY_TIMELINE_PROJECTION_SCHEMA_VERSION, EntityGraphHttpClient, EntityTimelineEditor, EntityTimelineProjectionError, IMPLEMENTED_SEMANTIC_OP_KINDS, LANE_KINDS_IN_STACK_ORDER, ManualSyncDoc, MedeoHttpDocStorage, MemoryDocStorage, MengineAckFailedError, MengineDocSession, MengineHttpClient, MengineHttpRequestError, MenginePushRejectedError, MirrorVideoDocumentAdapter, PlainMemoryAdapter, SchemaValidator, ScriptCompositionError, SemanticEditor, TIMELINE_SKELETON_DURATION_MS, VIDEO_DOCUMENT_SCHEMA_VERSION, ValidationError, VideoDocumentValidationError, applyEntityTimelineProjection, arrangeMainTrackSeamlessly, assembleCaptionContent, assembleEntityContent, assemblePhoneticScriptContent, assembleScriptText, assertCanonicalEditorResources, assertEntityProjectionPreservesLegacy, assertMediaAssetWritePolicy, assertValidVideoDocument, base64ToBytes, buildInitialVideoDocument, buildSpeechHostMap, bytesToBase64, cascadeAfterVideoClipChanges, 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, readMainTrackItems, readMengineEventStream, readPart, readPartDurationMs, readVideoDocumentFromDraft, reassignSpeechesToVideoClipsByTime, recalculateTimelineDuration, relativePositionForAbs, replayJournal, resolveAllSpeechOverlaps, resolveEntityTimelineLayout, resolveSpeechOverlapByShiftingVideos, safeDurationMs, schemas_exports as schemas, selectAudioScriptSegments, snapshotToPlain, solveVideoDocument, speedOf, syncAggregatedClipsTimePosition, toVideoDocument, validateVideoDocument, videoDocumentMirrorSchema, videoDocumentSchema, writeVideoDocumentToDraft };
4851
+ export { DEFAULT_UNIT_TIME_MS, ENTITY_TIMELINE_PROJECTION_SCHEMA_VERSION, 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, VIDEO_DOCUMENT_SCHEMA_VERSION, ValidationError, VideoDocumentValidationError, applyEntityRows, applyEntityTimelineProjection, arrangeMainTrackSeamlessly, assembleCaptionContent, assembleEntityContent, assemblePhoneticScriptContent, assembleScriptText, assertCanonicalEditorResources, assertEntityProjectionPreservesLegacy, assertMediaAssetWritePolicy, assertValidVideoDocument, 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, resolveSpeechOverlapByShiftingVideos, safeDurationMs, schemas_exports as schemas, selectAudioScriptSegments, snapshotToPlain, solveVideoDocument, speedOf, syncAggregatedClipsTimePosition, toVideoDocument, validateVideoDocument, videoDocumentMirrorSchema, videoDocumentSchema, writeVideoDocumentToDraft };
package/dist/testing.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Ot as VideoDraft, c as MirrorVideoDocumentAdapter } from "./index-BUkDsU7c.js";
1
+ import { c as MirrorVideoDocumentAdapter, kt as VideoDraft } from "./index-Bs60N9Hl.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 { dt as bytesToBase64, it as VIDEO_DOCUMENT_SCHEMA_VERSION, s as createMirrorVideoDocumentAdapter, ut as base64ToBytes } from "./document-BLYcbv8E.js";
1
+ import { _t as bytesToBase64, gt as base64ToBytes, s as createMirrorVideoDocumentAdapter, ut as VIDEO_DOCUMENT_SCHEMA_VERSION } from "./document-CF-q_mRy.js";
2
2
  import { t as classifyUpdate } from "./loro-relay-doc-ssdYpuef.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": "1.3.1-alpha.9",
3
+ "version": "1.4.1-alpha.0",
4
4
  "license": "UNLICENSED",
5
5
  "repository": {
6
6
  "type": "git",
@@ -24,12 +24,13 @@
24
24
  "registry": "https://registry.npmjs.org/"
25
25
  },
26
26
  "dependencies": {
27
+ "@noble/hashes": "^2.4.0",
27
28
  "immer": "^10.2.0",
28
29
  "loro-mirror": "^2.2.0",
29
30
  "zod": "^4.4.3",
30
- "@mengine/storage": "1.3.1-alpha.9",
31
- "@mengine/sync": "1.3.1-alpha.9",
32
- "@mengine/utils": "1.3.1-alpha.9"
31
+ "@mengine/storage": "1.4.1-alpha.0",
32
+ "@mengine/sync": "1.4.1-alpha.0",
33
+ "@mengine/utils": "1.4.1-alpha.0"
33
34
  },
34
35
  "devDependencies": {
35
36
  "@types/node": "^25.9.1",