@hifilabs/pixel 0.0.2 → 0.0.4
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/dist/index.esm.d.ts +1 -0
- package/dist/index.esm.js +19 -0
- package/dist/index.js +73 -3
- package/dist/index.min.js +1 -1
- package/package.json +9 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function BalanceAnalytics(): null;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
// src/react/BalanceAnalytics.tsx
|
|
3
|
+
import { useEffect } from "react";
|
|
4
|
+
import { usePathname, useSearchParams } from "next/navigation";
|
|
5
|
+
function BalanceAnalytics() {
|
|
6
|
+
const pathname = usePathname();
|
|
7
|
+
const searchParams = useSearchParams();
|
|
8
|
+
useEffect(() => {
|
|
9
|
+
if (typeof window !== "undefined" && window.balance) {
|
|
10
|
+
const url = window.location.href;
|
|
11
|
+
const title = document.title;
|
|
12
|
+
window.balance.page({ url, title });
|
|
13
|
+
}
|
|
14
|
+
}, [pathname, searchParams]);
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
export {
|
|
18
|
+
BalanceAnalytics
|
|
19
|
+
};
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,56 @@
|
|
|
1
1
|
var BalancePixel = (() => {
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
7
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
8
|
+
}) : x)(function(x) {
|
|
9
|
+
if (typeof require !== "undefined")
|
|
10
|
+
return require.apply(this, arguments);
|
|
11
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
12
|
+
});
|
|
13
|
+
var __export = (target, all) => {
|
|
14
|
+
for (var name in all)
|
|
15
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
16
|
+
};
|
|
17
|
+
var __copyProps = (to, from, except, desc) => {
|
|
18
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
19
|
+
for (let key of __getOwnPropNames(from))
|
|
20
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
21
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
22
|
+
}
|
|
23
|
+
return to;
|
|
24
|
+
};
|
|
25
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
26
|
+
|
|
27
|
+
// src/index.ts
|
|
28
|
+
var src_exports = {};
|
|
29
|
+
__export(src_exports, {
|
|
30
|
+
BalanceAnalytics: () => BalanceAnalytics
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
// src/react/BalanceAnalytics.tsx
|
|
34
|
+
var import_react = __require("react");
|
|
35
|
+
var import_navigation = __require("next/navigation");
|
|
36
|
+
function BalanceAnalytics() {
|
|
37
|
+
const pathname = (0, import_navigation.usePathname)();
|
|
38
|
+
const searchParams = (0, import_navigation.useSearchParams)();
|
|
39
|
+
(0, import_react.useEffect)(() => {
|
|
40
|
+
if (typeof window !== "undefined" && window.balance) {
|
|
41
|
+
const url = window.location.href;
|
|
42
|
+
const title = document.title;
|
|
43
|
+
window.balance.page({ url, title });
|
|
44
|
+
}
|
|
45
|
+
}, [pathname, searchParams]);
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
|
|
2
49
|
// src/index.ts
|
|
3
50
|
(function() {
|
|
4
51
|
const currentScript = document.currentScript;
|
|
5
52
|
const artistId = currentScript?.dataset.artistId;
|
|
53
|
+
const projectId = currentScript?.dataset.projectId;
|
|
6
54
|
const useEmulator = currentScript?.dataset.emulator === "true";
|
|
7
55
|
const debug = currentScript?.dataset.debug === "true";
|
|
8
56
|
if (!artistId) {
|
|
@@ -14,7 +62,7 @@ var BalancePixel = (() => {
|
|
|
14
62
|
const ATTRIBUTION_KEY = "balance_attribution";
|
|
15
63
|
const FAN_ID_KEY = "balance_fan_id_hash";
|
|
16
64
|
const CONSENT_STORAGE_KEY = "balance_consent";
|
|
17
|
-
const SESSION_DURATION =
|
|
65
|
+
const SESSION_DURATION = 60 * 60 * 1e3;
|
|
18
66
|
const API_ENDPOINT = useEmulator ? `http://localhost:5001/artist-os-distro/us-central1/pixelEndpoint` : `https://us-central1-artist-os-distro.cloudfunctions.net/pixelEndpoint`;
|
|
19
67
|
let sessionId = null;
|
|
20
68
|
let fanIdHash = null;
|
|
@@ -138,7 +186,7 @@ var BalancePixel = (() => {
|
|
|
138
186
|
return hashArray.map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
139
187
|
}
|
|
140
188
|
function buildEvent(partial) {
|
|
141
|
-
|
|
189
|
+
const base = {
|
|
142
190
|
artist_id: artistId,
|
|
143
191
|
fan_session_id: sessionId,
|
|
144
192
|
fan_id_hash: fanIdHash || void 0,
|
|
@@ -149,6 +197,10 @@ var BalancePixel = (() => {
|
|
|
149
197
|
...partial,
|
|
150
198
|
...attribution
|
|
151
199
|
};
|
|
200
|
+
if (projectId && !partial.projectId) {
|
|
201
|
+
base.projectId = projectId;
|
|
202
|
+
}
|
|
203
|
+
return base;
|
|
152
204
|
}
|
|
153
205
|
function enqueueEvent(event) {
|
|
154
206
|
const essentialEvents = ["identify", "consent_updated"];
|
|
@@ -218,7 +270,14 @@ var BalancePixel = (() => {
|
|
|
218
270
|
try {
|
|
219
271
|
fanIdHash = await hashEmail(email);
|
|
220
272
|
localStorage.setItem(FAN_ID_KEY, fanIdHash);
|
|
221
|
-
|
|
273
|
+
const emailParts = email.split("@");
|
|
274
|
+
const maskedEmail = emailParts[0].charAt(0) + "***@" + (emailParts[1] || "");
|
|
275
|
+
log("Fan identified:", {
|
|
276
|
+
name: traits.name || "(no name)",
|
|
277
|
+
email: maskedEmail,
|
|
278
|
+
hash: fanIdHash.substring(0, 16) + "...",
|
|
279
|
+
traits
|
|
280
|
+
});
|
|
222
281
|
const event = buildEvent({
|
|
223
282
|
event_name: "identify",
|
|
224
283
|
fan_id_hash: fanIdHash,
|
|
@@ -248,10 +307,20 @@ var BalancePixel = (() => {
|
|
|
248
307
|
sessionId = getOrCreateSession();
|
|
249
308
|
loadFanId();
|
|
250
309
|
loadConsent();
|
|
310
|
+
if (!consent) {
|
|
311
|
+
consent = {
|
|
312
|
+
analytics: true,
|
|
313
|
+
marketing: false,
|
|
314
|
+
personalization: false,
|
|
315
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
316
|
+
};
|
|
317
|
+
log("Using default consent (dev mode):", consent);
|
|
318
|
+
}
|
|
251
319
|
captureAttribution();
|
|
252
320
|
startFlushTimer();
|
|
253
321
|
log("Initialized", {
|
|
254
322
|
artistId,
|
|
323
|
+
projectId: projectId || "(none - will track to all projects)",
|
|
255
324
|
sessionId,
|
|
256
325
|
fanIdHash,
|
|
257
326
|
consent,
|
|
@@ -287,4 +356,5 @@ var BalancePixel = (() => {
|
|
|
287
356
|
}
|
|
288
357
|
log("Pixel script loaded");
|
|
289
358
|
})();
|
|
359
|
+
return __toCommonJS(src_exports);
|
|
290
360
|
})();
|
package/dist/index.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var BalancePixel=(()=>{(function(){let
|
|
1
|
+
var BalancePixel=(()=>{var E=Object.defineProperty;var Q=Object.getOwnPropertyDescriptor;var V=Object.getOwnPropertyNames;var W=Object.prototype.hasOwnProperty;var L=(n=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(n,{get:(r,s)=>(typeof require<"u"?require:r)[s]}):n)(function(n){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+n+'" is not supported')});var X=(n,r)=>{for(var s in r)E(n,s,{get:r[s],enumerable:!0})},Z=(n,r,s,u)=>{if(r&&typeof r=="object"||typeof r=="function")for(let g of V(r))!W.call(n,g)&&g!==s&&E(n,g,{get:()=>r[g],enumerable:!(u=Q(r,g))||u.enumerable});return n};var ee=n=>Z(E({},"__esModule",{value:!0}),n);var te={};X(te,{BalanceAnalytics:()=>k});var R=L("react"),_=L("next/navigation");function k(){let n=(0,_.usePathname)(),r=(0,_.useSearchParams)();return(0,R.useEffect)(()=>{if(typeof window<"u"&&window.balance){let s=window.location.href,u=document.title;window.balance.page({url:s,title:u})}},[n,r]),null}(function(){let n=document.currentScript,r=n?.dataset.artistId,s=n?.dataset.projectId,u=n?.dataset.emulator==="true",g=n?.dataset.debug==="true";if(!r){console.error("[BALANCE Pixel] Error: data-artist-id attribute is required");return}let w="balance_session_id",x="balance_session_timestamp",b="balance_attribution",A="balance_fan_id_hash",P="balance_consent",D=60*60*1e3,S=u?"http://localhost:5001/artist-os-distro/us-central1/pixelEndpoint":"https://us-central1-artist-os-distro.cloudfunctions.net/pixelEndpoint",h=null,l=null,c=null,f={},d=[],v=null,i=(...e)=>{g&&console.log("[BALANCE Pixel]",...e)};function C(){return crypto&&crypto.randomUUID?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{let t=Math.random()*16|0;return(e==="x"?t:t&3|8).toString(16)})}function U(){try{let e=localStorage.getItem(w),t=localStorage.getItem(x);if(e&&t&&Date.now()-parseInt(t,10)<D)return localStorage.setItem(x,Date.now().toString()),e;let o=C();return localStorage.setItem(w,o),localStorage.setItem(x,Date.now().toString()),o}catch{return C()}}function B(){let e=new URLSearchParams(window.location.search),t={};return["source","medium","campaign","content","term"].forEach(o=>{let a=e.get(`utm_${o}`);a&&(t[`utm_${o}`]=a)}),t}function j(){try{let e=localStorage.getItem(b);if(e){f=JSON.parse(e),i("Loaded attribution:",f);return}let t=B();Object.keys(t).length>0&&(f=t,localStorage.setItem(b,JSON.stringify(t)),i("Captured attribution:",f))}catch{}}function F(){try{l=localStorage.getItem(A)}catch{}}function z(){try{let e=localStorage.getItem(P);e&&(c=JSON.parse(e).preferences||null,i("Loaded consent:",c))}catch{}}function H(e){let t=c;c=e;try{let a={preferences:e,method:"explicit",version:1};localStorage.setItem(P,JSON.stringify(a)),i("Consent saved:",e)}catch(a){console.error("[BALANCE Pixel] Could not save consent:",a)}let o=m({event_name:"consent_updated",metadata:{consent_preferences:e,consent_method:"explicit",previous_consent:t||void 0}});p(o)}function M(){return c}function N(e){return c?.[e]===!0}async function J(e){let t=e.toLowerCase().trim(),a=new TextEncoder().encode(t),I=await crypto.subtle.digest("SHA-256",a);return Array.from(new Uint8Array(I)).map(G=>G.toString(16).padStart(2,"0")).join("")}function m(e){let t={artist_id:r,fan_session_id:h,fan_id_hash:l||void 0,timestamp:new Date().toISOString(),source_url:window.location.href,referrer_url:document.referrer||void 0,user_agent:navigator.userAgent,...e,...f};return s&&!e.projectId&&(t.projectId=s),t}function p(e){if(!["identify","consent_updated"].includes(e.event_name)&&!N("analytics")){i(`Event '${e.event_name}' blocked - no analytics consent`);return}d.push(e),i("Event queued:",e.event_name,"(queue:",d.length,")"),d.length>=10&&y()}async function y(){if(d.length===0)return;let e=[...d];d=[],i("Flushing",e.length,"events to",S);try{let t=await fetch(S,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({events:e}),keepalive:!0});if(!t.ok)throw new Error(`HTTP ${t.status}`);i("Events sent successfully")}catch(t){console.error("[BALANCE Pixel] Failed to send events:",t),d.length<50&&d.push(...e)}}function K(){v&&clearInterval(v),v=window.setInterval(()=>{d.length>0&&y()},5e3)}function O(e={}){let t=m({event_name:"pageview",page_title:e.title||document.title,source_url:e.url||window.location.href});p(t)}function Y(e,t={}){let o=m({event_name:"custom",metadata:{event_type:e,...t}});p(o)}async function q(e,t={}){try{l=await J(e),localStorage.setItem(A,l);let o=e.split("@"),a=o[0].charAt(0)+"***@"+(o[1]||"");i("Fan identified:",{name:t.name||"(no name)",email:a,hash:l.substring(0,16)+"...",traits:t});let I=m({event_name:"identify",fan_id_hash:l,metadata:{email_sha256:l,traits:t,consent_preferences:c||void 0}});p(I)}catch(o){console.error("[BALANCE Pixel] Failed to identify:",o)}}function $(e,t="USD",o={}){let a=m({event_name:"purchase",metadata:{revenue:e,currency:t,...o}});p(a)}function T(){h=U(),F(),z(),c||(c={analytics:!0,marketing:!1,personalization:!1,timestamp:new Date().toISOString()},i("Using default consent (dev mode):",c)),j(),K(),i("Initialized",{artistId:r,projectId:s||"(none - will track to all projects)",sessionId:h,fanIdHash:l,consent:c,useEmulator:u,endpoint:S}),O(),window.addEventListener("beforeunload",()=>{y()}),document.addEventListener("visibilitychange",()=>{document.visibilityState==="hidden"&&y()})}window.balance={track:Y,identify:q,page:O,purchase:$,getSessionId:()=>h,getFanIdHash:()=>l,getAttribution:()=>f,setConsent:H,getConsent:M,hasConsent:N},document.readyState==="loading"?document.addEventListener("DOMContentLoaded",T):T(),i("Pixel script loaded")})();return ee(te);})();
|
package/package.json
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hifilabs/pixel",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.4",
|
|
4
4
|
"description": "BALANCE Pixel - Lightweight browser tracking script for artist fan analytics",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
|
-
"
|
|
6
|
+
"module": "./dist/index.esm.js",
|
|
7
|
+
"types": "./dist/index.esm.d.ts",
|
|
7
8
|
"publishConfig": {
|
|
8
|
-
"access": "
|
|
9
|
+
"access": "public"
|
|
9
10
|
},
|
|
10
11
|
"files": [
|
|
11
12
|
"dist"
|
|
@@ -31,6 +32,11 @@
|
|
|
31
32
|
"url": "https://github.com/hifilabs/artist-os-distro"
|
|
32
33
|
},
|
|
33
34
|
"homepage": "https://github.com/hifilabs/artist-os-distro#readme",
|
|
35
|
+
"peerDependencies": {
|
|
36
|
+
"react": "^18.0.0 || ^19.0.0",
|
|
37
|
+
"react-dom": "^18.0.0 || ^19.0.0",
|
|
38
|
+
"next": "^13.0.0 || ^14.0.0 || ^15.0.0"
|
|
39
|
+
},
|
|
34
40
|
"devDependencies": {
|
|
35
41
|
"esbuild": "^0.19.0",
|
|
36
42
|
"typescript": "^5.4.5"
|