@vibecook/ice 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (115) hide show
  1. package/README.md +37 -2
  2. package/dist/chunk-5SJYHQI4.js +636 -0
  3. package/dist/chunk-5SJYHQI4.js.map +1 -0
  4. package/dist/{chunk-5S7GSXJG.js → chunk-DXU3RZZS.js} +2913 -1180
  5. package/dist/chunk-DXU3RZZS.js.map +1 -0
  6. package/dist/{chunk-FIAXPNNY.js → chunk-IASTQMU5.js} +130 -551
  7. package/dist/chunk-IASTQMU5.js.map +1 -0
  8. package/dist/{chunk-BCJ47SX7.js → chunk-OR5FNVUE.js} +460 -1
  9. package/dist/chunk-OR5FNVUE.js.map +1 -0
  10. package/dist/devtools.js +508 -372
  11. package/dist/devtools.js.map +1 -1
  12. package/dist/dom.js +3 -11
  13. package/dist/ground.js +715 -0
  14. package/dist/ground.js.map +1 -0
  15. package/dist/index.js +70 -2
  16. package/dist/kernel.js +31 -1
  17. package/dist/r3f.js +599 -62
  18. package/dist/r3f.js.map +1 -1
  19. package/dist/react.js +34 -418
  20. package/dist/react.js.map +1 -1
  21. package/dist/types/packages/core/src/catalog/camera-derived.d.ts +41 -3
  22. package/dist/types/packages/core/src/catalog/gesture.d.ts +39 -3
  23. package/dist/types/packages/core/src/catalog/graph.d.ts +7 -6
  24. package/dist/types/packages/core/src/catalog/index.d.ts +1 -0
  25. package/dist/types/packages/core/src/catalog/insert.d.ts +31 -0
  26. package/dist/types/packages/core/src/catalog/pointer.d.ts +11 -0
  27. package/dist/types/packages/core/src/catalog/scene.d.ts +37 -4
  28. package/dist/types/packages/core/src/catalog/selection-presence.d.ts +7 -0
  29. package/dist/types/packages/core/src/catalog/settings-resources.d.ts +21 -0
  30. package/dist/types/packages/core/src/doc/autosave.d.ts +15 -2
  31. package/dist/types/packages/core/src/doc/bootstrap.d.ts +29 -0
  32. package/dist/types/packages/core/src/doc/channels.d.ts +9 -0
  33. package/dist/types/packages/core/src/doc/doc-commit-sink.d.ts +2 -1
  34. package/dist/types/packages/core/src/doc/doc-kit.d.ts +16 -1
  35. package/dist/types/packages/core/src/doc/envelope.d.ts +2 -1
  36. package/dist/types/packages/core/src/doc/migrate.d.ts +8 -6
  37. package/dist/types/packages/core/src/doc/schema-migrate.d.ts +50 -0
  38. package/dist/types/packages/core/src/doc/version-gate.d.ts +3 -0
  39. package/dist/types/packages/core/src/engine/commit-sink.d.ts +24 -2
  40. package/dist/types/packages/core/src/engine/frame-info.d.ts +16 -1
  41. package/dist/types/packages/core/src/facade/create-canvas-engine.d.ts +70 -6
  42. package/dist/types/packages/core/src/guards/guarded-tx.d.ts +4 -2
  43. package/dist/types/packages/core/src/helpers/churn-guard.d.ts +40 -0
  44. package/dist/types/packages/core/src/index.d.ts +13 -7
  45. package/dist/types/packages/core/src/input/queue.d.ts +11 -0
  46. package/dist/types/packages/core/src/nav/nested-canvas.d.ts +47 -11
  47. package/dist/types/packages/core/src/ops/arrange.d.ts +15 -0
  48. package/dist/types/packages/core/src/ops/insert.d.ts +62 -0
  49. package/dist/types/packages/core/src/ops/point-pick.d.ts +11 -7
  50. package/dist/types/packages/core/src/ops/sibling-order.d.ts +70 -0
  51. package/dist/types/packages/core/src/schema/meta.d.ts +1 -0
  52. package/dist/types/packages/core/src/settings/defaults.d.ts +45 -0
  53. package/dist/types/packages/core/src/settings/ground-config.d.ts +55 -0
  54. package/dist/types/packages/core/src/systems/chrome.d.ts +6 -2
  55. package/dist/types/packages/core/src/systems/insert-ghost.d.ts +25 -0
  56. package/dist/types/packages/core/src/systems/l1-pick.d.ts +25 -11
  57. package/dist/types/packages/core/src/systems/l2-recognize.d.ts +10 -4
  58. package/dist/types/packages/core/src/systems/l3-behave.d.ts +6 -4
  59. package/dist/types/packages/core/src/systems/l3-claim.d.ts +7 -3
  60. package/dist/types/packages/core/src/systems/l3-drop.d.ts +3 -1
  61. package/dist/types/packages/core/src/systems/l3-resize.d.ts +3 -1
  62. package/dist/types/packages/core/src/systems/l3-snap.d.ts +25 -7
  63. package/dist/types/packages/core/src/systems/nav-flight.d.ts +95 -0
  64. package/dist/types/packages/core/src/widget/define-widget.d.ts +39 -0
  65. package/dist/types/packages/core/src/widget/mount-store.d.ts +11 -3
  66. package/dist/types/packages/core/src/widget/set-props.d.ts +16 -0
  67. package/dist/types/packages/core/src/widget/spawn.d.ts +21 -1
  68. package/dist/types/packages/devtools/src/attach.d.ts +77 -0
  69. package/dist/types/packages/devtools/src/dock.d.ts +38 -0
  70. package/dist/types/packages/devtools/src/gl-panel.d.ts +69 -0
  71. package/dist/types/packages/devtools/src/index.d.ts +8 -6
  72. package/dist/types/packages/dom/src/index.d.ts +1 -3
  73. package/dist/types/packages/dom/src/measure-wiring.d.ts +2 -2
  74. package/dist/types/packages/dom/src/pointer-adapter.d.ts +21 -1
  75. package/dist/types/packages/dom/src/reflectors/dom-widgets.d.ts +5 -0
  76. package/dist/types/packages/ground/src/index.d.ts +52 -0
  77. package/dist/types/packages/ground/src/layer.d.ts +40 -0
  78. package/dist/types/packages/ground/src/pass.d.ts +41 -0
  79. package/dist/types/packages/ground/src/passes/grid.d.ts +21 -0
  80. package/dist/types/packages/ground/src/passes/guides-collect.d.ts +14 -0
  81. package/dist/types/packages/ground/src/passes/guides.d.ts +3 -0
  82. package/dist/types/packages/ground/src/passes/soup-collect.d.ts +35 -0
  83. package/dist/types/packages/ground/src/passes/soup-mesh.d.ts +8 -0
  84. package/dist/types/packages/ground/src/passes/wires-collect.d.ts +31 -0
  85. package/dist/types/packages/ground/src/passes/wires.d.ts +10 -0
  86. package/dist/types/packages/ground/src/renderer.d.ts +15 -0
  87. package/dist/types/packages/ice/src/ground.d.ts +1 -0
  88. package/dist/types/packages/kernel/src/bezier.d.ts +15 -0
  89. package/dist/types/packages/kernel/src/coords.d.ts +15 -0
  90. package/dist/types/packages/kernel/src/easing.d.ts +11 -0
  91. package/dist/types/packages/kernel/src/index.d.ts +3 -0
  92. package/dist/types/packages/kernel/src/layout.d.ts +118 -0
  93. package/dist/types/packages/kernel/src/nav-flight.d.ts +93 -0
  94. package/dist/types/packages/r3f/src/bridge.d.ts +73 -12
  95. package/dist/types/packages/r3f/src/composite-material.d.ts +9 -0
  96. package/dist/types/packages/r3f/src/compositor-pass.d.ts +22 -0
  97. package/dist/types/packages/r3f/src/gl-root.d.ts +76 -1
  98. package/dist/types/packages/r3f/src/gl-router.d.ts +10 -0
  99. package/dist/types/packages/r3f/src/index.d.ts +3 -2
  100. package/dist/types/packages/r3f/src/island-state.d.ts +44 -0
  101. package/dist/types/packages/r3f/src/preview-capture.d.ts +19 -0
  102. package/dist/types/packages/r3f/src/self-sustain.d.ts +39 -0
  103. package/dist/types/packages/r3f/src/use-island-frame.d.ts +16 -1
  104. package/dist/types/packages/react/src/engine-context.d.ts +8 -0
  105. package/dist/types/packages/react/src/index.d.ts +4 -2
  106. package/dist/types/packages/react/src/infinite-canvas.d.ts +40 -6
  107. package/dist/types/packages/react/src/preview-snapshots.d.ts +17 -0
  108. package/dist/types/packages/react/src/widget-preview.d.ts +14 -0
  109. package/package.json +13 -8
  110. package/dist/chunk-5S7GSXJG.js.map +0 -1
  111. package/dist/chunk-BCJ47SX7.js.map +0 -1
  112. package/dist/chunk-FIAXPNNY.js.map +0 -1
  113. package/dist/types/packages/devtools/src/panel.d.ts +0 -48
  114. package/dist/types/packages/dom/src/reflectors/grid.d.ts +0 -63
  115. package/dist/types/packages/dom/src/reflectors/wires.d.ts +0 -88
