@jamesyong42/infinite-canvas 1.3.0 → 1.4.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.
package/dist/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import { $ as WidgetBreakpoint, A as ContainerCamera, B as OverlapTarget, C as ViewportResource, D as CardOverlapHotPoint, E as Card, F as Dragging, G as Selected, H as PreDragLayer, I as InteractionRole, J as SnapTarget, K as SelectionFrame, L as Layer, M as Culled, N as CursorHint, O as Children, P as Draggable, Q as Widget, R as Locked, S as SpatialIndexResource, T as Active, U as Resizable, V as ParentFrame, W as Selectable, X as TransformTween, Y as Transform2D, Z as Visible, _ as CursorResource, a as useEntityTags, b as NavigationStackResource, c as useRegisteredTags, d as useTaggedEntities, et as WidgetData, f as EngineProvider, g as CardPresetsResource, h as CameraResource, i as useEntityComponents, j as ContainerChildren, k as Container, l as useResource, m as BreakpointConfigResource, n as useCamera, o as useQuery, p as useLayoutEngine, q as SnapSource, r as useComponent, s as useRegisteredComponents, t as useAllEntities, tt as ZIndex, u as useTag, v as DEFAULT_CARD_PRESET_SIZES, w as ZoomConfigResource, x as RootCameraResource, y as LayerOrderResource, z as OverlapCandidate } from "./ecs-3kimUV5Z.mjs";
2
2
  import { B as Profiler, C as selectBand, F as useWidgetResolver, I as ContainerRefProvider, L as useContainerRef, M as inputGroupStart, N as inputLog, P as WidgetResolverProvider, R as computeSnapGuides, S as isOutOfBand, a as useWidgetInvalidate, c as SelectionOverlaySlot, d as DEFAULT_SNAP_GUIDE_CONFIG, f as DEFAULT_SELECTION_CONFIG, g as R3FManager, i as useWidgetAnimation, j as sharedGlowUniforms, l as CardChrome, m as DEFAULT_GRID_CONFIG, n as useSharedMaterial, o as useWidgetPhase, r as useSharedTexture, s as WidgetSlot, t as useSharedGeometry, u as WebGLManager, x as ZOOM_BANDS, z as SpatialIndex } from "./hooks-gsQDDE56.mjs";
3
- import { SystemScheduler, createWorld, defineSystem } from "@jamesyong42/reactive-ecs";
3
+ import { PhasedScheduler, createWorld, defineSystem } from "@jamesyong42/reactive-ecs";
4
4
  import React, { useCallback, useEffect, useImperativeHandle, useLayoutEffect, useMemo, useRef, useState } from "react";
5
5
  import { jsx, jsxs } from "react/jsx-runtime";
6
6
  //#region src/ecs/archetype.ts
