@jamesyong42/infinite-canvas 1.2.0 → 1.3.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/README.md +65 -0
- package/dist/advanced.cjs +61 -24
- package/dist/advanced.cjs.map +1 -1
- package/dist/advanced.d.cts +180 -64
- package/dist/advanced.d.cts.map +1 -1
- package/dist/advanced.d.mts +180 -64
- package/dist/advanced.d.mts.map +1 -1
- package/dist/advanced.mjs +29 -12
- package/dist/advanced.mjs.map +1 -1
- package/dist/devtools.cjs +22 -22
- package/dist/devtools.cjs.map +1 -1
- package/dist/devtools.d.cts +2 -2
- package/dist/devtools.d.cts.map +1 -1
- package/dist/devtools.d.mts +2 -2
- package/dist/devtools.d.mts.map +1 -1
- package/dist/devtools.mjs +2 -2
- package/dist/devtools.mjs.map +1 -1
- package/dist/{hooks-BwY7rRHg.mjs → ecs-3kimUV5Z.mjs} +238 -74
- package/dist/ecs-3kimUV5Z.mjs.map +1 -0
- package/dist/{hooks-DHShH86C.cjs → ecs-B4QrqfvQ.cjs} +320 -108
- package/dist/ecs-B4QrqfvQ.cjs.map +1 -0
- package/dist/hooks-CtP02JNt.cjs +3762 -0
- package/dist/hooks-CtP02JNt.cjs.map +1 -0
- package/dist/hooks-gsQDDE56.mjs +3494 -0
- package/dist/hooks-gsQDDE56.mjs.map +1 -0
- package/dist/index-3GY7T8JM.d.mts +480 -0
- package/dist/index-3GY7T8JM.d.mts.map +1 -0
- package/dist/index-B7B1tRPl.d.cts +480 -0
- package/dist/index-B7B1tRPl.d.cts.map +1 -0
- package/dist/index-DSdbSQ_t.d.cts +1451 -0
- package/dist/index-DSdbSQ_t.d.cts.map +1 -0
- package/dist/index-Dj9odADH.d.mts +1451 -0
- package/dist/index-Dj9odADH.d.mts.map +1 -0
- package/dist/index.cjs +3865 -643
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +315 -138
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +315 -138
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +3767 -571
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/dist/SelectionRenderer-CR2PBQwx.d.cts +0 -105
- package/dist/SelectionRenderer-CR2PBQwx.d.cts.map +0 -1
- package/dist/SelectionRenderer-DlsBstAq.d.mts +0 -105
- package/dist/SelectionRenderer-DlsBstAq.d.mts.map +0 -1
- package/dist/WebGLWidgetLayer-BBMuwzHq.cjs +0 -3560
- package/dist/WebGLWidgetLayer-BBMuwzHq.cjs.map +0 -1
- package/dist/WebGLWidgetLayer-C3p1tnpm.mjs +0 -3375
- package/dist/WebGLWidgetLayer-C3p1tnpm.mjs.map +0 -1
- package/dist/engine-BfbvWXSk.d.mts +0 -982
- package/dist/engine-BfbvWXSk.d.mts.map +0 -1
- package/dist/engine-CCjuFMC-.d.cts +0 -982
- package/dist/engine-CCjuFMC-.d.cts.map +0 -1
- package/dist/hooks-BwY7rRHg.mjs.map +0 -1
- package/dist/hooks-DHShH86C.cjs.map +0 -1
|
@@ -1,982 +0,0 @@
|
|
|
1
|
-
import * as _$_jamesyong42_reactive_ecs0 from "@jamesyong42/reactive-ecs";
|
|
2
|
-
import { ComponentInit, ComponentType, EntityId, SystemDef, TagType, Unsubscribe, World } from "@jamesyong42/reactive-ecs";
|
|
3
|
-
|
|
4
|
-
//#region src/archetype.d.ts
|
|
5
|
-
/**
|
|
6
|
-
* An archetype is a recipe for creating an entity: it declares which components
|
|
7
|
-
* and tags the entity should have on spawn. Archetypes may reference a widget
|
|
8
|
-
* type (for visible entities) or stand alone (for logic-only entities).
|
|
9
|
-
*
|
|
10
|
-
* The engine auto-generates a default archetype for every registered widget
|
|
11
|
-
* that does not have an explicit one — so simple widgets don't need to ship
|
|
12
|
-
* an archetype at all. Write an archetype only when you need to bundle extra
|
|
13
|
-
* behaviour (Container, Locked, custom components) with a widget.
|
|
14
|
-
*/
|
|
15
|
-
interface Archetype {
|
|
16
|
-
/** Unique archetype id. Pass this to `engine.spawn(id, ...)`. */
|
|
17
|
-
id: string;
|
|
18
|
-
/**
|
|
19
|
-
* The widget type this archetype renders as. Required for visible entities;
|
|
20
|
-
* omit for logic-only entities that have no view.
|
|
21
|
-
*/
|
|
22
|
-
widget?: string;
|
|
23
|
-
/** Extra components added on spawn, beyond Transform2D / Widget / WidgetData / ZIndex. */
|
|
24
|
-
components?: ComponentInit[];
|
|
25
|
-
/** Extra tags added on spawn, beyond the interactive defaults. */
|
|
26
|
-
tags?: TagType[];
|
|
27
|
-
/**
|
|
28
|
-
* Which interaction capabilities to grant on spawn.
|
|
29
|
-
*
|
|
30
|
-
* - `true` (default) / `undefined`: add Selectable, Draggable, Resizable,
|
|
31
|
-
* and the SelectionFrame (engine-drawn outline).
|
|
32
|
-
* - `false`: add none (backdrops, decorations, locked entities).
|
|
33
|
-
* - object form: pick and choose — e.g. iOS-style cards use
|
|
34
|
-
* `{ selectable: true, draggable: true, resizable: false, selectionFrame: false }`
|
|
35
|
-
* so they can be moved and selected but never resized, and they render
|
|
36
|
-
* their own chrome instead of the engine-drawn frame.
|
|
37
|
-
*
|
|
38
|
-
* Omitted interaction keys default to `false`. `selectionFrame` is an
|
|
39
|
-
* exception: if omitted, it follows `selectable` (an entity you can
|
|
40
|
-
* select gets a frame unless you explicitly opt out).
|
|
41
|
-
*/
|
|
42
|
-
interactive?: boolean | {
|
|
43
|
-
selectable?: boolean;
|
|
44
|
-
draggable?: boolean;
|
|
45
|
-
resizable?: boolean;
|
|
46
|
-
selectionFrame?: boolean;
|
|
47
|
-
};
|
|
48
|
-
/** Overrides the widget's defaultSize. */
|
|
49
|
-
defaultSize?: {
|
|
50
|
-
width: number;
|
|
51
|
-
height: number;
|
|
52
|
-
};
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
|
-
* Options for `engine.spawn(archetypeId, opts)`.
|
|
56
|
-
* All fields are optional — defaults come from the archetype + widget.
|
|
57
|
-
*/
|
|
58
|
-
interface SpawnOptions {
|
|
59
|
-
/** World-space position. Defaults to { x: 0, y: 0 }. */
|
|
60
|
-
at?: {
|
|
61
|
-
x: number;
|
|
62
|
-
y: number;
|
|
63
|
-
};
|
|
64
|
-
/** World-space size. Falls back to archetype.defaultSize → widget.defaultSize. */
|
|
65
|
-
size?: {
|
|
66
|
-
width: number;
|
|
67
|
-
height: number;
|
|
68
|
-
};
|
|
69
|
-
/** Initial rotation in radians. Default 0. */
|
|
70
|
-
rotation?: number;
|
|
71
|
-
/** Data patch merged into the widget's defaultData. */
|
|
72
|
-
data?: Record<string, unknown>;
|
|
73
|
-
/** Z-order. Default 0. */
|
|
74
|
-
zIndex?: number;
|
|
75
|
-
/** Parent entity for hierarchy nesting. */
|
|
76
|
-
parent?: EntityId;
|
|
77
|
-
}
|
|
78
|
-
/** Simple in-memory archetype registry. */
|
|
79
|
-
interface ArchetypeRegistry {
|
|
80
|
-
register(archetype: Archetype): void;
|
|
81
|
-
get(id: string): Archetype | null;
|
|
82
|
-
getAll(): Archetype[];
|
|
83
|
-
}
|
|
84
|
-
declare function createArchetypeRegistry(archetypes?: Archetype[]): ArchetypeRegistry;
|
|
85
|
-
//#endregion
|
|
86
|
-
//#region src/commands.d.ts
|
|
87
|
-
interface Command {
|
|
88
|
-
execute(world: World): void;
|
|
89
|
-
undo(world: World): void;
|
|
90
|
-
}
|
|
91
|
-
declare class CommandBuffer {
|
|
92
|
-
private undoStack;
|
|
93
|
-
private redoStack;
|
|
94
|
-
private currentGroup;
|
|
95
|
-
/** Start grouping commands (e.g., on pointerdown). All commands until endGroup() are one undo step. */
|
|
96
|
-
beginGroup(): void;
|
|
97
|
-
/** Execute a command and record it for undo. */
|
|
98
|
-
execute(command: Command, world: World): void;
|
|
99
|
-
/** Close the current group — all commands since beginGroup() become one undo step. */
|
|
100
|
-
endGroup(): void;
|
|
101
|
-
/** Undo the last command group. */
|
|
102
|
-
undo(world: World): boolean;
|
|
103
|
-
/** Redo the last undone command group. */
|
|
104
|
-
redo(world: World): boolean;
|
|
105
|
-
canUndo(): boolean;
|
|
106
|
-
canRedo(): boolean;
|
|
107
|
-
clear(): void;
|
|
108
|
-
get undoSize(): number;
|
|
109
|
-
get redoSize(): number;
|
|
110
|
-
}
|
|
111
|
-
declare class MoveCommand implements Command {
|
|
112
|
-
private entityIds;
|
|
113
|
-
private dx;
|
|
114
|
-
private dy;
|
|
115
|
-
private transformType;
|
|
116
|
-
private beforePositions;
|
|
117
|
-
private afterPositions;
|
|
118
|
-
private captured;
|
|
119
|
-
constructor(entityIds: EntityId[], dx: number, dy: number, transformType: ComponentType<{
|
|
120
|
-
x: number;
|
|
121
|
-
y: number;
|
|
122
|
-
}>);
|
|
123
|
-
execute(world: World): void;
|
|
124
|
-
undo(world: World): void;
|
|
125
|
-
}
|
|
126
|
-
declare class ResizeCommand implements Command {
|
|
127
|
-
private entityId;
|
|
128
|
-
private before;
|
|
129
|
-
private after;
|
|
130
|
-
private transformType;
|
|
131
|
-
constructor(entityId: EntityId, before: {
|
|
132
|
-
x: number;
|
|
133
|
-
y: number;
|
|
134
|
-
width: number;
|
|
135
|
-
height: number;
|
|
136
|
-
}, after: {
|
|
137
|
-
x: number;
|
|
138
|
-
y: number;
|
|
139
|
-
width: number;
|
|
140
|
-
height: number;
|
|
141
|
-
}, transformType: ComponentType<{
|
|
142
|
-
x: number;
|
|
143
|
-
y: number;
|
|
144
|
-
width: number;
|
|
145
|
-
height: number;
|
|
146
|
-
}>);
|
|
147
|
-
execute(world: World): void;
|
|
148
|
-
undo(world: World): void;
|
|
149
|
-
}
|
|
150
|
-
declare class SetComponentCommand<T> implements Command {
|
|
151
|
-
private entityId;
|
|
152
|
-
private type;
|
|
153
|
-
private before;
|
|
154
|
-
private after;
|
|
155
|
-
constructor(entityId: EntityId, type: ComponentType<T>, before: Partial<T>, after: Partial<T>);
|
|
156
|
-
execute(world: World): void;
|
|
157
|
-
undo(world: World): void;
|
|
158
|
-
}
|
|
159
|
-
//#endregion
|
|
160
|
-
//#region src/components.d.ts
|
|
161
|
-
/** Position, size, and rotation of an entity in local coordinates (world units). */
|
|
162
|
-
declare const Transform2D: _$_jamesyong42_reactive_ecs0.ComponentType<{
|
|
163
|
-
x: number;
|
|
164
|
-
y: number;
|
|
165
|
-
width: number;
|
|
166
|
-
height: number;
|
|
167
|
-
rotation: number;
|
|
168
|
-
}>;
|
|
169
|
-
/** Computed world-space bounding box. Read-only -- updated by the transform propagation system. */
|
|
170
|
-
declare const WorldBounds: _$_jamesyong42_reactive_ecs0.ComponentType<{
|
|
171
|
-
worldX: number;
|
|
172
|
-
worldY: number;
|
|
173
|
-
worldWidth: number;
|
|
174
|
-
worldHeight: number;
|
|
175
|
-
}>;
|
|
176
|
-
/** Rendering and hit-test ordering. Higher values render on top. */
|
|
177
|
-
declare const ZIndex: _$_jamesyong42_reactive_ecs0.ComponentType<{
|
|
178
|
-
value: number;
|
|
179
|
-
}>;
|
|
180
|
-
/** Parent entity reference. Used for nested containers and handle sync. */
|
|
181
|
-
declare const Parent: _$_jamesyong42_reactive_ecs0.ComponentType<{
|
|
182
|
-
id: EntityId;
|
|
183
|
-
}>;
|
|
184
|
-
/** Child entity IDs. Used for nested containers and handle sync. */
|
|
185
|
-
declare const Children: _$_jamesyong42_reactive_ecs0.ComponentType<{
|
|
186
|
-
ids: EntityId[];
|
|
187
|
-
}>;
|
|
188
|
-
/** Marks an entity as a renderable widget with a type identifier and rendering surface. */
|
|
189
|
-
declare const Widget$1: _$_jamesyong42_reactive_ecs0.ComponentType<{
|
|
190
|
-
surface: "dom" | "webgl" | "webview";
|
|
191
|
-
type: string;
|
|
192
|
-
}>;
|
|
193
|
-
/** Arbitrary application data attached to a widget entity. Access via useWidgetData(). */
|
|
194
|
-
declare const WidgetData: _$_jamesyong42_reactive_ecs0.ComponentType<{
|
|
195
|
-
data: Record<string, unknown>;
|
|
196
|
-
}>;
|
|
197
|
-
/** Computed responsive breakpoint based on screen-space size. Read-only. */
|
|
198
|
-
declare const WidgetBreakpoint: _$_jamesyong42_reactive_ecs0.ComponentType<{
|
|
199
|
-
current: "micro" | "compact" | "normal" | "expanded" | "detailed";
|
|
200
|
-
screenWidth: number;
|
|
201
|
-
screenHeight: number;
|
|
202
|
-
}>;
|
|
203
|
-
/** iOS-style card size presets. Actual dimensions live in CardPresetsResource. */
|
|
204
|
-
type CardPreset = 'small' | 'medium' | 'large' | 'xl';
|
|
205
|
-
/**
|
|
206
|
-
* Marks an entity as an iOS-style card with a fixed preset size.
|
|
207
|
-
* The `cardSystem` reconciles `Transform2D.width/height` from the preset
|
|
208
|
-
* each tick, so cards cannot be resized freely — change `preset` instead.
|
|
209
|
-
*/
|
|
210
|
-
declare const Card: _$_jamesyong42_reactive_ecs0.ComponentType<{
|
|
211
|
-
preset: CardPreset;
|
|
212
|
-
}>;
|
|
213
|
-
/** Marks an entity as an enterable container (double-click/double-tap to enter). */
|
|
214
|
-
declare const Container: _$_jamesyong42_reactive_ecs0.ComponentType<{
|
|
215
|
-
enterable: boolean;
|
|
216
|
-
}>;
|
|
217
|
-
/** Resize handle positions — 4 edges + 4 corners. */
|
|
218
|
-
type ResizeHandlePos = 'n' | 's' | 'e' | 'w' | 'ne' | 'nw' | 'se' | 'sw';
|
|
219
|
-
/**
|
|
220
|
-
* Rectangular interactable region anchored relative to the parent entity's WorldBounds.
|
|
221
|
-
* Anchor values are in 0..1 space: 0 = parent min edge, 1 = parent max edge.
|
|
222
|
-
* Widget bodies do NOT need Hitbox — their WorldBounds is already their hit area.
|
|
223
|
-
* Hitbox is only for sub-entities (handles, ports) whose position is parent-relative.
|
|
224
|
-
*/
|
|
225
|
-
declare const Hitbox: _$_jamesyong42_reactive_ecs0.ComponentType<{
|
|
226
|
-
anchorX: number;
|
|
227
|
-
anchorY: number;
|
|
228
|
-
width: number;
|
|
229
|
-
height: number;
|
|
230
|
-
}>;
|
|
231
|
-
/** Discriminated union of interaction roles an entity can fulfil. */
|
|
232
|
-
type InteractionRoleType = {
|
|
233
|
-
type: 'drag';
|
|
234
|
-
} | {
|
|
235
|
-
type: 'select';
|
|
236
|
-
} | {
|
|
237
|
-
type: 'resize';
|
|
238
|
-
handle: ResizeHandlePos;
|
|
239
|
-
} | {
|
|
240
|
-
type: 'rotate';
|
|
241
|
-
} | {
|
|
242
|
-
type: 'connect';
|
|
243
|
-
} | {
|
|
244
|
-
type: 'canvas';
|
|
245
|
-
};
|
|
246
|
-
type InteractionRoleData = {
|
|
247
|
-
/** Hit-test priority — higher wins when multiple entities contain the point. */layer: number; /** Discriminated role + role-specific data. */
|
|
248
|
-
role: InteractionRoleType;
|
|
249
|
-
};
|
|
250
|
-
/**
|
|
251
|
-
* Declares what happens when this entity is hit, plus its hit-test priority.
|
|
252
|
-
* Canonical layers: 0=canvas, 5=widget body, 10=edge handles, 15=corner handles, 20=reserved.
|
|
253
|
-
*/
|
|
254
|
-
declare const InteractionRole: _$_jamesyong42_reactive_ecs0.ComponentType<InteractionRoleData>;
|
|
255
|
-
/** Data shape for the HandleSet component. */
|
|
256
|
-
type HandleSetData = {
|
|
257
|
-
ids: EntityId[];
|
|
258
|
-
};
|
|
259
|
-
/**
|
|
260
|
-
* Component on the parent entity listing the EntityIds of its spawned handle children.
|
|
261
|
-
* Enables O(1) cascade destroy without a reverse-index scan of Parent components.
|
|
262
|
-
*/
|
|
263
|
-
declare const HandleSet: _$_jamesyong42_reactive_ecs0.ComponentType<HandleSetData>;
|
|
264
|
-
/** CSS cursor values the canvas may request. */
|
|
265
|
-
type CSSCursor = 'default' | 'grab' | 'grabbing' | 'crosshair' | 'n-resize' | 's-resize' | 'e-resize' | 'w-resize' | 'ne-resize' | 'nw-resize' | 'se-resize' | 'sw-resize';
|
|
266
|
-
type CursorHintData = {
|
|
267
|
-
/** Cursor when this entity is hovered in idle state. */hover: CSSCursor; /** Cursor while this entity is being dragged/resized. */
|
|
268
|
-
active: CSSCursor;
|
|
269
|
-
};
|
|
270
|
-
/** Declares the cursor this entity requests when hovered and when active. */
|
|
271
|
-
declare const CursorHint: _$_jamesyong42_reactive_ecs0.ComponentType<CursorHintData>;
|
|
272
|
-
/** Marks an entity as selectable by click or marquee. */
|
|
273
|
-
declare const Selectable: _$_jamesyong42_reactive_ecs0.TagType;
|
|
274
|
-
/** Marks an entity as draggable via pointer interaction. */
|
|
275
|
-
declare const Draggable: _$_jamesyong42_reactive_ecs0.TagType;
|
|
276
|
-
/** Marks an entity as resizable via edge/corner handles. */
|
|
277
|
-
declare const Resizable: _$_jamesyong42_reactive_ecs0.TagType;
|
|
278
|
-
/** Prevents an entity from being moved or resized. */
|
|
279
|
-
declare const Locked: _$_jamesyong42_reactive_ecs0.TagType;
|
|
280
|
-
/** Indicates the entity is currently selected. */
|
|
281
|
-
declare const Selected: _$_jamesyong42_reactive_ecs0.TagType;
|
|
282
|
-
/**
|
|
283
|
-
* Indicates the entity is currently being dragged by the user.
|
|
284
|
-
* Added after the drag dead-zone is crossed; removed on pointer up/cancel.
|
|
285
|
-
* Renderers read this to apply transient drag affordances (e.g. scale/shadow lift).
|
|
286
|
-
*/
|
|
287
|
-
declare const Dragging: _$_jamesyong42_reactive_ecs0.TagType;
|
|
288
|
-
/**
|
|
289
|
-
* Entities with this tag get the engine-drawn selection + hover outline frame.
|
|
290
|
-
* Granted automatically to Selectable entities unless explicitly disabled via
|
|
291
|
-
* `Archetype.interactive.selectionFrame: false`. Widgets that render their own
|
|
292
|
-
* selected/hover chrome (e.g. iOS-style cards) opt out.
|
|
293
|
-
*/
|
|
294
|
-
declare const SelectionFrame: _$_jamesyong42_reactive_ecs0.TagType;
|
|
295
|
-
/** Indicates the entity is currently being interacted with (drag, resize). */
|
|
296
|
-
declare const Active: _$_jamesyong42_reactive_ecs0.TagType;
|
|
297
|
-
/** Indicates the entity is within the visible viewport. Set by the cull system. */
|
|
298
|
-
declare const Visible: _$_jamesyong42_reactive_ecs0.TagType;
|
|
299
|
-
//#endregion
|
|
300
|
-
//#region src/profiler.d.ts
|
|
301
|
-
/**
|
|
302
|
-
* Multi-layer performance profiler.
|
|
303
|
-
*
|
|
304
|
-
* Tracks three independent rendering concerns:
|
|
305
|
-
*
|
|
306
|
-
* 1. ECS tick — systems, visibility, entity counts. Driven by `engine.tick()`.
|
|
307
|
-
* 2. WebGL engine pass — the library's grid + selection renderers. Runs
|
|
308
|
-
* inside the rAF loop immediately after each ECS tick, so samples share
|
|
309
|
-
* the ECS ring and carry matched tick ids.
|
|
310
|
-
* 3. R3F canvas — the user's 3D widgets inside the shared `<Canvas>`. Runs
|
|
311
|
-
* continuously at rAF cadence regardless of engine ticks, so it has its
|
|
312
|
-
* own ring.
|
|
313
|
-
*
|
|
314
|
-
* All methods are no-ops when disabled — zero cost for production builds.
|
|
315
|
-
* User Timing API marks are emitted when enabled so traces line up with
|
|
316
|
-
* Chrome DevTools' Performance panel.
|
|
317
|
-
*/
|
|
318
|
-
interface TickSample {
|
|
319
|
-
tick: number;
|
|
320
|
-
timestamp: number;
|
|
321
|
-
/** Total tick duration (ms) = ECS tick + WebGL engine pass. */
|
|
322
|
-
totalMs: number;
|
|
323
|
-
ecs: {
|
|
324
|
-
/** Per-system durations (ms). */systems: Record<string, number>; /** Visible entity computation (ms). */
|
|
325
|
-
visibilityMs: number; /** Entity counts at this frame. */
|
|
326
|
-
entityCount: number;
|
|
327
|
-
visibleCount: number;
|
|
328
|
-
};
|
|
329
|
-
webgl: {
|
|
330
|
-
/** Grid renderer pass duration (ms). */gridMs: number; /** Selection + hover + snap-guide render pass duration (ms). */
|
|
331
|
-
selectionMs: number; /** Total `renderer.info.render.calls` across all passes this tick. */
|
|
332
|
-
drawCalls: number; /** Total `renderer.info.render.triangles` across all passes this tick. */
|
|
333
|
-
triangles: number; /** Selection frames drawn this tick. */
|
|
334
|
-
selectionFrames: number; /** Snap guides drawn this tick. */
|
|
335
|
-
snapGuides: number; /** Equal-spacing indicators drawn this tick. */
|
|
336
|
-
spacingIndicators: number; /** DOM slot.transform writes this tick (from changes.positionsChanged). */
|
|
337
|
-
domPositionsUpdated: number;
|
|
338
|
-
};
|
|
339
|
-
}
|
|
340
|
-
interface R3FSample {
|
|
341
|
-
timestamp: number;
|
|
342
|
-
/** Delta since the previous R3F frame (ms). */
|
|
343
|
-
dtMs: number;
|
|
344
|
-
/** three.js renderer.info snapshot. */
|
|
345
|
-
drawCalls: number;
|
|
346
|
-
triangles: number;
|
|
347
|
-
points: number;
|
|
348
|
-
lines: number;
|
|
349
|
-
programs: number;
|
|
350
|
-
geometries: number;
|
|
351
|
-
textures: number;
|
|
352
|
-
activeWidgets: number;
|
|
353
|
-
}
|
|
354
|
-
interface FrameTimeStats {
|
|
355
|
-
avg: number;
|
|
356
|
-
p50: number;
|
|
357
|
-
p95: number;
|
|
358
|
-
p99: number;
|
|
359
|
-
max: number;
|
|
360
|
-
}
|
|
361
|
-
interface EcsStats {
|
|
362
|
-
fps: number;
|
|
363
|
-
frameTime: FrameTimeStats;
|
|
364
|
-
systemAvg: Record<string, number>;
|
|
365
|
-
systemP95: Record<string, number>;
|
|
366
|
-
/** Avg frame time as % of 16.67ms (60 fps). */
|
|
367
|
-
budgetUsed: number;
|
|
368
|
-
sampleCount: number;
|
|
369
|
-
}
|
|
370
|
-
interface WebGLStats {
|
|
371
|
-
/** Tick cadence — matches ECS since both fire together. */
|
|
372
|
-
fps: number;
|
|
373
|
-
/** Avg combined pass time (ms) and percentile breakdown. */
|
|
374
|
-
frameTime: FrameTimeStats;
|
|
375
|
-
/** Avg combined pass time as % of 16.67ms budget. */
|
|
376
|
-
budgetUsed: number;
|
|
377
|
-
gridAvg: number;
|
|
378
|
-
gridP95: number;
|
|
379
|
-
selectionAvg: number;
|
|
380
|
-
selectionP95: number;
|
|
381
|
-
avgDrawCalls: number;
|
|
382
|
-
avgTriangles: number;
|
|
383
|
-
avgSelectionFrames: number;
|
|
384
|
-
avgSnapGuides: number;
|
|
385
|
-
avgDomUpdates: number;
|
|
386
|
-
sampleCount: number;
|
|
387
|
-
}
|
|
388
|
-
interface R3FStats {
|
|
389
|
-
fps: number;
|
|
390
|
-
frameTime: FrameTimeStats;
|
|
391
|
-
avgDrawCalls: number;
|
|
392
|
-
avgTriangles: number;
|
|
393
|
-
/** Latest snapshots — these don't average meaningfully. */
|
|
394
|
-
programs: number;
|
|
395
|
-
geometries: number;
|
|
396
|
-
textures: number;
|
|
397
|
-
activeWidgets: number;
|
|
398
|
-
sampleCount: number;
|
|
399
|
-
}
|
|
400
|
-
interface ProfilerStats {
|
|
401
|
-
ecs: EcsStats;
|
|
402
|
-
webgl: WebGLStats;
|
|
403
|
-
r3f: R3FStats;
|
|
404
|
-
}
|
|
405
|
-
/** What's being timed inside the library's WebGL engine pass. */
|
|
406
|
-
type WebGLPass = 'grid' | 'selection';
|
|
407
|
-
declare class Profiler {
|
|
408
|
-
private enabled;
|
|
409
|
-
private tickRing;
|
|
410
|
-
private tickWrite;
|
|
411
|
-
private tickFilled;
|
|
412
|
-
private r3fRing;
|
|
413
|
-
private r3fWrite;
|
|
414
|
-
private r3fFilled;
|
|
415
|
-
private frameStart;
|
|
416
|
-
private currentSystems;
|
|
417
|
-
private visibilityMs;
|
|
418
|
-
private webglGridMs;
|
|
419
|
-
private webglSelectionMs;
|
|
420
|
-
private webglDrawCalls;
|
|
421
|
-
private webglTriangles;
|
|
422
|
-
private webglSelectionFrames;
|
|
423
|
-
private webglSnapGuides;
|
|
424
|
-
private webglSpacingIndicators;
|
|
425
|
-
private webglDomPositionsUpdated;
|
|
426
|
-
private currentTick;
|
|
427
|
-
/** Enable/disable profiling. When disabled, all methods are no-ops. */
|
|
428
|
-
setEnabled(on: boolean): void;
|
|
429
|
-
isEnabled(): boolean;
|
|
430
|
-
/** Call at the start of engine.tick(). */
|
|
431
|
-
beginFrame(tick: number): void;
|
|
432
|
-
/** Call around each ECS system execution. */
|
|
433
|
-
beginSystem(name: string): void;
|
|
434
|
-
endSystem(name: string): void;
|
|
435
|
-
beginVisibility(): void;
|
|
436
|
-
endVisibility(): void;
|
|
437
|
-
/** Call right before the named engine WebGL pass renders. */
|
|
438
|
-
beginWebGL(pass: WebGLPass): void;
|
|
439
|
-
/** Call right after the named engine WebGL pass renders. */
|
|
440
|
-
endWebGL(pass: WebGLPass): void;
|
|
441
|
-
/**
|
|
442
|
-
* Record WebGL engine pass counters for the current tick. `drawCalls` and
|
|
443
|
-
* `triangles` should be the totals from `renderer.info.render` accumulated
|
|
444
|
-
* across all engine passes in this tick (grid + selection). Callers must
|
|
445
|
-
* reset `renderer.info` at the start of the tick (with `autoReset=false`)
|
|
446
|
-
* so these values cover both passes.
|
|
447
|
-
*/
|
|
448
|
-
recordWebGLStats(stats: {
|
|
449
|
-
drawCalls: number;
|
|
450
|
-
triangles: number;
|
|
451
|
-
selectionFrames: number;
|
|
452
|
-
snapGuides: number;
|
|
453
|
-
spacingIndicators: number;
|
|
454
|
-
domPositionsUpdated: number;
|
|
455
|
-
}): void;
|
|
456
|
-
/** Call at the end of engine.tick() — flushes a TickSample to the ring. */
|
|
457
|
-
endFrame(entityCount: number, visibleCount: number): void;
|
|
458
|
-
/**
|
|
459
|
-
* Push one R3F frame sample. Called from the R3F canvas via a probe
|
|
460
|
-
* component that has access to `useThree`.
|
|
461
|
-
*/
|
|
462
|
-
recordR3FFrame(sample: Omit<R3FSample, 'timestamp'>): void;
|
|
463
|
-
/** Get the last N tick samples (newest first). */
|
|
464
|
-
getSamples(count?: number): TickSample[];
|
|
465
|
-
/** Get the last N R3F samples (newest first). */
|
|
466
|
-
getR3FSamples(count?: number): R3FSample[];
|
|
467
|
-
/** Compute rolling statistics across all three layers. */
|
|
468
|
-
getStats(): ProfilerStats;
|
|
469
|
-
private getEcsStats;
|
|
470
|
-
private getWebGLStats;
|
|
471
|
-
private getR3FStats;
|
|
472
|
-
/** Clear all collected data. */
|
|
473
|
-
clear(): void;
|
|
474
|
-
}
|
|
475
|
-
//#endregion
|
|
476
|
-
//#region src/schema.d.ts
|
|
477
|
-
/**
|
|
478
|
-
* Minimal Standard Schema v1 type definition.
|
|
479
|
-
*
|
|
480
|
-
* Compatible with Zod 3.24+, Valibot, ArkType, and any other library that
|
|
481
|
-
* implements the spec at https://standardschema.dev. We do not depend on any
|
|
482
|
-
* validator — users bring their own.
|
|
483
|
-
*
|
|
484
|
-
* Today we only carry the type parameter for `T`. Runtime validation via
|
|
485
|
-
* `validate()` is wired in by features that need it (inspector, serialization).
|
|
486
|
-
*/
|
|
487
|
-
interface StandardSchemaV1<Input = unknown, Output = Input> {
|
|
488
|
-
readonly '~standard': StandardSchemaV1.Props<Input, Output>;
|
|
489
|
-
}
|
|
490
|
-
declare namespace StandardSchemaV1 {
|
|
491
|
-
interface Props<Input = unknown, Output = Input> {
|
|
492
|
-
readonly version: 1;
|
|
493
|
-
readonly vendor: string;
|
|
494
|
-
readonly validate: (value: unknown) => Result<Output> | Promise<Result<Output>>;
|
|
495
|
-
readonly types?: Types<Input, Output>;
|
|
496
|
-
}
|
|
497
|
-
type Result<Output> = SuccessResult<Output> | FailureResult;
|
|
498
|
-
interface SuccessResult<Output> {
|
|
499
|
-
readonly value: Output;
|
|
500
|
-
readonly issues?: undefined;
|
|
501
|
-
}
|
|
502
|
-
interface FailureResult {
|
|
503
|
-
readonly issues: ReadonlyArray<Issue>;
|
|
504
|
-
}
|
|
505
|
-
interface Issue {
|
|
506
|
-
readonly message: string;
|
|
507
|
-
readonly path?: ReadonlyArray<PropertyKey | PathSegment> | undefined;
|
|
508
|
-
}
|
|
509
|
-
interface PathSegment {
|
|
510
|
-
readonly key: PropertyKey;
|
|
511
|
-
}
|
|
512
|
-
interface Types<Input = unknown, Output = Input> {
|
|
513
|
-
readonly input: Input;
|
|
514
|
-
readonly output: Output;
|
|
515
|
-
}
|
|
516
|
-
type InferOutput<Schema extends StandardSchemaV1> = NonNullable<Schema['~standard']['types']>['output'];
|
|
517
|
-
}
|
|
518
|
-
//#endregion
|
|
519
|
-
//#region src/react/registry.d.ts
|
|
520
|
-
/** Rendering surface for a widget. */
|
|
521
|
-
type WidgetSurface = 'dom' | 'webgl';
|
|
522
|
-
/** Props passed to every DOM widget component. */
|
|
523
|
-
interface DomWidgetProps {
|
|
524
|
-
entityId: EntityId;
|
|
525
|
-
}
|
|
526
|
-
/** Props passed to every R3F widget component. Rendered in local coords. */
|
|
527
|
-
interface R3FWidgetProps {
|
|
528
|
-
entityId: EntityId;
|
|
529
|
-
/** Widget width in world units. */
|
|
530
|
-
width: number;
|
|
531
|
-
/** Widget height in world units. */
|
|
532
|
-
height: number;
|
|
533
|
-
}
|
|
534
|
-
interface WidgetBase<T> {
|
|
535
|
-
/** Unique widget type id. Matches `Widget { type }` on spawned entities. */
|
|
536
|
-
type: string;
|
|
537
|
-
/**
|
|
538
|
-
* Standard Schema v1-compatible schema for the widget's data.
|
|
539
|
-
* Use Zod 3.24+, Valibot, ArkType, or any other conforming validator.
|
|
540
|
-
* The schema's output type drives the widget's data type.
|
|
541
|
-
*/
|
|
542
|
-
schema: StandardSchemaV1<any, T>;
|
|
543
|
-
/** Default data shape for new instances. Merged with user-supplied data at spawn. */
|
|
544
|
-
defaultData: T;
|
|
545
|
-
/** Default world-space size at spawn. */
|
|
546
|
-
defaultSize: {
|
|
547
|
-
width: number;
|
|
548
|
-
height: number;
|
|
549
|
-
};
|
|
550
|
-
/** Minimum world-space size when resizing. */
|
|
551
|
-
minSize?: {
|
|
552
|
-
width: number;
|
|
553
|
-
height: number;
|
|
554
|
-
};
|
|
555
|
-
}
|
|
556
|
-
/** A DOM-rendered widget. The component is wrapped in a sized div — size via CSS. */
|
|
557
|
-
interface DomWidget<T = Record<string, unknown>> extends WidgetBase<T> {
|
|
558
|
-
surface?: 'dom';
|
|
559
|
-
component: React.ComponentType<DomWidgetProps>;
|
|
560
|
-
}
|
|
561
|
-
/** An R3F (React Three Fiber) widget. The component receives local-space width/height. */
|
|
562
|
-
interface R3FWidget<T = Record<string, unknown>> extends WidgetBase<T> {
|
|
563
|
-
surface: 'webgl';
|
|
564
|
-
component: React.ComponentType<R3FWidgetProps>;
|
|
565
|
-
}
|
|
566
|
-
/** Either kind of widget. */
|
|
567
|
-
type Widget<T = Record<string, unknown>> = DomWidget<T> | R3FWidget<T>;
|
|
568
|
-
interface WidgetRegistry {
|
|
569
|
-
register(def: Widget): void;
|
|
570
|
-
get(type: string): Widget | null;
|
|
571
|
-
getAll(): Widget[];
|
|
572
|
-
}
|
|
573
|
-
declare function createWidgetRegistry(defs?: Widget[]): WidgetRegistry;
|
|
574
|
-
/** Narrows to the R3F variant. */
|
|
575
|
-
declare function isR3FWidget<T>(widget: Widget<T>): widget is R3FWidget<T>;
|
|
576
|
-
//#endregion
|
|
577
|
-
//#region src/resources.d.ts
|
|
578
|
-
/** A single frame in the navigation stack, capturing the container and camera state. */
|
|
579
|
-
interface NavigationFrame {
|
|
580
|
-
containerId: EntityId | null;
|
|
581
|
-
camera: {
|
|
582
|
-
x: number;
|
|
583
|
-
y: number;
|
|
584
|
-
zoom: number;
|
|
585
|
-
};
|
|
586
|
-
}
|
|
587
|
-
/** Data shape for the CursorResource. */
|
|
588
|
-
type CursorResourceData = {
|
|
589
|
-
cursor: CSSCursor;
|
|
590
|
-
};
|
|
591
|
-
/**
|
|
592
|
-
* Output sink for the cursor system. Written by cursorSystem each tick;
|
|
593
|
-
* read by the RAF loop to apply style.cursor on the root container div.
|
|
594
|
-
*/
|
|
595
|
-
declare const CursorResource: _$_jamesyong42_reactive_ecs0.ResourceType<CursorResourceData>;
|
|
596
|
-
/** Camera state: world-space position (x, y) and zoom level. Updated by pan/zoom gestures. */
|
|
597
|
-
declare const CameraResource: _$_jamesyong42_reactive_ecs0.ResourceType<{
|
|
598
|
-
x: number;
|
|
599
|
-
y: number;
|
|
600
|
-
zoom: number;
|
|
601
|
-
}>;
|
|
602
|
-
/** Viewport dimensions in CSS pixels and device pixel ratio. Updated on resize. */
|
|
603
|
-
declare const ViewportResource: _$_jamesyong42_reactive_ecs0.ResourceType<{
|
|
604
|
-
width: number;
|
|
605
|
-
height: number;
|
|
606
|
-
dpr: number;
|
|
607
|
-
}>;
|
|
608
|
-
/** Minimum and maximum zoom levels. */
|
|
609
|
-
declare const ZoomConfigResource: _$_jamesyong42_reactive_ecs0.ResourceType<{
|
|
610
|
-
min: number;
|
|
611
|
-
max: number;
|
|
612
|
-
}>;
|
|
613
|
-
/** Screen-space pixel thresholds for responsive breakpoints (micro/compact/normal/expanded/detailed). */
|
|
614
|
-
declare const BreakpointConfigResource: _$_jamesyong42_reactive_ecs0.ResourceType<{
|
|
615
|
-
micro: number;
|
|
616
|
-
compact: number;
|
|
617
|
-
normal: number;
|
|
618
|
-
expanded: number;
|
|
619
|
-
}>;
|
|
620
|
-
/** Navigation stack for hierarchical container traversal. */
|
|
621
|
-
declare const NavigationStackResource: _$_jamesyong42_reactive_ecs0.ResourceType<{
|
|
622
|
-
frames: NavigationFrame[];
|
|
623
|
-
changed: boolean;
|
|
624
|
-
}>;
|
|
625
|
-
/** Responsive breakpoint name derived from a widget's screen-space size. */
|
|
626
|
-
type Breakpoint = 'micro' | 'compact' | 'normal' | 'expanded' | 'detailed';
|
|
627
|
-
/**
|
|
628
|
-
* iOS-style card preset size map. Lookup happens by `Card.preset`; the
|
|
629
|
-
* `cardSystem` stamps `Transform2D.width/height` from the resolved size.
|
|
630
|
-
*
|
|
631
|
-
* Defaults mirror iOS widget conventions — 155×155 tile + 19px gap.
|
|
632
|
-
* Override at `createLayoutEngine({ cardPresets })` for tablet-scale or
|
|
633
|
-
* custom design systems.
|
|
634
|
-
*/
|
|
635
|
-
declare const CardPresetsResource: _$_jamesyong42_reactive_ecs0.ResourceType<{
|
|
636
|
-
presets: Record<CardPreset, {
|
|
637
|
-
width: number;
|
|
638
|
-
height: number;
|
|
639
|
-
}>; /** Gap between adjacent tiles (future tile-snap system reads this). */
|
|
640
|
-
gap: number;
|
|
641
|
-
}>;
|
|
642
|
-
//#endregion
|
|
643
|
-
//#region src/snap.d.ts
|
|
644
|
-
/**
|
|
645
|
-
* Snap guide computation for alignment during drag operations.
|
|
646
|
-
* Implements Figma-style snapping:
|
|
647
|
-
* 1. Edge/center alignment guides
|
|
648
|
-
* 2. Equal spacing snap + indicators
|
|
649
|
-
*/
|
|
650
|
-
interface SnapGuide {
|
|
651
|
-
/** Axis this guide aligns on */
|
|
652
|
-
axis: 'x' | 'y';
|
|
653
|
-
/** World-space coordinate of the alignment line */
|
|
654
|
-
position: number;
|
|
655
|
-
/** What kind of alignment */
|
|
656
|
-
type: 'edge' | 'center';
|
|
657
|
-
}
|
|
658
|
-
interface EqualSpacingIndicator {
|
|
659
|
-
/** Axis along which the equal gaps run */
|
|
660
|
-
axis: 'x' | 'y';
|
|
661
|
-
/** The equal gap value (world units) */
|
|
662
|
-
gap: number;
|
|
663
|
-
/** Pairs of (from, to) marking each equal gap segment */
|
|
664
|
-
segments: {
|
|
665
|
-
from: number;
|
|
666
|
-
to: number;
|
|
667
|
-
}[];
|
|
668
|
-
/** Position on the perpendicular axis (for rendering) */
|
|
669
|
-
perpPosition: number;
|
|
670
|
-
}
|
|
671
|
-
interface SnapResult {
|
|
672
|
-
/** Snap-corrected delta (world units). Apply to entity position. */
|
|
673
|
-
snapDx: number;
|
|
674
|
-
snapDy: number;
|
|
675
|
-
/** Active alignment guide lines to render */
|
|
676
|
-
guides: SnapGuide[];
|
|
677
|
-
/** Equal spacing indicators */
|
|
678
|
-
spacings: EqualSpacingIndicator[];
|
|
679
|
-
}
|
|
680
|
-
interface EntityBounds {
|
|
681
|
-
x: number;
|
|
682
|
-
y: number;
|
|
683
|
-
width: number;
|
|
684
|
-
height: number;
|
|
685
|
-
}
|
|
686
|
-
/**
|
|
687
|
-
* Compute snap guides for a dragged entity against reference entities.
|
|
688
|
-
*/
|
|
689
|
-
declare function computeSnapGuides(dragged: EntityBounds, references: EntityBounds[], threshold: number): SnapResult;
|
|
690
|
-
//#endregion
|
|
691
|
-
//#region src/math.d.ts
|
|
692
|
-
interface Vec2 {
|
|
693
|
-
x: number;
|
|
694
|
-
y: number;
|
|
695
|
-
}
|
|
696
|
-
interface Rect {
|
|
697
|
-
x: number;
|
|
698
|
-
y: number;
|
|
699
|
-
width: number;
|
|
700
|
-
height: number;
|
|
701
|
-
}
|
|
702
|
-
interface AABB {
|
|
703
|
-
minX: number;
|
|
704
|
-
minY: number;
|
|
705
|
-
maxX: number;
|
|
706
|
-
maxY: number;
|
|
707
|
-
}
|
|
708
|
-
/** Convert WorldBounds-shaped data to AABB */
|
|
709
|
-
declare function worldBoundsToAABB(wb: {
|
|
710
|
-
worldX: number;
|
|
711
|
-
worldY: number;
|
|
712
|
-
worldWidth: number;
|
|
713
|
-
worldHeight: number;
|
|
714
|
-
}): AABB;
|
|
715
|
-
/** Test if two AABBs overlap */
|
|
716
|
-
declare function intersectsAABB(a: AABB, b: AABB): boolean;
|
|
717
|
-
/** Test if a point is inside an AABB */
|
|
718
|
-
declare function pointInAABB(px: number, py: number, a: AABB): boolean;
|
|
719
|
-
/** Convert screen coordinates to world coordinates */
|
|
720
|
-
declare function screenToWorld(screenX: number, screenY: number, camera: {
|
|
721
|
-
x: number;
|
|
722
|
-
y: number;
|
|
723
|
-
zoom: number;
|
|
724
|
-
}): Vec2;
|
|
725
|
-
/** Convert world coordinates to screen coordinates */
|
|
726
|
-
declare function worldToScreen(worldX: number, worldY: number, camera: {
|
|
727
|
-
x: number;
|
|
728
|
-
y: number;
|
|
729
|
-
zoom: number;
|
|
730
|
-
}): Vec2;
|
|
731
|
-
/** Clamp a value between min and max */
|
|
732
|
-
declare function clamp(value: number, min: number, max: number): number;
|
|
733
|
-
//#endregion
|
|
734
|
-
//#region src/spatial.d.ts
|
|
735
|
-
interface SpatialEntry extends AABB {
|
|
736
|
-
entityId: EntityId;
|
|
737
|
-
}
|
|
738
|
-
/**
|
|
739
|
-
* Spatial index backed by an R-tree (rbush).
|
|
740
|
-
* Stores world-space AABBs for fast viewport culling and hit testing.
|
|
741
|
-
*/
|
|
742
|
-
declare class SpatialIndex {
|
|
743
|
-
private tree;
|
|
744
|
-
private entries;
|
|
745
|
-
upsert(entityId: EntityId, bounds: AABB): void;
|
|
746
|
-
remove(entityId: EntityId): void;
|
|
747
|
-
/** Query all entries intersecting the given AABB */
|
|
748
|
-
search(bounds: AABB): SpatialEntry[];
|
|
749
|
-
/** Find the topmost entity at a point (by z-order — caller sorts) */
|
|
750
|
-
searchPoint(x: number, y: number, tolerance?: number): SpatialEntry[];
|
|
751
|
-
clear(): void;
|
|
752
|
-
get size(): number;
|
|
753
|
-
}
|
|
754
|
-
//#endregion
|
|
755
|
-
//#region src/engine.d.ts
|
|
756
|
-
/** ECS resource holding the SpatialIndex instance for viewport culling and hit testing. */
|
|
757
|
-
declare const SpatialIndexResource: _$_jamesyong42_reactive_ecs0.ResourceType<{
|
|
758
|
-
instance: SpatialIndex | null;
|
|
759
|
-
}>;
|
|
760
|
-
/** Directive returned by pointer handlers indicating how the canvas should handle capture. */
|
|
761
|
-
type PointerDirective = {
|
|
762
|
-
action: 'passthrough';
|
|
763
|
-
} | {
|
|
764
|
-
action: 'passthrough-track-drag';
|
|
765
|
-
} | {
|
|
766
|
-
action: 'capture-drag';
|
|
767
|
-
} | {
|
|
768
|
-
action: 'capture-resize';
|
|
769
|
-
handle: ResizeHandlePos;
|
|
770
|
-
} | {
|
|
771
|
-
action: 'capture-marquee';
|
|
772
|
-
};
|
|
773
|
-
/** Keyboard modifier state captured alongside pointer events. */
|
|
774
|
-
interface Modifiers {
|
|
775
|
-
shift: boolean;
|
|
776
|
-
ctrl: boolean;
|
|
777
|
-
alt: boolean;
|
|
778
|
-
meta: boolean;
|
|
779
|
-
}
|
|
780
|
-
/** A visible entity with its computed world-space bounds and display metadata. */
|
|
781
|
-
interface VisibleEntity {
|
|
782
|
-
entityId: EntityId;
|
|
783
|
-
worldX: number;
|
|
784
|
-
worldY: number;
|
|
785
|
-
worldWidth: number;
|
|
786
|
-
worldHeight: number;
|
|
787
|
-
breakpoint: Breakpoint;
|
|
788
|
-
zIndex: number;
|
|
789
|
-
surface: string;
|
|
790
|
-
widgetType: string;
|
|
791
|
-
}
|
|
792
|
-
/** Per-frame change flags indicating what changed during the last tick. */
|
|
793
|
-
interface FrameChanges {
|
|
794
|
-
/** Entities whose world-space position or size changed. */
|
|
795
|
-
positionsChanged: EntityId[];
|
|
796
|
-
/** Entities whose responsive breakpoint changed. */
|
|
797
|
-
breakpointsChanged: EntityId[];
|
|
798
|
-
/** Entities that entered the visible viewport. */
|
|
799
|
-
entered: EntityId[];
|
|
800
|
-
/** Entities that exited the visible viewport. */
|
|
801
|
-
exited: EntityId[];
|
|
802
|
-
/** Whether the camera position or zoom changed. */
|
|
803
|
-
cameraChanged: boolean;
|
|
804
|
-
/** Whether the navigation stack changed (entered/exited container). */
|
|
805
|
-
navigationChanged: boolean;
|
|
806
|
-
/** Whether the selection set changed. */
|
|
807
|
-
selectionChanged: boolean;
|
|
808
|
-
}
|
|
809
|
-
/** Configuration options for `createLayoutEngine()`. */
|
|
810
|
-
interface LayoutEngineConfig {
|
|
811
|
-
/** Maximum entity count (default: 10000). */
|
|
812
|
-
maxEntities?: number;
|
|
813
|
-
/** Minimum and maximum zoom levels. */
|
|
814
|
-
zoom?: {
|
|
815
|
-
min: number;
|
|
816
|
-
max: number;
|
|
817
|
-
};
|
|
818
|
-
/** Screen-space pixel thresholds for responsive breakpoints. */
|
|
819
|
-
breakpoints?: {
|
|
820
|
-
micro: number;
|
|
821
|
-
compact: number;
|
|
822
|
-
normal: number;
|
|
823
|
-
expanded: number;
|
|
824
|
-
};
|
|
825
|
-
/** Snap alignment configuration. */
|
|
826
|
-
snap?: {
|
|
827
|
-
/** Whether snapping is enabled initially. */enabled?: boolean; /** Snap distance threshold in screen pixels. */
|
|
828
|
-
threshold?: number;
|
|
829
|
-
};
|
|
830
|
-
/** Widget definitions available to `spawn()`. */
|
|
831
|
-
widgets?: Widget[];
|
|
832
|
-
/** Archetype definitions available to `spawn()`. */
|
|
833
|
-
archetypes?: Archetype[];
|
|
834
|
-
/**
|
|
835
|
-
* Override the default iOS-style card preset sizes (small/medium/large/xl).
|
|
836
|
-
* Partial — unspecified presets keep their built-in defaults.
|
|
837
|
-
*/
|
|
838
|
-
cardPresets?: {
|
|
839
|
-
presets?: Partial<Record<CardPreset, {
|
|
840
|
-
width: number;
|
|
841
|
-
height: number;
|
|
842
|
-
}>>;
|
|
843
|
-
gap?: number;
|
|
844
|
-
};
|
|
845
|
-
}
|
|
846
|
-
/**
|
|
847
|
-
* The core layout engine. Manages the ECS world, camera, input, undo/redo,
|
|
848
|
-
* spatial indexing, and frame lifecycle for an infinite canvas.
|
|
849
|
-
*/
|
|
850
|
-
interface LayoutEngine {
|
|
851
|
-
/** The underlying ECS world. Use for direct component/tag/resource access. */
|
|
852
|
-
readonly world: World;
|
|
853
|
-
/** Creates a bare entity with optional initial components/tags. Low-level escape hatch. */
|
|
854
|
-
createEntity(inits?: ComponentInit[]): EntityId;
|
|
855
|
-
/**
|
|
856
|
-
* Spawns a new entity from a registered archetype or widget type.
|
|
857
|
-
* If `id` matches a registered archetype, that archetype is used.
|
|
858
|
-
* Otherwise, if `id` matches a registered widget, a default archetype is synthesized.
|
|
859
|
-
* Otherwise, a bare default archetype with type=`id` is used (useful in tests).
|
|
860
|
-
*/
|
|
861
|
-
spawn(id: string, opts?: SpawnOptions): EntityId;
|
|
862
|
-
/** Spawns at the current camera viewport centre (sized from the archetype/widget default). */
|
|
863
|
-
spawnAtCameraCenter(id: string, opts?: Omit<SpawnOptions, 'at'>): EntityId;
|
|
864
|
-
/** Removes an entity and cleans up all components, tags, and spatial index entries. */
|
|
865
|
-
destroyEntity(id: EntityId): void;
|
|
866
|
-
/** Registers a widget definition. Auto-creates a matching default archetype if none exists. */
|
|
867
|
-
registerWidget(widget: Widget): void;
|
|
868
|
-
/** Returns a registered widget by type, or null. */
|
|
869
|
-
getWidget(type: string): Widget | null;
|
|
870
|
-
/** Returns all registered widgets. */
|
|
871
|
-
getWidgets(): Widget[];
|
|
872
|
-
/** Registers a custom archetype. */
|
|
873
|
-
registerArchetype(archetype: Archetype): void;
|
|
874
|
-
/** Returns a registered archetype by id, or null. */
|
|
875
|
-
getArchetype(id: string): Archetype | null;
|
|
876
|
-
/** Reads a component from an entity. Returns undefined if not present. */
|
|
877
|
-
get<T>(entity: EntityId, type: ComponentType<T>): T | undefined;
|
|
878
|
-
/** Updates a component on an entity (partial merge). */
|
|
879
|
-
set<T>(entity: EntityId, type: ComponentType<T>, data: Partial<T>): void;
|
|
880
|
-
/** Checks if an entity has a component or tag. */
|
|
881
|
-
has(entity: EntityId, type: ComponentType | TagType): boolean;
|
|
882
|
-
/** Attaches a component to an entity. Uses type defaults if `data` is omitted. Marks dirty. */
|
|
883
|
-
addComponent<T>(entity: EntityId, type: ComponentType<T>, data?: T): void;
|
|
884
|
-
/** Removes a component from an entity. Marks dirty. */
|
|
885
|
-
removeComponent(entity: EntityId, type: ComponentType): void;
|
|
886
|
-
/** Adds a tag to an entity. Marks dirty. */
|
|
887
|
-
addTag(entity: EntityId, type: TagType): void;
|
|
888
|
-
/** Removes a tag from an entity. Marks dirty. */
|
|
889
|
-
removeTag(entity: EntityId, type: TagType): void;
|
|
890
|
-
/** Returns the Standard Schema for a widget entity's `WidgetData.data`, if the widget declared one. */
|
|
891
|
-
getSchemaFor(entity: EntityId): StandardSchemaV1 | undefined;
|
|
892
|
-
/** Registers a custom ECS system to run each tick. */
|
|
893
|
-
registerSystem(system: SystemDef): void;
|
|
894
|
-
/** Removes a registered system by name. */
|
|
895
|
-
removeSystem(name: string): void;
|
|
896
|
-
/** Returns the current camera state {x, y, zoom}. */
|
|
897
|
-
getCamera(): {
|
|
898
|
-
x: number;
|
|
899
|
-
y: number;
|
|
900
|
-
zoom: number;
|
|
901
|
-
};
|
|
902
|
-
/** Moves the camera by the specified screen-space delta. */
|
|
903
|
-
panBy(dx: number, dy: number): void;
|
|
904
|
-
/** Moves the camera to the specified world coordinates. */
|
|
905
|
-
panTo(worldX: number, worldY: number): void;
|
|
906
|
-
/** Adjusts zoom level anchored at a screen point. Delta is a multiplier offset. */
|
|
907
|
-
zoomAtPoint(screenX: number, screenY: number, delta: number): void;
|
|
908
|
-
/** Sets the zoom level directly. */
|
|
909
|
-
zoomTo(zoom: number): void;
|
|
910
|
-
/** Adjusts camera to fit all entities (or specified entities) in the viewport. */
|
|
911
|
-
zoomToFit(entityIds?: EntityId[], padding?: number): void;
|
|
912
|
-
/** Updates the viewport dimensions. Called automatically by InfiniteCanvas on resize. */
|
|
913
|
-
setViewport(width: number, height: number, dpr?: number): void;
|
|
914
|
-
/** Pointer-down handler. Returns a directive for how the canvas should capture the pointer. */
|
|
915
|
-
handlePointerDown(screenX: number, screenY: number, button: number, modifiers: Modifiers): PointerDirective;
|
|
916
|
-
/** Pointer-move handler. Returns a directive reflecting the current interaction. */
|
|
917
|
-
handlePointerMove(screenX: number, screenY: number, modifiers: Modifiers): PointerDirective;
|
|
918
|
-
/** Pointer-up handler. Commits drags/resizes and returns a directive. */
|
|
919
|
-
handlePointerUp(): PointerDirective;
|
|
920
|
-
/** Cancels the current pointer interaction without committing changes. */
|
|
921
|
-
handlePointerCancel(): void;
|
|
922
|
-
/** Returns IDs of all currently selected entities. */
|
|
923
|
-
getSelectedEntities(): EntityId[];
|
|
924
|
-
/** Returns the entity currently under the pointer, or null. */
|
|
925
|
-
getHoveredEntity(): EntityId | null;
|
|
926
|
-
/** Navigates into a container entity, pushing the current camera onto the navigation stack. */
|
|
927
|
-
enterContainer(entity: EntityId): void;
|
|
928
|
-
/** Navigates out of the current container, restoring the previous camera state. */
|
|
929
|
-
exitContainer(): void;
|
|
930
|
-
/** Returns the entity ID of the currently active container, or null if at root. */
|
|
931
|
-
getActiveContainer(): EntityId | null;
|
|
932
|
-
/** Returns the current navigation depth (0 = root). */
|
|
933
|
-
getNavigationDepth(): number;
|
|
934
|
-
/** Executes a command and pushes it onto the undo stack. */
|
|
935
|
-
execute(command: Command): void;
|
|
936
|
-
/** Begins a command group -- subsequent commands are bundled into one undo step. */
|
|
937
|
-
beginCommandGroup(): void;
|
|
938
|
-
/** Ends the current command group. */
|
|
939
|
-
endCommandGroup(): void;
|
|
940
|
-
/** Undoes the last command or command group. Returns true if anything was undone. */
|
|
941
|
-
undo(): boolean;
|
|
942
|
-
/** Redoes the last undone command. Returns true if anything was redone. */
|
|
943
|
-
redo(): boolean;
|
|
944
|
-
/** Returns whether there is a command to undo. */
|
|
945
|
-
canUndo(): boolean;
|
|
946
|
-
/** Returns whether there is a command to redo. */
|
|
947
|
-
canRedo(): boolean;
|
|
948
|
-
/** Schedules a tick on the next animation frame. Call after programmatic changes. */
|
|
949
|
-
markDirty(): void;
|
|
950
|
-
/** Runs one frame: executes all ECS systems, updates spatial index, emits frame events. */
|
|
951
|
-
tick(): void;
|
|
952
|
-
/** Ticks only if dirty. Returns true if a tick was performed. */
|
|
953
|
-
flushIfDirty(): boolean;
|
|
954
|
-
/** Returns visible entities with their world-space bounds, breakpoint, and surface info. */
|
|
955
|
-
getVisibleEntities(): VisibleEntity[];
|
|
956
|
-
/** Returns per-frame change flags from the last tick. */
|
|
957
|
-
getFrameChanges(): FrameChanges;
|
|
958
|
-
/** Returns the spatial index used for viewport culling and hit testing. */
|
|
959
|
-
getSpatialIndex(): SpatialIndex;
|
|
960
|
-
/** Returns active snap guide lines from the last tick. */
|
|
961
|
-
getSnapGuides(): SnapGuide[];
|
|
962
|
-
/** Returns equal-spacing indicators from the last tick. */
|
|
963
|
-
getEqualSpacing(): EqualSpacingIndicator[];
|
|
964
|
-
/** Enables or disables snap alignment. */
|
|
965
|
-
setSnapEnabled(on: boolean): void;
|
|
966
|
-
/** Sets the snap distance threshold in world pixels. */
|
|
967
|
-
setSnapThreshold(worldPx: number): void;
|
|
968
|
-
/** Performance profiler for measuring system execution times. */
|
|
969
|
-
readonly profiler: Profiler;
|
|
970
|
-
/** Registers a callback invoked after each tick. Returns an unsubscribe function. */
|
|
971
|
-
onFrame(handler: () => void): Unsubscribe;
|
|
972
|
-
/** Destroys the engine, releasing all resources and subscriptions. */
|
|
973
|
-
destroy(): void;
|
|
974
|
-
}
|
|
975
|
-
/**
|
|
976
|
-
* Creates a new LayoutEngine instance with the given configuration.
|
|
977
|
-
* This is the main entry point for the infinite canvas library.
|
|
978
|
-
*/
|
|
979
|
-
declare function createLayoutEngine(config?: LayoutEngineConfig): LayoutEngine;
|
|
980
|
-
//#endregion
|
|
981
|
-
export { Active as $, NavigationFrame as A, CommandBuffer as At, WidgetSurface as B, computeSnapGuides as C, Visible as Ct, CardPresetsResource as D, WorldBounds as Dt, CameraResource as E, WidgetData as Et, DomWidgetProps as F, ArchetypeRegistry as Ft, FrameTimeStats as G, isR3FWidget as H, R3FWidget as I, SpawnOptions as It, R3FSample as J, Profiler as K, R3FWidgetProps as L, createArchetypeRegistry as Lt, ViewportResource as M, ResizeCommand as Mt, ZoomConfigResource as N, SetComponentCommand as Nt, CursorResource as O, ZIndex as Ot, DomWidget as P, Archetype as Pt, WebGLStats as Q, Widget as R, SnapResult as S, Transform2D as St, BreakpointConfigResource as T, WidgetBreakpoint as Tt, StandardSchemaV1 as U, createWidgetRegistry as V, EcsStats as W, TickSample as X, R3FStats as Y, WebGLPass as Z, worldBoundsToAABB as _, Resizable as _t, PointerDirective as a, CursorHint as at, EqualSpacingIndicator as b, Selected as bt, createLayoutEngine as c, Dragging as ct, Rect as d, Hitbox as dt, CSSCursor as et, Vec2 as f, InteractionRole as ft, screenToWorld as g, Parent as gt, pointInAABB as h, Locked as ht, Modifiers as i, Container as it, NavigationStackResource as j, MoveCommand as jt, CursorResourceData as k, Command as kt, SpatialIndex as l, HandleSet as lt, intersectsAABB as m, InteractionRoleType as mt, LayoutEngine as n, CardPreset as nt, SpatialIndexResource as o, CursorHintData as ot, clamp as p, InteractionRoleData as pt, ProfilerStats as q, LayoutEngineConfig as r, Children as rt, VisibleEntity as s, Draggable as st, FrameChanges as t, Card as tt, AABB as u, HandleSetData as ut, worldToScreen as v, ResizeHandlePos as vt, Breakpoint as w, Widget$1 as wt, SnapGuide as x, SelectionFrame as xt, EntityBounds as y, Selectable as yt, WidgetRegistry as z };
|
|
982
|
-
//# sourceMappingURL=engine-CCjuFMC-.d.cts.map
|