@bendyline/squisq-editor-react 2.11.14 → 2.11.16

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.
@@ -294,13 +294,19 @@ function useImageEditor(options) {
294
294
  versioningAutoSaveIdleMs = 5e3,
295
295
  persistDebounceMs = 500
296
296
  } = options;
297
- const [state, dispatch] = useReducer(
297
+ const target = useMemo(
298
+ () => ({ container, stateFilename, initialSrc, resourcePolicy }),
299
+ [container, stateFilename, initialSrc, resourcePolicy]
300
+ );
301
+ const [loadedTarget, setLoadedTarget] = useState2(null);
302
+ const [loadedState, dispatch] = useReducer(
298
303
  (s, a) => {
299
304
  if (s === null) return a.type === "load" ? initialImageEditorState(a.doc) : null;
300
305
  return imageEditorReducer(s, a);
301
306
  },
302
307
  null
303
308
  );
309
+ const state = loadedTarget === target ? loadedState : null;
304
310
  const [ready, setReady] = useState2(false);
305
311
  const [error, setError] = useState2(null);
306
312
  const seededOnLoadRef = useRef2(false);
@@ -309,12 +315,15 @@ function useImageEditor(options) {
309
315
  const controller = new AbortController();
310
316
  setReady(false);
311
317
  setError(null);
318
+ seededOnLoadRef.current = false;
312
319
  (async () => {
313
320
  try {
321
+ await writeQueueRef.current;
314
322
  const existing = await readImageEditDoc(container, stateFilename);
315
323
  if (cancelled) return;
316
324
  if (existing) {
317
325
  dispatch({ type: "load", doc: existing });
326
+ setLoadedTarget(target);
318
327
  setReady(true);
319
328
  return;
320
329
  }
@@ -328,6 +337,7 @@ function useImageEditor(options) {
328
337
  await writeImageEditDoc(container, seeded, stateFilename);
329
338
  if (cancelled) return;
330
339
  dispatch({ type: "load", doc: seeded });
340
+ setLoadedTarget(target);
331
341
  setReady(true);
332
342
  seededOnLoadRef.current = true;
333
343
  } catch (err) {
@@ -340,33 +350,35 @@ function useImageEditor(options) {
340
350
  cancelled = true;
341
351
  controller.abort();
342
352
  };
343
- }, [container, stateFilename, initialSrc, resourcePolicy]);
353
+ }, [container, stateFilename, initialSrc, resourcePolicy, target]);
344
354
  const persistTimerRef = useRef2(null);
345
355
  const docRef = useRef2(null);
346
356
  const dirtyRef = useRef2(false);
347
357
  const revisionRef = useRef2(0);
348
358
  const previousDocRef = useRef2(null);
349
- const nextDoc = state?.doc ?? null;
359
+ const nextDoc = loadedState?.doc ?? null;
350
360
  if (nextDoc !== previousDocRef.current) {
351
361
  previousDocRef.current = nextDoc;
352
362
  revisionRef.current += 1;
353
363
  }
354
- docRef.current = nextDoc;
355
- dirtyRef.current = state?.dirty ?? false;
364
+ if (loadedTarget === target) {
365
+ docRef.current = nextDoc;
366
+ dirtyRef.current = state?.dirty ?? false;
367
+ }
356
368
  const writeQueueRef = useRef2(Promise.resolve());
357
369
  const persistTargetRef = useRef2({ container, stateFilename });
358
- persistTargetRef.current = { container, stateFilename };
370
+ if (loadedTarget === target) persistTargetRef.current = target;
359
371
  const enqueueWrite = useCallback2(
360
372
  (doc, revision, markClean) => {
361
373
  const write = writeQueueRef.current.catch(() => void 0).then(() => writeImageEditDoc(container, doc, stateFilename));
362
374
  writeQueueRef.current = write.catch(() => void 0);
363
375
  return write.then(() => {
364
- if (markClean && revision === revisionRef.current && docRef.current === doc) {
376
+ if (markClean && persistTargetRef.current === target && revision === revisionRef.current && docRef.current === doc) {
365
377
  dispatch({ type: "mark-clean" });
366
378
  }
367
379
  });
368
380
  },
369
- [container, stateFilename]
381
+ [container, stateFilename, target]
370
382
  );
371
383
  useEffect2(() => {
372
384
  if (!state?.dirty) return;
@@ -387,6 +399,7 @@ function useImageEditor(options) {
387
399
  };
388
400
  }, [state?.dirty, state?.doc, persistDebounceMs, enqueueWrite]);
389
401
  const flush = useCallback2(async () => {
402
+ if (loadedTarget !== target) return;
390
403
  const doc = docRef.current;
391
404
  if (!doc) return;
392
405
  if (persistTimerRef.current) {
@@ -394,14 +407,14 @@ function useImageEditor(options) {
394
407
  persistTimerRef.current = null;
395
408
  }
396
409
  await enqueueWrite(doc, revisionRef.current, true);
397
- }, [enqueueWrite]);
410
+ }, [enqueueWrite, loadedTarget, target]);
398
411
  useEffect2(
399
412
  () => () => {
400
413
  if (persistTimerRef.current) clearTimeout(persistTimerRef.current);
401
414
  const doc = docRef.current;
402
415
  if (!dirtyRef.current || !doc) return;
403
- const target = persistTargetRef.current;
404
- const write = writeQueueRef.current.catch(() => void 0).then(() => writeImageEditDoc(target.container, doc, target.stateFilename));
416
+ const target2 = persistTargetRef.current;
417
+ const write = writeQueueRef.current.catch(() => void 0).then(() => writeImageEditDoc(target2.container, doc, target2.stateFilename));
405
418
  writeQueueRef.current = write.catch((err) => {
406
419
  console.warn(
407
420
  "[squisq-editor] image-edit final persist failed:",
@@ -409,7 +422,7 @@ function useImageEditor(options) {
409
422
  );
410
423
  });
411
424
  },
412
- []
425
+ [target]
413
426
  );
414
427
  const versioning = useMemo(
415
428
  () => allowVersioning ? new ImageEditVersionManager(container, { stateFilename }) : null,
@@ -487,12 +500,14 @@ function useImageEditor(options) {
487
500
  );
488
501
  return {
489
502
  state,
490
- dispatch,
503
+ dispatch: (action) => {
504
+ if (loadedTarget === target) dispatch(action);
505
+ },
491
506
  flush,
492
507
  resolveAssetUrl,
493
508
  uploadAsset,
494
509
  versioning,
495
- ready,
510
+ ready: loadedTarget === target && ready,
496
511
  error
497
512
  };
498
513
  }
@@ -4,7 +4,7 @@ import {
4
4
  imageEditorReducer,
5
5
  initialImageEditorState,
6
6
  useImageEditor
7
- } from "../chunk-V44VP242.js";
7
+ } from "../chunk-K4Z2GIX4.js";
8
8
  import "../chunk-GS7QWYFT.js";
9
9
  export {
10
10
  ImageEditor,
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { C as CodeContext, E as EditorHostMode, S as SceneTextChannel, a as CalcEngineFactory, b as CsvSourceMeta, X as XlsxSourceMeta, F as FormulaEditRecord } from './shell-3UAmXcYE.js';
2
- export { B as BlockRange, c as BlockSlice, d as BlockTagVisibility, e as CodeContextSection, f as CoverImageSaveOutput, D as DashboardImageSaveOutput, g as DocumentLinkCandidate, h as DocumentLinkProvider, i as EditorActions, j as EditorColorScheme, k as EditorContextMenuContext, l as EditorContextMenuItem, m as EditorContextMenuItemVisibility, n as EditorContextMenuProvider, o as EditorContextMenuProviderProps, p as EditorContextValue, q as EditorMode, r as EditorProvider, s as EditorProviderProps, t as EditorSelectionInfo, u as EditorShell, v as EditorShellProps, w as EditorState, x as EditorView, y as FormulaSessionOptions, I as ImageDisplayMode, z as IngestedSidecar, L as LayoutMode, M as MentionCandidate, A as MentionProvider, P as PreviewPanel, G as PreviewPanelProps, R as RawEditor, H as RawEditorProps, T as ThemeInheritance, V as ViewPreferences, W as WriteCanvasSettings, J as WysiwygEditor, K as WysiwygEditorProps, N as XLSX_LOCKED_REASON, O as XlsxFormulaSession, Q as createXlsxFormulaSession, U as getBlockSlices, Y as ingestSidecarBytes, Z as lineToOffset, _ as offsetToLine, $ as sliceIndexAtOffset, a0 as spliceBlock, a1 as useEditorContext, a2 as useEditorContextMenuItems } from './shell-3UAmXcYE.js';
1
+ import { C as CodeContext, E as EditorHostMode, S as SceneTextChannel, a as CalcEngineFactory, b as CsvSourceMeta, X as XlsxSourceMeta, F as FormulaEditRecord } from './shell-X0EoQbbN.js';
2
+ export { B as BlockRange, c as BlockSlice, d as BlockTagVisibility, e as CodeContextSection, f as CoverImageSaveOutput, D as DashboardImageSaveOutput, g as DocumentLinkCandidate, h as DocumentLinkProvider, i as EditorActions, j as EditorColorScheme, k as EditorContextMenuContext, l as EditorContextMenuItem, m as EditorContextMenuItemVisibility, n as EditorContextMenuProvider, o as EditorContextMenuProviderProps, p as EditorContextValue, q as EditorMode, r as EditorProvider, s as EditorProviderProps, t as EditorSelectionInfo, u as EditorShell, v as EditorShellProps, w as EditorState, x as EditorView, y as FormulaSessionOptions, I as ImageDisplayMode, z as IngestedSidecar, L as LayoutMode, M as MentionCandidate, A as MentionProvider, P as PreviewPanel, G as PreviewPanelProps, R as RawEditor, H as RawEditorProps, T as ThemeInheritance, V as ViewPreferences, W as WriteCanvasSettings, J as WysiwygEditor, K as WysiwygEditorProps, N as XLSX_LOCKED_REASON, O as XlsxFormulaSession, Q as createXlsxFormulaSession, U as getBlockSlices, Y as ingestSidecarBytes, Z as lineToOffset, _ as offsetToLine, $ as sliceIndexAtOffset, a0 as spliceBlock, a1 as useEditorContext, a2 as useEditorContextMenuItems } from './shell-X0EoQbbN.js';
3
3
  import * as react_jsx_runtime from 'react/jsx-runtime';
4
4
  import * as react from 'react';
5
5
  import { ReactNode, CSSProperties, ReactElement } from 'react';
@@ -26,9 +26,9 @@ import { FenceRendererMap } from '@bendyline/squisq/fence';
26
26
  import { TableViewState } from '@bendyline/squisq/table';
27
27
  import { EditJournal } from '@bendyline/squisq-grid-react';
28
28
  export { JsonEditor, JsonEditorProps } from './json-editor/index.js';
29
- export { C as CameraStreamOptions, D as DEFAULT_RECORDER_DEVICE_SETTINGS, M as MediaDeviceInventory, R as RecordedBookmark, a as RecordedMediaKind, b as RecorderAudioDeviceSettings, c as RecorderButton, d as RecorderButtonProps, e as RecorderCameraDeviceSettings, f as RecorderCameraSaveResult, g as RecorderColorScheme, h as RecorderConstraintMode, i as RecorderDeviceOption, j as RecorderDeviceQuickPicks, k as RecorderDeviceQuickPicksProps, l as RecorderDeviceSettings, m as RecorderDeviceSettingsPanel, n as RecorderDeviceSettingsPanelProps, o as RecorderEncodingSettings, p as RecorderModal, q as RecorderModalProps, r as RecorderNarrationOptions, s as RecorderPanel, t as RecorderPanelProps, u as RecorderSaveResult, v as RecorderScreenAudioSettings, w as RecorderScreenDeviceSettings, x as RecorderSlidesOptions, S as ScreenStreamHandle, y as ScreenStreamOptions, z as SlideTimingSaveResult, T as TimingJson, A as buildRecorderAudioConstraints, B as buildRecorderCameraConstraints, E as buildRecorderScreenAudioConstraints, F as buildRecorderScreenConstraints, G as buildTimingJson, H as encodeTimingJson, I as hasRecorderDeviceChoice, J as recordedMediaKind, K as recorderBitsPerSecond, L as recorderDeviceGroups, N as recorderDeviceOptions, O as requestCameraStream, P as requestMicStream, Q as requestScreenStream, U as timingPathFor, V as useMediaDevices, W as useStreamPreview } from './recorder-CC3VW9Z7.js';
30
- import { R as RecorderState } from './useNarrationStage-D3Sgcf0L.js';
31
- export { C as CanvasSink, a as CaptureKind, D as DEFAULT_TELEPROMPTER_PREFS, F as FloatOpenOptions, b as FloatTier, c as FloatingWindowHandle, d as FloatingWindowManager, M as MicAnalysisHandle, e as MicAnalysisStatus, N as NarrationRecorderController, f as NarrationRecorderState, g as NarrationStageHandle, h as NarrationTake, P as PrompterTransport, i as RecorderAudioBitrateMode, j as RecorderCameraLane, k as RecorderExtendedMediaOptions, l as RecorderSource, m as ResolvedFormat, T as TeleprompterController, n as TeleprompterPrefs, o as TeleprompterRecordingDeps, U as UseMediaRecorderOptions, p as UseMediaRecorderResult, q as UseNarrationStageOptions, r as buildFilename, s as createFloatingWindowManager, t as detectFloatTiers, u as getCaptureKind, v as resolveFormat, w as supportsDisplayMedia, x as supportsMediaRecorder, y as supportsUserMedia, z as useFloatingWindow, A as useMediaRecorder, B as useMicAnalysis, E as useNarrationRecorder, G as useNarrationStage, H as useTeleprompter, I as vadConfigForSensitivity } from './useNarrationStage-D3Sgcf0L.js';
29
+ export { C as CameraStreamOptions, D as DEFAULT_RECORDER_DEVICE_SETTINGS, M as MediaDeviceInventory, R as RecordedBookmark, a as RecordedMediaKind, b as RecorderAudioDeviceSettings, c as RecorderButton, d as RecorderButtonProps, e as RecorderCameraDeviceSettings, f as RecorderCameraSaveResult, g as RecorderColorScheme, h as RecorderConstraintMode, i as RecorderDeviceOption, j as RecorderDeviceQuickPicks, k as RecorderDeviceQuickPicksProps, l as RecorderDeviceSettings, m as RecorderDeviceSettingsPanel, n as RecorderDeviceSettingsPanelProps, o as RecorderEncodingSettings, p as RecorderModal, q as RecorderModalProps, r as RecorderNarrationOptions, s as RecorderPanel, t as RecorderPanelProps, u as RecorderSaveResult, v as RecorderScreenAudioSettings, w as RecorderScreenDeviceSettings, x as RecorderSlidesOptions, S as ScreenStreamHandle, y as ScreenStreamOptions, z as SlideTimingSaveResult, T as TimingJson, A as buildRecorderAudioConstraints, B as buildRecorderCameraConstraints, E as buildRecorderScreenAudioConstraints, F as buildRecorderScreenConstraints, G as buildTimingJson, H as encodeTimingJson, I as hasRecorderDeviceChoice, J as recordedMediaKind, K as recorderBitsPerSecond, L as recorderDeviceGroups, N as recorderDeviceOptions, O as requestCameraStream, P as requestMicStream, Q as requestScreenStream, U as timingPathFor, V as useMediaDevices, W as useStreamPreview } from './recorder-C6ArYQBa.js';
30
+ import { R as RecorderState } from './useNarrationStage-DopDr_P5.js';
31
+ export { C as CanvasSink, a as CaptureKind, D as DEFAULT_TELEPROMPTER_PREFS, F as FloatOpenOptions, b as FloatTier, c as FloatingWindowHandle, d as FloatingWindowManager, M as MicAnalysisHandle, e as MicAnalysisStatus, N as NarrationRecorderController, f as NarrationRecorderState, g as NarrationStageHandle, h as NarrationTake, P as PrompterTransport, i as RecorderAudioBitrateMode, j as RecorderCameraLane, k as RecorderExtendedMediaOptions, l as RecorderSource, m as ResolvedFormat, T as TeleprompterController, n as TeleprompterPrefs, o as TeleprompterRecordingDeps, U as UseMediaRecorderOptions, p as UseMediaRecorderResult, q as UseNarrationStageOptions, r as buildFilename, s as createFloatingWindowManager, t as detectFloatTiers, u as getCaptureKind, v as resolveFormat, w as supportsDisplayMedia, x as supportsMediaRecorder, y as supportsUserMedia, z as useFloatingWindow, A as useMediaRecorder, B as useMicAnalysis, E as useNarrationRecorder, G as useNarrationStage, H as useTeleprompter, I as vadConfigForSensitivity } from './useNarrationStage-DopDr_P5.js';
32
32
  export { EYE_LINE_FRACTION, NarrationSavePlan, NarrationSaveResult, NarrationStage, NarrationStageProps, PCM_WORKLET_NAME, PCM_WORKLET_SOURCE, TELEPROMPTER_CSS, TeleprompterControls, TeleprompterControlsProps, TeleprompterSurface, TeleprompterSurfaceProps, TeleprompterView, TeleprompterViewProps, TokenLineMap, buildNarrationSavePlan, cameraVideoLine, ensureTeleprompterStyles, executeNarrationSave, insertNarrationPreamble, measureTokenLines, narrationAnnotationLine, prompterVarsFromTheme, registerPcmWorklet, stepScroll, targetOffsetFor } from './teleprompter/index.js';
33
33
  export { H as HarperProofingConfig, a as ProofingCapability, b as ProofingDocumentRef, c as ProofingIgnoreStore, d as ProofingLanguage, e as ProofingLintOptions, P as ProofingProvider, f as ProofingProviderFactory } from './types-De4z-gGb.js';
34
34
  export { createHarperProofingProvider } from './proofing/index.js';
@@ -3022,17 +3022,16 @@ declare function viewStateFromBinding(binding: HeadingViewBinding, headers: read
3022
3022
  * 1. BACKUP the original bytes first (`buildDataBackupPath`, pruned to the
3023
3023
  * newest 3 per sidecar) — the only cross-save undo the grid offers.
3024
3024
  * No container = no backup; the result says so rather than hiding it.
3025
- * 2. Serialize from the ORIGINAL parsed rows with journal edits splatted
3026
- * in — unedited cells reproduce the parse product byte-for-byte (values,
3027
- * not necessarily quoting style), sidestepping float-rendering drift.
3025
+ * 2. Serialize from the latest persisted bytes with a snapshot of this
3026
+ * region's journal, preserving saves made by other regions of the file.
3028
3027
  * Formula neutralization applies ONLY to journal-edited, non-numeric
3029
3028
  * cells (`serializeCsvRows` defaults `preserve`; blanket escaping would
3030
3029
  * corrupt every negative number in a re-saved file).
3031
3030
  * 3. `addMedia(samePath)` with FORK DETECTION: `addMedia` returns the path
3032
3031
  * the host actually used, and a collision-renaming provider would
3033
3032
  * silently fork the document's reference — surface it instead.
3034
- * 4. The caller bumps mediaRevision (previews re-resolve, journal cache
3035
- * rotates) only on success.
3033
+ * 4. Acknowledge only the saved snapshot. The caller refreshes the formula
3034
+ * baseline and bumps mediaRevision so previews re-resolve on success.
3036
3035
  */
3037
3036
 
3038
3037
  interface GridSaveResult {
@@ -3042,6 +3041,8 @@ interface GridSaveResult {
3042
3041
  /** Human-readable caveats: fork detected, backup skipped, … */
3043
3042
  notices: string[];
3044
3043
  error?: string;
3044
+ /** Persisted baseline for subsequent saves, including other regions' edits. */
3045
+ bytes?: ArrayBuffer;
3045
3046
  }
3046
3047
  interface SaveCsvEditsOptions {
3047
3048
  path: string;
package/dist/index.js CHANGED
@@ -219,7 +219,7 @@ import {
219
219
  useTreeViewData,
220
220
  viewStateFromBinding,
221
221
  writeHeadingViewState
222
- } from "./chunk-QY2ZFRJE.js";
222
+ } from "./chunk-5TYCTE33.js";
223
223
  import {
224
224
  EditorProvider,
225
225
  detectLanguageFromFileName,
@@ -249,10 +249,10 @@ import {
249
249
  imageEditorReducer,
250
250
  initialImageEditorState,
251
251
  useImageEditor
252
- } from "./chunk-V44VP242.js";
252
+ } from "./chunk-K4Z2GIX4.js";
253
253
  import {
254
254
  RecorderButton
255
- } from "./chunk-DN6XFOY2.js";
255
+ } from "./chunk-27WOOJXR.js";
256
256
  import {
257
257
  DEFAULT_RECORDER_DEVICE_SETTINGS,
258
258
  RecorderDeviceQuickPicks,
@@ -283,7 +283,7 @@ import {
283
283
  unshownSlidesWarning,
284
284
  useMediaDevices,
285
285
  useMediaRecorder
286
- } from "./chunk-BJ3TXAIQ.js";
286
+ } from "./chunk-4D7QMRTZ.js";
287
287
  import "./chunk-GS7QWYFT.js";
288
288
  import {
289
289
  TeleprompterView
@@ -1,5 +1,5 @@
1
- export { C as CameraStreamOptions, D as DEFAULT_RECORDER_DEVICE_SETTINGS, M as MediaDeviceInventory, R as RecordedBookmark, a as RecordedMediaKind, b as RecorderAudioDeviceSettings, c as RecorderButton, d as RecorderButtonProps, e as RecorderCameraDeviceSettings, f as RecorderCameraSaveResult, g as RecorderColorScheme, h as RecorderConstraintMode, i as RecorderDeviceOption, j as RecorderDeviceQuickPicks, k as RecorderDeviceQuickPicksProps, l as RecorderDeviceSettings, m as RecorderDeviceSettingsPanel, n as RecorderDeviceSettingsPanelProps, o as RecorderEncodingSettings, p as RecorderModal, q as RecorderModalProps, s as RecorderPanel, t as RecorderPanelProps, u as RecorderSaveResult, v as RecorderScreenAudioSettings, w as RecorderScreenDeviceSettings, S as ScreenStreamHandle, y as ScreenStreamOptions, T as TimingJson, A as buildRecorderAudioConstraints, B as buildRecorderCameraConstraints, E as buildRecorderScreenAudioConstraints, F as buildRecorderScreenConstraints, G as buildTimingJson, H as encodeTimingJson, I as hasRecorderDeviceChoice, J as recordedMediaKind, K as recorderBitsPerSecond, L as recorderDeviceGroups, N as recorderDeviceOptions, O as requestCameraStream, P as requestMicStream, Q as requestScreenStream, U as timingPathFor, V as useMediaDevices, W as useStreamPreview } from '../recorder-CC3VW9Z7.js';
2
- export { a as CaptureKind, i as RecorderAudioBitrateMode, j as RecorderCameraLane, k as RecorderExtendedMediaOptions, l as RecorderSource, R as RecorderState, m as ResolvedFormat, U as UseMediaRecorderOptions, p as UseMediaRecorderResult, r as buildFilename, u as getCaptureKind, v as resolveFormat, w as supportsDisplayMedia, x as supportsMediaRecorder, y as supportsUserMedia, A as useMediaRecorder } from '../useNarrationStage-D3Sgcf0L.js';
1
+ export { C as CameraStreamOptions, D as DEFAULT_RECORDER_DEVICE_SETTINGS, M as MediaDeviceInventory, R as RecordedBookmark, a as RecordedMediaKind, b as RecorderAudioDeviceSettings, c as RecorderButton, d as RecorderButtonProps, e as RecorderCameraDeviceSettings, f as RecorderCameraSaveResult, g as RecorderColorScheme, h as RecorderConstraintMode, i as RecorderDeviceOption, j as RecorderDeviceQuickPicks, k as RecorderDeviceQuickPicksProps, l as RecorderDeviceSettings, m as RecorderDeviceSettingsPanel, n as RecorderDeviceSettingsPanelProps, o as RecorderEncodingSettings, p as RecorderModal, q as RecorderModalProps, s as RecorderPanel, t as RecorderPanelProps, u as RecorderSaveResult, v as RecorderScreenAudioSettings, w as RecorderScreenDeviceSettings, S as ScreenStreamHandle, y as ScreenStreamOptions, T as TimingJson, A as buildRecorderAudioConstraints, B as buildRecorderCameraConstraints, E as buildRecorderScreenAudioConstraints, F as buildRecorderScreenConstraints, G as buildTimingJson, H as encodeTimingJson, I as hasRecorderDeviceChoice, J as recordedMediaKind, K as recorderBitsPerSecond, L as recorderDeviceGroups, N as recorderDeviceOptions, O as requestCameraStream, P as requestMicStream, Q as requestScreenStream, U as timingPathFor, V as useMediaDevices, W as useStreamPreview } from '../recorder-C6ArYQBa.js';
2
+ export { a as CaptureKind, i as RecorderAudioBitrateMode, j as RecorderCameraLane, k as RecorderExtendedMediaOptions, l as RecorderSource, R as RecorderState, m as ResolvedFormat, U as UseMediaRecorderOptions, p as UseMediaRecorderResult, r as buildFilename, u as getCaptureKind, v as resolveFormat, w as supportsDisplayMedia, x as supportsMediaRecorder, y as supportsUserMedia, A as useMediaRecorder } from '../useNarrationStage-DopDr_P5.js';
3
3
  import 'react/jsx-runtime';
4
4
  import '@bendyline/squisq/schemas';
5
5
  import '@bendyline/squisq/storage';
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  RecorderButton
3
- } from "../chunk-DN6XFOY2.js";
3
+ } from "../chunk-27WOOJXR.js";
4
4
  import {
5
5
  DEFAULT_RECORDER_DEVICE_SETTINGS,
6
6
  RecorderDeviceQuickPicks,
@@ -20,7 +20,7 @@ import {
20
20
  requestScreenStream,
21
21
  useMediaDevices,
22
22
  useMediaRecorder
23
- } from "../chunk-BJ3TXAIQ.js";
23
+ } from "../chunk-4D7QMRTZ.js";
24
24
  import "../chunk-GS7QWYFT.js";
25
25
  import {
26
26
  buildFilename,
@@ -1,7 +1,7 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { Doc, Theme, ViewportConfig, MediaProvider } from '@bendyline/squisq/schemas';
3
3
  import { ContentContainer } from '@bendyline/squisq/storage';
4
- import { l as RecorderSource, o as TeleprompterRecordingDeps } from './useNarrationStage-D3Sgcf0L.js';
4
+ import { l as RecorderSource, o as TeleprompterRecordingDeps, S as ScreenCaptureRegion } from './useNarrationStage-DopDr_P5.js';
5
5
  import { CSSProperties, RefObject } from 'react';
6
6
 
7
7
  type RecordedMediaKind = 'audio' | 'video';
@@ -225,6 +225,7 @@ declare function RecorderPanel({ mediaProvider, container, initialMode, colorSch
225
225
  * capture is the exception: the screen-capture standard rejects exact
226
226
  * constraints during its user picker, so those values always remain ideal.
227
227
  */
228
+
228
229
  type RecorderConstraintMode = 'ideal' | 'exact';
229
230
  interface RecorderAudioDeviceSettings {
230
231
  deviceId: string;
@@ -249,6 +250,8 @@ interface RecorderCameraDeviceSettings {
249
250
  width?: number;
250
251
  }
251
252
  interface RecorderScreenDeviceSettings {
253
+ /** Crop in captured pixels, relative to the chosen surface (not the desktop). */
254
+ crop?: ScreenCaptureRegion;
252
255
  aspectRatio?: number;
253
256
  cursor?: string;
254
257
  displaySurface?: string;
@@ -476,7 +479,9 @@ declare function requestCameraStream(options?: CameraStreamOptions): Promise<Med
476
479
  * `AudioContext`, so the resulting `MediaStream` carries a single audio
477
480
  * track and a single video track.
478
481
  */
482
+
479
483
  interface ScreenStreamOptions {
484
+ crop?: ScreenCaptureRegion;
480
485
  /** Video constraints for the screen surface. Pass `true` for browser default. */
481
486
  video?: boolean | MediaTrackConstraints;
482
487
  /**
@@ -1,4 +1,4 @@
1
- export { d as BlockTagVisibility, g as DocumentLinkCandidate, h as DocumentLinkProvider, i as EditorActions, j as EditorColorScheme, k as EditorContextMenuContext, l as EditorContextMenuItem, m as EditorContextMenuItemVisibility, n as EditorContextMenuProvider, o as EditorContextMenuProviderProps, p as EditorContextValue, E as EditorHostMode, q as EditorMode, r as EditorProvider, s as EditorProviderProps, u as EditorShell, v as EditorShellProps, w as EditorState, x as EditorView, I as ImageDisplayMode, L as LayoutMode, M as MentionCandidate, A as MentionProvider, P as PreviewPanel, G as PreviewPanelProps, R as RawEditor, H as RawEditorProps, T as ThemeInheritance, V as ViewPreferences, J as WysiwygEditor, K as WysiwygEditorProps, a1 as useEditorContext, a2 as useEditorContextMenuItems } from '../shell-3UAmXcYE.js';
1
+ export { d as BlockTagVisibility, g as DocumentLinkCandidate, h as DocumentLinkProvider, i as EditorActions, j as EditorColorScheme, k as EditorContextMenuContext, l as EditorContextMenuItem, m as EditorContextMenuItemVisibility, n as EditorContextMenuProvider, o as EditorContextMenuProviderProps, p as EditorContextValue, E as EditorHostMode, q as EditorMode, r as EditorProvider, s as EditorProviderProps, u as EditorShell, v as EditorShellProps, w as EditorState, x as EditorView, I as ImageDisplayMode, L as LayoutMode, M as MentionCandidate, A as MentionProvider, P as PreviewPanel, G as PreviewPanelProps, R as RawEditor, H as RawEditorProps, T as ThemeInheritance, V as ViewPreferences, J as WysiwygEditor, K as WysiwygEditorProps, a1 as useEditorContext, a2 as useEditorContextMenuItems } from '../shell-X0EoQbbN.js';
2
2
  import 'react/jsx-runtime';
3
3
  import '@bendyline/squisq/table';
4
4
  import '@bendyline/squisq-calc';
@@ -5,7 +5,7 @@ import {
5
5
  RawEditor,
6
6
  WysiwygEditor,
7
7
  useEditorContextMenuItems
8
- } from "../chunk-QY2ZFRJE.js";
8
+ } from "../chunk-5TYCTE33.js";
9
9
  import {
10
10
  EditorProvider,
11
11
  useEditorContext
@@ -13,8 +13,8 @@ import {
13
13
  import "../chunk-V4NBQF5C.js";
14
14
  import "../chunk-ZDWZRVAY.js";
15
15
  import "../chunk-EN5BYZOE.js";
16
- import "../chunk-V44VP242.js";
17
- import "../chunk-BJ3TXAIQ.js";
16
+ import "../chunk-K4Z2GIX4.js";
17
+ import "../chunk-4D7QMRTZ.js";
18
18
  import "../chunk-GS7QWYFT.js";
19
19
  import "../chunk-ENDRPV6T.js";
20
20
  import "../chunk-34FRFDQ6.js";
@@ -1,5 +1,5 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import { TableCellEdit, TableCellValue } from '@bendyline/squisq/table';
2
+ import { TableCellValue, TableCellEdit } from '@bendyline/squisq/table';
3
3
  import { CalcEngineConfig, CalcEngine } from '@bendyline/squisq-calc';
4
4
  import { IngestTable } from '@bendyline/squisq-grid-react';
5
5
  import { XlsxWorkbookGrids } from '@bendyline/squisq-formats/xlsx';
@@ -114,9 +114,13 @@ declare function ingestSidecarBytes(bytes: ArrayBuffer, ext: string, params: {
114
114
  type CalcEngineFactory = (config: CalcEngineConfig) => Promise<CalcEngine>;
115
115
  interface FormulaSessionOptions {
116
116
  engineFactory?: CalcEngineFactory;
117
+ /** Caller-owned edits survive view remounts; scoped to the same journal. */
118
+ edits?: Map<string, FormulaEditRecord>;
117
119
  }
118
120
  interface FormulaEditRecord {
119
- formula: string;
121
+ /** null explicitly removes a formula. */
122
+ formula: string | null;
123
+ value?: TableCellValue;
120
124
  /** Engine result, when scalar — persisted as the cached `<v>`. */
121
125
  cachedValue?: number | boolean | string;
122
126
  }
@@ -141,7 +145,9 @@ interface XlsxFormulaSession {
141
145
  /** Revert to the loaded workbook; returns the display updates to re-apply. */
142
146
  discard(): Promise<TableCellEdit[]>;
143
147
  /** Forget the edits after a successful save (values stay current). */
144
- markSaved(): void;
148
+ markSaved(snapshot?: ReadonlyMap<string, FormulaEditRecord>, baseline?: XlsxSourceMeta): void;
149
+ /** Wait for mutations already submitted to this session. */
150
+ flush(): Promise<void>;
145
151
  dispose(): void;
146
152
  }
147
153
  /**
@@ -1,8 +1,8 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { Doc, Theme, MediaProvider } from '@bendyline/squisq/schemas';
3
3
  import { ContentContainer } from '@bendyline/squisq/storage';
4
- import { o as TeleprompterRecordingDeps, g as NarrationStageHandle, T as TeleprompterController, c as FloatingWindowHandle } from '../useNarrationStage-D3Sgcf0L.js';
5
- export { C as CanvasSink, D as DEFAULT_TELEPROMPTER_PREFS, F as FloatOpenOptions, b as FloatTier, d as FloatingWindowManager, M as MicAnalysisHandle, e as MicAnalysisStatus, N as NarrationRecorderController, f as NarrationRecorderState, h as NarrationTake, P as PrompterTransport, J as TELEPROMPTER_PREF_LIMITS, n as TeleprompterPrefs, q as UseNarrationStageOptions, s as createFloatingWindowManager, t as detectFloatTiers, K as normalizeTeleprompterPrefs, z as useFloatingWindow, B as useMicAnalysis, E as useNarrationRecorder, G as useNarrationStage, H as useTeleprompter, I as vadConfigForSensitivity } from '../useNarrationStage-D3Sgcf0L.js';
4
+ import { o as TeleprompterRecordingDeps, g as NarrationStageHandle, T as TeleprompterController, c as FloatingWindowHandle } from '../useNarrationStage-DopDr_P5.js';
5
+ export { C as CanvasSink, D as DEFAULT_TELEPROMPTER_PREFS, F as FloatOpenOptions, b as FloatTier, d as FloatingWindowManager, M as MicAnalysisHandle, e as MicAnalysisStatus, N as NarrationRecorderController, f as NarrationRecorderState, h as NarrationTake, P as PrompterTransport, J as TELEPROMPTER_PREF_LIMITS, n as TeleprompterPrefs, q as UseNarrationStageOptions, s as createFloatingWindowManager, t as detectFloatTiers, K as normalizeTeleprompterPrefs, z as useFloatingWindow, B as useMicAnalysis, E as useNarrationRecorder, G as useNarrationStage, H as useTeleprompter, I as vadConfigForSensitivity } from '../useNarrationStage-DopDr_P5.js';
6
6
  import { NarrationTimingJsonV3, NarrationScript, NarrationAlignment } from '@bendyline/squisq/narration';
7
7
  import { ReactNode } from 'react';
8
8
 
@@ -57,6 +57,13 @@ declare function supportsDisplayMedia(): boolean;
57
57
  type RecordingFilenameSeed = 'audio' | 'camera' | 'camera-audio' | 'screen' | 'screen-audio';
58
58
  declare function buildFilename(kind: CaptureKind, extension: string, basename?: string, seed?: RecordingFilenameSeed): string;
59
59
 
60
+ interface ScreenCaptureRegion {
61
+ x: number;
62
+ y: number;
63
+ width: number;
64
+ height: number;
65
+ }
66
+
60
67
  /**
61
68
  * useMediaRecorder
62
69
  *
@@ -110,6 +117,8 @@ interface RecorderCameraLane {
110
117
  extension: string | null;
111
118
  }
112
119
  interface UseMediaRecorderOptions {
120
+ /** Optional crop applied to the screen lane before preview and encoding. */
121
+ screenRegion?: ScreenCaptureRegion;
113
122
  /**
114
123
  * Combined byte threshold for automatically stopping every capture lane.
115
124
  * Defaults to 90 MiB. Browser chunk delivery can be delayed, so the final
@@ -586,4 +595,4 @@ interface NarrationStageHandle {
586
595
  }
587
596
  declare function useNarrationStage(opts: UseNarrationStageOptions): NarrationStageHandle;
588
597
 
589
- export { useMediaRecorder as A, useMicAnalysis as B, type CanvasSink as C, DEFAULT_TELEPROMPTER_PREFS as D, useNarrationRecorder as E, type FloatOpenOptions as F, useNarrationStage as G, useTeleprompter as H, vadConfigForSensitivity as I, TELEPROMPTER_PREF_LIMITS as J, normalizeTeleprompterPrefs as K, type MicAnalysisHandle as M, type NarrationRecorderController as N, type PrompterTransport as P, type RecorderState as R, type TeleprompterController as T, type UseMediaRecorderOptions as U, type CaptureKind as a, type FloatTier as b, type FloatingWindowHandle as c, type FloatingWindowManager as d, type MicAnalysisStatus as e, type NarrationRecorderState as f, type NarrationStageHandle as g, type NarrationTake as h, type RecorderAudioBitrateMode as i, type RecorderCameraLane as j, type RecorderExtendedMediaOptions as k, type RecorderSource as l, type ResolvedFormat as m, type TeleprompterPrefs as n, type TeleprompterRecordingDeps as o, type UseMediaRecorderResult as p, type UseNarrationStageOptions as q, buildFilename as r, createFloatingWindowManager as s, detectFloatTiers as t, getCaptureKind as u, resolveFormat as v, supportsDisplayMedia as w, supportsMediaRecorder as x, supportsUserMedia as y, useFloatingWindow as z };
598
+ export { useMediaRecorder as A, useMicAnalysis as B, type CanvasSink as C, DEFAULT_TELEPROMPTER_PREFS as D, useNarrationRecorder as E, type FloatOpenOptions as F, useNarrationStage as G, useTeleprompter as H, vadConfigForSensitivity as I, TELEPROMPTER_PREF_LIMITS as J, normalizeTeleprompterPrefs as K, type MicAnalysisHandle as M, type NarrationRecorderController as N, type PrompterTransport as P, type RecorderState as R, type ScreenCaptureRegion as S, type TeleprompterController as T, type UseMediaRecorderOptions as U, type CaptureKind as a, type FloatTier as b, type FloatingWindowHandle as c, type FloatingWindowManager as d, type MicAnalysisStatus as e, type NarrationRecorderState as f, type NarrationStageHandle as g, type NarrationTake as h, type RecorderAudioBitrateMode as i, type RecorderCameraLane as j, type RecorderExtendedMediaOptions as k, type RecorderSource as l, type ResolvedFormat as m, type TeleprompterPrefs as n, type TeleprompterRecordingDeps as o, type UseMediaRecorderResult as p, type UseNarrationStageOptions as q, buildFilename as r, createFloatingWindowManager as s, detectFloatTiers as t, getCaptureKind as u, resolveFormat as v, supportsDisplayMedia as w, supportsMediaRecorder as x, supportsUserMedia as y, useFloatingWindow as z };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bendyline/squisq-editor-react",
3
- "version": "2.11.14",
3
+ "version": "2.11.16",
4
4
  "description": "React editor shell with raw/WYSIWYG/preview modes for Squisq documents",
5
5
  "license": "MIT",
6
6
  "author": "Bendyline",
@@ -98,12 +98,12 @@
98
98
  }
99
99
  },
100
100
  "dependencies": {
101
- "@bendyline/squisq": "2.11.11",
102
- "@bendyline/squisq-calc": "2.11.0",
103
- "@bendyline/squisq-formats": "2.6.11",
104
- "@bendyline/squisq-grid-react": "2.11.12",
105
- "@bendyline/squisq-react": "2.11.13",
106
- "@bendyline/squisq-video-react": "2.4.17",
101
+ "@bendyline/squisq": "2.11.13",
102
+ "@bendyline/squisq-calc": "2.11.1",
103
+ "@bendyline/squisq-formats": "2.6.13",
104
+ "@bendyline/squisq-grid-react": "2.11.14",
105
+ "@bendyline/squisq-react": "2.11.15",
106
+ "@bendyline/squisq-video-react": "2.4.19",
107
107
  "@fortawesome/fontawesome-free": "7.2.0",
108
108
  "@tiptap/core": "2.27.3",
109
109
  "@tiptap/extension-heading": "2.27.3",