@squasher-ai/browser 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 (63) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +12 -0
  3. package/dist/__tests__/client.test.d.ts +2 -0
  4. package/dist/__tests__/client.test.d.ts.map +1 -0
  5. package/dist/__tests__/client.test.js +103 -0
  6. package/dist/__tests__/errors.test.d.ts +2 -0
  7. package/dist/__tests__/errors.test.d.ts.map +1 -0
  8. package/dist/__tests__/errors.test.js +80 -0
  9. package/dist/__tests__/replay-privacy.test.d.ts +2 -0
  10. package/dist/__tests__/replay-privacy.test.d.ts.map +1 -0
  11. package/dist/__tests__/replay-privacy.test.js +124 -0
  12. package/dist/__tests__/replay-startup.test.d.ts +2 -0
  13. package/dist/__tests__/replay-startup.test.d.ts.map +1 -0
  14. package/dist/__tests__/replay-startup.test.js +99 -0
  15. package/dist/__tests__/replay.test.d.ts +2 -0
  16. package/dist/__tests__/replay.test.d.ts.map +1 -0
  17. package/dist/__tests__/replay.test.js +217 -0
  18. package/dist/__tests__/session.test.d.ts +2 -0
  19. package/dist/__tests__/session.test.d.ts.map +1 -0
  20. package/dist/__tests__/session.test.js +46 -0
  21. package/dist/__tests__/transport.test.d.ts +2 -0
  22. package/dist/__tests__/transport.test.d.ts.map +1 -0
  23. package/dist/__tests__/transport.test.js +101 -0
  24. package/dist/__tests__/types.test.d.ts +2 -0
  25. package/dist/__tests__/types.test.d.ts.map +1 -0
  26. package/dist/__tests__/types.test.js +139 -0
  27. package/dist/autocapture.d.ts +21 -0
  28. package/dist/autocapture.d.ts.map +1 -0
  29. package/dist/autocapture.js +191 -0
  30. package/dist/client.d.ts +46 -0
  31. package/dist/client.d.ts.map +1 -0
  32. package/dist/client.js +215 -0
  33. package/dist/errors.d.ts +29 -0
  34. package/dist/errors.d.ts.map +1 -0
  35. package/dist/errors.js +111 -0
  36. package/dist/index.d.ts +62 -0
  37. package/dist/index.d.ts.map +1 -0
  38. package/dist/index.js +105 -0
  39. package/dist/react.d.ts +32 -0
  40. package/dist/react.d.ts.map +1 -0
  41. package/dist/react.js +42 -0
  42. package/dist/replay-privacy.d.ts +16 -0
  43. package/dist/replay-privacy.d.ts.map +1 -0
  44. package/dist/replay-privacy.js +64 -0
  45. package/dist/replay.d.ts +30 -0
  46. package/dist/replay.d.ts.map +1 -0
  47. package/dist/replay.js +158 -0
  48. package/dist/session.d.ts +21 -0
  49. package/dist/session.d.ts.map +1 -0
  50. package/dist/session.js +52 -0
  51. package/dist/telemetry.d.ts +20 -0
  52. package/dist/telemetry.d.ts.map +1 -0
  53. package/dist/telemetry.js +145 -0
  54. package/dist/transport.d.ts +47 -0
  55. package/dist/transport.d.ts.map +1 -0
  56. package/dist/transport.js +145 -0
  57. package/dist/types.d.ts +234 -0
  58. package/dist/types.d.ts.map +1 -0
  59. package/dist/types.js +8 -0
  60. package/dist/vitals.d.ts +30 -0
  61. package/dist/vitals.d.ts.map +1 -0
  62. package/dist/vitals.js +92 -0
  63. package/package.json +44 -0
