hyperframes 0.8.34 → 0.8.36

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.
@@ -446,6 +446,16 @@ function Tooltip({ label, children, delay: delay2 = 400, side = "top" }) {
446
446
 
447
447
  // src/player/components/Player.tsx
448
448
  import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
449
+ var playerModule = null;
450
+ function loadPlayerModule() {
451
+ playerModule ??= import("@hyperframes/player").catch((err) => {
452
+ playerModule = null;
453
+ throw err;
454
+ });
455
+ return playerModule;
456
+ }
457
+ if (typeof window !== "undefined") void loadPlayerModule().catch(() => {
458
+ });
449
459
  var MEDIA_HAVE_FUTURE_DATA = 3;
450
460
  var MEDIA_NETWORK_NO_SOURCE = 3;
451
461
  function isRecord(value) {
@@ -543,7 +553,7 @@ var Player = forwardRef2(
543
553
  if (!previewSource) return;
544
554
  let canceled = false;
545
555
  let cleanup;
546
- import("@hyperframes/player").then(() => {
556
+ void loadPlayerModule().then(() => {
547
557
  if (canceled) return;
548
558
  const player = document.createElement("hyperframes-player");
549
559
  const srcUrl = new URL(previewSource, window.location.origin);
@@ -3780,11 +3790,18 @@ function resolveScrubAudioEl(doc, musicId) {
3780
3790
  }
3781
3791
  return doc.querySelector("audio[data-timeline-role='music']") ?? doc.querySelector("audio");
3782
3792
  }
3793
+ function leaseScrubElement(el) {
3794
+ el.ownerDocument.defaultView?.__hf?.leasePausedMedia?.(el);
3795
+ }
3796
+ function releaseScrubElement(el) {
3797
+ el.ownerDocument.defaultView?.__hf?.releasePausedMedia?.(el);
3798
+ }
3783
3799
  function applyScrub(el, audioFileTime, previewVolume) {
3784
3800
  if (scrubAudioEl && scrubAudioEl !== el) stopScrubPreviewAudio();
3785
3801
  if (scrubPrevMuted === null) scrubPrevMuted = el.muted;
3786
3802
  if (scrubPrevVolume === null) scrubPrevVolume = el.volume;
3787
3803
  scrubAudioEl = el;
3804
+ leaseScrubElement(el);
3788
3805
  try {
3789
3806
  el.muted = false;
3790
3807
  el.volume = SCRUB_VOLUME * normalizePreviewVolume(previewVolume);
@@ -3820,6 +3837,7 @@ function stopScrubPreviewAudio() {
3820
3837
  const el = scrubAudioEl;
3821
3838
  scrubAudioEl = null;
3822
3839
  if (!el) return;
3840
+ releaseScrubElement(el);
3823
3841
  try {
3824
3842
  el.pause();
3825
3843
  if (scrubPrevMuted !== null) el.muted = scrubPrevMuted;
@@ -17303,7 +17321,6 @@ async function persistTimelineEdit(input) {
17303
17321
  throw new Error(`Unable to patch timeline element ${input.element.id} in ${targetPath}`);
17304
17322
  }
17305
17323
  input.pendingTimelineEditPathRef.current.add(targetPath);
17306
- input.domEditSaveTimestampRef.current = Date.now();
17307
17324
  await saveProjectFilesWithHistory({
17308
17325
  projectId: input.projectId,
17309
17326
  label: input.label,
@@ -17314,7 +17331,6 @@ async function persistTimelineEdit(input) {
17314
17331
  writeFile: input.writeProjectFile,
17315
17332
  recordEdit: input.recordEdit
17316
17333
  });
17317
- input.domEditSaveTimestampRef.current = Date.now();
17318
17334
  }
17319
17335
  async function persistTimelineBatchEdit(input) {
17320
17336
  const originals = /* @__PURE__ */ new Map();
@@ -17340,7 +17356,6 @@ async function persistTimelineBatchEdit(input) {
17340
17356
  for (const targetPath of Object.keys(files)) {
17341
17357
  input.pendingTimelineEditPathRef.current.add(targetPath);
17342
17358
  }
17343
- input.domEditSaveTimestampRef.current = Date.now();
17344
17359
  await saveProjectFilesWithHistory({
17345
17360
  projectId: input.projectId,
17346
17361
  label: input.label,
@@ -17352,7 +17367,6 @@ async function persistTimelineBatchEdit(input) {
17352
17367
  writeFile: input.writeProjectFile,
17353
17368
  recordEdit: input.recordEdit
17354
17369
  });
17355
- input.domEditSaveTimestampRef.current = Date.now();
17356
17370
  }
17357
17371
  async function persistElementAttribute({
17358
17372
  projectId,
@@ -17363,7 +17377,6 @@ async function persistElementAttribute({
17363
17377
  label,
17364
17378
  writeProjectFile,
17365
17379
  recordEdit,
17366
- domEditSaveTimestampRef,
17367
17380
  pendingTimelineEditPathRef,
17368
17381
  patchLive
17369
17382
  }) {
@@ -17376,7 +17389,6 @@ async function persistElementAttribute({
17376
17389
  const operation = { type: "attribute", property: attr, value };
17377
17390
  const patched = applyPatchByTarget(before, patchTarget, operation);
17378
17391
  pendingTimelineEditPathRef.current.add(targetPath);
17379
- domEditSaveTimestampRef.current = Date.now();
17380
17392
  try {
17381
17393
  const changedPaths = await saveProjectFilesWithHistory({
17382
17394
  projectId,
@@ -17387,7 +17399,6 @@ async function persistElementAttribute({
17387
17399
  writeFile: writeProjectFile,
17388
17400
  recordEdit
17389
17401
  });
17390
- domEditSaveTimestampRef.current = Date.now();
17391
17402
  return changedPaths;
17392
17403
  } catch (error) {
17393
17404
  patchLive(previousValue);
@@ -29983,28 +29994,15 @@ function roundRotationAngle(angle) {
29983
29994
  function normalizeStudioFileChangePath(path) {
29984
29995
  return path.trim().replace(/\\/g, "/").replace(/^\.?\//, "");
29985
29996
  }
29986
- function readStudioFileChangePathFromValue(value) {
29987
- if (typeof value === "string") {
29988
- const trimmed = value.trim();
29989
- if (!trimmed) return null;
29990
- if (trimmed.startsWith("{")) {
29991
- try {
29992
- return readStudioFileChangePathFromValue(JSON.parse(trimmed));
29993
- } catch {
29994
- return normalizeStudioFileChangePath(trimmed);
29995
- }
29996
- }
29997
- return normalizeStudioFileChangePath(trimmed);
29998
- }
29999
- if (!value || typeof value !== "object") return null;
30000
- const record = value;
30001
- if (typeof record.path === "string") return normalizeStudioFileChangePath(record.path);
30002
- if (typeof record.filePath === "string") return normalizeStudioFileChangePath(record.filePath);
30003
- if ("data" in record) return readStudioFileChangePathFromValue(record.data);
30004
- return null;
29997
+ function readFileChangeField(payload, key2) {
29998
+ if (!payload || typeof payload !== "object") return null;
29999
+ const record = payload;
30000
+ const value = record[key2];
30001
+ return typeof value === "string" ? value : null;
30005
30002
  }
30006
30003
  function readStudioFileChangePath(payload) {
30007
- return readStudioFileChangePathFromValue(payload);
30004
+ const path = readFileChangeField(payload, "path") ?? readFileChangeField(payload, "filePath");
30005
+ return path === null ? null : normalizeStudioFileChangePath(path);
30008
30006
  }
30009
30007
 
30010
30008
  // src/components/editor/gsapAnimatesProperty.ts
@@ -38851,7 +38849,6 @@ function isCutoverResult(value) {
38851
38849
  }
38852
38850
  async function rollbackWrite(targetPath, originalContent, expectedCurrentContent, deps, cause) {
38853
38851
  try {
38854
- deps.domEditSaveTimestampRef.current = Date.now();
38855
38852
  markSelfWrite(targetPath, originalContent);
38856
38853
  await deps.writeProjectFile(targetPath, originalContent, expectedCurrentContent);
38857
38854
  return cause;
@@ -38863,7 +38860,6 @@ async function rollbackWrite(targetPath, originalContent, expectedCurrentContent
38863
38860
  }
38864
38861
  }
38865
38862
  async function writeAndRecord(after, targetPath, originalContent, deps, options) {
38866
- deps.domEditSaveTimestampRef.current = Date.now();
38867
38863
  markSelfWrite(targetPath, after);
38868
38864
  try {
38869
38865
  await deps.writeProjectFile(targetPath, after, originalContent);
@@ -39301,7 +39297,6 @@ function useElementLifecycleOps({
39301
39297
  activeCompPath,
39302
39298
  showToast,
39303
39299
  writeProjectFile,
39304
- domEditSaveTimestampRef,
39305
39300
  editHistory,
39306
39301
  projectIdRef,
39307
39302
  reloadPreview,
@@ -39351,7 +39346,6 @@ function useElementLifecycleOps({
39351
39346
  return { ok: true };
39352
39347
  }
39353
39348
  }
39354
- domEditSaveTimestampRef.current = Date.now();
39355
39349
  const removeResponse = await fetch(
39356
39350
  buildProjectApiPath(
39357
39351
  pid,
@@ -39407,7 +39401,6 @@ function useElementLifecycleOps({
39407
39401
  [
39408
39402
  activeCompPath,
39409
39403
  clearDomSelection,
39410
- domEditSaveTimestampRef,
39411
39404
  editHistory.recordEdit,
39412
39405
  onTrySdkDelete,
39413
39406
  onElementDeleted,
@@ -42851,6 +42844,7 @@ function reportRegistration(report, native) {
42851
42844
  }
42852
42845
  }
42853
42846
  function buildStudioTools(depsRef) {
42847
+ const writeTool = (name, run) => (input, options) => runToolBody(name, () => run(depsRef.current, input, options?.signal));
42854
42848
  return [
42855
42849
  {
42856
42850
  name: "studio_look",
@@ -42915,9 +42909,9 @@ function buildStudioTools(depsRef) {
42915
42909
  description: STUDIO_SET_TEXT_DESCRIPTION,
42916
42910
  inputSchema: STUDIO_SET_TEXT_INPUT_SCHEMA,
42917
42911
  annotations: { readOnlyHint: false, untrustedContentHint: true },
42918
- execute: (input, { signal }) => runToolBody(
42912
+ execute: writeTool(
42919
42913
  "studio_set_text",
42920
- () => studioSetText(depsRef.current, input, signal)
42914
+ (deps, input, signal) => studioSetText(deps, input, signal)
42921
42915
  )
42922
42916
  },
42923
42917
  {
@@ -42926,9 +42920,9 @@ function buildStudioTools(depsRef) {
42926
42920
  description: STUDIO_SET_STYLE_DESCRIPTION,
42927
42921
  inputSchema: STUDIO_SET_STYLE_INPUT_SCHEMA,
42928
42922
  annotations: { readOnlyHint: false },
42929
- execute: (input, { signal }) => runToolBody(
42923
+ execute: writeTool(
42930
42924
  "studio_set_style",
42931
- () => studioSetStyle(depsRef.current, input, signal)
42925
+ (deps, input, signal) => studioSetStyle(deps, input, signal)
42932
42926
  )
42933
42927
  },
42934
42928
  {
@@ -42937,9 +42931,9 @@ function buildStudioTools(depsRef) {
42937
42931
  description: STUDIO_TRANSFORM_DESCRIPTION,
42938
42932
  inputSchema: STUDIO_TRANSFORM_INPUT_SCHEMA,
42939
42933
  annotations: { readOnlyHint: false },
42940
- execute: (input, { signal }) => runToolBody(
42934
+ execute: writeTool(
42941
42935
  "studio_transform",
42942
- () => studioTransform(depsRef.current, input, signal)
42936
+ (deps, input, signal) => studioTransform(deps, input, signal)
42943
42937
  )
42944
42938
  },
42945
42939
  {
@@ -42948,9 +42942,9 @@ function buildStudioTools(depsRef) {
42948
42942
  description: STUDIO_ADD_ANIMATION_DESCRIPTION,
42949
42943
  inputSchema: STUDIO_ADD_ANIMATION_INPUT_SCHEMA,
42950
42944
  annotations: { readOnlyHint: false },
42951
- execute: (input, { signal }) => runToolBody(
42945
+ execute: writeTool(
42952
42946
  "studio_add_animation",
42953
- () => studioAddAnimation(depsRef.current, input, signal)
42947
+ (deps, input, signal) => studioAddAnimation(deps, input, signal)
42954
42948
  )
42955
42949
  },
42956
42950
  {
@@ -42959,9 +42953,9 @@ function buildStudioTools(depsRef) {
42959
42953
  description: STUDIO_UPDATE_ANIMATION_DESCRIPTION,
42960
42954
  inputSchema: STUDIO_UPDATE_ANIMATION_INPUT_SCHEMA,
42961
42955
  annotations: { readOnlyHint: false },
42962
- execute: (input, { signal }) => runToolBody(
42956
+ execute: writeTool(
42963
42957
  "studio_update_animation",
42964
- () => studioUpdateAnimation(depsRef.current, input, signal)
42958
+ (deps, input, signal) => studioUpdateAnimation(deps, input, signal)
42965
42959
  )
42966
42960
  },
42967
42961
  {
@@ -42970,9 +42964,9 @@ function buildStudioTools(depsRef) {
42970
42964
  description: STUDIO_ADD_KEYFRAME_DESCRIPTION,
42971
42965
  inputSchema: STUDIO_ADD_KEYFRAME_INPUT_SCHEMA,
42972
42966
  annotations: { readOnlyHint: false },
42973
- execute: (input, { signal }) => runToolBody(
42967
+ execute: writeTool(
42974
42968
  "studio_add_keyframe",
42975
- () => studioAddKeyframe(depsRef.current, input, signal)
42969
+ (deps, input, signal) => studioAddKeyframe(deps, input, signal)
42976
42970
  )
42977
42971
  },
42978
42972
  {
@@ -42981,9 +42975,9 @@ function buildStudioTools(depsRef) {
42981
42975
  description: STUDIO_DELETE_ANIMATION_DESCRIPTION,
42982
42976
  inputSchema: STUDIO_DELETE_ANIMATION_INPUT_SCHEMA,
42983
42977
  annotations: { readOnlyHint: false },
42984
- execute: (input, { signal }) => runToolBody(
42978
+ execute: writeTool(
42985
42979
  "studio_delete_animation",
42986
- () => studioDeleteAnimation(depsRef.current, input, signal)
42980
+ (deps, input, signal) => studioDeleteAnimation(deps, input, signal)
42987
42981
  )
42988
42982
  }
42989
42983
  ];
@@ -65225,7 +65219,6 @@ function useEditorSave({
65225
65219
  readProjectFile,
65226
65220
  writeProjectFile,
65227
65221
  recordEdit,
65228
- domEditSaveTimestampRef,
65229
65222
  setRefreshKey,
65230
65223
  showToast
65231
65224
  }) {
@@ -65309,11 +65302,10 @@ function useEditorSave({
65309
65302
  if (saveRafRef.current != null) cancelAnimationFrame(saveRafRef.current);
65310
65303
  saveRafRef.current = requestAnimationFrame(() => {
65311
65304
  saveRafRef.current = null;
65312
- domEditSaveTimestampRef.current = Date.now();
65313
65305
  void persistCandidate(candidate);
65314
65306
  });
65315
65307
  },
65316
- [domEditSaveTimestampRef, editingPathRef, projectIdRef, persistCandidate]
65308
+ [editingPathRef, projectIdRef, persistCandidate]
65317
65309
  );
65318
65310
  const flushPendingSave = useCallback87(async () => {
65319
65311
  if (saveRafRef.current != null) {
@@ -65325,11 +65317,10 @@ function useEditorSave({
65325
65317
  return inFlightRef.current;
65326
65318
  }
65327
65319
  if (candidate) {
65328
- domEditSaveTimestampRef.current = Date.now();
65329
65320
  return persistCandidate(candidate);
65330
65321
  }
65331
65322
  return await inFlightRef.current ?? { status: "clean" };
65332
- }, [domEditSaveTimestampRef, persistCandidate]);
65323
+ }, [persistCandidate]);
65333
65324
  const discardPendingSave = useCallback87(() => {
65334
65325
  if (saveRafRef.current != null) cancelAnimationFrame(saveRafRef.current);
65335
65326
  saveRafRef.current = null;
@@ -65349,7 +65340,6 @@ function useFileManager({
65349
65340
  projectId,
65350
65341
  showToast,
65351
65342
  recordEdit,
65352
- domEditSaveTimestampRef,
65353
65343
  setRefreshKey
65354
65344
  }) {
65355
65345
  const [editingFile, setEditingFile] = useState103(null);
@@ -65488,7 +65478,6 @@ function useFileManager({
65488
65478
  readProjectFile,
65489
65479
  writeProjectFile,
65490
65480
  recordEdit,
65491
- domEditSaveTimestampRef,
65492
65481
  setRefreshKey,
65493
65482
  showToast
65494
65483
  });
@@ -66285,7 +66274,6 @@ function useRazorSplit({
66285
66274
  writeProjectFile,
66286
66275
  observeProjectFileVersion,
66287
66276
  recordEdit,
66288
- domEditSaveTimestampRef,
66289
66277
  reloadPreview,
66290
66278
  forceReloadSdkSession,
66291
66279
  isRecordingRef
@@ -66313,7 +66301,6 @@ function useRazorSplit({
66313
66301
  const intents = buildAtomicCutIntents(elements, splitTime, activeCompPath);
66314
66302
  const requestedCount = intents.reduce((count, file) => count + file.targets.length, 0);
66315
66303
  const label = mode === "single" ? "Split timeline clip" : `Split ${requestedCount} clips at ${splitTime.toFixed(2)}s`;
66316
- domEditSaveTimestampRef.current = Date.now();
66317
66304
  const result = await runAtomicCutTransaction({
66318
66305
  projectId: pid,
66319
66306
  intents,
@@ -66340,7 +66327,6 @@ function useRazorSplit({
66340
66327
  },
66341
66328
  [
66342
66329
  activeCompPath,
66343
- domEditSaveTimestampRef,
66344
66330
  observeProjectFileVersion,
66345
66331
  recordEdit,
66346
66332
  showToast,
@@ -66460,7 +66446,6 @@ function useTimelineAssetDropOps({
66460
66446
  showToast,
66461
66447
  writeProjectFile,
66462
66448
  recordEdit,
66463
- domEditSaveTimestampRef,
66464
66449
  reloadPreview,
66465
66450
  uploadProjectFiles,
66466
66451
  isRecordingRef,
@@ -66511,7 +66496,6 @@ function useTimelineAssetDropOps({
66511
66496
  )
66512
66497
  })
66513
66498
  );
66514
- domEditSaveTimestampRef.current = Date.now();
66515
66499
  await saveProjectFilesWithHistory({
66516
66500
  projectId: pid,
66517
66501
  label: "Add timeline asset",
@@ -66535,7 +66519,6 @@ function useTimelineAssetDropOps({
66535
66519
  showToast,
66536
66520
  timelineElements,
66537
66521
  writeProjectFile,
66538
- domEditSaveTimestampRef,
66539
66522
  reloadPreview,
66540
66523
  isRecordingRef,
66541
66524
  forceReloadSdkSession
@@ -66595,7 +66578,6 @@ function useTimelineAssetDropOps({
66595
66578
  resync: forceReloadSdkSession,
66596
66579
  refresh: reloadPreview
66597
66580
  });
66598
- domEditSaveTimestampRef.current = Date.now();
66599
66581
  showToast("Composition added to the timeline.", "info");
66600
66582
  } catch (error) {
66601
66583
  showToast(
@@ -66606,7 +66588,6 @@ function useTimelineAssetDropOps({
66606
66588
  },
66607
66589
  [
66608
66590
  activeCompPath,
66609
- domEditSaveTimestampRef,
66610
66591
  forceReloadSdkSession,
66611
66592
  isRecordingRef,
66612
66593
  observeProjectFileVersion,
@@ -66680,7 +66661,6 @@ async function setAudioGroupAttribute({
66680
66661
  previewIframe,
66681
66662
  writeProjectFile,
66682
66663
  recordEdit,
66683
- domEditSaveTimestampRef,
66684
66664
  pendingTimelineEditPathRef
66685
66665
  }) {
66686
66666
  const groupEl = previewIframe?.contentDocument?.getElementById(groupId) ?? null;
@@ -66696,7 +66676,6 @@ async function setAudioGroupAttribute({
66696
66676
  label,
66697
66677
  writeProjectFile,
66698
66678
  recordEdit,
66699
- domEditSaveTimestampRef,
66700
66679
  pendingTimelineEditPathRef,
66701
66680
  patchLive: (v) => patchLiveGroupAttribute(previewIframe, groupId, attr, v)
66702
66681
  });
@@ -66707,7 +66686,6 @@ function useSetAudioGroupAttribute({
66707
66686
  showToast,
66708
66687
  writeProjectFile,
66709
66688
  recordEdit,
66710
- domEditSaveTimestampRef,
66711
66689
  previewIframeRef,
66712
66690
  pendingTimelineEditPathRef,
66713
66691
  isRecordingRef
@@ -66738,7 +66716,6 @@ function useSetAudioGroupAttribute({
66738
66716
  previewIframe: previewIframeRef.current,
66739
66717
  writeProjectFile,
66740
66718
  recordEdit,
66741
- domEditSaveTimestampRef,
66742
66719
  pendingTimelineEditPathRef
66743
66720
  });
66744
66721
  syncStoredGroupAttribute(groupId, attr, value);
@@ -66755,7 +66732,6 @@ function useSetAudioGroupAttribute({
66755
66732
  previewIframeRef,
66756
66733
  writeProjectFile,
66757
66734
  recordEdit,
66758
- domEditSaveTimestampRef,
66759
66735
  pendingTimelineEditPathRef,
66760
66736
  isRecordingRef,
66761
66737
  showToast,
@@ -66783,7 +66759,6 @@ async function setElementAttribute({
66783
66759
  previewIframe,
66784
66760
  writeProjectFile,
66785
66761
  recordEdit,
66786
- domEditSaveTimestampRef,
66787
66762
  pendingTimelineEditPathRef
66788
66763
  }) {
66789
66764
  const targetPath = element.sourceFile || activeCompPath || "index.html";
@@ -66798,7 +66773,6 @@ async function setElementAttribute({
66798
66773
  label,
66799
66774
  writeProjectFile,
66800
66775
  recordEdit,
66801
- domEditSaveTimestampRef,
66802
66776
  pendingTimelineEditPathRef,
66803
66777
  patchLive: (v) => patchLiveElementAttribute(previewIframe, element, attr, v, activeCompPath)
66804
66778
  });
@@ -66809,7 +66783,6 @@ function useSetElementAttribute({
66809
66783
  showToast,
66810
66784
  writeProjectFile,
66811
66785
  recordEdit,
66812
- domEditSaveTimestampRef,
66813
66786
  previewIframeRef,
66814
66787
  pendingTimelineEditPathRef,
66815
66788
  isRecordingRef
@@ -66839,7 +66812,6 @@ function useSetElementAttribute({
66839
66812
  previewIframe: previewIframeRef.current,
66840
66813
  writeProjectFile,
66841
66814
  recordEdit,
66842
- domEditSaveTimestampRef,
66843
66815
  pendingTimelineEditPathRef
66844
66816
  });
66845
66817
  } catch (error) {
@@ -66853,7 +66825,6 @@ function useSetElementAttribute({
66853
66825
  previewIframeRef,
66854
66826
  writeProjectFile,
66855
66827
  recordEdit,
66856
- domEditSaveTimestampRef,
66857
66828
  pendingTimelineEditPathRef,
66858
66829
  isRecordingRef,
66859
66830
  showToast,
@@ -66872,7 +66843,6 @@ function useTimelineDeleteOps({
66872
66843
  showToast,
66873
66844
  writeProjectFile,
66874
66845
  recordEdit,
66875
- domEditSaveTimestampRef,
66876
66846
  reloadPreview,
66877
66847
  isRecordingRef,
66878
66848
  forceReloadSdkSession,
@@ -66925,7 +66895,6 @@ function useTimelineDeleteOps({
66925
66895
  if (deleteContentEnd > 0 && targetPath === (activeCompPath || "index.html")) {
66926
66896
  usePlayerStore.getState().setDuration(deleteContentEnd);
66927
66897
  }
66928
- domEditSaveTimestampRef.current = Date.now();
66929
66898
  try {
66930
66899
  await saveProjectFilesWithHistory({
66931
66900
  projectId: pid,
@@ -66965,7 +66934,6 @@ function useTimelineDeleteOps({
66965
66934
  showToast,
66966
66935
  timelineElements,
66967
66936
  writeProjectFile,
66968
- domEditSaveTimestampRef,
66969
66937
  reloadPreview,
66970
66938
  isRecordingRef,
66971
66939
  forceReloadSdkSession,
@@ -67028,7 +66996,6 @@ async function setElementsHidden({
67028
66996
  previewIframe,
67029
66997
  writeProjectFile,
67030
66998
  recordEdit,
67031
- domEditSaveTimestampRef,
67032
66999
  pendingTimelineEditPathRef
67033
67000
  }) {
67034
67001
  if (elements.length === 0) return [];
@@ -67058,7 +67025,6 @@ async function setElementsHidden({
67058
67025
  files[targetPath] = patchedContent;
67059
67026
  pendingTimelineEditPathRef.current.add(targetPath);
67060
67027
  }
67061
- domEditSaveTimestampRef.current = Date.now();
67062
67028
  const changedPaths = await saveProjectFilesWithHistory({
67063
67029
  projectId,
67064
67030
  label,
@@ -67072,7 +67038,6 @@ async function setElementsHidden({
67072
67038
  writeFile: writeProjectFile,
67073
67039
  recordEdit
67074
67040
  });
67075
- domEditSaveTimestampRef.current = Date.now();
67076
67041
  for (const element of elements) {
67077
67042
  usePlayerStore.getState().updateElement(element.key ?? element.id, { hidden });
67078
67043
  }
@@ -67093,7 +67058,6 @@ async function toggleTimelineTrackHidden({
67093
67058
  previewIframe,
67094
67059
  writeProjectFile,
67095
67060
  recordEdit,
67096
- domEditSaveTimestampRef,
67097
67061
  pendingTimelineEditPathRef
67098
67062
  }) {
67099
67063
  const suffix = trackDisplaySuffix(
@@ -67111,7 +67075,6 @@ async function toggleTimelineTrackHidden({
67111
67075
  previewIframe,
67112
67076
  writeProjectFile,
67113
67077
  recordEdit,
67114
- domEditSaveTimestampRef,
67115
67078
  pendingTimelineEditPathRef
67116
67079
  });
67117
67080
  }
@@ -67124,7 +67087,6 @@ async function toggleTimelineElementHidden({
67124
67087
  previewIframe,
67125
67088
  writeProjectFile,
67126
67089
  recordEdit,
67127
- domEditSaveTimestampRef,
67128
67090
  pendingTimelineEditPathRef
67129
67091
  }) {
67130
67092
  const keys = new Set(typeof elementKey2 === "string" ? [elementKey2] : elementKey2);
@@ -67138,7 +67100,6 @@ async function toggleTimelineElementHidden({
67138
67100
  previewIframe,
67139
67101
  writeProjectFile,
67140
67102
  recordEdit,
67141
- domEditSaveTimestampRef,
67142
67103
  pendingTimelineEditPathRef
67143
67104
  });
67144
67105
  }
@@ -67148,7 +67109,6 @@ function useTimelineTrackVisibilityEditing({
67148
67109
  showToast,
67149
67110
  writeProjectFile,
67150
67111
  recordEdit,
67151
- domEditSaveTimestampRef,
67152
67112
  previewIframeRef,
67153
67113
  pendingTimelineEditPathRef,
67154
67114
  isRecordingRef,
@@ -67174,7 +67134,6 @@ function useTimelineTrackVisibilityEditing({
67174
67134
  previewIframe: previewIframeRef.current,
67175
67135
  writeProjectFile,
67176
67136
  recordEdit,
67177
- domEditSaveTimestampRef,
67178
67137
  pendingTimelineEditPathRef
67179
67138
  });
67180
67139
  forceReloadSdkSession?.();
@@ -67190,7 +67149,6 @@ function useTimelineTrackVisibilityEditing({
67190
67149
  previewIframeRef,
67191
67150
  writeProjectFile,
67192
67151
  recordEdit,
67193
- domEditSaveTimestampRef,
67194
67152
  pendingTimelineEditPathRef,
67195
67153
  isRecordingRef,
67196
67154
  showToast,
@@ -67205,7 +67163,6 @@ function useTimelineElementVisibilityEditing({
67205
67163
  showToast,
67206
67164
  writeProjectFile,
67207
67165
  recordEdit,
67208
- domEditSaveTimestampRef,
67209
67166
  previewIframeRef,
67210
67167
  pendingTimelineEditPathRef,
67211
67168
  isRecordingRef,
@@ -67230,7 +67187,6 @@ function useTimelineElementVisibilityEditing({
67230
67187
  previewIframe: previewIframeRef.current,
67231
67188
  writeProjectFile,
67232
67189
  recordEdit,
67233
- domEditSaveTimestampRef,
67234
67190
  pendingTimelineEditPathRef
67235
67191
  });
67236
67192
  forceReloadSdkSession?.();
@@ -67246,7 +67202,6 @@ function useTimelineElementVisibilityEditing({
67246
67202
  previewIframeRef,
67247
67203
  writeProjectFile,
67248
67204
  recordEdit,
67249
- domEditSaveTimestampRef,
67250
67205
  pendingTimelineEditPathRef,
67251
67206
  isRecordingRef,
67252
67207
  showToast,
@@ -67313,7 +67268,6 @@ async function createAudioGroupAndAssignMembers({
67313
67268
  previewIframe,
67314
67269
  writeProjectFile,
67315
67270
  recordEdit,
67316
- domEditSaveTimestampRef,
67317
67271
  pendingTimelineEditPathRef
67318
67272
  }) {
67319
67273
  if (elements.length < 2) {
@@ -67361,7 +67315,6 @@ async function createAudioGroupAndAssignMembers({
67361
67315
  files[groupPath] = withGroupElement;
67362
67316
  pendingTimelineEditPathRef.current.add(groupPath);
67363
67317
  }
67364
- domEditSaveTimestampRef.current = Date.now();
67365
67318
  const changedPaths = await saveProjectFilesWithHistory({
67366
67319
  projectId,
67367
67320
  label: groupLabel2 ? `Group ${elements.length} clips as ${groupLabel2}` : `Group ${elements.length} voice clips`,
@@ -67375,7 +67328,6 @@ async function createAudioGroupAndAssignMembers({
67375
67328
  writeFile: writeProjectFile,
67376
67329
  recordEdit
67377
67330
  });
67378
- domEditSaveTimestampRef.current = Date.now();
67379
67331
  for (const element of elements) {
67380
67332
  usePlayerStore.getState().updateElement(element.key ?? element.id, { audioGroup: groupId });
67381
67333
  }
@@ -67395,7 +67347,6 @@ function useAudioGroupCarveAssignment({
67395
67347
  showToast,
67396
67348
  writeProjectFile,
67397
67349
  recordEdit,
67398
- domEditSaveTimestampRef,
67399
67350
  previewIframeRef,
67400
67351
  pendingTimelineEditPathRef,
67401
67352
  isRecordingRef
@@ -67430,7 +67381,6 @@ function useAudioGroupCarveAssignment({
67430
67381
  previewIframe: previewIframeRef.current,
67431
67382
  writeProjectFile,
67432
67383
  recordEdit,
67433
- domEditSaveTimestampRef,
67434
67384
  pendingTimelineEditPathRef
67435
67385
  });
67436
67386
  } catch (error) {
@@ -67446,7 +67396,6 @@ function useAudioGroupCarveAssignment({
67446
67396
  previewIframeRef,
67447
67397
  writeProjectFile,
67448
67398
  recordEdit,
67449
- domEditSaveTimestampRef,
67450
67399
  pendingTimelineEditPathRef,
67451
67400
  isRecordingRef,
67452
67401
  showToast,
@@ -67481,7 +67430,6 @@ function resizeHasPlaybackStartAdjustment(change) {
67481
67430
  }
67482
67431
  function useTimelineGroupEditing({
67483
67432
  activeCompPath,
67484
- domEditSaveTimestampRef,
67485
67433
  editQueueRef,
67486
67434
  forceReloadSdkSession,
67487
67435
  invalidateGsapCache,
@@ -67524,7 +67472,6 @@ function useTimelineGroupEditing({
67524
67472
  changes: batchChanges,
67525
67473
  writeProjectFile,
67526
67474
  recordEdit,
67527
- domEditSaveTimestampRef,
67528
67475
  pendingTimelineEditPathRef,
67529
67476
  coalesceKey,
67530
67477
  coalesceMs
@@ -67533,7 +67480,6 @@ function useTimelineGroupEditing({
67533
67480
  },
67534
67481
  [
67535
67482
  activeCompPath,
67536
- domEditSaveTimestampRef,
67537
67483
  forceReloadSdkSession,
67538
67484
  pendingTimelineEditPathRef,
67539
67485
  recordEdit,
@@ -67553,7 +67499,6 @@ function useTimelineGroupEditing({
67553
67499
  editHistory: { recordEdit },
67554
67500
  writeProjectFile,
67555
67501
  reloadPreview,
67556
- domEditSaveTimestampRef,
67557
67502
  compositionPath: activeCompPath,
67558
67503
  readProjectFile: (path) => readFileContent(projectIdRef.current ?? "", path),
67559
67504
  publishSession: publishSdkSession
@@ -67569,7 +67514,6 @@ function useTimelineGroupEditing({
67569
67514
  },
67570
67515
  [
67571
67516
  activeCompPath,
67572
- domEditSaveTimestampRef,
67573
67517
  projectIdRef,
67574
67518
  publishSdkSession,
67575
67519
  recordEdit,
@@ -67793,7 +67737,6 @@ function useTimelineEditing({
67793
67737
  writeProjectFile,
67794
67738
  observeProjectFileVersion,
67795
67739
  recordEdit,
67796
- domEditSaveTimestampRef,
67797
67740
  reloadPreview,
67798
67741
  previewIframeRef,
67799
67742
  pendingTimelineEditPathRef,
@@ -67825,7 +67768,6 @@ function useTimelineEditing({
67825
67768
  buildPatches,
67826
67769
  writeProjectFile,
67827
67770
  recordEdit,
67828
- domEditSaveTimestampRef,
67829
67771
  pendingTimelineEditPathRef,
67830
67772
  coalesceKey
67831
67773
  })
@@ -67841,7 +67783,6 @@ function useTimelineEditing({
67841
67783
  activeCompPath,
67842
67784
  recordEdit,
67843
67785
  writeProjectFile,
67844
- domEditSaveTimestampRef,
67845
67786
  pendingTimelineEditPathRef,
67846
67787
  showToast,
67847
67788
  isRecordingRef,
@@ -67850,7 +67791,6 @@ function useTimelineEditing({
67850
67791
  );
67851
67792
  const groupEditing = useTimelineGroupEditing({
67852
67793
  activeCompPath,
67853
- domEditSaveTimestampRef,
67854
67794
  editQueueRef,
67855
67795
  forceReloadSdkSession,
67856
67796
  invalidateGsapCache,
@@ -67935,7 +67875,6 @@ function useTimelineEditing({
67935
67875
  editHistory: { recordEdit },
67936
67876
  writeProjectFile,
67937
67877
  reloadPreview,
67938
- domEditSaveTimestampRef,
67939
67878
  compositionPath: activeCompPath,
67940
67879
  // Capture on-disk bytes as the undo `before` so undoing a timing move
67941
67880
  // restores the file verbatim, not a normalized full-DOM re-emit.
@@ -67966,7 +67905,6 @@ function useTimelineEditing({
67966
67905
  recordEdit,
67967
67906
  writeProjectFile,
67968
67907
  reloadPreview,
67969
- domEditSaveTimestampRef,
67970
67908
  timelineElements,
67971
67909
  handleDomZIndexReorderCommitRef,
67972
67910
  showToast,
@@ -68021,7 +67959,6 @@ function useTimelineEditing({
68021
67959
  editHistory: { recordEdit },
68022
67960
  writeProjectFile,
68023
67961
  reloadPreview,
68024
- domEditSaveTimestampRef,
68025
67962
  compositionPath: activeCompPath,
68026
67963
  // Capture on-disk bytes as the undo `before` so undoing a timing
68027
67964
  // resize restores the file verbatim, not a normalized full-DOM re-emit.
@@ -68048,7 +67985,6 @@ function useTimelineEditing({
68048
67985
  recordEdit,
68049
67986
  writeProjectFile,
68050
67987
  reloadPreview,
68051
- domEditSaveTimestampRef,
68052
67988
  showToast,
68053
67989
  invalidateGsapCache
68054
67990
  ]
@@ -68060,7 +67996,6 @@ function useTimelineEditing({
68060
67996
  showToast,
68061
67997
  writeProjectFile,
68062
67998
  recordEdit,
68063
- domEditSaveTimestampRef,
68064
67999
  previewIframeRef,
68065
68000
  pendingTimelineEditPathRef,
68066
68001
  isRecordingRef,
@@ -68072,7 +68007,6 @@ function useTimelineEditing({
68072
68007
  showToast,
68073
68008
  writeProjectFile,
68074
68009
  recordEdit,
68075
- domEditSaveTimestampRef,
68076
68010
  previewIframeRef,
68077
68011
  pendingTimelineEditPathRef,
68078
68012
  isRecordingRef,
@@ -68084,7 +68018,6 @@ function useTimelineEditing({
68084
68018
  showToast,
68085
68019
  writeProjectFile,
68086
68020
  recordEdit,
68087
- domEditSaveTimestampRef,
68088
68021
  previewIframeRef,
68089
68022
  pendingTimelineEditPathRef,
68090
68023
  isRecordingRef
@@ -68095,7 +68028,6 @@ function useTimelineEditing({
68095
68028
  showToast,
68096
68029
  writeProjectFile,
68097
68030
  recordEdit,
68098
- domEditSaveTimestampRef,
68099
68031
  previewIframeRef,
68100
68032
  pendingTimelineEditPathRef,
68101
68033
  isRecordingRef
@@ -68106,7 +68038,6 @@ function useTimelineEditing({
68106
68038
  showToast,
68107
68039
  writeProjectFile,
68108
68040
  recordEdit,
68109
- domEditSaveTimestampRef,
68110
68041
  previewIframeRef,
68111
68042
  pendingTimelineEditPathRef,
68112
68043
  isRecordingRef
@@ -68118,7 +68049,6 @@ function useTimelineEditing({
68118
68049
  showToast,
68119
68050
  writeProjectFile,
68120
68051
  recordEdit,
68121
- domEditSaveTimestampRef,
68122
68052
  reloadPreview,
68123
68053
  isRecordingRef,
68124
68054
  forceReloadSdkSession,
@@ -68131,7 +68061,6 @@ function useTimelineEditing({
68131
68061
  showToast,
68132
68062
  writeProjectFile,
68133
68063
  recordEdit,
68134
- domEditSaveTimestampRef,
68135
68064
  reloadPreview,
68136
68065
  uploadProjectFiles,
68137
68066
  isRecordingRef,
@@ -68146,7 +68075,6 @@ function useTimelineEditing({
68146
68075
  writeProjectFile,
68147
68076
  observeProjectFileVersion,
68148
68077
  recordEdit,
68149
- domEditSaveTimestampRef,
68150
68078
  reloadPreview,
68151
68079
  isRecordingRef,
68152
68080
  forceReloadSdkSession
@@ -68929,7 +68857,7 @@ function usePreviewInteraction({
68929
68857
  const wasPlaying = usePlayerStore.getState().isPlaying;
68930
68858
  pausePreviewPlayback();
68931
68859
  const resumeIfNothingSelected = () => {
68932
- if (wasPlaying) usePlayerStore.getState().setIsPlaying(true);
68860
+ if (wasPlaying) usePlayerStore.getState().requestPlayback(true);
68933
68861
  };
68934
68862
  if (isDoubleClick && !e.shiftKey) {
68935
68863
  const hit = await resolveDomSelectionFromPreviewPoint(e.clientX, e.clientY);
@@ -70480,7 +70408,6 @@ function useDomEditCommits({
70480
70408
  showToast,
70481
70409
  queueDomEditSave,
70482
70410
  writeProjectFile,
70483
- domEditSaveTimestampRef,
70484
70411
  editHistory,
70485
70412
  fileTree,
70486
70413
  importedFontAssetsRef,
@@ -70570,7 +70497,6 @@ function useDomEditCommits({
70570
70497
  );
70571
70498
  }
70572
70499
  }
70573
- domEditSaveTimestampRef.current = Date.now();
70574
70500
  const patchResponse = await fetch(
70575
70501
  buildProjectApiPath(pid, `/file-mutations/patch-element/${encodeURIComponent(targetPath)}`),
70576
70502
  {
@@ -70643,7 +70569,6 @@ function useDomEditCommits({
70643
70569
  editHistory,
70644
70570
  writeProjectFile,
70645
70571
  projectIdRef,
70646
- domEditSaveTimestampRef,
70647
70572
  reloadPreview,
70648
70573
  showToast,
70649
70574
  forceReloadSdkSession,
@@ -70684,7 +70609,6 @@ function useDomEditCommits({
70684
70609
  { alreadyToasted: true }
70685
70610
  );
70686
70611
  }
70687
- domEditSaveTimestampRef.current = Date.now();
70688
70612
  const atomicResult = await patchElementBatches(pid, batches);
70689
70613
  const allMatched = atomicResult.durable && atomicResult.files.every((result) => result.allMatched);
70690
70614
  const files = Object.fromEntries(
@@ -70722,15 +70646,7 @@ function useDomEditCommits({
70722
70646
  throw error;
70723
70647
  });
70724
70648
  },
70725
- [
70726
- domEditSaveTimestampRef,
70727
- editHistory,
70728
- forceReloadSdkSession,
70729
- projectIdRef,
70730
- queueDomEditSave,
70731
- reloadPreview,
70732
- showToast
70733
- ]
70649
+ [editHistory, forceReloadSdkSession, projectIdRef, queueDomEditSave, reloadPreview, showToast]
70734
70650
  );
70735
70651
  const {
70736
70652
  handleDomStyleCommit,
@@ -70777,7 +70693,6 @@ function useDomEditCommits({
70777
70693
  activeCompPath,
70778
70694
  showToast,
70779
70695
  writeProjectFile,
70780
- domEditSaveTimestampRef,
70781
70696
  editHistory,
70782
70697
  projectIdRef,
70783
70698
  reloadPreview,
@@ -70835,7 +70750,6 @@ function computeGroupGeometry(members) {
70835
70750
  }
70836
70751
  async function commitStructuralMutation(pid, targetPath, route, body, label, deps) {
70837
70752
  const originalContent = await readProjectFileContent(pid, targetPath);
70838
- deps.domEditSaveTimestampRef.current = Date.now();
70839
70753
  const mutateResponse = await fetch(
70840
70754
  buildProjectApiPath(pid, `/file-mutations/${route}/${encodeURIComponent(targetPath)}`),
70841
70755
  {
@@ -72161,7 +72075,7 @@ function instantPatchesFor(options) {
72161
72075
  ...options.instantPatch ? [options.instantPatch] : []
72162
72076
  ];
72163
72077
  }
72164
- function useGsapScriptCommits({ projectIdRef, activeCompPath, previewIframeRef, editHistory, domEditSaveTimestampRef, reloadPreview, onCacheInvalidate, onFileContentChanged, showToast, sdkSession, publishSdkSession, writeProjectFile, forceReloadSdkSession }) {
72078
+ function useGsapScriptCommits({ projectIdRef, activeCompPath, previewIframeRef, editHistory, reloadPreview, onCacheInvalidate, onFileContentChanged, showToast, sdkSession, publishSdkSession, writeProjectFile, forceReloadSdkSession }) {
72165
72079
  const activeProjectId = projectIdRef.current;
72166
72080
  const activeCompPathRef = useRef127(activeCompPath);
72167
72081
  activeCompPathRef.current = activeCompPath;
@@ -72190,7 +72104,6 @@ function useGsapScriptCommits({ projectIdRef, activeCompPath, previewIframeRef,
72190
72104
  }
72191
72105
  return;
72192
72106
  }
72193
- if (previewIsActive) domEditSaveTimestampRef.current = Date.now();
72194
72107
  await recordMutationEdit(targetPath, result, options);
72195
72108
  if (!isActiveCommitTarget(projectIdRef, activeCompPathRef, projectId, compositionPath)) return;
72196
72109
  syncCommittedGsapMutation({
@@ -72205,7 +72118,7 @@ function useGsapScriptCommits({ projectIdRef, activeCompPath, previewIframeRef,
72205
72118
  reloadPreview,
72206
72119
  onCacheInvalidate
72207
72120
  });
72208
- }, [projectIdRef, previewIframeRef, domEditSaveTimestampRef, reloadPreview, onCacheInvalidate, onFileContentChanged, forceReloadSdkSession, recordMutationEdit]);
72121
+ }, [projectIdRef, previewIframeRef, reloadPreview, onCacheInvalidate, onFileContentChanged, forceReloadSdkSession, recordMutationEdit]);
72209
72122
  const runCommit = useCallback115(async (pid, compositionPath, targetPath, selection, mutation, options) => {
72210
72123
  const result = await runMutationRequest(
72211
72124
  [mutation],
@@ -72304,7 +72217,6 @@ function useGsapScriptCommits({ projectIdRef, activeCompPath, previewIframeRef,
72304
72217
  editHistory: { recordEdit: editHistory.recordEdit },
72305
72218
  writeProjectFile,
72306
72219
  reloadPreview,
72307
- domEditSaveTimestampRef,
72308
72220
  refresh: sdkRefresh,
72309
72221
  compositionPath: activeCompPath,
72310
72222
  readProjectFile: readProjectFileContent2,
@@ -72314,7 +72226,6 @@ function useGsapScriptCommits({ projectIdRef, activeCompPath, previewIframeRef,
72314
72226
  editHistory.recordEdit,
72315
72227
  writeProjectFile,
72316
72228
  reloadPreview,
72317
- domEditSaveTimestampRef,
72318
72229
  sdkRefresh,
72319
72230
  activeCompPath,
72320
72231
  readProjectFileContent2,
@@ -74215,7 +74126,6 @@ function useDomEditSession({
74215
74126
  readProjectFile,
74216
74127
  writeProjectFile,
74217
74128
  updateEditingFileContent,
74218
- domEditSaveTimestampRef,
74219
74129
  editHistory,
74220
74130
  fileTree,
74221
74131
  importedFontAssetsRef,
@@ -74328,7 +74238,6 @@ function useDomEditSession({
74328
74238
  activeCompPath,
74329
74239
  previewIframeRef,
74330
74240
  editHistory,
74331
- domEditSaveTimestampRef,
74332
74241
  reloadPreview,
74333
74242
  onCacheInvalidate: bumpGsapCache,
74334
74243
  onFileContentChanged: updateEditingFileContent,
@@ -74363,7 +74272,6 @@ function useDomEditSession({
74363
74272
  showToast,
74364
74273
  queueDomEditSave,
74365
74274
  writeProjectFile,
74366
- domEditSaveTimestampRef,
74367
74275
  editHistory,
74368
74276
  fileTree,
74369
74277
  importedFontAssetsRef,
@@ -74391,7 +74299,6 @@ function useDomEditSession({
74391
74299
  editHistory,
74392
74300
  writeProjectFile,
74393
74301
  reloadPreview,
74394
- domEditSaveTimestampRef,
74395
74302
  compositionPath: activeCompPath,
74396
74303
  readProjectFile,
74397
74304
  publishSession: publishSdkSession
@@ -74403,7 +74310,6 @@ function useDomEditSession({
74403
74310
  editHistory,
74404
74311
  writeProjectFile,
74405
74312
  reloadPreview,
74406
- domEditSaveTimestampRef,
74407
74313
  compositionPath: activeCompPath,
74408
74314
  readProjectFile,
74409
74315
  publishSession: publishSdkSession
@@ -74422,7 +74328,6 @@ function useDomEditSession({
74422
74328
  activeCompPath,
74423
74329
  showToast,
74424
74330
  writeProjectFile,
74425
- domEditSaveTimestampRef,
74426
74331
  editHistory,
74427
74332
  projectIdRef,
74428
74333
  reloadPreview,
@@ -74954,23 +74859,23 @@ function testHotAdapter() {
74954
74859
  const candidate = value;
74955
74860
  return typeof candidate.on === "function" && typeof candidate.off === "function" ? candidate : null;
74956
74861
  }
74957
- function readFileChangeContent(payload) {
74958
- if (!payload || typeof payload !== "object") return null;
74959
- const record = payload;
74960
- if (typeof record.content === "string") return record.content;
74961
- return "data" in record ? readFileChangeContent(record.data) : null;
74962
- }
74963
- function readFileChangeVersion(payload) {
74964
- if (!payload || typeof payload !== "object") return null;
74965
- const record = payload;
74966
- if (typeof record.version === "string") return record.version;
74967
- return "data" in record ? readFileChangeVersion(record.data) : null;
74862
+ var readFileChangeContent = (payload) => readFileChangeField(payload, "content");
74863
+ var readFileChangeVersion = (payload) => readFileChangeField(payload, "version");
74864
+ var readFileChangeWriteToken = (payload) => readFileChangeField(payload, "writeToken");
74865
+ function decodeFileChange(delivery) {
74866
+ const data = delivery?.data;
74867
+ if (typeof data !== "string") return delivery;
74868
+ try {
74869
+ return JSON.parse(data);
74870
+ } catch {
74871
+ logReload("file-change", { path: null, why: "unparseable payload" });
74872
+ return null;
74873
+ }
74968
74874
  }
74969
- function readFileChangeWriteToken(payload) {
74970
- if (!payload || typeof payload !== "object") return null;
74971
- const record = payload;
74972
- if (typeof record.writeToken === "string") return record.writeToken;
74973
- return "data" in record ? readFileChangeWriteToken(record.data) : null;
74875
+ function sseFileChangeChannel(onDelivery) {
74876
+ const eventSource = new EventSource("/api/events");
74877
+ eventSource.addEventListener("file-change", onDelivery);
74878
+ return () => eventSource.close();
74974
74879
  }
74975
74880
  function eventIdentity(path, payload) {
74976
74881
  const version = readFileChangeVersion(payload);
@@ -75183,7 +75088,10 @@ function useExternalFileChangeCoordinator({
75183
75088
  // fallow-ignore-next-line complexity
75184
75089
  (payload) => {
75185
75090
  const path = readStudioFileChangePath(payload);
75186
- if (!path || !projectId) return;
75091
+ if (!path || !projectId) {
75092
+ logReload("file-change", { path: null, why: path ? "no project" : "no path in payload" });
75093
+ return;
75094
+ }
75187
75095
  pendingTimelineEditPathRef.current.delete(path);
75188
75096
  const content = readFileChangeContent(payload);
75189
75097
  const token = readFileChangeWriteToken(payload);
@@ -75210,7 +75118,7 @@ function useExternalFileChangeCoordinator({
75210
75118
  [projectId, pendingTimelineEditPathRef, startDrainLoop, onAcceptedPersistedFileChange]
75211
75119
  );
75212
75120
  useEffect106(() => {
75213
- const handler = (payload) => processChange(payload);
75121
+ const handler = (delivery) => processChange(decodeFileChange(delivery));
75214
75122
  const adapter = testHotAdapter();
75215
75123
  if (adapter) {
75216
75124
  adapter.on("hf:file-change", handler);
@@ -75220,9 +75128,7 @@ function useExternalFileChangeCoordinator({
75220
75128
  import.meta.hot.on("hf:file-change", handler);
75221
75129
  return () => import.meta.hot?.off?.("hf:file-change", handler);
75222
75130
  }
75223
- const eventSource = new EventSource("/api/events");
75224
- eventSource.addEventListener("file-change", handler);
75225
- return () => eventSource.close();
75131
+ return sseFileChangeChannel(handler);
75226
75132
  }, [processChange]);
75227
75133
  const retry = useCallback125(async () => {
75228
75134
  const current = blockedRef.current;
@@ -75872,7 +75778,6 @@ function useAppHotkeys({
75872
75778
  readOptionalProjectFile,
75873
75779
  readProjectFile,
75874
75780
  writeProjectFile,
75875
- domEditSaveTimestampRef,
75876
75781
  showToast,
75877
75782
  syncHistoryPreviewAfterApply,
75878
75783
  waitForPendingDomEditSaves,
@@ -75896,10 +75801,9 @@ function useAppHotkeys({
75896
75801
  );
75897
75802
  const writeHistoryFile = useCallback128(
75898
75803
  async (path, content) => {
75899
- domEditSaveTimestampRef.current = Date.now();
75900
75804
  await writeProjectFile(path, content);
75901
75805
  },
75902
- [domEditSaveTimestampRef, writeProjectFile]
75806
+ [writeProjectFile]
75903
75807
  );
75904
75808
  const serializeHistoryFiles = useCallback128(
75905
75809
  (paths, task) => serializeStudioFileMutations(writeProjectFile, paths, task),
@@ -76135,7 +76039,6 @@ function useClipboard({
76135
76039
  showToast,
76136
76040
  writeProjectFile,
76137
76041
  recordEdit,
76138
- domEditSaveTimestampRef,
76139
76042
  reloadPreview,
76140
76043
  handleTimelineElementDelete,
76141
76044
  handleDomEditElementDelete,
@@ -76230,7 +76133,6 @@ function useClipboard({
76230
76133
  payload.originSelectorIndex
76231
76134
  );
76232
76135
  }
76233
- domEditSaveTimestampRef.current = Date.now();
76234
76136
  await saveProjectFilesWithHistory({
76235
76137
  projectId: pid,
76236
76138
  label: payload.kind === "timeline-clip" ? "Paste clip" : "Paste element",
@@ -76246,14 +76148,7 @@ function useClipboard({
76246
76148
  const message = error instanceof Error ? error.message : "Failed to paste";
76247
76149
  showToast(message);
76248
76150
  }
76249
- }, [
76250
- activeCompPath,
76251
- domEditSaveTimestampRef,
76252
- recordEdit,
76253
- reloadPreview,
76254
- showToast,
76255
- writeProjectFile
76256
- ]);
76151
+ }, [activeCompPath, recordEdit, reloadPreview, showToast, writeProjectFile]);
76257
76152
  const handleCut = useCallback129(async () => {
76258
76153
  const copied = handleCopy2();
76259
76154
  if (!copied) return false;
@@ -85276,7 +85171,6 @@ function useVariablesPersist({
85276
85171
  writeProjectFile,
85277
85172
  recordEdit,
85278
85173
  reloadPreview,
85279
- domEditSaveTimestampRef,
85280
85174
  publishSdkSession
85281
85175
  }) {
85282
85176
  return useCallback160(
@@ -85292,7 +85186,6 @@ function useVariablesPersist({
85292
85186
  editHistory: { recordEdit },
85293
85187
  writeProjectFile,
85294
85188
  reloadPreview,
85295
- domEditSaveTimestampRef,
85296
85189
  compositionPath: activeCompPath,
85297
85190
  readProjectFile,
85298
85191
  publishSession: publishSdkSession
@@ -85309,7 +85202,6 @@ function useVariablesPersist({
85309
85202
  writeProjectFile,
85310
85203
  recordEdit,
85311
85204
  reloadPreview,
85312
- domEditSaveTimestampRef,
85313
85205
  publishSdkSession
85314
85206
  ]
85315
85207
  );
@@ -85361,7 +85253,7 @@ function useProjectCompositionVariables(fileTree, excludePath, readProjectFile,
85361
85253
  return groups;
85362
85254
  }
85363
85255
  function useEditVariablesInFile(deps) {
85364
- const { readProjectFile, writeProjectFile, recordEdit, reloadPreview, domEditSaveTimestampRef } = deps;
85256
+ const { readProjectFile, writeProjectFile, recordEdit, reloadPreview } = deps;
85365
85257
  return useCallback161(
85366
85258
  async (path, label, mutate) => {
85367
85259
  const originalContent = await readProjectFile(path);
@@ -85381,14 +85273,13 @@ function useEditVariablesInFile(deps) {
85381
85273
  editHistory: { recordEdit },
85382
85274
  writeProjectFile,
85383
85275
  reloadPreview,
85384
- domEditSaveTimestampRef,
85385
85276
  compositionPath: path,
85386
85277
  readProjectFile
85387
85278
  },
85388
85279
  { label }
85389
85280
  );
85390
85281
  },
85391
- [readProjectFile, writeProjectFile, recordEdit, reloadPreview, domEditSaveTimestampRef]
85282
+ [readProjectFile, writeProjectFile, recordEdit, reloadPreview]
85392
85283
  );
85393
85284
  }
85394
85285
 
@@ -85724,8 +85615,7 @@ function VariablesOtherCompositions({
85724
85615
  readProjectFile,
85725
85616
  writeProjectFile,
85726
85617
  recordEdit,
85727
- reloadPreview,
85728
- domEditSaveTimestampRef
85618
+ reloadPreview
85729
85619
  }) {
85730
85620
  const [selfRefresh, setSelfRefresh] = useState144(0);
85731
85621
  const groups = useProjectCompositionVariables(
@@ -85738,8 +85628,7 @@ function VariablesOtherCompositions({
85738
85628
  readProjectFile,
85739
85629
  writeProjectFile,
85740
85630
  recordEdit,
85741
- reloadPreview,
85742
- domEditSaveTimestampRef
85631
+ reloadPreview
85743
85632
  });
85744
85633
  const [editingKey, setEditingKey] = useState144(null);
85745
85634
  const onSave = useCallback162(
@@ -85942,7 +85831,6 @@ var VariablesPanel = memo51(function VariablesPanel2({
85942
85831
  sdkSession,
85943
85832
  publishSdkSession,
85944
85833
  reloadPreview,
85945
- domEditSaveTimestampRef,
85946
85834
  recordEdit
85947
85835
  }) {
85948
85836
  const { activeCompPath, showToast } = useStudioShellContext();
@@ -85966,7 +85854,6 @@ var VariablesPanel = memo51(function VariablesPanel2({
85966
85854
  writeProjectFile,
85967
85855
  recordEdit,
85968
85856
  reloadPreview,
85969
- domEditSaveTimestampRef,
85970
85857
  publishSdkSession
85971
85858
  });
85972
85859
  const declarations = useMemo72(
@@ -86201,8 +86088,7 @@ var VariablesPanel = memo51(function VariablesPanel2({
86201
86088
  readProjectFile,
86202
86089
  writeProjectFile,
86203
86090
  recordEdit,
86204
- reloadPreview,
86205
- domEditSaveTimestampRef
86091
+ reloadPreview
86206
86092
  }
86207
86093
  )
86208
86094
  ] })
@@ -86284,7 +86170,6 @@ function useSlideshowPersist({
86284
86170
  writeProjectFile,
86285
86171
  recordEdit,
86286
86172
  reloadPreview,
86287
- domEditSaveTimestampRef,
86288
86173
  publishSdkSession,
86289
86174
  coalesceKey
86290
86175
  }) {
@@ -86301,7 +86186,6 @@ function useSlideshowPersist({
86301
86186
  editHistory: { recordEdit },
86302
86187
  writeProjectFile,
86303
86188
  reloadPreview,
86304
- domEditSaveTimestampRef,
86305
86189
  readProjectFile,
86306
86190
  publishSession: publishSdkSession
86307
86191
  },
@@ -86315,7 +86199,6 @@ function useSlideshowPersist({
86315
86199
  writeProjectFile,
86316
86200
  recordEdit,
86317
86201
  reloadPreview,
86318
- domEditSaveTimestampRef,
86319
86202
  publishSdkSession,
86320
86203
  coalesceKey
86321
86204
  ]
@@ -86571,7 +86454,6 @@ async function applyColorGradingScopeUpdate({
86571
86454
  selectedSourceFile,
86572
86455
  fileTree,
86573
86456
  projectId,
86574
- domEditSaveTimestampRef,
86575
86457
  waitForPendingDomEditSaves,
86576
86458
  readProjectFile,
86577
86459
  writeProjectFile,
@@ -86596,7 +86478,6 @@ async function applyColorGradingScopeUpdate({
86596
86478
  showToast("No color grading changed", "info");
86597
86479
  return EMPTY_COLOR_GRADING_SCOPE_RESULT;
86598
86480
  }
86599
- domEditSaveTimestampRef.current = Date.now();
86600
86481
  const changedPaths = await saveProjectFilesWithHistory({
86601
86482
  projectId,
86602
86483
  label: value ? "Apply color grading" : "Clear color grading",
@@ -86718,7 +86599,6 @@ function StudioRightPanel({
86718
86599
  publishSdkSession,
86719
86600
  forceReloadSdkSession,
86720
86601
  reloadPreview,
86721
- domEditSaveTimestampRef,
86722
86602
  recordEdit,
86723
86603
  onToggleElementHidden,
86724
86604
  onAutoGroupCarveSources,
@@ -86809,7 +86689,6 @@ function StudioRightPanel({
86809
86689
  writeProjectFile,
86810
86690
  recordEdit,
86811
86691
  reloadPreview,
86812
- domEditSaveTimestampRef,
86813
86692
  publishSdkSession
86814
86693
  });
86815
86694
  const onPersistSlideshowNotes = useSlideshowPersist({
@@ -86819,7 +86698,6 @@ function StudioRightPanel({
86819
86698
  writeProjectFile,
86820
86699
  recordEdit,
86821
86700
  reloadPreview,
86822
- domEditSaveTimestampRef,
86823
86701
  publishSdkSession,
86824
86702
  coalesceKey: activeCompPath ? `slideshow-notes:${activeCompPath}` : "slideshow-notes"
86825
86703
  });
@@ -86859,7 +86737,6 @@ function StudioRightPanel({
86859
86737
  selectedSourceFile: domEditSelection?.sourceFile || activeCompPath || "index.html",
86860
86738
  fileTree,
86861
86739
  projectId,
86862
- domEditSaveTimestampRef,
86863
86740
  waitForPendingDomEditSaves,
86864
86741
  readProjectFile,
86865
86742
  writeProjectFile,
@@ -86875,7 +86752,6 @@ function StudioRightPanel({
86875
86752
  }),
86876
86753
  [
86877
86754
  activeCompPath,
86878
- domEditSaveTimestampRef,
86879
86755
  domEditSelection?.sourceFile,
86880
86756
  fileTree,
86881
86757
  projectId,
@@ -86912,7 +86788,6 @@ function StudioRightPanel({
86912
86788
  writeProjectFile,
86913
86789
  recordEdit,
86914
86790
  reloadPreview,
86915
- domEditSaveTimestampRef,
86916
86791
  forceReloadSharedSdkSession: forceReloadSdkSession,
86917
86792
  children: /* @__PURE__ */ jsx205(
86918
86793
  PropertyPanel,
@@ -87085,7 +86960,6 @@ function StudioRightPanel({
87085
86960
  sdkSession,
87086
86961
  publishSdkSession,
87087
86962
  reloadPreview,
87088
- domEditSaveTimestampRef,
87089
86963
  recordEdit
87090
86964
  }
87091
86965
  ) : layersPaneOpen && designPaneOpen && !STUDIO_FLAT_INSPECTOR_ENABLED ? /* @__PURE__ */ jsxs170("div", { ref: splitContainerRef, className: "flex h-full min-h-0 min-w-0 flex-col", children: [
@@ -89595,7 +89469,6 @@ function StudioApp() {
89595
89469
  rightPanelTab: initialUrlStateRef.current.rightPanelTab
89596
89470
  });
89597
89471
  const editHistory = usePersistentEditHistory({ projectId });
89598
- const domEditSaveTimestampRef = useRef171(0);
89599
89472
  const handleDomZIndexReorderCommitRef = useRef171(null);
89600
89473
  const pendingTimelineEditPathRef = useRef171(/* @__PURE__ */ new Set());
89601
89474
  const isGestureRecordingRef = useRef171(false);
@@ -89604,7 +89477,6 @@ function StudioApp() {
89604
89477
  projectId,
89605
89478
  showToast,
89606
89479
  recordEdit: editHistory.recordEdit,
89607
- domEditSaveTimestampRef,
89608
89480
  setRefreshKey
89609
89481
  });
89610
89482
  const masterCompPath = useMemo77(
@@ -89653,7 +89525,6 @@ function StudioApp() {
89653
89525
  writeProjectFile: fileManager.writeProjectFile,
89654
89526
  observeProjectFileVersion: fileManager.observeProjectFileVersion,
89655
89527
  recordEdit: editHistory.recordEdit,
89656
- domEditSaveTimestampRef,
89657
89528
  reloadPreview,
89658
89529
  previewIframeRef,
89659
89530
  pendingTimelineEditPathRef,
@@ -89718,7 +89589,6 @@ function StudioApp() {
89718
89589
  showToast,
89719
89590
  writeProjectFile: fileManager.writeProjectFile,
89720
89591
  recordEdit: editHistory.recordEdit,
89721
- domEditSaveTimestampRef,
89722
89592
  reloadPreview,
89723
89593
  handleTimelineElementDelete: timelineEditing.handleTimelineElementDelete,
89724
89594
  handleDomEditElementDelete: domEditDeleteBridge,
@@ -89734,7 +89604,6 @@ function StudioApp() {
89734
89604
  readOptionalProjectFile: fileManager.readOptionalProjectFile,
89735
89605
  readProjectFile: fileManager.readProjectFile,
89736
89606
  writeProjectFile: fileManager.writeProjectFile,
89737
- domEditSaveTimestampRef,
89738
89607
  showToast,
89739
89608
  syncHistoryPreviewAfterApply: previewPersistence.syncHistoryPreviewAfterApply,
89740
89609
  waitForPendingDomEditSaves: previewPersistence.waitForPendingDomEditSaves,
@@ -89775,7 +89644,6 @@ function StudioApp() {
89775
89644
  readProjectFile: fileManager.readProjectFile,
89776
89645
  writeProjectFile: fileManager.writeProjectFile,
89777
89646
  updateEditingFileContent: fileManager.updateEditingFileContent,
89778
- domEditSaveTimestampRef,
89779
89647
  editHistory: { recordEdit: editHistory.recordEdit },
89780
89648
  fileTree: fileManager.fileTree,
89781
89649
  importedFontAssetsRef: fileManager.importedFontAssetsRef,
@@ -90022,7 +89890,6 @@ function StudioApp() {
90022
89890
  publishSdkSession: sdkHandle.publish,
90023
89891
  forceReloadSdkSession: sdkHandle.forceReload,
90024
89892
  reloadPreview,
90025
- domEditSaveTimestampRef,
90026
89893
  recordEdit: editHistory.recordEdit,
90027
89894
  onToggleElementHidden: timelineEditing.handleToggleElementHidden,
90028
89895
  onAutoGroupCarveSources: timelineEditing.handleAutoGroupCarveSources,