@uptimizr/sdk-core 0.1.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.
Files changed (65) hide show
  1. package/AGENTS.md +70 -0
  2. package/LICENSE +201 -0
  3. package/README.md +109 -0
  4. package/dist/client.d.ts +116 -0
  5. package/dist/client.d.ts.map +1 -0
  6. package/dist/client.js +451 -0
  7. package/dist/client.js.map +1 -0
  8. package/dist/coordinates.d.ts +98 -0
  9. package/dist/coordinates.d.ts.map +1 -0
  10. package/dist/coordinates.js +127 -0
  11. package/dist/coordinates.js.map +1 -0
  12. package/dist/gesture.d.ts +96 -0
  13. package/dist/gesture.d.ts.map +1 -0
  14. package/dist/gesture.js +178 -0
  15. package/dist/gesture.js.map +1 -0
  16. package/dist/idgen.d.ts +8 -0
  17. package/dist/idgen.d.ts.map +1 -0
  18. package/dist/idgen.js +15 -0
  19. package/dist/idgen.js.map +1 -0
  20. package/dist/index.d.ts +24 -0
  21. package/dist/index.d.ts.map +1 -0
  22. package/dist/index.js +18 -0
  23. package/dist/index.js.map +1 -0
  24. package/dist/matrix.d.ts +22 -0
  25. package/dist/matrix.d.ts.map +1 -0
  26. package/dist/matrix.js +60 -0
  27. package/dist/matrix.js.map +1 -0
  28. package/dist/offloadProtocol.d.ts +40 -0
  29. package/dist/offloadProtocol.d.ts.map +1 -0
  30. package/dist/offloadProtocol.js +2 -0
  31. package/dist/offloadProtocol.js.map +1 -0
  32. package/dist/offloadWorker.d.ts +2 -0
  33. package/dist/offloadWorker.d.ts.map +1 -0
  34. package/dist/offloadWorker.js +41 -0
  35. package/dist/offloadWorker.js.map +1 -0
  36. package/dist/processor.d.ts +102 -0
  37. package/dist/processor.d.ts.map +1 -0
  38. package/dist/processor.js +145 -0
  39. package/dist/processor.js.map +1 -0
  40. package/dist/queue.d.ts +22 -0
  41. package/dist/queue.d.ts.map +1 -0
  42. package/dist/queue.js +39 -0
  43. package/dist/queue.js.map +1 -0
  44. package/dist/sampling.d.ts +124 -0
  45. package/dist/sampling.d.ts.map +1 -0
  46. package/dist/sampling.js +36 -0
  47. package/dist/sampling.js.map +1 -0
  48. package/dist/transport.d.ts +10 -0
  49. package/dist/transport.d.ts.map +1 -0
  50. package/dist/transport.js +37 -0
  51. package/dist/transport.js.map +1 -0
  52. package/dist/types.d.ts +186 -0
  53. package/dist/types.d.ts.map +1 -0
  54. package/dist/types.js +2 -0
  55. package/dist/types.js.map +1 -0
  56. package/dist/version.d.ts +3 -0
  57. package/dist/version.d.ts.map +1 -0
  58. package/dist/version.js +3 -0
  59. package/dist/version.js.map +1 -0
  60. package/dist/xrInput.d.ts +54 -0
  61. package/dist/xrInput.d.ts.map +1 -0
  62. package/dist/xrInput.js +20 -0
  63. package/dist/xrInput.js.map +1 -0
  64. package/llms.txt +16 -0
  65. package/package.json +61 -0
