@obelism/numbers-sdk 0.3.0 → 0.4.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 CHANGED
@@ -35,8 +35,9 @@ query string or hash (`?tab=2`, `#pricing`) isn't a second page view.
35
35
  events belong to; without it they go to the organization's first space.
36
36
  `data-endpoint="https://…"` sends somewhere else, e.g. a proxy on your own
37
37
  domain; without it events go to numbers' origin, even when a CDN serves the
38
- file. `data-debug` turns on the client's development warnings (snake_case
39
- names, an 8 KB body, a `data-space` it can't use), and
38
+ file. `data-debug` turns on the development warnings (snake_case names, an 8 KB
39
+ body, a `data-organization` or `data-space` it can't use, an unknown
40
+ `data-environment` or `data-storage`), and
40
41
  `data-storage="session"` (or `"none"`) counts without a cookie. npm CDNs
41
42
  serve the same file from `@obelism/numbers-sdk/dist/script.global.js`.
42
43
 
package/dist/index.js CHANGED
@@ -178,6 +178,9 @@ const createNumbers = ({ organizationId, spaceId, environment = 'production', en
178
178
  // Epoch ms until which sending is paused after a 429.
179
179
  let pausedUntil = 0;
180
180
  let firstPageView = true;
181
+ // The path of the last page view, shared by every autoTrack: a second
182
+ // call replaces the listeners but must not count the page again.
183
+ let lastPath = null;
181
184
  let stopAutoTrack = null;
182
185
  const sentKeys = new Set();
183
186
  const exposed = new Set();
@@ -296,7 +299,6 @@ const createNumbers = ({ organizationId, spaceId, environment = 'production', en
296
299
  if (pageViews) {
297
300
  // One page view per path: replaceState for a query or hash change
298
301
  // isn't a new page.
299
- let lastPath = null;
300
302
  const onNavigate = ()=>{
301
303
  if (location.pathname === lastPath) return;
302
304
  lastPath = location.pathname;
@@ -342,9 +344,25 @@ const createNumbers = ({ organizationId, spaceId, environment = 'production', en
342
344
  } catch {
343
345
  return;
344
346
  }
347
+ // Only http(s): a data: URL's path is its whole payload, and
348
+ // mailto:/tel: aren't destinations.
349
+ if (!/^https?:$/.test(url.protocol)) return;
345
350
  const id = link.closest('[data-numbers-id]')?.getAttribute('data-numbers-id');
346
- if (downloads && isDownload(url, link)) track('file_download', id ?? url.pathname.split('/').pop() ?? url.pathname);
347
- else if (outbound && url.origin !== location.origin && /^https?:$/.test(url.protocol)) track('outbound_click', id ?? `${url.origin}${url.pathname}`);
351
+ const fileName = url.pathname.split('/').pop() || url.pathname;
352
+ const extension = fileName.includes('.') ? fileName.split('.').pop().toLowerCase() : '';
353
+ if (downloads && isDownload(url, link)) track('file_download', id ?? fileName, id ? undefined : {
354
+ params: {
355
+ file_name: extension ? fileName.slice(0, -(extension.length + 1)) : fileName,
356
+ ...extension && {
357
+ file_extension: extension
358
+ }
359
+ }
360
+ });
361
+ else if (outbound && url.origin !== location.origin) track('outbound_click', id ?? `${url.origin}${url.pathname}`, id ? undefined : {
362
+ params: {
363
+ link_domain: url.hostname
364
+ }
365
+ });
348
366
  };
349
367
  document.addEventListener('click', onLinkClick, true);
350
368
  stops.push(()=>document.removeEventListener('click', onLinkClick, true));
package/dist/index.mjs CHANGED
@@ -176,6 +176,9 @@ const createNumbers = ({ organizationId, spaceId, environment = 'production', en
176
176
  // Epoch ms until which sending is paused after a 429.
177
177
  let pausedUntil = 0;
178
178
  let firstPageView = true;
179
+ // The path of the last page view, shared by every autoTrack: a second
180
+ // call replaces the listeners but must not count the page again.
181
+ let lastPath = null;
179
182
  let stopAutoTrack = null;
180
183
  const sentKeys = new Set();
181
184
  const exposed = new Set();
@@ -294,7 +297,6 @@ const createNumbers = ({ organizationId, spaceId, environment = 'production', en
294
297
  if (pageViews) {
295
298
  // One page view per path: replaceState for a query or hash change
296
299
  // isn't a new page.
297
- let lastPath = null;
298
300
  const onNavigate = ()=>{
299
301
  if (location.pathname === lastPath) return;
300
302
  lastPath = location.pathname;
@@ -340,9 +342,25 @@ const createNumbers = ({ organizationId, spaceId, environment = 'production', en
340
342
  } catch {
341
343
  return;
342
344
  }
345
+ // Only http(s): a data: URL's path is its whole payload, and
346
+ // mailto:/tel: aren't destinations.
347
+ if (!/^https?:$/.test(url.protocol)) return;
343
348
  const id = link.closest('[data-numbers-id]')?.getAttribute('data-numbers-id');
344
- if (downloads && isDownload(url, link)) track('file_download', id ?? url.pathname.split('/').pop() ?? url.pathname);
345
- else if (outbound && url.origin !== location.origin && /^https?:$/.test(url.protocol)) track('outbound_click', id ?? `${url.origin}${url.pathname}`);
349
+ const fileName = url.pathname.split('/').pop() || url.pathname;
350
+ const extension = fileName.includes('.') ? fileName.split('.').pop().toLowerCase() : '';
351
+ if (downloads && isDownload(url, link)) track('file_download', id ?? fileName, id ? undefined : {
352
+ params: {
353
+ file_name: extension ? fileName.slice(0, -(extension.length + 1)) : fileName,
354
+ ...extension && {
355
+ file_extension: extension
356
+ }
357
+ }
358
+ });
359
+ else if (outbound && url.origin !== location.origin) track('outbound_click', id ?? `${url.origin}${url.pathname}`, id ? undefined : {
360
+ params: {
361
+ link_domain: url.hostname
362
+ }
363
+ });
346
364
  };
347
365
  document.addEventListener('click', onLinkClick, true);
348
366
  stops.push(()=>document.removeEventListener('click', onLinkClick, true));
@@ -1 +1 @@
1
- !/*! Obelism numbers (@obelism/numbers-sdk), MIT. https://numbers.obelism.studio */function(){"use strict";let e="https://numbers.obelism.studio/api/log",t="obelism_visitor_id",n="visitorId",r="visi",o="obelism_visitor_id",i=(e,t)=>e.get(t)?.slice(0,256)||void 0,s="ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789",a=e=>{let t=document.cookie.split("; ").find(t=>t.split("=")[0]===e);return t?t.split("=")[1]??"":""},l=(e,t)=>{let n=new Date(Date.now()+2592e6);document.cookie=`${e}=${t};path=/;expires=${n.toUTCString()};SameSite=Lax`+("https:"===location.protocol?";Secure":"")},u=()=>{let e=new Uint8Array(26);crypto.getRandomValues(e);let t="";for(let n of e)t+=s[n%s.length];return`${r}_${t}`},c=["7z","avi","csv","doc","docx","gz","mov","mp3","mp4","pdf","ppt","pptx","rar","tar","txt","wav","xls","xlsx","xml","zip"],d=/^[a-z][a-z0-9]*(_[a-z0-9]+)*$/,m=()=>"u">typeof window&&"u">typeof document;((s,p)=>{var h;if(!p||s.numbers)return;let f=p.dataset.organization;if(!f)return;let g=void 0!==p.dataset.debug;!f.startsWith("org_")&&"u">typeof console&&console.warn(`[numbers] data-organization "${f}" is not an org_… id.`);let b=p.dataset.space,w=b&&b.startsWith("space_")?b:void 0;b&&!w&&"u">typeof console&&console.warn(`[numbers] data-space "${b}" is not a space_… id and will be ignored.`);let v=p.dataset.storage;v&&"session"!==v&&"none"!==v&&(h=`data-storage "${v}" is not "session" or "none"; using a cookie.`,g&&"u">typeof console&&console.warn(`[numbers] ${h}`));let y=(({organizationId:s,spaceId:p,environment:h="production",endpoint:f=e,device:g,disableWarnings:b=!1,storage:w="cookie"})=>{let v=null,y=g,$=f,_=0,k=!0,x=null,L=new Set,S=new Set,E=new Set,A=(e,t)=>{!(b||E.has(e))&&(E.add(e),"u">typeof console&&console.warn(`[numbers] ${t}`))},T=()=>m()?(v??(v=((e="cookie")=>{let i;if("none"===e)return{id:u(),recurring:!1};let s=(e=>{if("session"===e)try{return sessionStorage.getItem(o)??""}catch{return""}return a(t)||a(n)})(e),c=2===(i=s.split("_")).length&&i[0]===r&&26===i[1].length,d=c?s:u();return((e,r)=>{if("session"===e){try{sessionStorage.setItem(o,r)}catch{}return}l(t,r),l(n,r)})(e,d),{id:d,recurring:c}})(w)),v):null,z=(e,t)=>{let n,r,o;return y??(n=navigator.userAgent.toLowerCase(),r=/ipad|tablet|android(?!.*mobile)/.test(n)?"tablet":/mobi|iphone|ipod|android/.test(n)?"mobile":"desktop",y={pointer:"desktop"===r?"fine":"coarse",device:r,browser:/edg\//.test(n)?"edge":/samsungbrowser/.test(n)?"samsung internet":/instagram|fban|fbav|tiktok|snapchat|wechat|line\//.test(n)?"social":/firefox|fxios/.test(n)?"firefox":/chrome|crios|chromium/.test(n)?"chrome":/safari/.test(n)?"safari":"other",os:/iphone|ipad|ipod/.test(n)?"ios":/android/.test(n)?"android":/windows/.test(n)?"windows":/mac os/.test(n)?"mac os":"unix"}),{type:e,organizationId:s,...p&&{spaceId:p},environment:h,visitorId:t.id,pointer:y.pointer,device:y.device,screen:(o=window.innerWidth)<=768?"small":o<=1024?"medium":o<=1200?"large":"huge",browser:y.browser,os:y.os,visitor:t.recurring?"recurring":"new"}},D=(e,t)=>{let n=JSON.stringify(e);return"u">typeof TextEncoder&&new TextEncoder().encode(n).length>8192&&A(`size:${t}`,`"${t}" is over 8192 bytes and will be refused: trim its \`params\`.`),fetch($,{method:"POST",headers:{"Content-Type":"text/plain;charset=UTF-8"},body:n,keepalive:!0}).then(e=>(429===e.status&&(_=Date.now()+((e=>{if(!e)return;let t=Number(e);if(Number.isFinite(t))return Math.max(0,1e3*t);let n=Date.parse(e);return Number.isNaN(n)?void 0:Math.max(0,n-Date.now())})(e.headers.get("Retry-After"))??6e4)),e),()=>void 0)},U=(e,t,n,r)=>{let o,s,a,l,u,c=T();if(!c||Date.now()<_)return null;let{value:d,currency:m,params:p,dedupeKey:h}=n;if(void 0!==h){let t=`${e}:${h}`;if(L.has(t))return null;L.add(t)}let f={...z("event",c),...(o=new URLSearchParams(location.search),s={path:location.pathname.slice(0,1024)},a=i(o,"utm_source"),l=i(o,"utm_medium"),u=i(o,"utm_campaign"),a&&(s.utmSource=a),l&&(s.utmMedium=l),u&&(s.utmCampaign=u),s),event:e.slice(0,256),scope:t.slice(0,256)};return r&&(f.referrer=r),"number"==typeof d&&Number.isFinite(d)&&(f.value=d),m&&(f.currency=m.slice(0,8)),p&&"object"==typeof p&&!Array.isArray(p)&&(f.params=p),D(f,e)},N=(e,t,n={})=>m()?(d.test(e)||A(`name:${e}`,`"${e}" isn't snake_case. Prefer GA4-style names like "add_to_cart" or "sign_up"; \`disableWarnings: true\` silences this.`),U(e,t||location.pathname,n)):null,R=()=>{if(!m())return null;let e=k?(()=>{if(document.referrer)try{let e=new URL(document.referrer);if(e.host===location.host)return;return`${e.origin}${e.pathname}`.slice(0,1024)}catch{return}})():void 0;return k=!1,U("page_view",location.pathname,{},e)},C=(e,t)=>N("form_submit",t||(e=>{let t=e.getAttribute("data-numbers-id")||e.id;if(t)return t;try{let t=new URL(e.action,location.href);return t.origin===location.origin?t.pathname:`${t.origin}${t.pathname}`}catch{return"form"}})(e));return{organizationId:s,spaceId:p,environment:h,visitor:T,setDevice:e=>{y=e},setEndpoint:e=>{$=e},track:N,pageView:R,formSubmit:C,expose:e=>{let t=T();if(!t||Date.now()<_)return null;let n=`${e.subjectKind}:${e.subjectId}`;return S.has(n)?null:(S.add(n),D({...z("exposure",t),...e},n))},autoTrack:({pageViews:e=!0,clicks:t=!0,outbound:n=!1,downloads:r=!1,forms:o=!1}={})=>{if(!m())return()=>{};x?.();let i=[];if(e){let e=null,t=()=>{location.pathname!==e&&(e=location.pathname,R())},n=e=>{let n=history[e],r=function(...e){let r=n.apply(this,e);return t(),r};history[e]=r,i.push(()=>{history[e]===r&&(history[e]=n)})};n("pushState"),n("replaceState"),window.addEventListener("popstate",t),i.push(()=>window.removeEventListener("popstate",t)),t()}if(t){let e=e=>{let t=e.target,n=t?.closest?.("[data-numbers-id]")?.getAttribute("data-numbers-id");n&&N("click",n)};document.addEventListener("click",e,!0),i.push(()=>document.removeEventListener("click",e,!0))}if(n||r){let e=e=>{let t,o,i=e.target,s=i?.closest?.("a[href]");if(!s)return;try{t=new URL(s.href,location.href)}catch{return}let a=s.closest("[data-numbers-id]")?.getAttribute("data-numbers-id");r&&(o=t,s.hasAttribute("download")||c.includes(o.pathname.split(".").pop()?.toLowerCase()??""))?N("file_download",a??t.pathname.split("/").pop()??t.pathname):n&&t.origin!==location.origin&&/^https?:$/.test(t.protocol)&&N("outbound_click",a??`${t.origin}${t.pathname}`)};document.addEventListener("click",e,!0),i.push(()=>document.removeEventListener("click",e,!0))}if(o){let e=e=>{let t=e.target;t instanceof HTMLFormElement&&C(t)};document.addEventListener("submit",e,!0),i.push(()=>document.removeEventListener("submit",e,!0))}let s=()=>{for(let e of i)e();x===s&&(x=null)};return x=s,s}}})({organizationId:f,spaceId:w,environment:p.dataset.environment||"production",endpoint:p.dataset.endpoint||(t=>{let n;try{n=new URL(t)}catch{return e}let r="localhost"===n.hostname||"127.0.0.1"===n.hostname;return"numbers.obelism.studio"===n.hostname||r?`${n.origin}/api/log`:e})(p.src),disableWarnings:!g,storage:"session"===v||"none"===v?v:"cookie"});return s.numbers=y,y.autoTrack()})(window,document.currentScript)}();
1
+ !/*! Obelism numbers (@obelism/numbers-sdk), MIT. https://numbers.obelism.studio */function(){"use strict";let e="https://numbers.obelism.studio/api/log",t="obelism_visitor_id",n="visitorId",i="visi",r="obelism_visitor_id",o=(e,t)=>e.get(t)?.slice(0,256)||void 0,s="ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789",a=e=>{let t=document.cookie.split("; ").find(t=>t.split("=")[0]===e);return t?t.split("=")[1]??"":""},l=(e,t)=>{let n=new Date(Date.now()+2592e6);document.cookie=`${e}=${t};path=/;expires=${n.toUTCString()};SameSite=Lax`+("https:"===location.protocol?";Secure":"")},u=()=>{let e=new Uint8Array(26);crypto.getRandomValues(e);let t="";for(let n of e)t+=s[n%s.length];return`${i}_${t}`},d=["7z","avi","csv","doc","docx","gz","mov","mp3","mp4","pdf","ppt","pptx","rar","tar","txt","wav","xls","xlsx","xml","zip"],c=/^[a-z][a-z0-9]*(_[a-z0-9]+)*$/,m=()=>"u">typeof window&&"u">typeof document,p=["develop","staging","production"];((s,h)=>{if(!h||s.numbers)return;let f=void 0!==h.dataset.debug,g=e=>{f&&"u">typeof console&&console.warn(`[numbers] ${e}`)},b=h.dataset.organization;if(!b)return g("data-organization is missing; nothing is tracked.");b.startsWith("org_")||g(`data-organization "${b}" is not an org_… id.`);let v=h.dataset.space,w=v&&v.startsWith("space_")?v:void 0;v&&!w&&g(`data-space "${v}" is not a space_… id and will be ignored.`);let y=h.dataset.storage;y&&"session"!==y&&"none"!==y&&g(`data-storage "${y}" is not "session" or "none"; using a cookie.`);let $=h.dataset.environment;$&&!p.includes($)&&g(`data-environment "${$}" is not one of ${p.join(", ")}; using production.`);let _=(({organizationId:s,spaceId:p,environment:h="production",endpoint:f=e,device:g,disableWarnings:b=!1,storage:v="cookie"})=>{let w=null,y=g,$=f,_=0,k=!0,x=null,L=null,S=new Set,E=new Set,A=new Set,z=(e,t)=>{!(b||A.has(e))&&(A.add(e),"u">typeof console&&console.warn(`[numbers] ${t}`))},T=()=>m()?(w??(w=((e="cookie")=>{let o;if("none"===e)return{id:u(),recurring:!1};let s=(e=>{if("session"===e)try{return sessionStorage.getItem(r)??""}catch{return""}return a(t)||a(n)})(e),d=2===(o=s.split("_")).length&&o[0]===i&&26===o[1].length,c=d?s:u();return((e,i)=>{if("session"===e){try{sessionStorage.setItem(r,i)}catch{}return}l(t,i),l(n,i)})(e,c),{id:c,recurring:d}})(v)),w):null,D=(e,t)=>{let n,i,r;return y??(n=navigator.userAgent.toLowerCase(),i=/ipad|tablet|android(?!.*mobile)/.test(n)?"tablet":/mobi|iphone|ipod|android/.test(n)?"mobile":"desktop",y={pointer:"desktop"===i?"fine":"coarse",device:i,browser:/edg\//.test(n)?"edge":/samsungbrowser/.test(n)?"samsung internet":/instagram|fban|fbav|tiktok|snapchat|wechat|line\//.test(n)?"social":/firefox|fxios/.test(n)?"firefox":/chrome|crios|chromium/.test(n)?"chrome":/safari/.test(n)?"safari":"other",os:/iphone|ipad|ipod/.test(n)?"ios":/android/.test(n)?"android":/windows/.test(n)?"windows":/mac os/.test(n)?"mac os":"unix"}),{type:e,organizationId:s,...p&&{spaceId:p},environment:h,visitorId:t.id,pointer:y.pointer,device:y.device,screen:(r=window.innerWidth)<=768?"small":r<=1024?"medium":r<=1200?"large":"huge",browser:y.browser,os:y.os,visitor:t.recurring?"recurring":"new"}},U=(e,t)=>{let n=JSON.stringify(e);return"u">typeof TextEncoder&&new TextEncoder().encode(n).length>8192&&z(`size:${t}`,`"${t}" is over 8192 bytes and will be refused: trim its \`params\`.`),fetch($,{method:"POST",headers:{"Content-Type":"text/plain;charset=UTF-8"},body:n,keepalive:!0}).then(e=>(429===e.status&&(_=Date.now()+((e=>{if(!e)return;let t=Number(e);if(Number.isFinite(t))return Math.max(0,1e3*t);let n=Date.parse(e);return Number.isNaN(n)?void 0:Math.max(0,n-Date.now())})(e.headers.get("Retry-After"))??6e4)),e),()=>void 0)},N=(e,t,n,i)=>{let r,s,a,l,u,d=T();if(!d||Date.now()<_)return null;let{value:c,currency:m,params:p,dedupeKey:h}=n;if(void 0!==h){let t=`${e}:${h}`;if(S.has(t))return null;S.add(t)}let f={...D("event",d),...(r=new URLSearchParams(location.search),s={path:location.pathname.slice(0,1024)},a=o(r,"utm_source"),l=o(r,"utm_medium"),u=o(r,"utm_campaign"),a&&(s.utmSource=a),l&&(s.utmMedium=l),u&&(s.utmCampaign=u),s),event:e.slice(0,256),scope:t.slice(0,256)};return i&&(f.referrer=i),"number"==typeof c&&Number.isFinite(c)&&(f.value=c),m&&(f.currency=m.slice(0,8)),p&&"object"==typeof p&&!Array.isArray(p)&&(f.params=p),U(f,e)},R=(e,t,n={})=>m()?(c.test(e)||z(`name:${e}`,`"${e}" isn't snake_case. Prefer GA4-style names like "add_to_cart" or "sign_up"; \`disableWarnings: true\` silences this.`),N(e,t||location.pathname,n)):null,C=()=>{if(!m())return null;let e=k?(()=>{if(document.referrer)try{let e=new URL(document.referrer);if(e.host===location.host)return;return`${e.origin}${e.pathname}`.slice(0,1024)}catch{return}})():void 0;return k=!1,N("page_view",location.pathname,{},e)},I=(e,t)=>R("form_submit",t||(e=>{let t=e.getAttribute("data-numbers-id")||e.id;if(t)return t;try{let t=new URL(e.action,location.href);return t.origin===location.origin?t.pathname:`${t.origin}${t.pathname}`}catch{return"form"}})(e));return{organizationId:s,spaceId:p,environment:h,visitor:T,setDevice:e=>{y=e},setEndpoint:e=>{$=e},track:R,pageView:C,formSubmit:I,expose:e=>{let t=T();if(!t||Date.now()<_)return null;let n=`${e.subjectKind}:${e.subjectId}`;return E.has(n)?null:(E.add(n),U({...D("exposure",t),...e},n))},autoTrack:({pageViews:e=!0,clicks:t=!0,outbound:n=!1,downloads:i=!1,forms:r=!1}={})=>{if(!m())return()=>{};L?.();let o=[];if(e){let e=()=>{location.pathname!==x&&(x=location.pathname,C())},t=t=>{let n=history[t],i=function(...t){let i=n.apply(this,t);return e(),i};history[t]=i,o.push(()=>{history[t]===i&&(history[t]=n)})};t("pushState"),t("replaceState"),window.addEventListener("popstate",e),o.push(()=>window.removeEventListener("popstate",e)),e()}if(t){let e=e=>{let t=e.target,n=t?.closest?.("[data-numbers-id]")?.getAttribute("data-numbers-id");n&&R("click",n)};document.addEventListener("click",e,!0),o.push(()=>document.removeEventListener("click",e,!0))}if(n||i){let e=e=>{let t,r,o=e.target,s=o?.closest?.("a[href]");if(!s)return;try{t=new URL(s.href,location.href)}catch{return}if(!/^https?:$/.test(t.protocol))return;let a=s.closest("[data-numbers-id]")?.getAttribute("data-numbers-id"),l=t.pathname.split("/").pop()||t.pathname,u=l.includes(".")?l.split(".").pop().toLowerCase():"";i&&(r=t,s.hasAttribute("download")||d.includes(r.pathname.split(".").pop()?.toLowerCase()??""))?R("file_download",a??l,a?void 0:{params:{file_name:u?l.slice(0,-(u.length+1)):l,...u&&{file_extension:u}}}):n&&t.origin!==location.origin&&R("outbound_click",a??`${t.origin}${t.pathname}`,a?void 0:{params:{link_domain:t.hostname}})};document.addEventListener("click",e,!0),o.push(()=>document.removeEventListener("click",e,!0))}if(r){let e=e=>{let t=e.target;t instanceof HTMLFormElement&&I(t)};document.addEventListener("submit",e,!0),o.push(()=>document.removeEventListener("submit",e,!0))}let s=()=>{for(let e of o)e();L===s&&(L=null)};return L=s,s}}})({organizationId:b,spaceId:w,environment:$||"production",endpoint:h.dataset.endpoint||(t=>{let n;try{n=new URL(t)}catch{return e}let i="localhost"===n.hostname||"127.0.0.1"===n.hostname;return"numbers.obelism.studio"===n.hostname||i?`${n.origin}/api/log`:e})(h.src),disableWarnings:!f,storage:"session"===y||"none"===y?y:"cookie"});return s.numbers=_,_.autoTrack()})(window,document.currentScript)}();
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@obelism/numbers-sdk",
3
3
  "description": "Obelism numbers SDK: page views, events and clicks on tagged elements, sent to numbers.obelism.studio",
4
- "version": "0.3.0",
4
+ "version": "0.4.0",
5
5
  "keywords": [
6
6
  "analytics",
7
7
  "events",