@volter/editor-game 0.5.65 → 0.5.66

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (141) hide show
  1. package/contributions/generation.service.ts +2 -2
  2. package/contributions/generations.status.tsx +1 -1
  3. package/contributions/godot.palette.json +99 -0
  4. package/contributions/godot.style.ts +62 -0
  5. package/contributions/godot.view.ts +69 -0
  6. package/contributions/ingest.service.ts +3 -3
  7. package/contributions/play.command.ts +1 -1
  8. package/contributions/react/react-inspector.service.ts +2 -2
  9. package/contributions/scene-document.service.ts +3 -3
  10. package/contributions/three/component-verbs.command.ts +3 -3
  11. package/contributions/unity.palette.json +102 -0
  12. package/contributions/unity.style.ts +62 -0
  13. package/contributions/unity.view.ts +76 -0
  14. package/contributions/unreal.palette.json +105 -0
  15. package/contributions/unreal.style.ts +58 -0
  16. package/contributions/unreal.view.ts +88 -0
  17. package/dist-node/serving.mjs +16 -0
  18. package/package.json +21 -14
  19. package/serving/index.ts +27 -0
  20. package/src/asset-budget/asset-budget-model.ts +3 -3
  21. package/src/asset-budget/optimize-apply.ts +7 -7
  22. package/src/bridge/dispatch.ts +2 -2
  23. package/src/bridge/screenshot.ts +3 -3
  24. package/src/coverage/live-authoring-surface.ts +1 -1
  25. package/src/coverage/live-project-verbs.ts +1 -1
  26. package/src/coverage/native-system-coverage.ts +1 -1
  27. package/src/coverage/session-coverage.ts +2 -2
  28. package/src/design-system-stories/InspectorNarrowBodies.stories.tsx +10 -50
  29. package/src/game-document/GameCaptureFrameButton.tsx +1 -1
  30. package/src/game-document/GamePanel.tsx +4 -4
  31. package/src/generation/GenerationActivity.tsx +3 -5
  32. package/src/generation/generation-documents.tsx +3 -3
  33. package/src/generation/generation-jobs.ts +1 -1
  34. package/src/generation/generation-presentation.ts +1 -1
  35. package/src/host/adapter-reach.ts +1 -1
  36. package/src/host/adapter-runtime-bindings.ts +1 -1
  37. package/src/host/api/configurations.ts +2 -2
  38. package/src/host/authoring/babylon-authoring-adapter.ts +2 -2
  39. package/src/host/authoring/contract-hierarchy-authoring.ts +1 -1
  40. package/src/host/authoring/contract-scenes-stories.ts +1 -1
  41. package/src/host/authoring/creation-site-related.ts +2 -2
  42. package/src/host/authoring/ephemeral-persistence.ts +1 -1
  43. package/src/host/authoring/gesture-persist.ts +1 -1
  44. package/src/host/authoring/ingest-source-persistence.ts +4 -4
  45. package/src/host/authoring/mount-isolated-pixi-screen.ts +1 -1
  46. package/src/host/authoring/pixi-authoring-adapter.ts +2 -2
  47. package/src/host/authoring/pixi-live-write-target.ts +3 -3
  48. package/src/host/authoring/pixi-still-presentation.ts +1 -1
  49. package/src/host/authoring/pixi-structure-history.ts +1 -1
  50. package/src/host/authoring/source-persistence-backend.ts +3 -3
  51. package/src/host/authoring/struct-write-pipe.ts +2 -2
  52. package/src/host/browser-transpile.ts +1 -1
  53. package/src/host/canvas-entry-runtime.ts +1 -1
  54. package/src/host/components/HeaderTelemetry.tsx +5 -12
  55. package/src/host/components/PixiIsolationSceneContent.tsx +8 -7
  56. package/src/host/components/ThreeIsolationSceneContent.tsx +2 -2
  57. package/src/host/components/scene-document.tsx +15 -47
  58. package/src/host/components/world-root-stage-binding.tsx +6 -15
  59. package/src/host/components/world-root-stage.ts +60 -14
  60. package/src/host/coverage/capability-coverage.ts +13 -1
  61. package/src/host/coverage/game-contract-seam-evidence.ts +1 -1
  62. package/src/host/coverage/project-verb-coverage.ts +2 -17
  63. package/src/host/coverage/system-adapter-coverage.ts +1 -1
  64. package/src/host/design-system-stories/fixtures/editor-runtime.tsx +9 -1
  65. package/src/host/document-preview-three.ts +1 -1
  66. package/src/host/game-module-access.ts +1 -1
  67. package/src/host/game-realm-page.ts +15 -7
  68. package/src/host/game-realm-reclaim.ts +1 -1
  69. package/src/host/gated-globals.ts +4 -4
  70. package/src/host/history/json-history-resource.ts +2 -2
  71. package/src/host/instance-extract-actions.ts +1 -1
  72. package/src/host/instance-fork-actions.ts +1 -1
  73. package/src/host/projection/dom.ts +2 -2
  74. package/src/host/projection/pixi.ts +1 -1
  75. package/src/host/r3f-entry-runtime.ts +1 -1
  76. package/src/host/react-mount-runtime.ts +1 -1
  77. package/src/host/realm-services.ts +1 -1
  78. package/src/host/roots/module-root.ts +1 -1
  79. package/src/host/scene-view-drawability.ts +2 -2
  80. package/src/host/server-log-bridge.ts +1 -1
  81. package/src/host/three-ingest-runtime.ts +1 -1
  82. package/src/host/use-active-performance-source.ts +1 -1
  83. package/src/ingest/active-ingest.ts +1 -1
  84. package/src/ingest/authoring/ingest-root-adapter.ts +5 -5
  85. package/src/ingest/capture-wait-report.ts +1 -1
  86. package/src/ingest/deferred-ingest-play.ts +5 -4
  87. package/src/ingest/ingest-boot-viewport.ts +4 -6
  88. package/src/ingest/ingest-canvas-scene-document.tsx +9 -8
  89. package/src/ingest/ingest-canvas-scene.ts +2 -5
  90. package/src/ingest/ingest-play-control.ts +3 -3
  91. package/src/ingest/ingest-render-debug.ts +1 -1
  92. package/src/ingest/ingest-siblings.ts +3 -3
  93. package/src/ingest/module-mode.ts +4 -5
  94. package/src/ingest/mount-canvas-ingest-root.ts +6 -6
  95. package/src/ingest/mount-coverage.ts +2 -2
  96. package/src/ingest/mount-dom-ingest-root.ts +5 -5
  97. package/src/ingest/mount-ingest-root.ts +7 -7
  98. package/src/ingest/mount-three-ingest-root.ts +4 -4
  99. package/src/ingest/unmount-ingest-root.ts +2 -2
  100. package/src/play/play-mode.ts +30 -16
  101. package/src/play/play-recording.ts +1 -1
  102. package/src/profiler/PerformancePanel.tsx +1 -1
  103. package/src/react/design-time-react-mount.ts +17 -23
  104. package/src/react/dom-authoring-adapter.ts +2 -2
  105. package/src/react/react-inspector-section.tsx +8 -8
  106. package/src/react/react-world-authoring-adapter.ts +20 -132
  107. package/src/react/story-documents/story-documents.tsx +9 -13
  108. package/src/react/ui-board-document.tsx +3 -4
  109. package/src/react/ui-component-board.ts +3 -3
  110. package/src/three/authoring/camera-runtime-inspector-section.tsx +1 -1
  111. package/src/three/authoring/constraint-inspector-section.tsx +3 -3
  112. package/src/three/authoring/model-asset-inspector-section.tsx +7 -11
  113. package/src/three/authoring/oid-source-persistence.ts +6 -6
  114. package/src/three/authoring/r3f-design-session.ts +21 -7
  115. package/src/three/authoring/r3f-source-authoring-adapter.ts +17 -17
  116. package/src/three/authoring/reflection-probe-inspector-section.tsx +3 -3
  117. package/src/three/authoring/spatial-joint-handles.ts +1 -1
  118. package/src/three/authoring/spatial-lod-handles.ts +1 -1
  119. package/src/three/authoring/spatial-particle-handles.ts +1 -1
  120. package/src/three/authoring/three-authoring-adapter.ts +4 -4
  121. package/src/three/component-verbs/extract-menu.ts +1 -1
  122. package/src/three/component-verbs/fork-menu.ts +1 -1
  123. package/src/three/component-verbs/internals-menu.ts +1 -1
  124. package/src/three/drei-asset-caches.ts +13 -0
  125. package/src/three/story-documents/three-story-documents.tsx +11 -21
  126. package/src/three/three-board/ThreeBoardDocument.tsx +12 -13
  127. package/src/three/three-board/board-scene.ts +1 -1
  128. package/src/three/three-board/three-component-board.ts +3 -3
  129. package/contributions/react/pasteboard.action.ts +0 -41
  130. package/contributions/xstate-behavior.action.ts +0 -42
  131. package/contributions/xstate-behavior.document.tsx +0 -73
  132. package/contributions/xstate-behavior.inspector.tsx +0 -28
  133. package/contributions/xstate-behavior.menu.ts +0 -23
  134. package/src/react/pasteboard-materialize.ts +0 -154
  135. package/src/xstate/XStateBehaviorSection.tsx +0 -130
  136. package/src/xstate/XStateMachineInspector.tsx +0 -566
  137. package/src/xstate/character-animation-machine.fixture.ts +0 -74
  138. package/src/xstate/live-behaviors.ts +0 -106
  139. package/src/xstate/use-live-actor-state.ts +0 -44
  140. package/src/xstate/xstate-graph.ts +0 -235
  141. package/src/xstate/xstate-layout.ts +0 -76