package/dist/client.js ADDED
@@ -0,0 +1,451 @@
1
+ import { SCHEMA_VERSION, DEFAULT_SCENE_ID, sceneIdSchema } from "@uptimizr/schema";
2
+ import { EventQueue } from "./queue.js";
3
+ import { randomId } from "./idgen.js";
4
+ import { createBeaconTransport } from "./transport.js";
5
+ import { createMainProcessor, createWorkerProcessor, } from "./processor.js";
6
+ import { SDK_VERSION } from "./version.js";
7
+ const DEFAULTS = {
8
+ batchSize: 20,
9
+ flushIntervalMs: 5000,
10
+ maxQueueSize: 1000,
11
+ resizeDebounceMs: 250,
12
+ };
13
+ function resolveConfig(config) {
14
+ return {
15
+ projectId: config.projectId,
16
+ endpoint: config.endpoint,
17
+ sdkVersion: config.sdkVersion ?? SDK_VERSION,
18
+ batchSize: config.batchSize ?? DEFAULTS.batchSize,
19
+ flushIntervalMs: config.flushIntervalMs ?? DEFAULTS.flushIntervalMs,
20
+ maxQueueSize: config.maxQueueSize ?? DEFAULTS.maxQueueSize,
21
+ offload: config.offload ?? "main",
22
+ disabled: config.disabled ?? false,
23
+ captureLifecycle: config.captureLifecycle ?? true,
24
+ resizeDebounceMs: config.resizeDebounceMs ?? DEFAULTS.resizeDebounceMs,
25
+ captureErrors: config.captureErrors ?? false,
26
+ debug: config.debug ?? false,
27
+ };
28
+ }
29
+ /**
30
+ * The core Uptimizr client. Framework-agnostic: it owns the session, the event
31
+ * queue, batching/flush scheduling, and transport. Engine-specific capture is added
32
+ * via `use(collector)` (e.g. the Babylon adapter), keeping this package free of any
33
+ * 3D-engine dependency.
34
+ *
35
+ * Privacy: no cookies, no persistent client ID. The `sessionId` is in-memory only
36
+ * and the server assigns the cookieless `visitorId` during ingestion (ADR 0003).
37
+ */
38
+ export class UptimizrClient {
39
+ config;
40
+ sessionId;
41
+ queue;
42
+ transport;
43
+ processor;
44
+ beforeSend;
45
+ collectors = [];
46
+ handles = [];
47
+ started = false;
48
+ startedAt = 0;
49
+ url;
50
+ currentScene = DEFAULT_SCENE_ID;
51
+ pageMeta;
52
+ flushTimer;
53
+ resizeTimer;
54
+ errorCount = 0;
55
+ lastErrorKey;
56
+ boundVisibility = () => this.onVisibilityChange();
57
+ boundPageHide = () => {
58
+ void this.stop("hidden");
59
+ };
60
+ boundFocus = () => this.onFocusChange(true);
61
+ boundBlur = () => this.onFocusChange(false);
62
+ boundResize = () => this.onResize();
63
+ boundError = (event) => this.onErrorEvent(event);
64
+ boundRejection = (event) => this.onUnhandledRejection(event);
65
+ constructor(config) {
66
+ this.config = resolveConfig(config);
67
+ this.sessionId = randomId();
68
+ this.queue = new EventQueue(this.config.maxQueueSize);
69
+ this.transport = config.transport ?? createBeaconTransport(this.config.endpoint);
70
+ this.processor = this.createProcessor(config);
71
+ this.beforeSend = config.beforeSend;
72
+ }
73
+ /** Register a capture plugin. Call before `start` (or after; it starts immediately). */
74
+ use(collector) {
75
+ this.collectors.push(collector);
76
+ if (this.started) {
77
+ this.startCollector(collector);
78
+ }
79
+ return this;
80
+ }
81
+ /** Begin the session: emit `session_start`, schedule flushing, and start collectors. */
82
+ start(meta = {}) {
83
+ if (this.started || this.config.disabled) {
84
+ return;
85
+ }
86
+ this.started = true;
87
+ this.startedAt = this.now();
88
+ this.url = meta.url ?? this.defaultUrl();
89
+ this.pageMeta = meta.pageMeta;
90
+ // Apply the initial scene (if any) before session_start so it is stamped.
91
+ if (meta.sceneId != null) {
92
+ const parsed = sceneIdSchema.safeParse(meta.sceneId);
93
+ if (parsed.success) {
94
+ this.currentScene = parsed.data;
95
+ }
96
+ else {
97
+ this.log(`ignoring invalid initial sceneId: ${String(meta.sceneId)}`);
98
+ }
99
+ }
100
+ this.emit({
101
+ type: "session_start",
102
+ ...(meta.device ? { device: meta.device } : {}),
103
+ ...(meta.graphics ? { graphics: meta.graphics } : {}),
104
+ ...(meta.scene ? { scene: meta.scene } : {}),
105
+ ...(meta.connector ? { connector: meta.connector } : {}),
106
+ ...(meta.user ? { user: meta.user } : {}),
107
+ });
108
+ if (this.config.flushIntervalMs > 0) {
109
+ this.flushTimer = setInterval(() => void this.flush(), this.config.flushIntervalMs);
110
+ }
111
+ this.bindLifecycle();
112
+ for (const collector of this.collectors) {
113
+ this.startCollector(collector);
114
+ }
115
+ }
116
+ /**
117
+ * Switch the active scene/area (ADR 0010). Stamps the new `sceneId` on every
118
+ * subsequent event and emits an ordered `scene_change` marker so the replay
119
+ * timeline records the transition. Invalid ids are ignored (logged in debug).
120
+ * No-ops if the scene is unchanged. May be called before `start`, in which case
121
+ * the scene is applied to `session_start`.
122
+ */
123
+ setScene(sceneId) {
124
+ if (this.config.disabled) {
125
+ return;
126
+ }
127
+ const parsed = sceneIdSchema.safeParse(sceneId);
128
+ if (!parsed.success) {
129
+ this.log(`ignoring invalid sceneId: ${String(sceneId)}`);
130
+ return;
131
+ }
132
+ if (parsed.data === this.currentScene) {
133
+ return;
134
+ }
135
+ this.currentScene = parsed.data;
136
+ if (this.started) {
137
+ this.emit({ type: "scene_change" });
138
+ }
139
+ }
140
+ /** Build the envelope and queue an event. */
141
+ emit(input) {
142
+ if (!this.started || this.config.disabled) {
143
+ return;
144
+ }
145
+ const event = {
146
+ ...input,
147
+ projectId: this.config.projectId,
148
+ sessionId: this.sessionId,
149
+ ts: this.now(),
150
+ sdkVersion: this.config.sdkVersion,
151
+ ...(this.url ? { url: this.url } : {}),
152
+ ...(this.currentScene !== DEFAULT_SCENE_ID ? { sceneId: this.currentScene } : {}),
153
+ ...(this.pageMeta ? { pageMeta: this.pageMeta } : {}),
154
+ };
155
+ const finalEvent = this.beforeSend ? this.beforeSend(event) : event;
156
+ if (!finalEvent) {
157
+ return;
158
+ }
159
+ this.queue.enqueue(finalEvent);
160
+ if (this.queue.size >= this.config.batchSize) {
161
+ void this.flush();
162
+ }
163
+ }
164
+ /** Emit a developer-defined `custom` event. */
165
+ track(name, props) {
166
+ this.emit({ type: "custom", name, ...(props ? { props } : {}) });
167
+ }
168
+ /**
169
+ * Emit an `input_action` for a discrete, non-pointer input — a keyboard
170
+ * key/chord or a gamepad button bound to an app action (ADR 0023). This is the
171
+ * engine-neutral path: the host app reports the *semantic* action it mapped the
172
+ * input to. Pointer/ray inputs flow through the connector's `pointer_*` /
173
+ * `mesh_interaction` capture instead; continuous navigation stays in
174
+ * `camera_sample`.
175
+ *
176
+ * Privacy (ADR 0003): pass app-defined action labels only — never raw typed
177
+ * text. `source` defaults to `"keyboard"` since that is the most common caller.
178
+ */
179
+ trackInput(action, opts = {}) {
180
+ if (!action) {
181
+ return;
182
+ }
183
+ this.emit({
184
+ type: "input_action",
185
+ action,
186
+ source: opts.source ?? "keyboard",
187
+ ...(opts.code ? { code: opts.code } : {}),
188
+ ...(typeof opts.button === "number" ? { button: opts.button } : {}),
189
+ ...(typeof opts.pressed === "boolean" ? { pressed: opts.pressed } : {}),
190
+ ...(opts.handedness ? { handedness: opts.handedness } : {}),
191
+ ...(opts.sourceId ? { sourceId: opts.sourceId } : {}),
192
+ });
193
+ }
194
+ /**
195
+ * Report a capability / fidelity transition — a fallback or recovery (#49,
196
+ * design §E). Engines decide their backend at init and rarely expose a runtime
197
+ * "I downgraded" hook, so this is the engine-neutral, **app-reported** path: the
198
+ * host app describes the transition it performed (e.g. a WebGPU→WebGL2
199
+ * downgrade, a quality/LOD auto-downgrade, or a re-init after a lost device).
200
+ * This pairs with the raw `context_lost` / `context_restored` lifecycle events.
201
+ *
202
+ * Privacy (ADR 0003): pass low-cardinality, app-defined tokens only — never raw
203
+ * device strings or PII.
204
+ */
205
+ reportCapabilityChange(change) {
206
+ if (!change.kind) {
207
+ return;
208
+ }
209
+ this.emit({
210
+ type: "capability_change",
211
+ kind: change.kind,
212
+ ...(change.from ? { from: change.from } : {}),
213
+ ...(change.to ? { to: change.to } : {}),
214
+ ...(change.reason ? { reason: change.reason } : {}),
215
+ });
216
+ }
217
+ /** Send all queued events. On failure, events are re-queued for the next attempt. */
218
+ async flush(opts) {
219
+ const events = this.queue.drain();
220
+ if (events.length === 0) {
221
+ return;
222
+ }
223
+ const batch = { schemaVersion: SCHEMA_VERSION, events };
224
+ // Steady-state batches may be offloaded to a worker; the terminal unload
225
+ // flush always runs on the main thread for delivery reliability (ADR 0031).
226
+ const ok = await (opts?.unload
227
+ ? this.processor.processUnload(batch)
228
+ : this.processor.process(batch));
229
+ if (!ok) {
230
+ this.queue.prepend(events);
231
+ this.log("flush failed; re-queued", events.length);
232
+ }
233
+ }
234
+ /** End the session: emit `session_end`, flush, and tear down collectors/timers. */
235
+ async stop(reason = "manual") {
236
+ if (!this.started) {
237
+ return;
238
+ }
239
+ this.emit({
240
+ type: "session_end",
241
+ durationMs: this.now() - this.startedAt,
242
+ reason,
243
+ });
244
+ this.started = false;
245
+ if (this.flushTimer) {
246
+ clearInterval(this.flushTimer);
247
+ this.flushTimer = undefined;
248
+ }
249
+ this.unbindLifecycle();
250
+ for (const handle of this.handles.splice(0)) {
251
+ handle.stop();
252
+ }
253
+ // Terminal flush on the main thread (beacon-reliable), then release the
254
+ // worker if one was running (ADR 0031).
255
+ await this.flush({ unload: true });
256
+ this.processor.dispose();
257
+ }
258
+ /** Current time in epoch ms. Isolated for test overrides. */
259
+ now() {
260
+ return Date.now();
261
+ }
262
+ /**
263
+ * Choose the processor (ADR 0031). Defaults to the main-thread processor.
264
+ * `offload: "worker"` opts into a worker for steady-state serialization +
265
+ * dispatch, but only when no custom transport is set (a custom transport is a
266
+ * main-thread closure the worker cannot run) and a worker can actually be
267
+ * constructed; otherwise it transparently falls back to the main thread.
268
+ */
269
+ createProcessor(config) {
270
+ if (this.config.offload === "worker") {
271
+ if (config.transport) {
272
+ this.log("custom transport set; worker offload disabled (transport runs on main thread)");
273
+ }
274
+ else {
275
+ const worker = createWorkerProcessor({
276
+ endpoint: this.config.endpoint,
277
+ unloadTransport: this.transport,
278
+ ...(config.createWorker
279
+ ? { workerFactory: config.createWorker }
280
+ : {}),
281
+ });
282
+ if (worker) {
283
+ return worker;
284
+ }
285
+ this.log("worker offload unavailable; falling back to main-thread processor");
286
+ }
287
+ }
288
+ return createMainProcessor(this.transport);
289
+ }
290
+ startCollector(collector) {
291
+ const ctx = {
292
+ config: this.config,
293
+ sessionId: this.sessionId,
294
+ emit: (event) => this.emit(event),
295
+ track: (name, props) => this.track(name, props),
296
+ trackInput: (action, opts) => this.trackInput(action, opts),
297
+ reportCapabilityChange: (change) => this.reportCapabilityChange(change),
298
+ setScene: (sceneId) => this.setScene(sceneId),
299
+ now: () => this.now(),
300
+ };
301
+ try {
302
+ const handle = collector.start(ctx);
303
+ if (handle) {
304
+ this.handles.push(handle);
305
+ }
306
+ }
307
+ catch (err) {
308
+ this.log(`collector "${collector.name}" failed to start`, err);
309
+ }
310
+ }
311
+ onVisibilityChange() {
312
+ const doc = globalThis.document;
313
+ const hidden = doc?.visibilityState === "hidden";
314
+ if (this.config.captureLifecycle && doc) {
315
+ this.emit({ type: "visibility_change", state: hidden ? "hidden" : "visible" });
316
+ }
317
+ if (hidden) {
318
+ void this.flush({ unload: true });
319
+ }
320
+ }
321
+ onFocusChange(focused) {
322
+ if (this.config.captureLifecycle) {
323
+ this.emit({ type: "focus_change", focused });
324
+ }
325
+ }
326
+ onResize() {
327
+ if (!this.config.captureLifecycle) {
328
+ return;
329
+ }
330
+ if (this.resizeTimer) {
331
+ clearTimeout(this.resizeTimer);
332
+ }
333
+ this.resizeTimer = setTimeout(() => {
334
+ this.resizeTimer = undefined;
335
+ this.emitViewportResize();
336
+ }, this.config.resizeDebounceMs);
337
+ }
338
+ /** Emit a `viewport_resize` from the current window dimensions, if available. */
339
+ emitViewportResize() {
340
+ const g = globalThis;
341
+ if (typeof g.innerWidth !== "number" || typeof g.innerHeight !== "number") {
342
+ return;
343
+ }
344
+ if (g.innerWidth <= 0 || g.innerHeight <= 0) {
345
+ return;
346
+ }
347
+ this.emit({
348
+ type: "viewport_resize",
349
+ width: g.innerWidth,
350
+ height: g.innerHeight,
351
+ ...(typeof g.devicePixelRatio === "number" ? { dpr: g.devicePixelRatio } : {}),
352
+ });
353
+ }
354
+ /** Max `runtime_error` events emitted per session (ADR 0013 storm control). */
355
+ static MAX_ERRORS_PER_SESSION = 50;
356
+ onErrorEvent(event) {
357
+ this.emitError({
358
+ kind: "error",
359
+ message: event.message || "Unknown error",
360
+ ...(event.filename ? { source: event.filename } : {}),
361
+ ...(typeof event.lineno === "number" ? { lineno: event.lineno } : {}),
362
+ ...(typeof event.colno === "number" ? { colno: event.colno } : {}),
363
+ ...(event.error instanceof Error && event.error.stack ? { stack: event.error.stack } : {}),
364
+ });
365
+ }
366
+ onUnhandledRejection(event) {
367
+ const reason = event.reason;
368
+ const message = reason instanceof Error
369
+ ? reason.message
370
+ : typeof reason === "string"
371
+ ? reason
372
+ : "Unhandled promise rejection";
373
+ this.emitError({
374
+ kind: "unhandledrejection",
375
+ message: message || "Unhandled promise rejection",
376
+ ...(reason instanceof Error && reason.stack ? { stack: reason.stack } : {}),
377
+ });
378
+ }
379
+ /**
380
+ * Emit a `runtime_error`, applying ADR 0013 storm control: drop a consecutive
381
+ * duplicate (same message+stack) and cap the total per session. Free-text
382
+ * fields are length-bounded to match the schema; deeper redaction is the
383
+ * deployer's job via `beforeSend`.
384
+ */
385
+ emitError(input) {
386
+ if (this.errorCount >= UptimizrClient.MAX_ERRORS_PER_SESSION)
387
+ return;
388
+ const key = `${input.message}\u0000${input.stack ?? ""}`;
389
+ if (key === this.lastErrorKey)
390
+ return;
391
+ this.lastErrorKey = key;
392
+ this.errorCount += 1;
393
+ this.emit({
394
+ type: "runtime_error",
395
+ kind: input.kind,
396
+ message: input.message.slice(0, 1024),
397
+ ...(input.source ? { source: input.source.slice(0, 1024) } : {}),
398
+ ...(typeof input.lineno === "number" ? { lineno: input.lineno } : {}),
399
+ ...(typeof input.colno === "number" ? { colno: input.colno } : {}),
400
+ ...(input.stack ? { stack: input.stack.slice(0, 4096) } : {}),
401
+ });
402
+ }
403
+ bindLifecycle() {
404
+ const doc = globalThis.document;
405
+ const win = globalThis.addEventListener
406
+ ? globalThis
407
+ : undefined;
408
+ doc?.addEventListener("visibilitychange", this.boundVisibility);
409
+ win?.addEventListener("pagehide", this.boundPageHide);
410
+ if (this.config.captureLifecycle && win) {
411
+ win.addEventListener("focus", this.boundFocus);
412
+ win.addEventListener("blur", this.boundBlur);
413
+ win.addEventListener("resize", this.boundResize);
414
+ // Emit an initial viewport sample so every session has a known starting
415
+ // viewport for heatmap normalization.
416
+ this.emitViewportResize();
417
+ }
418
+ if (this.config.captureErrors && win) {
419
+ win.addEventListener("error", this.boundError);
420
+ win.addEventListener("unhandledrejection", this.boundRejection);
421
+ }
422
+ }
423
+ unbindLifecycle() {
424
+ const doc = globalThis.document;
425
+ const win = globalThis
426
+ .removeEventListener
427
+ ? globalThis
428
+ : undefined;
429
+ doc?.removeEventListener("visibilitychange", this.boundVisibility);
430
+ win?.removeEventListener("pagehide", this.boundPageHide);
431
+ win?.removeEventListener("focus", this.boundFocus);
432
+ win?.removeEventListener("blur", this.boundBlur);
433
+ win?.removeEventListener("resize", this.boundResize);
434
+ win?.removeEventListener("error", this.boundError);
435
+ win?.removeEventListener("unhandledrejection", this.boundRejection);
436
+ if (this.resizeTimer) {
437
+ clearTimeout(this.resizeTimer);
438
+ this.resizeTimer = undefined;
439
+ }
440
+ }
441
+ defaultUrl() {
442
+ const loc = globalThis.location;
443
+ return loc?.href;
444
+ }
445
+ log(...args) {
446
+ if (this.config.debug) {
447
+ console.debug("[uptimizr]", ...args);
448
+ }
449
+ }
450
+ }
451
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,98 @@
1
+ import type { Aabb, CoordinateHandedness, Quat, Vec3 } from "@uptimizr/schema";
2
+ /**
3
+ * Canonical world coordinate frame for everything on the wire (ADR 0018):
4
+ * **left-handed, y-up, unit scale 1** (Babylon-native). Connectors normalize their
5
+ * engine's world-space data to this frame at the emission boundary and record their
6
+ * native frame as provenance on `session_start`.
7
+ */
8
+ export declare const CANONICAL_FRAME: {
9
+ readonly handedness: "left";
10
+ readonly upAxis: "y";
11
+ readonly unitScale: 1;
12
+ };
13
+ /**
14
+ * Convert a **world-space position** from a source engine's frame to the canonical
15
+ * frame (left-handed, y-up).
16
+ *
17
+ * Assumes a **y-up** source (true for three.js, glTF, PlayCanvas, Babylon). For a
18
+ * right-handed source the handedness flip is the reflection `diag(1, 1, -1)` —
19
+ * i.e. negate Z. A left-handed source is already canonical and is returned
20
+ * unchanged (a fresh copy). Non-y-up sources are out of scope; the connector must
21
+ * rebase to y-up before calling.
22
+ */
23
+ export declare function toCanonicalPosition(p: Vec3, sourceHandedness: CoordinateHandedness): Vec3;
24
+ /**
25
+ * Convert a **world-space direction vector** (e.g. a camera's forward ray) from a
26
+ * source engine's frame to the canonical frame. Same reflection as
27
+ * {@link toCanonicalPosition} — directions ignore translation, so a right-handed
28
+ * source negates Z.
29
+ *
30
+ * ⚠️ Orientation is convention-dependent, and this is the common trap. A camera's
31
+ * *look direction* differs per engine: three.js cameras look along local **−Z**,
32
+ * the canonical (Babylon-style) camera looks along local **+Z**. This helper is
33
+ * correct **only when you pass a true world-space direction** (the actual look
34
+ * vector in world coordinates). If you instead reconstruct orientation from a
35
+ * **local quaternion / Euler**, reflecting components is **not** enough — you must
36
+ * also apply a rotation (a forward-axis flip / ~180° about the up axis) to account
37
+ * for the −Z vs +Z forward convention. Capture orientation as a world-space
38
+ * forward (and up) direction *before* converting.
39
+ */
40
+ export declare function toCanonicalDirection(d: Vec3, sourceHandedness: CoordinateHandedness): Vec3;
41
+ /**
42
+ * Convert a world-space axis-aligned bounding box `[minX, minY, minZ, maxX, maxY,
43
+ * maxZ]` to the canonical frame. Negating the Z axis swaps the Z min/max, so the
44
+ * result stays a well-formed AABB (min ≤ max per axis).
45
+ */
46
+ export declare function toCanonicalAabb(aabb: Aabb, sourceHandedness: CoordinateHandedness): Aabb;
47
+ /**
48
+ * Convert a **world-space position** from the canonical frame back into a target
49
+ * engine's native frame — the inverse of {@link toCanonicalPosition}. Used by
50
+ * replay drivers, which read canonical events off the wire and write them into a
51
+ * host scene (e.g. re-driving a three.js camera).
52
+ *
53
+ * The handedness flip is the reflection `diag(1, 1, -1)`, which is its own
54
+ * inverse, so this delegates to the same basis change — but the named inverse
55
+ * keeps replay/host code self-documenting (canonical → engine).
56
+ */
57
+ export declare function fromCanonicalPosition(p: Vec3, targetHandedness: CoordinateHandedness): Vec3;
58
+ /**
59
+ * Convert a **world-space direction vector** from the canonical frame back into a
60
+ * target engine's native frame — the inverse of {@link toCanonicalDirection}.
61
+ *
62
+ * The same orientation caveat applies in reverse: this yields a correct
63
+ * world-space direction, but a host that needs a *camera orientation* should
64
+ * point the camera at a converted world-space target (e.g. `camera.lookAt`)
65
+ * rather than feeding this into a local-rotation reconstruction.
66
+ */
67
+ export declare function fromCanonicalDirection(d: Vec3, targetHandedness: CoordinateHandedness): Vec3;
68
+ /**
69
+ * Convert a world-space AABB from the canonical frame back into a target engine's
70
+ * native frame — the inverse of {@link toCanonicalAabb} (Z min/max swap is its
71
+ * own inverse, so the box stays well-formed).
72
+ */
73
+ export declare function fromCanonicalAabb(aabb: Aabb, targetHandedness: CoordinateHandedness): Aabb;
74
+ /**
75
+ * Convert a **world-space orientation quaternion** `[x, y, z, w]` from a source
76
+ * engine's frame to the canonical frame (left-handed, y-up). Used for
77
+ * `node_transform` (ADR 0027): a scene actor's world rotation.
78
+ *
79
+ * The handedness flip is the same reflection as {@link toCanonicalPosition}
80
+ * (`diag(1, 1, -1)`, i.e. negate Z). Conjugating a rotation by that reflection
81
+ * maps the quaternion `(x, y, z, w) → (-x, -y, z, w)`: the reflected rotation
82
+ * axis is `(ax, ay, -az)` while the handedness flip negates the angle, and the
83
+ * two sign changes combine to leave only `x` and `y` negated. A left-handed
84
+ * source is already canonical and returned as a copy.
85
+ *
86
+ * Unlike a camera's *look direction* (whose forward-axis convention differs per
87
+ * engine — see {@link toCanonicalDirection}), an object's world rotation has no
88
+ * such convention, so this conversion is exact for scene-actor orientation.
89
+ */
90
+ export declare function toCanonicalQuat(q: Quat, sourceHandedness: CoordinateHandedness): Quat;
91
+ /**
92
+ * Convert a **world-space orientation quaternion** from the canonical frame back
93
+ * into a target engine's native frame — the inverse of {@link toCanonicalQuat}.
94
+ * The reflection is its own inverse, so this delegates to the same basis change;
95
+ * the named inverse keeps replay/host code self-documenting (canonical → engine).
96
+ */
97
+ export declare function fromCanonicalQuat(q: Quat, targetHandedness: CoordinateHandedness): Quat;
98
+ //# sourceMappingURL=coordinates.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"coordinates.d.ts","sourceRoot":"","sources":["../src/coordinates.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,oBAAoB,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAE/E;;;;;GAKG;AACH,eAAO,MAAM,eAAe;;;;CAIlB,CAAC;AAOX;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,IAAI,EAAE,gBAAgB,EAAE,oBAAoB,GAAG,IAAI,CAGzF;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,IAAI,EAAE,gBAAgB,EAAE,oBAAoB,GAAG,IAAI,CAG1F;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,IAAI,EAAE,gBAAgB,EAAE,oBAAoB,GAAG,IAAI,CAMxF;AAED;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,EAAE,IAAI,EAAE,gBAAgB,EAAE,oBAAoB,GAAG,IAAI,CAE3F;AAED;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CAAC,CAAC,EAAE,IAAI,EAAE,gBAAgB,EAAE,oBAAoB,GAAG,IAAI,CAE5F;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,IAAI,EAAE,gBAAgB,EAAE,oBAAoB,GAAG,IAAI,CAE1F;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,IAAI,EAAE,gBAAgB,EAAE,oBAAoB,GAAG,IAAI,CAGrF;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,IAAI,EAAE,gBAAgB,EAAE,oBAAoB,GAAG,IAAI,CAEvF"}