@@ -279,6 +279,7 @@ function clamp(value, min, max) {
279
279
  */
280
280
  const breakpointSystem = defineSystem({
281
281
  name: "breakpoint",
282
+ phase: "derive",
282
283
  after: "cull",
283
284
  execute: (world) => {
284
285
  const camera = world.getResource(CameraResource);
@@ -323,6 +324,7 @@ const breakpointSystem = defineSystem({
323
324
  */
324
325
  const cardSystem = defineSystem({
325
326
  name: "card",
327
+ phase: "derive",
326
328
  execute: (world) => {
327
329
  const resource = world.getResource(CardPresetsResource);
328
330
  if (!resource) return;
@@ -353,7 +355,7 @@ const cardSystem = defineSystem({
353
355
  */
354
356
  const cullSystem = defineSystem({
355
357
  name: "cull",
356
- after: "navigationFilter",
358
+ phase: "derive",
357
359
  execute: (world) => {
358
360
  const camera = world.getResource(CameraResource);
359
361
  const viewport = world.getResource(ViewportResource);
@@ -398,14 +400,13 @@ const cullSystem = defineSystem({
398
400
  * Dragging present, no PreDragLayer → promote (stash old layer, set overlay)
399
401
  * PreDragLayer present, no Dragging → restore (write back stashed layer)
400
402
  *
401
- * RFC-010 Phase 1 migrates the two `onTagAdded(Dragging)` /
402
- * `onTagRemoved(Dragging)` observers out of `LayoutEngine.ts` into a
403
- * `SystemScheduler` system. The `before: 'cull'` constraint is conservative
404
- * and becomes implicit once RFC-010 Phase 2 stamps `phase: 'react'`.
403
+ * RFC-010 runs in the `react` phase so the promote/restore is settled
404
+ * before `derive`-phase systems (`cull`, `breakpoint`, `sort`) and the
405
+ * `present`-phase visibility / frame-changes assembly run.
405
406
  */
406
407
  const dragPromoteSystem = defineSystem({
407
408
  name: "dragPromote",
408
- before: "cull",
409
+ phase: "react",
409
410
  execute: (world) => {
410
411
  for (const entity of world.queryTagged(Dragging)) {
411
412
  if (world.hasComponent(entity, PreDragLayer)) continue;
@@ -453,6 +454,7 @@ function reconcileEntityActive(world, entity) {
453
454
  */
454
455
  const navigationFilterSystem = defineSystem({
455
456
  name: "navigationFilter",
457
+ phase: "control",
456
458
  execute: (world) => {
457
459
  const navStack = world.getResource(NavigationStackResource);
458
460
  const stackChanged = navStack.changed;
@@ -477,6 +479,7 @@ const navigationFilterSystem = defineSystem({
477
479
  */
478
480
  const sortSystem = defineSystem({
479
481
  name: "sort",
482
+ phase: "derive",
480
483
  after: "breakpoint",
481
484
  execute: (_world) => {}
482
485
  });
@@ -514,6 +517,7 @@ function applyEasing(p, easing) {
514
517
  */
515
518
  const transformTweenSystem = defineSystem({
516
519
  name: "transformTween",
520
+ phase: "simulate",
517
521
  execute: (world) => {
518
522
  const nowMs = typeof performance !== "undefined" ? performance.now() : Date.now();
519
523
  for (const entity of world.query(TransformTween)) {
@@ -1481,6 +1485,35 @@ function createInteractionRuntime(ctx) {
1481
1485
  };
1482
1486
  }
1483
1487
  //#endregion
1488
+ //#region src/ecs/engine/phases.ts
1489
+ /**
1490
+ * Pipeline phases for the infinite-canvas `LayoutEngine`.
1491
+ *
1492
+ * `reactive-ecs` ships zero phase vocabulary — phase names and order are the
1493
+ * consumer's responsibility. These names are infinite-canvas's choice; a UI
1494
+ * tool, a game engine, and an agent simulator would each pick differently.
1495
+ *
1496
+ * Phase intent:
1497
+ * - `input` — drain external intent (gestures, raw flag captures) into the world
1498
+ * - `react` — maintain invariants in response to mutations from prior writes
1499
+ * - `control` — state machines, intent resolution, navigation
1500
+ * - `simulate` — time-driven mutations (tweens, animation)
1501
+ * - `derive` — compute frame-local derived state (visibility, sort, layout)
1502
+ * - `present` — build outputs for renderers (frame-changes, visible lists)
1503
+ * - `cleanup` — end-of-frame bookkeeping (clearDirty, incrementTick, emitFrame)
1504
+ *
1505
+ * See RFC-010 for the full architectural rationale.
1506
+ */
1507
+ const ENGINE_PHASES = [
1508
+ "input",
1509
+ "react",
1510
+ "control",
1511
+ "simulate",
1512
+ "derive",
1513
+ "present",
1514
+ "cleanup"
1515
+ ];
1516
+ //#endregion
1484
1517
  //#region src/ecs/engine/widget-binding.ts
1485
1518
  function createWidgetRegistry(defs = []) {
1486
1519
  const map = /* @__PURE__ */ new Map();
@@ -1505,7 +1538,10 @@ function createWidgetRegistry(defs = []) {
1505
1538
  */
1506
1539
  function createLayoutEngine(config) {
1507
1540
  const world = createWorld();
1508
- const scheduler = new SystemScheduler();
1541
+ const scheduler = new PhasedScheduler({
1542
+ phases: ENGINE_PHASES,
1543
+ defaultPhase: "derive"
1544
+ });
1509
1545
  const spatialIndex = new SpatialIndex();
1510
1546
  const profiler = new Profiler();
1511
1547
  scheduler.profiler = profiler;