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 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
- if (Object.keys(configParams).length > 0) {
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
- var import_crypto = require("crypto");
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
- return (0, import_crypto.createHash)("sha256").update(value).digest("hex");
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
- result[key] = sha256(value);
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
- if (Object.keys(configParams).length > 0) {
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
- import { createHash } from "crypto";
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
- return createHash("sha256").update(value).digest("hex");
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
- result[key] = sha256(value);
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;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mytart",
3
- "version": "0.5.0",
3
+ "version": "0.5.2",
4
4
  "description": "Multi-Yield Tracking & Analytics Relay Tool — framework-agnostic analytics for any project",
5
5
  "keywords": [
6
6
  "analytics",