@@ -20,5 +20,20 @@ export declare function useIslandInvalidate(): () => void;
20
20
  * corners together) and pops it over neighbors while ≠1. Scaling scene content
21
21
  * instead crops the corners at the card-sized frustum — the 2026-07-12
22
22
  * hard-corner field report. Resets to 1 on unmount.
23
+ *
24
+ * The scale EASES to each new value (default 180ms, the DOM card-lift
25
+ * spring — GL has no CSS transitions, so the compositor runs the curve;
26
+ * 2026-07-13 field report: "GL lift snaps while DOM lifts smooth").
27
+ * `durationMs: 0` snaps.
23
28
  */
24
- export declare function useIslandLift(scale: number): void;
29
+ export declare function useIslandLift(scale: number, durationMs?: number): void;
30
+ /**
31
+ * Composite-quad fade — the lift's opacity twin (e.g. the drag-lift 75 %
32
+ * fade): eases the quad's drawn opacity to `opacity` (default 180ms; 0
33
+ * snaps) and MULTIPLIES the widget's durable `Opacity` cell, so a transient
34
+ * fade stacks over a doc-level opacity instead of fighting it. The DOM
35
+ * chrome runs its own CSS `opacity … ease` transition — same duration/curve
36
+ * family, so card body and GL content fade in lockstep. Resets to 1 on
37
+ * unmount.
38
+ */
39
+ export declare function useIslandOpacity(opacity: number, durationMs?: number): void;
@@ -22,6 +22,14 @@ export declare function EngineProvider({ engine, children }: EngineProviderProps
22
22
  export declare function useCanvasEngine(): CanvasEngine;
23
23
  /** The engine-owned write paths (design-005 §4): setTool, deleteSelection, etc. */
24
24
  export declare function useOps(): CanvasOps;
25
+ /**
26
+ * Take a stage background hold while `active` (ce.stage, 2026-07-19): the
27
+ * overlay-lifecycle sugar — the disposer releases on deactivate AND unmount,
28
+ * so a crashed/unmounted overlay can never wedge the canvas backgrounded.
29
+ * `engine` is an explicit param (not context): overlays typically render as
30
+ * SIBLINGS of <InfiniteCanvas>, outside the provider.
31
+ */
32
+ export declare function useStageHold(engine: CanvasEngine, active: boolean, name: string): void;
25
33
  /**
26
34
  * Escape hatch — the raw {@link World} for READS and Tier-3 OBSERVATION only.
27
35
  * Mutation goes through {@link useOps}/{@link useCommit} (a gesture-claimed,
@@ -6,9 +6,11 @@
6
6
  export declare const REACT_VERSION = "0.0.0";
7
7
  export { WidgetHiddenContext, useBreakpoint, useSelected, useWidgetProps, useWorldComponent, } from "./hooks";
8
8
  export { WidgetRoot, type WidgetComponentProps, type WidgetHosts, type WidgetRootProps } from "./widget-root";
9
- export { EngineProvider, useCanvasEngine, useOps, useWorld, type EngineProviderProps, } from "./engine-context";
9
+ export { EngineProvider, useCanvasEngine, useOps, useStageHold, useWorld, type EngineProviderProps, } from "./engine-context";
10
10
  export { useCommit, useUndoStatus, type Commit, type UndoStatus } from "./use-commit";
11
+ export { WidgetPreview, type WidgetPreviewProps } from "./widget-preview";
12
+ export { getPreviewSnapshot, hasPreviewSnapshot, setPreviewSnapshot, subscribePreviewSnapshots, type PreviewImage, } from "./preview-snapshots";
11
13
  export { useTool, useToolState } from "./use-tool";
12
14
  export { usePresencePeers, type PresencePeerView } from "./use-presence";
13
15
  export { attachKeymap, type KeymapEntry } from "./keymap";
14
- export { InfiniteCanvas, type InfiniteCanvasHandle, type InfiniteCanvasProps, } from "./infinite-canvas";
16
+ export { InfiniteCanvas, type GroundLayerFactory, type GroundLayerHandle, type InfiniteCanvasHandle, type InfiniteCanvasProps, } from "./infinite-canvas";
@@ -7,7 +7,7 @@
7
7
  * and the viewport sync — everything that must live next to a real container.
8
8
  *
9
9
  * Boot order (registration order = reflector flush order, mirrored exactly):
10
- * host → planes → reflectors[ planeTransform · grid(P0) · wires(P0) ·
10
+ * host → planes → reflectors[ planeTransform · ground(P0, app-injected) ·
11
11
  * domWidgets(P1/P3) · chrome(P4) · cursor · remoteCursors(P5) ] →
12
12
  * pointer adapter → measurement (optional) → keymap → rAF loop → viewport RO.
13
13
  *
@@ -24,14 +24,19 @@
24
24
  * - GL / R3F: the `@ice/r3f` wall forbids `@ice/react` importing three, so a
25
25
  * GL layer (GLViews) mounts APP-SIDE. Use {@link onReady} to receive the host
26
26
  * + planes and mount it yourself (like apps/glboard).
27
+ * - The GROUND layer (P0: dot grid, wires, snap guides — @ice/ground, three's
28
+ * WebGPURenderer) rides the same wall: pass its factory through the OPAQUE
29
+ * {@link InfiniteCanvasProps.ground} prop (`ground={ground({...})}`); this
30
+ * component types it structurally and never imports the package. No factory
31
+ * ⇒ no ground layer (headless/test boots).
27
32
  * - Devtools: the import wall forbids `@ice/react` importing `@ice/devtools`.
28
33
  * Wire the panel app-side against `engine.engine` (also via {@link onReady}).
29
34
  * - Measurement: auto-sized widgets need a `MeasureQueue` passed to BOTH
30
35
  * `createCanvasEngine({ measureQueue })` (ingest side) and this component's
31
36
  * `measureQueue` prop (ResizeObserver side). Absent ⇒ measurement is skipped.
32
37
  */
33
- import { type CanvasEngine, type MeasureQueue } from "@ice/core";
34
- import { type CanvasHost, type GLRoute, type GridConfig, type Planes } from "@ice/dom";
38
+ import { type CanvasEngine, type GridConfig, type MeasureQueue, type ReflectorDef, type WirePreviewBuffer, type World } from "@ice/core";
39
+ import { type CanvasHost, type GLRoute, type Planes } from "@ice/dom";
35
40
  import { type CSSProperties, type ReactElement, type ReactNode } from "react";
36
41
  /** Handed to {@link InfiniteCanvasProps.onReady} for app-side GL/devtools wiring. */
37
42
  export interface InfiniteCanvasHandle {
@@ -39,6 +44,27 @@ export interface InfiniteCanvasHandle {
39
44
  readonly host: CanvasHost;
40
45
  readonly planes: Planes;
41
46
  }
47
+ /**
48
+ * STRUCTURAL mirror of `@ice/ground`'s GroundLayer/GroundFactory (the
49
+ * `WidgetDef.component`-style opaque seam: react never imports the package —
50
+ * the wall forbids three here). `@ice/ground.ground(...)` returns a function
51
+ * assignable to this type.
52
+ */
53
+ export interface GroundLayerHandle {
54
+ readonly reflector: ReflectorDef & {
55
+ available(): boolean;
56
+ };
57
+ configureGrid(cfg: Partial<GridConfig>): void;
58
+ dispose(): void;
59
+ }
60
+ export type GroundLayerFactory = (ctx: {
61
+ readonly host: {
62
+ readonly container: HTMLElement;
63
+ readonly contentPlane: HTMLElement;
64
+ };
65
+ readonly world: World;
66
+ readonly readWirePreview: () => WirePreviewBuffer;
67
+ }) => GroundLayerHandle;
42
68
  export interface InfiniteCanvasProps {
43
69
  /** A constructed engine (`createCanvasEngine(...)`); NOT disposed on unmount. */
44
70
  readonly engine: CanvasEngine;
@@ -49,10 +75,18 @@ export interface InfiniteCanvasProps {
49
75
  readonly measureQueue?: MeasureQueue;
50
76
  /** Called once after the host/reflectors/loop are live (app-side GL/devtools). */
51
77
  readonly onReady?: (handle: InfiniteCanvasHandle) => void;
78
+ /**
79
+ * The P0 ground layer (dot grid, wires, snap guides — one WebGPU canvas).
80
+ * Pass `ground(opts)` from `@ice/ground`; received opaquely (see
81
+ * {@link GroundLayerFactory}). Memoize in the caller — a new identity
82
+ * re-boots the canvas mount effect. Absent ⇒ no ground layer renders.
83
+ */
84
+ readonly ground?: GroundLayerFactory;
52
85
  /**
53
86
  * Dot-grid tuning (theme dot color, spacing, fades). Applied live via the
54
- * grid reflector's `configure` — changing it never re-boots the canvas
55
- * (memoize in the caller to avoid redundant same-value redraws).
87
+ * ground layer's `configureGrid` — changing it never re-boots the canvas
88
+ * (memoize in the caller to avoid redundant same-value redraws). No-op
89
+ * when {@link ground} is absent.
56
90
  */
57
91
  readonly grid?: Partial<GridConfig>;
58
92
  /**
@@ -68,4 +102,4 @@ export interface InfiniteCanvasProps {
68
102
  /** Overlays inside the viewport (toolbars, HUD) — rendered under the EngineProvider. */
69
103
  readonly children?: ReactNode;
70
104
  }
71
- export declare function InfiniteCanvas({ engine, measureQueue, onReady, grid: gridConfig, glRoute, className, style, children, }: InfiniteCanvasProps): ReactElement;
105
+ export declare function InfiniteCanvas({ engine, measureQueue, onReady, ground, grid: gridConfig, glRoute, className, style, children, }: InfiniteCanvasProps): ReactElement;
@@ -0,0 +1,17 @@
1
+ /**
2
+ * The GL preview snapshot store (design-005 §2 preview contract, P2 —
3
+ * 2026-07-19). react stays three-free by LAW, so the capture pipeline lives
4
+ * in @ice/r3f and meets `<WidgetPreview>` HERE, at a dumb data seam: a
5
+ * module-level map of widget type → captured image, with subscription so an
6
+ * open palette re-renders the moment a capture lands.
7
+ *
8
+ * `PreviewImage` accepts a canvas alongside ImageBitmap so tests (and any
9
+ * app-side prebuilt-cache policy — the P3 seam) can inject without a GPU.
10
+ */
11
+ export type PreviewImage = ImageBitmap | HTMLCanvasElement;
12
+ export declare function setPreviewSnapshot(type: string, image: PreviewImage): void;
13
+ export declare function getPreviewSnapshot(type: string): PreviewImage | undefined;
14
+ export declare function hasPreviewSnapshot(type: string): boolean;
15
+ export declare function subscribePreviewSnapshots(listener: () => void): () => void;
16
+ /** TEST-ONLY wipe (not on the barrel). */
17
+ export declare function __resetPreviewSnapshotsForTests(): void;
@@ -0,0 +1,14 @@
1
+ import { type CSSProperties, type ReactElement, type ReactNode } from "react";
2
+ /** TEST-ONLY sandbox wipe (mirrors __resetWidgetsForTests; not on the barrel). */
3
+ export declare function __resetPreviewSandboxForTests(): void;
4
+ export interface WidgetPreviewProps {
5
+ readonly type: string;
6
+ /** The available box; the preview renders aspect-FITTED inside it. */
7
+ readonly width: number;
8
+ readonly height: number;
9
+ /** App silhouette shown when no preview path applies (or one throws). */
10
+ readonly fallback?: ReactNode;
11
+ readonly className?: string;
12
+ readonly style?: CSSProperties;
13
+ }
14
+ export declare function WidgetPreview({ type, width, height, fallback, className, style }: WidgetPreviewProps): ReactElement;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vibecook/ice",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "ICE — infinite canvas engine. Figma-grade infinite-canvas UX as a framework: defineWidget turns React/R3F components into canvas citizens — selectable, movable, resizable, wired into node graphs, CRDT-synced, undoable per gesture.",
5
5
  "license": "MIT",
6
6
  "author": "James Yong <me@jamesyong42.com>",
@@ -52,6 +52,10 @@
52
52
  "types": "./dist/types/packages/ice/src/r3f.d.ts",
53
53
  "default": "./dist/r3f.js"
54
54
  },
55
+ "./ground": {
56
+ "types": "./dist/types/packages/ice/src/ground.d.ts",
57
+ "default": "./dist/ground.js"
58
+ },
55
59
  "./devtools": {
56
60
  "types": "./dist/types/packages/ice/src/devtools.d.ts",
57
61
  "default": "./dist/devtools.js"
@@ -65,14 +69,15 @@
65
69
  "access": "public"
66
70
  },
67
71
  "dependencies": {
68
- "@vibecook/strata-ecs": "0.5.0",
69
- "loro-crdt": "^1.13.6",
72
+ "@vibecook/strata-ecs": "0.11.0",
73
+ "loro-crdt": "^1.13.8",
74
+ "stats-gl": "^4.2.3",
70
75
  "rbush": "^3.0.1"
71
76
  },
72
77
  "peerDependencies": {
73
78
  "@react-three/fiber": ">=9",
74
- "react": ">=18",
75
- "react-dom": ">=18",
79
+ "react": ">=19",
80
+ "react-dom": ">=19",
76
81
  "three": ">=0.160.0"
77
82
  },
78
83
  "peerDependenciesMeta": {
@@ -99,11 +104,11 @@
99
104
  "react-dom": "^19",
100
105
  "three": "^0.185.0",
101
106
  "@ice/core": "0.0.0",
107
+ "@ice/devtools": "0.0.0",
102
108
  "@ice/dom": "0.0.0",
103
- "@ice/kernel": "0.0.0",
104
109
  "@ice/r3f": "0.0.0",
105
- "@ice/devtools": "0.0.0",
106
- "@ice/react": "0.0.0"
110
+ "@ice/react": "0.0.0",
111
+ "@ice/kernel": "0.0.0"
107
112
  },
108
113
  "scripts": {
109
114
  "typecheck": "tsc --noEmit",