@@ -43,9 +43,9 @@
43
43
  * mount ends — which is also when the edits themselves expire.
44
44
  */
45
45
 
46
- import { numericStyleValue } from '@volter/editor-core/authoring/css-numeric-style';
46
+ import { numericStyleValue } from '@volter/editor-sdk/css-numeric-style';
47
47
  import { createEphemeralPersistence } from '../host/authoring/ephemeral-persistence';
48
- import { LIVE_ONLY_DESTINATION } from '@volter/editor-core/authoring/write-pipe';
48
+ import { LIVE_ONLY_DESTINATION } from '@volter/editor-sdk/kit/write-pipe';
49
49
  import type { EditorShellStore } from '@volter/editor-core/editor-shell-store';
50
50
  import { type JournalSubject, JsonHistoryResource } from '../host/history/json-history-resource';
51
51
  import { DomProjector, structuralDomIdentity } from '../host/projection/dom';
@@ -52,13 +52,13 @@ import {
52
52
  activeBreakpoint,
53
53
  setActiveBreakpoint,
54
54
  subscribeBreakpoint,
55
- } from '@volter/editor-core/authoring/breakpoint-state';
55
+ } from '@volter/editor-sdk/kit/breakpoint-state';
56
56
  import { CompositeAuthoringAdapter } from '@volter/editor-core/authoring/composite-authoring-adapter';
57
- import { numericStyleValue, UNITLESS_NUMBER_PROPS } from '@volter/editor-core/authoring/css-numeric-style';
58
- import { beginEyedropperSession } from '@volter/editor-core/authoring/eyedropper-session';
59
- import { groupProperties } from '@volter/editor-core/components/inspector-property-grouping';
57
+ import { numericStyleValue, UNITLESS_NUMBER_PROPS } from '@volter/editor-sdk/css-numeric-style';
58
+ import { beginEyedropperSession } from '@volter/editor-sdk/kit/eyedropper-session';
59
+ import { groupProperties } from '@volter/editor-sdk/kit/inspector-property-grouping';
60
60
  import { useEditorStore } from '@volter/editor-core/editor-runtime';
61
- import { createHmrRegistrationGroup } from '@volter/editor-core/hmr-registration-group';
61
+ import { createHmrRegistrationGroup } from '@volter/editor-sdk/kit/hmr-registration-group';
62
62
  import { groupIcon } from '@volter/editor-core/inspection/compose';
63
63
  import {
64
64
  GROUP_SECTION_ORDER,
@@ -66,10 +66,10 @@ import {
66
66
  type InspectionSection,
67
67
  PROPERTIES_SECTION_ID,
68
68
  PROPERTIES_SECTION_ORDER,
69
- } from '@volter/editor-core/inspection/model';
70
- import { registerInspectorSections } from '@volter/editor-core/inspector-section-registry';
69
+ } from '@volter/editor-sdk/kit/inspection-model';
70
+ import { registerInspectorSections } from '@volter/editor-sdk/kit/inspector-section-registry';
71
71
  import { effectiveColorFromChain, getAvailableFonts } from '@volter/editor-core/ui-source/inspect';
