@downdraft/engine 0.2.0 → 0.3.1
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/app/src/renderer/bootstrap.ts +0 -6
- package/app/src/renderer/feature-log.ts +1 -9
- package/app/src/renderer/mcp-harness.ts +8 -11
- package/app/src/renderer/standard-automation-tools.ts +8 -145
- package/core/src/index.ts +2 -2
- package/core/src/module/host.ts +3 -6
- package/core/src/module/index.ts +1 -1
- package/core/src/module/module.ts +4 -47
- package/core/src/physics/interface.ts +5 -0
- package/core/src/platform/render-surface.ts +13 -0
- package/core/src/platform/rpc.ts +4 -1
- package/core/src/render/canvas-resize-watcher.ts +1 -10
- package/core/src/render/game-renderer.ts +164 -79
- package/core/src/render/index.ts +0 -2
- package/core/src/render/input-manager.ts +7 -7
- package/core/src/render/renderer-module-host.ts +2 -4
- package/core/src/sab/grid-buffer.ts +55 -2
- package/core/src/sab/record-buffer.ts +48 -5
- package/core/src/sab/sim-channel.ts +181 -17
- package/core/src/sab/slot-buffer.ts +55 -1
- package/core/src/sab/types.ts +11 -0
- package/core/src/telemetry/gpu-resource-tracker.ts +24 -0
- package/core/src/ui-font-scale.ts +5 -38
- package/core/src/util/index.ts +1 -0
- package/core/src/util/session-timer.ts +23 -0
- package/core/src/worker/base-worker-host.ts +2 -1
- package/core/src/worker/buffer-sync.ts +20 -13
- package/core/src/worker/rpc.ts +119 -5
- package/core/src/worker/sim-worker-base.ts +5 -2
- package/core/src/worker/task-pool.ts +4 -0
- package/dist/.dd-manifest.json +893 -908
- package/dist/app/src/renderer/bootstrap.js +0 -4
- package/dist/app/src/renderer/feature-log.js +1 -10
- package/dist/app/src/renderer/mcp-harness.js +8 -11
- package/dist/app/src/renderer/standard-automation-tools.js +6 -138
- package/dist/core/src/index.js +2 -2
- package/dist/core/src/module/host.js +3 -6
- package/dist/core/src/platform/rpc.js +2 -1
- package/dist/core/src/render/canvas-resize-watcher.js +1 -10
- package/dist/core/src/render/game-renderer.js +166 -74
- package/dist/core/src/render/index.js +0 -1
- package/dist/core/src/render/input-manager.js +7 -7
- package/dist/core/src/render/renderer-module-host.js +2 -4
- package/dist/core/src/sab/grid-buffer.js +53 -1
- package/dist/core/src/sab/record-buffer.js +49 -5
- package/dist/core/src/sab/sim-channel.js +173 -17
- package/dist/core/src/sab/slot-buffer.js +54 -1
- package/dist/core/src/telemetry/gpu-resource-tracker.js +26 -0
- package/dist/core/src/ui-font-scale.js +5 -38
- package/dist/core/src/util/index.js +1 -0
- package/dist/core/src/util/session-timer.js +22 -0
- package/dist/core/src/worker/base-worker-host.js +2 -1
- package/dist/core/src/worker/buffer-sync.js +16 -9
- package/dist/core/src/worker/rpc.js +105 -8
- package/dist/core/src/worker/sim-worker-base.js +5 -2
- package/dist/core/src/worker/task-pool.js +5 -0
- package/dist/libraries/blitz-ui/src/native-module.js +8 -1
- package/dist/libraries/devtools/src/backend.js +35 -9
- package/dist/libraries/devtools/src/collectors.js +73 -22
- package/dist/libraries/devtools/src/native-providers.js +0 -2
- package/dist/libraries/entities/src/model-renderer.js +87 -27
- package/dist/libraries/entities/src/shaders/model.wgsl +13 -4
- package/dist/libraries/networking/src/index.js +1 -0
- package/dist/libraries/networking/src/ws-server.js +387 -0
- package/dist/libraries/physics-rapier/src/api.js +15 -0
- package/dist/libraries/physics-rapier/src/backend.js +15 -0
- package/dist/libraries/physics-rapier/src/rapier-backend.js +5 -0
- package/dist/libraries/postfx/src/post-process-stack.js +1 -3
- package/dist/libraries/sand/src/materials.js +2 -32
- package/dist/libraries/sand/src/sand-world.js +0 -3
- package/dist/modules/devtools/src/api.js +8 -23
- package/dist/modules/devtools/src/blitz/fonts.js +75 -0
- package/dist/modules/devtools/src/blitz/host.js +124 -30
- package/dist/modules/devtools/src/blitz/panels/console.js +19 -7
- package/dist/modules/devtools/src/blitz/panels/elements.js +217 -28
- package/dist/modules/devtools/src/blitz/panels/gpu.js +5 -2
- package/dist/modules/devtools/src/blitz/panels/performance.js +26 -12
- package/dist/modules/devtools/src/blitz/panels/snapshot.js +31 -8
- package/dist/modules/devtools/src/blitz/panels/types.js +2 -1
- package/dist/modules/devtools/src/blitz/theme.js +26 -4
- package/dist/modules/devtools/src/data-bridge.js +0 -11
- package/dist/modules/devtools/src/index.js +0 -6
- package/dist/modules/devtools/src/init.js +8 -42
- package/dist/modules/devtools/src/scene-inspector.js +1 -4
- package/dist/modules/devtools/src/worker-sync.js +3 -11
- package/dist/modules/html-ui/src/doc-backend.js +52 -3
- package/dist/modules/html-ui/src/host.js +6 -3
- package/dist/test/src/vision-test.js +1 -3
- package/libraries/blitz-ui/native/Cargo.toml +6 -0
- package/libraries/blitz-ui/native-osr/Cargo.toml +3 -1
- package/libraries/blitz-ui/src/native-module.ts +8 -1
- package/libraries/devtools/src/backend.ts +38 -12
- package/libraries/devtools/src/collectors.ts +75 -22
- package/libraries/devtools/src/native-providers.ts +0 -2
- package/libraries/entities/src/model-renderer.ts +88 -27
- package/libraries/entities/src/shaders/model.wgsl +13 -4
- package/libraries/networking/src/index.ts +4 -0
- package/libraries/networking/src/ws-server.ts +397 -0
- package/libraries/physics-rapier/src/api.ts +15 -0
- package/libraries/physics-rapier/src/backend.ts +15 -0
- package/libraries/physics-rapier/src/rapier-backend.ts +6 -0
- package/libraries/postfx/src/post-process-stack.ts +1 -2
- package/libraries/sand/src/materials.ts +2 -32
- package/libraries/sand/src/sand-world.ts +0 -4
- package/modules/devtools/README.md +1 -3
- package/modules/devtools/src/api.ts +10 -34
- package/modules/devtools/src/blitz/fonts.ts +78 -0
- package/modules/devtools/src/blitz/host.ts +107 -31
- package/modules/devtools/src/blitz/panels/console.ts +20 -8
- package/modules/devtools/src/blitz/panels/elements.ts +212 -31
- package/modules/devtools/src/blitz/panels/gpu.ts +4 -2
- package/modules/devtools/src/blitz/panels/performance.ts +24 -12
- package/modules/devtools/src/blitz/panels/snapshot.ts +30 -8
- package/modules/devtools/src/blitz/panels/types.ts +2 -1
- package/modules/devtools/src/blitz/theme.ts +26 -4
- package/modules/devtools/src/data-bridge.ts +0 -16
- package/modules/devtools/src/index.ts +1 -11
- package/modules/devtools/src/init.ts +8 -51
- package/modules/devtools/src/scene-inspector.ts +2 -6
- package/modules/devtools/src/types.ts +5 -90
- package/modules/devtools/src/worker-sync.ts +3 -13
- package/modules/html-ui/src/doc-backend.ts +67 -4
- package/modules/html-ui/src/host.ts +11 -3
- package/modules/html-ui/src/protocol.ts +1 -1
- package/package.json +4 -5
- package/test/src/vision-test.ts +2 -4
- package/core/src/render/sab-canvas-overlay.ts +0 -122
- package/dist/core/src/render/sab-canvas-overlay.js +0 -83
- package/dist/modules/devtools/src/debug-overlay.js +0 -181
- package/dist/modules/devtools/src/doctor-panel.js +0 -163
- package/dist/modules/devtools/src/label-overlay.js +0 -129
- package/dist/modules/devtools/src/material-stats-panel.js +0 -171
- package/dist/modules/devtools/src/sim-stats-panel.js +0 -250
- package/modules/devtools/src/debug-overlay.ts +0 -238
- package/modules/devtools/src/doctor-panel.ts +0 -182
- package/modules/devtools/src/label-overlay.ts +0 -154
- package/modules/devtools/src/material-stats-panel.ts +0 -188
- package/modules/devtools/src/sim-stats-panel.ts +0 -272
|
@@ -132,15 +132,11 @@ export async function bootstrapGame(opts) {
|
|
|
132
132
|
return;
|
|
133
133
|
const { initDevTools } = devtoolsMod;
|
|
134
134
|
const simStatsProvider = opts.devtools.createSimStatsProvider?.(renderer);
|
|
135
|
-
const panels = typeof opts.devtools.panels === "function"
|
|
136
|
-
? opts.devtools.panels(renderer)
|
|
137
|
-
: opts.devtools.panels ?? [];
|
|
138
135
|
const workerHosts = typeof opts.devtools.workerHosts === "function"
|
|
139
136
|
? opts.devtools.workerHosts(renderer)
|
|
140
137
|
: opts.devtools.workerHosts;
|
|
141
138
|
const devtoolsBridge = await importOrDead(initDevTools(renderer, {
|
|
142
139
|
simStatsProvider,
|
|
143
|
-
panels,
|
|
144
140
|
sceneInspector: opts.devtools.sceneInspector,
|
|
145
141
|
bridgeClass: opts.devtools.bridgeClass,
|
|
146
142
|
workerHosts,
|
|
@@ -82,22 +82,13 @@ export function collectRendererFeatureLog(opts) {
|
|
|
82
82
|
data.mem = `${nav.deviceMemory}G`;
|
|
83
83
|
}
|
|
84
84
|
catch { /* navigator unavailable */ }
|
|
85
|
-
// --- SharedArrayBuffer
|
|
86
|
-
// there is no origin model on the native host) ---
|
|
85
|
+
// --- SharedArrayBuffer ---
|
|
87
86
|
try {
|
|
88
87
|
data.sab = typeof SharedArrayBuffer !== "undefined" ? 1 : 0;
|
|
89
88
|
}
|
|
90
89
|
catch {
|
|
91
90
|
data.sab = 0;
|
|
92
91
|
}
|
|
93
|
-
if (getHostCapabilities().hasDom) {
|
|
94
|
-
try {
|
|
95
|
-
data.coi = self.crossOriginIsolated ? 1 : 0;
|
|
96
|
-
}
|
|
97
|
-
catch {
|
|
98
|
-
data.coi = 0;
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
92
|
// --- Worker load status (best-effort; na = not checked) ---
|
|
102
93
|
data.wk = "na";
|
|
103
94
|
// --- Active plugins ---
|
|
@@ -90,17 +90,14 @@ export function createMcpHarness(opts) {
|
|
|
90
90
|
// These utilities are used by multiple games' MCP automation harnesses.
|
|
91
91
|
// Games import them instead of duplicating the implementation.
|
|
92
92
|
/** Convert a Blob to a base64 string (without the data: prefix). */
|
|
93
|
-
export function blobToBase64(blob) {
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
reader.onerror = reject;
|
|
102
|
-
reader.readAsDataURL(blob);
|
|
103
|
-
});
|
|
93
|
+
export async function blobToBase64(blob) {
|
|
94
|
+
const bytes = new Uint8Array(await blob.arrayBuffer());
|
|
95
|
+
let bin = "";
|
|
96
|
+
const CHUNK = 0x8000;
|
|
97
|
+
for (let i = 0; i < bytes.length; i += CHUNK) {
|
|
98
|
+
bin += String.fromCharCode(...bytes.subarray(i, i + CHUNK));
|
|
99
|
+
}
|
|
100
|
+
return btoa(bin);
|
|
104
101
|
}
|
|
105
102
|
/** MCP result helper: wrap data as a JSON content array. */
|
|
106
103
|
export function jsonResult(data) {
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
// }),
|
|
26
26
|
// });
|
|
27
27
|
// ============================================================================
|
|
28
|
-
import {
|
|
28
|
+
import { KEY } from "@downdraft/engine";
|
|
29
29
|
import { createLogger } from "@downdraft/engine/util/logger";
|
|
30
30
|
import { downdraft } from "./index.js";
|
|
31
31
|
import { blobToBase64, createMcpHarness, errorResult, jsonResult } from "./mcp-harness.js";
|
|
@@ -290,21 +290,13 @@ export function createStandardAutomationTools(ctx) {
|
|
|
290
290
|
const rect = surface.getBoundingClientRect();
|
|
291
291
|
const clientX = rect.left + x;
|
|
292
292
|
const clientY = rect.top + y;
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
//
|
|
296
|
-
//
|
|
297
|
-
const target = hasDom
|
|
298
|
-
? (document.elementFromPoint(clientX, clientY) ?? surface)
|
|
299
|
-
: surface;
|
|
300
|
-
// MiniEventTarget (native event polyfill) has no capture/bubble —
|
|
301
|
-
// mirror real propagation by also dispatching on window. In a real
|
|
302
|
-
// DOM this would double-fire, so only do it under the polyfill.
|
|
303
|
-
const isNativeDom = !hasDom;
|
|
293
|
+
// There is no DOM tree — the surface itself is the input target.
|
|
294
|
+
const target = surface;
|
|
295
|
+
// MiniEventTarget (native event target) has no capture/bubble —
|
|
296
|
+
// mirror DOM propagation by also dispatching on window.
|
|
304
297
|
const fire = (ev) => {
|
|
305
298
|
target.dispatchEvent(ev);
|
|
306
|
-
|
|
307
|
-
window.dispatchEvent?.(ev);
|
|
299
|
+
window.dispatchEvent?.(ev);
|
|
308
300
|
};
|
|
309
301
|
if (type === "wheel") {
|
|
310
302
|
const deltaX = params.deltaX ?? 0;
|
|
@@ -487,130 +479,6 @@ export function createStandardAutomationTools(ctx) {
|
|
|
487
479
|
handler: () => jsonResult(ctx.getUiState()),
|
|
488
480
|
});
|
|
489
481
|
}
|
|
490
|
-
// ── get_element_bounds ──
|
|
491
|
-
if (want("get_element_bounds")) {
|
|
492
|
-
tools.push({
|
|
493
|
-
def: {
|
|
494
|
-
name: "get_element_bounds",
|
|
495
|
-
description: "Get the bounding box of a DOM element matching a CSS selector. Returns {x, y, width, height, top, left, bottom, right} or found:false.",
|
|
496
|
-
inputSchema: {
|
|
497
|
-
type: "object",
|
|
498
|
-
properties: { selector: { type: "string", description: "CSS selector" } },
|
|
499
|
-
required: ["selector"],
|
|
500
|
-
},
|
|
501
|
-
},
|
|
502
|
-
handler: (params) => {
|
|
503
|
-
const selector = params.selector;
|
|
504
|
-
try {
|
|
505
|
-
const el = document.querySelector(selector);
|
|
506
|
-
if (!el)
|
|
507
|
-
return jsonResult({ found: false, selector });
|
|
508
|
-
const rect = el.getBoundingClientRect();
|
|
509
|
-
return jsonResult({
|
|
510
|
-
found: true, selector,
|
|
511
|
-
x: rect.x, y: rect.y, width: rect.width, height: rect.height,
|
|
512
|
-
top: rect.top, left: rect.left, bottom: rect.bottom, right: rect.right,
|
|
513
|
-
});
|
|
514
|
-
}
|
|
515
|
-
catch (e) {
|
|
516
|
-
return errorResult(`Failed to query selector "${selector}": ${e.message}`);
|
|
517
|
-
}
|
|
518
|
-
},
|
|
519
|
-
});
|
|
520
|
-
}
|
|
521
|
-
// ── inspect_dom ──
|
|
522
|
-
if (want("inspect_dom")) {
|
|
523
|
-
tools.push({
|
|
524
|
-
def: {
|
|
525
|
-
name: "inspect_dom",
|
|
526
|
-
description: "Inspect the main thread's DOM for debugging CSS/layout issues. 'stylesheets' lists all <style>/<link> tags; 'element' gets details for a selector.",
|
|
527
|
-
inputSchema: {
|
|
528
|
-
type: "object",
|
|
529
|
-
properties: {
|
|
530
|
-
action: { type: "string", enum: ["stylesheets", "element"] },
|
|
531
|
-
selector: { type: "string", description: "CSS selector (for action='element')" },
|
|
532
|
-
},
|
|
533
|
-
required: ["action"],
|
|
534
|
-
},
|
|
535
|
-
},
|
|
536
|
-
handler: (params) => {
|
|
537
|
-
if (!getHostCapabilities().hasDom) {
|
|
538
|
-
return errorResult("inspect_dom requires a real DOM — the native host's document is a canvas-compat facade, not a DOM tree");
|
|
539
|
-
}
|
|
540
|
-
const action = params.action;
|
|
541
|
-
if (action === "stylesheets") {
|
|
542
|
-
const styles = Array.from(document.querySelectorAll("style, link[rel='stylesheet']")).map((el) => {
|
|
543
|
-
const tag = el.tagName.toLowerCase();
|
|
544
|
-
if (tag === "style") {
|
|
545
|
-
const text = el.textContent ?? "";
|
|
546
|
-
return { tag, length: text.length, preview: text.slice(0, 200) };
|
|
547
|
-
}
|
|
548
|
-
return { tag, href: el.href };
|
|
549
|
-
});
|
|
550
|
-
return jsonResult({ stylesheets: styles, count: styles.length });
|
|
551
|
-
}
|
|
552
|
-
if (action === "element" && params.selector) {
|
|
553
|
-
const el = document.querySelector(params.selector);
|
|
554
|
-
if (!el)
|
|
555
|
-
return jsonResult({ found: false, selector: params.selector });
|
|
556
|
-
const cs = getComputedStyle(el);
|
|
557
|
-
return jsonResult({
|
|
558
|
-
found: true,
|
|
559
|
-
selector: params.selector,
|
|
560
|
-
tagName: el.tagName,
|
|
561
|
-
className: el.className,
|
|
562
|
-
id: el.id,
|
|
563
|
-
style: {
|
|
564
|
-
width: cs.width, height: cs.height,
|
|
565
|
-
maxWidth: cs.maxWidth, maxHeight: cs.maxHeight,
|
|
566
|
-
display: cs.display, position: cs.position,
|
|
567
|
-
top: cs.top, left: cs.left, overflow: cs.overflow,
|
|
568
|
-
},
|
|
569
|
-
bounds: el.getBoundingClientRect().toJSON(),
|
|
570
|
-
childCount: el.children.length,
|
|
571
|
-
});
|
|
572
|
-
}
|
|
573
|
-
return errorResult("Invalid action or missing selector");
|
|
574
|
-
},
|
|
575
|
-
});
|
|
576
|
-
}
|
|
577
|
-
// ── get_element_style ──
|
|
578
|
-
if (want("get_element_style")) {
|
|
579
|
-
tools.push({
|
|
580
|
-
def: {
|
|
581
|
-
name: "get_element_style",
|
|
582
|
-
description: "Get computed style of a DOM element matching a CSS selector. Pass properties[] to read specific CSS properties.",
|
|
583
|
-
inputSchema: {
|
|
584
|
-
type: "object",
|
|
585
|
-
properties: {
|
|
586
|
-
selector: { type: "string", description: "CSS selector" },
|
|
587
|
-
properties: { type: "array", items: { type: "string" }, description: "CSS properties to read" },
|
|
588
|
-
},
|
|
589
|
-
required: ["selector"],
|
|
590
|
-
},
|
|
591
|
-
},
|
|
592
|
-
handler: (params) => {
|
|
593
|
-
if (!getHostCapabilities().hasDom) {
|
|
594
|
-
return errorResult("get_element_style requires a real DOM — no computed styles on the native host");
|
|
595
|
-
}
|
|
596
|
-
const selector = params.selector;
|
|
597
|
-
const props = params.properties ?? [];
|
|
598
|
-
try {
|
|
599
|
-
const el = document.querySelector(selector);
|
|
600
|
-
if (!el)
|
|
601
|
-
return jsonResult({ found: false, selector });
|
|
602
|
-
const cs = getComputedStyle(el);
|
|
603
|
-
const result = { found: true, selector };
|
|
604
|
-
props.forEach((p) => { result[p] = cs.getPropertyValue(p); ; });
|
|
605
|
-
result._className = el.className;
|
|
606
|
-
return jsonResult(result);
|
|
607
|
-
}
|
|
608
|
-
catch (e) {
|
|
609
|
-
return errorResult(`Failed to query style for "${selector}": ${e.message}`);
|
|
610
|
-
}
|
|
611
|
-
},
|
|
612
|
-
});
|
|
613
|
-
}
|
|
614
482
|
// ── inspectable_list / inspectable_get / inspectable_set ──
|
|
615
483
|
const inspectables = ctx.inspectables;
|
|
616
484
|
if (want("inspectable_list") && inspectables) {
|
package/dist/core/src/index.js
CHANGED
|
@@ -45,7 +45,7 @@ export { createMultiInputChannel, DEFAULT_KEY_BITFIELD_COUNT, DEFAULT_MAX_PLAYER
|
|
|
45
45
|
// Game Input SAB Channel
|
|
46
46
|
export { INP, INP_FLAG, INP_HDR, INPUT_MAGIC, INPUT_VERSION, InputBufferReader, InputBufferWriter, InputChannel, KEY, MAX_INPUT_PLAYERS } from "./sab/game-input.js";
|
|
47
47
|
// Sim SAB Channel
|
|
48
|
-
export { allocateInputBuffer, allocateSimBuffer, ENT, MAX_ENTITIES, MAX_PLAYERS, PLR, PLR_FLAG, SIM_ENTITY_SLOT_SIZE, SIM_HDR, SIM_MAGIC, SIM_PLAYER_SLOT_SIZE, SIM_VERSION, SimBufferReader, SimBufferWriter, SimChannel } from "./sab/sim-channel.js";
|
|
48
|
+
export { allocateInputBuffer, allocateSimBuffer, ENT, MAX_ENTITIES, MAX_PLAYERS, PLR, PLR_FLAG, PREV, SIM_ENTITY_SLOT_SIZE, SIM_HDR, SIM_MAGIC, SIM_PLAYER_SLOT_SIZE, SIM_VERSION, SimBufferReader, SimBufferWriter, SimChannel } from "./sab/sim-channel.js";
|
|
49
49
|
// SAB Framework
|
|
50
50
|
export { defineChannel, defineManifest } from "./sab/define.js";
|
|
51
51
|
export { isDebug, resetWarnings, ValidationError as SABValidationError, setDebug, warnOnce } from "./sab/errors.js";
|
|
@@ -57,7 +57,7 @@ export { BufferSyncHost, BufferSyncWorker, isBufferSyncMessage } from "./worker/
|
|
|
57
57
|
export { CrashRecoveryManager, DEFAULT_RECOVERY_CONFIG } from "./worker/crash-recovery.js";
|
|
58
58
|
export { EntitySimWorkerHost } from "./worker/entity-sim-worker-host.js";
|
|
59
59
|
export { exposeProfilingApi, InstrumentedWorkerHost } from "./worker/instrumented-worker-host.js";
|
|
60
|
-
export { expose, exposeEvents, getWorkerHost, wrap } from "./worker/rpc.js";
|
|
60
|
+
export { expose, exposeBatchedEvents, exposeEvents, getWorkerHost, wrap } from "./worker/rpc.js";
|
|
61
61
|
export { createSimWorker } from "./worker/sim-worker-base.js";
|
|
62
62
|
export { RawInputRegionWriter, SimWorkerHost } from "./worker/sim-worker-host.js";
|
|
63
63
|
export { createTaskWorker, PortChannel, TaskPool } from "./worker/task-pool.js";
|
|
@@ -23,15 +23,15 @@ export class ModuleHost {
|
|
|
23
23
|
}
|
|
24
24
|
/**
|
|
25
25
|
* Inject the DevTools API. Called by the game bootstrap after
|
|
26
|
-
* `initDevTools()` so plugins can self-register
|
|
27
|
-
* `ctx.devtools.
|
|
26
|
+
* `initDevTools()` so plugins can self-register data feeds via
|
|
27
|
+
* `ctx.devtools.registerDataFeed(...)` during their `register()` lifecycle.
|
|
28
28
|
*/
|
|
29
29
|
setDevToolsAPI(api) {
|
|
30
30
|
this._devtools = api;
|
|
31
31
|
}
|
|
32
32
|
get devtools() {
|
|
33
33
|
// Return the injected API, or a no-op stub if not set (so plugins that
|
|
34
|
-
// call ctx.devtools.
|
|
34
|
+
// call ctx.devtools.register*() don't crash if devtools isn't wired).
|
|
35
35
|
return this._devtools ?? NoopDevToolsAPI;
|
|
36
36
|
}
|
|
37
37
|
getRegistry() {
|
|
@@ -439,10 +439,7 @@ export class ModuleHost {
|
|
|
439
439
|
}
|
|
440
440
|
}
|
|
441
441
|
// No-op DevTools API stub — used when setDevToolsAPI() hasn't been called.
|
|
442
|
-
// Plugins that call ctx.devtools.registerPanel() will silently no-op.
|
|
443
442
|
const NoopDevToolsAPI = {
|
|
444
|
-
registerPanel: () => { },
|
|
445
|
-
registerOverlayToggle: () => { },
|
|
446
443
|
registerDataFeed: () => { },
|
|
447
444
|
registerCommand: () => { },
|
|
448
445
|
registerSABStat: () => { },
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { untrackedTimeout } from "../util/session-timer.js";
|
|
1
2
|
export class RPC {
|
|
2
3
|
handlers = new Map();
|
|
3
4
|
pending = new Map();
|
|
@@ -20,7 +21,7 @@ export class RPC {
|
|
|
20
21
|
}
|
|
21
22
|
const id = this.messageIdCounter = (this.messageIdCounter + 1) % 0xFFFFFFFF;
|
|
22
23
|
return new Promise((resolve, reject) => {
|
|
23
|
-
const timer =
|
|
24
|
+
const timer = untrackedTimeout(() => {
|
|
24
25
|
if (this.pending.has(id)) {
|
|
25
26
|
this.pending.delete(id);
|
|
26
27
|
reject(new Error(`[RPC] Call to "${channel}" timed out after ${timeoutMs}ms`));
|
|
@@ -1,20 +1,13 @@
|
|
|
1
1
|
export class CanvasResizeWatcher {
|
|
2
2
|
canvas;
|
|
3
3
|
handler;
|
|
4
|
-
observer = null;
|
|
5
4
|
dpr = 1;
|
|
6
5
|
onSurfaceResize = () => this.resize();
|
|
7
6
|
constructor(canvas, handler) {
|
|
8
7
|
this.canvas = canvas;
|
|
9
8
|
this.handler = handler;
|
|
10
9
|
this.dpr = (typeof window !== "undefined" ? window.devicePixelRatio : 0) || 1;
|
|
11
|
-
//
|
|
12
|
-
// aren't Elements — they push a "resize" event instead. Both paths feed
|
|
13
|
-
// the same resize() so either host drives layout updates.
|
|
14
|
-
if (typeof ResizeObserver !== "undefined") {
|
|
15
|
-
this.observer = new ResizeObserver(() => this.resize());
|
|
16
|
-
this.observer.observe(canvas);
|
|
17
|
-
}
|
|
10
|
+
// Native surfaces push a "resize" event when the backing store changes.
|
|
18
11
|
canvas.addEventListener("resize", this.onSurfaceResize);
|
|
19
12
|
this.resize();
|
|
20
13
|
}
|
|
@@ -29,8 +22,6 @@ export class CanvasResizeWatcher {
|
|
|
29
22
|
return this.dpr;
|
|
30
23
|
}
|
|
31
24
|
destroy() {
|
|
32
|
-
this.observer?.disconnect();
|
|
33
|
-
this.observer = null;
|
|
34
25
|
this.canvas.removeEventListener("resize", this.onSurfaceResize);
|
|
35
26
|
}
|
|
36
27
|
}
|