You're reading the 2.x docs. quantum-forge 3.0 is out: this page in 3.x / migration guide

Skip to content

Quantum API ​

typescript
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:

typescript
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 ​

typescript
new QuantumPropertyManager(options?: {
  dimension?: number;  // default: 2
  logger?: LoggerInterface;
})

Public API ​

MethodReturnsDescription
acquireProperty()QFPropertyGet a property at |0⟩ (pool first, then fresh)
releaseProperty(prop, value)voidReset to |0⟩ and return to pool
setProperty(id, prop)voidMap a string ID to a property handle
getProperty(id)QFProperty | undefinedGet handle by ID
hasProperty(id)booleanCheck if ID exists
deleteProperty(id)voidRemove ID mapping (does not release)
removeProperty(id)voidMeasure + release + delete in one call
getModule()QFModuleAccess the WASM module for all gate and query calls
dimensionnumberThe configured dimension (readonly)
clear()voidClear all properties and pool
sizenumberNumber of registered properties
poolSizenumberNumber of pooled (recycled) properties
setRecorder(recorder)voidAttach a QuantumRecorder for opt-in operation logging
getRecorder()QuantumRecorderHook | undefinedGet attached recorder

WASM gate functions ​

All gates are called via getModule(). Names are snake_case.

Single-property gates ​

FunctionSignatureDescription
cyclem.cycle(prop, fraction?, predicates?)Cyclic permutation (the NOT/X flip at dim=2)
shiftm.shift(prop, fraction?, predicates?)Shift gate / Pauli X
hadamardm.hadamard(prop, fraction?, predicates?)Hadamard gate
inverse_hadamardm.inverse_hadamard(prop, predicates?)Adjoint Hadamard
clockm.clock(prop, fraction?, predicates?)Clock gate / Z-rotation
xm.x(prop, fraction?, predicates?)Pauli X. Alias for shift, not cycle. The two coincide only at dimension 2
zm.z(prop, fraction?, predicates?)Pauli Z. Alias for clock
ym.y(prop, fraction?, predicates?)Pauli Y (dim=2 only, throws otherwise)
resetm.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 ​

FunctionSignatureDescription
i_swapm.i_swap(p1, p2, fraction, predicates?)iSwap entanglement gate
swapm.swap(p1, p2, predicates?)Swap two properties

Phase ​

FunctionSignatureDescription
phase_rotatem.phase_rotate(predicates, angle)Phase rotation (predicates required)

Measurement ​

FunctionReturnsDescription
m.measure_properties(props)number[]Measure and collapse
m.forced_measure_properties(props, values)number[]Force specific outcomes (replay)
m.measure_predicate(predicates)numberProjective predicate measurement (0 or 1)
m.forced_measure_predicate(predicates, value)numberForce predicate measurement outcome (replay)
m.predicate_probability(predicates)numberProbability 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.

typescript
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.

MethodReturnsDescription
prop.destroy()voidFactorize the qudit out of its shared state vector and release the property
prop.is_valid()booleanWhether the property still holds a valid state. false after destroy()
prop.num_active_qudits()numberNumber of qudits in this property's shared quantum state
prop.state_vector_size()numberCurrent number of basis amplitudes (sparse size)
prop.index()numberThe qudit's index within its shared state
prop.dimension()numberThe qudit's dimension
prop.is(value)QFPredicatePredicate: this qudit equals value
prop.is_not(value)QFPredicatePredicate: 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 ​

typescript
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 ​

typescript
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 into properties array, or -1 for none
  • fraction: NaN for non-fractional gate variant
  • pred_is_equal: 1.0 for is(), 0.0 for is_not()

OP constants ​

typescript
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  // 11

ROTATE_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 ​

typescript
new QuantumRecorder(manager: QuantumPropertyManager)

Recording API ​

MethodReturnsDescription
startRecording()voidBegin recording; resets log
stopRecording()QuantumOperation[]Stop and return log
isRecording()booleanCheck recording status
getOperationLog()QuantumOperation[]Get log copy (even while recording)
replayLog(ops)voidClear manager state and replay from log
recordOp(op)voidRecord a gate operation manually
getIndex(prop)number | undefinedGet recorded index for a property
buildWasmPredicates(specs)QFPredicate[]Build WASM predicates from specs
serializePredicates(specs)SerializedPredicate[] | undefinedSerialize for log

See Recording & Replay for usage guide.

PredicateSpec ​

typescript
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:

typescript
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 ​

MethodReturnsDescription
createProperty(dimension)QFPropertyCreate a property bound to this simulation
destroyProperty(prop)voidFactorize one property out, auto-split separable qudits
factorizeAllSeparable()voidScan all shared states and split separable qudits
destroy()voidRelease all properties and state vectors at once
isDestroyed()booleanWhether 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.

PrefixMeaning
[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.

Powered by Quantum Forge