@mengine/medeo-client 1.2.0 → 1.2.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.
@@ -1,6 +1,7 @@
1
1
  import { Mirror, schema } from "loro-mirror";
2
2
  import { z } from "zod";
3
3
  import { LoroDoc } from "loro-crdt";
4
+ import { produce } from "immer";
4
5
  //#region src/client/base64.ts
5
6
  function bytesToBase64(bytes) {
6
7
  let binary = "";
@@ -1612,7 +1613,7 @@ function createMirrorVideoDocument(document, options = {}) {
1612
1613
  doc,
1613
1614
  schema: videoDocumentMirrorSchema
1614
1615
  }).setState((draft) => {
1615
- seedDraft(draft, document);
1616
+ writeVideoDocumentToDraft(draft, document);
1616
1617
  }, { origin: options.origin ?? "mengine.bootstrap" });
1617
1618
  return doc;
1618
1619
  }
@@ -1620,8 +1621,8 @@ function createMirrorVideoDocument(document, options = {}) {
1620
1621
  function createMirrorVideoDocumentAdapter(document, options) {
1621
1622
  return new MirrorVideoDocumentAdapter(createMirrorVideoDocument(document, options));
1622
1623
  }
1623
- /** Write a whole `VideoDocument` into the mirror draft (used to seed a fresh doc). */
1624
- function seedDraft(draft, document) {
1624
+ /** Write a whole `VideoDocument` into a draft (seed a fresh doc / plain-memory state). */
1625
+ function writeVideoDocumentToDraft(draft, document) {
1625
1626
  draft.meta = {
1626
1627
  schema_version: document.meta.schema_version,
1627
1628
  draft_id: document.meta.draft_id ?? void 0,
@@ -1651,4 +1652,119 @@ function toTrackRow(track) {
1651
1652
  };
1652
1653
  }
1653
1654
  //#endregion
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 };
1655
+ //#region src/editor/id-gen.ts
1656
+ /**
1657
+ * Part-id generation, aligned with the online ecosystem.
1658
+ *
1659
+ * The authoritative online producers — agent-harness (`@harness/shared`
1660
+ * `genObjId`) and director.v2 (`common/obj_id.py` `gen_obj_id`) — both mint part
1661
+ * ids as `` `${prefix}_${ulid()}` ``, and real captured drafts use exactly that
1662
+ * shape (`clip_…` / `spe_…` / `cap_…` / `bgm_…`, each a 26-char ULID). The engine
1663
+ * previously emitted `vc_<base36 timestamp><6 random>`, a different prefix AND a
1664
+ * different encoding — the sole cross-repo id divergence. This module removes it
1665
+ * by emitting the same `<prefix>_<ULID>` bytes.
1666
+ *
1667
+ * The ULID is generated inline (Crockford Base32, 48-bit time + 80-bit random)
1668
+ * rather than pulling the `ulid` npm package: the randomness class matches the
1669
+ * old generator (both `Math.random`-based) and it keeps `@mengine/medeo-client`
1670
+ * dependency-free for a purely mechanical id string. Part ids only need to be
1671
+ * unique and lexicographically time-sortable, which this satisfies.
1672
+ */
1673
+ /** Crockford Base32 alphabet (no I, L, O, U), per the ULID spec. */
1674
+ const CROCKFORD = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
1675
+ const TIME_LEN = 10;
1676
+ const RANDOM_LEN = 16;
1677
+ function encodeTime(now) {
1678
+ let out = "";
1679
+ let ms = now;
1680
+ for (let i = TIME_LEN - 1; i >= 0; i--) {
1681
+ const mod = ms % 32;
1682
+ out = CROCKFORD[mod] + out;
1683
+ ms = (ms - mod) / 32;
1684
+ }
1685
+ return out;
1686
+ }
1687
+ function encodeRandom() {
1688
+ let out = "";
1689
+ for (let i = 0; i < RANDOM_LEN; i++) out += CROCKFORD[Math.floor(Math.random() * 32)];
1690
+ return out;
1691
+ }
1692
+ /** A 26-char Crockford Base32 ULID (10-char time + 16-char random). */
1693
+ function ulid() {
1694
+ return encodeTime(Date.now()) + encodeRandom();
1695
+ }
1696
+ function generatePartId(prefix) {
1697
+ return `${prefix}_${ulid()}`;
1698
+ }
1699
+ //#endregion
1700
+ //#region src/document/plain-memory-adapter.ts
1701
+ /**
1702
+ * Pure in-memory `SemanticDocumentAdapter` — no Loro/WASM. Holds a
1703
+ * `VideoDocumentDraft` object and applies each `transact` via immer `produce`,
1704
+ * journaling every audit that actually mutated state (plus any ids minted
1705
+ * during that transact).
1706
+ *
1707
+ * Known benign difference vs `MirrorVideoDocumentAdapter`: the editor's
1708
+ * `setPart` assigns a fresh part object on every call, so a same-value rewrite
1709
+ * produces a new immer state and IS journaled here, while the mirror's deep
1710
+ * diff emits no commit. Terminal `snapshot()` stays equal; replay is idempotent.
1711
+ */
1712
+ var PlainMemoryAdapter = class {
1713
+ state;
1714
+ _journal = [];
1715
+ baseIdFactory;
1716
+ /** Non-null only while a `transact` edit callback is running. */
1717
+ pendingIds = null;
1718
+ /**
1719
+ * Recording wrapper around the underlying factory. Callers (sandbox editor)
1720
+ * use this so every minted id is appended to the current transact's list.
1721
+ */
1722
+ idFactory;
1723
+ constructor(document, options) {
1724
+ assertValidVideoDocument(document);
1725
+ const draft = {};
1726
+ writeVideoDocumentToDraft(draft, document);
1727
+ this.state = draft;
1728
+ this.baseIdFactory = options?.idFactory ?? generatePartId;
1729
+ this.idFactory = (prefix) => {
1730
+ const id = this.baseIdFactory(prefix);
1731
+ if (this.pendingIds != null) this.pendingIds.push(id);
1732
+ return id;
1733
+ };
1734
+ }
1735
+ get journal() {
1736
+ return this._journal;
1737
+ }
1738
+ hasContent() {
1739
+ return (this.state.meta?.schema_version ?? "") !== "";
1740
+ }
1741
+ snapshot() {
1742
+ return readVideoDocumentFromDraft(this.state);
1743
+ }
1744
+ /**
1745
+ * Apply one op via immer. A throw in `edit` discards the draft (state and
1746
+ * journal unchanged). When `produce` returns the same reference, there was
1747
+ * no structural change — skip journal, matching mirror "no change, no commit".
1748
+ */
1749
+ transact(edit, audit) {
1750
+ this.pendingIds = [];
1751
+ try {
1752
+ const next = produce(this.state, edit);
1753
+ if (next !== this.state) {
1754
+ this.state = next;
1755
+ this._journal.push({
1756
+ ...audit,
1757
+ generated_ids: this.pendingIds
1758
+ });
1759
+ }
1760
+ } finally {
1761
+ this.pendingIds = null;
1762
+ }
1763
+ }
1764
+ };
1765
+ /** Build a `PlainMemoryAdapter` seeded with `document`. */
1766
+ function createPlainMemoryAdapter(document, options) {
1767
+ return new PlainMemoryAdapter(document, options);
1768
+ }
1769
+ //#endregion
1770
+ export { resolveSpeechOverlapByShiftingVideos as A, partUnionToDraft as B, solveVideoDocument as C, reassignSpeechesToVideoClipsByTime as D, fillMainTrackTimeGaps as E, safeDurationMs as F, videoDocumentMirrorSchema as H, DEFAULT_UNIT_TIME_MS as I, VIDEO_DOCUMENT_SCHEMA_VERSION as L, TIMELINE_SKELETON_DURATION_MS as M, isEmptyVideoClip as N, recalculateTimelineDuration as O, partDurationMs as P, effectiveVideoClipDurationMs as R, laneTrackId as S, arrangeMainTrackSeamlessly as T, base64ToBytes as U, recordEntries as V, bytesToBase64 as W, partUnionSchema as _, createMirrorVideoDocument as a, ensureLaneTrack as b, readVideoDocumentFromDraft as c, derivePositionFromAbs as d, fromVideoDocument as f, validateVideoDocument as g, assertValidVideoDocument as h, MirrorVideoDocumentAdapter as i, syncAggregatedClipsTimePosition as j, resolveAllSpeechOverlaps as k, buildInitialVideoDocument as l, VideoDocumentValidationError as m, createPlainMemoryAdapter as n, createMirrorVideoDocumentAdapter as o, toVideoDocument as p, generatePartId as r, writeVideoDocumentToDraft as s, PlainMemoryAdapter as t, buildSpeechHostMap as u, videoDocumentSchema as v, cascadeAfterVideoClipChanges as w, findLaneTrack as x, LANE_KINDS_IN_STACK_ORDER as y, speedOf as z };