mytart 0.5.1 → 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
@@ -760,12 +760,14 @@ var PostHogProvider = class extends BaseProvider {
760
760
  };
761
761
 
762
762
  // src/utils/hash.ts
763
- var import_crypto = require("crypto");
764
- function sha256(value) {
763
+ async function sha256(value) {
765
764
  if (/^[a-f0-9]{64}$/.test(value)) {
766
765
  return value;
767
766
  }
768
- 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("");
769
771
  }
770
772
  var PII_FIELDS = /* @__PURE__ */ new Set([
771
773
  "em",
@@ -779,15 +781,22 @@ var PII_FIELDS = /* @__PURE__ */ new Set([
779
781
  "zp",
780
782
  "country"
781
783
  ]);
782
- function hashUserData(userData) {
784
+ async function hashUserData(userData) {
783
785
  const result = {};
786
+ const hashPromises = [];
784
787
  for (const [key, value] of Object.entries(userData)) {
785
788
  if (PII_FIELDS.has(key) && typeof value === "string" && value.length > 0) {
786
- result[key] = sha256(value);
789
+ hashPromises.push({ key, promise: sha256(value) });
787
790
  } else {
788
791
  result[key] = value;
789
792
  }
790
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
+ }
791
800
  return result;
792
801
  }
793
802
 
@@ -966,7 +975,7 @@ var MetaPixelProvider = class extends BaseProvider {
966
975
  * Merges cached user data (from `identify()` / config) with any per-event
967
976
  * overrides, then SHA-256 hashes known PII fields.
968
977
  */
969
- buildUserData(overrides) {
978
+ async buildUserData(overrides) {
970
979
  const merged = { ...this.cachedUserData, ...overrides };
971
980
  return hashUserData(merged);
972
981
  }
@@ -983,7 +992,7 @@ var MetaPixelProvider = class extends BaseProvider {
983
992
  event_name: event,
984
993
  event_time: timestamp ? Math.floor(timestamp.getTime() / 1e3) : Math.floor(Date.now() / 1e3),
985
994
  action_source: "website",
986
- user_data: this.buildUserData(userDataOverrides)
995
+ user_data: await this.buildUserData(userDataOverrides)
987
996
  };
988
997
  if (eventId) {
989
998
  eventData["event_id"] = eventId;
package/dist/index.mjs CHANGED
@@ -716,12 +716,14 @@ var PostHogProvider = class extends BaseProvider {
716
716
  };
717
717
 
718
718
  // src/utils/hash.ts
719
- import { createHash } from "crypto";
720
- function sha256(value) {
719
+ async function sha256(value) {
721
720
  if (/^[a-f0-9]{64}$/.test(value)) {
722
721
  return value;
723
722
  }
724
- 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("");
725
727
  }
726
728
  var PII_FIELDS = /* @__PURE__ */ new Set([
727
729
  "em",
@@ -735,15 +737,22 @@ var PII_FIELDS = /* @__PURE__ */ new Set([
735
737
  "zp",
736
738
  "country"
737
739
  ]);
738
- function hashUserData(userData) {
740
+ async function hashUserData(userData) {
739
741
  const result = {};
742
+ const hashPromises = [];
740
743
  for (const [key, value] of Object.entries(userData)) {
741
744
  if (PII_FIELDS.has(key) && typeof value === "string" && value.length > 0) {
742
- result[key] = sha256(value);
745
+ hashPromises.push({ key, promise: sha256(value) });
743
746
  } else {
744
747
  result[key] = value;
745
748
  }
746
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
+ }
747
756
  return result;
748
757
  }
749
758
 
@@ -922,7 +931,7 @@ var MetaPixelProvider = class extends BaseProvider {
922
931
  * Merges cached user data (from `identify()` / config) with any per-event
923
932
  * overrides, then SHA-256 hashes known PII fields.
924
933
  */
925
- buildUserData(overrides) {
934
+ async buildUserData(overrides) {
926
935
  const merged = { ...this.cachedUserData, ...overrides };
927
936
  return hashUserData(merged);
928
937
  }
@@ -939,7 +948,7 @@ var MetaPixelProvider = class extends BaseProvider {
939
948
  event_name: event,
940
949
  event_time: timestamp ? Math.floor(timestamp.getTime() / 1e3) : Math.floor(Date.now() / 1e3),
941
950
  action_source: "website",
942
- user_data: this.buildUserData(userDataOverrides)
951
+ user_data: await this.buildUserData(userDataOverrides)
943
952
  };
944
953
  if (eventId) {
945
954
  eventData["event_id"] = eventId;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mytart",
3
- "version": "0.5.1",
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",