@foblex/flow 19.1.2 → 19.1.4
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/AI.md +1 -0
- package/fesm2022/foblex-flow.mjs +54 -13
- package/fesm2022/foblex-flow.mjs.map +1 -1
- package/index.d.ts +6 -3
- package/package.json +1 -1
package/AI.md
CHANGED
|
@@ -139,6 +139,7 @@ export class Editor {
|
|
|
139
139
|
- Rotation, connection waypoint editing, and user resize are not captured by managed state in v1.
|
|
140
140
|
- `state.changes()` increments once when a standalone mutation or outer batch settles. A drag can emit selection at start and move/drop at end while remaining one history step and one `changes()` increment.
|
|
141
141
|
- Use `state.snapshot()` for persistence; `load()` replaces data and resets history.
|
|
142
|
+
- `canvasTransformDebounce` defaults to `350ms`. It waits for wheel/pinch zoom events to settle, then records the current canvas transform as one change and one undo item. Setting it to `0` disables batching: every emitted `fCanvasChange` is applied immediately, increments `state.changes()`, and normally creates a separate undo item. Keep the canvas `[debounceTime]` unset when managed state owns viewport history; do not stack canvas and State debounce layers.
|
|
142
143
|
- For initial or other application-driven viewport positioning, suppress the event at the canvas helper: `canvas.resetScaleAndCenter(false, false)`. The second `false` means `emitCanvasChange = false`, so managed history is untouched.
|
|
143
144
|
- Connection endpoints are connector ids. Automatic cascade from node/group deletion uses the rendered connector registry; before connectors render, remove known attached connection ids explicitly in the same `state.batch(...)`.
|
|
144
145
|
|
package/fesm2022/foblex-flow.mjs
CHANGED
|
@@ -370,7 +370,13 @@ class FChannelHub {
|
|
|
370
370
|
return result;
|
|
371
371
|
}
|
|
372
372
|
listen(destroyRef, callback) {
|
|
373
|
-
let
|
|
373
|
+
let tornDown = false;
|
|
374
|
+
let current = () => {
|
|
375
|
+
if (tornDown || destroyRef.destroyed) {
|
|
376
|
+
return;
|
|
377
|
+
}
|
|
378
|
+
callback();
|
|
379
|
+
};
|
|
374
380
|
const cleanups = [];
|
|
375
381
|
const onSubscribes = [];
|
|
376
382
|
const teardownSetters = [];
|
|
@@ -384,9 +390,8 @@ class FChannelHub {
|
|
|
384
390
|
if (res.setTeardown)
|
|
385
391
|
teardownSetters.push(res.setTeardown);
|
|
386
392
|
}
|
|
387
|
-
const unsubs =
|
|
393
|
+
const unsubs = [];
|
|
388
394
|
let unregisterOnDestroy = null;
|
|
389
|
-
let tornDown = false;
|
|
390
395
|
const teardown = () => {
|
|
391
396
|
if (tornDown)
|
|
392
397
|
return;
|
|
@@ -400,11 +405,31 @@ class FChannelHub {
|
|
|
400
405
|
.slice()
|
|
401
406
|
.reverse()
|
|
402
407
|
.forEach((set) => set(teardown));
|
|
408
|
+
if (destroyRef.destroyed) {
|
|
409
|
+
teardown();
|
|
410
|
+
return;
|
|
411
|
+
}
|
|
412
|
+
this._channels.forEach((channel) => {
|
|
413
|
+
unsubs.push(channel.listen(() => {
|
|
414
|
+
if (tornDown || destroyRef.destroyed) {
|
|
415
|
+
return;
|
|
416
|
+
}
|
|
417
|
+
current();
|
|
418
|
+
}));
|
|
419
|
+
});
|
|
420
|
+
if (destroyRef.destroyed) {
|
|
421
|
+
teardown();
|
|
422
|
+
return;
|
|
423
|
+
}
|
|
424
|
+
unregisterOnDestroy = destroyRef.onDestroy(teardown);
|
|
403
425
|
onSubscribes
|
|
404
426
|
.slice()
|
|
405
427
|
.reverse()
|
|
406
|
-
.forEach((fn) =>
|
|
407
|
-
|
|
428
|
+
.forEach((fn) => {
|
|
429
|
+
if (!tornDown && !destroyRef.destroyed) {
|
|
430
|
+
fn(current);
|
|
431
|
+
}
|
|
432
|
+
});
|
|
408
433
|
}
|
|
409
434
|
}
|
|
410
435
|
|
|
@@ -22492,7 +22517,7 @@ function mergeFlowStateConfig(config) {
|
|
|
22492
22517
|
historyLimit: 50,
|
|
22493
22518
|
selectionInHistory: true,
|
|
22494
22519
|
canvasTransformInHistory: true,
|
|
22495
|
-
canvasTransformDebounce:
|
|
22520
|
+
canvasTransformDebounce: 350,
|
|
22496
22521
|
dropToGroup: false,
|
|
22497
22522
|
...config,
|
|
22498
22523
|
};
|
|
@@ -23308,18 +23333,34 @@ class FFlowStateController {
|
|
|
23308
23333
|
if (this._transformDebounceTimer !== null) {
|
|
23309
23334
|
clearTimeout(this._transformDebounceTimer);
|
|
23310
23335
|
}
|
|
23336
|
+
this._scheduleCanvasChangeFlush(debounce);
|
|
23337
|
+
}
|
|
23338
|
+
_flushCanvasChange() {
|
|
23339
|
+
const pending = this._pendingTransform;
|
|
23340
|
+
if (!pending) {
|
|
23341
|
+
return;
|
|
23342
|
+
}
|
|
23343
|
+
const current = this._readCanvasTransform();
|
|
23344
|
+
const debounce = this._config?.canvasTransformDebounce ?? 0;
|
|
23345
|
+
if (debounce > 0 && current && !this._isSameCanvasTransform(pending, current)) {
|
|
23346
|
+
this._pendingTransform = current;
|
|
23347
|
+
this._scheduleCanvasChangeFlush(debounce);
|
|
23348
|
+
return;
|
|
23349
|
+
}
|
|
23350
|
+
this._pendingTransform = null;
|
|
23351
|
+
const settled = debounce > 0 ? (current ?? pending) : pending;
|
|
23352
|
+
this._dispatch(() => this._state.applyTransform(settled));
|
|
23353
|
+
}
|
|
23354
|
+
_scheduleCanvasChangeFlush(debounce) {
|
|
23311
23355
|
this._transformDebounceTimer = setTimeout(() => {
|
|
23312
23356
|
this._transformDebounceTimer = null;
|
|
23313
23357
|
this._flushCanvasChange();
|
|
23314
23358
|
}, debounce);
|
|
23315
23359
|
}
|
|
23316
|
-
|
|
23317
|
-
|
|
23318
|
-
|
|
23319
|
-
|
|
23320
|
-
return;
|
|
23321
|
-
}
|
|
23322
|
-
this._dispatch(() => this._state.applyTransform(transform));
|
|
23360
|
+
_isSameCanvasTransform(first, second) {
|
|
23361
|
+
return (first.position.x === second.position.x &&
|
|
23362
|
+
first.position.y === second.position.y &&
|
|
23363
|
+
first.scale === second.scale);
|
|
23323
23364
|
}
|
|
23324
23365
|
/**
|
|
23325
23366
|
* Subscribes to every node's and group's `sizeChange` (a per-directive
|