@realitycollective/webxr-interactions 0.1.1-preview.3 → 0.1.2-preview.0

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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trace.js","sourceRoot":"","sources":["../src/trace.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Recorded input traces - parity as a number, checkable without a device\n * per platform (Pale Signal handover of 29 September 2026, G6).\n *\n * The host conformance kits feed ideal scripted values: exact thresholds,\n * perfect poses, an empty world. They pass on native while a person still\n * finds the mechanics broken, because real hands are not ideal. A TRACE is\n * a real session, recorded frame by frame on the reference platform (IWSDK\n * on a Quest 3 in the Quest Browser): each frame's input source snapshots,\n * the head pose, and the reference's own outcome, the events it raised\n * (press and grab start and end), the values its behaviours published (the\n * dial's angle, the slide's pull), the poses its objects took, and the\n * velocity a thrown object left the hand with.\n *\n * Replaying the trace's INPUT through a binding's core (the same runtime,\n * over that binding's own hit tester and transform port) and comparing the\n * outcome with the reference's, frame for frame, within stated tolerances,\n * is what proves the binding's rules match the web on the input a person\n * actually produced. `traceParityCases()` is that comparison as a\n * runner-free suite every binding runs in CI over the synthetic traces\n * (`synthesizeTrace()`), and locally over recorded ones.\n *\n * The format is plain JSON (`rc-trace.v1`), so a trace recorded in a browser\n * can be downloaded and replayed as it is.\n */\nimport {\n NO_CAPABILITIES,\n type HeadPose,\n type InputCapabilities,\n type InputHitHint,\n type InputProvider,\n type InputSourceSnapshot,\n type PoseTuple,\n type Unsubscribe,\n type Vec3Tuple,\n} from \"@realitycollective/webxr-input\";\nimport type { InteractableDescriptor } from \"./descriptor.js\";\nimport type { InteractionEvent } from \"./events.js\";\nimport type { HoldRelease, TransformPort } from \"./ports.js\";\nimport { InteractionRuntime, type InteractionRuntimeOptions } from \"./runtime.js\";\n\n/** The trace format version this module writes and reads. */\nexport const TRACE_VERSION = \"rc-trace.v1\";\n\n/** An interactable as the reference registered it, so a replay can rebuild the scene. */\nexport interface TraceTarget {\n descriptor: InteractableDescriptor;\n /** The target's rest pose, world space, at the start of the trace. */\n restPose: PoseTuple;\n /** The radius the reference hit-tests it with, metres (IWSDK: `targetRadius`, default 0.1). */\n radius: number;\n}\n\n/** The reference's outcome on one frame. */\nexport interface TraceReference {\n /** The events the reference raised this frame (type, interactable, interactor). */\n events: Array<Pick<InteractionEvent, \"type\" | \"interactableId\" | \"interactorId\" | \"behaviourKind\">>;\n /** Each registered target's primary value after the frame (a dial's 0..1, a slide's 0..1). */\n values: Record<string, number>;\n /** Each target's world pose after the frame. */\n poses: Record<string, PoseTuple>;\n /** A release velocity the reference handed a target's physics this frame. */\n releases?: Record<string, HoldRelease>;\n}\n\nexport interface TraceFrame {\n /** Seconds since the trace began. */\n t: number;\n /** Seconds since the previous frame. */\n dt: number;\n head?: HeadPose;\n sources: InputSourceSnapshot[];\n hints?: InputHitHint[];\n reference: TraceReference;\n}\n\nexport interface TraceMeta {\n /** The platform the trace was recorded on: `\"iwsdk\"` is the reference. */\n platform: string;\n /** ISO date and time of the recording. */\n recordedAt: string;\n /** The device, as the recorder knew it (`\"Quest 3\"`, `\"synthetic\"`). */\n device: string;\n /** The mechanic the person performed: `\"press\"`, `\"grab\"`, `\"dial\"`, `\"slide\"`, `\"hinge\"`, `\"throw\"`. */\n mechanic: string;\n /** What the person used. */\n input: \"hands\" | \"controllers\";\n /** Package versions in the recording app, for the record. */\n packages?: Record<string, string>;\n /** True for a trace a program made up rather than a person recorded; such a trace proves the pipeline, never parity. */\n synthetic?: boolean;\n notes?: string;\n}\n\nexport interface InteractionTrace {\n version: typeof TRACE_VERSION;\n meta: TraceMeta;\n /** The capabilities the reference reported, so the replay negotiates the same behaviours. */\n capabilities: InputCapabilities;\n targets: TraceTarget[];\n frames: TraceFrame[];\n}\n\n// ---------------------------------------------------------------------------\n// Recording\n// ---------------------------------------------------------------------------\n\nexport interface TraceRecorderOptions {\n meta: Omit<TraceMeta, \"recordedAt\"> & { recordedAt?: string };\n /** The targets to record, with a port to read each one's pose and a way to read its primary value. */\n targets: Array<{ descriptor: InteractableDescriptor; port: TransformPort; radius?: number }>;\n /** The head pose each frame, when the recorder has one. */\n head?: () => HeadPose | undefined;\n /** A release the reference's physics received this frame, per target, when the recorder can read one. */\n releases?: () => Record<string, HoldRelease> | undefined;\n}\n\n/**\n * Records a trace from a live runtime: attach it, play the mechanic, then\n * `stop()` and keep the JSON. It listens to the runtime's sampled sources\n * (the input) and its events (the outcome), and reads each target's value\n * and pose after every frame. On IWSDK the runtime's grab events mirror\n * IWSDK's own `Grabbed` tag (through hints and `nativeGrabbing`), so the\n * events recorded there ARE the engine's outcome.\n */\nexport class TraceRecorder {\n private readonly frames: TraceFrame[] = [];\n private pending: Omit<TraceFrame, \"reference\"> | null = null;\n private pendingEvents: TraceReference[\"events\"] = [];\n private elapsed = 0;\n private readonly unsubscribe: Unsubscribe[] = [];\n private readonly options: TraceRecorderOptions;\n private readonly runtime: InteractionRuntime;\n private stopped = false;\n\n constructor(runtime: InteractionRuntime, options: TraceRecorderOptions) {\n this.runtime = runtime;\n this.options = options;\n this.unsubscribe.push(\n runtime.onSample((sources) => this.onSample(sources)),\n runtime.onEvent((event) => {\n this.pendingEvents.push({\n type: event.type,\n interactableId: event.interactableId,\n ...(event.interactorId !== undefined ? { interactorId: event.interactorId } : {}),\n ...(event.behaviourKind !== undefined ? { behaviourKind: event.behaviourKind } : {}),\n });\n }),\n );\n }\n\n /** Call once per frame AFTER `runtime.update(dt)`, with the same dt. */\n endFrame(dt: number): void {\n if (this.stopped || !this.pending) return;\n const values: Record<string, number> = {};\n const poses: Record<string, PoseTuple> = {};\n for (const target of this.options.targets) {\n const id = target.descriptor.id;\n values[id] = this.runtime.getState(id)?.value ?? 0;\n const pose = target.port.getWorldPose();\n poses[id] = { position: [...pose.position] as Vec3Tuple, quaternion: [...pose.quaternion] as PoseTuple[\"quaternion\"] };\n }\n const releases = this.options.releases?.();\n const frame: TraceFrame = {\n ...this.pending,\n dt,\n reference: { events: this.pendingEvents, values, poses, ...(releases && Object.keys(releases).length > 0 ? { releases } : {}) },\n };\n this.frames.push(frame);\n this.pending = null;\n this.pendingEvents = [];\n }\n\n private onSample(sources: readonly InputSourceSnapshot[]): void {\n if (this.stopped) return;\n const head = this.options.head?.();\n const hints = this.runtime.getProvider().sampleHints?.();\n this.pending = {\n t: this.elapsed,\n dt: 0,\n ...(head ? { head: { position: [...head.position] as Vec3Tuple, quaternion: [...head.quaternion] as HeadPose[\"quaternion\"] } } : {}),\n sources: sources.map(cloneSnapshot),\n ...(hints && hints.length > 0 ? { hints: hints.map((hint) => ({ ...hint })) } : {}),\n };\n this.pendingEvents = [];\n // The frame's dt is known at endFrame; the elapsed time advances there.\n }\n\n /** How many frames are recorded so far. */\n get length(): number {\n return this.frames.length;\n }\n\n /** Stop listening and return the trace. Further frames are ignored. */\n stop(): InteractionTrace {\n this.stopped = true;\n for (const off of this.unsubscribe) off();\n let elapsed = 0;\n for (const frame of this.frames) {\n frame.t = elapsed;\n elapsed += frame.dt;\n }\n return {\n version: TRACE_VERSION,\n meta: { recordedAt: this.options.meta.recordedAt ?? new Date().toISOString(), ...this.options.meta },\n capabilities: { ...this.runtime.getCapabilities() },\n targets: this.options.targets.map((target) => ({\n descriptor: target.descriptor,\n restPose: target.port.getRestWorldPose(),\n radius: target.radius ?? 0.1,\n })),\n frames: this.frames,\n };\n }\n}\n\nfunction cloneSnapshot(source: InputSourceSnapshot): InputSourceSnapshot {\n return JSON.parse(JSON.stringify(source)) as InputSourceSnapshot;\n}\n\n// ---------------------------------------------------------------------------\n// Replay\n// ---------------------------------------------------------------------------\n\n/** A provider that plays a trace's frames back, one per `sample()`. */\nexport class TraceInputProvider implements InputProvider {\n private index = -1;\n private readonly trace: InteractionTrace;\n private readonly capsListeners = new Set<(c: InputCapabilities) => void>();\n\n constructor(trace: InteractionTrace) {\n this.trace = trace;\n }\n\n /** Advance to the next frame; returns it, or null past the end. */\n next(): TraceFrame | null {\n this.index += 1;\n return this.trace.frames[this.index] ?? null;\n }\n\n /** The frame `sample()` currently reports. */\n get frame(): TraceFrame | null {\n return this.trace.frames[this.index] ?? null;\n }\n\n getCapabilities(): InputCapabilities {\n return { ...NO_CAPABILITIES, ...this.trace.capabilities };\n }\n\n onCapabilitiesChanged(listener: (c: InputCapabilities) => void): Unsubscribe {\n this.capsListeners.add(listener);\n return () => {\n this.capsListeners.delete(listener);\n };\n }\n\n onSourcesChanged(): Unsubscribe {\n return () => undefined;\n }\n\n sample(): readonly InputSourceSnapshot[] {\n return this.frame?.sources.map(cloneSnapshot) ?? [];\n }\n\n sampleHints(): readonly InputHitHint[] {\n return this.frame?.hints ?? [];\n }\n\n getHeadPose(): HeadPose {\n return this.frame?.head ?? { position: [0, 1.6, 0], quaternion: [0, 0, 0, 1] };\n }\n}\n\n/** What a binding provides so a trace can be replayed through its own ports. */\nexport interface TraceReplaySubject {\n /**\n * Build the trace's targets in the binding's scene and register them with\n * the runtime the replay hands over. The subject owns the hit tester the\n * runtime was built with (`hitTester` on the options it returned).\n */\n build(trace: InteractionTrace, runtime: InteractionRuntime): { ports: Record<string, TransformPort>; dispose?: () => void };\n /** Runtime options beyond the provider (the binding's hit tester, near-pointer options). */\n runtimeOptions(trace: InteractionTrace): Omit<InteractionRuntimeOptions, \"provider\">;\n}\n\n/** A frame index on which a given event happened, for a target. */\nexport interface TraceEventTiming {\n type: string;\n interactableId: string;\n frame: number;\n t: number;\n}\n\n/** The outcome of one replay, in the same terms as the reference. */\nexport interface TraceOutcome {\n events: TraceEventTiming[];\n /** Per target, the value after each frame. */\n values: Record<string, number[]>;\n /** Per target, the world pose after each frame. */\n poses: Record<string, PoseTuple[]>;\n /** Per target, the last release velocity `endHold` received. */\n releases: Record<string, HoldRelease>;\n}\n\n/** Replay a trace's input through a runtime built over the subject's ports and collect the outcome. */\nexport function replayTrace(trace: InteractionTrace, subject: TraceReplaySubject): TraceOutcome {\n const provider = new TraceInputProvider(trace);\n const runtime = new InteractionRuntime({ provider, ...subject.runtimeOptions(trace) });\n const built = subject.build(trace, runtime);\n const outcome: TraceOutcome = { events: [], values: {}, poses: {}, releases: {} };\n for (const target of trace.targets) {\n outcome.values[target.descriptor.id] = [];\n outcome.poses[target.descriptor.id] = [];\n const port = built.ports[target.descriptor.id];\n if (port && port.endHold) {\n const original = port.endHold.bind(port);\n port.endHold = (release: HoldRelease) => {\n outcome.releases[target.descriptor.id] = { linearVelocity: [...release.linearVelocity] as Vec3Tuple, angularVelocity: [...release.angularVelocity] as Vec3Tuple };\n original(release);\n };\n }\n }\n let frameIndex = -1;\n const off = runtime.onEvent((event) => {\n outcome.events.push({ type: event.type, interactableId: event.interactableId, frame: frameIndex, t: trace.frames[frameIndex]?.t ?? 0 });\n });\n try {\n let frame = provider.next();\n while (frame) {\n frameIndex += 1;\n runtime.update(frame.dt);\n for (const target of trace.targets) {\n const id = target.descriptor.id;\n outcome.values[id]!.push(runtime.getState(id)?.value ?? 0);\n const pose = built.ports[id]?.getWorldPose() ?? { position: [0, 0, 0], quaternion: [0, 0, 0, 1] };\n outcome.poses[id]!.push({ position: [...pose.position] as Vec3Tuple, quaternion: [...pose.quaternion] as PoseTuple[\"quaternion\"] });\n }\n frame = provider.next();\n }\n } finally {\n off();\n runtime.dispose();\n built.dispose?.();\n }\n return outcome;\n}\n\n/** The reference outcome of a trace in the same terms as a replay's. */\nexport function referenceOutcome(trace: InteractionTrace): TraceOutcome {\n const outcome: TraceOutcome = { events: [], values: {}, poses: {}, releases: {} };\n for (const target of trace.targets) {\n outcome.values[target.descriptor.id] = [];\n outcome.poses[target.descriptor.id] = [];\n }\n trace.frames.forEach((frame, index) => {\n for (const event of frame.reference.events) {\n outcome.events.push({ type: event.type, interactableId: event.interactableId, frame: index, t: frame.t });\n }\n for (const target of trace.targets) {\n const id = target.descriptor.id;\n outcome.values[id]!.push(frame.reference.values[id] ?? 0);\n outcome.poses[id]!.push(frame.reference.poses[id] ?? { position: [0, 0, 0], quaternion: [0, 0, 0, 1] });\n }\n for (const [id, release] of Object.entries(frame.reference.releases ?? {})) outcome.releases[id] = release;\n });\n return outcome;\n}\n\nexport interface TraceTolerances {\n /** Frames a press or grab start or end may differ by. Default 1 (one frame at 72 Hz, 14 ms). */\n eventFrames: number;\n /** Absolute difference allowed in a target's 0..1 value on any frame. Default 0.02. */\n value: number;\n /** Metres a target's position may differ by on any frame. Default 0.01. */\n position: number;\n /** Fraction of the reference release speed the replay may differ by, or `releaseFloor` m/s, whichever is larger. Default 0.1. */\n releaseFraction: number;\n /** Metres per second below which two release speeds count as equal. Default 0.1. */\n releaseFloor: number;\n}\n\nexport const TRACE_TOLERANCES: Readonly<TraceTolerances> = Object.freeze({\n eventFrames: 1,\n value: 0.02,\n position: 0.01,\n releaseFraction: 0.1,\n releaseFloor: 0.1,\n});\n\n/** The events whose timing parity compares. */\nconst TIMED_EVENTS = new Set([\"pressStart\", \"pressEnd\", \"grabStart\", \"grabEnd\"]);\n\n/** One difference between a replay and the reference. */\nexport interface TraceDifference {\n kind: \"event-missing\" | \"event-extra\" | \"event-late\" | \"value\" | \"position\" | \"release\";\n interactableId: string;\n detail: string;\n}\n\n/** Compare a replay's outcome with the reference's within the tolerances. */\nexport function compareOutcomes(reference: TraceOutcome, replay: TraceOutcome, tolerances: Partial<TraceTolerances> = {}): TraceDifference[] {\n const tol = { ...TRACE_TOLERANCES, ...tolerances };\n const differences: TraceDifference[] = [];\n const refEvents = reference.events.filter((e) => TIMED_EVENTS.has(e.type));\n const repEvents = replay.events.filter((e) => TIMED_EVENTS.has(e.type));\n const used = new Set<number>();\n for (const ref of refEvents) {\n let best = -1;\n let bestDelta = Number.POSITIVE_INFINITY;\n repEvents.forEach((rep, index) => {\n if (used.has(index) || rep.type !== ref.type || rep.interactableId !== ref.interactableId) return;\n const delta = Math.abs(rep.frame - ref.frame);\n if (delta < bestDelta) {\n bestDelta = delta;\n best = index;\n }\n });\n if (best < 0) {\n differences.push({ kind: \"event-missing\", interactableId: ref.interactableId, detail: `${ref.type} on frame ${ref.frame} (t=${ref.t.toFixed(3)} s) never happened in the replay` });\n continue;\n }\n used.add(best);\n if (bestDelta > tol.eventFrames) {\n differences.push({ kind: \"event-late\", interactableId: ref.interactableId, detail: `${ref.type}: reference frame ${ref.frame}, replay frame ${repEvents[best]!.frame} (${bestDelta} frames apart, ${tol.eventFrames} allowed)` });\n }\n }\n repEvents.forEach((rep, index) => {\n if (!used.has(index)) differences.push({ kind: \"event-extra\", interactableId: rep.interactableId, detail: `${rep.type} on frame ${rep.frame} happened in the replay but not in the reference` });\n });\n for (const [id, values] of Object.entries(reference.values)) {\n const replayed = replay.values[id] ?? [];\n let worst = 0;\n let worstFrame = -1;\n values.forEach((value, frame) => {\n const delta = Math.abs((replayed[frame] ?? 0) - value);\n if (delta > worst) {\n worst = delta;\n worstFrame = frame;\n }\n });\n if (worst > tol.value) differences.push({ kind: \"value\", interactableId: id, detail: `value differs by ${worst.toFixed(4)} on frame ${worstFrame} (${tol.value} allowed)` });\n }\n for (const [id, poses] of Object.entries(reference.poses)) {\n const replayed = replay.poses[id] ?? [];\n let worst = 0;\n let worstFrame = -1;\n poses.forEach((pose, frame) => {\n const other = replayed[frame];\n if (!other) return;\n const delta = Math.hypot(other.position[0] - pose.position[0], other.position[1] - pose.position[1], other.position[2] - pose.position[2]);\n if (delta > worst) {\n worst = delta;\n worstFrame = frame;\n }\n });\n if (worst > tol.position) differences.push({ kind: \"position\", interactableId: id, detail: `position differs by ${worst.toFixed(4)} m on frame ${worstFrame} (${tol.position} allowed)` });\n }\n for (const [id, release] of Object.entries(reference.releases)) {\n const other = replay.releases[id];\n const refSpeed = Math.hypot(...release.linearVelocity);\n if (!other) {\n differences.push({ kind: \"release\", interactableId: id, detail: `the reference released at ${refSpeed.toFixed(2)} m/s; the replay handed its physics no release` });\n continue;\n }\n const speed = Math.hypot(...other.linearVelocity);\n const allowed = Math.max(tol.releaseFloor, refSpeed * tol.releaseFraction);\n const delta = Math.hypot(other.linearVelocity[0] - release.linearVelocity[0], other.linearVelocity[1] - release.linearVelocity[1], other.linearVelocity[2] - release.linearVelocity[2]);\n if (delta > allowed) {\n differences.push({ kind: \"release\", interactableId: id, detail: `release velocity differs by ${delta.toFixed(3)} m/s (reference ${refSpeed.toFixed(2)} m/s, replay ${speed.toFixed(2)} m/s, ${allowed.toFixed(3)} allowed)` });\n }\n }\n return differences;\n}\n\n/** One check a binding must pass over one trace. */\nexport interface TraceParityCase {\n name: string;\n trace: InteractionTrace;\n run(subject: TraceReplaySubject): void;\n}\n\n/**\n * The trace parity suite over a set of traces: for each, replay through the\n * subject and compare with the reference. A case fails with every difference\n * listed. A synthetic trace's case names itself as such: it proves the\n * pipeline runs on that platform, not parity with the web.\n */\nexport function traceParityCases(traces: readonly InteractionTrace[], tolerances: Partial<TraceTolerances> = {}): TraceParityCase[] {\n return traces.map((trace) => {\n const label = `${trace.meta.mechanic} with ${trace.meta.input} on ${trace.meta.device}${trace.meta.synthetic ? \" (synthetic: proves the pipeline, not parity)\" : \"\"}`;\n return {\n name: `trace parity: ${label}`,\n trace,\n run(subject) {\n if (trace.version !== TRACE_VERSION) throw new Error(`[trace parity] \"${label}\" is ${String((trace as { version: string }).version)}, this suite reads ${TRACE_VERSION}`);\n const differences = compareOutcomes(referenceOutcome(trace), replayTrace(trace, subject), tolerances);\n if (differences.length > 0) {\n throw new Error(`[trace parity] \"${label}\" differs from the reference:\\n` + differences.map((d) => ` - ${d.interactableId}: ${d.detail}`).join(\"\\n\"));\n }\n },\n };\n });\n}\n\n/** Check a parsed JSON value is a trace this module can replay. */\nexport function isInteractionTrace(value: unknown): value is InteractionTrace {\n if (typeof value !== \"object\" || value === null) return false;\n const trace = value as Partial<InteractionTrace>;\n return trace.version === TRACE_VERSION && Array.isArray(trace.frames) && Array.isArray(trace.targets) && typeof trace.meta === \"object\" && trace.meta !== null;\n}\n"]}
package/package.json CHANGED
@@ -1,14 +1,18 @@
1
1
  {
2
2
  "name": "@realitycollective/webxr-interactions",
3
- "version": "0.1.1-preview.3",
4
- "description": "Engine-free core of the Reality Collective Interaction Extensions: interactables, interactors, behaviours (press, hinge, dial, slide, grab, toss-scoring, pulse, gaze-dwell), capability negotiation and feedback hooks - driven through the shared @realitycollective/webxr-input contracts. Pair with an engine adapter: threejs-interactions, iwsdk-interactions or xrblocks-interactions.",
3
+ "version": "0.1.2-preview.0",
4
+ "description": "Engine-free core of the Reality Collective Interaction Extensions: interactables, interactors, behaviours (press, hinge, dial, slide, grab, toss-scoring, pulse, gaze-dwell), eye gaze and pinch, one pointer decision per hand across objects and UI panels, the pointer display as app configuration, a physics facility contract with held pose and release velocity, recorded-trace parity, capability negotiation and feedback hooks - driven through the shared @realitycollective/webxr-input contracts. Pair with an engine adapter: threejs-interactions, iwsdk-interactions, xrblocks-interactions, babylon-interactions or native-interactions.",
5
5
  "keywords": [
6
6
  "realitycollective",
7
7
  "webxr",
8
8
  "xr",
9
9
  "interaction",
10
10
  "input",
11
- "typescript"
11
+ "typescript",
12
+ "physics",
13
+ "grab",
14
+ "pointer",
15
+ "eye-gaze"
12
16
  ],
13
17
  "license": "MIT",
14
18
  "author": "Reality Collective",
@@ -31,7 +35,7 @@
31
35
  "typecheck": "tsc -p tsconfig.json --noEmit"
32
36
  },
33
37
  "dependencies": {
34
- "@realitycollective/webxr-input": "^0.1.7"
38
+ "@realitycollective/webxr-input": "^0.1.8"
35
39
  },
36
40
  "repository": {
37
41
  "type": "git",