@zsviczian/excalidraw 0.11.0-obsidian-8 → 0.11.0-obsidian-9

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.
Files changed (64) hide show
  1. package/dist/excalidraw.development.js +84 -73
  2. package/dist/excalidraw.production.min.js +1 -1
  3. package/package.json +3 -3
  4. package/types/actions/actionAddToLibrary.d.ts +18 -6
  5. package/types/actions/actionAlign.d.ts +18 -0
  6. package/types/actions/actionBoundText.d.ts +123 -0
  7. package/types/actions/actionCanvas.d.ts +72 -19
  8. package/types/actions/actionClipboard.d.ts +50 -10
  9. package/types/actions/actionDeleteSelected.d.ts +19 -6
  10. package/types/actions/actionDistribute.d.ts +6 -0
  11. package/types/actions/actionDuplicateSelection.d.ts +3 -0
  12. package/types/actions/actionExport.d.ts +71 -18
  13. package/types/actions/actionFinalize.d.ts +13 -6
  14. package/types/actions/actionFlip.d.ts +6 -0
  15. package/types/actions/actionGroup.d.ts +6 -0
  16. package/types/actions/actionMenu.d.ts +29 -6
  17. package/types/actions/actionNavigate.d.ts +3 -0
  18. package/types/actions/actionProperties.d.ts +82 -26
  19. package/types/actions/actionSelectAll.d.ts +3 -0
  20. package/types/actions/actionStyles.d.ts +11 -2
  21. package/types/actions/actionToggleGridMode.d.ts +9 -2
  22. package/types/actions/actionToggleLock.d.ts +17 -0
  23. package/types/actions/actionToggleStats.d.ts +8 -2
  24. package/types/actions/actionToggleViewMode.d.ts +9 -2
  25. package/types/actions/actionToggleZenMode.d.ts +9 -2
  26. package/types/actions/actionZindex.d.ts +12 -0
  27. package/types/actions/index.d.ts +3 -2
  28. package/types/actions/manager.d.ts +3 -3
  29. package/types/actions/shortcuts.d.ts +1 -1
  30. package/types/actions/types.d.ts +7 -9
  31. package/types/appState.d.ts +9 -4
  32. package/types/clipboard.d.ts +1 -1
  33. package/types/components/Actions.d.ts +4 -4
  34. package/types/components/App.d.ts +3 -2
  35. package/types/components/ImageExportDialog.d.ts +2 -2
  36. package/types/components/JSONExportDialog.d.ts +2 -2
  37. package/types/components/ToolButton.d.ts +3 -0
  38. package/types/constants.d.ts +1 -0
  39. package/types/createInverseContext.d.ts +20 -1
  40. package/types/data/index.d.ts +1 -1
  41. package/types/data/json.d.ts +1 -0
  42. package/types/data/restore.d.ts +1 -1
  43. package/types/element/Hyperlink.d.ts +9 -3
  44. package/types/element/dragElements.d.ts +1 -1
  45. package/types/element/linearElementEditor.d.ts +6 -3
  46. package/types/element/sizeHelpers.d.ts +2 -1
  47. package/types/element/textElement.d.ts +1 -2
  48. package/types/element/typeChecks.d.ts +5 -5
  49. package/types/element/types.d.ts +1 -0
  50. package/types/excalidraw-app/app_constants.d.ts +13 -1
  51. package/types/excalidraw-app/collab/CollabWrapper.d.ts +20 -8
  52. package/types/excalidraw-app/collab/Portal.d.ts +2 -2
  53. package/types/excalidraw-app/collab/reconciliation.d.ts +9 -0
  54. package/types/excalidraw-app/data/FileManager.d.ts +66 -0
  55. package/types/excalidraw-app/data/firebase.d.ts +11 -11
  56. package/types/excalidraw-app/data/index.d.ts +32 -27
  57. package/types/excalidraw-app/data/localStorage.d.ts +19 -19
  58. package/types/excalidraw-app/data/tabSync.d.ts +9 -0
  59. package/types/packages/excalidraw/index.d.ts +1 -1
  60. package/types/packages/utils.d.ts +1 -1
  61. package/types/scene/Scene.d.ts +1 -1
  62. package/types/shapes.d.ts +1 -1
  63. package/types/types.d.ts +10 -3
  64. package/types/utils.d.ts +3 -0
