@mindexec/cli 0.2.483 → 0.2.494
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/codex-runtime.js +6 -2
- package/electron/main.cjs +56 -32
- package/electron/preload.cjs +178 -0
- package/electron/source-smoke.mjs +14 -1
- package/electron/windows-package-smoke.mjs +16 -0
- package/package.json +11 -10
- package/remote-fast/osx-arm64/mindexec-remote-fast.dll +0 -0
- package/remote-fast/osx-x64/mindexec-remote-fast.dll +0 -0
- package/remote-fast/win-x64/mindexec-remote-fast.dll +0 -0
- package/wwwroot/_content/MindExecution.Shared/css/app.css +1 -1
- package/wwwroot/_content/MindExecution.Shared/js/canvas-chat-task-switch.js +122 -0
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-css3d-manager.js +161 -16
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-interactions.js +68 -2
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-lod-plan-worker.js +44 -8
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-logic-workers.js +823 -111
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-native-core-bridge.js +399 -0
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-node-search-worker.js +53 -10
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-visibility-worker.js +71 -11
- package/wwwroot/_content/MindExecution.Shared/native-core/mindexec-core-simd.js +18 -0
- package/wwwroot/_content/MindExecution.Shared/native-core/mindexec-core-simd.wasm +0 -0
- package/wwwroot/_content/MindExecution.Shared/native-core/mindexec-core.js +18 -0
- package/wwwroot/_content/MindExecution.Shared/native-core/mindexec-core.wasm +0 -0
- package/wwwroot/_content/MindExecution.Shared/native-core/mindexec-native-core-adapter.js +566 -0
- package/wwwroot/_content/MindExecution.Shared/native-core/mindexec-native-core-worker.js +89 -0
- package/wwwroot/_content/MindExecution.Shared/native-core/native-core-manifest.json +59 -0
- package/wwwroot/_framework/BenchmarkUtils.ytz7pn9azy.dll +0 -0
- package/wwwroot/_framework/Edgar.9yqq548b45.dll +0 -0
- package/wwwroot/_framework/GraphPlanarityTesting.lgk3vd0bh9.dll +0 -0
- package/wwwroot/_framework/Microsoft.Win32.SystemEvents.f8qhom7uq5.dll +0 -0
- package/wwwroot/_framework/{MindExecution.Core.zs4n1f9hjc.dll → MindExecution.Core.tre9kny2uo.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Kernel.l9idvg7mp7.dll → MindExecution.Kernel.lvfnhwdksf.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Plugins.Admin.l37qx5d8zi.dll → MindExecution.Plugins.Admin.k2vbe4lt64.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Plugins.Business.d7b282yazn.dll → MindExecution.Plugins.Business.u7i3r45xp5.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Plugins.Concept.iw98n0qz5k.dll → MindExecution.Plugins.Concept.7eoasvev17.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Plugins.Directory.cqgn6pa8di.dll → MindExecution.Plugins.Directory.rhh13u0z6c.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Plugins.PlanMaster.j8xoa8nl57.dll → MindExecution.Plugins.PlanMaster.xzl2x2cqk4.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Plugins.YouTube.zvpzk7om4z.dll → MindExecution.Plugins.YouTube.945tf0zc9m.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Shared.ovot7q606x.dll → MindExecution.Shared.e0w408b0ti.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Web.bzuaz35jv0.dll → MindExecution.Web.vc6ux7xjcw.dll} +0 -0
- package/wwwroot/_framework/RangeTree.iw8h1x5u2y.dll +0 -0
- package/wwwroot/_framework/System.Collections.Concurrent.jzwteolu29.dll +0 -0
- package/wwwroot/_framework/System.Collections.NonGeneric.uqtvwssxuq.dll +0 -0
- package/wwwroot/_framework/System.Collections.Specialized.85qtrfslgb.dll +0 -0
- package/wwwroot/_framework/System.Collections.xmhu72xgrp.dll +0 -0
- package/wwwroot/_framework/System.ComponentModel.Primitives.excbd02v5j.dll +0 -0
- package/wwwroot/_framework/System.ComponentModel.TypeConverter.ek2jcwibb9.dll +0 -0
- package/wwwroot/_framework/System.ComponentModel.wfe9zz2icv.dll +0 -0
- package/wwwroot/_framework/System.Console.5j283so6ps.dll +0 -0
- package/wwwroot/_framework/System.Drawing.Common.xzizafq144.dll +0 -0
- package/wwwroot/_framework/System.Private.CoreLib.7ouudb2fbl.dll +0 -0
- package/wwwroot/_framework/{System.Text.RegularExpressions.cvkox11l6l.dll → System.Text.RegularExpressions.b0vqxbob08.dll} +0 -0
- package/wwwroot/_framework/System.Threading.Tasks.Parallel.9tqazg1b0u.dll +0 -0
- package/wwwroot/_framework/System.Threading.Tasks.zl4yo3otxa.dll +0 -0
- package/wwwroot/_framework/YamlDotNet.dtey92juka.dll +0 -0
- package/wwwroot/_framework/blazor.boot.json +63 -45
- package/wwwroot/_framework/{dotnet.native.60hhmnxyoo.wasm → dotnet.native.58bvs6q392.wasm} +0 -0
- package/wwwroot/_framework/netstandard.he3m3p1s9q.dll +0 -0
- package/wwwroot/index.html +2 -1
- package/wwwroot/service-worker-assets.js +128 -56
- package/wwwroot/service-worker.js +1 -1
- package/wwwroot/_framework/System.Collections.3iuoxbe8my.dll +0 -0
- package/wwwroot/_framework/System.Collections.Concurrent.vow3rm1dku.dll +0 -0
- package/wwwroot/_framework/System.Collections.NonGeneric.npjkaz40oc.dll +0 -0
- package/wwwroot/_framework/System.Collections.Specialized.ugkjbs6p02.dll +0 -0
- package/wwwroot/_framework/System.ComponentModel.Primitives.end4v0xe2c.dll +0 -0
- package/wwwroot/_framework/System.ComponentModel.TypeConverter.tgtp5sm4iv.dll +0 -0
- package/wwwroot/_framework/System.ComponentModel.wupoltkk1t.dll +0 -0
- package/wwwroot/_framework/System.Console.9dik0wogo2.dll +0 -0
- package/wwwroot/_framework/System.Private.CoreLib.7s8wte759y.dll +0 -0
- package/wwwroot/_framework/netstandard.b50t77veor.dll +0 -0
|
@@ -1,12 +1,45 @@
|
|
|
1
1
|
(function () {
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
const LOGIC_WORKER_BRIDGE_BUILD_ID = '
|
|
5
|
-
const
|
|
4
|
+
const LOGIC_WORKER_BRIDGE_BUILD_ID = '20260830-native-primary-v013';
|
|
5
|
+
const LEGACY_VISIBILITY_WORKER_URL = `_content/MindExecution.Shared/js/mind-map-visibility-worker.js?v=${LOGIC_WORKER_BRIDGE_BUILD_ID}`;
|
|
6
|
+
const NATIVE_CORE_MODE = String(window.MindMapNativeCoreBridge?.getMode?.() || 'off');
|
|
7
|
+
const NATIVE_PRIMARY_ENABLED = NATIVE_CORE_MODE === 'native';
|
|
8
|
+
const VISIBILITY_WORKER_URL = window.MindMapNativeCoreBridge?.getPrimaryWorkerUrl?.(LEGACY_VISIBILITY_WORKER_URL)
|
|
9
|
+
|| LEGACY_VISIBILITY_WORKER_URL;
|
|
6
10
|
const LOD_PLAN_WORKER_URL = `_content/MindExecution.Shared/js/mind-map-lod-plan-worker.js?v=${LOGIC_WORKER_BRIDGE_BUILD_ID}`;
|
|
7
11
|
const NODE_SEARCH_WORKER_URL = `_content/MindExecution.Shared/js/mind-map-node-search-worker.js?v=${LOGIC_WORKER_BRIDGE_BUILD_ID}`;
|
|
8
12
|
const CTRL_WHEEL_SCROLL_ACTIVE_WINDOW_MS = 140;
|
|
9
13
|
const SEARCH_METADATA_TEXT_LIMIT = 8192;
|
|
14
|
+
const WORKER_TIMEOUT_OVERRIDES = window.__MIND_EXECUTION_WORKER_TIMEOUTS || {};
|
|
15
|
+
const NATIVE_READY_TIMEOUT_MS = normalizeTimeout(WORKER_TIMEOUT_OVERRIDES.nativeReadyMs, 10000, 10, 60000);
|
|
16
|
+
const NATIVE_QUERY_TIMEOUT_MS = normalizeTimeout(WORKER_TIMEOUT_OVERRIDES.nativeQueryMs, 1200, 10, 10000);
|
|
17
|
+
const LEGACY_FALLBACK_READY_TIMEOUT_MS = normalizeTimeout(
|
|
18
|
+
WORKER_TIMEOUT_OVERRIDES.legacyFallbackReadyMs,
|
|
19
|
+
NATIVE_READY_TIMEOUT_MS,
|
|
20
|
+
10,
|
|
21
|
+
60000
|
|
22
|
+
);
|
|
23
|
+
const LEGACY_FALLBACK_QUERY_TIMEOUT_MS = normalizeTimeout(
|
|
24
|
+
WORKER_TIMEOUT_OVERRIDES.legacyFallbackQueryMs,
|
|
25
|
+
NATIVE_QUERY_TIMEOUT_MS,
|
|
26
|
+
10,
|
|
27
|
+
10000
|
|
28
|
+
);
|
|
29
|
+
const SEARCH_QUERY_TIMEOUT_MS = normalizeTimeout(WORKER_TIMEOUT_OVERRIDES.searchQueryMs, 5000, 10, 30000);
|
|
30
|
+
let nextEngineGeneration = 1;
|
|
31
|
+
|
|
32
|
+
function normalizeTimeout(value, fallback, minimum, maximum) {
|
|
33
|
+
const number = Number(value);
|
|
34
|
+
if (!Number.isFinite(number)) return fallback;
|
|
35
|
+
return Math.max(minimum, Math.min(maximum, Math.floor(number)));
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function monotonicNow() {
|
|
39
|
+
return (typeof performance !== 'undefined' && typeof performance.now === 'function')
|
|
40
|
+
? performance.now()
|
|
41
|
+
: Date.now();
|
|
42
|
+
}
|
|
10
43
|
|
|
11
44
|
function getNodeContentType(model) {
|
|
12
45
|
return String(model?.contentType ?? model?.ContentType ?? '').trim().toLowerCase();
|
|
@@ -170,6 +203,10 @@
|
|
|
170
203
|
constructor(module) {
|
|
171
204
|
this.module = module || null;
|
|
172
205
|
this.boardId = normalizeBoardId(module?.activeBoardId || window.mindMap?.activeBoardId || '');
|
|
206
|
+
this._engineGeneration = nextEngineGeneration++;
|
|
207
|
+
this._boardEpoch = 0;
|
|
208
|
+
this._boardRevision = 0;
|
|
209
|
+
this._searchRevision = 0;
|
|
173
210
|
|
|
174
211
|
this._visibilityWorker = null;
|
|
175
212
|
this._lodPlanWorker = null;
|
|
@@ -178,6 +215,16 @@
|
|
|
178
215
|
this._lodPlanReady = false;
|
|
179
216
|
this._searchReady = false;
|
|
180
217
|
this._visibilityDisabled = false;
|
|
218
|
+
this._visibilityBackend = NATIVE_PRIMARY_ENABLED ? 'native' : 'legacy';
|
|
219
|
+
this._nativeFallbackActive = false;
|
|
220
|
+
this._disposed = false;
|
|
221
|
+
this._visibilityReadyTimer = null;
|
|
222
|
+
this._visibilityQueryTimer = null;
|
|
223
|
+
this._hitTestQueryTimer = null;
|
|
224
|
+
this._visibilityQueryStartedAt = 0;
|
|
225
|
+
this._hitTestQueryStartedAt = 0;
|
|
226
|
+
this._visibilityNodeIds = new Set();
|
|
227
|
+
this._visibilityNodeSnapshots = new Map();
|
|
181
228
|
this._lodPlanDisabled = false;
|
|
182
229
|
this._searchDisabled = false;
|
|
183
230
|
this._latestVisibilityRequestSeq = 0;
|
|
@@ -188,21 +235,31 @@
|
|
|
188
235
|
this._pendingLodPlanKey = '';
|
|
189
236
|
this._visibilityQueryPending = false;
|
|
190
237
|
this._inFlightVisibilityRequestSeq = 0;
|
|
238
|
+
this._visibilityQueryStartedAt = 0;
|
|
191
239
|
this._deferredVisibilityPayload = null;
|
|
192
240
|
this._hitTestQueryPending = false;
|
|
241
|
+
this._inFlightHitTestRequestSeq = 0;
|
|
242
|
+
this._hitTestQueryStartedAt = 0;
|
|
243
|
+
this._inFlightHitTestPayload = null;
|
|
193
244
|
this._deferredHitTestPayload = null;
|
|
194
245
|
this._pendingSelectionResolvers = new Map();
|
|
195
246
|
this._pendingSearchResolvers = new Map();
|
|
247
|
+
this._nativeCoreShadow = window.MindMapNativeCoreBridge?.createShadow?.() || null;
|
|
196
248
|
|
|
197
249
|
this._createWorkers();
|
|
198
250
|
}
|
|
199
251
|
|
|
200
252
|
_createWorkers() {
|
|
201
|
-
|
|
202
|
-
'
|
|
203
|
-
VISIBILITY_WORKER_URL
|
|
204
|
-
|
|
205
|
-
|
|
253
|
+
if (!this._startVisibilityWorker(
|
|
254
|
+
NATIVE_PRIMARY_ENABLED ? 'native' : 'legacy',
|
|
255
|
+
VISIBILITY_WORKER_URL
|
|
256
|
+
)) {
|
|
257
|
+
if (NATIVE_PRIMARY_ENABLED) {
|
|
258
|
+
this._activateLegacyVisibilityFallback('native visibility worker creation failed');
|
|
259
|
+
} else {
|
|
260
|
+
this._visibilityDisabled = true;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
206
263
|
this._lodPlanWorker = this._createWorker(
|
|
207
264
|
'lod-plan',
|
|
208
265
|
LOD_PLAN_WORKER_URL,
|
|
@@ -213,12 +270,54 @@
|
|
|
213
270
|
NODE_SEARCH_WORKER_URL,
|
|
214
271
|
(data) => this._handleSearchMessage(data)
|
|
215
272
|
);
|
|
273
|
+
this._lodPlanDisabled = !this._lodPlanWorker;
|
|
274
|
+
this._searchDisabled = !this._searchWorker;
|
|
216
275
|
}
|
|
217
276
|
|
|
218
|
-
|
|
277
|
+
_startVisibilityWorker(backend, url) {
|
|
278
|
+
this._visibilityBackend = backend;
|
|
279
|
+
this._visibilityReady = false;
|
|
280
|
+
this._visibilityDisabled = false;
|
|
281
|
+
const worker = this._createWorker(
|
|
282
|
+
'visibility',
|
|
283
|
+
url,
|
|
284
|
+
(data) => this._handleVisibilityMessage(data),
|
|
285
|
+
{ backend }
|
|
286
|
+
);
|
|
287
|
+
this._visibilityWorker = worker;
|
|
288
|
+
if (!worker) {
|
|
289
|
+
return false;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
const fallbackLegacy = backend === 'legacy' && this._nativeFallbackActive === true;
|
|
293
|
+
if (backend === 'native' || fallbackLegacy) {
|
|
294
|
+
const timeoutMs = backend === 'native'
|
|
295
|
+
? NATIVE_READY_TIMEOUT_MS
|
|
296
|
+
: LEGACY_FALLBACK_READY_TIMEOUT_MS;
|
|
297
|
+
this._clearVisibilityReadyTimer();
|
|
298
|
+
this._visibilityReadyTimer = setTimeout(() => {
|
|
299
|
+
if (this._disposed !== true &&
|
|
300
|
+
this._visibilityWorker === worker &&
|
|
301
|
+
this._visibilityBackend === backend &&
|
|
302
|
+
this._visibilityReady !== true) {
|
|
303
|
+
if (backend === 'native') {
|
|
304
|
+
this._activateLegacyVisibilityFallback(`native READY timeout after ${timeoutMs}ms`);
|
|
305
|
+
} else if (this._nativeFallbackActive === true) {
|
|
306
|
+
this._disableVisibilityWorker(`legacy fallback READY timeout after ${timeoutMs}ms`);
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
}, timeoutMs);
|
|
310
|
+
}
|
|
311
|
+
return true;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
_createWorker(kind, url, onMessage, options = {}) {
|
|
219
315
|
try {
|
|
220
316
|
const worker = new Worker(url);
|
|
221
317
|
worker.onmessage = (event) => {
|
|
318
|
+
if (this._disposed === true || (kind === 'visibility' && worker !== this._visibilityWorker)) {
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
222
321
|
const data = event?.data || null;
|
|
223
322
|
if (!data || typeof data !== 'object') {
|
|
224
323
|
return;
|
|
@@ -226,7 +325,14 @@
|
|
|
226
325
|
|
|
227
326
|
if (data.type === 'READY') {
|
|
228
327
|
if (kind === 'visibility') {
|
|
328
|
+
this._clearVisibilityReadyTimer();
|
|
229
329
|
this._visibilityReady = true;
|
|
330
|
+
this._visibilityDisabled = false;
|
|
331
|
+
if (options.backend === 'native') {
|
|
332
|
+
window.MindMapNativeCoreBridge?.notifyPrimaryReady?.(data);
|
|
333
|
+
} else if (this._nativeFallbackActive === true) {
|
|
334
|
+
window.MindMapNativeCoreBridge?.notifyFallbackReady?.();
|
|
335
|
+
}
|
|
230
336
|
} else if (kind === 'lod-plan') {
|
|
231
337
|
this._lodPlanReady = true;
|
|
232
338
|
} else if (kind === 'node-search') {
|
|
@@ -238,17 +344,16 @@
|
|
|
238
344
|
onMessage(data);
|
|
239
345
|
};
|
|
240
346
|
worker.onerror = (error) => {
|
|
347
|
+
if (this._disposed === true || (kind === 'visibility' && worker !== this._visibilityWorker)) {
|
|
348
|
+
return;
|
|
349
|
+
}
|
|
241
350
|
console.warn(`[MindMapLogicWorkerBridge] ${kind} worker disabled after error.`, error);
|
|
242
351
|
if (kind === 'visibility') {
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
this.
|
|
248
|
-
this._clearHitTestCache(this.module);
|
|
249
|
-
this._hitTestQueryPending = false;
|
|
250
|
-
this._deferredHitTestPayload = null;
|
|
251
|
-
this._resolvePendingSelectionQueries(null);
|
|
352
|
+
if (options.backend === 'native') {
|
|
353
|
+
this._activateLegacyVisibilityFallback(String(error?.message || 'native visibility worker error'));
|
|
354
|
+
return;
|
|
355
|
+
}
|
|
356
|
+
this._disableVisibilityWorker(String(error?.message || 'legacy visibility worker error'));
|
|
252
357
|
} else if (kind === 'lod-plan') {
|
|
253
358
|
this._lodPlanDisabled = true;
|
|
254
359
|
this._lodPlanReady = false;
|
|
@@ -257,30 +362,31 @@
|
|
|
257
362
|
this._searchReady = false;
|
|
258
363
|
this._resolvePendingSearches(null);
|
|
259
364
|
}
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
365
|
+
if (kind !== 'visibility') {
|
|
366
|
+
try {
|
|
367
|
+
worker.terminate();
|
|
368
|
+
} catch { }
|
|
369
|
+
}
|
|
263
370
|
};
|
|
264
371
|
return worker;
|
|
265
372
|
} catch (error) {
|
|
266
373
|
console.warn(`[MindMapLogicWorkerBridge] Failed to create ${kind} worker.`, error);
|
|
267
|
-
if (kind === '
|
|
268
|
-
this._visibilityDisabled = true;
|
|
269
|
-
} else if (kind === 'lod-plan') {
|
|
374
|
+
if (kind === 'lod-plan') {
|
|
270
375
|
this._lodPlanDisabled = true;
|
|
271
|
-
} else {
|
|
376
|
+
} else if (kind === 'node-search') {
|
|
272
377
|
this._searchDisabled = true;
|
|
273
378
|
}
|
|
274
379
|
return null;
|
|
275
380
|
}
|
|
276
381
|
}
|
|
277
382
|
|
|
278
|
-
_post(worker, payload) {
|
|
383
|
+
_post(worker, payload, boardRevision = this._boardRevision) {
|
|
279
384
|
if (!worker || !payload) {
|
|
280
385
|
return false;
|
|
281
386
|
}
|
|
282
387
|
|
|
283
388
|
try {
|
|
389
|
+
this._stampOwnerPayload(payload, boardRevision);
|
|
284
390
|
worker.postMessage(payload);
|
|
285
391
|
return true;
|
|
286
392
|
} catch (error) {
|
|
@@ -289,28 +395,285 @@
|
|
|
289
395
|
}
|
|
290
396
|
}
|
|
291
397
|
|
|
398
|
+
_postVisibility(payload) {
|
|
399
|
+
this._stampOwnerPayload(payload);
|
|
400
|
+
const posted = this._post(this._visibilityWorker, payload);
|
|
401
|
+
this._nativeCoreShadow?.post?.(payload);
|
|
402
|
+
if (!posted) {
|
|
403
|
+
if (this._visibilityBackend === 'native') {
|
|
404
|
+
this._activateLegacyVisibilityFallback(`native ${String(payload?.type || 'message')} post failed`);
|
|
405
|
+
} else if (this._visibilityBackend === 'legacy' && this._nativeFallbackActive === true) {
|
|
406
|
+
this._disableVisibilityWorker(`legacy fallback ${String(payload?.type || 'message')} post failed`);
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
return posted;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
_postSearch(payload) {
|
|
413
|
+
return this._post(this._searchWorker, payload, this._searchRevision);
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
_clearVisibilityReadyTimer() {
|
|
417
|
+
if (this._visibilityReadyTimer !== null) {
|
|
418
|
+
clearTimeout(this._visibilityReadyTimer);
|
|
419
|
+
this._visibilityReadyTimer = null;
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
_clearVisibilityQueryTimer() {
|
|
424
|
+
if (this._visibilityQueryTimer !== null) {
|
|
425
|
+
clearTimeout(this._visibilityQueryTimer);
|
|
426
|
+
this._visibilityQueryTimer = null;
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
_clearHitTestQueryTimer() {
|
|
431
|
+
if (this._hitTestQueryTimer !== null) {
|
|
432
|
+
clearTimeout(this._hitTestQueryTimer);
|
|
433
|
+
this._hitTestQueryTimer = null;
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
_armVisibilityQueryTimer(seq) {
|
|
438
|
+
this._clearVisibilityQueryTimer();
|
|
439
|
+
const backend = this._visibilityBackend;
|
|
440
|
+
const fallbackLegacy = backend === 'legacy' && this._nativeFallbackActive === true;
|
|
441
|
+
if (backend !== 'native' && !fallbackLegacy) return;
|
|
442
|
+
const timeoutMs = backend === 'native'
|
|
443
|
+
? NATIVE_QUERY_TIMEOUT_MS
|
|
444
|
+
: LEGACY_FALLBACK_QUERY_TIMEOUT_MS;
|
|
445
|
+
const expectedSeq = Math.max(0, Math.floor(Number(seq || 0)));
|
|
446
|
+
this._visibilityQueryTimer = setTimeout(() => {
|
|
447
|
+
if (this._disposed !== true &&
|
|
448
|
+
this._visibilityBackend === backend &&
|
|
449
|
+
this._visibilityQueryPending === true &&
|
|
450
|
+
Number(this._inFlightVisibilityRequestSeq || 0) === expectedSeq) {
|
|
451
|
+
if (backend === 'native') {
|
|
452
|
+
this._activateLegacyVisibilityFallback(
|
|
453
|
+
`native VISIBILITY_QUERY ${expectedSeq} timeout after ${timeoutMs}ms`
|
|
454
|
+
);
|
|
455
|
+
} else if (this._nativeFallbackActive === true) {
|
|
456
|
+
this._disableVisibilityWorker(
|
|
457
|
+
`legacy fallback VISIBILITY_QUERY ${expectedSeq} timeout after ${timeoutMs}ms`
|
|
458
|
+
);
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
}, timeoutMs);
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
_armHitTestQueryTimer(seq) {
|
|
465
|
+
this._clearHitTestQueryTimer();
|
|
466
|
+
const backend = this._visibilityBackend;
|
|
467
|
+
const fallbackLegacy = backend === 'legacy' && this._nativeFallbackActive === true;
|
|
468
|
+
if (backend !== 'native' && !fallbackLegacy) return;
|
|
469
|
+
const timeoutMs = backend === 'native'
|
|
470
|
+
? NATIVE_QUERY_TIMEOUT_MS
|
|
471
|
+
: LEGACY_FALLBACK_QUERY_TIMEOUT_MS;
|
|
472
|
+
const expectedSeq = Math.max(0, Math.floor(Number(seq || 0)));
|
|
473
|
+
this._hitTestQueryTimer = setTimeout(() => {
|
|
474
|
+
if (this._disposed !== true &&
|
|
475
|
+
this._visibilityBackend === backend &&
|
|
476
|
+
this._hitTestQueryPending === true &&
|
|
477
|
+
Number(this._inFlightHitTestRequestSeq || 0) === expectedSeq) {
|
|
478
|
+
if (backend === 'native') {
|
|
479
|
+
this._activateLegacyVisibilityFallback(
|
|
480
|
+
`native HIT_TEST_QUERY ${expectedSeq} timeout after ${timeoutMs}ms`
|
|
481
|
+
);
|
|
482
|
+
} else if (this._nativeFallbackActive === true) {
|
|
483
|
+
this._disableVisibilityWorker(
|
|
484
|
+
`legacy fallback HIT_TEST_QUERY ${expectedSeq} timeout after ${timeoutMs}ms`
|
|
485
|
+
);
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
}, timeoutMs);
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
_armSelectionQueryTimer(seq, pending) {
|
|
492
|
+
const backend = this._visibilityBackend;
|
|
493
|
+
const fallbackLegacy = backend === 'legacy' && this._nativeFallbackActive === true;
|
|
494
|
+
if (!pending || (backend !== 'native' && !fallbackLegacy)) return;
|
|
495
|
+
const timeoutMs = backend === 'native'
|
|
496
|
+
? NATIVE_QUERY_TIMEOUT_MS
|
|
497
|
+
: LEGACY_FALLBACK_QUERY_TIMEOUT_MS;
|
|
498
|
+
pending.timer = setTimeout(() => {
|
|
499
|
+
if (!this._pendingSelectionResolvers.has(seq) ||
|
|
500
|
+
this._disposed === true ||
|
|
501
|
+
this._visibilityBackend !== backend) {
|
|
502
|
+
return;
|
|
503
|
+
}
|
|
504
|
+
if (backend === 'native') {
|
|
505
|
+
this._activateLegacyVisibilityFallback(
|
|
506
|
+
`native SELECTION_QUERY ${seq} timeout after ${timeoutMs}ms`
|
|
507
|
+
);
|
|
508
|
+
} else if (this._nativeFallbackActive === true) {
|
|
509
|
+
this._disableVisibilityWorker(
|
|
510
|
+
`legacy fallback SELECTION_QUERY ${seq} timeout after ${timeoutMs}ms`
|
|
511
|
+
);
|
|
512
|
+
}
|
|
513
|
+
}, timeoutMs);
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
_wakeVisibilityFallback(reason) {
|
|
517
|
+
const module = this.module;
|
|
518
|
+
if (!module) return;
|
|
519
|
+
module._forceUpdateFrames = Math.max(Number(module._forceUpdateFrames || 0), 1);
|
|
520
|
+
module.requestAnimationWake?.(String(reason || 'visibility-fallback'));
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
_resetPendingVisibilityQueries() {
|
|
524
|
+
this._clearVisibilityQueryTimer();
|
|
525
|
+
this._clearHitTestQueryTimer();
|
|
526
|
+
this._visibilityQueryPending = false;
|
|
527
|
+
this._inFlightVisibilityRequestSeq = 0;
|
|
528
|
+
this._deferredVisibilityPayload = null;
|
|
529
|
+
this._hitTestQueryPending = false;
|
|
530
|
+
this._inFlightHitTestRequestSeq = 0;
|
|
531
|
+
this._inFlightHitTestPayload = null;
|
|
532
|
+
this._deferredHitTestPayload = null;
|
|
533
|
+
this._clearHitTestCache(this.module);
|
|
534
|
+
this._resolvePendingSelectionQueries(null);
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
_disableVisibilityWorker(reason) {
|
|
538
|
+
const worker = this._visibilityWorker;
|
|
539
|
+
this._visibilityWorker = null;
|
|
540
|
+
this._visibilityDisabled = true;
|
|
541
|
+
this._visibilityReady = false;
|
|
542
|
+
this._clearVisibilityReadyTimer();
|
|
543
|
+
this._resetPendingVisibilityQueries();
|
|
544
|
+
if (this.module) {
|
|
545
|
+
this.module._visibilityWorkerPrimed = false;
|
|
546
|
+
this.module._preserveVisibleSetThisFrame = false;
|
|
547
|
+
}
|
|
548
|
+
if (this._nativeFallbackActive === true) {
|
|
549
|
+
window.MindMapNativeCoreBridge?.notifyFallbackUnavailable?.(reason);
|
|
550
|
+
this._wakeVisibilityFallback('native-primary-main-thread-fallback');
|
|
551
|
+
}
|
|
552
|
+
try { worker?.terminate?.(); } catch { }
|
|
553
|
+
window.MindCanvasTrace?.emit?.('logicWorker.visibilityDisabled', {
|
|
554
|
+
backend: this._visibilityBackend,
|
|
555
|
+
reason: String(reason || 'visibility worker disabled')
|
|
556
|
+
});
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
_snapshotCurrentSpatialNodes(module = this.module) {
|
|
560
|
+
const nodes = Array.from(this._visibilityNodeSnapshots.values());
|
|
561
|
+
this._visibilityNodeIds = new Set(nodes.map((node) => node.id));
|
|
562
|
+
return nodes;
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
_synchronizeVisibilityWorker(worker, reason) {
|
|
566
|
+
const module = this.module;
|
|
567
|
+
const boardId = this._resolveBoardId(module);
|
|
568
|
+
if (!worker || !module || !boardId) return false;
|
|
569
|
+
return this._post(worker, {
|
|
570
|
+
type: 'REBUILD_BOARD',
|
|
571
|
+
boardId,
|
|
572
|
+
reason: String(reason || 'visibility-worker-synchronize'),
|
|
573
|
+
cellSize: Math.max(1, Number(module.GRID_CELL_SIZE || 500)),
|
|
574
|
+
nodes: this._snapshotCurrentSpatialNodes(module)
|
|
575
|
+
});
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
_activateLegacyVisibilityFallback(reason) {
|
|
579
|
+
if (this._disposed === true || this._visibilityBackend !== 'native') {
|
|
580
|
+
return false;
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
const message = String(reason || 'native visibility fallback');
|
|
584
|
+
const nativeWorker = this._visibilityWorker;
|
|
585
|
+
this._visibilityWorker = null;
|
|
586
|
+
this._visibilityReady = false;
|
|
587
|
+
this._visibilityDisabled = false;
|
|
588
|
+
this._nativeFallbackActive = true;
|
|
589
|
+
this._clearVisibilityReadyTimer();
|
|
590
|
+
this._resetPendingVisibilityQueries();
|
|
591
|
+
if (this.module) {
|
|
592
|
+
this.module._visibilityWorkerPrimed = false;
|
|
593
|
+
this.module._preserveVisibleSetThisFrame = false;
|
|
594
|
+
}
|
|
595
|
+
this._wakeVisibilityFallback('native-primary-fallback');
|
|
596
|
+
try { nativeWorker?.terminate?.(); } catch { }
|
|
597
|
+
|
|
598
|
+
window.MindMapNativeCoreBridge?.notifyPrimaryFallback?.(message);
|
|
599
|
+
console.warn('[MindMapLogicWorkerBridge] Native visibility fell back to the JS worker.', message);
|
|
600
|
+
|
|
601
|
+
if (!this._startVisibilityWorker('legacy', LEGACY_VISIBILITY_WORKER_URL)) {
|
|
602
|
+
this._disableVisibilityWorker('legacy visibility fallback creation failed');
|
|
603
|
+
return false;
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
if (!this._synchronizeVisibilityWorker(this._visibilityWorker, 'native-primary-fallback')) {
|
|
607
|
+
this._disableVisibilityWorker('legacy visibility fallback synchronization failed');
|
|
608
|
+
return false;
|
|
609
|
+
}
|
|
610
|
+
return true;
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
_handleVisibilityProtocolFailure(reason) {
|
|
614
|
+
if (this._visibilityBackend === 'native') {
|
|
615
|
+
this._activateLegacyVisibilityFallback(reason);
|
|
616
|
+
} else {
|
|
617
|
+
this._disableVisibilityWorker(reason);
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
_stampOwnerPayload(payload, boardRevision = this._boardRevision) {
|
|
622
|
+
if (!payload || typeof payload !== 'object') {
|
|
623
|
+
return payload;
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
payload.engineGeneration = Number(this._engineGeneration || 0);
|
|
627
|
+
payload.boardEpoch = Number(this._boardEpoch || 0);
|
|
628
|
+
payload.boardRevision = Number(boardRevision || 0);
|
|
629
|
+
return payload;
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
_isCurrentWorkerOwner(data, boardId = this._resolveBoardId(this.module), boardRevision = this._boardRevision) {
|
|
633
|
+
const owner = this._classifyWorkerOwner(data, boardId, boardRevision);
|
|
634
|
+
return owner.identityMatches && owner.revisionMatches;
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
_classifyWorkerOwner(data, boardId = this._resolveBoardId(this.module), boardRevision = this._boardRevision) {
|
|
638
|
+
const identityMatches = normalizeBoardId(data?.boardId) === normalizeBoardId(boardId) &&
|
|
639
|
+
Number(data?.engineGeneration || 0) === Number(this._engineGeneration || 0) &&
|
|
640
|
+
Number(data?.boardEpoch || 0) === Number(this._boardEpoch || 0);
|
|
641
|
+
const revisionMatches = Number(data?.boardRevision || 0) === Number(boardRevision || 0);
|
|
642
|
+
return { identityMatches, revisionMatches };
|
|
643
|
+
}
|
|
644
|
+
|
|
292
645
|
_stampVisibilityPayloadForPost(payload) {
|
|
293
646
|
if (!payload || String(payload.type || '') !== 'VISIBILITY_QUERY') {
|
|
294
647
|
return payload;
|
|
295
648
|
}
|
|
296
649
|
|
|
297
|
-
payload.mainLastAppliedSeq =
|
|
298
|
-
0,
|
|
299
|
-
|
|
300
|
-
);
|
|
650
|
+
payload.mainLastAppliedSeq = this.module?._visibilityWorkerPrimed === true
|
|
651
|
+
? Math.max(0, Math.floor(Number(this.module?._workerVisibilitySeq || 0)))
|
|
652
|
+
: 0;
|
|
301
653
|
return payload;
|
|
302
654
|
}
|
|
303
655
|
|
|
304
|
-
_resolveBoardId(module = this.module, fallbackBoardId =
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
)
|
|
311
|
-
|
|
312
|
-
|
|
656
|
+
_resolveBoardId(module = this.module, fallbackBoardId = undefined) {
|
|
657
|
+
let sourceValue;
|
|
658
|
+
let ownerSourcePresent = false;
|
|
659
|
+
if (fallbackBoardId !== undefined) {
|
|
660
|
+
sourceValue = fallbackBoardId;
|
|
661
|
+
ownerSourcePresent = true;
|
|
662
|
+
} else if (module && 'activeBoardId' in Object(module)) {
|
|
663
|
+
sourceValue = module.activeBoardId;
|
|
664
|
+
ownerSourcePresent = true;
|
|
665
|
+
} else if (typeof module?.getCurrentBoardId === 'function') {
|
|
666
|
+
sourceValue = module.getCurrentBoardId();
|
|
667
|
+
ownerSourcePresent = true;
|
|
668
|
+
} else if (window.mindMap && 'activeBoardId' in Object(window.mindMap)) {
|
|
669
|
+
sourceValue = window.mindMap.activeBoardId;
|
|
670
|
+
ownerSourcePresent = true;
|
|
671
|
+
} else {
|
|
672
|
+
sourceValue = this.boardId;
|
|
313
673
|
}
|
|
674
|
+
|
|
675
|
+
const candidate = normalizeBoardId(sourceValue);
|
|
676
|
+
if (ownerSourcePresent || candidate) this.boardId = candidate;
|
|
314
677
|
return candidate;
|
|
315
678
|
}
|
|
316
679
|
|
|
@@ -330,15 +693,156 @@
|
|
|
330
693
|
module._workerHitTestProfile = null;
|
|
331
694
|
}
|
|
332
695
|
|
|
696
|
+
_validateWorkerNodeIds(source, required = true) {
|
|
697
|
+
if (!Array.isArray(source)) {
|
|
698
|
+
return required ? { valid: false, ids: [] } : { valid: true, ids: null };
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
const ids = [];
|
|
702
|
+
const seen = new Set();
|
|
703
|
+
for (let index = 0; index < source.length; index++) {
|
|
704
|
+
const nodeId = String(source[index] || '').trim();
|
|
705
|
+
if (!nodeId || seen.has(nodeId) || !this._visibilityNodeIds.has(nodeId)) {
|
|
706
|
+
return { valid: false, ids: [] };
|
|
707
|
+
}
|
|
708
|
+
seen.add(nodeId);
|
|
709
|
+
ids.push(nodeId);
|
|
710
|
+
}
|
|
711
|
+
return { valid: true, ids };
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
_validateWorkerRect(source) {
|
|
715
|
+
if (!source || typeof source !== 'object') return false;
|
|
716
|
+
const left = Number(source.left);
|
|
717
|
+
const right = Number(source.right);
|
|
718
|
+
const bottom = Number(source.bottom);
|
|
719
|
+
const top = Number(source.top);
|
|
720
|
+
return Number.isFinite(left) && Number.isFinite(right) &&
|
|
721
|
+
Number.isFinite(bottom) && Number.isFinite(top) &&
|
|
722
|
+
right >= left && top >= bottom;
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
_validateVisibilityResult(data) {
|
|
726
|
+
if (String(data?.type || '') !== 'VISIBILITY_RESULT') {
|
|
727
|
+
return { valid: false, reason: 'unexpected visibility result type' };
|
|
728
|
+
}
|
|
729
|
+
const visibleCount = Number(data.visibleCount);
|
|
730
|
+
if (!Number.isInteger(visibleCount) || visibleCount < 0 || visibleCount > this._visibilityNodeIds.size) {
|
|
731
|
+
return { valid: false, reason: 'invalid visibleCount' };
|
|
732
|
+
}
|
|
733
|
+
if (typeof data.visibilityChanged !== 'boolean' ||
|
|
734
|
+
typeof data.fullResVisibilityReconcilePending !== 'boolean' ||
|
|
735
|
+
!this._validateWorkerRect(data.viewportRect) ||
|
|
736
|
+
Number(data.lastVisibilityNodeCount) !== this._visibilityNodeIds.size) {
|
|
737
|
+
return { valid: false, reason: 'invalid visibility state fields' };
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
const entered = this._validateWorkerNodeIds(data.enteredIds, true);
|
|
741
|
+
const exited = this._validateWorkerNodeIds(data.exitedIds, true);
|
|
742
|
+
const visible = this._validateWorkerNodeIds(data.visibleIds, false);
|
|
743
|
+
const priority = this._validateWorkerNodeIds(data.priorityIds, false);
|
|
744
|
+
if (!entered.valid || !exited.valid || !visible.valid || !priority.valid) {
|
|
745
|
+
return { valid: false, reason: 'invalid or unknown visibility node id' };
|
|
746
|
+
}
|
|
747
|
+
const exitedSet = new Set(exited.ids);
|
|
748
|
+
if (entered.ids.some((nodeId) => exitedSet.has(nodeId))) {
|
|
749
|
+
return { valid: false, reason: 'visibility enter and exit overlap' };
|
|
750
|
+
}
|
|
751
|
+
if (data.visibilityChanged !== (entered.ids.length > 0 || exited.ids.length > 0)) {
|
|
752
|
+
return { valid: false, reason: 'visibilityChanged does not match diff' };
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
const lastAppliedSeq = Math.max(0, Math.floor(Number(this.module?._workerVisibilitySeq || 0)));
|
|
756
|
+
const resultSeq = Math.max(0, Math.floor(Number(data.seq || 0)));
|
|
757
|
+
const hasExactDiffBase = this.module?._visibilityWorkerPrimed === true &&
|
|
758
|
+
lastAppliedSeq > 0 && resultSeq === lastAppliedSeq + 1;
|
|
759
|
+
if (!hasExactDiffBase && visible.ids === null) {
|
|
760
|
+
return { valid: false, reason: 'full visibility result is required without an exact diff base' };
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
let expectedVisibleIds = visible.ids !== null ? new Set(visible.ids) : new Set();
|
|
764
|
+
if (hasExactDiffBase) {
|
|
765
|
+
const previousVisibleIds = new Set();
|
|
766
|
+
this.module?._visibleIds?.forEach?.((nodeId) => {
|
|
767
|
+
const normalizedId = String(nodeId || '').trim();
|
|
768
|
+
if (this._visibilityNodeIds.has(normalizedId)) previousVisibleIds.add(normalizedId);
|
|
769
|
+
});
|
|
770
|
+
for (let index = 0; index < entered.ids.length; index++) {
|
|
771
|
+
if (previousVisibleIds.has(entered.ids[index])) {
|
|
772
|
+
return { valid: false, reason: 'entered visibility id was already visible' };
|
|
773
|
+
}
|
|
774
|
+
}
|
|
775
|
+
for (let index = 0; index < exited.ids.length; index++) {
|
|
776
|
+
if (!previousVisibleIds.has(exited.ids[index])) {
|
|
777
|
+
return { valid: false, reason: 'exited visibility id was not visible' };
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
for (let index = 0; index < exited.ids.length; index++) previousVisibleIds.delete(exited.ids[index]);
|
|
781
|
+
for (let index = 0; index < entered.ids.length; index++) previousVisibleIds.add(entered.ids[index]);
|
|
782
|
+
if (visible.ids !== null &&
|
|
783
|
+
(previousVisibleIds.size !== expectedVisibleIds.size ||
|
|
784
|
+
Array.from(previousVisibleIds).some((nodeId) => !expectedVisibleIds.has(nodeId)))) {
|
|
785
|
+
return { valid: false, reason: 'full visibility set does not match diff' };
|
|
786
|
+
}
|
|
787
|
+
expectedVisibleIds = previousVisibleIds;
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
if (expectedVisibleIds.size !== visibleCount) {
|
|
791
|
+
return { valid: false, reason: 'visibleCount does not match visible set' };
|
|
792
|
+
}
|
|
793
|
+
if (priority.ids !== null) {
|
|
794
|
+
if (priority.ids.length !== visibleCount ||
|
|
795
|
+
priority.ids.some((nodeId) => !expectedVisibleIds.has(nodeId))) {
|
|
796
|
+
return { valid: false, reason: 'priorityIds do not match visible set' };
|
|
797
|
+
}
|
|
798
|
+
}
|
|
799
|
+
return { valid: true, reason: '' };
|
|
800
|
+
}
|
|
801
|
+
|
|
802
|
+
_validateHitTestResult(data, payload) {
|
|
803
|
+
const candidates = this._validateWorkerNodeIds(data?.candidateIds, true);
|
|
804
|
+
if (String(data?.type || '') !== 'HIT_TEST_RESULT' || !candidates.valid || !payload) return false;
|
|
805
|
+
return String(data.rangeKey || '') === `${payload.cellX}:${payload.cellY}:${payload.cellRadius}` &&
|
|
806
|
+
Number(data.cellX) === Number(payload.cellX) &&
|
|
807
|
+
Number(data.cellY) === Number(payload.cellY) &&
|
|
808
|
+
Number(data.cellRadius) === Number(payload.cellRadius);
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
_validateSelectionResult(data, payload) {
|
|
812
|
+
const selected = this._validateWorkerNodeIds(data?.selectedIds, true);
|
|
813
|
+
if (String(data?.type || '') !== 'SELECTION_QUERY_RESULT' || !selected.valid || !payload) return false;
|
|
814
|
+
const expected = payload.selectionRect;
|
|
815
|
+
const actual = data.selectionRect;
|
|
816
|
+
if (!this._validateWorkerRect(actual) || !expected || typeof expected !== 'object') return false;
|
|
817
|
+
const expectedLeft = Number(expected.left);
|
|
818
|
+
const expectedRight = Number(expected.right);
|
|
819
|
+
const expectedBottom = Number(expected.bottom);
|
|
820
|
+
const expectedTop = Number(expected.top);
|
|
821
|
+
if (!Number.isFinite(expectedLeft) || !Number.isFinite(expectedRight) ||
|
|
822
|
+
!Number.isFinite(expectedBottom) || !Number.isFinite(expectedTop)) return false;
|
|
823
|
+
const epsilon = 0.000001;
|
|
824
|
+
return Math.abs(Number(actual.left) - Math.min(expectedLeft, expectedRight)) <= epsilon &&
|
|
825
|
+
Math.abs(Number(actual.right) - Math.max(expectedLeft, expectedRight)) <= epsilon &&
|
|
826
|
+
Math.abs(Number(actual.bottom) - Math.min(expectedBottom, expectedTop)) <= epsilon &&
|
|
827
|
+
Math.abs(Number(actual.top) - Math.max(expectedBottom, expectedTop)) <= epsilon;
|
|
828
|
+
}
|
|
829
|
+
|
|
333
830
|
_handleVisibilityMessage(data) {
|
|
334
|
-
|
|
831
|
+
const messageType = String(data?.type || '');
|
|
832
|
+
if (messageType === 'NATIVE_CORE_INIT_ERROR' || messageType === 'NATIVE_CORE_RUNTIME_ERROR') {
|
|
833
|
+
this._handleVisibilityProtocolFailure(String(data?.message || messageType));
|
|
834
|
+
return;
|
|
835
|
+
}
|
|
836
|
+
this._nativeCoreShadow?.observePrimaryResult?.(data);
|
|
837
|
+
if (messageType === 'HIT_TEST_RESULT') {
|
|
335
838
|
this._handleHitTestMessage(data);
|
|
336
839
|
return;
|
|
337
840
|
}
|
|
338
|
-
if (
|
|
841
|
+
if (messageType === 'SELECTION_QUERY_RESULT') {
|
|
339
842
|
this._handleSelectionQueryMessage(data);
|
|
340
843
|
return;
|
|
341
844
|
}
|
|
845
|
+
if (messageType !== 'VISIBILITY_RESULT') return;
|
|
342
846
|
|
|
343
847
|
const module = this.module;
|
|
344
848
|
const boardId = this._resolveBoardId(module);
|
|
@@ -346,42 +850,142 @@
|
|
|
346
850
|
return;
|
|
347
851
|
}
|
|
348
852
|
|
|
349
|
-
if (normalizeBoardId(data.boardId) !== boardId) {
|
|
350
|
-
return;
|
|
351
|
-
}
|
|
352
|
-
|
|
353
853
|
const resultSeq = Math.max(0, Math.floor(Number(data.seq || 0)));
|
|
354
854
|
const inFlightSeq = Math.max(0, Math.floor(Number(this._inFlightVisibilityRequestSeq || 0)));
|
|
355
855
|
if (resultSeq <= 0 || resultSeq !== inFlightSeq) {
|
|
356
856
|
return;
|
|
357
857
|
}
|
|
858
|
+
const roundTripMs = this._visibilityQueryStartedAt > 0
|
|
859
|
+
? Math.max(0, monotonicNow() - this._visibilityQueryStartedAt)
|
|
860
|
+
: 0;
|
|
861
|
+
|
|
862
|
+
const owner = this._classifyWorkerOwner(data, boardId);
|
|
863
|
+
if (data?.stale === true || !owner.identityMatches || !owner.revisionMatches) {
|
|
864
|
+
this._clearVisibilityQueryTimer();
|
|
865
|
+
this._visibilityQueryPending = false;
|
|
866
|
+
this._inFlightVisibilityRequestSeq = 0;
|
|
867
|
+
this._visibilityQueryStartedAt = 0;
|
|
868
|
+
module._visibilityWorkerPrimed = false;
|
|
869
|
+
module._preserveVisibleSetThisFrame = false;
|
|
870
|
+
if (!owner.identityMatches) {
|
|
871
|
+
if (this._visibilityBackend === 'native' || this._nativeFallbackActive === true) {
|
|
872
|
+
this._handleVisibilityProtocolFailure('visibility result owner identity mismatch');
|
|
873
|
+
} else {
|
|
874
|
+
this._flushDeferredVisibilityRequest();
|
|
875
|
+
}
|
|
876
|
+
return;
|
|
877
|
+
}
|
|
878
|
+
if ((this._visibilityBackend === 'native' || this._nativeFallbackActive === true) &&
|
|
879
|
+
data?.stale === true && owner.revisionMatches) {
|
|
880
|
+
this._handleVisibilityProtocolFailure(
|
|
881
|
+
this._visibilityBackend === 'native'
|
|
882
|
+
? 'native rejected a current visibility owner'
|
|
883
|
+
: 'legacy fallback rejected a current visibility owner'
|
|
884
|
+
);
|
|
885
|
+
return;
|
|
886
|
+
}
|
|
887
|
+
this._flushDeferredVisibilityRequest();
|
|
888
|
+
return;
|
|
889
|
+
}
|
|
358
890
|
|
|
359
|
-
|
|
891
|
+
const validation = this._validateVisibilityResult(data);
|
|
892
|
+
if (!validation.valid) {
|
|
893
|
+
this._clearVisibilityQueryTimer();
|
|
894
|
+
this._visibilityQueryPending = false;
|
|
895
|
+
this._inFlightVisibilityRequestSeq = 0;
|
|
896
|
+
this._visibilityQueryStartedAt = 0;
|
|
897
|
+
module._visibilityWorkerPrimed = false;
|
|
898
|
+
module._preserveVisibleSetThisFrame = false;
|
|
899
|
+
this._handleVisibilityProtocolFailure(validation.reason);
|
|
900
|
+
return;
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
this._clearVisibilityQueryTimer();
|
|
904
|
+
try {
|
|
905
|
+
if (typeof module._applyWorkerVisibilityResult !== 'function') {
|
|
906
|
+
throw new Error('renderer visibility apply hook is missing');
|
|
907
|
+
}
|
|
908
|
+
module._applyWorkerVisibilityResult(data);
|
|
909
|
+
if (Math.max(0, Math.floor(Number(module._workerVisibilitySeq || 0))) !== resultSeq) {
|
|
910
|
+
throw new Error(`renderer did not acknowledge visibility seq ${resultSeq}`);
|
|
911
|
+
}
|
|
912
|
+
} catch (error) {
|
|
913
|
+
const message = `visibility result apply failed: ${String(error?.message || error || 'unknown error')}`;
|
|
914
|
+
window.MindCanvasTrace?.emit?.('logicWorker.visibilityApplyFailed', {
|
|
915
|
+
backend: this._visibilityBackend,
|
|
916
|
+
resultType: String(data?.type || ''),
|
|
917
|
+
seq: resultSeq,
|
|
918
|
+
reason: message
|
|
919
|
+
});
|
|
920
|
+
console.error('[MindMapLogicWorkerBridge] Visibility result apply failed.', error);
|
|
921
|
+
this._handleVisibilityProtocolFailure(message);
|
|
922
|
+
return;
|
|
923
|
+
}
|
|
924
|
+
if (this._visibilityBackend === 'native') {
|
|
925
|
+
window.MindMapNativeCoreBridge?.notifyPrimaryResultAccepted?.(data, roundTripMs);
|
|
926
|
+
}
|
|
360
927
|
this._visibilityQueryPending = false;
|
|
361
928
|
this._inFlightVisibilityRequestSeq = 0;
|
|
929
|
+
this._visibilityQueryStartedAt = 0;
|
|
362
930
|
this._flushDeferredVisibilityRequest();
|
|
363
931
|
}
|
|
364
932
|
|
|
365
933
|
_handleHitTestMessage(data) {
|
|
366
934
|
const module = this.module;
|
|
367
935
|
const boardId = this._resolveBoardId(module);
|
|
936
|
+
const seq = Number(data?.seq || 0);
|
|
937
|
+
if (seq !== Number(this._inFlightHitTestRequestSeq || 0)) {
|
|
938
|
+
return;
|
|
939
|
+
}
|
|
940
|
+
|
|
941
|
+
const inFlightPayload = this._inFlightHitTestPayload;
|
|
942
|
+
const roundTripMs = this._hitTestQueryStartedAt > 0
|
|
943
|
+
? Math.max(0, monotonicNow() - this._hitTestQueryStartedAt)
|
|
944
|
+
: 0;
|
|
945
|
+
this._clearHitTestQueryTimer();
|
|
368
946
|
this._hitTestQueryPending = false;
|
|
947
|
+
this._inFlightHitTestRequestSeq = 0;
|
|
948
|
+
this._hitTestQueryStartedAt = 0;
|
|
949
|
+
this._inFlightHitTestPayload = null;
|
|
369
950
|
|
|
370
951
|
if (!module || !boardId) {
|
|
371
952
|
this._flushDeferredHitTestRequest();
|
|
372
953
|
return;
|
|
373
954
|
}
|
|
374
955
|
|
|
375
|
-
|
|
956
|
+
const owner = this._classifyWorkerOwner(data, boardId);
|
|
957
|
+
if (data?.stale === true || !owner.identityMatches || !owner.revisionMatches) {
|
|
958
|
+
if (!owner.identityMatches) {
|
|
959
|
+
if (this._visibilityBackend === 'native' || this._nativeFallbackActive === true) {
|
|
960
|
+
this._handleVisibilityProtocolFailure('hit-test result owner identity mismatch');
|
|
961
|
+
} else {
|
|
962
|
+
this._flushDeferredHitTestRequest();
|
|
963
|
+
}
|
|
964
|
+
return;
|
|
965
|
+
}
|
|
966
|
+
if ((this._visibilityBackend === 'native' || this._nativeFallbackActive === true) &&
|
|
967
|
+
data?.stale === true && owner.revisionMatches) {
|
|
968
|
+
this._handleVisibilityProtocolFailure(
|
|
969
|
+
this._visibilityBackend === 'native'
|
|
970
|
+
? 'native rejected a current hit-test owner'
|
|
971
|
+
: 'legacy fallback rejected a current hit-test owner'
|
|
972
|
+
);
|
|
973
|
+
return;
|
|
974
|
+
}
|
|
376
975
|
this._flushDeferredHitTestRequest();
|
|
377
976
|
return;
|
|
378
977
|
}
|
|
379
978
|
|
|
380
|
-
if (
|
|
979
|
+
if (seq !== Number(this._latestHitTestRequestSeq || 0)) {
|
|
381
980
|
this._flushDeferredHitTestRequest();
|
|
382
981
|
return;
|
|
383
982
|
}
|
|
384
983
|
|
|
984
|
+
if (!this._validateHitTestResult(data, inFlightPayload)) {
|
|
985
|
+
this._handleVisibilityProtocolFailure('invalid hit-test result payload');
|
|
986
|
+
return;
|
|
987
|
+
}
|
|
988
|
+
|
|
385
989
|
module._workerHitTestRangeKey = String(data.rangeKey || '').trim();
|
|
386
990
|
module._workerHitTestBoardId = boardId;
|
|
387
991
|
module._workerHitTestCandidateIds = Array.isArray(data.candidateIds)
|
|
@@ -395,6 +999,9 @@
|
|
|
395
999
|
? performance.now()
|
|
396
1000
|
: Date.now();
|
|
397
1001
|
module._workerHitTestProfile = data.profile || null;
|
|
1002
|
+
if (this._visibilityBackend === 'native') {
|
|
1003
|
+
window.MindMapNativeCoreBridge?.notifyPrimaryResultAccepted?.(data, roundTripMs);
|
|
1004
|
+
}
|
|
398
1005
|
|
|
399
1006
|
this._flushDeferredHitTestRequest();
|
|
400
1007
|
}
|
|
@@ -402,29 +1009,59 @@
|
|
|
402
1009
|
_handleSelectionQueryMessage(data) {
|
|
403
1010
|
const boardId = this._resolveBoardId(this.module);
|
|
404
1011
|
const seq = Number(data.seq || 0);
|
|
405
|
-
const
|
|
406
|
-
if (
|
|
1012
|
+
const pending = this._pendingSelectionResolvers.get(seq) || null;
|
|
1013
|
+
if (pending) {
|
|
407
1014
|
this._pendingSelectionResolvers.delete(seq);
|
|
1015
|
+
if (pending.timer !== null) clearTimeout(pending.timer);
|
|
408
1016
|
}
|
|
409
1017
|
|
|
410
|
-
if (!
|
|
1018
|
+
if (!pending) {
|
|
411
1019
|
return;
|
|
412
1020
|
}
|
|
413
1021
|
|
|
414
|
-
if (seq
|
|
415
|
-
|
|
1022
|
+
if (seq !== Number(this._latestSelectionRequestSeq || 0)) {
|
|
1023
|
+
pending.resolve(null);
|
|
416
1024
|
return;
|
|
417
1025
|
}
|
|
418
1026
|
|
|
419
|
-
|
|
420
|
-
|
|
1027
|
+
const owner = this._classifyWorkerOwner(data, boardId);
|
|
1028
|
+
if (!owner.identityMatches) {
|
|
1029
|
+
pending.resolve(null);
|
|
1030
|
+
if (this._visibilityBackend === 'native' || this._nativeFallbackActive === true) {
|
|
1031
|
+
this._handleVisibilityProtocolFailure('selection result owner identity mismatch');
|
|
1032
|
+
}
|
|
1033
|
+
return;
|
|
1034
|
+
}
|
|
1035
|
+
|
|
1036
|
+
if (data?.stale === true || !owner.revisionMatches) {
|
|
1037
|
+
pending.resolve(null);
|
|
1038
|
+
if (data?.stale === true && owner.revisionMatches &&
|
|
1039
|
+
(this._visibilityBackend === 'native' || this._nativeFallbackActive === true)) {
|
|
1040
|
+
this._handleVisibilityProtocolFailure(
|
|
1041
|
+
this._visibilityBackend === 'native'
|
|
1042
|
+
? 'native rejected a current selection owner'
|
|
1043
|
+
: 'legacy fallback rejected a current selection owner'
|
|
1044
|
+
);
|
|
1045
|
+
}
|
|
1046
|
+
return;
|
|
1047
|
+
}
|
|
1048
|
+
|
|
1049
|
+
if (!this._validateSelectionResult(data, pending.payload)) {
|
|
1050
|
+
pending.resolve(null);
|
|
1051
|
+
this._handleVisibilityProtocolFailure('invalid selection result payload');
|
|
421
1052
|
return;
|
|
422
1053
|
}
|
|
423
1054
|
|
|
424
1055
|
const selectedIds = Array.isArray(data.selectedIds)
|
|
425
1056
|
? data.selectedIds.map((nodeId) => String(nodeId || '').trim()).filter(Boolean)
|
|
426
1057
|
: [];
|
|
427
|
-
|
|
1058
|
+
if (this._visibilityBackend === 'native') {
|
|
1059
|
+
const roundTripMs = pending.startedAt > 0
|
|
1060
|
+
? Math.max(0, monotonicNow() - pending.startedAt)
|
|
1061
|
+
: 0;
|
|
1062
|
+
window.MindMapNativeCoreBridge?.notifyPrimaryResultAccepted?.(data, roundTripMs);
|
|
1063
|
+
}
|
|
1064
|
+
pending.resolve(selectedIds);
|
|
428
1065
|
}
|
|
429
1066
|
|
|
430
1067
|
_handleLodPlanMessage(data) {
|
|
@@ -434,7 +1071,7 @@
|
|
|
434
1071
|
return;
|
|
435
1072
|
}
|
|
436
1073
|
|
|
437
|
-
if (
|
|
1074
|
+
if (!this._isCurrentWorkerOwner(data, boardId)) {
|
|
438
1075
|
return;
|
|
439
1076
|
}
|
|
440
1077
|
|
|
@@ -442,9 +1079,10 @@
|
|
|
442
1079
|
return;
|
|
443
1080
|
}
|
|
444
1081
|
|
|
445
|
-
if (String(data.key || '')
|
|
446
|
-
|
|
1082
|
+
if (String(data.key || '') !== this._pendingLodPlanKey) {
|
|
1083
|
+
return;
|
|
447
1084
|
}
|
|
1085
|
+
this._pendingLodPlanKey = '';
|
|
448
1086
|
|
|
449
1087
|
module.lodRenderer._applyWorkerLodPlanResult?.(data);
|
|
450
1088
|
}
|
|
@@ -453,52 +1091,68 @@
|
|
|
453
1091
|
const boardId = this._resolveBoardId(this.module);
|
|
454
1092
|
const normalizedBoardId = normalizeBoardId(data.boardId);
|
|
455
1093
|
const seq = Number(data.seq || 0);
|
|
456
|
-
const
|
|
457
|
-
if (
|
|
1094
|
+
const pending = this._pendingSearchResolvers.get(seq) || null;
|
|
1095
|
+
if (pending) {
|
|
458
1096
|
this._pendingSearchResolvers.delete(seq);
|
|
1097
|
+
if (pending.timer !== null) clearTimeout(pending.timer);
|
|
459
1098
|
}
|
|
460
1099
|
|
|
461
|
-
if (!
|
|
1100
|
+
if (!pending) {
|
|
462
1101
|
return;
|
|
463
1102
|
}
|
|
464
1103
|
|
|
465
|
-
if (
|
|
466
|
-
|
|
1104
|
+
if (String(data?.type || '') !== 'SEARCH_RESULT' ||
|
|
1105
|
+
data?.stale === true ||
|
|
1106
|
+
!boardId ||
|
|
1107
|
+
normalizedBoardId !== boardId ||
|
|
1108
|
+
!this._isCurrentWorkerOwner(data, boardId, this._searchRevision) ||
|
|
1109
|
+
!Array.isArray(data.hits)) {
|
|
1110
|
+
pending.resolve(null);
|
|
467
1111
|
return;
|
|
468
1112
|
}
|
|
469
1113
|
|
|
470
|
-
const hits =
|
|
471
|
-
|
|
1114
|
+
const hits = data.hits
|
|
1115
|
+
.map((hit) => ({
|
|
472
1116
|
nodeId: String(hit?.nodeId ?? hit?.id ?? '').trim(),
|
|
473
1117
|
score: Number(hit?.score || 0)
|
|
474
|
-
}))
|
|
475
|
-
|
|
476
|
-
|
|
1118
|
+
}))
|
|
1119
|
+
.filter((hit) => hit.nodeId && Number.isFinite(hit.score));
|
|
1120
|
+
if (hits.length !== data.hits.length ||
|
|
1121
|
+
hits.some((hit) => !this.module?.nodeObjectsById?.has?.(hit.nodeId))) {
|
|
1122
|
+
pending.resolve(null);
|
|
1123
|
+
return;
|
|
1124
|
+
}
|
|
1125
|
+
pending.resolve(hits);
|
|
477
1126
|
}
|
|
478
1127
|
|
|
479
1128
|
_resolvePendingSearches(hits) {
|
|
480
|
-
const
|
|
1129
|
+
const pendingQueries = Array.from(this._pendingSearchResolvers.values());
|
|
481
1130
|
this._pendingSearchResolvers.clear();
|
|
482
|
-
for (let i = 0; i <
|
|
1131
|
+
for (let i = 0; i < pendingQueries.length; i++) {
|
|
483
1132
|
try {
|
|
484
|
-
|
|
1133
|
+
if (pendingQueries[i].timer !== null) clearTimeout(pendingQueries[i].timer);
|
|
1134
|
+
pendingQueries[i].resolve(hits);
|
|
485
1135
|
} catch {
|
|
486
1136
|
}
|
|
487
1137
|
}
|
|
488
1138
|
}
|
|
489
1139
|
|
|
490
1140
|
_resolvePendingSelectionQueries(nodeIds) {
|
|
491
|
-
const
|
|
1141
|
+
const pendingQueries = Array.from(this._pendingSelectionResolvers.values());
|
|
492
1142
|
this._pendingSelectionResolvers.clear();
|
|
493
|
-
for (let i = 0; i <
|
|
1143
|
+
for (let i = 0; i < pendingQueries.length; i++) {
|
|
494
1144
|
try {
|
|
495
|
-
|
|
1145
|
+
if (pendingQueries[i].timer !== null) clearTimeout(pendingQueries[i].timer);
|
|
1146
|
+
pendingQueries[i].resolve(nodeIds);
|
|
496
1147
|
} catch {
|
|
497
1148
|
}
|
|
498
1149
|
}
|
|
499
1150
|
}
|
|
500
1151
|
|
|
501
1152
|
dispose() {
|
|
1153
|
+
this._disposed = true;
|
|
1154
|
+
this._clearVisibilityReadyTimer();
|
|
1155
|
+
this._resetPendingVisibilityQueries();
|
|
502
1156
|
try {
|
|
503
1157
|
this._visibilityWorker?.terminate?.();
|
|
504
1158
|
} catch { }
|
|
@@ -512,35 +1166,29 @@
|
|
|
512
1166
|
this._visibilityWorker = null;
|
|
513
1167
|
this._lodPlanWorker = null;
|
|
514
1168
|
this._searchWorker = null;
|
|
1169
|
+
this._nativeCoreShadow?.dispose?.();
|
|
1170
|
+
this._nativeCoreShadow = null;
|
|
515
1171
|
this._visibilityReady = false;
|
|
516
1172
|
this._lodPlanReady = false;
|
|
517
1173
|
this._searchReady = false;
|
|
518
|
-
this._visibilityQueryPending = false;
|
|
519
|
-
this._inFlightVisibilityRequestSeq = 0;
|
|
520
|
-
this._deferredVisibilityPayload = null;
|
|
521
|
-
this._hitTestQueryPending = false;
|
|
522
|
-
this._deferredHitTestPayload = null;
|
|
523
|
-
this._resolvePendingSelectionQueries(null);
|
|
524
|
-
this._clearHitTestCache(this.module);
|
|
525
1174
|
this._resolvePendingSearches(null);
|
|
1175
|
+
this._visibilityNodeIds.clear();
|
|
1176
|
+
this._visibilityNodeSnapshots.clear();
|
|
1177
|
+
if (NATIVE_PRIMARY_ENABLED) {
|
|
1178
|
+
window.MindMapNativeCoreBridge?.notifyPrimaryDisposed?.('logic-worker-dispose');
|
|
1179
|
+
}
|
|
526
1180
|
}
|
|
527
1181
|
|
|
528
1182
|
resetBoard(boardId, reason = 'reset-board') {
|
|
529
1183
|
const normalizedBoardId = this._resolveBoardId(this.module, boardId);
|
|
530
|
-
this.
|
|
531
|
-
this.
|
|
532
|
-
this.
|
|
533
|
-
this._latestLodPlanRequestSeq = 0;
|
|
534
|
-
this._latestSearchRequestSeq = 0;
|
|
1184
|
+
this._boardEpoch++;
|
|
1185
|
+
this._boardRevision = 0;
|
|
1186
|
+
this._searchRevision = 0;
|
|
535
1187
|
this._pendingLodPlanKey = '';
|
|
536
|
-
this.
|
|
537
|
-
this._inFlightVisibilityRequestSeq = 0;
|
|
538
|
-
this._deferredVisibilityPayload = null;
|
|
539
|
-
this._hitTestQueryPending = false;
|
|
540
|
-
this._deferredHitTestPayload = null;
|
|
541
|
-
this._resolvePendingSelectionQueries(null);
|
|
1188
|
+
this._resetPendingVisibilityQueries();
|
|
542
1189
|
this._resolvePendingSearches(null);
|
|
543
|
-
this.
|
|
1190
|
+
this._visibilityNodeIds.clear();
|
|
1191
|
+
this._visibilityNodeSnapshots.clear();
|
|
544
1192
|
|
|
545
1193
|
if (this.module) {
|
|
546
1194
|
this.module._visibilityWorkerPrimed = false;
|
|
@@ -552,9 +1200,9 @@
|
|
|
552
1200
|
reason,
|
|
553
1201
|
cellSize: Math.max(1, Number(this.module?.GRID_CELL_SIZE || 500))
|
|
554
1202
|
};
|
|
555
|
-
this.
|
|
1203
|
+
this._postVisibility(payload);
|
|
556
1204
|
this._post(this._lodPlanWorker, payload);
|
|
557
|
-
this.
|
|
1205
|
+
this._postSearch(payload);
|
|
558
1206
|
}
|
|
559
1207
|
|
|
560
1208
|
rebuildNodeTables(module = this.module, options = {}) {
|
|
@@ -577,6 +1225,10 @@
|
|
|
577
1225
|
searchNodes.push(searchSnapshot);
|
|
578
1226
|
}
|
|
579
1227
|
});
|
|
1228
|
+
this._boardRevision++;
|
|
1229
|
+
this._searchRevision++;
|
|
1230
|
+
this._visibilityNodeIds = new Set(nodes.map((node) => node.id));
|
|
1231
|
+
this._visibilityNodeSnapshots = new Map(nodes.map((node) => [node.id, node]));
|
|
580
1232
|
|
|
581
1233
|
const payload = {
|
|
582
1234
|
type: 'REBUILD_BOARD',
|
|
@@ -586,9 +1238,9 @@
|
|
|
586
1238
|
nodes
|
|
587
1239
|
};
|
|
588
1240
|
|
|
589
|
-
const postedVisibility = this.
|
|
1241
|
+
const postedVisibility = this._postVisibility(payload);
|
|
590
1242
|
const postedLodPlan = this._post(this._lodPlanWorker, payload);
|
|
591
|
-
const postedSearch = this.
|
|
1243
|
+
const postedSearch = this._postSearch({
|
|
592
1244
|
type: 'REBUILD_BOARD',
|
|
593
1245
|
boardId,
|
|
594
1246
|
reason: String(options.reason || 'rebuild-search-index'),
|
|
@@ -622,6 +1274,14 @@
|
|
|
622
1274
|
if (!snapshot && !searchSnapshot) {
|
|
623
1275
|
return false;
|
|
624
1276
|
}
|
|
1277
|
+
if (snapshot) {
|
|
1278
|
+
this._boardRevision++;
|
|
1279
|
+
this._visibilityNodeIds.add(snapshot.id);
|
|
1280
|
+
this._visibilityNodeSnapshots.set(snapshot.id, snapshot);
|
|
1281
|
+
}
|
|
1282
|
+
if (searchSnapshot) {
|
|
1283
|
+
this._searchRevision++;
|
|
1284
|
+
}
|
|
625
1285
|
|
|
626
1286
|
let postedVisibility = false;
|
|
627
1287
|
let postedLodPlan = false;
|
|
@@ -632,11 +1292,11 @@
|
|
|
632
1292
|
boardId,
|
|
633
1293
|
node: snapshot
|
|
634
1294
|
};
|
|
635
|
-
postedVisibility = this.
|
|
1295
|
+
postedVisibility = this._postVisibility(payload);
|
|
636
1296
|
postedLodPlan = this._post(this._lodPlanWorker, payload);
|
|
637
1297
|
}
|
|
638
1298
|
if (searchSnapshot) {
|
|
639
|
-
postedSearch = this.
|
|
1299
|
+
postedSearch = this._postSearch({
|
|
640
1300
|
type: 'UPSERT_NODE',
|
|
641
1301
|
boardId,
|
|
642
1302
|
node: searchSnapshot
|
|
@@ -654,6 +1314,10 @@
|
|
|
654
1314
|
if (!boardId || !normalizedNodeId) {
|
|
655
1315
|
return false;
|
|
656
1316
|
}
|
|
1317
|
+
this._boardRevision++;
|
|
1318
|
+
this._searchRevision++;
|
|
1319
|
+
this._visibilityNodeIds.delete(normalizedNodeId);
|
|
1320
|
+
this._visibilityNodeSnapshots.delete(normalizedNodeId);
|
|
657
1321
|
|
|
658
1322
|
const payload = {
|
|
659
1323
|
type: 'REMOVE_NODE',
|
|
@@ -661,9 +1325,9 @@
|
|
|
661
1325
|
nodeId: normalizedNodeId
|
|
662
1326
|
};
|
|
663
1327
|
|
|
664
|
-
const postedVisibility = this.
|
|
1328
|
+
const postedVisibility = this._postVisibility(payload);
|
|
665
1329
|
const postedLodPlan = this._post(this._lodPlanWorker, payload);
|
|
666
|
-
const postedSearch = this.
|
|
1330
|
+
const postedSearch = this._postSearch(payload);
|
|
667
1331
|
if (postedVisibility || postedLodPlan) {
|
|
668
1332
|
this._clearHitTestCache(module || this.module);
|
|
669
1333
|
}
|
|
@@ -690,7 +1354,8 @@
|
|
|
690
1354
|
return false;
|
|
691
1355
|
}
|
|
692
1356
|
|
|
693
|
-
|
|
1357
|
+
this._searchRevision++;
|
|
1358
|
+
return this._postSearch({
|
|
694
1359
|
type: 'BATCH_SYNC',
|
|
695
1360
|
boardId: normalizedBoardId,
|
|
696
1361
|
nodes: normalizedNodes,
|
|
@@ -766,9 +1431,15 @@
|
|
|
766
1431
|
return true;
|
|
767
1432
|
}
|
|
768
1433
|
|
|
769
|
-
const posted = this.
|
|
1434
|
+
const posted = this._postVisibility(this._stampVisibilityPayloadForPost(payload));
|
|
770
1435
|
this._visibilityQueryPending = posted;
|
|
771
1436
|
this._inFlightVisibilityRequestSeq = posted ? seq : 0;
|
|
1437
|
+
if (posted) {
|
|
1438
|
+
this._visibilityQueryStartedAt = monotonicNow();
|
|
1439
|
+
this._armVisibilityQueryTimer(seq);
|
|
1440
|
+
} else if (this._visibilityBackend === 'native') {
|
|
1441
|
+
this._activateLegacyVisibilityFallback('native visibility query post failed');
|
|
1442
|
+
}
|
|
772
1443
|
return posted;
|
|
773
1444
|
}
|
|
774
1445
|
|
|
@@ -779,11 +1450,17 @@
|
|
|
779
1450
|
|
|
780
1451
|
const payload = this._deferredVisibilityPayload;
|
|
781
1452
|
this._deferredVisibilityPayload = null;
|
|
782
|
-
const posted = this.
|
|
1453
|
+
const posted = this._postVisibility(this._stampVisibilityPayloadForPost(payload));
|
|
783
1454
|
this._visibilityQueryPending = posted;
|
|
784
1455
|
this._inFlightVisibilityRequestSeq = posted
|
|
785
1456
|
? Math.max(0, Math.floor(Number(payload.seq || 0)))
|
|
786
1457
|
: 0;
|
|
1458
|
+
if (posted) {
|
|
1459
|
+
this._visibilityQueryStartedAt = monotonicNow();
|
|
1460
|
+
this._armVisibilityQueryTimer(this._inFlightVisibilityRequestSeq);
|
|
1461
|
+
} else if (this._visibilityBackend === 'native') {
|
|
1462
|
+
this._activateLegacyVisibilityFallback('deferred native visibility query post failed');
|
|
1463
|
+
}
|
|
787
1464
|
}
|
|
788
1465
|
|
|
789
1466
|
_describeHitTestQuery(module = this.module, options = {}) {
|
|
@@ -797,7 +1474,7 @@
|
|
|
797
1474
|
}
|
|
798
1475
|
|
|
799
1476
|
const cellSize = Math.max(1, Number(activeModule.GRID_CELL_SIZE || 500));
|
|
800
|
-
const cellRadius = Math.max(0, Math.min(3, Math.round(Number(options.cellRadius
|
|
1477
|
+
const cellRadius = Math.max(0, Math.min(3, Math.round(Number(options.cellRadius ?? 1))));
|
|
801
1478
|
const cellX = Math.floor(pointX / cellSize);
|
|
802
1479
|
const cellY = Math.floor(pointY / cellSize);
|
|
803
1480
|
|
|
@@ -841,8 +1518,16 @@
|
|
|
841
1518
|
return true;
|
|
842
1519
|
}
|
|
843
1520
|
|
|
844
|
-
const posted = this.
|
|
1521
|
+
const posted = this._postVisibility(payload);
|
|
845
1522
|
this._hitTestQueryPending = posted;
|
|
1523
|
+
this._inFlightHitTestRequestSeq = posted ? payload.seq : 0;
|
|
1524
|
+
this._inFlightHitTestPayload = posted ? { ...payload } : null;
|
|
1525
|
+
if (posted) {
|
|
1526
|
+
this._hitTestQueryStartedAt = monotonicNow();
|
|
1527
|
+
this._armHitTestQueryTimer(payload.seq);
|
|
1528
|
+
} else if (this._visibilityBackend === 'native') {
|
|
1529
|
+
this._activateLegacyVisibilityFallback('native hit-test query post failed');
|
|
1530
|
+
}
|
|
846
1531
|
return posted;
|
|
847
1532
|
}
|
|
848
1533
|
|
|
@@ -853,8 +1538,16 @@
|
|
|
853
1538
|
|
|
854
1539
|
const payload = this._deferredHitTestPayload;
|
|
855
1540
|
this._deferredHitTestPayload = null;
|
|
856
|
-
const posted = this.
|
|
1541
|
+
const posted = this._postVisibility(payload);
|
|
857
1542
|
this._hitTestQueryPending = posted;
|
|
1543
|
+
this._inFlightHitTestRequestSeq = posted ? Number(payload.seq || 0) : 0;
|
|
1544
|
+
this._inFlightHitTestPayload = posted ? { ...payload } : null;
|
|
1545
|
+
if (posted) {
|
|
1546
|
+
this._hitTestQueryStartedAt = monotonicNow();
|
|
1547
|
+
this._armHitTestQueryTimer(payload.seq);
|
|
1548
|
+
} else if (this._visibilityBackend === 'native') {
|
|
1549
|
+
this._activateLegacyVisibilityFallback('deferred native hit-test query post failed');
|
|
1550
|
+
}
|
|
858
1551
|
}
|
|
859
1552
|
|
|
860
1553
|
getCachedHitTestCandidateIds(module = this.module, options = {}) {
|
|
@@ -903,12 +1596,18 @@
|
|
|
903
1596
|
};
|
|
904
1597
|
|
|
905
1598
|
return new Promise((resolve) => {
|
|
906
|
-
|
|
907
|
-
|
|
1599
|
+
const pending = { resolve, payload: { ...payload }, timer: null, startedAt: monotonicNow() };
|
|
1600
|
+
this._pendingSelectionResolvers.set(payload.seq, pending);
|
|
1601
|
+
const posted = this._postVisibility(payload);
|
|
908
1602
|
if (!posted) {
|
|
909
1603
|
this._pendingSelectionResolvers.delete(payload.seq);
|
|
910
1604
|
resolve(null);
|
|
1605
|
+
if (this._visibilityBackend === 'native') {
|
|
1606
|
+
this._activateLegacyVisibilityFallback('native selection query post failed');
|
|
1607
|
+
}
|
|
1608
|
+
return;
|
|
911
1609
|
}
|
|
1610
|
+
this._armSelectionQueryTimer(payload.seq, pending);
|
|
912
1611
|
});
|
|
913
1612
|
}
|
|
914
1613
|
|
|
@@ -982,12 +1681,25 @@
|
|
|
982
1681
|
};
|
|
983
1682
|
|
|
984
1683
|
return new Promise((resolve) => {
|
|
985
|
-
|
|
986
|
-
|
|
1684
|
+
const pending = { resolve, timer: null };
|
|
1685
|
+
this._pendingSearchResolvers.set(seq, pending);
|
|
1686
|
+
const posted = this._postSearch(payload);
|
|
987
1687
|
if (!posted) {
|
|
988
1688
|
this._pendingSearchResolvers.delete(seq);
|
|
989
1689
|
resolve(null);
|
|
1690
|
+
return;
|
|
990
1691
|
}
|
|
1692
|
+
pending.timer = setTimeout(() => {
|
|
1693
|
+
if (!this._pendingSearchResolvers.has(seq)) return;
|
|
1694
|
+
this._pendingSearchResolvers.delete(seq);
|
|
1695
|
+
resolve(null);
|
|
1696
|
+
window.MindCanvasTrace?.emit?.('logicWorker.searchTimeout', {
|
|
1697
|
+
boardId,
|
|
1698
|
+
seq,
|
|
1699
|
+
boardRevision: this._searchRevision,
|
|
1700
|
+
timeoutMs: SEARCH_QUERY_TIMEOUT_MS
|
|
1701
|
+
});
|
|
1702
|
+
}, SEARCH_QUERY_TIMEOUT_MS);
|
|
991
1703
|
});
|
|
992
1704
|
}
|
|
993
1705
|
}
|