@volter/editor-core 0.5.57
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/BUNDLED_NOTICES +1527 -0
- package/LICENSE +686 -0
- package/LICENSE-APACHE +202 -0
- package/NOTICE +18 -0
- package/README.md +24 -0
- package/dist/build/chunk-JS4D4XZ3.js +175 -0
- package/dist/build/chunk-JS4D4XZ3.js.map +7 -0
- package/dist/build/vite-plugin-product-contributions.js +100 -0
- package/dist/build/vite-plugin-product-contributions.js.map +7 -0
- package/dist/build/vite-plugin-shared-react.js +25 -0
- package/dist/build/vite-plugin-shared-react.js.map +7 -0
- package/dist/build/vite-plugin-shared-three.js +86 -0
- package/dist/build/vite-plugin-shared-three.js.map +7 -0
- package/dist/server/chunk-KMJC7AGO.js +98 -0
- package/dist/server/chunk-KMJC7AGO.js.map +7 -0
- package/dist/server/chunk-PSILUMGS.js +46 -0
- package/dist/server/chunk-PSILUMGS.js.map +7 -0
- package/dist/server/frame-proxy.js +255 -0
- package/dist/server/frame-proxy.js.map +7 -0
- package/dist/server/open-browser.js +53 -0
- package/dist/server/open-browser.js.map +7 -0
- package/dist/server/process-shutdown.js +127 -0
- package/dist/server/process-shutdown.js.map +7 -0
- package/dist/server/session-registry.js +141 -0
- package/dist/server/session-registry.js.map +7 -0
- package/dist/server/spawn-opener.js +11 -0
- package/dist/server/spawn-opener.js.map +7 -0
- package/dist/server/worktree-identity.js +11 -0
- package/dist/server/worktree-identity.js.map +7 -0
- package/dist-server/packaged.mjs +88816 -0
- package/package.json +118 -0
- package/scripts/build-plugins.mjs +14 -0
- package/scripts/build-server.mjs +26 -0
- package/scripts/build-session.mjs +9 -0
- package/server/account-credentials.ts +60 -0
- package/server/account-service.ts +1434 -0
- package/server/adapter-region-includes.ts +47 -0
- package/server/asset-catalog-v2.ts +175 -0
- package/server/asset-history-snapshots.ts +196 -0
- package/server/asset-ledger-store.ts +195 -0
- package/server/asset-library-routes.ts +1595 -0
- package/server/blender-wasm-artifact.ts +430 -0
- package/server/boot-timings.ts +106 -0
- package/server/canonical-path.ts +50 -0
- package/server/checkout-workspace-preflight.ts +349 -0
- package/server/cloud-asset-catalog.ts +158 -0
- package/server/coding-inference-launch.ts +237 -0
- package/server/collaboration-account-client.ts +202 -0
- package/server/collaboration-attribution.ts +122 -0
- package/server/collaboration-session.ts +934 -0
- package/server/comfyui-bridge.ts +248 -0
- package/server/console-ledger.ts +499 -0
- package/server/creation-site-transform.ts +304 -0
- package/server/creation-site-write.ts +648 -0
- package/server/data-file-serialize.ts +158 -0
- package/server/editor-brand-html.ts +72 -0
- package/server/editor-control-socket.ts +366 -0
- package/server/editor-server-options.ts +190 -0
- package/server/editor-server.ts +1483 -0
- package/server/editor-sse.ts +352 -0
- package/server/engine-provenance.ts +169 -0
- package/server/engine-source-restart.ts +117 -0
- package/server/frame-bridge.ts +115 -0
- package/server/frame-proxy.ts +490 -0
- package/server/frame-workbench.ts +259 -0
- package/server/frontend-handoff.ts +229 -0
- package/server/game-globals-shadow.ts +113 -0
- package/server/gameplay-session-retention.ts +149 -0
- package/server/gameplay-sessions.ts +123 -0
- package/server/generation-jobs.ts +201 -0
- package/server/generation-reconciler.ts +137 -0
- package/server/generative-execution-context.ts +59 -0
- package/server/git-workflow.ts +612 -0
- package/server/harness-chat-caller.ts +36 -0
- package/server/harness-chat-service.ts +1681 -0
- package/server/idle-shutdown.ts +170 -0
- package/server/js-profiling-policy.ts +52 -0
- package/server/launcher-settings.ts +84 -0
- package/server/local-asset-catalog.ts +410 -0
- package/server/managed-account-defaults.ts +22 -0
- package/server/mock-control-plane.ts +540 -0
- package/server/model-import-conversion.ts +345 -0
- package/server/native-credential-store.ts +162 -0
- package/server/open-browser.ts +118 -0
- package/server/packaged.ts +1192 -0
- package/server/play-stall.ts +126 -0
- package/server/process-shutdown.ts +218 -0
- package/server/product-presets.ts +55 -0
- package/server/project-build-artifact.ts +95 -0
- package/server/project-components.ts +100 -0
- package/server/project-dependency-invalidation.ts +114 -0
- package/server/project-file-scan.ts +235 -0
- package/server/project-hmr-files.ts +215 -0
- package/server/project-install-roots.ts +210 -0
- package/server/project-kinds.ts +71 -0
- package/server/project-mcp-servers.ts +82 -0
- package/server/project-module-freshness.ts +109 -0
- package/server/project-module-instance.ts +375 -0
- package/server/project-optimize-deps-entries.ts +827 -0
- package/server/project-output-writer.ts +679 -0
- package/server/project-package-origin.ts +63 -0
- package/server/project-root-surface.ts +831 -0
- package/server/project-scratch-path.ts +47 -0
- package/server/project-script-hmr.ts +619 -0
- package/server/project-serving-plugins.ts +236 -0
- package/server/project-tools.ts +653 -0
- package/server/project-validation.ts +250 -0
- package/server/project-verbs.ts +127 -0
- package/server/project-view.ts +52 -0
- package/server/project-watch.ts +1134 -0
- package/server/project-work-coordinator.ts +288 -0
- package/server/provider-credentials.ts +331 -0
- package/server/recent-projects-store.ts +98 -0
- package/server/redact-secrets.ts +71 -0
- package/server/repository-presence.ts +267 -0
- package/server/routes/account.ts +357 -0
- package/server/routes/agents.ts +60 -0
- package/server/routes/assets.ts +154 -0
- package/server/routes/build.ts +13 -0
- package/server/routes/collaboration.ts +595 -0
- package/server/routes/configurations.ts +419 -0
- package/server/routes/context.ts +264 -0
- package/server/routes/control-plane.ts +1811 -0
- package/server/routes/logs.ts +272 -0
- package/server/routes/project-identity.ts +302 -0
- package/server/routes/project-open.ts +429 -0
- package/server/routes/project-source.ts +686 -0
- package/server/routes/project-state.ts +383 -0
- package/server/routes/relay.ts +1029 -0
- package/server/routes/route-helpers.ts +29 -0
- package/server/routes/served-modules.ts +138 -0
- package/server/routes/session-tabs.ts +196 -0
- package/server/routes/settings.ts +121 -0
- package/server/routes/share-control.ts +486 -0
- package/server/routes/themes.ts +116 -0
- package/server/routes/tools.ts +230 -0
- package/server/routes/worktrees.ts +595 -0
- package/server/scoped-game-css.ts +461 -0
- package/server/server-utils.ts +1194 -0
- package/server/session-product.ts +112 -0
- package/server/session-registry.ts +230 -0
- package/server/share-claims.ts +138 -0
- package/server/share-host.ts +526 -0
- package/server/share-session-gateway.ts +1362 -0
- package/server/share-tunnel.ts +123 -0
- package/server/spawn-opener.ts +74 -0
- package/server/support/play/log-format.ts +76 -0
- package/server/support/play/session-record.ts +199 -0
- package/server/support/project/build-discipline.ts +718 -0
- package/server/support/project/inspection-node.ts +119 -0
- package/server/support/project/log-naming.ts +54 -0
- package/server/support/project/provenance.ts +290 -0
- package/server/support/project/run-name.ts +18 -0
- package/server/support/project/session-journal.ts +830 -0
- package/server/support/project/shared.ts +327 -0
- package/server/tab-bootstrap.ts +62 -0
- package/server/tab-heartbeat.ts +477 -0
- package/server/tab-lifecycle.ts +550 -0
- package/server/tab-presence.ts +1508 -0
- package/server/team-agent-mirror.ts +95 -0
- package/server/twin-auth.ts +138 -0
- package/server/vendored-lock-recorder.ts +968 -0
- package/server/worktree-identity.ts +121 -0
- package/server/worktree-management.ts +398 -0
- package/server/worktree-retention.d.mts +13 -0
- package/server/worktree-retention.mjs +205 -0
- package/src/EditorContext.tsx +169 -0
- package/src/account.ts +333 -0
- package/src/action-registry.ts +532 -0
- package/src/active-product.ts +74 -0
- package/src/active-project.ts +155 -0
- package/src/adapter-editor-config.ts +25 -0
- package/src/adapter-observation.ts +49 -0
- package/src/animation/stage-transport.ts +379 -0
- package/src/animation/three-clips-subject.ts +172 -0
- package/src/api/asset-library-wire.ts +45 -0
- package/src/api/assets.ts +365 -0
- package/src/api/base.ts +10 -0
- package/src/api/build.ts +99 -0
- package/src/api/git-wire.ts +56 -0
- package/src/api/logs.ts +92 -0
- package/src/api/project-identity.ts +74 -0
- package/src/api/project-open.ts +355 -0
- package/src/api/project-source.ts +162 -0
- package/src/api/project-state.ts +107 -0
- package/src/api/relay.ts +268 -0
- package/src/api/settings.ts +36 -0
- package/src/api/themes.ts +45 -0
- package/src/api/worktrees.ts +257 -0
- package/src/asset-compare-core.ts +171 -0
- package/src/asset-compare.ts +294 -0
- package/src/asset-editor-context.tsx +100 -0
- package/src/asset-events.ts +97 -0
- package/src/asset-inspector-actions.ts +87 -0
- package/src/asset-preview-framing.ts +357 -0
- package/src/asset-preview.ts +2802 -0
- package/src/asset-selection-viewer-registry.ts +113 -0
- package/src/asset-selection.ts +133 -0
- package/src/asset-workflow/asset-capabilities.ts +344 -0
- package/src/asset-workflow/asset-import-jobs.ts +106 -0
- package/src/asset-workflow/asset-ledger-backend.ts +126 -0
- package/src/asset-workflow/asset-ledger.ts +156 -0
- package/src/asset-workflow/asset-materialization-report.ts +140 -0
- package/src/asset-workflow/asset-pack-manifest.ts +320 -0
- package/src/asset-workflow/asset-types.ts +142 -0
- package/src/asset-workflow/asset-workflow-quality.ts +61 -0
- package/src/asset-workflow/audio-preview-player.ts +193 -0
- package/src/asset-workflow/audio-waveform.ts +22 -0
- package/src/asset-workflow/cloud-asset-client.ts +263 -0
- package/src/asset-workflow/folder-preview.ts +345 -0
- package/src/asset-workflow/hosted-asset-materialization.ts +236 -0
- package/src/asset-workflow/image-view-scale.ts +32 -0
- package/src/asset-workflow/import-contract.ts +124 -0
- package/src/asset-workflow/ledger-write-lock.ts +244 -0
- package/src/asset-workflow/model-inspection.ts +818 -0
- package/src/asset-workflow/pixi-spritesheet.ts +197 -0
- package/src/asset-workflow/preview-resource-lifetime.ts +44 -0
- package/src/asset-workflow/project-asset-commands.ts +23 -0
- package/src/asset-workflow/project-asset-health.ts +139 -0
- package/src/asset-workflow/project-asset-operations.ts +154 -0
- package/src/asset-workflow/project-asset-roots.ts +68 -0
- package/src/asset-workflow/project-content.ts +288 -0
- package/src/asset-workflow/project-source-index.ts +550 -0
- package/src/asset-workflow/thumbnail-system.ts +256 -0
- package/src/authoring/active-adapter.ts +199 -0
- package/src/authoring/active-systems.ts +422 -0
- package/src/authoring/adapter-key.ts +18 -0
- package/src/authoring/authoring-asset-url.ts +27 -0
- package/src/authoring/bootstrap-state.ts +49 -0
- package/src/authoring/boundary-authoring-adapter.ts +184 -0
- package/src/authoring/breakpoint-state.ts +43 -0
- package/src/authoring/canvas-scene-guides.ts +76 -0
- package/src/authoring/component-instance-root.ts +171 -0
- package/src/authoring/composite-authoring-adapter.ts +2110 -0
- package/src/authoring/consumer-actions.ts +520 -0
- package/src/authoring/css-numeric-style.ts +97 -0
- package/src/authoring/design-time-layers.ts +849 -0
- package/src/authoring/design-time-mount-registry.ts +235 -0
- package/src/authoring/design-time-settle.ts +343 -0
- package/src/authoring/edit-mode-authoring.ts +619 -0
- package/src/authoring/eyedropper-session.ts +60 -0
- package/src/authoring/instance-source-menu-register.ts +13 -0
- package/src/authoring/instance-source-menu.ts +135 -0
- package/src/authoring/layered-pick.ts +183 -0
- package/src/authoring/live-gesture-lock.ts +50 -0
- package/src/authoring/live-object-transform.ts +62 -0
- package/src/authoring/mount-failure-report.ts +154 -0
- package/src/authoring/mounted-root-subjects.ts +144 -0
- package/src/authoring/no-authoring-adapter.ts +55 -0
- package/src/authoring/null-inspection-subjects.tsx +75 -0
- package/src/authoring/object3d-document-persistence.ts +106 -0
- package/src/authoring/object3d-document-session-registry.ts +120 -0
- package/src/authoring/object3d-document-session.ts +1326 -0
- package/src/authoring/object3d-gesture-controller.ts +113 -0
- package/src/authoring/panel-authoring.ts +121 -0
- package/src/authoring/prefab-instance-inspector-section.tsx +237 -0
- package/src/authoring/prefab-instance-section-model.ts +55 -0
- package/src/authoring/project-authoring-session.ts +105 -0
- package/src/authoring/provenance.ts +99 -0
- package/src/authoring/quarks-particle-systems.ts +19 -0
- package/src/authoring/react-canvas-navigation.ts +255 -0
- package/src/authoring/react-design-canvas-style.ts +20 -0
- package/src/authoring/react-story-board.ts +937 -0
- package/src/authoring/selection-scope.ts +195 -0
- package/src/authoring/shell-document-ops.ts +169 -0
- package/src/authoring/shell-object3d-document-write-policy.ts +108 -0
- package/src/authoring/shell-viewport-policy.ts +48 -0
- package/src/authoring/source-object3d-authoring-adapter.ts +526 -0
- package/src/authoring/stories-scope.ts +35 -0
- package/src/authoring/story-board-chrome-fit.ts +107 -0
- package/src/authoring/story-board-presentation.ts +111 -0
- package/src/authoring/three-projection-core.ts +226 -0
- package/src/authoring/viewport-pick-context.ts +40 -0
- package/src/authoring/viewport-raycast.ts +240 -0
- package/src/authoring/viewport-tool-context.ts +73 -0
- package/src/authoring/world-canvas-viewport-state.ts +35 -0
- package/src/authoring/world-hidden-viewport.ts +152 -0
- package/src/authoring/world-pan-state.ts +198 -0
- package/src/authoring/world-session-state.ts +101 -0
- package/src/authoring/write-pipe.ts +173 -0
- package/src/availability-tick.ts +66 -0
- package/src/bitmap-label.ts +120 -0
- package/src/blender-tab-metrics.ts +161 -0
- package/src/board-open-actions.ts +20 -0
- package/src/boot-routing.ts +391 -0
- package/src/build-identity.ts +15 -0
- package/src/bytes-codec.ts +62 -0
- package/src/camera-authoring.ts +175 -0
- package/src/cancellation-reason.ts +58 -0
- package/src/canvas-preview-frames.ts +482 -0
- package/src/capture-camera-pose.ts +77 -0
- package/src/chrome-registry.ts +159 -0
- package/src/chrome-slot-registry.ts +91 -0
- package/src/collaboration-client.ts +264 -0
- package/src/collaboration-presence.ts +41 -0
- package/src/command-dispatch.ts +19 -0
- package/src/command-listener.ts +2743 -0
- package/src/command-registry.ts +70 -0
- package/src/component-board-registry.ts +205 -0
- package/src/component-states-registry.ts +200 -0
- package/src/components/AgentPresentationNotice.tsx +75 -0
- package/src/components/AlignToolbar.tsx +204 -0
- package/src/components/AppRoot.tsx +394 -0
- package/src/components/ApplicationMenus.tsx +415 -0
- package/src/components/AssetBrowser.tsx +2843 -0
- package/src/components/AssetEditorShell.tsx +216 -0
- package/src/components/AssetInspectorToolSection.tsx +124 -0
- package/src/components/BoardRulers.tsx +354 -0
- package/src/components/CameraInfo.tsx +81 -0
- package/src/components/CanvasSceneViewport.tsx +556 -0
- package/src/components/CapabilityCoverageSection.tsx +185 -0
- package/src/components/CenterDocuments.tsx +22 -0
- package/src/components/ChromeSlot.tsx +20 -0
- package/src/components/CodeView.tsx +470 -0
- package/src/components/CollaborationHeaderControl.css +74 -0
- package/src/components/CompactInspectorCard.tsx +190 -0
- package/src/components/CompactInspectorShell.tsx +39 -0
- package/src/components/ConsolePanel.css +55 -0
- package/src/components/ConsolePanel.tsx +270 -0
- package/src/components/DefaultEditorLayout.tsx +106 -0
- package/src/components/DocumentHeaderStrip.tsx +96 -0
- package/src/components/DocumentShelfRail.tsx +45 -0
- package/src/components/DocumentThumbnail.tsx +345 -0
- package/src/components/EditorLeaseGuard.tsx +372 -0
- package/src/components/ErrorBanner.tsx +123 -0
- package/src/components/FolderPreviewTile.tsx +159 -0
- package/src/components/GameHierarchy.tsx +3842 -0
- package/src/components/GameplaySessionTimeline.tsx +295 -0
- package/src/components/InspectionProjection.tsx +968 -0
- package/src/components/Inspector.tsx +233 -0
- package/src/components/InspectorCanvasPreview.tsx +35 -0
- package/src/components/InspectorFieldsSection.tsx +290 -0
- package/src/components/InspectorObjectPreview.tsx +57 -0
- package/src/components/InspectorStoriesSection.tsx +92 -0
- package/src/components/InspectorToolSection.tsx +96 -0
- package/src/components/InspectorTransformSection.tsx +245 -0
- package/src/components/LightExplorerPanel.tsx +433 -0
- package/src/components/MediaProperties.tsx +145 -0
- package/src/components/NonThreeAuthoringBootstrap.tsx +19 -0
- package/src/components/Object3DDocumentToolbar.css +100 -0
- package/src/components/Object3DDocumentToolbar.tsx +454 -0
- package/src/components/Object3DDocumentViewport.tsx +58 -0
- package/src/components/ProjectHeader.css +617 -0
- package/src/components/ProjectHeader.tsx +328 -0
- package/src/components/ProjectLayout.tsx +249 -0
- package/src/components/ReactCanvasControls.tsx +284 -0
- package/src/components/RootSelectionOverlay.tsx +3162 -0
- package/src/components/RootTextEditor.tsx +79 -0
- package/src/components/SaveStatus.tsx +70 -0
- package/src/components/StageHost.tsx +1954 -0
- package/src/components/StageOverlays.tsx +21 -0
- package/src/components/StartupErrorScreen.tsx +76 -0
- package/src/components/StartupLoadingScreen.tsx +65 -0
- package/src/components/StatsOverlay.tsx +78 -0
- package/src/components/SurfaceStateOverlay.tsx +24 -0
- package/src/components/ToolContributionSurfaces.tsx +65 -0
- package/src/components/ToolHost.tsx +370 -0
- package/src/components/ToolObject3DPreview.tsx +39 -0
- package/src/components/Toolbar.tsx +595 -0
- package/src/components/TransientHint.tsx +44 -0
- package/src/components/TransportStrip.tsx +174 -0
- package/src/components/VersionControlSection.tsx +470 -0
- package/src/components/VgaiLogo.css +83 -0
- package/src/components/VgaiLogo.tsx +35 -0
- package/src/components/ViewportControlsHint.tsx +60 -0
- package/src/components/ViewportFurniture.tsx +401 -0
- package/src/components/ViewportOverlay.tsx +145 -0
- package/src/components/ViewportOverlaysMenu.tsx +153 -0
- package/src/components/ViewportShadingMenu.tsx +300 -0
- package/src/components/ViewportViewMenu.tsx +101 -0
- package/src/components/WorkspaceDocumentSurface.tsx +204 -0
- package/src/components/WorkspaceUtilitySurface.tsx +22 -0
- package/src/components/WorktreeSwitcher.css +239 -0
- package/src/components/WorktreeSwitcher.tsx +890 -0
- package/src/components/account-documents.tsx +1162 -0
- package/src/components/asset-documents.tsx +812 -0
- package/src/components/asset-editor-persistence.ts +216 -0
- package/src/components/asset-selection-section.tsx +535 -0
- package/src/components/asset-thumbnails.tsx +312 -0
- package/src/components/asset-viewers/AudioViewer.tsx +201 -0
- package/src/components/asset-viewers/EntityModelDocument.tsx +122 -0
- package/src/components/asset-viewers/EnvironmentAssetDocument.tsx +440 -0
- package/src/components/asset-viewers/GenericJsonViewer.tsx +102 -0
- package/src/components/asset-viewers/ImageViewer.tsx +300 -0
- package/src/components/asset-viewers/JsonAssetDocument.tsx +93 -0
- package/src/components/asset-viewers/LiveModuleDocument.tsx +417 -0
- package/src/components/asset-viewers/LutAssetDocument.tsx +444 -0
- package/src/components/asset-viewers/ModelAssetDocument.tsx +105 -0
- package/src/components/asset-viewers/Object3DPreview.tsx +359 -0
- package/src/components/asset-viewers/OnlineAssetDetail.tsx +421 -0
- package/src/components/asset-viewers/PasteboardModuleDocument.tsx +67 -0
- package/src/components/asset-viewers/QuarksAssetDocument.tsx +526 -0
- package/src/components/asset-viewers/ShaderAssetDocument.tsx +743 -0
- package/src/components/asset-viewers/SourceAssetViewer.tsx +281 -0
- package/src/components/asset-viewers/SpritesheetSpriteView.tsx +102 -0
- package/src/components/asset-viewers/VideoViewer.tsx +101 -0
- package/src/components/asset-viewers/shader-source.ts +144 -0
- package/src/components/asset-workflow.css +731 -0
- package/src/components/board-guides.ts +150 -0
- package/src/components/compact-inspector.css +539 -0
- package/src/components/core-utilities.tsx +90 -0
- package/src/components/editor-notifications.css +40 -0
- package/src/components/engine-workspace.css +274 -0
- package/src/components/inspector-preview-section.tsx +238 -0
- package/src/components/inspector-property-grouping.ts +64 -0
- package/src/components/inspector-revert-label.ts +20 -0
- package/src/components/inspector-selection.ts +42 -0
- package/src/components/inspector-stories-gating.ts +171 -0
- package/src/components/inspector-transform-subject.ts +11 -0
- package/src/components/inspector-transform.ts +75 -0
- package/src/components/kind-documents.tsx +500 -0
- package/src/components/palette-action-publisher.tsx +140 -0
- package/src/components/primitives/DraftColorInput.tsx +74 -0
- package/src/components/product-shell.css +1829 -0
- package/src/components/project-tool-documents.tsx +410 -0
- package/src/components/scene-documents.tsx +223 -0
- package/src/components/stage-keyboard.tsx +37 -0
- package/src/components/stage-overlay-set.tsx +107 -0
- package/src/components/stage-presence-markers.ts +478 -0
- package/src/components/standard-viewport-dressing.ts +417 -0
- package/src/components/status-contributions.tsx +403 -0
- package/src/components/tool-documents.tsx +309 -0
- package/src/components/tool-schema-form.tsx +262 -0
- package/src/components/use-after-paint.ts +41 -0
- package/src/components/use-project-image-assets.ts +86 -0
- package/src/components/viewport-header-controls.css +90 -0
- package/src/components/viewport-surface-status.tsx +55 -0
- package/src/components/workspace-history.ts +32 -0
- package/src/components/workspace-static-panel-registry.tsx +152 -0
- package/src/components/workspace-surfaces.css +621 -0
- package/src/components/world-documents.tsx +586 -0
- package/src/components/world-overlay-gestures.ts +1694 -0
- package/src/composite-screenshot.ts +1641 -0
- package/src/console-sync.ts +131 -0
- package/src/constraint-helper.ts +338 -0
- package/src/content-entry-source-registry.ts +184 -0
- package/src/coverage/authoring-seam-evidence.ts +300 -0
- package/src/coverage/canvas-reveal.ts +192 -0
- package/src/coverage/design-time-surfaces.ts +101 -0
- package/src/coverage/live-seam-evidence.ts +11 -0
- package/src/coverage/ontology-invariants.ts +466 -0
- package/src/coverage/session-vitals.ts +501 -0
- package/src/coverage/system-seam-evidence.ts +72 -0
- package/src/crash-null-boundary.ts +36 -0
- package/src/creation-site-edit.ts +1479 -0
- package/src/creation-site-registry.ts +160 -0
- package/src/delegate-harness-registry.ts +143 -0
- package/src/document-context-registry.ts +177 -0
- package/src/document-open-registry.ts +200 -0
- package/src/document-preview-source.ts +20 -0
- package/src/document-renderer-session.ts +138 -0
- package/src/editor-api.ts +46 -0
- package/src/editor-chrome-capture.ts +139 -0
- package/src/editor-commands.ts +164 -0
- package/src/editor-console.ts +563 -0
- package/src/editor-current-view.ts +82 -0
- package/src/editor-document-probe.ts +881 -0
- package/src/editor-git-client.ts +115 -0
- package/src/editor-host-door.ts +462 -0
- package/src/editor-hotkeys.ts +842 -0
- package/src/editor-lease-view.ts +39 -0
- package/src/editor-lease.ts +415 -0
- package/src/editor-mode.ts +19 -0
- package/src/editor-notifications.ts +140 -0
- package/src/editor-presence.ts +563 -0
- package/src/editor-presentation-activity.ts +50 -0
- package/src/editor-presentation-notice.ts +42 -0
- package/src/editor-runtime.tsx +145 -0
- package/src/editor-server-response.ts +86 -0
- package/src/editor-session-attribution.ts +75 -0
- package/src/editor-session-mode.ts +54 -0
- package/src/editor-shell-store.ts +1304 -0
- package/src/editor-state-facets.ts +74 -0
- package/src/editor-styles.css +33 -0
- package/src/editor-view-presentation.ts +810 -0
- package/src/editor-viewport.ts +5302 -0
- package/src/entity-lod.ts +31 -0
- package/src/entity-object.ts +91 -0
- package/src/files/file-provider.ts +62 -0
- package/src/files/project-files.ts +264 -0
- package/src/finders/index.ts +136 -0
- package/src/finders/scenes-from-entrypoint-selection.ts +387 -0
- package/src/frame/bridge.tsx +1408 -0
- package/src/frame/product.ts +77 -0
- package/src/gameplay-dom-recording.ts +319 -0
- package/src/gameplay-export-state.ts +14 -0
- package/src/gameplay-replay.ts +417 -0
- package/src/gameplay-session-time.ts +9 -0
- package/src/gameplay-sessions.ts +204 -0
- package/src/harness-chat-types.ts +253 -0
- package/src/hierarchy-component-marks.ts +298 -0
- package/src/hierarchy-drop.ts +91 -0
- package/src/hierarchy-expansion-state.ts +80 -0
- package/src/hierarchy-header-slot.ts +52 -0
- package/src/hierarchy-internals.ts +197 -0
- package/src/hierarchy-kind-icon.ts +217 -0
- package/src/hierarchy-mark-reader.ts +73 -0
- package/src/hierarchy-menu-registry.ts +67 -0
- package/src/hierarchy-node-rows.ts +307 -0
- package/src/hierarchy-panel-view.ts +280 -0
- package/src/hierarchy-projection.ts +76 -0
- package/src/hierarchy-row-cache.ts +243 -0
- package/src/hierarchy-row-model.ts +308 -0
- package/src/hierarchy-rows.ts +11 -0
- package/src/hierarchy-walk.ts +86 -0
- package/src/history/editor-session.ts +25 -0
- package/src/history/history-commands.ts +147 -0
- package/src/history/history-delegate.ts +163 -0
- package/src/history/history-limit-notices.ts +43 -0
- package/src/history/history-service.ts +1173 -0
- package/src/history/persistence-coordinator.ts +35 -0
- package/src/history/project-file-history.ts +386 -0
- package/src/history/project-root-history-backends.ts +139 -0
- package/src/history/resource-registry.ts +209 -0
- package/src/history/snapshot-store.ts +103 -0
- package/src/history/source-history-backend.ts +546 -0
- package/src/history/types.ts +124 -0
- package/src/hmr-registration-group.ts +67 -0
- package/src/hmr-stable-react-context.ts +23 -0
- package/src/hotkeys.ts +188 -0
- package/src/inference-diagnostics.ts +69 -0
- package/src/initial-project.ts +80 -0
- package/src/inspection/active-subject.ts +578 -0
- package/src/inspection/active-surface.ts +142 -0
- package/src/inspection/compose.ts +1064 -0
- package/src/inspection/display.ts +170 -0
- package/src/inspection/document-subject.ts +109 -0
- package/src/inspection/game-subject.ts +85 -0
- package/src/inspection/model.ts +542 -0
- package/src/inspection/null-subject.ts +115 -0
- package/src/inspection/serialize.ts +357 -0
- package/src/inspection/use-active-inspection.ts +180 -0
- package/src/inspector-presentation.ts +201 -0
- package/src/inspector-section-registry.ts +221 -0
- package/src/instance-source-actions.ts +163 -0
- package/src/instanced-presentation.ts +164 -0
- package/src/js-heap.ts +71 -0
- package/src/key-actions.ts +91 -0
- package/src/keymap-presets.ts +401 -0
- package/src/layout-policy.ts +31 -0
- package/src/learn-links.ts +73 -0
- package/src/light-explorer-model.ts +134 -0
- package/src/live-canvas-frame.ts +55 -0
- package/src/live-document.ts +279 -0
- package/src/live-module-source.ts +230 -0
- package/src/live-session-registry.ts +220 -0
- package/src/live-transition.ts +633 -0
- package/src/manifest-project.ts +107 -0
- package/src/model-thumbnail.ts +523 -0
- package/src/native-selection-style.ts +202 -0
- package/src/object3d-document-write-policy.ts +137 -0
- package/src/packaged-runtime.ts +108 -0
- package/src/palettes/maya.palette.json +57 -0
- package/src/palettes/substance.palette.json +57 -0
- package/src/pasteboard-module.ts +81 -0
- package/src/performance-profiler.ts +367 -0
- package/src/performance-sources.ts +69 -0
- package/src/play-boot-phase.ts +145 -0
- package/src/presentation-surface.ts +248 -0
- package/src/project-adapter.ts +1143 -0
- package/src/project-asset-refresh.ts +26 -0
- package/src/project-declaration-refresh.ts +31 -0
- package/src/project-local-state.ts +118 -0
- package/src/project-manager.ts +243 -0
- package/src/project-module-changes.ts +163 -0
- package/src/project-module-split.ts +266 -0
- package/src/project-provenance.ts +115 -0
- package/src/project-ready.ts +42 -0
- package/src/project-session-reset.ts +67 -0
- package/src/project-shape.ts +68 -0
- package/src/project-tool-discovery.ts +66 -0
- package/src/project-tools.ts +107 -0
- package/src/project-work-types.ts +149 -0
- package/src/projection/three.ts +898 -0
- package/src/projection/types.ts +44 -0
- package/src/readiness.ts +113 -0
- package/src/reflection-probe-helper.ts +142 -0
- package/src/reported-play-state.ts +90 -0
- package/src/resolve-relative-specifier.ts +33 -0
- package/src/scene-document-plan.ts +315 -0
- package/src/scene-framing.ts +315 -0
- package/src/scene-live-open.ts +210 -0
- package/src/scene-view-fog.ts +89 -0
- package/src/scoped-game-css.ts +152 -0
- package/src/session-orphan-record.ts +193 -0
- package/src/session-tombstone.ts +126 -0
- package/src/settings/settings-provider.ts +82 -0
- package/src/settings-store.ts +345 -0
- package/src/shared-view-restore.ts +42 -0
- package/src/shell-store-door.ts +45 -0
- package/src/source-conflict.ts +122 -0
- package/src/spatial-handle-visuals.ts +332 -0
- package/src/stage-context.ts +341 -0
- package/src/stage-store-registry.ts +63 -0
- package/src/stale-chunk-recovery.ts +34 -0
- package/src/state-report-deferral.ts +73 -0
- package/src/storage/host-files-storage.ts +97 -0
- package/src/storage/http-storage.ts +174 -0
- package/src/storage/index.ts +75 -0
- package/src/storage/mem-storage.ts +149 -0
- package/src/storage/path-lock.ts +44 -0
- package/src/storage/paths.ts +26 -0
- package/src/storage/types.ts +116 -0
- package/src/stories/StoryComponentThumbnail.tsx +184 -0
- package/src/stories/StoryPreviewMount.tsx +306 -0
- package/src/stories/component-content-source.tsx +106 -0
- package/src/stories/component-states-source.ts +78 -0
- package/src/stories/compose-project-stories.ts +255 -0
- package/src/stories/pixi-story-model.ts +30 -0
- package/src/stories/prefabs-finder.ts +54 -0
- package/src/stories/prefabs-from-stories.ts +182 -0
- package/src/stories/project-story-discovery.ts +78 -0
- package/src/stories/project-story-regions.ts +24 -0
- package/src/stories/story-actions.ts +54 -0
- package/src/stories/story-capture-command.ts +124 -0
- package/src/stories/story-capture.ts +584 -0
- package/src/stories/story-declared-medium.ts +126 -0
- package/src/stories/story-discovery.ts +176 -0
- package/src/stories/story-document-openers.ts +36 -0
- package/src/stories/story-dom-runtime.ts +78 -0
- package/src/stories/story-grouping.ts +111 -0
- package/src/stories/story-lane.ts +88 -0
- package/src/stories/story-mount-turn.ts +27 -0
- package/src/stories/story-opener.ts +260 -0
- package/src/stories/story-pixi-preview.ts +408 -0
- package/src/stories/story-presentation.ts +215 -0
- package/src/stories/story-registry.ts +517 -0
- package/src/stories/story-three-preview.ts +807 -0
- package/src/stories/three-story-model.ts +96 -0
- package/src/story-three-preview-runtime.ts +56 -0
- package/src/surface-keyboard.ts +112 -0
- package/src/surface-state.ts +124 -0
- package/src/tab-bootstrap.js +628 -0
- package/src/tab-census.ts +198 -0
- package/src/tab-lifecycle-client.ts +196 -0
- package/src/theme-library.ts +844 -0
- package/src/theme-preference.ts +378 -0
- package/src/theme.css +3437 -0
- package/src/three-viewport/bone-selection-highlight.ts +119 -0
- package/src/three-viewport/camera-fit.ts +41 -0
- package/src/three-viewport/interactive-renderer.ts +132 -0
- package/src/three-viewport/selection-brackets.ts +310 -0
- package/src/three-viewport/selection-outline.ts +183 -0
- package/src/three-viewport/skeleton-helper.ts +61 -0
- package/src/three-viewport/source-color.ts +167 -0
- package/src/three-viewport/studio-environment.ts +96 -0
- package/src/three-viewport-presentation.ts +23 -0
- package/src/tool-contribution-play.ts +74 -0
- package/src/tool-loader.ts +1798 -0
- package/src/transform-mode-request.ts +57 -0
- package/src/transient-hint.ts +78 -0
- package/src/trigger-volume-helper.ts +116 -0
- package/src/ui-source/adapter-region-includes.ts +241 -0
- package/src/ui-source/ensure-import.ts +132 -0
- package/src/ui-source/file-region-resolver.ts +302 -0
- package/src/ui-source/inspect.ts +775 -0
- package/src/ui-source/oid-transform.ts +1845 -0
- package/src/ui-source/plan-csf-story.ts +196 -0
- package/src/ui-source/plan-extract-component.ts +421 -0
- package/src/ui-source/plan-fork-component.ts +621 -0
- package/src/ui-source/plan-named-style.ts +95 -0
- package/src/ui-source/plan-source-edit.ts +353 -0
- package/src/ui-source/r3f-contract-resolver.ts +327 -0
- package/src/ui-source/r3f-diagnostic-index.ts +165 -0
- package/src/ui-source/r3f-environment-binding.ts +133 -0
- package/src/ui-source/r3f-joint-binding.ts +251 -0
- package/src/ui-source/r3f-lod-binding.ts +91 -0
- package/src/ui-source/r3f-particle-binding.ts +235 -0
- package/src/ui-source/r3f-physics-binding.ts +483 -0
- package/src/ui-source/r3f-project-contracts.ts +444 -0
- package/src/ui-source/relative-import-specifier.ts +34 -0
- package/src/ui-source/reparent-guard.ts +544 -0
- package/src/ui-source/source-edit-request.ts +97 -0
- package/src/ui-source/source-write-backend.ts +618 -0
- package/src/ui-source/syntactic-prop-specs.ts +296 -0
- package/src/ui-source/tier-source-write-backend.ts +279 -0
- package/src/ui-source/ts-ast.ts +171 -0
- package/src/ui-source/utility-class-support.ts +169 -0
- package/src/ui-source/write-component-default.ts +133 -0
- package/src/ui-source/writer.ts +1989 -0
- package/src/viewport-activation-timings.ts +840 -0
- package/src/viewport-authoring-policy.ts +186 -0
- package/src/viewport-controls-hint.ts +57 -0
- package/src/viewport-door.ts +237 -0
- package/src/viewport-shading-boundary.ts +12 -0
- package/src/vite-error-surface.ts +141 -0
- package/src/wait-until.ts +37 -0
- package/src/workspace-areas.ts +156 -0
- package/src/workspace-aux-commands.ts +11 -0
- package/src/workspace-available-documents.ts +127 -0
- package/src/workspace-core-utilities.ts +31 -0
- package/src/workspace-document-ids.ts +59 -0
- package/src/workspace-document-registry.ts +612 -0
- package/src/workspace-document-restore.ts +145 -0
- package/src/workspace-host-commands.ts +141 -0
- package/src/workspace-persistence-gate.ts +40 -0
- package/src/workspace-play-utilities.ts +44 -0
- package/src/workspace-presets.ts +425 -0
- package/src/workspace-regions.ts +294 -0
- package/src/workspace-state-persistence.ts +536 -0
- package/src/workspace-static-panels.ts +73 -0
- package/src/workspace-status-registry.ts +121 -0
- package/src/workspace-style.ts +239 -0
- package/src/workspace-utility-commands.ts +74 -0
- package/src/workspace-utility-registry.ts +263 -0
- package/src/workspace-viewport-rect.ts +97 -0
- package/src/world-adoption.ts +115 -0
- package/src/world-document-routing.ts +104 -0
- package/vite-plugin-creation-site-write.ts +184 -0
- package/vite-plugin-creation-site.ts +80 -0
- package/vite-plugin-game-static.ts +303 -0
- package/vite-plugin-module-doorways.ts +336 -0
- package/vite-plugin-product-contributions.ts +197 -0
- package/vite-plugin-project-game-static.ts +125 -0
- package/vite-plugin-project-jsx-js.ts +65 -0
- package/vite-plugin-project-root-absolute-assets.ts +359 -0
- package/vite-plugin-shared-react.ts +420 -0
- package/vite-plugin-shared-three.ts +203 -0
- package/vite-plugin-ui-oid.ts +2106 -0
|
@@ -0,0 +1,546 @@
|
|
|
1
|
+
import { sha256Hex } from '../bytes-codec';
|
|
2
|
+
import type {
|
|
3
|
+
PreparedSourceEdit,
|
|
4
|
+
SourceEditRequest,
|
|
5
|
+
SourceWriteBackend,
|
|
6
|
+
} from '../ui-source/source-write-backend';
|
|
7
|
+
import {
|
|
8
|
+
type AppliedResourceChange,
|
|
9
|
+
HistoryOperationError,
|
|
10
|
+
type HistoryService,
|
|
11
|
+
} from './history-service';
|
|
12
|
+
import type { ResourceDescriptor, ResourceDriver, ResourceKey } from './types';
|
|
13
|
+
|
|
14
|
+
const encoder = new TextEncoder();
|
|
15
|
+
const decoder = new TextDecoder();
|
|
16
|
+
|
|
17
|
+
interface SourceResource {
|
|
18
|
+
descriptor: ResourceDescriptor;
|
|
19
|
+
expectedSha: string | null;
|
|
20
|
+
/** Whether the last read said this file is BYTES rather than text. Recorded
|
|
21
|
+
* at preflight (which always precedes a restore) so the restore hands the
|
|
22
|
+
* backend the same kind of value it was given. */
|
|
23
|
+
binary: boolean;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
interface GestureFile {
|
|
27
|
+
resourcePath: string;
|
|
28
|
+
before: string;
|
|
29
|
+
beforeSha: string;
|
|
30
|
+
after: string;
|
|
31
|
+
afterSha: string;
|
|
32
|
+
/** Every source state produced or observed by this gesture. */
|
|
33
|
+
knownShas: Set<string>;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
interface SourceGesture {
|
|
37
|
+
label: string;
|
|
38
|
+
files: Map<string, GestureFile>;
|
|
39
|
+
applyOrder: string[];
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
type WriteResponse = { changed: boolean; [key: string]: unknown };
|
|
43
|
+
|
|
44
|
+
class SourceHistoryManager {
|
|
45
|
+
private readonly resources = new Map<string, SourceResource>();
|
|
46
|
+
private tail: Promise<void> = Promise.resolve();
|
|
47
|
+
|
|
48
|
+
constructor(
|
|
49
|
+
private readonly history: HistoryService,
|
|
50
|
+
private readonly backend: SourceWriteBackend,
|
|
51
|
+
) {}
|
|
52
|
+
|
|
53
|
+
commit(label: string, request: SourceEditRequest): Promise<WriteResponse> {
|
|
54
|
+
try {
|
|
55
|
+
this.history.assertCanRecordAppliedChange();
|
|
56
|
+
} catch (error) {
|
|
57
|
+
return Promise.reject(error);
|
|
58
|
+
}
|
|
59
|
+
const releaseProducer = this.history.reserveProducer();
|
|
60
|
+
return this.enqueue(() => {
|
|
61
|
+
this.history.assertCanRecordAppliedChange();
|
|
62
|
+
return this.prepareAndCommit(label, request);
|
|
63
|
+
}).finally(releaseProducer);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
replaceSource(label: string, file: string, source: string): Promise<boolean> {
|
|
67
|
+
try {
|
|
68
|
+
this.history.assertCanRecordAppliedChange();
|
|
69
|
+
} catch (error) {
|
|
70
|
+
return Promise.reject(error);
|
|
71
|
+
}
|
|
72
|
+
const releaseProducer = this.history.reserveProducer();
|
|
73
|
+
return this.enqueue(async () => {
|
|
74
|
+
this.history.assertCanRecordAppliedChange();
|
|
75
|
+
const current = await this.backend.readSource!(file);
|
|
76
|
+
if (current.source === source) return false;
|
|
77
|
+
const resource = this.resource(file, current.resourcePath);
|
|
78
|
+
return this.history.transaction(
|
|
79
|
+
{ label, resources: [resource.descriptor.key], scope: 'project' },
|
|
80
|
+
async (tx) => {
|
|
81
|
+
await tx.writeText(resource.descriptor.key, source, 'text/typescript');
|
|
82
|
+
return true;
|
|
83
|
+
},
|
|
84
|
+
);
|
|
85
|
+
}).finally(releaseProducer);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Runs the complete callback while holding the manager queue. The callback's
|
|
90
|
+
* scoped backend writes directly into this gesture; calls on the ordinary
|
|
91
|
+
* backend queue after it, so unrelated inspector edits cannot be absorbed or
|
|
92
|
+
* interleaved. Overlapping gestures likewise become distinct queue entries.
|
|
93
|
+
*/
|
|
94
|
+
runGesture<T>(
|
|
95
|
+
label: string,
|
|
96
|
+
operation: (scopedBackend: SourceWriteBackend) => Promise<T>,
|
|
97
|
+
): Promise<T> {
|
|
98
|
+
try {
|
|
99
|
+
this.history.assertCanRecordAppliedChange();
|
|
100
|
+
} catch (error) {
|
|
101
|
+
return Promise.reject(error);
|
|
102
|
+
}
|
|
103
|
+
const releaseProducer = this.history.reserveProducer();
|
|
104
|
+
return this.enqueue(async () => {
|
|
105
|
+
this.history.assertCanRecordAppliedChange();
|
|
106
|
+
const gesture: SourceGesture = { label, files: new Map(), applyOrder: [] };
|
|
107
|
+
try {
|
|
108
|
+
const result = await operation(this.scopedBackend(gesture));
|
|
109
|
+
await this.recordGesture(gesture);
|
|
110
|
+
return result;
|
|
111
|
+
} catch (error) {
|
|
112
|
+
try {
|
|
113
|
+
await this.compensateGesture(gesture);
|
|
114
|
+
} catch (compensationError) {
|
|
115
|
+
throw this.history.blockForCompensationFailure(label, this.gestureResourceKeys(gesture), {
|
|
116
|
+
operationError: error,
|
|
117
|
+
compensationError,
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
if (!(error instanceof HistoryOperationError)) {
|
|
121
|
+
this.history.reportAppliedChangeFailure(label, this.gestureResourceKeys(gesture), error);
|
|
122
|
+
}
|
|
123
|
+
throw error;
|
|
124
|
+
}
|
|
125
|
+
}).finally(releaseProducer);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/** Run `op` after every previously queued source operation. */
|
|
129
|
+
private enqueue<T>(op: () => Promise<T>): Promise<T> {
|
|
130
|
+
const result = this.tail.then(op, op);
|
|
131
|
+
this.tail = result.then(
|
|
132
|
+
() => undefined,
|
|
133
|
+
() => undefined,
|
|
134
|
+
);
|
|
135
|
+
return result;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
private scopedBackend(gesture: SourceGesture): SourceWriteBackend {
|
|
139
|
+
const commit = (request: SourceEditRequest) => this.applyInGesture(gesture, request);
|
|
140
|
+
const { runGesture: _nestedGesture, ...backend } = this.backend;
|
|
141
|
+
return {
|
|
142
|
+
...backend,
|
|
143
|
+
historyManaged: true,
|
|
144
|
+
writeStyle: (oid, prop, value) =>
|
|
145
|
+
commit({ kind: 'style', oid, prop, value }) as ReturnType<SourceWriteBackend['writeStyle']>,
|
|
146
|
+
removeStyle: (oid, prop) =>
|
|
147
|
+
commit({ kind: 'style', oid, prop, value: null }) as ReturnType<
|
|
148
|
+
SourceWriteBackend['removeStyle']
|
|
149
|
+
>,
|
|
150
|
+
writeCss: (file, selector, prop, value, media) =>
|
|
151
|
+
commit({
|
|
152
|
+
kind: 'css',
|
|
153
|
+
file,
|
|
154
|
+
selector,
|
|
155
|
+
prop,
|
|
156
|
+
value,
|
|
157
|
+
...(media !== undefined ? { media } : {}),
|
|
158
|
+
}),
|
|
159
|
+
writeText: (oid, text) => commit({ kind: 'text', oid, text }),
|
|
160
|
+
// Forward the opt-in flags into the gesture-scoped prepare request too
|
|
161
|
+
// (W2's addIfMissing used to be dropped HERE alone — a multi-channel
|
|
162
|
+
// gesture write on a prop the source never authored silently no-op'd
|
|
163
|
+
// while the single-write path appended it; R2's allowShapeUpgrade
|
|
164
|
+
// would have hit the same asymmetry).
|
|
165
|
+
writeProp: (oid, prop, value, opts) =>
|
|
166
|
+
commit({
|
|
167
|
+
kind: 'prop',
|
|
168
|
+
oid,
|
|
169
|
+
prop,
|
|
170
|
+
value,
|
|
171
|
+
...(opts?.addIfMissing ? { addIfMissing: true } : {}),
|
|
172
|
+
...(opts?.allowShapeUpgrade ? { allowShapeUpgrade: true } : {}),
|
|
173
|
+
}),
|
|
174
|
+
// Same removal the ungestured wrapper routes below — kept in step so a
|
|
175
|
+
// revert made inside a gesture belongs to that gesture rather than
|
|
176
|
+
// escaping to the raw backend (the asymmetry `writeProp`'s comment above
|
|
177
|
+
// records having been bitten by once already).
|
|
178
|
+
removeProp: (oid, prop) =>
|
|
179
|
+
commit({ kind: 'prop', oid, prop, value: null }) as ReturnType<
|
|
180
|
+
NonNullable<SourceWriteBackend['removeProp']>
|
|
181
|
+
>,
|
|
182
|
+
writeComponentDefault: (oid, prop, value) =>
|
|
183
|
+
commit({ kind: 'component-default', oid, prop, value }) as ReturnType<
|
|
184
|
+
NonNullable<SourceWriteBackend['writeComponentDefault']>
|
|
185
|
+
>,
|
|
186
|
+
writeStruct: (oid, op, options) =>
|
|
187
|
+
commit({ kind: 'struct', oid, op, ...options }) as ReturnType<
|
|
188
|
+
SourceWriteBackend['writeStruct']
|
|
189
|
+
>,
|
|
190
|
+
writeStructMany: (oids, op, options) =>
|
|
191
|
+
commit({ kind: 'struct-many', oids, op, ...options }) as ReturnType<
|
|
192
|
+
NonNullable<SourceWriteBackend['writeStructMany']>
|
|
193
|
+
>,
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
private async recordGesture(gesture: SourceGesture): Promise<void> {
|
|
198
|
+
const changes = [...gesture.files.entries()]
|
|
199
|
+
.filter(([, touched]) => touched.beforeSha !== touched.afterSha)
|
|
200
|
+
.map(([file, touched]) => {
|
|
201
|
+
const resource = this.resource(file, touched.resourcePath);
|
|
202
|
+
return {
|
|
203
|
+
resource: resource.descriptor.key,
|
|
204
|
+
beforeBytes: encoder.encode(touched.before),
|
|
205
|
+
afterBytes: encoder.encode(touched.after),
|
|
206
|
+
contentType: 'text/plain',
|
|
207
|
+
};
|
|
208
|
+
});
|
|
209
|
+
if (changes.length === 0) return;
|
|
210
|
+
await this.history.recordAppliedTransaction(
|
|
211
|
+
{
|
|
212
|
+
label: gesture.label,
|
|
213
|
+
resources: changes.map((change) => change.resource),
|
|
214
|
+
scope: 'project',
|
|
215
|
+
},
|
|
216
|
+
changes,
|
|
217
|
+
);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
private async prepareAndCommit(
|
|
221
|
+
label: string,
|
|
222
|
+
request: SourceEditRequest,
|
|
223
|
+
): Promise<WriteResponse> {
|
|
224
|
+
const prepared = await this.backend.prepare!(request);
|
|
225
|
+
const response = this.response(prepared);
|
|
226
|
+
if (
|
|
227
|
+
!prepared.changed ||
|
|
228
|
+
!prepared.file ||
|
|
229
|
+
!prepared.resourcePath ||
|
|
230
|
+
prepared.newSource === undefined
|
|
231
|
+
) {
|
|
232
|
+
return response;
|
|
233
|
+
}
|
|
234
|
+
const resource = this.resource(prepared.file, prepared.resourcePath);
|
|
235
|
+
await this.history.transaction(
|
|
236
|
+
{ label, resources: [resource.descriptor.key], scope: 'project' },
|
|
237
|
+
(tx) => tx.writeText(resource.descriptor.key, prepared.newSource!, 'text/plain'),
|
|
238
|
+
);
|
|
239
|
+
return response;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
private async applyInGesture(
|
|
243
|
+
gesture: SourceGesture,
|
|
244
|
+
request: SourceEditRequest,
|
|
245
|
+
): Promise<WriteResponse> {
|
|
246
|
+
const prepared = await this.backend.prepare!(request);
|
|
247
|
+
const response = this.response(prepared);
|
|
248
|
+
if (
|
|
249
|
+
!prepared.changed ||
|
|
250
|
+
!prepared.file ||
|
|
251
|
+
!prepared.resourcePath ||
|
|
252
|
+
prepared.newSource === undefined ||
|
|
253
|
+
prepared.prevSource === undefined ||
|
|
254
|
+
prepared.prevSha === undefined
|
|
255
|
+
) {
|
|
256
|
+
return response;
|
|
257
|
+
}
|
|
258
|
+
const newSha = prepared.newSha ?? (await sha256Hex(encoder.encode(prepared.newSource)));
|
|
259
|
+
const existing = gesture.files.get(prepared.file);
|
|
260
|
+
if (existing) {
|
|
261
|
+
existing.knownShas.add(prepared.prevSha);
|
|
262
|
+
existing.knownShas.add(newSha);
|
|
263
|
+
} else {
|
|
264
|
+
gesture.files.set(prepared.file, {
|
|
265
|
+
resourcePath: prepared.resourcePath,
|
|
266
|
+
before: prepared.prevSource,
|
|
267
|
+
beforeSha: prepared.prevSha,
|
|
268
|
+
after: prepared.prevSource,
|
|
269
|
+
afterSha: prepared.prevSha,
|
|
270
|
+
knownShas: new Set([prepared.prevSha, newSha]),
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
// The candidate is registered before apply. If transport fails after the
|
|
275
|
+
// server wrote, compensation rereads and recognizes this exact hash.
|
|
276
|
+
const touched = gesture.files.get(prepared.file)!;
|
|
277
|
+
touched.after = prepared.newSource;
|
|
278
|
+
touched.afterSha = newSha;
|
|
279
|
+
gesture.applyOrder.push(prepared.file);
|
|
280
|
+
const applied = await this.backend.applySource!(
|
|
281
|
+
prepared.file,
|
|
282
|
+
prepared.newSource,
|
|
283
|
+
prepared.prevSha,
|
|
284
|
+
);
|
|
285
|
+
if (!applied.applied) {
|
|
286
|
+
throw new Error(applied.error ?? `Failed to apply source file "${prepared.file}".`);
|
|
287
|
+
}
|
|
288
|
+
return response;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
/** Restore all touched files in reverse order, guarded by a fresh read/hash. */
|
|
292
|
+
private async compensateGesture(gesture: SourceGesture): Promise<void> {
|
|
293
|
+
const seen = new Set<string>();
|
|
294
|
+
const reverseLastApplyOrder = [...gesture.applyOrder].reverse().filter((file) => {
|
|
295
|
+
if (seen.has(file)) return false;
|
|
296
|
+
seen.add(file);
|
|
297
|
+
return true;
|
|
298
|
+
});
|
|
299
|
+
for (const file of reverseLastApplyOrder) {
|
|
300
|
+
const touched = gesture.files.get(file)!;
|
|
301
|
+
const current = await this.backend.readSource!(file);
|
|
302
|
+
const currentSha = await sha256Hex(encoder.encode(current.source));
|
|
303
|
+
if (current.sha !== currentSha) {
|
|
304
|
+
throw new Error(`Source file "${file}" returned bytes that do not match its hash.`);
|
|
305
|
+
}
|
|
306
|
+
if (currentSha === touched.beforeSha) continue;
|
|
307
|
+
if (!touched.knownShas.has(currentSha)) {
|
|
308
|
+
throw new Error(`Source file "${file}" changed outside the failed gesture.`);
|
|
309
|
+
}
|
|
310
|
+
const restored = await this.backend.applySource!(file, touched.before, currentSha);
|
|
311
|
+
if (!restored.applied) {
|
|
312
|
+
throw new Error(restored.error ?? `Failed to compensate source file "${file}".`);
|
|
313
|
+
}
|
|
314
|
+
const verified = await this.backend.readSource!(file);
|
|
315
|
+
const verifiedSha = await sha256Hex(encoder.encode(verified.source));
|
|
316
|
+
if (verified.sha !== verifiedSha || verifiedSha !== touched.beforeSha) {
|
|
317
|
+
throw new Error(`Source file "${file}" compensated with the wrong hash.`);
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
private gestureResourceKeys(gesture: SourceGesture): ResourceKey[] {
|
|
323
|
+
return [...gesture.files.entries()].map(
|
|
324
|
+
([file, touched]) => this.resource(file, touched.resourcePath).descriptor.key,
|
|
325
|
+
);
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
private response(prepared: PreparedSourceEdit): WriteResponse {
|
|
329
|
+
return {
|
|
330
|
+
changed: prepared.changed,
|
|
331
|
+
...prepared.result,
|
|
332
|
+
file: prepared.file,
|
|
333
|
+
prevSource: prepared.prevSource,
|
|
334
|
+
newSource: prepared.newSource,
|
|
335
|
+
prevSha: prepared.prevSha,
|
|
336
|
+
newSha: prepared.newSha,
|
|
337
|
+
};
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
/** The registered history key for one source file — see
|
|
341
|
+
* {@link projectSourceAppliedChange}, the only caller that needs the key
|
|
342
|
+
* without also needing this manager to journal the change. */
|
|
343
|
+
sourceResourceKey(file: string, resourcePath: string): ResourceKey {
|
|
344
|
+
return this.resource(file, resourcePath).descriptor.key;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
private resource(file: string, resourcePath: string): SourceResource {
|
|
348
|
+
const existing = this.resources.get(file);
|
|
349
|
+
if (existing) return existing;
|
|
350
|
+
const descriptor = this.history.registry.registerProject('source', resourcePath);
|
|
351
|
+
const resource: SourceResource = { descriptor, expectedSha: null, binary: false };
|
|
352
|
+
const driver: ResourceDriver = {
|
|
353
|
+
descriptor,
|
|
354
|
+
capture: async () => {
|
|
355
|
+
const current = await this.backend.readSource!(file);
|
|
356
|
+
resource.binary = current.bytes !== undefined;
|
|
357
|
+
return {
|
|
358
|
+
revision: 0,
|
|
359
|
+
contentType: resource.binary ? 'application/octet-stream' : 'text/plain',
|
|
360
|
+
// The FILE's bytes, never the wire's — `sha256` below is the file's
|
|
361
|
+
// digest and the two have to describe the same thing.
|
|
362
|
+
bytes: current.bytes ?? encoder.encode(current.source),
|
|
363
|
+
sha256: current.sha,
|
|
364
|
+
};
|
|
365
|
+
},
|
|
366
|
+
preflight: async (expected) => {
|
|
367
|
+
const current = await this.backend.readSource!(file);
|
|
368
|
+
resource.expectedSha = current.sha;
|
|
369
|
+
resource.binary = current.bytes !== undefined;
|
|
370
|
+
return current.sha === expected.sha256
|
|
371
|
+
? { ok: true }
|
|
372
|
+
: { ok: false, reason: 'content-conflict', actualSha256: current.sha };
|
|
373
|
+
},
|
|
374
|
+
restore: async (snapshot) => {
|
|
375
|
+
const expectedSha = resource.expectedSha;
|
|
376
|
+
resource.expectedSha = null;
|
|
377
|
+
if (!expectedSha) throw new Error(`Source resource "${file}" was not preflighted.`);
|
|
378
|
+
const stored = this.history.snapshots.read(snapshot).bytes;
|
|
379
|
+
const source = resource.binary ? stored : decoder.decode(stored);
|
|
380
|
+
const result = await this.backend.applySource!(file, source, expectedSha);
|
|
381
|
+
if (!result.applied)
|
|
382
|
+
throw new Error(result.error ?? `Failed to apply source file "${file}".`);
|
|
383
|
+
const actual =
|
|
384
|
+
result.sha ??
|
|
385
|
+
(await sha256Hex(typeof source === 'string' ? encoder.encode(source) : source));
|
|
386
|
+
if (actual !== snapshot.sha256)
|
|
387
|
+
throw new Error(`Source file "${file}" restored with the wrong hash.`);
|
|
388
|
+
},
|
|
389
|
+
estimateBytes: (snapshot) => snapshot.byteLength,
|
|
390
|
+
};
|
|
391
|
+
this.history.registerDriver(driver);
|
|
392
|
+
this.resources.set(file, resource);
|
|
393
|
+
return resource;
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
const managers = new WeakMap<HistoryService, WeakMap<object, SourceHistoryManager>>();
|
|
398
|
+
|
|
399
|
+
function sourceHistoryManager(
|
|
400
|
+
backend: SourceWriteBackend,
|
|
401
|
+
history: HistoryService,
|
|
402
|
+
): SourceHistoryManager {
|
|
403
|
+
let byBackend = managers.get(history);
|
|
404
|
+
if (!byBackend) {
|
|
405
|
+
byBackend = new WeakMap();
|
|
406
|
+
managers.set(history, byBackend);
|
|
407
|
+
}
|
|
408
|
+
const identity = backend.historyIdentity ?? backend;
|
|
409
|
+
let manager = byBackend.get(identity);
|
|
410
|
+
if (!manager) {
|
|
411
|
+
manager = new SourceHistoryManager(history, backend);
|
|
412
|
+
byBackend.set(identity, manager);
|
|
413
|
+
}
|
|
414
|
+
return manager;
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
/**
|
|
418
|
+
* The applied-change record for one project source file's before→after bytes,
|
|
419
|
+
* with its history resource registered (or reused) — but NOT journaled.
|
|
420
|
+
*
|
|
421
|
+
* Every other entry point here journals its own transaction, which is right
|
|
422
|
+
* when the source IS the truth: an R3F undo rewrites the file and the live tree
|
|
423
|
+
* follows on re-render. The ingest write-back is the case where it is not —
|
|
424
|
+
* an unmodified game does not re-derive its scene from source, so the file
|
|
425
|
+
* and the live `Object3D` are two halves of one edit, and putting them in two
|
|
426
|
+
* transactions would mean two Ctrl+Z presses to undo one drag, with a window in
|
|
427
|
+
* between where the file and the running game disagree.
|
|
428
|
+
*
|
|
429
|
+
* Handing the caller the change record instead of committing it lets both
|
|
430
|
+
* halves go into ONE `recordAppliedTransaction`, which is the whole of what
|
|
431
|
+
* this export exists for. It deliberately does not know what the other half is.
|
|
432
|
+
*/
|
|
433
|
+
export function projectSourceAppliedChange(
|
|
434
|
+
backend: SourceWriteBackend,
|
|
435
|
+
history: HistoryService,
|
|
436
|
+
options: {
|
|
437
|
+
readonly file: string;
|
|
438
|
+
readonly resourcePath: string;
|
|
439
|
+
/** Bytes for a file that is not text — see `SourceWriteBackend.readSource`. */
|
|
440
|
+
readonly before: string | Uint8Array;
|
|
441
|
+
readonly after: string | Uint8Array;
|
|
442
|
+
},
|
|
443
|
+
): AppliedResourceChange {
|
|
444
|
+
if (!backend.readSource || !backend.applySource) {
|
|
445
|
+
throw new Error('This editor tier cannot write project source.');
|
|
446
|
+
}
|
|
447
|
+
const manager = sourceHistoryManager(backend, history);
|
|
448
|
+
return {
|
|
449
|
+
resource: manager.sourceResourceKey(options.file, options.resourcePath),
|
|
450
|
+
beforeBytes:
|
|
451
|
+
typeof options.before === 'string' ? encoder.encode(options.before) : options.before,
|
|
452
|
+
afterBytes: typeof options.after === 'string' ? encoder.encode(options.after) : options.after,
|
|
453
|
+
contentType: typeof options.after === 'string' ? 'text/plain' : 'application/octet-stream',
|
|
454
|
+
};
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
/** Replace one project-owned source file through checksum-guarded project history. */
|
|
458
|
+
export function replaceProjectSource(
|
|
459
|
+
backend: SourceWriteBackend,
|
|
460
|
+
history: HistoryService,
|
|
461
|
+
options: { readonly file: string; readonly source: string; readonly label: string },
|
|
462
|
+
): Promise<boolean> {
|
|
463
|
+
if (!backend.readSource || !backend.applySource) {
|
|
464
|
+
return Promise.reject(new Error('This editor tier cannot write project source.'));
|
|
465
|
+
}
|
|
466
|
+
return sourceHistoryManager(backend, history).replaceSource(
|
|
467
|
+
options.label,
|
|
468
|
+
options.file,
|
|
469
|
+
options.source,
|
|
470
|
+
);
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
/** Routes the existing React authoring seam through prepare → HistoryService → guarded apply. */
|
|
474
|
+
export function withProjectSourceHistory(
|
|
475
|
+
backend: SourceWriteBackend | undefined,
|
|
476
|
+
history: HistoryService | null,
|
|
477
|
+
): SourceWriteBackend | undefined {
|
|
478
|
+
if (!backend || !history || !backend.prepare || !backend.readSource || !backend.applySource) {
|
|
479
|
+
return backend;
|
|
480
|
+
}
|
|
481
|
+
const manager = sourceHistoryManager(backend, history);
|
|
482
|
+
const commit = (label: string, request: SourceEditRequest) => manager!.commit(label, request);
|
|
483
|
+
const activeManager = manager;
|
|
484
|
+
return {
|
|
485
|
+
...backend,
|
|
486
|
+
historyManaged: true,
|
|
487
|
+
runGesture: (label, operation) => activeManager.runGesture(label, operation),
|
|
488
|
+
writeStyle: (oid, prop, value) =>
|
|
489
|
+
commit(`Set ${prop}`, { kind: 'style', oid, prop, value }) as ReturnType<
|
|
490
|
+
SourceWriteBackend['writeStyle']
|
|
491
|
+
>,
|
|
492
|
+
removeStyle: (oid, prop) =>
|
|
493
|
+
commit(`Remove ${prop}`, { kind: 'style', oid, prop, value: null }) as ReturnType<
|
|
494
|
+
SourceWriteBackend['removeStyle']
|
|
495
|
+
>,
|
|
496
|
+
writeCss: (file, selector, prop, value, media) =>
|
|
497
|
+
commit(`Set ${prop}`, {
|
|
498
|
+
kind: 'css',
|
|
499
|
+
file,
|
|
500
|
+
selector,
|
|
501
|
+
prop,
|
|
502
|
+
value,
|
|
503
|
+
...(media !== undefined ? { media } : {}),
|
|
504
|
+
}),
|
|
505
|
+
writeText: (oid, text) => commit('Edit Text', { kind: 'text', oid, text }),
|
|
506
|
+
writeProp: (oid, prop, value, opts) =>
|
|
507
|
+
commit(`Set ${prop}`, {
|
|
508
|
+
kind: 'prop',
|
|
509
|
+
oid,
|
|
510
|
+
prop,
|
|
511
|
+
value,
|
|
512
|
+
...(opts?.addIfMissing ? { addIfMissing: true } : {}),
|
|
513
|
+
...(opts?.allowShapeUpgrade ? { allowShapeUpgrade: true } : {}),
|
|
514
|
+
}),
|
|
515
|
+
// H4 — the inspector's revert arrow. It used to fall through the `...backend`
|
|
516
|
+
// spread to the RAW backend: the attribute really was deleted, but outside
|
|
517
|
+
// the transaction, so it left no undo entry and no checksum guard while
|
|
518
|
+
// every other write on this seam had both. Same `value: null` removal
|
|
519
|
+
// sentinel `removeStyle` above uses.
|
|
520
|
+
removeProp: (oid, prop) =>
|
|
521
|
+
commit(`Revert ${prop}`, { kind: 'prop', oid, prop, value: null }) as ReturnType<
|
|
522
|
+
NonNullable<SourceWriteBackend['removeProp']>
|
|
523
|
+
>,
|
|
524
|
+
writeComponentDefault: (oid, prop, value) =>
|
|
525
|
+
commit(`Apply ${prop} to Component`, {
|
|
526
|
+
kind: 'component-default',
|
|
527
|
+
oid,
|
|
528
|
+
prop,
|
|
529
|
+
value,
|
|
530
|
+
}) as ReturnType<NonNullable<SourceWriteBackend['writeComponentDefault']>>,
|
|
531
|
+
writeStruct: (oid, op, options) =>
|
|
532
|
+
commit(`${op[0]?.toUpperCase() ?? ''}${op.slice(1)}`, {
|
|
533
|
+
kind: 'struct',
|
|
534
|
+
oid,
|
|
535
|
+
op,
|
|
536
|
+
...options,
|
|
537
|
+
}),
|
|
538
|
+
writeStructMany: (oids, op, options) =>
|
|
539
|
+
commit(`${op[0]?.toUpperCase() ?? ''}${op.slice(1)} ${oids.length} Elements`, {
|
|
540
|
+
kind: 'struct-many',
|
|
541
|
+
oids,
|
|
542
|
+
op,
|
|
543
|
+
...options,
|
|
544
|
+
}),
|
|
545
|
+
};
|
|
546
|
+
}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
declare const resourceKeyBrand: unique symbol;
|
|
2
|
+
|
|
3
|
+
/** Stable for the lifetime of one open project session, including across file moves. */
|
|
4
|
+
export type ResourceKey = string & { readonly [resourceKeyBrand]: true };
|
|
5
|
+
|
|
6
|
+
export type ResourceKind =
|
|
7
|
+
| 'scene'
|
|
8
|
+
| 'ui-tree'
|
|
9
|
+
| 'material'
|
|
10
|
+
| 'data'
|
|
11
|
+
| 'manifest'
|
|
12
|
+
| 'settings'
|
|
13
|
+
| 'source'
|
|
14
|
+
| 'overlay'
|
|
15
|
+
| 'project-file'
|
|
16
|
+
| 'session-state';
|
|
17
|
+
|
|
18
|
+
export interface ResourceDescriptor {
|
|
19
|
+
readonly key: ResourceKey;
|
|
20
|
+
readonly kind: ResourceKind;
|
|
21
|
+
readonly scope: 'project' | 'session';
|
|
22
|
+
readonly displayName: string;
|
|
23
|
+
readonly location: string | null;
|
|
24
|
+
readonly sessionId: string | null;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface ResourceSnapshot {
|
|
28
|
+
readonly revision: number;
|
|
29
|
+
readonly contentType: string;
|
|
30
|
+
readonly bytes: Uint8Array;
|
|
31
|
+
readonly sha256: string;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface SnapshotRef {
|
|
35
|
+
readonly revision: number;
|
|
36
|
+
readonly contentType: string;
|
|
37
|
+
readonly sha256: string;
|
|
38
|
+
readonly blobKey: string;
|
|
39
|
+
readonly byteLength: number;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export type PreflightResult =
|
|
43
|
+
| { readonly ok: true }
|
|
44
|
+
| {
|
|
45
|
+
readonly ok: false;
|
|
46
|
+
readonly reason: 'missing' | 'revision-conflict' | 'content-conflict' | 'expired';
|
|
47
|
+
readonly actualRevision?: number;
|
|
48
|
+
readonly actualSha256?: string;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export interface ResourceDriver {
|
|
52
|
+
readonly descriptor: ResourceDescriptor;
|
|
53
|
+
capture(): Promise<ResourceSnapshot>;
|
|
54
|
+
preflight(expected: SnapshotRef): Promise<PreflightResult>;
|
|
55
|
+
restore(snapshot: SnapshotRef): Promise<void>;
|
|
56
|
+
estimateBytes(snapshot: SnapshotRef): number;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export type HistoryStatus =
|
|
60
|
+
| 'committed'
|
|
61
|
+
| 'undoing'
|
|
62
|
+
| 'undone'
|
|
63
|
+
| 'redoing'
|
|
64
|
+
| 'failed'
|
|
65
|
+
| 'failed-partial'
|
|
66
|
+
| 'expired';
|
|
67
|
+
|
|
68
|
+
export interface HistoryError {
|
|
69
|
+
readonly code:
|
|
70
|
+
| 'busy'
|
|
71
|
+
| 'conflict'
|
|
72
|
+
| 'expired'
|
|
73
|
+
| 'apply-failed'
|
|
74
|
+
| 'compensation-failed'
|
|
75
|
+
| 'history-limit';
|
|
76
|
+
readonly message: string;
|
|
77
|
+
readonly resources: readonly ResourceKey[];
|
|
78
|
+
readonly cause?: unknown;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Two independent budgets evict undo entries, and which one binds first depends
|
|
83
|
+
* entirely on what is being edited. Naming the budget is the whole point of the
|
|
84
|
+
* warning: a count-only warning is a lie whenever bytes bind first.
|
|
85
|
+
*/
|
|
86
|
+
export type HistoryBudget = 'transactions' | 'bytes';
|
|
87
|
+
|
|
88
|
+
/** Emitted once per threshold crossing, before any undo depth is actually lost. */
|
|
89
|
+
export interface HistoryLimitWarning {
|
|
90
|
+
readonly budget: HistoryBudget;
|
|
91
|
+
/** Entry count, or unique retained snapshot bytes, at the moment of crossing. */
|
|
92
|
+
readonly used: number;
|
|
93
|
+
readonly limit: number;
|
|
94
|
+
readonly message: string;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/** Reported whenever trimming actually dropped entries — eviction is never silent. */
|
|
98
|
+
export interface HistoryEviction {
|
|
99
|
+
readonly budget: HistoryBudget;
|
|
100
|
+
readonly droppedCount: number;
|
|
101
|
+
/** Entries dropped over the life of this in-memory session. */
|
|
102
|
+
readonly totalDropped: number;
|
|
103
|
+
readonly message: string;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export interface ResourceChange {
|
|
107
|
+
readonly resource: ResourceKey;
|
|
108
|
+
readonly before: SnapshotRef;
|
|
109
|
+
readonly after: SnapshotRef;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export interface HistoryTransaction {
|
|
113
|
+
readonly id: string;
|
|
114
|
+
readonly label: string;
|
|
115
|
+
readonly detail: string | null;
|
|
116
|
+
readonly timestamp: number;
|
|
117
|
+
readonly scope: 'project' | 'session';
|
|
118
|
+
readonly sessionId: string | null;
|
|
119
|
+
readonly changes: readonly ResourceChange[];
|
|
120
|
+
readonly byteSize: number;
|
|
121
|
+
readonly mergeKey: string | null;
|
|
122
|
+
readonly status: HistoryStatus;
|
|
123
|
+
readonly error: HistoryError | null;
|
|
124
|
+
}
|