@@ -16,5 +16,5 @@ export declare const copyToClipboard: (elements: readonly NonDeletedExcalidrawEl
16
16
  * Attempts to parse clipboard. Prefers system clipboard.
17
17
  */
18
18
  export declare const parseClipboard: (event: ClipboardEvent | null) => Promise<ClipboardData>;
19
- export declare const copyBlobToClipboardAsPng: (blob: Blob) => Promise<void>;
19
+ export declare const copyBlobToClipboardAsPng: (blob: Blob | Promise<Blob>) => Promise<void>;
20
20
  export declare const copyTextToSystemClipboard: (text: string | null) => Promise<void>;
@@ -2,15 +2,15 @@ import React from "react";
2
2
  import { ActionManager } from "../actions/manager";
3
3
  import { ExcalidrawElement, PointerType } from "../element/types";
4
4
  import { AppState, Zoom } from "../types";
5
- export declare const SelectedShapeActions: ({ appState, elements, renderAction, elementType, }: {
5
+ export declare const SelectedShapeActions: ({ appState, elements, renderAction, activeTool, }: {
6
6
  appState: AppState;
7
7
  elements: readonly ExcalidrawElement[];
8
8
  renderAction: ActionManager["renderAction"];
9
- elementType: AppState["elementType"];
9
+ activeTool: AppState["activeTool"]["type"];
10
10
  }) => JSX.Element;
11
- export declare const ShapesSwitcher: ({ canvas, elementType, setAppState, onImageAction, appState, }: {
11
+ export declare const ShapesSwitcher: ({ canvas, activeTool, setAppState, onImageAction, appState, }: {
12
12
  canvas: HTMLCanvasElement | null;
13
- elementType: AppState["elementType"];
13
+ activeTool: AppState["activeTool"];
14
14
  setAppState: React.Component<any, AppState>["setState"];
15
15
  onImageAction: (data: {
16
16
  pointerType: PointerType | null;
@@ -77,7 +77,7 @@ declare class App extends React.Component<AppProps, AppState> {
77
77
  private addTextFromPaste;
78
78
  setAppState: (obj: any) => void;
79
79
  removePointer: (event: React.PointerEvent<HTMLElement> | PointerEvent) => void;
80
- toggleLock: () => void;
80
+ toggleLock: (source?: "keyboard" | "ui") => void;
81
81
  togglePenMode: () => void;
82
82
  toggleZenMode: () => void;
83
83
  toggleStats: () => void;
@@ -107,7 +107,7 @@ declare class App extends React.Component<AppProps, AppState> {
107
107
  private updateCurrentCursorPosition;
108
108
  private onKeyDown;
109
109
  private onKeyUp;
110
- private selectShapeTool;
110
+ private setActiveTool;
111
111
  private onGestureStart;
112
112
  private onGestureChange;
113
113
  private onGestureEnd;
@@ -149,6 +149,7 @@ declare class App extends React.Component<AppProps, AppState> {
149
149
  private onPointerMoveFromPointerDownHandler;
150
150
  private handlePointerMoveOverScrollbars;
151
151
  private onPointerUpFromPointerDownHandler;
152
+ private restoreReadyToEraseElements;
152
153
  private eraseElements;
153
154
  private initializeImage;
154
155
  /**
@@ -1,8 +1,8 @@
1
1
  /// <reference types="react" />
2
- import { ActionsManagerInterface } from "../actions/types";
3
2
  import { NonDeletedExcalidrawElement } from "../element/types";
4
3
  import { AppState, BinaryFiles } from "../types";
5
4
  import "./ExportDialog.scss";
5
+ import { ActionManager } from "../actions/manager";
6
6
  export declare const ErrorCanvasPreview: () => JSX.Element;
7
7
  export declare type ExportCB = (elements: readonly NonDeletedExcalidrawElement[], scale?: number) => void;
8
8
  export declare const ImageExportDialog: ({ elements, appState, files, exportPadding, actionManager, onExportToPng, onExportToSvg, onExportToClipboard, }: {
@@ -10,7 +10,7 @@ export declare const ImageExportDialog: ({ elements, appState, files, exportPadd
10
10
  elements: readonly NonDeletedExcalidrawElement[];
11
11
  files: BinaryFiles;
12
12
  exportPadding?: number | undefined;
13
- actionManager: ActionsManagerInterface;
13
+ actionManager: ActionManager;
14
14
  onExportToPng: ExportCB;
15
15
  onExportToSvg: ExportCB;
16
16
  onExportToClipboard: ExportCB;
@@ -1,14 +1,14 @@
1
1
  /// <reference types="react" />
2
- import { ActionsManagerInterface } from "../actions/types";
3
2
  import { NonDeletedExcalidrawElement } from "../element/types";
4
3
  import { AppState, ExportOpts, BinaryFiles } from "../types";
5
4
  import "./ExportDialog.scss";
5
+ import { ActionManager } from "../actions/manager";
6
6
  export declare type ExportCB = (elements: readonly NonDeletedExcalidrawElement[], scale?: number) => void;
7
7
  export declare const JSONExportDialog: ({ elements, appState, files, actionManager, exportOpts, canvas, }: {
8
8
  elements: readonly NonDeletedExcalidrawElement[];
9
9
  appState: AppState;
10
10
  files: BinaryFiles;
11
- actionManager: ActionsManagerInterface;
11
+ actionManager: ActionManager;
12
12
  exportOpts: ExportOpts;
13
13
  canvas: HTMLCanvasElement | null;
14
14
  }) => JSX.Element;
@@ -38,6 +38,9 @@ declare type ToolButtonProps = (ToolButtonBaseProps & {
38
38
  onChange?(data: {
39
39
  pointerType: PointerType | null;
40
40
  }): void;
41
+ onPointerDown?(data: {
42
+ pointerType: PointerType;
43
+ }): void;
41
44
  });
42
45
  export declare const ToolButton: React.ForwardRefExoticComponent<ToolButtonProps & React.RefAttributes<unknown>>;
43
46
  export {};
@@ -138,3 +138,4 @@ export declare const VERTICAL_ALIGN: {
138
138
  MIDDLE: string;
139
139
  BOTTOM: string;
140
140
  };
141
+ export declare const ELEMENT_READY_TO_ERASE_OPACITY = 20;
@@ -1 +1,20 @@
1
- export declare const createInverseContext: <T extends unknown = null>(initialValue: T) => any;
1
+ import React from "react";
2
+ export declare class InverseConsumer extends React.Component {
3
+ state: {
4
+ value: any;
5
+ };
6
+ constructor(props: any);
7
+ render(): JSX.Element;
8
+ }
9
+ export declare class InverseProvider extends React.Component<{
10
+ value: any;
11
+ }> {
12
+ componentDidMount(): void;
13
+ componentDidUpdate(): void;
14
+ render(): JSX.Element;
15
+ }
16
+ export declare const createInverseContext: <T extends unknown = null>(initialValue: T) => {
17
+ Context: any;
18
+ Consumer: typeof InverseConsumer;
19
+ Provider: typeof InverseProvider;
20
+ };
@@ -4,7 +4,7 @@ import { AppState, BinaryFiles } from "../types";
4
4
  import { FileSystemHandle } from "./filesystem";
5
5
  export { loadFromBlob } from "./blob";
6
6
  export { loadFromJSON, saveAsJSON } from "./json";
7
- export declare const exportCanvas: (type: ExportType, elements: readonly NonDeletedExcalidrawElement[], appState: AppState, files: BinaryFiles, { exportBackground, exportPadding, viewBackgroundColor, name, fileHandle, }: {
7
+ export declare const exportCanvas: (type: Omit<ExportType, "backend">, elements: readonly NonDeletedExcalidrawElement[], appState: AppState, files: BinaryFiles, { exportBackground, exportPadding, viewBackgroundColor, name, fileHandle, }: {
8
8
  exportBackground: boolean;
9
9
  exportPadding?: number | undefined;
10
10
  viewBackgroundColor: string;
@@ -13,5 +13,6 @@ export declare const isValidExcalidrawData: (data?: {
13
13
  appState?: any;
14
14
  } | undefined) => data is ImportedDataState;
15
15
  export declare const isValidLibrary: (json: any) => any;
16
+ export declare const serializeLibraryAsJSON: (libraryItems: LibraryItems) => string;
16
17
  export declare const saveLibraryAsJSON: (libraryItems: LibraryItems) => Promise<void>;
17
18
  export declare const importLibraryFromJSON: (library: Library) => Promise<void>;
@@ -2,7 +2,7 @@ import { ExcalidrawElement } from "../element/types";
2
2
  import { AppState, BinaryFiles, LibraryItem } from "../types";
3
3
  import { ImportedDataState } from "./types";
4
4
  declare type RestoredAppState = Omit<AppState, "offsetTop" | "offsetLeft" | "width" | "height">;
5
- export declare const AllowedExcalidrawElementTypes: Record<AppState["elementType"], boolean>;
5
+ export declare const AllowedExcalidrawActiveTools: Record<AppState["activeTool"]["type"], boolean>;
6
6
  export declare type RestoredDataState = {
7
7
  elements: ExcalidrawElement[];
8
8
  appState: RestoredAppState;
@@ -30,8 +30,11 @@ export declare const actionLink: {
30
30
  suggestedBindings: import("./binding").SuggestedBinding[];
31
31
  editingElement: NonDeletedExcalidrawElement | null;
32
32
  editingLinearElement: import("./linearElementEditor").LinearElementEditor | null;
33
- elementType: "line" | "arrow" | "text" | "selection" | "rectangle" | "diamond" | "ellipse" | "image" | "freedraw" | "eraser";
34
- elementLocked: boolean;
33
+ activeTool: {
34
+ type: "line" | "arrow" | "text" | "selection" | "rectangle" | "diamond" | "ellipse" | "image" | "freedraw" | "eraser";
35
+ lastActiveToolBeforeEraser: "line" | "arrow" | "text" | "selection" | "rectangle" | "diamond" | "ellipse" | "image" | "freedraw" | null;
36
+ locked: boolean;
37
+ };
35
38
  penMode: boolean;
36
39
  penDetected: boolean;
37
40
  exportBackground: boolean;
@@ -109,7 +112,10 @@ export declare const actionLink: {
109
112
  };
110
113
  commitToHistory: true;
111
114
  };
112
- trackEvent: (action: import("../actions/types").Action, source: "ui" | "keyboard" | "api") => void;
115
+ trackEvent: {
116
+ category: "hyperlink";
117
+ action: string;
118
+ };
113
119
  keyTest: (event: KeyboardEvent | import("react").KeyboardEvent<Element>) => boolean;
114
120
  contextItemLabel: (elements: readonly import("./types").ExcalidrawElement[], appState: Readonly<AppState>) => "labels.link.edit" | "labels.link.create";
115
121
  contextItemPredicate: (elements: readonly import("./types").ExcalidrawElement[], appState: AppState) => boolean;
@@ -2,4 +2,4 @@ import { NonDeletedExcalidrawElement } from "./types";
2
2
  import { AppState, PointerDownState } from "../types";
3
3
  export declare const dragSelectedElements: (pointerDownState: PointerDownState, selectedElements: NonDeletedExcalidrawElement[], pointerX: number, pointerY: number, lockDirection: boolean | undefined, distanceX: number | undefined, distanceY: number | undefined, appState: AppState) => void;
4
4
  export declare const getDragOffsetXY: (selectedElements: NonDeletedExcalidrawElement[], x: number, y: number) => [number, number];
5
- export declare const dragNewElement: (draggingElement: NonDeletedExcalidrawElement, elementType: AppState["elementType"], originX: number, originY: number, x: number, y: number, width: number, height: number, shouldMaintainAspectRatio: boolean, shouldResizeFromCenter: boolean, widthAspectRatio?: number | null | undefined) => void;
5
+ export declare const dragNewElement: (draggingElement: NonDeletedExcalidrawElement, elementType: AppState["activeTool"]["type"], originX: number, originY: number, x: number, y: number, width: number, height: number, shouldMaintainAspectRatio: boolean, shouldResizeFromCenter: boolean, widthAspectRatio?: number | null | undefined) => void;
@@ -96,8 +96,11 @@ export declare class LinearElementEditor {
96
96
  startBoundElement: NonDeleted<ExcalidrawBindableElement> | null;
97
97
  suggestedBindings: import("./binding").SuggestedBinding[];
98
98
  editingElement: import("./types").NonDeletedExcalidrawElement | null;
99
- elementType: "line" | "arrow" | "text" | "selection" | "rectangle" | "diamond" | "ellipse" | "image" | "freedraw" | "eraser";
100
- elementLocked: boolean;
99
+ activeTool: {
100
+ type: "line" | "arrow" | "text" | "selection" | "rectangle" | "diamond" | "ellipse" | "image" | "freedraw" | "eraser";
101
+ lastActiveToolBeforeEraser: "line" | "arrow" | "text" | "selection" | "rectangle" | "diamond" | "ellipse" | "image" | "freedraw" | null;
102
+ locked: boolean;
103
+ };
101
104
  penMode: boolean;
102
105
  penDetected: boolean;
103
106
  exportBackground: boolean;
@@ -140,7 +143,7 @@ export declare class LinearElementEditor {
140
143
  };
141
144
  shouldCacheIgnoreZoom: boolean;
142
145
  showHelpDialog: boolean;
143
- toastMessage: string | null; /** @returns whether point was dragged */
146
+ toastMessage: string | null;
144
147
  zenModeEnabled: boolean;
145
148
  theme: string;
146
149
  gridSize: number | null;
@@ -1,9 +1,10 @@
1
1
  import { ExcalidrawElement } from "./types";
2
+ import { AppState } from "../types";
2
3
  export declare const isInvisiblySmallElement: (element: ExcalidrawElement) => boolean;
3
4
  /**
4
5
  * Makes a perfect shape or diagonal/horizontal/vertical line
5
6
  */
6
- export declare const getPerfectElementSize: (elementType: string, width: number, height: number) => {
7
+ export declare const getPerfectElementSize: (elementType: AppState["activeTool"]["type"], width: number, height: number) => {
7
8
  width: number;
8
9
  height: number;
9
10
  };
@@ -1,7 +1,6 @@
1
1
  import { ExcalidrawElement, ExcalidrawTextElement, ExcalidrawTextElementWithContainer, FontString, NonDeletedExcalidrawElement } from "./types";
2
2
  import { MaybeTransformHandleType } from "./transformHandles";
3
- import { AppState } from "../types";
4
- export declare const redrawTextBoundingBox: (element: ExcalidrawTextElement, container: ExcalidrawElement | null, appState: AppState) => void;
3
+ export declare const redrawTextBoundingBox: (element: ExcalidrawTextElement, container: ExcalidrawElement | null) => void;
5
4
  export declare const bindTextToShapeAfterDuplication: (sceneElements: ExcalidrawElement[], oldElements: ExcalidrawElement[], oldIdToDuplicatedId: Map<ExcalidrawElement["id"], ExcalidrawElement["id"]>) => void;
6
5
  export declare const handleBindTextResize: (element: NonDeletedExcalidrawElement, transformHandleType: MaybeTransformHandleType) => void;
7
6
  export declare const measureText: (text: string, font: FontString, maxWidth?: number | null | undefined) => {
@@ -7,11 +7,11 @@ export declare const isTextElement: (element: ExcalidrawElement | null) => eleme
7
7
  export declare const isFreeDrawElement: (element?: ExcalidrawElement | null | undefined) => element is ExcalidrawFreeDrawElement;
8
8
  export declare const isFreeDrawElementType: (elementType: ExcalidrawElement["type"]) => boolean;
9
9
  export declare const isLinearElement: (element?: ExcalidrawElement | null | undefined) => element is ExcalidrawLinearElement;
10
- export declare const isLinearElementType: (elementType: AppState["elementType"]) => boolean;
11
- export declare const isBindingElement: (element?: ExcalidrawElement | null | undefined) => element is ExcalidrawLinearElement;
12
- export declare const isBindingElementType: (elementType: AppState["elementType"]) => boolean;
13
- export declare const isBindableElement: (element: ExcalidrawElement | null) => element is ExcalidrawBindableElement;
14
- export declare const isTextBindableContainer: (element: ExcalidrawElement | null) => element is ExcalidrawTextContainer;
10
+ export declare const isLinearElementType: (elementType: AppState["activeTool"]["type"]) => boolean;
11
+ export declare const isBindingElement: (element?: ExcalidrawElement | null | undefined, includeLocked?: boolean) => element is ExcalidrawLinearElement;
12
+ export declare const isBindingElementType: (elementType: AppState["activeTool"]["type"]) => boolean;
13
+ export declare const isBindableElement: (element: ExcalidrawElement | null, includeLocked?: boolean) => element is ExcalidrawBindableElement;
14
+ export declare const isTextBindableContainer: (element: ExcalidrawElement | null, includeLocked?: boolean) => element is ExcalidrawTextContainer;
15
15
  export declare const isExcalidrawElement: (element: any) => boolean;
16
16
  export declare const hasBoundTextElement: (element: ExcalidrawElement | null) => element is ExcalidrawBindableElement;
17
17
  export declare const isBoundToContainer: (element: ExcalidrawElement | null) => element is ExcalidrawTextElementWithContainer;
@@ -52,6 +52,7 @@ declare type _ExcalidrawElementBase = Readonly<{
52
52
  /** epoch (ms) timestamp of last element update */
53
53
  updated: number;
54
54
  link: string | null;
55
+ locked: boolean;
55
56
  }>;
56
57
  export declare type ExcalidrawSelectionElement = _ExcalidrawElementBase & {
57
58
  type: "selection";
@@ -3,8 +3,10 @@ export declare const INITIAL_SCENE_UPDATE_TIMEOUT = 5000;
3
3
  export declare const FILE_UPLOAD_TIMEOUT = 300;
4
4
  export declare const LOAD_IMAGES_TIMEOUT = 500;
5
5
  export declare const SYNC_FULL_SCENE_INTERVAL_MS = 20000;
6
+ export declare const SYNC_BROWSER_TABS_TIMEOUT = 50;
7
+ export declare const CURSOR_SYNC_TIMEOUT = 33;
6
8
  export declare const FILE_UPLOAD_MAX_BYTES: number;
7
- export declare const FILE_CACHE_MAX_AGE_SEC = 2592000;
9
+ export declare const FILE_CACHE_MAX_AGE_SEC = 31536000;
8
10
  export declare const BROADCAST: {
9
11
  SERVER_VOLATILE: string;
10
12
  SERVER: string;
@@ -17,3 +19,13 @@ export declare const FIREBASE_STORAGE_PREFIXES: {
17
19
  shareLinkFiles: string;
18
20
  collabFiles: string;
19
21
  };
22
+ export declare const ROOM_ID_BYTES = 10;
23
+ export declare const STORAGE_KEYS: {
24
+ readonly LOCAL_STORAGE_ELEMENTS: "excalidraw";
25
+ readonly LOCAL_STORAGE_APP_STATE: "excalidraw-state";
26
+ readonly LOCAL_STORAGE_COLLAB: "excalidraw-collab";
27
+ readonly LOCAL_STORAGE_KEY_COLLAB_FORCE_FLAG: "collabLinkForceLoadFlag";
28
+ readonly LOCAL_STORAGE_LIBRARY: "excalidraw-library";
29
+ readonly VERSION_DATA_STATE: "version-dataState";
30
+ readonly VERSION_FILES: "version-files";
31
+ };
@@ -7,7 +7,8 @@ import { Gesture } from "../../types";
7
7
  import { SocketUpdateDataSource } from "../data";
8
8
  import Portal from "./Portal";
9
9
  import { UserIdleState } from "../../types";
10
- import { FileSync } from "../data/FileSync";
10
+ import { FileManager } from "../data/FileManager";
11
+ import React from "react";
11
12
  interface CollabState {
12
13
  modalIsShown: boolean;
13
14
  errorMessage: string;
@@ -26,15 +27,23 @@ export interface CollabAPI {
26
27
  onCollabButtonClick: CollabInstance["onCollabButtonClick"];
27
28
  broadcastElements: CollabInstance["broadcastElements"];
28
29
  fetchImageFilesFromFirebase: CollabInstance["fetchImageFilesFromFirebase"];
30
+ setUsername: (username: string) => void;
29
31
  }
30
32
  interface Props {
31
33
  excalidrawAPI: ExcalidrawImperativeAPI;
34
+ onRoomClose?: () => void;
32
35
  }
33
- declare const CollabContext: any, CollabContextConsumer: any;
34
- export { CollabContext, CollabContextConsumer };
36
+ declare const CollabContext: React.Context<{
37
+ api: CollabAPI | null;
38
+ }> & {
39
+ _updateProviderValue?: ((value: {
40
+ api: CollabAPI | null;
41
+ }) => void) | undefined;
42
+ };
43
+ export { CollabContext };
35
44
  declare class CollabWrapper extends PureComponent<Props, CollabState> {
36
45
  portal: Portal;
37
- fileSync: FileSync;
46
+ fileManager: FileManager;
38
47
  excalidrawAPI: Props["excalidrawAPI"];
39
48
  isCollaborating: boolean;
40
49
  activeIntervalId: number | null;
@@ -47,13 +56,14 @@ declare class CollabWrapper extends PureComponent<Props, CollabState> {
47
56
  componentWillUnmount(): void;
48
57
  private onUnload;
49
58
  private beforeUnload;
50
- saveCollabRoomToFirebase: (syncableElements?: ExcalidrawElement[]) => Promise<void>;
59
+ saveCollabRoomToFirebase: (syncableElements?: readonly ExcalidrawElement[]) => Promise<void>;
51
60
  openPortal: () => Promise<ImportedDataState | null>;
52
61
  closePortal: () => void;
53
62
  private destroySocketClient;
54
63
  private fetchImageFilesFromFirebase;
64
+ private decryptPayload;
55
65
  private initializeSocketClient;
56
- private initializeSocket;
66
+ private initializeRoom;
57
67
  private reconcileElements;
58
68
  private loadImageFiles;
59
69
  private handleRemoteSceneUpdate;
@@ -66,17 +76,19 @@ declare class CollabWrapper extends PureComponent<Props, CollabState> {
66
76
  setLastBroadcastedOrReceivedSceneVersion: (version: number) => void;
67
77
  getLastBroadcastedOrReceivedSceneVersion: () => number;
68
78
  getSceneElementsIncludingDeleted: () => readonly ExcalidrawElement[];
69
- onPointerUpdate: (payload: {
79
+ onPointerUpdate: import("lodash").DebouncedFunc<(payload: {
70
80
  pointer: SocketUpdateDataSource["MOUSE_LOCATION"]["payload"]["pointer"];
71
81
  button: SocketUpdateDataSource["MOUSE_LOCATION"]["payload"]["button"];
72
82
  pointersMap: Gesture["pointers"];
73
- }) => void;
83
+ }) => void>;
74
84
  onIdleStateChange: (userState: UserIdleState) => void;
75
85
  broadcastElements: (elements: readonly ExcalidrawElement[]) => void;
76
86
  queueBroadcastAllElements: import("lodash").DebouncedFunc<() => void>;
77
87
  handleClose: () => void;
88
+ setUsername: (username: string) => void;
78
89
  onUsernameChange: (username: string) => void;
79
90
  onCollabButtonClick: () => void;
91
+ isSyncableElement: (element: ExcalidrawElement) => boolean;
80
92
  getSyncableElements: (elements: readonly ExcalidrawElement[]) => ExcalidrawElement[];
81
93
  /** PRIVATE. Use `this.getContextValue()` instead. */
82
94
  private contextValue;
@@ -13,12 +13,12 @@ declare class Portal {
13
13
  roomKey: string | null;
14
14
  broadcastedElementVersions: Map<string, number>;
15
15
  constructor(collab: CollabWrapper);
16
- open(socket: SocketIOClient.Socket, id: string, key: string): void;
16
+ open(socket: SocketIOClient.Socket, id: string, key: string): SocketIOClient.Socket;
17
17
  close(): void;
18
18
  isOpen(): boolean;
19
19
  _broadcastSocketData(data: SocketUpdateData, volatile?: boolean): Promise<void>;
20
20
  queueFileUpload: import("lodash").DebouncedFunc<() => Promise<void>>;
21
- broadcastScene: (sceneType: SCENE.INIT | SCENE.UPDATE, syncableElements: ExcalidrawElement[], syncAll: boolean) => Promise<void>;
21
+ broadcastScene: (sceneType: SCENE.INIT | SCENE.UPDATE, allElements: readonly ExcalidrawElement[], syncAll: boolean) => Promise<void>;
22
22
  broadcastIdleChange: (userState: UserIdleState) => Promise<void> | undefined;
23
23
  broadcastMouseLocation: (payload: {
24
24
  pointer: SocketUpdateDataSource["MOUSE_LOCATION"]["payload"]["pointer"];
@@ -0,0 +1,9 @@
1
+ import { ExcalidrawElement } from "../../element/types";
2
+ import { AppState } from "../../types";
3
+ export declare type ReconciledElements = readonly ExcalidrawElement[] & {
4
+ _brand: "reconciledElements";
5
+ };
6
+ export declare type BroadcastedExcalidrawElement = ExcalidrawElement & {
7
+ parent?: string;
8
+ };
9
+ export declare const reconcileElements: (localElements: readonly ExcalidrawElement[], remoteElements: readonly BroadcastedExcalidrawElement[], localAppState: AppState) => ReconciledElements;
@@ -0,0 +1,66 @@
1
+ import { ExcalidrawElement, FileId, InitializedExcalidrawImageElement } from "../../element/types";
2
+ import { BinaryFileData, ExcalidrawImperativeAPI, BinaryFiles } from "../../types";
3
+ export declare class FileManager {
4
+ /** files being fetched */
5
+ private fetchingFiles;
6
+ /** files being saved */
7
+ private savingFiles;
8
+ private savedFiles;
9
+ private erroredFiles;
10
+ private _getFiles;
11
+ private _saveFiles;
12
+ constructor({ getFiles, saveFiles, }: {
13
+ getFiles: (fileIds: FileId[]) => Promise<{
14
+ loadedFiles: BinaryFileData[];
15
+ erroredFiles: Map<FileId, true>;
16
+ }>;
17
+ saveFiles: (data: {
18
+ addedFiles: Map<FileId, BinaryFileData>;
19
+ }) => Promise<{
20
+ savedFiles: Map<FileId, true>;
21
+ erroredFiles: Map<FileId, true>;
22
+ }>;
23
+ });
24
+ /**
25
+ * returns whether file is already saved or being processed
26
+ */
27
+ isFileHandled: (id: FileId) => boolean;
28
+ isFileSaved: (id: FileId) => boolean;
29
+ saveFiles: ({ elements, files, }: {
30
+ elements: readonly ExcalidrawElement[];
31
+ files: BinaryFiles;
32
+ }) => Promise<{
33
+ savedFiles: Map<FileId, true>;
34
+ erroredFiles: Map<FileId, true>;
35
+ }>;
36
+ getFiles: (ids: FileId[]) => Promise<{
37
+ loadedFiles: BinaryFileData[];
38
+ erroredFiles: Map<FileId, true>;
39
+ }>;
40
+ /** a file element prevents unload only if it's being saved regardless of
41
+ * its `status`. This ensures that elements who for any reason haven't
42
+ * beed set to `saved` status don't prevent unload in future sessions.
43
+ * Technically we should prevent unload when the origin client haven't
44
+ * yet saved the `status` update to storage, but that should be taken care
45
+ * of during regular beforeUnload unsaved files check.
46
+ */
47
+ shouldPreventUnload: (elements: readonly ExcalidrawElement[]) => boolean;
48
+ /**
49
+ * helper to determine if image element status needs updating
50
+ */
51
+ shouldUpdateImageElementStatus: (element: ExcalidrawElement) => element is InitializedExcalidrawImageElement;
52
+ reset(): void;
53
+ }
54
+ export declare const encodeFilesForUpload: ({ files, maxBytes, encryptionKey, }: {
55
+ files: Map<FileId, BinaryFileData>;
56
+ maxBytes: number;
57
+ encryptionKey: string;
58
+ }) => Promise<{
59
+ id: FileId;
60
+ buffer: Uint8Array;
61
+ }[]>;
62
+ export declare const updateStaleImageStatuses: (params: {
63
+ excalidrawAPI: ExcalidrawImperativeAPI;
64
+ erroredFiles: Map<FileId, true>;
65
+ elements: readonly ExcalidrawElement[];
66
+ }) => void;
@@ -1,22 +1,22 @@
1
1
  /// <reference types="socket.io-client" />
2
- import { ExcalidrawElement, ImageId } from "../../element/types";
2
+ import { ExcalidrawElement, FileId } from "../../element/types";
3
3
  import Portal from "../collab/Portal";
4
- import { BinaryFileData, DataURL } from "../../types";
4
+ import { BinaryFileData } from "../../types";
5
5
  export declare const loadFirebaseStorage: () => Promise<typeof import("firebase/app").default>;
6
6
  export declare const isSavedToFirebase: (portal: Portal, elements: readonly ExcalidrawElement[]) => boolean;
7
- export declare const saveFilesToFirebase: ({ prefix, encryptionKey, files, allowedTypes, maxBytes, }: {
7
+ export declare const saveFilesToFirebase: ({ prefix, files, }: {
8
8
  prefix: string;
9
- encryptionKey: string;
10
- files: Map<ImageId, DataURL>;
11
- allowedTypes: string[];
12
- maxBytes: number;
9
+ files: {
10
+ id: FileId;
11
+ buffer: Uint8Array;
12
+ }[];
13
13
  }) => Promise<{
14
- savedFiles: Map<ImageId, true>;
15
- erroredFiles: Map<ImageId, true>;
14
+ savedFiles: Map<FileId, true>;
15
+ erroredFiles: Map<FileId, true>;
16
16
  }>;
17
17
  export declare const saveToFirebase: (portal: Portal, elements: readonly ExcalidrawElement[]) => Promise<boolean>;
18
18
  export declare const loadFromFirebase: (roomId: string, roomKey: string, socket: SocketIOClient.Socket | null) => Promise<readonly ExcalidrawElement[] | null>;
19
- export declare const loadFilesFromFirebase: (prefix: string, decryptionKey: string, filesIds: readonly ImageId[]) => Promise<{
19
+ export declare const loadFilesFromFirebase: (prefix: string, decryptionKey: string, filesIds: readonly FileId[]) => Promise<{
20
20
  loadedFiles: BinaryFileData[];
21
- erroredFiles: ImageId[];
21
+ erroredFiles: Map<FileId, true>;
22
22
  }>;
@@ -1,8 +1,17 @@
1
1
  import { ImportedDataState } from "../../data/types";
2
2
  import { ExcalidrawElement } from "../../element/types";
3
- import { AppState, UserIdleState } from "../../types";
4
- export declare const generateEncryptionKey: () => Promise<string | undefined>;
5
- export declare const SOCKET_SERVER: string;
3
+ import { AppState, BinaryFiles, UserIdleState } from "../../types";
4
+ /**
5
+ * Right now the reason why we resolve connection params (url, polling...)
6
+ * from upstream is to allow changing the params immediately when needed without
7
+ * having to wait for clients to update the SW.
8
+ *
9
+ * If REACT_APP_WS_SERVER_URL env is set, we use that instead (useful for forks)
10
+ */
11
+ export declare const getCollabServer: () => Promise<{
12
+ url: string;
13
+ polling: boolean;
14
+ }>;
6
15
  export declare type EncryptedData = {
7
16
  data: ArrayBuffer;
8
17
  iv: Uint8Array;
@@ -48,9 +57,6 @@ export declare type SocketUpdateDataIncoming = SocketUpdateDataSource[keyof Sock
48
57
  export declare type SocketUpdateData = SocketUpdateDataSource[keyof SocketUpdateDataSource] & {
49
58
  _brand: "socketUpdateData";
50
59
  };
51
- export declare const createIV: () => Uint8Array;
52
- export declare const encryptAESGEM: (data: Uint8Array, key: string) => Promise<EncryptedData>;
53
- export declare const decryptAESGEM: (data: ArrayBuffer, key: string, iv: Uint8Array) => Promise<SocketUpdateDataIncoming>;
54
60
  export declare const getCollaborationLinkData: (link: string) => {
55
61
  roomId: string;
56
62
  roomKey: string;
@@ -63,22 +69,19 @@ export declare const getCollaborationLink: (data: {
63
69
  roomId: string;
64
70
  roomKey: string;
65
71
  }) => string;
66
- export declare const getImportedKey: (key: string, usage: KeyUsage) => Promise<CryptoKey>;
67
- export declare const decryptImported: (iv: ArrayBuffer, encrypted: ArrayBuffer, privateKey: string) => Promise<ArrayBuffer>;
68
72
  export declare const loadScene: (id: string | null, privateKey: string | null, localDataState: ImportedDataState | undefined | null) => Promise<{
69
73
  elements: ExcalidrawElement[];
70
74
  appState: {
71
- theme: "light" | "dark";
75
+ elementType: "line" | "arrow" | "text" | "selection" | "rectangle" | "diamond" | "ellipse" | "image" | "freedraw" | "eraser";
76
+ scrollX: number;
77
+ scrollY: number;
78
+ viewBackgroundColor: string;
72
79
  zoom: Readonly<{
73
80
  value: import("../../types").NormalizedZoomValue;
74
- translation: Readonly<{
75
- x: number;
76
- y: number;
77
- }>;
78
81
  }>;
79
- scrollX: number;
80
- scrollY: number;
81
- files: Record<string, import("../../types").BinaryFileData>;
82
+ shouldCacheIgnoreZoom: boolean;
83
+ theme: string;
84
+ name: string;
82
85
  isLoading: boolean;
83
86
  errorMessage: string | null;
84
87
  draggingElement: import("../../element/types").NonDeletedExcalidrawElement | null;
@@ -90,8 +93,9 @@ export declare const loadScene: (id: string | null, privateKey: string | null, l
90
93
  suggestedBindings: import("../../element/binding").SuggestedBinding[];
91
94
  editingElement: import("../../element/types").NonDeletedExcalidrawElement | null;
92
95
  editingLinearElement: import("../../element/linearElementEditor").LinearElementEditor | null;
93
- elementType: "line" | "selection" | "rectangle" | "diamond" | "ellipse" | "image" | "text" | "arrow" | "freedraw";
94
96
  elementLocked: boolean;
97
+ penMode: boolean;
98
+ penDetected: boolean;
95
99
  exportBackground: boolean;
96
100
  exportEmbedScene: boolean;
97
101
  exportWithDarkMode: boolean;
@@ -110,10 +114,8 @@ export declare const loadScene: (id: string | null, privateKey: string | null, l
110
114
  currentItemStartArrowhead: import("../../element/types").Arrowhead | null;
111
115
  currentItemEndArrowhead: import("../../element/types").Arrowhead | null;
112
116
  currentItemLinearStrokeSharpness: import("../../element/types").StrokeSharpness;
113
- viewBackgroundColor: string;
114
117
  cursorButton: "up" | "down";
115
118
  scrolledOutside: boolean;
116
- name: string;
117
119
  isResizing: boolean;
118
120
  isRotating: boolean;
119
121
  openMenu: "canvas" | "shape" | null;
@@ -125,7 +127,6 @@ export declare const loadScene: (id: string | null, privateKey: string | null, l
125
127
  previousSelectedElementIds: {
126
128
  [id: string]: boolean;
127
129
  };
128
- shouldCacheIgnoreZoom: boolean;
129
130
  showHelpDialog: boolean;
130
131
  toastMessage: string | null;
131
132
  zenModeEnabled: boolean;
@@ -136,7 +137,7 @@ export declare const loadScene: (id: string | null, privateKey: string | null, l
136
137
  };
137
138
  editingGroupId: string | null;
138
139
  isLibraryOpen: boolean;
139
- fileHandle: import("@dwelle/browser-fs-access").FileSystemHandle | null;
140
+ fileHandle: import("browser-fs-access").FileSystemHandle | null;
140
141
  collaborators: Map<string, import("../../types").Collaborator>;
141
142
  showStats: boolean;
142
143
  currentChartType: import("../../element/types").ChartType;
@@ -148,12 +149,16 @@ export declare const loadScene: (id: string | null, privateKey: string | null, l
148
149
  data: import("../../charts").Spreadsheet;
149
150
  };
150
151
  pendingImageElement: import("../../element/types").NonDeleted<import("../../element/types").ExcalidrawImageElement> | null;
152
+ showHyperlinkPopup: false | "info" | "editor";
153
+ linkOpacity: number;
154
+ trayModeEnabled: boolean;
155
+ colorPalette: {
156
+ canvasBackground?: string[] | undefined;
157
+ elementBackground?: string[] | undefined;
158
+ elementStroke?: string[] | undefined;
159
+ };
151
160
  };
161
+ files: BinaryFiles;
152
162
  commitToHistory: boolean;
153
163
  }>;
154
- export declare const exportToBackend: (elements: readonly ExcalidrawElement[], appState: AppState) => Promise<void>;
155
- export declare const encryptData: (key: string, data: Uint8Array | Blob | File | string) => Promise<{
156
- encryptedBuffer: ArrayBuffer;
157
- iv: Uint8Array;
158
- }>;
159
- export declare const decryptData: (iv: ArrayBuffer, encrypted: ArrayBuffer, privateKey: string) => Promise<ArrayBuffer>;
164
+ export declare const exportToBackend: (elements: readonly ExcalidrawElement[], appState: AppState, files: BinaryFiles) => Promise<void>;