@excalidraw/excalidraw 0.17.1-890ed9f → 0.17.1-96eeec5
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/CHANGELOG.md +15 -2
- package/dist/browser/dev/excalidraw-assets-dev/{blockDiagram-91b80b7a-ACFH36JV.js → blockDiagram-91b80b7a-H47FTXHA.js} +5 -5
- package/dist/browser/dev/excalidraw-assets-dev/{c4Diagram-b2a90758-QZ27YR47.js → c4Diagram-b2a90758-NNJK6GKC.js} +3 -3
- package/dist/browser/dev/excalidraw-assets-dev/{chunk-HO2HMSK7.js → chunk-4KQVEBHW.js} +3 -3
- package/dist/browser/dev/excalidraw-assets-dev/{chunk-USGV265L.js → chunk-53YI56GV.js} +4 -4
- package/dist/browser/dev/excalidraw-assets-dev/{chunk-EDFX3S7X.js → chunk-A2WCJI4I.js} +3 -3
- package/dist/browser/dev/excalidraw-assets-dev/{chunk-WQFMSDPT.js → chunk-DEYXWPUO.js} +7503 -2575
- package/dist/browser/dev/excalidraw-assets-dev/chunk-DEYXWPUO.js.map +7 -0
- package/dist/browser/dev/excalidraw-assets-dev/{chunk-IX4V72YG.js → chunk-EFLPX7NE.js} +6 -6
- package/dist/browser/dev/excalidraw-assets-dev/{chunk-XOM7LNOU.js → chunk-EM6LVGFW.js} +27 -4
- package/dist/browser/dev/excalidraw-assets-dev/chunk-EM6LVGFW.js.map +7 -0
- package/dist/browser/dev/excalidraw-assets-dev/{chunk-MXVETLVM.js → chunk-JYIQCNWV.js} +2 -2
- package/dist/browser/dev/excalidraw-assets-dev/{chunk-YZIOORVX.js → chunk-LVIQQW6F.js} +2 -2
- package/dist/browser/dev/excalidraw-assets-dev/{chunk-6U7GQNJT.js → chunk-PXLO3FOU.js} +2 -2
- package/dist/browser/dev/excalidraw-assets-dev/{chunk-7DACDEY3.js → chunk-TO2AW5PW.js} +2 -2
- package/dist/browser/dev/excalidraw-assets-dev/{chunk-NJ77ZFNJ.js → chunk-VURILHLY.js} +2 -2
- package/dist/browser/dev/excalidraw-assets-dev/{chunk-2T2GU7NF.js → chunk-ZAYGSUHF.js} +2 -2
- package/dist/browser/dev/excalidraw-assets-dev/{chunk-Z3PH3V2B.js → chunk-ZQR5ML6Y.js} +26 -26
- package/dist/browser/dev/excalidraw-assets-dev/chunk-ZQR5ML6Y.js.map +7 -0
- package/dist/browser/dev/excalidraw-assets-dev/{classDiagram-30eddba6-QSLMH4JW.js → classDiagram-30eddba6-CUYIJICN.js} +5 -5
- package/dist/browser/dev/excalidraw-assets-dev/{classDiagram-v2-f2df5561-DY4DYQ5P.js → classDiagram-v2-f2df5561-K6WW6K73.js} +8 -8
- package/dist/browser/dev/excalidraw-assets-dev/{dist-Z46EOVOL.js → dist-6QVAH5JA.js} +37 -15
- package/dist/browser/dev/excalidraw-assets-dev/dist-6QVAH5JA.js.map +7 -0
- package/dist/browser/dev/excalidraw-assets-dev/{en-TR4QLF5E.js → en-AZFA5HJJ.js} +4 -2
- package/dist/browser/dev/excalidraw-assets-dev/{erDiagram-47591fe2-SOOJRTCB.js → erDiagram-47591fe2-XGAD7EEP.js} +4 -4
- package/dist/browser/dev/excalidraw-assets-dev/{flowDiagram-5540d9b9-AHGL4KPK.js → flowDiagram-5540d9b9-B6EOVNNO.js} +9 -9
- package/dist/browser/dev/excalidraw-assets-dev/{flowDiagram-v2-3b53844e-56LDZZWY.js → flowDiagram-v2-3b53844e-NUG24FJH.js} +9 -9
- package/dist/browser/dev/excalidraw-assets-dev/{flowchart-elk-definition-5fe447d6-27LUKRI6.js → flowchart-elk-definition-5fe447d6-25Y7PCBL.js} +5 -5
- package/dist/browser/dev/excalidraw-assets-dev/{ganttDiagram-9a3bba1f-EHGYGNG6.js → ganttDiagram-9a3bba1f-GNL6ZDTC.js} +2 -2
- package/dist/browser/dev/excalidraw-assets-dev/{gitGraphDiagram-96e6b4ee-AJQNBDW5.js → gitGraphDiagram-96e6b4ee-HNW52NVO.js} +2 -2
- package/dist/browser/dev/excalidraw-assets-dev/{image-OIPMBJGR.js → image-5XCR4WHS.js} +2 -2
- package/dist/browser/dev/excalidraw-assets-dev/{image-OFRRV5MB.css → image-O66MQ7WQ.css} +1 -1
- package/dist/browser/dev/excalidraw-assets-dev/image-O66MQ7WQ.css.map +7 -0
- package/dist/browser/dev/excalidraw-assets-dev/{infoDiagram-bcd20f53-SWLLQVES.js → infoDiagram-bcd20f53-FWEUVFLT.js} +2 -2
- package/dist/browser/dev/excalidraw-assets-dev/{journeyDiagram-4fe6b3dc-7UAVCWOZ.js → journeyDiagram-4fe6b3dc-RZIUI7UG.js} +3 -3
- package/dist/browser/dev/excalidraw-assets-dev/{mindmap-definition-f354de21-SROW5KGM.js → mindmap-definition-f354de21-GBVN45GU.js} +3 -3
- package/dist/browser/dev/excalidraw-assets-dev/{pieDiagram-79897490-QKCI6NCB.js → pieDiagram-79897490-ECENNII6.js} +2 -2
- package/dist/browser/dev/excalidraw-assets-dev/{quadrantDiagram-62f64e94-LNYJZFC5.js → quadrantDiagram-62f64e94-ZMEOFVNL.js} +2 -2
- package/dist/browser/dev/excalidraw-assets-dev/{requirementDiagram-05bf5f74-ZZD7ZHFA.js → requirementDiagram-05bf5f74-FHZSFHCR.js} +4 -4
- package/dist/browser/dev/excalidraw-assets-dev/{sankeyDiagram-97764748-L75ZZ4UM.js → sankeyDiagram-97764748-VDKIKTA6.js} +2 -2
- package/dist/browser/dev/excalidraw-assets-dev/{sequenceDiagram-acc0e65c-6PCU7TDK.js → sequenceDiagram-acc0e65c-6JUSPVKX.js} +3 -3
- package/dist/browser/dev/excalidraw-assets-dev/{stateDiagram-0ff1cf1a-WM76WOPR.js → stateDiagram-0ff1cf1a-L3AKWENF.js} +5 -5
- package/dist/browser/dev/excalidraw-assets-dev/{stateDiagram-v2-9a9d610d-N4HZW3O2.js → stateDiagram-v2-9a9d610d-NU3GGMCH.js} +8 -8
- package/dist/browser/dev/excalidraw-assets-dev/{timeline-definition-fea2a41d-ZHGCAXGP.js → timeline-definition-fea2a41d-JGP7XCHW.js} +2 -2
- package/dist/browser/dev/excalidraw-assets-dev/{xychartDiagram-ab372869-2DLOVRAZ.js → xychartDiagram-ab372869-HLFHHF2I.js} +3 -3
- package/dist/browser/dev/index.css +199 -77
- package/dist/browser/dev/index.css.map +3 -3
- package/dist/browser/dev/index.js +12477 -8028
- package/dist/browser/dev/index.js.map +4 -4
- package/dist/browser/prod/excalidraw-assets/{blockDiagram-91b80b7a-ONPS22AM.js → blockDiagram-91b80b7a-FVCRVGN5.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{c4Diagram-b2a90758-XMIQY7ZT.js → c4Diagram-b2a90758-56CXO7GA.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{chunk-GCHQBOKV.js → chunk-635MQ3CK.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{chunk-5SYIAZGL.js → chunk-7DXALCB2.js} +5 -5
- package/dist/browser/prod/excalidraw-assets/{chunk-P5M3G2RP.js → chunk-AIKXYJX3.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{chunk-E2YLWFZX.js → chunk-CR7VMNWC.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{chunk-WEYK4A2L.js → chunk-FFF2CSVG.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{chunk-R3HAIP6R.js → chunk-G4WDCSPE.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{chunk-HFOXJM22.js → chunk-HKZSHFLX.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{chunk-XIMFFJTE.js → chunk-IKCDYWMW.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{chunk-AHLLBBVJ.js → chunk-L5DS24G6.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{chunk-CQJF3C6G.js → chunk-MUNOKHUD.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/chunk-ODWTVSS7.js +68 -0
- package/dist/browser/prod/excalidraw-assets/{chunk-NI6SYCUG.js → chunk-QOQYOOQ4.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{chunk-I2PZFXTK.js → chunk-ZTIWFPBM.js} +21 -21
- package/dist/browser/prod/excalidraw-assets/{classDiagram-30eddba6-IEJXXCVX.js → classDiagram-30eddba6-BCUTAUMD.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{classDiagram-v2-f2df5561-7LZDSWOS.js → classDiagram-v2-f2df5561-6SOXSGQ2.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/dist-567JAXHK.js +7 -0
- package/dist/browser/prod/excalidraw-assets/en-6E7MYLWO.js +1 -0
- package/dist/browser/prod/excalidraw-assets/{erDiagram-47591fe2-E5V666CF.js → erDiagram-47591fe2-RE6HB7RM.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{flowDiagram-5540d9b9-GMBRCYVF.js → flowDiagram-5540d9b9-ZNJZBERW.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{flowDiagram-v2-3b53844e-Z4HUWP6B.js → flowDiagram-v2-3b53844e-LY44JLQJ.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{flowchart-elk-definition-5fe447d6-5ZCYTX5N.js → flowchart-elk-definition-5fe447d6-TMTJ6Z7O.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{ganttDiagram-9a3bba1f-WM32OMT5.js → ganttDiagram-9a3bba1f-5O6EA6LX.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{gitGraphDiagram-96e6b4ee-CAKZ2U6E.js → gitGraphDiagram-96e6b4ee-UHYNM5DI.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/image-LQAMCFQI.js +1 -0
- package/dist/browser/prod/excalidraw-assets/{infoDiagram-bcd20f53-MUIKXGC4.js → infoDiagram-bcd20f53-BP77NQEH.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{journeyDiagram-4fe6b3dc-NYRV4HK2.js → journeyDiagram-4fe6b3dc-XMGKCMES.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{mindmap-definition-f354de21-MY55DRSM.js → mindmap-definition-f354de21-ZQRRBRWF.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{pieDiagram-79897490-47L6J6L2.js → pieDiagram-79897490-IGXEC2KX.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{quadrantDiagram-62f64e94-DF5C2GDT.js → quadrantDiagram-62f64e94-WTHHDYJL.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{requirementDiagram-05bf5f74-C4IMUBDN.js → requirementDiagram-05bf5f74-MV4OFRVW.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{sankeyDiagram-97764748-YHW7EUST.js → sankeyDiagram-97764748-ZGYUHEJT.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{sequenceDiagram-acc0e65c-H3XEHT32.js → sequenceDiagram-acc0e65c-IBSENK6W.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{stateDiagram-0ff1cf1a-Z5WB6Q3P.js → stateDiagram-0ff1cf1a-DB73XNZH.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{stateDiagram-v2-9a9d610d-T7OZETQC.js → stateDiagram-v2-9a9d610d-2OOBUPNR.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{timeline-definition-fea2a41d-VVC22BWF.js → timeline-definition-fea2a41d-P3NQQVDU.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/{xychartDiagram-ab372869-JAXODQF7.js → xychartDiagram-ab372869-HI3XLK3Y.js} +1 -1
- package/dist/browser/prod/index.css +1 -1
- package/dist/browser/prod/index.js +69 -51
- package/dist/{prod/en-XW4JO6VX.json → dev/en-EB2MBPAV.json} +24 -3
- package/dist/dev/index.css +199 -77
- package/dist/dev/index.css.map +3 -3
- package/dist/dev/index.js +15120 -11334
- package/dist/dev/index.js.map +4 -4
- package/dist/excalidraw/actions/actionAddToLibrary.d.ts +16 -7
- package/dist/excalidraw/actions/actionAddToLibrary.js +4 -3
- package/dist/excalidraw/actions/actionAlign.d.ts +22 -22
- package/dist/excalidraw/actions/actionAlign.js +7 -6
- package/dist/excalidraw/actions/actionBoundText.d.ts +18 -12
- package/dist/excalidraw/actions/actionBoundText.js +7 -4
- package/dist/excalidraw/actions/actionCanvas.d.ts +100 -64
- package/dist/excalidraw/actions/actionCanvas.js +17 -14
- package/dist/excalidraw/actions/actionClipboard.d.ts +52 -31
- package/dist/excalidraw/actions/actionClipboard.js +14 -13
- package/dist/excalidraw/actions/actionDeleteSelected.d.ts +22 -13
- package/dist/excalidraw/actions/actionDeleteSelected.js +6 -3
- package/dist/excalidraw/actions/actionDistribute.d.ts +10 -10
- package/dist/excalidraw/actions/actionDistribute.js +3 -2
- package/dist/excalidraw/actions/actionDuplicateSelection.d.ts +7 -8
- package/dist/excalidraw/actions/actionDuplicateSelection.js +4 -4
- package/dist/excalidraw/actions/actionElementLock.d.ts +17 -11
- package/dist/excalidraw/actions/actionElementLock.js +3 -2
- package/dist/excalidraw/actions/actionExport.d.ts +68 -41
- package/dist/excalidraw/actions/actionExport.js +15 -11
- package/dist/excalidraw/actions/actionFinalize.d.ts +17 -11
- package/dist/excalidraw/actions/actionFinalize.js +7 -3
- package/dist/excalidraw/actions/actionFlip.d.ts +10 -10
- package/dist/excalidraw/actions/actionFlip.js +9 -9
- package/dist/excalidraw/actions/actionFrame.d.ts +186 -21
- package/dist/excalidraw/actions/actionFrame.js +7 -6
- package/dist/excalidraw/actions/actionGroup.d.ts +24 -18
- package/dist/excalidraw/actions/actionGroup.js +7 -11
- package/dist/excalidraw/actions/actionHistory.d.ts +4 -3
- package/dist/excalidraw/actions/actionHistory.js +27 -31
- package/dist/excalidraw/actions/actionLinearEditor.d.ts +10 -5
- package/dist/excalidraw/actions/actionLinearEditor.js +21 -5
- package/dist/excalidraw/actions/actionLink.d.ts +9 -6
- package/dist/excalidraw/actions/actionLink.js +2 -1
- package/dist/excalidraw/actions/actionMenu.d.ts +20 -11
- package/dist/excalidraw/actions/actionMenu.js +4 -3
- package/dist/excalidraw/actions/actionNavigate.d.ts +12 -6
- package/dist/excalidraw/actions/actionNavigate.js +3 -2
- package/dist/excalidraw/actions/actionProperties.d.ts +86 -47
- package/dist/excalidraw/actions/actionProperties.js +19 -14
- package/dist/excalidraw/actions/actionSelectAll.d.ts +9 -6
- package/dist/excalidraw/actions/actionSelectAll.js +2 -1
- package/dist/excalidraw/actions/actionStyles.d.ts +15 -12
- package/dist/excalidraw/actions/actionStyles.js +4 -3
- package/dist/excalidraw/actions/actionTextAutoResize.d.ts +17 -0
- package/dist/excalidraw/actions/actionTextAutoResize.js +38 -0
- package/dist/excalidraw/actions/actionToggleGridMode.d.ts +9 -6
- package/dist/excalidraw/actions/actionToggleGridMode.js +2 -1
- package/dist/excalidraw/actions/actionToggleObjectsSnapMode.d.ts +8 -5
- package/dist/excalidraw/actions/actionToggleObjectsSnapMode.js +2 -1
- package/dist/excalidraw/actions/actionToggleStats.d.ts +9 -5
- package/dist/excalidraw/actions/actionToggleStats.js +6 -4
- package/dist/excalidraw/actions/actionToggleViewMode.d.ts +8 -5
- package/dist/excalidraw/actions/actionToggleViewMode.js +2 -1
- package/dist/excalidraw/actions/actionToggleZenMode.d.ts +8 -5
- package/dist/excalidraw/actions/actionToggleZenMode.js +2 -1
- package/dist/excalidraw/actions/actionZindex.d.ts +20 -16
- package/dist/excalidraw/actions/actionZindex.js +9 -4
- package/dist/excalidraw/actions/manager.d.ts +5 -5
- package/dist/excalidraw/actions/register.d.ts +1 -1
- package/dist/excalidraw/actions/shortcuts.d.ts +2 -2
- package/dist/excalidraw/actions/types.d.ts +8 -8
- package/dist/excalidraw/align.d.ts +1 -1
- package/dist/excalidraw/animated-trail.d.ts +2 -2
- package/dist/excalidraw/appState.d.ts +9 -6
- package/dist/excalidraw/appState.js +6 -3
- package/dist/excalidraw/change.d.ts +191 -0
- package/dist/excalidraw/change.js +901 -0
- package/dist/excalidraw/charts.d.ts +1 -1
- package/dist/excalidraw/clients.d.ts +2 -2
- package/dist/excalidraw/clients.js +1 -1
- package/dist/excalidraw/clipboard.d.ts +3 -3
- package/dist/excalidraw/colors.d.ts +1 -1
- package/dist/excalidraw/components/Actions.d.ts +3 -3
- package/dist/excalidraw/components/Actions.js +9 -6
- package/dist/excalidraw/components/App.d.ts +19 -20
- package/dist/excalidraw/components/App.js +323 -195
- package/dist/excalidraw/components/ButtonIconSelect.js +1 -1
- package/dist/excalidraw/components/CheckboxItem.js +1 -1
- package/dist/excalidraw/components/ColorPicker/ColorInput.d.ts +1 -1
- package/dist/excalidraw/components/ColorPicker/ColorInput.js +1 -1
- package/dist/excalidraw/components/ColorPicker/ColorPicker.d.ts +4 -4
- package/dist/excalidraw/components/ColorPicker/ColorPicker.js +1 -1
- package/dist/excalidraw/components/ColorPicker/Picker.d.ts +3 -3
- package/dist/excalidraw/components/ColorPicker/PickerColorList.d.ts +1 -1
- package/dist/excalidraw/components/ColorPicker/PickerHeading.d.ts +1 -1
- package/dist/excalidraw/components/ColorPicker/ShadeList.d.ts +1 -1
- package/dist/excalidraw/components/ColorPicker/TopPicks.d.ts +1 -1
- package/dist/excalidraw/components/ColorPicker/colorPickerUtils.d.ts +2 -2
- package/dist/excalidraw/components/ColorPicker/colorPickerUtils.js +1 -1
- package/dist/excalidraw/components/ColorPicker/keyboardNavHandlers.d.ts +2 -2
- package/dist/excalidraw/components/ColorPicker/keyboardNavHandlers.js +1 -1
- package/dist/excalidraw/components/CommandPalette/CommandPalette.d.ts +1 -1
- package/dist/excalidraw/components/CommandPalette/CommandPalette.js +5 -5
- package/dist/excalidraw/components/CommandPalette/defaultCommandPaletteItems.d.ts +1 -1
- package/dist/excalidraw/components/CommandPalette/types.d.ts +3 -3
- package/dist/excalidraw/components/ConfirmDialog.d.ts +1 -1
- package/dist/excalidraw/components/ContextMenu.d.ts +2 -2
- package/dist/excalidraw/components/ContextMenu.js +2 -2
- package/dist/excalidraw/components/DarkModeToggle.d.ts +1 -1
- package/dist/excalidraw/components/DefaultSidebar.d.ts +2 -2
- package/dist/excalidraw/components/Dialog.js +1 -1
- package/dist/excalidraw/components/DialogActionButton.d.ts +1 -1
- package/dist/excalidraw/components/EyeDropper.d.ts +2 -2
- package/dist/excalidraw/components/FollowMode/FollowMode.d.ts +1 -1
- package/dist/excalidraw/components/FollowMode/FollowMode.js +1 -1
- package/dist/excalidraw/components/HelpDialog.js +1 -1
- package/dist/excalidraw/components/HintViewer.d.ts +1 -1
- package/dist/excalidraw/components/IconPicker.js +2 -2
- package/dist/excalidraw/components/ImageExportDialog.d.ts +1 -1
- package/dist/excalidraw/components/InitializeApp.d.ts +2 -2
- package/dist/excalidraw/components/JSONExportDialog.d.ts +3 -3
- package/dist/excalidraw/components/LayerUI.d.ts +4 -4
- package/dist/excalidraw/components/LayerUI.js +10 -7
- package/dist/excalidraw/components/LibraryMenu.d.ts +2 -2
- package/dist/excalidraw/components/LibraryMenuBrowseButton.d.ts +1 -1
- package/dist/excalidraw/components/LibraryMenuControlButtons.d.ts +1 -1
- package/dist/excalidraw/components/LibraryMenuHeaderContent.d.ts +2 -2
- package/dist/excalidraw/components/LibraryMenuItems.d.ts +1 -1
- package/dist/excalidraw/components/LibraryMenuSection.d.ts +5 -4
- package/dist/excalidraw/components/LibraryUnit.d.ts +2 -2
- package/dist/excalidraw/components/LoadingMessage.d.ts +1 -1
- package/dist/excalidraw/components/MagicSettings.js +2 -2
- package/dist/excalidraw/components/MobileMenu.d.ts +3 -3
- package/dist/excalidraw/components/MobileMenu.js +2 -6
- package/dist/excalidraw/components/Modal.d.ts +1 -1
- package/dist/excalidraw/components/OverwriteConfirm/OverwriteConfirmState.d.ts +1 -1
- package/dist/excalidraw/components/PasteChartDialog.d.ts +1 -1
- package/dist/excalidraw/components/PasteChartDialog.js +1 -1
- package/dist/excalidraw/components/PublishLibrary.d.ts +1 -1
- package/dist/excalidraw/components/SVGLayer.d.ts +1 -1
- package/dist/excalidraw/components/Sidebar/Sidebar.d.ts +2 -2
- package/dist/excalidraw/components/Sidebar/Sidebar.js +1 -1
- package/dist/excalidraw/components/Sidebar/SidebarTab.d.ts +1 -1
- package/dist/excalidraw/components/Sidebar/SidebarTabTrigger.d.ts +1 -1
- package/dist/excalidraw/components/Sidebar/SidebarTrigger.d.ts +1 -1
- package/dist/excalidraw/components/Sidebar/common.d.ts +1 -1
- package/dist/excalidraw/components/Stack.d.ts +2 -2
- package/dist/excalidraw/components/Stats/Angle.d.ts +12 -0
- package/dist/excalidraw/components/Stats/Angle.js +52 -0
- package/dist/excalidraw/components/Stats/Collapsible.d.ts +9 -0
- package/dist/excalidraw/components/Stats/Collapsible.js +12 -0
- package/dist/excalidraw/components/Stats/Dimension.d.ts +12 -0
- package/dist/excalidraw/components/Stats/Dimension.js +67 -0
- package/dist/excalidraw/components/Stats/DragInput.d.ts +32 -0
- package/dist/excalidraw/components/Stats/DragInput.js +174 -0
- package/dist/excalidraw/components/Stats/FontSize.d.ts +12 -0
- package/dist/excalidraw/components/Stats/FontSize.js +50 -0
- package/dist/excalidraw/components/Stats/MultiAngle.d.ts +12 -0
- package/dist/excalidraw/components/Stats/MultiAngle.js +66 -0
- package/dist/excalidraw/components/Stats/MultiDimension.d.ts +15 -0
- package/dist/excalidraw/components/Stats/MultiDimension.js +197 -0
- package/dist/excalidraw/components/Stats/MultiFontSize.d.ts +13 -0
- package/dist/excalidraw/components/Stats/MultiFontSize.js +72 -0
- package/dist/excalidraw/components/Stats/MultiPosition.d.ts +15 -0
- package/dist/excalidraw/components/Stats/MultiPosition.js +100 -0
- package/dist/excalidraw/components/Stats/Position.d.ts +13 -0
- package/dist/excalidraw/components/Stats/Position.js +39 -0
- package/dist/excalidraw/components/Stats/index.d.ts +16 -0
- package/dist/excalidraw/components/Stats/index.js +78 -0
- package/dist/excalidraw/components/Stats/utils.d.ts +25 -0
- package/dist/excalidraw/components/Stats/utils.js +158 -0
- package/dist/excalidraw/components/TTDDialog/MermaidToExcalidraw.d.ts +1 -1
- package/dist/excalidraw/components/TTDDialog/TTDDialog.js +2 -2
- package/dist/excalidraw/components/TTDDialog/TTDDialogInput.d.ts +1 -1
- package/dist/excalidraw/components/TTDDialog/TTDDialogPanel.d.ts +1 -1
- package/dist/excalidraw/components/TTDDialog/TTDDialogPanels.d.ts +1 -1
- package/dist/excalidraw/components/TTDDialog/TTDDialogTabs.d.ts +1 -1
- package/dist/excalidraw/components/TTDDialog/TTDDialogTrigger.d.ts +1 -1
- package/dist/excalidraw/components/TTDDialog/common.d.ts +4 -4
- package/dist/excalidraw/components/TextField.d.ts +1 -1
- package/dist/excalidraw/components/Toast.d.ts +1 -1
- package/dist/excalidraw/components/ToolButton.d.ts +4 -2
- package/dist/excalidraw/components/ToolButton.js +1 -1
- package/dist/excalidraw/components/Trans.d.ts +1 -1
- package/dist/excalidraw/components/UserList.d.ts +1 -1
- package/dist/excalidraw/components/canvases/InteractiveCanvas.d.ts +5 -3
- package/dist/excalidraw/components/canvases/InteractiveCanvas.js +5 -2
- package/dist/excalidraw/components/canvases/StaticCanvas.d.ts +2 -2
- package/dist/excalidraw/components/canvases/StaticCanvas.js +2 -2
- package/dist/excalidraw/components/dropdownMenu/DropdownMenuItem.js +2 -2
- package/dist/excalidraw/components/footer/Footer.d.ts +2 -2
- package/dist/excalidraw/components/hyperlink/Hyperlink.d.ts +2 -2
- package/dist/excalidraw/components/hyperlink/helpers.d.ts +3 -3
- package/dist/excalidraw/components/icons.d.ts +6 -2
- package/dist/excalidraw/components/icons.js +22 -6
- package/dist/excalidraw/constants.d.ts +11 -2
- package/dist/excalidraw/constants.js +14 -1
- package/dist/excalidraw/context/ui-appState.d.ts +1 -1
- package/dist/excalidraw/cursor.d.ts +1 -1
- package/dist/excalidraw/data/EditorLocalStorage.d.ts +2 -2
- package/dist/excalidraw/data/blob.d.ts +5 -5
- package/dist/excalidraw/data/filesystem.d.ts +2 -1
- package/dist/excalidraw/data/index.d.ts +4 -4
- package/dist/excalidraw/data/json.d.ts +3 -3
- package/dist/excalidraw/data/library.d.ts +3 -3
- package/dist/excalidraw/data/magic.d.ts +3 -3
- package/dist/excalidraw/data/reconcile.d.ts +3 -3
- package/dist/excalidraw/data/reconcile.js +1 -1
- package/dist/excalidraw/data/resave.d.ts +2 -2
- package/dist/excalidraw/data/restore.d.ts +3 -3
- package/dist/excalidraw/data/restore.js +17 -2
- package/dist/excalidraw/data/transform.d.ts +3 -3
- package/dist/excalidraw/data/types.d.ts +3 -3
- package/dist/excalidraw/element/ElementCanvasButtons.d.ts +1 -1
- package/dist/excalidraw/element/binding.d.ts +48 -20
- package/dist/excalidraw/element/binding.js +354 -168
- package/dist/excalidraw/element/bounds.d.ts +3 -3
- package/dist/excalidraw/element/collision.d.ts +3 -3
- package/dist/excalidraw/element/collision.js +1 -1
- package/dist/excalidraw/element/containerCache.d.ts +1 -1
- package/dist/excalidraw/element/dragElements.d.ts +4 -4
- package/dist/excalidraw/element/dragElements.js +27 -3
- package/dist/excalidraw/element/embeddable.d.ts +10 -7
- package/dist/excalidraw/element/embeddable.js +2 -1
- package/dist/excalidraw/element/image.d.ts +2 -2
- package/dist/excalidraw/element/index.d.ts +2 -2
- package/dist/excalidraw/element/index.js +1 -1
- package/dist/excalidraw/element/linearElementEditor.d.ts +10 -7
- package/dist/excalidraw/element/linearElementEditor.js +9 -6
- package/dist/excalidraw/element/mutateElement.d.ts +3 -4
- package/dist/excalidraw/element/mutateElement.js +1 -1
- package/dist/excalidraw/element/newElement.d.ts +5 -8
- package/dist/excalidraw/element/newElement.js +16 -14
- package/dist/excalidraw/element/resizeElements.d.ts +12 -4
- package/dist/excalidraw/element/resizeElements.js +174 -98
- package/dist/excalidraw/element/resizeTest.d.ts +7 -7
- package/dist/excalidraw/element/resizeTest.js +53 -8
- package/dist/excalidraw/element/showSelectedShapeActions.d.ts +2 -2
- package/dist/excalidraw/element/sizeHelpers.d.ts +2 -2
- package/dist/excalidraw/element/sizeHelpers.js +3 -0
- package/dist/excalidraw/element/sortElements.d.ts +1 -1
- package/dist/excalidraw/element/textElement.d.ts +6 -5
- package/dist/excalidraw/element/textElement.js +16 -7
- package/dist/excalidraw/element/textWysiwyg.d.ts +12 -6
- package/dist/excalidraw/element/textWysiwyg.js +38 -17
- package/dist/excalidraw/element/transformHandles.d.ts +24 -6
- package/dist/excalidraw/element/transformHandles.js +22 -11
- package/dist/excalidraw/element/typeChecks.d.ts +5 -5
- package/dist/excalidraw/element/types.d.ts +16 -8
- package/dist/excalidraw/emitter.d.ts +1 -1
- package/dist/excalidraw/fractionalIndex.d.ts +1 -1
- package/dist/excalidraw/fractionalIndex.js +2 -4
- package/dist/excalidraw/frame.d.ts +3 -3
- package/dist/excalidraw/gatransforms.d.ts +1 -1
- package/dist/excalidraw/gesture.d.ts +1 -1
- package/dist/excalidraw/groups.d.ts +6 -4
- package/dist/excalidraw/groups.js +17 -0
- package/dist/excalidraw/history.d.ts +35 -47
- package/dist/excalidraw/history.js +100 -167
- package/dist/excalidraw/hooks/useEmitter.d.ts +2 -0
- package/dist/excalidraw/hooks/useEmitter.js +13 -0
- package/dist/excalidraw/hooks/useLibraryItemSvg.d.ts +1 -1
- package/dist/excalidraw/i18n.d.ts +1 -1
- package/dist/excalidraw/index.d.ts +3 -1
- package/dist/excalidraw/index.js +2 -0
- package/dist/excalidraw/jotai.d.ts +1 -1
- package/dist/excalidraw/laser-trails.d.ts +3 -2
- package/dist/excalidraw/locales/en.json +24 -3
- package/dist/excalidraw/math.d.ts +4 -2
- package/dist/excalidraw/math.js +6 -0
- package/dist/excalidraw/mermaid.d.ts +2 -0
- package/dist/excalidraw/mermaid.js +28 -0
- package/dist/excalidraw/points.d.ts +1 -1
- package/dist/excalidraw/queue.d.ts +1 -1
- package/dist/excalidraw/renderer/helpers.d.ts +2 -2
- package/dist/excalidraw/renderer/interactiveScene.d.ts +2 -2
- package/dist/excalidraw/renderer/interactiveScene.js +38 -11
- package/dist/excalidraw/renderer/renderElement.d.ts +4 -4
- package/dist/excalidraw/renderer/renderElement.js +5 -5
- package/dist/excalidraw/renderer/renderSnaps.d.ts +1 -1
- package/dist/excalidraw/renderer/staticScene.d.ts +1 -1
- package/dist/excalidraw/renderer/staticScene.js +1 -1
- package/dist/excalidraw/renderer/staticSvgScene.d.ts +4 -4
- package/dist/excalidraw/scene/Fonts.d.ts +2 -4
- package/dist/excalidraw/scene/Fonts.js +12 -15
- package/dist/excalidraw/scene/Renderer.d.ts +4 -4
- package/dist/excalidraw/scene/Renderer.js +2 -3
- package/dist/excalidraw/scene/Scene.d.ts +17 -8
- package/dist/excalidraw/scene/Scene.js +19 -10
- package/dist/excalidraw/scene/Shape.d.ts +1 -1
- package/dist/excalidraw/scene/ShapeCache.d.ts +4 -4
- package/dist/excalidraw/scene/comparisons.d.ts +2 -2
- package/dist/excalidraw/scene/export.d.ts +2 -2
- package/dist/excalidraw/scene/export.js +2 -2
- package/dist/excalidraw/scene/scroll.d.ts +2 -2
- package/dist/excalidraw/scene/scrollbars.d.ts +3 -3
- package/dist/excalidraw/scene/selection.d.ts +2 -2
- package/dist/excalidraw/scene/types.d.ts +7 -8
- package/dist/excalidraw/scene/zoom.d.ts +1 -1
- package/dist/excalidraw/shapes.d.ts +7 -0
- package/dist/excalidraw/shapes.js +40 -0
- package/dist/excalidraw/snapping.d.ts +4 -4
- package/dist/excalidraw/snapping.js +2 -1
- package/dist/excalidraw/store.d.ts +129 -0
- package/dist/excalidraw/store.js +296 -0
- package/dist/excalidraw/types.d.ts +38 -20
- package/dist/excalidraw/utils.d.ts +10 -4
- package/dist/excalidraw/utils.js +7 -0
- package/dist/excalidraw/zindex.d.ts +2 -2
- package/dist/{dev/en-XW4JO6VX.json → prod/en-EB2MBPAV.json} +24 -3
- package/dist/prod/index.css +1 -1
- package/dist/prod/index.js +39 -39
- package/dist/utils/bbox.d.ts +2 -2
- package/dist/utils/collision.d.ts +1 -1
- package/dist/utils/export.d.ts +2 -2
- package/dist/utils/geometry/geometry.d.ts +1 -1
- package/dist/utils/geometry/shape.d.ts +2 -1
- package/dist/utils/geometry/shape.js +19 -0
- package/dist/utils/withinBounds.d.ts +1 -1
- package/history.ts +163 -218
- package/package.json +2 -2
- package/dist/browser/dev/excalidraw-assets-dev/chunk-WQFMSDPT.js.map +0 -7
- package/dist/browser/dev/excalidraw-assets-dev/chunk-XOM7LNOU.js.map +0 -7
- package/dist/browser/dev/excalidraw-assets-dev/chunk-Z3PH3V2B.js.map +0 -7
- package/dist/browser/dev/excalidraw-assets-dev/dist-Z46EOVOL.js.map +0 -7
- package/dist/browser/dev/excalidraw-assets-dev/image-OFRRV5MB.css.map +0 -7
- package/dist/browser/prod/excalidraw-assets/chunk-U3COIHDW.js +0 -55
- package/dist/browser/prod/excalidraw-assets/dist-PIPZXALV.js +0 -6
- package/dist/browser/prod/excalidraw-assets/en-7GPZE2Y2.js +0 -1
- package/dist/browser/prod/excalidraw-assets/image-ZLNYKWVQ.js +0 -1
- package/dist/excalidraw/components/Stats.d.ts +0 -11
- package/dist/excalidraw/components/Stats.js +0 -13
- /package/dist/browser/dev/excalidraw-assets-dev/{blockDiagram-91b80b7a-ACFH36JV.js.map → blockDiagram-91b80b7a-H47FTXHA.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{c4Diagram-b2a90758-QZ27YR47.js.map → c4Diagram-b2a90758-NNJK6GKC.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{chunk-HO2HMSK7.js.map → chunk-4KQVEBHW.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{chunk-USGV265L.js.map → chunk-53YI56GV.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{chunk-EDFX3S7X.js.map → chunk-A2WCJI4I.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{chunk-IX4V72YG.js.map → chunk-EFLPX7NE.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{chunk-MXVETLVM.js.map → chunk-JYIQCNWV.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{chunk-YZIOORVX.js.map → chunk-LVIQQW6F.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{chunk-6U7GQNJT.js.map → chunk-PXLO3FOU.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{chunk-7DACDEY3.js.map → chunk-TO2AW5PW.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{chunk-NJ77ZFNJ.js.map → chunk-VURILHLY.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{chunk-2T2GU7NF.js.map → chunk-ZAYGSUHF.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{classDiagram-30eddba6-QSLMH4JW.js.map → classDiagram-30eddba6-CUYIJICN.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{classDiagram-v2-f2df5561-DY4DYQ5P.js.map → classDiagram-v2-f2df5561-K6WW6K73.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{en-TR4QLF5E.js.map → en-AZFA5HJJ.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{erDiagram-47591fe2-SOOJRTCB.js.map → erDiagram-47591fe2-XGAD7EEP.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{flowDiagram-5540d9b9-AHGL4KPK.js.map → flowDiagram-5540d9b9-B6EOVNNO.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{flowDiagram-v2-3b53844e-56LDZZWY.js.map → flowDiagram-v2-3b53844e-NUG24FJH.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{flowchart-elk-definition-5fe447d6-27LUKRI6.js.map → flowchart-elk-definition-5fe447d6-25Y7PCBL.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{ganttDiagram-9a3bba1f-EHGYGNG6.js.map → ganttDiagram-9a3bba1f-GNL6ZDTC.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{gitGraphDiagram-96e6b4ee-AJQNBDW5.js.map → gitGraphDiagram-96e6b4ee-HNW52NVO.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{image-OIPMBJGR.js.map → image-5XCR4WHS.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{infoDiagram-bcd20f53-SWLLQVES.js.map → infoDiagram-bcd20f53-FWEUVFLT.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{journeyDiagram-4fe6b3dc-7UAVCWOZ.js.map → journeyDiagram-4fe6b3dc-RZIUI7UG.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{mindmap-definition-f354de21-SROW5KGM.js.map → mindmap-definition-f354de21-GBVN45GU.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{pieDiagram-79897490-QKCI6NCB.js.map → pieDiagram-79897490-ECENNII6.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{quadrantDiagram-62f64e94-LNYJZFC5.js.map → quadrantDiagram-62f64e94-ZMEOFVNL.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{requirementDiagram-05bf5f74-ZZD7ZHFA.js.map → requirementDiagram-05bf5f74-FHZSFHCR.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{sankeyDiagram-97764748-L75ZZ4UM.js.map → sankeyDiagram-97764748-VDKIKTA6.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{sequenceDiagram-acc0e65c-6PCU7TDK.js.map → sequenceDiagram-acc0e65c-6JUSPVKX.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{stateDiagram-0ff1cf1a-WM76WOPR.js.map → stateDiagram-0ff1cf1a-L3AKWENF.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{stateDiagram-v2-9a9d610d-N4HZW3O2.js.map → stateDiagram-v2-9a9d610d-NU3GGMCH.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{timeline-definition-fea2a41d-ZHGCAXGP.js.map → timeline-definition-fea2a41d-JGP7XCHW.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{xychartDiagram-ab372869-2DLOVRAZ.js.map → xychartDiagram-ab372869-HLFHHF2I.js.map} +0 -0
|
@@ -0,0 +1,901 @@
|
|
|
1
|
+
import { ENV } from "./constants";
|
|
2
|
+
import { BoundElement, BindableElement, bindingProperties, updateBoundElements, } from "./element/binding";
|
|
3
|
+
import { LinearElementEditor } from "./element/linearElementEditor";
|
|
4
|
+
import { mutateElement, newElementWith } from "./element/mutateElement";
|
|
5
|
+
import { getBoundTextElementId, redrawTextBoundingBox, } from "./element/textElement";
|
|
6
|
+
import { hasBoundTextElement, isBindableElement, isBoundToContainer, isTextElement, } from "./element/typeChecks";
|
|
7
|
+
import { orderByFractionalIndex, syncMovedIndices } from "./fractionalIndex";
|
|
8
|
+
import { getNonDeletedGroupIds } from "./groups";
|
|
9
|
+
import { getObservedAppState } from "./store";
|
|
10
|
+
import { arrayToMap, arrayToObject, assertNever, isShallowEqual, toBrandedType, } from "./utils";
|
|
11
|
+
/**
|
|
12
|
+
* Represents the difference between two objects of the same type.
|
|
13
|
+
*
|
|
14
|
+
* Both `deleted` and `inserted` partials represent the same set of added, removed or updated properties, where:
|
|
15
|
+
* - `deleted` is a set of all the deleted values
|
|
16
|
+
* - `inserted` is a set of all the inserted (added, updated) values
|
|
17
|
+
*
|
|
18
|
+
* Keeping it as pure object (without transient state, side-effects, etc.), so we won't have to instantiate it on load.
|
|
19
|
+
*/
|
|
20
|
+
class Delta {
|
|
21
|
+
deleted;
|
|
22
|
+
inserted;
|
|
23
|
+
constructor(deleted, inserted) {
|
|
24
|
+
this.deleted = deleted;
|
|
25
|
+
this.inserted = inserted;
|
|
26
|
+
}
|
|
27
|
+
static create(deleted, inserted, modifier, modifierOptions) {
|
|
28
|
+
const modifiedDeleted = modifier && modifierOptions !== "inserted" ? modifier(deleted) : deleted;
|
|
29
|
+
const modifiedInserted = modifier && modifierOptions !== "deleted" ? modifier(inserted) : inserted;
|
|
30
|
+
return new Delta(modifiedDeleted, modifiedInserted);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Calculates the delta between two objects.
|
|
34
|
+
*
|
|
35
|
+
* @param prevObject - The previous state of the object.
|
|
36
|
+
* @param nextObject - The next state of the object.
|
|
37
|
+
*
|
|
38
|
+
* @returns new delta instance.
|
|
39
|
+
*/
|
|
40
|
+
static calculate(prevObject, nextObject, modifier, postProcess) {
|
|
41
|
+
if (prevObject === nextObject) {
|
|
42
|
+
return Delta.empty();
|
|
43
|
+
}
|
|
44
|
+
const deleted = {};
|
|
45
|
+
const inserted = {};
|
|
46
|
+
// O(n^3) here for elements, but it's not as bad as it looks:
|
|
47
|
+
// - we do this only on store recordings, not on every frame (not for ephemerals)
|
|
48
|
+
// - we do this only on previously detected changed elements
|
|
49
|
+
// - we do shallow compare only on the first level of properties (not going any deeper)
|
|
50
|
+
// - # of properties is reasonably small
|
|
51
|
+
for (const key of this.distinctKeysIterator("full", prevObject, nextObject)) {
|
|
52
|
+
deleted[key] = prevObject[key];
|
|
53
|
+
inserted[key] = nextObject[key];
|
|
54
|
+
}
|
|
55
|
+
const [processedDeleted, processedInserted] = postProcess
|
|
56
|
+
? postProcess(deleted, inserted)
|
|
57
|
+
: [deleted, inserted];
|
|
58
|
+
return Delta.create(processedDeleted, processedInserted, modifier);
|
|
59
|
+
}
|
|
60
|
+
static empty() {
|
|
61
|
+
return new Delta({}, {});
|
|
62
|
+
}
|
|
63
|
+
static isEmpty(delta) {
|
|
64
|
+
return (!Object.keys(delta.deleted).length && !Object.keys(delta.inserted).length);
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Merges deleted and inserted object partials.
|
|
68
|
+
*/
|
|
69
|
+
static mergeObjects(prev, added, removed) {
|
|
70
|
+
const cloned = { ...prev };
|
|
71
|
+
for (const key of Object.keys(removed)) {
|
|
72
|
+
delete cloned[key];
|
|
73
|
+
}
|
|
74
|
+
return { ...cloned, ...added };
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Merges deleted and inserted array partials.
|
|
78
|
+
*/
|
|
79
|
+
static mergeArrays(prev, added, removed, predicate) {
|
|
80
|
+
return Object.values(Delta.mergeObjects(arrayToObject(prev ?? [], predicate), arrayToObject(added ?? [], predicate), arrayToObject(removed ?? [], predicate)));
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Diff object partials as part of the `postProcess`.
|
|
84
|
+
*/
|
|
85
|
+
static diffObjects(deleted, inserted, property, setValue) {
|
|
86
|
+
if (!deleted[property] && !inserted[property]) {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
if (typeof deleted[property] === "object" ||
|
|
90
|
+
typeof inserted[property] === "object") {
|
|
91
|
+
const deletedObject = deleted[property] ?? {};
|
|
92
|
+
const insertedObject = inserted[property] ?? {};
|
|
93
|
+
const deletedDifferences = Delta.getLeftDifferences(deletedObject, insertedObject).reduce((acc, curr) => {
|
|
94
|
+
acc[curr] = setValue(deletedObject[curr]);
|
|
95
|
+
return acc;
|
|
96
|
+
}, {});
|
|
97
|
+
const insertedDifferences = Delta.getRightDifferences(deletedObject, insertedObject).reduce((acc, curr) => {
|
|
98
|
+
acc[curr] = setValue(insertedObject[curr]);
|
|
99
|
+
return acc;
|
|
100
|
+
}, {});
|
|
101
|
+
if (Object.keys(deletedDifferences).length ||
|
|
102
|
+
Object.keys(insertedDifferences).length) {
|
|
103
|
+
Reflect.set(deleted, property, deletedDifferences);
|
|
104
|
+
Reflect.set(inserted, property, insertedDifferences);
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
Reflect.deleteProperty(deleted, property);
|
|
108
|
+
Reflect.deleteProperty(inserted, property);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Diff array partials as part of the `postProcess`.
|
|
114
|
+
*/
|
|
115
|
+
static diffArrays(deleted, inserted, property, groupBy) {
|
|
116
|
+
if (!deleted[property] && !inserted[property]) {
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
if (Array.isArray(deleted[property]) || Array.isArray(inserted[property])) {
|
|
120
|
+
const deletedArray = (Array.isArray(deleted[property]) ? deleted[property] : []);
|
|
121
|
+
const insertedArray = (Array.isArray(inserted[property]) ? inserted[property] : []);
|
|
122
|
+
const deletedDifferences = arrayToObject(Delta.getLeftDifferences(arrayToObject(deletedArray, groupBy), arrayToObject(insertedArray, groupBy)));
|
|
123
|
+
const insertedDifferences = arrayToObject(Delta.getRightDifferences(arrayToObject(deletedArray, groupBy), arrayToObject(insertedArray, groupBy)));
|
|
124
|
+
if (Object.keys(deletedDifferences).length ||
|
|
125
|
+
Object.keys(insertedDifferences).length) {
|
|
126
|
+
const deletedValue = deletedArray.filter((x) => deletedDifferences[groupBy ? groupBy(x) : String(x)]);
|
|
127
|
+
const insertedValue = insertedArray.filter((x) => insertedDifferences[groupBy ? groupBy(x) : String(x)]);
|
|
128
|
+
Reflect.set(deleted, property, deletedValue);
|
|
129
|
+
Reflect.set(inserted, property, insertedValue);
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
Reflect.deleteProperty(deleted, property);
|
|
133
|
+
Reflect.deleteProperty(inserted, property);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Compares if object1 contains any different value compared to the object2.
|
|
139
|
+
*/
|
|
140
|
+
static isLeftDifferent(object1, object2, skipShallowCompare = false) {
|
|
141
|
+
const anyDistinctKey = this.distinctKeysIterator("left", object1, object2, skipShallowCompare).next().value;
|
|
142
|
+
return !!anyDistinctKey;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Compares if object2 contains any different value compared to the object1.
|
|
146
|
+
*/
|
|
147
|
+
static isRightDifferent(object1, object2, skipShallowCompare = false) {
|
|
148
|
+
const anyDistinctKey = this.distinctKeysIterator("right", object1, object2, skipShallowCompare).next().value;
|
|
149
|
+
return !!anyDistinctKey;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Returns all the object1 keys that have distinct values.
|
|
153
|
+
*/
|
|
154
|
+
static getLeftDifferences(object1, object2, skipShallowCompare = false) {
|
|
155
|
+
return Array.from(this.distinctKeysIterator("left", object1, object2, skipShallowCompare));
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Returns all the object2 keys that have distinct values.
|
|
159
|
+
*/
|
|
160
|
+
static getRightDifferences(object1, object2, skipShallowCompare = false) {
|
|
161
|
+
return Array.from(this.distinctKeysIterator("right", object1, object2, skipShallowCompare));
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Iterator comparing values of object properties based on the passed joining strategy.
|
|
165
|
+
*
|
|
166
|
+
* @yields keys of properties with different values
|
|
167
|
+
*
|
|
168
|
+
* WARN: it's based on shallow compare performed only on the first level and doesn't go deeper than that.
|
|
169
|
+
*/
|
|
170
|
+
static *distinctKeysIterator(join, object1, object2, skipShallowCompare = false) {
|
|
171
|
+
if (object1 === object2) {
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
let keys = [];
|
|
175
|
+
if (join === "left") {
|
|
176
|
+
keys = Object.keys(object1);
|
|
177
|
+
}
|
|
178
|
+
else if (join === "right") {
|
|
179
|
+
keys = Object.keys(object2);
|
|
180
|
+
}
|
|
181
|
+
else if (join === "full") {
|
|
182
|
+
keys = Array.from(new Set([...Object.keys(object1), ...Object.keys(object2)]));
|
|
183
|
+
}
|
|
184
|
+
else {
|
|
185
|
+
assertNever(join, `Unknown distinctKeysIterator's join param "${join}"`, true);
|
|
186
|
+
}
|
|
187
|
+
for (const key of keys) {
|
|
188
|
+
const object1Value = object1[key];
|
|
189
|
+
const object2Value = object2[key];
|
|
190
|
+
if (object1Value !== object2Value) {
|
|
191
|
+
if (!skipShallowCompare &&
|
|
192
|
+
typeof object1Value === "object" &&
|
|
193
|
+
typeof object2Value === "object" &&
|
|
194
|
+
object1Value !== null &&
|
|
195
|
+
object2Value !== null &&
|
|
196
|
+
isShallowEqual(object1Value, object2Value)) {
|
|
197
|
+
continue;
|
|
198
|
+
}
|
|
199
|
+
yield key;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
export class AppStateChange {
|
|
205
|
+
delta;
|
|
206
|
+
constructor(delta) {
|
|
207
|
+
this.delta = delta;
|
|
208
|
+
}
|
|
209
|
+
static calculate(prevAppState, nextAppState) {
|
|
210
|
+
const delta = Delta.calculate(prevAppState, nextAppState, undefined, AppStateChange.postProcess);
|
|
211
|
+
return new AppStateChange(delta);
|
|
212
|
+
}
|
|
213
|
+
static empty() {
|
|
214
|
+
return new AppStateChange(Delta.create({}, {}));
|
|
215
|
+
}
|
|
216
|
+
inverse() {
|
|
217
|
+
const inversedDelta = Delta.create(this.delta.inserted, this.delta.deleted);
|
|
218
|
+
return new AppStateChange(inversedDelta);
|
|
219
|
+
}
|
|
220
|
+
applyTo(appState, nextElements) {
|
|
221
|
+
try {
|
|
222
|
+
const { selectedElementIds: removedSelectedElementIds = {}, selectedGroupIds: removedSelectedGroupIds = {}, } = this.delta.deleted;
|
|
223
|
+
const { selectedElementIds: addedSelectedElementIds = {}, selectedGroupIds: addedSelectedGroupIds = {}, selectedLinearElementId, editingLinearElementId, ...directlyApplicablePartial } = this.delta.inserted;
|
|
224
|
+
const mergedSelectedElementIds = Delta.mergeObjects(appState.selectedElementIds, addedSelectedElementIds, removedSelectedElementIds);
|
|
225
|
+
const mergedSelectedGroupIds = Delta.mergeObjects(appState.selectedGroupIds, addedSelectedGroupIds, removedSelectedGroupIds);
|
|
226
|
+
const selectedLinearElement = selectedLinearElementId && nextElements.has(selectedLinearElementId)
|
|
227
|
+
? new LinearElementEditor(nextElements.get(selectedLinearElementId))
|
|
228
|
+
: null;
|
|
229
|
+
const editingLinearElement = editingLinearElementId && nextElements.has(editingLinearElementId)
|
|
230
|
+
? new LinearElementEditor(nextElements.get(editingLinearElementId))
|
|
231
|
+
: null;
|
|
232
|
+
const nextAppState = {
|
|
233
|
+
...appState,
|
|
234
|
+
...directlyApplicablePartial,
|
|
235
|
+
selectedElementIds: mergedSelectedElementIds,
|
|
236
|
+
selectedGroupIds: mergedSelectedGroupIds,
|
|
237
|
+
selectedLinearElement: typeof selectedLinearElementId !== "undefined"
|
|
238
|
+
? selectedLinearElement // element was either inserted or deleted
|
|
239
|
+
: appState.selectedLinearElement,
|
|
240
|
+
editingLinearElement: typeof editingLinearElementId !== "undefined"
|
|
241
|
+
? editingLinearElement // element was either inserted or deleted
|
|
242
|
+
: appState.editingLinearElement, // otherwise assign what we had before
|
|
243
|
+
};
|
|
244
|
+
const constainsVisibleChanges = this.filterInvisibleChanges(appState, nextAppState, nextElements);
|
|
245
|
+
return [nextAppState, constainsVisibleChanges];
|
|
246
|
+
}
|
|
247
|
+
catch (e) {
|
|
248
|
+
// shouldn't really happen, but just in case
|
|
249
|
+
console.error(`Couldn't apply appstate change`, e);
|
|
250
|
+
if (import.meta.env.DEV || import.meta.env.MODE === ENV.TEST) {
|
|
251
|
+
throw e;
|
|
252
|
+
}
|
|
253
|
+
return [appState, false];
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
isEmpty() {
|
|
257
|
+
return Delta.isEmpty(this.delta);
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* It is necessary to post process the partials in case of reference values,
|
|
261
|
+
* for which we need to calculate the real diff between `deleted` and `inserted`.
|
|
262
|
+
*/
|
|
263
|
+
static postProcess(deleted, inserted) {
|
|
264
|
+
try {
|
|
265
|
+
Delta.diffObjects(deleted, inserted, "selectedElementIds",
|
|
266
|
+
// ts language server has a bit trouble resolving this, so we are giving it a little push
|
|
267
|
+
(_) => true);
|
|
268
|
+
Delta.diffObjects(deleted, inserted, "selectedGroupIds", (prevValue) => (prevValue ?? false));
|
|
269
|
+
}
|
|
270
|
+
catch (e) {
|
|
271
|
+
// if postprocessing fails it does not make sense to bubble up, but let's make sure we know about it
|
|
272
|
+
console.error(`Couldn't postprocess appstate change deltas.`);
|
|
273
|
+
if (import.meta.env.DEV || import.meta.env.MODE === ENV.TEST) {
|
|
274
|
+
throw e;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
finally {
|
|
278
|
+
return [deleted, inserted];
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* Mutates `nextAppState` be filtering out state related to deleted elements.
|
|
283
|
+
*
|
|
284
|
+
* @returns `true` if a visible change is found, `false` otherwise.
|
|
285
|
+
*/
|
|
286
|
+
filterInvisibleChanges(prevAppState, nextAppState, nextElements) {
|
|
287
|
+
// TODO: #7348 we could still get an empty undo/redo, as we assume that previous appstate does not contain references to deleted elements
|
|
288
|
+
// which is not always true - i.e. now we do cleanup appstate during history, but we do not do it during remote updates
|
|
289
|
+
const prevObservedAppState = getObservedAppState(prevAppState);
|
|
290
|
+
const nextObservedAppState = getObservedAppState(nextAppState);
|
|
291
|
+
const containsStandaloneDifference = Delta.isRightDifferent(AppStateChange.stripElementsProps(prevObservedAppState), AppStateChange.stripElementsProps(nextObservedAppState));
|
|
292
|
+
const containsElementsDifference = Delta.isRightDifferent(AppStateChange.stripStandaloneProps(prevObservedAppState), AppStateChange.stripStandaloneProps(nextObservedAppState));
|
|
293
|
+
if (!containsStandaloneDifference && !containsElementsDifference) {
|
|
294
|
+
// no change in appstate was detected
|
|
295
|
+
return false;
|
|
296
|
+
}
|
|
297
|
+
const visibleDifferenceFlag = {
|
|
298
|
+
value: containsStandaloneDifference,
|
|
299
|
+
};
|
|
300
|
+
if (containsElementsDifference) {
|
|
301
|
+
// filter invisible changes on each iteration
|
|
302
|
+
const changedElementsProps = Delta.getRightDifferences(AppStateChange.stripStandaloneProps(prevObservedAppState), AppStateChange.stripStandaloneProps(nextObservedAppState));
|
|
303
|
+
let nonDeletedGroupIds = new Set();
|
|
304
|
+
if (changedElementsProps.includes("editingGroupId") ||
|
|
305
|
+
changedElementsProps.includes("selectedGroupIds")) {
|
|
306
|
+
// this one iterates through all the non deleted elements, so make sure it's not done twice
|
|
307
|
+
nonDeletedGroupIds = getNonDeletedGroupIds(nextElements);
|
|
308
|
+
}
|
|
309
|
+
// check whether delta properties are related to the existing non-deleted elements
|
|
310
|
+
for (const key of changedElementsProps) {
|
|
311
|
+
switch (key) {
|
|
312
|
+
case "selectedElementIds":
|
|
313
|
+
nextAppState[key] = AppStateChange.filterSelectedElements(nextAppState[key], nextElements, visibleDifferenceFlag);
|
|
314
|
+
break;
|
|
315
|
+
case "selectedGroupIds":
|
|
316
|
+
nextAppState[key] = AppStateChange.filterSelectedGroups(nextAppState[key], nonDeletedGroupIds, visibleDifferenceFlag);
|
|
317
|
+
break;
|
|
318
|
+
case "editingGroupId":
|
|
319
|
+
const editingGroupId = nextAppState[key];
|
|
320
|
+
if (!editingGroupId) {
|
|
321
|
+
// previously there was an editingGroup (assuming visible), now there is none
|
|
322
|
+
visibleDifferenceFlag.value = true;
|
|
323
|
+
}
|
|
324
|
+
else if (nonDeletedGroupIds.has(editingGroupId)) {
|
|
325
|
+
// previously there wasn't an editingGroup, now there is one which is visible
|
|
326
|
+
visibleDifferenceFlag.value = true;
|
|
327
|
+
}
|
|
328
|
+
else {
|
|
329
|
+
// there was assigned an editingGroup now, but it's related to deleted element
|
|
330
|
+
nextAppState[key] = null;
|
|
331
|
+
}
|
|
332
|
+
break;
|
|
333
|
+
case "selectedLinearElementId":
|
|
334
|
+
case "editingLinearElementId":
|
|
335
|
+
const appStateKey = AppStateChange.convertToAppStateKey(key);
|
|
336
|
+
const linearElement = nextAppState[appStateKey];
|
|
337
|
+
if (!linearElement) {
|
|
338
|
+
// previously there was a linear element (assuming visible), now there is none
|
|
339
|
+
visibleDifferenceFlag.value = true;
|
|
340
|
+
}
|
|
341
|
+
else {
|
|
342
|
+
const element = nextElements.get(linearElement.elementId);
|
|
343
|
+
if (element && !element.isDeleted) {
|
|
344
|
+
// previously there wasn't a linear element, now there is one which is visible
|
|
345
|
+
visibleDifferenceFlag.value = true;
|
|
346
|
+
}
|
|
347
|
+
else {
|
|
348
|
+
// there was assigned a linear element now, but it's deleted
|
|
349
|
+
nextAppState[appStateKey] = null;
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
break;
|
|
353
|
+
default: {
|
|
354
|
+
assertNever(key, `Unknown ObservedElementsAppState's key "${key}"`, true);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
return visibleDifferenceFlag.value;
|
|
360
|
+
}
|
|
361
|
+
static convertToAppStateKey(key) {
|
|
362
|
+
switch (key) {
|
|
363
|
+
case "selectedLinearElementId":
|
|
364
|
+
return "selectedLinearElement";
|
|
365
|
+
case "editingLinearElementId":
|
|
366
|
+
return "editingLinearElement";
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
static filterSelectedElements(selectedElementIds, elements, visibleDifferenceFlag) {
|
|
370
|
+
const ids = Object.keys(selectedElementIds);
|
|
371
|
+
if (!ids.length) {
|
|
372
|
+
// previously there were ids (assuming related to visible elements), now there are none
|
|
373
|
+
visibleDifferenceFlag.value = true;
|
|
374
|
+
return selectedElementIds;
|
|
375
|
+
}
|
|
376
|
+
const nextSelectedElementIds = { ...selectedElementIds };
|
|
377
|
+
for (const id of ids) {
|
|
378
|
+
const element = elements.get(id);
|
|
379
|
+
if (element && !element.isDeleted) {
|
|
380
|
+
// there is a selected element id related to a visible element
|
|
381
|
+
visibleDifferenceFlag.value = true;
|
|
382
|
+
}
|
|
383
|
+
else {
|
|
384
|
+
delete nextSelectedElementIds[id];
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
return nextSelectedElementIds;
|
|
388
|
+
}
|
|
389
|
+
static filterSelectedGroups(selectedGroupIds, nonDeletedGroupIds, visibleDifferenceFlag) {
|
|
390
|
+
const ids = Object.keys(selectedGroupIds);
|
|
391
|
+
if (!ids.length) {
|
|
392
|
+
// previously there were ids (assuming related to visible groups), now there are none
|
|
393
|
+
visibleDifferenceFlag.value = true;
|
|
394
|
+
return selectedGroupIds;
|
|
395
|
+
}
|
|
396
|
+
const nextSelectedGroupIds = { ...selectedGroupIds };
|
|
397
|
+
for (const id of Object.keys(nextSelectedGroupIds)) {
|
|
398
|
+
if (nonDeletedGroupIds.has(id)) {
|
|
399
|
+
// there is a selected group id related to a visible group
|
|
400
|
+
visibleDifferenceFlag.value = true;
|
|
401
|
+
}
|
|
402
|
+
else {
|
|
403
|
+
delete nextSelectedGroupIds[id];
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
return nextSelectedGroupIds;
|
|
407
|
+
}
|
|
408
|
+
static stripElementsProps(delta) {
|
|
409
|
+
// WARN: Do not remove the type-casts as they here to ensure proper type checks
|
|
410
|
+
const { editingGroupId, selectedGroupIds, selectedElementIds, editingLinearElementId, selectedLinearElementId, ...standaloneProps } = delta;
|
|
411
|
+
return standaloneProps;
|
|
412
|
+
}
|
|
413
|
+
static stripStandaloneProps(delta) {
|
|
414
|
+
// WARN: Do not remove the type-casts as they here to ensure proper type checks
|
|
415
|
+
const { name, viewBackgroundColor, ...elementsProps } = delta;
|
|
416
|
+
return elementsProps;
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
/**
|
|
420
|
+
* Elements change is a low level primitive to capture a change between two sets of elements.
|
|
421
|
+
* It does so by encapsulating forward and backward `Delta`s, allowing to time-travel in both directions.
|
|
422
|
+
*/
|
|
423
|
+
export class ElementsChange {
|
|
424
|
+
added;
|
|
425
|
+
removed;
|
|
426
|
+
updated;
|
|
427
|
+
constructor(added, removed, updated) {
|
|
428
|
+
this.added = added;
|
|
429
|
+
this.removed = removed;
|
|
430
|
+
this.updated = updated;
|
|
431
|
+
}
|
|
432
|
+
static create(added, removed, updated, options = { shouldRedistribute: false }) {
|
|
433
|
+
let change;
|
|
434
|
+
if (options.shouldRedistribute) {
|
|
435
|
+
const nextAdded = new Map();
|
|
436
|
+
const nextRemoved = new Map();
|
|
437
|
+
const nextUpdated = new Map();
|
|
438
|
+
const deltas = [...added, ...removed, ...updated];
|
|
439
|
+
for (const [id, delta] of deltas) {
|
|
440
|
+
if (this.satisfiesAddition(delta)) {
|
|
441
|
+
nextAdded.set(id, delta);
|
|
442
|
+
}
|
|
443
|
+
else if (this.satisfiesRemoval(delta)) {
|
|
444
|
+
nextRemoved.set(id, delta);
|
|
445
|
+
}
|
|
446
|
+
else {
|
|
447
|
+
nextUpdated.set(id, delta);
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
change = new ElementsChange(nextAdded, nextRemoved, nextUpdated);
|
|
451
|
+
}
|
|
452
|
+
else {
|
|
453
|
+
change = new ElementsChange(added, removed, updated);
|
|
454
|
+
}
|
|
455
|
+
if (import.meta.env.DEV || import.meta.env.MODE === ENV.TEST) {
|
|
456
|
+
ElementsChange.validate(change, "added", this.satisfiesAddition);
|
|
457
|
+
ElementsChange.validate(change, "removed", this.satisfiesRemoval);
|
|
458
|
+
ElementsChange.validate(change, "updated", this.satisfiesUpdate);
|
|
459
|
+
}
|
|
460
|
+
return change;
|
|
461
|
+
}
|
|
462
|
+
static satisfiesAddition = ({ deleted, inserted, }) =>
|
|
463
|
+
// dissallowing added as "deleted", which could cause issues when resolving conflicts
|
|
464
|
+
deleted.isDeleted === true && !inserted.isDeleted;
|
|
465
|
+
static satisfiesRemoval = ({ deleted, inserted, }) => !deleted.isDeleted && inserted.isDeleted === true;
|
|
466
|
+
static satisfiesUpdate = ({ deleted, inserted, }) => !!deleted.isDeleted === !!inserted.isDeleted;
|
|
467
|
+
static validate(change, type, satifies) {
|
|
468
|
+
for (const [id, delta] of change[type].entries()) {
|
|
469
|
+
if (!satifies(delta)) {
|
|
470
|
+
console.error(`Broken invariant for "${type}" delta, element "${id}", delta:`, delta);
|
|
471
|
+
throw new Error(`ElementsChange invariant broken for element "${id}".`);
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
/**
|
|
476
|
+
* Calculates the `Delta`s between the previous and next set of elements.
|
|
477
|
+
*
|
|
478
|
+
* @param prevElements - Map representing the previous state of elements.
|
|
479
|
+
* @param nextElements - Map representing the next state of elements.
|
|
480
|
+
*
|
|
481
|
+
* @returns `ElementsChange` instance representing the `Delta` changes between the two sets of elements.
|
|
482
|
+
*/
|
|
483
|
+
static calculate(prevElements, nextElements) {
|
|
484
|
+
if (prevElements === nextElements) {
|
|
485
|
+
return ElementsChange.empty();
|
|
486
|
+
}
|
|
487
|
+
const added = new Map();
|
|
488
|
+
const removed = new Map();
|
|
489
|
+
const updated = new Map();
|
|
490
|
+
// this might be needed only in same edge cases, like during collab, when `isDeleted` elements get removed or when we (un)intentionally remove the elements
|
|
491
|
+
for (const prevElement of prevElements.values()) {
|
|
492
|
+
const nextElement = nextElements.get(prevElement.id);
|
|
493
|
+
if (!nextElement) {
|
|
494
|
+
const deleted = { ...prevElement, isDeleted: false };
|
|
495
|
+
const inserted = { isDeleted: true };
|
|
496
|
+
const delta = Delta.create(deleted, inserted, ElementsChange.stripIrrelevantProps);
|
|
497
|
+
removed.set(prevElement.id, delta);
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
for (const nextElement of nextElements.values()) {
|
|
501
|
+
const prevElement = prevElements.get(nextElement.id);
|
|
502
|
+
if (!prevElement) {
|
|
503
|
+
const deleted = { isDeleted: true };
|
|
504
|
+
const inserted = {
|
|
505
|
+
...nextElement,
|
|
506
|
+
isDeleted: false,
|
|
507
|
+
};
|
|
508
|
+
const delta = Delta.create(deleted, inserted, ElementsChange.stripIrrelevantProps);
|
|
509
|
+
added.set(nextElement.id, delta);
|
|
510
|
+
continue;
|
|
511
|
+
}
|
|
512
|
+
if (prevElement.versionNonce !== nextElement.versionNonce) {
|
|
513
|
+
const delta = Delta.calculate(prevElement, nextElement, ElementsChange.stripIrrelevantProps, ElementsChange.postProcess);
|
|
514
|
+
if (
|
|
515
|
+
// making sure we don't get here some non-boolean values (i.e. undefined, null, etc.)
|
|
516
|
+
typeof prevElement.isDeleted === "boolean" &&
|
|
517
|
+
typeof nextElement.isDeleted === "boolean" &&
|
|
518
|
+
prevElement.isDeleted !== nextElement.isDeleted) {
|
|
519
|
+
// notice that other props could have been updated as well
|
|
520
|
+
if (prevElement.isDeleted && !nextElement.isDeleted) {
|
|
521
|
+
added.set(nextElement.id, delta);
|
|
522
|
+
}
|
|
523
|
+
else {
|
|
524
|
+
removed.set(nextElement.id, delta);
|
|
525
|
+
}
|
|
526
|
+
continue;
|
|
527
|
+
}
|
|
528
|
+
// making sure there are at least some changes
|
|
529
|
+
if (!Delta.isEmpty(delta)) {
|
|
530
|
+
updated.set(nextElement.id, delta);
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
return ElementsChange.create(added, removed, updated);
|
|
535
|
+
}
|
|
536
|
+
static empty() {
|
|
537
|
+
return ElementsChange.create(new Map(), new Map(), new Map());
|
|
538
|
+
}
|
|
539
|
+
inverse() {
|
|
540
|
+
const inverseInternal = (deltas) => {
|
|
541
|
+
const inversedDeltas = new Map();
|
|
542
|
+
for (const [id, delta] of deltas.entries()) {
|
|
543
|
+
inversedDeltas.set(id, Delta.create(delta.inserted, delta.deleted));
|
|
544
|
+
}
|
|
545
|
+
return inversedDeltas;
|
|
546
|
+
};
|
|
547
|
+
const added = inverseInternal(this.added);
|
|
548
|
+
const removed = inverseInternal(this.removed);
|
|
549
|
+
const updated = inverseInternal(this.updated);
|
|
550
|
+
// notice we inverse removed with added not to break the invariants
|
|
551
|
+
return ElementsChange.create(removed, added, updated);
|
|
552
|
+
}
|
|
553
|
+
isEmpty() {
|
|
554
|
+
return (this.added.size === 0 &&
|
|
555
|
+
this.removed.size === 0 &&
|
|
556
|
+
this.updated.size === 0);
|
|
557
|
+
}
|
|
558
|
+
/**
|
|
559
|
+
* Update delta/s based on the existing elements.
|
|
560
|
+
*
|
|
561
|
+
* @param elements current elements
|
|
562
|
+
* @param modifierOptions defines which of the delta (`deleted` or `inserted`) will be updated
|
|
563
|
+
* @returns new instance with modified delta/s
|
|
564
|
+
*/
|
|
565
|
+
applyLatestChanges(elements) {
|
|
566
|
+
const modifier = (element) => (partial) => {
|
|
567
|
+
const latestPartial = {};
|
|
568
|
+
for (const key of Object.keys(partial)) {
|
|
569
|
+
// do not update following props:
|
|
570
|
+
// - `boundElements`, as it is a reference value which is postprocessed to contain only deleted/inserted keys
|
|
571
|
+
switch (key) {
|
|
572
|
+
case "boundElements":
|
|
573
|
+
latestPartial[key] = partial[key];
|
|
574
|
+
break;
|
|
575
|
+
default:
|
|
576
|
+
latestPartial[key] = element[key];
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
return latestPartial;
|
|
580
|
+
};
|
|
581
|
+
const applyLatestChangesInternal = (deltas) => {
|
|
582
|
+
const modifiedDeltas = new Map();
|
|
583
|
+
for (const [id, delta] of deltas.entries()) {
|
|
584
|
+
const existingElement = elements.get(id);
|
|
585
|
+
if (existingElement) {
|
|
586
|
+
const modifiedDelta = Delta.create(delta.deleted, delta.inserted, modifier(existingElement), "inserted");
|
|
587
|
+
modifiedDeltas.set(id, modifiedDelta);
|
|
588
|
+
}
|
|
589
|
+
else {
|
|
590
|
+
modifiedDeltas.set(id, delta);
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
return modifiedDeltas;
|
|
594
|
+
};
|
|
595
|
+
const added = applyLatestChangesInternal(this.added);
|
|
596
|
+
const removed = applyLatestChangesInternal(this.removed);
|
|
597
|
+
const updated = applyLatestChangesInternal(this.updated);
|
|
598
|
+
return ElementsChange.create(added, removed, updated, {
|
|
599
|
+
shouldRedistribute: true, // redistribute the deltas as `isDeleted` could have been updated
|
|
600
|
+
});
|
|
601
|
+
}
|
|
602
|
+
applyTo(elements, snapshot) {
|
|
603
|
+
let nextElements = toBrandedType(new Map(elements));
|
|
604
|
+
let changedElements;
|
|
605
|
+
const flags = {
|
|
606
|
+
containsVisibleDifference: false,
|
|
607
|
+
containsZindexDifference: false,
|
|
608
|
+
};
|
|
609
|
+
// mimic a transaction by applying deltas into `nextElements` (always new instance, no mutation)
|
|
610
|
+
try {
|
|
611
|
+
const applyDeltas = ElementsChange.createApplier(nextElements, snapshot, flags);
|
|
612
|
+
const addedElements = applyDeltas(this.added);
|
|
613
|
+
const removedElements = applyDeltas(this.removed);
|
|
614
|
+
const updatedElements = applyDeltas(this.updated);
|
|
615
|
+
const affectedElements = this.resolveConflicts(elements, nextElements);
|
|
616
|
+
// TODO: #7348 validate elements semantically and syntactically the changed elements, in case they would result data integrity issues
|
|
617
|
+
changedElements = new Map([
|
|
618
|
+
...addedElements,
|
|
619
|
+
...removedElements,
|
|
620
|
+
...updatedElements,
|
|
621
|
+
...affectedElements,
|
|
622
|
+
]);
|
|
623
|
+
}
|
|
624
|
+
catch (e) {
|
|
625
|
+
console.error(`Couldn't apply elements change`, e);
|
|
626
|
+
if (import.meta.env.DEV || import.meta.env.MODE === ENV.TEST) {
|
|
627
|
+
throw e;
|
|
628
|
+
}
|
|
629
|
+
// should not really happen, but just in case we cannot apply deltas, let's return the previous elements with visible change set to `true`
|
|
630
|
+
// even though there is obviously no visible change, returning `false` could be dangerous, as i.e.:
|
|
631
|
+
// in the worst case, it could lead into iterating through the whole stack with no possibility to redo
|
|
632
|
+
// instead, the worst case when returning `true` is an empty undo / redo
|
|
633
|
+
return [elements, true];
|
|
634
|
+
}
|
|
635
|
+
try {
|
|
636
|
+
// TODO: #7348 refactor away mutations below, so that we couldn't end up in an incosistent state
|
|
637
|
+
ElementsChange.redrawTextBoundingBoxes(nextElements, changedElements);
|
|
638
|
+
ElementsChange.redrawBoundArrows(nextElements, changedElements);
|
|
639
|
+
// the following reorder performs also mutations, but only on new instances of changed elements
|
|
640
|
+
// (unless something goes really bad and it fallbacks to fixing all invalid indices)
|
|
641
|
+
nextElements = ElementsChange.reorderElements(nextElements, changedElements, flags);
|
|
642
|
+
}
|
|
643
|
+
catch (e) {
|
|
644
|
+
console.error(`Couldn't mutate elements after applying elements change`, e);
|
|
645
|
+
if (import.meta.env.DEV || import.meta.env.MODE === ENV.TEST) {
|
|
646
|
+
throw e;
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
finally {
|
|
650
|
+
return [nextElements, flags.containsVisibleDifference];
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
static createApplier = (nextElements, snapshot, flags) => {
|
|
654
|
+
const getElement = ElementsChange.createGetter(nextElements, snapshot, flags);
|
|
655
|
+
return (deltas) => Array.from(deltas.entries()).reduce((acc, [id, delta]) => {
|
|
656
|
+
const element = getElement(id, delta.inserted);
|
|
657
|
+
if (element) {
|
|
658
|
+
const newElement = ElementsChange.applyDelta(element, delta, flags);
|
|
659
|
+
nextElements.set(newElement.id, newElement);
|
|
660
|
+
acc.set(newElement.id, newElement);
|
|
661
|
+
}
|
|
662
|
+
return acc;
|
|
663
|
+
}, new Map());
|
|
664
|
+
};
|
|
665
|
+
static createGetter = (elements, snapshot, flags) => (id, partial) => {
|
|
666
|
+
let element = elements.get(id);
|
|
667
|
+
if (!element) {
|
|
668
|
+
// always fallback to the local snapshot, in cases when we cannot find the element in the elements array
|
|
669
|
+
element = snapshot.get(id);
|
|
670
|
+
if (element) {
|
|
671
|
+
// as the element was brought from the snapshot, it automatically results in a possible zindex difference
|
|
672
|
+
flags.containsZindexDifference = true;
|
|
673
|
+
// as the element was force deleted, we need to check if adding it back results in a visible change
|
|
674
|
+
if (partial.isDeleted === false ||
|
|
675
|
+
(partial.isDeleted !== true && element.isDeleted === false)) {
|
|
676
|
+
flags.containsVisibleDifference = true;
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
return element;
|
|
681
|
+
};
|
|
682
|
+
static applyDelta(element, delta, flags = {
|
|
683
|
+
// by default we don't care about about the flags
|
|
684
|
+
containsVisibleDifference: true,
|
|
685
|
+
containsZindexDifference: true,
|
|
686
|
+
}) {
|
|
687
|
+
const { boundElements, ...directlyApplicablePartial } = delta.inserted;
|
|
688
|
+
if (delta.deleted.boundElements?.length ||
|
|
689
|
+
delta.inserted.boundElements?.length) {
|
|
690
|
+
const mergedBoundElements = Delta.mergeArrays(element.boundElements, delta.inserted.boundElements, delta.deleted.boundElements, (x) => x.id);
|
|
691
|
+
Object.assign(directlyApplicablePartial, {
|
|
692
|
+
boundElements: mergedBoundElements,
|
|
693
|
+
});
|
|
694
|
+
}
|
|
695
|
+
if (!flags.containsVisibleDifference) {
|
|
696
|
+
// strip away fractional as even if it would be different, it doesn't have to result in visible change
|
|
697
|
+
const { index, ...rest } = directlyApplicablePartial;
|
|
698
|
+
const containsVisibleDifference = ElementsChange.checkForVisibleDifference(element, rest);
|
|
699
|
+
flags.containsVisibleDifference = containsVisibleDifference;
|
|
700
|
+
}
|
|
701
|
+
if (!flags.containsZindexDifference) {
|
|
702
|
+
flags.containsZindexDifference =
|
|
703
|
+
delta.deleted.index !== delta.inserted.index;
|
|
704
|
+
}
|
|
705
|
+
return newElementWith(element, directlyApplicablePartial);
|
|
706
|
+
}
|
|
707
|
+
/**
|
|
708
|
+
* Check for visible changes regardless of whether they were removed, added or updated.
|
|
709
|
+
*/
|
|
710
|
+
static checkForVisibleDifference(element, partial) {
|
|
711
|
+
if (element.isDeleted && partial.isDeleted !== false) {
|
|
712
|
+
// when it's deleted and partial is not false, it cannot end up with a visible change
|
|
713
|
+
return false;
|
|
714
|
+
}
|
|
715
|
+
if (element.isDeleted && partial.isDeleted === false) {
|
|
716
|
+
// when we add an element, it results in a visible change
|
|
717
|
+
return true;
|
|
718
|
+
}
|
|
719
|
+
if (element.isDeleted === false && partial.isDeleted) {
|
|
720
|
+
// when we remove an element, it results in a visible change
|
|
721
|
+
return true;
|
|
722
|
+
}
|
|
723
|
+
// check for any difference on a visible element
|
|
724
|
+
return Delta.isRightDifferent(element, partial);
|
|
725
|
+
}
|
|
726
|
+
/**
|
|
727
|
+
* Resolves conflicts for all previously added, removed and updated elements.
|
|
728
|
+
* Updates the previous deltas with all the changes after conflict resolution.
|
|
729
|
+
*
|
|
730
|
+
* @returns all elements affected by the conflict resolution
|
|
731
|
+
*/
|
|
732
|
+
resolveConflicts(prevElements, nextElements) {
|
|
733
|
+
const nextAffectedElements = new Map();
|
|
734
|
+
const updater = (element, updates) => {
|
|
735
|
+
const nextElement = nextElements.get(element.id); // only ever modify next element!
|
|
736
|
+
if (!nextElement) {
|
|
737
|
+
return;
|
|
738
|
+
}
|
|
739
|
+
let affectedElement;
|
|
740
|
+
if (prevElements.get(element.id) === nextElement) {
|
|
741
|
+
// create the new element instance in case we didn't modify the element yet
|
|
742
|
+
// so that we won't end up in an incosistent state in case we would fail in the middle of mutations
|
|
743
|
+
affectedElement = newElementWith(nextElement, updates);
|
|
744
|
+
}
|
|
745
|
+
else {
|
|
746
|
+
affectedElement = mutateElement(nextElement, updates);
|
|
747
|
+
}
|
|
748
|
+
nextAffectedElements.set(affectedElement.id, affectedElement);
|
|
749
|
+
nextElements.set(affectedElement.id, affectedElement);
|
|
750
|
+
};
|
|
751
|
+
// removed delta is affecting the bindings always, as all the affected elements of the removed elements need to be unbound
|
|
752
|
+
for (const [id] of this.removed) {
|
|
753
|
+
ElementsChange.unbindAffected(prevElements, nextElements, id, updater);
|
|
754
|
+
}
|
|
755
|
+
// added delta is affecting the bindings always, all the affected elements of the added elements need to be rebound
|
|
756
|
+
for (const [id] of this.added) {
|
|
757
|
+
ElementsChange.rebindAffected(prevElements, nextElements, id, updater);
|
|
758
|
+
}
|
|
759
|
+
// updated delta is affecting the binding only in case it contains changed binding or bindable property
|
|
760
|
+
for (const [id] of Array.from(this.updated).filter(([_, delta]) => Object.keys({ ...delta.deleted, ...delta.inserted }).find((prop) => bindingProperties.has(prop)))) {
|
|
761
|
+
const updatedElement = nextElements.get(id);
|
|
762
|
+
if (!updatedElement || updatedElement.isDeleted) {
|
|
763
|
+
// skip fixing bindings for updates on deleted elements
|
|
764
|
+
continue;
|
|
765
|
+
}
|
|
766
|
+
ElementsChange.rebindAffected(prevElements, nextElements, id, updater);
|
|
767
|
+
}
|
|
768
|
+
// filter only previous elements, which were now affected
|
|
769
|
+
const prevAffectedElements = new Map(Array.from(prevElements).filter(([id]) => nextAffectedElements.has(id)));
|
|
770
|
+
// calculate complete deltas for affected elements, and assign them back to all the deltas
|
|
771
|
+
// technically we could do better here if perf. would become an issue
|
|
772
|
+
const { added, removed, updated } = ElementsChange.calculate(prevAffectedElements, nextAffectedElements);
|
|
773
|
+
for (const [id, delta] of added) {
|
|
774
|
+
this.added.set(id, delta);
|
|
775
|
+
}
|
|
776
|
+
for (const [id, delta] of removed) {
|
|
777
|
+
this.removed.set(id, delta);
|
|
778
|
+
}
|
|
779
|
+
for (const [id, delta] of updated) {
|
|
780
|
+
this.updated.set(id, delta);
|
|
781
|
+
}
|
|
782
|
+
return nextAffectedElements;
|
|
783
|
+
}
|
|
784
|
+
/**
|
|
785
|
+
* Non deleted affected elements of removed elements (before and after applying delta),
|
|
786
|
+
* should be unbound ~ bindings should not point from non deleted into the deleted element/s.
|
|
787
|
+
*/
|
|
788
|
+
static unbindAffected(prevElements, nextElements, id, updater) {
|
|
789
|
+
// the instance could have been updated, so make sure we are passing the latest element to each function below
|
|
790
|
+
const prevElement = () => prevElements.get(id); // element before removal
|
|
791
|
+
const nextElement = () => nextElements.get(id); // element after removal
|
|
792
|
+
BoundElement.unbindAffected(nextElements, prevElement(), updater);
|
|
793
|
+
BoundElement.unbindAffected(nextElements, nextElement(), updater);
|
|
794
|
+
BindableElement.unbindAffected(nextElements, prevElement(), updater);
|
|
795
|
+
BindableElement.unbindAffected(nextElements, nextElement(), updater);
|
|
796
|
+
}
|
|
797
|
+
/**
|
|
798
|
+
* Non deleted affected elements of added or updated element/s (before and after applying delta),
|
|
799
|
+
* should be rebound (if possible) with the current element ~ bindings should be bidirectional.
|
|
800
|
+
*/
|
|
801
|
+
static rebindAffected(prevElements, nextElements, id, updater) {
|
|
802
|
+
// the instance could have been updated, so make sure we are passing the latest element to each function below
|
|
803
|
+
const prevElement = () => prevElements.get(id); // element before addition / update
|
|
804
|
+
const nextElement = () => nextElements.get(id); // element after addition / update
|
|
805
|
+
BoundElement.unbindAffected(nextElements, prevElement(), updater);
|
|
806
|
+
BoundElement.rebindAffected(nextElements, nextElement(), updater);
|
|
807
|
+
BindableElement.unbindAffected(nextElements, prevElement(), (element, updates) => {
|
|
808
|
+
// we cannot rebind arrows with bindable element so we don't unbind them at all during rebind (we still need to unbind them on removal)
|
|
809
|
+
// TODO: #7348 add startBinding / endBinding to the `BoundElement` context so that we could rebind arrows and remove this condition
|
|
810
|
+
if (isTextElement(element)) {
|
|
811
|
+
updater(element, updates);
|
|
812
|
+
}
|
|
813
|
+
});
|
|
814
|
+
BindableElement.rebindAffected(nextElements, nextElement(), updater);
|
|
815
|
+
}
|
|
816
|
+
static redrawTextBoundingBoxes(elements, changed) {
|
|
817
|
+
const boxesToRedraw = new Map();
|
|
818
|
+
for (const element of changed.values()) {
|
|
819
|
+
if (isBoundToContainer(element)) {
|
|
820
|
+
const { containerId } = element;
|
|
821
|
+
const container = containerId ? elements.get(containerId) : undefined;
|
|
822
|
+
if (container) {
|
|
823
|
+
boxesToRedraw.set(container.id, {
|
|
824
|
+
container,
|
|
825
|
+
boundText: element,
|
|
826
|
+
});
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
if (hasBoundTextElement(element)) {
|
|
830
|
+
const boundTextElementId = getBoundTextElementId(element);
|
|
831
|
+
const boundText = boundTextElementId
|
|
832
|
+
? elements.get(boundTextElementId)
|
|
833
|
+
: undefined;
|
|
834
|
+
if (boundText) {
|
|
835
|
+
boxesToRedraw.set(element.id, {
|
|
836
|
+
container: element,
|
|
837
|
+
boundText: boundText,
|
|
838
|
+
});
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
for (const { container, boundText } of boxesToRedraw.values()) {
|
|
843
|
+
if (container.isDeleted || boundText.isDeleted) {
|
|
844
|
+
// skip redraw if one of them is deleted, as it would not result in a meaningful redraw
|
|
845
|
+
continue;
|
|
846
|
+
}
|
|
847
|
+
redrawTextBoundingBox(boundText, container, elements, false);
|
|
848
|
+
}
|
|
849
|
+
}
|
|
850
|
+
static redrawBoundArrows(elements, changed) {
|
|
851
|
+
for (const element of changed.values()) {
|
|
852
|
+
if (!element.isDeleted && isBindableElement(element)) {
|
|
853
|
+
updateBoundElements(element, elements);
|
|
854
|
+
}
|
|
855
|
+
}
|
|
856
|
+
}
|
|
857
|
+
static reorderElements(elements, changed, flags) {
|
|
858
|
+
if (!flags.containsZindexDifference) {
|
|
859
|
+
return elements;
|
|
860
|
+
}
|
|
861
|
+
const unordered = Array.from(elements.values());
|
|
862
|
+
const ordered = orderByFractionalIndex([...unordered]);
|
|
863
|
+
const moved = Delta.getRightDifferences(unordered, ordered, true).reduce((acc, arrayIndex) => {
|
|
864
|
+
const candidate = unordered[Number(arrayIndex)];
|
|
865
|
+
if (candidate && changed.has(candidate.id)) {
|
|
866
|
+
acc.set(candidate.id, candidate);
|
|
867
|
+
}
|
|
868
|
+
return acc;
|
|
869
|
+
}, new Map());
|
|
870
|
+
if (!flags.containsVisibleDifference && moved.size) {
|
|
871
|
+
// we found a difference in order!
|
|
872
|
+
flags.containsVisibleDifference = true;
|
|
873
|
+
}
|
|
874
|
+
// synchronize all elements that were actually moved
|
|
875
|
+
// could fallback to synchronizing all invalid indices
|
|
876
|
+
return arrayToMap(syncMovedIndices(ordered, moved));
|
|
877
|
+
}
|
|
878
|
+
/**
|
|
879
|
+
* It is necessary to post process the partials in case of reference values,
|
|
880
|
+
* for which we need to calculate the real diff between `deleted` and `inserted`.
|
|
881
|
+
*/
|
|
882
|
+
static postProcess(deleted, inserted) {
|
|
883
|
+
try {
|
|
884
|
+
Delta.diffArrays(deleted, inserted, "boundElements", (x) => x.id);
|
|
885
|
+
}
|
|
886
|
+
catch (e) {
|
|
887
|
+
// if postprocessing fails, it does not make sense to bubble up, but let's make sure we know about it
|
|
888
|
+
console.error(`Couldn't postprocess elements change deltas.`);
|
|
889
|
+
if (import.meta.env.DEV || import.meta.env.MODE === ENV.TEST) {
|
|
890
|
+
throw e;
|
|
891
|
+
}
|
|
892
|
+
}
|
|
893
|
+
finally {
|
|
894
|
+
return [deleted, inserted];
|
|
895
|
+
}
|
|
896
|
+
}
|
|
897
|
+
static stripIrrelevantProps(partial) {
|
|
898
|
+
const { id, updated, version, versionNonce, seed, ...strippedPartial } = partial;
|
|
899
|
+
return strippedPartial;
|
|
900
|
+
}
|
|
901
|
+
}
|