Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 37 additions & 17 deletions src/lib/wasmLoader.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { StoreSnapshot } from '../state/types';
import { buildRustSimBridge, type RustSimBridge, type WasmSimExports } from './wasmSimBridge';
import type { InitOutput } from '../gen/rust_engine';
import { normalizeSnapshot, validateSnapshotForWasm } from '../state/serialization/store';
import { parityDebugEnabled } from './parityDebug';

Expand Down Expand Up @@ -27,25 +28,44 @@

try {
// Dynamic import to allow tree-shaking when WASM is not used
const wasmModule = await import('../gen/rust_engine');
const initOutput = await wasmModule.default();
const memory = (initOutput as { memory?: WebAssembly.Memory }).memory;
if (!memory) {
throw new Error('WASM init missing memory');
}
const mod = (await import('../gen/rust_engine')) as unknown;

if (
parityDebugEnabled &&
typeof (wasmModule as { set_parity_debug?: (enabled: boolean) => void }).set_parity_debug ===
'function'
) {
(wasmModule as { set_parity_debug?: (enabled: boolean) => void }).set_parity_debug?.(true);
}
type RustEngineModule = WasmSimExports & {
default: (...args: unknown[]) => Promise<InitOutput>;
set_parity_debug?: (enabled: boolean) => void;
};

const exports: WasmSimExports = {
memory,
WasmGameState: wasmModule.WasmGameState,
};
const isRustEngineModule = (m: unknown): m is RustEngineModule => {
if (typeof m !== 'object' || m === null) return false;
const r = m as Record<string, unknown>;
return (
typeof r.default === 'function' &&
typeof r.WasmGameState === 'function' &&
// `memory` is returned from the init output rather than being a top-level export
true
);
};

if (!isRustEngineModule(mod)) {
throw new Error('Imported rust_engine module has an unexpected shape');
}

const wasmModule = mod;
const initOutput = await wasmModule.default();

Check failure on line 54 in src/lib/wasmLoader.ts

View workflow job for this annotation

GitHub Actions / lint

Unsafe assignment of an error typed value
const memory = initOutput.memory;

Check failure on line 55 in src/lib/wasmLoader.ts

View workflow job for this annotation

GitHub Actions / lint

Unsafe member access .memory on a type that cannot be resolved

Check failure on line 55 in src/lib/wasmLoader.ts

View workflow job for this annotation

GitHub Actions / lint

Unsafe assignment of an error typed value
const hasMemoryBuffer = Boolean(memory && (memory as { buffer?: unknown }).buffer);
if (!hasMemoryBuffer && !(memory instanceof WebAssembly.Memory)) {
throw new Error('WASM init missing memory');
}

if (parityDebugEnabled && typeof wasmModule.set_parity_debug === 'function') {
wasmModule.set_parity_debug(true);
}

const exports: WasmSimExports = {
memory,

Check failure on line 66 in src/lib/wasmLoader.ts

View workflow job for this annotation

GitHub Actions / lint

Unsafe assignment of an error typed value
WasmGameState: wasmModule.WasmGameState,
};

// Pre-validate the original snapshot and provide friendly messages
// if it looks incomplete. We still normalize and proceed because
Expand Down
Loading