mytart 0.5.0 → 0.5.2
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 +39 -0
- package/dist/index.js +20 -13
- package/dist/index.mjs +20 -13
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -402,6 +402,45 @@ export class MyProvider extends BaseProvider {
|
|
|
402
402
|
}
|
|
403
403
|
```
|
|
404
404
|
|
|
405
|
+
## Framework Integration
|
|
406
|
+
|
|
407
|
+
### Page View Tracking
|
|
408
|
+
|
|
409
|
+
mytart does **not** send automatic page views — `send_page_view: false` is set in the GA `gtag('config')` call, and other providers have no auto-pageview behaviour. This means your framework is responsible for calling `analytics.page()` on navigation.
|
|
410
|
+
|
|
411
|
+
### SvelteKit (Svelte 5)
|
|
412
|
+
|
|
413
|
+
Create a shared analytics instance and use `$effect` in your root layout to reactively track page URL changes:
|
|
414
|
+
|
|
415
|
+
```typescript
|
|
416
|
+
// src/lib/analytics.ts
|
|
417
|
+
import { Mytart } from 'mytart';
|
|
418
|
+
|
|
419
|
+
export const analytics = new Mytart({
|
|
420
|
+
providers: [
|
|
421
|
+
{ provider: 'google-analytics', measurementId: 'G-XXXXXXXXXX', appType: 'browser', enabled: true },
|
|
422
|
+
{ provider: 'meta-pixel', pixelId: '123456789', appType: 'browser', enabled: true },
|
|
423
|
+
],
|
|
424
|
+
});
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
```svelte
|
|
428
|
+
<!-- src/routes/+layout.svelte -->
|
|
429
|
+
<script lang="ts">
|
|
430
|
+
import { page } from '$app/state';
|
|
431
|
+
import { analytics } from '$lib/analytics';
|
|
432
|
+
|
|
433
|
+
$effect(() => {
|
|
434
|
+
// Runs on initial load and every client-side navigation
|
|
435
|
+
analytics.page({ url: page.url.href });
|
|
436
|
+
});
|
|
437
|
+
</script>
|
|
438
|
+
|
|
439
|
+
<slot />
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
> **Why `$effect`?** Svelte 5's `$effect` reactively tracks `page.url.href`. Whenever SvelteKit performs a client-side navigation and the URL changes, the effect re-runs and sends a single page view. This avoids the double-fire problem that can occur with `onMount` + `afterNavigate`, and works correctly on initial load.
|
|
443
|
+
|
|
405
444
|
## License
|
|
406
445
|
|
|
407
446
|
MIT
|
package/dist/index.js
CHANGED
|
@@ -146,7 +146,9 @@ var GoogleAnalyticsProvider = class extends BaseProvider {
|
|
|
146
146
|
window.gtag("consent", "default", consentParams);
|
|
147
147
|
}
|
|
148
148
|
window.gtag("js", /* @__PURE__ */ new Date());
|
|
149
|
-
const configParams = {
|
|
149
|
+
const configParams = {
|
|
150
|
+
send_page_view: false
|
|
151
|
+
};
|
|
150
152
|
if (this.config.signals === true) {
|
|
151
153
|
configParams["allow_google_signals"] = true;
|
|
152
154
|
configParams["allow_ad_personalization_signals"] = true;
|
|
@@ -154,11 +156,7 @@ var GoogleAnalyticsProvider = class extends BaseProvider {
|
|
|
154
156
|
configParams["allow_google_signals"] = false;
|
|
155
157
|
configParams["allow_ad_personalization_signals"] = false;
|
|
156
158
|
}
|
|
157
|
-
|
|
158
|
-
window.gtag("config", this.config.measurementId, configParams);
|
|
159
|
-
} else {
|
|
160
|
-
window.gtag("config", this.config.measurementId);
|
|
161
|
-
}
|
|
159
|
+
window.gtag("config", this.config.measurementId, configParams);
|
|
162
160
|
return new Promise((resolve) => {
|
|
163
161
|
const script = document.createElement("script");
|
|
164
162
|
script.async = true;
|
|
@@ -762,12 +760,14 @@ var PostHogProvider = class extends BaseProvider {
|
|
|
762
760
|
};
|
|
763
761
|
|
|
764
762
|
// src/utils/hash.ts
|
|
765
|
-
|
|
766
|
-
function sha256(value) {
|
|
763
|
+
async function sha256(value) {
|
|
767
764
|
if (/^[a-f0-9]{64}$/.test(value)) {
|
|
768
765
|
return value;
|
|
769
766
|
}
|
|
770
|
-
|
|
767
|
+
const data = new TextEncoder().encode(value);
|
|
768
|
+
const hashBuffer = await crypto.subtle.digest("SHA-256", data);
|
|
769
|
+
const hashArray = Array.from(new Uint8Array(hashBuffer));
|
|
770
|
+
return hashArray.map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
771
771
|
}
|
|
772
772
|
var PII_FIELDS = /* @__PURE__ */ new Set([
|
|
773
773
|
"em",
|
|
@@ -781,15 +781,22 @@ var PII_FIELDS = /* @__PURE__ */ new Set([
|
|
|
781
781
|
"zp",
|
|
782
782
|
"country"
|
|
783
783
|
]);
|
|
784
|
-
function hashUserData(userData) {
|
|
784
|
+
async function hashUserData(userData) {
|
|
785
785
|
const result = {};
|
|
786
|
+
const hashPromises = [];
|
|
786
787
|
for (const [key, value] of Object.entries(userData)) {
|
|
787
788
|
if (PII_FIELDS.has(key) && typeof value === "string" && value.length > 0) {
|
|
788
|
-
|
|
789
|
+
hashPromises.push({ key, promise: sha256(value) });
|
|
789
790
|
} else {
|
|
790
791
|
result[key] = value;
|
|
791
792
|
}
|
|
792
793
|
}
|
|
794
|
+
const settled = await Promise.all(
|
|
795
|
+
hashPromises.map(async ({ key, promise }) => ({ key, hash: await promise }))
|
|
796
|
+
);
|
|
797
|
+
for (const { key, hash } of settled) {
|
|
798
|
+
result[key] = hash;
|
|
799
|
+
}
|
|
793
800
|
return result;
|
|
794
801
|
}
|
|
795
802
|
|
|
@@ -968,7 +975,7 @@ var MetaPixelProvider = class extends BaseProvider {
|
|
|
968
975
|
* Merges cached user data (from `identify()` / config) with any per-event
|
|
969
976
|
* overrides, then SHA-256 hashes known PII fields.
|
|
970
977
|
*/
|
|
971
|
-
buildUserData(overrides) {
|
|
978
|
+
async buildUserData(overrides) {
|
|
972
979
|
const merged = { ...this.cachedUserData, ...overrides };
|
|
973
980
|
return hashUserData(merged);
|
|
974
981
|
}
|
|
@@ -985,7 +992,7 @@ var MetaPixelProvider = class extends BaseProvider {
|
|
|
985
992
|
event_name: event,
|
|
986
993
|
event_time: timestamp ? Math.floor(timestamp.getTime() / 1e3) : Math.floor(Date.now() / 1e3),
|
|
987
994
|
action_source: "website",
|
|
988
|
-
user_data: this.buildUserData(userDataOverrides)
|
|
995
|
+
user_data: await this.buildUserData(userDataOverrides)
|
|
989
996
|
};
|
|
990
997
|
if (eventId) {
|
|
991
998
|
eventData["event_id"] = eventId;
|
package/dist/index.mjs
CHANGED
|
@@ -102,7 +102,9 @@ var GoogleAnalyticsProvider = class extends BaseProvider {
|
|
|
102
102
|
window.gtag("consent", "default", consentParams);
|
|
103
103
|
}
|
|
104
104
|
window.gtag("js", /* @__PURE__ */ new Date());
|
|
105
|
-
const configParams = {
|
|
105
|
+
const configParams = {
|
|
106
|
+
send_page_view: false
|
|
107
|
+
};
|
|
106
108
|
if (this.config.signals === true) {
|
|
107
109
|
configParams["allow_google_signals"] = true;
|
|
108
110
|
configParams["allow_ad_personalization_signals"] = true;
|
|
@@ -110,11 +112,7 @@ var GoogleAnalyticsProvider = class extends BaseProvider {
|
|
|
110
112
|
configParams["allow_google_signals"] = false;
|
|
111
113
|
configParams["allow_ad_personalization_signals"] = false;
|
|
112
114
|
}
|
|
113
|
-
|
|
114
|
-
window.gtag("config", this.config.measurementId, configParams);
|
|
115
|
-
} else {
|
|
116
|
-
window.gtag("config", this.config.measurementId);
|
|
117
|
-
}
|
|
115
|
+
window.gtag("config", this.config.measurementId, configParams);
|
|
118
116
|
return new Promise((resolve) => {
|
|
119
117
|
const script = document.createElement("script");
|
|
120
118
|
script.async = true;
|
|
@@ -718,12 +716,14 @@ var PostHogProvider = class extends BaseProvider {
|
|
|
718
716
|
};
|
|
719
717
|
|
|
720
718
|
// src/utils/hash.ts
|
|
721
|
-
|
|
722
|
-
function sha256(value) {
|
|
719
|
+
async function sha256(value) {
|
|
723
720
|
if (/^[a-f0-9]{64}$/.test(value)) {
|
|
724
721
|
return value;
|
|
725
722
|
}
|
|
726
|
-
|
|
723
|
+
const data = new TextEncoder().encode(value);
|
|
724
|
+
const hashBuffer = await crypto.subtle.digest("SHA-256", data);
|
|
725
|
+
const hashArray = Array.from(new Uint8Array(hashBuffer));
|
|
726
|
+
return hashArray.map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
727
727
|
}
|
|
728
728
|
var PII_FIELDS = /* @__PURE__ */ new Set([
|
|
729
729
|
"em",
|
|
@@ -737,15 +737,22 @@ var PII_FIELDS = /* @__PURE__ */ new Set([
|
|
|
737
737
|
"zp",
|
|
738
738
|
"country"
|
|
739
739
|
]);
|
|
740
|
-
function hashUserData(userData) {
|
|
740
|
+
async function hashUserData(userData) {
|
|
741
741
|
const result = {};
|
|
742
|
+
const hashPromises = [];
|
|
742
743
|
for (const [key, value] of Object.entries(userData)) {
|
|
743
744
|
if (PII_FIELDS.has(key) && typeof value === "string" && value.length > 0) {
|
|
744
|
-
|
|
745
|
+
hashPromises.push({ key, promise: sha256(value) });
|
|
745
746
|
} else {
|
|
746
747
|
result[key] = value;
|
|
747
748
|
}
|
|
748
749
|
}
|
|
750
|
+
const settled = await Promise.all(
|
|
751
|
+
hashPromises.map(async ({ key, promise }) => ({ key, hash: await promise }))
|
|
752
|
+
);
|
|
753
|
+
for (const { key, hash } of settled) {
|
|
754
|
+
result[key] = hash;
|
|
755
|
+
}
|
|
749
756
|
return result;
|
|
750
757
|
}
|
|
751
758
|
|
|
@@ -924,7 +931,7 @@ var MetaPixelProvider = class extends BaseProvider {
|
|
|
924
931
|
* Merges cached user data (from `identify()` / config) with any per-event
|
|
925
932
|
* overrides, then SHA-256 hashes known PII fields.
|
|
926
933
|
*/
|
|
927
|
-
buildUserData(overrides) {
|
|
934
|
+
async buildUserData(overrides) {
|
|
928
935
|
const merged = { ...this.cachedUserData, ...overrides };
|
|
929
936
|
return hashUserData(merged);
|
|
930
937
|
}
|
|
@@ -941,7 +948,7 @@ var MetaPixelProvider = class extends BaseProvider {
|
|
|
941
948
|
event_name: event,
|
|
942
949
|
event_time: timestamp ? Math.floor(timestamp.getTime() / 1e3) : Math.floor(Date.now() / 1e3),
|
|
943
950
|
action_source: "website",
|
|
944
|
-
user_data: this.buildUserData(userDataOverrides)
|
|
951
|
+
user_data: await this.buildUserData(userDataOverrides)
|
|
945
952
|
};
|
|
946
953
|
if (eventId) {
|
|
947
954
|
eventData["event_id"] = eventId;
|