@hyperframes/studio 0.8.130 → 0.8.132

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.
package/dist/index.d.ts CHANGED
@@ -272,6 +272,8 @@ interface PlaybackReadinessSlice {
272
272
  previewBooted: boolean;
273
273
  setTimelineReady: (ready: boolean) => void;
274
274
  markPreviewBooted: () => void;
275
+ playLocked: boolean;
276
+ setPlayLocked: (locked: boolean) => void;
275
277
  /** Sets timelineReady once doc's readiness inputs settle, or immediately
276
278
  * if doc is null. A wait a later call supersedes never wins the race.
277
279
  * Waits for doc's load step first: it pauses and rewinds the preview, so a
@@ -2865,6 +2867,7 @@ declare function usePersistentEditHistory({ projectId }: UsePersistentEditHistor
2865
2867
  }[];
2866
2868
  };
2867
2869
  recordEdit: ({ label, coalesceKey, coalesceMs, files, created }: RecordEditInput$5) => Promise<void>;
2870
+ claimKey: (key: string) => string;
2868
2871
  undo: (callbacks: ApplyCallbacks) => Promise<ApplyResult>;
2869
2872
  redo: (callbacks: ApplyCallbacks) => Promise<ApplyResult>;
2870
2873
  predict: (direction: "undo" | "redo") => {
package/dist/index.html CHANGED
@@ -14,7 +14,7 @@
14
14
  document.documentElement.dataset.theme = "paper";
15
15
  }
16
16
  </script>
17
- <script type="module" crossorigin src="/assets/index-DDsV6l9T.js"></script>
17
+ <script type="module" crossorigin src="/assets/index-oE1pOdAy.js"></script>
18
18
  <link rel="stylesheet" crossorigin href="/assets/index-D11atkBt.css">
19
19
  </head>
20
20
  <body>
package/dist/index.js CHANGED
@@ -39,7 +39,7 @@ import {
39
39
  usePreviewVariablesStore,
40
40
  whenPreviewBooted,
41
41
  writeStudioUiPreferences
42
- } from "./chunk-DRVWEPO5.js";
42
+ } from "./chunk-FOEID72M.js";
43
43
  import {
44
44
  Button,
45
45
  ContextMenu,
@@ -28278,6 +28278,7 @@ function usePlaybackKeyboard({
28278
28278
  );
28279
28279
  const shuttle = useCallback38(
28280
28280
  (direction) => {
28281
+ if (usePlayerStore.getState().playLocked) return;
28281
28282
  if (shuttleDirectionRef.current === direction) {
28282
28283
  shuttleSpeedIndexRef.current = Math.min(
28283
28284
  shuttleSpeedIndexRef.current + 1,
@@ -31213,7 +31214,7 @@ function useTimelinePlayerLoop({
31213
31214
  const looping = usePlayerStore.getState().loopEnabled && dur > 0;
31214
31215
  setLoopStart(looping ? loopStart : null);
31215
31216
  if (time >= loopEnd) {
31216
- if (looping) {
31217
+ if (looping && !usePlayerStore.getState().playLocked) {
31217
31218
  adapter.seek(loopStart, { keepPlaying: true });
31218
31219
  liveTime.notify(loopStart);
31219
31220
  adapter.play();
@@ -31506,7 +31507,7 @@ function pumpProbeQueue() {
31506
31507
 
31507
31508
  // src/player/lib/playbackSeek.ts
31508
31509
  function shouldResumeForwardPlaybackAfterSeek(input) {
31509
- return input.keepPlaying && !input.wasReverseShuttle && input.storeWasPlaying && (input.duration <= 0 || input.nextTime < input.duration);
31510
+ return !input.playLocked && input.keepPlaying && !input.wasReverseShuttle && input.storeWasPlaying && (input.duration <= 0 || input.nextTime < input.duration);
31510
31511
  }
31511
31512
  function shouldStopAfterSeek(input) {
31512
31513
  return !input.keepPlaying || input.wasReverseShuttle;
@@ -31709,7 +31710,8 @@ function useTimelinePlayer({
31709
31710
  applyPreviewAudioFlags(iframeRef.current, audioMuted, audioVolume);
31710
31711
  }, []);
31711
31712
  const play = useCallback42(() => {
31712
- if (!usePlayerStore.getState().timelineReady) return;
31713
+ const { timelineReady, playLocked } = usePlayerStore.getState();
31714
+ if (!timelineReady || playLocked) return;
31713
31715
  stopRAFLoop();
31714
31716
  stopReverseLoop();
31715
31717
  stopScrubPreviewAudio();
@@ -31793,9 +31795,8 @@ function useTimelinePlayer({
31793
31795
  const pause = useCallback42(() => {
31794
31796
  stopReverseLoop();
31795
31797
  const adapter = getAdapter();
31796
- if (!adapter) return;
31797
- adapter.pause();
31798
- setCurrentTime(adapter.getTime());
31798
+ adapter?.pause();
31799
+ if (adapter) setCurrentTime(adapter.getTime());
31799
31800
  setIsPlaying(false);
31800
31801
  shuttleDirectionRef.current = null;
31801
31802
  shuttleSpeedIndexRef.current = 0;
@@ -31813,17 +31814,19 @@ function useTimelinePlayer({
31813
31814
  const duration = Math.max(0, adapter.getDuration());
31814
31815
  const nextTime = clampToDuration(time, duration);
31815
31816
  const keepPlaying = options?.keepPlaying === true;
31817
+ const { playLocked, isPlaying: storeWasPlaying } = usePlayerStore.getState();
31816
31818
  const shouldResumeAfterSeek = shouldResumeForwardPlaybackAfterSeek({
31817
31819
  keepPlaying,
31818
31820
  wasReverseShuttle,
31819
- storeWasPlaying: usePlayerStore.getState().isPlaying,
31821
+ storeWasPlaying,
31820
31822
  duration,
31821
- nextTime
31823
+ nextTime,
31824
+ playLocked
31822
31825
  });
31823
31826
  adapter.seek(nextTime, options);
31824
31827
  publishSeek(nextTime, options);
31825
31828
  setCurrentTime(nextTime);
31826
- if (!shouldResumeAfterSeek && !keepPlaying) scrubMusicAtSeek(iframeRef.current, nextTime);
31829
+ if (!keepPlaying && !playLocked) scrubMusicAtSeek(iframeRef.current, nextTime);
31827
31830
  if (shouldResumeAfterSeek) {
31828
31831
  stopRAFLoop();
31829
31832
  applyPlaybackRate(usePlayerStore.getState().playbackRate);
@@ -31855,6 +31858,12 @@ function useTimelinePlayer({
31855
31858
  shuttleSpeedIndexRef
31856
31859
  ]
31857
31860
  );
31861
+ useEffect35(
31862
+ () => usePlayerStore.subscribe((state, prev) => {
31863
+ if (state.playLocked && !prev.playLocked && state.isPlaying) pause();
31864
+ }),
31865
+ [pause]
31866
+ );
31858
31867
  useEffect35(() => {
31859
31868
  return usePlayerStore.subscribe((state, prev) => {
31860
31869
  if (state.requestedSeekTime !== null && state.requestedSeekTime !== prev.requestedSeekTime) {
@@ -73774,6 +73783,7 @@ function usePersistentEditHistory({ projectId }) {
73774
73783
  projectIdRef.current = projectId;
73775
73784
  const [own] = useState111(createOwnHistory);
73776
73785
  const [pageKeyScope] = useState111(generateId);
73786
+ const claimKey = useCallback100((key2) => `${pageKeyScope}:${key2}`, [pageKeyScope]);
73777
73787
  const refresh2 = useCallback100(async () => {
73778
73788
  if (!projectId) return;
73779
73789
  const seen = own.changes();
@@ -73805,7 +73815,7 @@ function usePersistentEditHistory({ projectId }) {
73805
73815
  paths,
73806
73816
  overwrote: await overwroteVersions(files),
73807
73817
  ...coalesceKey && {
73808
- coalesceKey: `${pageKeyScope}:${coalesceKey}`,
73818
+ coalesceKey: claimKey(coalesceKey),
73809
73819
  idleMs: coalesceMs ?? DEFAULT_COALESCE_MS
73810
73820
  }
73811
73821
  });
@@ -73817,7 +73827,7 @@ function usePersistentEditHistory({ projectId }) {
73817
73827
  heldClaimRef.current = claimed && coalesceKey ? { paths, at: Date.now() } : null;
73818
73828
  await refresh2();
73819
73829
  },
73820
- [projectId, refresh2, own, pageKeyScope]
73830
+ [projectId, refresh2, own, claimKey]
73821
73831
  );
73822
73832
  const step = useCallback100(
73823
73833
  async (direction, callbacks) => {
@@ -73891,6 +73901,7 @@ function usePersistentEditHistory({ projectId }) {
73891
73901
  redoPaths: view.forward?.paths ?? [],
73892
73902
  state,
73893
73903
  recordEdit,
73904
+ claimKey,
73894
73905
  undo,
73895
73906
  redo,
73896
73907
  predict: own.predict,