@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.
- package/AGENTS.md +70 -0
- package/LICENSE +201 -0
- package/README.md +109 -0
- package/dist/client.d.ts +116 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +451 -0
- package/dist/client.js.map +1 -0
- package/dist/coordinates.d.ts +98 -0
- package/dist/coordinates.d.ts.map +1 -0
- package/dist/coordinates.js +127 -0
- package/dist/coordinates.js.map +1 -0
- package/dist/gesture.d.ts +96 -0
- package/dist/gesture.d.ts.map +1 -0
- package/dist/gesture.js +178 -0
- package/dist/gesture.js.map +1 -0
- package/dist/idgen.d.ts +8 -0
- package/dist/idgen.d.ts.map +1 -0
- package/dist/idgen.js +15 -0
- package/dist/idgen.js.map +1 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -0
- package/dist/matrix.d.ts +22 -0
- package/dist/matrix.d.ts.map +1 -0
- package/dist/matrix.js +60 -0
- package/dist/matrix.js.map +1 -0
- package/dist/offloadProtocol.d.ts +40 -0
- package/dist/offloadProtocol.d.ts.map +1 -0
- package/dist/offloadProtocol.js +2 -0
- package/dist/offloadProtocol.js.map +1 -0
- package/dist/offloadWorker.d.ts +2 -0
- package/dist/offloadWorker.d.ts.map +1 -0
- package/dist/offloadWorker.js +41 -0
- package/dist/offloadWorker.js.map +1 -0
- package/dist/processor.d.ts +102 -0
- package/dist/processor.d.ts.map +1 -0
- package/dist/processor.js +145 -0
- package/dist/processor.js.map +1 -0
- package/dist/queue.d.ts +22 -0
- package/dist/queue.d.ts.map +1 -0
- package/dist/queue.js +39 -0
- package/dist/queue.js.map +1 -0
- package/dist/sampling.d.ts +124 -0
- package/dist/sampling.d.ts.map +1 -0
- package/dist/sampling.js +36 -0
- package/dist/sampling.js.map +1 -0
- package/dist/transport.d.ts +10 -0
- package/dist/transport.d.ts.map +1 -0
- package/dist/transport.js +37 -0
- package/dist/transport.js.map +1 -0
- package/dist/types.d.ts +186 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/version.d.ts +3 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +3 -0
- package/dist/version.js.map +1 -0
- package/dist/xrInput.d.ts +54 -0
- package/dist/xrInput.d.ts.map +1 -0
- package/dist/xrInput.js +20 -0
- package/dist/xrInput.js.map +1 -0
- package/llms.txt +16 -0
- package/package.json +61 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default browser transport.
|
|
3
|
+
*
|
|
4
|
+
* Prefers `navigator.sendBeacon` so in-flight batches survive page unload, and
|
|
5
|
+
* falls back to `fetch` with `keepalive` (and finally a plain `fetch`) in
|
|
6
|
+
* environments where beacon is unavailable (including Node for tests).
|
|
7
|
+
*/
|
|
8
|
+
export function createBeaconTransport(endpoint) {
|
|
9
|
+
const url = endpoint.replace(/\/$/, "") + "/api/v1/collect";
|
|
10
|
+
return {
|
|
11
|
+
async send(batch) {
|
|
12
|
+
const payload = JSON.stringify(batch);
|
|
13
|
+
const nav = globalThis.navigator;
|
|
14
|
+
if (nav && typeof nav.sendBeacon === "function") {
|
|
15
|
+
const blob = new Blob([payload], { type: "application/json" });
|
|
16
|
+
return nav.sendBeacon(url, blob);
|
|
17
|
+
}
|
|
18
|
+
const fetchFn = globalThis.fetch;
|
|
19
|
+
if (typeof fetchFn !== "function") {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
try {
|
|
23
|
+
const res = await fetchFn(url, {
|
|
24
|
+
method: "POST",
|
|
25
|
+
headers: { "content-type": "application/json" },
|
|
26
|
+
body: payload,
|
|
27
|
+
keepalive: payload.length < 64_000,
|
|
28
|
+
});
|
|
29
|
+
return res.ok;
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=transport.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transport.js","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"AAGA;;;;;;GAMG;AACH,MAAM,UAAU,qBAAqB,CAAC,QAAgB;IACpD,MAAM,GAAG,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,iBAAiB,CAAC;IAE5D,OAAO;QACL,KAAK,CAAC,IAAI,CAAC,KAAqB;YAC9B,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;YAEtC,MAAM,GAAG,GAAI,UAAwC,CAAC,SAAS,CAAC;YAChE,IAAI,GAAG,IAAI,OAAO,GAAG,CAAC,UAAU,KAAK,UAAU,EAAE,CAAC;gBAChD,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,CAAC,OAAO,CAAC,EAAE,EAAE,IAAI,EAAE,kBAAkB,EAAE,CAAC,CAAC;gBAC/D,OAAO,GAAG,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;YACnC,CAAC;YAED,MAAM,OAAO,GAAI,UAAuC,CAAC,KAAK,CAAC;YAC/D,IAAI,OAAO,OAAO,KAAK,UAAU,EAAE,CAAC;gBAClC,OAAO,KAAK,CAAC;YACf,CAAC;YAED,IAAI,CAAC;gBACH,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,GAAG,EAAE;oBAC7B,MAAM,EAAE,MAAM;oBACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;oBAC/C,IAAI,EAAE,OAAO;oBACb,SAAS,EAAE,OAAO,CAAC,MAAM,GAAG,MAAM;iBACnC,CAAC,CAAC;gBACH,OAAO,GAAG,CAAC,EAAE,CAAC;YAChB,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import type { AnyEvent, CapabilityChangeKind, CollectRequest, Connector, CustomPropValue, Device, Graphics, Handedness, InputSource, PageMeta, SceneMeta, SessionUser } from "@uptimizr/schema";
|
|
2
|
+
/**
|
|
3
|
+
* Envelope fields the client fills in automatically. Collectors and callers only
|
|
4
|
+
* provide the event `type` and its payload — never these.
|
|
5
|
+
*/
|
|
6
|
+
export type EnvelopeKey = "projectId" | "visitorId" | "sessionId" | "ts" | "sdkVersion" | "url" | "sceneId" | "pageMeta";
|
|
7
|
+
/**
|
|
8
|
+
* The shape a caller passes to `emit`: any event minus the auto-filled envelope.
|
|
9
|
+
* Distributes over the event union so each variant keeps its own payload typing.
|
|
10
|
+
*/
|
|
11
|
+
export type EventInput = AnyEvent extends infer E ? E extends AnyEvent ? Omit<E, EnvelopeKey> : never : never;
|
|
12
|
+
/**
|
|
13
|
+
* Options for {@link UptimizrClient.trackInput} — a discrete keyboard/gamepad
|
|
14
|
+
* action (ADR 0023). `source` defaults to `"keyboard"`.
|
|
15
|
+
*/
|
|
16
|
+
export interface TrackInputOptions {
|
|
17
|
+
/** The discrete input source. Defaults to `"keyboard"`. */
|
|
18
|
+
source?: InputSource;
|
|
19
|
+
/** Raw key code (`KeyboardEvent.code`) for keyboard inputs. */
|
|
20
|
+
code?: string;
|
|
21
|
+
/** Raw button index for gamepad inputs. */
|
|
22
|
+
button?: number;
|
|
23
|
+
/** Whether this is a press (`true`) or release (`false`). Omit for a single fire. */
|
|
24
|
+
pressed?: boolean;
|
|
25
|
+
/** Handedness for paired sources, when applicable. */
|
|
26
|
+
handedness?: Handedness;
|
|
27
|
+
/** Ephemeral, session-local id correlating a concurrent source (ADR 0011). */
|
|
28
|
+
sourceId?: string;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* A capability / fidelity transition reported to
|
|
32
|
+
* {@link UptimizrClient.reportCapabilityChange} (#49). Engines decide their
|
|
33
|
+
* backend at init and rarely expose a runtime "I downgraded" hook, so this is
|
|
34
|
+
* **app-reported**: the host app describes the fallback or recovery it performed.
|
|
35
|
+
*
|
|
36
|
+
* Privacy (ADR 0003): `from` / `to` / `reason` must be low-cardinality,
|
|
37
|
+
* app-defined tokens (e.g. `"webgpu"`, `"webgl2"`, `"high"`) — never raw device
|
|
38
|
+
* strings or PII.
|
|
39
|
+
*/
|
|
40
|
+
export interface CapabilityChangeReport {
|
|
41
|
+
/** What class of capability changed. */
|
|
42
|
+
kind: CapabilityChangeKind;
|
|
43
|
+
/** Previous capability/level as a short app-defined token (e.g. `"webgpu"`). */
|
|
44
|
+
from?: string;
|
|
45
|
+
/** New capability/level as a short app-defined token (e.g. `"webgl2"`). */
|
|
46
|
+
to?: string;
|
|
47
|
+
/** Optional short, app-defined reason for the change (no PII). */
|
|
48
|
+
reason?: string;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* A transport delivers a batch to the collector. Returns `true` on success.
|
|
52
|
+
* Swappable so callers can provide a custom transport (extension point).
|
|
53
|
+
*/
|
|
54
|
+
export interface Transport {
|
|
55
|
+
send(batch: CollectRequest): Promise<boolean>;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Context handed to each collector plugin. The capture-side API surface.
|
|
59
|
+
*/
|
|
60
|
+
export interface CollectorContext {
|
|
61
|
+
readonly config: ResolvedConfig;
|
|
62
|
+
readonly sessionId: string;
|
|
63
|
+
/** Emit a typed event; the envelope is filled in automatically. */
|
|
64
|
+
emit(event: EventInput): void;
|
|
65
|
+
/** Convenience for emitting a `custom` event. */
|
|
66
|
+
track(name: string, props?: Record<string, CustomPropValue>): void;
|
|
67
|
+
/** Emit an `input_action` for a discrete keyboard/gamepad input (ADR 0023). */
|
|
68
|
+
trackInput(action: string, opts?: TrackInputOptions): void;
|
|
69
|
+
/** Report a capability fallback/recovery transition (#49); emits `capability_change`. */
|
|
70
|
+
reportCapabilityChange(change: CapabilityChangeReport): void;
|
|
71
|
+
/** Switch the active scene/area (ADR 0010); emits a `scene_change` marker. */
|
|
72
|
+
setScene(sceneId: string): void;
|
|
73
|
+
/** Current timestamp in epoch ms (overridable for testing). */
|
|
74
|
+
now(): number;
|
|
75
|
+
}
|
|
76
|
+
/** Handle returned by a collector's `start`, used to tear it down. */
|
|
77
|
+
export interface CollectorHandle {
|
|
78
|
+
stop(): void;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* A capture plugin. This is the primary SDK extension point: engine adapters
|
|
82
|
+
* (e.g. Babylon) and custom instrumentation register as collectors via
|
|
83
|
+
* `client.use(collector)`. `start` wires up listeners and returns a handle.
|
|
84
|
+
*/
|
|
85
|
+
export interface Collector {
|
|
86
|
+
readonly name: string;
|
|
87
|
+
start(ctx: CollectorContext): CollectorHandle | void;
|
|
88
|
+
}
|
|
89
|
+
/** A hook to inspect, modify, or drop an event before it is queued. */
|
|
90
|
+
export type BeforeSendHook = (event: AnyEvent) => AnyEvent | null;
|
|
91
|
+
/** Public configuration accepted by the client. */
|
|
92
|
+
export interface UptimizrConfig {
|
|
93
|
+
/** Project identifier (public, non-secret). */
|
|
94
|
+
projectId: string;
|
|
95
|
+
/** Collector endpoint base URL, e.g. `https://collect.example.com`. */
|
|
96
|
+
endpoint: string;
|
|
97
|
+
/** Override the reported SDK version. Defaults to the package version. */
|
|
98
|
+
sdkVersion?: string;
|
|
99
|
+
/** Flush when this many events are queued. Default 20. */
|
|
100
|
+
batchSize?: number;
|
|
101
|
+
/** Flush at least this often, in ms. Default 5000. Set 0 to disable the timer. */
|
|
102
|
+
flushIntervalMs?: number;
|
|
103
|
+
/** Max events retained while offline before the oldest are dropped. Default 1000. */
|
|
104
|
+
maxQueueSize?: number;
|
|
105
|
+
/** Provide a custom transport. Defaults to a beacon/fetch transport. */
|
|
106
|
+
transport?: Transport;
|
|
107
|
+
/**
|
|
108
|
+
* Where the offload-eligible processing phase runs (ADR 0031). `"main"`
|
|
109
|
+
* (default) keeps serialization + network dispatch on the main thread —
|
|
110
|
+
* today's behaviour, byte-for-byte. `"worker"` moves *steady-state*
|
|
111
|
+
* serialization + dispatch to an opt-in Web Worker, while the terminal unload
|
|
112
|
+
* flush always stays on the main thread.
|
|
113
|
+
*
|
|
114
|
+
* Worker mode is never required for correctness: if a worker cannot be created
|
|
115
|
+
* (no `Worker`, restrictive CSP, SSR, tests) the SDK silently falls back to
|
|
116
|
+
* `"main"`. Supplying a custom {@link UptimizrConfig.transport} also disables
|
|
117
|
+
* worker offload, since a custom transport is a main-thread closure the worker
|
|
118
|
+
* cannot run; the transport is honoured on the main thread instead.
|
|
119
|
+
*/
|
|
120
|
+
offload?: "main" | "worker";
|
|
121
|
+
/**
|
|
122
|
+
* Advanced bundler escape hatch: construct the offload worker yourself when
|
|
123
|
+
* the default `new Worker(new URL("./offloadWorker.js", import.meta.url))`
|
|
124
|
+
* pattern is not handled by your bundler. Only consulted when
|
|
125
|
+
* `offload: "worker"`.
|
|
126
|
+
*/
|
|
127
|
+
createWorker?: () => Worker;
|
|
128
|
+
/** Inspect/modify/drop each event before queueing. */
|
|
129
|
+
beforeSend?: BeforeSendHook;
|
|
130
|
+
/** When true, the client collects nothing (e.g. respect Do-Not-Track). */
|
|
131
|
+
disabled?: boolean;
|
|
132
|
+
/**
|
|
133
|
+
* Capture generic browser lifecycle events — `viewport_resize` (debounced),
|
|
134
|
+
* `focus_change`, and `visibility_change` — so the timeline records when the
|
|
135
|
+
* canvas was resized, blurred, or backgrounded. Default true. The session
|
|
136
|
+
* flush-on-hidden and end-on-pagehide behavior is always active regardless.
|
|
137
|
+
*/
|
|
138
|
+
captureLifecycle?: boolean;
|
|
139
|
+
/** Debounce window for `viewport_resize`, in ms. Default 250. */
|
|
140
|
+
resizeDebounceMs?: number;
|
|
141
|
+
/**
|
|
142
|
+
* Capture JavaScript errors and unhandled promise rejections as
|
|
143
|
+
* `runtime_error` events (`window.onerror` / `unhandledrejection`). Off by
|
|
144
|
+
* default because error text can carry PII (ADR 0013) — when enabled, use
|
|
145
|
+
* `beforeSend` to redact or drop. Consecutive identical errors are deduped and
|
|
146
|
+
* at most 50 are emitted per session.
|
|
147
|
+
*/
|
|
148
|
+
captureErrors?: boolean;
|
|
149
|
+
/** Emit debug logs to the console. */
|
|
150
|
+
debug?: boolean;
|
|
151
|
+
}
|
|
152
|
+
/** Config with defaults applied. */
|
|
153
|
+
export interface ResolvedConfig {
|
|
154
|
+
projectId: string;
|
|
155
|
+
endpoint: string;
|
|
156
|
+
sdkVersion: string;
|
|
157
|
+
batchSize: number;
|
|
158
|
+
flushIntervalMs: number;
|
|
159
|
+
maxQueueSize: number;
|
|
160
|
+
offload: "main" | "worker";
|
|
161
|
+
disabled: boolean;
|
|
162
|
+
captureLifecycle: boolean;
|
|
163
|
+
resizeDebounceMs: number;
|
|
164
|
+
captureErrors: boolean;
|
|
165
|
+
debug: boolean;
|
|
166
|
+
}
|
|
167
|
+
/** Optional metadata passed to `start`. */
|
|
168
|
+
export interface StartMeta {
|
|
169
|
+
/** Device/GPU capabilities, supplied by engine adapters that can introspect them. */
|
|
170
|
+
device?: Device;
|
|
171
|
+
/** Underlying graphics technology (API/backend/version/shading language) (ADR 0021). */
|
|
172
|
+
graphics?: Graphics;
|
|
173
|
+
/** Coarse scene descriptor (camera kind, mesh count, description). */
|
|
174
|
+
scene?: SceneMeta;
|
|
175
|
+
/** Connector/engine provenance and the source's native coordinate frame (ADR 0018). */
|
|
176
|
+
connector?: Connector;
|
|
177
|
+
/** Caller-supplied, anonymized user context. Opt-in; never PII. */
|
|
178
|
+
user?: SessionUser;
|
|
179
|
+
/** Page/document context. */
|
|
180
|
+
pageMeta?: PageMeta;
|
|
181
|
+
/** Page URL. Defaults to `location.href` when available. */
|
|
182
|
+
url?: string;
|
|
183
|
+
/** Initial scene/area id (ADR 0010). Stamped on `session_start` and after. */
|
|
184
|
+
sceneId?: string;
|
|
185
|
+
}
|
|
186
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,eAAO,MAAM,WAAW,UAAU,CAAC"}
|
package/dist/version.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,MAAM,CAAC,MAAM,WAAW,GAAG,OAAO,CAAC"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { Handedness, InputSource, Vec3 } from "@uptimizr/schema";
|
|
2
|
+
/**
|
|
3
|
+
* Engine-agnostic WebXR input mapping shared by the connectors (three.js, A-Frame,
|
|
4
|
+
* Babylon, …). The per-engine XR collectors read controller pose from their own
|
|
5
|
+
* renderer / XR object and canonicalize coordinates at the emission boundary
|
|
6
|
+
* (ADR 0018); everything in this module is frame-independent — classifying a WebXR
|
|
7
|
+
* input source into the source-neutral schema vocabulary (ADR 0011) and the shared
|
|
8
|
+
* capture-option / ray-probe shapes. No new event types or fields are introduced.
|
|
9
|
+
*
|
|
10
|
+
* Privacy (ADR 0003): the only identity these collectors ever emit is the ephemeral,
|
|
11
|
+
* session-local {@link Handedness} disambiguator — never a persistent device/user id.
|
|
12
|
+
*/
|
|
13
|
+
/** Structural view of a WebXR `XRInputSource` (only the fields we classify on). */
|
|
14
|
+
export interface XrInputSourceLike {
|
|
15
|
+
/** `"left"` / `"right"` / `"none"`. */
|
|
16
|
+
handedness?: string;
|
|
17
|
+
/** `"tracked-pointer"` / `"gaze"` / `"screen"` / `"transient-pointer"`. */
|
|
18
|
+
targetRayMode?: string;
|
|
19
|
+
/** Present for articulated-hand input. */
|
|
20
|
+
hand?: unknown;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Map a WebXR input source to an Uptimizr {@link InputSource} (ADR 0011):
|
|
24
|
+
* articulated hands → `hand`, gaze target-ray → `gaze`, transient/screen taps →
|
|
25
|
+
* `transient`, everything else (tracked controllers) → `xr-controller`.
|
|
26
|
+
*/
|
|
27
|
+
export declare function xrSource(input: XrInputSourceLike): InputSource;
|
|
28
|
+
/** The paired XR hand, or `undefined` when not applicable (e.g. gaze). */
|
|
29
|
+
export declare function xrHandedness(input: XrInputSourceLike): Handedness | undefined;
|
|
30
|
+
/** Which XR signals a connector's XR collector captures. All default to `true`. */
|
|
31
|
+
export interface XrCaptureOptions {
|
|
32
|
+
/** Continuous controller/gaze pose → `pointer_move` (with `ray`). */
|
|
33
|
+
pointerMove?: boolean;
|
|
34
|
+
/** Controller `select` (trigger) → `pointer_click`. */
|
|
35
|
+
clicks?: boolean;
|
|
36
|
+
/** Named hit on select/squeeze → `mesh_interaction`. Requires a {@link XrRayProbe}. */
|
|
37
|
+
meshPicks?: boolean;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* A controller-ray raycast result, in the engine's **native** world frame (the
|
|
41
|
+
* collector canonicalizes it before emitting). Optional in every XR collector —
|
|
42
|
+
* without a probe, controller/gaze pose is still captured as `pointer_move` rays and
|
|
43
|
+
* `select` still emits `pointer_click`; only `hitPoint` / `hitMesh` and
|
|
44
|
+
* `mesh_interaction` need a probe.
|
|
45
|
+
*/
|
|
46
|
+
export interface XrRayHit {
|
|
47
|
+
/** Hit point in the engine's native world frame. */
|
|
48
|
+
point: Vec3;
|
|
49
|
+
/** Hit object's name (empty string when unnamed). */
|
|
50
|
+
name: string;
|
|
51
|
+
}
|
|
52
|
+
/** Resolve a world-space controller ray to the nearest scene hit, or `undefined`. */
|
|
53
|
+
export type XrRayProbe = (origin: Vec3, direction: Vec3) => XrRayHit | undefined;
|
|
54
|
+
//# sourceMappingURL=xrInput.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"xrInput.d.ts","sourceRoot":"","sources":["../src/xrInput.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAEtE;;;;;;;;;;GAUG;AAEH,mFAAmF;AACnF,MAAM,WAAW,iBAAiB;IAChC,uCAAuC;IACvC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,2EAA2E;IAC3E,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,0CAA0C;IAC1C,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,iBAAiB,GAAG,WAAW,CAM9D;AAED,0EAA0E;AAC1E,wBAAgB,YAAY,CAAC,KAAK,EAAE,iBAAiB,GAAG,UAAU,GAAG,SAAS,CAE7E;AAED,mFAAmF;AACnF,MAAM,WAAW,gBAAgB;IAC/B,qEAAqE;IACrE,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,uDAAuD;IACvD,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,uFAAuF;IACvF,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,QAAQ;IACvB,oDAAoD;IACpD,KAAK,EAAE,IAAI,CAAC;IACZ,qDAAqD;IACrD,IAAI,EAAE,MAAM,CAAC;CACd;AAED,qFAAqF;AACrF,MAAM,MAAM,UAAU,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,KAAK,QAAQ,GAAG,SAAS,CAAC"}
|
package/dist/xrInput.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Map a WebXR input source to an Uptimizr {@link InputSource} (ADR 0011):
|
|
3
|
+
* articulated hands → `hand`, gaze target-ray → `gaze`, transient/screen taps →
|
|
4
|
+
* `transient`, everything else (tracked controllers) → `xr-controller`.
|
|
5
|
+
*/
|
|
6
|
+
export function xrSource(input) {
|
|
7
|
+
if (input.hand != null)
|
|
8
|
+
return "hand";
|
|
9
|
+
const mode = input.targetRayMode;
|
|
10
|
+
if (mode === "gaze")
|
|
11
|
+
return "gaze";
|
|
12
|
+
if (mode === "transient-pointer" || mode === "screen")
|
|
13
|
+
return "transient";
|
|
14
|
+
return "xr-controller";
|
|
15
|
+
}
|
|
16
|
+
/** The paired XR hand, or `undefined` when not applicable (e.g. gaze). */
|
|
17
|
+
export function xrHandedness(input) {
|
|
18
|
+
return input.handedness === "left" || input.handedness === "right" ? input.handedness : undefined;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=xrInput.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"xrInput.js","sourceRoot":"","sources":["../src/xrInput.ts"],"names":[],"mappings":"AAwBA;;;;GAIG;AACH,MAAM,UAAU,QAAQ,CAAC,KAAwB;IAC/C,IAAI,KAAK,CAAC,IAAI,IAAI,IAAI;QAAE,OAAO,MAAM,CAAC;IACtC,MAAM,IAAI,GAAG,KAAK,CAAC,aAAa,CAAC;IACjC,IAAI,IAAI,KAAK,MAAM;QAAE,OAAO,MAAM,CAAC;IACnC,IAAI,IAAI,KAAK,mBAAmB,IAAI,IAAI,KAAK,QAAQ;QAAE,OAAO,WAAW,CAAC;IAC1E,OAAO,eAAe,CAAC;AACzB,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,YAAY,CAAC,KAAwB;IACnD,OAAO,KAAK,CAAC,UAAU,KAAK,MAAM,IAAI,KAAK,CAAC,UAAU,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC;AACpG,CAAC"}
|
package/llms.txt
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# @uptimizr/sdk-core
|
|
2
|
+
|
|
3
|
+
> The framework-agnostic Uptimizr capture runtime: session, in-memory batching, flush
|
|
4
|
+
> scheduling, and a cookieless transport, with a pluggable collector system. No engine knowledge.
|
|
5
|
+
|
|
6
|
+
## Docs
|
|
7
|
+
|
|
8
|
+
- [Package reference](./README.md): usage, collector extension point, all config options, transport.
|
|
9
|
+
- [Agent guide](./AGENTS.md): rules and canonical usage for AI agents.
|
|
10
|
+
- [Integration & API reference](https://github.com/RaananW/Uptimizr/blob/main/docs/integration.md): how tracking flows end-to-end.
|
|
11
|
+
- [Architecture Decision Records](https://github.com/RaananW/Uptimizr/tree/main/docs/adr): privacy model (0003), thin backends (0005).
|
|
12
|
+
|
|
13
|
+
## Key exports
|
|
14
|
+
|
|
15
|
+
- `UptimizrClient` — create, `start()`, `track(name, props)`, `use(collector)`, `stop()`.
|
|
16
|
+
- `Collector` / `Transport` types — the extension points.
|
package/package.json
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@uptimizr/sdk-core",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Framework-agnostic Uptimizr capture runtime — session, batching, cookieless transport, and a pluggable collector system.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"uptimizr",
|
|
7
|
+
"analytics",
|
|
8
|
+
"3d",
|
|
9
|
+
"webgl",
|
|
10
|
+
"webgpu",
|
|
11
|
+
"telemetry",
|
|
12
|
+
"session",
|
|
13
|
+
"cookieless",
|
|
14
|
+
"privacy"
|
|
15
|
+
],
|
|
16
|
+
"license": "Apache-2.0",
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "git+https://github.com/RaananW/Uptimizr.git",
|
|
20
|
+
"directory": "oss/packages/sdk-core"
|
|
21
|
+
},
|
|
22
|
+
"bugs": {
|
|
23
|
+
"url": "https://github.com/RaananW/Uptimizr/issues"
|
|
24
|
+
},
|
|
25
|
+
"homepage": "https://github.com/RaananW/Uptimizr/tree/main/oss/packages/sdk-core#readme",
|
|
26
|
+
"publishConfig": {
|
|
27
|
+
"access": "public"
|
|
28
|
+
},
|
|
29
|
+
"type": "module",
|
|
30
|
+
"main": "./dist/index.js",
|
|
31
|
+
"module": "./dist/index.js",
|
|
32
|
+
"types": "./dist/index.d.ts",
|
|
33
|
+
"exports": {
|
|
34
|
+
".": {
|
|
35
|
+
"types": "./dist/index.d.ts",
|
|
36
|
+
"import": "./dist/index.js"
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
"files": [
|
|
40
|
+
"dist",
|
|
41
|
+
"README.md",
|
|
42
|
+
"LICENSE",
|
|
43
|
+
"AGENTS.md",
|
|
44
|
+
"llms.txt"
|
|
45
|
+
],
|
|
46
|
+
"sideEffects": false,
|
|
47
|
+
"dependencies": {
|
|
48
|
+
"@uptimizr/schema": "0.1.0"
|
|
49
|
+
},
|
|
50
|
+
"devDependencies": {
|
|
51
|
+
"vitest": "^4.1.9"
|
|
52
|
+
},
|
|
53
|
+
"scripts": {
|
|
54
|
+
"build": "tsc -p tsconfig.json",
|
|
55
|
+
"dev": "tsc -p tsconfig.json --watch",
|
|
56
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
57
|
+
"test": "vitest run",
|
|
58
|
+
"lint": "eslint .",
|
|
59
|
+
"clean": "rm -rf dist *.tsbuildinfo"
|
|
60
|
+
}
|
|
61
|
+
}
|