@vibecook/ice 0.10.0 → 0.11.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.
@@ -48,8 +48,8 @@ export interface GroundOptions {
48
48
  /**
49
49
  * Magnet pole sources (design-010 §3.3) — live app-authored objects, so they
50
50
  * live HERE, not in the plain-data GridConfig. Nothing wired ⇒ the magnet
51
- * field (if enabled) is widget-only; with magnet off they cost one gated
52
- * no-op subscription each.
51
+ * field is widget-only. The classic implementation accepts this same
52
+ * GroundOptions contract and ignores the sources.
53
53
  */
54
54
  readonly poles?: PoleSource | readonly PoleSource[];
55
55
  /** Extra app passes, rendered after the built-ins (renderOrder ≥ 3 is yours). */
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Shared contract for build-time-selectable grid implementations.
3
+ *
4
+ * Both classic and magnet factories accept the same config and dependency
5
+ * shape. `grid.ts` wires exactly one factory into the production entry graph,
6
+ * so selecting an implementation is an import change, never a runtime mode.
7
+ */
8
+ import { type GridConfig } from "../../../core/src/index";
9
+ import type { GroundPass } from "../pass";
10
+ import type { PoleSource } from "../poles";
11
+ import type { ReadSpatial } from "./magnet-collect";
12
+ export interface GridPass extends GroundPass {
13
+ /** Live re-tune (the react `grid` prop seam) — partial merge over current values. */
14
+ configure(cfg: Partial<GridConfig>): void;
15
+ }
16
+ /**
17
+ * Superset of implementation dependencies. Classic deliberately ignores
18
+ * these; magnet consumes them. Keeping one signature makes the wired factory
19
+ * interchangeable without changing its parent.
20
+ */
21
+ export interface GridPassDeps {
22
+ readonly poles?: readonly PoleSource[];
23
+ readonly readSpatial?: ReadSpatial;
24
+ }
25
+ export type GridPassFactory = (initial?: Partial<GridConfig>, deps?: GridPassDeps) => GridPass;
26
+ /** Shallow grid merge + one-level merge of the optional magnet tuning block. */
27
+ export declare function mergeGridConfig(base: GridConfig, next: Partial<GridConfig>): GridConfig;
28
+ export declare function resolveInitialGridConfig(initial: Partial<GridConfig>): GridConfig;
@@ -0,0 +1,2 @@
1
+ import { type GridPassFactory } from "./grid-contract";
2
+ export declare const createGridPass: GridPassFactory;
@@ -11,8 +11,8 @@
11
11
  * D4); the mouse uniform / `mouseOn` branch are deleted.
12
12
  * - fade ladder, level weight and dotAlpha are CPU-baked into ONE per-level
13
13
  * alpha (they are per-level constants per frame — magnet-collect owns them).
14
- * - dot rest radius comes from `GridConfig.dotRadius[0]` (config continuity
15
- * with the classic grid), not the WGSL's hardcoded `halfLen·0.16`.
14
+ * - dot rest radius comes from `GridConfig.dotRadius[0]` (shared config
15
+ * continuity), not the WGSL's hardcoded `halfLen·0.16`.
16
16
  * - coincidence skip (§5.4): sites shared with a visible coarser level drop
17
17
  * out (integer spacing ratios), replicating the classic max-composite look.
18
18
  * - NDC is computed from CSS-px directly (the WGSL path) — glyph sizes are
@@ -1,28 +1,10 @@
1
1
  /**
2
- * The grid pass — a MODE FACADE since design-010: the classic analytic dot
3
- * grid (grid-classic.ts, the default — byte-identical to pre-magnet builds)
4
- * and the magnet field lattice (grid-magnet.ts + magnet-collect.ts) behind
5
- * ONE `GridPass` contract. `configure` deep-merges the `magnet` key one level
6
- * (§3.1) so partial re-tunes never clobber the block.
2
+ * Production grid wiring — BUILD-TIME selection, not a runtime mode facade.
7
3
  *
8
- * Wake graph (all magnet wakes gated on `enabled` — the idle-scene zero-frame
9
- * guarantee is untouched when off): camera/resize are layer-owned;
10
- * `SpatialVersion` re-collects widget sources (gated on `widgets` too);
11
- * injected pole sources wake through their own subscriptions (D5 — the pass
12
- * observes no pointer/cursor/presence vocabulary). The magnet renderer is
13
- * built LAZILY on first enable: classic-only apps pay zero magnet cost.
4
+ * Keep this module intentionally tiny and import exactly one implementation.
5
+ * The unselected renderer then has no path from the package entry graph and
6
+ * is absent from the production bundle. To restore the classic grid, change
7
+ * only the implementation path below to `./grid-classic-pass`.
14
8
  */
