@dailies-studio/shot-editor 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/.vite/manifest.json +382 -0
- package/dist/assets/AgentPanel-CQejLbiX.js +2 -0
- package/dist/assets/AgentPanel-DJEphah0.css +1 -0
- package/dist/assets/AgentQuestionDialog-BqkD0kXF.js +1 -0
- package/dist/assets/CodeStudio-Dv4ihHpz.js +23 -0
- package/dist/assets/CommentsPanel-B4yhhT1T.js +1 -0
- package/dist/assets/ComponentLibraryRail-Ch_dsAru.js +1 -0
- package/dist/assets/ComponentStage-BRhRotyH.js +1 -0
- package/dist/assets/CurvePane-BjFVabKX.css +1 -0
- package/dist/assets/CurvePane-R22WzllJ.js +1 -0
- package/dist/assets/ExportDialog-CWLQWTmG.js +2 -0
- package/dist/assets/FontPicker-DWKaYL7F.js +1 -0
- package/dist/assets/FontPicker-v0IOIArM.css +1 -0
- package/dist/assets/GenerateDrawer-Bh3SqDKt.js +2 -0
- package/dist/assets/InsertDrawer-Ce1fod1L.js +1 -0
- package/dist/assets/LibraryBrowser-D9sEGz5w.js +2 -0
- package/dist/assets/MakeItYoursSection-CMO4319_.js +2 -0
- package/dist/assets/MaterialGraphCanvas-BFzl4wWR.js +23 -0
- package/dist/assets/MaterialGraphCanvas-BIUD59ik.css +1 -0
- package/dist/assets/MaterialWorkspace-CqTWqaRA.js +14 -0
- package/dist/assets/PreferencesDialog-CBf9_OoD.js +1 -0
- package/dist/assets/PresetsSection-CUEaoCVU.js +1 -0
- package/dist/assets/SoundHistory-BeS8EW1h.js +1 -0
- package/dist/assets/SoundMode-BmcZru3i.js +3 -0
- package/dist/assets/StockSounds-DdAUGRYK.js +1 -0
- package/dist/assets/TemplateFieldSection-CaeXpLFo.js +1 -0
- package/dist/assets/VersionHistoryPanel-CxG6XhNP.js +1 -0
- package/dist/assets/board-B88EPuLO.css +1 -0
- package/dist/assets/board-CL-he7SL.js +3 -0
- package/dist/assets/components-0oOSPN0l.js +1 -0
- package/dist/assets/googleFontRanges-gp32wJMo.js +1 -0
- package/dist/assets/googleFonts-BNon6M7X.js +1 -0
- package/dist/assets/iconsAndAliases-DL7gXP5j.js +1863 -0
- package/dist/assets/index-4F5NQmI8.css +1 -0
- package/dist/assets/index-BGHQGV5z.js +117 -0
- package/dist/assets/inter-cyrillic-ext-wght-normal-BOeWTOD4.woff2 +0 -0
- package/dist/assets/inter-cyrillic-wght-normal-DqGufNeO.woff2 +0 -0
- package/dist/assets/inter-greek-ext-wght-normal-DlzME5K_.woff2 +0 -0
- package/dist/assets/inter-greek-wght-normal-CkhJZR-_.woff2 +0 -0
- package/dist/assets/inter-latin-ext-wght-normal-DO1Apj_S.woff2 +0 -0
- package/dist/assets/inter-latin-wght-normal-Dx4kXJAl.woff2 +0 -0
- package/dist/assets/inter-vietnamese-wght-normal-CBcvBZtf.woff2 +0 -0
- package/dist/assets/libraryModel-CpIwfFha.js +1 -0
- package/dist/assets/lucide-6iK64tTB.js +9319 -0
- package/dist/assets/motionStamp-CH-Hew4E.js +1 -0
- package/dist/assets/takeMeasure-Tdg0TxEi.js +1 -0
- package/dist/assets/webmcp-BsB9gxWC.js +2 -0
- package/dist/index.html +34 -3
- package/package.json +12 -9
- package/src/addFamilies.ts +66 -0
- package/src/api.ts +1631 -55
- package/src/app/App.tsx +977 -198
- package/src/app/lazyPanel.tsx +137 -0
- package/src/app/lazySurfaces.tsx +203 -0
- package/src/audio/index.tsx +41 -10
- package/src/audio/meter.ts +485 -0
- package/src/audio/meterMath.ts +273 -0
- package/src/audio/meterStore.ts +155 -0
- package/src/audio/offlineMix.ts +289 -0
- package/src/audio/preview.ts +928 -118
- package/src/bridge.ts +15 -5
- package/src/bridgeTypes.ts +1611 -36
- package/src/channels.ts +17 -32
- package/src/fonts/googleFonts.ts +4 -0
- package/src/hostApi.ts +174 -0
- package/src/icons.tsx +770 -0
- package/src/layerWords.ts +61 -0
- package/src/main.tsx +56 -4
- package/src/panels/ResizeHandle.tsx +33 -43
- package/src/panels/agent/AgentDots.tsx +36 -0
- package/src/panels/agent/AgentPanel.tsx +119 -43
- package/src/panels/agent/AgentQuestionDialog.tsx +202 -0
- package/src/panels/agent/agent.css +113 -97
- package/src/panels/agent/agentGate.ts +35 -0
- package/src/panels/code/CodeDefaultsPanel.tsx +345 -0
- package/src/panels/code/CodeStudio.tsx +373 -0
- package/src/panels/code/FileTree.tsx +265 -0
- package/src/panels/code/codeBufferGuard.ts +52 -0
- package/src/panels/code/codeParts.tsx +321 -0
- package/src/panels/comments/CommentComposer.tsx +239 -0
- package/src/panels/comments/CommentThread.tsx +346 -0
- package/src/panels/comments/CommentsPanel.tsx +336 -0
- package/src/panels/comments/InboxButton.tsx +131 -0
- package/src/panels/comments/MentionMenu.tsx +98 -0
- package/src/panels/comments/parts.tsx +171 -0
- package/src/panels/export/ExportDialog.tsx +919 -96
- package/src/panels/export/ExportScrim.tsx +57 -0
- package/src/panels/files/AssetsTab.tsx +656 -0
- package/src/panels/files/FilePanel.tsx +1466 -216
- package/src/panels/files/LayerMarks.tsx +40 -0
- package/src/panels/files/LeftColumn.tsx +37 -0
- package/src/panels/files/McpSection.tsx +690 -47
- package/src/panels/files/MissingAssetsNotice.tsx +60 -0
- package/src/panels/files/assetDrag.ts +79 -0
- package/src/panels/files/resourceParts.tsx +255 -0
- package/src/panels/fonts/FontPicker.tsx +762 -0
- package/src/panels/fonts/faceCache.ts +207 -0
- package/src/panels/fonts/fontPicker.css +271 -0
- package/src/panels/fonts/pickerModel.ts +265 -0
- package/src/panels/fonts/pickerRequest.ts +46 -0
- package/src/panels/header/AccountAvatar.tsx +76 -0
- package/src/panels/header/AgentChip.tsx +77 -0
- package/src/panels/header/AppMenu.tsx +213 -0
- package/src/panels/header/Header.tsx +564 -84
- package/src/panels/header/HistoryControls.tsx +31 -5
- package/src/panels/header/PresenceStack.tsx +329 -0
- package/src/panels/header/ProjectTitle.tsx +232 -0
- package/src/panels/header/ShareButton.tsx +59 -0
- package/src/panels/header/StatusBadges.tsx +358 -27
- package/src/panels/header/SyncDeletedDialog.tsx +88 -0
- package/src/panels/header/ZoomControls.tsx +46 -15
- package/src/panels/header/agentHandoff.ts +52 -0
- package/src/panels/header/leave.ts +26 -0
- package/src/panels/help/HelpSection.tsx +189 -163
- package/src/panels/insert/InsertDrawer.tsx +723 -0
- package/src/panels/insert/iconSet.ts +109 -0
- package/src/panels/inspector/ExposeDot.tsx +117 -0
- package/src/panels/inspector/FramingRows.tsx +314 -44
- package/src/panels/inspector/InspectorFooter.tsx +91 -0
- package/src/panels/inspector/InspectorHead.tsx +425 -0
- package/src/panels/inspector/InspectorPanel.tsx +408 -124
- package/src/panels/inspector/KeyframeDot.tsx +373 -0
- package/src/panels/inspector/KeyframeSection.tsx +257 -0
- package/src/panels/inspector/MarkerSection.tsx +55 -11
- package/src/panels/inspector/ParamRow.tsx +84 -53
- package/src/panels/inspector/RightColumn.tsx +152 -0
- package/src/panels/inspector/TimeSection.tsx +866 -0
- package/src/panels/inspector/animate/EaseControl.tsx +244 -0
- package/src/panels/inspector/animate/PresetsSection.tsx +135 -0
- package/src/panels/inspector/animate/ShotSection.tsx +562 -48
- package/src/panels/inspector/design/AlignRow.tsx +95 -31
- package/src/panels/inspector/design/AppearanceSection.tsx +118 -9
- package/src/panels/inspector/design/ClonerSection.tsx +323 -62
- package/src/panels/inspector/design/ComponentSection.tsx +50 -43
- package/src/panels/inspector/design/CornerSection.tsx +45 -14
- package/src/panels/inspector/design/DefinitionProps.tsx +315 -0
- package/src/panels/inspector/design/DefinitionSection.tsx +136 -0
- package/src/panels/inspector/design/DeviceSection.tsx +210 -0
- package/src/panels/inspector/design/FillSection.tsx +83 -51
- package/src/panels/inspector/design/FontField.tsx +196 -0
- package/src/panels/inspector/design/HtmlSection.tsx +23 -12
- package/src/panels/inspector/design/InstanceSection.tsx +373 -154
- package/src/panels/inspector/design/MaskSection.tsx +84 -0
- package/src/panels/inspector/design/MaterialSection.tsx +177 -0
- package/src/panels/inspector/design/MediaSection.tsx +273 -120
- package/src/panels/inspector/design/MeshSection.tsx +910 -82
- package/src/panels/inspector/design/PaintRows.tsx +550 -0
- package/src/panels/inspector/design/PlateStyleSection.tsx +177 -0
- package/src/panels/inspector/design/ShadowSection.tsx +221 -48
- package/src/panels/inspector/design/SplineFollowSection.tsx +235 -0
- package/src/panels/inspector/design/StrokeSection.tsx +228 -43
- package/src/panels/inspector/design/TemplateFieldSection.tsx +57 -0
- package/src/panels/inspector/design/TransformSection.tsx +244 -50
- package/src/panels/inspector/design/TypographySection.tsx +679 -110
- package/src/panels/inspector/layout.ts +295 -0
- package/src/panels/inspector/propValue.ts +199 -0
- package/src/panels/inspector/scene/CameraSection.tsx +232 -22
- package/src/panels/inspector/scene/EffectsSection.tsx +722 -71
- package/src/panels/inspector/scene/MakeItYoursSection.tsx +180 -0
- package/src/panels/inspector/scene/SceneDocSection.tsx +191 -0
- package/src/panels/inspector/scene/SceneSection.tsx +219 -44
- package/src/panels/inspector/scene/TransitionSection.tsx +523 -72
- package/src/panels/inspector/storyboard/StoryboardReferenceSection.tsx +593 -0
- package/src/panels/inspector/storyboard/VideoStill.tsx +120 -0
- package/src/panels/inspector/timeModel.ts +190 -0
- package/src/panels/inspector/useDocWrite.ts +438 -146
- package/src/panels/library/LibraryBrowser.tsx +435 -0
- package/src/panels/library/LibraryGrid.tsx +190 -0
- package/src/panels/library/LibraryPreviewPanel.tsx +349 -0
- package/src/panels/library/LibraryRail.tsx +84 -0
- package/src/panels/library/LibrarySoundPanel.tsx +293 -0
- package/src/panels/library/SoundHistory.tsx +245 -0
- package/src/panels/library/StockSounds.tsx +390 -0
- package/src/panels/library/libraryModel.ts +147 -0
- package/src/panels/library/stockSearch.ts +77 -0
- package/src/panels/maskMarks.tsx +117 -0
- package/src/panels/material/MaterialCommentNode.tsx +54 -0
- package/src/panels/material/MaterialGraphCanvas.tsx +861 -0
- package/src/panels/material/MaterialGraphMenu.tsx +45 -0
- package/src/panels/material/MaterialGroupNode.tsx +56 -0
- package/src/panels/material/MaterialLibrary.tsx +253 -0
- package/src/panels/material/MaterialNode.tsx +453 -0
- package/src/panels/material/MaterialNodePalette.tsx +349 -0
- package/src/panels/material/MaterialParameterControls.tsx +525 -0
- package/src/panels/material/MaterialRerouteNode.tsx +42 -0
- package/src/panels/material/MaterialWorkspace.tsx +501 -0
- package/src/panels/material/NodePreview.tsx +70 -0
- package/src/panels/material/flowModel.ts +441 -0
- package/src/panels/material/parameterValues.ts +231 -0
- package/src/panels/material/previewScheduler.ts +235 -0
- package/src/panels/material/reactFlow.css +6 -0
- package/src/panels/material/socketGlyph.ts +85 -0
- package/src/panels/material/viewportMemory.ts +58 -0
- package/src/panels/preferences/PreferencesDialog.tsx +215 -0
- package/src/panels/share/ShareComponentDialog.tsx +247 -0
- package/src/panels/stage/StageMenu.tsx +35 -5
- package/src/panels/stage/StagePanel.tsx +338 -23
- package/src/panels/stage/cellSlots.tsx +70 -0
- package/src/panels/storyboard/BoardCanvas.tsx +739 -0
- package/src/panels/storyboard/BoardCursors.tsx +158 -0
- package/src/panels/storyboard/BoardDropDialog.tsx +161 -0
- package/src/panels/storyboard/BoardPlan.tsx +42 -0
- package/src/panels/storyboard/ComponentSheet.tsx +187 -0
- package/src/panels/storyboard/ComponentStage.tsx +235 -0
- package/src/panels/storyboard/MiniSketch.tsx +173 -0
- package/src/panels/storyboard/PartPicker.tsx +64 -0
- package/src/panels/storyboard/PlanPanel.tsx +617 -0
- package/src/panels/storyboard/ReferencePreview.tsx +217 -0
- package/src/panels/storyboard/ShotBrief.tsx +360 -0
- package/src/panels/storyboard/ShotCard.tsx +251 -0
- package/src/panels/storyboard/StagePreview.tsx +348 -0
- package/src/panels/storyboard/StillThumbs.tsx +162 -0
- package/src/panels/storyboard/StoryboardView.tsx +79 -0
- package/src/panels/storyboard/board.css +1065 -0
- package/src/panels/storyboard/board.ts +12 -0
- package/src/panels/storyboard/boardClipboard.ts +111 -0
- package/src/panels/storyboard/boardOrder.ts +68 -0
- package/src/panels/storyboard/boardRows.tsx +425 -0
- package/src/panels/storyboard/liveCap.ts +90 -0
- package/src/panels/storyboard/plan.css +295 -0
- package/src/panels/storyboard/posterCache.ts +133 -0
- package/src/panels/storyboard/shotboard/ComponentPicker.tsx +373 -0
- package/src/panels/storyboard/shotboard/ImagePicker.tsx +145 -0
- package/src/panels/storyboard/shotboard/ShotBoard.tsx +292 -0
- package/src/panels/storyboard/shotboard/SketchCanvas.tsx +443 -0
- package/src/panels/storyboard/shotboard/SketchInspector.tsx +471 -0
- package/src/panels/storyboard/shotboard/SketchItem.tsx +240 -0
- package/src/panels/storyboard/shotboard/SketchLayers.tsx +130 -0
- package/src/panels/storyboard/shotboard/SketchPlay.tsx +108 -0
- package/src/panels/storyboard/shotboard/SketchStrip.tsx +178 -0
- package/src/panels/storyboard/shotboard/SketchToolFooter.tsx +99 -0
- package/src/panels/storyboard/shotboard/sketch.css +1392 -0
- package/src/panels/storyboard/shotboard/sketchModel.ts +219 -0
- package/src/panels/storyboard/storyboardDrop.ts +164 -0
- package/src/panels/studio/ComponentLibraryRail.tsx +346 -0
- package/src/panels/studio/ComponentSidePanel.tsx +355 -0
- package/src/panels/studio/ComponentStudio.tsx +243 -0
- package/src/panels/studio/ComponentsHome.tsx +318 -0
- package/src/panels/studio/ComponentsPreview.tsx +179 -0
- package/src/panels/studio/EveryUse.tsx +244 -0
- package/src/panels/studio/ThisUsePanel.tsx +679 -0
- package/src/panels/studio/componentParts.tsx +341 -0
- package/src/panels/studio/components.ts +6 -0
- package/src/panels/studio/newCodeComponent.ts +66 -0
- package/src/panels/timeline/AudioFxButton.tsx +290 -0
- package/src/panels/timeline/AudioLane.tsx +674 -85
- package/src/panels/timeline/BlockRow.tsx +154 -85
- package/src/panels/timeline/ChannelRow.tsx +378 -129
- package/src/panels/timeline/CurvePane.tsx +508 -0
- package/src/panels/timeline/Filmstrip.tsx +361 -0
- package/src/panels/timeline/GenerateDrawer.tsx +407 -0
- package/src/panels/timeline/KeyStretch.tsx +115 -0
- package/src/panels/timeline/LifespanRow.tsx +730 -47
- package/src/panels/timeline/MarkerLane.tsx +46 -8
- package/src/panels/timeline/PlayButton.tsx +91 -0
- package/src/panels/timeline/PropertyPicker.tsx +254 -0
- package/src/panels/timeline/ShotRow.tsx +400 -0
- package/src/panels/timeline/SoundMode.tsx +1406 -0
- package/src/panels/timeline/TimelineDock.tsx +2338 -272
- package/src/panels/timeline/TransportVolume.tsx +163 -0
- package/src/panels/timeline/beatRuler.ts +74 -0
- package/src/panels/timeline/curveModel.ts +500 -0
- package/src/panels/timeline/duckUnderVoice.ts +68 -0
- package/src/panels/timeline/keyframeMenu.ts +138 -0
- package/src/panels/timeline/labelWidth.ts +49 -0
- package/src/panels/timeline/marquee.ts +155 -0
- package/src/panels/timeline/model.ts +1860 -199
- package/src/panels/timeline/snap.ts +125 -43
- package/src/panels/timeline/staggerPreview.tsx +92 -0
- package/src/panels/timeline/takeMeasure.ts +72 -0
- package/src/panels/timeline/useLive.ts +48 -0
- package/src/panels/timeline/viewport.ts +234 -0
- package/src/panels/toolbar/BackChip.tsx +116 -0
- package/src/panels/toolbar/CameraViewBar.tsx +118 -49
- package/src/panels/toolbar/CanvasBar.tsx +117 -0
- package/src/panels/toolbar/InsertButton.tsx +38 -0
- package/src/panels/toolbar/IsolationTrail.tsx +156 -0
- package/src/panels/toolbar/PanelToggles.tsx +86 -0
- package/src/panels/toolbar/ShadingBar.tsx +119 -26
- package/src/panels/toolbar/ToolDockBar.tsx +329 -80
- package/src/panels/toolbar/ToolFooter.tsx +102 -0
- package/src/panels/toolbar/ViewModeBar.tsx +247 -38
- package/src/panels/toolbar/WorkPlaneBar.tsx +94 -0
- package/src/panels/toolbar/useAddRows.tsx +326 -0
- package/src/panels/toolbar/useDismiss.ts +122 -0
- package/src/panels/versions/VersionHistoryPanel.tsx +274 -0
- package/src/panels/versions/versionModel.ts +103 -0
- package/src/panels/virtualWindow.ts +271 -0
- package/src/shotTokens.css +151 -60
- package/src/stage/FrustumGizmo.tsx +504 -84
- package/src/stage/GridPlane.tsx +225 -16
- package/src/stage/NodePreviews.tsx +628 -0
- package/src/stage/PerfHud.tsx +437 -47
- package/src/stage/SplitRenderer.tsx +816 -169
- package/src/stage/StageApp.tsx +4274 -486
- package/src/stage/StageRootBoundary.tsx +114 -0
- package/src/stage/StageTools.tsx +651 -151
- package/src/stage/TransformGizmo.tsx +696 -0
- package/src/stage/adaptivePresentation.ts +145 -0
- package/src/stage/bridgeClient.ts +2522 -41
- package/src/stage/exportWorker.ts +9 -0
- package/src/stage/feed.ts +305 -14
- package/src/stage/fontPreview.ts +176 -0
- package/src/stage/frustumGeometry.ts +319 -1
- package/src/stage/furnitureTokens.ts +33 -0
- package/src/stage/gizmoMath.ts +508 -16
- package/src/stage/gpuTimer.ts +276 -0
- package/src/stage/instanceModules.ts +194 -33
- package/src/stage/interactions/move.ts +24 -5
- package/src/stage/isolation.ts +291 -33
- package/src/stage/jsSelfProfiler.ts +325 -0
- package/src/stage/main.tsx +116 -16
- package/src/stage/modalState.ts +222 -23
- package/src/stage/moduleEpoch.ts +60 -0
- package/src/stage/motionPathStage.ts +279 -0
- package/src/stage/motionPreview.ts +74 -0
- package/src/stage/overlays/Overlays.tsx +1112 -159
- package/src/stage/overlays/Rulers.tsx +495 -0
- package/src/stage/panes.ts +159 -10
- package/src/stage/project.ts +68 -3
- package/src/stage/renderScaleController.ts +730 -0
- package/src/stage/rulers.ts +129 -0
- package/src/stage/sceneExtent.ts +75 -0
- package/src/stage/shading.ts +20 -0
- package/src/stage/splineStage.ts +632 -0
- package/src/stage/stagePerformanceTelemetry.ts +717 -0
- package/src/stage/stageTheme.ts +36 -0
- package/src/stage/stageWarmup.ts +11 -0
- package/src/stage/textAutoSize.ts +124 -0
- package/src/stage/tier1Export.ts +641 -0
- package/src/stage/tokenColor.ts +14 -9
- package/src/stage/view.ts +56 -9
- package/src/stage/workingView.ts +277 -33
- package/src/state/accountPrefs.ts +261 -0
- package/src/state/agentActions.ts +173 -15
- package/src/state/agentActivity.ts +198 -0
- package/src/state/agentQuestion.ts +239 -0
- package/src/state/bootOpen.ts +42 -0
- package/src/state/cameraVerbs.ts +139 -0
- package/src/state/clientId.ts +6 -1
- package/src/state/comments.ts +1099 -0
- package/src/state/context.tsx +19 -1
- package/src/state/editorPrefs.ts +220 -0
- package/src/state/errorReports.ts +121 -0
- package/src/state/fieldWrite.ts +161 -0
- package/src/state/fontRecents.ts +70 -0
- package/src/state/fonts.ts +656 -0
- package/src/state/graphClipboard.ts +414 -0
- package/src/state/imageThumbs.ts +216 -0
- package/src/state/insert.ts +444 -67
- package/src/state/isolationTrail.ts +92 -0
- package/src/state/keyMoves.ts +134 -0
- package/src/state/keyframeClipboard.ts +177 -0
- package/src/state/keymap.ts +1153 -117
- package/src/state/layoutPrefs.ts +272 -0
- package/src/state/layouts.ts +205 -0
- package/src/state/measureMedia.ts +167 -0
- package/src/state/menu.ts +2341 -28
- package/src/state/motionStamp.ts +7 -0
- package/src/state/panelSize.ts +375 -5
- package/src/state/pendingChanges.ts +119 -0
- package/src/state/playHold.ts +78 -0
- package/src/state/playbackPreparation.ts +562 -0
- package/src/state/posterCapture.ts +242 -0
- package/src/state/presence.ts +254 -0
- package/src/state/projectComponents.ts +160 -0
- package/src/state/renderEvents.ts +298 -18
- package/src/state/runtimeErrors.ts +46 -0
- package/src/state/selection.ts +12 -0
- package/src/state/shortcuts.ts +1606 -0
- package/src/state/sketchGuide.ts +51 -0
- package/src/state/splineRefs.ts +87 -0
- package/src/state/stageHealth.ts +259 -0
- package/src/state/stageWatchdog.ts +47 -0
- package/src/state/stillStage.ts +330 -0
- package/src/state/stillThumbs.ts +474 -0
- package/src/state/store.ts +23591 -2982
- package/src/state/storyboardModel.ts +528 -0
- package/src/state/sync.ts +1257 -0
- package/src/state/syncCache.ts +159 -0
- package/src/state/triangles.ts +13 -0
- package/src/state/types.ts +1698 -55
- package/src/state/unsavedGuard.ts +49 -0
- package/src/state/viewMode.ts +200 -0
- package/src/state/webmcp.ts +1128 -0
- package/src/state/workspace.ts +1147 -0
- package/src/styles/assets-tab.css +304 -0
- package/src/styles/canvas.css +545 -0
- package/src/styles/comments.css +1435 -0
- package/src/styles/controls.css +162 -0
- package/src/styles/dialogs.css +390 -0
- package/src/styles/insert-drawer.css +586 -0
- package/src/styles/inspector-board.css +207 -0
- package/src/styles/inspector-object.css +486 -0
- package/src/styles/inspector-shot.css +252 -0
- package/src/styles/inspector.css +360 -0
- package/src/styles/left-column.css +1628 -0
- package/src/styles/library-preview.css +575 -0
- package/src/styles/library.css +512 -0
- package/src/styles/modes/code.css +569 -0
- package/src/styles/modes/component.css +1561 -0
- package/src/styles/modes/material.css +1201 -0
- package/src/styles/modes/storyboard.css +518 -0
- package/src/styles/share-component.css +49 -0
- package/src/styles/shell.css +653 -0
- package/src/styles/shot-brief.css +360 -0
- package/src/styles/states.css +76 -0
- package/src/styles/sync.css +380 -0
- package/src/styles/timeline-graph.css +384 -0
- package/src/styles/timeline-meters.css +89 -0
- package/src/styles/timeline-rows.css +1959 -0
- package/src/styles/timeline-sound.css +1003 -0
- package/src/styles/timeline.css +754 -0
- package/src/styles/tool-footer.css +525 -0
- package/src/styles/topbar.css +886 -0
- package/src/styles/versions.css +262 -0
- package/src/styles.css +72 -2921
- package/src/tools.ts +108 -23
- package/dist/assets/index-B7notge7.css +0 -1
- package/dist/assets/index-BBE6Ta9L.js +0 -52
- package/src/panels/files/icons.tsx +0 -118
- package/src/panels/header/DocSwitcher.tsx +0 -85
- package/src/panels/header/TransportBar.tsx +0 -86
- package/src/panels/inspector/animate/BlockTiming.tsx +0 -341
- package/src/panels/inspector/animate/DuringBlocks.tsx +0 -85
- package/src/panels/inspector/animate/InOutPresets.tsx +0 -57
- package/src/panels/inspector/animate/ResolvedChannels.tsx +0 -150
- package/src/panels/inspector/animate/useBlocks.ts +0 -43
- package/src/panels/material/MaterialPicker.tsx +0 -172
- package/src/panels/timeline/SceneStrip.tsx +0 -145
- package/src/panels/toolbar/AddMenu.tsx +0 -230
- package/src/stage/MoveGizmo.tsx +0 -411
|
@@ -15,17 +15,41 @@
|
|
|
15
15
|
// "the document moved underneath me", and only one of them would have that
|
|
16
16
|
// refusal in it.
|
|
17
17
|
//
|
|
18
|
-
// EventSource reconnects on its own
|
|
19
|
-
//
|
|
20
|
-
//
|
|
21
|
-
//
|
|
22
|
-
//
|
|
18
|
+
// EventSource reconnects on its own. For the document a dropped frame is safe:
|
|
19
|
+
// `doc-changed` is a NOTIFICATION and `adoptExternalChange` re-reads from the
|
|
20
|
+
// server, so it costs a stale view until the next write, which the baseRev 409
|
|
21
|
+
// protocol already makes safe. For a render it was NOT: a dropped "done" or
|
|
22
|
+
// "failed" left the export lock held and the dialog on "Rendering" forever, and
|
|
23
|
+
// a server restart dropped the job itself. So every `hello` (the first frame of
|
|
24
|
+
// every connection, reconnects included) re-reads the render state; see
|
|
25
|
+
// `reconcileRender`.
|
|
26
|
+
import { renderState } from "../api.js";
|
|
27
|
+
import type { RenderJob, RenderState } from "../api.js";
|
|
28
|
+
import type { StageHealthRequest } from "@dailies-studio/shot/doc";
|
|
29
|
+
import { dailiesHost } from "../hostApi.js";
|
|
30
|
+
import { CLIENT_ID, CLIENT_ID_HEADER } from "./clientId.js";
|
|
31
|
+
import { setRuntimeErrorRevision } from "./runtimeErrors.js";
|
|
32
|
+
import { awaitStageHealth } from "./stageHealth.js";
|
|
23
33
|
import type { ShotEditorStore } from "./store.js";
|
|
24
|
-
import
|
|
34
|
+
import { buffersOpen } from "./types.js";
|
|
35
|
+
import { parseAgentActivity } from "./agentActivity.js";
|
|
25
36
|
|
|
26
37
|
/** The SSE event names; `docEvents.ts` is the other half of this contract. */
|
|
27
38
|
const EVENT = "shot-render";
|
|
28
39
|
const DOC_EVENT = "doc-changed";
|
|
40
|
+
const CONTRACT_EVENT = "contract-changed";
|
|
41
|
+
const FILES_EVENT = "files-changed";
|
|
42
|
+
const RELAY_EVENT = "relay-request";
|
|
43
|
+
/** Comment events (plan C4): `{v:1, projectId, threadId, stillId}` and
|
|
44
|
+
* `{v:1}`. Signals only: the comments store refetches. */
|
|
45
|
+
const COMMENTS_EVENT = "comments-changed";
|
|
46
|
+
const INBOX_EVENT = "inbox-changed";
|
|
47
|
+
/** An MCP agent's tool call started or ended (store mcpActivity.ts). */
|
|
48
|
+
const AGENT_EVENT = "agent-activity";
|
|
49
|
+
/** An agent's question to the person moved: `{v:1, project, id, status}`. */
|
|
50
|
+
const QUESTION_EVENT = "agent-question";
|
|
51
|
+
/** A project file's bytes changed: `{v:1, path, hash}`. */
|
|
52
|
+
const SOURCE_EVENT = "source-changed";
|
|
29
53
|
|
|
30
54
|
/**
|
|
31
55
|
* Subscribe until the returned function is called.
|
|
@@ -35,47 +59,303 @@ const DOC_EVENT = "doc-changed";
|
|
|
35
59
|
* chrome from booting.
|
|
36
60
|
*/
|
|
37
61
|
export function subscribeStudioEvents(store: ShotEditorStore): () => void {
|
|
62
|
+
// ── WHAT THE STAGE MADE OF A WRITE, FOR AN AGENT ─────────────────────
|
|
63
|
+
//
|
|
64
|
+
// An MCP write waits for an editor tab's stage to draw it and reports what
|
|
65
|
+
// the stage holds (state/stageHealth.ts). Hosted, the code host answers the
|
|
66
|
+
// workspace's relayed question and asks this chrome through the host seam.
|
|
67
|
+
// Locally there is no code host: this chrome's feed names it and asks for
|
|
68
|
+
// the dev server's one relayed question, `stage`, which it answers itself.
|
|
69
|
+
const host = dailiesHost();
|
|
70
|
+
setRuntimeErrorRevision(() => {
|
|
71
|
+
const now = store.getState();
|
|
72
|
+
return now.dirty ? null : now.rev;
|
|
73
|
+
});
|
|
74
|
+
host?.provideStageHealth((request) => awaitStageHealth(store, request));
|
|
75
|
+
// ── COMMENTS COME BACK ON FOCUS ─────────────────────────────────────────
|
|
76
|
+
//
|
|
77
|
+
// A hidden tab's EventSource may be throttled or dropped, and an access
|
|
78
|
+
// change made in the dashboard tab (Share and mention) sends no comment
|
|
79
|
+
// event. So a tab that comes back to the front re-reads both.
|
|
80
|
+
const refetchComments = (): void => {
|
|
81
|
+
if (typeof document !== "undefined" && document.visibilityState === "hidden") return;
|
|
82
|
+
void store.comments.refresh();
|
|
83
|
+
void store.comments.loadInbox();
|
|
84
|
+
};
|
|
85
|
+
const win = typeof window === "undefined" ? undefined : window;
|
|
86
|
+
win?.addEventListener("focus", refetchComments);
|
|
87
|
+
win?.document.addEventListener("visibilitychange", refetchComments);
|
|
88
|
+
const unlistenFocus = (): void => {
|
|
89
|
+
win?.removeEventListener("focus", refetchComments);
|
|
90
|
+
win?.document.removeEventListener("visibilitychange", refetchComments);
|
|
91
|
+
};
|
|
38
92
|
const Source = (globalThis as { EventSource?: typeof EventSource }).EventSource;
|
|
39
|
-
if (Source === undefined) return
|
|
40
|
-
const source = new Source("/api/events");
|
|
93
|
+
if (Source === undefined) return unlistenFocus;
|
|
94
|
+
const source = new Source(host === undefined ? `/api/events?client=${encodeURIComponent(CLIENT_ID)}&relay=1` : "/api/events");
|
|
41
95
|
const onMessage = (e: MessageEvent<string>): void => {
|
|
42
96
|
const job = parseJob(e.data);
|
|
43
97
|
// Only THIS document's renders. The bus is project-wide and a second chrome
|
|
44
98
|
// may be exporting something else; showing its progress here would be a
|
|
45
|
-
// progress bar for a file this window is not making.
|
|
46
|
-
|
|
99
|
+
// progress bar for a file this window is not making. The job this window
|
|
100
|
+
// already holds is followed to its end even after it opened another shot:
|
|
101
|
+
// that job holds the export lock, and dropping its "done" held it for good.
|
|
102
|
+
if (job === null) return;
|
|
103
|
+
const now = store.getState();
|
|
104
|
+
if (job.name === now.name || job.id === now.renderJob?.id) store.setRenderJob(job);
|
|
47
105
|
};
|
|
48
106
|
const onDoc = (e: MessageEvent<string>): void => {
|
|
49
107
|
const payload = parseDocChange(e.data);
|
|
50
|
-
|
|
51
|
-
//
|
|
52
|
-
//
|
|
53
|
-
|
|
108
|
+
if (payload === null) return;
|
|
109
|
+
// The SHOT lane only. The bus carries other lanes' writes too, and handing
|
|
110
|
+
// one of those to a shot store would ask it to reload a document that is
|
|
111
|
+
// not in its store at all.
|
|
112
|
+
if (payload.lane === "shot") store.adoptExternalChange(payload);
|
|
113
|
+
};
|
|
114
|
+
// ── A COMPONENT'S SOURCE CHANGED ON DISK ────────────────────────────────
|
|
115
|
+
//
|
|
116
|
+
// The watcher re-extracts the contract and tells Vite, which reloads the
|
|
117
|
+
// stage. That covers the PICTURE. It never covered the chrome: the drift
|
|
118
|
+
// badge, the props panel and the open source buffer all stayed on what they
|
|
119
|
+
// had, so an edit made from outside this window — a second editor, or an
|
|
120
|
+
// agent through MCP — was invisible here until something happened to refetch.
|
|
121
|
+
const onContract = (e: MessageEvent<string>): void => {
|
|
122
|
+
const componentId = parseContractChange(e.data);
|
|
123
|
+
if (componentId === null) return;
|
|
124
|
+
store.adoptContractChange(componentId);
|
|
125
|
+
};
|
|
126
|
+
// ── A FILE APPEARED OR VANISHED ─────────────────────────────────────────
|
|
127
|
+
//
|
|
128
|
+
// The payload names nothing on purpose, so there is nothing to parse and
|
|
129
|
+
// nothing to get wrong: re-list and take the server's answer. Only while code
|
|
130
|
+
// buffers are open (Code Studio): a chrome editing a
|
|
131
|
+
// shot has no reason to fetch a file listing every time a build writes.
|
|
132
|
+
const onFiles = (): void => {
|
|
133
|
+
if (buffersOpen(store.getState())) void store.refreshProjectFiles();
|
|
134
|
+
};
|
|
135
|
+
const onComments = (e: MessageEvent<string>): void => {
|
|
136
|
+
store.comments.changed(parseJson(e.data) ?? {});
|
|
137
|
+
};
|
|
138
|
+
const onInbox = (): void => {
|
|
139
|
+
void store.comments.loadInbox();
|
|
140
|
+
};
|
|
141
|
+
const onAgent = (e: MessageEvent<string>): void => {
|
|
142
|
+
const event = parseAgentActivity(e.data);
|
|
143
|
+
if (event !== null) store.agentActivity.receive(event);
|
|
144
|
+
};
|
|
145
|
+
// The open Project's question only: re-read it, which opens the dialog for
|
|
146
|
+
// a new one and closes it for one answered elsewhere.
|
|
147
|
+
const onQuestion = (e: MessageEvent<string>): void => {
|
|
148
|
+
const name = store.getState().name;
|
|
149
|
+
if (name !== null && parseJson(e.data)?.["project"] === name) void store.agentQuestion.load(name);
|
|
150
|
+
};
|
|
151
|
+
// ── FOLLOWING AN AGENT'S WRITES ─────────────────────────────────────────
|
|
152
|
+
//
|
|
153
|
+
// `contract-changed` fires only when a contract moves, so a body-only write
|
|
154
|
+
// left an open buffer on the old text until its save 409'd. Each write now
|
|
155
|
+
// reaches the buffer holding that file, which is what Code Studio's follow
|
|
156
|
+
// mode shows.
|
|
157
|
+
const onSource = (e: MessageEvent<string>): void => {
|
|
158
|
+
const change = parseJson(e.data);
|
|
159
|
+
const path = change?.["path"];
|
|
160
|
+
const hash = change?.["hash"];
|
|
161
|
+
if (typeof path !== "string" || (hash !== null && typeof hash !== "string")) return;
|
|
162
|
+
void store.adoptSourceChange(path, hash);
|
|
163
|
+
};
|
|
164
|
+
const onHello = (): void => {
|
|
165
|
+
// A reconnect may have dropped comment events: read both again.
|
|
166
|
+
refetchComments();
|
|
167
|
+
const name = store.getState().name;
|
|
168
|
+
if (name === null) return;
|
|
169
|
+
// And the question: an ask sent while the feed was down is still open.
|
|
170
|
+
void store.agentQuestion.load(name);
|
|
171
|
+
const asked = store.getState().renderJob;
|
|
172
|
+
void renderState(name)
|
|
173
|
+
.then((state) => reconcileRender(store, name, state, asked))
|
|
174
|
+
.catch(() => {
|
|
175
|
+
// A server without the render lane, or one mid-restart: the next
|
|
176
|
+
// hello asks again.
|
|
177
|
+
});
|
|
178
|
+
};
|
|
179
|
+
const onRelay = (e: MessageEvent<string>): void => {
|
|
180
|
+
const ask = parseStageAsk(e.data);
|
|
181
|
+
if (ask === null) return;
|
|
182
|
+
const answer = (outcome: { ok: true; result: unknown } | { ok: false; error: string }): void => {
|
|
183
|
+
void fetch(`/api/relay/${encodeURIComponent(ask.id)}/result`, {
|
|
184
|
+
method: "POST",
|
|
185
|
+
headers: { "content-type": "application/json", [CLIENT_ID_HEADER]: CLIENT_ID },
|
|
186
|
+
body: JSON.stringify(outcome),
|
|
187
|
+
}).catch(() => {
|
|
188
|
+
// The dev server times the question out and says so.
|
|
189
|
+
});
|
|
190
|
+
};
|
|
191
|
+
if (ask.tool !== "stage") {
|
|
192
|
+
answer({ ok: false, error: `this editor answers "stage", not ${JSON.stringify(ask.tool)}: reload it, which picks up the newer build` });
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
void awaitStageHealth(store, ask.input).then(
|
|
196
|
+
(report) => answer({ ok: true, result: report }),
|
|
197
|
+
(error: unknown) => answer({ ok: false, error: error instanceof Error ? error.message : String(error) }),
|
|
198
|
+
);
|
|
54
199
|
};
|
|
200
|
+
source.addEventListener("hello", onHello);
|
|
55
201
|
source.addEventListener(EVENT, onMessage as EventListener);
|
|
56
202
|
source.addEventListener(DOC_EVENT, onDoc as EventListener);
|
|
203
|
+
source.addEventListener(CONTRACT_EVENT, onContract as EventListener);
|
|
204
|
+
source.addEventListener(FILES_EVENT, onFiles);
|
|
205
|
+
if (host === undefined) source.addEventListener(RELAY_EVENT, onRelay as EventListener);
|
|
206
|
+
source.addEventListener(COMMENTS_EVENT, onComments as EventListener);
|
|
207
|
+
source.addEventListener(INBOX_EVENT, onInbox);
|
|
208
|
+
source.addEventListener(AGENT_EVENT, onAgent as EventListener);
|
|
209
|
+
source.addEventListener(SOURCE_EVENT, onSource as EventListener);
|
|
210
|
+
source.addEventListener(QUESTION_EVENT, onQuestion as EventListener);
|
|
57
211
|
return () => {
|
|
212
|
+
source.removeEventListener(QUESTION_EVENT, onQuestion as EventListener);
|
|
213
|
+
source.removeEventListener(AGENT_EVENT, onAgent as EventListener);
|
|
214
|
+
source.removeEventListener(SOURCE_EVENT, onSource as EventListener);
|
|
215
|
+
unlistenFocus();
|
|
216
|
+
source.removeEventListener(COMMENTS_EVENT, onComments as EventListener);
|
|
217
|
+
source.removeEventListener(INBOX_EVENT, onInbox);
|
|
218
|
+
source.removeEventListener("hello", onHello);
|
|
58
219
|
source.removeEventListener(EVENT, onMessage as EventListener);
|
|
59
220
|
source.removeEventListener(DOC_EVENT, onDoc as EventListener);
|
|
221
|
+
source.removeEventListener(CONTRACT_EVENT, onContract as EventListener);
|
|
222
|
+
source.removeEventListener(FILES_EVENT, onFiles);
|
|
223
|
+
source.removeEventListener(RELAY_EVENT, onRelay as EventListener);
|
|
60
224
|
source.close();
|
|
61
225
|
};
|
|
62
226
|
}
|
|
63
227
|
|
|
228
|
+
/** The render reason a job the server no longer knows gets. */
|
|
229
|
+
export const RENDER_LOST =
|
|
230
|
+
"the studio server lost track of this render (it restarted, or its progress stopped reaching " +
|
|
231
|
+
"this window); check the output folder, or export again";
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Adopt what the server says about THIS shot's render after a (re)connect.
|
|
235
|
+
*
|
|
236
|
+
* The live job wins, then the newest finished one, so a chrome that reloaded
|
|
237
|
+
* still shows the last result. A job this window thinks is running that the
|
|
238
|
+
* server has never heard of ended with the old server, and it is closed as
|
|
239
|
+
* failed rather than holding the export lock forever.
|
|
240
|
+
*
|
|
241
|
+
* `asked` is the job this window held when the read was sent. If that changed
|
|
242
|
+
* while the read was in flight (an Export click, a bus frame), the answer is
|
|
243
|
+
* older than what the window knows and is dropped: applying it could close a
|
|
244
|
+
* render that had just started.
|
|
245
|
+
*/
|
|
246
|
+
export function reconcileRender(
|
|
247
|
+
store: ShotEditorStore,
|
|
248
|
+
name: string,
|
|
249
|
+
state: RenderState,
|
|
250
|
+
asked: RenderJob | null,
|
|
251
|
+
): void {
|
|
252
|
+
const now = store.getState();
|
|
253
|
+
if (now.name !== name || now.renderJob !== asked) return;
|
|
254
|
+
const newest = state.job ?? state.recent.at(-1) ?? null;
|
|
255
|
+
if (newest !== null) {
|
|
256
|
+
store.setRenderJob(newest);
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
// A job of ANOTHER shot (the author switched, renamed or duplicated while
|
|
260
|
+
// it ran). The route reports only this shot's renders, so its silence says
|
|
261
|
+
// nothing about that job: it is dropped from this window, never declared
|
|
262
|
+
// lost while the server may still be rendering it.
|
|
263
|
+
if (asked !== null && asked.name !== name) {
|
|
264
|
+
store.setRenderJob(null);
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
if (asked !== null && asked.phase === "running") {
|
|
268
|
+
store.setRenderJob({ ...asked, phase: "failed", error: RENDER_LOST });
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/** A relayed question the dev server asks this chrome (`relay-request`,
|
|
273
|
+
* `{v, id, tool, input}`): only `stage` is asked locally. */
|
|
274
|
+
function parseStageAsk(raw: string): { id: string; tool: string; input: StageHealthRequest } | null {
|
|
275
|
+
try {
|
|
276
|
+
const data: unknown = JSON.parse(raw);
|
|
277
|
+
if (data === null || typeof data !== "object") return null;
|
|
278
|
+
const p = data as { id?: unknown; tool?: unknown; input?: unknown };
|
|
279
|
+
if (typeof p.id !== "string" || typeof p.tool !== "string") return null;
|
|
280
|
+
const i = (typeof p.input === "object" && p.input !== null ? p.input : {}) as Record<string, unknown>;
|
|
281
|
+
const code = (typeof i["code"] === "object" && i["code"] !== null ? i["code"] : null) as Record<string, unknown> | null;
|
|
282
|
+
return {
|
|
283
|
+
id: p.id,
|
|
284
|
+
tool: p.tool,
|
|
285
|
+
input: {
|
|
286
|
+
...(typeof i["name"] === "string" ? { name: i["name"] } : {}),
|
|
287
|
+
...(typeof i["rev"] === "string" ? { rev: i["rev"] } : {}),
|
|
288
|
+
...(code === null
|
|
289
|
+
? {}
|
|
290
|
+
: {
|
|
291
|
+
code: {
|
|
292
|
+
...(typeof code["epoch"] === "number" ? { epoch: code["epoch"] } : {}),
|
|
293
|
+
...(typeof code["since"] === "number" ? { since: code["since"] } : {}),
|
|
294
|
+
},
|
|
295
|
+
}),
|
|
296
|
+
waitMs: typeof i["waitMs"] === "number" && Number.isFinite(i["waitMs"]) ? Math.max(0, i["waitMs"]) : 0,
|
|
297
|
+
},
|
|
298
|
+
};
|
|
299
|
+
} catch {
|
|
300
|
+
return null;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
/** The one field this chrome acts on. `ContractChangedPayload` also carries the
|
|
305
|
+
* hashes, which are what the REFETCH is for. */
|
|
306
|
+
/** A comment frame's fields, or null for a malformed one. */
|
|
307
|
+
function parseJson(raw: string): Record<string, unknown> | null {
|
|
308
|
+
try {
|
|
309
|
+
const data: unknown = JSON.parse(raw);
|
|
310
|
+
return data !== null && typeof data === "object" ? (data as Record<string, unknown>) : null;
|
|
311
|
+
} catch {
|
|
312
|
+
return null;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
function parseContractChange(raw: string): string | null {
|
|
317
|
+
try {
|
|
318
|
+
const data: unknown = JSON.parse(raw);
|
|
319
|
+
if (data === null || typeof data !== "object") return null;
|
|
320
|
+
const p = data as { componentId?: unknown };
|
|
321
|
+
return typeof p.componentId === "string" && p.componentId.length > 0 ? p.componentId : null;
|
|
322
|
+
} catch {
|
|
323
|
+
return null;
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
|
|
64
327
|
/** The subset of `DocChangedPayload` this chrome acts on. A malformed frame is
|
|
65
328
|
* dropped for the same reason a malformed job frame is. */
|
|
66
|
-
function parseDocChange(
|
|
67
|
-
|
|
68
|
-
|
|
329
|
+
function parseDocChange(raw: string): {
|
|
330
|
+
lane: string;
|
|
331
|
+
name?: string;
|
|
332
|
+
origin?: string;
|
|
333
|
+
clientId?: string;
|
|
334
|
+
deleted?: true;
|
|
335
|
+
renamedFrom?: string;
|
|
336
|
+
renamedTo?: string;
|
|
337
|
+
} | null {
|
|
69
338
|
try {
|
|
70
339
|
const data: unknown = JSON.parse(raw);
|
|
71
340
|
if (data === null || typeof data !== "object") return null;
|
|
72
|
-
const p = data as {
|
|
341
|
+
const p = data as {
|
|
342
|
+
lane?: unknown;
|
|
343
|
+
name?: unknown;
|
|
344
|
+
origin?: unknown;
|
|
345
|
+
clientId?: unknown;
|
|
346
|
+
deleted?: unknown;
|
|
347
|
+
renamedFrom?: unknown;
|
|
348
|
+
renamedTo?: unknown;
|
|
349
|
+
};
|
|
73
350
|
if (typeof p.lane !== "string") return null;
|
|
74
351
|
return {
|
|
75
352
|
lane: p.lane,
|
|
76
353
|
...(typeof p.name === "string" ? { name: p.name } : {}),
|
|
77
354
|
...(typeof p.origin === "string" ? { origin: p.origin } : {}),
|
|
78
355
|
...(typeof p.clientId === "string" ? { clientId: p.clientId } : {}),
|
|
356
|
+
...(p.deleted === true ? { deleted: true as const } : {}),
|
|
357
|
+
...(typeof p.renamedFrom === "string" ? { renamedFrom: p.renamedFrom } : {}),
|
|
358
|
+
...(typeof p.renamedTo === "string" ? { renamedTo: p.renamedTo } : {}),
|
|
79
359
|
};
|
|
80
360
|
} catch {
|
|
81
361
|
return null;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
// The chrome realm's errors that no panel owns: a worklet processor that
|
|
2
|
+
// throws (the level meters' ran `process()` into a ReferenceError on every
|
|
3
|
+
// render quantum in the shipped chrome, and said so only in the console).
|
|
4
|
+
// Kept, deduplicated, for the stage health an agent asks for
|
|
5
|
+
// (state/stageHealth.ts), stamped with the saved revision on screen when each
|
|
6
|
+
// was last seen, so a write's check counts only what happened at the
|
|
7
|
+
// revision it wrote. One log per page, like the chrome's one store.
|
|
8
|
+
import { recordStageError, settleStageErrors } from "@dailies-studio/shot/doc";
|
|
9
|
+
import type { StageErrorSource, StageRuntimeError } from "@dailies-studio/shot/doc";
|
|
10
|
+
|
|
11
|
+
let errors: StageRuntimeError[] = [];
|
|
12
|
+
let revision: () => string | null = () => null;
|
|
13
|
+
const listeners = new Set<() => void>();
|
|
14
|
+
|
|
15
|
+
/** How the log reads the saved revision on screen (the store registers it). */
|
|
16
|
+
export function setRuntimeErrorRevision(read: () => string | null): void {
|
|
17
|
+
revision = read;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/** `standing`: the realm that threw is dead until it restarts (see
|
|
21
|
+
* `runtimeRealmRestarted`), so the error counts at every revision. */
|
|
22
|
+
export function recordRuntimeError(source: StageErrorSource, message: string, standing = false): void {
|
|
23
|
+
errors = recordStageError(errors, source, message, revision(), Date.now(), standing);
|
|
24
|
+
for (const listener of [...listeners]) listener();
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** `source`'s realm runs again (every dead processor was torn down): its
|
|
28
|
+
* errors are history. */
|
|
29
|
+
export function runtimeRealmRestarted(source: StageErrorSource): void {
|
|
30
|
+
errors = settleStageErrors(errors, source);
|
|
31
|
+
for (const listener of [...listeners]) listener();
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function runtimeErrors(): readonly StageRuntimeError[] {
|
|
35
|
+
return errors;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function subscribeRuntimeErrors(listener: () => void): () => void {
|
|
39
|
+
listeners.add(listener);
|
|
40
|
+
return () => listeners.delete(listener);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** Test seam: an empty log. */
|
|
44
|
+
export function clearRuntimeErrors(): void {
|
|
45
|
+
errors = [];
|
|
46
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/** Selection membership is read by every visible outline row. Store selection
|
|
2
|
+
* arrays are immutable, so their identity is the exact invalidation key for a
|
|
3
|
+
* single shared Set rather than one linear `includes` scan per row. */
|
|
4
|
+
const MEMBERSHIP = new WeakMap<readonly string[], ReadonlySet<string>>();
|
|
5
|
+
|
|
6
|
+
export function selectionMembership(selection: readonly string[]): ReadonlySet<string> {
|
|
7
|
+
const found = MEMBERSHIP.get(selection);
|
|
8
|
+
if (found !== undefined) return found;
|
|
9
|
+
const next = new Set(selection);
|
|
10
|
+
MEMBERSHIP.set(selection, next);
|
|
11
|
+
return next;
|
|
12
|
+
}
|