@aranova/tracking-next 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 +150 -0
- package/dist/index.d.mts +194 -112
- package/dist/index.d.ts +194 -112
- package/dist/index.js +183 -73
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +183 -73
- package/dist/index.mjs.map +1 -1
- package/dist/middleware.js +97 -66
- package/dist/middleware.js.map +1 -1
- package/dist/middleware.mjs +98 -67
- package/dist/middleware.mjs.map +1 -1
- package/dist/server.js +97 -66
- package/dist/server.js.map +1 -1
- package/dist/server.mjs +98 -67
- package/dist/server.mjs.map +1 -1
- package/package.json +3 -2
package/dist/index.mjs
CHANGED
|
@@ -206,7 +206,7 @@ function getVisitorId() {
|
|
|
206
206
|
}
|
|
207
207
|
function getOrRotateSessionId(now = Date.now()) {
|
|
208
208
|
if (typeof window === "undefined")
|
|
209
|
-
return safeUuid();
|
|
209
|
+
return { id: safeUuid(), isNew: true };
|
|
210
210
|
const raw = readLocalStorage(SESSION_STORAGE_KEY);
|
|
211
211
|
if (raw) {
|
|
212
212
|
try {
|
|
@@ -215,7 +215,7 @@ function getOrRotateSessionId(now = Date.now()) {
|
|
|
215
215
|
if (now - parsed.last_event_at <= SESSION_IDLE_MS) {
|
|
216
216
|
const refreshed = { id: parsed.id, last_event_at: now };
|
|
217
217
|
writeLocalStorage(SESSION_STORAGE_KEY, JSON.stringify(refreshed));
|
|
218
|
-
return parsed.id;
|
|
218
|
+
return { id: parsed.id, isNew: false };
|
|
219
219
|
}
|
|
220
220
|
}
|
|
221
221
|
} catch {
|
|
@@ -223,7 +223,7 @@ function getOrRotateSessionId(now = Date.now()) {
|
|
|
223
223
|
}
|
|
224
224
|
const fresh = { id: safeUuid(), last_event_at: now };
|
|
225
225
|
writeLocalStorage(SESSION_STORAGE_KEY, JSON.stringify(fresh));
|
|
226
|
-
return fresh.id;
|
|
226
|
+
return { id: fresh.id, isNew: true };
|
|
227
227
|
}
|
|
228
228
|
|
|
229
229
|
// ../tracking-core/src/events/page-view.ts
|
|
@@ -234,7 +234,7 @@ var pageViewMetadataSchema = z.object({
|
|
|
234
234
|
path: z.string(),
|
|
235
235
|
search: z.string(),
|
|
236
236
|
hash: z.string()
|
|
237
|
-
}),
|
|
237
|
+
}).strict(),
|
|
238
238
|
referrer: z.string().nullable(),
|
|
239
239
|
// `.nullable().optional()` — absent (undefined) OR explicit null OR a
|
|
240
240
|
// real viewport object. Mirrors Pydantic's `_Viewport | None = None`
|
|
@@ -242,7 +242,7 @@ var pageViewMetadataSchema = z.object({
|
|
|
242
242
|
viewport: z.object({
|
|
243
243
|
w: z.number(),
|
|
244
244
|
h: z.number()
|
|
245
|
-
}).nullable().optional()
|
|
245
|
+
}).strict().nullable().optional()
|
|
246
246
|
}).strict();
|
|
247
247
|
var pageViewConfigSchema = z.object({}).strict();
|
|
248
248
|
|
|
@@ -323,6 +323,56 @@ function attachBfcacheRestore(client) {
|
|
|
323
323
|
};
|
|
324
324
|
}
|
|
325
325
|
|
|
326
|
+
// ../tracking-core/src/heartbeat.ts
|
|
327
|
+
function serializeValue(value) {
|
|
328
|
+
if (value instanceof RegExp) return value.source;
|
|
329
|
+
if (Array.isArray(value)) return value.map(serializeValue);
|
|
330
|
+
if (value !== null && typeof value === "object") {
|
|
331
|
+
const out = {};
|
|
332
|
+
for (const [k, v] of Object.entries(value)) {
|
|
333
|
+
out[k] = serializeValue(v);
|
|
334
|
+
}
|
|
335
|
+
return out;
|
|
336
|
+
}
|
|
337
|
+
return value;
|
|
338
|
+
}
|
|
339
|
+
function buildHeartbeatMetadata(surface, sdkVersion, packageName, triggers) {
|
|
340
|
+
const automaticNames = triggers ? Object.keys(triggers.automatic) : [];
|
|
341
|
+
const manualNames = triggers?.manual ? Object.keys(triggers.manual) : [];
|
|
342
|
+
let triggerConfig = null;
|
|
343
|
+
if (triggers) {
|
|
344
|
+
const cfg = {};
|
|
345
|
+
for (const [name, config] of Object.entries(triggers.automatic)) {
|
|
346
|
+
const serialized = serializeValue(config);
|
|
347
|
+
if (Object.keys(serialized).length > 0) {
|
|
348
|
+
cfg[name] = serialized;
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
if (triggers.manual) {
|
|
352
|
+
for (const [name, config] of Object.entries(triggers.manual)) {
|
|
353
|
+
if (config === void 0) continue;
|
|
354
|
+
const serialized = serializeValue(config);
|
|
355
|
+
if (Object.keys(serialized).length > 0) {
|
|
356
|
+
cfg[name] = serialized;
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
if (Object.keys(cfg).length > 0) {
|
|
361
|
+
triggerConfig = cfg;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
return {
|
|
365
|
+
sdk_version: sdkVersion ?? "unknown",
|
|
366
|
+
package_name: packageName,
|
|
367
|
+
surface,
|
|
368
|
+
triggers: {
|
|
369
|
+
automatic: automaticNames,
|
|
370
|
+
manual: manualNames
|
|
371
|
+
},
|
|
372
|
+
trigger_config: triggerConfig
|
|
373
|
+
};
|
|
374
|
+
}
|
|
375
|
+
|
|
326
376
|
// ../tracking-core/src/ingest.ts
|
|
327
377
|
var DEFAULT_FLUSH_INTERVAL_MS = 2e3;
|
|
328
378
|
var DEFAULT_MAX_QUEUE_SIZE = 10;
|
|
@@ -402,11 +452,33 @@ function createTrackingClient(config) {
|
|
|
402
452
|
let firstPage = null;
|
|
403
453
|
let destroyed = false;
|
|
404
454
|
const visitorId = getVisitorId();
|
|
405
|
-
|
|
455
|
+
const initialSession = getOrRotateSessionId();
|
|
456
|
+
let sessionId = initialSession.id;
|
|
406
457
|
if (typeof window !== "undefined")
|
|
407
458
|
firstPage = window.location.href;
|
|
459
|
+
function enqueueHeartbeat() {
|
|
460
|
+
const metadata = buildHeartbeatMetadata(
|
|
461
|
+
config.surface,
|
|
462
|
+
sdkVersion,
|
|
463
|
+
packageName,
|
|
464
|
+
config.triggers ?? null
|
|
465
|
+
);
|
|
466
|
+
queue.push({
|
|
467
|
+
event_type: "sdk_heartbeat",
|
|
468
|
+
page_url: typeof window === "undefined" ? null : window.location.href,
|
|
469
|
+
metadata,
|
|
470
|
+
occurred_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
471
|
+
});
|
|
472
|
+
}
|
|
473
|
+
if (initialSession.isNew) {
|
|
474
|
+
enqueueHeartbeat();
|
|
475
|
+
}
|
|
408
476
|
function buildSessionPayload() {
|
|
409
|
-
|
|
477
|
+
const rotated = getOrRotateSessionId();
|
|
478
|
+
if (rotated.isNew && rotated.id !== sessionId) {
|
|
479
|
+
enqueueHeartbeat();
|
|
480
|
+
}
|
|
481
|
+
sessionId = rotated.id;
|
|
410
482
|
const params = readTrackingParams();
|
|
411
483
|
const context = buildContext(config.surface, sdkVersion, packageName);
|
|
412
484
|
return {
|
|
@@ -513,85 +585,110 @@ var ctaClickMetadataSchema = z2.object({
|
|
|
513
585
|
cta_name: z2.string(),
|
|
514
586
|
page: z2.object({
|
|
515
587
|
path: z2.string()
|
|
516
|
-
}),
|
|
588
|
+
}).strict(),
|
|
517
589
|
section: z2.string().nullable().optional(),
|
|
518
590
|
destination_url: z2.string().nullable().optional()
|
|
519
591
|
}).strict();
|
|
520
592
|
var ctaClickConfigSchema = z2.object({}).strict();
|
|
521
593
|
|
|
522
|
-
// ../tracking-core/src/events/
|
|
594
|
+
// ../tracking-core/src/events/sdk-heartbeat.ts
|
|
523
595
|
import { z as z3 } from "zod";
|
|
524
|
-
var
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
action: z3.string().nullable()
|
|
528
|
-
}),
|
|
529
|
-
page: z3.object({
|
|
530
|
-
path: z3.string()
|
|
531
|
-
})
|
|
596
|
+
var sdkHeartbeatTriggersSchema = z3.object({
|
|
597
|
+
automatic: z3.array(z3.string()),
|
|
598
|
+
manual: z3.array(z3.string())
|
|
532
599
|
}).strict();
|
|
533
|
-
var
|
|
534
|
-
|
|
600
|
+
var sdkHeartbeatMetadataSchema = z3.object({
|
|
601
|
+
sdk_version: z3.string(),
|
|
602
|
+
package_name: z3.string().nullable(),
|
|
603
|
+
surface: z3.enum(["next", "react", "script"]),
|
|
604
|
+
triggers: sdkHeartbeatTriggersSchema,
|
|
605
|
+
trigger_config: z3.record(z3.string(), z3.record(z3.string(), z3.unknown())).nullable().optional()
|
|
535
606
|
}).strict();
|
|
607
|
+
var sdkHeartbeatConfigSchema = z3.object({}).strict();
|
|
536
608
|
|
|
537
|
-
// ../tracking-core/src/events/form-
|
|
609
|
+
// ../tracking-core/src/events/form-start.ts
|
|
538
610
|
import { z as z4 } from "zod";
|
|
539
|
-
var
|
|
611
|
+
var formStartMetadataSchema = z4.object({
|
|
540
612
|
form: z4.object({
|
|
541
613
|
id: z4.string(),
|
|
542
|
-
action: z4.string().nullable()
|
|
543
|
-
|
|
544
|
-
z4.object({
|
|
545
|
-
name: z4.string(),
|
|
546
|
-
type: z4.string(),
|
|
547
|
-
label: z4.string().nullable(),
|
|
548
|
-
has_value: z4.boolean()
|
|
549
|
-
})
|
|
550
|
-
).optional()
|
|
551
|
-
}),
|
|
614
|
+
action: z4.string().nullable()
|
|
615
|
+
}).strict(),
|
|
552
616
|
page: z4.object({
|
|
553
617
|
path: z4.string()
|
|
554
|
-
})
|
|
618
|
+
}).strict()
|
|
619
|
+
}).strict();
|
|
620
|
+
var formStartConfigSchema = z4.object({
|
|
621
|
+
selector: z4.string().optional()
|
|
555
622
|
}).strict();
|
|
556
|
-
var formSubmitConfigSchema = z4.object({}).strict();
|
|
557
623
|
|
|
558
|
-
// ../tracking-core/src/events/
|
|
624
|
+
// ../tracking-core/src/events/form-submit.ts
|
|
559
625
|
import { z as z5 } from "zod";
|
|
560
|
-
var
|
|
561
|
-
|
|
626
|
+
var jsonValueSchema = z5.lazy(
|
|
627
|
+
() => z5.union([
|
|
628
|
+
z5.string(),
|
|
629
|
+
z5.number().finite(),
|
|
630
|
+
z5.boolean(),
|
|
631
|
+
z5.null(),
|
|
632
|
+
z5.array(jsonValueSchema),
|
|
633
|
+
z5.record(jsonValueSchema)
|
|
634
|
+
])
|
|
635
|
+
);
|
|
636
|
+
var formSubmitMetadataSchema = z5.object({
|
|
637
|
+
form: z5.object({
|
|
638
|
+
id: z5.string(),
|
|
639
|
+
action: z5.string().nullable(),
|
|
640
|
+
fields: z5.array(
|
|
641
|
+
z5.object({
|
|
642
|
+
name: z5.string(),
|
|
643
|
+
type: z5.string(),
|
|
644
|
+
label: z5.string().nullable(),
|
|
645
|
+
value: jsonValueSchema
|
|
646
|
+
}).strict()
|
|
647
|
+
).optional()
|
|
648
|
+
}).strict(),
|
|
562
649
|
page: z5.object({
|
|
563
650
|
path: z5.string()
|
|
564
|
-
})
|
|
565
|
-
}).strict();
|
|
566
|
-
var multiPageSessionConfigSchema = z5.object({
|
|
567
|
-
pageThreshold: z5.number().int().min(2)
|
|
651
|
+
}).strict()
|
|
568
652
|
}).strict();
|
|
653
|
+
var formSubmitConfigSchema = z5.object({}).strict();
|
|
569
654
|
|
|
570
|
-
// ../tracking-core/src/events/
|
|
655
|
+
// ../tracking-core/src/events/multi-page-session.ts
|
|
571
656
|
import { z as z6 } from "zod";
|
|
572
|
-
var
|
|
573
|
-
|
|
657
|
+
var multiPageSessionMetadataSchema = z6.object({
|
|
658
|
+
page_count: z6.number().int().min(2),
|
|
574
659
|
page: z6.object({
|
|
575
660
|
path: z6.string()
|
|
576
|
-
})
|
|
577
|
-
|
|
661
|
+
}).strict()
|
|
662
|
+
}).strict();
|
|
663
|
+
var multiPageSessionConfigSchema = z6.object({
|
|
664
|
+
pageThreshold: z6.number().int().min(2)
|
|
578
665
|
}).strict();
|
|
579
|
-
var phoneClickConfigSchema = z6.object({}).strict();
|
|
580
666
|
|
|
581
|
-
// ../tracking-core/src/events/
|
|
667
|
+
// ../tracking-core/src/events/phone-click.ts
|
|
582
668
|
import { z as z7 } from "zod";
|
|
583
|
-
var
|
|
584
|
-
|
|
669
|
+
var phoneClickMetadataSchema = z7.object({
|
|
670
|
+
phone_number: z7.string(),
|
|
585
671
|
page: z7.object({
|
|
586
672
|
path: z7.string()
|
|
587
|
-
})
|
|
673
|
+
}).strict(),
|
|
674
|
+
section: z7.string().nullable().optional()
|
|
588
675
|
}).strict();
|
|
589
|
-
var
|
|
590
|
-
|
|
676
|
+
var phoneClickConfigSchema = z7.object({}).strict();
|
|
677
|
+
|
|
678
|
+
// ../tracking-core/src/events/scroll-depth.ts
|
|
679
|
+
import { z as z8 } from "zod";
|
|
680
|
+
var scrollDepthMetadataSchema = z8.object({
|
|
681
|
+
depth_percent: z8.number().int().min(1).max(100),
|
|
682
|
+
page: z8.object({
|
|
683
|
+
path: z8.string()
|
|
684
|
+
}).strict()
|
|
685
|
+
}).strict();
|
|
686
|
+
var scrollDepthConfigSchema = z8.object({
|
|
687
|
+
thresholds: z8.array(z8.number().int().min(1).max(100)).min(1)
|
|
591
688
|
}).strict();
|
|
592
689
|
|
|
593
690
|
// ../tracking-core/src/events/specific-page-visit.ts
|
|
594
|
-
import { z as
|
|
691
|
+
import { z as z9 } from "zod";
|
|
595
692
|
var SPECIFIC_PAGE_NAMES = [
|
|
596
693
|
"contact_page",
|
|
597
694
|
"about_page",
|
|
@@ -602,34 +699,34 @@ var SPECIFIC_PAGE_NAMES = [
|
|
|
602
699
|
"faq_page",
|
|
603
700
|
"testimonials_page"
|
|
604
701
|
];
|
|
605
|
-
var specificPageNameSchema =
|
|
606
|
-
var specificPageVisitMetadataSchema =
|
|
702
|
+
var specificPageNameSchema = z9.enum(SPECIFIC_PAGE_NAMES);
|
|
703
|
+
var specificPageVisitMetadataSchema = z9.object({
|
|
607
704
|
page_name: specificPageNameSchema,
|
|
608
|
-
page:
|
|
609
|
-
path:
|
|
610
|
-
})
|
|
705
|
+
page: z9.object({
|
|
706
|
+
path: z9.string()
|
|
707
|
+
}).strict()
|
|
611
708
|
}).strict();
|
|
612
|
-
var specificPageVisitConfigSchema =
|
|
613
|
-
pages:
|
|
614
|
-
|
|
709
|
+
var specificPageVisitConfigSchema = z9.object({
|
|
710
|
+
pages: z9.array(
|
|
711
|
+
z9.object({
|
|
615
712
|
name: specificPageNameSchema,
|
|
616
|
-
pathPattern:
|
|
713
|
+
pathPattern: z9.custom((value) => value instanceof RegExp, {
|
|
617
714
|
message: "pathPattern must be a RegExp"
|
|
618
715
|
})
|
|
619
|
-
})
|
|
716
|
+
}).strict()
|
|
620
717
|
).min(1)
|
|
621
718
|
}).strict();
|
|
622
719
|
|
|
623
720
|
// ../tracking-core/src/events/time-on-site.ts
|
|
624
|
-
import { z as
|
|
625
|
-
var timeOnSiteMetadataSchema =
|
|
626
|
-
duration_ms:
|
|
627
|
-
page:
|
|
628
|
-
path:
|
|
629
|
-
})
|
|
721
|
+
import { z as z10 } from "zod";
|
|
722
|
+
var timeOnSiteMetadataSchema = z10.object({
|
|
723
|
+
duration_ms: z10.number().int().nonnegative(),
|
|
724
|
+
page: z10.object({
|
|
725
|
+
path: z10.string()
|
|
726
|
+
}).strict()
|
|
630
727
|
}).strict();
|
|
631
|
-
var timeOnSiteConfigSchema =
|
|
632
|
-
thresholdSeconds:
|
|
728
|
+
var timeOnSiteConfigSchema = z10.object({
|
|
729
|
+
thresholdSeconds: z10.number().int().positive()
|
|
633
730
|
}).strict();
|
|
634
731
|
|
|
635
732
|
// ../tracking-core/src/events/registry.ts
|
|
@@ -665,6 +762,12 @@ var EVENT_REGISTRY = {
|
|
|
665
762
|
metadataSchema: formStartMetadataSchema,
|
|
666
763
|
configSchema: formStartConfigSchema
|
|
667
764
|
},
|
|
765
|
+
// --- SDK-internal automatic (not consumer-configurable) ---
|
|
766
|
+
sdk_heartbeat: {
|
|
767
|
+
kind: "automatic",
|
|
768
|
+
metadataSchema: sdkHeartbeatMetadataSchema,
|
|
769
|
+
configSchema: sdkHeartbeatConfigSchema
|
|
770
|
+
},
|
|
668
771
|
// --- manual triggers ---
|
|
669
772
|
form_submit: {
|
|
670
773
|
kind: "manual",
|
|
@@ -1007,7 +1110,7 @@ function GoogleAdsTracking({ gtagId }) {
|
|
|
1007
1110
|
import { usePathname, useSearchParams } from "next/navigation";
|
|
1008
1111
|
|
|
1009
1112
|
// package.json
|
|
1010
|
-
var version = "0.
|
|
1113
|
+
var version = "0.6.0";
|
|
1011
1114
|
|
|
1012
1115
|
// src/factory.tsx
|
|
1013
1116
|
import {
|
|
@@ -1053,6 +1156,7 @@ function createTracking(options) {
|
|
|
1053
1156
|
surface: "next",
|
|
1054
1157
|
packageName: "@aranova/tracking-next",
|
|
1055
1158
|
sdkVersion: version,
|
|
1159
|
+
triggers,
|
|
1056
1160
|
debug
|
|
1057
1161
|
}),
|
|
1058
1162
|
triggers,
|
|
@@ -1066,6 +1170,7 @@ function createTracking(options) {
|
|
|
1066
1170
|
endpoint,
|
|
1067
1171
|
surface: "next",
|
|
1068
1172
|
packageName: "@aranova/tracking-next",
|
|
1173
|
+
triggers,
|
|
1069
1174
|
debug
|
|
1070
1175
|
});
|
|
1071
1176
|
fireManualPageView(rawClient);
|
|
@@ -1078,6 +1183,7 @@ function createTracking(options) {
|
|
|
1078
1183
|
endpoint,
|
|
1079
1184
|
surface: "next",
|
|
1080
1185
|
packageName: "@aranova/tracking-next",
|
|
1186
|
+
triggers,
|
|
1081
1187
|
debug
|
|
1082
1188
|
});
|
|
1083
1189
|
for (const { name, pathPattern } of specificPageVisitConfig.pages) {
|
|
@@ -1099,6 +1205,7 @@ function createTracking(options) {
|
|
|
1099
1205
|
endpoint,
|
|
1100
1206
|
surface: "next",
|
|
1101
1207
|
packageName: "@aranova/tracking-next",
|
|
1208
|
+
triggers,
|
|
1102
1209
|
debug
|
|
1103
1210
|
});
|
|
1104
1211
|
return attachBfcacheRestore(rawClient);
|
|
@@ -1110,6 +1217,7 @@ function createTracking(options) {
|
|
|
1110
1217
|
endpoint,
|
|
1111
1218
|
surface: "next",
|
|
1112
1219
|
packageName: "@aranova/tracking-next",
|
|
1220
|
+
triggers,
|
|
1113
1221
|
debug
|
|
1114
1222
|
});
|
|
1115
1223
|
return attachTimeOnSite(rawClient, timeOnSiteConfig);
|
|
@@ -1125,7 +1233,7 @@ function createTracking(options) {
|
|
|
1125
1233
|
const MPS_FIRED_KEY = "aranova_tracking_mps_fired";
|
|
1126
1234
|
try {
|
|
1127
1235
|
const store = window.sessionStorage;
|
|
1128
|
-
const currentSession = getOrRotateSessionId();
|
|
1236
|
+
const currentSession = getOrRotateSessionId().id;
|
|
1129
1237
|
const storedSession = store.getItem(MPS_SESSION_KEY);
|
|
1130
1238
|
if (storedSession !== currentSession) {
|
|
1131
1239
|
store.setItem(MPS_SESSION_KEY, currentSession);
|
|
@@ -1144,6 +1252,7 @@ function createTracking(options) {
|
|
|
1144
1252
|
endpoint,
|
|
1145
1253
|
surface: "next",
|
|
1146
1254
|
packageName: "@aranova/tracking-next",
|
|
1255
|
+
triggers,
|
|
1147
1256
|
debug
|
|
1148
1257
|
});
|
|
1149
1258
|
rawClient.trackEvent({
|
|
@@ -1166,6 +1275,7 @@ function createTracking(options) {
|
|
|
1166
1275
|
endpoint,
|
|
1167
1276
|
surface: "next",
|
|
1168
1277
|
packageName: "@aranova/tracking-next",
|
|
1278
|
+
triggers,
|
|
1169
1279
|
debug
|
|
1170
1280
|
});
|
|
1171
1281
|
const scrollDepth = triggers.automatic.scroll_depth;
|