@mengine/medeo-client 2.1.1-dsl.0 → 2.1.1-dsl.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  import { M as DslDiagnostic, o as VideoDraftContent, p as CommitOptions } from "./video-draft-types-c_shaRyq.js";
2
2
  import { LoroDoc, PeerID, VersionVector } from "loro-crdt";
3
- import { DocState } from "@mengine/sync";
3
+ import { DocState, LocalSaveState } from "@mengine/sync";
4
4
  import { BaseDocStorage, Connection, DocDiff, DocPushReceipt, DocSnapshotRecord, DocStorage, DocStorageOptions, DocUpdate, DocUpdateRecord } from "@mengine/storage";
5
5
 
6
6
  //#region src/client/base64.d.ts
@@ -532,13 +532,18 @@ declare class MengineAckFailedError extends Error {
532
532
  readonly cause: Error | undefined;
533
533
  constructor(reason: 'timeout' | 'rejected' | 'failed', code: string | undefined, cause: Error | undefined, message: string);
534
534
  }
535
+ type MengineLocalSaveState = LocalSaveState;
536
+ interface WaitForLocalSaveOptions {
537
+ /** Only limits waiting, never cancels persistence. */
538
+ timeoutMs?: number;
539
+ }
535
540
  interface WaitForServerAckOptions {
536
541
  /** Deadline in ms. Rejects with reason `timeout` when it elapses. */
537
542
  timeoutMs?: number;
538
543
  }
539
544
  /** Document-level confirmation is independent of local operation completion. */
