@tomorrowevening/theatre-studio 1.0.5 → 1.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +105 -56
- package/package.json +1 -1
- package/dist/IDBStorage.js +0 -19
- package/dist/PaneManager.js +0 -112
- package/dist/Scrub.js +0 -134
- package/dist/Studio.js +0 -405
- package/dist/StudioBundle.js +0 -21
- package/dist/StudioStore/StudioStore.js +0 -163
- package/dist/StudioStore/createTransactionPrivateApi.js +0 -204
- package/dist/StudioStore/generateDiskStateRevision.js +0 -4
- package/dist/StudioStore/persistStateOfStudio.js +0 -61
- package/dist/TheatreStudio.js +0 -154
- package/dist/UI/UI.js +0 -65
- package/dist/UI/UINonSSRBits.js +0 -60
- package/dist/UIRoot/PanelsRoot.js +0 -19
- package/dist/UIRoot/PointerCapturing.js +0 -96
- package/dist/UIRoot/ProvideTheme.js +0 -9
- package/dist/UIRoot/UIRoot.js +0 -79
- package/dist/UIRoot/useKeyboardShortcuts.js +0 -158
- package/dist/checkForUpdates.js +0 -86
- package/dist/css.js +0 -116
- package/dist/getStudio.js +0 -10
- package/dist/notify.js +0 -328
- package/dist/panels/BasePanel/BasePanel.js +0 -74
- package/dist/panels/BasePanel/ExtensionPaneWrapper.js +0 -138
- package/dist/panels/BasePanel/PanelDragZone.js +0 -88
- package/dist/panels/BasePanel/PanelResizeHandle.js +0 -184
- package/dist/panels/BasePanel/PanelResizers.js +0 -14
- package/dist/panels/BasePanel/PanelWrapper.js +0 -34
- package/dist/panels/BasePanel/common.js +0 -52
- package/dist/panels/DetailPanel/DetailPanel.js +0 -146
- package/dist/panels/DetailPanel/DeterminePropEditorForDetail/DetailCompoundPropEditor.js +0 -169
- package/dist/panels/DetailPanel/DeterminePropEditorForDetail/DetailSimplePropEditor.js +0 -22
- package/dist/panels/DetailPanel/DeterminePropEditorForDetail/SingleRowPropEditor.js +0 -89
- package/dist/panels/DetailPanel/DeterminePropEditorForDetail/getDetailRowHighlightBackground.js +0 -7
- package/dist/panels/DetailPanel/DeterminePropEditorForDetail/rowIndentationFormulaCSS.js +0 -1
- package/dist/panels/DetailPanel/DeterminePropEditorForDetail.js +0 -28
- package/dist/panels/DetailPanel/EmptyState.js +0 -36
- package/dist/panels/DetailPanel/ObjectDetails.js +0 -52
- package/dist/panels/DetailPanel/ProjectDetails/StateConflictRow.js +0 -86
- package/dist/panels/DetailPanel/ProjectDetails.js +0 -98
- package/dist/panels/OutlinePanel/BaseItem.js +0 -136
- package/dist/panels/OutlinePanel/ObjectsList/ObjectItem.js +0 -14
- package/dist/panels/OutlinePanel/ObjectsList/ObjectsList.js +0 -85
- package/dist/panels/OutlinePanel/OutlinePanel.js +0 -73
- package/dist/panels/OutlinePanel/ProjectsList/ProjectListItem.js +0 -38
- package/dist/panels/OutlinePanel/ProjectsList/ProjectsList.js +0 -22
- package/dist/panels/OutlinePanel/SheetsList/SheetInstanceItem.js +0 -36
- package/dist/panels/OutlinePanel/SheetsList/SheetItem.js +0 -23
- package/dist/panels/OutlinePanel/SheetsList/SheetsList.js +0 -15
- package/dist/panels/OutlinePanel/outlinePanelUtils.js +0 -23
- package/dist/panels/SequenceEditorPanel/DopeSheet/DopeSheet.js +0 -21
- package/dist/panels/SequenceEditorPanel/DopeSheet/Left/AnyCompositeRow.js +0 -74
- package/dist/panels/SequenceEditorPanel/DopeSheet/Left/Left.js +0 -25
- package/dist/panels/SequenceEditorPanel/DopeSheet/Left/PrimitivePropRow.js +0 -97
- package/dist/panels/SequenceEditorPanel/DopeSheet/Left/PropWithChildrenRow.js +0 -15
- package/dist/panels/SequenceEditorPanel/DopeSheet/Left/SheetObjectRow.js +0 -19
- package/dist/panels/SequenceEditorPanel/DopeSheet/Left/SheetRow.js +0 -20
- package/dist/panels/SequenceEditorPanel/DopeSheet/Left/usePropHighlightMouseEnter.js +0 -33
- package/dist/panels/SequenceEditorPanel/DopeSheet/Right/AggregatedKeyframeTrack/AggregateKeyframeEditor/AggregateKeyframeConnector.js +0 -187
- package/dist/panels/SequenceEditorPanel/DopeSheet/Right/AggregatedKeyframeTrack/AggregateKeyframeEditor/AggregateKeyframeDot.js +0 -158
- package/dist/panels/SequenceEditorPanel/DopeSheet/Right/AggregatedKeyframeTrack/AggregateKeyframeEditor/AggregateKeyframeEditor.js +0 -32
- package/dist/panels/SequenceEditorPanel/DopeSheet/Right/AggregatedKeyframeTrack/AggregateKeyframeEditor/AggregateKeyframeVisualDot.js +0 -61
- package/dist/panels/SequenceEditorPanel/DopeSheet/Right/AggregatedKeyframeTrack/AggregateKeyframeEditor/iif.js +0 -3
- package/dist/panels/SequenceEditorPanel/DopeSheet/Right/AggregatedKeyframeTrack/AggregateKeyframeEditor/useAggregateKeyframeEditorUtils.js +0 -73
- package/dist/panels/SequenceEditorPanel/DopeSheet/Right/AggregatedKeyframeTrack/AggregatedKeyframeTrack.js +0 -407
- package/dist/panels/SequenceEditorPanel/DopeSheet/Right/BasicKeyframedTrack/BasicKeyframedTrack.js +0 -108
- package/dist/panels/SequenceEditorPanel/DopeSheet/Right/BasicKeyframedTrack/KeyframeEditor/BasicKeyframeConnector.js +0 -185
- package/dist/panels/SequenceEditorPanel/DopeSheet/Right/BasicKeyframedTrack/KeyframeEditor/CurveEditorPopover/CurveEditorPopover.js +0 -397
- package/dist/panels/SequenceEditorPanel/DopeSheet/Right/BasicKeyframedTrack/KeyframeEditor/CurveEditorPopover/CurveSegmentEditor.js +0 -136
- package/dist/panels/SequenceEditorPanel/DopeSheet/Right/BasicKeyframedTrack/KeyframeEditor/CurveEditorPopover/EasingOption.js +0 -52
- package/dist/panels/SequenceEditorPanel/DopeSheet/Right/BasicKeyframedTrack/KeyframeEditor/CurveEditorPopover/SVGCurveSegment.js +0 -43
- package/dist/panels/SequenceEditorPanel/DopeSheet/Right/BasicKeyframedTrack/KeyframeEditor/CurveEditorPopover/colors.js +0 -3
- package/dist/panels/SequenceEditorPanel/DopeSheet/Right/BasicKeyframedTrack/KeyframeEditor/CurveEditorPopover/shared.js +0 -84
- package/dist/panels/SequenceEditorPanel/DopeSheet/Right/BasicKeyframedTrack/KeyframeEditor/CurveEditorPopover/useFreezableMemo.js +0 -16
- package/dist/panels/SequenceEditorPanel/DopeSheet/Right/BasicKeyframedTrack/KeyframeEditor/CurveEditorPopover/useUIOptionGrid.js +0 -82
- package/dist/panels/SequenceEditorPanel/DopeSheet/Right/BasicKeyframedTrack/KeyframeEditor/DeterminePropEditorForSingleKeyframe.js +0 -93
- package/dist/panels/SequenceEditorPanel/DopeSheet/Right/BasicKeyframedTrack/KeyframeEditor/SingleKeyframeDot.js +0 -254
- package/dist/panels/SequenceEditorPanel/DopeSheet/Right/BasicKeyframedTrack/KeyframeEditor/SingleKeyframeEditor.js +0 -22
- package/dist/panels/SequenceEditorPanel/DopeSheet/Right/BasicKeyframedTrack/KeyframeEditor/useSingleKeyframeInlineEditorPopover.js +0 -11
- package/dist/panels/SequenceEditorPanel/DopeSheet/Right/BasicKeyframedTrack/KeyframeEditor/useTempTransactionEditingTools.js +0 -43
- package/dist/panels/SequenceEditorPanel/DopeSheet/Right/DopeSheetBackground.js +0 -24
- package/dist/panels/SequenceEditorPanel/DopeSheet/Right/DopeSheetSelectionView.js +0 -272
- package/dist/panels/SequenceEditorPanel/DopeSheet/Right/FocusRangeCurtains.js +0 -88
- package/dist/panels/SequenceEditorPanel/DopeSheet/Right/HorizontallyScrollableArea.js +0 -215
- package/dist/panels/SequenceEditorPanel/DopeSheet/Right/KeyframeSnapTarget.js +0 -55
- package/dist/panels/SequenceEditorPanel/DopeSheet/Right/LengthIndicator/LengthEditorPopover.js +0 -69
- package/dist/panels/SequenceEditorPanel/DopeSheet/Right/LengthIndicator/LengthIndicator.js +0 -217
- package/dist/panels/SequenceEditorPanel/DopeSheet/Right/PrimitivePropRow.js +0 -25
- package/dist/panels/SequenceEditorPanel/DopeSheet/Right/PropWithChildrenRow.js +0 -18
- package/dist/panels/SequenceEditorPanel/DopeSheet/Right/Right.js +0 -30
- package/dist/panels/SequenceEditorPanel/DopeSheet/Right/Row.js +0 -50
- package/dist/panels/SequenceEditorPanel/DopeSheet/Right/SheetObjectRow.js +0 -14
- package/dist/panels/SequenceEditorPanel/DopeSheet/Right/SheetRow.js +0 -14
- package/dist/panels/SequenceEditorPanel/DopeSheet/Right/collectAggregateKeyframes.js +0 -92
- package/dist/panels/SequenceEditorPanel/DopeSheet/Right/keyframeRowUI/ConnectorLine.js +0 -62
- package/dist/panels/SequenceEditorPanel/DopeSheet/selections.js +0 -149
- package/dist/panels/SequenceEditorPanel/DopeSheet/setCollapsedSheetObjectOrCompoundProp.js +0 -10
- package/dist/panels/SequenceEditorPanel/FrameGrid/FrameGrid.js +0 -92
- package/dist/panels/SequenceEditorPanel/FrameGrid/StampsGrid.js +0 -99
- package/dist/panels/SequenceEditorPanel/FrameGrid/createGrid.js +0 -49
- package/dist/panels/SequenceEditorPanel/FrameStampPositionProvider.js +0 -189
- package/dist/panels/SequenceEditorPanel/GraphEditor/BasicKeyframedTrack/BasicKeyframedTrack.js +0 -91
- package/dist/panels/SequenceEditorPanel/GraphEditor/BasicKeyframedTrack/KeyframeEditor/Curve.js +0 -87
- package/dist/panels/SequenceEditorPanel/GraphEditor/BasicKeyframedTrack/KeyframeEditor/CurveHandle.js +0 -186
- package/dist/panels/SequenceEditorPanel/GraphEditor/BasicKeyframedTrack/KeyframeEditor/GraphEditorDotNonScalar.js +0 -162
- package/dist/panels/SequenceEditorPanel/GraphEditor/BasicKeyframedTrack/KeyframeEditor/GraphEditorDotScalar.js +0 -209
- package/dist/panels/SequenceEditorPanel/GraphEditor/BasicKeyframedTrack/KeyframeEditor/GraphEditorNonScalarDash.js +0 -23
- package/dist/panels/SequenceEditorPanel/GraphEditor/BasicKeyframedTrack/KeyframeEditor/KeyframeEditor.js +0 -30
- package/dist/panels/SequenceEditorPanel/GraphEditor/GraphEditor.js +0 -73
- package/dist/panels/SequenceEditorPanel/GraphEditor/PrimitivePropGraph.js +0 -20
- package/dist/panels/SequenceEditorPanel/GraphEditorToggle.js +0 -59
- package/dist/panels/SequenceEditorPanel/RightOverlay/DopeSnap.js +0 -36
- package/dist/panels/SequenceEditorPanel/RightOverlay/DopeSnapHitZoneUI.js +0 -57
- package/dist/panels/SequenceEditorPanel/RightOverlay/FocusRangeZone/FocusRangeStrip.js +0 -233
- package/dist/panels/SequenceEditorPanel/RightOverlay/FocusRangeZone/FocusRangeThumb.js +0 -217
- package/dist/panels/SequenceEditorPanel/RightOverlay/FocusRangeZone/FocusRangeZone.js +0 -181
- package/dist/panels/SequenceEditorPanel/RightOverlay/FrameStamp.js +0 -65
- package/dist/panels/SequenceEditorPanel/RightOverlay/HorizontalScrollbar.js +0 -235
- package/dist/panels/SequenceEditorPanel/RightOverlay/Markers/MarkerDot.js +0 -184
- package/dist/panels/SequenceEditorPanel/RightOverlay/Markers/MarkerEditorPopover.js +0 -65
- package/dist/panels/SequenceEditorPanel/RightOverlay/Markers/Markers.js +0 -13
- package/dist/panels/SequenceEditorPanel/RightOverlay/Playhead.js +0 -265
- package/dist/panels/SequenceEditorPanel/RightOverlay/PlayheadPositionPopover.js +0 -64
- package/dist/panels/SequenceEditorPanel/RightOverlay/RightOverlay.js +0 -35
- package/dist/panels/SequenceEditorPanel/RightOverlay/TopStrip.js +0 -31
- package/dist/panels/SequenceEditorPanel/SequenceEditorPanel.js +0 -179
- package/dist/panels/SequenceEditorPanel/VerticalScrollContainer.js +0 -42
- package/dist/panels/SequenceEditorPanel/layout/layout.js +0 -166
- package/dist/panels/SequenceEditorPanel/layout/tree.js +0 -139
- package/dist/panels/SequenceEditorPanel/whatPropIsHighlighted.js +0 -58
- package/dist/propEditors/DefaultValueIndicator.js +0 -64
- package/dist/propEditors/NextPrevKeyframeCursors.js +0 -135
- package/dist/propEditors/getNearbyKeyframesOfTrack.js +0 -46
- package/dist/propEditors/simpleEditors/BooleanPropEditor.js +0 -17
- package/dist/propEditors/simpleEditors/FilePropEditor.js +0 -118
- package/dist/propEditors/simpleEditors/ISimplePropEditorReactProps.js +0 -1
- package/dist/propEditors/simpleEditors/ImagePropEditor.js +0 -126
- package/dist/propEditors/simpleEditors/NumberPropEditor.js +0 -9
- package/dist/propEditors/simpleEditors/RgbaPropEditor.js +0 -73
- package/dist/propEditors/simpleEditors/StringLiteralPropEditor.js +0 -10
- package/dist/propEditors/simpleEditors/StringPropEditor.js +0 -6
- package/dist/propEditors/simpleEditors/simplePropEditorByPropType.js +0 -16
- package/dist/propEditors/useEditingToolsForCompoundProp.js +0 -228
- package/dist/propEditors/useEditingToolsForSimpleProp.js +0 -229
- package/dist/propEditors/utils/IEditingTools.js +0 -1
- package/dist/propEditors/utils/PropConfigForType.js +0 -1
- package/dist/propEditors/utils/getPropTypeByPointer.js +0 -48
- package/dist/propEditors/utils/propNameTextCSS.js +0 -7
- package/dist/selectors.js +0 -63
- package/dist/store/index.js +0 -184
- package/dist/store/stateEditors.js +0 -774
- package/dist/store/types/ahistoric.js +0 -1
- package/dist/store/types/ephemeral.js +0 -1
- package/dist/store/types/historic.js +0 -1
- package/dist/store/types/index.js +0 -3
- package/dist/toolbars/ExtensionToolbar/ExtensionToolbar.js +0 -51
- package/dist/toolbars/ExtensionToolbar/Toolset.js +0 -27
- package/dist/toolbars/ExtensionToolbar/tools/ExtensionFlyoutMenu.js +0 -51
- package/dist/toolbars/ExtensionToolbar/tools/IconButton.js +0 -16
- package/dist/toolbars/ExtensionToolbar/tools/Switch.js +0 -20
- package/dist/toolbars/GlobalToolbar.js +0 -142
- package/dist/toolbars/MoreMenu/MoreMenu.js +0 -133
- package/dist/toolbars/PinButton.js +0 -26
- package/dist/uiComponents/DetailPanelButton.js +0 -21
- package/dist/uiComponents/PointerEventsHandler.js +0 -80
- package/dist/uiComponents/Popover/ArrowContext.js +0 -3
- package/dist/uiComponents/Popover/BasicPopover.js +0 -35
- package/dist/uiComponents/Popover/BasicTooltip.js +0 -10
- package/dist/uiComponents/Popover/ErrorTooltip.js +0 -9
- package/dist/uiComponents/Popover/MinimalTooltip.js +0 -6
- package/dist/uiComponents/Popover/PopoverArrow.js +0 -38
- package/dist/uiComponents/Popover/TooltipContext.js +0 -46
- package/dist/uiComponents/Popover/TooltipWrapper.js +0 -103
- package/dist/uiComponents/Popover/usePopover.js +0 -132
- package/dist/uiComponents/Popover/useTooltip.js +0 -33
- package/dist/uiComponents/RoomToClick.js +0 -10
- package/dist/uiComponents/SVGIcon.js +0 -19
- package/dist/uiComponents/ShowMousePosition.js +0 -30
- package/dist/uiComponents/colorPicker/components/EditingProvider.js +0 -15
- package/dist/uiComponents/colorPicker/components/RgbaColorPicker.js +0 -31
- package/dist/uiComponents/colorPicker/components/common/Alpha.js +0 -54
- package/dist/uiComponents/colorPicker/components/common/AlphaColorPicker.js +0 -28
- package/dist/uiComponents/colorPicker/components/common/Hue.js +0 -41
- package/dist/uiComponents/colorPicker/components/common/Interactive.js +0 -142
- package/dist/uiComponents/colorPicker/components/common/Pointer.js +0 -39
- package/dist/uiComponents/colorPicker/components/common/Saturation.js +0 -44
- package/dist/uiComponents/colorPicker/hooks/useColorManipulation.js +0 -77
- package/dist/uiComponents/colorPicker/hooks/useEventCallback.js +0 -10
- package/dist/uiComponents/colorPicker/hooks/useIsomorphicLayoutEffect.js +0 -5
- package/dist/uiComponents/colorPicker/index.js +0 -1
- package/dist/uiComponents/colorPicker/types.js +0 -1
- package/dist/uiComponents/colorPicker/utils/clamp.js +0 -6
- package/dist/uiComponents/colorPicker/utils/compare.js +0 -25
- package/dist/uiComponents/colorPicker/utils/convert.js +0 -165
- package/dist/uiComponents/colorPicker/utils/round.js +0 -3
- package/dist/uiComponents/colorPicker/utils/validate.js +0 -10
- package/dist/uiComponents/createCursorLock.js +0 -2
- package/dist/uiComponents/form/BasicCheckbox.js +0 -5
- package/dist/uiComponents/form/BasicNumberInput.js +0 -261
- package/dist/uiComponents/form/BasicSelect.js +0 -58
- package/dist/uiComponents/form/BasicStringInput.js +0 -151
- package/dist/uiComponents/form/BasicSwitch.js +0 -60
- package/dist/uiComponents/icons/AddImage.js +0 -6
- package/dist/uiComponents/icons/ArrowClockwise.js +0 -6
- package/dist/uiComponents/icons/ArrowsOutCardinal.js +0 -6
- package/dist/uiComponents/icons/Bell.js +0 -6
- package/dist/uiComponents/icons/Camera.js +0 -7
- package/dist/uiComponents/icons/ChevronDown.js +0 -6
- package/dist/uiComponents/icons/ChevronLeft.js +0 -6
- package/dist/uiComponents/icons/ChevronRight.js +0 -6
- package/dist/uiComponents/icons/Cube.js +0 -6
- package/dist/uiComponents/icons/CubeFull.js +0 -6
- package/dist/uiComponents/icons/CubeHalf.js +0 -6
- package/dist/uiComponents/icons/CubeRendered.js +0 -7
- package/dist/uiComponents/icons/Details.js +0 -6
- package/dist/uiComponents/icons/DoubleChevronLeft.js +0 -6
- package/dist/uiComponents/icons/DoubleChevronRight.js +0 -6
- package/dist/uiComponents/icons/Ellipsis.js +0 -6
- package/dist/uiComponents/icons/EllipsisFill.js +0 -6
- package/dist/uiComponents/icons/GlobeSimple.js +0 -6
- package/dist/uiComponents/icons/Outline.js +0 -6
- package/dist/uiComponents/icons/Package.js +0 -6
- package/dist/uiComponents/icons/Resize.js +0 -7
- package/dist/uiComponents/icons/Trash.js +0 -6
- package/dist/uiComponents/icons/index.js +0 -20
- package/dist/uiComponents/isSafari.js +0 -2
- package/dist/uiComponents/onPointerOutside.js +0 -19
- package/dist/uiComponents/selects/BasicSelect.js +0 -24
- package/dist/uiComponents/simpleContextMenu/ContextMenu/BaseMenu.js +0 -40
- package/dist/uiComponents/simpleContextMenu/ContextMenu/ContextMenu.js +0 -87
- package/dist/uiComponents/simpleContextMenu/ContextMenu/Item.js +0 -37
- package/dist/uiComponents/simpleContextMenu/useContextMenu.js +0 -20
- package/dist/uiComponents/simpleContextMenu/useRequestContextMenu.js +0 -22
- package/dist/uiComponents/toolbar/ToolbarDropdownSelect.js +0 -7
- package/dist/uiComponents/toolbar/ToolbarIconButton.js +0 -74
- package/dist/uiComponents/toolbar/ToolbarSwitchSelect.js +0 -12
- package/dist/uiComponents/toolbar/ToolbarSwitchSelectContainer.js +0 -9
- package/dist/uiComponents/useBoundingClientRect.js +0 -13
- package/dist/uiComponents/useDebugRefreshEvery.js +0 -19
- package/dist/uiComponents/useDrag.js +0 -199
- package/dist/uiComponents/useHotspot.js +0 -30
- package/dist/uiComponents/useHover.js +0 -23
- package/dist/uiComponents/useHoverWithoutDescendants.js +0 -33
- package/dist/uiComponents/useKeyDown.js +0 -9
- package/dist/uiComponents/useKeyDownCallback.js +0 -28
- package/dist/uiComponents/useLockSet.js +0 -17
- package/dist/uiComponents/useLogger.js +0 -16
- package/dist/uiComponents/useOnClickOutside.js +0 -25
- package/dist/uiComponents/useOnKeyDown.js +0 -12
- package/dist/uiComponents/usePresence.js +0 -156
- package/dist/uiComponents/useValToAtom.js +0 -11
- package/dist/utils/absoluteDims.js +0 -7
- package/dist/utils/contextualWebComponents.js +0 -44
- package/dist/utils/copyToClipboard.js +0 -28
- package/dist/utils/derive-utils.js +0 -61
- package/dist/utils/devStringify.js +0 -20
- package/dist/utils/invariant.js +0 -79
- package/dist/utils/isMac.js +0 -2
- package/dist/utils/keyboardUtils.js +0 -23
- package/dist/utils/mousePositionD.js +0 -18
- package/dist/utils/redux/actionCreator.js +0 -15
- package/dist/utils/redux/actionCreator.test.js +0 -35
- package/dist/utils/redux/actionReducersBundle.js +0 -18
- package/dist/utils/redux/atomFromReduxStore.js +0 -11
- package/dist/utils/redux/configureStore.js +0 -18
- package/dist/utils/redux/pointerFriendlySelector.js +0 -8
- package/dist/utils/redux/withHistory/withBatchActions.js +0 -13
- package/dist/utils/redux/withHistory/withHistory.js +0 -157
- package/dist/utils/renderInPortalInContext.js +0 -38
- package/dist/utils/selectClosestHTMLAncestor.js +0 -13
- package/dist/utils/tightJsonStringify.js +0 -27
- package/dist/utils/tightJsonStringify.test.js +0 -25
- package/dist/utils/useRefAndState.js +0 -32
package/package.json
CHANGED
package/dist/IDBStorage.js
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import * as idb from 'idb-keyval';
|
|
2
|
-
/**
|
|
3
|
-
* Custom IDB keyval storage creator. Right now this exists solely as a more convenient way to use idb-keyval with a custom db name.
|
|
4
|
-
* It also automatically prefixes the provided name with `theatrejs-` to avoid conflicts with other libraries.
|
|
5
|
-
*
|
|
6
|
-
* @param name - The name of the database
|
|
7
|
-
* @returns An object with the same methods as idb-keyval, but with a custom database name
|
|
8
|
-
*/
|
|
9
|
-
export const createStore = (name) => {
|
|
10
|
-
const customStore = idb.createStore(`theatrejs-${name}`, 'default-store');
|
|
11
|
-
return {
|
|
12
|
-
set: (key, value) => idb.set(key, value, customStore),
|
|
13
|
-
get: (key) => idb.get(key, customStore),
|
|
14
|
-
del: (key) => idb.del(key, customStore),
|
|
15
|
-
keys: () => idb.keys(customStore),
|
|
16
|
-
entries: () => idb.entries(customStore),
|
|
17
|
-
values: () => idb.values(customStore),
|
|
18
|
-
};
|
|
19
|
-
};
|
package/dist/PaneManager.js
DELETED
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
import { prism, val } from '@tomorrowevening/theatre-dataverse';
|
|
2
|
-
import SimpleCache from '@tomorrowevening/theatre-shared/utils/SimpleCache';
|
|
3
|
-
export default class PaneManager {
|
|
4
|
-
_studio;
|
|
5
|
-
_cache = new SimpleCache();
|
|
6
|
-
constructor(_studio) {
|
|
7
|
-
this._studio = _studio;
|
|
8
|
-
this._instantiatePanesAsTheyComeIn();
|
|
9
|
-
}
|
|
10
|
-
_instantiatePanesAsTheyComeIn() {
|
|
11
|
-
const allPanesD = this._getAllPanes();
|
|
12
|
-
allPanesD.onStale(() => {
|
|
13
|
-
allPanesD.getValue();
|
|
14
|
-
});
|
|
15
|
-
}
|
|
16
|
-
_getAllPanes() {
|
|
17
|
-
return this._cache.get('_getAllPanels()', () => prism(() => {
|
|
18
|
-
const core = val(this._studio.coreP);
|
|
19
|
-
if (!core)
|
|
20
|
-
return {};
|
|
21
|
-
const instanceDescriptors = val(this._studio.atomP.historic.panelInstanceDesceriptors);
|
|
22
|
-
const paneClasses = val(this._studio.atomP.ephemeral.extensions.paneClasses);
|
|
23
|
-
const instances = {};
|
|
24
|
-
for (const instanceDescriptor of Object.values(instanceDescriptors)) {
|
|
25
|
-
if (!instanceDescriptor)
|
|
26
|
-
continue;
|
|
27
|
-
const panelClass = paneClasses[instanceDescriptor.paneClass];
|
|
28
|
-
if (!panelClass)
|
|
29
|
-
continue;
|
|
30
|
-
const { instanceId } = instanceDescriptor;
|
|
31
|
-
const { extensionId, classDefinition: definition } = panelClass;
|
|
32
|
-
const instance = prism.memo(`instance-${instanceDescriptor.instanceId}`, () => {
|
|
33
|
-
const inst = {
|
|
34
|
-
extensionId,
|
|
35
|
-
instanceId,
|
|
36
|
-
definition,
|
|
37
|
-
};
|
|
38
|
-
return inst;
|
|
39
|
-
}, [definition]);
|
|
40
|
-
instances[instanceId] = instance;
|
|
41
|
-
}
|
|
42
|
-
return instances;
|
|
43
|
-
}));
|
|
44
|
-
}
|
|
45
|
-
get allPanesD() {
|
|
46
|
-
return this._getAllPanes();
|
|
47
|
-
}
|
|
48
|
-
createPane(paneClass) {
|
|
49
|
-
const core = this._studio.core;
|
|
50
|
-
if (!core) {
|
|
51
|
-
throw new Error(`Can't create a pane because @tomorrowevening/theatre-core is not yet loaded`);
|
|
52
|
-
}
|
|
53
|
-
const extensionId = val(this._studio.atomP.ephemeral.extensions.paneClasses[paneClass]
|
|
54
|
-
.extensionId);
|
|
55
|
-
const allPaneInstances = val(this._studio.atomP.historic.panelInstanceDesceriptors);
|
|
56
|
-
let instanceId;
|
|
57
|
-
for (let i = 1; i < 1000; i++) {
|
|
58
|
-
instanceId = `${paneClass} #${i}`;
|
|
59
|
-
if (!allPaneInstances[instanceId])
|
|
60
|
-
break;
|
|
61
|
-
}
|
|
62
|
-
if (!extensionId) {
|
|
63
|
-
throw new Error(`Pane class "${paneClass}" is not registered.`);
|
|
64
|
-
}
|
|
65
|
-
this._studio.transaction(({ drafts }) => {
|
|
66
|
-
drafts.historic.panelInstanceDesceriptors[instanceId] = {
|
|
67
|
-
instanceId,
|
|
68
|
-
paneClass,
|
|
69
|
-
};
|
|
70
|
-
// Add to focus order (bring new pane to front)
|
|
71
|
-
if (!drafts.historic.paneFocusOrder) {
|
|
72
|
-
drafts.historic.paneFocusOrder = [];
|
|
73
|
-
}
|
|
74
|
-
const focusOrder = drafts.historic.paneFocusOrder;
|
|
75
|
-
const existingIndex = focusOrder.indexOf(instanceId);
|
|
76
|
-
if (existingIndex !== -1) {
|
|
77
|
-
focusOrder.splice(existingIndex, 1);
|
|
78
|
-
}
|
|
79
|
-
focusOrder.push(instanceId);
|
|
80
|
-
});
|
|
81
|
-
return this._getAllPanes().getValue()[instanceId];
|
|
82
|
-
}
|
|
83
|
-
destroyPane(instanceId) {
|
|
84
|
-
const core = this._studio.core;
|
|
85
|
-
if (!core) {
|
|
86
|
-
throw new Error(`Can't do this yet because @tomorrowevening/theatre-core is not yet loaded`);
|
|
87
|
-
}
|
|
88
|
-
this._studio.transaction(({ drafts }) => {
|
|
89
|
-
delete drafts.historic.panelInstanceDesceriptors[instanceId];
|
|
90
|
-
// Remove from focus order
|
|
91
|
-
if (drafts.historic.paneFocusOrder) {
|
|
92
|
-
const index = drafts.historic.paneFocusOrder.indexOf(instanceId);
|
|
93
|
-
if (index !== -1) {
|
|
94
|
-
drafts.historic.paneFocusOrder.splice(index, 1);
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
});
|
|
98
|
-
}
|
|
99
|
-
bringPaneToFront(instanceId) {
|
|
100
|
-
this._studio.transaction(({ drafts }) => {
|
|
101
|
-
if (!drafts.historic.paneFocusOrder) {
|
|
102
|
-
drafts.historic.paneFocusOrder = [];
|
|
103
|
-
}
|
|
104
|
-
const focusOrder = drafts.historic.paneFocusOrder;
|
|
105
|
-
const existingIndex = focusOrder.indexOf(instanceId);
|
|
106
|
-
if (existingIndex !== -1) {
|
|
107
|
-
focusOrder.splice(existingIndex, 1);
|
|
108
|
-
}
|
|
109
|
-
focusOrder.push(instanceId);
|
|
110
|
-
});
|
|
111
|
-
}
|
|
112
|
-
}
|
package/dist/Scrub.js
DELETED
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
import forEachPropDeep from '@tomorrowevening/theatre-shared/utils/forEachDeep';
|
|
2
|
-
import { getPointerParts } from '@tomorrowevening/theatre-dataverse';
|
|
3
|
-
import { isSheetObject } from '@tomorrowevening/theatre-shared/instanceTypes';
|
|
4
|
-
let lastScrubIdAsNumber = 0;
|
|
5
|
-
export default class Scrub {
|
|
6
|
-
_studio;
|
|
7
|
-
_id;
|
|
8
|
-
_state = { type: 'Ready' };
|
|
9
|
-
// private readonly _scrubApi: IScrubApi
|
|
10
|
-
get status() {
|
|
11
|
-
return this._state.type;
|
|
12
|
-
}
|
|
13
|
-
constructor(_studio) {
|
|
14
|
-
this._studio = _studio;
|
|
15
|
-
this._id = String(lastScrubIdAsNumber++);
|
|
16
|
-
}
|
|
17
|
-
reset() {
|
|
18
|
-
const { _state: state } = this;
|
|
19
|
-
if (state.type === 'Ready') {
|
|
20
|
-
return;
|
|
21
|
-
}
|
|
22
|
-
else if (state.type === 'Captured') {
|
|
23
|
-
this._state = { type: 'Ready' };
|
|
24
|
-
state.transaction.discard();
|
|
25
|
-
state.flagsTransaction.discard();
|
|
26
|
-
}
|
|
27
|
-
else if (state.type === 'Committed') {
|
|
28
|
-
throw new Error(`This scrub is already committed and can't be reset.`);
|
|
29
|
-
}
|
|
30
|
-
else {
|
|
31
|
-
throw new Error(`This scrub is already discarded and can't be reset.`);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
commit() {
|
|
35
|
-
const { _state: state } = this;
|
|
36
|
-
if (state.type === 'Captured') {
|
|
37
|
-
state.transaction.commit();
|
|
38
|
-
state.flagsTransaction.discard();
|
|
39
|
-
this._state = { type: 'Committed' };
|
|
40
|
-
}
|
|
41
|
-
else if (state.type === 'Ready') {
|
|
42
|
-
console.warn(`Scrub is empty. Nothing to commit.`);
|
|
43
|
-
return;
|
|
44
|
-
}
|
|
45
|
-
else if (state.type === 'Committed') {
|
|
46
|
-
throw new Error(`This scrub is already committed.`);
|
|
47
|
-
}
|
|
48
|
-
else {
|
|
49
|
-
throw new Error(`This scrub is already discarded and can't be comitted.`);
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
capture(fn) {
|
|
53
|
-
if (this._state.type === 'Captured') {
|
|
54
|
-
this.reset();
|
|
55
|
-
}
|
|
56
|
-
if (this._state.type === 'Ready') {
|
|
57
|
-
let errored = true;
|
|
58
|
-
try {
|
|
59
|
-
this._state = { type: 'Captured', ...this._capture(fn) };
|
|
60
|
-
errored = false;
|
|
61
|
-
}
|
|
62
|
-
finally {
|
|
63
|
-
if (errored) {
|
|
64
|
-
console.error(`This scrub's callback threw an error. We're undo-ing all of the changes made by this scrub, and marking it as discarded.`);
|
|
65
|
-
this._state = { type: 'Discarded' };
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
else {
|
|
70
|
-
if (this._state.type === 'Committed') {
|
|
71
|
-
throw new Error(`This scrub is already committed and cannot capture again. ` +
|
|
72
|
-
`If you wish to capture more, you can start a new studio.scrub() or do so before scrub.commit()`);
|
|
73
|
-
}
|
|
74
|
-
else {
|
|
75
|
-
throw new Error(`This scrub is already discarded and cannot capture again. ` +
|
|
76
|
-
`If you wish to capture more, you can start a new studio.scrub() or do so before scrub.discard()`);
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
_capture(fn) {
|
|
81
|
-
const sets = [];
|
|
82
|
-
const transaction = this._studio.tempTransaction((transactionApi) => {
|
|
83
|
-
let running = true;
|
|
84
|
-
const api = {
|
|
85
|
-
set: (pointer, value) => {
|
|
86
|
-
if (!running) {
|
|
87
|
-
throw new Error(`You seem to have called the scrub api after scrub.capture()`);
|
|
88
|
-
}
|
|
89
|
-
const { root, path } = getPointerParts(pointer);
|
|
90
|
-
if (!isSheetObject(root)) {
|
|
91
|
-
throw new Error(`We can only scrub props of Sheet Objects for now`);
|
|
92
|
-
}
|
|
93
|
-
transactionApi.set(pointer, value);
|
|
94
|
-
sets.push(pointer);
|
|
95
|
-
},
|
|
96
|
-
};
|
|
97
|
-
try {
|
|
98
|
-
fn(api);
|
|
99
|
-
}
|
|
100
|
-
finally {
|
|
101
|
-
running = false;
|
|
102
|
-
}
|
|
103
|
-
});
|
|
104
|
-
const flagsTransaction = this._studio.tempTransaction(({ stateEditors }) => {
|
|
105
|
-
sets.forEach((pointer) => {
|
|
106
|
-
const { root, path } = getPointerParts(pointer);
|
|
107
|
-
if (!isSheetObject(root)) {
|
|
108
|
-
return;
|
|
109
|
-
}
|
|
110
|
-
const defaultValueOfProp = root.template.getDefaultsAtPointer(pointer);
|
|
111
|
-
forEachPropDeep(defaultValueOfProp, (val, pathToProp) => {
|
|
112
|
-
stateEditors.studio.ephemeral.projects.stateByProjectId.stateBySheetId.stateByObjectKey.propsBeingScrubbed.flag({ ...root.address, pathToProp });
|
|
113
|
-
}, path);
|
|
114
|
-
});
|
|
115
|
-
});
|
|
116
|
-
return { transaction, flagsTransaction };
|
|
117
|
-
}
|
|
118
|
-
discard() {
|
|
119
|
-
const { _state: state } = this;
|
|
120
|
-
if (state.type === 'Captured' || state.type === 'Ready') {
|
|
121
|
-
if (state.type === 'Captured') {
|
|
122
|
-
state.transaction.discard();
|
|
123
|
-
state.flagsTransaction.discard();
|
|
124
|
-
}
|
|
125
|
-
this._state = { type: 'Discarded' };
|
|
126
|
-
}
|
|
127
|
-
else if (state.type === 'Committed') {
|
|
128
|
-
throw new Error(`This scrub is already committed and can't be discarded.`);
|
|
129
|
-
}
|
|
130
|
-
else {
|
|
131
|
-
throw new Error(`This scrub is already discarded`);
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
}
|
package/dist/Studio.js
DELETED
|
@@ -1,405 +0,0 @@
|
|
|
1
|
-
import Scrub from '@tomorrowevening/theatre-studio/Scrub';
|
|
2
|
-
import UI from '@tomorrowevening/theatre-studio/UI/UI';
|
|
3
|
-
import { Atom, PointerProxy, pointerToPrism } from '@tomorrowevening/theatre-dataverse';
|
|
4
|
-
import StudioStore from './StudioStore/StudioStore';
|
|
5
|
-
import TheatreStudio from './TheatreStudio';
|
|
6
|
-
import { nanoid } from 'nanoid/non-secure';
|
|
7
|
-
import SimpleCache from '@tomorrowevening/theatre-shared/utils/SimpleCache';
|
|
8
|
-
import PaneManager from './PaneManager';
|
|
9
|
-
import { defer } from '@tomorrowevening/theatre-shared/utils/defer';
|
|
10
|
-
import checkForUpdates from './checkForUpdates';
|
|
11
|
-
import shallowEqual from 'shallowequal';
|
|
12
|
-
import { createStore } from './IDBStorage';
|
|
13
|
-
import { getAllPossibleAssetIDs } from '@tomorrowevening/theatre-shared/utils/assets';
|
|
14
|
-
import { notify } from './notify';
|
|
15
|
-
const DEFAULT_PERSISTENCE_KEY = 'theatre-0.4';
|
|
16
|
-
const STUDIO_NOT_INITIALIZED_MESSAGE = `You seem to have imported '@tomorrowevening/theatre-studio' but haven't initialized it. You can initialize the studio by:
|
|
17
|
-
\`\`\`
|
|
18
|
-
import studio from '@tomorrowevening/theatre-studio'
|
|
19
|
-
studio.initialize()
|
|
20
|
-
\`\`\`
|
|
21
|
-
|
|
22
|
-
* If you didn't mean to import '@tomorrowevening/theatre-studio', this means that your bundler is not tree-shaking it. This is most likely a bundler misconfiguration.
|
|
23
|
-
|
|
24
|
-
* If you meant to import '@tomorrowevening/theatre-studio' without showing its UI, you can do that by running:
|
|
25
|
-
|
|
26
|
-
\`\`\`
|
|
27
|
-
import studio from '@tomorrowevening/theatre-studio'
|
|
28
|
-
studio.initialize()
|
|
29
|
-
studio.ui.hide()
|
|
30
|
-
\`\`\`
|
|
31
|
-
`;
|
|
32
|
-
const STUDIO_INITIALIZED_LATE_MSG = `You seem to have imported '@tomorrowevening/theatre-studio' but called \`studio.initialize()\` after some delay.
|
|
33
|
-
Theatre.js projects remain in pending mode (won't play their sequences) until the studio is initialized, so you should place the \`studio.initialize()\` line right after the import line:
|
|
34
|
-
|
|
35
|
-
\`\`\`
|
|
36
|
-
import studio from '@tomorrowevening/theatre-studio'
|
|
37
|
-
// ... and other imports
|
|
38
|
-
|
|
39
|
-
studio.initialize()
|
|
40
|
-
\`\`\`
|
|
41
|
-
`;
|
|
42
|
-
export class Studio {
|
|
43
|
-
ui;
|
|
44
|
-
// this._uiInitDeferred.promise will resolve once this._ui is set
|
|
45
|
-
publicApi;
|
|
46
|
-
address;
|
|
47
|
-
_projectsProxy = new PointerProxy(new Atom({}).pointer);
|
|
48
|
-
projectsP = this._projectsProxy.pointer;
|
|
49
|
-
_store = new StudioStore();
|
|
50
|
-
_corePrivateApi;
|
|
51
|
-
_cache = new SimpleCache();
|
|
52
|
-
paneManager;
|
|
53
|
-
/**
|
|
54
|
-
* An atom holding the exports of '\@tomorrowevening/theatre-core'. Will be undefined if '\@tomorrowevening/theatre-core' is never imported
|
|
55
|
-
*/
|
|
56
|
-
_coreAtom = new Atom({});
|
|
57
|
-
/**
|
|
58
|
-
* A Deferred that will resolve once studio is initialized (and its state is read from storage)
|
|
59
|
-
*/
|
|
60
|
-
_initializedDeferred = defer();
|
|
61
|
-
/**
|
|
62
|
-
* Tracks whether studio.initialize() is called.
|
|
63
|
-
*/
|
|
64
|
-
_initializeFnCalled = false;
|
|
65
|
-
/**
|
|
66
|
-
* Will be set to true if studio.initialize() isn't called after 100ms.
|
|
67
|
-
*/
|
|
68
|
-
_didWarnAboutNotInitializing = false;
|
|
69
|
-
/**
|
|
70
|
-
* This will be set as soon as `@tomorrowevening/theatre-core` registers itself on `@tomorrowevening/theatre-studio`
|
|
71
|
-
*/
|
|
72
|
-
_coreBits;
|
|
73
|
-
get ticker() {
|
|
74
|
-
if (!this._rafDriver) {
|
|
75
|
-
throw new Error('`studio.ticker` was read before studio.initialize() was called.');
|
|
76
|
-
}
|
|
77
|
-
return this._rafDriver.ticker;
|
|
78
|
-
}
|
|
79
|
-
_rafDriver;
|
|
80
|
-
get atomP() {
|
|
81
|
-
return this._store.atomP;
|
|
82
|
-
}
|
|
83
|
-
constructor() {
|
|
84
|
-
this.address = { studioId: nanoid(10) };
|
|
85
|
-
this.publicApi = new TheatreStudio(this);
|
|
86
|
-
this.ui = new UI(this);
|
|
87
|
-
this._attachToIncomingProjects();
|
|
88
|
-
this.paneManager = new PaneManager(this);
|
|
89
|
-
// check whether studio.initialize() is called, but only if we're in the browser
|
|
90
|
-
if (typeof window !== 'undefined') {
|
|
91
|
-
setTimeout(() => {
|
|
92
|
-
if (!this._initializeFnCalled) {
|
|
93
|
-
console.error(STUDIO_NOT_INITIALIZED_MESSAGE);
|
|
94
|
-
this._didWarnAboutNotInitializing = true;
|
|
95
|
-
}
|
|
96
|
-
}, 100);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
async initialize(opts) {
|
|
100
|
-
if (!this._coreBits) {
|
|
101
|
-
throw new Error(`You seem to have imported \`@tomorrowevening/theatre-studio\` without importing \`@tomorrowevening/theatre-core\`. Make sure to include an import of \`@tomorrowevening/theatre-core\` before calling \`studio.initializer()\`.`);
|
|
102
|
-
}
|
|
103
|
-
if (this._initializeFnCalled) {
|
|
104
|
-
return this._initializedDeferred.promise;
|
|
105
|
-
}
|
|
106
|
-
this._initializeFnCalled = true;
|
|
107
|
-
if (this._didWarnAboutNotInitializing) {
|
|
108
|
-
console.warn(STUDIO_INITIALIZED_LATE_MSG);
|
|
109
|
-
}
|
|
110
|
-
const storeOpts = {
|
|
111
|
-
persistenceKey: DEFAULT_PERSISTENCE_KEY,
|
|
112
|
-
usePersistentStorage: true,
|
|
113
|
-
};
|
|
114
|
-
if (typeof opts?.persistenceKey === 'string') {
|
|
115
|
-
storeOpts.persistenceKey = opts.persistenceKey;
|
|
116
|
-
}
|
|
117
|
-
if (opts?.usePersistentStorage === false || typeof window === 'undefined') {
|
|
118
|
-
storeOpts.usePersistentStorage = false;
|
|
119
|
-
}
|
|
120
|
-
if (opts?.__experimental_rafDriver) {
|
|
121
|
-
if (opts.__experimental_rafDriver.type !== 'Theatre_RafDriver_PublicAPI') {
|
|
122
|
-
throw new Error('parameter `rafDriver` in `studio.initialize({__experimental_rafDriver})` must be either be undefined, or the return type of core.createRafDriver()');
|
|
123
|
-
}
|
|
124
|
-
const rafDriverPrivateApi = this._coreBits.privateAPI(opts.__experimental_rafDriver);
|
|
125
|
-
if (!rafDriverPrivateApi) {
|
|
126
|
-
// TODO - need to educate the user about this edge case
|
|
127
|
-
throw new Error('parameter `rafDriver` in `studio.initialize({__experimental_rafDriver})` seems to come from a different version of `@tomorrowevening/theatre-core` than the version that is attached to `@tomorrowevening/theatre-studio`');
|
|
128
|
-
}
|
|
129
|
-
this._rafDriver = rafDriverPrivateApi;
|
|
130
|
-
}
|
|
131
|
-
else {
|
|
132
|
-
this._rafDriver = this._coreBits.getCoreRafDriver();
|
|
133
|
-
}
|
|
134
|
-
try {
|
|
135
|
-
await this._store.initialize(storeOpts);
|
|
136
|
-
}
|
|
137
|
-
catch (e) {
|
|
138
|
-
this._initializedDeferred.reject(e);
|
|
139
|
-
return;
|
|
140
|
-
}
|
|
141
|
-
if (process.env.NODE_ENV !== 'test' && typeof window !== 'undefined') {
|
|
142
|
-
await this.ui.ready;
|
|
143
|
-
}
|
|
144
|
-
this._initializedDeferred.resolve();
|
|
145
|
-
if (process.env.NODE_ENV !== 'test') {
|
|
146
|
-
this.ui.render();
|
|
147
|
-
checkForUpdates().catch((err) => {
|
|
148
|
-
console.error(err);
|
|
149
|
-
});
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
get initialized() {
|
|
153
|
-
return this._initializedDeferred.promise;
|
|
154
|
-
}
|
|
155
|
-
_attachToIncomingProjects() {
|
|
156
|
-
const projectsD = pointerToPrism(this.projectsP);
|
|
157
|
-
const attachToProjects = (projects) => {
|
|
158
|
-
for (const project of Object.values(projects)) {
|
|
159
|
-
if (!project.isAttachedToStudio) {
|
|
160
|
-
project.attachToStudio(this);
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
};
|
|
164
|
-
projectsD.onStale(() => {
|
|
165
|
-
attachToProjects(projectsD.getValue());
|
|
166
|
-
});
|
|
167
|
-
attachToProjects(projectsD.getValue());
|
|
168
|
-
}
|
|
169
|
-
setCoreBits(coreBits) {
|
|
170
|
-
this._coreBits = coreBits;
|
|
171
|
-
this._corePrivateApi = coreBits.privateAPI;
|
|
172
|
-
this._coreAtom.setByPointer((p) => p.core, coreBits.coreExports);
|
|
173
|
-
this._setProjectsP(coreBits.projectsP);
|
|
174
|
-
}
|
|
175
|
-
_setProjectsP(projectsP) {
|
|
176
|
-
this._projectsProxy.setPointer(projectsP);
|
|
177
|
-
}
|
|
178
|
-
scrub() {
|
|
179
|
-
return new Scrub(this);
|
|
180
|
-
}
|
|
181
|
-
tempTransaction(fn) {
|
|
182
|
-
return this._store.tempTransaction(fn);
|
|
183
|
-
}
|
|
184
|
-
transaction(fn) {
|
|
185
|
-
return this.tempTransaction(fn).commit();
|
|
186
|
-
}
|
|
187
|
-
__dev_startHistoryFromScratch(newHistoricPart) {
|
|
188
|
-
return this._store.__dev_startHistoryFromScratch(newHistoricPart);
|
|
189
|
-
}
|
|
190
|
-
get corePrivateAPI() {
|
|
191
|
-
return this._corePrivateApi;
|
|
192
|
-
}
|
|
193
|
-
get core() {
|
|
194
|
-
return this._coreAtom.get().core;
|
|
195
|
-
}
|
|
196
|
-
get coreP() {
|
|
197
|
-
return this._coreAtom.pointer.core;
|
|
198
|
-
}
|
|
199
|
-
extend(extension, opts) {
|
|
200
|
-
if (!extension || typeof extension !== 'object') {
|
|
201
|
-
throw new Error(`Extensions must be JS objects`);
|
|
202
|
-
}
|
|
203
|
-
if (typeof extension.id !== 'string') {
|
|
204
|
-
throw new Error(`extension.id must be a string`);
|
|
205
|
-
}
|
|
206
|
-
const reconfigure = opts?.__experimental_reconfigure === true;
|
|
207
|
-
const extensionId = extension.id;
|
|
208
|
-
const prevExtension = this._store.getState().ephemeral.extensions.byId[extensionId];
|
|
209
|
-
if (prevExtension) {
|
|
210
|
-
if (reconfigure) {
|
|
211
|
-
}
|
|
212
|
-
else {
|
|
213
|
-
if (extension === prevExtension ||
|
|
214
|
-
shallowEqual(extension, prevExtension)) {
|
|
215
|
-
// probably running studio.extend() several times because of hot reload.
|
|
216
|
-
// as long as it's the same extension, we can safely ignore.
|
|
217
|
-
return;
|
|
218
|
-
}
|
|
219
|
-
throw new Error(`Extension id "${extension.id}" is already defined. If you mean to re-configure the extension, do it like this: studio.extend(extension, {__experimental_reconfigure: true})})`);
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
this.transaction(({ drafts }) => {
|
|
223
|
-
drafts.ephemeral.extensions.byId[extension.id] = extension;
|
|
224
|
-
const allPaneClasses = drafts.ephemeral.extensions.paneClasses;
|
|
225
|
-
if (reconfigure && prevExtension) {
|
|
226
|
-
// remove all pane classes that were set by the previous version of the extension
|
|
227
|
-
prevExtension.panes?.forEach((classDefinition) => {
|
|
228
|
-
delete allPaneClasses[classDefinition.class];
|
|
229
|
-
});
|
|
230
|
-
}
|
|
231
|
-
// if the extension defines pane classes, add them to the list of all pane classes
|
|
232
|
-
extension.panes?.forEach((classDefinition) => {
|
|
233
|
-
if (typeof classDefinition.class !== 'string') {
|
|
234
|
-
throw new Error(`pane.class must be a string`);
|
|
235
|
-
}
|
|
236
|
-
if (classDefinition.class.length < 3) {
|
|
237
|
-
throw new Error(`pane.class should be a string with 3 or more characters`);
|
|
238
|
-
}
|
|
239
|
-
const existing = allPaneClasses[classDefinition.class];
|
|
240
|
-
if (existing) {
|
|
241
|
-
if (reconfigure && existing.extensionId === extension.id) {
|
|
242
|
-
// well this should never happen because we already deleted the pane class above
|
|
243
|
-
console.warn(`Pane class "${classDefinition.class}" already exists. This is a bug in Theatre.js. Please report it at https://github.com/theatre-js/theatre/issues/new`);
|
|
244
|
-
}
|
|
245
|
-
else {
|
|
246
|
-
throw new Error(`Pane class "${classDefinition.class}" already exists and is supplied by extension ${existing}`);
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
allPaneClasses[classDefinition.class] = {
|
|
250
|
-
extensionId: extension.id,
|
|
251
|
-
classDefinition: classDefinition,
|
|
252
|
-
};
|
|
253
|
-
});
|
|
254
|
-
});
|
|
255
|
-
}
|
|
256
|
-
getStudioProject(core) {
|
|
257
|
-
return this._cache.get('getStudioProject', () => core.getProject('Studio'));
|
|
258
|
-
}
|
|
259
|
-
getExtensionSheet(extensionId, core) {
|
|
260
|
-
return this._cache.get('extensionSheet-' + extensionId, () => this.getStudioProject(core).sheet('Extension ' + extensionId));
|
|
261
|
-
}
|
|
262
|
-
undo() {
|
|
263
|
-
this._store.undo();
|
|
264
|
-
}
|
|
265
|
-
redo() {
|
|
266
|
-
this._store.redo();
|
|
267
|
-
}
|
|
268
|
-
createContentOfSaveFile(projectId) {
|
|
269
|
-
return this._store.createContentOfSaveFile(projectId);
|
|
270
|
-
}
|
|
271
|
-
/** A function that returns a promise to an object containing asset storage methods for a project to be used by studio. */
|
|
272
|
-
async createAssetStorage(project, baseUrl) {
|
|
273
|
-
// in SSR we bail out and return a dummy asset manager
|
|
274
|
-
if (typeof window === 'undefined') {
|
|
275
|
-
return {
|
|
276
|
-
getAssetUrl: () => '',
|
|
277
|
-
createAsset: () => Promise.resolve(null),
|
|
278
|
-
};
|
|
279
|
-
}
|
|
280
|
-
// Check for support.
|
|
281
|
-
if (!('indexedDB' in window)) {
|
|
282
|
-
if (process.env.NODE_ENV !== 'test')
|
|
283
|
-
console.log("This browser doesn't support IndexedDB.");
|
|
284
|
-
return {
|
|
285
|
-
getAssetUrl: (assetId) => {
|
|
286
|
-
throw new Error(`IndexedDB is required by the default asset manager, but it's not supported by this browser. To use assets, please provide your own asset manager to the project config.`);
|
|
287
|
-
},
|
|
288
|
-
createAsset: (asset) => {
|
|
289
|
-
throw new Error(`IndexedDB is required by the default asset manager, but it's not supported by this browser. To use assets, please provide your own asset manager to the project config.`);
|
|
290
|
-
},
|
|
291
|
-
};
|
|
292
|
-
}
|
|
293
|
-
const idb = createStore(`${project.address.projectId}-assets`);
|
|
294
|
-
// get all possible asset ids referenced by either static props or keyframes
|
|
295
|
-
const possibleAssetIDs = getAllPossibleAssetIDs(project);
|
|
296
|
-
// Clean up assets not referenced by the project. We can only do this at the start because otherwise
|
|
297
|
-
// we'd break undo/redo.
|
|
298
|
-
const idbKeys = await idb.keys();
|
|
299
|
-
await Promise.all(idbKeys.map(async (key) => {
|
|
300
|
-
if (!possibleAssetIDs.includes(key)) {
|
|
301
|
-
await idb.del(key);
|
|
302
|
-
}
|
|
303
|
-
}));
|
|
304
|
-
// Clean up idb entries exported to disk
|
|
305
|
-
await Promise.all(idbKeys.map(async (key) => {
|
|
306
|
-
const assetUrl = `${baseUrl}/${key}`;
|
|
307
|
-
try {
|
|
308
|
-
const response = await fetch(assetUrl, { method: 'HEAD' });
|
|
309
|
-
if (response.ok) {
|
|
310
|
-
await idb.del(key);
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
catch (e) {
|
|
314
|
-
notify.error('Failed to access assets', `Failed to access assets at ${project.config.assets?.baseUrl ?? '/'}. This is likely due to a CORS issue.`);
|
|
315
|
-
}
|
|
316
|
-
}));
|
|
317
|
-
// A map for caching the assets outside of the db. We also need this to be able to retrieve idb asset urls synchronously.
|
|
318
|
-
const assetsMap = new Map(await idb.entries());
|
|
319
|
-
// A map for caching the object urls created from idb assets.
|
|
320
|
-
const urlCache = new Map();
|
|
321
|
-
/** Gets idb aset url from asset blob */
|
|
322
|
-
const getUrlForAsset = (asset) => {
|
|
323
|
-
if (urlCache.has(asset)) {
|
|
324
|
-
return urlCache.get(asset);
|
|
325
|
-
}
|
|
326
|
-
else {
|
|
327
|
-
const url = URL.createObjectURL(asset);
|
|
328
|
-
urlCache.set(asset, url);
|
|
329
|
-
return url;
|
|
330
|
-
}
|
|
331
|
-
};
|
|
332
|
-
/** Gets idb asset url from id */
|
|
333
|
-
const getUrlForId = (assetId) => {
|
|
334
|
-
const asset = assetsMap.get(assetId);
|
|
335
|
-
if (!asset) {
|
|
336
|
-
throw new Error(`Asset with id ${assetId} not found`);
|
|
337
|
-
}
|
|
338
|
-
return getUrlForAsset(asset);
|
|
339
|
-
};
|
|
340
|
-
return {
|
|
341
|
-
getAssetUrl: (assetId) => {
|
|
342
|
-
return assetsMap.has(assetId)
|
|
343
|
-
? getUrlForId(assetId)
|
|
344
|
-
: `${baseUrl}/${assetId}`;
|
|
345
|
-
},
|
|
346
|
-
createAsset: async (asset) => {
|
|
347
|
-
const existingIDs = getAllPossibleAssetIDs(project);
|
|
348
|
-
let sameSame = false;
|
|
349
|
-
if (existingIDs.includes(asset.name)) {
|
|
350
|
-
let existingAsset;
|
|
351
|
-
try {
|
|
352
|
-
existingAsset =
|
|
353
|
-
assetsMap.get(asset.name) ??
|
|
354
|
-
(await fetch(`${baseUrl}/${asset.name}`).then((r) => r.ok ? r.blob() : undefined));
|
|
355
|
-
}
|
|
356
|
-
catch (e) {
|
|
357
|
-
notify.error('Failed to access assets', `Failed to access assets at ${project.config.assets?.baseUrl ?? '/'}. This is likely due to a CORS issue.`);
|
|
358
|
-
return Promise.resolve(null);
|
|
359
|
-
}
|
|
360
|
-
if (existingAsset) {
|
|
361
|
-
const blobCompare = (await import('blob-compare')).default;
|
|
362
|
-
// @ts-ignore
|
|
363
|
-
sameSame = await blobCompare.isEqual(asset, existingAsset);
|
|
364
|
-
// if same same, we do nothing
|
|
365
|
-
if (sameSame) {
|
|
366
|
-
return asset.name;
|
|
367
|
-
// if different, we ask the user to pls rename
|
|
368
|
-
}
|
|
369
|
-
else {
|
|
370
|
-
/** Initiates rename using a dialog. Returns a boolean indicating if the rename was succesful. */
|
|
371
|
-
const renameAsset = (text) => {
|
|
372
|
-
const newAssetName = prompt(text, asset.name);
|
|
373
|
-
if (newAssetName === null) {
|
|
374
|
-
// asset creation canceled
|
|
375
|
-
return false;
|
|
376
|
-
}
|
|
377
|
-
else if (newAssetName === '') {
|
|
378
|
-
return renameAsset('Asset name cannot be empty. Please choose a different file name for this asset.');
|
|
379
|
-
}
|
|
380
|
-
else if (existingIDs.includes(newAssetName)) {
|
|
381
|
-
console.log(existingIDs);
|
|
382
|
-
return renameAsset('An asset with this name already exists. Please choose a different file name for this asset.');
|
|
383
|
-
}
|
|
384
|
-
// rename asset
|
|
385
|
-
asset = new File([asset], newAssetName, { type: asset.type });
|
|
386
|
-
return true;
|
|
387
|
-
};
|
|
388
|
-
// rename asset returns false if the user cancels the rename
|
|
389
|
-
const success = renameAsset('An asset with this name already exists. Please choose a different file name for this asset.');
|
|
390
|
-
if (!success) {
|
|
391
|
-
return null;
|
|
392
|
-
}
|
|
393
|
-
}
|
|
394
|
-
}
|
|
395
|
-
}
|
|
396
|
-
assetsMap.set(asset.name, asset);
|
|
397
|
-
await idb.set(asset.name, asset);
|
|
398
|
-
return asset.name;
|
|
399
|
-
},
|
|
400
|
-
};
|
|
401
|
-
}
|
|
402
|
-
clearPersistentStorage(persistenceKey = DEFAULT_PERSISTENCE_KEY) {
|
|
403
|
-
this._store.__experimental_clearPersistentStorage(persistenceKey);
|
|
404
|
-
}
|
|
405
|
-
}
|