Quantum API
import {
QuantumPropertyManager,
QuantumRecorder,
ensureLoaded,
startBackgroundLoad,
isReady,
getModule,
getQuantumForge,
getVersion,
getMaxDimension,
getMaxQudits,
getMaxStateSize,
getWasmMemoryBytes,
getAttribution,
setWasmBasePath,
registerServiceWorker,
} from "quantum-forge/quantum";
import type {
QuantumOperation,
SerializedPredicate,
PredicateSpec,
QuantumRecorderHook,
OpCode,
BatchOp,
BatchResult,
} from "quantum-forge/quantum";Module loading
ensureLoaded(): Promise<void>
Loads the WASM module. Must complete before any quantum operations. Caches the result, so subsequent calls resolve immediately.
startBackgroundLoad(logger?: LoggerInterface): void
Begins loading in the background via requestIdleCallback. Call early for faster perceived startup.
isReady(): boolean
Non-blocking check. Returns true if the module has finished loading.
setWasmBasePath(path: string): void
Set the URL path where WASM files are served. Default: "/quantum-forge". Must be called before ensureLoaded().
registerServiceWorker(swPath?: string): Promise<ServiceWorkerRegistration | null>
Register the offline caching service worker. Default path: "/quantum-forge-sw.js".
getQuantumForge().initialize(options?: InitializeOptions): Promise<void>
Low-level WASM initialization. The QuantumForge class is not exported directly; reach it through getQuantumForge(). Most consumers use ensureLoaded() instead, but calling initialize() directly lets you pass InitializeOptions:
interface InitializeOptions {
/** Override Emscripten's default stderr handler (console.warn). */
printErr?: (text: string) => void;
/** Override Emscripten's default stdout handler (console.log). */
print?: (text: string) => void;
}See Setup: WASM Output Redirection for usage examples.
INFO
The framework's startBackgroundLoad(logger) / ensureLoaded() already passes printErr to route WASM stderr through the provided logger at warn level.
Module queries
getModule(): QFModule
Returns the loaded WASM module for gate calls and queries.
getVersion(): string
WASM module version string.
getMaxDimension(): number
Maximum qudit dimension supported by the loaded build. Read it after ensureLoaded() to detect which edition is running: 2 for the Qubit Edition, 3 for the Qutrit Edition.
getMaxQudits(): number
Maximum number of qudits supported by the loaded build. Pair it with getMaxDimension() to branch on edition at runtime rather than hard-coding limits.
getMaxStateSize(): number
Maximum number of basis amplitudes any single state vector can hold (compile-time limit, currently 100,000). See Lifecycle: State Budget.
getWasmMemoryBytes(): number | null
Current WASM heap usage in bytes.
getAttribution(): string
The attribution string to display in your application. Showing it is a license requirement, so put it somewhere a player can see: a credits screen, an about panel, or a splash screen.
QuantumPropertyManager
Base class for quantum property lifecycle management. Extend or compose this in your game.
Constructor
new QuantumPropertyManager(options?: {
dimension?: number; // default: 2
logger?: LoggerInterface;
})Public API
| Method | Returns | Description |
|---|---|---|
acquireProperty() | QFProperty | Get a property at |0⟩ (pool first, then fresh) |
releaseProperty(prop, value) | void | Reset to |0⟩ and return to pool |
setProperty(id, prop) | void | Map a string ID to a property handle |
getProperty(id) | QFProperty | undefined | Get handle by ID |
hasProperty(id) | boolean | Check if ID exists |
deleteProperty(id) | void | Remove ID mapping (does not release) |
removeProperty(id) | void | Measure + release + delete in one call |
getModule() | QFModule | Access the WASM module for all gate and query calls |
dimension | number | The configured dimension (readonly) |
clear() | void | Clear all properties and pool |
size | number | Number of registered properties |
poolSize | number | Number of pooled (recycled) properties |
setRecorder(recorder) | void | Attach a QuantumRecorder for opt-in operation logging |
getRecorder() | QuantumRecorderHook | undefined | Get attached recorder |
WASM gate functions
All gates are called via getModule(). Names are snake_case.
Single-property gates
| Function | Signature | Description |
|---|---|---|
cycle | m.cycle(prop, fraction?, predicates?) | Cyclic permutation (the NOT/X flip at dim=2) |
shift | m.shift(prop, fraction?, predicates?) | Shift gate / Pauli X |
hadamard | m.hadamard(prop, fraction?, predicates?) | Hadamard gate |
inverse_hadamard | m.inverse_hadamard(prop, predicates?) | Adjoint Hadamard |
clock | m.clock(prop, fraction?, predicates?) | Clock gate / Z-rotation |
x | m.x(prop, fraction?, predicates?) | Pauli X. Alias for shift, not cycle. The two coincide only at dimension 2 |
z | m.z(prop, fraction?, predicates?) | Pauli Z. Alias for clock |
y | m.y(prop, fraction?, predicates?) | Pauli Y (dim=2 only, throws otherwise) |
reset | m.reset(prop, value) | Reset property to |0⟩ from known value |
Omitting fraction does not mean "fraction 1.0". It calls the non-fractional gate, a discrete permutation, which is a different operation from the fractional gate at any value.
Two-property gates
| Function | Signature | Description |
|---|---|---|
i_swap | m.i_swap(p1, p2, fraction, predicates?) | iSwap entanglement gate |
swap | m.swap(p1, p2, predicates?) | Swap two properties |
Phase
| Function | Signature | Description |
|---|---|---|
phase_rotate | m.phase_rotate(predicates, angle) | Phase rotation (predicates required) |
Measurement
| Function | Returns | Description |
|---|---|---|
m.measure_properties(props) | number[] | Measure and collapse |
m.forced_measure_properties(props, values) | number[] | Force specific outcomes (replay) |
m.measure_predicate(predicates) | number | Projective predicate measurement (0 or 1) |
m.forced_measure_predicate(predicates, value) | number | Force predicate measurement outcome (replay) |
m.predicate_probability(predicates) | number | Probability that every predicate holds. Read-only, no collapse |
forced_measure_predicate does not throw when the forced value has zero probability. It falls back to a stochastic measurement and returns the outcome that actually happened, so compare the return value against what you asked for when replaying.
Read-only queries
Both take an array of properties.
m.probabilities(props: QFProperty[]): Array<{
probability: number;
qudit_values: number[];
}>
m.reduced_density_matrix(props: QFProperty[]): Array<{
row_values: number[];
col_values: number[];
value: { real: number; imag: number };
}>Property methods
Gates are module functions, but lifecycle and inspection live on the property handle itself.
| Method | Returns | Description |
|---|---|---|
prop.destroy() | void | Factorize the qudit out of its shared state vector and release the property |
prop.is_valid() | boolean | Whether the property still holds a valid state. false after destroy() |
prop.num_active_qudits() | number | Number of qudits in this property's shared quantum state |
prop.state_vector_size() | number | Current number of basis amplitudes (sparse size) |
prop.index() | number | The qudit's index within its shared state |
prop.dimension() | number | The qudit's dimension |
prop.is(value) | QFPredicate | Predicate: this qudit equals value |
prop.is_not(value) | QFPredicate | Predicate: this qudit does not equal value |
See Lifecycle & State Management for the usage guide, and Lifecycle: State Budget for backpressure patterns built on num_active_qudits() and state_vector_size().
Batch execution
m.executeBatch(ops: BatchOp[]): BatchResult
Execute multiple gate operations in a single WASM call. See Gates: Batch Gate Execution for the full guide.
BatchOp
type OpCode =
| 'cycle' | 'shift' | 'clock'
| 'x' | 'z' | 'y'
| 'hadamard' | 'inverse_hadamard'
| 'swap' | 'i_swap'
| 'phase_rotate';
interface BatchOp {
op: OpCode;
target?: QFProperty;
target2?: QFProperty; // swap, i_swap
fraction?: number; // omit for non-fractional variant
angle?: number; // phase_rotate only
predicates?: QFPredicate[];
}BatchResult
interface BatchResult {
opsExecuted: number; // how many completed before stopping
success: boolean;
errorMessage: string; // non-empty on failure
}m.executeBatchTape(properties: QFProperty[], tape: Float64Array): BatchResult
High-throughput batch execution using a pre-encoded Float64Array. Bypasses per-op embind marshaling, so the tape crosses into WASM as one bulk memcpy instead of thousands of JS object conversions. Use for pre-built operation sequences with 50+ ops.
Tape format per operation (variable length, minimum 6 doubles):
[opcode, target_idx, target2_idx, fraction, angle, pred_count,
(pred_prop_idx, pred_value, pred_is_equal) × pred_count]target_idx/target2_idx: index intopropertiesarray, or -1 for nonefraction: NaN for non-fractional gate variantpred_is_equal: 1.0 for is(), 0.0 for is_not()
OP constants
import { OP } from "quantum-forge/quantum";
OP.CYCLE // 0
OP.SHIFT // 1
OP.CLOCK // 2
OP.X // 3
OP.Z // 4
OP.Y // 5
OP.HADAMARD // 6
OP.INVERSE_HADAMARD // 7
OP.SWAP // 8
OP.I_SWAP // 9
OP.PHASE_ROTATE // 10
OP.ROTATE_BASIS_PAIR // 11ROTATE_BASIS_PAIR has a different tape layout: [11, nq, -1, NaN, angle, 0, a[0]..a[nq-1], b[0]..b[nq-1]]
See Gates: Batch Gate Execution for usage guide.
QuantumRecorder
Opt-in recording and replay of quantum operations. Attach to a manager via setRecorder().
Constructor
new QuantumRecorder(manager: QuantumPropertyManager)Recording API
| Method | Returns | Description |
|---|---|---|
startRecording() | void | Begin recording; resets log |
stopRecording() | QuantumOperation[] | Stop and return log |
isRecording() | boolean | Check recording status |
getOperationLog() | QuantumOperation[] | Get log copy (even while recording) |
replayLog(ops) | void | Clear manager state and replay from log |
recordOp(op) | void | Record a gate operation manually |
getIndex(prop) | number | undefined | Get recorded index for a property |
buildWasmPredicates(specs) | QFPredicate[] | Build WASM predicates from specs |
serializePredicates(specs) | SerializedPredicate[] | undefined | Serialize for log |
See Recording & Replay for usage guide.
PredicateSpec
interface PredicateSpec {
property: QFProperty;
value: number;
isEqual: boolean; // true = "is this value", false = "is NOT this value"
}QuantumSimulation
Isolated simulation context. Properties created within a simulation can entangle with each other but not with properties from other simulations or the global context. See Lifecycle: QuantumSimulation for usage guide.
Constructing one
QuantumSimulation is not exported from quantum-forge/quantum. Reach it through the loaded module:
const sim = getQuantumForge().createSimulation();
// or, if you want the class itself
const { QuantumSimulation } = getModule();
const sim2 = new QuantumSimulation();Either way, load the module first with ensureLoaded().
API
| Method | Returns | Description |
|---|---|---|
createProperty(dimension) | QFProperty | Create a property bound to this simulation |
destroyProperty(prop) | void | Factorize one property out, auto-split separable qudits |
factorizeAllSeparable() | void | Scan all shared states and split separable qudits |
destroy() | void | Release all properties and state vectors at once |
isDestroyed() | boolean | Whether destroy() has already run |
Gates and queries still come from getModule(). The simulation itself has no getModule().
Error types
All WASM operations throw standard Error objects with a message prefix identifying the error type. See Error Handling for the full guide.
| Prefix | Meaning |
|---|---|
[QuantumForgeStateSizeError] | State vector would exceed the maximum size (100,000 basis amplitudes) |
[QuantumForgeOutOfMemoryError] | WASM memory allocation failed |
[QuantumForgeError] | General error (invalid operation, destroyed property, cross-simulation entanglement) |
QuantumOperation
Union type for all recorded operations. See Recording & Replay for the full type definition.