72
- import type { OidEntry } from '@volter/editor-core/ui-source/oid-transform';
72
+ import type { OidEntry } from '@volter/editor-react/source/oid-transform';
73
73
  import type { AuthoringAdapter, EditorNode, PropertyDescriptor } from '@volter/editor-project/adapter';
74
74
  import {
75
75
  AlignmentGrid,
@@ -6,7 +6,7 @@
6
6
  * entities ARE the `data-oid`-stamped elements of its rendered DOM (the OID
7
7
  * instrumentation from the UI visual-edit program, `../ui-source/oid-transform.ts`,
8
8
  * whose vite-plugin include this slice widens from the `editable-components` fixture
9
- * dir to project scope — see `../../vite-plugin-ui-oid.ts`). This adapter derives
9
+ * dir to project scope — see `@volter/editor-react`'s `serving/ui-oid-plugin.ts`). This adapter derives
10
10
  * its hierarchy from the shared DOM projector (`../projection/dom.ts`) under the
11
11
  * OID identity, over the world's live DOM root (`RootInstance.reactRoot()`);
12
12
  * there is no cached/mirrored state to fall out of sync — every `hierarchy`
@@ -15,7 +15,7 @@
15
15
  * Writes (style/className/delete) reuse the EXISTING T3.2-slice-3 source-write seam
16
16
  * verbatim (`../ui-source/source-write-backend.ts`'s `SourceWriteBackend`, the same
17
17
  * `/__ui-source/write` + `/__ui-source/struct` dev-server endpoints
18
- * `vite-plugin-ui-oid.ts` serves for `UIAuthoringAdapter`/`SourceEditPanel`) — this
18
+ * `@volter/editor-react`'s `serving/ui-oid-plugin.ts` serves for `UIAuthoringAdapter`/`SourceEditPanel`) — this
19
19
  * file does NOT invent a second source-writer. Every edit prepares complete next-file
20
20
  * text and commits it through one checksum-guarded source history resource. Style,
21
21
  * text, prop, and structural changes therefore share exact-byte undo/redo semantics.
@@ -27,23 +27,23 @@
27
27
  * unavailable via a loud console warning instead of silently no-op'ing).
28
28
  */
29
29
 
30
- import { activeBreakpoint } from '@volter/editor-core/authoring/breakpoint-state';
30
+ import { activeBreakpoint } from '@volter/editor-sdk/kit/breakpoint-state';
31
31
  import {
32
32
  cssTextForStyleValue,
33
33
  numericStyleValue,
34
34
  preserveNumericStyleUnit,
35
- } from '@volter/editor-core/authoring/css-numeric-style';
36
- import { WORLD_SCOPE_NODE_ID } from '@volter/editor-core/authoring/stories-scope';
35
+ } from '@volter/editor-sdk/css-numeric-style';
36
+ import { WORLD_SCOPE_NODE_ID } from '@volter/editor-sdk/kit/stories-scope';
37
37
  import { createStructWritePipe, type StructOpOptions } from '../host/authoring/struct-write-pipe';
38
- import { getRootPan } from '@volter/editor-core/authoring/world-pan-state';
38
+ import { getRootPan } from '@volter/editor-sdk/kit/world-pan-state';
39
39
  import {
40
40
  resolvesLiveOnly,
41
41
  runWritePipe,
42
42
  type WriteAck,
43
43
  type WriteResolution,
44
- } from '@volter/editor-core/authoring/write-pipe';
44
+ } from '@volter/editor-sdk/kit/write-pipe';
45
45
  import { guideClientEdges } from '@volter/editor-core/components/board-guides';
46
- import { editorConsole } from '@volter/editor-core/editor-console';
46
+ import { editorConsole } from '@volter/editor-sdk/kit/editor-console';
47
47
  import type { EditorShellStore } from '@volter/editor-core/editor-shell-store';
48
48
  import { withProjectSourceHistory } from '@volter/editor-core/history/source-history-backend';
49
49
  import { DomProjector, oidDomIdentity, projectOidDom } from '../host/projection/dom';
@@ -52,7 +52,7 @@ import { storyDiscoveryUnavailable } from '@volter/editor-core/stories/story-dis
52
52
  import { deriveStoryGroupPath, formatStoryGroupPath } from '@volter/editor-core/stories/story-grouping';
53
53
  import type { StoryPresentationIndex } from '@volter/editor-core/stories/story-presentation';
54
54
  import { subscribeProjectStoryModules } from '@volter/editor-core/stories/story-registry';
