@pixerate/editor 0.16.2 → 0.18.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/agent/index.cjs +32 -29
- package/dist/agent/index.cjs.map +1 -1
- package/dist/agent/index.d.cts +9 -3
- package/dist/agent/index.d.ts +9 -3
- package/dist/agent/index.js +31 -28
- package/dist/agent/index.js.map +1 -1
- package/dist/canvas/index.cjs +133 -65
- package/dist/canvas/index.cjs.map +1 -1
- package/dist/canvas/index.d.cts +64 -11
- package/dist/canvas/index.d.ts +64 -11
- package/dist/canvas/index.js +128 -60
- package/dist/canvas/index.js.map +1 -1
- package/dist/{chunk-33UVEDOS.cjs → chunk-2TWGLC5K.cjs} +58 -29
- package/dist/chunk-2TWGLC5K.cjs.map +1 -0
- package/dist/{chunk-3A7KVDEA.js → chunk-AIZUKWTL.js} +527 -114
- package/dist/chunk-AIZUKWTL.js.map +1 -0
- package/dist/{chunk-GWHJVZPI.js → chunk-KAADNAPF.js} +58 -29
- package/dist/chunk-KAADNAPF.js.map +1 -0
- package/dist/{chunk-TYG7K6WK.cjs → chunk-YQCI4CCN.cjs} +562 -149
- package/dist/chunk-YQCI4CCN.cjs.map +1 -0
- package/dist/history/index.cjs +2 -2
- package/dist/history/index.d.cts +5 -0
- package/dist/history/index.d.ts +5 -0
- package/dist/history/index.js +1 -1
- package/dist/index.cjs +13 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +12 -2
- package/dist/index.js.map +1 -1
- package/dist/spreadsheet/index.cjs +12 -2
- package/dist/spreadsheet/index.cjs.map +1 -1
- package/dist/spreadsheet/index.d.cts +71 -2
- package/dist/spreadsheet/index.d.ts +71 -2
- package/dist/spreadsheet/index.js +11 -1
- package/dist/{types-DC8b2TsA.d.cts → types-JV3S8VeR.d.cts} +6 -2
- package/dist/{types-DC8b2TsA.d.ts → types-JV3S8VeR.d.ts} +6 -2
- package/package.json +1 -1
- package/dist/chunk-33UVEDOS.cjs.map +0 -1
- package/dist/chunk-3A7KVDEA.js.map +0 -1
- package/dist/chunk-GWHJVZPI.js.map +0 -1
- package/dist/chunk-TYG7K6WK.cjs.map +0 -1
package/dist/canvas/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { R as Rect, C as CanvasNode, X as XYPosition, a as CanvasEdge, I as IncrementalLayoutOptions, S as Side, b as CanvasLayoutOptions, P as PlaceBesideOptions, T as TrajectoryFunction, F as FanOutTrajectoryOptions, N as NodeTransition, c as ReflowDisplacementOptions, D as DirectionalDisplacementOptions,
|
|
2
|
-
export {
|
|
1
|
+
import { R as Rect, C as CanvasNode, X as XYPosition, a as CanvasEdge, I as IncrementalLayoutOptions, S as Side, b as CanvasLayoutOptions, P as PlaceBesideOptions, T as TrajectoryFunction, F as FanOutTrajectoryOptions, N as NodeTransition, c as CanvasNodeStyle, d as ReflowDisplacementOptions, D as DirectionalDisplacementOptions, e as CanvasClipboardPayload } from '../types-JV3S8VeR.cjs';
|
|
2
|
+
export { f as CanvasDockingCallbacks, g as CollapseNodeOptions, h as DisplacementDirection, i as DockStrategy, E as ExplodeNodeOptions, j as ExplosionSnapshot, G as GraphDifferences, k as Point, l as Position, m as TrajectoryPoint } from '../types-JV3S8VeR.cjs';
|
|
3
3
|
|
|
4
4
|
declare const DEFAULT_NODE_WIDTH = 200;
|
|
5
5
|
declare const DEFAULT_NODE_HEIGHT = 60;
|
|
@@ -131,15 +131,40 @@ declare function createFanOutTrajectory(options?: FanOutTrajectoryOptions): Traj
|
|
|
131
131
|
declare function createBezierTrajectory(getControlPoint: (origin: XYPosition, target: XYPosition) => XYPosition): TrajectoryFunction;
|
|
132
132
|
|
|
133
133
|
/**
|
|
134
|
-
*
|
|
134
|
+
* Returns a copy of `style` with its opacity set to `opacity`.
|
|
135
|
+
*
|
|
136
|
+
* Supports both CSS strings (`"color: red; opacity: 0.5;"`, used by SvelteFlow)
|
|
137
|
+
* and style objects (`{ color: 'red', opacity: 0.5 }`, used by React Flow / xyflow).
|
|
138
|
+
* When `style` is empty, `emptyFormat` decides which representation is produced.
|
|
139
|
+
* Never mutates the input.
|
|
135
140
|
*/
|
|
136
|
-
declare function
|
|
141
|
+
declare function withStyleOpacity(style: CanvasNodeStyle | undefined | null, opacity: number, emptyFormat?: 'string' | 'object'): CanvasNodeStyle;
|
|
142
|
+
interface MultiNodeTransitionOptions<TNode extends CanvasNode = CanvasNode> {
|
|
137
143
|
defaultDuration?: number;
|
|
138
144
|
defaultEasing?: (t: number) => number;
|
|
139
145
|
clock?: Clock;
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
146
|
+
/**
|
|
147
|
+
* Style representation to create for nodes that have no `style` yet when an opacity
|
|
148
|
+
* is applied. Defaults to `'string'` (SvelteFlow); pass `'object'` for React Flow.
|
|
149
|
+
* Existing styles always keep their representation.
|
|
150
|
+
*/
|
|
151
|
+
styleFormat?: 'string' | 'object';
|
|
152
|
+
/**
|
|
153
|
+
* Called on every frame with updated copies of the transitioning nodes, in the same
|
|
154
|
+
* order as the `transitions` array. Input nodes are never mutated.
|
|
155
|
+
*/
|
|
156
|
+
onUpdate?: (nodes: TNode[]) => void;
|
|
157
|
+
/** Called once all transitions finished, with the final node copies. */
|
|
158
|
+
onComplete?: (nodes: TNode[]) => void;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Coordinates and animates multiple node transitions simultaneously.
|
|
162
|
+
*
|
|
163
|
+
* The input nodes are treated as immutable: every frame produces updated copies
|
|
164
|
+
* (position, `data.scale` / `data.opacity`, and `style` opacity) which are handed to
|
|
165
|
+
* `onUpdate` and finally `onComplete`. Merge them into your node state by `id`.
|
|
166
|
+
*/
|
|
167
|
+
declare function runMultiNodeTransition<TNode extends CanvasNode = CanvasNode>(transitions: NodeTransition<TNode>[], options?: MultiNodeTransitionOptions<TNode>): () => void;
|
|
143
168
|
|
|
144
169
|
/**
|
|
145
170
|
* Calculates a bounding rectangle for a set of nodes if not provided by getNodesBounds.
|
|
@@ -175,9 +200,14 @@ declare function isEventFromTextInput(event: Event | {
|
|
|
175
200
|
target: EventTarget | null;
|
|
176
201
|
}): boolean;
|
|
177
202
|
/**
|
|
178
|
-
* Validates that an object conforms to minimal CanvasNode shape
|
|
203
|
+
* Validates that an object conforms to minimal CanvasNode shape:
|
|
204
|
+
* a string `id` and a `position` whose `x` / `y` are finite numbers.
|
|
179
205
|
*/
|
|
180
206
|
declare function isValidCanvasNode(obj: unknown): obj is CanvasNode;
|
|
207
|
+
/**
|
|
208
|
+
* Validates that an object conforms to minimal CanvasEdge shape (string `id`, `source`, `target`).
|
|
209
|
+
*/
|
|
210
|
+
declare function isValidCanvasEdge(obj: unknown): obj is CanvasEdge;
|
|
181
211
|
/**
|
|
182
212
|
* Checks if a string is a valid HTTP/HTTPS URL.
|
|
183
213
|
*/
|
|
@@ -192,8 +222,14 @@ declare function serializeCanvasNodes<TNode extends CanvasNode = CanvasNode, TEd
|
|
|
192
222
|
declare function parseCanvasClipboardData<TNode extends CanvasNode = CanvasNode, TEdge extends CanvasEdge = CanvasEdge>(raw: string): CanvasClipboardPayload<TNode, TEdge> | null;
|
|
193
223
|
/**
|
|
194
224
|
* Generates unique new IDs for pasted nodes and updates edge references accordingly.
|
|
225
|
+
*
|
|
226
|
+
* - Nodes without a valid id / finite numeric position are skipped.
|
|
227
|
+
* - `parentId` (and legacy `parentNode`) references to other pasted nodes are remapped to
|
|
228
|
+
* the new IDs; such children keep their parent-relative position (no extra offset).
|
|
229
|
+
* References to parents outside the pasted set are left unchanged.
|
|
230
|
+
* - Edges are kept only when both endpoints were pasted; a non-array `edges` is ignored.
|
|
195
231
|
*/
|
|
196
|
-
declare function remapPastedNodes<TNode extends CanvasNode = CanvasNode, TEdge extends CanvasEdge = CanvasEdge>(nodes: TNode[], edges?: TEdge[], offset?: XYPosition, idGenerator?: () => string): {
|
|
232
|
+
declare function remapPastedNodes<TNode extends CanvasNode = CanvasNode, TEdge extends CanvasEdge = CanvasEdge>(nodes: TNode[], edges?: TEdge[] | null | undefined, offset?: XYPosition, idGenerator?: () => string): {
|
|
197
233
|
nodes: TNode[];
|
|
198
234
|
edges: TEdge[];
|
|
199
235
|
};
|
|
@@ -213,6 +249,15 @@ interface StreamingLayoutManagerOptions {
|
|
|
213
249
|
/**
|
|
214
250
|
* Manages throttled incremental layout recalculation and smooth tweened node gliding
|
|
215
251
|
* during active streaming (e.g. LLM streaming or graph generation).
|
|
252
|
+
*
|
|
253
|
+
* - `pushStreamUpdate` is a true throttle (leading + trailing edge): the first update
|
|
254
|
+
* lays out immediately, further updates within `throttleMs` are coalesced and the
|
|
255
|
+
* latest one is laid out when the window closes. Layouts therefore keep running at
|
|
256
|
+
* most once per `throttleMs` while a stream is active, instead of being postponed
|
|
257
|
+
* until the stream goes quiet.
|
|
258
|
+
* - Every layout is computed from the graph (respecting `layoutOptions.storedPositions`
|
|
259
|
+
* as pinned/manual coordinates) and each known node glides from its *current*
|
|
260
|
+
* position (the `currentPositions` argument) to its newly computed position.
|
|
216
261
|
*/
|
|
217
262
|
declare class StreamingLayoutManager<TNode extends CanvasNode = CanvasNode, TEdge extends CanvasEdge = CanvasEdge> {
|
|
218
263
|
private throttleMs;
|
|
@@ -222,18 +267,26 @@ declare class StreamingLayoutManager<TNode extends CanvasNode = CanvasNode, TEdg
|
|
|
222
267
|
private layoutOptions;
|
|
223
268
|
private onLayoutUpdated?;
|
|
224
269
|
private pendingTimer;
|
|
270
|
+
private pendingArgs;
|
|
225
271
|
private activeTransitionCancel;
|
|
226
272
|
private targetPositions;
|
|
273
|
+
private livePositions;
|
|
227
274
|
constructor(options?: StreamingLayoutManagerOptions);
|
|
228
275
|
/**
|
|
229
276
|
* Feed incoming nodes and edges into the streaming manager.
|
|
230
|
-
*
|
|
277
|
+
* Throttles rapid streaming bursts (leading + trailing edge) and triggers smooth layout gliding.
|
|
231
278
|
*/
|
|
232
279
|
pushStreamUpdate(nodes: TNode[], edges: TEdge[], currentPositions: Map<string, XYPosition>): void;
|
|
280
|
+
private startWindow;
|
|
233
281
|
/**
|
|
234
282
|
* Forces immediate calculation and cancels pending throttled timers.
|
|
235
283
|
*/
|
|
236
284
|
flush(nodes: TNode[], edges: TEdge[], currentPositions: Map<string, XYPosition>): void;
|
|
285
|
+
/**
|
|
286
|
+
* Latest computed layout targets (the positions nodes are gliding towards).
|
|
287
|
+
*/
|
|
288
|
+
getTargetPositions(): Map<string, XYPosition>;
|
|
289
|
+
private clearPending;
|
|
237
290
|
private recalculateAndGlide;
|
|
238
291
|
destroy(): void;
|
|
239
292
|
}
|
|
@@ -274,4 +327,4 @@ declare function blendLayout<TNode extends CanvasNode = CanvasNode>(from: TNode[
|
|
|
274
327
|
*/
|
|
275
328
|
declare function connectedOnly<TNode extends CanvasNode = CanvasNode, TEdge extends CanvasEdge = CanvasEdge>(nodes: TNode[], edges: TEdge[]): TNode[];
|
|
276
329
|
|
|
277
|
-
export { CanvasClipboardPayload, CanvasEdge, type CanvasHeightOptions, CanvasLayoutOptions, CanvasNode, type Clock, DEFAULT_NODE_HEIGHT, DEFAULT_NODE_WIDTH, DEFAULT_PLACEMENT_GAP, DirectionalDisplacementOptions, FanOutTrajectoryOptions, IncrementalLayoutOptions, ManualClock, NodeTransition, PlaceBesideOptions, Rect, ReflowDisplacementOptions, Side, StreamingLayoutManager, type StreamingLayoutManagerOptions, TrajectoryFunction, XYPosition, blendLayout, boundsOf, calculateDagreReflowDisplacement, calculateDirectionalDisplacement, canvasHeight, centerNodes, centre, computeNodesBoundingBox, connectedOnly, createBezierTrajectory, createFanOutTrajectory, defaultEasing, ensureLayout, estimateCanvasHeight, estimateNodeSize, flowSide, getCenteredNodePosition, getLayoutedNodes, isEventFromTextInput, isValidCanvasNode, isValidUrl, layoutBounds, linearPositionTrajectory, linearTrajectory, overlaps, pageHidden, parseCanvasClipboardData, placeBeside, realClock, remapPastedNodes, repositionNodesTo, runMultiNodeTransition, serializeCanvasNodes };
|
|
330
|
+
export { CanvasClipboardPayload, CanvasEdge, type CanvasHeightOptions, CanvasLayoutOptions, CanvasNode, CanvasNodeStyle, type Clock, DEFAULT_NODE_HEIGHT, DEFAULT_NODE_WIDTH, DEFAULT_PLACEMENT_GAP, DirectionalDisplacementOptions, FanOutTrajectoryOptions, IncrementalLayoutOptions, ManualClock, type MultiNodeTransitionOptions, NodeTransition, PlaceBesideOptions, Rect, ReflowDisplacementOptions, Side, StreamingLayoutManager, type StreamingLayoutManagerOptions, TrajectoryFunction, XYPosition, blendLayout, boundsOf, calculateDagreReflowDisplacement, calculateDirectionalDisplacement, canvasHeight, centerNodes, centre, computeNodesBoundingBox, connectedOnly, createBezierTrajectory, createFanOutTrajectory, defaultEasing, ensureLayout, estimateCanvasHeight, estimateNodeSize, flowSide, getCenteredNodePosition, getLayoutedNodes, isEventFromTextInput, isValidCanvasEdge, isValidCanvasNode, isValidUrl, layoutBounds, linearPositionTrajectory, linearTrajectory, overlaps, pageHidden, parseCanvasClipboardData, placeBeside, realClock, remapPastedNodes, repositionNodesTo, runMultiNodeTransition, serializeCanvasNodes, withStyleOpacity };
|
package/dist/canvas/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { R as Rect, C as CanvasNode, X as XYPosition, a as CanvasEdge, I as IncrementalLayoutOptions, S as Side, b as CanvasLayoutOptions, P as PlaceBesideOptions, T as TrajectoryFunction, F as FanOutTrajectoryOptions, N as NodeTransition, c as ReflowDisplacementOptions, D as DirectionalDisplacementOptions,
|
|
2
|
-
export {
|
|
1
|
+
import { R as Rect, C as CanvasNode, X as XYPosition, a as CanvasEdge, I as IncrementalLayoutOptions, S as Side, b as CanvasLayoutOptions, P as PlaceBesideOptions, T as TrajectoryFunction, F as FanOutTrajectoryOptions, N as NodeTransition, c as CanvasNodeStyle, d as ReflowDisplacementOptions, D as DirectionalDisplacementOptions, e as CanvasClipboardPayload } from '../types-JV3S8VeR.js';
|
|
2
|
+
export { f as CanvasDockingCallbacks, g as CollapseNodeOptions, h as DisplacementDirection, i as DockStrategy, E as ExplodeNodeOptions, j as ExplosionSnapshot, G as GraphDifferences, k as Point, l as Position, m as TrajectoryPoint } from '../types-JV3S8VeR.js';
|
|
3
3
|
|
|
4
4
|
declare const DEFAULT_NODE_WIDTH = 200;
|
|
5
5
|
declare const DEFAULT_NODE_HEIGHT = 60;
|
|
@@ -131,15 +131,40 @@ declare function createFanOutTrajectory(options?: FanOutTrajectoryOptions): Traj
|
|
|
131
131
|
declare function createBezierTrajectory(getControlPoint: (origin: XYPosition, target: XYPosition) => XYPosition): TrajectoryFunction;
|
|
132
132
|
|
|
133
133
|
/**
|
|
134
|
-
*
|
|
134
|
+
* Returns a copy of `style` with its opacity set to `opacity`.
|
|
135
|
+
*
|
|
136
|
+
* Supports both CSS strings (`"color: red; opacity: 0.5;"`, used by SvelteFlow)
|
|
137
|
+
* and style objects (`{ color: 'red', opacity: 0.5 }`, used by React Flow / xyflow).
|
|
138
|
+
* When `style` is empty, `emptyFormat` decides which representation is produced.
|
|
139
|
+
* Never mutates the input.
|
|
135
140
|
*/
|
|
136
|
-
declare function
|
|
141
|
+
declare function withStyleOpacity(style: CanvasNodeStyle | undefined | null, opacity: number, emptyFormat?: 'string' | 'object'): CanvasNodeStyle;
|
|
142
|
+
interface MultiNodeTransitionOptions<TNode extends CanvasNode = CanvasNode> {
|
|
137
143
|
defaultDuration?: number;
|
|
138
144
|
defaultEasing?: (t: number) => number;
|
|
139
145
|
clock?: Clock;
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
146
|
+
/**
|
|
147
|
+
* Style representation to create for nodes that have no `style` yet when an opacity
|
|
148
|
+
* is applied. Defaults to `'string'` (SvelteFlow); pass `'object'` for React Flow.
|
|
149
|
+
* Existing styles always keep their representation.
|
|
150
|
+
*/
|
|
151
|
+
styleFormat?: 'string' | 'object';
|
|
152
|
+
/**
|
|
153
|
+
* Called on every frame with updated copies of the transitioning nodes, in the same
|
|
154
|
+
* order as the `transitions` array. Input nodes are never mutated.
|
|
155
|
+
*/
|
|
156
|
+
onUpdate?: (nodes: TNode[]) => void;
|
|
157
|
+
/** Called once all transitions finished, with the final node copies. */
|
|
158
|
+
onComplete?: (nodes: TNode[]) => void;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Coordinates and animates multiple node transitions simultaneously.
|
|
162
|
+
*
|
|
163
|
+
* The input nodes are treated as immutable: every frame produces updated copies
|
|
164
|
+
* (position, `data.scale` / `data.opacity`, and `style` opacity) which are handed to
|
|
165
|
+
* `onUpdate` and finally `onComplete`. Merge them into your node state by `id`.
|
|
166
|
+
*/
|
|
167
|
+
declare function runMultiNodeTransition<TNode extends CanvasNode = CanvasNode>(transitions: NodeTransition<TNode>[], options?: MultiNodeTransitionOptions<TNode>): () => void;
|
|
143
168
|
|
|
144
169
|
/**
|
|
145
170
|
* Calculates a bounding rectangle for a set of nodes if not provided by getNodesBounds.
|
|
@@ -175,9 +200,14 @@ declare function isEventFromTextInput(event: Event | {
|
|
|
175
200
|
target: EventTarget | null;
|
|
176
201
|
}): boolean;
|
|
177
202
|
/**
|
|
178
|
-
* Validates that an object conforms to minimal CanvasNode shape
|
|
203
|
+
* Validates that an object conforms to minimal CanvasNode shape:
|
|
204
|
+
* a string `id` and a `position` whose `x` / `y` are finite numbers.
|
|
179
205
|
*/
|
|
180
206
|
declare function isValidCanvasNode(obj: unknown): obj is CanvasNode;
|
|
207
|
+
/**
|
|
208
|
+
* Validates that an object conforms to minimal CanvasEdge shape (string `id`, `source`, `target`).
|
|
209
|
+
*/
|
|
210
|
+
declare function isValidCanvasEdge(obj: unknown): obj is CanvasEdge;
|
|
181
211
|
/**
|
|
182
212
|
* Checks if a string is a valid HTTP/HTTPS URL.
|
|
183
213
|
*/
|
|
@@ -192,8 +222,14 @@ declare function serializeCanvasNodes<TNode extends CanvasNode = CanvasNode, TEd
|
|
|
192
222
|
declare function parseCanvasClipboardData<TNode extends CanvasNode = CanvasNode, TEdge extends CanvasEdge = CanvasEdge>(raw: string): CanvasClipboardPayload<TNode, TEdge> | null;
|
|
193
223
|
/**
|
|
194
224
|
* Generates unique new IDs for pasted nodes and updates edge references accordingly.
|
|
225
|
+
*
|
|
226
|
+
* - Nodes without a valid id / finite numeric position are skipped.
|
|
227
|
+
* - `parentId` (and legacy `parentNode`) references to other pasted nodes are remapped to
|
|
228
|
+
* the new IDs; such children keep their parent-relative position (no extra offset).
|
|
229
|
+
* References to parents outside the pasted set are left unchanged.
|
|
230
|
+
* - Edges are kept only when both endpoints were pasted; a non-array `edges` is ignored.
|
|
195
231
|
*/
|
|
196
|
-
declare function remapPastedNodes<TNode extends CanvasNode = CanvasNode, TEdge extends CanvasEdge = CanvasEdge>(nodes: TNode[], edges?: TEdge[], offset?: XYPosition, idGenerator?: () => string): {
|
|
232
|
+
declare function remapPastedNodes<TNode extends CanvasNode = CanvasNode, TEdge extends CanvasEdge = CanvasEdge>(nodes: TNode[], edges?: TEdge[] | null | undefined, offset?: XYPosition, idGenerator?: () => string): {
|
|
197
233
|
nodes: TNode[];
|
|
198
234
|
edges: TEdge[];
|
|
199
235
|
};
|
|
@@ -213,6 +249,15 @@ interface StreamingLayoutManagerOptions {
|
|
|
213
249
|
/**
|
|
214
250
|
* Manages throttled incremental layout recalculation and smooth tweened node gliding
|
|
215
251
|
* during active streaming (e.g. LLM streaming or graph generation).
|
|
252
|
+
*
|
|
253
|
+
* - `pushStreamUpdate` is a true throttle (leading + trailing edge): the first update
|
|
254
|
+
* lays out immediately, further updates within `throttleMs` are coalesced and the
|
|
255
|
+
* latest one is laid out when the window closes. Layouts therefore keep running at
|
|
256
|
+
* most once per `throttleMs` while a stream is active, instead of being postponed
|
|
257
|
+
* until the stream goes quiet.
|
|
258
|
+
* - Every layout is computed from the graph (respecting `layoutOptions.storedPositions`
|
|
259
|
+
* as pinned/manual coordinates) and each known node glides from its *current*
|
|
260
|
+
* position (the `currentPositions` argument) to its newly computed position.
|
|
216
261
|
*/
|
|
217
262
|
declare class StreamingLayoutManager<TNode extends CanvasNode = CanvasNode, TEdge extends CanvasEdge = CanvasEdge> {
|
|
218
263
|
private throttleMs;
|
|
@@ -222,18 +267,26 @@ declare class StreamingLayoutManager<TNode extends CanvasNode = CanvasNode, TEdg
|
|
|
222
267
|
private layoutOptions;
|
|
223
268
|
private onLayoutUpdated?;
|
|
224
269
|
private pendingTimer;
|
|
270
|
+
private pendingArgs;
|
|
225
271
|
private activeTransitionCancel;
|
|
226
272
|
private targetPositions;
|
|
273
|
+
private livePositions;
|
|
227
274
|
constructor(options?: StreamingLayoutManagerOptions);
|
|
228
275
|
/**
|
|
229
276
|
* Feed incoming nodes and edges into the streaming manager.
|
|
230
|
-
*
|
|
277
|
+
* Throttles rapid streaming bursts (leading + trailing edge) and triggers smooth layout gliding.
|
|
231
278
|
*/
|
|
232
279
|
pushStreamUpdate(nodes: TNode[], edges: TEdge[], currentPositions: Map<string, XYPosition>): void;
|
|
280
|
+
private startWindow;
|
|
233
281
|
/**
|
|
234
282
|
* Forces immediate calculation and cancels pending throttled timers.
|
|
235
283
|
*/
|
|
236
284
|
flush(nodes: TNode[], edges: TEdge[], currentPositions: Map<string, XYPosition>): void;
|
|
285
|
+
/**
|
|
286
|
+
* Latest computed layout targets (the positions nodes are gliding towards).
|
|
287
|
+
*/
|
|
288
|
+
getTargetPositions(): Map<string, XYPosition>;
|
|
289
|
+
private clearPending;
|
|
237
290
|
private recalculateAndGlide;
|
|
238
291
|
destroy(): void;
|
|
239
292
|
}
|
|
@@ -274,4 +327,4 @@ declare function blendLayout<TNode extends CanvasNode = CanvasNode>(from: TNode[
|
|
|
274
327
|
*/
|
|
275
328
|
declare function connectedOnly<TNode extends CanvasNode = CanvasNode, TEdge extends CanvasEdge = CanvasEdge>(nodes: TNode[], edges: TEdge[]): TNode[];
|
|
276
329
|
|
|
277
|
-
export { CanvasClipboardPayload, CanvasEdge, type CanvasHeightOptions, CanvasLayoutOptions, CanvasNode, type Clock, DEFAULT_NODE_HEIGHT, DEFAULT_NODE_WIDTH, DEFAULT_PLACEMENT_GAP, DirectionalDisplacementOptions, FanOutTrajectoryOptions, IncrementalLayoutOptions, ManualClock, NodeTransition, PlaceBesideOptions, Rect, ReflowDisplacementOptions, Side, StreamingLayoutManager, type StreamingLayoutManagerOptions, TrajectoryFunction, XYPosition, blendLayout, boundsOf, calculateDagreReflowDisplacement, calculateDirectionalDisplacement, canvasHeight, centerNodes, centre, computeNodesBoundingBox, connectedOnly, createBezierTrajectory, createFanOutTrajectory, defaultEasing, ensureLayout, estimateCanvasHeight, estimateNodeSize, flowSide, getCenteredNodePosition, getLayoutedNodes, isEventFromTextInput, isValidCanvasNode, isValidUrl, layoutBounds, linearPositionTrajectory, linearTrajectory, overlaps, pageHidden, parseCanvasClipboardData, placeBeside, realClock, remapPastedNodes, repositionNodesTo, runMultiNodeTransition, serializeCanvasNodes };
|
|
330
|
+
export { CanvasClipboardPayload, CanvasEdge, type CanvasHeightOptions, CanvasLayoutOptions, CanvasNode, CanvasNodeStyle, type Clock, DEFAULT_NODE_HEIGHT, DEFAULT_NODE_WIDTH, DEFAULT_PLACEMENT_GAP, DirectionalDisplacementOptions, FanOutTrajectoryOptions, IncrementalLayoutOptions, ManualClock, type MultiNodeTransitionOptions, NodeTransition, PlaceBesideOptions, Rect, ReflowDisplacementOptions, Side, StreamingLayoutManager, type StreamingLayoutManagerOptions, TrajectoryFunction, XYPosition, blendLayout, boundsOf, calculateDagreReflowDisplacement, calculateDirectionalDisplacement, canvasHeight, centerNodes, centre, computeNodesBoundingBox, connectedOnly, createBezierTrajectory, createFanOutTrajectory, defaultEasing, ensureLayout, estimateCanvasHeight, estimateNodeSize, flowSide, getCenteredNodePosition, getLayoutedNodes, isEventFromTextInput, isValidCanvasEdge, isValidCanvasNode, isValidUrl, layoutBounds, linearPositionTrajectory, linearTrajectory, overlaps, pageHidden, parseCanvasClipboardData, placeBeside, realClock, remapPastedNodes, repositionNodesTo, runMultiNodeTransition, serializeCanvasNodes, withStyleOpacity };
|
package/dist/canvas/index.js
CHANGED
|
@@ -148,9 +148,19 @@ function createBezierTrajectory(getControlPoint) {
|
|
|
148
148
|
};
|
|
149
149
|
};
|
|
150
150
|
}
|
|
151
|
+
function withStyleOpacity(style, opacity, emptyFormat = "string") {
|
|
152
|
+
if (style !== null && typeof style === "object") {
|
|
153
|
+
return { ...style, opacity };
|
|
154
|
+
}
|
|
155
|
+
if (typeof style === "string" && style.trim() !== "") {
|
|
156
|
+
const rest = style.replace(/(^|;)\s*opacity\s*:\s*[^;]*;?/gi, "$1").trim().replace(/;+\s*$/, "").trim();
|
|
157
|
+
return `${rest ? rest + "; " : ""}opacity: ${opacity};`;
|
|
158
|
+
}
|
|
159
|
+
return emptyFormat === "object" ? { opacity } : `opacity: ${opacity};`;
|
|
160
|
+
}
|
|
151
161
|
function runMultiNodeTransition(transitions, options = {}) {
|
|
152
162
|
if (transitions.length === 0) {
|
|
153
|
-
options.onComplete?.();
|
|
163
|
+
options.onComplete?.([]);
|
|
154
164
|
return () => {
|
|
155
165
|
};
|
|
156
166
|
}
|
|
@@ -158,6 +168,7 @@ function runMultiNodeTransition(transitions, options = {}) {
|
|
|
158
168
|
defaultDuration = 400,
|
|
159
169
|
defaultEasing: easingFunc = defaultEasing,
|
|
160
170
|
clock = realClock,
|
|
171
|
+
styleFormat = "string",
|
|
161
172
|
onUpdate,
|
|
162
173
|
onComplete
|
|
163
174
|
} = options;
|
|
@@ -172,6 +183,7 @@ function runMultiNodeTransition(transitions, options = {}) {
|
|
|
172
183
|
delay: tr.delay ?? 0,
|
|
173
184
|
trajectory: tr.trajectory ?? linearTrajectory
|
|
174
185
|
}));
|
|
186
|
+
const current = items.map((item) => item.node);
|
|
175
187
|
function frame() {
|
|
176
188
|
if (isCancelled) return;
|
|
177
189
|
const now = clock.now();
|
|
@@ -186,29 +198,28 @@ function runMultiNodeTransition(transitions, options = {}) {
|
|
|
186
198
|
const rawProgress = item.duration <= 0 ? 1 : Math.min(elapsed / item.duration, 1);
|
|
187
199
|
const progress = item.duration <= 0 ? 1 : item.easing(rawProgress);
|
|
188
200
|
const point = item.trajectory(item.from, item.to, progress, item.index, item.total);
|
|
189
|
-
item.node
|
|
201
|
+
const next = { ...item.node, position: { ...point.position } };
|
|
190
202
|
if (point.scale !== void 0 || point.opacity !== void 0) {
|
|
191
|
-
|
|
192
|
-
item.node.data = {};
|
|
193
|
-
}
|
|
203
|
+
const data = { ...item.node.data ?? {} };
|
|
194
204
|
if (point.scale !== void 0) {
|
|
195
|
-
|
|
205
|
+
data.scale = point.scale;
|
|
196
206
|
}
|
|
197
207
|
if (point.opacity !== void 0) {
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
item.node.style = `${currentStyle ? currentStyle + "; " : ""}opacity: ${point.opacity};`;
|
|
208
|
+
data.opacity = point.opacity;
|
|
209
|
+
next.style = withStyleOpacity(item.node.style, point.opacity, styleFormat);
|
|
201
210
|
}
|
|
211
|
+
next.data = data;
|
|
202
212
|
}
|
|
213
|
+
current[i] = next;
|
|
203
214
|
if (rawProgress < 1) {
|
|
204
215
|
allCompleted = false;
|
|
205
216
|
}
|
|
206
217
|
}
|
|
207
|
-
onUpdate?.();
|
|
218
|
+
onUpdate?.(current.slice());
|
|
208
219
|
if (!allCompleted) {
|
|
209
220
|
clock.frame().then(frame);
|
|
210
221
|
} else {
|
|
211
|
-
onComplete?.();
|
|
222
|
+
onComplete?.(current.slice());
|
|
212
223
|
}
|
|
213
224
|
}
|
|
214
225
|
frame();
|
|
@@ -417,7 +428,16 @@ function isEventFromTextInput(event) {
|
|
|
417
428
|
return false;
|
|
418
429
|
}
|
|
419
430
|
function isValidCanvasNode(obj) {
|
|
420
|
-
|
|
431
|
+
if (typeof obj !== "object" || obj === null) return false;
|
|
432
|
+
const candidate = obj;
|
|
433
|
+
if (typeof candidate.id !== "string") return false;
|
|
434
|
+
const position = candidate.position;
|
|
435
|
+
return typeof position === "object" && position !== null && typeof position.x === "number" && Number.isFinite(position.x) && typeof position.y === "number" && Number.isFinite(position.y);
|
|
436
|
+
}
|
|
437
|
+
function isValidCanvasEdge(obj) {
|
|
438
|
+
if (typeof obj !== "object" || obj === null) return false;
|
|
439
|
+
const candidate = obj;
|
|
440
|
+
return typeof candidate.id === "string" && typeof candidate.source === "string" && typeof candidate.target === "string";
|
|
421
441
|
}
|
|
422
442
|
function isValidUrl(url) {
|
|
423
443
|
try {
|
|
@@ -439,28 +459,46 @@ function parseCanvasClipboardData(raw) {
|
|
|
439
459
|
try {
|
|
440
460
|
const parsed = JSON.parse(raw);
|
|
441
461
|
if (typeof parsed === "object" && parsed !== null && Array.isArray(parsed.nodes) && parsed.nodes.length > 0 && parsed.nodes.every(isValidCanvasNode)) {
|
|
442
|
-
|
|
462
|
+
const edges = Array.isArray(parsed.edges) ? parsed.edges.filter(isValidCanvasEdge) : void 0;
|
|
463
|
+
return { ...parsed, edges };
|
|
443
464
|
}
|
|
444
465
|
} catch {
|
|
445
466
|
}
|
|
446
467
|
return null;
|
|
447
468
|
}
|
|
448
469
|
function remapPastedNodes(nodes, edges = [], offset = { x: 30, y: 30 }, idGenerator = () => `node-${Math.random().toString(36).substring(2, 9)}`) {
|
|
470
|
+
const validNodes = (Array.isArray(nodes) ? nodes : []).filter(isValidCanvasNode);
|
|
471
|
+
const validEdges = (Array.isArray(edges) ? edges : []).filter(isValidCanvasEdge);
|
|
472
|
+
const dx = Number.isFinite(offset?.x) ? offset.x : 0;
|
|
473
|
+
const dy = Number.isFinite(offset?.y) ? offset.y : 0;
|
|
449
474
|
const idMap = /* @__PURE__ */ new Map();
|
|
450
|
-
const
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
475
|
+
for (const node of validNodes) {
|
|
476
|
+
idMap.set(node.id, idGenerator());
|
|
477
|
+
}
|
|
478
|
+
const newNodes = validNodes.map((node) => {
|
|
479
|
+
const next = {
|
|
454
480
|
...node,
|
|
455
|
-
id:
|
|
481
|
+
id: idMap.get(node.id),
|
|
456
482
|
position: {
|
|
457
|
-
x: node.position.x +
|
|
458
|
-
y: node.position.y +
|
|
483
|
+
x: node.position.x + dx,
|
|
484
|
+
y: node.position.y + dy
|
|
459
485
|
},
|
|
460
486
|
selected: true
|
|
461
487
|
};
|
|
488
|
+
let parentRemapped = false;
|
|
489
|
+
for (const key of ["parentId", "parentNode"]) {
|
|
490
|
+
const parent = node[key];
|
|
491
|
+
if (typeof parent === "string" && idMap.has(parent)) {
|
|
492
|
+
next[key] = idMap.get(parent);
|
|
493
|
+
parentRemapped = true;
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
if (parentRemapped) {
|
|
497
|
+
next.position = { x: node.position.x, y: node.position.y };
|
|
498
|
+
}
|
|
499
|
+
return next;
|
|
462
500
|
});
|
|
463
|
-
const newEdges =
|
|
501
|
+
const newEdges = validEdges.filter((e) => idMap.has(e.source) && idMap.has(e.target)).map((edge) => ({
|
|
464
502
|
...edge,
|
|
465
503
|
id: `edge-${Math.random().toString(36).substring(2, 9)}`,
|
|
466
504
|
source: idMap.get(edge.source),
|
|
@@ -557,8 +595,10 @@ var StreamingLayoutManager = class {
|
|
|
557
595
|
layoutOptions;
|
|
558
596
|
onLayoutUpdated;
|
|
559
597
|
pendingTimer = null;
|
|
598
|
+
pendingArgs = null;
|
|
560
599
|
activeTransitionCancel = null;
|
|
561
600
|
targetPositions = /* @__PURE__ */ new Map();
|
|
601
|
+
livePositions = /* @__PURE__ */ new Map();
|
|
562
602
|
constructor(options = {}) {
|
|
563
603
|
this.throttleMs = options.throttleMs ?? 200;
|
|
564
604
|
this.glideDurationMs = options.glideDurationMs ?? 300;
|
|
@@ -569,52 +609,70 @@ var StreamingLayoutManager = class {
|
|
|
569
609
|
}
|
|
570
610
|
/**
|
|
571
611
|
* Feed incoming nodes and edges into the streaming manager.
|
|
572
|
-
*
|
|
612
|
+
* Throttles rapid streaming bursts (leading + trailing edge) and triggers smooth layout gliding.
|
|
573
613
|
*/
|
|
574
614
|
pushStreamUpdate(nodes, edges, currentPositions) {
|
|
575
|
-
if (this.pendingTimer) {
|
|
576
|
-
|
|
615
|
+
if (this.pendingTimer !== null) {
|
|
616
|
+
this.pendingArgs = [nodes, edges, currentPositions];
|
|
617
|
+
return;
|
|
577
618
|
}
|
|
619
|
+
this.recalculateAndGlide(nodes, edges, currentPositions);
|
|
620
|
+
this.startWindow();
|
|
621
|
+
}
|
|
622
|
+
startWindow() {
|
|
578
623
|
this.pendingTimer = setTimeout(() => {
|
|
579
624
|
this.pendingTimer = null;
|
|
580
|
-
this.
|
|
581
|
-
|
|
625
|
+
const args = this.pendingArgs;
|
|
626
|
+
this.pendingArgs = null;
|
|
627
|
+
if (args) {
|
|
628
|
+
this.recalculateAndGlide(...args);
|
|
629
|
+
this.startWindow();
|
|
630
|
+
}
|
|
631
|
+
}, Math.max(0, this.throttleMs));
|
|
582
632
|
}
|
|
583
633
|
/**
|
|
584
634
|
* Forces immediate calculation and cancels pending throttled timers.
|
|
585
635
|
*/
|
|
586
636
|
flush(nodes, edges, currentPositions) {
|
|
587
|
-
|
|
637
|
+
this.clearPending();
|
|
638
|
+
this.recalculateAndGlide(nodes, edges, currentPositions);
|
|
639
|
+
}
|
|
640
|
+
/**
|
|
641
|
+
* Latest computed layout targets (the positions nodes are gliding towards).
|
|
642
|
+
*/
|
|
643
|
+
getTargetPositions() {
|
|
644
|
+
return new Map(this.targetPositions);
|
|
645
|
+
}
|
|
646
|
+
clearPending() {
|
|
647
|
+
if (this.pendingTimer !== null) {
|
|
588
648
|
clearTimeout(this.pendingTimer);
|
|
589
649
|
this.pendingTimer = null;
|
|
590
650
|
}
|
|
591
|
-
this.
|
|
651
|
+
this.pendingArgs = null;
|
|
592
652
|
}
|
|
593
653
|
recalculateAndGlide(nodes, edges, currentPositions) {
|
|
594
654
|
const targetNodes = this.connectedOnly ? connectedOnly(nodes, edges) : nodes;
|
|
595
655
|
if (targetNodes.length === 0) return;
|
|
656
|
+
const startPositions = new Map(currentPositions);
|
|
596
657
|
if (this.activeTransitionCancel) {
|
|
658
|
+
for (const [id, pos] of this.livePositions) {
|
|
659
|
+
startPositions.set(id, pos);
|
|
660
|
+
}
|
|
597
661
|
this.activeTransitionCancel();
|
|
598
662
|
this.activeTransitionCancel = null;
|
|
599
663
|
}
|
|
600
|
-
const
|
|
601
|
-
for (const [id, pos] of currentPositions.entries()) {
|
|
602
|
-
stored[id] = pos;
|
|
603
|
-
}
|
|
604
|
-
const layouted = ensureLayout(targetNodes, edges, {
|
|
605
|
-
...this.layoutOptions,
|
|
606
|
-
storedPositions: stored
|
|
607
|
-
});
|
|
664
|
+
const layouted = ensureLayout(targetNodes, edges, this.layoutOptions);
|
|
608
665
|
const nextPositions = /* @__PURE__ */ new Map();
|
|
609
666
|
const transitions = [];
|
|
610
667
|
for (const node of layouted) {
|
|
611
|
-
const target = node.position;
|
|
668
|
+
const target = { ...node.position };
|
|
612
669
|
nextPositions.set(node.id, target);
|
|
613
|
-
const current =
|
|
670
|
+
const current = startPositions.get(node.id);
|
|
671
|
+
if (!current) continue;
|
|
614
672
|
const distance = Math.hypot(target.x - current.x, target.y - current.y);
|
|
615
673
|
if (distance > 2) {
|
|
616
674
|
transitions.push({
|
|
617
|
-
node,
|
|
675
|
+
node: { ...node, position: { ...current } },
|
|
618
676
|
from: current,
|
|
619
677
|
to: target,
|
|
620
678
|
trajectory: linearPositionTrajectory,
|
|
@@ -623,30 +681,38 @@ var StreamingLayoutManager = class {
|
|
|
623
681
|
}
|
|
624
682
|
}
|
|
625
683
|
this.targetPositions = nextPositions;
|
|
626
|
-
if (transitions.length
|
|
627
|
-
this.
|
|
628
|
-
clock: this.clock,
|
|
629
|
-
onUpdate: () => {
|
|
630
|
-
const liveMap = new Map(currentPositions);
|
|
631
|
-
for (const trans of transitions) {
|
|
632
|
-
liveMap.set(trans.node.id, { ...trans.node.position });
|
|
633
|
-
}
|
|
634
|
-
this.onLayoutUpdated?.(liveMap);
|
|
635
|
-
},
|
|
636
|
-
onComplete: () => {
|
|
637
|
-
this.activeTransitionCancel = null;
|
|
638
|
-
this.onLayoutUpdated?.(nextPositions);
|
|
639
|
-
}
|
|
640
|
-
});
|
|
641
|
-
} else {
|
|
684
|
+
if (transitions.length === 0) {
|
|
685
|
+
this.livePositions = new Map(nextPositions);
|
|
642
686
|
this.onLayoutUpdated?.(nextPositions);
|
|
687
|
+
return;
|
|
643
688
|
}
|
|
689
|
+
const live = new Map(nextPositions);
|
|
690
|
+
for (const trans of transitions) {
|
|
691
|
+
live.set(trans.node.id, { ...trans.from });
|
|
692
|
+
}
|
|
693
|
+
this.livePositions = live;
|
|
694
|
+
let finished = false;
|
|
695
|
+
const cancel = runMultiNodeTransition(transitions, {
|
|
696
|
+
clock: this.clock,
|
|
697
|
+
onUpdate: (updated) => {
|
|
698
|
+
const frame = new Map(this.livePositions);
|
|
699
|
+
for (const node of updated) {
|
|
700
|
+
frame.set(node.id, { ...node.position });
|
|
701
|
+
}
|
|
702
|
+
this.livePositions = frame;
|
|
703
|
+
this.onLayoutUpdated?.(frame);
|
|
704
|
+
},
|
|
705
|
+
onComplete: () => {
|
|
706
|
+
finished = true;
|
|
707
|
+
this.activeTransitionCancel = null;
|
|
708
|
+
this.livePositions = new Map(nextPositions);
|
|
709
|
+
this.onLayoutUpdated?.(nextPositions);
|
|
710
|
+
}
|
|
711
|
+
});
|
|
712
|
+
this.activeTransitionCancel = finished ? null : cancel;
|
|
644
713
|
}
|
|
645
714
|
destroy() {
|
|
646
|
-
|
|
647
|
-
clearTimeout(this.pendingTimer);
|
|
648
|
-
this.pendingTimer = null;
|
|
649
|
-
}
|
|
715
|
+
this.clearPending();
|
|
650
716
|
if (this.activeTransitionCancel) {
|
|
651
717
|
this.activeTransitionCancel();
|
|
652
718
|
this.activeTransitionCancel = null;
|
|
@@ -678,6 +744,7 @@ export {
|
|
|
678
744
|
getCenteredNodePosition,
|
|
679
745
|
getLayoutedNodes,
|
|
680
746
|
isEventFromTextInput,
|
|
747
|
+
isValidCanvasEdge,
|
|
681
748
|
isValidCanvasNode,
|
|
682
749
|
isValidUrl,
|
|
683
750
|
layoutBounds,
|
|
@@ -691,6 +758,7 @@ export {
|
|
|
691
758
|
remapPastedNodes,
|
|
692
759
|
repositionNodesTo,
|
|
693
760
|
runMultiNodeTransition,
|
|
694
|
-
serializeCanvasNodes
|
|
761
|
+
serializeCanvasNodes,
|
|
762
|
+
withStyleOpacity
|
|
695
763
|
};
|
|
696
764
|
//# sourceMappingURL=index.js.map
|