@aranova/tracking-react 0.5.0 → 0.6.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/README.md +114 -0
- package/dist/index.d.mts +194 -112
- package/dist/index.d.ts +194 -112
- package/dist/index.js +178 -73
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +178 -73
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -2
package/dist/index.mjs
CHANGED
|
@@ -229,7 +229,7 @@ function getVisitorId() {
|
|
|
229
229
|
}
|
|
230
230
|
function getOrRotateSessionId(now = Date.now()) {
|
|
231
231
|
if (typeof window === "undefined")
|
|
232
|
-
return safeUuid();
|
|
232
|
+
return { id: safeUuid(), isNew: true };
|
|
233
233
|
const raw = readLocalStorage(SESSION_STORAGE_KEY);
|
|
234
234
|
if (raw) {
|
|
235
235
|
try {
|
|
@@ -238,7 +238,7 @@ function getOrRotateSessionId(now = Date.now()) {
|
|
|
238
238
|
if (now - parsed.last_event_at <= SESSION_IDLE_MS) {
|
|
239
239
|
const refreshed = { id: parsed.id, last_event_at: now };
|
|
240
240
|
writeLocalStorage(SESSION_STORAGE_KEY, JSON.stringify(refreshed));
|
|
241
|
-
return parsed.id;
|
|
241
|
+
return { id: parsed.id, isNew: false };
|
|
242
242
|
}
|
|
243
243
|
}
|
|
244
244
|
} catch {
|
|
@@ -246,7 +246,7 @@ function getOrRotateSessionId(now = Date.now()) {
|
|
|
246
246
|
}
|
|
247
247
|
const fresh = { id: safeUuid(), last_event_at: now };
|
|
248
248
|
writeLocalStorage(SESSION_STORAGE_KEY, JSON.stringify(fresh));
|
|
249
|
-
return fresh.id;
|
|
249
|
+
return { id: fresh.id, isNew: true };
|
|
250
250
|
}
|
|
251
251
|
|
|
252
252
|
// ../tracking-core/src/events/page-view.ts
|
|
@@ -257,7 +257,7 @@ var pageViewMetadataSchema = z.object({
|
|
|
257
257
|
path: z.string(),
|
|
258
258
|
search: z.string(),
|
|
259
259
|
hash: z.string()
|
|
260
|
-
}),
|
|
260
|
+
}).strict(),
|
|
261
261
|
referrer: z.string().nullable(),
|
|
262
262
|
// `.nullable().optional()` — absent (undefined) OR explicit null OR a
|
|
263
263
|
// real viewport object. Mirrors Pydantic's `_Viewport | None = None`
|
|
@@ -265,7 +265,7 @@ var pageViewMetadataSchema = z.object({
|
|
|
265
265
|
viewport: z.object({
|
|
266
266
|
w: z.number(),
|
|
267
267
|
h: z.number()
|
|
268
|
-
}).nullable().optional()
|
|
268
|
+
}).strict().nullable().optional()
|
|
269
269
|
}).strict();
|
|
270
270
|
var pageViewConfigSchema = z.object({}).strict();
|
|
271
271
|
|
|
@@ -386,6 +386,56 @@ function attachAutoPageView(client, options = {}) {
|
|
|
386
386
|
};
|
|
387
387
|
}
|
|
388
388
|
|
|
389
|
+
// ../tracking-core/src/heartbeat.ts
|
|
390
|
+
function serializeValue(value) {
|
|
391
|
+
if (value instanceof RegExp) return value.source;
|
|
392
|
+
if (Array.isArray(value)) return value.map(serializeValue);
|
|
393
|
+
if (value !== null && typeof value === "object") {
|
|
394
|
+
const out = {};
|
|
395
|
+
for (const [k, v] of Object.entries(value)) {
|
|
396
|
+
out[k] = serializeValue(v);
|
|
397
|
+
}
|
|
398
|
+
return out;
|
|
399
|
+
}
|
|
400
|
+
return value;
|
|
401
|
+
}
|
|
402
|
+
function buildHeartbeatMetadata(surface, sdkVersion, packageName, triggers) {
|
|
403
|
+
const automaticNames = triggers ? Object.keys(triggers.automatic) : [];
|
|
404
|
+
const manualNames = triggers?.manual ? Object.keys(triggers.manual) : [];
|
|
405
|
+
let triggerConfig = null;
|
|
406
|
+
if (triggers) {
|
|
407
|
+
const cfg = {};
|
|
408
|
+
for (const [name, config] of Object.entries(triggers.automatic)) {
|
|
409
|
+
const serialized = serializeValue(config);
|
|
410
|
+
if (Object.keys(serialized).length > 0) {
|
|
411
|
+
cfg[name] = serialized;
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
if (triggers.manual) {
|
|
415
|
+
for (const [name, config] of Object.entries(triggers.manual)) {
|
|
416
|
+
if (config === void 0) continue;
|
|
417
|
+
const serialized = serializeValue(config);
|
|
418
|
+
if (Object.keys(serialized).length > 0) {
|
|
419
|
+
cfg[name] = serialized;
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
if (Object.keys(cfg).length > 0) {
|
|
424
|
+
triggerConfig = cfg;
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
return {
|
|
428
|
+
sdk_version: sdkVersion ?? "unknown",
|
|
429
|
+
package_name: packageName,
|
|
430
|
+
surface,
|
|
431
|
+
triggers: {
|
|
432
|
+
automatic: automaticNames,
|
|
433
|
+
manual: manualNames
|
|
434
|
+
},
|
|
435
|
+
trigger_config: triggerConfig
|
|
436
|
+
};
|
|
437
|
+
}
|
|
438
|
+
|
|
389
439
|
// ../tracking-core/src/ingest.ts
|
|
390
440
|
var DEFAULT_FLUSH_INTERVAL_MS = 2e3;
|
|
391
441
|
var DEFAULT_MAX_QUEUE_SIZE = 10;
|
|
@@ -465,11 +515,33 @@ function createTrackingClient(config) {
|
|
|
465
515
|
let firstPage = null;
|
|
466
516
|
let destroyed = false;
|
|
467
517
|
const visitorId = getVisitorId();
|
|
468
|
-
|
|
518
|
+
const initialSession = getOrRotateSessionId();
|
|
519
|
+
let sessionId = initialSession.id;
|
|
469
520
|
if (typeof window !== "undefined")
|
|
470
521
|
firstPage = window.location.href;
|
|
522
|
+
function enqueueHeartbeat() {
|
|
523
|
+
const metadata = buildHeartbeatMetadata(
|
|
524
|
+
config.surface,
|
|
525
|
+
sdkVersion,
|
|
526
|
+
packageName,
|
|
527
|
+
config.triggers ?? null
|
|
528
|
+
);
|
|
529
|
+
queue.push({
|
|
530
|
+
event_type: "sdk_heartbeat",
|
|
531
|
+
page_url: typeof window === "undefined" ? null : window.location.href,
|
|
532
|
+
metadata,
|
|
533
|
+
occurred_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
534
|
+
});
|
|
535
|
+
}
|
|
536
|
+
if (initialSession.isNew) {
|
|
537
|
+
enqueueHeartbeat();
|
|
538
|
+
}
|
|
471
539
|
function buildSessionPayload() {
|
|
472
|
-
|
|
540
|
+
const rotated = getOrRotateSessionId();
|
|
541
|
+
if (rotated.isNew && rotated.id !== sessionId) {
|
|
542
|
+
enqueueHeartbeat();
|
|
543
|
+
}
|
|
544
|
+
sessionId = rotated.id;
|
|
473
545
|
const params = readTrackingParams();
|
|
474
546
|
const context = buildContext(config.surface, sdkVersion, packageName);
|
|
475
547
|
return {
|
|
@@ -576,85 +648,110 @@ var ctaClickMetadataSchema = z2.object({
|
|
|
576
648
|
cta_name: z2.string(),
|
|
577
649
|
page: z2.object({
|
|
578
650
|
path: z2.string()
|
|
579
|
-
}),
|
|
651
|
+
}).strict(),
|
|
580
652
|
section: z2.string().nullable().optional(),
|
|
581
653
|
destination_url: z2.string().nullable().optional()
|
|
582
654
|
}).strict();
|
|
583
655
|
var ctaClickConfigSchema = z2.object({}).strict();
|
|
584
656
|
|
|
585
|
-
// ../tracking-core/src/events/
|
|
657
|
+
// ../tracking-core/src/events/sdk-heartbeat.ts
|
|
586
658
|
import { z as z3 } from "zod";
|
|
587
|
-
var
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
action: z3.string().nullable()
|
|
591
|
-
}),
|
|
592
|
-
page: z3.object({
|
|
593
|
-
path: z3.string()
|
|
594
|
-
})
|
|
659
|
+
var sdkHeartbeatTriggersSchema = z3.object({
|
|
660
|
+
automatic: z3.array(z3.string()),
|
|
661
|
+
manual: z3.array(z3.string())
|
|
595
662
|
}).strict();
|
|
596
|
-
var
|
|
597
|
-
|
|
663
|
+
var sdkHeartbeatMetadataSchema = z3.object({
|
|
664
|
+
sdk_version: z3.string(),
|
|
665
|
+
package_name: z3.string().nullable(),
|
|
666
|
+
surface: z3.enum(["next", "react", "script"]),
|
|
667
|
+
triggers: sdkHeartbeatTriggersSchema,
|
|
668
|
+
trigger_config: z3.record(z3.string(), z3.record(z3.string(), z3.unknown())).nullable().optional()
|
|
598
669
|
}).strict();
|
|
670
|
+
var sdkHeartbeatConfigSchema = z3.object({}).strict();
|
|
599
671
|
|
|
600
|
-
// ../tracking-core/src/events/form-
|
|
672
|
+
// ../tracking-core/src/events/form-start.ts
|
|
601
673
|
import { z as z4 } from "zod";
|
|
602
|
-
var
|
|
674
|
+
var formStartMetadataSchema = z4.object({
|
|
603
675
|
form: z4.object({
|
|
604
676
|
id: z4.string(),
|
|
605
|
-
action: z4.string().nullable()
|
|
606
|
-
|
|
607
|
-
z4.object({
|
|
608
|
-
name: z4.string(),
|
|
609
|
-
type: z4.string(),
|
|
610
|
-
label: z4.string().nullable(),
|
|
611
|
-
has_value: z4.boolean()
|
|
612
|
-
})
|
|
613
|
-
).optional()
|
|
614
|
-
}),
|
|
677
|
+
action: z4.string().nullable()
|
|
678
|
+
}).strict(),
|
|
615
679
|
page: z4.object({
|
|
616
680
|
path: z4.string()
|
|
617
|
-
})
|
|
681
|
+
}).strict()
|
|
682
|
+
}).strict();
|
|
683
|
+
var formStartConfigSchema = z4.object({
|
|
684
|
+
selector: z4.string().optional()
|
|
618
685
|
}).strict();
|
|
619
|
-
var formSubmitConfigSchema = z4.object({}).strict();
|
|
620
686
|
|
|
621
|
-
// ../tracking-core/src/events/
|
|
687
|
+
// ../tracking-core/src/events/form-submit.ts
|
|
622
688
|
import { z as z5 } from "zod";
|
|
623
|
-
var
|
|
624
|
-
|
|
689
|
+
var jsonValueSchema = z5.lazy(
|
|
690
|
+
() => z5.union([
|
|
691
|
+
z5.string(),
|
|
692
|
+
z5.number().finite(),
|
|
693
|
+
z5.boolean(),
|
|
694
|
+
z5.null(),
|
|
695
|
+
z5.array(jsonValueSchema),
|
|
696
|
+
z5.record(jsonValueSchema)
|
|
697
|
+
])
|
|
698
|
+
);
|
|
699
|
+
var formSubmitMetadataSchema = z5.object({
|
|
700
|
+
form: z5.object({
|
|
701
|
+
id: z5.string(),
|
|
702
|
+
action: z5.string().nullable(),
|
|
703
|
+
fields: z5.array(
|
|
704
|
+
z5.object({
|
|
705
|
+
name: z5.string(),
|
|
706
|
+
type: z5.string(),
|
|
707
|
+
label: z5.string().nullable(),
|
|
708
|
+
value: jsonValueSchema
|
|
709
|
+
}).strict()
|
|
710
|
+
).optional()
|
|
711
|
+
}).strict(),
|
|
625
712
|
page: z5.object({
|
|
626
713
|
path: z5.string()
|
|
627
|
-
})
|
|
628
|
-
}).strict();
|
|
629
|
-
var multiPageSessionConfigSchema = z5.object({
|
|
630
|
-
pageThreshold: z5.number().int().min(2)
|
|
714
|
+
}).strict()
|
|
631
715
|
}).strict();
|
|
716
|
+
var formSubmitConfigSchema = z5.object({}).strict();
|
|
632
717
|
|
|
633
|
-
// ../tracking-core/src/events/
|
|
718
|
+
// ../tracking-core/src/events/multi-page-session.ts
|
|
634
719
|
import { z as z6 } from "zod";
|
|
635
|
-
var
|
|
636
|
-
|
|
720
|
+
var multiPageSessionMetadataSchema = z6.object({
|
|
721
|
+
page_count: z6.number().int().min(2),
|
|
637
722
|
page: z6.object({
|
|
638
723
|
path: z6.string()
|
|
639
|
-
})
|
|
640
|
-
|
|
724
|
+
}).strict()
|
|
725
|
+
}).strict();
|
|
726
|
+
var multiPageSessionConfigSchema = z6.object({
|
|
727
|
+
pageThreshold: z6.number().int().min(2)
|
|
641
728
|
}).strict();
|
|
642
|
-
var phoneClickConfigSchema = z6.object({}).strict();
|
|
643
729
|
|
|
644
|
-
// ../tracking-core/src/events/
|
|
730
|
+
// ../tracking-core/src/events/phone-click.ts
|
|
645
731
|
import { z as z7 } from "zod";
|
|
646
|
-
var
|
|
647
|
-
|
|
732
|
+
var phoneClickMetadataSchema = z7.object({
|
|
733
|
+
phone_number: z7.string(),
|
|
648
734
|
page: z7.object({
|
|
649
735
|
path: z7.string()
|
|
650
|
-
})
|
|
736
|
+
}).strict(),
|
|
737
|
+
section: z7.string().nullable().optional()
|
|
738
|
+
}).strict();
|
|
739
|
+
var phoneClickConfigSchema = z7.object({}).strict();
|
|
740
|
+
|
|
741
|
+
// ../tracking-core/src/events/scroll-depth.ts
|
|
742
|
+
import { z as z8 } from "zod";
|
|
743
|
+
var scrollDepthMetadataSchema = z8.object({
|
|
744
|
+
depth_percent: z8.number().int().min(1).max(100),
|
|
745
|
+
page: z8.object({
|
|
746
|
+
path: z8.string()
|
|
747
|
+
}).strict()
|
|
651
748
|
}).strict();
|
|
652
|
-
var scrollDepthConfigSchema =
|
|
653
|
-
thresholds:
|
|
749
|
+
var scrollDepthConfigSchema = z8.object({
|
|
750
|
+
thresholds: z8.array(z8.number().int().min(1).max(100)).min(1)
|
|
654
751
|
}).strict();
|
|
655
752
|
|
|
656
753
|
// ../tracking-core/src/events/specific-page-visit.ts
|
|
657
|
-
import { z as
|
|
754
|
+
import { z as z9 } from "zod";
|
|
658
755
|
var SPECIFIC_PAGE_NAMES = [
|
|
659
756
|
"contact_page",
|
|
660
757
|
"about_page",
|
|
@@ -665,34 +762,34 @@ var SPECIFIC_PAGE_NAMES = [
|
|
|
665
762
|
"faq_page",
|
|
666
763
|
"testimonials_page"
|
|
667
764
|
];
|
|
668
|
-
var specificPageNameSchema =
|
|
669
|
-
var specificPageVisitMetadataSchema =
|
|
765
|
+
var specificPageNameSchema = z9.enum(SPECIFIC_PAGE_NAMES);
|
|
766
|
+
var specificPageVisitMetadataSchema = z9.object({
|
|
670
767
|
page_name: specificPageNameSchema,
|
|
671
|
-
page:
|
|
672
|
-
path:
|
|
673
|
-
})
|
|
768
|
+
page: z9.object({
|
|
769
|
+
path: z9.string()
|
|
770
|
+
}).strict()
|
|
674
771
|
}).strict();
|
|
675
|
-
var specificPageVisitConfigSchema =
|
|
676
|
-
pages:
|
|
677
|
-
|
|
772
|
+
var specificPageVisitConfigSchema = z9.object({
|
|
773
|
+
pages: z9.array(
|
|
774
|
+
z9.object({
|
|
678
775
|
name: specificPageNameSchema,
|
|
679
|
-
pathPattern:
|
|
776
|
+
pathPattern: z9.custom((value) => value instanceof RegExp, {
|
|
680
777
|
message: "pathPattern must be a RegExp"
|
|
681
778
|
})
|
|
682
|
-
})
|
|
779
|
+
}).strict()
|
|
683
780
|
).min(1)
|
|
684
781
|
}).strict();
|
|
685
782
|
|
|
686
783
|
// ../tracking-core/src/events/time-on-site.ts
|
|
687
|
-
import { z as
|
|
688
|
-
var timeOnSiteMetadataSchema =
|
|
689
|
-
duration_ms:
|
|
690
|
-
page:
|
|
691
|
-
path:
|
|
692
|
-
})
|
|
784
|
+
import { z as z10 } from "zod";
|
|
785
|
+
var timeOnSiteMetadataSchema = z10.object({
|
|
786
|
+
duration_ms: z10.number().int().nonnegative(),
|
|
787
|
+
page: z10.object({
|
|
788
|
+
path: z10.string()
|
|
789
|
+
}).strict()
|
|
693
790
|
}).strict();
|
|
694
|
-
var timeOnSiteConfigSchema =
|
|
695
|
-
thresholdSeconds:
|
|
791
|
+
var timeOnSiteConfigSchema = z10.object({
|
|
792
|
+
thresholdSeconds: z10.number().int().positive()
|
|
696
793
|
}).strict();
|
|
697
794
|
|
|
698
795
|
// ../tracking-core/src/events/registry.ts
|
|
@@ -728,6 +825,12 @@ var EVENT_REGISTRY = {
|
|
|
728
825
|
metadataSchema: formStartMetadataSchema,
|
|
729
826
|
configSchema: formStartConfigSchema
|
|
730
827
|
},
|
|
828
|
+
// --- SDK-internal automatic (not consumer-configurable) ---
|
|
829
|
+
sdk_heartbeat: {
|
|
830
|
+
kind: "automatic",
|
|
831
|
+
metadataSchema: sdkHeartbeatMetadataSchema,
|
|
832
|
+
configSchema: sdkHeartbeatConfigSchema
|
|
833
|
+
},
|
|
731
834
|
// --- manual triggers ---
|
|
732
835
|
form_submit: {
|
|
733
836
|
kind: "manual",
|
|
@@ -987,7 +1090,7 @@ function attachMultiPageSession(client, config) {
|
|
|
987
1090
|
}
|
|
988
1091
|
}
|
|
989
1092
|
function resetIfSessionChanged() {
|
|
990
|
-
const currentSession = getOrRotateSessionId();
|
|
1093
|
+
const currentSession = getOrRotateSessionId().id;
|
|
991
1094
|
const storedSession = storage.getItem(SESSION_KEY);
|
|
992
1095
|
if (storedSession !== currentSession) {
|
|
993
1096
|
storage.setItem(SESSION_KEY, currentSession);
|
|
@@ -1200,7 +1303,7 @@ import {
|
|
|
1200
1303
|
} from "react";
|
|
1201
1304
|
|
|
1202
1305
|
// package.json
|
|
1203
|
-
var version = "0.
|
|
1306
|
+
var version = "0.6.0";
|
|
1204
1307
|
|
|
1205
1308
|
// src/factory.tsx
|
|
1206
1309
|
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
@@ -1236,6 +1339,7 @@ function createTracking(options) {
|
|
|
1236
1339
|
surface: "react",
|
|
1237
1340
|
packageName: "@aranova/tracking-react",
|
|
1238
1341
|
sdkVersion: version,
|
|
1342
|
+
triggers,
|
|
1239
1343
|
debug
|
|
1240
1344
|
}),
|
|
1241
1345
|
triggers,
|
|
@@ -1254,6 +1358,7 @@ function createTracking(options) {
|
|
|
1254
1358
|
endpoint,
|
|
1255
1359
|
surface: "react",
|
|
1256
1360
|
packageName: "@aranova/tracking-react",
|
|
1361
|
+
triggers,
|
|
1257
1362
|
debug
|
|
1258
1363
|
});
|
|
1259
1364
|
detachers.push(attachAutoPageView(rawClient));
|