55
- import { showTransientHint } from '@volter/editor-core/transient-hint';
55
+ import { showTransientHint } from '@volter/editor-sdk/kit/transient-hint';
56
56
  import {
57
57
  browserOrInlineResolver,
58
58
  type ComputedStyleResolver,
@@ -62,7 +62,6 @@ import {
62
62
  findClassRuleSource,
63
63
  findEmptyContainers,
64
64
  firstPartyStylesheetFiles,
65
- getCallSiteOid,
66
65
  getComponentProps,
67
66
  getComputedStyleValue,
68
67
  getDesignTokens,
@@ -70,8 +69,8 @@ import {
70
69
  getReactComponentName,
71
70
  type MatchableElement,
72
71
  } from '@volter/editor-core/ui-source/inspect';
73
- import type { ComponentPropSpec, OidEntry } from '@volter/editor-core/ui-source/oid-transform';
74
- import { relativeImportSpecifier } from '@volter/editor-core/ui-source/relative-import-specifier';
72
+ import type { ComponentPropSpec, OidEntry } from '@volter/editor-react/source/oid-transform';
73
+ import { relativeImportSpecifier } from '@volter/editor-react/source/relative-import-specifier';
75
74
  import type { SourceWriteBackend } from '@volter/editor-core/ui-source/source-write-backend';
76
75
  import { writeCsfStory, writeNamedStyle } from '@volter/editor-core/ui-source/source-write-backend';
77
76
  import {
@@ -79,9 +78,9 @@ import {
79
78
  namedStyleRuleFor,
80
79
  pickCssRuleTarget,
81
80
  tokenReferenceGuardText,
82
- } from '@volter/editor-core/ui-source/writer';
83
- import { UI_COMPONENTS_DOCUMENT_ID } from '@volter/editor-core/workspace-document-ids';
84
- import { activateWorkspaceDocument } from '@volter/editor-core/workspace-document-registry';
81
+ } from '@volter/editor-react/source/writer';
82
+ import { UI_COMPONENTS_DOCUMENT_ID } from '@volter/editor-sdk/kit/workspace-document-ids';
83
+ import { activateWorkspaceDocument } from '@volter/editor-sdk/kit/workspace-document-registry';
85
84
  import type {
86
85
  AssetDropContext,
87
86
  AssetDropProvider,
@@ -255,20 +254,6 @@ export function mapBoxEditPatchKey(key: string, isPositioned: boolean): BoxEditP
255
254
  }
256
255
  }
257
256
 
258
- /**
259
- * A pasteboard `<At>` mount — detected by the STRUCTURAL marker the pasteboard
260
- * capability's helper renders (`data-vgai-at="true"`), never by filename or
261
- * import path, so a project's freely edited copy of the helper keeps working
262
- * (the LiveModuleDocument precedent: detection is structural). An `x`/`y` drag
263
- * on one of these writes the callsite's `x`/`y` JSX literals instead of inline
264
- * `left`/`top` style — the authored form the pasteboard design ratified
265
- * (docs/PARITY-PROGRAM-HANDOFF.md, queue item 4: "drag = OID literal write to
266
- * x/y").
267
- */
268
- function isPasteboardAtElement(el: OidElementLike): boolean {
269
- return el.getAttribute('data-vgai-at') === 'true';
270
- }
271
-
272
257
  const OID_ATTR = 'data-oid';
273
258
  const HTML_NAMESPACE = 'http://www.w3.org/1999/xhtml';
274
259
  const VOID_HTML_ELEMENTS = new Set([
@@ -1993,38 +1978,10 @@ export class ReactRootAuthoringAdapter implements AuthoringAdapter {
1993
1978
  bestOrder = order;
1994
1979
  }
1995
1980
  }
1996
- return bestId === null ? null : this.resolvePlacementUnit(bestId);
1981
+ return bestId;
1997
1982
  },
1998
1983
  };
1999
1984
 
