@mengine/medeo-client 1.1.0 → 1.2.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.
@@ -230,6 +230,16 @@ function effectiveVideoClipDurationMs(clip) {
230
230
  const effective = Math.round(sourceMs / speed);
231
231
  return Number.isFinite(effective) && effective > 0 ? effective : 0;
232
232
  }
233
+ /**
234
+ * The `timeline.unit_time_ms` the read-view states when the document states none.
235
+ *
236
+ * One frame at 30fps. A document legitimately has no such fact (display
237
+ * granularity is the editor's, not the timeline's), but the read-view IDL marks
238
+ * the field `@required`, so the projection has to name a value. This one is a
239
+ * usable granularity; `0` — which a downstream consumer had been defaulting to —
240
+ * is not, and passes any `>= 0` guard on its way to an editor that cannot use it.
241
+ */
242
+ const DEFAULT_UNIT_TIME_MS = 33.333;
233
243
  //#endregion
234
244
  //#region src/timeline-core/types.ts
235
245
  /** Total document duration when there is no real content (matches FE bgm fallback). */
@@ -1279,6 +1289,20 @@ function deriveItem(item, isMain, speechHost, partLibrary) {
1279
1289
  * Project the authoritative `VideoDocument` back into the legacy `VideoDraft`
1280
1290
  * read-view, solving each item's absolute position, the `part_aggregations`, and
1281
1291
  * the total duration via the timeline-core cascade.
1292
+ *
1293
+ * The read-view is a compatibility contract, and the IDL declares
1294
+ * `Timeline.unit_time_ms` and `Track.is_hidden` `@required`
1295
+ * (`video_draft_comp.smithy`) — so a projection that omitted them handed every
1296
+ * consumer a payload that violated the shape it claims to satisfy, leaving each
1297
+ * one to invent its own default. Two already had, and they disagreed: the agent
1298
+ * harness used `unit_time_ms: 0`, director used a frame at 30fps. Defaulting here
1299
+ * makes the contract true at the one place that produces it.
1300
+ *
1301
+ * These two are defaultable because the projection knows their values on its own:
1302
+ * absent `unit_time_ms` means "no display granularity was ever stated" and absent
1303
+ * `is_hidden` means "this track was never hidden". `version` is NOT defaultable
1304
+ * here — its only honest value is server state (`update_seq`) that a
1305
+ * `VideoDocument` cannot see, so it stays absent and the HTTP layer fills it.
1282
1306
  */
1283
1307
  function fromVideoDocument(document) {
1284
1308
  assertValidVideoDocument(document);
@@ -1294,7 +1318,7 @@ function fromVideoDocument(document) {
1294
1318
  thumbnail_storage_key: document.meta.thumbnail_storage_key,
1295
1319
  timeline: {
1296
1320
  duration_ms: view.durationMs,
1297
- unit_time_ms: document.timeline?.unit_time_ms
1321
+ unit_time_ms: document.timeline?.unit_time_ms ?? 33.333
1298
1322
  },
1299
1323
  video_creation_settings: clone(document.meta.video_creation_settings),
1300
1324
  chat_session_id: document.meta.chat_session_id,
@@ -1390,7 +1414,7 @@ function draftTrack(track, absByPartId) {
1390
1414
  return {
1391
1415
  id: track.id,
1392
1416
  parts_kind: track.parts_kind,
1393
- is_hidden: track.is_hidden,
1417
+ is_hidden: track.is_hidden ?? false,
1394
1418
  items: (track.items ?? []).map((item) => ({
1395
1419
  part_id: item.part_id,
1396
1420
  abs_time_position: absByPartId.get(item.part_id) ?? 0
@@ -1627,4 +1651,4 @@ function toTrackRow(track) {
1627
1651
  };
1628
1652
  }
1629
1653
  //#endregion
1630
- export { partDurationMs as A, reassignSpeechesToVideoClipsByTime as C, syncAggregatedClipsTimePosition as D, resolveSpeechOverlapByShiftingVideos as E, recordEntries as F, videoDocumentMirrorSchema as I, base64ToBytes as L, VIDEO_DOCUMENT_SCHEMA_VERSION as M, effectiveVideoClipDurationMs as N, TIMELINE_SKELETON_DURATION_MS as O, partUnionToDraft as P, bytesToBase64 as R, fillMainTrackTimeGaps as S, resolveAllSpeechOverlaps as T, findLaneTrack as _, buildInitialVideoDocument as a, cascadeAfterVideoClipChanges as b, fromVideoDocument as c, assertValidVideoDocument as d, validateVideoDocument as f, ensureLaneTrack as g, LANE_KINDS_IN_STACK_ORDER as h, readVideoDocumentFromDraft as i, safeDurationMs as j, isEmptyVideoClip as k, toVideoDocument as l, videoDocumentSchema as m, createMirrorVideoDocument as n, buildSpeechHostMap as o, partUnionSchema as p, createMirrorVideoDocumentAdapter as r, derivePositionFromAbs as s, MirrorVideoDocumentAdapter as t, VideoDocumentValidationError as u, laneTrackId as v, recalculateTimelineDuration as w, arrangeMainTrackSeamlessly as x, solveVideoDocument as y };
1654
+ export { partDurationMs as A, reassignSpeechesToVideoClipsByTime as C, syncAggregatedClipsTimePosition as D, resolveSpeechOverlapByShiftingVideos as E, partUnionToDraft as F, recordEntries as I, videoDocumentMirrorSchema as L, DEFAULT_UNIT_TIME_MS as M, VIDEO_DOCUMENT_SCHEMA_VERSION as N, TIMELINE_SKELETON_DURATION_MS as O, effectiveVideoClipDurationMs as P, base64ToBytes as R, fillMainTrackTimeGaps as S, resolveAllSpeechOverlaps as T, findLaneTrack as _, buildInitialVideoDocument as a, cascadeAfterVideoClipChanges as b, fromVideoDocument as c, assertValidVideoDocument as d, validateVideoDocument as f, ensureLaneTrack as g, LANE_KINDS_IN_STACK_ORDER as h, readVideoDocumentFromDraft as i, safeDurationMs as j, isEmptyVideoClip as k, toVideoDocument as l, videoDocumentSchema as m, createMirrorVideoDocument as n, buildSpeechHostMap as o, partUnionSchema as p, createMirrorVideoDocumentAdapter as r, derivePositionFromAbs as s, MirrorVideoDocumentAdapter as t, VideoDocumentValidationError as u, laneTrackId as v, recalculateTimelineDuration as w, arrangeMainTrackSeamlessly as x, solveVideoDocument as y, bytesToBase64 as z };
@@ -632,6 +632,16 @@ type VideoDraft = Omit<VideoDraft$1, 'part_library' | 'video_creation_settings'>
632
632
  interface Timeline {
633
633
  unit_time_ms: number | undefined;
634
634
  }
635
+ /**
636
+ * The `timeline.unit_time_ms` the read-view states when the document states none.
637
+ *
638
+ * One frame at 30fps. A document legitimately has no such fact (display
639
+ * granularity is the editor's, not the timeline's), but the read-view IDL marks
640
+ * the field `@required`, so the projection has to name a value. This one is a
641
+ * usable granularity; `0` — which a downstream consumer had been defaulting to —
642
+ * is not, and passes any `>= 0` guard on its way to an editor that cannot use it.
643
+ */
644
+ declare const DEFAULT_UNIT_TIME_MS = 33.333;
635
645
  /**
636
646
  * Project-level scalars that do not participate in track ordering. Grouped under
637
647
  * `meta` because the loro-mirror `schema()` root only accepts container schemas,
@@ -748,6 +758,20 @@ declare function derivePositionFromAbs(partId: string, abs: number, isMain: bool
748
758
  * Project the authoritative `VideoDocument` back into the legacy `VideoDraft`
749
759
  * read-view, solving each item's absolute position, the `part_aggregations`, and
750
760
  * the total duration via the timeline-core cascade.
761
+ *
762
+ * The read-view is a compatibility contract, and the IDL declares
763
+ * `Timeline.unit_time_ms` and `Track.is_hidden` `@required`
764
+ * (`video_draft_comp.smithy`) — so a projection that omitted them handed every
765
+ * consumer a payload that violated the shape it claims to satisfy, leaving each
766
+ * one to invent its own default. Two already had, and they disagreed: the agent
767
+ * harness used `unit_time_ms: 0`, director used a frame at 30fps. Defaulting here
768
+ * makes the contract true at the one place that produces it.
769
+ *
770
+ * These two are defaultable because the projection knows their values on its own:
771
+ * absent `unit_time_ms` means "no display granularity was ever stated" and absent
772
+ * `is_hidden` means "this track was never hidden". `version` is NOT defaultable
773
+ * here — its only honest value is server state (`update_seq`) that a
774
+ * `VideoDocument` cannot see, so it stays absent and the HTTP layer fills it.
751
775
  */
752
776
  declare function fromVideoDocument(document: VideoDocument): VideoDraft;
753
777
  //#endregion
@@ -2072,4 +2096,4 @@ declare const videoDocumentSchema: z.ZodObject<{
2072
2096
  }, z.core.$loose>]>>>;
2073
2097
  }, z.core.$loose>;
2074
2098
  //#endregion
2075
- export { VideoDocumentValidationIssue as $, assertValidVideoDocument as A, BgmPart as B, index_d_exports as C, VideoDocumentMirrorSchema as D, VideoDocumentDraft as E, SpeechHostMap as F, Timeline as G, PartKind as H, buildSpeechHostMap as I, TrackItemTimePosition as J, Track as K, derivePositionFromAbs as L, InitialDocumentFacts as M, buildInitialVideoDocument as N, videoDocumentMirrorSchema as O, DerivedItemPosition as P, VideoDocumentSchemaVersion as Q, fromVideoDocument as R, ValidationError as S, TrackItemDraft as T, PartUnion as U, CaptionPart as V, SpeechPart as W, VideoClipPart as X, VIDEO_DOCUMENT_SCHEMA_VERSION as Y, VideoDocument as Z, PlannedSemanticOpKind as _, MirrorVideoDocumentOptions as a, CaptionStyle as at, SchemaValidator as b, CommitOptions as c, Timeline$1 as ct, SemanticEditor as d, VideoDocumentValidationIssueCode as et, SemanticOpInput as f, ImplementedSemanticOpKind as g, IMPLEMENTED_SEMANTIC_OP_KINDS as h, MirrorVideoDocumentAdapter as i, CaptionPart$1 as it, validateVideoDocument as j, VideoDocumentValidationError as k, OpActor as l, Track$1 as lt, TransactAudit as m, videoDocumentSchema as n, VideoDraftPartUnion as nt, createMirrorVideoDocument as o, PartAggregation as ot, SemanticOpName as p, TrackItem as q, readVideoDocumentFromDraft as r, Attachment as rt, createMirrorVideoDocumentAdapter as s, SpeedShift as st, partUnionSchema as t, VideoDraft as tt, SemanticDocumentAdapter as u, TrackItem$1 as ut, SemanticOpKind as v, TrackDraft as w, SnapshotReadable as x, isImplementedSemanticOpKind as y, toVideoDocument as z };
2099
+ export { VideoDocumentSchemaVersion as $, assertValidVideoDocument as A, BgmPart as B, index_d_exports as C, VideoDocumentMirrorSchema as D, VideoDocumentDraft as E, SpeechHostMap as F, SpeechPart as G, DEFAULT_UNIT_TIME_MS as H, buildSpeechHostMap as I, TrackItem as J, Timeline as K, derivePositionFromAbs as L, InitialDocumentFacts as M, buildInitialVideoDocument as N, videoDocumentMirrorSchema as O, DerivedItemPosition as P, VideoDocument as Q, fromVideoDocument as R, ValidationError as S, TrackItemDraft as T, PartKind as U, CaptionPart as V, PartUnion as W, VIDEO_DOCUMENT_SCHEMA_VERSION as X, TrackItemTimePosition as Y, VideoClipPart as Z, PlannedSemanticOpKind as _, MirrorVideoDocumentOptions as a, CaptionPart$1 as at, SchemaValidator as b, CommitOptions as c, SpeedShift as ct, SemanticEditor as d, TrackItem$1 as dt, VideoDocumentValidationIssue as et, SemanticOpInput as f, ImplementedSemanticOpKind as g, IMPLEMENTED_SEMANTIC_OP_KINDS as h, MirrorVideoDocumentAdapter as i, Attachment as it, validateVideoDocument as j, VideoDocumentValidationError as k, OpActor as l, Timeline$1 as lt, TransactAudit as m, videoDocumentSchema as n, VideoDraft as nt, createMirrorVideoDocument as o, CaptionStyle as ot, SemanticOpName as p, Track as q, readVideoDocumentFromDraft as r, VideoDraftPartUnion as rt, createMirrorVideoDocumentAdapter as s, PartAggregation as st, partUnionSchema as t, VideoDocumentValidationIssueCode as tt, SemanticDocumentAdapter as u, Track$1 as ut, SemanticOpKind as v, TrackDraft as w, SnapshotReadable as x, isImplementedSemanticOpKind as y, toVideoDocument as z };
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- import { $ as VideoDocumentValidationIssue, A as assertValidVideoDocument, B as BgmPart, C as index_d_exports, D as VideoDocumentMirrorSchema, E as VideoDocumentDraft, F as SpeechHostMap, G as Timeline, H as PartKind, I as buildSpeechHostMap, J as TrackItemTimePosition, K as Track, L as derivePositionFromAbs, M as InitialDocumentFacts, N as buildInitialVideoDocument, O as videoDocumentMirrorSchema, P as DerivedItemPosition, Q as VideoDocumentSchemaVersion, R as fromVideoDocument, S as ValidationError, T as TrackItemDraft, U as PartUnion, V as CaptionPart, W as SpeechPart, X as VideoClipPart, Y as VIDEO_DOCUMENT_SCHEMA_VERSION, Z as VideoDocument, _ as PlannedSemanticOpKind, a as MirrorVideoDocumentOptions, at as CaptionStyle, b as SchemaValidator, c as CommitOptions, ct as Timeline$1, d as SemanticEditor, et as VideoDocumentValidationIssueCode, f as SemanticOpInput, g as ImplementedSemanticOpKind, h as IMPLEMENTED_SEMANTIC_OP_KINDS, i as MirrorVideoDocumentAdapter, it as CaptionPart$1, j as validateVideoDocument, k as VideoDocumentValidationError, l as OpActor, lt as Track$1, m as TransactAudit, n as videoDocumentSchema, nt as VideoDraftPartUnion, o as createMirrorVideoDocument, ot as PartAggregation, p as SemanticOpName, q as TrackItem, r as readVideoDocumentFromDraft, rt as Attachment, s as createMirrorVideoDocumentAdapter, st as SpeedShift, t as partUnionSchema, tt as VideoDraft, u as SemanticDocumentAdapter, ut as TrackItem$1, v as SemanticOpKind, w as TrackDraft, x as SnapshotReadable, y as isImplementedSemanticOpKind, z as toVideoDocument } from "./index-BUKA3L7o.js";
1
+ import { $ as VideoDocumentSchemaVersion, A as assertValidVideoDocument, B as BgmPart, C as index_d_exports, D as VideoDocumentMirrorSchema, E as VideoDocumentDraft, F as SpeechHostMap, G as SpeechPart, H as DEFAULT_UNIT_TIME_MS, I as buildSpeechHostMap, J as TrackItem, K as Timeline, L as derivePositionFromAbs, M as InitialDocumentFacts, N as buildInitialVideoDocument, O as videoDocumentMirrorSchema, P as DerivedItemPosition, Q as VideoDocument, R as fromVideoDocument, S as ValidationError, T as TrackItemDraft, U as PartKind, V as CaptionPart, W as PartUnion, X as VIDEO_DOCUMENT_SCHEMA_VERSION, Y as TrackItemTimePosition, Z as VideoClipPart, _ as PlannedSemanticOpKind, a as MirrorVideoDocumentOptions, at as CaptionPart$1, b as SchemaValidator, c as CommitOptions, ct as SpeedShift, d as SemanticEditor, dt as TrackItem$1, et as VideoDocumentValidationIssue, f as SemanticOpInput, g as ImplementedSemanticOpKind, h as IMPLEMENTED_SEMANTIC_OP_KINDS, i as MirrorVideoDocumentAdapter, it as Attachment, j as validateVideoDocument, k as VideoDocumentValidationError, l as OpActor, lt as Timeline$1, m as TransactAudit, n as videoDocumentSchema, nt as VideoDraft, o as createMirrorVideoDocument, ot as CaptionStyle, p as SemanticOpName, q as Track, r as readVideoDocumentFromDraft, rt as VideoDraftPartUnion, s as createMirrorVideoDocumentAdapter, st as PartAggregation, t as partUnionSchema, tt as VideoDocumentValidationIssueCode, u as SemanticDocumentAdapter, ut as Track$1, v as SemanticOpKind, w as TrackDraft, x as SnapshotReadable, y as isImplementedSemanticOpKind, z as toVideoDocument } from "./index-DWVYLTjv.js";
2
2
  import { PeerID } from "loro-crdt";
3
3
  import { DocState } from "@mengine/sync";
4
- import { BaseDocStorage, Connection, DocDiff, DocSnapshotRecord, DocStorage, DocStorageOptions, DocUpdate, DocUpdateRecord } from "@mengine/storage";
4
+ import { BaseDocStorage, Connection, DocDiff, DocPushReceipt, DocSnapshotRecord, DocStorage, DocStorageOptions, DocUpdate, DocUpdateRecord } from "@mengine/storage";
5
5
 
6
6
  //#region src/client/base64.d.ts
7
7
  declare function bytesToBase64(bytes: Uint8Array): string;
@@ -549,19 +549,24 @@ declare class MedeoHttpDocStorage implements DocStorage {
549
549
  getDoc(docId: string): Promise<DocSnapshotRecord | null>;
550
550
  getDocDiff(docId: string, knownVersion?: Uint8Array): Promise<DocDiff | null>;
551
551
  /**
552
- * Forward one update to the server.
552
+ * Forward one update to the server, returning what the server says it now holds.
553
553
  *
554
- * The `DocStorage` contract returns `void`, so the server's verdict cannot be
555
- * the return value it is published on {@link subscribePushOutcome} instead,
556
- * for BOTH outcomes and failures. That channel is what makes the push
557
- * observable; previously the verdict was read and dropped, so a `duplicate`
558
- * (bytes contributed nothing) was indistinguishable from a successful write.
554
+ * The returned `server_vv` is the server's own statement about itself, computed
555
+ * inside the write transaction. A caller tracking "what the remote has" can
556
+ * adopt it directly, which is strictly better than inferring that bound from
557
+ * the pushed blob: it also covers ops other peers wrote, so those stop being
558
+ * re-sent on every later push. `ack` and `duplicate` both carry it.
559
+ *
560
+ * The verdict itself stays on {@link subscribePushOutcome}, which reports
561
+ * failures too — a return value cannot. Previously the verdict was read and
562
+ * dropped, so a `duplicate` (bytes contributed nothing) was indistinguishable
563
+ * from a successful write.
559
564
  *
560
565
  * The error is still rethrown after being published: the synchronizer treats a
561
566
  * throw as "retry this cycle", and swallowing it here would strand the update.
562
567
  * Publishing is therefore additive observability, not error handling.
563
568
  */
564
- pushDocUpdate(update: DocUpdate, _origin: unknown): Promise<void>;
569
+ pushDocUpdate(update: DocUpdate, _origin: unknown): Promise<DocPushReceipt>;
565
570
  /**
566
571
  * Observe the server's verdict for every pushed update, including failures.
567
572
  *
@@ -750,7 +755,7 @@ declare class MemoryDocStorage extends BaseDocStorage {
750
755
  readonly connection: Connection;
751
756
  private readonly entries;
752
757
  constructor(options?: DocStorageOptions);
753
- pushDocUpdate(update: DocUpdate, origin: unknown): Promise<void>;
758
+ pushDocUpdate(update: DocUpdate, origin: unknown): Promise<DocPushReceipt>;
754
759
  deleteDoc(docId: string): Promise<void>;
755
760
  protected getDocSnapshot(docId: string): Promise<DocSnapshotRecord | null>;
756
761
  protected setDocSnapshot(snapshot: DocSnapshotRecord): Promise<boolean>;
@@ -1059,4 +1064,4 @@ declare function hostForAbsMs(ranges: MainClipRange[], absMs: number): MainClipR
1059
1064
  */
1060
1065
  declare function relativePositionForAbs(ranges: MainClipRange[], absMs: number): TrackItemTimePosition;
1061
1066
  //#endregion
1062
- export { type Aggregation, type Attachment, type BgmPart, type CaptionPart, type CaptionStyle, type CommitOptions, type DerivedItemPosition, type DocStorageLike, type DocVersionMark, IMPLEMENTED_SEMANTIC_OP_KINDS, type ImplementedSemanticOpKind, type InitialDocumentFacts, LANE_KINDS_IN_STACK_ORDER, type LaneKind, type MainClipRange, type MakeEmptyPart, ManualSyncDoc, type ManualSyncDocOptions, MedeoHttpDocStorage, type MedeoHttpDocStorageOptions, 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 OpActor, type PartAggregation, type PartKind, type PartUnion, type PlannedSemanticOpKind, type PullFailureReason, type PullResult, type PushOutcome, type PushOutcomeKind, type PushResult, type PushResultKind, SchemaValidator, type SemanticDocumentAdapter, SemanticEditor, type SemanticOpInput, type SemanticOpKind, type SemanticOpName, 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, 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 WaitForServerAckOptions, arrangeMainTrackSeamlessly, assertValidVideoDocument, base64ToBytes, buildInitialVideoDocument, buildSpeechHostMap, bytesToBase64, cascadeAfterVideoClipChanges, createMirrorVideoDocument, createMirrorVideoDocumentAdapter, decodeDocVersionMark, derivePositionFromAbs, encodeDocVersionMark, ensureLaneTrack, fillMainTrackTimeGaps, findLaneTrack, fromVideoDocument, generatePartId, getAt, hostForAbsMs, isEmptyVideoClip, isImplementedSemanticOpKind, isMap, laneTrackId, mainTrackRanges, partDurationMs, partUnionSchema, readMainTrackItems, readMengineEventStream, readPart, readPartDurationMs, readVideoDocumentFromDraft, reassignSpeechesToVideoClipsByTime, recalculateTimelineDuration, relativePositionForAbs, resolveAllSpeechOverlaps, resolveSpeechOverlapByShiftingVideos, safeDurationMs, index_d_exports as schemas, snapshotToPlain, solveVideoDocument, syncAggregatedClipsTimePosition, toVideoDocument, validateVideoDocument, videoDocumentMirrorSchema, videoDocumentSchema };
1067
+ export { type Aggregation, type Attachment, type BgmPart, type CaptionPart, type CaptionStyle, type CommitOptions, DEFAULT_UNIT_TIME_MS, type DerivedItemPosition, type DocStorageLike, type DocVersionMark, IMPLEMENTED_SEMANTIC_OP_KINDS, type ImplementedSemanticOpKind, type InitialDocumentFacts, LANE_KINDS_IN_STACK_ORDER, type LaneKind, type MainClipRange, type MakeEmptyPart, ManualSyncDoc, type ManualSyncDocOptions, MedeoHttpDocStorage, type MedeoHttpDocStorageOptions, 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 OpActor, type PartAggregation, type PartKind, type PartUnion, type PlannedSemanticOpKind, type PullFailureReason, type PullResult, type PushOutcome, type PushOutcomeKind, type PushResult, type PushResultKind, SchemaValidator, type SemanticDocumentAdapter, SemanticEditor, type SemanticOpInput, type SemanticOpKind, type SemanticOpName, 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, 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 WaitForServerAckOptions, arrangeMainTrackSeamlessly, assertValidVideoDocument, base64ToBytes, buildInitialVideoDocument, buildSpeechHostMap, bytesToBase64, cascadeAfterVideoClipChanges, createMirrorVideoDocument, createMirrorVideoDocumentAdapter, decodeDocVersionMark, derivePositionFromAbs, encodeDocVersionMark, ensureLaneTrack, fillMainTrackTimeGaps, findLaneTrack, fromVideoDocument, generatePartId, getAt, hostForAbsMs, isEmptyVideoClip, isImplementedSemanticOpKind, isMap, laneTrackId, mainTrackRanges, partDurationMs, partUnionSchema, readMainTrackItems, readMengineEventStream, readPart, readPartDurationMs, readVideoDocumentFromDraft, reassignSpeechesToVideoClipsByTime, recalculateTimelineDuration, relativePositionForAbs, resolveAllSpeechOverlaps, resolveSpeechOverlapByShiftingVideos, safeDurationMs, index_d_exports as schemas, snapshotToPlain, solveVideoDocument, syncAggregatedClipsTimePosition, toVideoDocument, validateVideoDocument, videoDocumentMirrorSchema, videoDocumentSchema };
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { t as __exportAll } from "./chunk-D7D4PA-g.js";
2
- import { A as partDurationMs, C as reassignSpeechesToVideoClipsByTime, D as syncAggregatedClipsTimePosition, E as resolveSpeechOverlapByShiftingVideos, F as recordEntries, I as videoDocumentMirrorSchema, L as base64ToBytes, M as VIDEO_DOCUMENT_SCHEMA_VERSION, N as effectiveVideoClipDurationMs, O as TIMELINE_SKELETON_DURATION_MS, P as partUnionToDraft, R as bytesToBase64, S as fillMainTrackTimeGaps, T as resolveAllSpeechOverlaps, _ as findLaneTrack, a as buildInitialVideoDocument, b as cascadeAfterVideoClipChanges, c as fromVideoDocument, d as assertValidVideoDocument, f as validateVideoDocument, g as ensureLaneTrack, h as LANE_KINDS_IN_STACK_ORDER, i as readVideoDocumentFromDraft, j as safeDurationMs, k as isEmptyVideoClip, l as toVideoDocument, m as videoDocumentSchema, n as createMirrorVideoDocument, o as buildSpeechHostMap, p as partUnionSchema, r as createMirrorVideoDocumentAdapter, s as derivePositionFromAbs, t as MirrorVideoDocumentAdapter, u as VideoDocumentValidationError, v as laneTrackId, w as recalculateTimelineDuration, x as arrangeMainTrackSeamlessly, y as solveVideoDocument } from "./document-C98vSu7J.js";
2
+ import { A as partDurationMs, C as reassignSpeechesToVideoClipsByTime, D as syncAggregatedClipsTimePosition, E as resolveSpeechOverlapByShiftingVideos, F as partUnionToDraft, I as recordEntries, L as videoDocumentMirrorSchema, M as DEFAULT_UNIT_TIME_MS, N as VIDEO_DOCUMENT_SCHEMA_VERSION, O as TIMELINE_SKELETON_DURATION_MS, P as effectiveVideoClipDurationMs, R as base64ToBytes, S as fillMainTrackTimeGaps, T as resolveAllSpeechOverlaps, _ as findLaneTrack, a as buildInitialVideoDocument, b as cascadeAfterVideoClipChanges, c as fromVideoDocument, d as assertValidVideoDocument, f as validateVideoDocument, g as ensureLaneTrack, h as LANE_KINDS_IN_STACK_ORDER, i as readVideoDocumentFromDraft, j as safeDurationMs, k as isEmptyVideoClip, l as toVideoDocument, m as videoDocumentSchema, n as createMirrorVideoDocument, o as buildSpeechHostMap, p as partUnionSchema, r as createMirrorVideoDocumentAdapter, s as derivePositionFromAbs, t as MirrorVideoDocumentAdapter, u as VideoDocumentValidationError, v as laneTrackId, w as recalculateTimelineDuration, x as arrangeMainTrackSeamlessly, y as solveVideoDocument, z as bytesToBase64 } from "./document-C0o_cjAH.js";
3
3
  import { z } from "zod";
4
4
  import { LoroDoc, VersionVector } from "loro-crdt";
5
5
  import { ClientServerSynchronizer, DocManager } from "@mengine/sync";
@@ -2348,13 +2348,18 @@ var MedeoHttpDocStorage = class {
2348
2348
  };
2349
2349
  }
2350
2350
  /**
2351
- * Forward one update to the server.
2351
+ * Forward one update to the server, returning what the server says it now holds.
2352
2352
  *
2353
- * The `DocStorage` contract returns `void`, so the server's verdict cannot be
2354
- * the return value it is published on {@link subscribePushOutcome} instead,
2355
- * for BOTH outcomes and failures. That channel is what makes the push
2356
- * observable; previously the verdict was read and dropped, so a `duplicate`
2357
- * (bytes contributed nothing) was indistinguishable from a successful write.
2353
+ * The returned `server_vv` is the server's own statement about itself, computed
2354
+ * inside the write transaction. A caller tracking "what the remote has" can
2355
+ * adopt it directly, which is strictly better than inferring that bound from
2356
+ * the pushed blob: it also covers ops other peers wrote, so those stop being
2357
+ * re-sent on every later push. `ack` and `duplicate` both carry it.
2358
+ *
2359
+ * The verdict itself stays on {@link subscribePushOutcome}, which reports
2360
+ * failures too — a return value cannot. Previously the verdict was read and
2361
+ * dropped, so a `duplicate` (bytes contributed nothing) was indistinguishable
2362
+ * from a successful write.
2358
2363
  *
2359
2364
  * The error is still rethrown after being published: the synchronizer treats a
2360
2365
  * throw as "retry this cycle", and swallowing it here would strand the update.
@@ -2362,14 +2367,17 @@ var MedeoHttpDocStorage = class {
2362
2367
  */
2363
2368
  async pushDocUpdate(update, _origin) {
2364
2369
  this.assertDocId(update.docId);
2365
- if (this.isReadonly || update.data.byteLength === 0) return;
2370
+ if (this.isReadonly) throw new Error(`MedeoHttpDocStorage is readonly; refusing to push ${update.docId}`);
2371
+ if (update.data.byteLength === 0) return {};
2366
2372
  try {
2367
2373
  const response = await this.client.pushUpdate(update.data);
2374
+ const serverVV = decodeServerVV(response.version?.server_vv);
2368
2375
  this.events.emit("pushOutcome", {
2369
2376
  kind: response.kind,
2370
2377
  updateSeq: response.update_seq ?? void 0,
2371
- serverVV: decodeServerVV(response.version?.server_vv)
2378
+ serverVV
2372
2379
  });
2380
+ return { version: serverVV };
2373
2381
  } catch (error) {
2374
2382
  const failure = error instanceof Error ? error : new Error(String(error));
2375
2383
  const rejected = error instanceof MenginePushRejectedError;
@@ -2467,6 +2475,7 @@ var MemoryDocStorage = class extends BaseDocStorage {
2467
2475
  },
2468
2476
  origin
2469
2477
  });
2478
+ return {};
2470
2479
  }
2471
2480
  async deleteDoc(docId) {
2472
2481
  this.entries.delete(docId);
@@ -2769,4 +2778,4 @@ function serverCovers(serverVV, target) {
2769
2778
  return covers(server, target);
2770
2779
  }
2771
2780
  //#endregion
2772
- export { IMPLEMENTED_SEMANTIC_OP_KINDS, LANE_KINDS_IN_STACK_ORDER, ManualSyncDoc, MedeoHttpDocStorage, MemoryDocStorage, MengineAckFailedError, MengineDocSession, MengineHttpClient, MengineHttpRequestError, MenginePushRejectedError, MirrorVideoDocumentAdapter, SchemaValidator, SemanticEditor, TIMELINE_SKELETON_DURATION_MS, VIDEO_DOCUMENT_SCHEMA_VERSION, ValidationError, VideoDocumentValidationError, arrangeMainTrackSeamlessly, assertValidVideoDocument, base64ToBytes, buildInitialVideoDocument, buildSpeechHostMap, bytesToBase64, cascadeAfterVideoClipChanges, createMirrorVideoDocument, createMirrorVideoDocumentAdapter, decodeDocVersionMark, derivePositionFromAbs, encodeDocVersionMark, ensureLaneTrack, fillMainTrackTimeGaps, findLaneTrack, fromVideoDocument, generatePartId, getAt, hostForAbsMs, isEmptyVideoClip, isImplementedSemanticOpKind, isMap, laneTrackId, mainTrackRanges, partDurationMs, partUnionSchema, readMainTrackItems, readMengineEventStream, readPart, readPartDurationMs, readVideoDocumentFromDraft, reassignSpeechesToVideoClipsByTime, recalculateTimelineDuration, relativePositionForAbs, resolveAllSpeechOverlaps, resolveSpeechOverlapByShiftingVideos, safeDurationMs, schemas_exports as schemas, snapshotToPlain, solveVideoDocument, syncAggregatedClipsTimePosition, toVideoDocument, validateVideoDocument, videoDocumentMirrorSchema, videoDocumentSchema };
2781
+ export { DEFAULT_UNIT_TIME_MS, IMPLEMENTED_SEMANTIC_OP_KINDS, LANE_KINDS_IN_STACK_ORDER, ManualSyncDoc, MedeoHttpDocStorage, MemoryDocStorage, MengineAckFailedError, MengineDocSession, MengineHttpClient, MengineHttpRequestError, MenginePushRejectedError, MirrorVideoDocumentAdapter, SchemaValidator, SemanticEditor, TIMELINE_SKELETON_DURATION_MS, VIDEO_DOCUMENT_SCHEMA_VERSION, ValidationError, VideoDocumentValidationError, arrangeMainTrackSeamlessly, assertValidVideoDocument, base64ToBytes, buildInitialVideoDocument, buildSpeechHostMap, bytesToBase64, cascadeAfterVideoClipChanges, createMirrorVideoDocument, createMirrorVideoDocumentAdapter, decodeDocVersionMark, derivePositionFromAbs, encodeDocVersionMark, ensureLaneTrack, fillMainTrackTimeGaps, findLaneTrack, fromVideoDocument, generatePartId, getAt, hostForAbsMs, isEmptyVideoClip, isImplementedSemanticOpKind, isMap, laneTrackId, mainTrackRanges, partDurationMs, partUnionSchema, readMainTrackItems, readMengineEventStream, readPart, readPartDurationMs, readVideoDocumentFromDraft, reassignSpeechesToVideoClipsByTime, recalculateTimelineDuration, relativePositionForAbs, resolveAllSpeechOverlaps, resolveSpeechOverlapByShiftingVideos, safeDurationMs, schemas_exports as schemas, snapshotToPlain, solveVideoDocument, syncAggregatedClipsTimePosition, toVideoDocument, validateVideoDocument, videoDocumentMirrorSchema, videoDocumentSchema };
package/dist/testing.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { i as MirrorVideoDocumentAdapter, tt as VideoDraft } from "./index-BUKA3L7o.js";
1
+ import { i as MirrorVideoDocumentAdapter, nt as VideoDraft } from "./index-DWVYLTjv.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 { L as base64ToBytes, M as VIDEO_DOCUMENT_SCHEMA_VERSION, R as bytesToBase64, r as createMirrorVideoDocumentAdapter } from "./document-C98vSu7J.js";
1
+ import { N as VIDEO_DOCUMENT_SCHEMA_VERSION, R as base64ToBytes, r as createMirrorVideoDocumentAdapter, z as bytesToBase64 } from "./document-C0o_cjAH.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.1.0",
3
+ "version": "1.2.0",
4
4
  "license": "UNLICENSED",
5
5
  "repository": {
6
6
  "type": "git",
@@ -25,9 +25,9 @@
25
25
  "dependencies": {
26
26
  "loro-mirror": "^2.2.0",
27
27
  "zod": "^4.4.3",
28
- "@mengine/storage": "1.1.0",
29
- "@mengine/sync": "1.1.0",
30
- "@mengine/utils": "1.1.0"
28
+ "@mengine/sync": "1.2.0",
29
+ "@mengine/storage": "1.2.0",
30
+ "@mengine/utils": "1.2.0"
31
31
  },
32
32
  "devDependencies": {
33
33
  "@types/node": "^25.9.1",