package/dist/vitals.js ADDED
@@ -0,0 +1,92 @@
1
+ /**
2
+ * Core Web Vitals collector.
3
+ *
4
+ * Uses Google's `web-vitals` library to measure:
5
+ * - LCP (Largest Contentful Paint)
6
+ * - CLS (Cumulative Layout Shift)
7
+ * - INP (Interaction to Next Paint)
8
+ * - FCP (First Contentful Paint)
9
+ * - TTFB (Time to First Byte)
10
+ *
11
+ * Each metric fires once (LCP, FCP, TTFB) or accumulates (CLS, INP).
12
+ * Measurements are mapped to VitalEvent and queued via the transport.
13
+ */
14
+ import { onLCP, onCLS, onINP, onFCP, onTTFB } from "web-vitals";
15
+ import { getSessionId } from "./session";
16
+ /**
17
+ * Infer device type from screen width.
18
+ * Mobile < 768px, Tablet < 1024px, Desktop >= 1024px.
19
+ */
20
+ function inferDeviceType() {
21
+ if (typeof screen === "undefined")
22
+ return undefined;
23
+ const width = screen.width;
24
+ if (width < 768)
25
+ return "mobile";
26
+ if (width < 1024)
27
+ return "tablet";
28
+ return "desktop";
29
+ }
30
+ /**
31
+ * Get the effective connection type from the Network Information API.
32
+ * Returns undefined if not supported (Firefox, Safari).
33
+ */
34
+ function getConnectionType() {
35
+ const nav = navigator;
36
+ return nav.connection?.effectiveType;
37
+ }
38
+ /**
39
+ * Map a web-vitals Metric to our VitalEvent shape.
40
+ */
41
+ function mapMetric(metric, config) {
42
+ return {
43
+ type: "vital",
44
+ name: metric.name,
45
+ value: metric.value,
46
+ rating: metric.rating,
47
+ delta: metric.delta,
48
+ navigationType: metric.navigationType,
49
+ url: location.href,
50
+ session_id: getSessionId(),
51
+ timestamp: Date.now(),
52
+ environment: config.environment,
53
+ release: config.release,
54
+ connection: getConnectionType(),
55
+ device_type: inferDeviceType(),
56
+ referrer: document.referrer || undefined,
57
+ };
58
+ }
59
+ /** Decide whether to sample this vital based on the configured rate. */
60
+ function shouldSample(sampleRate) {
61
+ if (sampleRate >= 1)
62
+ return true;
63
+ if (sampleRate <= 0)
64
+ return false;
65
+ return Math.random() < sampleRate;
66
+ }
67
+ /**
68
+ * Start collecting all 5 Core Web Vitals and feed them to the transport.
69
+ * Call once during SDK initialization.
70
+ */
71
+ export function startVitalsCollection(transport, config) {
72
+ if (!shouldSample(config.sampleRate)) {
73
+ if (config.debug) {
74
+ console.log("[squasher] Vitals collection skipped (sampled out)");
75
+ }
76
+ return;
77
+ }
78
+ const handle = (metric) => {
79
+ const event = mapMetric(metric, config);
80
+ if (config.debug) {
81
+ console.log(`[squasher] ${metric.name}: ${metric.value.toFixed(2)} (${metric.rating})`);
82
+ }
83
+ transport.enqueueVital(event);
84
+ };
85
+ // Register all 5 metric observers.
86
+ // reportAllChanges: true for CLS/INP so we get cumulative values.
87
+ onLCP(handle);
88
+ onCLS(handle, { reportAllChanges: true });
89
+ onINP(handle, { reportAllChanges: true });
90
+ onFCP(handle);
91
+ onTTFB(handle);
92
+ }
package/package.json ADDED
@@ -0,0 +1,44 @@
1
+ {
2
+ "name": "@squasher-ai/browser",
3
+ "version": "0.1.0",
4
+ "description": "Official @squasher-ai/browser package for Squasher.",
5
+ "homepage": "https://squasher.ai",
6
+ "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/squasher-ai/squasher.git",
10
+ "directory": "packages/sdk-browser"
11
+ },
12
+ "bugs": {
13
+ "url": "https://github.com/squasher-ai/squasher/issues"
14
+ },
15
+ "publishConfig": {
16
+ "access": "public"
17
+ },
18
+ "type": "module",
19
+ "main": "./dist/index.js",
20
+ "types": "./dist/index.d.ts",
21
+ "exports": {
22
+ ".": {
23
+ "import": "./dist/index.js",
24
+ "types": "./dist/index.d.ts"
25
+ },
26
+ "./react": {
27
+ "import": "./dist/react.js",
28
+ "types": "./dist/react.d.ts"
29
+ }
30
+ },
31
+ "sideEffects": false,
32
+ "dependencies": {
33
+ "rrweb": "^2.0.0-alpha.4",
34
+ "web-vitals": "^4.2.4"
35
+ },
36
+ "peerDependencies": {
37
+ "react": ">=18"
38
+ },
39
+ "peerDependenciesMeta": {
40
+ "react": {
41
+ "optional": true
42
+ }
43
+ }
44
+ }