2000
- /**
2001
- * The pasteboard's PICK RULE: a hit anywhere inside an `<At>` subtree
2002
- * selects the At — the placement unit whose `x`/`y` a drag writes — never
2003
- * the helper's internals. Without this, the deepest-wins rule above picked
2004
- * a Swatch's inner chip div (a STATIC node whose x/y drag drops by design),
2005
- * and the drag gesture that followed re-picked it out from under the
2006
- * selected At on pointerdown, so no pasteboard drag could ever commit
2007
- * (measured on the moodboard acceptance run, 2026-08-30). Deeper selection
2008
- * stays reachable through the hierarchy panel, which projects the full
2009
- * subtree. Structural (`data-vgai-at`), so it costs nothing outside
2010
- * pasteboard content.
2011
- */
2012
- private resolvePlacementUnit(pickedId: string): string {
2013
- const { nodes } = this.snapshot();
2014
- const picked = nodes.get(pickedId);
2015
- const el = picked?.el as unknown as
2016
- | { closest?(selector: string): unknown; getAttribute?(name: string): string | null }
2017
- | undefined;
2018
- if (!el?.closest) return pickedId;
2019
- if (el.getAttribute?.('data-vgai-at') === 'true') return pickedId;
2020
- const at = el.closest('[data-vgai-at="true"]');
2021
- if (!at) return pickedId;
2022
- for (const [id, node] of nodes) {
2023
- if ((node.el as unknown) === at) return id;
2024
- }
2025
- return pickedId;
2026
- }
2027
-
2028
1985
  /** Host rect to subtract for {@link rects}' HOST-RELATIVE geometry — `this.root`
2029
1986
  * IS the world's own mounted DOM layer (`world.mounted.container` / the ingest
2030
1987
  * sibling's `layer`, see the constructor call sites), i.e. exactly the
@@ -2308,30 +2265,13 @@ export class ReactRootAuthoringAdapter implements AuthoringAdapter {
2308
2265
  priorInline: Map<string, string>,
2309
2266
  ): Promise<void> {
2310
2267
  const wasDirty = this.dirty;
2311
- // A pasteboard `<At>` mount routes its position to the CALLSITE's `x`/`y`
2312
- // JSX literals rather than inline `left`/`top` style — the drag's live
2313
- // preview still moved `el.style.left/top` (the helper renders exactly that
2314
- // from `x`/`y`), but the AUTHORED truth is the props, so that is what the
2315
- // commit writes. Resolved from the fiber (the helper's own internal stamp
2316
- // sits on the same element, so the element's `data-oid` alone would name
2317
- // the helper file, not the callsite in the pasteboard file).
2318
- const node = this.snapshot().nodes.get(id);
2319
- const atCallSiteOid = node && isPasteboardAtElement(node.el) ? getCallSiteOid(node.el) : null;
2320
- const atPropForStyle = (prop: string): 'x' | 'y' | null =>
2321
- atCallSiteOid === null ? null : prop === 'left' ? 'x' : prop === 'top' ? 'y' : null;
2322
2268
  // A4 — echo every touched prop BEFORE any write, so the inspector field shows
2323
2269
  // the dragged value at once (same discipline as `inspector.set`). The echo holds
2324
2270
  // the BARE numeric (a `type:'number'` descriptor's `Inspector` field needs an
2325
2271
  // actual number — see `inspector.get`'s `numericStyleValue` note), NOT the
2326
- // px-suffixed source form D1 writes below. An At placement echoes on the
2327
- // PROP path instead (its Props section is where x/y render).
2272
+ // px-suffixed source form D1 writes below.
2328
2273
  for (const [prop, value] of touched) {
2329
- const atProp = atPropForStyle(prop);
2330
- if (atProp && typeof value === 'number') {
2331
- this.setEcho(id, `${PROP_PATH_PREFIX}${atProp}`, String(Math.round(value)));
2332
- } else {
2333
- this.setEcho(id, `${STYLE_PATH_PREFIX}${prop}`, value);
2334
- }
2274
+ this.setEcho(id, `${STYLE_PATH_PREFIX}${prop}`, value);
2335
2275
  }
2336
2276
  // A GESTURE THAT WROTE NOTHING SAYS SO. Every refusal below only warned in
2337
2277
  // the browser console, so a drag whose commit was refused looked done —
@@ -2345,12 +2285,6 @@ export class ReactRootAuthoringAdapter implements AuthoringAdapter {
2345
2285
  this.lastStyleWriteRefusal = null;
2346
2286
  const commit = async (backend: SourceWriteBackend | undefined): Promise<void> => {
2347
2287
  for (const [prop, value] of touched) {
2348
- const atProp = atPropForStyle(prop);
2349
- if (atProp && typeof value === 'number') {
2350
- await this.writeAtPlacement(id, atCallSiteOid as string, atProp, value, backend);
2351
- applied += 1;
2352
- continue;
2353
- }
2354
2288
  // D1 (spec 27 §4 B2/B3 reload-safety) — a numeric length-prop value must
2355
2289
  // persist to JSX SOURCE in a form React honors on REMOUNT. React 19 DROPS a
2356
2290
  // bare UNITLESS numeric STRING (the writer quotes `String(152)` → `width:
@@ -2396,52 +2330,6 @@ export class ReactRootAuthoringAdapter implements AuthoringAdapter {
2396
2330
  }
2397
2331
  }
2398
2332
 
2399
- /**
2400
- * The pasteboard placement write: one `<At>` callsite prop (`x` or `y`) as a
2401
- * JSX NUMBER LITERAL, `addIfMissing` because the helper defaults both to 0
2402
- * and an author legitimately omits them until the first drag. Refusals
2403
- * follow {@link writePropEdit}'s contract: a dynamic expression (`x={GRID *
2404
- * 2}`) is authored truth the drag must not flatten — guarded and warned by
2405
- * name, never overwritten. Runs inside {@link commitBoxEdit}'s gesture, so a
2406
- * corner drag that writes both axes stays one undo entry.
2407
- */
2408
- private async writeAtPlacement(
2409
- id: string,
2410
- callSiteOid: string,
2411
- prop: 'x' | 'y',
2412
- value: number,
2413
- backend: SourceWriteBackend | undefined,
2414
- ): Promise<void> {
2415
- const echoPath = `${PROP_PATH_PREFIX}${prop}`;
2416
- const b = backend ?? this.writeBackend;
2417
- if (!b?.writeProp) {
2418
- this.clearEcho(id, echoPath);
2419
- console.warn(
2420
- `[ReactRootAuthoringAdapter] cannot write At placement "${prop}" on "${id}": no ` +
2421
- 'source-write backend with prop support in this session (hosted/no dev server).',
2422
- );
2423
- return;
2424
- }
2425
- const res = await b.writeProp(callSiteOid, prop, String(Math.round(value)), {
2426
- addIfMissing: true,
2427
- });
2428
- if (!res.changed) {
2429
- this.clearEcho(id, echoPath);
2430
- if (res.dynamic) this.markGuarded(id, echoPath, DYNAMIC_EXPRESSION_GUARD);
2431
- this.store.notifyIngestEdit();
2432
- console.warn(
2433
- `[ReactRootAuthoringAdapter] At placement write refused/no-op for oid ` +
2434
- `"${callSiteOid}" prop "${prop}": ${
2435
- res.dynamic
2436
- ? 'value is a dynamic expression (guarded) — authored truth the drag must not flatten'
2437
- : (res.error ?? 'no change')
2438
- }`,
2439
- );
2440
- return;
2441
- }
2442
- this.dirty = true;
2443
- }
2444
-
2445
2333
  /**
2446
2334
  * T0 (spec 27 §2) — brings the react adapter's existing off-contract `editText`
2447
2335
  * (below) onto the contract. `get` is a best-effort CLIENT-side read: the live
@@ -3044,12 +2932,12 @@ export class ReactRootAuthoringAdapter implements AuthoringAdapter {
3044
2932
  // `removeMany` here as unsound because the OBVIOUS implementation is N
3045
2933
  // separate `structOp`-style calls, each targeting its OID's `{file,
3046
2934
  // line, col}` from the SERVER's `OidStore.index`
3047
- // (`vite-plugin-ui-oid.ts`'s `handleStruct`) — exactly the per-id
2935
+ // (`@volter/editor-react`'s `serving/ui-oid-plugin.ts`'s `handleStruct`) — exactly the per-id
3048
2936
  // `remove` loop's own stale-offset hazard (see the CORRECTNESS INVARIANT
3049
2937
  // comment below), just without the ordering discipline that loop needs
3050
2938
  // to stay sound. This implementation is NOT that: `removeManyElements`
3051
2939
  // posts every id's raw oid in ONE request to `/__ui-source/struct-many`
3052
- // (`handleStructMany`, `vite-plugin-ui-oid.ts`), which resolves every
2940
+ // (`handleStructMany`, `@volter/editor-react`'s `serving/ui-oid-plugin.ts`), which resolves every
3053
2941
  // oid's offset against a SINGLE shared `readFileSync` snapshot (never a
3054
2942
  // per-id re-read, so no write-to-write staleness is even possible) and
3055
2943
  // applies them highest-offset-first in one pass, one write. That is also
@@ -3677,7 +3565,7 @@ export class ReactRootAuthoringAdapter implements AuthoringAdapter {
3677
3565
  * `#n` siblings share ONE raw oid — deleting it once is correct, per
3678
3566
  * `walkOidTree`'s own disambiguation comment), and posts them ALL in ONE
3679
3567
  * `writeStructMany` call — see that method's doc comment on `SourceWriteBackend`
3680
- * (`source-write-backend.ts`) and `handleStructMany`'s (`vite-plugin-ui-oid.ts`)
3568
+ * (`source-write-backend.ts`) and `handleStructMany`'s (`@volter/editor-react`'s `serving/ui-oid-plugin.ts`)
3681
3569
  * for the soundness argument (one shared file snapshot, highest-offset-first,
3682
3570
  * caller-order-independent). Degrades to a loud no-op — never a silent partial
3683
3571
  * delete — when this session's backend hasn't implemented `writeStructMany` (a
@@ -40,18 +40,17 @@ import { Checkbox, TextInput, themeVars } from '@volter/editor-sdk/widgets';
40
40
  // `@editor/active-project` and not `@editor/project-manager`: the same
41
41
  // function, re-exported, without dragging the whole project-open/storage
42
42
  // estate into this package's program.
43
- import { getCurrentProject } from '@volter/editor-core/active-project';
43
+ import { getCurrentProject } from '@volter/editor-sdk/kit/active-project';
44
44
  import { type Resolution, ResolutionPicker } from '../../host/components/ResolutionPicker';
45
45
  import { SurfaceStateOverlay } from '@volter/editor-core/components/SurfaceStateOverlay';
46
46
  import { registerDocumentOpener } from '@volter/editor-core/document-open-registry';
47
- import type { ViewportTab } from '@volter/editor-core/editor-shell-store';
48
- import { createHmrRegistrationGroup } from '@volter/editor-core/hmr-registration-group';
47
+ import { createHmrRegistrationGroup } from '@volter/editor-sdk/kit/hmr-registration-group';
49
48
  import {
50
49
  CONTRIBUTED_SECTION_ORDER,
51
50
  STORY_ARGS_SECTION_ID,
52
51
  STORY_ARGS_SECTION_TITLE,
53
- } from '@volter/editor-core/inspection/model';
54
- import { registerInspectorSections } from '@volter/editor-core/inspector-section-registry';
52
+ } from '@volter/editor-sdk/kit/inspection-model';
53
+ import { registerInspectorSections } from '@volter/editor-sdk/kit/inspector-section-registry';
55
54
  import type { ComposedProjectStory } from '@volter/editor-core/stories/compose-project-stories';
56
55
  import { getProjectStoryRegions } from '@volter/editor-core/stories/project-story-regions';
57
56
  import { mountIsolatedStory, runStoryPlay } from '@volter/editor-core/stories/StoryPreviewMount';
@@ -60,7 +59,7 @@ import {
60
59
  ISOLATED_STORY_DOCUMENT_OPENER,
61
60
  STORY_DOCS_DOCUMENT_OPENER,
62
61
  type StoryDocumentOpenRequest,
63
- } from '@volter/editor-core/stories/story-document-openers';
62
+ } from '@volter/editor-sdk/kit/story-document-openers';
64
63
  import {
65
64
  getProjectStoryModules,
66
65
  refreshProjectStories,
@@ -68,15 +67,15 @@ import {
68
67
  whenProjectStoriesReady,
69
68
  } from '@volter/editor-core/stories/story-registry';
70
69
  import { domHasRenderableContent } from '../../host/surface-content';
71
- import { explainSurface, type SurfaceContentState } from '@volter/editor-core/surface-state';
72
- import { CONTRIBUTED_WORKSPACE_UTILITIES } from '@volter/editor-core/workspace-core-utilities';
70
+ import { explainSurface, type SurfaceContentState } from '@volter/editor-sdk/kit/surface-state';
71
+ import { CONTRIBUTED_WORKSPACE_UTILITIES } from '@volter/editor-sdk/kit/workspace-core-utilities';
73
72
  import {
74
73
  activeWorkspaceDocument,
75
74
  openWorkspaceDocument,
76
75
  type WorkspaceDocumentContentProps,
77
- } from '@volter/editor-core/workspace-document-registry';
76
+ } from '@volter/editor-sdk/kit/workspace-document-registry';
78
77
  import { registerWorkspaceDocumentRestorer } from '@volter/editor-core/workspace-document-restore';
79
- import { registerWorkspaceUtility } from '@volter/editor-core/workspace-utility-registry';
78
+ import { registerWorkspaceUtility } from '@volter/editor-sdk/kit/workspace-utility-registry';
80
79
  import { fitPresentation } from '@volter/game-runtime/runtime/presentation';
81
80
  import { Button, fontMono, fontSizeVar, spaceVar } from '@volter/editor-sdk/widgets';
82
81
  import { useEffect, useRef, useState, useSyncExternalStore } from 'react';
@@ -205,7 +204,6 @@ export function clearStoryActionLog(id: string): void {
205
204
  /** The narrow store surface story documents need (T6.3 gate hand-off —
206
205
  * same contract as `asset-documents.tsx`). */