540
545
  interface MengineDocSyncState {
541
- /** Remote-only imports do not create a new local confirmation obligation. */
546
+ /** Server-originated imports do not create a new local confirmation obligation. */
542
547
  readonly confirmation: 'unknown' | 'pending' | 'confirmed';
543
548
  /** Transport/activity phase. Idle does not imply confirmation; failure details
544
549
  * remain available through push outcomes and confirmation wait errors. */
@@ -553,6 +558,9 @@ interface MengineDocSessionOptions {
553
558
  * Browsers should pass an `IndexedDBDocStorage` for refresh/cross-tab support.
554
559
  */
555
560
  localStorage?: DocStorageLike;
561
+ /** A freshly fetched remote snapshot to merge into storage before loading.
562
+ * Existing local changes are retained; the host owns any online startup gate. */
563
+ initialSnapshot?: Uint8Array;
556
564
  sseReconnectDelayMs?: number;
557
565
  /**
558
566
  * Keep remote synchronization read-only: pull snapshot/diffs and subscribe to
@@ -587,6 +595,7 @@ declare class DocumentSession<Snapshot, Editor, Document> {
587
595
  private started;
588
596
  private startTask;
589
597
  private destroyed;
598
+ private closeTask;
590
599
  private lifetime;
591
600
  private hasConnected;
592
601
  private initialVersionValue;
@@ -687,7 +696,17 @@ declare class DocumentSession<Snapshot, Editor, Document> {
687
696
  */
688
697
  start(): Promise<Snapshot>;
689
698
  private open;
699
+ getLocalSaveState(): MengineLocalSaveState;
700
+ /** Immediately reports local transaction state; independent of server confirmation. */
701
+ subscribeLocalSaveState(cb: (state: MengineLocalSaveState) => void): () => void;
702
+ /** Waits until all local saves finish, including edits made while waiting. Does not wait for the network. */
703
+ waitForLocalSave(options?: WaitForLocalSaveOptions): Promise<void>;
704
+ /** Stop accepting edits and drain local persistence before releasing resources.
705
+ * A failed local write keeps retrying, even after the host has unmounted.
706
+ * Hosts should use this for normal teardown; destroy() is immediate cancellation. */
707
+ close(): Promise<void>;
690
708
  getSyncState(): MengineDocSyncState;
709
+ private trackLocalVersion;
691
710
  private confirmationTarget;
692
711
  /** Immediately supplies current state; unsubscribe when the host changes docs. */
693
712
  subscribeSyncState(cb: (state: MengineDocSyncState) => void): () => void;
@@ -725,4 +744,4 @@ declare class MemoryDocStorage extends BaseDocStorage {
725
744
  private now;
726
745
  }
727
746
  //#endregion
728
- export { MengineAuditResponse as A, base64ToBytes as B, MengineEventStreamOptions as C, MengineHttpRequestError as D, MengineHttpClientOptions as E, MengineRejectedResponse as F, MengineSnapshotResponse as I, MengineSseUpdateEvent as L, MengineDraftResponse as M, MenginePushResponse as N, MenginePushRejectedError as O, MenginePushUpdateResponse as P, MengineSyncResponse as R, PushResultKind as S, MengineHttpClient as T, bytesToBase64 as V, encodeDocVersionMark as _, MengineDocSessionOptions as a, PullResult as b, DocStorageLike as c, MedeoHttpDocStorageOptions as d, PushOutcome as f, decodeDocVersionMark as g, ManualSyncTransport as h, MengineAckFailedError as i, MengineDocumentVersion as j, MengineAuditEntry as k, MengineUndoState as l, ManualSyncDocOptions as m, DocumentSession as n, MengineDocSyncState as o, PushOutcomeKind as p, DocumentSessionUpdateEvent as r, WaitForServerAckOptions as s, MemoryDocStorage as t, MedeoHttpDocStorage as u, DocVersionMark as v, readMengineEventStream as w, PushResult as x, PullFailureReason as y, MengineUpdateMeta as z };
747
+ export { MenginePushRejectedError as A, MengineSyncResponse as B, PushResult as C, MengineHttpClient as D, readMengineEventStream as E, MenginePushResponse as F, base64ToBytes as H, MenginePushUpdateResponse as I, MengineRejectedResponse as L, MengineAuditResponse as M, MengineDocumentVersion as N, MengineHttpClientOptions as O, MengineDraftResponse as P, MengineSnapshotResponse as R, PullResult as S, MengineEventStreamOptions as T, bytesToBase64 as U, MengineUpdateMeta as V, ManualSyncTransport as _, MengineDocSessionOptions as a, DocVersionMark as b, WaitForLocalSaveOptions as c, MengineUndoState as d, MedeoHttpDocStorage as f, ManualSyncDocOptions as g, PushOutcomeKind as h, MengineAckFailedError as i, MengineAuditEntry as j, MengineHttpRequestError as k, WaitForServerAckOptions as l, PushOutcome as m, DocumentSession as n, MengineDocSyncState as o, MedeoHttpDocStorageOptions as p, DocumentSessionUpdateEvent as r, MengineLocalSaveState as s, MemoryDocStorage as t, DocStorageLike as u, decodeDocVersionMark as v, PushResultKind as w, PullFailureReason as x, encodeDocVersionMark as y, MengineSseUpdateEvent as z };
@@ -1,6 +1,6 @@
1
1
  import { G as ResourceSystem, et as TrackRole, z as MedeoDslSnapshot } from "./video-draft-types-c_shaRyq.js";
2
- import { _ as MedeoDsl, f as DslEditor, i as VideoDraftProjection } from "./index-DKDMTXUe.js";
3
- import { a as MengineDocSessionOptions, h as ManualSyncTransport, m as ManualSyncDocOptions, n as DocumentSession, r as DocumentSessionUpdateEvent } from "./index-B7fC7q7P.js";
2
+ import { _ as MedeoDsl, f as DslEditor, i as VideoDraftProjection } from "./index-Cu7SdKN5.js";
3
+ import { _ as ManualSyncTransport, a as MengineDocSessionOptions, g as ManualSyncDocOptions, n as DocumentSession, r as DocumentSessionUpdateEvent } from "./index-D-3rdfUP.js";
4
4
 
5
5
  //#region src/manual-sync/manual-sync-doc.d.ts
6
6
  /** Explicit synchronization over the same DSL/editor used by the live Session. */
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { $ as Track, A as ContainNode, B as Media, C as Caption, D as CaptionText, E as CaptionStyle, F as EntityTable, G as ResourceSystem, H as RelationTable, I as EntityTables, J as TextEdit, K as RichTextSnapshot, L as EntityValues, M as DslDiagnostic, N as DslMutation, O as Clip, P as EntityMutation, Q as TimeAnchor, R as FieldPatch, S as AudioScript, T as CaptionSelection, U as RelationTables, V as RelationMutation, W as RelationValues, X as TextMutation, Y as TextMark, Z as TextRun, _ as defaultIdFactory, a as VideoDraftCaptionStyle, b as tupleHash, c as VideoDraftInput, d as VideoDraftTrack, et as TrackRole, f as VideoDraftTrackItem, g as EntityIdKind, h as DslIdFactory, i as VideoDraft, j as DeepReadonly, k as ContainMutation, l as VideoDraftPartUnion, m as OpActor, n as DEFAULT_UNIT_TIME_MS, o as VideoDraftContent, p as CommitOptions, q as TextDelta, r as VideoCreationSettings, s as VideoDraftContentPartUnion, t as CaptionDisplayCue, tt as Voice, u as VideoDraftTimeline, v as relationId, w as CaptionContent, x as Asset, y as resourceId, z as MedeoDslSnapshot } from "./video-draft-types-c_shaRyq.js";
2
- import { A as AddDslClip, C as MedeoDslDraft, D as captionContentCodec, E as InvalidAtomic, F as ReplaceDslClipsInput, I as ClipPlacement, M as ClipSource, N as DslClipUpdate, O as isInvalidAtomic, P as MoveDslClipsInput, S as documentFormat, T as medeoDslLoroShape, _ as MedeoDsl, a as toVideoDraft, b as UnsupportedDocumentFormatError, c as DslLayout, d as createInitialMedeoDsl, f as DslEditor, g as CreateMedeoDslOptions, h as VoiceoverResult, i as VideoDraftProjection, j as AddDslClipsInput, k as timeAnchorCodec, l as DslProjectionError, m as VoiceoverCaptionInput, n as ImportedVideoDraft, o as resolveDslLayout, p as ApplyVoiceoverInput, r as fromVideoDraft, s as DslClipLayout, t as FromVideoDraftOptions, u as DslTrackLayout, v as DslAudit, w as MedeoDslLoroState, x as assertDslDocument, y as DslTransaction } from "./index-DKDMTXUe.js";
3
- import { A as MengineAuditResponse, B as base64ToBytes, C as MengineEventStreamOptions, D as MengineHttpRequestError, E as MengineHttpClientOptions, F as MengineRejectedResponse, I as MengineSnapshotResponse, L as MengineSseUpdateEvent, M as MengineDraftResponse, N as MenginePushResponse, O as MenginePushRejectedError, P as MenginePushUpdateResponse, R as MengineSyncResponse, S as PushResultKind, T as MengineHttpClient, V as bytesToBase64, _ as encodeDocVersionMark, a as MengineDocSessionOptions, b as PullResult, c as DocStorageLike, d as MedeoHttpDocStorageOptions, f as PushOutcome, g as decodeDocVersionMark, i as MengineAckFailedError, j as MengineDocumentVersion, k as MengineAuditEntry, l as MengineUndoState, m as ManualSyncDocOptions, o as MengineDocSyncState, p as PushOutcomeKind, s as WaitForServerAckOptions, t as MemoryDocStorage, u as MedeoHttpDocStorage, v as DocVersionMark, w as readMengineEventStream, x as PushResult, y as PullFailureReason, z as MengineUpdateMeta } from "./index-B7fC7q7P.js";
4
- import { n as MengineDocSessionUpdateEvent, r as ManualSyncDoc, t as MengineDocSession } from "./index-DQZUkrpg.js";
5
- export { type AddDslClip, type AddDslClipsInput, type ApplyVoiceoverInput, type Asset, type AudioScript, type Caption, type CaptionContent, type CaptionDisplayCue, type CaptionSelection, type CaptionStyle, type CaptionText, type Clip, type ClipPlacement, type ClipSource, type CommitOptions, type ContainMutation, type ContainNode, type CreateMedeoDslOptions, DEFAULT_UNIT_TIME_MS, type DeepReadonly, type DocStorageLike, type DocVersionMark, type DslAudit, type DslClipLayout, type DslClipUpdate, type DslDiagnostic, DslEditor, type DslIdFactory, type DslLayout, type DslMutation, DslProjectionError, type DslTrackLayout, type DslTransaction, type EntityIdKind, type EntityMutation, type EntityTable, type EntityTables, type EntityValues, type FieldPatch, type FromVideoDraftOptions, type ImportedVideoDraft, type InvalidAtomic, ManualSyncDoc, type ManualSyncDocOptions, MedeoDsl, type MedeoDslDraft, type MedeoDslLoroState, type MedeoDslSnapshot, MedeoHttpDocStorage, type MedeoHttpDocStorageOptions, type Media, MemoryDocStorage, MengineAckFailedError, type MengineAuditEntry, type MengineAuditResponse, MengineDocSession, type MengineDocSessionOptions, type MengineDocSessionUpdateEvent, type MengineDocSyncState, type MengineDocumentVersion, type MengineDraftResponse, type MengineEventStreamOptions, MengineHttpClient, type MengineHttpClientOptions, MengineHttpRequestError, MenginePushRejectedError, type MenginePushResponse, type MenginePushUpdateResponse, type MengineRejectedResponse, type MengineSnapshotResponse, type MengineSseUpdateEvent, type MengineSyncResponse, type MengineUndoState, type MengineUpdateMeta, type MoveDslClipsInput, type OpActor, type PullFailureReason, type PullResult, type PushOutcome, type PushOutcomeKind, type PushResult, type PushResultKind, type RelationMutation, type RelationTable, type RelationTables, type RelationValues, type ReplaceDslClipsInput, type ResourceSystem, type RichTextSnapshot, type TextDelta, type TextEdit, type TextMark, type TextMutation, type TextRun, type TimeAnchor, type Track, type TrackRole, UnsupportedDocumentFormatError, type VideoCreationSettings, type VideoDraft, type VideoDraftCaptionStyle, type VideoDraftContent, type VideoDraftContentPartUnion, type VideoDraftInput, type VideoDraftPartUnion, type VideoDraftProjection, type VideoDraftTimeline, type VideoDraftTrack, type VideoDraftTrackItem, type Voice, type VoiceoverCaptionInput, type VoiceoverResult, type WaitForServerAckOptions, assertDslDocument, base64ToBytes, bytesToBase64, captionContentCodec, createInitialMedeoDsl, decodeDocVersionMark, defaultIdFactory, documentFormat, encodeDocVersionMark, fromVideoDraft, isInvalidAtomic, medeoDslLoroShape, readMengineEventStream, relationId, resolveDslLayout, resourceId, timeAnchorCodec, toVideoDraft, tupleHash };
2
+ import { A as AddDslClip, C as MedeoDslDraft, D as captionContentCodec, E as InvalidAtomic, F as ReplaceDslClipsInput, I as ClipPlacement, M as ClipSource, N as DslClipUpdate, O as isInvalidAtomic, P as MoveDslClipsInput, S as documentFormat, T as medeoDslLoroShape, _ as MedeoDsl, a as toVideoDraft, b as UnsupportedDocumentFormatError, c as DslLayout, d as createInitialMedeoDsl, f as DslEditor, g as CreateMedeoDslOptions, h as VoiceoverResult, i as VideoDraftProjection, j as AddDslClipsInput, k as timeAnchorCodec, l as DslProjectionError, m as VoiceoverCaptionInput, n as ImportedVideoDraft, o as resolveDslLayout, p as ApplyVoiceoverInput, r as fromVideoDraft, s as DslClipLayout, t as FromVideoDraftOptions, u as DslTrackLayout, v as DslAudit, w as MedeoDslLoroState, x as assertDslDocument, y as DslTransaction } from "./index-Cu7SdKN5.js";
3
+ import { A as MenginePushRejectedError, B as MengineSyncResponse, C as PushResult, D as MengineHttpClient, E as readMengineEventStream, F as MenginePushResponse, H as base64ToBytes, I as MenginePushUpdateResponse, L as MengineRejectedResponse, M as MengineAuditResponse, N as MengineDocumentVersion, O as MengineHttpClientOptions, P as MengineDraftResponse, R as MengineSnapshotResponse, S as PullResult, T as MengineEventStreamOptions, U as bytesToBase64, V as MengineUpdateMeta, a as MengineDocSessionOptions, b as DocVersionMark, c as WaitForLocalSaveOptions, d as MengineUndoState, f as MedeoHttpDocStorage, g as ManualSyncDocOptions, h as PushOutcomeKind, i as MengineAckFailedError, j as MengineAuditEntry, k as MengineHttpRequestError, l as WaitForServerAckOptions, m as PushOutcome, o as MengineDocSyncState, p as MedeoHttpDocStorageOptions, s as MengineLocalSaveState, t as MemoryDocStorage, u as DocStorageLike, v as decodeDocVersionMark, w as PushResultKind, x as PullFailureReason, y as encodeDocVersionMark, z as MengineSseUpdateEvent } from "./index-D-3rdfUP.js";
4
+ import { n as MengineDocSessionUpdateEvent, r as ManualSyncDoc, t as MengineDocSession } from "./index-D-6uebu4.js";
5
+ export { type AddDslClip, type AddDslClipsInput, type ApplyVoiceoverInput, type Asset, type AudioScript, type Caption, type CaptionContent, type CaptionDisplayCue, type CaptionSelection, type CaptionStyle, type CaptionText, type Clip, type ClipPlacement, type ClipSource, type CommitOptions, type ContainMutation, type ContainNode, type CreateMedeoDslOptions, DEFAULT_UNIT_TIME_MS, type DeepReadonly, type DocStorageLike, type DocVersionMark, type DslAudit, type DslClipLayout, type DslClipUpdate, type DslDiagnostic, DslEditor, type DslIdFactory, type DslLayout, type DslMutation, DslProjectionError, type DslTrackLayout, type DslTransaction, type EntityIdKind, type EntityMutation, type EntityTable, type EntityTables, type EntityValues, type FieldPatch, type FromVideoDraftOptions, type ImportedVideoDraft, type InvalidAtomic, ManualSyncDoc, type ManualSyncDocOptions, MedeoDsl, type MedeoDslDraft, type MedeoDslLoroState, type MedeoDslSnapshot, MedeoHttpDocStorage, type MedeoHttpDocStorageOptions, type Media, MemoryDocStorage, MengineAckFailedError, type MengineAuditEntry, type MengineAuditResponse, MengineDocSession, type MengineDocSessionOptions, type MengineDocSessionUpdateEvent, type MengineDocSyncState, type MengineDocumentVersion, type MengineDraftResponse, type MengineEventStreamOptions, MengineHttpClient, type MengineHttpClientOptions, MengineHttpRequestError, type MengineLocalSaveState, MenginePushRejectedError, type MenginePushResponse, type MenginePushUpdateResponse, type MengineRejectedResponse, type MengineSnapshotResponse, type MengineSseUpdateEvent, type MengineSyncResponse, type MengineUndoState, type MengineUpdateMeta, type MoveDslClipsInput, type OpActor, type PullFailureReason, type PullResult, type PushOutcome, type PushOutcomeKind, type PushResult, type PushResultKind, type RelationMutation, type RelationTable, type RelationTables, type RelationValues, type ReplaceDslClipsInput, type ResourceSystem, type RichTextSnapshot, type TextDelta, type TextEdit, type TextMark, type TextMutation, type TextRun, type TimeAnchor, type Track, type TrackRole, UnsupportedDocumentFormatError, type VideoCreationSettings, type VideoDraft, type VideoDraftCaptionStyle, type VideoDraftContent, type VideoDraftContentPartUnion, type VideoDraftInput, type VideoDraftPartUnion, type VideoDraftProjection, type VideoDraftTimeline, type VideoDraftTrack, type VideoDraftTrackItem, type Voice, type VoiceoverCaptionInput, type VoiceoverResult, type WaitForLocalSaveOptions, type WaitForServerAckOptions, assertDslDocument, base64ToBytes, bytesToBase64, captionContentCodec, createInitialMedeoDsl, decodeDocVersionMark, defaultIdFactory, documentFormat, encodeDocVersionMark, fromVideoDraft, isInvalidAtomic, medeoDslLoroShape, readMengineEventStream, relationId, resolveDslLayout, resourceId, timeAnchorCodec, toVideoDraft, tupleHash };
package/dist/index.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import { n as bytesToBase64, t as base64ToBytes } from "./base64-D-jd-dr5.js";
2
2
  import { a as covers, c as readMengineEventStream, d as MenginePushRejectedError, i as openManualDocument, l as MengineHttpClient, n as MedeoHttpDocStorage, o as decodeDocVersionMark, r as ManualSyncTransport, s as encodeDocVersionMark, t as MemoryDocStorage, u as MengineHttpRequestError } from "./storage-BW3tI_ER.js";
3
- import { C as resourceId, S as relationId, a as documentFormat, c as isInvalidAtomic, i as assertDslDocument, l as timeAnchorCodec, o as medeoDslLoroShape, r as UnsupportedDocumentFormatError, s as captionContentCodec, t as DEFAULT_UNIT_TIME_MS, w as tupleHash, x as defaultIdFactory } from "./video-draft-types-DTXxvPt-.js";
4
- import { a as MedeoDsl, i as DslEditor, n as toVideoDraft, o as resolveDslLayout, r as createInitialMedeoDsl, s as DslProjectionError, t as fromVideoDraft } from "./dsl-Dkecq_2c.js";
5
- import { UndoManager, VersionVector } from "loro-crdt";
3
+ import { a as documentFormat, c as isInvalidAtomic, ct as relationId, i as assertDslDocument, l as timeAnchorCodec, lt as resourceId, o as medeoDslLoroShape, r as UnsupportedDocumentFormatError, s as captionContentCodec, st as defaultIdFactory, t as DEFAULT_UNIT_TIME_MS, ut as tupleHash } from "./video-draft-types-TXRv3wS6.js";
4
+ import { a as MedeoDsl, i as DslEditor, n as toVideoDraft, o as resolveDslLayout, r as createInitialMedeoDsl, s as DslProjectionError, t as fromVideoDraft } from "./dsl-EV6kCdr6.js";
5
+ import { UndoManager, VersionVector, decodeImportBlobMeta } from "loro-crdt";
6
6
  import { ClientServerSynchronizer, DocManager } from "@mengine/sync";
7
7
  import { DisposableSet, EventBus } from "@mengine/utils";
8
8
  //#region src/manual-sync/manual-sync-doc.ts
@@ -222,6 +222,7 @@ var DocumentSession = class {
222
222
  started = false;
223
223
  startTask = null;
224
224
  destroyed = false;
225
+ closeTask = null;
225
226
  lifetime = null;
226
227
  hasConnected = false;
227
228
  initialVersionValue = null;
@@ -438,6 +439,13 @@ var DocumentSession = class {
438
439
  this.local.connection.connect();
439
440
  await this.local.connection.waitForConnected().abortOn(this.lifetime.signal);
440
441
  if (this.destroyed) throw new Error("mengine doc session destroyed");
442
+ if (this.options.initialSnapshot) {
443
+ await this.local.pushDocUpdate({
444
+ docId: this.docId,
445
+ data: this.options.initialSnapshot
446
+ }, "initial-snapshot");
447
+ if (this.destroyed) throw new Error("mengine doc session destroyed");
448
+ }
441
449
  this.server.connection.connect();
442
450
  this.synchronizer.start();
443
451
  this.manager.start();
@@ -446,6 +454,10 @@ var DocumentSession = class {
446
454
  const doc = this.manager.connectDoc(this.docId);
447
455
  this.disposables.add(() => this.manager.disconnectDoc(this.docId));
448
456
  if (this.options.peerId != null) doc.setPeerId(this.options.peerId);
457
+ this.disposables.add(this.manager.onLocalUpdateReceived(this.docId, (update) => {
458
+ this.trackLocalVersion(decodeImportBlobMeta(update, true).partialEndVersionVector);
459
+ this.emitSyncState();
460
+ }));
449
461
  this.disposables.add(this.manager.onDocStateChange(this.docId, (state) => {
450
462
  this.events.emit("state", state);
451
463
  this.emitSyncState();
@@ -455,7 +467,7 @@ var DocumentSession = class {
455
467
  this.adapterValue = this.model(doc, this.mutationGuard);
456
468
  this.disposables.add(this.adapterValue.subscribe((source) => {
457
469
  if (!this.adapterValue) return;
458
- if (source === "local") this.localVersionValue = doc.version();
470
+ if (source === "local") this.trackLocalVersion(doc.version());
459
471
  this.emitSyncState();
460
472
  this.events.emit("update", {
461
473
  source,
@@ -470,9 +482,39 @@ var DocumentSession = class {
470
482
  this.undoManagerValue = new DocumentUndoManager(doc, this.mutationGuard, () => this.events.emit("undoState"));
471
483
  this.editorValue = this.adapterValue.editor;
472
484
  this.initialVersionValue = doc.version();
485
+ if (this.localVersionValue) this.trackLocalVersion(this.initialVersionValue);
473
486
  this.emitSyncState();
474
487
  return this.snapshot();
475
488
  }
489
+ getLocalSaveState() {
490
+ return this.getState().localSave;
491
+ }
492
+ /** Immediately reports local transaction state; independent of server confirmation. */
493
+ subscribeLocalSaveState(cb) {
494
+ const off = this.events.on("state", () => cb(this.getLocalSaveState()));
495
+ cb(this.getLocalSaveState());
496
+ return off;
497
+ }
498
+ /** Waits until all local saves finish, including edits made while waiting. Does not wait for the network. */
499
+ async waitForLocalSave(options = {}) {
500
+ if (!this.editorValue || this.destroyed) throw new Error("mengine doc session is not started");
501
+ await this.manager.waitForLocalSave(this.docId).timeout(options.timeoutMs ?? 15e3);
502
+ }
503
+ /** Stop accepting edits and drain local persistence before releasing resources.
504
+ * A failed local write keeps retrying, even after the host has unmounted.
505
+ * Hosts should use this for normal teardown; destroy() is immediate cancellation. */
506
+ close() {
507
+ if (this.closeTask) return this.closeTask;
508
+ if (this.destroyed || !this.editorValue) {
509
+ this.destroy();
510
+ return Promise.resolve();
511
+ }
512
+ this.mutationGuard.close();
513
+ this.synchronizer.stop();
514
+ this.server.connection.disconnect();
515
+ this.closeTask = this.manager.waitForLocalSave(this.docId).then(() => this.destroy());
516
+ return this.closeTask;
517
+ }
476
518
  getSyncState() {
477
519
  const state = this.getState();
478
520
  const target = this.confirmationTarget();
@@ -483,6 +525,14 @@ var DocumentSession = class {
483
525
  phase: connection === "disconnected" ? "offline" : this.pushErrorValue != null || state.error != null ? "failed" : connection === "connecting" ? "connecting" : state.syncing ? "syncing" : "idle"
484
526
  };
485
527
  }
528
+ trackLocalVersion(version) {
529
+ const target = VersionVector.parseJSON(this.confirmationTarget()?.toJSON() ?? /* @__PURE__ */ new Map());
530
+ for (const [peer, counter] of version.toJSON()) if ((target.get(peer) ?? 0) < counter) target.setEnd({
531
+ peer,
532
+ counter
533
+ });
534
+ this.localVersionValue = target;
535
+ }
486
536
  confirmationTarget() {
487
537
  return this.localVersionValue ?? this.initialVersionValue;
488
538
  }
package/dist/legacy.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { i as VideoDraft, l as VideoDraftPartUnion, o as VideoDraftContent, p as CommitOptions, t as CaptionDisplayCue } from "./video-draft-types-c_shaRyq.js";
2
- import { A as MengineAuditResponse, B as base64ToBytes, C as MengineEventStreamOptions, D as MengineHttpRequestError, E as MengineHttpClientOptions, F as MengineRejectedResponse, I as MengineSnapshotResponse, L as MengineSseUpdateEvent, M as MengineDraftResponse, N as MenginePushResponse, O as MenginePushRejectedError, P as MenginePushUpdateResponse, R as MengineSyncResponse, S as PushResultKind, T as MengineHttpClient, V as bytesToBase64, _ as encodeDocVersionMark, a as MengineDocSessionOptions, b as PullResult, c as DocStorageLike, d as MedeoHttpDocStorageOptions, f as PushOutcome, g as decodeDocVersionMark, h as ManualSyncTransport, j as MengineDocumentVersion, k as MengineAuditEntry, l as MengineUndoState, m as ManualSyncDocOptions, o as MengineDocSyncState, p as PushOutcomeKind, s as WaitForServerAckOptions, t as MemoryDocStorage, u as MedeoHttpDocStorage, v as DocVersionMark, w as readMengineEventStream, x as PushResult, y as PullFailureReason, z as MengineUpdateMeta } from "./index-B7fC7q7P.js";
2
+ import { A as MenginePushRejectedError, B as MengineSyncResponse, C as PushResult, D as MengineHttpClient, E as readMengineEventStream, F as MenginePushResponse, H as base64ToBytes, I as MenginePushUpdateResponse, L as MengineRejectedResponse, M as MengineAuditResponse, N as MengineDocumentVersion, O as MengineHttpClientOptions, P as MengineDraftResponse, R as MengineSnapshotResponse, S as PullResult, T as MengineEventStreamOptions, U as bytesToBase64, V as MengineUpdateMeta, _ as ManualSyncTransport, a as MengineDocSessionOptions, b as DocVersionMark, d as MengineUndoState, f as MedeoHttpDocStorage, g as ManualSyncDocOptions, h as PushOutcomeKind, j as MengineAuditEntry, k as MengineHttpRequestError, l as WaitForServerAckOptions, m as PushOutcome, o as MengineDocSyncState, p as MedeoHttpDocStorageOptions, t as MemoryDocStorage, u as DocStorageLike, v as decodeDocVersionMark, w as PushResultKind, x as PullFailureReason, y as encodeDocVersionMark, z as MengineSseUpdateEvent } from "./index-D-3rdfUP.js";
3
3
  import { LoroDoc, PeerID } from "loro-crdt";
4
4
 
5
5
  //#region ../medeo-dsl/depreacted/sandbox.d.ts
package/dist/legacy.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { n as bytesToBase64, t as base64ToBytes } from "./base64-D-jd-dr5.js";
2
2
  import { c as readMengineEventStream, d as MenginePushRejectedError, i as openManualDocument, l as MengineHttpClient, n as MedeoHttpDocStorage, o as decodeDocVersionMark, r as ManualSyncTransport, s as encodeDocVersionMark, t as MemoryDocStorage, u as MengineHttpRequestError } from "./storage-BW3tI_ER.js";
3
- import { a as documentFormat, r as UnsupportedDocumentFormatError, t as DEFAULT_UNIT_TIME_MS } from "./video-draft-types-DTXxvPt-.js";
3
+ import { a as documentFormat, r as UnsupportedDocumentFormatError, t as DEFAULT_UNIT_TIME_MS } from "./video-draft-types-TXRv3wS6.js";
4
4
  import { u as volumeSchema } from "./shared-iWnU2osE.js";
5
5
  import { sha256 } from "@noble/hashes/sha2.js";
6
6
  import { LoroDoc, LoroMap, LoroMovableList, LoroText, UndoManager } from "loro-crdt";
package/dist/testing.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { i as VideoDraft } from "./video-draft-types-c_shaRyq.js";
2
- import { _ as MedeoDsl } from "./index-DKDMTXUe.js";
2
+ import { _ as MedeoDsl } from "./index-Cu7SdKN5.js";
3
3
  import { LoroDoc } from "loro-crdt";
4
4
 
5
5
  //#region src/testing/in-memory-mengine-server.d.ts
package/dist/testing.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { n as bytesToBase64, t as base64ToBytes } from "./base64-D-jd-dr5.js";
2
- import { a as documentFormat, i as assertDslDocument } from "./video-draft-types-DTXxvPt-.js";
3
- import { a as MedeoDsl, i as DslEditor, n as toVideoDraft, r as createInitialMedeoDsl } from "./dsl-Dkecq_2c.js";
2
+ import { a as documentFormat, i as assertDslDocument } from "./video-draft-types-TXRv3wS6.js";
3
+ import { a as MedeoDsl, i as DslEditor, n as toVideoDraft, r as createInitialMedeoDsl } from "./dsl-EV6kCdr6.js";
4
4
  import { t as classifyUpdate } from "./loro-relay-doc-Bi6JKqtQ.js";
5
5
  import { LoroDoc, VersionVector, encodeFrontiers } from "loro-crdt";
6
6
  //#region src/testing/in-memory-mengine-server.ts