@pascal-app/core 0.9.1 → 0.9.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/events/bus.d.ts +30 -2
- package/dist/events/bus.d.ts.map +1 -1
- package/dist/hooks/scene-registry/item-clip-registry.d.ts +18 -0
- package/dist/hooks/scene-registry/item-clip-registry.d.ts.map +1 -0
- package/dist/hooks/scene-registry/item-clip-registry.js +10 -0
- package/dist/hooks/scene-registry/scene-registry.d.ts +8 -1
- package/dist/hooks/scene-registry/scene-registry.d.ts.map +1 -1
- package/dist/hooks/scene-registry/scene-registry.js +27 -1
- package/dist/hooks/scene-registry/scene-registry.test.d.ts +2 -0
- package/dist/hooks/scene-registry/scene-registry.test.d.ts.map +1 -0
- package/dist/hooks/scene-registry/scene-registry.test.js +26 -0
- package/dist/hooks/spatial-grid/floor-placed-elevation.test.js +93 -0
- package/dist/hooks/spatial-grid/spatial-grid-manager.d.ts +69 -12
- package/dist/hooks/spatial-grid/spatial-grid-manager.d.ts.map +1 -1
- package/dist/hooks/spatial-grid/spatial-grid-manager.js +476 -195
- package/dist/hooks/spatial-grid/spatial-grid-sync.d.ts.map +1 -1
- package/dist/hooks/spatial-grid/spatial-grid-sync.js +19 -1
- package/dist/hooks/spatial-grid/wall-slab-overlap.test.d.ts +2 -0
- package/dist/hooks/spatial-grid/wall-slab-overlap.test.d.ts.map +1 -0
- package/dist/hooks/spatial-grid/wall-slab-overlap.test.js +363 -0
- package/dist/index.d.ts +16 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +15 -5
- package/dist/lib/level-name.d.ts +4 -0
- package/dist/lib/level-name.d.ts.map +1 -0
- package/dist/lib/level-name.js +10 -0
- package/dist/lib/measurement-geometry.d.ts +19 -0
- package/dist/lib/measurement-geometry.d.ts.map +1 -0
- package/dist/lib/measurement-geometry.js +232 -0
- package/dist/lib/measurement-geometry.test.d.ts +2 -0
- package/dist/lib/measurement-geometry.test.d.ts.map +1 -0
- package/dist/lib/measurement-geometry.test.js +102 -0
- package/dist/lib/polygon-geometry.d.ts +0 -1
- package/dist/lib/polygon-geometry.d.ts.map +1 -1
- package/dist/lib/polygon-geometry.js +0 -18
- package/dist/lib/selection-proxy.d.ts +4 -0
- package/dist/lib/selection-proxy.d.ts.map +1 -0
- package/dist/lib/selection-proxy.js +12 -0
- package/dist/lib/slab-polygon.d.ts +31 -2
- package/dist/lib/slab-polygon.d.ts.map +1 -1
- package/dist/lib/slab-polygon.js +525 -31
- package/dist/lib/slab-polygon.test.d.ts +2 -0
- package/dist/lib/slab-polygon.test.d.ts.map +1 -0
- package/dist/lib/slab-polygon.test.js +635 -0
- package/dist/lib/slots.d.ts +14 -0
- package/dist/lib/slots.d.ts.map +1 -0
- package/dist/lib/slots.js +26 -0
- package/dist/lib/space-detection.d.ts +25 -2
- package/dist/lib/space-detection.d.ts.map +1 -1
- package/dist/lib/space-detection.js +414 -118
- package/dist/lib/space-detection.test.js +301 -2
- package/dist/lib/wall-distance.d.ts +60 -0
- package/dist/lib/wall-distance.d.ts.map +1 -0
- package/dist/lib/wall-distance.js +85 -0
- package/dist/lib/zone-quantities.d.ts +21 -0
- package/dist/lib/zone-quantities.d.ts.map +1 -0
- package/dist/lib/zone-quantities.js +183 -0
- package/dist/lib/zone-quantities.test.d.ts +2 -0
- package/dist/lib/zone-quantities.test.d.ts.map +1 -0
- package/dist/lib/zone-quantities.test.js +82 -0
- package/dist/material-library.d.ts +20 -1
- package/dist/material-library.d.ts.map +1 -1
- package/dist/material-library.js +2181 -441
- package/dist/registry/handles.d.ts +75 -2
- package/dist/registry/handles.d.ts.map +1 -1
- package/dist/registry/index.d.ts +3 -3
- package/dist/registry/index.d.ts.map +1 -1
- package/dist/registry/index.js +1 -1
- package/dist/registry/registry.d.ts +46 -3
- package/dist/registry/registry.d.ts.map +1 -1
- package/dist/registry/registry.js +82 -1
- package/dist/registry/registry.test.js +14 -1
- package/dist/registry/subtree.d.ts.map +1 -1
- package/dist/registry/subtree.js +4 -0
- package/dist/registry/subtree.test.js +30 -0
- package/dist/registry/types.d.ts +717 -38
- package/dist/registry/types.d.ts.map +1 -1
- package/dist/schema/index.d.ts +21 -5
- package/dist/schema/index.d.ts.map +1 -1
- package/dist/schema/index.js +17 -3
- package/dist/schema/material.d.ts +3 -2
- package/dist/schema/material.d.ts.map +1 -1
- package/dist/schema/material.js +7 -5
- package/dist/schema/material.test.d.ts +2 -0
- package/dist/schema/material.test.d.ts.map +1 -0
- package/dist/schema/material.test.js +43 -0
- package/dist/schema/nodes/box-vent.d.ts +2 -2
- package/dist/schema/nodes/cabinet.d.ts +534 -0
- package/dist/schema/nodes/cabinet.d.ts.map +1 -0
- package/dist/schema/nodes/cabinet.js +137 -0
- package/dist/schema/nodes/ceiling.d.ts +3 -2
- package/dist/schema/nodes/ceiling.d.ts.map +1 -1
- package/dist/schema/nodes/ceiling.js +4 -0
- package/dist/schema/nodes/chimney.d.ts +4 -4
- package/dist/schema/nodes/column.d.ts +3 -2
- package/dist/schema/nodes/column.d.ts.map +1 -1
- package/dist/schema/nodes/column.js +3 -0
- package/dist/schema/nodes/cupola.d.ts +2 -2
- package/dist/schema/nodes/door.d.ts +13 -5
- package/dist/schema/nodes/door.d.ts.map +1 -1
- package/dist/schema/nodes/door.js +12 -0
- package/dist/schema/nodes/dormer.d.ts +8 -8
- package/dist/schema/nodes/dormer.js +1 -1
- package/dist/schema/nodes/downspout.d.ts +2 -2
- package/dist/schema/nodes/duct-fitting.d.ts +91 -0
- package/dist/schema/nodes/duct-fitting.d.ts.map +1 -0
- package/dist/schema/nodes/duct-fitting.js +92 -0
- package/dist/schema/nodes/duct-segment.d.ts +61 -0
- package/dist/schema/nodes/duct-segment.d.ts.map +1 -0
- package/dist/schema/nodes/duct-segment.js +73 -0
- package/dist/schema/nodes/duct-terminal.d.ts +57 -0
- package/dist/schema/nodes/duct-terminal.d.ts.map +1 -0
- package/dist/schema/nodes/duct-terminal.js +51 -0
- package/dist/schema/nodes/elevator.d.ts +3 -2
- package/dist/schema/nodes/elevator.d.ts.map +1 -1
- package/dist/schema/nodes/elevator.js +3 -0
- package/dist/schema/nodes/eyebrow-vent.d.ts +2 -2
- package/dist/schema/nodes/fence.d.ts +18 -2
- package/dist/schema/nodes/fence.d.ts.map +1 -1
- package/dist/schema/nodes/fence.js +25 -2
- package/dist/schema/nodes/gutter.d.ts +2 -2
- package/dist/schema/nodes/hvac-equipment.d.ts +63 -0
- package/dist/schema/nodes/hvac-equipment.d.ts.map +1 -0
- package/dist/schema/nodes/hvac-equipment.js +55 -0
- package/dist/schema/nodes/item.d.ts +8 -0
- package/dist/schema/nodes/item.d.ts.map +1 -1
- package/dist/schema/nodes/item.js +11 -0
- package/dist/schema/nodes/level.d.ts +1 -1
- package/dist/schema/nodes/level.d.ts.map +1 -1
- package/dist/schema/nodes/level.js +2 -0
- package/dist/schema/nodes/lineset.d.ts +42 -0
- package/dist/schema/nodes/lineset.d.ts.map +1 -0
- package/dist/schema/nodes/lineset.js +38 -0
- package/dist/schema/nodes/liquid-line.d.ts +34 -0
- package/dist/schema/nodes/liquid-line.d.ts.map +1 -0
- package/dist/schema/nodes/liquid-line.js +24 -0
- package/dist/schema/nodes/measurement.d.ts +306 -0
- package/dist/schema/nodes/measurement.d.ts.map +1 -0
- package/dist/schema/nodes/measurement.js +87 -0
- package/dist/schema/nodes/measurement.test.d.ts +2 -0
- package/dist/schema/nodes/measurement.test.d.ts.map +1 -0
- package/dist/schema/nodes/measurement.test.js +139 -0
- package/dist/schema/nodes/pipe-fitting.d.ts +56 -0
- package/dist/schema/nodes/pipe-fitting.d.ts.map +1 -0
- package/dist/schema/nodes/pipe-fitting.js +45 -0
- package/dist/schema/nodes/pipe-segment.d.ts +48 -0
- package/dist/schema/nodes/pipe-segment.d.ts.map +1 -0
- package/dist/schema/nodes/pipe-segment.js +36 -0
- package/dist/schema/nodes/pipe-trap.d.ts +43 -0
- package/dist/schema/nodes/pipe-trap.d.ts.map +1 -0
- package/dist/schema/nodes/pipe-trap.js +36 -0
- package/dist/schema/nodes/ridge-vent-defaults.test.d.ts +2 -0
- package/dist/schema/nodes/ridge-vent-defaults.test.d.ts.map +1 -0
- package/dist/schema/nodes/ridge-vent-defaults.test.js +205 -0
- package/dist/schema/nodes/ridge-vent.d.ts +18 -3
- package/dist/schema/nodes/ridge-vent.d.ts.map +1 -1
- package/dist/schema/nodes/ridge-vent.js +221 -3
- package/dist/schema/nodes/roof-segment-shape.d.ts +90 -0
- package/dist/schema/nodes/roof-segment-shape.d.ts.map +1 -0
- package/dist/schema/nodes/roof-segment-shape.js +318 -0
- package/dist/schema/nodes/roof-segment-shape.test.d.ts +2 -0
- package/dist/schema/nodes/roof-segment-shape.test.d.ts.map +1 -0
- package/dist/schema/nodes/roof-segment-shape.test.js +175 -0
- package/dist/schema/nodes/roof-segment-surface.test.d.ts +2 -0
- package/dist/schema/nodes/roof-segment-surface.test.d.ts.map +1 -0
- package/dist/schema/nodes/roof-segment-surface.test.js +48 -0
- package/dist/schema/nodes/roof-segment-trim.test.d.ts +2 -0
- package/dist/schema/nodes/roof-segment-trim.test.d.ts.map +1 -0
- package/dist/schema/nodes/roof-segment-trim.test.js +107 -0
- package/dist/schema/nodes/roof-segment-walls.d.ts +101 -0
- package/dist/schema/nodes/roof-segment-walls.d.ts.map +1 -0
- package/dist/schema/nodes/roof-segment-walls.js +330 -0
- package/dist/schema/nodes/roof-segment-walls.test.d.ts +2 -0
- package/dist/schema/nodes/roof-segment-walls.test.d.ts.map +1 -0
- package/dist/schema/nodes/roof-segment-walls.test.js +92 -0
- package/dist/schema/nodes/roof-segment.d.ts +84 -8
- package/dist/schema/nodes/roof-segment.d.ts.map +1 -1
- package/dist/schema/nodes/roof-segment.js +290 -5
- package/dist/schema/nodes/roof.d.ts +8 -8
- package/dist/schema/nodes/shelf.d.ts +3 -2
- package/dist/schema/nodes/shelf.d.ts.map +1 -1
- package/dist/schema/nodes/shelf.js +6 -0
- package/dist/schema/nodes/skylight.d.ts +10 -10
- package/dist/schema/nodes/slab.d.ts +3 -2
- package/dist/schema/nodes/slab.d.ts.map +1 -1
- package/dist/schema/nodes/slab.js +4 -0
- package/dist/schema/nodes/solar-panel.d.ts +4 -4
- package/dist/schema/nodes/stair-segment.d.ts +4 -4
- package/dist/schema/nodes/stair.d.ts +13 -12
- package/dist/schema/nodes/stair.d.ts.map +1 -1
- package/dist/schema/nodes/stair.js +3 -0
- package/dist/schema/nodes/turbine-vent.d.ts +2 -2
- package/dist/schema/nodes/wall.d.ts +245 -6
- package/dist/schema/nodes/wall.d.ts.map +1 -1
- package/dist/schema/nodes/wall.js +257 -0
- package/dist/schema/nodes/wall.test.d.ts +2 -0
- package/dist/schema/nodes/wall.test.d.ts.map +1 -0
- package/dist/schema/nodes/wall.test.js +208 -0
- package/dist/schema/nodes/window.d.ts +11 -3
- package/dist/schema/nodes/window.d.ts.map +1 -1
- package/dist/schema/nodes/window.js +12 -0
- package/dist/schema/nodes/zone.d.ts +2 -0
- package/dist/schema/nodes/zone.d.ts.map +1 -1
- package/dist/schema/nodes/zone.js +6 -0
- package/dist/schema/scene-material.d.ts +41 -0
- package/dist/schema/scene-material.d.ts.map +1 -0
- package/dist/schema/scene-material.js +9 -0
- package/dist/schema/types.d.ts +1089 -94
- package/dist/schema/types.d.ts.map +1 -1
- package/dist/schema/types.js +23 -0
- package/dist/services/alignment-anchors.d.ts.map +1 -1
- package/dist/services/alignment-anchors.js +30 -1
- package/dist/services/alignment.d.ts +5 -0
- package/dist/services/alignment.d.ts.map +1 -1
- package/dist/services/alignment.js +2 -0
- package/dist/services/hosting.d.ts +8 -0
- package/dist/services/hosting.d.ts.map +1 -1
- package/dist/services/hosting.js +13 -4
- package/dist/services/hosting.test.js +32 -1
- package/dist/services/index.d.ts +8 -2
- package/dist/services/index.d.ts.map +1 -1
- package/dist/services/index.js +8 -2
- package/dist/services/level-height.d.ts +28 -0
- package/dist/services/level-height.d.ts.map +1 -0
- package/dist/services/level-height.js +62 -0
- package/dist/services/opening-guides.d.ts +141 -0
- package/dist/services/opening-guides.d.ts.map +1 -0
- package/dist/services/opening-guides.js +267 -0
- package/dist/services/opening-guides.test.d.ts +2 -0
- package/dist/services/opening-guides.test.d.ts.map +1 -0
- package/dist/services/opening-guides.test.js +208 -0
- package/dist/services/port-connectivity.d.ts +115 -0
- package/dist/services/port-connectivity.d.ts.map +1 -0
- package/dist/services/port-connectivity.js +300 -0
- package/dist/services/port-connectivity.test.d.ts +2 -0
- package/dist/services/port-connectivity.test.d.ts.map +1 -0
- package/dist/services/port-connectivity.test.js +297 -0
- package/dist/services/riser-diagram.d.ts +40 -0
- package/dist/services/riser-diagram.d.ts.map +1 -0
- package/dist/services/riser-diagram.js +110 -0
- package/dist/services/riser-diagram.test.d.ts +2 -0
- package/dist/services/riser-diagram.test.d.ts.map +1 -0
- package/dist/services/riser-diagram.test.js +66 -0
- package/dist/services/snap.d.ts +9 -1
- package/dist/services/snap.d.ts.map +1 -1
- package/dist/services/snap.js +21 -1
- package/dist/services/snap.test.js +43 -1
- package/dist/services/system-graph.d.ts +30 -0
- package/dist/services/system-graph.d.ts.map +1 -0
- package/dist/services/system-graph.js +164 -0
- package/dist/services/system-graph.test.d.ts +2 -0
- package/dist/services/system-graph.test.d.ts.map +1 -0
- package/dist/services/system-graph.test.js +138 -0
- package/dist/services/validate-dwv.d.ts +32 -0
- package/dist/services/validate-dwv.d.ts.map +1 -0
- package/dist/services/validate-dwv.js +118 -0
- package/dist/services/validate-dwv.test.d.ts +2 -0
- package/dist/services/validate-dwv.test.d.ts.map +1 -0
- package/dist/services/validate-dwv.test.js +109 -0
- package/dist/store/actions/node-actions.d.ts.map +1 -1
- package/dist/store/actions/node-actions.js +94 -1
- package/dist/store/actions/ridge-vent-update.test.d.ts +2 -0
- package/dist/store/actions/ridge-vent-update.test.d.ts.map +1 -0
- package/dist/store/actions/ridge-vent-update.test.js +264 -0
- package/dist/store/history-control.d.ts +11 -0
- package/dist/store/history-control.d.ts.map +1 -1
- package/dist/store/history-control.js +33 -0
- package/dist/store/use-scene-dirty-tracking.test.d.ts +2 -0
- package/dist/store/use-scene-dirty-tracking.test.d.ts.map +1 -0
- package/dist/store/use-scene-dirty-tracking.test.js +68 -0
- package/dist/store/use-scene-measurement-roundtrip.test.d.ts +2 -0
- package/dist/store/use-scene-measurement-roundtrip.test.d.ts.map +1 -0
- package/dist/store/use-scene-measurement-roundtrip.test.js +97 -0
- package/dist/store/use-scene-plugins.test.d.ts +2 -0
- package/dist/store/use-scene-plugins.test.d.ts.map +1 -0
- package/dist/store/use-scene-plugins.test.js +51 -0
- package/dist/store/use-scene-wall-slot-migration.test.d.ts +2 -0
- package/dist/store/use-scene-wall-slot-migration.test.d.ts.map +1 -0
- package/dist/store/use-scene-wall-slot-migration.test.js +210 -0
- package/dist/store/use-scene-window-migration.test.d.ts +2 -0
- package/dist/store/use-scene-window-migration.test.d.ts.map +1 -0
- package/dist/store/use-scene-window-migration.test.js +85 -0
- package/dist/store/use-scene.d.ts +17 -2
- package/dist/store/use-scene.d.ts.map +1 -1
- package/dist/store/use-scene.js +358 -51
- package/dist/systems/elevator/elevator-service.js +1 -1
- package/dist/systems/fence/fence-centerline.d.ts +12 -0
- package/dist/systems/fence/fence-centerline.d.ts.map +1 -0
- package/dist/systems/fence/fence-centerline.js +37 -0
- package/dist/systems/fence/fence-spline.d.ts +39 -0
- package/dist/systems/fence/fence-spline.d.ts.map +1 -0
- package/dist/systems/fence/fence-spline.js +196 -0
- package/dist/systems/fence/fence-spline.test.d.ts +2 -0
- package/dist/systems/fence/fence-spline.test.d.ts.map +1 -0
- package/dist/systems/fence/fence-spline.test.js +136 -0
- package/dist/systems/stair/stair-footprint.d.ts.map +1 -1
- package/dist/systems/stair/stair-footprint.js +21 -11
- package/dist/systems/stair/stair-opening-preview.d.ts +1139 -469
- package/dist/systems/stair/stair-opening-preview.d.ts.map +1 -1
- package/dist/systems/stair/stair-opening-sync.d.ts.map +1 -1
- package/dist/systems/stair/stair-opening-sync.js +1 -18
- package/dist/systems/stair/stair-opening-sync.test.js +39 -0
- package/dist/systems/wall/wall-mitering.d.ts.map +1 -1
- package/dist/systems/wall/wall-mitering.js +38 -2
- package/dist/systems/wall/wall-mitering.test.d.ts +2 -0
- package/dist/systems/wall/wall-mitering.test.d.ts.map +1 -0
- package/dist/systems/wall/wall-mitering.test.js +63 -0
- package/dist/utils/clone-scene-graph.d.ts +1 -0
- package/dist/utils/clone-scene-graph.d.ts.map +1 -1
- package/dist/utils/clone-scene-graph.js +23 -3
- package/dist/utils/clone-scene-graph.test.js +3 -0
- package/dist/utils/heal-scene-graph.d.ts +18 -0
- package/dist/utils/heal-scene-graph.d.ts.map +1 -0
- package/dist/utils/heal-scene-graph.js +90 -0
- package/dist/utils/heal-scene-graph.test.d.ts +2 -0
- package/dist/utils/heal-scene-graph.test.d.ts.map +1 -0
- package/dist/utils/heal-scene-graph.test.js +88 -0
- package/dist/validation/validate-build-json.d.ts +1 -0
- package/dist/validation/validate-build-json.d.ts.map +1 -1
- package/dist/validation/validate-build-json.js +31 -2
- package/package.json +3 -3
|
@@ -30,6 +30,17 @@ export type EditorApi = {
|
|
|
30
30
|
* fences). No-ops for kinds without endpoints.
|
|
31
31
|
*/
|
|
32
32
|
engageEndpointMove: (node: AnyNode, endpoint: 'start' | 'end') => void;
|
|
33
|
+
/**
|
|
34
|
+
* Engage drag of a spline control point (`path[index]`). Used by spline
|
|
35
|
+
* fences to reshape their centerline. No-ops for kinds without a path.
|
|
36
|
+
*/
|
|
37
|
+
engageControlPointMove: (node: AnyNode, index: number) => void;
|
|
38
|
+
/**
|
|
39
|
+
* Engage drag of a spline tangent handle (`path[index]`, which end). Used by
|
|
40
|
+
* spline fences to bend the curve through one control point. No-ops for kinds
|
|
41
|
+
* without tangents.
|
|
42
|
+
*/
|
|
43
|
+
engageTangentMove: (node: AnyNode, index: number, side: 'in' | 'out') => void;
|
|
33
44
|
};
|
|
34
45
|
export type HandlePortal = 'self' | 'parent' | 'grandparent';
|
|
35
46
|
export type HandleAxis = 'x' | 'y' | 'z';
|
|
@@ -58,9 +69,11 @@ export type Cursor = 'ew-resize' | 'ns-resize' | 'move' | 'grab' | 'grabbing';
|
|
|
58
69
|
export type HandleDecoration<N> = {
|
|
59
70
|
kind: 'ring';
|
|
60
71
|
/** Node-local radius of the ring (XZ plane). */
|
|
61
|
-
radius: (node: N) => number;
|
|
72
|
+
radius: (node: N, sceneApi: SceneApi) => number;
|
|
62
73
|
/** Node-local Y of the ring. Defaults to 0. */
|
|
63
74
|
y?: (node: N) => number;
|
|
75
|
+
/** Node-local center of the ring. Defaults to the node origin. */
|
|
76
|
+
center?: (node: N, sceneApi: SceneApi) => readonly [number, number, number];
|
|
64
77
|
};
|
|
65
78
|
/**
|
|
66
79
|
* Linear resize along a single local axis. Covers width / depth / height
|
|
@@ -84,6 +97,24 @@ export type LinearResizeHandle<N> = {
|
|
|
84
97
|
anchor: HandleAnchor;
|
|
85
98
|
currentValue: (node: N) => number;
|
|
86
99
|
apply: (node: N, newValue: number, sceneApi: SceneApi) => Partial<N>;
|
|
100
|
+
/** Optional live-scene visibility gate for context-dependent arrows. */
|
|
101
|
+
visible?: (node: N, sceneApi: SceneApi) => boolean;
|
|
102
|
+
/**
|
|
103
|
+
* Optional committed-write hook. The generic handle renderer previews the
|
|
104
|
+
* selected node with the `apply` patch during drag; on release it normally
|
|
105
|
+
* writes that patch back to the same node. Composite nodes can override the
|
|
106
|
+
* final write here to fan the resize out to siblings / parents while keeping
|
|
107
|
+
* the handle UI generic.
|
|
108
|
+
*/
|
|
109
|
+
commit?: (node: N, patch: Partial<N>, sceneApi: SceneApi) => void;
|
|
110
|
+
/**
|
|
111
|
+
* Optional per-tick hook fired while this handle is being dragged, with the
|
|
112
|
+
* live (in-progress, override-merged) node. A pure side-channel for transient
|
|
113
|
+
* feedback — doors/windows use it to publish proximity / sill guides for the
|
|
114
|
+
* edge being resized. The return value is ignored; the resize itself is driven
|
|
115
|
+
* by `apply`.
|
|
116
|
+
*/
|
|
117
|
+
onDrag?: (node: N, sceneApi: SceneApi) => void;
|
|
87
118
|
/**
|
|
88
119
|
* Cross-node redirect. By default the drag's live override + the
|
|
89
120
|
* committed write both land on the SELECTED node. When this returns
|
|
@@ -142,6 +173,25 @@ export type LinearResizeHandle<N> = {
|
|
|
142
173
|
* the roof shell below it. Only consulted when `shape === 'tracker'`.
|
|
143
174
|
*/
|
|
144
175
|
trackerBaseY?: (node: N, sceneApi: SceneApi) => number;
|
|
176
|
+
/**
|
|
177
|
+
* Stand the chevron blade up into the node's facing plane instead of
|
|
178
|
+
* leaving it flat in the local XZ plane. For an `axis: 'x'` handle on a
|
|
179
|
+
* wall-mounted opening (door / window), the local XZ plane is horizontal,
|
|
180
|
+
* so the default blade is seen edge-on from the front — rotating it 90°
|
|
181
|
+
* about its pointing axis lays it in the wall face (local XY) so it reads
|
|
182
|
+
* face-on toward the camera. Chevron shape only; `axis: 'y'` handles are
|
|
183
|
+
* already stood up unconditionally so this is a no-op for them.
|
|
184
|
+
*/
|
|
185
|
+
faceNormal?: boolean;
|
|
186
|
+
/**
|
|
187
|
+
* Gate this arrow behind a click-to-latch cube. When set, the arrow is
|
|
188
|
+
* hidden until the user clicks the {@link LatchHandle} cube declaring the
|
|
189
|
+
* same `group` name; clicking the cube again hides it. Lets a node keep a
|
|
190
|
+
* dense cluster (e.g. a dormer's window width/height arrows) collapsed
|
|
191
|
+
* behind a single grip until the user opts in. The latch state is local to
|
|
192
|
+
* the selection and resets when the node is deselected.
|
|
193
|
+
*/
|
|
194
|
+
latchGroup?: string;
|
|
145
195
|
};
|
|
146
196
|
/**
|
|
147
197
|
* 1:1 outward growth — dragging the arrow outward by `delta` grows the
|
|
@@ -257,6 +307,11 @@ export type TapActionHandle<N = any> = {
|
|
|
257
307
|
* drag, so the move tool's own preview / ticker feedback shows up.
|
|
258
308
|
*/
|
|
259
309
|
shape?: 'arrow' | 'corner-picker' | 'move-cross';
|
|
310
|
+
/**
|
|
311
|
+
* `shape: 'corner-picker'` only — render the disc and its outer ring as a
|
|
312
|
+
* circle instead of the default hexagon.
|
|
313
|
+
*/
|
|
314
|
+
round?: boolean;
|
|
260
315
|
/**
|
|
261
316
|
* Required when `shape: 'corner-picker'` — controls the dashed leader's
|
|
262
317
|
* vertical extent. Pure callback so the descriptor doesn't need to
|
|
@@ -312,7 +367,25 @@ export type TranslateHandle<N = any> = {
|
|
|
312
367
|
snapExtents?: (node: N, sceneApi: SceneApi) => readonly [number, number] | null;
|
|
313
368
|
portal?: HandlePortal;
|
|
314
369
|
};
|
|
315
|
-
|
|
370
|
+
/**
|
|
371
|
+
* Click-to-latch cube. Renders a small persistent cube at `placement` that
|
|
372
|
+
* toggles the visibility of every handle tagged with the matching
|
|
373
|
+
* {@link LinearResizeHandle.latchGroup} `group`. Clicking the cube once shows
|
|
374
|
+
* the group's arrows; clicking again hides them. The latch state is local to
|
|
375
|
+
* the current selection and resets on deselect.
|
|
376
|
+
*
|
|
377
|
+
* Mirrors the duct-fitting selection cube but driven by descriptor data so any
|
|
378
|
+
* node can collapse a dense arrow cluster behind one grip — e.g. a dormer's
|
|
379
|
+
* window width/height arrows latch behind a cube at the window center.
|
|
380
|
+
*/
|
|
381
|
+
export type LatchHandle<N = any> = {
|
|
382
|
+
kind: 'latch';
|
|
383
|
+
/** The `latchGroup` name whose arrows this cube reveals / hides. */
|
|
384
|
+
group: string;
|
|
385
|
+
placement: HandlePlacement<N>;
|
|
386
|
+
portal?: HandlePortal;
|
|
387
|
+
};
|
|
388
|
+
export type HandleDescriptor<N = any> = LinearResizeHandle<N> | RadialResizeHandle<N> | ArcResizeHandle<N> | EndpointMoveHandle<N> | TapActionHandle<N> | TranslateHandle<N> | LatchHandle<N>;
|
|
316
389
|
/**
|
|
317
390
|
* Static array, or a function for shape-dependent cases (column
|
|
318
391
|
* crossSection / supportStyle, stair-segment segmentType, etc.).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handles.d.ts","sourceRoot":"","sources":["../../src/registry/handles.ts"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AACzD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAEvC;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,SAAS,GAAG;IACtB;;;;OAIG;IACH,UAAU,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAA;IACnC;;;;OAIG;IACH,cAAc,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAA;IACvC;;;OAGG;IACH,kBAAkB,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,GAAG,KAAK,KAAK,IAAI,CAAA;
|
|
1
|
+
{"version":3,"file":"handles.d.ts","sourceRoot":"","sources":["../../src/registry/handles.ts"],"names":[],"mappings":"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"}
|
package/dist/registry/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export type { ArcResizeHandle, Cursor, EditorApi, EndpointMoveHandle, HandleAnchor, HandleAxis, HandleDescriptor, HandleList, HandlePlacement, HandlePortal, LinearResizeHandle, RadialResizeHandle, TapActionHandle, TranslateHandle, } from './handles';
|
|
2
|
-
export { discoverPlugins, getHostRefFields, getSelectableKinds, isDrawnViaTool, isDrawnViaToolKind, isPresettable, isPresettableKind, isRegistryMovable, isRegistrySelectable, kindsWithFloorplanScope, loadPlugin, nodeRegistry, type PluginDiscovery, registerNode, setPluginDiscovery, } from './registry';
|
|
1
|
+
export type { ArcResizeHandle, Cursor, EditorApi, EndpointMoveHandle, HandleAnchor, HandleAxis, HandleDescriptor, HandleList, HandlePlacement, HandlePortal, LatchHandle, LinearResizeHandle, RadialResizeHandle, TapActionHandle, TranslateHandle, } from './handles';
|
|
2
|
+
export { bakePolicyOf, discoverPlugins, extendPluginDiscovery, getHostRefFields, getNodePluginId, getSelectableKinds, hasRegistry3DMoveTool, isDrawnViaTool, isDrawnViaToolKind, isNodeKindEnabled, isPresettable, isPresettableKind, isRegistryMovable, isRegistrySelectable, kindsWithBakePolicy, kindsWithFloorplanScope, loadPlugin, nodeRegistry, type PluginDiscovery, registerNode, resolveFacingIndicator, setPluginDiscovery, } from './registry';
|
|
3
3
|
export { type CascadeContext, type ChildQuery, cascadeDirty, collectDescendants, type SpatialQuery, } from './relations-resolver';
|
|
4
4
|
export { createSceneApi, type SceneStoreLike } from './scene-api';
|
|
5
5
|
export { type CloneNodesIntoOptions, type CloneNodesIntoResult, cloneNodesInto, collectSubtree, type Subtree, } from './subtree';
|
|
6
|
-
export type { Affordance, AlignmentFootprint, AlignmentFootprintConfig, AnyNodeDefinition, AssetRef, Capabilities, CapabilityCtx, CuttableConfig, DragAction, EditorCtx, FloorPlacedConfig, FloorPlacedFootprint, FloorPlacedFootprintContext, FloorPlacedFootprintResolver, FloorPlacedFootprintsResolver, FloorplanAffordance, FloorplanAffordanceModifiers, FloorplanAffordancePoint, FloorplanAffordanceSession, FloorplanGeometry, FloorplanMoveTarget, FloorplanMoveTargetSession, FloorplanPalette, FloorplanPoint, FloorplanStyle, GeometryContext, HostableConfig, IconRef, Issue, KeyboardAction, KeyboardActions, LazyComponent, McpOverrides, Modifiers, MovableConfig, NodeCategory, NodeDefinition, NodeRegistry, PaintCapability, PaintEffectiveMaterialArgs, PaintPatchArgs, PaintPreviewArgs, PaintResolveArgs, ParamAction, ParametricDescriptor, ParamField, ParamGroup, Plugin, Presentation, Relations, RendererSource, RoofAccessoryConfig, RotatableConfig, ScalableConfig, SceneApi, SelectableConfig, SnapPointKind, SnappableConfig, SnapServicesLike, SurfacePoint, SurfaceQuery, SurfaceRole, SurfacesConfig, SystemContribution, ToolHint, Vec2, } from './types';
|
|
6
|
+
export type { Affordance, AlignmentFootprint, AlignmentFootprintConfig, AnyNodeDefinition, AssetRef, BakePolicy, BakeReplaceRenderer, Capabilities, CapabilityCtx, CuttableConfig, DistributionRole, DragAction, DuplicableConfig, DuplicateSubtreeCloneArgs, DuplicateSubtreeCloneResult, EditorCtx, ExportAnimationContext, FloorPlacedConfig, FloorPlacedFootprint, FloorPlacedFootprintContext, FloorPlacedFootprintResolver, FloorPlacedFootprintsResolver, FloorplanAffordance, FloorplanAffordanceModifiers, FloorplanAffordancePoint, FloorplanAffordanceSession, FloorplanGeometry, FloorplanMoveTarget, FloorplanMoveTargetSession, FloorplanPalette, FloorplanPoint, FloorplanStyle, GeometryContext, HostableConfig, IconRef, Issue, KeyboardAction, KeyboardActions, LazyComponent, LiveTransformLike, McpOverrides, MeasurementContribution, MeasurementFeature, MeasurementFeatureBinding, MeasurementFeatureGeometry, MeasurementSnapKind, Modifiers, MovableConfig, MovableParentFrame, NodeCategory, NodeDefinition, NodePort, NodeQuickAction, NodeQuickActionIcon, NodeQuickActionProvider, NodeQuickActionResult, NodeRegistry, PaintCapability, PaintEffectiveMaterialArgs, PaintPatchArgs, PaintPreviewArgs, PaintResolveArgs, ParamAction, ParametricDescriptor, ParamField, ParamGroup, ParentFrameSnapMatch, Plugin, Presentation, QuickMeasurementMetric, QuickMeasurementQuantity, QuickMeasurementReport, Relations, RendererSource, RoofAccessoryConfig, RotatableConfig, ScalableConfig, SceneActionCapability, SceneApi, SelectableConfig, SlotDeclaration, SnapPointKind, SnapProfile, SnappableConfig, SnapServicesLike, SurfacePoint, SurfaceQuery, SurfaceRole, SurfacesConfig, SystemContribution, ToolHint, ToolHintChip, Vec2, } from './types';
|
|
7
7
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/registry/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,eAAe,EACf,MAAM,EACN,SAAS,EACT,kBAAkB,EAClB,YAAY,EACZ,UAAU,EACV,gBAAgB,EAChB,UAAU,EACV,eAAe,EACf,YAAY,EACZ,kBAAkB,EAClB,kBAAkB,EAClB,eAAe,EACf,eAAe,GAChB,MAAM,WAAW,CAAA;AAClB,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,kBAAkB,EAClB,cAAc,EACd,kBAAkB,EAClB,aAAa,EACb,iBAAiB,EACjB,iBAAiB,EACjB,oBAAoB,EACpB,uBAAuB,EACvB,UAAU,EACV,YAAY,EACZ,KAAK,eAAe,EACpB,YAAY,EACZ,kBAAkB,GACnB,MAAM,YAAY,CAAA;AACnB,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,UAAU,EACf,YAAY,EACZ,kBAAkB,EAClB,KAAK,YAAY,GAClB,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAAE,cAAc,EAAE,KAAK,cAAc,EAAE,MAAM,aAAa,CAAA;AACjE,OAAO,EACL,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EACzB,cAAc,EACd,cAAc,EACd,KAAK,OAAO,GACb,MAAM,WAAW,CAAA;AAClB,YAAY,EACV,UAAU,EACV,kBAAkB,EAClB,wBAAwB,EACxB,iBAAiB,EACjB,QAAQ,EACR,YAAY,EACZ,aAAa,EACb,cAAc,EACd,UAAU,EACV,SAAS,EACT,iBAAiB,EACjB,oBAAoB,EACpB,2BAA2B,EAC3B,4BAA4B,EAC5B,6BAA6B,EAC7B,mBAAmB,EACnB,4BAA4B,EAC5B,wBAAwB,EACxB,0BAA0B,EAC1B,iBAAiB,EACjB,mBAAmB,EACnB,0BAA0B,EAC1B,gBAAgB,EAChB,cAAc,EACd,cAAc,EACd,eAAe,EACf,cAAc,EACd,OAAO,EACP,KAAK,EACL,cAAc,EACd,eAAe,EACf,aAAa,EACb,YAAY,EACZ,SAAS,EACT,aAAa,EACb,YAAY,EACZ,cAAc,EACd,YAAY,EACZ,eAAe,EACf,0BAA0B,EAC1B,cAAc,EACd,gBAAgB,EAChB,gBAAgB,EAChB,WAAW,EACX,oBAAoB,EACpB,UAAU,EACV,UAAU,EACV,MAAM,EACN,YAAY,EACZ,SAAS,EACT,cAAc,EACd,mBAAmB,EACnB,eAAe,EACf,cAAc,EACd,QAAQ,EACR,gBAAgB,EAChB,aAAa,EACb,eAAe,EACf,gBAAgB,EAChB,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,cAAc,EACd,kBAAkB,EAClB,QAAQ,EACR,IAAI,GACL,MAAM,SAAS,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/registry/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,eAAe,EACf,MAAM,EACN,SAAS,EACT,kBAAkB,EAClB,YAAY,EACZ,UAAU,EACV,gBAAgB,EAChB,UAAU,EACV,eAAe,EACf,YAAY,EACZ,WAAW,EACX,kBAAkB,EAClB,kBAAkB,EAClB,eAAe,EACf,eAAe,GAChB,MAAM,WAAW,CAAA;AAClB,OAAO,EACL,YAAY,EACZ,eAAe,EACf,qBAAqB,EACrB,gBAAgB,EAChB,eAAe,EACf,kBAAkB,EAClB,qBAAqB,EACrB,cAAc,EACd,kBAAkB,EAClB,iBAAiB,EACjB,aAAa,EACb,iBAAiB,EACjB,iBAAiB,EACjB,oBAAoB,EACpB,mBAAmB,EACnB,uBAAuB,EACvB,UAAU,EACV,YAAY,EACZ,KAAK,eAAe,EACpB,YAAY,EACZ,sBAAsB,EACtB,kBAAkB,GACnB,MAAM,YAAY,CAAA;AACnB,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,UAAU,EACf,YAAY,EACZ,kBAAkB,EAClB,KAAK,YAAY,GAClB,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAAE,cAAc,EAAE,KAAK,cAAc,EAAE,MAAM,aAAa,CAAA;AACjE,OAAO,EACL,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EACzB,cAAc,EACd,cAAc,EACd,KAAK,OAAO,GACb,MAAM,WAAW,CAAA;AAClB,YAAY,EACV,UAAU,EACV,kBAAkB,EAClB,wBAAwB,EACxB,iBAAiB,EACjB,QAAQ,EACR,UAAU,EACV,mBAAmB,EACnB,YAAY,EACZ,aAAa,EACb,cAAc,EACd,gBAAgB,EAChB,UAAU,EACV,gBAAgB,EAChB,yBAAyB,EACzB,2BAA2B,EAC3B,SAAS,EACT,sBAAsB,EACtB,iBAAiB,EACjB,oBAAoB,EACpB,2BAA2B,EAC3B,4BAA4B,EAC5B,6BAA6B,EAC7B,mBAAmB,EACnB,4BAA4B,EAC5B,wBAAwB,EACxB,0BAA0B,EAC1B,iBAAiB,EACjB,mBAAmB,EACnB,0BAA0B,EAC1B,gBAAgB,EAChB,cAAc,EACd,cAAc,EACd,eAAe,EACf,cAAc,EACd,OAAO,EACP,KAAK,EACL,cAAc,EACd,eAAe,EACf,aAAa,EACb,iBAAiB,EACjB,YAAY,EACZ,uBAAuB,EACvB,kBAAkB,EAClB,yBAAyB,EACzB,0BAA0B,EAC1B,mBAAmB,EACnB,SAAS,EACT,aAAa,EACb,kBAAkB,EAClB,YAAY,EACZ,cAAc,EACd,QAAQ,EACR,eAAe,EACf,mBAAmB,EACnB,uBAAuB,EACvB,qBAAqB,EACrB,YAAY,EACZ,eAAe,EACf,0BAA0B,EAC1B,cAAc,EACd,gBAAgB,EAChB,gBAAgB,EAChB,WAAW,EACX,oBAAoB,EACpB,UAAU,EACV,UAAU,EACV,oBAAoB,EACpB,MAAM,EACN,YAAY,EACZ,sBAAsB,EACtB,wBAAwB,EACxB,sBAAsB,EACtB,SAAS,EACT,cAAc,EACd,mBAAmB,EACnB,eAAe,EACf,cAAc,EACd,qBAAqB,EACrB,QAAQ,EACR,gBAAgB,EAChB,eAAe,EACf,aAAa,EACb,WAAW,EACX,eAAe,EACf,gBAAgB,EAChB,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,cAAc,EACd,kBAAkB,EAClB,QAAQ,EACR,YAAY,EACZ,IAAI,GACL,MAAM,SAAS,CAAA"}
|
package/dist/registry/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { discoverPlugins, getHostRefFields, getSelectableKinds, isDrawnViaTool, isDrawnViaToolKind, isPresettable, isPresettableKind, isRegistryMovable, isRegistrySelectable, kindsWithFloorplanScope, loadPlugin, nodeRegistry, registerNode, setPluginDiscovery, } from './registry';
|
|
1
|
+
export { bakePolicyOf, discoverPlugins, extendPluginDiscovery, getHostRefFields, getNodePluginId, getSelectableKinds, hasRegistry3DMoveTool, isDrawnViaTool, isDrawnViaToolKind, isNodeKindEnabled, isPresettable, isPresettableKind, isRegistryMovable, isRegistrySelectable, kindsWithBakePolicy, kindsWithFloorplanScope, loadPlugin, nodeRegistry, registerNode, resolveFacingIndicator, setPluginDiscovery, } from './registry';
|
|
2
2
|
export { cascadeDirty, collectDescendants, } from './relations-resolver';
|
|
3
3
|
export { createSceneApi } from './scene-api';
|
|
4
4
|
export { cloneNodesInto, collectSubtree, } from './subtree';
|
|
@@ -1,9 +1,18 @@
|
|
|
1
|
-
import type { AnyNodeDefinition, NodeRegistry, Plugin } from './types';
|
|
1
|
+
import type { AnyNodeDefinition, BakePolicy, NodeRegistry, Plugin } from './types';
|
|
2
2
|
export declare const nodeRegistry: NodeRegistry & {
|
|
3
3
|
_register: (def: AnyNodeDefinition) => void;
|
|
4
4
|
_reset: () => void;
|
|
5
5
|
};
|
|
6
6
|
export declare function registerNode(def: AnyNodeDefinition): void;
|
|
7
|
+
/** The plugin that registered a node kind, when it came through {@link loadPlugin}. */
|
|
8
|
+
export declare function getNodePluginId(kind: string): string | undefined;
|
|
9
|
+
/**
|
|
10
|
+
* Whether a registered kind should participate in a project. Kinds registered
|
|
11
|
+
* directly by the host and the built-in plugin are always enabled. An omitted
|
|
12
|
+
* install list means a legacy scene whose plugin state predates persistence, so
|
|
13
|
+
* loaded plugins remain visible for backward compatibility.
|
|
14
|
+
*/
|
|
15
|
+
export declare function isNodeKindEnabled(kind: string, installedPlugins?: readonly string[]): boolean;
|
|
7
16
|
/**
|
|
8
17
|
* Returns the set of registered kinds whose definition declares the
|
|
9
18
|
* `selectable` capability. Callers that maintain hardcoded "selectable kinds"
|
|
@@ -28,6 +37,16 @@ export declare function isRegistrySelectable(kind: string): boolean;
|
|
|
28
37
|
* that didn't set the field at all.
|
|
29
38
|
*/
|
|
30
39
|
export declare function kindsWithFloorplanScope(scope: 'level' | 'building'): string[];
|
|
40
|
+
/**
|
|
41
|
+
* A kind's {@link BakePolicy} from the registry, defaulting to `'static'` for
|
|
42
|
+
* kinds that don't declare one (or aren't registered). The bake and the baked
|
|
43
|
+
* `/viewer` consult this instead of hardcoding kind names — see
|
|
44
|
+
* plans/editor-plugin-trees-example.md → Part D.
|
|
45
|
+
*/
|
|
46
|
+
export declare function bakePolicyOf(kind: string): BakePolicy;
|
|
47
|
+
/** Registered kinds whose {@link BakePolicy} matches `policy`. `'static'` is the
|
|
48
|
+
* default, so `kindsWithBakePolicy('static')` includes kinds that didn't set it. */
|
|
49
|
+
export declare function kindsWithBakePolicy(policy: BakePolicy): string[];
|
|
31
50
|
/**
|
|
32
51
|
* Returns true when the kind is movable from a 2D floor-plan handle —
|
|
33
52
|
* either via `capabilities.movable`, an explicit
|
|
@@ -36,6 +55,15 @@ export declare function kindsWithFloorplanScope(scope: 'level' | 'building'): st
|
|
|
36
55
|
* chain in `floating-action-menu.tsx`.
|
|
37
56
|
*/
|
|
38
57
|
export declare function isRegistryMovable(kind: string): boolean;
|
|
58
|
+
/**
|
|
59
|
+
* Whether the kind has a move tool that MOUNTS in the 3D viewport — the
|
|
60
|
+
* generic `capabilities.movable` mover or a bespoke `affordanceTools.move`.
|
|
61
|
+
* Narrower than {@link isRegistryMovable}, which also accepts floorplan-only
|
|
62
|
+
* movers (e.g. zone) that have no 3D tool. Gates 3D direct move: Ctrl/Meta-drag
|
|
63
|
+
* and the move-cross grip. Kept beside `isRegistryMovable` so the 2D and 3D
|
|
64
|
+
* movability predicates can't drift apart.
|
|
65
|
+
*/
|
|
66
|
+
export declare function hasRegistry3DMoveTool(kind: string): boolean;
|
|
39
67
|
/**
|
|
40
68
|
* Whether the kind can be saved as a reusable preset. Default: an
|
|
41
69
|
* explicit `capabilities.presettable` boolean wins; otherwise the kind
|
|
@@ -44,6 +72,15 @@ export declare function isRegistryMovable(kind: string): boolean;
|
|
|
44
72
|
*/
|
|
45
73
|
export declare function isPresettable(def: AnyNodeDefinition): boolean;
|
|
46
74
|
export declare function isPresettableKind(kind: string): boolean;
|
|
75
|
+
/**
|
|
76
|
+
* Resolve a kind's facing-triangle config, or `null` when it has none.
|
|
77
|
+
* `{ reversed }` says whether the triangle points along the node's local -Z
|
|
78
|
+
* (its front) instead of +Z. One reader (the editor-side `<FacingPoseIndicator>`
|
|
79
|
+
* publishers) so placement and move stay consistent.
|
|
80
|
+
*/
|
|
81
|
+
export declare function resolveFacingIndicator(kind: string): {
|
|
82
|
+
reversed: boolean;
|
|
83
|
+
} | null;
|
|
47
84
|
/**
|
|
48
85
|
* Names of schema fields on `def` that are host references (`wallId`,
|
|
49
86
|
* `wallT`, etc.). Read by host apps at preset-save time to strip these
|
|
@@ -69,8 +106,8 @@ export declare function loadPlugin(plugin: Plugin): Promise<void>;
|
|
|
69
106
|
* {@link setPluginDiscovery} before the bootstrap module runs.
|
|
70
107
|
*
|
|
71
108
|
* Kept async so a future loader can fetch over the network without
|
|
72
|
-
* changing the contract. See `wiki/
|
|
73
|
-
* plugin author surface this enables.
|
|
109
|
+
* changing the contract. See `wiki/architecture/plugin-authoring.md` for
|
|
110
|
+
* the plugin author surface this enables.
|
|
74
111
|
*/
|
|
75
112
|
export type PluginDiscovery = () => Promise<Plugin[]>;
|
|
76
113
|
/**
|
|
@@ -84,6 +121,12 @@ export type PluginDiscovery = () => Promise<Plugin[]>;
|
|
|
84
121
|
* gate + duplicate-kind protection applies.
|
|
85
122
|
*/
|
|
86
123
|
export declare function setPluginDiscovery(fn: PluginDiscovery): void;
|
|
124
|
+
/**
|
|
125
|
+
* Extend the current plugin discovery instead of replacing it. Useful for app-
|
|
126
|
+
* bundled example or first-party plugins that should load alongside any host-
|
|
127
|
+
* provided discovery source, not clobber it.
|
|
128
|
+
*/
|
|
129
|
+
export declare function extendPluginDiscovery(fn: PluginDiscovery): void;
|
|
87
130
|
/**
|
|
88
131
|
* Run the active plugin discovery and return the discovered plugins.
|
|
89
132
|
* Bootstrap code is expected to call this after `loadPlugin(builtinPlugin)`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/registry/registry.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/registry/registry.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAkFlF,eAAO,MAAM,YAAY,EAAE,YAAY,GAAG;IACxC,SAAS,EAAE,CAAC,GAAG,EAAE,iBAAiB,KAAK,IAAI,CAAA;IAC3C,MAAM,EAAE,MAAM,IAAI,CAAA;CACM,CAAA;AAE1B,wBAAgB,YAAY,CAAC,GAAG,EAAE,iBAAiB,GAAG,IAAI,CAEzD;AAED,uFAAuF;AACvF,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAEhE;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,gBAAgB,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAI7F;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,EAAE,CAQ7C;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE1D;AAED;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,GAAG,UAAU,GAAG,MAAM,EAAE,CAO7E;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CAErD;AAED;qFACqF;AACrF,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,EAAE,CAMhE;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAOvD;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAI3D;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,iBAAiB,GAAG,OAAO,CAK7D;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAGvD;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,QAAQ,EAAE,OAAO,CAAA;CAAE,GAAG,IAAI,CAIjF;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,iBAAiB,GAAG,aAAa,CAAC,MAAM,CAAC,CAE9E;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,iBAAiB,GAAG,OAAO,CAE9D;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAGxD;AAED,wBAAsB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAU9D;AAED;;;;;;;;;;GAUG;AACH,MAAM,MAAM,eAAe,GAAG,MAAM,OAAO,CAAC,MAAM,EAAE,CAAC,CAAA;AAMrD;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,eAAe,GAAG,IAAI,CAO5D;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,eAAe,GAAG,IAAI,CAM/D;AAED;;;;GAIG;AACH,wBAAgB,eAAe,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAEnD"}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
const HOST_API_VERSION = 1;
|
|
2
|
+
const BUILTIN_PLUGIN_ID = 'pascal:core';
|
|
3
|
+
const pluginIdsByKind = new Map();
|
|
2
4
|
// True in dev / test builds, false in production. Tries Vite's
|
|
3
5
|
// `import.meta.env.DEV` first (the editor app's bundler) and falls back
|
|
4
6
|
// to `process.env.NODE_ENV !== 'production'` for Node test runners.
|
|
@@ -63,12 +65,29 @@ class NodeRegistryImpl {
|
|
|
63
65
|
// Test-only — clears the registry. Not exported from the package barrel.
|
|
64
66
|
_reset() {
|
|
65
67
|
this.defs.clear();
|
|
68
|
+
pluginIdsByKind.clear();
|
|
66
69
|
}
|
|
67
70
|
}
|
|
68
71
|
export const nodeRegistry = new NodeRegistryImpl();
|
|
69
72
|
export function registerNode(def) {
|
|
70
73
|
nodeRegistry._register(def);
|
|
71
74
|
}
|
|
75
|
+
/** The plugin that registered a node kind, when it came through {@link loadPlugin}. */
|
|
76
|
+
export function getNodePluginId(kind) {
|
|
77
|
+
return pluginIdsByKind.get(kind);
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Whether a registered kind should participate in a project. Kinds registered
|
|
81
|
+
* directly by the host and the built-in plugin are always enabled. An omitted
|
|
82
|
+
* install list means a legacy scene whose plugin state predates persistence, so
|
|
83
|
+
* loaded plugins remain visible for backward compatibility.
|
|
84
|
+
*/
|
|
85
|
+
export function isNodeKindEnabled(kind, installedPlugins) {
|
|
86
|
+
const pluginId = getNodePluginId(kind);
|
|
87
|
+
if (!pluginId || pluginId === BUILTIN_PLUGIN_ID || installedPlugins === undefined)
|
|
88
|
+
return true;
|
|
89
|
+
return installedPlugins.includes(pluginId);
|
|
90
|
+
}
|
|
72
91
|
/**
|
|
73
92
|
* Returns the set of registered kinds whose definition declares the
|
|
74
93
|
* `selectable` capability. Callers that maintain hardcoded "selectable kinds"
|
|
@@ -111,6 +130,25 @@ export function kindsWithFloorplanScope(scope) {
|
|
|
111
130
|
}
|
|
112
131
|
return result;
|
|
113
132
|
}
|
|
133
|
+
/**
|
|
134
|
+
* A kind's {@link BakePolicy} from the registry, defaulting to `'static'` for
|
|
135
|
+
* kinds that don't declare one (or aren't registered). The bake and the baked
|
|
136
|
+
* `/viewer` consult this instead of hardcoding kind names — see
|
|
137
|
+
* plans/editor-plugin-trees-example.md → Part D.
|
|
138
|
+
*/
|
|
139
|
+
export function bakePolicyOf(kind) {
|
|
140
|
+
return nodeRegistry.get(kind)?.bake ?? 'static';
|
|
141
|
+
}
|
|
142
|
+
/** Registered kinds whose {@link BakePolicy} matches `policy`. `'static'` is the
|
|
143
|
+
* default, so `kindsWithBakePolicy('static')` includes kinds that didn't set it. */
|
|
144
|
+
export function kindsWithBakePolicy(policy) {
|
|
145
|
+
const result = [];
|
|
146
|
+
for (const [kind, def] of nodeRegistry.entries()) {
|
|
147
|
+
if ((def.bake ?? 'static') === policy)
|
|
148
|
+
result.push(kind);
|
|
149
|
+
}
|
|
150
|
+
return result;
|
|
151
|
+
}
|
|
114
152
|
/**
|
|
115
153
|
* Returns true when the kind is movable from a 2D floor-plan handle —
|
|
116
154
|
* either via `capabilities.movable`, an explicit
|
|
@@ -130,6 +168,20 @@ export function isRegistryMovable(kind) {
|
|
|
130
168
|
return true;
|
|
131
169
|
return false;
|
|
132
170
|
}
|
|
171
|
+
/**
|
|
172
|
+
* Whether the kind has a move tool that MOUNTS in the 3D viewport — the
|
|
173
|
+
* generic `capabilities.movable` mover or a bespoke `affordanceTools.move`.
|
|
174
|
+
* Narrower than {@link isRegistryMovable}, which also accepts floorplan-only
|
|
175
|
+
* movers (e.g. zone) that have no 3D tool. Gates 3D direct move: Ctrl/Meta-drag
|
|
176
|
+
* and the move-cross grip. Kept beside `isRegistryMovable` so the 2D and 3D
|
|
177
|
+
* movability predicates can't drift apart.
|
|
178
|
+
*/
|
|
179
|
+
export function hasRegistry3DMoveTool(kind) {
|
|
180
|
+
const def = nodeRegistry.get(kind);
|
|
181
|
+
if (!def)
|
|
182
|
+
return false;
|
|
183
|
+
return def.capabilities.movable !== undefined || def.affordanceTools?.move !== undefined;
|
|
184
|
+
}
|
|
133
185
|
/**
|
|
134
186
|
* Whether the kind can be saved as a reusable preset. Default: an
|
|
135
187
|
* explicit `capabilities.presettable` boolean wins; otherwise the kind
|
|
@@ -146,6 +198,18 @@ export function isPresettableKind(kind) {
|
|
|
146
198
|
const def = nodeRegistry.get(kind);
|
|
147
199
|
return def ? isPresettable(def) : false;
|
|
148
200
|
}
|
|
201
|
+
/**
|
|
202
|
+
* Resolve a kind's facing-triangle config, or `null` when it has none.
|
|
203
|
+
* `{ reversed }` says whether the triangle points along the node's local -Z
|
|
204
|
+
* (its front) instead of +Z. One reader (the editor-side `<FacingPoseIndicator>`
|
|
205
|
+
* publishers) so placement and move stay consistent.
|
|
206
|
+
*/
|
|
207
|
+
export function resolveFacingIndicator(kind) {
|
|
208
|
+
const facing = nodeRegistry.get(kind)?.facingIndicator;
|
|
209
|
+
if (!facing)
|
|
210
|
+
return null;
|
|
211
|
+
return { reversed: facing === true ? false : (facing.reversed ?? false) };
|
|
212
|
+
}
|
|
149
213
|
/**
|
|
150
214
|
* Names of schema fields on `def` that are host references (`wallId`,
|
|
151
215
|
* `wallT`, etc.). Read by host apps at preset-save time to strip these
|
|
@@ -175,9 +239,11 @@ export async function loadPlugin(plugin) {
|
|
|
175
239
|
}
|
|
176
240
|
for (const def of plugin.nodes ?? []) {
|
|
177
241
|
registerNode(def);
|
|
242
|
+
pluginIdsByKind.set(def.kind, plugin.id);
|
|
178
243
|
}
|
|
179
244
|
}
|
|
180
|
-
|
|
245
|
+
const defaultPluginDiscovery = async () => [];
|
|
246
|
+
let pluginDiscovery = defaultPluginDiscovery;
|
|
181
247
|
/**
|
|
182
248
|
* Replace the plugin discovery implementation. Call once at app startup
|
|
183
249
|
* before {@link discoverPlugins} is invoked (bootstrap order matters).
|
|
@@ -189,8 +255,23 @@ let pluginDiscovery = async () => [];
|
|
|
189
255
|
* gate + duplicate-kind protection applies.
|
|
190
256
|
*/
|
|
191
257
|
export function setPluginDiscovery(fn) {
|
|
258
|
+
if (isDevMode() && pluginDiscovery !== defaultPluginDiscovery) {
|
|
259
|
+
console.warn('[registry] setPluginDiscovery replaced an existing discovery chain — plugins registered earlier (e.g. via extendPluginDiscovery) are dropped. Use extendPluginDiscovery to compose instead.');
|
|
260
|
+
}
|
|
192
261
|
pluginDiscovery = fn;
|
|
193
262
|
}
|
|
263
|
+
/**
|
|
264
|
+
* Extend the current plugin discovery instead of replacing it. Useful for app-
|
|
265
|
+
* bundled example or first-party plugins that should load alongside any host-
|
|
266
|
+
* provided discovery source, not clobber it.
|
|
267
|
+
*/
|
|
268
|
+
export function extendPluginDiscovery(fn) {
|
|
269
|
+
const previous = pluginDiscovery;
|
|
270
|
+
pluginDiscovery = async () => {
|
|
271
|
+
const [base, extra] = await Promise.all([previous(), fn()]);
|
|
272
|
+
return [...base, ...extra];
|
|
273
|
+
};
|
|
274
|
+
}
|
|
194
275
|
/**
|
|
195
276
|
* Run the active plugin discovery and return the discovered plugins.
|
|
196
277
|
* Bootstrap code is expected to call this after `loadPlugin(builtinPlugin)`
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { beforeEach, describe, expect, test } from 'bun:test';
|
|
2
2
|
import { z } from 'zod';
|
|
3
|
-
import { getHostRefFields, isDrawnViaTool, isDrawnViaToolKind, isPresettable, isPresettableKind, loadPlugin, nodeRegistry, registerNode, } from './registry';
|
|
3
|
+
import { getHostRefFields, getNodePluginId, isDrawnViaTool, isDrawnViaToolKind, isNodeKindEnabled, isPresettable, isPresettableKind, loadPlugin, nodeRegistry, registerNode, } from './registry';
|
|
4
4
|
// Re-registering a kind warns + replaces in dev (HMR) but throws in
|
|
5
5
|
// production — see `registry._register`. `bun test` runs with
|
|
6
6
|
// NODE_ENV=test (dev path), so the throw-path tests pin NODE_ENV to
|
|
@@ -149,6 +149,19 @@ describe('loadPlugin', () => {
|
|
|
149
149
|
expect(nodeRegistry.size).toBe(2);
|
|
150
150
|
expect(nodeRegistry.has('a')).toBe(true);
|
|
151
151
|
expect(nodeRegistry.has('b')).toBe(true);
|
|
152
|
+
expect(getNodePluginId('a')).toBe('test:plugin');
|
|
153
|
+
expect(getNodePluginId('b')).toBe('test:plugin');
|
|
154
|
+
});
|
|
155
|
+
test('enables plugin kinds only when the project has the plugin installed', async () => {
|
|
156
|
+
await loadPlugin({ id: 'test:plugin', apiVersion: 1, nodes: [makeDefinition('plugin:node')] });
|
|
157
|
+
expect(isNodeKindEnabled('plugin:node', [])).toBe(false);
|
|
158
|
+
expect(isNodeKindEnabled('plugin:node', ['test:plugin'])).toBe(true);
|
|
159
|
+
expect(isNodeKindEnabled('plugin:node')).toBe(true);
|
|
160
|
+
expect(isNodeKindEnabled('host:node', [])).toBe(true);
|
|
161
|
+
});
|
|
162
|
+
test('keeps built-in plugin kinds enabled independently of project installs', async () => {
|
|
163
|
+
await loadPlugin({ id: 'pascal:core', apiVersion: 1, nodes: [makeDefinition('wall')] });
|
|
164
|
+
expect(isNodeKindEnabled('wall', [])).toBe(true);
|
|
152
165
|
});
|
|
153
166
|
test('handles plugin with no nodes', async () => {
|
|
154
167
|
await loadPlugin({ id: 'empty', apiVersion: 1 });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"subtree.d.ts","sourceRoot":"","sources":["../../src/registry/subtree.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"subtree.d.ts","sourceRoot":"","sources":["../../src/registry/subtree.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAmBzD,kDAAkD;AAClD,MAAM,MAAM,OAAO,GAAG;IACpB,oEAAoE;IACpE,IAAI,EAAE,OAAO,CAAA;IACb,gGAAgG;IAChG,WAAW,EAAE,OAAO,EAAE,CAAA;CACvB,CAAA;AAcD;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,EAC3C,MAAM,EAAE,SAAS,GAChB,OAAO,GAAG,IAAI,CAmBhB;AAED,MAAM,MAAM,qBAAqB,GAAG;IAClC;;;;;OAKG;IACH,MAAM,EAAE,SAAS,CAAA;IACjB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAA;IACpB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;CAC7C,CAAA;AAED,MAAM,MAAM,oBAAoB,GAAG;IACjC,8DAA8D;IAC9D,MAAM,EAAE,SAAS,CAAA;IACjB,uEAAuE;IACvE,KAAK,EAAE,OAAO,EAAE,CAAA;IAChB,qFAAqF;IACrF,KAAK,EAAE,GAAG,CAAC,SAAS,EAAE,SAAS,CAAC,CAAA;CACjC,CAAA;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,aAAa,CAAC,OAAO,CAAC,EAC7B,IAAI,EAAE,qBAAqB,GAC1B,oBAAoB,CAiEtB"}
|
package/dist/registry/subtree.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { remapMeasurementReferences } from '../lib/measurement-geometry';
|
|
1
2
|
import { generateId } from '../schema/base';
|
|
2
3
|
function extractIdPrefix(id) {
|
|
3
4
|
const i = id.indexOf('_');
|
|
@@ -97,6 +98,9 @@ export function cloneNodesInto(nodes, opts) {
|
|
|
97
98
|
.map((cid) => idMap.get(cid))
|
|
98
99
|
.filter((cid) => cid !== undefined);
|
|
99
100
|
}
|
|
101
|
+
if (cloned.type === 'measurement') {
|
|
102
|
+
cloned.measurement = remapMeasurementReferences(cloned.measurement, idMap);
|
|
103
|
+
}
|
|
100
104
|
if (original.id === opts.rootId) {
|
|
101
105
|
if (opts.position) {
|
|
102
106
|
;
|
|
@@ -105,6 +105,36 @@ describe('cloneNodesInto', () => {
|
|
|
105
105
|
expect(Array.isArray(desc.position)).toBe(true);
|
|
106
106
|
}
|
|
107
107
|
});
|
|
108
|
+
test('remaps associative measurement references inside the cloned subtree', () => {
|
|
109
|
+
const wall = makeNode('wall_1', 'wall', { parentId: 'level_1' });
|
|
110
|
+
const measurement = makeNode('measurement_1', 'measurement', {
|
|
111
|
+
parentId: 'level_1',
|
|
112
|
+
measurement: {
|
|
113
|
+
kind: 'distance',
|
|
114
|
+
points: [
|
|
115
|
+
{
|
|
116
|
+
kind: 'feature',
|
|
117
|
+
reference: { nodeId: 'wall_1', featureId: 'wall:start' },
|
|
118
|
+
fallback: [0, 0, 0],
|
|
119
|
+
},
|
|
120
|
+
[1, 0, 0],
|
|
121
|
+
],
|
|
122
|
+
},
|
|
123
|
+
});
|
|
124
|
+
const result = cloneNodesInto([wall, measurement], {
|
|
125
|
+
rootId: 'wall_1',
|
|
126
|
+
});
|
|
127
|
+
const clonedMeasurement = result.nodes.find((node) => node.type === 'measurement');
|
|
128
|
+
expect(clonedMeasurement?.type).toBe('measurement');
|
|
129
|
+
if (clonedMeasurement?.type === 'measurement' &&
|
|
130
|
+
clonedMeasurement.measurement.kind === 'distance') {
|
|
131
|
+
const anchor = clonedMeasurement.measurement.points[0];
|
|
132
|
+
expect(Array.isArray(anchor)).toBe(false);
|
|
133
|
+
if (!Array.isArray(anchor)) {
|
|
134
|
+
expect(anchor.reference.nodeId).toBe(result.idMap.get('wall_1'));
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
});
|
|
108
138
|
test('parents the cloned root under opts.parentId when supplied', () => {
|
|
109
139
|
const orig = makeNode('shelf_1', 'shelf', { parentId: 'level_old' });
|
|
110
140
|
const { nodes } = cloneNodesInto([orig], {
|