207
206
  export interface StoryDocumentStore {
208
- setActiveViewportTab(tab: ViewportTab): void;
209
207
  }
210
208
 
211
209
  /**
@@ -254,7 +252,6 @@ export function openStoryDocument(
254
252
  closeable: true,
255
253
  presentation: () => ({ kind: 'story', modulePath, storyName, mode: 'preview' }),
256
254
  persist: () => ({ modulePath, storyName }),
257
- onActivate: () => store.setActiveViewportTab('edit'),
258
255
  onDispose: (documentId) => {
259
256
  if (_states.delete(documentId)) notifyChanged();
260
257
  },
@@ -298,7 +295,6 @@ export function openStoryDocsDocument(
298
295
  closeable: true,
299
296
  presentation: () => ({ kind: 'story', modulePath, storyName, mode: 'docs' }),
300
297
  persist: () => ({ modulePath, storyName, view: 'docs' }),
301
- onActivate: () => store.setActiveViewportTab('edit'),
302
298
  onDispose: (documentId) => {
303
299
  if (_states.delete(documentId)) notifyChanged();
304
300
  },
@@ -32,14 +32,14 @@ import {
32
32
  } from '@volter/editor-core/authoring/design-time-layers';
33
33
  import type { ComponentBoardContext } from '@volter/editor-core/component-board-registry';
34
34
  import { RootDocumentContent } from '@volter/editor-core/components/world-documents';
35
- import type { DocumentPreviewSource } from '@volter/editor-core/document-preview-source';
35
+ import type { DocumentPreviewSource } from '@volter/editor-sdk/kit/document-preview-source';
36
36
  import { getCurrentProject } from '@volter/editor-core/project-manager';
37
37
  import {
38
38
  getProjectPreviewStories,
39
39
  subscribeProjectStoryModules,
40
40
  } from '@volter/editor-core/stories/story-registry';
41
- import { UI_COMPONENTS_DOCUMENT_ID } from '@volter/editor-core/workspace-document-ids';
42
- import type { WorkspaceDocumentContentProps } from '@volter/editor-core/workspace-document-registry';
41
+ import { UI_COMPONENTS_DOCUMENT_ID } from '@volter/editor-sdk/kit/workspace-document-ids';
42
+ import type { WorkspaceDocumentContentProps } from '@volter/editor-sdk/kit/workspace-document-registry';
43
43
 
44
44
  import { UI_COMPONENTS_TITLE } from './ui-board-title';
45
45
 
@@ -85,7 +85,6 @@ export function installUiBoard({ store, composite }: ComponentBoardContext): voi
85
85
  ...(story ? { story } : {}),
86
86
  };
87
87
  },
88
- onActivate: () => store.setActiveViewportTab('edit'),
89
88
  },
90
89
  // A board NEVER steals focus — presence is answered asynchronously, so a
91
90
  // board that arrives late would otherwise yank the author off whatever
@@ -12,15 +12,15 @@
12
12
  * whose verdict is `'present'`.
13
13
  */
