@modernrelay/orbit-core 0.14.0 → 0.16.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/{chunk-KRCG2JFN.js → chunk-DCY66QZS.js} +34 -7
- package/dist/chunk-DCY66QZS.js.map +1 -0
- package/dist/engine.d.ts +1 -1
- package/dist/{index-CPRTWpGA.d.ts → index-BoX8Q5jn.d.ts} +29 -2
- package/dist/index.d.ts +47 -16
- package/dist/index.js +139 -41
- package/dist/index.js.map +1 -1
- package/dist/{lane-_KPQ1deI.d.ts → lane-DKwMcUe3.d.ts} +1 -1
- package/dist/testing.d.ts +3 -3
- package/dist/testing.js +2 -2
- package/dist/worker/entry.js +35 -15
- package/dist/worker/entry.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-KRCG2JFN.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { DIAGNOSTIC_SAMPLE_CAP, encodeStringTable, collectTransfers, deriveClusters, resolveClusterCenters, clusterCentroids, EnvelopeSequencer, RequestLedger } from './chunk-
|
|
2
|
-
export { DEFAULT_CLUSTER_CENTER_RADIUS, DEFAULT_LAYOUT_SEED, DIAGNOSTIC_SAMPLE_CAP, acceptColumnar, clusterCentroids, collectTransfers, decodeStringTable, deriveClusters, encodeStringTable, generateClusterCenters, judgeEpoch, resolveClusterCenters } from './chunk-
|
|
1
|
+
import { DIAGNOSTIC_SAMPLE_CAP, resolveSimulation, encodeStringTable, collectTransfers, deriveClusters, resolveClusterCenters, clusterCentroids, EnvelopeSequencer, RequestLedger } from './chunk-DCY66QZS.js';
|
|
2
|
+
export { DEFAULT_CLUSTER_CENTER_RADIUS, DEFAULT_LAYOUT_SEED, DIAGNOSTIC_SAMPLE_CAP, SIMULATION_PRESETS, acceptColumnar, clusterCentroids, collectTransfers, decodeStringTable, deriveClusters, encodeStringTable, generateClusterCenters, judgeEpoch, resolveClusterCenters, resolveSimulation } from './chunk-DCY66QZS.js';
|
|
3
3
|
import { createStore } from 'zustand/vanilla';
|
|
4
4
|
|
|
5
5
|
// src/errors.ts
|
|
@@ -123,6 +123,10 @@ function validateSnapshot(snapshot) {
|
|
|
123
123
|
record(invalidEdge, typeof edge.id === "string" ? edge.id : `[${i}]`);
|
|
124
124
|
continue;
|
|
125
125
|
}
|
|
126
|
+
if (typeof edge.id === "string" && edge.id.includes("\0")) {
|
|
127
|
+
record(invalidEdge, `[${i}]`);
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
126
130
|
if (!nodeIndex.has(source)) {
|
|
127
131
|
record(danglingEdge, source);
|
|
128
132
|
continue;
|
|
@@ -172,7 +176,7 @@ function validateSnapshot(snapshot) {
|
|
|
172
176
|
"invalid-edge",
|
|
173
177
|
"error",
|
|
174
178
|
invalidEdge,
|
|
175
|
-
`${invalidEdge.count} edge row(s) dropped: missing or non-string source/target`
|
|
179
|
+
`${invalidEdge.count} edge row(s) dropped: missing or non-string source/target, or NUL-containing explicit id`
|
|
176
180
|
);
|
|
177
181
|
pushDiagnostic(
|
|
178
182
|
diagnostics,
|
|
@@ -1239,7 +1243,7 @@ function stageBatch(contribution, batch, tallies, nextOrder) {
|
|
|
1239
1243
|
for (let i = 0; i < rawNodes.length; i++) {
|
|
1240
1244
|
const row = rawNodes[i];
|
|
1241
1245
|
const id = typeof row === "object" && row !== null ? row.id : void 0;
|
|
1242
|
-
if (typeof id !== "string") {
|
|
1246
|
+
if (typeof id !== "string" || id.includes("\0")) {
|
|
1243
1247
|
recordRow(tallies.invalidNodes, `[${batch.sequence}:${i}]`);
|
|
1244
1248
|
continue;
|
|
1245
1249
|
}
|
|
@@ -1263,6 +1267,10 @@ function stageBatch(contribution, batch, tallies, nextOrder) {
|
|
|
1263
1267
|
recordRow(tallies.invalidEdges, typeof edge.id === "string" ? edge.id : `[${batch.sequence}:${i}]`);
|
|
1264
1268
|
continue;
|
|
1265
1269
|
}
|
|
1270
|
+
if (typeof edge.id === "string" && edge.id.includes("\0")) {
|
|
1271
|
+
recordRow(tallies.invalidEdges, `[${batch.sequence}:${i}]`);
|
|
1272
|
+
continue;
|
|
1273
|
+
}
|
|
1266
1274
|
const hasExplicitId = typeof edge.id === "string";
|
|
1267
1275
|
let id;
|
|
1268
1276
|
if (hasExplicitId) {
|
|
@@ -1415,7 +1423,7 @@ function sessionCommitDiagnostics(tallies, danglingCount, danglingSamples = [])
|
|
|
1415
1423
|
"invalid-node",
|
|
1416
1424
|
"error",
|
|
1417
1425
|
tallies.invalidNodes,
|
|
1418
|
-
`${tallies.invalidNodes.count} ingested node row(s) dropped: missing
|
|
1426
|
+
`${tallies.invalidNodes.count} ingested node row(s) dropped: missing, non-string, or NUL-containing id`
|
|
1419
1427
|
);
|
|
1420
1428
|
push(
|
|
1421
1429
|
"duplicate-node-id",
|
|
@@ -1427,7 +1435,7 @@ function sessionCommitDiagnostics(tallies, danglingCount, danglingSamples = [])
|
|
|
1427
1435
|
"invalid-edge",
|
|
1428
1436
|
"error",
|
|
1429
1437
|
tallies.invalidEdges,
|
|
1430
|
-
`${tallies.invalidEdges.count} ingested edge row(s) dropped: missing or non-string source/target`
|
|
1438
|
+
`${tallies.invalidEdges.count} ingested edge row(s) dropped: missing or non-string source/target, or NUL-containing explicit id`
|
|
1431
1439
|
);
|
|
1432
1440
|
push(
|
|
1433
1441
|
"duplicate-edge-id",
|
|
@@ -2982,6 +2990,16 @@ function checkStringColumn(col, rows, where, isIds, out) {
|
|
|
2982
2990
|
out.push({ where, problem: "not-a-string-column", detail: 'expected {kind:"string", dictionary, codes}' });
|
|
2983
2991
|
return;
|
|
2984
2992
|
}
|
|
2993
|
+
for (let d = 0; d < col.dictionary.length; d++) {
|
|
2994
|
+
if (typeof col.dictionary[d] !== "string") {
|
|
2995
|
+
out.push({
|
|
2996
|
+
where,
|
|
2997
|
+
problem: "not-a-string-column",
|
|
2998
|
+
detail: `dictionary entry ${d} is not a string`
|
|
2999
|
+
});
|
|
3000
|
+
return;
|
|
3001
|
+
}
|
|
3002
|
+
}
|
|
2985
3003
|
if (col.codes.length !== rows) {
|
|
2986
3004
|
const detached = col.codes.length === 0 && col.codes.buffer.byteLength === 0;
|
|
2987
3005
|
out.push({
|
|
@@ -3230,10 +3248,12 @@ function detachColumnarBuffers(snapshot) {
|
|
|
3230
3248
|
return detached;
|
|
3231
3249
|
}
|
|
3232
3250
|
|
|
3233
|
-
// src/
|
|
3234
|
-
function
|
|
3235
|
-
return new URL("./worker/entry.js", import.meta.url);
|
|
3251
|
+
// src/workerAsset.ts
|
|
3252
|
+
function createDefaultWorker() {
|
|
3253
|
+
return new Worker(new URL("./worker/entry.js", import.meta.url), { type: "module" });
|
|
3236
3254
|
}
|
|
3255
|
+
|
|
3256
|
+
// src/worker/lane.ts
|
|
3237
3257
|
function transportFromWorker(worker) {
|
|
3238
3258
|
return {
|
|
3239
3259
|
post: (envelope, transfers) => worker.postMessage(envelope, [...transfers]),
|
|
@@ -3275,10 +3295,7 @@ var WorkerLane = class {
|
|
|
3275
3295
|
let transport = this.options.transport ?? null;
|
|
3276
3296
|
if (transport === null) {
|
|
3277
3297
|
const factory = this.options.factory;
|
|
3278
|
-
const worker = factory !== void 0 && "create" in factory ? factory.create() : new Worker(
|
|
3279
|
-
factory !== void 0 && "url" in factory ? factory.url : defaultWorkerUrl(),
|
|
3280
|
-
{ type: "module" }
|
|
3281
|
-
);
|
|
3298
|
+
const worker = factory !== void 0 && "create" in factory ? factory.create() : factory !== void 0 && "url" in factory ? new Worker(factory.url, { type: "module" }) : createDefaultWorker();
|
|
3282
3299
|
transport = transportFromWorker(worker);
|
|
3283
3300
|
}
|
|
3284
3301
|
transport.onReply((reply) => this.settle(reply));
|
|
@@ -5026,6 +5043,7 @@ var isNum = (v) => typeof v === "number" && Number.isFinite(v);
|
|
|
5026
5043
|
var isBool = (v) => typeof v === "boolean";
|
|
5027
5044
|
var isObj = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
5028
5045
|
var isStrArray = (v) => Array.isArray(v) && v.every(isStr);
|
|
5046
|
+
var isNumArray = (v) => Array.isArray(v) && v.every(isNum);
|
|
5029
5047
|
function validateBrush(v, at, problems) {
|
|
5030
5048
|
if (!isObj(v)) {
|
|
5031
5049
|
problems.push(`${at}: not an object`);
|
|
@@ -5044,18 +5062,43 @@ function validateBrush(v, at, problems) {
|
|
|
5044
5062
|
}
|
|
5045
5063
|
problems.push(`${at}: unknown brush kind`);
|
|
5046
5064
|
}
|
|
5047
|
-
function validateScale(v, at, problems) {
|
|
5065
|
+
function validateScale(v, at, valueKind, problems) {
|
|
5048
5066
|
if (!isObj(v)) {
|
|
5049
5067
|
problems.push(`${at}: not an object`);
|
|
5050
5068
|
return;
|
|
5051
5069
|
}
|
|
5052
|
-
|
|
5070
|
+
const isValueArray = valueKind === "string" ? isStrArray : isNumArray;
|
|
5071
|
+
const valueLabel = valueKind === "string" ? "string" : "finite number";
|
|
5072
|
+
if (v["kind"] === "sequential") {
|
|
5053
5073
|
if (!isStr(v["metric"])) problems.push(`${at}: metric must be a string`);
|
|
5054
|
-
if (!
|
|
5074
|
+
if (!isValueArray(v["range"]) || v["range"].length !== 2) {
|
|
5075
|
+
problems.push(`${at}: sequential range must be a [${valueLabel}, ${valueLabel}] tuple`);
|
|
5076
|
+
}
|
|
5077
|
+
if (v["domain"] !== void 0 && (!isNumArray(v["domain"]) || v["domain"].length !== 2)) {
|
|
5078
|
+
problems.push(`${at}: sequential domain must be a [min, max] finite-number tuple`);
|
|
5079
|
+
}
|
|
5080
|
+
return;
|
|
5081
|
+
}
|
|
5082
|
+
if (v["kind"] === "diverging") {
|
|
5083
|
+
if (!isStr(v["metric"])) problems.push(`${at}: metric must be a string`);
|
|
5084
|
+
if (!isValueArray(v["range"]) || v["range"].length !== 3) {
|
|
5085
|
+
problems.push(
|
|
5086
|
+
`${at}: diverging range must be a [${valueLabel}, ${valueLabel}, ${valueLabel}] tuple`
|
|
5087
|
+
);
|
|
5088
|
+
}
|
|
5089
|
+
if (!isNum(v["mid"])) {
|
|
5090
|
+
problems.push(`${at}: diverging mid must be a finite number`);
|
|
5091
|
+
}
|
|
5055
5092
|
return;
|
|
5056
5093
|
}
|
|
5057
5094
|
if (v["kind"] === "categorical") {
|
|
5058
5095
|
if (!isStr(v["by"])) problems.push(`${at}: categorical 'by' must be a field string`);
|
|
5096
|
+
if (v["domain"] !== void 0 && !isStrArray(v["domain"])) {
|
|
5097
|
+
problems.push(`${at}: categorical domain must be a string[]`);
|
|
5098
|
+
}
|
|
5099
|
+
if (v["palette"] !== void 0 && !isValueArray(v["palette"])) {
|
|
5100
|
+
problems.push(`${at}: categorical palette must be a ${valueLabel}[]`);
|
|
5101
|
+
}
|
|
5059
5102
|
return;
|
|
5060
5103
|
}
|
|
5061
5104
|
problems.push(`${at}: unknown scale kind`);
|
|
@@ -5180,10 +5223,10 @@ function validateViewState(raw) {
|
|
|
5180
5223
|
problems.push("styling: must be an object");
|
|
5181
5224
|
} else {
|
|
5182
5225
|
if (styling["nodeColor"] !== void 0) {
|
|
5183
|
-
validateScale(styling["nodeColor"], "styling.nodeColor", problems);
|
|
5226
|
+
validateScale(styling["nodeColor"], "styling.nodeColor", "string", problems);
|
|
5184
5227
|
}
|
|
5185
5228
|
if (styling["nodeSize"] !== void 0) {
|
|
5186
|
-
validateScale(styling["nodeSize"], "styling.nodeSize", problems);
|
|
5229
|
+
validateScale(styling["nodeSize"], "styling.nodeSize", "number", problems);
|
|
5187
5230
|
}
|
|
5188
5231
|
for (const flag of ["showLinks", "edgeArrows"]) {
|
|
5189
5232
|
if (styling[flag] !== void 0 && !isBool(styling[flag])) {
|
|
@@ -6339,6 +6382,9 @@ function pruneIds(ids, base) {
|
|
|
6339
6382
|
function createGraphInstance(opts) {
|
|
6340
6383
|
const engineFactory = opts.engine;
|
|
6341
6384
|
const fitViewOnFirstData = opts.fitViewOnFirstData ?? true;
|
|
6385
|
+
const fitViewOnSettle = opts.fitViewOnSettle ?? "follow";
|
|
6386
|
+
const fitViewMaxZoom = opts.fitViewMaxZoom === void 0 ? 1.5 : opts.fitViewMaxZoom;
|
|
6387
|
+
const clampFit = (o) => fitViewMaxZoom === null ? o : { ...o, maxZoom: fitViewMaxZoom };
|
|
6342
6388
|
const store = createStore(() => ({
|
|
6343
6389
|
status: "idle",
|
|
6344
6390
|
revisions: { source: null, model: 0, scope: 0, render: 0, appliedRender: null },
|
|
@@ -6507,7 +6553,7 @@ function createGraphInstance(opts) {
|
|
|
6507
6553
|
let linkColor;
|
|
6508
6554
|
let linkWidth;
|
|
6509
6555
|
let layout = "force";
|
|
6510
|
-
let simulation;
|
|
6556
|
+
let simulation = resolveSimulation(void 0);
|
|
6511
6557
|
let theme = resolveTheme(void 0);
|
|
6512
6558
|
let edgeArrows = false;
|
|
6513
6559
|
let showLinks = true;
|
|
@@ -8193,7 +8239,7 @@ function createGraphInstance(opts) {
|
|
|
8193
8239
|
simRestarted = true;
|
|
8194
8240
|
}
|
|
8195
8241
|
}
|
|
8196
|
-
eng
|
|
8242
|
+
commitToEngine(eng, commit);
|
|
8197
8243
|
revisions.appliedRender = eng.appliedRevision();
|
|
8198
8244
|
const facade = session !== null ? session.edgePicking : null;
|
|
8199
8245
|
if (facade !== null) {
|
|
@@ -9078,12 +9124,41 @@ function createGraphInstance(opts) {
|
|
|
9078
9124
|
if (idx !== void 0) applyEmphasis(eng, idx);
|
|
9079
9125
|
}
|
|
9080
9126
|
}
|
|
9127
|
+
const SETTLE_FOLLOW_INTERVAL_FRAMES = 55;
|
|
9128
|
+
const SETTLE_FOLLOW_CAP_FRAMES = 480;
|
|
9129
|
+
let settleFollowFrames = null;
|
|
9130
|
+
let settleFollowContainer = null;
|
|
9131
|
+
const settleFollowCancelListener = () => {
|
|
9132
|
+
cancelSettleFollow();
|
|
9133
|
+
};
|
|
9134
|
+
function cancelSettleFollow() {
|
|
9135
|
+
if (settleFollowContainer !== null) {
|
|
9136
|
+
settleFollowContainer.removeEventListener?.("pointerdown", settleFollowCancelListener);
|
|
9137
|
+
settleFollowContainer.removeEventListener?.("wheel", settleFollowCancelListener);
|
|
9138
|
+
settleFollowContainer = null;
|
|
9139
|
+
}
|
|
9140
|
+
settleFollowFrames = null;
|
|
9141
|
+
}
|
|
9142
|
+
function armSettleFollow(s) {
|
|
9143
|
+
if (fitViewOnSettle === false || layout !== "force") return;
|
|
9144
|
+
settleFollowFrames = 0;
|
|
9145
|
+
if (typeof s.container.addEventListener === "function") {
|
|
9146
|
+
settleFollowContainer = s.container;
|
|
9147
|
+
s.container.addEventListener("pointerdown", settleFollowCancelListener);
|
|
9148
|
+
s.container.addEventListener("wheel", settleFollowCancelListener);
|
|
9149
|
+
}
|
|
9150
|
+
}
|
|
9151
|
+
function settleFollowFit(eng, durationMs) {
|
|
9152
|
+
if (effectiveReducedMotion()) eng.fitView(clampFit({ durationMs: 0 }));
|
|
9153
|
+
else eng.fitView(clampFit({ durationMs }));
|
|
9154
|
+
}
|
|
9081
9155
|
function maybeFitView(eng) {
|
|
9082
9156
|
if (!fitViewOnFirstData || session === null || session.fitDone) return;
|
|
9083
9157
|
if (accepted === null) return;
|
|
9084
9158
|
session.fitDone = true;
|
|
9085
|
-
if (effectiveReducedMotion()) eng.fitView({ durationMs: 0 });
|
|
9086
|
-
else eng.fitView();
|
|
9159
|
+
if (effectiveReducedMotion()) eng.fitView(clampFit({ durationMs: 0 }));
|
|
9160
|
+
else eng.fitView(clampFit({}));
|
|
9161
|
+
armSettleFollow(session);
|
|
9087
9162
|
}
|
|
9088
9163
|
function nodeIndexBase() {
|
|
9089
9164
|
return accepted === null ? EMPTY_INDEX2 : accepted.nodeIndex;
|
|
@@ -11498,10 +11573,13 @@ function createGraphInstance(opts) {
|
|
|
11498
11573
|
{
|
|
11499
11574
|
const c = {};
|
|
11500
11575
|
let any = false;
|
|
11501
|
-
if (update.simulation !== void 0
|
|
11502
|
-
|
|
11503
|
-
|
|
11504
|
-
|
|
11576
|
+
if (update.simulation !== void 0) {
|
|
11577
|
+
const nextSimulation = resolveSimulation(update.simulation);
|
|
11578
|
+
if (!Object.is(nextSimulation, simulation)) {
|
|
11579
|
+
simulation = nextSimulation;
|
|
11580
|
+
c.simulation = nextSimulation;
|
|
11581
|
+
any = true;
|
|
11582
|
+
}
|
|
11505
11583
|
}
|
|
11506
11584
|
if (update.theme !== void 0) {
|
|
11507
11585
|
const nextTheme = resolveTheme(update.theme);
|
|
@@ -12082,6 +12160,14 @@ function createGraphInstance(opts) {
|
|
|
12082
12160
|
onFrame(timeMs) {
|
|
12083
12161
|
if (!active()) return;
|
|
12084
12162
|
frameCadence += 1;
|
|
12163
|
+
if (settleFollowFrames !== null && fitViewOnSettle === "follow") {
|
|
12164
|
+
settleFollowFrames += 1;
|
|
12165
|
+
if (settleFollowFrames > SETTLE_FOLLOW_CAP_FRAMES) {
|
|
12166
|
+
cancelSettleFollow();
|
|
12167
|
+
} else if (settleFollowFrames % SETTLE_FOLLOW_INTERVAL_FRAMES === 0) {
|
|
12168
|
+
settleFollowFit(s.engine, 650);
|
|
12169
|
+
}
|
|
12170
|
+
}
|
|
12085
12171
|
pressureSampler.noteFrame(timeMs, !store.getState().simulationRunning);
|
|
12086
12172
|
flushCrossfilterNotify();
|
|
12087
12173
|
if (timeMs - lastPerfSampleAt >= PERF_SAMPLE_THROTTLE_MS) {
|
|
@@ -12128,6 +12214,10 @@ function createGraphInstance(opts) {
|
|
|
12128
12214
|
},
|
|
12129
12215
|
onSimulationEnd() {
|
|
12130
12216
|
if (!active()) return;
|
|
12217
|
+
if (settleFollowFrames !== null) {
|
|
12218
|
+
settleFollowFit(s.engine, 800);
|
|
12219
|
+
cancelSettleFollow();
|
|
12220
|
+
}
|
|
12131
12221
|
if (accretionPinIds !== null) {
|
|
12132
12222
|
accretionPinIds = null;
|
|
12133
12223
|
pushPinsToEngine(s.engine, store.getState().pins);
|
|
@@ -12361,6 +12451,7 @@ function createGraphInstance(opts) {
|
|
|
12361
12451
|
s.alive = false;
|
|
12362
12452
|
session = null;
|
|
12363
12453
|
mountPromise = null;
|
|
12454
|
+
cancelSettleFollow();
|
|
12364
12455
|
cancelRerankTimer();
|
|
12365
12456
|
flushCrossfilterNotify();
|
|
12366
12457
|
if (quiescenceTimer !== null) {
|
|
@@ -12489,33 +12580,34 @@ function createGraphInstance(opts) {
|
|
|
12489
12580
|
return void 0;
|
|
12490
12581
|
}
|
|
12491
12582
|
if (!isScaleValue(value)) return void 0;
|
|
12492
|
-
|
|
12583
|
+
const scale = value;
|
|
12584
|
+
if (scale.kind === "sequential") {
|
|
12493
12585
|
return {
|
|
12494
12586
|
kind: "sequential",
|
|
12495
|
-
metric:
|
|
12496
|
-
range:
|
|
12587
|
+
metric: scale.metric,
|
|
12588
|
+
range: scale.range,
|
|
12497
12589
|
// The numeric-array domain form is data; a DomainPolicy is app
|
|
12498
12590
|
// behavior config and stays with the app.
|
|
12499
|
-
...Array.isArray(
|
|
12591
|
+
...Array.isArray(scale.domain) ? { domain: scale.domain } : {}
|
|
12500
12592
|
};
|
|
12501
12593
|
}
|
|
12502
|
-
if (
|
|
12594
|
+
if (scale.kind === "diverging") {
|
|
12503
12595
|
return {
|
|
12504
12596
|
kind: "diverging",
|
|
12505
|
-
metric:
|
|
12506
|
-
range:
|
|
12507
|
-
mid:
|
|
12597
|
+
metric: scale.metric,
|
|
12598
|
+
range: scale.range,
|
|
12599
|
+
mid: scale.mid
|
|
12508
12600
|
};
|
|
12509
12601
|
}
|
|
12510
|
-
if (typeof
|
|
12602
|
+
if (typeof scale.by !== "string") {
|
|
12511
12603
|
warnViewStateDrop(channel, "a function-`by` categorical scale does not serialize");
|
|
12512
12604
|
return void 0;
|
|
12513
12605
|
}
|
|
12514
12606
|
return {
|
|
12515
12607
|
kind: "categorical",
|
|
12516
|
-
by:
|
|
12517
|
-
...
|
|
12518
|
-
...
|
|
12608
|
+
by: scale.by,
|
|
12609
|
+
...scale.palette !== void 0 ? { palette: scale.palette } : {},
|
|
12610
|
+
...scale.domain !== void 0 ? { domain: scale.domain } : {}
|
|
12519
12611
|
};
|
|
12520
12612
|
}
|
|
12521
12613
|
function serializableThemeOf() {
|
|
@@ -12835,7 +12927,7 @@ function createGraphInstance(opts) {
|
|
|
12835
12927
|
...prevState.revisions,
|
|
12836
12928
|
render: prevState.revisions.render + 1
|
|
12837
12929
|
};
|
|
12838
|
-
eng
|
|
12930
|
+
commitToEngine(eng, {
|
|
12839
12931
|
revision: nextRevisions.render,
|
|
12840
12932
|
structure: {
|
|
12841
12933
|
pointCount: scene.count,
|
|
@@ -12843,6 +12935,7 @@ function createGraphInstance(opts) {
|
|
|
12843
12935
|
links: scene.links
|
|
12844
12936
|
}
|
|
12845
12937
|
});
|
|
12938
|
+
nextRevisions.appliedRender = eng.appliedRevision();
|
|
12846
12939
|
eng.pause();
|
|
12847
12940
|
const patch = { revisions: nextRevisions };
|
|
12848
12941
|
if (prevState.simulationRunning) patch.simulationRunning = false;
|
|
@@ -12851,6 +12944,7 @@ function createGraphInstance(opts) {
|
|
|
12851
12944
|
}
|
|
12852
12945
|
}
|
|
12853
12946
|
if (state.camera !== null) {
|
|
12947
|
+
cancelSettleFollow();
|
|
12854
12948
|
const eng = engineIfReady();
|
|
12855
12949
|
if (eng !== null) {
|
|
12856
12950
|
if (effectiveReducedMotion()) eng.setViewport(state.camera, { durationMs: 0 });
|
|
@@ -13170,6 +13264,7 @@ function createGraphInstance(opts) {
|
|
|
13170
13264
|
});
|
|
13171
13265
|
}
|
|
13172
13266
|
function focusNode(id, opts2) {
|
|
13267
|
+
cancelSettleFollow();
|
|
13173
13268
|
const eng = engineIfReady();
|
|
13174
13269
|
if (eng === null || scene === null) return EMPTY_IDS;
|
|
13175
13270
|
const idx = scene.indexById.get(id);
|
|
@@ -13250,6 +13345,7 @@ function createGraphInstance(opts) {
|
|
|
13250
13345
|
return bytes;
|
|
13251
13346
|
}
|
|
13252
13347
|
function cameraZoom(factor) {
|
|
13348
|
+
cancelSettleFollow();
|
|
13253
13349
|
const eng = engineIfReady();
|
|
13254
13350
|
if (eng === null) return;
|
|
13255
13351
|
if (effectiveReducedMotion()) eng.zoom(factor, 0);
|
|
@@ -13303,10 +13399,11 @@ function createGraphInstance(opts) {
|
|
|
13303
13399
|
destroy,
|
|
13304
13400
|
on,
|
|
13305
13401
|
fitView: () => {
|
|
13402
|
+
cancelSettleFollow();
|
|
13306
13403
|
const eng = engineIfReady();
|
|
13307
13404
|
if (eng === null) return;
|
|
13308
|
-
if (effectiveReducedMotion()) eng.fitView({ durationMs: 0 });
|
|
13309
|
-
else eng.fitView();
|
|
13405
|
+
if (effectiveReducedMotion()) eng.fitView(clampFit({ durationMs: 0 }));
|
|
13406
|
+
else eng.fitView(clampFit({}));
|
|
13310
13407
|
},
|
|
13311
13408
|
zoomIn: () => {
|
|
13312
13409
|
cameraZoom(ZOOM_STEP);
|
|
@@ -13315,6 +13412,7 @@ function createGraphInstance(opts) {
|
|
|
13315
13412
|
cameraZoom(1 / ZOOM_STEP);
|
|
13316
13413
|
},
|
|
13317
13414
|
setViewport: (v) => {
|
|
13415
|
+
cancelSettleFollow();
|
|
13318
13416
|
const eng = engineIfReady();
|
|
13319
13417
|
if (eng === null) return;
|
|
13320
13418
|
if (effectiveReducedMotion()) eng.setViewport(v, { durationMs: 0 });
|