15
- import { type GridConfig } from "../../../core/src/index";
16
- import type { GroundPass } from "../pass";
17
- import type { PoleSource } from "../poles";
18
- import { type ReadSpatial } from "./magnet-collect";
19
- export interface GridPass extends GroundPass {
20
- /** Live re-tune (the react `grid` prop seam) — partial merge over current values. */
21
- configure(cfg: Partial<GridConfig>): void;
22
- }
23
- /** Injected magnet inputs (design-010 §3.2) — absent pieces disable their sources. */
24
- export interface GridPassDeps {
25
- readonly poles?: readonly PoleSource[];
26
- readonly readSpatial?: ReadSpatial;
27
- }
28
- export declare function createGridPass(initial?: Partial<GridConfig>, deps?: GridPassDeps): GridPass;
9
+ export { createGridPass } from "./grid-magnet-pass";
10
+ export type { GridPass, GridPassDeps, GridPassFactory } from "./grid-contract";
@@ -24,8 +24,8 @@ export interface PoleSource {
24
24
  /** Called during collect — read-only world access (GroundPass.collect rules). */
25
25
  read(world: World): readonly Pole[];
26
26
  /**
27
- * Called during arm — `wake` marks the grid pass dirty (the pass gates it on
28
- * `magnet.enabled`, so idle scenes stay at zero frames). Returns unsubscriber.
27
+ * Called during arm — `wake` marks the wired magnet grid dirty. The classic
28
+ * implementation never subscribes. Returns an unsubscriber.
29
29
  */
30
30
  subscribe(world: World, wake: () => void): () => void;
31
31
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vibecook/ice",
3
- "version": "0.10.0",
3
+ "version": "0.11.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>",
@@ -1,30 +0,0 @@
1
- /**
2
- * The CLASSIC dot-grid renderer — extracted VERBATIM from grid.ts when the
3
- * magnet mode arrived (design-010 D1: classic stays the default and the
4
- * pixel-exact baseline; the pass facade in grid.ts owns mode switching).
5
- *
6
- * TSL port of the raw-WebGL grid (itself verbatim from v1 GridRenderer.ts;
7
- * the fragment math below is that shader re-expressed as a node graph, level
8
- * loop unrolled in JS). Screen-space: a fullscreen triangle whose vertex
9
- * stage passes clip coords through; the fragment reconstructs world position
10
- * from `screenCoordinate` (top-left device px on BOTH backends — three
11
- * normalizes, so the old manual y-flip is gone) + camera uniforms.
12
- *
13
- * One deliberate re-expression: the GLSL if/else fade ladder became the
14
- * closed form `clamp(min(rise, fall), 0, 1)` — identical piecewise output
15
- * (rise 0→1 across fadeIn, plateau 1, fall 1→0 across fadeOut) with no
16
- * branching. Everything else (fract-distance dots, 0.5-device-px AA,
17
- * max-composited levels) matches term for term.
18
- */
19
- import type { GridConfig } from "../../../core/src/index";
20
- import { Mesh } from "three/webgpu";
21
- import type { GroundFrame } from "../pass";
22
- export interface ClassicGridRenderer {
23
- readonly mesh: Mesh;
24
- /** Layer-written each collect. */
25
- setCamera(frame: GroundFrame): void;
26
- /** Config-written (the configure seam). */
27
- configure(cfg: GridConfig): void;
28
- dispose(): void;
29
- }
30
- export declare function createClassicGrid(cfg: GridConfig): ClassicGridRenderer;