14
14
 
15
- import { commandLine } from '@volter/editor-core/product-command';
15
+ import { commandLine } from '@volter/editor-sdk/kit/product-command';
16
16
  import type { ComponentBoard, ComponentBoardContext } from '@volter/editor-core/component-board-registry';
17
- import { editorConsole } from '@volter/editor-core/editor-console';
17
+ import { editorConsole } from '@volter/editor-sdk/kit/editor-console';
18
18
  import {
19
19
  getStoryMediaPresence,
20
20
  subscribeStoryMediaPresence,
21
21
  } from '../host/stories/story-media-presence';
22
22
  import { projectStoriesReady, subscribeProjectStoryModules } from '@volter/editor-core/stories/story-registry';
23
- import { UI_COMPONENTS_DOCUMENT_ID } from '@volter/editor-core/workspace-document-ids';
23
+ import { UI_COMPONENTS_DOCUMENT_ID } from '@volter/editor-sdk/kit/workspace-document-ids';
24
24
  import { UI_COMPONENTS_TITLE } from './ui-board-title';
25
25
 
26
26
  export const uiComponentBoard: ComponentBoard = {
@@ -10,7 +10,7 @@
10
10
  */
11
11
 
12
12
  import { getActiveCamera } from '@volter/editor-core/authoring/active-systems';
13
- import type { InspectorSectionProps } from '@volter/editor-core/inspector-section-registry';
13
+ import type { InspectorSectionProps } from '@volter/editor-sdk/kit/inspector-section-registry';
14
14
  import type {
15
15
  AuthoringAdapter,
16
16
  CameraAdapter,
@@ -1,7 +1,7 @@
1
1
  import { instanceStampOf } from '@volter/editor-core/authoring/component-instance-root';
2
2
  import { setAuthoringSelection } from '@volter/editor-core/authoring/consumer-actions';
3
- import { useEditorStore } from '@volter/editor-core/editor-runtime';
4
- import type { InspectorSectionProps } from '@volter/editor-core/inspector-section-registry';
3
+ import { useThreeEditorStore } from '@volter/editor-core/editor-runtime';
4
+ import type { InspectorSectionProps } from '@volter/editor-sdk/kit/inspector-section-registry';
5
5
  import type { AuthoringAdapter, EditorNode } from '@volter/editor-project/adapter';
6
6
  import {
7
7
  type ConstraintMark,
@@ -65,7 +65,7 @@ function typeLabel(type: ConstraintMark['config']['type']): string {
65
65
  }
66
66
 
67
67
  export function ConstraintStackSection({ adapter, nodeId }: InspectorSectionProps) {
68
- const store = useEditorStore();
68
+ const store = useThreeEditorStore();
69
69
  const object = nodeId
70
70
  ? (store.objectMap.get(nodeId) ?? objectFor(adapter, nodeId) ?? null)
71
71
  : null;
@@ -14,18 +14,17 @@ import {
14
14
  import { setAuthoringSelection } from '@volter/editor-core/authoring/consumer-actions';
15
15
  import { SourceObject3DAuthoringAdapter } from '@volter/editor-core/authoring/source-object3d-authoring-adapter';
16
16
  import { openToolDocument } from '@volter/editor-core/components/tool-documents';
17
- import { useEditorStore } from '@volter/editor-core/editor-runtime';
18
- import { createHmrRegistrationGroup } from '@volter/editor-core/hmr-registration-group';
17
+ import { createHmrRegistrationGroup } from '@volter/editor-sdk/kit/hmr-registration-group';
19
18
  import {
20
19
  CONTRIBUTED_SECTION_ORDER,
21
20
  type InspectionSection,
22
21
  PROPERTIES_SECTION_ID,
23
- } from '@volter/editor-core/inspection/model';
24
- import { registerInspectorSections } from '@volter/editor-core/inspector-section-registry';
22
+ } from '@volter/editor-sdk/kit/inspection-model';
23
+ import { registerInspectorSections } from '@volter/editor-sdk/kit/inspector-section-registry';
25
24
  import {
26
25
  type ProjectOutputProvenance,
27
26
  provenanceForProjectAsset,
28
- } from '@volter/editor-core/project-provenance';
27
+ } from '@volter/editor-sdk/kit/project-provenance';
29
28
  import {
30
29
  getDocumentToolContributions,
31
30
  getGlobalToolContributions,
@@ -372,7 +371,6 @@ function SourceBody({
372
371
  readonly provenance: ProjectOutputProvenance | null;
373
372
  readonly provenanceLoaded: boolean;
374
373
  }) {
375
- const store = useEditorStore();
376
374
  useSyncExternalStore(subscribeToolContributions, getGlobalToolContributions);
377
375
  const sourceContribution = provenance
378
376
  ? getDocumentToolContributions().find(
@@ -387,7 +385,7 @@ function SourceBody({
387
385
  type="button"
388
386
  variant="ghost"
389
387
  size="compact"
390
- onClick={() => openToolDocument(store, sourceContribution.id)}
388
+ onClick={() => openToolDocument(sourceContribution.id)}
391
389
  >
392
390
  Open Source
393
391
  </Button>
@@ -647,10 +645,8 @@ const MODEL_SECTION_ORDER = {
647
645
  splat: CONTRIBUTED_SECTION_ORDER,
648
646
  geometry: CONTRIBUTED_SECTION_ORDER + 10,
649
647
  rig: CONTRIBUTED_SECTION_ORDER + 20,
650
- // +25 is the RAGDOLL's, and it is `@volter/editor-game`'s
651
- // (`contributions/ragdoll.inspector.tsx`, `export const order = 25`) — a
652
- // contributed section's order is this same base plus what it declares, so
653
- // the slot after Rig is held from there.
648
+ // A contributed section's order is this same base plus what it declares, so
649
+ // a package's section after Rig takes a slot in this gap.
654
650
  materials: CONTRIBUTED_SECTION_ORDER + 40,
655
651
  source: CONTRIBUTED_SECTION_ORDER + 50,
656
652
  } as const;
@@ -10,7 +10,7 @@
10
10
  * `constructed outside project source` for EVERY object in the world and the
11
11
  * creation-site writer can never fire once. The game's own source still says
12
12
  * exactly where each object came from — it says it in JSX
13
- * (`<mesh position={[0, 1, 0]}>`), and `vite-plugin-ui-oid.ts` already stamps
13
+ * (`<mesh position={[0, 1, 0]}>`), and `@volter/editor-react`'s `serving/ui-oid-plugin.ts` already stamps
14
14
  * that callsite onto the constructed object as `userData.oid`. This backend is
15
15
  * the other end of that stamp.
16
16
  *
@@ -37,16 +37,16 @@
37
37
 
38
38
  import { reportIngestSourceRefusal } from '../../host/authoring/ingest-source-persistence';
39
39
  import type { SourcePersistenceBackend } from '../../host/authoring/source-persistence-backend';
40
- import { LIVE_ONLY_DESTINATION } from '@volter/editor-core/authoring/write-pipe';
40
+ import { LIVE_ONLY_DESTINATION } from '@volter/editor-sdk/kit/write-pipe';
41
41
  import type { ChannelValue } from '@volter/editor-core/creation-site-edit';
42
42
  import { channelFor } from '@volter/editor-core/creation-site-edit';
43
- import { editorConsole } from '@volter/editor-core/editor-console';
44
- import { editorIsAuthoring } from '@volter/editor-core/editor-session-mode';
43
+ import { editorConsole } from '@volter/editor-sdk/kit/editor-console';
44
+ import { editorIsAuthoring } from '@volter/editor-sdk/kit/editor-session-mode';
45
45
  import type { HistoryService } from '@volter/editor-core/history/history-service';
46
46
  import { withProjectSourceHistory } from '@volter/editor-core/history/source-history-backend';
47
47
  import { getCurrentProject } from '@volter/editor-core/project-manager';
48
- import type { OidEntry } from '@volter/editor-core/ui-source/oid-transform';
49
- import { bodyPlacedChannel, physicsRefusal } from '@volter/editor-core/ui-source/r3f-physics-binding';
48
+ import type { OidEntry } from '@volter/editor-react/source/oid-transform';
49
+ import { bodyPlacedChannel, physicsRefusal } from '@volter/editor-react/source/r3f-physics-binding';
50
50
  import type { SourceWriteBackend } from '@volter/editor-core/ui-source/source-write-backend';
51
51
  import { sourceWriteBackendIfPrimed } from '@volter/editor-core/ui-source/tier-source-write-backend';
52
52
  import type { NodeCreationSite, WriteAck } from '@volter/editor-project/adapter';
@@ -1,4 +1,4 @@
1
- import { onAssetReload } from '@volter/editor-core/project-asset-refresh';
1
+ import { onAssetReload } from '@volter/editor-sdk/kit/project-asset-refresh';
2
2
 
3
3
  /**
4
4
  * R3F design session (W4) — mounts an entry-based R3F three world at DESIGN
@@ -71,7 +71,12 @@ import {
71
71
  collaborationSnapshot,
72
72
  subscribeCollaborationRevision,
73
73
  } from '@volter/editor-core/collaboration-client';
74
- import { editorConsole } from '@volter/editor-core/editor-console';
74
+ import { editorConsole } from '@volter/editor-sdk/kit/editor-console';
75
+ import {
76
+ describeModuleFetch,
77
+ diagnoseModuleFetch,
78
+ failedImportEntry,
79
+ } from '@volter/editor-sdk/kit/module-fetch-diagnosis';
75
80
  import type { EditorShellStore } from '@volter/editor-core/editor-shell-store';
76
81
  import { adjudicateThreeEntry } from '../../host/entry-adjudication';
77
82
  import { onPlayTransitionSettled } from '@volter/editor-core/live-transition';
@@ -132,12 +137,12 @@ import {
132
137
  parseEditModeManifest,
133
138
  queueEditModeRebuild,
134
139
  } from '@volter/editor-core/authoring/edit-mode-authoring';
135
- import { liveGestureActive, whenLiveGestureIdle } from '@volter/editor-core/authoring/live-gesture-lock';
140
+ import { liveGestureActive, whenLiveGestureIdle } from '@volter/editor-sdk/kit/live-gesture-lock';
136
141
  import {
137
142
  addMountFailureReport,
138
143
  clearMountFailureReport,
139
144
  formatMountFailureMessage,
140
- } from '@volter/editor-core/authoring/mount-failure-report';
145
+ } from '@volter/editor-sdk/kit/mount-failure-report';
141
146
  import { SelectionRemountHandoff } from '../../host/authoring/selection-remount-handoff';
142
147
  import {
143
148
  type RefreshSource,
@@ -145,6 +150,7 @@ import {
145
150
  } from '../../host/authoring/source-refresh-revisions';
146
151
  import type { R3fSourceAuthoringAdapter } from './r3f-source-authoring-adapter';
147
152
  import { isThreeScene } from './three-scene-identity';
153
+ import { evictDreiCaches } from '../drei-asset-caches';
148
154
 
149
155
  // The world root's stage is recreated when the workspace changes.
150
156
  // The outgoing panel restores the editor scene and the incoming panel loads
@@ -178,6 +184,12 @@ export function unresolvedDesignEntryError(
178
184
  export function reportDesignMountFailure(worldId: string, err: unknown): string {
179
185
  const message = formatMountFailureMessage(err);
180
186
  editorConsole.error(`[r3f-design] world "${worldId}" failed to mount: ${message}`, 'authoring');
187
+ const entry = failedImportEntry(message);
188
+ if (entry) {
189
+ void diagnoseModuleFetch(entry).then((diagnosis) =>
190
+ editorConsole.error(`[r3f-design] world "${worldId}": ${describeModuleFetch(diagnosis)}`, 'authoring'),
191
+ );
192
+ }
181
193
  addMountFailureReport({
182
194
  worldId,
183
195
  kind: 'three',
@@ -1042,9 +1054,11 @@ export async function mountR3FDesignSession(
1042
1054
  }, 80);
1043
1055
  };
1044
1056
 
1045
- const stopAssetReload = onAssetReload(() => {
1046
- writeStamp += 1;
1047
- scheduleRemount();
1057
+ const stopAssetReload = onAssetReload((paths) => {
1058
+ void evictDreiCaches(paths).then(() => {
1059
+ writeStamp += 1;
1060
+ scheduleRemount();
1061
+ });
1048
1062
  });
1049
1063
 
1050
1064
  const hot = import.meta.hot;