@xom11/whiteboard 0.10.1 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -79,8 +79,24 @@ interface WhiteboardProps {
79
79
  * `STABLE_STAMPS` để chỉ bật stamp ổn định.
80
80
  */
81
81
  stamps?: ReadonlyArray<StampType>;
82
+ /**
83
+ * Snapshot từ server. Precedence: `initialScene` > localStorage > blank.
84
+ * - `undefined` (default) → đọc từ localStorage qua `storageKey`
85
+ * - `null` → explicit blank, bỏ qua localStorage
86
+ * - object → dùng làm initialData của Excalidraw, bỏ qua localStorage
87
+ *
88
+ * Dùng để load board từ server. Thường đi cùng `storageKey={null}` để
89
+ * tránh localStorage stale override server data.
90
+ */
91
+ initialScene?: ExcalidrawSceneSnapshot | null;
92
+ /**
93
+ * Binary files (raster, base64) từ server. Add vào Excalidraw đúng 1 lần
94
+ * khi api ready. Dùng kèm `initialScene` cho flow load-from-server.
95
+ * Nếu cần inject files động về sau, dùng `onApi` rồi gọi `api.addFiles`.
96
+ */
97
+ initialFiles?: BinaryFiles;
82
98
  }
83
- declare function Whiteboard({ storageKey, readOnly, onSceneChange, onFilesChange, onApi, langCode, stamps, }: WhiteboardProps): react_jsx_runtime.JSX.Element;
99
+ declare function Whiteboard({ storageKey, readOnly, onSceneChange, onFilesChange, onApi, langCode, stamps, initialScene, initialFiles, }: WhiteboardProps): react_jsx_runtime.JSX.Element;
84
100
 
85
101
  declare function pickSyncableAppState(s: AppState): SyncableAppState;
86
102
 
package/dist/index.d.ts CHANGED
@@ -79,8 +79,24 @@ interface WhiteboardProps {
79
79
  * `STABLE_STAMPS` để chỉ bật stamp ổn định.
80
80
  */
81
81
  stamps?: ReadonlyArray<StampType>;
82
+ /**
83
+ * Snapshot từ server. Precedence: `initialScene` > localStorage > blank.
84
+ * - `undefined` (default) → đọc từ localStorage qua `storageKey`
85
+ * - `null` → explicit blank, bỏ qua localStorage
86
+ * - object → dùng làm initialData của Excalidraw, bỏ qua localStorage
87
+ *
88
+ * Dùng để load board từ server. Thường đi cùng `storageKey={null}` để
89
+ * tránh localStorage stale override server data.
90
+ */
91
+ initialScene?: ExcalidrawSceneSnapshot | null;
92
+ /**
93
+ * Binary files (raster, base64) từ server. Add vào Excalidraw đúng 1 lần
94
+ * khi api ready. Dùng kèm `initialScene` cho flow load-from-server.
95
+ * Nếu cần inject files động về sau, dùng `onApi` rồi gọi `api.addFiles`.
96
+ */
97
+ initialFiles?: BinaryFiles;
82
98
  }
83
- declare function Whiteboard({ storageKey, readOnly, onSceneChange, onFilesChange, onApi, langCode, stamps, }: WhiteboardProps): react_jsx_runtime.JSX.Element;
99
+ declare function Whiteboard({ storageKey, readOnly, onSceneChange, onFilesChange, onApi, langCode, stamps, initialScene, initialFiles, }: WhiteboardProps): react_jsx_runtime.JSX.Element;
84
100
 
85
101
  declare function pickSyncableAppState(s: AppState): SyncableAppState;
86
102
 
package/dist/index.js CHANGED
@@ -11429,7 +11429,9 @@ function Whiteboard({
11429
11429
  onFilesChange,
11430
11430
  onApi,
11431
11431
  langCode = "vi-VN",
11432
- stamps = DEFAULT_STAMPS
11432
+ stamps = DEFAULT_STAMPS,
11433
+ initialScene,
11434
+ initialFiles
11433
11435
  }) {
11434
11436
  const [api, setApi] = React8.useState(null);
11435
11437
  const apiRef = React8.useRef(null);
@@ -11458,7 +11460,7 @@ function Whiteboard({
11458
11460
  () => persistEnabled ? readScene(storageKey) : null,
11459
11461
  [persistEnabled, storageKey]
11460
11462
  );
11461
- const effectiveInitialScene = persistedInitial ? {
11463
+ const effectiveInitialScene = initialScene !== void 0 ? initialScene : persistedInitial ? {
11462
11464
  elements: persistedInitial.elements,
11463
11465
  appState: persistedInitial.appState
11464
11466
  } : null;
@@ -11633,6 +11635,30 @@ function Whiteboard({
11633
11635
  console.warn("[whiteboard] flushPrune th\u1EA5t b\u1EA1i:", err);
11634
11636
  }
11635
11637
  };
11638
+ const initialFilesAddedRef = React8.useRef(false);
11639
+ React8.useEffect(() => {
11640
+ if (!api || initialFilesAddedRef.current) return;
11641
+ initialFilesAddedRef.current = true;
11642
+ if (!initialFiles) return;
11643
+ const entries = Object.entries(initialFiles);
11644
+ if (entries.length === 0) return;
11645
+ try {
11646
+ api.addFiles(
11647
+ entries.map(([id, f]) => ({
11648
+ id,
11649
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
11650
+ dataURL: f.dataURL,
11651
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
11652
+ mimeType: f.mimeType,
11653
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
11654
+ created: f.created ?? Date.now()
11655
+ }))
11656
+ );
11657
+ entries.forEach(([id]) => knownFileIdsRef.current.add(id));
11658
+ } catch (err) {
11659
+ console.warn("[whiteboard] addFiles initialFiles th\u1EA5t b\u1EA1i:", err);
11660
+ }
11661
+ }, [api]);
11636
11662
  React8.useEffect(() => {
11637
11663
  if (!api || !persistEnabled) return;
11638
11664
  let cancelled = false;