@uptimizr/db 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 +109 -0
- package/LICENSE +201 -0
- package/README.md +89 -0
- package/dist/cli/createProject.d.ts +3 -0
- package/dist/cli/createProject.d.ts.map +1 -0
- package/dist/cli/createProject.js +41 -0
- package/dist/cli/createProject.js.map +1 -0
- package/dist/cli/migrate.d.ts +3 -0
- package/dist/cli/migrate.d.ts.map +1 -0
- package/dist/cli/migrate.js +21 -0
- package/dist/cli/migrate.js.map +1 -0
- package/dist/cli/seed.d.ts +2 -0
- package/dist/cli/seed.d.ts.map +1 -0
- package/dist/cli/seed.js +175 -0
- package/dist/cli/seed.js.map +1 -0
- package/dist/duckdb/client.d.ts +42 -0
- package/dist/duckdb/client.d.ts.map +1 -0
- package/dist/duckdb/client.js +93 -0
- package/dist/duckdb/client.js.map +1 -0
- package/dist/duckdb/events.d.ts +44 -0
- package/dist/duckdb/events.d.ts.map +1 -0
- package/dist/duckdb/events.js +225 -0
- package/dist/duckdb/events.js.map +1 -0
- package/dist/duckdb/migrations.d.ts +20 -0
- package/dist/duckdb/migrations.d.ts.map +1 -0
- package/dist/duckdb/migrations.js +323 -0
- package/dist/duckdb/migrations.js.map +1 -0
- package/dist/duckdb/projects.d.ts +23 -0
- package/dist/duckdb/projects.d.ts.map +1 -0
- package/dist/duckdb/projects.js +55 -0
- package/dist/duckdb/projects.js.map +1 -0
- package/dist/duckdb/queries.d.ts +10 -0
- package/dist/duckdb/queries.d.ts.map +1 -0
- package/dist/duckdb/queries.js +10 -0
- package/dist/duckdb/queries.js.map +1 -0
- package/dist/duckdb/sceneRegistry.d.ts +15 -0
- package/dist/duckdb/sceneRegistry.d.ts.map +1 -0
- package/dist/duckdb/sceneRegistry.js +98 -0
- package/dist/duckdb/sceneRegistry.js.map +1 -0
- package/dist/env.d.ts +25 -0
- package/dist/env.d.ts.map +1 -0
- package/dist/env.js +55 -0
- package/dist/env.js.map +1 -0
- package/dist/events.d.ts +107 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +153 -0
- package/dist/events.js.map +1 -0
- package/dist/index.d.ts +36 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +34 -0
- package/dist/index.js.map +1 -0
- package/dist/metadata.d.ts +84 -0
- package/dist/metadata.d.ts.map +1 -0
- package/dist/metadata.js +23 -0
- package/dist/metadata.js.map +1 -0
- package/dist/parity/cases.d.ts +31 -0
- package/dist/parity/cases.d.ts.map +1 -0
- package/dist/parity/cases.js +524 -0
- package/dist/parity/cases.js.map +1 -0
- package/dist/parity/compare.d.ts +47 -0
- package/dist/parity/compare.d.ts.map +1 -0
- package/dist/parity/compare.js +90 -0
- package/dist/parity/compare.js.map +1 -0
- package/dist/parity/fixtures.d.ts +45 -0
- package/dist/parity/fixtures.d.ts.map +1 -0
- package/dist/parity/fixtures.js +157 -0
- package/dist/parity/fixtures.js.map +1 -0
- package/dist/parity/index.d.ts +12 -0
- package/dist/parity/index.d.ts.map +1 -0
- package/dist/parity/index.js +12 -0
- package/dist/parity/index.js.map +1 -0
- package/dist/query/aggregations.d.ts +393 -0
- package/dist/query/aggregations.d.ts.map +1 -0
- package/dist/query/aggregations.js +1412 -0
- package/dist/query/aggregations.js.map +1 -0
- package/dist/query/dialect.d.ts +100 -0
- package/dist/query/dialect.d.ts.map +1 -0
- package/dist/query/dialect.js +88 -0
- package/dist/query/dialect.js.map +1 -0
- package/dist/query/duckdbDialect.d.ts +27 -0
- package/dist/query/duckdbDialect.d.ts.map +1 -0
- package/dist/query/duckdbDialect.js +83 -0
- package/dist/query/duckdbDialect.js.map +1 -0
- package/dist/query/index.d.ts +22 -0
- package/dist/query/index.d.ts.map +1 -0
- package/dist/query/index.js +30 -0
- package/dist/query/index.js.map +1 -0
- package/dist/query/types.d.ts +388 -0
- package/dist/query/types.d.ts.map +1 -0
- package/dist/query/types.js +11 -0
- package/dist/query/types.js.map +1 -0
- package/llms.txt +21 -0
- package/package.json +71 -0
|
@@ -0,0 +1,524 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-engine parity cases (Phase C, ADR 0020).
|
|
3
|
+
*
|
|
4
|
+
* Each case pairs one dialect-agnostic aggregation builder with the
|
|
5
|
+
* engine-independent golden output it must produce for {@link PARITY_EVENTS}.
|
|
6
|
+
* The golden is authored as truth (hand-verified from the fixtures) so that any
|
|
7
|
+
* engine — DuckDB in OSS, ClickHouse in the scale tier — can be checked against
|
|
8
|
+
* the same expectations. Two engines that both match the golden are, by
|
|
9
|
+
* transitivity, in parity with each other.
|
|
10
|
+
*
|
|
11
|
+
* Comparison uses the tolerance rules in {@link diffParity}: order-insensitive,
|
|
12
|
+
* float-tolerant on continuous columns, integer-exact on bin indices, and
|
|
13
|
+
* temporal projection columns excluded.
|
|
14
|
+
*/
|
|
15
|
+
import { buildCameraDirectionHeatmap, buildCameraDistance, buildCameraPositionHeatmap, buildClickGazeRay, buildDistinctScenes, buildEventTypeCounts, buildEventsDaily, buildFlowHeatmap, buildListSessions, buildMeshDwell, buildDeadClicks, buildRageClicks, buildHoverDwell, buildCompileStalls, buildResourceSummary, buildCapabilityChanges, buildCameraGestures, buildNavigationStats, buildXrRotationRate, buildXrSourceUsage, buildXrAbandonment, buildInteractionsBySource, buildPerfDaily, buildPerfSummary, buildPerfDistribution, buildFpsHistogram, buildFrameTimePercentiles, buildJankRate, buildPerfByDevice, buildPerfByScene, buildResourcePercentiles, buildStabilityCounts, buildPointerHeatmap, buildSceneCoverage, buildSessionTrajectory, buildTimeseries, buildTopMeshes, buildWorldHeatmap, buildGazeHeatmap, } from "../query/aggregations.js";
|
|
16
|
+
import { PARITY_DAY, PARITY_DAY_RANGE, PARITY_PROJECT_ID, PARITY_RANGE, PARITY_T0, } from "./fixtures.js";
|
|
17
|
+
const PID = PARITY_PROJECT_ID;
|
|
18
|
+
export const PARITY_CASES = [
|
|
19
|
+
{
|
|
20
|
+
name: "listSessions",
|
|
21
|
+
build: (d) => buildListSessions(PID, PARITY_RANGE, d),
|
|
22
|
+
sortKeys: ["session_id"],
|
|
23
|
+
ignoreColumns: ["started_at", "ended_at"],
|
|
24
|
+
golden: [
|
|
25
|
+
{ session_id: "s1", visitor_id: "", events: 9 },
|
|
26
|
+
{ session_id: "s2", visitor_id: "", events: 5 },
|
|
27
|
+
],
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
name: "pointerHeatmap",
|
|
31
|
+
build: (d) => buildPointerHeatmap(PID, { ...PARITY_RANGE, bins: 10 }, d),
|
|
32
|
+
sortKeys: ["gx", "gy"],
|
|
33
|
+
golden: [
|
|
34
|
+
{ gx: 1, gy: 1, count: 1 },
|
|
35
|
+
{ gx: 5, gy: 5, count: 2 },
|
|
36
|
+
{ gx: 9, gy: 9, count: 1 },
|
|
37
|
+
],
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
name: "worldHeatmap",
|
|
41
|
+
build: (d) => buildWorldHeatmap(PID, { ...PARITY_RANGE, cellSize: 1 }, d),
|
|
42
|
+
sortKeys: ["vx", "vy", "vz"],
|
|
43
|
+
golden: [
|
|
44
|
+
{ vx: 0, vy: 0, vz: 0, count: 1 },
|
|
45
|
+
{ vx: 1, vy: 1, vz: 1, count: 2 },
|
|
46
|
+
{ vx: 5, vy: 5, vz: 5, count: 1 },
|
|
47
|
+
],
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
// Gaze heatmap (ADR 0030): voxel-binned `camera_sample.hitPoint`. Three camera
|
|
51
|
+
// samples carry a gaze hit ([0.2,0.2,0.2], [1,1,1], [5,5,5]); at cellSize 1
|
|
52
|
+
// they fall in three distinct voxels. Hand-verified from the fixtures.
|
|
53
|
+
name: "gazeHeatmap",
|
|
54
|
+
build: (d) => buildGazeHeatmap(PID, { ...PARITY_RANGE, cellSize: 1 }, d),
|
|
55
|
+
sortKeys: ["vx", "vy", "vz"],
|
|
56
|
+
golden: [
|
|
57
|
+
{ vx: 0, vy: 0, vz: 0, count: 1 },
|
|
58
|
+
{ vx: 1, vy: 1, vz: 1, count: 1 },
|
|
59
|
+
{ vx: 5, vy: 5, vz: 5, count: 1 },
|
|
60
|
+
],
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
name: "cameraDirectionHeatmap",
|
|
64
|
+
build: (d) => buildCameraDirectionHeatmap(PID, { ...PARITY_RANGE, bins: 8 }, d),
|
|
65
|
+
sortKeys: ["azimuth_bin", "elevation_bin"],
|
|
66
|
+
// Hand-verified from the three camera directions ([2,1,2], [1,3,-2],
|
|
67
|
+
// [-2,-1,1]) via azimuth=atan2(z,x), elevation=asin(y/|v|) into 8 bins.
|
|
68
|
+
golden: [
|
|
69
|
+
{ azimuth_bin: 2, elevation_bin: 6, count: 1 },
|
|
70
|
+
{ azimuth_bin: 5, elevation_bin: 4, count: 1 },
|
|
71
|
+
{ azimuth_bin: 7, elevation_bin: 2, count: 1 },
|
|
72
|
+
],
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
name: "cameraPositionHeatmap",
|
|
76
|
+
build: (d) => buildCameraPositionHeatmap(PID, { ...PARITY_RANGE, cellSize: 1 }, d),
|
|
77
|
+
sortKeys: ["gx", "gz"],
|
|
78
|
+
// The three camera positions [0,0,0], [10,0,0], [0,0,0] binned on X/Z at
|
|
79
|
+
// cellSize 1: two samples share cell (0,0), one lands in (10,0).
|
|
80
|
+
golden: [
|
|
81
|
+
{ gx: 0, gz: 0, avg_y: 0, count: 2 },
|
|
82
|
+
{ gx: 10, gz: 0, avg_y: 0, count: 1 },
|
|
83
|
+
],
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
name: "sessionTrajectory",
|
|
87
|
+
build: (d) => buildSessionTrajectory(PID, { ...PARITY_RANGE, session: "s1" }, d),
|
|
88
|
+
sortKeys: ["x", "z"],
|
|
89
|
+
ignoreColumns: ["ts"],
|
|
90
|
+
// Session s1's two camera samples in order: [0,0,0] then [10,0,0].
|
|
91
|
+
golden: [
|
|
92
|
+
{ x: 0, y: 0, z: 0 },
|
|
93
|
+
{ x: 10, y: 0, z: 0 },
|
|
94
|
+
],
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
name: "clickGazeRay",
|
|
98
|
+
build: (d) => buildClickGazeRay(PID, { ...PARITY_RANGE, cellSize: 1 }, d),
|
|
99
|
+
sortKeys: ["mesh"],
|
|
100
|
+
golden: [
|
|
101
|
+
{
|
|
102
|
+
cam_vx: 0,
|
|
103
|
+
cam_vy: 0,
|
|
104
|
+
cam_vz: 0,
|
|
105
|
+
origin_x: 0,
|
|
106
|
+
origin_y: 0,
|
|
107
|
+
origin_z: 0,
|
|
108
|
+
hit_vx: 0,
|
|
109
|
+
hit_vy: 0,
|
|
110
|
+
hit_vz: 0,
|
|
111
|
+
hit_x: 0.2,
|
|
112
|
+
hit_y: 0.2,
|
|
113
|
+
hit_z: 0.2,
|
|
114
|
+
mesh: "box",
|
|
115
|
+
count: 1,
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
cam_vx: 0,
|
|
119
|
+
cam_vy: 0,
|
|
120
|
+
cam_vz: 0,
|
|
121
|
+
origin_x: 0,
|
|
122
|
+
origin_y: 0,
|
|
123
|
+
origin_z: 0,
|
|
124
|
+
hit_vx: 1,
|
|
125
|
+
hit_vy: 1,
|
|
126
|
+
hit_vz: 1,
|
|
127
|
+
hit_x: 1,
|
|
128
|
+
hit_y: 1,
|
|
129
|
+
hit_z: 1,
|
|
130
|
+
mesh: "floor",
|
|
131
|
+
count: 1,
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
cam_vx: 10,
|
|
135
|
+
cam_vy: 0,
|
|
136
|
+
cam_vz: 0,
|
|
137
|
+
origin_x: 10,
|
|
138
|
+
origin_y: 0,
|
|
139
|
+
origin_z: 0,
|
|
140
|
+
hit_vx: 5,
|
|
141
|
+
hit_vy: 5,
|
|
142
|
+
hit_vz: 5,
|
|
143
|
+
hit_x: 5,
|
|
144
|
+
hit_y: 5,
|
|
145
|
+
hit_z: 5,
|
|
146
|
+
mesh: "sphere",
|
|
147
|
+
count: 1,
|
|
148
|
+
},
|
|
149
|
+
],
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
name: "flowHeatmap",
|
|
153
|
+
build: (d) => buildFlowHeatmap(PID, { ...PARITY_RANGE, bins: 24 }, d),
|
|
154
|
+
sortKeys: ["mesh"],
|
|
155
|
+
// One link per (clicked mesh, ASOF-preceding gaze direction), binned into 24
|
|
156
|
+
// azimuth/elevation buckets. Hand-verified from the fixtures.
|
|
157
|
+
golden: [
|
|
158
|
+
{ azimuth_bin: 15, elevation_bin: 14, mesh: "box", count: 1 },
|
|
159
|
+
{ azimuth_bin: 22, elevation_bin: 8, mesh: "floor", count: 1 },
|
|
160
|
+
{ azimuth_bin: 7, elevation_bin: 19, mesh: "sphere", count: 1 },
|
|
161
|
+
],
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
// Position-aware flow (§7.8): same three links, now also carrying the
|
|
165
|
+
// ASOF-preceding camera *position* as a standpoint voxel. At cellSize 1 the
|
|
166
|
+
// standpoints are box→(0,0,0), sphere→(10,0,0), floor→(0,0,0). The direction
|
|
167
|
+
// bins are unchanged from `flowHeatmap`. Hand-verified from the fixtures.
|
|
168
|
+
name: "flowHeatmapByStandpoint",
|
|
169
|
+
build: (d) => buildFlowHeatmap(PID, { ...PARITY_RANGE, bins: 24, cellSize: 1, groupByOrigin: true }, d),
|
|
170
|
+
sortKeys: ["mesh"],
|
|
171
|
+
golden: [
|
|
172
|
+
{
|
|
173
|
+
azimuth_bin: 15,
|
|
174
|
+
elevation_bin: 14,
|
|
175
|
+
origin_vx: 0,
|
|
176
|
+
origin_vy: 0,
|
|
177
|
+
origin_vz: 0,
|
|
178
|
+
origin_x: 0,
|
|
179
|
+
origin_y: 0,
|
|
180
|
+
origin_z: 0,
|
|
181
|
+
mesh: "box",
|
|
182
|
+
count: 1,
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
azimuth_bin: 22,
|
|
186
|
+
elevation_bin: 8,
|
|
187
|
+
origin_vx: 0,
|
|
188
|
+
origin_vy: 0,
|
|
189
|
+
origin_vz: 0,
|
|
190
|
+
origin_x: 0,
|
|
191
|
+
origin_y: 0,
|
|
192
|
+
origin_z: 0,
|
|
193
|
+
mesh: "floor",
|
|
194
|
+
count: 1,
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
azimuth_bin: 7,
|
|
198
|
+
elevation_bin: 19,
|
|
199
|
+
origin_vx: 10,
|
|
200
|
+
origin_vy: 0,
|
|
201
|
+
origin_vz: 0,
|
|
202
|
+
origin_x: 10,
|
|
203
|
+
origin_y: 0,
|
|
204
|
+
origin_z: 0,
|
|
205
|
+
mesh: "sphere",
|
|
206
|
+
count: 1,
|
|
207
|
+
},
|
|
208
|
+
],
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
name: "topMeshes",
|
|
212
|
+
build: (d) => buildTopMeshes(PID, PARITY_RANGE, d),
|
|
213
|
+
sortKeys: ["mesh"],
|
|
214
|
+
// Counts any event carrying a mesh (interactions plus mesh_visibility):
|
|
215
|
+
// box has 1 click + 1 visibility, floor 2 hits, sphere 1 click + 1 visibility.
|
|
216
|
+
golden: [
|
|
217
|
+
{ mesh: "box", count: 2 },
|
|
218
|
+
{ mesh: "floor", count: 2 },
|
|
219
|
+
{ mesh: "sphere", count: 2 },
|
|
220
|
+
],
|
|
221
|
+
},
|
|
222
|
+
{
|
|
223
|
+
name: "meshDwell",
|
|
224
|
+
build: (d) => buildMeshDwell(PID, PARITY_RANGE, d),
|
|
225
|
+
sortKeys: ["mesh"],
|
|
226
|
+
// Per-object dwell from the two mesh_visibility summaries, ranked by total
|
|
227
|
+
// on-screen time (box 4000 > sphere 2000).
|
|
228
|
+
golden: [
|
|
229
|
+
{ mesh: "box", visible_ms: 4000, centered_ms: 1500, max_screen_fraction: 0.4, samples: 1 },
|
|
230
|
+
{ mesh: "sphere", visible_ms: 2000, centered_ms: 800, max_screen_fraction: 0.7, samples: 1 },
|
|
231
|
+
],
|
|
232
|
+
},
|
|
233
|
+
{
|
|
234
|
+
name: "perfSummary",
|
|
235
|
+
build: (d) => buildPerfSummary(PID, PARITY_RANGE, d),
|
|
236
|
+
sortKeys: ["samples"],
|
|
237
|
+
golden: [{ samples: 3, avg_fps: 45, min_fps: 30, p50_fps: 45 }],
|
|
238
|
+
},
|
|
239
|
+
{
|
|
240
|
+
name: "perfDistribution",
|
|
241
|
+
build: (d) => buildPerfDistribution(PID, PARITY_RANGE, d),
|
|
242
|
+
sortKeys: ["sessions"],
|
|
243
|
+
// Per session: s1 fps [30,60] -> p05 31.5 / p50 45 / p95 58.5; s2 fps [45] ->
|
|
244
|
+
// 45 across the board. Median across the two sessions of each percentile.
|
|
245
|
+
golden: [{ sessions: 2, samples: 3, p05_fps: 38.25, p50_fps: 45, p95_fps: 51.75 }],
|
|
246
|
+
},
|
|
247
|
+
{
|
|
248
|
+
name: "fpsHistogram",
|
|
249
|
+
build: (d) => buildFpsHistogram(PID, PARITY_RANGE, d),
|
|
250
|
+
sortKeys: ["bucket"],
|
|
251
|
+
// Session medians: s1 -> 45, s2 -> 45. Both land in the [40,50) bin (width 10).
|
|
252
|
+
golden: [{ bucket: 40, sessions: 2 }],
|
|
253
|
+
},
|
|
254
|
+
{
|
|
255
|
+
name: "frameTimePercentiles",
|
|
256
|
+
build: (d) => buildFrameTimePercentiles(PID, PARITY_RANGE, d),
|
|
257
|
+
sortKeys: ["sessions"],
|
|
258
|
+
// Per session: s1 median frame_time_ms = median(16,33) = 24.5, worst p95 =
|
|
259
|
+
// max(20,40) = 40; s2 = 22 / 28. Median across sessions of each.
|
|
260
|
+
golden: [{ sessions: 2, samples: 3, p50_ms: 23.25, p95_ms: 34 }],
|
|
261
|
+
},
|
|
262
|
+
{
|
|
263
|
+
name: "jankRate",
|
|
264
|
+
build: (d) => buildJankRate(PID, PARITY_RANGE, d),
|
|
265
|
+
sortKeys: ["sessions"],
|
|
266
|
+
// Per session long-frames-per-window: s1 = (1+5)/2 = 3, s2 = 2/1 = 2.
|
|
267
|
+
// median(3,2) = 2.5; p90 of [2,3] = 2.9; total long frames = 8.
|
|
268
|
+
golden: [{ sessions: 2, total_long_frames: 8, median_rate: 2.5, worst_decile_rate: 2.9 }],
|
|
269
|
+
},
|
|
270
|
+
{
|
|
271
|
+
name: "perfByDevice",
|
|
272
|
+
build: (d) => buildPerfByDevice(PID, PARITY_RANGE, d),
|
|
273
|
+
sortKeys: ["engine"],
|
|
274
|
+
// s1 -> webgpu (2 samples), s2 -> webgl2 (1 sample); both sessions have a
|
|
275
|
+
// single median FPS of 45. isMobile/renderer were never reported -> ''.
|
|
276
|
+
golden: [
|
|
277
|
+
{ engine: "webgl2", is_mobile: "", renderer: "", sessions: 1, samples: 1, p50_fps: 45 },
|
|
278
|
+
{ engine: "webgpu", is_mobile: "", renderer: "", sessions: 1, samples: 2, p50_fps: 45 },
|
|
279
|
+
],
|
|
280
|
+
},
|
|
281
|
+
{
|
|
282
|
+
name: "perfByScene",
|
|
283
|
+
build: (d) => buildPerfByScene(PID, PARITY_RANGE, d),
|
|
284
|
+
sortKeys: ["scene_id"],
|
|
285
|
+
// s1 renders lobby (2 samples), s2 renders arena (1 sample); each session's
|
|
286
|
+
// median FPS is 45.
|
|
287
|
+
golden: [
|
|
288
|
+
{ scene_id: "arena", sessions: 1, samples: 1, p50_fps: 45 },
|
|
289
|
+
{ scene_id: "lobby", sessions: 1, samples: 2, p50_fps: 45 },
|
|
290
|
+
],
|
|
291
|
+
},
|
|
292
|
+
{
|
|
293
|
+
name: "resourcePercentiles",
|
|
294
|
+
build: (d) => buildResourcePercentiles(PID, PARITY_RANGE, d),
|
|
295
|
+
sortKeys: ["sessions"],
|
|
296
|
+
// No resource_sample fixtures: no sessions contribute, so every percentile is
|
|
297
|
+
// NULL and the sample total is NULL. Validates the nested per-session
|
|
298
|
+
// aggregation renders identically on both engines.
|
|
299
|
+
golden: [
|
|
300
|
+
{
|
|
301
|
+
sessions: 0,
|
|
302
|
+
samples: null,
|
|
303
|
+
p50_js_heap_bytes: null,
|
|
304
|
+
p95_js_heap_bytes: null,
|
|
305
|
+
p50_texture_bytes: null,
|
|
306
|
+
p95_texture_bytes: null,
|
|
307
|
+
p50_triangles: null,
|
|
308
|
+
p95_triangles: null,
|
|
309
|
+
},
|
|
310
|
+
],
|
|
311
|
+
},
|
|
312
|
+
{
|
|
313
|
+
name: "stabilityCounts",
|
|
314
|
+
build: (d) => buildStabilityCounts(PID, PARITY_RANGE, d),
|
|
315
|
+
sortKeys: ["incidents"],
|
|
316
|
+
// No context_lost / compile_stall fixtures: all counts coalesce to 0.
|
|
317
|
+
golden: [{ context_losses: 0, compile_stalls: 0, incidents: 0 }],
|
|
318
|
+
},
|
|
319
|
+
{
|
|
320
|
+
name: "deadClicks",
|
|
321
|
+
build: (d) => buildDeadClicks(PID, PARITY_RANGE, d),
|
|
322
|
+
sortKeys: ["total_clicks"],
|
|
323
|
+
// All three pointer_click fixtures hit a mesh, so none are dead. Validates
|
|
324
|
+
// the empty-mesh count renders identically on both engines (#46).
|
|
325
|
+
golden: [{ total_clicks: 3, dead_clicks: 0 }],
|
|
326
|
+
},
|
|
327
|
+
{
|
|
328
|
+
name: "rageClicks",
|
|
329
|
+
build: (d) => buildRageClicks(PID, PARITY_RANGE, d),
|
|
330
|
+
sortKeys: ["session_id", "mesh", "bucket"],
|
|
331
|
+
// The three clicks are on distinct meshes spread across time, so no burst
|
|
332
|
+
// reaches the default threshold. Validates the GROUP/HAVING renders the same
|
|
333
|
+
// (empty) result on both engines (#47).
|
|
334
|
+
golden: [],
|
|
335
|
+
},
|
|
336
|
+
{
|
|
337
|
+
name: "hoverDwell",
|
|
338
|
+
build: (d) => buildHoverDwell(PID, PARITY_RANGE, d),
|
|
339
|
+
sortKeys: ["mesh"],
|
|
340
|
+
// No hover_dwell fixtures in the parity set, so the per-mesh hesitation roll-up
|
|
341
|
+
// is empty. Validates the GROUP/ORDER renders identically on both engines (#48).
|
|
342
|
+
golden: [],
|
|
343
|
+
},
|
|
344
|
+
{
|
|
345
|
+
name: "compileStalls",
|
|
346
|
+
build: (d) => buildCompileStalls(PID, PARITY_RANGE, d),
|
|
347
|
+
sortKeys: ["phase"],
|
|
348
|
+
// No compile_stall fixtures in the parity set, so the per-phase compile-stall
|
|
349
|
+
// roll-up is empty. Validates the GROUP/ORDER renders identically on both
|
|
350
|
+
// engines (#42).
|
|
351
|
+
golden: [],
|
|
352
|
+
},
|
|
353
|
+
{
|
|
354
|
+
name: "resourceSummary",
|
|
355
|
+
build: (d) => buildResourceSummary(PID, PARITY_RANGE, d),
|
|
356
|
+
sortKeys: ["samples"],
|
|
357
|
+
// No resource_sample fixtures in the parity set: count is 0 and every
|
|
358
|
+
// avg/max is NULL. Validates the aggregate (incl. NULLIF) renders identically
|
|
359
|
+
// on both engines (#44).
|
|
360
|
+
golden: [
|
|
361
|
+
{
|
|
362
|
+
samples: 0,
|
|
363
|
+
avg_js_heap_bytes: null,
|
|
364
|
+
max_js_heap_bytes: null,
|
|
365
|
+
avg_triangles: null,
|
|
366
|
+
max_triangles: null,
|
|
367
|
+
avg_vertices: null,
|
|
368
|
+
max_vertices: null,
|
|
369
|
+
avg_texture_bytes: null,
|
|
370
|
+
max_texture_bytes: null,
|
|
371
|
+
avg_geometry_bytes: null,
|
|
372
|
+
max_geometry_bytes: null,
|
|
373
|
+
},
|
|
374
|
+
],
|
|
375
|
+
},
|
|
376
|
+
{
|
|
377
|
+
name: "capabilityChanges",
|
|
378
|
+
build: (d) => buildCapabilityChanges(PID, PARITY_RANGE, d),
|
|
379
|
+
sortKeys: ["kind", "from", "to"],
|
|
380
|
+
// No capability_change fixtures in the parity set, so the per-transition
|
|
381
|
+
// roll-up is empty. Validates the GROUP/ORDER (with reserved-word aliases)
|
|
382
|
+
// renders identically on both engines (#49).
|
|
383
|
+
golden: [],
|
|
384
|
+
},
|
|
385
|
+
{
|
|
386
|
+
name: "cameraGestures",
|
|
387
|
+
build: (d) => buildCameraGestures(PID, PARITY_RANGE, d),
|
|
388
|
+
sortKeys: ["kind"],
|
|
389
|
+
// No camera_gesture fixtures in the parity set, so the per-kind navigation
|
|
390
|
+
// roll-up is empty. Validates the GROUP/ORDER renders identically on both
|
|
391
|
+
// engines (ADR 0025).
|
|
392
|
+
golden: [],
|
|
393
|
+
},
|
|
394
|
+
{
|
|
395
|
+
name: "perfDaily",
|
|
396
|
+
build: (d) => buildPerfDaily(PID, PARITY_DAY_RANGE, d),
|
|
397
|
+
sortKeys: ["day"],
|
|
398
|
+
golden: [{ day: PARITY_DAY, samples: 3, avg_fps: 45, min_fps: 30, p50_fps: 45 }],
|
|
399
|
+
},
|
|
400
|
+
{
|
|
401
|
+
name: "eventsDaily",
|
|
402
|
+
build: (d) => buildEventsDaily(PID, PARITY_DAY_RANGE, d),
|
|
403
|
+
sortKeys: ["event_type"],
|
|
404
|
+
golden: [
|
|
405
|
+
{ day: PARITY_DAY, event_type: "camera_sample", events: 3 },
|
|
406
|
+
{ day: PARITY_DAY, event_type: "frame_perf", events: 3 },
|
|
407
|
+
{ day: PARITY_DAY, event_type: "mesh_visibility", events: 2 },
|
|
408
|
+
{ day: PARITY_DAY, event_type: "pointer_click", events: 3 },
|
|
409
|
+
{ day: PARITY_DAY, event_type: "pointer_move", events: 1 },
|
|
410
|
+
{ day: PARITY_DAY, event_type: "session_start", events: 2 },
|
|
411
|
+
],
|
|
412
|
+
},
|
|
413
|
+
{
|
|
414
|
+
name: "distinctScenes",
|
|
415
|
+
build: (d) => buildDistinctScenes(PID, PARITY_RANGE, d),
|
|
416
|
+
sortKeys: ["scene_id"],
|
|
417
|
+
ignoreColumns: ["last_seen"],
|
|
418
|
+
golden: [
|
|
419
|
+
{ scene_id: "arena", events: 5 },
|
|
420
|
+
{ scene_id: "lobby", events: 9 },
|
|
421
|
+
],
|
|
422
|
+
},
|
|
423
|
+
{
|
|
424
|
+
name: "timeseries",
|
|
425
|
+
build: (d) => buildTimeseries(PID, { ...PARITY_RANGE, interval: 60 }, d),
|
|
426
|
+
sortKeys: ["bucket"],
|
|
427
|
+
golden: [{ bucket: PARITY_T0, events: 14, avg_fps: 45 }],
|
|
428
|
+
},
|
|
429
|
+
{
|
|
430
|
+
name: "eventTypeCounts",
|
|
431
|
+
build: (d) => buildEventTypeCounts(PID, PARITY_RANGE, d),
|
|
432
|
+
sortKeys: ["event_type"],
|
|
433
|
+
golden: [
|
|
434
|
+
{ event_type: "camera_sample", count: 3 },
|
|
435
|
+
{ event_type: "frame_perf", count: 3 },
|
|
436
|
+
{ event_type: "mesh_visibility", count: 2 },
|
|
437
|
+
{ event_type: "pointer_click", count: 3 },
|
|
438
|
+
{ event_type: "pointer_move", count: 1 },
|
|
439
|
+
{ event_type: "session_start", count: 2 },
|
|
440
|
+
],
|
|
441
|
+
},
|
|
442
|
+
{
|
|
443
|
+
name: "sceneCoverage",
|
|
444
|
+
build: (d) => buildSceneCoverage(PID, { ...PARITY_RANGE, cellSize: 1 }, d),
|
|
445
|
+
sortKeys: ["vx", "vy", "vz"],
|
|
446
|
+
// Camera positions [0,0,0] (s1 + s2) and [10,0,0] (s1) voxel-binned at size 1.
|
|
447
|
+
golden: [
|
|
448
|
+
{ vx: 0, vy: 0, vz: 0, count: 2 },
|
|
449
|
+
{ vx: 10, vy: 0, vz: 0, count: 1 },
|
|
450
|
+
],
|
|
451
|
+
},
|
|
452
|
+
{
|
|
453
|
+
name: "cameraDistance",
|
|
454
|
+
build: (d) => buildCameraDistance(PID, { ...PARITY_RANGE, center: [0, 0, 0], bucketSize: 1 }, d),
|
|
455
|
+
sortKeys: ["bucket"],
|
|
456
|
+
// Distances from origin: 0 (s1 + s2) and 10 (s1), bucketed by 1.
|
|
457
|
+
golden: [
|
|
458
|
+
{ bucket: 0, count: 2 },
|
|
459
|
+
{ bucket: 10, count: 1 },
|
|
460
|
+
],
|
|
461
|
+
},
|
|
462
|
+
{
|
|
463
|
+
name: "navigationStats",
|
|
464
|
+
build: (d) => buildNavigationStats(PID, PARITY_RANGE, d),
|
|
465
|
+
sortKeys: ["session_id"],
|
|
466
|
+
// s1 travels [0,0,0] -> [10,0,0] = 10 units (one active segment); s2 has a
|
|
467
|
+
// single sample, so it yields no segment and drops out of the inner join.
|
|
468
|
+
golden: [
|
|
469
|
+
{
|
|
470
|
+
session_id: "s1",
|
|
471
|
+
segments: 1,
|
|
472
|
+
total_distance: 10,
|
|
473
|
+
active_segments: 1,
|
|
474
|
+
active_distance: 10,
|
|
475
|
+
},
|
|
476
|
+
],
|
|
477
|
+
},
|
|
478
|
+
{
|
|
479
|
+
name: "xrRotationRate",
|
|
480
|
+
build: (d) => buildXrRotationRate(PID, PARITY_RANGE, d),
|
|
481
|
+
sortKeys: ["session_id"],
|
|
482
|
+
// s1's two view directions ([2,1,2] -> [1,3,-2]) subtend
|
|
483
|
+
// acos(1 / (3*sqrt(14))) = 1.4815909832 rad — one segment, above the 0.5 rad
|
|
484
|
+
// rapid threshold. s2 has a single sample, so no segment.
|
|
485
|
+
golden: [
|
|
486
|
+
{
|
|
487
|
+
session_id: "s1",
|
|
488
|
+
samples: 1,
|
|
489
|
+
avg_turn_rad: 1.4815909832473548,
|
|
490
|
+
max_turn_rad: 1.4815909832473548,
|
|
491
|
+
total_turn_rad: 1.4815909832473548,
|
|
492
|
+
rapid_segments: 1,
|
|
493
|
+
},
|
|
494
|
+
],
|
|
495
|
+
},
|
|
496
|
+
{
|
|
497
|
+
name: "xrSourceUsage",
|
|
498
|
+
build: (d) => buildXrSourceUsage(PID, PARITY_RANGE, d),
|
|
499
|
+
sortKeys: ["source"],
|
|
500
|
+
// The fixtures use only `mouse`, so no immersive input source is present.
|
|
501
|
+
golden: [],
|
|
502
|
+
},
|
|
503
|
+
{
|
|
504
|
+
name: "xrAbandonment",
|
|
505
|
+
build: (d) => buildXrAbandonment(PID, PARITY_RANGE, d),
|
|
506
|
+
sortKeys: ["session_id"],
|
|
507
|
+
ignoreColumns: ["started_at", "ended_at"],
|
|
508
|
+
// No session used an XR input source in the fixtures, so none qualifies.
|
|
509
|
+
golden: [],
|
|
510
|
+
},
|
|
511
|
+
{
|
|
512
|
+
name: "interactionsBySource",
|
|
513
|
+
build: (d) => buildInteractionsBySource(PID, PARITY_RANGE, d),
|
|
514
|
+
sortKeys: ["event_type", "source"],
|
|
515
|
+
// The fixtures hold three mouse clicks (two in s1, one in s2) and one mouse
|
|
516
|
+
// move (s2). Validates the per-(event_type, source) GROUP and the
|
|
517
|
+
// DISTINCT-session count render identically on both engines (ADR 0011).
|
|
518
|
+
golden: [
|
|
519
|
+
{ event_type: "pointer_click", source: "mouse", count: 3, sessions: 2 },
|
|
520
|
+
{ event_type: "pointer_move", source: "mouse", count: 1, sessions: 1 },
|
|
521
|
+
],
|
|
522
|
+
},
|
|
523
|
+
];
|
|
524
|
+
//# sourceMappingURL=cases.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cases.js","sourceRoot":"","sources":["../../src/parity/cases.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tolerance-aware row comparison for cross-engine parity (Phase C, ADR 0020).
|
|
3
|
+
*
|
|
4
|
+
* Two SQL engines (DuckDB for OSS, ClickHouse for the scale tier)
|
|
5
|
+
* implement the same dialect-agnostic aggregations. Their numeric output can
|
|
6
|
+
* differ in the last bits of floating-point arithmetic and their row order is
|
|
7
|
+
* only as stable as the query's `ORDER BY`. This module encodes the tolerance
|
|
8
|
+
* rules that let "equal analytics" be asserted despite those differences.
|
|
9
|
+
*
|
|
10
|
+
* ## Tolerance rules
|
|
11
|
+
*
|
|
12
|
+
* 1. **Order-insensitive.** Rows are compared as a multiset: both sides are
|
|
13
|
+
* sorted by the case's `sortKeys` before comparison. SQL guarantees no row
|
|
14
|
+
* order beyond an explicit `ORDER BY`, and ties under `ORDER BY count` are
|
|
15
|
+
* unstable across engines.
|
|
16
|
+
* 2. **Float tolerance.** Numeric columns (averages, quantiles, ASOF ray
|
|
17
|
+
* origins/hits) match when their absolute difference is within
|
|
18
|
+
* {@link PARITY_ABS_TOLERANCE} or their relative difference is within
|
|
19
|
+
* {@link PARITY_REL_TOLERANCE}. Counts and bin indices are integers and so
|
|
20
|
+
* compare exactly under the same rule (difference 0).
|
|
21
|
+
* 3. **Bin indices are integer-exact.** Heatmap bin columns come from
|
|
22
|
+
* `floor(...)` and are deterministic within an engine; they are integers and
|
|
23
|
+
* compared exactly. Inputs are chosen to avoid landing exactly on a bin
|
|
24
|
+
* boundary, where a sub-ulp difference could flip the floor across engines.
|
|
25
|
+
* 4. **Temporal projections are excluded.** Wall-clock `TIMESTAMP` columns
|
|
26
|
+
* (e.g. `started_at`, `ended_at`, `last_seen`) are presentation metadata, not
|
|
27
|
+
* analytics, and their string rendering differs by engine; list them in a
|
|
28
|
+
* case's `ignoreColumns`. Date-granular `day` strings (`YYYY-MM-DD`) render
|
|
29
|
+
* identically in both engines and are compared.
|
|
30
|
+
*/
|
|
31
|
+
/** Absolute tolerance for floating-point column comparison. */
|
|
32
|
+
export declare const PARITY_ABS_TOLERANCE = 0.000001;
|
|
33
|
+
/** Relative tolerance for floating-point column comparison. */
|
|
34
|
+
export declare const PARITY_REL_TOLERANCE = 1e-9;
|
|
35
|
+
export type ParityRow = Record<string, unknown>;
|
|
36
|
+
export interface ParityCompareOptions {
|
|
37
|
+
/** Columns that, together, uniquely order a row for multiset comparison. */
|
|
38
|
+
readonly sortKeys: readonly string[];
|
|
39
|
+
/** Columns ignored entirely (engine-specific temporal renderings). */
|
|
40
|
+
readonly ignoreColumns?: readonly string[];
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Compare engine output against golden rows under the tolerance rules above.
|
|
44
|
+
* Returns a list of human-readable differences; an empty list means parity.
|
|
45
|
+
*/
|
|
46
|
+
export declare function diffParity(actual: readonly ParityRow[], golden: readonly ParityRow[], options: ParityCompareOptions): string[];
|
|
47
|
+
//# sourceMappingURL=compare.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compare.d.ts","sourceRoot":"","sources":["../../src/parity/compare.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,+DAA+D;AAC/D,eAAO,MAAM,oBAAoB,WAAO,CAAC;AAEzC,+DAA+D;AAC/D,eAAO,MAAM,oBAAoB,OAAO,CAAC;AAEzC,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEhD,MAAM,WAAW,oBAAoB;IACnC,4EAA4E;IAC5E,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,sEAAsE;IACtE,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC5C;AAiCD;;;GAGG;AACH,wBAAgB,UAAU,CACxB,MAAM,EAAE,SAAS,SAAS,EAAE,EAC5B,MAAM,EAAE,SAAS,SAAS,EAAE,EAC5B,OAAO,EAAE,oBAAoB,GAC5B,MAAM,EAAE,CA0BV"}
|