@modernrelay/orbit-engine-cosmos 0.13.5 → 0.13.6
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/index.d.ts +3 -0
- package/dist/index.js +9 -2
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -143,6 +143,9 @@ declare class CosmosEngine implements GraphEngine {
|
|
|
143
143
|
private dragIndex;
|
|
144
144
|
/** Last hover reported by cosmos — fallback dragged-point source. */
|
|
145
145
|
private lastHoverIndex;
|
|
146
|
+
/** Live native link hover (review P1: gates the unified onClick's
|
|
147
|
+
* background interpretation — a hovered link owns the click). */
|
|
148
|
+
private hoveredLinkIndex;
|
|
146
149
|
/** rAF id of the pending activity-clock tick; null = clock not running. */
|
|
147
150
|
private frameHandle;
|
|
148
151
|
/** Window driving the clock, cached so stop works after the div detaches. */
|
package/dist/index.js
CHANGED
|
@@ -129,6 +129,9 @@ var CosmosEngine = class {
|
|
|
129
129
|
dragIndex = null;
|
|
130
130
|
/** Last hover reported by cosmos — fallback dragged-point source. */
|
|
131
131
|
lastHoverIndex = null;
|
|
132
|
+
/** Live native link hover (review P1: gates the unified onClick's
|
|
133
|
+
* background interpretation — a hovered link owns the click). */
|
|
134
|
+
hoveredLinkIndex = null;
|
|
132
135
|
// --- adapter-owned GATED overlay/activity clock (see module header) ---
|
|
133
136
|
/** rAF id of the pending activity-clock tick; null = clock not running. */
|
|
134
137
|
frameHandle = null;
|
|
@@ -675,12 +678,14 @@ var CosmosEngine = class {
|
|
|
675
678
|
this.events?.onPointClick?.(index, clickModifiers(event));
|
|
676
679
|
},
|
|
677
680
|
onBackgroundClick: (event) => {
|
|
678
|
-
this.emitNullPointClick(event);
|
|
681
|
+
if (this.hoveredLinkIndex === null) this.emitNullPointClick(event);
|
|
679
682
|
},
|
|
680
683
|
// onClick fires for every canvas click; an undefined index means no
|
|
681
684
|
// point was hit (background clicks — link clicks arrive via onLinkClick).
|
|
682
685
|
onClick: (index, _position, event) => {
|
|
683
|
-
if (index === void 0
|
|
686
|
+
if (index === void 0 && this.hoveredLinkIndex === null) {
|
|
687
|
+
this.emitNullPointClick(event);
|
|
688
|
+
}
|
|
684
689
|
},
|
|
685
690
|
// Unified context-menu channel: fires exactly once per gesture (desktop
|
|
686
691
|
// right-click AND touch long-press — cosmos synthesizes the latter);
|
|
@@ -705,10 +710,12 @@ var CosmosEngine = class {
|
|
|
705
710
|
this.events?.onLinkClick?.(linkIndex);
|
|
706
711
|
},
|
|
707
712
|
onLinkMouseOver: (linkIndex) => {
|
|
713
|
+
this.hoveredLinkIndex = linkIndex;
|
|
708
714
|
this.requestTicks(1);
|
|
709
715
|
this.events?.onLinkHover?.(linkIndex);
|
|
710
716
|
},
|
|
711
717
|
onLinkMouseOut: () => {
|
|
718
|
+
this.hoveredLinkIndex = null;
|
|
712
719
|
this.requestTicks(1);
|
|
713
720
|
this.events?.onLinkHover?.(null);
|
|
714
721
|
},
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/restoreDeadline.ts","../src/CosmosEngine.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * RestoreDeadline — a visibility-aware countdown used while a WebGL context is\n * lost. Browsers routinely defer `webglcontextrestored` for backgrounded tabs,\n * so the budget must only burn while the document is visible: hidden time is\n * banked (timer cleared, remaining ms kept) and the countdown re-arms from the\n * remainder when the tab becomes visible again.\n */\nexport class RestoreDeadline {\n private timer: ReturnType<typeof setTimeout> | null = null;\n /** Unspent budget in ms; recomputed each time the timer is disarmed. */\n private remaining: number;\n /** Timestamp when the current timer was armed (for banking on hide). */\n private armedAt = 0;\n private started = false;\n /** Terminal: set on expiry or cancel; guarantees onExpire fires at most once. */\n private done = false;\n\n private readonly handleVisibilityChange = (): void => {\n if (this.done) return;\n if (this.doc.visibilityState === 'visible') this.arm();\n else this.disarm();\n };\n\n constructor(\n private readonly doc: Document,\n ms: number,\n private readonly onExpire: () => void,\n ) {\n this.remaining = ms;\n }\n\n start(): void {\n if (this.done || this.started) return;\n this.started = true;\n this.doc.addEventListener('visibilitychange', this.handleVisibilityChange);\n if (this.doc.visibilityState === 'visible') this.arm();\n }\n\n cancel(): void {\n if (this.done) return;\n this.done = true;\n if (this.timer !== null) {\n globalThis.clearTimeout(this.timer);\n this.timer = null;\n }\n if (this.started) {\n this.doc.removeEventListener('visibilitychange', this.handleVisibilityChange);\n }\n }\n\n private arm(): void {\n if (this.timer !== null) return;\n this.armedAt = Date.now();\n this.timer = globalThis.setTimeout(() => {\n this.timer = null;\n this.done = true;\n this.doc.removeEventListener('visibilitychange', this.handleVisibilityChange);\n this.onExpire();\n }, this.remaining);\n }\n\n private disarm(): void {\n if (this.timer === null) return;\n globalThis.clearTimeout(this.timer);\n this.timer = null;\n this.remaining = Math.max(0, this.remaining - (Date.now() - this.armedAt));\n }\n}\n","/**\n * CosmosEngine — GraphEngine adapter over @cosmos.gl/graph (spec §13).\n *\n * Node-safe module: cosmos is loaded lazily via `await import()` inside\n * `mount()` (§18); module scope carries only type-only imports (erased at\n * runtime) and never touches the DOM.\n *\n * Color scale note: the EngineCommit contract carries RGBA floats in [0,1],\n * which is exactly cosmos' native scale (verified against the 3.3.0 dist:\n * hex config colors are parsed via /255 into 0–1 floats and setPointColors\n * input is fed to GPU buffers untouched) — so color buffers pass through.\n *\n * Interaction notes (verified against the 3.3.0 dist):\n * - Link picking is native: setting any onLink* config callback flips\n * cosmos' internal `isLinkHoveringEnabled` on, so wiring the callbacks in\n * `buildInitialConfig` is sufficient (no extra config flag exists).\n * - `findPointsInPolygon` takes SCREEN coordinates (\"from 0 to the\n * width/height of the canvas\" per dist/index.d.ts), so `pointsInPolygon`\n * passes the host's screen polygon through without conversion.\n * - `findPointsInRect` uses the SAME screen space and expects ordered\n * corners `[[left, top], [right, bottom]]` (the dist flips Y assuming that\n * ordering), so `pointsInRect` normalizes the host's [x0,y0,x1,y1] rect to\n * min/max corners and passes it through without conversion.\n * - Camera pan (S11 — the zoom-only limitation is LIFTED): cosmos 3.3 has no\n * pan-to API, but `setZoomTransformByPointPositions(positions, duration,\n * scale, padding)` (dist/index.d.ts) is an exact center+zoom when `scale`\n * is explicit. Derivation from the dist (`zoomInstance.getTransform`):\n * space→screen-at-k=1 goes through `store.scaleX/scaleY`, which are LINEAR\n * with slope ±1 (scaleX(x) = x + (w−S)/2; scaleY(y) = (S−y) + (h−S)/2,\n * S = adjustedSpaceSize, w/h = canvas size); a single-point bbox is widened\n * ±0.5 SYMMETRICALLY (center preserved); an explicit `scale` bypasses the\n * fit math and `padding` entirely — k = clamp(scale, d3 scaleExtent) and\n * the result is translate(w/2 − scaleX(x)·k, h/2 − scaleY(y)·k).scale(k),\n * i.e. space point (x, y) lands exactly at the screen center with\n * eventTransform.k = scale. Since `getZoomLevel()` returns eventTransform.k\n * and `getViewport()` reads screenToSpacePosition(screen center),\n * `setViewport({x, y, zoom})` → setZoomTransformByPointPositions(\n * Float32Array.of(x, y), durationMs ?? 0, zoom ?? getZoomLevel()) makes a\n * follow-up `getViewport()` return exactly {x, y, zoom} (modulo the\n * scaleExtent clamp). This also completes §13.1 recovery: the core replays\n * the full stored {x, y, zoom} through setViewport, so viewport restore is\n * no longer zoom-only.\n * - Context menu: cosmos fires the unified config `onContextMenu(index |\n * undefined, pos, event)` exactly ONCE per gesture — desktop right-click\n * (dist `onContextMenu(e)`) and touch/pen long-press (dist long-press timer\n * → `fireContextMenu`) both route through it — while the per-target\n * `onPointContextMenu`/`onLinkContextMenu`/`onBackgroundContextMenu`\n * callbacks fire ADDITIONALLY for the same gesture. Wiring only the unified\n * callback therefore avoids a double-report (same shape as the\n * onClick/onBackgroundClick dedupe). A context menu over a LINK arrives\n * with index undefined and is reported as background (the host event\n * carries node-or-background only).\n *\n * GATED overlay/activity clock (ADR-005; M0 evidence docs/m0-conformance.md):\n * cosmos still exposes no draw/render-phase hook (`postDrawFrames: false`),\n * so the adapter owns the single requestAnimationFrame loop that reports\n * `onFrame(timeMs)` to the host — an ACTIVITY clock, not a post-draw hook:\n * overlays may lag the canvas by one sample (reported once at mount via\n * `engine:overlay-activity-clock`). Since cosmos 3.4 idle-stops its own\n * rendering (on-demand rendering, quiescence probe: 0 idle frames/750ms),\n * this clock is GATED to match — it free-runs only while a run reason is\n * held (sim hot via onSimulationStart/Pause/Unpause/End, drag gestures,\n * cosmos transitions) and otherwise burns a small one-shot tick budget that\n * every visual write re-arms (commits, highlight/focus/pin setters, camera\n * moves, hover events; animated camera moves self-sustain through per-step\n * onZoom bursts). Releasing a run reason always grants ONE trailing tick —\n * the releasing activity's final GPU write lands after the current draw\n * pass. At rest: zero rAF registrations from cosmos AND from this adapter\n * (`capabilities.idleFrames: 'stops'`). The clock stops on context\n * loss/destroy, re-arms on recovery, and skips the callback (keeping its\n * schedule) while `document.hidden`.\n *\n * Screenshots use the M0 same-tick capture method (apps/spike/src/instrument.ts):\n * cosmos renders with preserveDrawingBuffer:false, so the WebGL buffer is only\n * readable via a synchronous drawImage inside the same rAF tick it was drawn —\n * `captureScreenshot` schedules one rAF, draws the cosmos canvas onto an\n * offscreen 2D canvas inside that tick, and resolves the Blob (null on any\n * failure or unusable lifecycle state).\n * - The D3 drag events carry NO point index (the drag subject is a bare\n * `{x, y}`); cosmos assigns `store.draggingPointIndex` immediately before\n * invoking `onDragStart`, so the adapter reads it there (see\n * `readDraggingIndex` for the public-callback fallback).\n * - During a drag, cosmos' drag shader hard-pins the dragged point's\n * position texture entry to the mouse's SPACE position every frame\n * (dist `drag()`: `pointPosition.rg = mousePos` where `mousePos` =\n * screenToSpace(pointer)). So the point's final space position equals\n * `screenToSpacePosition([event.x, event.y])` at drag end — an O(1) CPU\n * transform, chosen over `getPointPositions()` (full GPU readback).\n */\n\nimport type { Graph as CosmosGraph, GraphConfig } from '@cosmos.gl/graph';\nimport type {\n EngineCapabilities,\n EngineCommit,\n EngineHostEvents,\n FitViewOptions,\n GraphEngine,\n} from '@modernrelay/orbit-core/engine';\nimport { RestoreDeadline } from './restoreDeadline';\n\n/** Derived from the contract to avoid importing the core root barrel. */\ntype ViewportState = NonNullable<ReturnType<GraphEngine['getViewport']>>;\n\n/**\n * Structural view of cosmos' `graph.store` — private in the 3.3.0 d.ts but a\n * stable runtime field. `draggingPointIndex` is assigned right before cosmos\n * invokes `onDragStart` (verified in the dist), making it the authoritative\n * dragged-point source; `hoveredPoint` mirrors the public onPointMouseOver\n * payload.\n */\ninterface CosmosStoreLike {\n hoveredPoint?: { index: number; position: [number, number] };\n draggingPointIndex?: number;\n}\n\n/**\n * Extracts click modifiers from a cosmos-forwarded event. Duck-typed rather\n * than `instanceof MouseEvent`: node-safe and cross-realm-safe. Returns\n * undefined when the event carries no modifier state.\n */\nfunction clickModifiers(event: unknown): { metaKey: boolean; shiftKey: boolean } | undefined {\n const e = event as { metaKey?: unknown; shiftKey?: unknown } | null | undefined;\n if (e && typeof e.metaKey === 'boolean' && typeof e.shiftKey === 'boolean') {\n return { metaKey: e.metaKey, shiftKey: e.shiftKey };\n }\n return undefined;\n}\n\nexport interface CosmosEngineOptions {\n /** Simulation space size passed to cosmos (cosmos default: 4096). */\n spaceSize?: number;\n /** Ring radius for seeding unknown (NaN) positions. Default: spaceSize/4. */\n seedRadius?: number;\n /** Whether cosmos auto-fits the view on init. Default: false (the core drives the camera). */\n fitViewOnInit?: boolean;\n /** Native point dragging (cosmos `enableDrag`). Default: true. */\n enableDrag?: boolean;\n /** Escape hatch: shallow-merged last into the cosmos constructor config. */\n initialConfig?: Record<string, unknown>;\n /**\n * Visible-time budget (ms) for the browser to restore a lost WebGL context\n * before an `engine:context-restore-deadline` diagnostic is emitted. The\n * deadline is observability only — a later restore still recovers.\n * Default: 10_000.\n */\n restoreDeadlineMs?: number;\n}\n\n/** cosmos' own default `spaceSize` (see @cosmos.gl/graph config defaults). */\nconst DEFAULT_SPACE_SIZE = 4096;\n\n/** Default visible-time budget before the restore-deadline diagnostic. */\nconst DEFAULT_RESTORE_DEADLINE_MS = 10_000;\n\n/** §8 image-atlas channel of an EngineCommit (adapter-local alias). */\ntype EngineResources = NonNullable<EngineCommit['resources']>;\n\nexport class CosmosEngine implements GraphEngine {\n readonly capabilities: EngineCapabilities = {\n // Evidence-backed S6 flip: the M0 probe measured native onLinkClick/\n // onLinkMouseOver delivering correct link indices with ~4px perpendicular\n // tolerance (docs/m0-conformance.json, `link-picking`).\n linkPicking: true,\n rangeUpdates: [],\n trackedPositions: true,\n simulation: true,\n // §16.12: cosmos 3.3.0 exposes the `linkDefaultArrows` config key\n // (config.d.ts) — instanced arrowheads toggle atomically via setConfigPartial.\n edgeArrows: true,\n // §8: cosmos 3.3.0 exposes setImageData(ImageData[]) +\n // setPointImageIndices(Float32Array) (index.d.ts) — per-point sprites via\n // an adapter-maintained slot→ImageData atlas.\n pointImages: true,\n // §16.3 stage 4: cosmos 3.3.0 ships a real GPU cluster force —\n // `setPointClusters((number|undefined)[])`, `setClusterPositions(\n // (number|undefined)[])`, `setPointClusterStrength(Float32Array)`\n // (index.d.ts) plus the `simulationCluster` coefficient (config.d.ts,\n // default 0.1) and the `Clusters` core module (dist/modules/Clusters).\n // `undefined` is cosmos' documented \"not in any cluster\" value, which the\n // adapter maps from the contract's NaN.\n clusterForce: true,\n // §17 stop-at-rest: cosmos 3.4.0 ships on-demand rendering — the M0\n // quiescence row measured 0 idle frames AND 0 rAF registrations per\n // 750ms at rest (docs/m0-conformance.md, was 91 on 3.3.0/ADR-002).\n // The adapter's own activity clock is gated to match (ADR-005).\n idleFrames: 'stops',\n // onFrame is an activity clock, not an exact post-draw hook — cosmos\n // still exposes no public frame hook (probe `post-draw-frames`);\n // overlays may lag one sample (ADR-002).\n postDrawFrames: false,\n };\n\n private readonly options: CosmosEngineOptions;\n private graph: CosmosGraph | null = null;\n private innerDiv: HTMLDivElement | null = null;\n private events: EngineHostEvents | null = null;\n /**\n * Pre-mount/lost-context commits collapse per channel and are applied as one\n * atomic commit once a usable graph exists.\n */\n private pendingCommit: EngineCommit | null = null;\n private applied: number | null = null;\n private destroyed = false;\n private mounting = false;\n /** Constructed graph whose `ready` promise has not settled yet. */\n private graphAwaitingReady: CosmosGraph | null = null;\n /** Guards every graph teardown, including async init/recovery races. */\n private readonly destroyedGraphs = new WeakSet<CosmosGraph>();\n /** Sticky override from EngineConfigUpdate.seedRadius. */\n private seedRadiusOverride: number | undefined;\n /** Point count of the last structure-bearing commit — the roster length a\n * `cluster: null` clear must write an all-unclustered array for (§16.3). */\n private lastPointCount = 0;\n /**\n * cosmos fires `onClick` (index undefined) AND `onBackgroundClick` for the\n * same background click; remembering the MouseEvent dedupes the null emit.\n */\n private lastNullClickEvent: unknown = null;\n /** Point latched at cosmos onDragStart; cleared when the gesture ends. */\n private dragIndex: number | null = null;\n /** Last hover reported by cosmos — fallback dragged-point source. */\n private lastHoverIndex: number | null = null;\n\n // --- adapter-owned GATED overlay/activity clock (see module header) ---\n\n /** rAF id of the pending activity-clock tick; null = clock not running. */\n private frameHandle: number | null = null;\n /** Window driving the clock, cached so stop works after the div detaches. */\n private frameWindow: Window | null = null;\n /** Continuous-run reasons; the clock free-runs while any is held. */\n private readonly runReasons = new Set<'sim' | 'drag' | 'transition'>();\n /** One-shot tick budget for write/interaction re-arm bursts. */\n private pendingTicks = 0;\n /** One-shot guard for the repulsionTheta deprecation diagnostic. */\n private repulsionThetaWarned = false;\n\n // --- WebGL context-loss recovery state (§13.1) ---\n\n /** cosmos' canvas (queried post-mount) carrying the webglcontext* listeners. */\n private canvas: HTMLCanvasElement | null = null;\n private contextLost = false;\n /** Terminal: GL reinitialization failed; commits stash inertly forever. */\n private failed = false;\n private deadline: RestoreDeadline | null = null;\n /** Graph constructor cached at mount so recovery never re-imports cosmos. */\n private cosmosCtor: (new (div: HTMLDivElement, config?: GraphConfig) => CosmosGraph) | null =\n null;\n\n // --- §8 image atlas (capability pointImages) ---\n\n /**\n * slot → ImageData mirror of the cosmos image atlas. ImageData is CPU-side,\n * so the mirror survives context loss — any post-restore atlas commit\n * re-uploads the FULL array to the fresh graph. `null` = removed (blank).\n */\n private imageSlots: (ImageData | null)[] = [];\n /** Lazily created 1×1 transparent entry filling removed/hole slots. */\n private blankImage: ImageData | null = null;\n /** One-shot guard for the `engine:image-channel-unavailable` diagnostic. */\n private imageChannelUnavailable = false;\n\n constructor(options: CosmosEngineOptions = {}) {\n this.options = options;\n }\n\n async mount(container: HTMLElement, events: EngineHostEvents): Promise<void> {\n if (this.destroyed) throw new Error('CosmosEngine: mount() after destroy()');\n if (this.mounting || this.graph) throw new Error('CosmosEngine: mount() may only be called once');\n this.mounting = true;\n this.events = events;\n\n // cosmos wants a dedicated HTMLDivElement filling the host container.\n const div = container.ownerDocument.createElement('div');\n div.style.width = '100%';\n div.style.height = '100%';\n container.appendChild(div);\n this.innerDiv = div;\n\n let graph: CosmosGraph | null = null;\n try {\n // §18: cosmos (and its WebGL dependencies) load only at mount time.\n const { Graph } = await import('@cosmos.gl/graph');\n // destroy() may have landed while the dynamic import was pending.\n if (this.destroyed) {\n div.remove();\n return;\n }\n graph = new Graph(div, this.buildInitialConfig());\n this.graphAwaitingReady = graph;\n await graph.ready;\n if (this.graphAwaitingReady === graph) this.graphAwaitingReady = null;\n if (this.destroyed) {\n // destroy() raced the async init; tear the graph down immediately.\n this.destroyGraphOnce(graph);\n div.remove();\n return;\n }\n this.graph = graph;\n this.cosmosCtor = Graph;\n this.attachContextListeners();\n // Documented degradation (M0): overlays ride an activity clock because\n // cosmos has no draw-phase hook. Emitted once, at mount only.\n events.onDiagnostic?.({\n code: 'engine:overlay-activity-clock',\n severity: 'info',\n message:\n 'CosmosEngine: cosmos exposes no draw-phase hook (postDrawFrames:false); ' +\n 'overlays ride an adapter-owned, idle-gated requestAnimationFrame activity ' +\n 'clock (stops at rest — idleFrames:stops) and may lag the canvas by one frame.',\n });\n // cosmos 3.4 keeps rendering when the FPS monitor is shown — that\n // silently defeats the idleFrames:'stops' declaration, so say so once.\n if ((this.options.initialConfig as GraphConfig | undefined)?.showFPSMonitor) {\n events.onDiagnostic?.({\n code: 'engine:fps-monitor-defeats-quiescence',\n severity: 'info',\n message:\n 'CosmosEngine: showFPSMonitor keeps cosmos rendering every frame; ' +\n 'stop-at-rest quiescence is disabled while it is shown.',\n });\n }\n // Gated clock: no unconditional start — cosmos draws its own init\n // frame; a short burst lets overlays sample it, then the clock stops\n // until a wake source (commit/sim/gesture) re-arms it.\n this.requestTicks(2);\n const pending = this.pendingCommit;\n this.pendingCommit = null;\n if (pending) this.applyCommit(graph, pending);\n } catch (err) {\n if (graph !== null) {\n if (this.graph === graph) {\n this.stopFrameLoop();\n this.detachContextListeners();\n this.graph = null;\n }\n if (this.graphAwaitingReady === graph) this.graphAwaitingReady = null;\n this.destroyGraphOnce(graph);\n }\n div.remove();\n if (this.innerDiv === div) this.innerDiv = null;\n // destroy() is terminal and already cleaned up the constructed graph;\n // a later ready rejection must not escape or notify stale hosts.\n if (this.destroyed) return;\n const error = err instanceof Error ? err : new Error(String(err));\n events.onError?.(error);\n throw error;\n }\n }\n\n commit(update: EngineCommit): void {\n if (this.destroyed) throw new Error('CosmosEngine: commit() after destroy()');\n const graph = this.activeGraph;\n if (!graph) {\n // Pre-mount, context-lost, or failed: retain the latest value of every\n // independently replaceable channel. The merged commit is flushed on\n // mount/restore (or remains inert forever after terminal failure).\n this.queueCommit(update);\n return;\n }\n this.applyCommit(graph, update);\n }\n\n appliedRevision(): number | null {\n return this.applied;\n }\n\n // --- camera ---\n // Every camera write re-arms the clock; ANIMATED moves then self-sustain\n // through cosmos' per-step onZoom events (each grants a fresh burst), so\n // no duration bookkeeping is needed here.\n\n fitView(opts?: FitViewOptions): void {\n this.activeGraph?.fitView(opts?.durationMs, opts?.padding);\n this.requestTicks(2);\n }\n\n zoom(factor: number, durationMs?: number): void {\n const graph = this.activeGraph;\n if (!graph) return;\n graph.setZoomLevel(graph.getZoomLevel() * factor, durationMs);\n this.requestTicks(2);\n }\n\n /**\n * REAL pan (the former zoom-only limitation is lifted — see module header):\n * when a target center is provided, one `setZoomTransformByPointPositions`\n * call centers space point (x, y) at EXACTLY the requested (or current)\n * zoom — `setViewport(p)` then `getViewport()` returns p, modulo cosmos'\n * d3 scaleExtent clamp. A missing x or y is filled from the current\n * viewport; zoom-only calls keep the `setZoomLevel` path (d3's scaleTo\n * preserves the current center). Instant unless `durationMs` is given —\n * cosmos' own default duration is 250 ms, which would animate context-\n * recovery replays.\n */\n setViewport(v: Partial<ViewportState>, opts?: { durationMs?: number }): void {\n const graph = this.activeGraph;\n if (!graph) return;\n if (v.x !== undefined || v.y !== undefined) {\n const current = v.x === undefined || v.y === undefined ? this.getViewport() : null;\n const x = v.x ?? current?.x;\n const y = v.y ?? current?.y;\n if (x !== undefined && y !== undefined) {\n graph.setZoomTransformByPointPositions(\n Float32Array.of(x, y),\n opts?.durationMs ?? 0,\n v.zoom ?? graph.getZoomLevel(),\n );\n this.requestTicks(2);\n return;\n }\n // No usable center (detached container): degrade to zoom-only below.\n }\n if (v.zoom !== undefined) graph.setZoomLevel(v.zoom, opts?.durationMs ?? 0);\n this.requestTicks(2);\n }\n\n getViewport(): ViewportState | null {\n const graph = this.activeGraph;\n const div = this.innerDiv;\n if (!graph || !div) return null;\n const [x, y] = graph.screenToSpacePosition([div.clientWidth / 2, div.clientHeight / 2]);\n return { x, y, zoom: graph.getZoomLevel() };\n }\n\n zoomToIndex(index: number, durationMs?: number): void {\n this.activeGraph?.zoomToPointByIndex(index, durationMs);\n this.requestTicks(2);\n }\n\n // --- simulation ---\n\n start(alpha?: number): void {\n // cosmos fires onSimulationStart (→ wake) — the direct wake covers a\n // callback wiring gap and is idempotent through the Set.\n this.wake('sim');\n this.activeGraph?.start(alpha);\n }\n\n pause(): void {\n this.sleep('sim');\n this.activeGraph?.pause();\n }\n\n // --- built-in interaction visuals ---\n\n setSelectedIndices(indices: readonly number[] | null): void {\n const graph = this.activeGraph;\n if (!graph) return;\n // cosmos 3.3 has no imperative select/unselect API; selection visuals are\n // config-driven — points NOT in `highlightedPointIndices` grey out, and an\n // explicit `undefined` resets the key (clears highlighting) per\n // setConfigPartial semantics.\n graph.setConfigPartial({\n highlightedPointIndices: indices === null ? undefined : Array.from(indices),\n } as unknown as GraphConfig);\n this.requestTicks(2); // §17 write re-arm: overlays sample the new state\n }\n\n setFocusedIndex(index: number | null): void {\n const graph = this.activeGraph;\n if (!graph) return;\n graph.setConfigPartial({\n focusedPointIndex: index === null ? undefined : index,\n } as unknown as GraphConfig);\n this.requestTicks(2);\n }\n\n // --- spatial queries & pinning (§13/§15) ---\n\n pointsInPolygon(screenPolygon: readonly [number, number][]): number[] {\n const graph = this.activeGraph;\n if (!graph) return [];\n // cosmos' findPointsInPolygon already expects SCREEN coordinates (0 to\n // canvas width/height per the 3.3.0 d.ts) — no conversion; copy the pairs\n // only to satisfy cosmos' mutable-signature and shield the caller's input.\n return graph.findPointsInPolygon(screenPolygon.map(([x, y]): [number, number] => [x, y]));\n }\n\n pointsInRect(screenRect: readonly [number, number, number, number]): number[] {\n const graph = this.activeGraph;\n if (!graph) return [];\n // cosmos' findPointsInRect expects SCREEN coordinates (0 to canvas\n // width/height — the same space as findPointsInPolygon per the 3.3.0\n // d.ts) as ordered corners [[left, top], [right, bottom]] (the dist flips\n // Y assuming that ordering) — normalize so any opposite-corner pair works.\n const [x0, y0, x1, y1] = screenRect;\n return graph.findPointsInRect([\n [Math.min(x0, x1), Math.min(y0, y1)],\n [Math.max(x0, x1), Math.max(y0, y1)],\n ]);\n }\n\n neighborIndices(index: number): number[] {\n const graph = this.activeGraph;\n if (!graph) return [];\n // cosmos dedupes but a self-loop can report the point as its own neighbor.\n return graph.getNeighboringPointIndices(index).filter((i) => i !== index);\n }\n\n screenToSpace(p: readonly [number, number]): [number, number] | null {\n const graph = this.activeGraph;\n return graph ? graph.screenToSpacePosition([p[0], p[1]]) : null;\n }\n\n spaceToScreen(p: readonly [number, number]): [number, number] | null {\n const graph = this.activeGraph;\n return graph ? graph.spaceToScreenPosition([p[0], p[1]]) : null;\n }\n\n setPinnedIndices(indices: readonly number[] | null): void {\n // Full-set replace, idempotent; null and [] both unpin all (cosmos treats\n // them identically). Pin re-application after recovery is core-owned.\n this.activeGraph?.setPinnedPoints(indices === null ? null : Array.from(indices));\n this.requestTicks(2);\n }\n\n // --- readback ---\n\n getPositions(): Float32Array | null {\n const graph = this.activeGraph;\n return graph ? Float32Array.from(graph.getPointPositions()) : null;\n }\n\n /**\n * Captures the cosmos canvas via the M0 same-tick method (see module\n * header): one rAF is scheduled and, inside that tick, the WebGL canvas is\n * drawn synchronously onto an offscreen 2D canvas (cosmos renders with\n * preserveDrawingBuffer:false, so the buffer is only readable same-tick).\n * Resolves null on any failure or unusable lifecycle state (pre-mount,\n * context lost/failed, destroyed, no 2D context, toBlob failure).\n */\n captureScreenshot(): Promise<Blob | null> {\n const graph = this.activeGraph;\n const canvas = graph ? this.canvas : null;\n const win = canvas?.ownerDocument.defaultView ?? null;\n if (!graph || !canvas || !win || typeof win.requestAnimationFrame !== 'function') {\n return Promise.resolve(null);\n }\n // Under on-demand rendering (cosmos >= 3.4) an idle scene draws nothing,\n // and with preserveDrawingBuffer:false an undrawn buffer reads blank —\n // render() is a visual mutator that schedules the frame our capture rAF\n // then samples same-tick.\n try {\n graph.render();\n } catch {\n return Promise.resolve(null);\n }\n return new Promise((resolve) => {\n win.requestAnimationFrame(() => {\n // Re-check: loss/destroy (or a restore swapping in a new canvas) may\n // have landed between scheduling and this tick.\n if (this.destroyed || !this.activeGraph || this.canvas !== canvas) {\n resolve(null);\n return;\n }\n try {\n const off = canvas.ownerDocument.createElement('canvas');\n off.width = canvas.width;\n off.height = canvas.height;\n const ctx = off.getContext('2d');\n if (!ctx) {\n resolve(null);\n return;\n }\n ctx.drawImage(canvas, 0, 0);\n off.toBlob((blob) => {\n resolve(blob);\n });\n } catch {\n resolve(null);\n }\n });\n });\n }\n\n destroy(): void {\n if (this.destroyed) return;\n // Set first: if a context-restore reinit is mid-await, it observes the\n // flag, destroys the graph it just built, and emits nothing.\n this.destroyed = true;\n this.stopFrameLoop();\n this.deadline?.cancel();\n this.deadline = null;\n this.detachContextListeners();\n const graph = this.graph;\n this.graph = null;\n this.destroyGraphOnce(graph);\n const awaiting = this.graphAwaitingReady;\n this.graphAwaitingReady = null;\n this.destroyGraphOnce(awaiting);\n this.innerDiv?.remove();\n this.innerDiv = null;\n this.events = null;\n this.pendingCommit = null;\n this.imageSlots = [];\n this.blankImage = null;\n }\n\n // --- gated overlay/activity clock (see module header) ---\n\n /**\n * One rAF tick of the gated activity clock. Ordering is load-bearing:\n * 1. the tick budget is consumed BEFORE the host callback runs, so work\n * scheduled from inside onFrame re-arms a fresh tick instead of being\n * coalesced away;\n * 2. the reschedule/stop decision is made BEFORE the host callback, so a\n * throwing host can never kill a should-keep-running clock (and a\n * stopping clock stays stopped even if the callback wakes it — the\n * wake starts a new loop via requestTicks/wake, not this handle).\n * Skips the callback (but keeps its schedule) while the document is hidden.\n */\n private readonly frameTick = (timeMs: number): void => {\n const win = this.frameWindow;\n if (!win || this.frameHandle === null) return;\n if (this.pendingTicks > 0) this.pendingTicks -= 1;\n const keepRunning = this.runReasons.size > 0 || this.pendingTicks > 0;\n this.frameHandle = keepRunning ? win.requestAnimationFrame(this.frameTick) : null;\n if (!keepRunning) this.frameWindow = null;\n if (!win.document.hidden) this.events?.onFrame?.(timeMs);\n };\n\n /** Hold the clock open for a continuous activity (sim/drag/transition). */\n private wake(reason: 'sim' | 'drag' | 'transition'): void {\n this.runReasons.add(reason);\n this.ensureFrameLoop();\n }\n\n /**\n * Release a continuous-run reason. ALWAYS grants one trailing tick: the\n * releasing activity's final GPU write lands after the current draw pass\n * (the upstream drag-release bug class), so overlays need one more sample.\n */\n private sleep(reason: 'sim' | 'drag' | 'transition'): void {\n this.runReasons.delete(reason);\n this.requestTicks(1);\n }\n\n /**\n * Grant a one-shot tick budget (write/interaction re-arm). Two ticks is\n * the standard write burst: ordering between this clock's rAF callback and\n * cosmos' internal render frame within one tick is unguaranteed, so the\n * second tick guarantees overlays sample post-draw state (consistent with\n * the documented may-lag-one-sample degradation).\n */\n private requestTicks(n: number): void {\n if (this.destroyed || this.contextLost || this.failed || !this.graph) return;\n this.pendingTicks = Math.max(this.pendingTicks, n);\n this.ensureFrameLoop();\n }\n\n private ensureFrameLoop(): void {\n if (this.destroyed || this.frameHandle !== null) return;\n const win = this.innerDiv?.ownerDocument.defaultView ?? null;\n // No window / no rAF (detached document, exotic embedder): no clock — the\n // engine keeps working, overlays simply get no ticks.\n if (!win || typeof win.requestAnimationFrame !== 'function') return;\n this.frameWindow = win;\n this.frameHandle = win.requestAnimationFrame(this.frameTick);\n }\n\n private stopFrameLoop(): void {\n if (this.frameHandle !== null) {\n this.frameWindow?.cancelAnimationFrame(this.frameHandle);\n this.frameHandle = null;\n }\n this.frameWindow = null;\n this.runReasons.clear();\n this.pendingTicks = 0;\n }\n\n // --- WebGL context-loss recovery (§13.1) ---\n\n /** The graph, unless it is unusable (context lost / terminally failed). */\n private get activeGraph(): CosmosGraph | null {\n return this.contextLost || this.failed ? null : this.graph;\n }\n\n /**\n * cosmos owns its canvas; we can only wire webglcontext* listeners after\n * init by querying it. A missing canvas downgrades to an info diagnostic —\n * the engine keeps working, just without context-loss recovery.\n */\n private attachContextListeners(): void {\n const canvas = this.innerDiv?.querySelector('canvas') ?? null;\n if (!canvas) {\n this.events?.onDiagnostic?.({\n code: 'engine:context-listeners-unavailable',\n severity: 'info',\n message:\n 'CosmosEngine: no <canvas> found in the cosmos container; WebGL context-loss recovery is disabled.',\n });\n return;\n }\n this.canvas = canvas;\n canvas.addEventListener('webglcontextlost', this.handleContextLost);\n canvas.addEventListener('webglcontextrestored', this.handleContextRestored);\n }\n\n private detachContextListeners(): void {\n const canvas = this.canvas;\n if (!canvas) return;\n canvas.removeEventListener('webglcontextlost', this.handleContextLost);\n canvas.removeEventListener('webglcontextrestored', this.handleContextRestored);\n this.canvas = null;\n }\n\n /** DOM listener: nothing may throw out of it. */\n private readonly handleContextLost = (event: Event): void => {\n try {\n // preventDefault signals the browser that restoration is wanted; it must\n // run even on states we otherwise ignore.\n event.preventDefault();\n if (this.destroyed || this.failed || this.contextLost) return;\n this.contextLost = true;\n // The GL machine is dead: pause the activity clock until recovery.\n this.stopFrameLoop();\n // Any in-flight gesture died with the context; drop its latched state.\n this.dragIndex = null;\n this.lastHoverIndex = null;\n try {\n this.graph?.pause();\n } catch {\n // pausing a dead-context graph is best-effort only\n }\n this.startRestoreDeadline();\n this.events?.onContextEvent?.({ type: 'lost' });\n } catch {\n // swallow: DOM listeners must never throw\n }\n };\n\n /** DOM listener: nothing may throw out of it (async work is caught below). */\n private readonly handleContextRestored = (): void => {\n if (this.destroyed || this.failed || !this.contextLost) return;\n this.reinitializeAfterRestore().catch((err: unknown) => {\n if (this.destroyed) return;\n this.failed = true;\n const error = err instanceof Error ? err : new Error(String(err));\n try {\n this.events?.onContextEvent?.({ type: 'failed', error });\n } catch {\n // swallow: host callback errors must not become unhandled rejections\n }\n });\n };\n\n /**\n * cosmos cannot reuse a restored context (its GPU resources are gone), so\n * recovery = tear down the old Graph and build a fresh one in the same div,\n * flush the stashed commit, and only then report `restored` — the core\n * re-commits the full scene in response.\n */\n private async reinitializeAfterRestore(): Promise<void> {\n this.deadline?.cancel();\n this.deadline = null;\n this.detachContextListeners();\n const oldGraph = this.graph;\n this.graph = null;\n this.destroyGraphOnce(oldGraph);\n const div = this.innerDiv;\n const Ctor = this.cosmosCtor;\n if (!div || !Ctor) return; // destroy() raced ahead of us\n const graph = new Ctor(div, this.buildInitialConfig());\n this.graphAwaitingReady = graph;\n try {\n await graph.ready;\n if (this.graphAwaitingReady === graph) this.graphAwaitingReady = null;\n if (this.destroyed) {\n // destroy() landed mid-reinit: tear down the new graph, emit nothing.\n this.destroyGraphOnce(graph);\n return;\n }\n\n // Activation is one failure boundary. If listener wiring, frame-loop\n // startup, pending-channel upload, or restored delivery throws, the\n // replacement must not survive as an inert failed graph.\n this.graph = graph;\n this.attachContextListeners(); // the new Graph made a new canvas\n this.contextLost = false;\n // Gated clock: the fresh graph starts paused; the stashed commit (and\n // the core's full replay after `restored`) re-arm via requestTicks —\n // no unconditional restart, no re-diagnostic.\n this.requestTicks(2);\n const pending = this.pendingCommit;\n this.pendingCommit = null;\n if (pending) this.applyCommit(graph, pending);\n // Emit only after the stashed commit is visible: `restored` promises a\n // commit-ready engine whose applied revision is consistent.\n this.events?.onContextEvent?.({ type: 'restored' });\n } catch (err) {\n if (this.graphAwaitingReady === graph) this.graphAwaitingReady = null;\n this.stopFrameLoop();\n if (this.graph === graph) {\n this.detachContextListeners();\n this.graph = null;\n }\n this.destroyGraphOnce(graph);\n throw err;\n }\n }\n\n private startRestoreDeadline(): void {\n const doc = this.canvas?.ownerDocument;\n if (!doc) return;\n const ms = this.options.restoreDeadlineMs ?? DEFAULT_RESTORE_DEADLINE_MS;\n const deadline = new RestoreDeadline(doc, ms, () => {\n // Observability only: listeners stay mounted, state is unchanged, and a\n // late restore still recovers.\n this.deadline = null;\n this.events?.onDiagnostic?.({\n code: 'engine:context-restore-deadline',\n severity: 'warning',\n message: `CosmosEngine: WebGL context was not restored within ${ms}ms of visible time.`,\n });\n });\n this.deadline = deadline;\n deadline.start();\n }\n\n // -------------------------------------------------------------------------\n\n /**\n * Coalesces partial commits without discarding independent channels. The\n * newest call supplies the visible revision; structure is one atomic\n * channel, buffers/config merge per field, and restart persists until a\n * later explicit directive (including `false`) replaces it.\n */\n private queueCommit(update: EngineCommit): void {\n const previous = this.pendingCommit;\n if (previous === null) {\n this.pendingCommit = update;\n return;\n }\n\n const merged: EngineCommit = { revision: update.revision };\n\n const structure = update.structure ?? previous.structure;\n if (structure !== undefined) merged.structure = structure;\n\n if (previous.buffers !== undefined || update.buffers !== undefined) {\n merged.buffers = { ...previous.buffers, ...update.buffers };\n }\n\n if (previous.config !== undefined || update.config !== undefined) {\n const config = { ...previous.config, ...update.config };\n if (\n previous.config?.simulation !== undefined ||\n update.config?.simulation !== undefined\n ) {\n config.simulation = {\n ...previous.config?.simulation,\n ...update.config?.simulation,\n };\n }\n merged.config = config;\n }\n\n if (previous.resources !== undefined || update.resources !== undefined) {\n merged.resources = mergeResources(previous.resources, update.resources);\n }\n\n // Contract (§13 EngineCommit): `restart: false` and an ABSENT restart are\n // equivalent no-ops (\"false/absent = keep state\") — so neither cancels a\n // pending queued restart directive; only a new {alpha} replaces it\n // (PR #8 follow-up: explicit false previously cancelled while queued).\n const restart =\n update.restart !== undefined && update.restart !== false\n ? update.restart\n : previous.restart;\n if (restart !== undefined) merged.restart = restart;\n\n this.pendingCommit = merged;\n }\n\n /** Invokes a graph's destructor at most once, even across async races. */\n private destroyGraphOnce(graph: CosmosGraph | null): void {\n if (graph === null || this.destroyedGraphs.has(graph)) return;\n this.destroyedGraphs.add(graph);\n try {\n graph.destroy();\n } catch {\n // Teardown is best-effort, but no later path may invoke it again.\n }\n }\n\n private get spaceSize(): number {\n // The escape hatch is applied last in the constructor config, so a\n // spaceSize there is what cosmos actually uses — mirror it for seeding.\n const fromInitial = this.options.initialConfig?.['spaceSize'];\n if (typeof fromInitial === 'number') return fromInitial;\n return this.options.spaceSize ?? DEFAULT_SPACE_SIZE;\n }\n\n private get seedRadius(): number {\n return this.seedRadiusOverride ?? this.options.seedRadius ?? this.spaceSize / 4;\n }\n\n private buildInitialConfig(): GraphConfig {\n const base: GraphConfig = {\n // Default false: the core owns the camera (fitView is driven explicitly).\n fitViewOnInit: this.options.fitViewOnInit ?? false,\n // cosmos 3.4 defaults this to true. Pinned OFF for the 3.4 upgrade:\n // occlusion culling changes which overlapping pixels draw, and the M5\n // pixel-diff thresholds (CHANGED_MIN/RESTORED_MAX) were tuned against\n // un-culled rendering. One variable at a time — flipping it is a\n // registered follow-up with its own threshold re-validation.\n pointOcclusionCulling: false,\n // Native point dragging; the core owns pin semantics on top (§16.3).\n enableDrag: this.options.enableDrag ?? true,\n onPointClick: (index, _position, event) => {\n this.events?.onPointClick?.(index, clickModifiers(event));\n },\n onBackgroundClick: (event) => {\n this.emitNullPointClick(event);\n },\n // onClick fires for every canvas click; an undefined index means no\n // point was hit (background clicks — link clicks arrive via onLinkClick).\n onClick: (index, _position, event) => {\n if (index === undefined) this.emitNullPointClick(event);\n },\n // Unified context-menu channel: fires exactly once per gesture (desktop\n // right-click AND touch long-press — cosmos synthesizes the latter);\n // the per-target onPoint/onLink/onBackgroundContextMenu callbacks fire\n // ADDITIONALLY for the same gesture, so only this one is wired (see\n // module header). index undefined = background (or a link).\n onContextMenu: (index, _position, event) => {\n this.handleContextMenu(index, event);\n },\n onPointMouseOver: (index) => {\n this.lastHoverIndex = index;\n this.requestTicks(1); // overlay resync (tooltip/ring anchors)\n this.events?.onPointHover?.(index);\n },\n onPointMouseOut: () => {\n this.lastHoverIndex = null;\n this.requestTicks(1);\n this.events?.onPointHover?.(null);\n },\n // Setting any onLink* callback enables cosmos' native link hit-testing.\n onLinkClick: (linkIndex) => {\n this.events?.onLinkClick?.(linkIndex);\n },\n onLinkMouseOver: (linkIndex) => {\n this.requestTicks(1);\n this.events?.onLinkHover?.(linkIndex);\n },\n onLinkMouseOut: () => {\n this.requestTicks(1);\n this.events?.onLinkHover?.(null);\n },\n onDragStart: () => {\n this.handleDragStart();\n },\n onDragEnd: (e) => {\n this.handleDragEnd(e);\n },\n onZoom: () => {\n // Per-event ticks rather than a paired start/end reason: d3-zoom\n // fires this every animation step of BOTH user gestures and\n // programmatic transitions, so the burst self-sustains for exactly\n // as long as the camera actually moves.\n this.requestTicks(2);\n this.emitViewportChange();\n },\n onZoomEnd: () => {\n this.requestTicks(2);\n this.emitViewportChange();\n },\n // --- gated-clock run reasons (§17 stop-at-rest, ADR-005) ---\n onSimulationStart: () => {\n this.wake('sim');\n },\n onSimulationUnpause: () => {\n this.wake('sim');\n },\n onSimulationPause: () => {\n this.sleep('sim');\n },\n onSimulationEnd: () => {\n this.sleep('sim');\n this.events?.onSimulationEnd?.();\n },\n onTransitionStart: () => {\n this.wake('transition');\n },\n onTransitionEnd: () => {\n this.sleep('transition');\n },\n };\n if (this.options.spaceSize !== undefined) base.spaceSize = this.options.spaceSize;\n // Escape hatch: shallow-merged last so callers can override anything\n // above — EXCEPT that callback keys defined on BOTH sides COMPOSE\n // (adapter's first, then the caller's) rather than clobber. The gated\n // clock's wake/sleep wiring and the host event channels live in these\n // callbacks; a caller supplying onSimulationStart/onZoom/onDragEnd/…\n // through initialConfig must not silently sever them (ADR-005).\n const extra = this.options.initialConfig as GraphConfig | undefined;\n if (!extra) return base;\n const merged: GraphConfig = { ...base, ...extra };\n for (const key of Object.keys(base)) {\n const ours = (base as Record<string, unknown>)[key];\n const theirs = (extra as Record<string, unknown>)[key];\n if (typeof ours === 'function' && typeof theirs === 'function') {\n (merged as Record<string, unknown>)[key] = (...args: unknown[]) => {\n (ours as (...a: unknown[]) => unknown)(...args);\n return (theirs as (...a: unknown[]) => unknown)(...args);\n };\n }\n }\n return merged;\n }\n\n /**\n * Maps cosmos' unified context-menu callback to the host event: index\n * undefined → null (background), MouseEvent client coords → container-\n * relative CSS px (the inner div fills the host container exactly). The\n * native event is preventDefault-ed so the browser menu never opens — but\n * only when the host actually registered onContextMenu (it always does in\n * Orbit: the core owns the typed 'contextMenu' event channel). cosmos'\n * desktop `contextmenu` handler already prevents the event itself; repeating\n * it is an idempotent no-op that also covers the touch long-press path\n * (where cosmos forwards the originating pointerdown event instead).\n */\n private handleContextMenu(index: number | undefined, event: MouseEvent): void {\n const events = this.events;\n if (!events?.onContextMenu) return;\n if (typeof event.preventDefault === 'function') event.preventDefault();\n const div = this.innerDiv;\n if (!div) return;\n const rect = div.getBoundingClientRect();\n events.onContextMenu(index ?? null, [event.clientX - rect.left, event.clientY - rect.top]);\n }\n\n /** Emits onPointClick(null) once per originating click event. */\n private emitNullPointClick(event: unknown): void {\n if (event != null && event === this.lastNullClickEvent) return;\n this.lastNullClickEvent = event ?? null;\n this.events?.onPointClick?.(null, clickModifiers(event));\n }\n\n /**\n * The D3 drag event carries no point index; cosmos assigns\n * `store.draggingPointIndex` right before invoking onDragStart (see module\n * header). The public onPointMouseOver stream is the fallback — cosmos only\n * starts a drag while a point is hovered.\n */\n private readDraggingIndex(): number | null {\n const store = (this.graph as unknown as { store?: CosmosStoreLike } | null)?.store;\n return store?.draggingPointIndex ?? store?.hoveredPoint?.index ?? this.lastHoverIndex;\n }\n\n private handleDragStart(): void {\n // Wake before the index resolution: the gesture is real (cosmos renders\n // it) even when the dragged-point fallback chain comes up empty.\n this.wake('drag');\n const index = this.readDraggingIndex();\n if (index === null) return;\n this.dragIndex = index;\n this.events?.onDragStart?.(index);\n }\n\n /**\n * Reports the dragged point's final SPACE position. cosmos' drag shader\n * pins the point to the mouse's space position every frame, so converting\n * the event's screen coords is exact and O(1) (see module header).\n */\n private handleDragEnd(e: { x: number; y: number }): void {\n // Release the run reason even when no index was latched — cosmos pairs\n // start/end, but a mid-gesture hover loss must not leak a held reason.\n this.sleep('drag');\n const index = this.dragIndex;\n this.dragIndex = null;\n if (index === null) return;\n const graph = this.activeGraph;\n if (!graph) return; // context died mid-gesture; the drag is dropped\n const [x, y] = graph.screenToSpacePosition([e.x, e.y]);\n this.events?.onDragEnd?.(index, x, y);\n }\n\n private emitViewportChange(): void {\n const viewport = this.getViewport();\n if (viewport) this.events?.onViewportChange?.(viewport);\n }\n\n /**\n * One visibly atomic update (§13): all channels and config are staged, then\n * exactly one render() draws them; restart reheats after the render.\n */\n private applyCommit(graph: CosmosGraph, update: EngineCommit): void {\n const { config, structure, buffers, resources, restart } = update;\n\n if (config) {\n if (config.seedRadius !== undefined) this.seedRadiusOverride = config.seedRadius;\n const partial: GraphConfig = {};\n if (config.backgroundColor !== undefined) partial.backgroundColor = config.backgroundColor;\n // §16.12 arrowheads: cosmos' `linkDefaultArrows` config key (3.3.0\n // config.d.ts) — a pure config toggle, no per-link buffer involved.\n if (config.linkArrows !== undefined) partial.linkDefaultArrows = config.linkArrows;\n // §16.13 link visibility: cosmos 3.3.0 has a first-class `renderLinks`\n // config key (config.d.ts, default true) — config-only, never a buffer\n // rebuild (no linkOpacity workaround needed).\n if (config.renderLinks !== undefined) partial.renderLinks = config.renderLinks;\n // §8 theme tokens: cosmos accepts CSS color strings natively.\n if (config.defaultPointColor !== undefined) {\n partial.pointDefaultColor = config.defaultPointColor;\n }\n if (config.defaultLinkColor !== undefined) {\n partial.linkDefaultColor = config.defaultLinkColor;\n }\n // §17 disable-transitions ladder step: 0 = atomic jumps; null restores\n // cosmos' own default (config.d.ts `transitionDuration`, 800ms).\n if (config.transitionDurationMs !== undefined) {\n partial.transitionDuration = config.transitionDurationMs ?? 800;\n }\n // §13 emphasis ring: cosmos' FOCUSED ring (config.d.ts\n // `focusedPointRingColor`; drawn whenever a focused index is set — no\n // boolean gate). Deliberately NOT `renderHoveredPointRing`: that would\n // draw a second ring from cosmos' own hover state, and the focused path\n // is what lets orbit choose the ringed node (keyboard nav, focusNode).\n if (config.emphasisRingColor !== undefined) {\n partial.focusedPointRingColor = config.emphasisRingColor;\n }\n const sim = config.simulation;\n if (sim) {\n if (sim.gravity !== undefined) partial.simulationGravity = sim.gravity;\n if (sim.repulsion !== undefined) partial.simulationRepulsion = sim.repulsion;\n if (sim.friction !== undefined) partial.simulationFriction = sim.friction;\n if (sim.linkDistance !== undefined) partial.simulationLinkDistance = sim.linkDistance;\n if (sim.linkSpring !== undefined) partial.simulationLinkSpring = sim.linkSpring;\n // §10 tunables added in v0.10.2 — each maps 1:1 onto a cosmos config\n // key; an omitted field is never written, so cosmos' own default\n // stands (config.d.ts `defaultConfigValues`).\n if (sim.decay !== undefined) partial.simulationDecay = sim.decay;\n if (sim.collision !== undefined) partial.simulationCollision = sim.collision;\n if (sim.collisionRadius !== undefined) {\n partial.simulationCollisionRadius = sim.collisionRadius;\n }\n if (sim.collisionPadding !== undefined) {\n partial.simulationCollisionPadding = sim.collisionPadding;\n }\n // cosmos >= 3.4 replaced Barnes-Hut many-body with grid-based\n // repulsion: `simulationRepulsionTheta` is deprecated and\n // NON-FUNCTIONAL. Sending it would misrepresent state, so the key is\n // not mapped; the host learns once instead of wondering silently.\n if (sim.repulsionTheta !== undefined && !this.repulsionThetaWarned) {\n this.repulsionThetaWarned = true;\n this.events?.onDiagnostic?.({\n code: 'engine:repulsion-theta-deprecated',\n severity: 'info',\n message:\n 'CosmosEngine: cosmos >= 3.4 uses grid-based repulsion; ' +\n 'simulation.repulsionTheta is ignored by this engine.',\n });\n }\n if (sim.center !== undefined) partial.simulationCenter = sim.center;\n if (sim.repulsionFromMouse !== undefined) {\n partial.simulationRepulsionFromMouse = sim.repulsionFromMouse;\n }\n }\n // §16.3 stage-4 cluster force: the scene-wide coefficient is cosmos'\n // `simulationCluster` config key (config.d.ts, default 0.1); membership\n // and centers are buffer-shaped and staged below.\n if (config.cluster != null && config.cluster.strength !== undefined) {\n partial.simulationCluster = config.cluster.strength;\n }\n if (Object.keys(partial).length > 0) graph.setConfigPartial(partial);\n }\n\n if (structure) {\n this.lastPointCount = structure.pointCount;\n graph.setPointPositions(this.withSeededPositions(structure.positions));\n // cosmos takes link endpoint indices as Float32Array; exact for < 2^24 points.\n graph.setLinks(Float32Array.from(structure.links));\n }\n\n // Staged AFTER the roster so cosmos sees a membership array matching the\n // point count of this same commit (I2), and before the single render().\n if (config && config.cluster !== undefined) this.applyClusterForce(graph, config.cluster);\n\n if (buffers) {\n // [0,1] RGBA floats — cosmos' native scale; pass through (see header note).\n if (buffers.pointColor) graph.setPointColors(buffers.pointColor);\n if (buffers.pointSize) graph.setPointSizes(buffers.pointSize);\n if (buffers.linkColor) graph.setLinkColors(buffers.linkColor);\n if (buffers.linkWidth) graph.setLinkWidths(buffers.linkWidth);\n }\n\n // §8 atlas resources are staged before the SAME render() as every other\n // channel, keeping the commit visibly atomic.\n if (resources) this.applyResources(graph, resources);\n\n graph.render();\n this.applied = update.revision;\n\n if (restart) graph.start(restart.alpha);\n // §17 write re-arm: the commit's render lands this tick; the burst lets\n // overlays sample the post-draw state. A restart additionally holds the\n // clock via the sim run reason (onSimulationStart → wake).\n if (restart) this.wake('sim');\n this.requestTicks(2);\n }\n\n /**\n * Applies the §16.3 stage-4 cluster force (capability `clusterForce`).\n *\n * Contract mapping, verified against the 3.3.0 dist (`index.d.ts`):\n * - `pointClusters` (Float32Array, NaN = unclustered) →\n * `setPointClusters((number | undefined)[])`, where cosmos' documented\n * \"does not belong to any cluster\" value is `undefined`;\n * - `centers` (Float32Array, `[x0,y0,x1,y1,…]`) →\n * `setClusterPositions((number | undefined)[])`; a non-finite entry means\n * \"no position\" and cosmos falls back to that cluster's centermass;\n * - `null` clears: an all-`undefined` array of the CURRENT roster length\n * (length must track the roster) plus empty cluster positions.\n * `strength` is the scene-wide `simulationCluster` config coefficient\n * applied in the config block, not the per-point\n * `setPointClusterStrength` buffer (Orbit's strength is scene-wide).\n */\n private applyClusterForce(\n graph: CosmosGraph,\n cluster: NonNullable<EngineCommit['config']>['cluster'],\n ): void {\n if (cluster == null) {\n graph.setPointClusters(new Array<number | undefined>(this.lastPointCount).fill(undefined));\n graph.setClusterPositions([]);\n return;\n }\n const source = cluster.pointClusters;\n const assignments = new Array<number | undefined>(source.length);\n for (let i = 0; i < source.length; i++) {\n const value = source[i]!;\n assignments[i] = Number.isFinite(value) ? value : undefined;\n }\n graph.setPointClusters(assignments);\n const centers = cluster.centers;\n if (centers !== undefined) {\n const positions = new Array<number | undefined>(centers.length);\n for (let i = 0; i < centers.length; i++) {\n const value = centers[i]!;\n positions[i] = Number.isFinite(value) ? value : undefined;\n }\n graph.setClusterPositions(positions);\n }\n }\n\n /**\n * Applies the §8 image-atlas channel: upserts convert ImageBitmap →\n * ImageData through an offscreen 2D canvas into the slot mirror, removals\n * blank their slot, and any atlas change re-uploads the FULL ImageData\n * array (cosmos' setImageData is whole-array only, matching\n * `rangeUpdates: []`). Environments without a usable 2D context (jsdom)\n * no-op the channel and report `engine:image-channel-unavailable` once —\n * never throw.\n */\n private applyResources(graph: CosmosGraph, resources: EngineResources): void {\n const atlas = resources.imageAtlas;\n if (atlas) {\n let dirty = false;\n let conversionFailed = false;\n if (atlas.upserts) {\n for (const { slot, bitmap } of atlas.upserts) {\n if (!Number.isInteger(slot) || slot < 0) continue;\n const data = this.canvasImageData(bitmap.width, bitmap.height, bitmap);\n if (data === null) {\n conversionFailed = true;\n continue;\n }\n while (this.imageSlots.length <= slot) this.imageSlots.push(null);\n this.imageSlots[slot] = data;\n dirty = true;\n }\n }\n if (atlas.removeSlots) {\n for (const slot of atlas.removeSlots) {\n // Only slots that currently hold an image need blanking.\n if (slot >= 0 && slot < this.imageSlots.length && this.imageSlots[slot] != null) {\n this.imageSlots[slot] = null;\n dirty = true;\n }\n }\n }\n if (conversionFailed) this.reportImageChannelUnavailable();\n if (dirty) {\n const blank = this.blankImage ?? (this.blankImage = this.canvasImageData(1, 1));\n if (blank === null) {\n this.reportImageChannelUnavailable();\n } else {\n // Array.from (not .map) so sparse holes also materialize as blanks.\n graph.setImageData(Array.from(this.imageSlots, (d) => d ?? blank));\n }\n }\n }\n // Indices into an atlas that can never be populated are meaningless —\n // once the channel is known-unavailable the whole channel no-ops.\n if (resources.pointImageIndex && !this.imageChannelUnavailable) {\n graph.setPointImageIndices(resources.pointImageIndex);\n }\n }\n\n /**\n * Reads an ImageData of the given size off an offscreen 2D canvas, drawing\n * `bitmap` onto it first when provided (ImageBitmap → ImageData transcode;\n * without a bitmap: a transparent blank). Returns null — never throws —\n * where no 2D context exists (jsdom without the canvas package).\n */\n private canvasImageData(width: number, height: number, bitmap?: ImageBitmap): ImageData | null {\n const doc = this.innerDiv?.ownerDocument;\n if (!doc || !(width > 0) || !(height > 0)) return null;\n try {\n const canvas = doc.createElement('canvas');\n canvas.width = width;\n canvas.height = height;\n const ctx = canvas.getContext('2d');\n if (!ctx) return null;\n if (bitmap) ctx.drawImage(bitmap, 0, 0);\n return ctx.getImageData(0, 0, width, height);\n } catch {\n return null;\n }\n }\n\n /** Documented degradation, reported at most once per engine instance. */\n private reportImageChannelUnavailable(): void {\n if (this.imageChannelUnavailable) return;\n this.imageChannelUnavailable = true;\n this.events?.onDiagnostic?.({\n code: 'engine:image-channel-unavailable',\n severity: 'warning',\n message:\n 'CosmosEngine: no 2D canvas context is available to convert ImageBitmap ' +\n 'atlas entries to ImageData; point images are disabled in this environment.',\n });\n }\n\n /**\n * Replaces NaN pairs (= \"no known position\", §7.3) with random points on a\n * ring of radius seedRadius around the space center. cosmos treats NaN\n * positions as *absent* points, so they must never reach setPointPositions.\n * Known positions pass through verbatim (same array when nothing to seed).\n */\n private withSeededPositions(positions: Float32Array): Float32Array {\n let needsSeeding = false;\n for (let i = 0; i < positions.length; i += 2) {\n if (Number.isNaN(positions[i]!) || Number.isNaN(positions[i + 1]!)) {\n needsSeeding = true;\n break;\n }\n }\n if (!needsSeeding) return positions;\n\n const out = Float32Array.from(positions);\n const center = this.spaceSize / 2;\n const radius = this.seedRadius;\n for (let i = 0; i < out.length; i += 2) {\n if (Number.isNaN(out[i]!) || Number.isNaN(out[i + 1]!)) {\n const angle = Math.random() * Math.PI * 2;\n out[i] = center + radius * Math.cos(angle);\n out[i + 1] = center + radius * Math.sin(angle);\n }\n }\n return out;\n }\n}\n\n/**\n * Per-channel merge for queued §8 resources (pre-mount / context-lost):\n * upserts union per slot (latest bitmap wins), a later remove drops an\n * earlier pending upsert of the same slot (and vice versa — folding order\n * mirrors applyResources: upserts before removes within each commit), and\n * the latest pointImageIndex replaces wholesale.\n */\nfunction mergeResources(\n previous: EngineCommit['resources'],\n update: EngineCommit['resources'],\n): EngineResources {\n const upsertBySlot = new Map<number, ImageBitmap>();\n const removes = new Set<number>();\n for (const atlas of [previous?.imageAtlas, update?.imageAtlas]) {\n if (!atlas) continue;\n for (const { slot, bitmap } of atlas.upserts ?? []) {\n upsertBySlot.set(slot, bitmap);\n removes.delete(slot);\n }\n for (const slot of atlas.removeSlots ?? []) {\n upsertBySlot.delete(slot);\n removes.add(slot);\n }\n }\n const merged: EngineResources = {};\n if (upsertBySlot.size > 0 || removes.size > 0) {\n const imageAtlas: NonNullable<EngineResources['imageAtlas']> = {};\n if (upsertBySlot.size > 0) {\n imageAtlas.upserts = Array.from(upsertBySlot, ([slot, bitmap]) => ({ slot, bitmap }));\n }\n if (removes.size > 0) imageAtlas.removeSlots = Array.from(removes);\n merged.imageAtlas = imageAtlas;\n }\n const pointImageIndex = update?.pointImageIndex ?? previous?.pointImageIndex;\n if (pointImageIndex !== undefined) merged.pointImageIndex = pointImageIndex;\n return merged;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/restoreDeadline.ts","../src/CosmosEngine.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * RestoreDeadline — a visibility-aware countdown used while a WebGL context is\n * lost. Browsers routinely defer `webglcontextrestored` for backgrounded tabs,\n * so the budget must only burn while the document is visible: hidden time is\n * banked (timer cleared, remaining ms kept) and the countdown re-arms from the\n * remainder when the tab becomes visible again.\n */\nexport class RestoreDeadline {\n private timer: ReturnType<typeof setTimeout> | null = null;\n /** Unspent budget in ms; recomputed each time the timer is disarmed. */\n private remaining: number;\n /** Timestamp when the current timer was armed (for banking on hide). */\n private armedAt = 0;\n private started = false;\n /** Terminal: set on expiry or cancel; guarantees onExpire fires at most once. */\n private done = false;\n\n private readonly handleVisibilityChange = (): void => {\n if (this.done) return;\n if (this.doc.visibilityState === 'visible') this.arm();\n else this.disarm();\n };\n\n constructor(\n private readonly doc: Document,\n ms: number,\n private readonly onExpire: () => void,\n ) {\n this.remaining = ms;\n }\n\n start(): void {\n if (this.done || this.started) return;\n this.started = true;\n this.doc.addEventListener('visibilitychange', this.handleVisibilityChange);\n if (this.doc.visibilityState === 'visible') this.arm();\n }\n\n cancel(): void {\n if (this.done) return;\n this.done = true;\n if (this.timer !== null) {\n globalThis.clearTimeout(this.timer);\n this.timer = null;\n }\n if (this.started) {\n this.doc.removeEventListener('visibilitychange', this.handleVisibilityChange);\n }\n }\n\n private arm(): void {\n if (this.timer !== null) return;\n this.armedAt = Date.now();\n this.timer = globalThis.setTimeout(() => {\n this.timer = null;\n this.done = true;\n this.doc.removeEventListener('visibilitychange', this.handleVisibilityChange);\n this.onExpire();\n }, this.remaining);\n }\n\n private disarm(): void {\n if (this.timer === null) return;\n globalThis.clearTimeout(this.timer);\n this.timer = null;\n this.remaining = Math.max(0, this.remaining - (Date.now() - this.armedAt));\n }\n}\n","/**\n * CosmosEngine — GraphEngine adapter over @cosmos.gl/graph (spec §13).\n *\n * Node-safe module: cosmos is loaded lazily via `await import()` inside\n * `mount()` (§18); module scope carries only type-only imports (erased at\n * runtime) and never touches the DOM.\n *\n * Color scale note: the EngineCommit contract carries RGBA floats in [0,1],\n * which is exactly cosmos' native scale (verified against the 3.3.0 dist:\n * hex config colors are parsed via /255 into 0–1 floats and setPointColors\n * input is fed to GPU buffers untouched) — so color buffers pass through.\n *\n * Interaction notes (verified against the 3.3.0 dist):\n * - Link picking is native: setting any onLink* config callback flips\n * cosmos' internal `isLinkHoveringEnabled` on, so wiring the callbacks in\n * `buildInitialConfig` is sufficient (no extra config flag exists).\n * - `findPointsInPolygon` takes SCREEN coordinates (\"from 0 to the\n * width/height of the canvas\" per dist/index.d.ts), so `pointsInPolygon`\n * passes the host's screen polygon through without conversion.\n * - `findPointsInRect` uses the SAME screen space and expects ordered\n * corners `[[left, top], [right, bottom]]` (the dist flips Y assuming that\n * ordering), so `pointsInRect` normalizes the host's [x0,y0,x1,y1] rect to\n * min/max corners and passes it through without conversion.\n * - Camera pan (S11 — the zoom-only limitation is LIFTED): cosmos 3.3 has no\n * pan-to API, but `setZoomTransformByPointPositions(positions, duration,\n * scale, padding)` (dist/index.d.ts) is an exact center+zoom when `scale`\n * is explicit. Derivation from the dist (`zoomInstance.getTransform`):\n * space→screen-at-k=1 goes through `store.scaleX/scaleY`, which are LINEAR\n * with slope ±1 (scaleX(x) = x + (w−S)/2; scaleY(y) = (S−y) + (h−S)/2,\n * S = adjustedSpaceSize, w/h = canvas size); a single-point bbox is widened\n * ±0.5 SYMMETRICALLY (center preserved); an explicit `scale` bypasses the\n * fit math and `padding` entirely — k = clamp(scale, d3 scaleExtent) and\n * the result is translate(w/2 − scaleX(x)·k, h/2 − scaleY(y)·k).scale(k),\n * i.e. space point (x, y) lands exactly at the screen center with\n * eventTransform.k = scale. Since `getZoomLevel()` returns eventTransform.k\n * and `getViewport()` reads screenToSpacePosition(screen center),\n * `setViewport({x, y, zoom})` → setZoomTransformByPointPositions(\n * Float32Array.of(x, y), durationMs ?? 0, zoom ?? getZoomLevel()) makes a\n * follow-up `getViewport()` return exactly {x, y, zoom} (modulo the\n * scaleExtent clamp). This also completes §13.1 recovery: the core replays\n * the full stored {x, y, zoom} through setViewport, so viewport restore is\n * no longer zoom-only.\n * - Context menu: cosmos fires the unified config `onContextMenu(index |\n * undefined, pos, event)` exactly ONCE per gesture — desktop right-click\n * (dist `onContextMenu(e)`) and touch/pen long-press (dist long-press timer\n * → `fireContextMenu`) both route through it — while the per-target\n * `onPointContextMenu`/`onLinkContextMenu`/`onBackgroundContextMenu`\n * callbacks fire ADDITIONALLY for the same gesture. Wiring only the unified\n * callback therefore avoids a double-report (same shape as the\n * onClick/onBackgroundClick dedupe). A context menu over a LINK arrives\n * with index undefined and is reported as background (the host event\n * carries node-or-background only).\n *\n * GATED overlay/activity clock (ADR-005; M0 evidence docs/m0-conformance.md):\n * cosmos still exposes no draw/render-phase hook (`postDrawFrames: false`),\n * so the adapter owns the single requestAnimationFrame loop that reports\n * `onFrame(timeMs)` to the host — an ACTIVITY clock, not a post-draw hook:\n * overlays may lag the canvas by one sample (reported once at mount via\n * `engine:overlay-activity-clock`). Since cosmos 3.4 idle-stops its own\n * rendering (on-demand rendering, quiescence probe: 0 idle frames/750ms),\n * this clock is GATED to match — it free-runs only while a run reason is\n * held (sim hot via onSimulationStart/Pause/Unpause/End, drag gestures,\n * cosmos transitions) and otherwise burns a small one-shot tick budget that\n * every visual write re-arms (commits, highlight/focus/pin setters, camera\n * moves, hover events; animated camera moves self-sustain through per-step\n * onZoom bursts). Releasing a run reason always grants ONE trailing tick —\n * the releasing activity's final GPU write lands after the current draw\n * pass. At rest: zero rAF registrations from cosmos AND from this adapter\n * (`capabilities.idleFrames: 'stops'`). The clock stops on context\n * loss/destroy, re-arms on recovery, and skips the callback (keeping its\n * schedule) while `document.hidden`.\n *\n * Screenshots use the M0 same-tick capture method (apps/spike/src/instrument.ts):\n * cosmos renders with preserveDrawingBuffer:false, so the WebGL buffer is only\n * readable via a synchronous drawImage inside the same rAF tick it was drawn —\n * `captureScreenshot` schedules one rAF, draws the cosmos canvas onto an\n * offscreen 2D canvas inside that tick, and resolves the Blob (null on any\n * failure or unusable lifecycle state).\n * - The D3 drag events carry NO point index (the drag subject is a bare\n * `{x, y}`); cosmos assigns `store.draggingPointIndex` immediately before\n * invoking `onDragStart`, so the adapter reads it there (see\n * `readDraggingIndex` for the public-callback fallback).\n * - During a drag, cosmos' drag shader hard-pins the dragged point's\n * position texture entry to the mouse's SPACE position every frame\n * (dist `drag()`: `pointPosition.rg = mousePos` where `mousePos` =\n * screenToSpace(pointer)). So the point's final space position equals\n * `screenToSpacePosition([event.x, event.y])` at drag end — an O(1) CPU\n * transform, chosen over `getPointPositions()` (full GPU readback).\n */\n\nimport type { Graph as CosmosGraph, GraphConfig } from '@cosmos.gl/graph';\nimport type {\n EngineCapabilities,\n EngineCommit,\n EngineHostEvents,\n FitViewOptions,\n GraphEngine,\n} from '@modernrelay/orbit-core/engine';\nimport { RestoreDeadline } from './restoreDeadline';\n\n/** Derived from the contract to avoid importing the core root barrel. */\ntype ViewportState = NonNullable<ReturnType<GraphEngine['getViewport']>>;\n\n/**\n * Structural view of cosmos' `graph.store` — private in the 3.3.0 d.ts but a\n * stable runtime field. `draggingPointIndex` is assigned right before cosmos\n * invokes `onDragStart` (verified in the dist), making it the authoritative\n * dragged-point source; `hoveredPoint` mirrors the public onPointMouseOver\n * payload.\n */\ninterface CosmosStoreLike {\n hoveredPoint?: { index: number; position: [number, number] };\n draggingPointIndex?: number;\n}\n\n/**\n * Extracts click modifiers from a cosmos-forwarded event. Duck-typed rather\n * than `instanceof MouseEvent`: node-safe and cross-realm-safe. Returns\n * undefined when the event carries no modifier state.\n */\nfunction clickModifiers(event: unknown): { metaKey: boolean; shiftKey: boolean } | undefined {\n const e = event as { metaKey?: unknown; shiftKey?: unknown } | null | undefined;\n if (e && typeof e.metaKey === 'boolean' && typeof e.shiftKey === 'boolean') {\n return { metaKey: e.metaKey, shiftKey: e.shiftKey };\n }\n return undefined;\n}\n\nexport interface CosmosEngineOptions {\n /** Simulation space size passed to cosmos (cosmos default: 4096). */\n spaceSize?: number;\n /** Ring radius for seeding unknown (NaN) positions. Default: spaceSize/4. */\n seedRadius?: number;\n /** Whether cosmos auto-fits the view on init. Default: false (the core drives the camera). */\n fitViewOnInit?: boolean;\n /** Native point dragging (cosmos `enableDrag`). Default: true. */\n enableDrag?: boolean;\n /** Escape hatch: shallow-merged last into the cosmos constructor config. */\n initialConfig?: Record<string, unknown>;\n /**\n * Visible-time budget (ms) for the browser to restore a lost WebGL context\n * before an `engine:context-restore-deadline` diagnostic is emitted. The\n * deadline is observability only — a later restore still recovers.\n * Default: 10_000.\n */\n restoreDeadlineMs?: number;\n}\n\n/** cosmos' own default `spaceSize` (see @cosmos.gl/graph config defaults). */\nconst DEFAULT_SPACE_SIZE = 4096;\n\n/** Default visible-time budget before the restore-deadline diagnostic. */\nconst DEFAULT_RESTORE_DEADLINE_MS = 10_000;\n\n/** §8 image-atlas channel of an EngineCommit (adapter-local alias). */\ntype EngineResources = NonNullable<EngineCommit['resources']>;\n\nexport class CosmosEngine implements GraphEngine {\n readonly capabilities: EngineCapabilities = {\n // Evidence-backed S6 flip: the M0 probe measured native onLinkClick/\n // onLinkMouseOver delivering correct link indices with ~4px perpendicular\n // tolerance (docs/m0-conformance.json, `link-picking`).\n linkPicking: true,\n rangeUpdates: [],\n trackedPositions: true,\n simulation: true,\n // §16.12: cosmos 3.3.0 exposes the `linkDefaultArrows` config key\n // (config.d.ts) — instanced arrowheads toggle atomically via setConfigPartial.\n edgeArrows: true,\n // §8: cosmos 3.3.0 exposes setImageData(ImageData[]) +\n // setPointImageIndices(Float32Array) (index.d.ts) — per-point sprites via\n // an adapter-maintained slot→ImageData atlas.\n pointImages: true,\n // §16.3 stage 4: cosmos 3.3.0 ships a real GPU cluster force —\n // `setPointClusters((number|undefined)[])`, `setClusterPositions(\n // (number|undefined)[])`, `setPointClusterStrength(Float32Array)`\n // (index.d.ts) plus the `simulationCluster` coefficient (config.d.ts,\n // default 0.1) and the `Clusters` core module (dist/modules/Clusters).\n // `undefined` is cosmos' documented \"not in any cluster\" value, which the\n // adapter maps from the contract's NaN.\n clusterForce: true,\n // §17 stop-at-rest: cosmos 3.4.0 ships on-demand rendering — the M0\n // quiescence row measured 0 idle frames AND 0 rAF registrations per\n // 750ms at rest (docs/m0-conformance.md, was 91 on 3.3.0/ADR-002).\n // The adapter's own activity clock is gated to match (ADR-005).\n idleFrames: 'stops',\n // onFrame is an activity clock, not an exact post-draw hook — cosmos\n // still exposes no public frame hook (probe `post-draw-frames`);\n // overlays may lag one sample (ADR-002).\n postDrawFrames: false,\n };\n\n private readonly options: CosmosEngineOptions;\n private graph: CosmosGraph | null = null;\n private innerDiv: HTMLDivElement | null = null;\n private events: EngineHostEvents | null = null;\n /**\n * Pre-mount/lost-context commits collapse per channel and are applied as one\n * atomic commit once a usable graph exists.\n */\n private pendingCommit: EngineCommit | null = null;\n private applied: number | null = null;\n private destroyed = false;\n private mounting = false;\n /** Constructed graph whose `ready` promise has not settled yet. */\n private graphAwaitingReady: CosmosGraph | null = null;\n /** Guards every graph teardown, including async init/recovery races. */\n private readonly destroyedGraphs = new WeakSet<CosmosGraph>();\n /** Sticky override from EngineConfigUpdate.seedRadius. */\n private seedRadiusOverride: number | undefined;\n /** Point count of the last structure-bearing commit — the roster length a\n * `cluster: null` clear must write an all-unclustered array for (§16.3). */\n private lastPointCount = 0;\n /**\n * cosmos fires `onClick` (index undefined) AND `onBackgroundClick` for the\n * same background click; remembering the MouseEvent dedupes the null emit.\n */\n private lastNullClickEvent: unknown = null;\n /** Point latched at cosmos onDragStart; cleared when the gesture ends. */\n private dragIndex: number | null = null;\n /** Last hover reported by cosmos — fallback dragged-point source. */\n private lastHoverIndex: number | null = null;\n /** Live native link hover (review P1: gates the unified onClick's\n * background interpretation — a hovered link owns the click). */\n private hoveredLinkIndex: number | null = null;\n\n // --- adapter-owned GATED overlay/activity clock (see module header) ---\n\n /** rAF id of the pending activity-clock tick; null = clock not running. */\n private frameHandle: number | null = null;\n /** Window driving the clock, cached so stop works after the div detaches. */\n private frameWindow: Window | null = null;\n /** Continuous-run reasons; the clock free-runs while any is held. */\n private readonly runReasons = new Set<'sim' | 'drag' | 'transition'>();\n /** One-shot tick budget for write/interaction re-arm bursts. */\n private pendingTicks = 0;\n /** One-shot guard for the repulsionTheta deprecation diagnostic. */\n private repulsionThetaWarned = false;\n\n // --- WebGL context-loss recovery state (§13.1) ---\n\n /** cosmos' canvas (queried post-mount) carrying the webglcontext* listeners. */\n private canvas: HTMLCanvasElement | null = null;\n private contextLost = false;\n /** Terminal: GL reinitialization failed; commits stash inertly forever. */\n private failed = false;\n private deadline: RestoreDeadline | null = null;\n /** Graph constructor cached at mount so recovery never re-imports cosmos. */\n private cosmosCtor: (new (div: HTMLDivElement, config?: GraphConfig) => CosmosGraph) | null =\n null;\n\n // --- §8 image atlas (capability pointImages) ---\n\n /**\n * slot → ImageData mirror of the cosmos image atlas. ImageData is CPU-side,\n * so the mirror survives context loss — any post-restore atlas commit\n * re-uploads the FULL array to the fresh graph. `null` = removed (blank).\n */\n private imageSlots: (ImageData | null)[] = [];\n /** Lazily created 1×1 transparent entry filling removed/hole slots. */\n private blankImage: ImageData | null = null;\n /** One-shot guard for the `engine:image-channel-unavailable` diagnostic. */\n private imageChannelUnavailable = false;\n\n constructor(options: CosmosEngineOptions = {}) {\n this.options = options;\n }\n\n async mount(container: HTMLElement, events: EngineHostEvents): Promise<void> {\n if (this.destroyed) throw new Error('CosmosEngine: mount() after destroy()');\n if (this.mounting || this.graph) throw new Error('CosmosEngine: mount() may only be called once');\n this.mounting = true;\n this.events = events;\n\n // cosmos wants a dedicated HTMLDivElement filling the host container.\n const div = container.ownerDocument.createElement('div');\n div.style.width = '100%';\n div.style.height = '100%';\n container.appendChild(div);\n this.innerDiv = div;\n\n let graph: CosmosGraph | null = null;\n try {\n // §18: cosmos (and its WebGL dependencies) load only at mount time.\n const { Graph } = await import('@cosmos.gl/graph');\n // destroy() may have landed while the dynamic import was pending.\n if (this.destroyed) {\n div.remove();\n return;\n }\n graph = new Graph(div, this.buildInitialConfig());\n this.graphAwaitingReady = graph;\n await graph.ready;\n if (this.graphAwaitingReady === graph) this.graphAwaitingReady = null;\n if (this.destroyed) {\n // destroy() raced the async init; tear the graph down immediately.\n this.destroyGraphOnce(graph);\n div.remove();\n return;\n }\n this.graph = graph;\n this.cosmosCtor = Graph;\n this.attachContextListeners();\n // Documented degradation (M0): overlays ride an activity clock because\n // cosmos has no draw-phase hook. Emitted once, at mount only.\n events.onDiagnostic?.({\n code: 'engine:overlay-activity-clock',\n severity: 'info',\n message:\n 'CosmosEngine: cosmos exposes no draw-phase hook (postDrawFrames:false); ' +\n 'overlays ride an adapter-owned, idle-gated requestAnimationFrame activity ' +\n 'clock (stops at rest — idleFrames:stops) and may lag the canvas by one frame.',\n });\n // cosmos 3.4 keeps rendering when the FPS monitor is shown — that\n // silently defeats the idleFrames:'stops' declaration, so say so once.\n if ((this.options.initialConfig as GraphConfig | undefined)?.showFPSMonitor) {\n events.onDiagnostic?.({\n code: 'engine:fps-monitor-defeats-quiescence',\n severity: 'info',\n message:\n 'CosmosEngine: showFPSMonitor keeps cosmos rendering every frame; ' +\n 'stop-at-rest quiescence is disabled while it is shown.',\n });\n }\n // Gated clock: no unconditional start — cosmos draws its own init\n // frame; a short burst lets overlays sample it, then the clock stops\n // until a wake source (commit/sim/gesture) re-arms it.\n this.requestTicks(2);\n const pending = this.pendingCommit;\n this.pendingCommit = null;\n if (pending) this.applyCommit(graph, pending);\n } catch (err) {\n if (graph !== null) {\n if (this.graph === graph) {\n this.stopFrameLoop();\n this.detachContextListeners();\n this.graph = null;\n }\n if (this.graphAwaitingReady === graph) this.graphAwaitingReady = null;\n this.destroyGraphOnce(graph);\n }\n div.remove();\n if (this.innerDiv === div) this.innerDiv = null;\n // destroy() is terminal and already cleaned up the constructed graph;\n // a later ready rejection must not escape or notify stale hosts.\n if (this.destroyed) return;\n const error = err instanceof Error ? err : new Error(String(err));\n events.onError?.(error);\n throw error;\n }\n }\n\n commit(update: EngineCommit): void {\n if (this.destroyed) throw new Error('CosmosEngine: commit() after destroy()');\n const graph = this.activeGraph;\n if (!graph) {\n // Pre-mount, context-lost, or failed: retain the latest value of every\n // independently replaceable channel. The merged commit is flushed on\n // mount/restore (or remains inert forever after terminal failure).\n this.queueCommit(update);\n return;\n }\n this.applyCommit(graph, update);\n }\n\n appliedRevision(): number | null {\n return this.applied;\n }\n\n // --- camera ---\n // Every camera write re-arms the clock; ANIMATED moves then self-sustain\n // through cosmos' per-step onZoom events (each grants a fresh burst), so\n // no duration bookkeeping is needed here.\n\n fitView(opts?: FitViewOptions): void {\n this.activeGraph?.fitView(opts?.durationMs, opts?.padding);\n this.requestTicks(2);\n }\n\n zoom(factor: number, durationMs?: number): void {\n const graph = this.activeGraph;\n if (!graph) return;\n graph.setZoomLevel(graph.getZoomLevel() * factor, durationMs);\n this.requestTicks(2);\n }\n\n /**\n * REAL pan (the former zoom-only limitation is lifted — see module header):\n * when a target center is provided, one `setZoomTransformByPointPositions`\n * call centers space point (x, y) at EXACTLY the requested (or current)\n * zoom — `setViewport(p)` then `getViewport()` returns p, modulo cosmos'\n * d3 scaleExtent clamp. A missing x or y is filled from the current\n * viewport; zoom-only calls keep the `setZoomLevel` path (d3's scaleTo\n * preserves the current center). Instant unless `durationMs` is given —\n * cosmos' own default duration is 250 ms, which would animate context-\n * recovery replays.\n */\n setViewport(v: Partial<ViewportState>, opts?: { durationMs?: number }): void {\n const graph = this.activeGraph;\n if (!graph) return;\n if (v.x !== undefined || v.y !== undefined) {\n const current = v.x === undefined || v.y === undefined ? this.getViewport() : null;\n const x = v.x ?? current?.x;\n const y = v.y ?? current?.y;\n if (x !== undefined && y !== undefined) {\n graph.setZoomTransformByPointPositions(\n Float32Array.of(x, y),\n opts?.durationMs ?? 0,\n v.zoom ?? graph.getZoomLevel(),\n );\n this.requestTicks(2);\n return;\n }\n // No usable center (detached container): degrade to zoom-only below.\n }\n if (v.zoom !== undefined) graph.setZoomLevel(v.zoom, opts?.durationMs ?? 0);\n this.requestTicks(2);\n }\n\n getViewport(): ViewportState | null {\n const graph = this.activeGraph;\n const div = this.innerDiv;\n if (!graph || !div) return null;\n const [x, y] = graph.screenToSpacePosition([div.clientWidth / 2, div.clientHeight / 2]);\n return { x, y, zoom: graph.getZoomLevel() };\n }\n\n zoomToIndex(index: number, durationMs?: number): void {\n this.activeGraph?.zoomToPointByIndex(index, durationMs);\n this.requestTicks(2);\n }\n\n // --- simulation ---\n\n start(alpha?: number): void {\n // cosmos fires onSimulationStart (→ wake) — the direct wake covers a\n // callback wiring gap and is idempotent through the Set.\n this.wake('sim');\n this.activeGraph?.start(alpha);\n }\n\n pause(): void {\n this.sleep('sim');\n this.activeGraph?.pause();\n }\n\n // --- built-in interaction visuals ---\n\n setSelectedIndices(indices: readonly number[] | null): void {\n const graph = this.activeGraph;\n if (!graph) return;\n // cosmos 3.3 has no imperative select/unselect API; selection visuals are\n // config-driven — points NOT in `highlightedPointIndices` grey out, and an\n // explicit `undefined` resets the key (clears highlighting) per\n // setConfigPartial semantics.\n graph.setConfigPartial({\n highlightedPointIndices: indices === null ? undefined : Array.from(indices),\n } as unknown as GraphConfig);\n this.requestTicks(2); // §17 write re-arm: overlays sample the new state\n }\n\n setFocusedIndex(index: number | null): void {\n const graph = this.activeGraph;\n if (!graph) return;\n graph.setConfigPartial({\n focusedPointIndex: index === null ? undefined : index,\n } as unknown as GraphConfig);\n this.requestTicks(2);\n }\n\n // --- spatial queries & pinning (§13/§15) ---\n\n pointsInPolygon(screenPolygon: readonly [number, number][]): number[] {\n const graph = this.activeGraph;\n if (!graph) return [];\n // cosmos' findPointsInPolygon already expects SCREEN coordinates (0 to\n // canvas width/height per the 3.3.0 d.ts) — no conversion; copy the pairs\n // only to satisfy cosmos' mutable-signature and shield the caller's input.\n return graph.findPointsInPolygon(screenPolygon.map(([x, y]): [number, number] => [x, y]));\n }\n\n pointsInRect(screenRect: readonly [number, number, number, number]): number[] {\n const graph = this.activeGraph;\n if (!graph) return [];\n // cosmos' findPointsInRect expects SCREEN coordinates (0 to canvas\n // width/height — the same space as findPointsInPolygon per the 3.3.0\n // d.ts) as ordered corners [[left, top], [right, bottom]] (the dist flips\n // Y assuming that ordering) — normalize so any opposite-corner pair works.\n const [x0, y0, x1, y1] = screenRect;\n return graph.findPointsInRect([\n [Math.min(x0, x1), Math.min(y0, y1)],\n [Math.max(x0, x1), Math.max(y0, y1)],\n ]);\n }\n\n neighborIndices(index: number): number[] {\n const graph = this.activeGraph;\n if (!graph) return [];\n // cosmos dedupes but a self-loop can report the point as its own neighbor.\n return graph.getNeighboringPointIndices(index).filter((i) => i !== index);\n }\n\n screenToSpace(p: readonly [number, number]): [number, number] | null {\n const graph = this.activeGraph;\n return graph ? graph.screenToSpacePosition([p[0], p[1]]) : null;\n }\n\n spaceToScreen(p: readonly [number, number]): [number, number] | null {\n const graph = this.activeGraph;\n return graph ? graph.spaceToScreenPosition([p[0], p[1]]) : null;\n }\n\n setPinnedIndices(indices: readonly number[] | null): void {\n // Full-set replace, idempotent; null and [] both unpin all (cosmos treats\n // them identically). Pin re-application after recovery is core-owned.\n this.activeGraph?.setPinnedPoints(indices === null ? null : Array.from(indices));\n this.requestTicks(2);\n }\n\n // --- readback ---\n\n getPositions(): Float32Array | null {\n const graph = this.activeGraph;\n return graph ? Float32Array.from(graph.getPointPositions()) : null;\n }\n\n /**\n * Captures the cosmos canvas via the M0 same-tick method (see module\n * header): one rAF is scheduled and, inside that tick, the WebGL canvas is\n * drawn synchronously onto an offscreen 2D canvas (cosmos renders with\n * preserveDrawingBuffer:false, so the buffer is only readable same-tick).\n * Resolves null on any failure or unusable lifecycle state (pre-mount,\n * context lost/failed, destroyed, no 2D context, toBlob failure).\n */\n captureScreenshot(): Promise<Blob | null> {\n const graph = this.activeGraph;\n const canvas = graph ? this.canvas : null;\n const win = canvas?.ownerDocument.defaultView ?? null;\n if (!graph || !canvas || !win || typeof win.requestAnimationFrame !== 'function') {\n return Promise.resolve(null);\n }\n // Under on-demand rendering (cosmos >= 3.4) an idle scene draws nothing,\n // and with preserveDrawingBuffer:false an undrawn buffer reads blank —\n // render() is a visual mutator that schedules the frame our capture rAF\n // then samples same-tick.\n try {\n graph.render();\n } catch {\n return Promise.resolve(null);\n }\n return new Promise((resolve) => {\n win.requestAnimationFrame(() => {\n // Re-check: loss/destroy (or a restore swapping in a new canvas) may\n // have landed between scheduling and this tick.\n if (this.destroyed || !this.activeGraph || this.canvas !== canvas) {\n resolve(null);\n return;\n }\n try {\n const off = canvas.ownerDocument.createElement('canvas');\n off.width = canvas.width;\n off.height = canvas.height;\n const ctx = off.getContext('2d');\n if (!ctx) {\n resolve(null);\n return;\n }\n ctx.drawImage(canvas, 0, 0);\n off.toBlob((blob) => {\n resolve(blob);\n });\n } catch {\n resolve(null);\n }\n });\n });\n }\n\n destroy(): void {\n if (this.destroyed) return;\n // Set first: if a context-restore reinit is mid-await, it observes the\n // flag, destroys the graph it just built, and emits nothing.\n this.destroyed = true;\n this.stopFrameLoop();\n this.deadline?.cancel();\n this.deadline = null;\n this.detachContextListeners();\n const graph = this.graph;\n this.graph = null;\n this.destroyGraphOnce(graph);\n const awaiting = this.graphAwaitingReady;\n this.graphAwaitingReady = null;\n this.destroyGraphOnce(awaiting);\n this.innerDiv?.remove();\n this.innerDiv = null;\n this.events = null;\n this.pendingCommit = null;\n this.imageSlots = [];\n this.blankImage = null;\n }\n\n // --- gated overlay/activity clock (see module header) ---\n\n /**\n * One rAF tick of the gated activity clock. Ordering is load-bearing:\n * 1. the tick budget is consumed BEFORE the host callback runs, so work\n * scheduled from inside onFrame re-arms a fresh tick instead of being\n * coalesced away;\n * 2. the reschedule/stop decision is made BEFORE the host callback, so a\n * throwing host can never kill a should-keep-running clock (and a\n * stopping clock stays stopped even if the callback wakes it — the\n * wake starts a new loop via requestTicks/wake, not this handle).\n * Skips the callback (but keeps its schedule) while the document is hidden.\n */\n private readonly frameTick = (timeMs: number): void => {\n const win = this.frameWindow;\n if (!win || this.frameHandle === null) return;\n if (this.pendingTicks > 0) this.pendingTicks -= 1;\n const keepRunning = this.runReasons.size > 0 || this.pendingTicks > 0;\n this.frameHandle = keepRunning ? win.requestAnimationFrame(this.frameTick) : null;\n if (!keepRunning) this.frameWindow = null;\n if (!win.document.hidden) this.events?.onFrame?.(timeMs);\n };\n\n /** Hold the clock open for a continuous activity (sim/drag/transition). */\n private wake(reason: 'sim' | 'drag' | 'transition'): void {\n this.runReasons.add(reason);\n this.ensureFrameLoop();\n }\n\n /**\n * Release a continuous-run reason. ALWAYS grants one trailing tick: the\n * releasing activity's final GPU write lands after the current draw pass\n * (the upstream drag-release bug class), so overlays need one more sample.\n */\n private sleep(reason: 'sim' | 'drag' | 'transition'): void {\n this.runReasons.delete(reason);\n this.requestTicks(1);\n }\n\n /**\n * Grant a one-shot tick budget (write/interaction re-arm). Two ticks is\n * the standard write burst: ordering between this clock's rAF callback and\n * cosmos' internal render frame within one tick is unguaranteed, so the\n * second tick guarantees overlays sample post-draw state (consistent with\n * the documented may-lag-one-sample degradation).\n */\n private requestTicks(n: number): void {\n if (this.destroyed || this.contextLost || this.failed || !this.graph) return;\n this.pendingTicks = Math.max(this.pendingTicks, n);\n this.ensureFrameLoop();\n }\n\n private ensureFrameLoop(): void {\n if (this.destroyed || this.frameHandle !== null) return;\n const win = this.innerDiv?.ownerDocument.defaultView ?? null;\n // No window / no rAF (detached document, exotic embedder): no clock — the\n // engine keeps working, overlays simply get no ticks.\n if (!win || typeof win.requestAnimationFrame !== 'function') return;\n this.frameWindow = win;\n this.frameHandle = win.requestAnimationFrame(this.frameTick);\n }\n\n private stopFrameLoop(): void {\n if (this.frameHandle !== null) {\n this.frameWindow?.cancelAnimationFrame(this.frameHandle);\n this.frameHandle = null;\n }\n this.frameWindow = null;\n this.runReasons.clear();\n this.pendingTicks = 0;\n }\n\n // --- WebGL context-loss recovery (§13.1) ---\n\n /** The graph, unless it is unusable (context lost / terminally failed). */\n private get activeGraph(): CosmosGraph | null {\n return this.contextLost || this.failed ? null : this.graph;\n }\n\n /**\n * cosmos owns its canvas; we can only wire webglcontext* listeners after\n * init by querying it. A missing canvas downgrades to an info diagnostic —\n * the engine keeps working, just without context-loss recovery.\n */\n private attachContextListeners(): void {\n const canvas = this.innerDiv?.querySelector('canvas') ?? null;\n if (!canvas) {\n this.events?.onDiagnostic?.({\n code: 'engine:context-listeners-unavailable',\n severity: 'info',\n message:\n 'CosmosEngine: no <canvas> found in the cosmos container; WebGL context-loss recovery is disabled.',\n });\n return;\n }\n this.canvas = canvas;\n canvas.addEventListener('webglcontextlost', this.handleContextLost);\n canvas.addEventListener('webglcontextrestored', this.handleContextRestored);\n }\n\n private detachContextListeners(): void {\n const canvas = this.canvas;\n if (!canvas) return;\n canvas.removeEventListener('webglcontextlost', this.handleContextLost);\n canvas.removeEventListener('webglcontextrestored', this.handleContextRestored);\n this.canvas = null;\n }\n\n /** DOM listener: nothing may throw out of it. */\n private readonly handleContextLost = (event: Event): void => {\n try {\n // preventDefault signals the browser that restoration is wanted; it must\n // run even on states we otherwise ignore.\n event.preventDefault();\n if (this.destroyed || this.failed || this.contextLost) return;\n this.contextLost = true;\n // The GL machine is dead: pause the activity clock until recovery.\n this.stopFrameLoop();\n // Any in-flight gesture died with the context; drop its latched state.\n this.dragIndex = null;\n this.lastHoverIndex = null;\n try {\n this.graph?.pause();\n } catch {\n // pausing a dead-context graph is best-effort only\n }\n this.startRestoreDeadline();\n this.events?.onContextEvent?.({ type: 'lost' });\n } catch {\n // swallow: DOM listeners must never throw\n }\n };\n\n /** DOM listener: nothing may throw out of it (async work is caught below). */\n private readonly handleContextRestored = (): void => {\n if (this.destroyed || this.failed || !this.contextLost) return;\n this.reinitializeAfterRestore().catch((err: unknown) => {\n if (this.destroyed) return;\n this.failed = true;\n const error = err instanceof Error ? err : new Error(String(err));\n try {\n this.events?.onContextEvent?.({ type: 'failed', error });\n } catch {\n // swallow: host callback errors must not become unhandled rejections\n }\n });\n };\n\n /**\n * cosmos cannot reuse a restored context (its GPU resources are gone), so\n * recovery = tear down the old Graph and build a fresh one in the same div,\n * flush the stashed commit, and only then report `restored` — the core\n * re-commits the full scene in response.\n */\n private async reinitializeAfterRestore(): Promise<void> {\n this.deadline?.cancel();\n this.deadline = null;\n this.detachContextListeners();\n const oldGraph = this.graph;\n this.graph = null;\n this.destroyGraphOnce(oldGraph);\n const div = this.innerDiv;\n const Ctor = this.cosmosCtor;\n if (!div || !Ctor) return; // destroy() raced ahead of us\n const graph = new Ctor(div, this.buildInitialConfig());\n this.graphAwaitingReady = graph;\n try {\n await graph.ready;\n if (this.graphAwaitingReady === graph) this.graphAwaitingReady = null;\n if (this.destroyed) {\n // destroy() landed mid-reinit: tear down the new graph, emit nothing.\n this.destroyGraphOnce(graph);\n return;\n }\n\n // Activation is one failure boundary. If listener wiring, frame-loop\n // startup, pending-channel upload, or restored delivery throws, the\n // replacement must not survive as an inert failed graph.\n this.graph = graph;\n this.attachContextListeners(); // the new Graph made a new canvas\n this.contextLost = false;\n // Gated clock: the fresh graph starts paused; the stashed commit (and\n // the core's full replay after `restored`) re-arm via requestTicks —\n // no unconditional restart, no re-diagnostic.\n this.requestTicks(2);\n const pending = this.pendingCommit;\n this.pendingCommit = null;\n if (pending) this.applyCommit(graph, pending);\n // Emit only after the stashed commit is visible: `restored` promises a\n // commit-ready engine whose applied revision is consistent.\n this.events?.onContextEvent?.({ type: 'restored' });\n } catch (err) {\n if (this.graphAwaitingReady === graph) this.graphAwaitingReady = null;\n this.stopFrameLoop();\n if (this.graph === graph) {\n this.detachContextListeners();\n this.graph = null;\n }\n this.destroyGraphOnce(graph);\n throw err;\n }\n }\n\n private startRestoreDeadline(): void {\n const doc = this.canvas?.ownerDocument;\n if (!doc) return;\n const ms = this.options.restoreDeadlineMs ?? DEFAULT_RESTORE_DEADLINE_MS;\n const deadline = new RestoreDeadline(doc, ms, () => {\n // Observability only: listeners stay mounted, state is unchanged, and a\n // late restore still recovers.\n this.deadline = null;\n this.events?.onDiagnostic?.({\n code: 'engine:context-restore-deadline',\n severity: 'warning',\n message: `CosmosEngine: WebGL context was not restored within ${ms}ms of visible time.`,\n });\n });\n this.deadline = deadline;\n deadline.start();\n }\n\n // -------------------------------------------------------------------------\n\n /**\n * Coalesces partial commits without discarding independent channels. The\n * newest call supplies the visible revision; structure is one atomic\n * channel, buffers/config merge per field, and restart persists until a\n * later explicit directive (including `false`) replaces it.\n */\n private queueCommit(update: EngineCommit): void {\n const previous = this.pendingCommit;\n if (previous === null) {\n this.pendingCommit = update;\n return;\n }\n\n const merged: EngineCommit = { revision: update.revision };\n\n const structure = update.structure ?? previous.structure;\n if (structure !== undefined) merged.structure = structure;\n\n if (previous.buffers !== undefined || update.buffers !== undefined) {\n merged.buffers = { ...previous.buffers, ...update.buffers };\n }\n\n if (previous.config !== undefined || update.config !== undefined) {\n const config = { ...previous.config, ...update.config };\n if (\n previous.config?.simulation !== undefined ||\n update.config?.simulation !== undefined\n ) {\n config.simulation = {\n ...previous.config?.simulation,\n ...update.config?.simulation,\n };\n }\n merged.config = config;\n }\n\n if (previous.resources !== undefined || update.resources !== undefined) {\n merged.resources = mergeResources(previous.resources, update.resources);\n }\n\n // Contract (§13 EngineCommit): `restart: false` and an ABSENT restart are\n // equivalent no-ops (\"false/absent = keep state\") — so neither cancels a\n // pending queued restart directive; only a new {alpha} replaces it\n // (PR #8 follow-up: explicit false previously cancelled while queued).\n const restart =\n update.restart !== undefined && update.restart !== false\n ? update.restart\n : previous.restart;\n if (restart !== undefined) merged.restart = restart;\n\n this.pendingCommit = merged;\n }\n\n /** Invokes a graph's destructor at most once, even across async races. */\n private destroyGraphOnce(graph: CosmosGraph | null): void {\n if (graph === null || this.destroyedGraphs.has(graph)) return;\n this.destroyedGraphs.add(graph);\n try {\n graph.destroy();\n } catch {\n // Teardown is best-effort, but no later path may invoke it again.\n }\n }\n\n private get spaceSize(): number {\n // The escape hatch is applied last in the constructor config, so a\n // spaceSize there is what cosmos actually uses — mirror it for seeding.\n const fromInitial = this.options.initialConfig?.['spaceSize'];\n if (typeof fromInitial === 'number') return fromInitial;\n return this.options.spaceSize ?? DEFAULT_SPACE_SIZE;\n }\n\n private get seedRadius(): number {\n return this.seedRadiusOverride ?? this.options.seedRadius ?? this.spaceSize / 4;\n }\n\n private buildInitialConfig(): GraphConfig {\n const base: GraphConfig = {\n // Default false: the core owns the camera (fitView is driven explicitly).\n fitViewOnInit: this.options.fitViewOnInit ?? false,\n // cosmos 3.4 defaults this to true. Pinned OFF for the 3.4 upgrade:\n // occlusion culling changes which overlapping pixels draw, and the M5\n // pixel-diff thresholds (CHANGED_MIN/RESTORED_MAX) were tuned against\n // un-culled rendering. One variable at a time — flipping it is a\n // registered follow-up with its own threshold re-validation.\n pointOcclusionCulling: false,\n // Native point dragging; the core owns pin semantics on top (§16.3).\n enableDrag: this.options.enableDrag ?? true,\n onPointClick: (index, _position, event) => {\n this.events?.onPointClick?.(index, clickModifiers(event));\n },\n onBackgroundClick: (event) => {\n // Same review-P1 guard as the unified onClick below: a hovered link\n // owns the gesture regardless of which cosmos channel reports it.\n if (this.hoveredLinkIndex === null) this.emitNullPointClick(event);\n },\n // onClick fires for every canvas click; an undefined index means no\n // point was hit (background clicks — link clicks arrive via onLinkClick).\n onClick: (index, _position, event) => {\n // Review P1: a LINK click also reaches here with index undefined\n // (no POINT was hit), so treating every undefined as background\n // cleared selection on every edge click. A hovered link means the\n // gesture targets the link — cosmos's ~4px hover tolerance IS its\n // click tolerance — and onLinkClick delivers it; only a no-point,\n // no-link click is background.\n if (index === undefined && this.hoveredLinkIndex === null) {\n this.emitNullPointClick(event);\n }\n },\n // Unified context-menu channel: fires exactly once per gesture (desktop\n // right-click AND touch long-press — cosmos synthesizes the latter);\n // the per-target onPoint/onLink/onBackgroundContextMenu callbacks fire\n // ADDITIONALLY for the same gesture, so only this one is wired (see\n // module header). index undefined = background (or a link).\n onContextMenu: (index, _position, event) => {\n this.handleContextMenu(index, event);\n },\n onPointMouseOver: (index) => {\n this.lastHoverIndex = index;\n this.requestTicks(1); // overlay resync (tooltip/ring anchors)\n this.events?.onPointHover?.(index);\n },\n onPointMouseOut: () => {\n this.lastHoverIndex = null;\n this.requestTicks(1);\n this.events?.onPointHover?.(null);\n },\n // Setting any onLink* callback enables cosmos' native link hit-testing.\n onLinkClick: (linkIndex) => {\n this.events?.onLinkClick?.(linkIndex);\n },\n onLinkMouseOver: (linkIndex) => {\n this.hoveredLinkIndex = linkIndex;\n this.requestTicks(1);\n this.events?.onLinkHover?.(linkIndex);\n },\n onLinkMouseOut: () => {\n this.hoveredLinkIndex = null;\n this.requestTicks(1);\n this.events?.onLinkHover?.(null);\n },\n onDragStart: () => {\n this.handleDragStart();\n },\n onDragEnd: (e) => {\n this.handleDragEnd(e);\n },\n onZoom: () => {\n // Per-event ticks rather than a paired start/end reason: d3-zoom\n // fires this every animation step of BOTH user gestures and\n // programmatic transitions, so the burst self-sustains for exactly\n // as long as the camera actually moves.\n this.requestTicks(2);\n this.emitViewportChange();\n },\n onZoomEnd: () => {\n this.requestTicks(2);\n this.emitViewportChange();\n },\n // --- gated-clock run reasons (§17 stop-at-rest, ADR-005) ---\n onSimulationStart: () => {\n this.wake('sim');\n },\n onSimulationUnpause: () => {\n this.wake('sim');\n },\n onSimulationPause: () => {\n this.sleep('sim');\n },\n onSimulationEnd: () => {\n this.sleep('sim');\n this.events?.onSimulationEnd?.();\n },\n onTransitionStart: () => {\n this.wake('transition');\n },\n onTransitionEnd: () => {\n this.sleep('transition');\n },\n };\n if (this.options.spaceSize !== undefined) base.spaceSize = this.options.spaceSize;\n // Escape hatch: shallow-merged last so callers can override anything\n // above — EXCEPT that callback keys defined on BOTH sides COMPOSE\n // (adapter's first, then the caller's) rather than clobber. The gated\n // clock's wake/sleep wiring and the host event channels live in these\n // callbacks; a caller supplying onSimulationStart/onZoom/onDragEnd/…\n // through initialConfig must not silently sever them (ADR-005).\n const extra = this.options.initialConfig as GraphConfig | undefined;\n if (!extra) return base;\n const merged: GraphConfig = { ...base, ...extra };\n for (const key of Object.keys(base)) {\n const ours = (base as Record<string, unknown>)[key];\n const theirs = (extra as Record<string, unknown>)[key];\n if (typeof ours === 'function' && typeof theirs === 'function') {\n (merged as Record<string, unknown>)[key] = (...args: unknown[]) => {\n (ours as (...a: unknown[]) => unknown)(...args);\n return (theirs as (...a: unknown[]) => unknown)(...args);\n };\n }\n }\n return merged;\n }\n\n /**\n * Maps cosmos' unified context-menu callback to the host event: index\n * undefined → null (background), MouseEvent client coords → container-\n * relative CSS px (the inner div fills the host container exactly). The\n * native event is preventDefault-ed so the browser menu never opens — but\n * only when the host actually registered onContextMenu (it always does in\n * Orbit: the core owns the typed 'contextMenu' event channel). cosmos'\n * desktop `contextmenu` handler already prevents the event itself; repeating\n * it is an idempotent no-op that also covers the touch long-press path\n * (where cosmos forwards the originating pointerdown event instead).\n */\n private handleContextMenu(index: number | undefined, event: MouseEvent): void {\n const events = this.events;\n if (!events?.onContextMenu) return;\n if (typeof event.preventDefault === 'function') event.preventDefault();\n const div = this.innerDiv;\n if (!div) return;\n const rect = div.getBoundingClientRect();\n events.onContextMenu(index ?? null, [event.clientX - rect.left, event.clientY - rect.top]);\n }\n\n /** Emits onPointClick(null) once per originating click event. */\n private emitNullPointClick(event: unknown): void {\n if (event != null && event === this.lastNullClickEvent) return;\n this.lastNullClickEvent = event ?? null;\n this.events?.onPointClick?.(null, clickModifiers(event));\n }\n\n /**\n * The D3 drag event carries no point index; cosmos assigns\n * `store.draggingPointIndex` right before invoking onDragStart (see module\n * header). The public onPointMouseOver stream is the fallback — cosmos only\n * starts a drag while a point is hovered.\n */\n private readDraggingIndex(): number | null {\n const store = (this.graph as unknown as { store?: CosmosStoreLike } | null)?.store;\n return store?.draggingPointIndex ?? store?.hoveredPoint?.index ?? this.lastHoverIndex;\n }\n\n private handleDragStart(): void {\n // Wake before the index resolution: the gesture is real (cosmos renders\n // it) even when the dragged-point fallback chain comes up empty.\n this.wake('drag');\n const index = this.readDraggingIndex();\n if (index === null) return;\n this.dragIndex = index;\n this.events?.onDragStart?.(index);\n }\n\n /**\n * Reports the dragged point's final SPACE position. cosmos' drag shader\n * pins the point to the mouse's space position every frame, so converting\n * the event's screen coords is exact and O(1) (see module header).\n */\n private handleDragEnd(e: { x: number; y: number }): void {\n // Release the run reason even when no index was latched — cosmos pairs\n // start/end, but a mid-gesture hover loss must not leak a held reason.\n this.sleep('drag');\n const index = this.dragIndex;\n this.dragIndex = null;\n if (index === null) return;\n const graph = this.activeGraph;\n if (!graph) return; // context died mid-gesture; the drag is dropped\n const [x, y] = graph.screenToSpacePosition([e.x, e.y]);\n this.events?.onDragEnd?.(index, x, y);\n }\n\n private emitViewportChange(): void {\n const viewport = this.getViewport();\n if (viewport) this.events?.onViewportChange?.(viewport);\n }\n\n /**\n * One visibly atomic update (§13): all channels and config are staged, then\n * exactly one render() draws them; restart reheats after the render.\n */\n private applyCommit(graph: CosmosGraph, update: EngineCommit): void {\n const { config, structure, buffers, resources, restart } = update;\n\n if (config) {\n if (config.seedRadius !== undefined) this.seedRadiusOverride = config.seedRadius;\n const partial: GraphConfig = {};\n if (config.backgroundColor !== undefined) partial.backgroundColor = config.backgroundColor;\n // §16.12 arrowheads: cosmos' `linkDefaultArrows` config key (3.3.0\n // config.d.ts) — a pure config toggle, no per-link buffer involved.\n if (config.linkArrows !== undefined) partial.linkDefaultArrows = config.linkArrows;\n // §16.13 link visibility: cosmos 3.3.0 has a first-class `renderLinks`\n // config key (config.d.ts, default true) — config-only, never a buffer\n // rebuild (no linkOpacity workaround needed).\n if (config.renderLinks !== undefined) partial.renderLinks = config.renderLinks;\n // §8 theme tokens: cosmos accepts CSS color strings natively.\n if (config.defaultPointColor !== undefined) {\n partial.pointDefaultColor = config.defaultPointColor;\n }\n if (config.defaultLinkColor !== undefined) {\n partial.linkDefaultColor = config.defaultLinkColor;\n }\n // §17 disable-transitions ladder step: 0 = atomic jumps; null restores\n // cosmos' own default (config.d.ts `transitionDuration`, 800ms).\n if (config.transitionDurationMs !== undefined) {\n partial.transitionDuration = config.transitionDurationMs ?? 800;\n }\n // §13 emphasis ring: cosmos' FOCUSED ring (config.d.ts\n // `focusedPointRingColor`; drawn whenever a focused index is set — no\n // boolean gate). Deliberately NOT `renderHoveredPointRing`: that would\n // draw a second ring from cosmos' own hover state, and the focused path\n // is what lets orbit choose the ringed node (keyboard nav, focusNode).\n if (config.emphasisRingColor !== undefined) {\n partial.focusedPointRingColor = config.emphasisRingColor;\n }\n const sim = config.simulation;\n if (sim) {\n if (sim.gravity !== undefined) partial.simulationGravity = sim.gravity;\n if (sim.repulsion !== undefined) partial.simulationRepulsion = sim.repulsion;\n if (sim.friction !== undefined) partial.simulationFriction = sim.friction;\n if (sim.linkDistance !== undefined) partial.simulationLinkDistance = sim.linkDistance;\n if (sim.linkSpring !== undefined) partial.simulationLinkSpring = sim.linkSpring;\n // §10 tunables added in v0.10.2 — each maps 1:1 onto a cosmos config\n // key; an omitted field is never written, so cosmos' own default\n // stands (config.d.ts `defaultConfigValues`).\n if (sim.decay !== undefined) partial.simulationDecay = sim.decay;\n if (sim.collision !== undefined) partial.simulationCollision = sim.collision;\n if (sim.collisionRadius !== undefined) {\n partial.simulationCollisionRadius = sim.collisionRadius;\n }\n if (sim.collisionPadding !== undefined) {\n partial.simulationCollisionPadding = sim.collisionPadding;\n }\n // cosmos >= 3.4 replaced Barnes-Hut many-body with grid-based\n // repulsion: `simulationRepulsionTheta` is deprecated and\n // NON-FUNCTIONAL. Sending it would misrepresent state, so the key is\n // not mapped; the host learns once instead of wondering silently.\n if (sim.repulsionTheta !== undefined && !this.repulsionThetaWarned) {\n this.repulsionThetaWarned = true;\n this.events?.onDiagnostic?.({\n code: 'engine:repulsion-theta-deprecated',\n severity: 'info',\n message:\n 'CosmosEngine: cosmos >= 3.4 uses grid-based repulsion; ' +\n 'simulation.repulsionTheta is ignored by this engine.',\n });\n }\n if (sim.center !== undefined) partial.simulationCenter = sim.center;\n if (sim.repulsionFromMouse !== undefined) {\n partial.simulationRepulsionFromMouse = sim.repulsionFromMouse;\n }\n }\n // §16.3 stage-4 cluster force: the scene-wide coefficient is cosmos'\n // `simulationCluster` config key (config.d.ts, default 0.1); membership\n // and centers are buffer-shaped and staged below.\n if (config.cluster != null && config.cluster.strength !== undefined) {\n partial.simulationCluster = config.cluster.strength;\n }\n if (Object.keys(partial).length > 0) graph.setConfigPartial(partial);\n }\n\n if (structure) {\n this.lastPointCount = structure.pointCount;\n graph.setPointPositions(this.withSeededPositions(structure.positions));\n // cosmos takes link endpoint indices as Float32Array; exact for < 2^24 points.\n graph.setLinks(Float32Array.from(structure.links));\n }\n\n // Staged AFTER the roster so cosmos sees a membership array matching the\n // point count of this same commit (I2), and before the single render().\n if (config && config.cluster !== undefined) this.applyClusterForce(graph, config.cluster);\n\n if (buffers) {\n // [0,1] RGBA floats — cosmos' native scale; pass through (see header note).\n if (buffers.pointColor) graph.setPointColors(buffers.pointColor);\n if (buffers.pointSize) graph.setPointSizes(buffers.pointSize);\n if (buffers.linkColor) graph.setLinkColors(buffers.linkColor);\n if (buffers.linkWidth) graph.setLinkWidths(buffers.linkWidth);\n }\n\n // §8 atlas resources are staged before the SAME render() as every other\n // channel, keeping the commit visibly atomic.\n if (resources) this.applyResources(graph, resources);\n\n graph.render();\n this.applied = update.revision;\n\n if (restart) graph.start(restart.alpha);\n // §17 write re-arm: the commit's render lands this tick; the burst lets\n // overlays sample the post-draw state. A restart additionally holds the\n // clock via the sim run reason (onSimulationStart → wake).\n if (restart) this.wake('sim');\n this.requestTicks(2);\n }\n\n /**\n * Applies the §16.3 stage-4 cluster force (capability `clusterForce`).\n *\n * Contract mapping, verified against the 3.3.0 dist (`index.d.ts`):\n * - `pointClusters` (Float32Array, NaN = unclustered) →\n * `setPointClusters((number | undefined)[])`, where cosmos' documented\n * \"does not belong to any cluster\" value is `undefined`;\n * - `centers` (Float32Array, `[x0,y0,x1,y1,…]`) →\n * `setClusterPositions((number | undefined)[])`; a non-finite entry means\n * \"no position\" and cosmos falls back to that cluster's centermass;\n * - `null` clears: an all-`undefined` array of the CURRENT roster length\n * (length must track the roster) plus empty cluster positions.\n * `strength` is the scene-wide `simulationCluster` config coefficient\n * applied in the config block, not the per-point\n * `setPointClusterStrength` buffer (Orbit's strength is scene-wide).\n */\n private applyClusterForce(\n graph: CosmosGraph,\n cluster: NonNullable<EngineCommit['config']>['cluster'],\n ): void {\n if (cluster == null) {\n graph.setPointClusters(new Array<number | undefined>(this.lastPointCount).fill(undefined));\n graph.setClusterPositions([]);\n return;\n }\n const source = cluster.pointClusters;\n const assignments = new Array<number | undefined>(source.length);\n for (let i = 0; i < source.length; i++) {\n const value = source[i]!;\n assignments[i] = Number.isFinite(value) ? value : undefined;\n }\n graph.setPointClusters(assignments);\n const centers = cluster.centers;\n if (centers !== undefined) {\n const positions = new Array<number | undefined>(centers.length);\n for (let i = 0; i < centers.length; i++) {\n const value = centers[i]!;\n positions[i] = Number.isFinite(value) ? value : undefined;\n }\n graph.setClusterPositions(positions);\n }\n }\n\n /**\n * Applies the §8 image-atlas channel: upserts convert ImageBitmap →\n * ImageData through an offscreen 2D canvas into the slot mirror, removals\n * blank their slot, and any atlas change re-uploads the FULL ImageData\n * array (cosmos' setImageData is whole-array only, matching\n * `rangeUpdates: []`). Environments without a usable 2D context (jsdom)\n * no-op the channel and report `engine:image-channel-unavailable` once —\n * never throw.\n */\n private applyResources(graph: CosmosGraph, resources: EngineResources): void {\n const atlas = resources.imageAtlas;\n if (atlas) {\n let dirty = false;\n let conversionFailed = false;\n if (atlas.upserts) {\n for (const { slot, bitmap } of atlas.upserts) {\n if (!Number.isInteger(slot) || slot < 0) continue;\n const data = this.canvasImageData(bitmap.width, bitmap.height, bitmap);\n if (data === null) {\n conversionFailed = true;\n continue;\n }\n while (this.imageSlots.length <= slot) this.imageSlots.push(null);\n this.imageSlots[slot] = data;\n dirty = true;\n }\n }\n if (atlas.removeSlots) {\n for (const slot of atlas.removeSlots) {\n // Only slots that currently hold an image need blanking.\n if (slot >= 0 && slot < this.imageSlots.length && this.imageSlots[slot] != null) {\n this.imageSlots[slot] = null;\n dirty = true;\n }\n }\n }\n if (conversionFailed) this.reportImageChannelUnavailable();\n if (dirty) {\n const blank = this.blankImage ?? (this.blankImage = this.canvasImageData(1, 1));\n if (blank === null) {\n this.reportImageChannelUnavailable();\n } else {\n // Array.from (not .map) so sparse holes also materialize as blanks.\n graph.setImageData(Array.from(this.imageSlots, (d) => d ?? blank));\n }\n }\n }\n // Indices into an atlas that can never be populated are meaningless —\n // once the channel is known-unavailable the whole channel no-ops.\n if (resources.pointImageIndex && !this.imageChannelUnavailable) {\n graph.setPointImageIndices(resources.pointImageIndex);\n }\n }\n\n /**\n * Reads an ImageData of the given size off an offscreen 2D canvas, drawing\n * `bitmap` onto it first when provided (ImageBitmap → ImageData transcode;\n * without a bitmap: a transparent blank). Returns null — never throws —\n * where no 2D context exists (jsdom without the canvas package).\n */\n private canvasImageData(width: number, height: number, bitmap?: ImageBitmap): ImageData | null {\n const doc = this.innerDiv?.ownerDocument;\n if (!doc || !(width > 0) || !(height > 0)) return null;\n try {\n const canvas = doc.createElement('canvas');\n canvas.width = width;\n canvas.height = height;\n const ctx = canvas.getContext('2d');\n if (!ctx) return null;\n if (bitmap) ctx.drawImage(bitmap, 0, 0);\n return ctx.getImageData(0, 0, width, height);\n } catch {\n return null;\n }\n }\n\n /** Documented degradation, reported at most once per engine instance. */\n private reportImageChannelUnavailable(): void {\n if (this.imageChannelUnavailable) return;\n this.imageChannelUnavailable = true;\n this.events?.onDiagnostic?.({\n code: 'engine:image-channel-unavailable',\n severity: 'warning',\n message:\n 'CosmosEngine: no 2D canvas context is available to convert ImageBitmap ' +\n 'atlas entries to ImageData; point images are disabled in this environment.',\n });\n }\n\n /**\n * Replaces NaN pairs (= \"no known position\", §7.3) with random points on a\n * ring of radius seedRadius around the space center. cosmos treats NaN\n * positions as *absent* points, so they must never reach setPointPositions.\n * Known positions pass through verbatim (same array when nothing to seed).\n */\n private withSeededPositions(positions: Float32Array): Float32Array {\n let needsSeeding = false;\n for (let i = 0; i < positions.length; i += 2) {\n if (Number.isNaN(positions[i]!) || Number.isNaN(positions[i + 1]!)) {\n needsSeeding = true;\n break;\n }\n }\n if (!needsSeeding) return positions;\n\n const out = Float32Array.from(positions);\n const center = this.spaceSize / 2;\n const radius = this.seedRadius;\n for (let i = 0; i < out.length; i += 2) {\n if (Number.isNaN(out[i]!) || Number.isNaN(out[i + 1]!)) {\n const angle = Math.random() * Math.PI * 2;\n out[i] = center + radius * Math.cos(angle);\n out[i + 1] = center + radius * Math.sin(angle);\n }\n }\n return out;\n }\n}\n\n/**\n * Per-channel merge for queued §8 resources (pre-mount / context-lost):\n * upserts union per slot (latest bitmap wins), a later remove drops an\n * earlier pending upsert of the same slot (and vice versa — folding order\n * mirrors applyResources: upserts before removes within each commit), and\n * the latest pointImageIndex replaces wholesale.\n */\nfunction mergeResources(\n previous: EngineCommit['resources'],\n update: EngineCommit['resources'],\n): EngineResources {\n const upsertBySlot = new Map<number, ImageBitmap>();\n const removes = new Set<number>();\n for (const atlas of [previous?.imageAtlas, update?.imageAtlas]) {\n if (!atlas) continue;\n for (const { slot, bitmap } of atlas.upserts ?? []) {\n upsertBySlot.set(slot, bitmap);\n removes.delete(slot);\n }\n for (const slot of atlas.removeSlots ?? []) {\n upsertBySlot.delete(slot);\n removes.add(slot);\n }\n }\n const merged: EngineResources = {};\n if (upsertBySlot.size > 0 || removes.size > 0) {\n const imageAtlas: NonNullable<EngineResources['imageAtlas']> = {};\n if (upsertBySlot.size > 0) {\n imageAtlas.upserts = Array.from(upsertBySlot, ([slot, bitmap]) => ({ slot, bitmap }));\n }\n if (removes.size > 0) imageAtlas.removeSlots = Array.from(removes);\n merged.imageAtlas = imageAtlas;\n }\n const pointImageIndex = update?.pointImageIndex ?? previous?.pointImageIndex;\n if (pointImageIndex !== undefined) merged.pointImageIndex = pointImageIndex;\n return merged;\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@modernrelay/orbit-engine-cosmos",
|
|
3
|
-
"version": "0.13.
|
|
3
|
+
"version": "0.13.6",
|
|
4
4
|
"description": "cosmos.gl engine adapter for Orbit: GPU force layout, native picking, context-loss recovery.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
26
|
"@cosmos.gl/graph": "3.4.0",
|
|
27
|
-
"@modernrelay/orbit-core": "0.13.
|
|
27
|
+
"@modernrelay/orbit-core": "0.13.6"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
30
|
"typescript": "^5.6.0",
|