@walkeros/web-source-session 4.1.3-next-1779963694449 → 4.2.0-next-1780387694663

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/CHANGELOG.md CHANGED
@@ -1,12 +1,15 @@
1
1
  # @walkeros/web-source-session
2
2
 
3
- ## 4.1.3-next-1779963694449
3
+ ## 4.2.0-next-1780387694663
4
4
 
5
5
  ### Patch Changes
6
6
 
7
7
  - Updated dependencies [908d6f0]
8
- - @walkeros/core@4.1.3-next-1779963694449
9
- - @walkeros/web-core@4.1.3-next-1779963694449
8
+ - Updated dependencies [f4a9013]
9
+ - Updated dependencies [654ba38]
10
+ - Updated dependencies [3eb2467]
11
+ - @walkeros/core@4.2.0-next-1780387694663
12
+ - @walkeros/web-core@4.2.0-next-1780387694663
10
13
 
11
14
  ## 4.1.2
12
15
 
package/dist/dev.js CHANGED
@@ -1 +1 @@
1
- "use strict";var e,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,o=Object.getOwnPropertyNames,s=Object.prototype.hasOwnProperty,r=(e,n)=>{for(var o in n)t(e,o,{get:n[o],enumerable:!0})},i={};r(i,{examples:()=>p,schemas:()=>a}),module.exports=(e=i,((e,r,i,a)=>{if(r&&"object"==typeof r||"function"==typeof r)for(let c of o(r))s.call(e,c)||c===i||t(e,c,{get:()=>r[c],enumerable:!(a=n(r,c))||a.enumerable});return e})(t({},"__esModule",{value:!0}),e));var a={};r(a,{SettingsSchema:()=>u,settings:()=>d});var c=require("@walkeros/core/dev"),l=require("@walkeros/core/dev"),u=l.z.object({storage:l.z.boolean().default(!1).describe("Enable persistent storage for session/device IDs").optional(),consent:l.z.union([l.z.string(),l.z.array(l.z.string())]).describe("Consent key(s) required to enable storage mode").optional(),length:l.z.number().default(30).describe("Session timeout in minutes").optional(),pulse:l.z.boolean().default(!1).describe("Keep session alive on each event").optional(),sessionKey:l.z.string().default("elbSessionId").describe("Storage key for session ID").optional(),sessionStorage:l.z.enum(["local","session"]).default("local").describe("Storage type for session").optional(),deviceKey:l.z.string().default("elbDeviceId").describe("Storage key for device ID").optional(),deviceStorage:l.z.enum(["local","session"]).default("local").describe("Storage type for device").optional(),deviceAge:l.z.number().default(30).describe("Device ID age in days").optional(),cb:l.z.any().describe("Custom session callback function or false to disable").optional(),clickIds:l.z.array(l.ClickIdEntrySchema).describe("Custom click-ID registry. Entries with a `param` matching a default override the platform name in place; new params append to the end of the priority list.").optional()}),d=(0,c.zodToSchema)(u),p={};r(p,{createTrigger:()=>ye,step:()=>f,trigger:()=>we});var f={};r(f,{newMarketingSession:()=>g,returningVisitor:()=>h});var g={title:"New marketing session",description:"A visit with UTM parameters starts a new session and emits walker user, session, and session start calls.",trigger:{type:"load",options:{url:"https://example.com/?utm_source=google&utm_medium=cpc&utm_campaign=winter-sale"}},in:{storage:!0},out:[["elb","user",{session:"s3ss10n-id",device:"d3v1c3-id"}],["elb","session",{id:"s3ss10n-id",start:17e11,isNew:!0,count:1,runs:1,marketing:!0,source:"google",medium:"cpc",campaign:"winter-sale",referrer:"",device:"d3v1c3-id",isStart:!0,storage:!0,updated:17e11}],["elb",{name:"session start",data:{id:"s3ss10n-id",start:17e11,isNew:!0,count:1,runs:1,marketing:!0,source:"google",medium:"cpc",campaign:"winter-sale",referrer:"",device:"d3v1c3-id",isStart:!0,storage:!0,updated:17e11}}]]},h={title:"Returning visitor",description:"A returning visit with a google referrer reuses the stored device id and increments the session count.",trigger:{type:"load",options:{referrer:"https://google.com"}},in:{storage:!0},out:[["elb","user",{session:"n3w-s3ss10n",device:"d3v1c3-id"}],["elb","session",{id:"n3w-s3ss10n",start:1700001e6,isNew:!1,count:3,runs:1,referrer:"google.com",device:"d3v1c3-id",isStart:!0,storage:!0,updated:1700001e6}],["elb",{name:"session start",data:{id:"n3w-s3ss10n",start:1700001e6,isNew:!1,count:3,runs:1,referrer:"google.com",device:"d3v1c3-id",isStart:!0,storage:!0,updated:1700001e6}}]]},m=require("@walkeros/core"),v=require("@walkeros/core"),y=require("@walkeros/core"),w=(require("@walkeros/core"),require("@walkeros/core")),b=require("@walkeros/core"),k=require("@walkeros/core"),I=require("@walkeros/core"),S=require("@walkeros/core"),C=require("@walkeros/core"),q=require("@walkeros/core"),x=require("@walkeros/core"),O=require("@walkeros/core"),j=require("@walkeros/core"),D={Action:"action",Actions:"actions",Config:"config",Consent:"consent",Context:"context",Custom:"custom",Destination:"destination",Elb:"elb",Globals:"globals",Hook:"hook",Init:"init",Link:"link",On:"on",Prefix:"data-elb",Ready:"ready",Run:"run",Session:"session",Shutdown:"shutdown",User:"user",Walker:"walker"};function A(e,t){const n=e.status.startedAt;return{flowId:"default",stepId:t.stepId,stepType:t.stepType,phase:t.phase,eventId:t.eventId,timestamp:new Date(t.now).toISOString(),elapsedMs:t.now-n}}function E(e,t){return e.storeId&&t.stores[e.storeId]?t.stores[e.storeId]:t.stores.__cache}function $(e){var t;const n={};for(const[o,s]of Object.entries(e)){const e=null==(t=s.config)?void 0:t.next;"string"==typeof e||Array.isArray(e)&&e.every(e=>"string"==typeof e)?n[o]={next:e}:n[o]={}}return n}function M(e,t){const n=e.config||{},o=e[t];return void 0!==o?{config:{...n,[t]:o},chainValue:o}:{config:n,chainValue:void 0}}function _(e,t={}){if(!e)return[];if(Array.isArray(e))return e;const n=[],o=new Set;let s=e;for(;s&&t[s]&&!o.has(s);){o.add(s),n.push(s);const e=t[s].next;if(Array.isArray(e)){n.push(...e);break}s=e}return n}async function T(e,t,n){if(t.init&&!t.config.init){const o=t.type||"unknown",s=e.logger.scope(`transformer:${o}`),r={collector:e,logger:s,id:n,ingest:(0,I.createIngest)(n),config:t.config,env:H(t.config.env)};s.debug("init");const i=await(0,I.useHooks)(t.init,"TransformerInit",e.hooks,e.logger)(r);if(!1===i)return!1;t.config={...i||t.config,env:(null==i?void 0:i.env)||t.config.env,init:!0},s.debug("init done")}return!0}async function P(e,t,n,o,s,r){const i=t.type||"unknown",a=e.logger.scope(`transformer:${i}`),c={collector:e,logger:a,id:n,ingest:s,config:t.config,env:{...H(t.config.env),...r?{respond:r}:{}}};a.debug("push",{event:o.name});const l="string"==typeof o.id?o.id:"",u=Date.now(),d=A(e,{stepId:(0,I.stepId)("transformer",n),stepType:"transformer",phase:"in",eventId:l,now:u});(0,I.emitStep)(e,d);try{const s=await(0,I.useHooks)(t.push,"TransformerPush",e.hooks,e.logger)(o,c),r=Date.now(),i=A(e,{stepId:(0,I.stepId)("transformer",n),stepType:"transformer",phase:"out",eventId:l,now:r});return i.durationMs=r-u,i.outEvent=s,(0,I.emitStep)(e,i),a.debug("push done"),s}catch(t){const o=Date.now(),s=A(e,{stepId:(0,I.stepId)("transformer",n),stepType:"transformer",phase:"error",eventId:l,now:o});throw s.durationMs=o-u,s.error=t instanceof Error?{name:t.name,message:t.message}:{message:String(t)},(0,I.emitStep)(e,s),t}}function z(e,t){return e?{...e,_meta:{...e._meta,path:[...e._meta.path]}}:(0,I.createIngest)(t)}async function K(e,t,n,o,s,r,i){var a,c,l,u,d,p,f,g;s||(s=(0,I.createIngest)(null!=(a=n[0])?a:"chain")),i&&s._meta&&(s._meta.chainPath=i);let h=o,m=r;for(const o of n){const r=t[o];if(!r){e.logger.warn(`Transformer not found: ${o}`);continue}if(s&&s._meta&&s._meta.path.length>256)return e.logger.error(`Max path length exceeded at ${o}`),{event:null,respond:m};if(s&&s._meta&&(s._meta.hops++,s._meta.path.push(o)),!await(0,I.tryCatchAsync)(T,t=>{if(t instanceof I.FatalError)throw t;return e.status.failed++,e.logger.scope(`transformer:${r.type||"unknown"}`).error("transformer init failed",{transformer:o,error:t}),!1})(e,r,o))return{event:null,respond:m};if(i&&void 0!==(null==(l=null==(c=r.config)?void 0:c.chainMocks)?void 0:l[i])){const t=r.config.chainMocks[i];e.logger.scope(`transformer:${r.type||"unknown"}`).debug("chainMock",{chain:i}),h=t;continue}if(void 0!==(null==(u=r.config)?void 0:u.mock)){e.logger.scope(`transformer:${r.type||"unknown"}`).debug("mock"),h=r.config.mock;continue}if(null==(d=r.config)?void 0:d.disabled)continue;const a=null==(p=r.config)?void 0:p.cache,v=a?(0,I.compileCache)(a):void 0,y=v?E(v,e):void 0;let w;if(v&&y){const e=(0,I.buildCacheContext)(s,h),t=await(0,I.checkCache)(v,y,e);if("HIT"===(null==t?void 0:t.status)&&t.value){if(h=t.value,v.stop)return{event:h,respond:m,stopped:!0};continue}"MISS"===(null==t?void 0:t.status)&&(w={key:t.key,ttl:t.rule.ttl})}const b=r.config.before;if(b){const n=(0,I.getNextSteps)(b,(0,I.buildCacheContext)(s,h));if(1===n.length){const o=_(n[0],$(t));if(o.length>0){const n=await K(e,t,o,h,s,m,i);if(null===n.event)return{event:null,respond:null!=(f=n.respond)?f:m};if(n.stopped)return{event:Array.isArray(n.event)?n.event[0]:n.event,respond:null!=(g=n.respond)?g:m,stopped:!0};n.respond&&(m=n.respond),h=Array.isArray(n.event)?n.event[0]:n.event}}else n.length>1&&await Promise.all(n.map(n=>(0,I.tryCatchAsync)(K,t=>(e.logger.scope("transformer:many").error(`many branch ${n} failed`,{error:t}),{event:null,respond:void 0}))(e,t,_(n,$(t)),h,z(s,n),void 0,i)))}const k=await(0,I.tryCatchAsync)(P,t=>(e.logger.scope(`transformer:${r.type||"unknown"}`).error("Push failed",{error:t}),!1))(e,r,o,h,s,m);if(!1===k)return{event:null,respond:m};if(Array.isArray(k)){const r=n.slice(n.indexOf(o)+1),a=await Promise.all(k.map(async n=>{const o=n.event||h,a=z(s,"unknown");if(n.next){const s=(0,I.getNextSteps)(n.next,(0,I.buildCacheContext)(a,o));if(0===s.length)return{event:o,respond:m};if(1===s.length){const n=_(s[0],$(t));return n.length>0?K(e,t,n,o,a,m,i):{event:o,respond:m}}return(await Promise.all(s.map(n=>(0,I.tryCatchAsync)(K,t=>(e.logger.scope("transformer:many").error(`many branch ${n} failed`,{error:t}),{event:null,respond:void 0}))(e,t,_(n,$(t)),o,z(a,n),void 0,i)))).map(e=>({event:e.event,respond:void 0}))}return r.length>0?K(e,t,r,o,a,m,i):{event:o,respond:m}}));let c=m;const l=[];for(const e of a.flat())if(null!==e)if(e&&"object"==typeof e&&"event"in e){const t=e;if(t.respond&&(c=t.respond),null===t.event)continue;Array.isArray(t.event)?l.push(...t.event):l.push(t.event)}else l.push(e);return 0===l.length?{event:null,respond:c}:1===l.length?{event:l[0],respond:c}:{event:l,respond:c}}if(k&&"object"==typeof k){const{event:n,respond:o,next:r}=k;if(o&&(m=o),void 0!==r){const o=(0,I.getNextSteps)(r,(0,I.buildCacheContext)(s,h));if(0===o.length){n&&(h=n);continue}if(1===o.length){const a=_(o[0],$(t));return a.length>0?K(e,t,a,n||h,s,m,i):(e.logger.warn(`Branch target not found: ${JSON.stringify(r)}`),{event:null,respond:m})}return await Promise.all(o.map(o=>(0,I.tryCatchAsync)(K,t=>(e.logger.scope("transformer:many").error(`many branch ${o} failed`,{error:t}),{event:null,respond:void 0}))(e,t,_(o,$(t)),n||h,z(s,o),void 0,i))),{event:null,respond:void 0}}n&&(h=n)}w&&y&&(0,I.storeCache)(y,w.key,h,w.ttl);const S=r.config.next,C="string"==typeof S||Array.isArray(S)&&S.every(e=>"string"==typeof e),q=void 0!==S&&!C;if((!k||"object"==typeof k&&!k.next)&&q){const n=(0,I.getNextSteps)(r.config.next,(0,I.buildCacheContext)(s,h));if(1===n.length){const o=_(n[0],$(t));return o.length>0?K(e,t,o,h,s,m,i):{event:h,respond:m}}return n.length>1?(await Promise.all(n.map(n=>(0,I.tryCatchAsync)(K,t=>(e.logger.scope("transformer:many").error(`many branch ${n} failed`,{error:t}),{event:null,respond:void 0}))(e,t,_(n,$(t)),h,z(s,n),void 0,i))),{event:null,respond:void 0}):{event:h,respond:m}}}return{event:h,respond:m}}function H(e){return e&&(0,I.isObject)(e)?e:{}}function N(e){return"string"==typeof e||!(!Array.isArray(e)||!e.every(e=>"string"==typeof e))}async function R(e,t,n){var o,s;if(!t.on||!(null==(o=t.queueOn)?void 0:o.length))return;const r=t.queueOn;t.queueOn=[];const i=n||(null==(s=t.config)?void 0:s.id)||"unknown";for(const{type:n,data:o}of r)await(0,k.tryCatchAsync)(t.on,t=>{if(t instanceof k.FatalError)throw t;e.status.failed++,e.logger.scope("source").error("source on flush failed",{sourceId:i,type:n,error:t})})(n,o)}function F(e){var t;return Boolean(e.config.init)&&!(null==(t=e.config.require)?void 0:t.length)}async function B(e,t,n){var o;const{code:s,config:r={},env:i={},primary:a,next:c,before:l,cache:u}=n,d=u,p=d?(0,k.compileCache)({...d,stop:null==(o=d.stop)||o}):void 0,f=N(c)?_(c,$(e.transformers)):void 0,g=N(l)?_(l,$(e.transformers)):void 0,h=i.push,m=null!=h?h:e.push,v=Boolean(h),y=async(n,o,s)=>{var i;let a;const u=null!=g?g:void 0!==l?(()=>{const t=(0,k.getNextSteps)(l,(0,k.buildCacheContext)(s.ingest));return 0===t.length?[]:_(1===t.length?t[0]:t,$(e.transformers))})():[];let d=[n];if(u.length>0&&e.transformers&&Object.keys(e.transformers).length>0){const o=await K(e,e.transformers,u,n,s.ingest,s.respond,`source.${t}.before`);if(null===o.event)return{ok:!0};if(o.stopped)return o.respond&&(s.respond=o.respond),{ok:!0};o.respond&&(s.respond=o.respond),d=Array.isArray(o.event)?o.event:[o.event]}if(p){const t=E(p,e);if(t){const n=(0,k.buildCacheContext)(s.ingest),o=await(0,k.checkCache)(p,t,n);if(o){if("HIT"===o.status&&void 0!==o.value&&p.stop){let t=o.value;return o.rule.update&&(t=await(0,k.applyUpdate)(t,o.rule.update,{...n,cache:{status:"HIT"}},e)),null==(i=s.respond)||i.call(s,t),{ok:!0}}if("MISS"===o.status&&p.stop&&s.respond){const r=s.respond,i=o.rule.update,c={...n,cache:{status:"MISS"}},l=o.key,u=o.rule.ttl,d=n=>{(0,k.storeCache)(t,l,n,u),i?a=(async()=>{const t=await(0,k.applyUpdate)(n,i,c,e);r(t)})():r(n)};s.respond=d}"MISS"!==o.status||p.stop||(0,k.storeCache)(t,o.key,!0,o.rule.ttl)}}}const h=f?{kind:"single",preChain:f}:void 0!==c?(()=>{const t=(0,k.getNextSteps)(c,(0,k.buildCacheContext)(s.ingest));return 0===t.length?{kind:"single",preChain:[]}:1===t.length?{kind:"single",preChain:_(t[0],$(e.transformers))}:{kind:"many",branches:t.map(t=>_(t,$(e.transformers)))}})():{kind:"single",preChain:[]};let y={ok:!0};for(const n of d)"many"===h.kind?(await Promise.all(h.branches.map((i,a)=>(0,k.tryCatchAsync)(async()=>v?m(n):m(n,{...o,id:t,ingest:z(s.ingest,`${t}.${a}`),respond:void 0,mapping:r,preChain:i}),t=>(e.logger.scope("source:many").error(`many branch ${a} failed`,{error:t}),{ok:!0}))())),y={ok:!0}):y=v?await m(n):await m(n,{...o,id:t,ingest:s.ingest,respond:s.respond,mapping:r,preChain:h.preChain});return a&&await a,y},w=async n=>{const o=(0,k.createIngest)(t);if(!r.ingest||void 0===n)return o;const s=await(0,k.getMappingValue)(n,r.ingest,{collector:e});return{...o,...s,_meta:o._meta}},b=e.logger.scope("source").scope(t),I={command:e.command,sources:e.sources,elb:e.sources.elb.push,logger:b,...i,push:async(e,n={})=>{const o={ingest:(0,k.createIngest)(t),respond:void 0};return y(e,n,o)}},S={collector:e,logger:b,id:t,config:r,env:I,withScope:async(e,t,n)=>{const o={ingest:await w(e),respond:t};return n({...I,push:(e,t={})=>y(e,t,o),ingest:o.ingest,respond:o.respond})}},C=await(0,k.tryCatchAsync)(s,n=>{if(n instanceof k.FatalError)throw n;e.status.failed++,e.logger.scope("source").error("source factory failed",{sourceId:t,error:n})})(S);if(!C)return;const q=C.type||"unknown",x=e.logger.scope(q).scope(t);return I.logger=x,a&&(C.config={...C.config,primary:a}),C}function G(e,t,n,o){if(n instanceof w.FatalError)throw n;e.logger.scope("on").error("on callback failed",{kind:t,...o,error:n})}function U(e,t){return{collector:e,logger:e.logger.scope("on").scope(String(t))}}function W(e,t,n,o,s){if(!t.on)return;const r=t.type||"unknown",i=e.logger.scope(r).scope("on").scope(o),a={collector:e,logger:i,id:n,config:t.config,data:s,env:le(t.env,t.config.env)};(0,b.tryCatch)(t.on,t=>G(e,"destination",t,{destId:n,type:o}))(o,a)}function L(e,t,n,o){let s;switch(t){case D.Consent:s=o||e.consent;break;case D.Session:s=e.session;break;case D.User:s=o||e.user;break;case D.Custom:s=o||e.custom;break;case D.Globals:s=o||e.globals;break;case D.Config:s=o||e.config;break;case D.Ready:case D.Run:default:s=void 0}if(n.length)switch(t){case D.Consent:!function(e,t,n){const o=n||e.consent,s=U(e,D.Consent);t.forEach(t=>{Object.keys(o).filter(e=>e in t).forEach(n=>{(0,b.tryCatch)(t[n],t=>G(e,"consent",t,{key:n}))(o,s)})})}(e,n,o);break;case D.Ready:!function(e,t){if(!e.allowed)return;const n=U(e,D.Ready);t.forEach(t=>{(0,b.tryCatch)(t,t=>G(e,"ready",t))(void 0,n)})}(e,n);break;case D.Run:!function(e,t){if(!e.allowed)return;const n=U(e,D.Run);t.forEach(t=>{(0,b.tryCatch)(t,t=>G(e,"run",t))(void 0,n)})}(e,n);break;case D.Session:!function(e,t){if(!e.session)return;const n=U(e,D.Session);t.forEach(t=>{(0,b.tryCatch)(t,t=>G(e,"session",t))(e.session,n)})}(e,n);break;default:{const o=U(e,t);n.forEach(n=>{"function"==typeof n&&(0,b.tryCatch)(n,n=>G(e,"generic",n,{type:t}))(s,o)});break}}}function J(e,t,n,o){var s;if(!Number.isFinite(n.max)||n.max<=0)throw new Error(`pushBounded: max must be > 0 (got ${n.max})`);if("dropNewest"===(null!=(s=n.onOverflow)?s:"dropOldest"))return e.length>=n.max?(o&&o([t]),{appended:!1,dropped:1}):(e.push(t),{appended:!0,dropped:0});const r=[];for(;e.length>=n.max;)r.push(e.shift());return e.push(t),r.length>0&&o&&o(r),{appended:!0,dropped:r.length}}var V=new WeakMap;function Y(e,t,n,o){V.get(e)||(V.set(e,!0),t.warn(n,o))}function Q(e){V.delete(e)}var X=Object.freeze({batched:!0});function Z(e){return e===X}function ee(e){return void 0===e?{}:"number"==typeof e?{wait:e}:{wait:e.wait,size:e.size,age:e.age}}function te(e,t){return e.status.destinations[t]||(e.status.destinations[t]={count:0,failed:0,duration:0,queuePushSize:0,dlqSize:0}),e.status.destinations[t]}function ne(e,t,n,o){var s;e.dropped[t]||(e.dropped[t]={});const r=e.dropped[t];return r[n]=(null!=(s=r[n])?s:0)+o,r[n]}function oe(e,t,n){if(!e)return[];if(Array.isArray(e)&&e.every(e=>"string"==typeof e))return _(e,t);if("string"==typeof e)return _(e,t);const o=(0,y.getNextSteps)(e,(0,y.buildCacheContext)(n));return 0===o.length?[]:1===o.length?_(o[0],t):_(o,t)}async function se(e,t,n={},o){var s,r,i,a,c,l;const{allowed:u,consent:d,globals:p,user:f}=e;if(!u)return ae({ok:!1});if(t){const n=e.config.queueMax;if(void 0===n)throw new Error("Collector.Config.queueMax is undefined; defaults must be seeded by collector()");const o=J(e.queue,t,{max:n});if(o.dropped>0){const t=ne(e.status,(0,y.stepId)("collector"),"queue",o.dropped);Y(e.queue,e.logger,"collector.queue overflow; oldest events dropped",{buffer:"queue",cap:n,droppedCount:t})}else e.queue.length<n&&Q(e.queue);e.status.in++}o||(o=e.destinations);const g=e.transformers?$(e.transformers):{},h=await Promise.all(Object.entries(o||{}).map(async([o,s])=>{var r,i,a,c;if(s.config.disabled)return{id:o,destination:s,skipped:!0};let l=(s.queuePush||[]).map(e=>({...e,consent:d}));s.queuePush=[],t&&l.push((0,y.clone)(t));const u=n.ingest?{...n.ingest,_meta:{...n.ingest._meta,path:[...n.ingest._meta.path]}}:(0,y.createIngest)("unknown");if(!l.length&&!(null==(r=s.queueOn)?void 0:r.length))return{id:o,destination:s,skipped:!0};if(!l.length&&(null==(i=s.queueOn)?void 0:i.length)){let t=!1;try{t=await re(e,s,o)}catch(t){e.status.failed++;const n=s.type||"unknown";e.logger.scope(n).error("destination init failed",{error:t instanceof Error?t.message:String(t)})}return{id:o,destination:s,skipped:!t}}const h=[],m=l.filter(t=>{const n=(0,y.getGrantedConsent)(s.config.consent,d,t.consent);if(n)return t.consent=n,h.push(t),!1;const r=A(e,{stepId:(0,y.stepId)("destination",o),stepType:"destination",phase:"skip",eventId:"string"==typeof t.id?t.id:"",now:Date.now()});return r.skipReason="consent",d&&(r.consent={...d}),s.config.consent&&(r.meta={required:{...s.config.consent}}),(0,y.emitStep)(e,r),!0});if(m.length>0){const t=s.queuePush,n=s.config.id||o,r={max:null!=(a=s.config.queueMax)?a:1e3};let i=0;for(const e of m)i+=J(t,e,r).dropped;if(i>0){te(e,n);const o=ne(e.status,(0,y.stepId)("destination",n),"queue",i);Y(t,e.logger.scope(s.type||"unknown"),"destination.queuePush overflow; oldest events dropped",{buffer:"queuePush",destination:n,cap:r.max,droppedCount:o})}else t.length<r.max&&Q(t)}if(!h.length)return{id:o,destination:s,queue:l};let v,w,b=!1;try{b=await re(e,s,o)}catch(t){e.status.failed++;const n=s.type||"unknown";e.logger.scope(n).error("destination init failed",{error:t instanceof Error?t.message:String(t)})}if(!b)return{id:o,destination:s,queue:l};s.dlq||(s.dlq=[]);const k=oe(s.config.before,g,u),I=s.config.next,S=null==(c=s.config)?void 0:c.cache,C=S?(0,y.compileCache)(S):void 0,q=C?E(C,e):void 0;let x=0,O=0;return await Promise.all(h.map(async t=>{let r;if(t.globals=(0,y.assign)(p,t.globals),t.user=(0,y.assign)(f,t.user),(null==C?void 0:C.stop)&&q){const e=(0,y.buildCacheContext)(u,t),n=await(0,y.checkCache)(C,q,e);if("HIT"===(null==n?void 0:n.status))return t;"MISS"===(null==n?void 0:n.status)&&(r={key:n.key,ttl:n.rule.ttl})}let i=t,a=n.respond;if(k.length>0&&e.transformers&&Object.keys(e.transformers).length>0){const s=await K(e,e.transformers,k,t,u,n.respond,`destination.${o}.before`);if(null===s.event)return t;s.respond&&(a=s.respond),i=Array.isArray(s.event)?s.event[0]:s.event}if(C&&!C.stop&&q){const e=(0,y.buildCacheContext)(u,i),n=await(0,y.checkCache)(C,q,e);if("HIT"===(null==n?void 0:n.status))return t;"MISS"===(null==n?void 0:n.status)&&(r={key:n.key,ttl:n.rule.ttl})}const c=Date.now();let l=!1;const d=await(0,y.tryCatchAsync)(ie,t=>{var n;const r=s.type||"unknown";e.logger.scope(r).error("Push failed",{error:t,event:i.name}),v=t,l=!0;const a=s.dlq,c=s.config.id||o,u={max:null!=(n=s.config.dlqMax)?n:100},d=J(a,[i,t],u);if(d.dropped>0){te(e,c);const t=ne(e.status,(0,y.stepId)("destination",c),"dlq",d.dropped);Y(a,e.logger.scope(s.type||"unknown"),"destination.dlq overflow; oldest entries dropped",{buffer:"dlq",destination:c,cap:u.max,droppedCount:t})}else a.length<u.max&&Q(a)})(e,s,o,i,u,a);if(x+=Date.now()-c,r&&q&&void 0===s.config.mock&&(0,y.storeCache)(q,r.key,null==d||d,r.ttl),void 0===d||Z(d)||(w=d),Z(d)&&O++,!l&&I){void 0!==d&&(u._response=d);const t=oe(I,g,u);if(t.length>0&&e.transformers&&Object.keys(e.transformers).length>0){const n=await K(e,e.transformers,t,i,u,a,`destination.${o}.next`);n.respond&&(a=n.respond)}}return t})),{id:o,destination:s,error:v,response:w,totalDuration:x,batchedCount:O,allowedCount:h.length}})),m={},v={},w={};for(const t of h){if(t.skipped)continue;const n=t.destination,o={type:n.type||"unknown",data:t.response};te(e,t.id);const u=e.status.destinations[t.id],d=Date.now();if(u.queuePushSize=null!=(r=null==(s=n.queuePush)?void 0:s.length)?r:0,u.dlqSize=null!=(a=null==(i=n.dlq)?void 0:i.length)?a:0,t.error)o.error=t.error,w[t.id]=o,u.failed++,u.lastAt=d,u.duration+=t.totalDuration||0,e.status.failed++;else if(t.queue&&t.queue.length)v[t.id]=o;else{const n=null!=(c=t.batchedCount)?c:0,s=null!=(l=t.allowedCount)?l:0;(Math.max(0,s-n)>0||0===s)&&(m[t.id]=o,u.count++,u.lastAt=d,u.duration+=t.totalDuration||0,e.status.out++)}}return ae({event:t,...Object.keys(m).length&&{done:m},...Object.keys(v).length&&{queued:v},...Object.keys(w).length&&{failed:w}})}async function re(e,t,n){var o;if(t.init&&!t.config.init){const s=t.type||"unknown",r=e.logger.scope(s),i={collector:e,logger:r,id:n,config:t.config,env:le(t.env,t.config.env)};r.debug("init");const a=Date.now();let c;(0,y.emitStep)(e,A(e,{stepId:(0,y.stepId)("destination",n),stepType:"destination",phase:"init",eventId:"",now:a}));try{c=await(0,y.useHooks)(t.init,"DestinationInit",e.hooks,e.logger)(i)}catch(t){const o=Date.now(),s=A(e,{stepId:(0,y.stepId)("destination",n),stepType:"destination",phase:"error",eventId:"",now:o});throw s.durationMs=o-a,s.error=t instanceof Error?{name:t.name,message:t.message}:{message:String(t)},(0,y.emitStep)(e,s),t}if(!1===c)return c;if(t.config={...c||t.config,init:!0},null==(o=t.queueOn)?void 0:o.length){const o=t.queueOn;t.queueOn=[];for(const{type:s,data:r}of o)W(e,t,n,s,r)}r.debug("init done")}return!0}async function ie(e,t,n,o,s,r){var i,a,c,l,u,d,p;const{config:f}=t,g=await(0,y.processEventMapping)(o,f,e);if(g.ignore)return!1;const h=t.type||"unknown",m=e.logger.scope(h),v={collector:e,logger:m,id:n,config:f,data:g.data,rule:g.mapping,ingest:s,env:{...le(t.env,f.env),...r?{respond:r}:{}}};if(void 0!==f.mock)return m.debug("mock",{event:g.event.name}),f.mock;const w=g.mapping,b=g.mappingKey||"* *";if((null==w?void 0:w.batch)&&t.pushBatch&&void 0===f.mock){if(t.batches=t.batches||{},!t.batches[b]){const o={key:b,entries:[],events:[],data:[]},s=ee(w.batch),r=ee(f.batch),p=null!=(a=null!=(i=s.wait)?i:r.wait)?a:3e4,g=null!=(l=null!=(c=s.size)?c:r.size)?l:1e3,h=null!=(d=null!=(u=s.age)?u:r.age)?d:3e4,v=le(t.env,f.env),k=(0,y.debounce)(async()=>{var o;const s=t.batches[b].batched;if(0===s.entries.length)return;const r={key:s.key,entries:s.entries,events:s.events,data:s.data};s.entries=[],s.events=[],s.data=[];const i=r.entries[0],a={collector:e,logger:m,id:n,config:f,data:void 0,rule:i.rule,ingest:i.ingest,env:{...v,...i.respond?{respond:i.respond}:{}}};m.debug("push batch",{events:r.entries.length});const c=t.config.id||n,l=te(e,c),u=Date.now(),d=A(e,{stepId:(0,y.stepId)("destination",n),stepType:"destination",phase:"flush",eventId:"",now:u});d.batch={size:r.entries.length,index:0},(0,y.emitStep)(e,d);let p=!0;await(0,y.tryCatchAsync)((0,y.useHooks)(t.pushBatch,"DestinationPushBatch",e.hooks,e.logger),o=>{var s;p=!1;const i=Date.now(),a=A(e,{stepId:(0,y.stepId)("destination",n),stepType:"destination",phase:"error",eventId:"",now:i});a.durationMs=i-u,a.error=o instanceof Error?{name:o.name,message:o.message}:{message:String(o)},a.batch={size:r.entries.length,index:0},(0,y.emitStep)(e,a);const d=t.dlq=t.dlq||[],f={max:null!=(s=t.config.dlqMax)?s:100};let g=0;for(const e of r.entries)g+=J(d,[e.event,o],f).dropped;if(g>0){const t=ne(e.status,(0,y.stepId)("destination",c),"dlq",g);Y(d,m,"destination.dlq overflow; oldest entries dropped",{buffer:"dlq",destination:c,cap:f.max,droppedCount:t})}else d.length<f.max&&Q(d);l.failed+=r.entries.length,l.dlqSize=d.length,e.status.failed+=r.entries.length,m.error("Push batch failed",{error:o instanceof Error?o.message:String(o),entries:r.entries.length})})(r,a),m.debug("push batch done"),l.inFlightBatch=Math.max(0,(null!=(o=l.inFlightBatch)?o:0)-r.entries.length),p&&(l.count+=r.entries.length,l.lastAt=Date.now(),e.status.out+=r.entries.length)},{wait:p,size:g,age:h});t.batches[b]={batched:o,batchFn:()=>{k()},flush:async()=>{await k.flush()}}}const o=t.batches[b];o.batched.entries.push({event:g.event,ingest:s,respond:r,rule:w,data:g.data}),o.batched.events.push(g.event),(0,y.isDefined)(g.data)&&o.batched.data.push(g.data);const h=t.config.id||n,v=te(e,h);return v.inFlightBatch=(null!=(p=v.inFlightBatch)?p:0)+1,o.batchFn(),X}{m.debug("push",{event:g.event.name});const o="string"==typeof g.event.id?g.event.id:"",s=Date.now(),r=A(e,{stepId:(0,y.stepId)("destination",n),stepType:"destination",phase:"in",eventId:o,now:s});g.mappingKey&&(r.mappingKey=g.mappingKey),g.event.consent&&(r.consent={...g.event.consent}),(0,y.emitStep)(e,r);try{const r=await(0,y.useHooks)(t.push,"DestinationPush",e.hooks,e.logger)(g.event,v),i=Date.now(),a=A(e,{stepId:(0,y.stepId)("destination",n),stepType:"destination",phase:"out",eventId:o,now:i});return a.durationMs=i-s,a.outEvent=r,g.mappingKey&&(a.mappingKey=g.mappingKey),(0,y.emitStep)(e,a),m.debug("push done"),r}catch(t){const r=Date.now(),i=A(e,{stepId:(0,y.stepId)("destination",n),stepType:"destination",phase:"error",eventId:o,now:r});throw i.durationMs=r-s,i.error=t instanceof Error?{name:t.name,message:t.message}:{message:String(t)},g.mappingKey&&(i.mappingKey=g.mappingKey),(0,y.emitStep)(e,i),t}}}function ae(e){return{ok:!(null==e?void 0:e.failed),...e}}function ce(e){const{code:t,config:n={},env:o={},cache:s}=e,{config:r}=M(e,"before"),{config:i}=M({...e,config:r},"next"),a={...t.config,...n,...i};s&&(a.cache=s);const c=le(t.env,o);return{...t,config:a,env:c}}function le(e,t){return e||t?t?e&&(0,y.isObject)(e)&&(0,y.isObject)(t)?{...e,...t}:t:e:{}}async function ue(e,t,n){const o=Object.entries(e).map(async([e,o])=>{var s;const r=o.destroy;if(!r)return;const i=o.type||"unknown",a=n.scope(i),c={id:e,config:o.config,env:null!=(s=o.env)?s:{},logger:a};try{await Promise.race([r(c),new Promise((n,o)=>setTimeout(()=>o(new Error(`${t} '${e}' destroy timed out`)),5e3))])}catch(n){a.error(`${t} '${e}' destroy failed: ${n}`)}});await Promise.allSettled(o)}async function de(e,t,n){let o,s,r=!1;switch(t){case D.Config:(0,C.isObject)(n)&&((0,S.assign)(e.config,n,{shallow:!1}),s=n,r=!0);break;case D.Consent:if((0,C.isObject)(n)){const{update:t}=function(e,t){const n={};return Object.entries(t).forEach(([e,t])=>{n[e]=!!t}),e.consent=(0,m.assign)(e.consent,n),{update:n}}(e,n);s=t,r=!0}break;case D.Custom:(0,C.isObject)(n)&&(e.custom=(0,S.assign)(e.custom,n),s=n,r=!0);break;case D.Destination:(0,C.isObject)(n)&&"code"in n&&(0,C.isObject)(n.code)&&(o=await async function(e,t){const{code:n,config:o={},env:s={},before:r,next:i,cache:a}=t;if(!(0,y.isFunction)(n.push))return ae({ok:!1,failed:{invalid:{type:"invalid",error:"Destination code must have a push method"}}});const c=o||{init:!1};let l=r?{...c,before:r}:{...c};i&&(l={...l,next:i}),a&&(l={...l,cache:a});const u={...n,config:l,env:le(n.env,s)};let d=u.config.id;if(!d)do{d=(0,y.getId)(5,"abcdefghijklmnopqrstuvwxyz")}while(e.destinations[d]);return e.destinations[d]=u,!1!==u.config.queue&&(u.queuePush=[...e.queue]),se(e,void 0,{},{[d]:u})}(e,n));break;case D.Globals:(0,C.isObject)(n)&&(e.globals=(0,S.assign)(e.globals,n),s=n,r=!0);break;case D.Hook:if((0,C.isObject)(n)&&(0,S.isString)(n.name)&&(0,S.isFunction)(n.fn)){const{name:t,fn:o}=n;e.hooks[t]=o,s=n,r=!0}break;case D.On:if((0,C.isObject)(n)&&(0,S.isString)(n.type)){const{type:t,rules:o}=n;await async function(e,t,n){const o=e.on,s=o[t]||[],r=(0,w.isArray)(n)?n:[n];r.forEach(e=>{s.push(e)}),o[t]=s,L(e,t,r)}(e,t,o)}break;case D.Ready:r=!0;break;case D.Run:o=await async function(e,t){return e.allowed=!0,e.timing=Date.now(),t&&(t.consent&&(e.consent=(0,S.assign)(e.consent,t.consent)),t.user&&(e.user=(0,S.assign)(e.user,t.user)),t.globals&&(e.globals=(0,S.assign)(e.config.globalsStatic||{},t.globals)),t.custom&&(e.custom=(0,S.assign)(e.custom,t.custom))),Object.values(e.destinations).forEach(e=>{e.queuePush=[]}),e.queue=[],e.round++,await se(e)}(e,n),r=!0;break;case D.Session:r=!0;break;case D.Shutdown:await async function(e){const t=e.logger;await ue(e.sources,"source",t),await ue(e.destinations,"destination",t),await ue(e.transformers,"transformer",t),await ue(e.stores,"store",t)}(e);break;case D.User:(0,C.isObject)(n)&&((0,S.assign)(e.user,n,{shallow:!1}),s=n,r=!0)}return r&&(await async function(e,t,n,o){var s,r;let i,a=n||[];switch(n||(a=e.on[t]||[]),t){case D.Consent:i=o||e.consent;break;case D.Session:i=e.session;break;case D.User:i=o||e.user;break;case D.Custom:i=o||e.custom;break;case D.Globals:i=o||e.globals;break;case D.Config:i=o||e.config;break;case D.Ready:case D.Run:default:i=void 0}let c=!1;for(const[n,o]of Object.entries(e.sources)){if(null==(s=o.config.require)?void 0:s.length){const e=o.config.require.indexOf(t);-1!==e&&o.config.require.splice(e,1)}o.on&&(F(o)?!1===await(0,b.tryCatchAsync)(o.on,o=>G(e,"source",o,{sourceId:n,type:t}))(t,i)&&(c=!0):(o.queueOn=o.queueOn||[],o.queueOn.push({type:t,data:i})))}Object.entries(e.destinations).forEach(([n,o])=>{if(o.on){if(!o.config.init)return o.queueOn=o.queueOn||[],void o.queueOn.push({type:t,data:i});W(e,o,n,t,i)}});for(const[t,n]of Object.entries(e.sources))F(n)&&(null==(r=n.queueOn)?void 0:r.length)&&await R(e,n,t);return Object.keys(e.pending.destinations).length>0&&await async function(e,t){var n;for(const[o,s]of Object.entries(e.pending.destinations)){if(!e.pending.destinations[o]||e.destinations[o])continue;const r=null==(n=s.config)?void 0:n.require;if(!r)continue;const i=r.indexOf(t);if(-1===i)continue;if(r.splice(i,1),r.length>0)continue;delete e.pending.destinations[o];const a=ce(s);!1!==a.config.queue&&(a.queuePush=[...e.queue]),e.destinations[o]=a}}(e,t),L(e,t,a,o),!c}(e,t,void 0,s),o=await se(e)),o||ae({ok:!0})}function pe(e,t){if(!t.name)throw new Error("Event name is required");const[n,o]=t.name.split(" ");if(!n||!o)throw new Error("Event name is invalid");const{timestamp:s=Date.now(),name:r=`${n} ${o}`,data:i={},context:a={},globals:c=e.globals,custom:l={},user:u=e.user,nested:d=[],consent:p=e.consent,id:f=(0,S.getSpanId)(),trigger:g="",entity:h=n,action:m=o,timing:v=0,source:y={type:"collector",schema:"4"}}=t;return{name:r,data:i,context:a,globals:c,custom:l,user:u,nested:d,consent:p,id:f,trigger:g,entity:h,action:m,timestamp:s,timing:v,source:y}}function fe(e={}){var t,n,o;const s=null!=(t=e.maxEntries)?t:1e4,r=null!=(n=e.lowWaterMark)?n:.8,i=null!=(o=e.sweepIntervalMs)?o:6e4,a=Math.floor(s*r),c=new Map,l={hits:0,misses:0,populates:0,writes:0,deletes:0,evictions_entries:0,evictions_ttl:0};let u;return i>0&&(u=setInterval(function(){const e=Date.now();let t=0;for(const[n,o]of c)void 0!==o.expires&&o.expires<=e&&(c.delete(n),t++);l.evictions_ttl+=t},i),u&&"function"==typeof u.unref&&u.unref()),{type:"memory",config:{},get(e){const t=c.get(e);if(t)return void 0!==t.expires&&t.expires<=Date.now()?(c.delete(e),l.evictions_ttl++,void l.misses++):(c.delete(e),c.set(e,t),l.hits++,t.value);l.misses++},set(e,t,n){const o=!c.has(e);o||c.delete(e),c.set(e,{value:t,expires:void 0!==n?Date.now()+n:void 0}),l.writes++,o&&l.populates++,c.size>s&&function(){if(c.size<=s)return;const e=c.size-a;let t=0;for(const n of c.keys()){if(t>=e)break;c.delete(n),t++}l.evictions_entries+=t}()},delete(e){c.delete(e)&&l.deletes++},get counters(){return{...l}},destroy(){void 0!==u&&(clearInterval(u),u=void 0),c.clear()}}}function ge(e,t){const{cacheConfig:n,cacheStore:o,namespace:s,logger:r,storeId:i,collector:a}=t,c=(e,t)=>{if(!a)return;const n=A(a,{stepId:`store.${i}`,stepType:"store",phase:"in",eventId:"",now:Date.now()});n.meta={op:"cache",cached:"hit"===t,status:t,key:e},(0,j.emitStep)(a,n)},l={hits:0,misses:0,populates:0,writes:0,deletes:0,inflight_dedups:0},u=n.rules.map(e=>({match:e.match?(0,j.compileMatcher)(e.match):()=>!0,ttl:e.ttl})),d=e=>`${s}:${e}`;function p(e,t){const n=void 0===t?{key:e}:{key:e,value:t};return u.find(e=>e.match(n))}const f=new Map;return{type:e.type,config:e.config,setup:e.setup,get counters(){return{...l}},async get(t){const n=d(t),s=await o.get(n);if(void 0!==s)return l.hits++,c(t,"hit"),s;const r=f.get(n);if(r)return l.inflight_dedups++,c(t,"hit"),r;l.misses++,c(t,"miss");const i=(async()=>{try{const s=await e.get(t);if(void 0===s)return;const r=p(t,s);if(r)try{await o.set(n,s,1e3*r.ttl),l.populates++}catch(e){g("set",t,e)}return s}finally{f.delete(n)}})();return f.set(n,i),i},async set(t,n,s){l.writes++,await e.set(t,n,s);const r=p(t,n);if(r)try{await o.set(d(t),n,1e3*r.ttl)}catch(e){g("set",t,e)}},async delete(t){l.deletes++,await e.delete(t);try{await o.delete(d(t))}catch(e){g("delete",t,e)}}};function g(e,t,n){const o=`store-cache(${i}): cache ${e} failed for "${t}"; backing succeeded, continuing`;r?r.warn(o,{error:n}):console.warn(o,n)}}function he(e,t,n){const o=`store.${n}`,s=(0,O.useHooks)(t.get,"StoreGet",e.hooks,e.logger),r=(0,O.useHooks)(t.set,"StoreSet",e.hooks,e.logger),i=(0,O.useHooks)(t.delete,"StoreDelete",e.hooks,e.logger);t.get=async t=>{const n=Date.now(),r=A(e,{stepId:o,stepType:"store",phase:"in",eventId:"",now:n});r.meta={op:"get",key:t},(0,O.emitStep)(e,r);try{const r=await s(t),i=Date.now(),a=A(e,{stepId:o,stepType:"store",phase:"out",eventId:"",now:i});return a.durationMs=i-n,a.meta={op:"get",key:t},(0,O.emitStep)(e,a),r}catch(s){const r=Date.now(),i=A(e,{stepId:o,stepType:"store",phase:"error",eventId:"",now:r});throw i.durationMs=r-n,i.meta={op:"get",key:t},i.error=s instanceof Error?{name:s.name,message:s.message}:{message:String(s)},(0,O.emitStep)(e,i),s}},t.set=async(t,n,s)=>{const i=Date.now(),a=A(e,{stepId:o,stepType:"store",phase:"in",eventId:"",now:i});a.meta={op:"set",key:t},(0,O.emitStep)(e,a);try{await r(t,n,s);const a=Date.now(),c=A(e,{stepId:o,stepType:"store",phase:"out",eventId:"",now:a});c.durationMs=a-i,c.meta={op:"set",key:t},(0,O.emitStep)(e,c)}catch(n){const s=Date.now(),r=A(e,{stepId:o,stepType:"store",phase:"error",eventId:"",now:s});throw r.durationMs=s-i,r.meta={op:"set",key:t},r.error=n instanceof Error?{name:n.name,message:n.message}:{message:String(n)},(0,O.emitStep)(e,r),n}},t.delete=async t=>{const n=Date.now(),s=A(e,{stepId:o,stepType:"store",phase:"in",eventId:"",now:n});s.meta={op:"delete",key:t},(0,O.emitStep)(e,s);try{await i(t);const s=Date.now(),r=A(e,{stepId:o,stepType:"store",phase:"out",eventId:"",now:s});r.durationMs=s-n,r.meta={op:"delete",key:t},(0,O.emitStep)(e,r)}catch(s){const r=Date.now(),i=A(e,{stepId:o,stepType:"store",phase:"error",eventId:"",now:r});throw i.durationMs=r-n,i.meta={op:"delete",key:t},i.error=s instanceof Error?{name:s.name,message:s.message}:{message:String(s)},(0,O.emitStep)(e,i),s}}}async function me(e){var t,n;const o=(0,v.assign)({globalsStatic:{},sessionStatic:{},run:!0,queueMax:1e3},e,{merge:!1,extend:!1}),s={level:null==(t=e.logger)?void 0:t.level,handler:null==(n=e.logger)?void 0:n.handler},r=(0,v.createLogger)(s),i={...o.globalsStatic,...e.globals},a={allowed:!1,config:o,consent:e.consent||{},custom:e.custom||{},destinations:{},transformers:{},stores:{},globals:i,hooks:e.hooks||{},observers:new Set,logger:r,on:{},queue:[],round:0,session:void 0,status:{startedAt:Date.now(),in:0,out:0,failed:0,sources:{},destinations:{},dropped:{}},timing:Date.now(),user:e.user||{},sources:{},pending:{destinations:{}},push:void 0,command:void 0};var c,l;a.push=function(e,t){const n=(0,q.useHooks)(async(n,o={})=>await(0,q.tryCatchAsync)(async()=>{var s;const r=Date.now(),{id:i,ingest:a,respond:c,mapping:l,preChain:u,include:d,exclude:p}=o;let f=c,g=n;const h=d||p?function(e,t,n){let o=e;return t&&(o=Object.fromEntries(Object.entries(o).filter(([e])=>t.includes(e)))),n&&(o=Object.fromEntries(Object.entries(o).filter(([e])=>!n.includes(e)))),o}(e.destinations,d,p):void 0,m=null!=a?a:(0,q.createIngest)(i||"unknown");if(l){const t=await(0,q.processEventMapping)(g,l,e);if(t.ignore)return ae({ok:!0});if(l.consent&&!(0,q.getGrantedConsent)(l.consent,e.consent,t.event.consent))return ae({ok:!0});g=t.event}if((null==u?void 0:u.length)&&e.transformers&&Object.keys(e.transformers).length>0){const n=await K(e,e.transformers,u,g,m,f,i?`source.${i}.next`:void 0);if(null===n.event)return ae({ok:!0});if(n.stopped)return n.respond&&(f=n.respond),ae({ok:!0});if(n.respond&&(f=n.respond),Array.isArray(n.event)){const o=await Promise.all(n.event.map(async n=>{const o=t(n),s=pe(e,o);return se(e,s,{id:i,ingest:m,respond:f},h)}));if(i){e.status.sources[i]||(e.status.sources[i]={count:0,duration:0});const t=e.status.sources[i];t.count+=n.event.length,t.lastAt=Date.now(),t.duration+=Date.now()-r}return null!=(s=o[0])?s:ae({ok:!0})}g=n.event}const v=t(g),y=pe(e,v),w=await se(e,y,{id:i,ingest:m,respond:f},h);if(i){e.status.sources[i]||(e.status.sources[i]={count:0,duration:0});const t=e.status.sources[i];t.count++,t.lastAt=Date.now(),t.duration+=Date.now()-r}return w},t=>{if(t instanceof q.FatalError)throw t;return e.status.failed++,e.logger.error("push failed",{event:n,ingest:o.ingest,error:t}),ae({ok:!1})})(),"Push",e.hooks,e.logger);return async(t,o)=>{const s="string"==typeof t.id?t.id:"",r=Date.now();(0,q.emitStep)(e,A(e,{stepId:"collector.push",stepType:"collector",phase:"in",eventId:s,now:r}));try{const i=await n(t,o),a=Date.now(),c=A(e,{stepId:"collector.push",stepType:"collector",phase:"out",eventId:s,now:a});return c.durationMs=a-r,c.outEvent=i,(0,q.emitStep)(e,c),i}catch(t){const n=Date.now(),o=A(e,{stepId:"collector.push",stepType:"collector",phase:"error",eventId:s,now:n});throw o.durationMs=n-r,o.error=t instanceof Error?{name:t.name,message:t.message}:{message:String(t)},(0,q.emitStep)(e,o),t}}}(a,e=>({timing:Math.round((Date.now()-a.timing)/10)/100,source:{type:"collector",schema:"4",version:"4.1.3-next-1779963694449"},...e})),a.command=(c=a,l=de,(0,x.useHooks)(async(e,t,n)=>await(0,x.tryCatchAsync)(async()=>await l(c,e,t,n),n=>{if(n instanceof x.FatalError)throw n;return c.status.failed++,c.logger.error("command failed",{command:e,data:t,error:n}),ae({ok:!1})})(),"Command",c.hooks,c.logger));const u=e.stores||{};return a.stores=await async function(e,t={}){var n;const o={};for(const[n,s]of Object.entries(t)){const{code:t,config:r={},env:i={}}=s,a=e.logger.scope("store").scope(n),c={collector:e,logger:a,id:n,config:r,env:i},l=await t(c);o[n]=l}const s=t,r=function(e){const t={};for(const n of Object.keys(e))t[n]="WHITE";const n=[],o=[];function s(r){var i;const a=t[r];if("BLACK"===a)return;if("GRAY"===a){const e=o.indexOf(r),t=o.slice(-1===e?0:e).concat(r).join(" -> ");throw new Error(`Cycle in cache.store chain: ${t}`)}t[r]="GRAY",o.push(r);const c=null==(i=e[r].cache)?void 0:i.store;if(void 0!==c){if(!(c in e))throw new Error(`Store "${r}" cache.store references "${c}", which is not declared in flow.stores`);s(c)}o.pop(),t[r]="BLACK",n.push(r)}for(const n of Object.keys(e))"WHITE"===t[n]&&s(n);return n}(s);for(const t of r){const r=s[t].cache;if(!r)continue;let i,a;void 0!==r.store?(i=o[r.store],a=r.store):(o.__cache||(o.__cache=fe()),i=o.__cache,a="__cache");const c=null!=(n=r.namespace)?n:t;e.logger.scope("store-cache").scope(t).info(`store "${t}" caches with namespace "${c}:" via ${a}`),o[t]=ge(o[t],{storeId:t,cacheConfig:r,cacheStore:i,namespace:c,logger:e.logger.scope("store-cache").scope(t),collector:e})}for(const[t,n]of Object.entries(o))"__cache"!==t&&he(e,n,t);return o}(a,u),function(e,t,n){const o=new Map;for(const[n,s]of Object.entries(e))t[n]&&o.set(s,t[n]);if(0!==o.size)for(const e of[n.transformers,n.destinations,n.sources])if(e)for(const t of Object.values(e))s(t.env);function s(e){if(e)for(const[t,n]of Object.entries(e))if("object"==typeof n&&null!==n){const s=o.get(n);s&&(e[t]=s)}}}(u,a.stores,e),a.stores.__cache||(a.stores.__cache=fe()),a.destinations=await async function(e,t={}){var n,o;const s={};for(const[r,i]of Object.entries(t))(null==(o=null==(n=i.config)?void 0:n.require)?void 0:o.length)?e.pending.destinations[r]=i:s[r]=ce(i);return s}(a,e.destinations||{}),a.transformers=await async function(e,t={}){var n,o,s,r;const i={};for(const[a,c]of Object.entries(t)){const{code:t,env:l={}}=c,u=(0,I.validateStepEntry)(c,"Transformer");if(!u.ok){e.logger.warn(`Transformer ${a} invalid (${u.code}): ${u.reason}. Skipping.`);continue}const{config:d}=M(c,"before"),{config:p}=M({...c,config:d},"next"),f=Object.keys(l).length>0?{...p,env:l}:p,{cache:g}=c,h=g?{...f,cache:g}:f,m=e.logger.scope("transformer").scope(a),v={collector:e,logger:m,id:a,ingest:(0,I.createIngest)(a),config:h,env:l},y=null!=t?t:e=>{const t=c.mapping;if(t){const n=[];if(void 0!==t.data&&n.push("data"),t.mapping)for(const[e,o]of Object.entries(t.mapping))if("object"==typeof o&&null!==o)for(const[t,s]of Object.entries(o)){if("object"!=typeof s||null===s)continue;const o=s;void 0!==o.data&&n.push(`mapping[${e}][${t}].data`),void 0!==o.silent&&n.push(`mapping[${e}][${t}].silent`)}return n.length>0&&e.collector.logger.warn(`Transformer ${a}: \`${n.join(", ")}\` ignored at transformer position (only event-mutating fields apply).`),{type:"pass",config:e.config,push:async n=>{const o=await(0,I.processEventMapping)(n,t,e.collector);return!o.ignore&&{event:o.event}}}}return{type:"pass",config:e.config,push:e=>({event:e})}},w=await y(v);void 0!==c.before&&void 0===(null==(n=w.config)?void 0:n.before)&&(w.config={...null!=(o=w.config)?o:{},before:c.before}),void 0!==c.next&&void 0===(null==(s=w.config)?void 0:s.next)&&(w.config={...null!=(r=w.config)?r:{},next:c.next}),i[a]=w}return i}(a,e.transformers||{}),a}async function ve(e){e=e||{};const t=await me(e),n=(o=t,{type:"elb",config:{},push:async(e,t,n,s,r)=>{if("string"==typeof e&&e.startsWith("walker ")){const n=e.replace("walker ","");return o.command(n,t)}let i;if("string"==typeof e)i={name:e},t&&"object"==typeof t&&!Array.isArray(t)&&(i.data=t);else{if(!e||"object"!=typeof e)return ae({ok:!1});i=e,t&&"object"==typeof t&&!Array.isArray(t)&&(i.data={...i.data||{},...t})}return n&&"object"==typeof n&&(i.context=n),s&&Array.isArray(s)&&(i.nested=s),r&&"object"==typeof r&&(i.custom=r),o.push(i)}});var o;t.sources.elb=n,await async function(e,t={}){var n;const o={};for(const[s,r]of Object.entries(t)){const t=await B(e,s,r);if(!t)continue;const i=null==(n=r.config)?void 0:n.require;t.config={...t.config,init:!1,...i?{require:[...i]}:{}},o[s]=t}Object.assign(e.sources,o);for(const t of Object.keys(o)){const n=e.sources[t];let o=!1;n.init&&await(0,k.tryCatchAsync)(n.init.bind(n),n=>{if(n instanceof k.FatalError)throw n;o=!0,e.status.failed++,e.logger.scope("source").error("source init failed",{sourceId:t,error:n})})(),o||(n.config.init=!0,F(n)&&await R(e,n,t))}return o}(t,e.sources||{});const{consent:s,user:r,globals:i,custom:a}=e;s&&await t.command("consent",s),r&&await t.command("user",r),i&&Object.assign(t.globals,i),a&&Object.assign(t.custom,a),t.config.run&&await t.command("run");let c=n.push;const l=Object.values(t.sources).filter(e=>"elb"!==e.type),u=l.find(e=>e.config.primary);return u?c=u.push:l.length>0&&(c=l[0].push),{collector:t,elb:c}}var ye=async e=>{let t;return{get flow(){return t},trigger:(n,o)=>async n=>{var s,r,i,a,c,l,u,d,p;const f=o||{};if(f.url){const e=new URL(f.url);window.history.replaceState({},"",e.pathname+e.search)}if(f.referrer&&Object.defineProperty(document,"referrer",{value:f.referrer,configurable:!0}),f.sessionData){const e=f.sessionKey||"elbSessionId";localStorage.setItem(e,JSON.stringify(f.sessionData))}if(f.deviceId){const e=f.deviceKey||"elbDeviceId";localStorage.setItem(e,f.deviceId)}if(!t){const n=await ve({...e,run:null==(s=e.run)||s});t={collector:n.collector,elb:n.elb};const o=f.sessionKey||(null==(c=null==(a=null==(i=null==(r=e.sources)?void 0:r.session)?void 0:i.config)?void 0:a.settings)?void 0:c.sessionKey)||"elbSessionId",g=f.deviceKey||(null==(p=null==(d=null==(u=null==(l=e.sources)?void 0:l.session)?void 0:u.config)?void 0:d.settings)?void 0:p.deviceKey)||"elbDeviceId";localStorage.removeItem(o),localStorage.removeItem(g),f.sessionData&&localStorage.setItem(o,JSON.stringify(f.sessionData)),f.deviceId&&localStorage.setItem(g,f.deviceId),e.consent&&await t.collector.command("consent",e.consent)}}}},we=(e,t)=>{if(!e||"object"!=typeof e)return;const n=e,o=t.localStorage;if(n.sessionData&&"object"==typeof n.sessionData){const e="string"==typeof n.sessionKey?n.sessionKey:"elbSessionId";o.setItem(e,JSON.stringify(n.sessionData))}if("string"==typeof n.deviceId){const e="string"==typeof n.deviceKey?n.deviceKey:"elbDeviceId";o.setItem(e,n.deviceId)}};//# sourceMappingURL=dev.js.map
1
+ "use strict";var e,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,o=Object.getOwnPropertyNames,s=Object.prototype.hasOwnProperty,r=(e,n)=>{for(var o in n)t(e,o,{get:n[o],enumerable:!0})},i={};r(i,{examples:()=>p,schemas:()=>a}),module.exports=(e=i,((e,r,i,a)=>{if(r&&"object"==typeof r||"function"==typeof r)for(let c of o(r))s.call(e,c)||c===i||t(e,c,{get:()=>r[c],enumerable:!(a=n(r,c))||a.enumerable});return e})(t({},"__esModule",{value:!0}),e));var a={};r(a,{SettingsSchema:()=>u,settings:()=>d});var c=require("@walkeros/core/dev"),l=require("@walkeros/core/dev"),u=l.z.object({storage:l.z.boolean().default(!1).describe("Enable persistent storage for session/device IDs").optional(),consent:l.z.union([l.z.string(),l.z.array(l.z.string())]).describe("Consent key(s) required to enable storage mode").optional(),length:l.z.number().default(30).describe("Session timeout in minutes").optional(),pulse:l.z.boolean().default(!1).describe("Keep session alive on each event").optional(),sessionKey:l.z.string().default("elbSessionId").describe("Storage key for session ID").optional(),sessionStorage:l.z.enum(["local","session"]).default("local").describe("Storage type for session").optional(),deviceKey:l.z.string().default("elbDeviceId").describe("Storage key for device ID").optional(),deviceStorage:l.z.enum(["local","session"]).default("local").describe("Storage type for device").optional(),deviceAge:l.z.number().default(30).describe("Device ID age in days").optional(),cb:l.z.any().describe("Custom session callback function or false to disable").optional(),clickIds:l.z.array(l.ClickIdEntrySchema).describe("Custom click-ID registry. Entries with a `param` matching a default override the platform name in place; new params append to the end of the priority list.").optional()}),d=(0,c.zodToSchema)(u),p={};r(p,{createTrigger:()=>qe,step:()=>f,trigger:()=>Oe});var f={};r(f,{newMarketingSession:()=>g,returningVisitor:()=>h});var g={title:"New marketing session",description:"A visit with UTM parameters starts a new session and emits walker user, session, and session start calls.",trigger:{type:"load",options:{url:"https://example.com/?utm_source=google&utm_medium=cpc&utm_campaign=winter-sale"}},in:{storage:!0},out:[["elb","user",{session:"s3ss10n-id",device:"d3v1c3-id"}],["elb","session",{id:"s3ss10n-id",start:17e11,isNew:!0,count:1,runs:1,marketing:!0,source:"google",medium:"cpc",campaign:"winter-sale",referrer:"",device:"d3v1c3-id",isStart:!0,storage:!0,updated:17e11}],["elb",{name:"session start",data:{id:"s3ss10n-id",start:17e11,isNew:!0,count:1,runs:1,marketing:!0,source:"google",medium:"cpc",campaign:"winter-sale",referrer:"",device:"d3v1c3-id",isStart:!0,storage:!0,updated:17e11}}]]},h={title:"Returning visitor",description:"A returning visit with a google referrer reuses the stored device id and increments the session count.",trigger:{type:"load",options:{referrer:"https://google.com"}},in:{storage:!0},out:[["elb","user",{session:"n3w-s3ss10n",device:"d3v1c3-id"}],["elb","session",{id:"n3w-s3ss10n",start:1700001e6,isNew:!1,count:3,runs:1,referrer:"google.com",device:"d3v1c3-id",isStart:!0,storage:!0,updated:1700001e6}],["elb",{name:"session start",data:{id:"n3w-s3ss10n",start:1700001e6,isNew:!1,count:3,runs:1,referrer:"google.com",device:"d3v1c3-id",isStart:!0,storage:!0,updated:1700001e6}}]]},m=require("@walkeros/core"),v=require("@walkeros/core"),y=require("@walkeros/core"),w=(require("@walkeros/core"),require("@walkeros/core")),b=require("@walkeros/core"),k=require("@walkeros/core"),I=require("@walkeros/core"),S=require("@walkeros/core"),C=require("@walkeros/core"),q=require("@walkeros/core"),O=require("@walkeros/core"),x=require("@walkeros/core"),j=require("@walkeros/core"),D={Action:"action",Actions:"actions",Config:"config",Consent:"consent",Context:"context",Custom:"custom",Destination:"destination",Elb:"elb",Globals:"globals",Hook:"hook",Init:"init",Link:"link",On:"on",Prefix:"data-elb",Ready:"ready",Run:"run",Session:"session",Shutdown:"shutdown",User:"user",Walker:"walker"};function A(e,t){const n=e.status.startedAt;return{flowId:"default",stepId:t.stepId,stepType:t.stepType,phase:t.phase,eventId:t.eventId,timestamp:new Date(t.now).toISOString(),elapsedMs:t.now-n}}function E(e,t){return e.storeId&&t.stores[e.storeId]?t.stores[e.storeId]:t.stores.__cache}function M(e,t){return e?t.stores[e]:t.stores.__cache}function $(e){var t;const n={};for(const[o,s]of Object.entries(e)){const e=null==(t=s.config)?void 0:t.next;"string"==typeof e||Array.isArray(e)&&e.every(e=>"string"==typeof e)?n[o]={next:e}:n[o]={}}return n}function _(e,t){const n=e.config||{},o=e[t];return void 0!==o?{config:{...n,[t]:o},chainValue:o}:{config:n,chainValue:void 0}}function T(e,t={}){if(!e)return[];if(Array.isArray(e))return e;const n=[],o=new Set;let s=e;for(;s&&t[s]&&!o.has(s);){o.add(s),n.push(s);const e=t[s].next;if(Array.isArray(e)){n.push(...e);break}s=e}return n}async function P(e,t,n){if(t.init&&!t.config.init){const o=t.type||"unknown",s=e.logger.scope(`transformer:${o}`),r={collector:e,logger:s,id:n,ingest:(0,I.createIngest)(n),config:t.config,env:N(t.config.env)};s.debug("init");const i=await(0,I.useHooks)(t.init,"TransformerInit",e.hooks,e.logger)(r);if(!1===i)return!1;t.config={...i||t.config,env:(null==i?void 0:i.env)||t.config.env,init:!0},s.debug("init done")}return!0}async function z(e,t,n,o,s,r){const i=t.type||"unknown",a=e.logger.scope(`transformer:${i}`),c={collector:e,logger:a,id:n,ingest:s,config:t.config,env:{...N(t.config.env),...r?{respond:r}:{}}};a.debug("push",{event:o.name});const l="string"==typeof o.id?o.id:"",u=Date.now(),d=A(e,{stepId:(0,I.stepId)("transformer",n),stepType:"transformer",phase:"in",eventId:l,now:u});(0,I.emitStep)(e,d);try{const s=await(0,I.useHooks)(t.push,"TransformerPush",e.hooks,e.logger)(o,c),r=Date.now(),i=A(e,{stepId:(0,I.stepId)("transformer",n),stepType:"transformer",phase:"out",eventId:l,now:r});return i.durationMs=r-u,i.outEvent=s,(0,I.emitStep)(e,i),a.debug("push done"),s}catch(t){const o=Date.now(),s=A(e,{stepId:(0,I.stepId)("transformer",n),stepType:"transformer",phase:"error",eventId:l,now:o});throw s.durationMs=o-u,s.error=t instanceof Error?{name:t.name,message:t.message}:{message:String(t)},(0,I.emitStep)(e,s),t}}function K(e,t){return e?{...e,_meta:{...e._meta,path:[...e._meta.path]}}:(0,I.createIngest)(t)}async function H(e,t,n,o,s,r,i){var a,c,l,u,d,p,f,g,h;s||(s=(0,I.createIngest)(null!=(a=n[0])?a:"chain")),i&&s._meta&&(s._meta.chainPath=i);let m=o,v=r;for(const o of n){const r=t[o];if(!r){e.logger.warn(`Transformer not found: ${o}`);continue}if(s&&s._meta&&s._meta.path.length>256)return e.logger.error(`Max path length exceeded at ${o}`),{event:null,respond:v};if(s&&s._meta&&(s._meta.hops++,s._meta.path.push(o)),!await(0,I.tryCatchAsync)(P,t=>{if(t instanceof I.FatalError)throw t;return e.status.failed++,e.logger.scope(`transformer:${r.type||"unknown"}`).error("transformer init failed",{transformer:o,error:t}),!1})(e,r,o))return{event:null,respond:v};if(i&&void 0!==(null==(l=null==(c=r.config)?void 0:c.chainMocks)?void 0:l[i])){const t=r.config.chainMocks[i];e.logger.scope(`transformer:${r.type||"unknown"}`).debug("chainMock",{chain:i}),m=t;continue}if(void 0!==(null==(u=r.config)?void 0:u.mock)){e.logger.scope(`transformer:${r.type||"unknown"}`).debug("mock"),m=r.config.mock;continue}if(null==(d=r.config)?void 0:d.disabled)continue;const a=null==(p=r.config)?void 0:p.cache,y=a?(0,I.compileCache)(a):void 0,w=y?E(y,e):void 0,b=(null==(f=r.config)?void 0:f.state)?(0,I.compileState)(r.config.state):void 0,k=null==b?void 0:b.filter(e=>"get"===e.mode),S=null==b?void 0:b.filter(e=>"set"===e.mode),C=async t=>S&&0!==S.length?(0,I.applyState)(S,t=>M(t,e),t,e):t;let q;if(y&&w){const e=(0,I.buildCacheContext)(s,m),t=await(0,I.checkCache)(y,w,e);if("HIT"===(null==t?void 0:t.status)&&t.value){if(m=t.value,y.stop)return{event:m,respond:v,stopped:!0};continue}"MISS"===(null==t?void 0:t.status)&&(q={key:t.key,ttl:t.rule.ttl})}const O=r.config.before;if(O){const n=(0,I.getNextSteps)(O,(0,I.buildCacheContext)(s,m));if(1===n.length){const o=T(n[0],$(t));if(o.length>0){const n=await H(e,t,o,m,s,v,i);if(null===n.event)return{event:null,respond:null!=(g=n.respond)?g:v};if(n.stopped)return{event:Array.isArray(n.event)?n.event[0]:n.event,respond:null!=(h=n.respond)?h:v,stopped:!0};n.respond&&(v=n.respond),m=Array.isArray(n.event)?n.event[0]:n.event}}else n.length>1&&await Promise.all(n.map(n=>(0,I.tryCatchAsync)(H,t=>(e.logger.scope("transformer:many").error(`many branch ${n} failed`,{error:t}),{event:null,respond:void 0}))(e,t,T(n,$(t)),m,K(s,n),void 0,i)))}k&&k.length>0&&(m=await(0,I.applyState)(k,t=>M(t,e),m,e));const x=await(0,I.tryCatchAsync)(z,t=>(e.logger.scope(`transformer:${r.type||"unknown"}`).error("Push failed",{error:t}),!1))(e,r,o,m,s,v);if(!1===x)return{event:null,respond:v};if(Array.isArray(x)){const r=n.slice(n.indexOf(o)+1),a=await Promise.all(x.map(async n=>{const o=await C(n.event||m),a=K(s,"unknown");if(n.next){const s=(0,I.getNextSteps)(n.next,(0,I.buildCacheContext)(a,o));if(0===s.length)return{event:o,respond:v};if(1===s.length){const n=T(s[0],$(t));return n.length>0?H(e,t,n,o,a,v,i):{event:o,respond:v}}return(await Promise.all(s.map(n=>(0,I.tryCatchAsync)(H,t=>(e.logger.scope("transformer:many").error(`many branch ${n} failed`,{error:t}),{event:null,respond:void 0}))(e,t,T(n,$(t)),o,K(a,n),void 0,i)))).map(e=>({event:e.event,respond:void 0}))}return r.length>0?H(e,t,r,o,a,v,i):{event:o,respond:v}}));let c=v;const l=[];for(const e of a.flat())if(null!==e)if(e&&"object"==typeof e&&"event"in e){const t=e;if(t.respond&&(c=t.respond),null===t.event)continue;Array.isArray(t.event)?l.push(...t.event):l.push(t.event)}else l.push(e);return 0===l.length?{event:null,respond:c}:1===l.length?{event:l[0],respond:c}:{event:l,respond:c}}if(x&&"object"==typeof x){const{event:n,respond:o,next:r}=x;if(o&&(v=o),void 0!==r){const o=await C(n||m),a=(0,I.getNextSteps)(r,(0,I.buildCacheContext)(s,o));if(0===a.length){m=o;continue}if(1===a.length){const n=T(a[0],$(t));return n.length>0?H(e,t,n,o,s,v,i):(e.logger.warn(`Branch target not found: ${JSON.stringify(r)}`),{event:null,respond:v})}return await Promise.all(a.map(n=>(0,I.tryCatchAsync)(H,t=>(e.logger.scope("transformer:many").error(`many branch ${n} failed`,{error:t}),{event:null,respond:void 0}))(e,t,T(n,$(t)),o,K(s,n),void 0,i))),{event:null,respond:void 0}}n&&(m=n)}S&&S.length>0&&(m=await(0,I.applyState)(S,t=>M(t,e),m,e)),q&&w&&(0,I.storeCache)(w,q.key,m,q.ttl);const j=r.config.next,D="string"==typeof j||Array.isArray(j)&&j.every(e=>"string"==typeof e),A=void 0!==j&&!D;if((!x||"object"==typeof x&&!x.next)&&A){const n=(0,I.getNextSteps)(r.config.next,(0,I.buildCacheContext)(s,m));if(1===n.length){const o=T(n[0],$(t));return o.length>0?H(e,t,o,m,s,v,i):{event:m,respond:v}}return n.length>1?(await Promise.all(n.map(n=>(0,I.tryCatchAsync)(H,t=>(e.logger.scope("transformer:many").error(`many branch ${n} failed`,{error:t}),{event:null,respond:void 0}))(e,t,T(n,$(t)),m,K(s,n),void 0,i))),{event:null,respond:void 0}):{event:m,respond:v}}}return{event:m,respond:v}}function N(e){return e&&(0,I.isObject)(e)?e:{}}function R(e){return"string"==typeof e||!(!Array.isArray(e)||!e.every(e=>"string"==typeof e))}async function F(e,t,n){var o,s;if(!t.on||!(null==(o=t.queueOn)?void 0:o.length))return;const r=t.queueOn;t.queueOn=[];const i=n||(null==(s=t.config)?void 0:s.id)||"unknown";for(const{type:n,data:o}of r)U(n)&&!L(e,t)||(await(0,k.tryCatchAsync)(t.on,t=>{if(t instanceof k.FatalError)throw t;e.status.failed++,e.logger.scope("source").error("source on flush failed",{sourceId:i,type:n,error:t})})(n,o),U(n)&&W(e,t))}function V(e){var t;return Boolean(e.config.init)&&!(null==(t=e.config.require)?void 0:t.length)}async function B(e,t,n){var o,s;const{code:r,config:i={},env:a={},primary:c,next:l,before:u,cache:d}=n,p=null!=(o=i.state)?o:n.state,f=p?(0,k.compileState)(p):void 0,g=d,h=g?(0,k.compileCache)({...g,stop:null==(s=g.stop)||s}):void 0,m=R(l)?T(l,$(e.transformers)):void 0,v=R(u)?T(u,$(e.transformers)):void 0,y=a.push,w=null!=y?y:e.push,b=Boolean(y),I=async(n,o,s)=>{var r;let a;const c=null!=v?v:void 0!==u?(()=>{const t=(0,k.getNextSteps)(u,(0,k.buildCacheContext)(s.ingest));return 0===t.length?[]:T(1===t.length?t[0]:t,$(e.transformers))})():[];let d=[n];if(c.length>0&&e.transformers&&Object.keys(e.transformers).length>0){const o=await H(e,e.transformers,c,n,s.ingest,s.respond,`source.${t}.before`);if(null===o.event)return{ok:!0};if(o.stopped)return o.respond&&(s.respond=o.respond),{ok:!0};o.respond&&(s.respond=o.respond),d=Array.isArray(o.event)?o.event:[o.event]}if(h){const t=E(h,e);if(t){const n=(0,k.buildCacheContext)(s.ingest),o=await(0,k.checkCache)(h,t,n);if(o){if("HIT"===o.status&&void 0!==o.value&&h.stop){let t=o.value;return o.rule.update&&(t=await(0,k.applyUpdate)(t,o.rule.update,{...n,cache:{status:"HIT"}},e)),null==(r=s.respond)||r.call(s,t),{ok:!0}}if("MISS"===o.status&&h.stop&&s.respond){const r=s.respond,i=o.rule.update,c={...n,cache:{status:"MISS"}},l=o.key,u=o.rule.ttl,d=n=>{(0,k.storeCache)(t,l,n,u),i?a=(async()=>{const t=await(0,k.applyUpdate)(n,i,c,e);r(t)})():r(n)};s.respond=d}"MISS"!==o.status||h.stop||(0,k.storeCache)(t,o.key,!0,o.rule.ttl)}}}const p=m?{kind:"single",preChain:m}:void 0!==l?(()=>{const t=(0,k.getNextSteps)(l,(0,k.buildCacheContext)(s.ingest));return 0===t.length?{kind:"single",preChain:[]}:1===t.length?{kind:"single",preChain:T(t[0],$(e.transformers))}:{kind:"many",branches:t.map(t=>T(t,$(e.transformers)))}})():{kind:"single",preChain:[]};!b&&f&&f.length>0&&(d=await Promise.all(d.map(t=>(0,k.applyState)(f,t=>M(t,e),t,e))));let g={ok:!0};for(const n of d)"many"===p.kind?(await Promise.all(p.branches.map((r,a)=>(0,k.tryCatchAsync)(async()=>b?w(n):w(n,{...o,id:t,ingest:K(s.ingest,`${t}.${a}`),respond:void 0,mapping:i,preChain:r}),t=>(e.logger.scope("source:many").error(`many branch ${a} failed`,{error:t}),{ok:!0}))())),g={ok:!0}):g=b?await w(n):await w(n,{...o,id:t,ingest:s.ingest,respond:s.respond,mapping:i,preChain:p.preChain});return a&&await a,g},S=async n=>{const o=(0,k.createIngest)(t);if(!i.ingest||void 0===n)return o;const s=await(0,k.getMappingValue)(n,i.ingest,{collector:e});return{...o,...s,_meta:o._meta}},C=e.logger.scope("source").scope(t),q={command:e.command,sources:e.sources,elb:e.sources.elb.push,logger:C,...a,push:async(e,n={})=>{const o={ingest:(0,k.createIngest)(t),respond:void 0};return I(e,n,o)}},O={collector:e,logger:C,id:t,config:i,env:q,withScope:async(e,t,n)=>{const o={ingest:await S(e),respond:t};return n({...q,push:(e,t={})=>I(e,t,o),ingest:o.ingest,respond:o.respond})}},x=await(0,k.tryCatchAsync)(r,n=>{if(n instanceof k.FatalError)throw n;e.status.failed++,e.logger.scope("source").error("source factory failed",{sourceId:t,error:n})})(O);if(!x)return;const j=x.type||"unknown",D=e.logger.scope(j).scope(t);return q.logger=D,c&&(x.config={...x.config,primary:c}),x}function G(e,t,n,o){if(n instanceof w.FatalError)throw n;e.logger.scope("on").error("on callback failed",{kind:t,...o,error:n})}function U(e){return e===D.Consent||e===D.User||e===D.Globals||e===D.Custom}function W(e,t){e.delivery.set(t,e.stateVersion)}function L(e,t){return e.allowed&&e.stateVersion>function(e,t){const n=e.delivery.get(t);return void 0===n?-1:n}(e,t)}function J(e,t,n){const o=e.cascade;if(!o)return!0;let s=o.counts.get(t);s||(s={},o.counts.set(t,s));const r=String(n),i=(s[r]||0)+1;return s[r]=i,i<=8||(9===i&&e.logger.error("state delivery did not converge",{type:r}),!1)}function Y(e,t){return{collector:e,logger:e.logger.scope("on").scope(String(t))}}function Q(e,t,n,o,s){if(!t.on)return;const r=t.type||"unknown",i=e.logger.scope(r).scope("on").scope(o),a={collector:e,logger:i,id:n,config:t.config,data:s,env:me(t.env,t.config.env)};(0,b.tryCatch)(t.on,t=>G(e,"destination",t,{destId:n,type:o}))(o,a)}function X(e,t,n,o){let s;switch(t){case D.Consent:s=o||e.consent;break;case D.Session:s=e.session;break;case D.User:s=o||e.user;break;case D.Custom:s=o||e.custom;break;case D.Globals:s=o||e.globals;break;case D.Config:s=o||e.config;break;case D.Ready:case D.Run:default:s=void 0}if(n.length)switch(t){case D.Consent:!function(e,t,n){const o=n||e.consent,s=Y(e,D.Consent);t.forEach(t=>{L(e,t)&&J(e,t,D.Consent)&&(Object.keys(o).filter(e=>e in t).forEach(n=>{(0,b.tryCatch)(t[n],t=>G(e,"consent",t,{key:n}))(o,s)}),W(e,t))})}(e,n,o);break;case D.Ready:!function(e,t){if(!e.allowed)return;const n=Y(e,D.Ready);t.forEach(t=>{(0,b.tryCatch)(t,t=>G(e,"ready",t))(void 0,n)})}(e,n);break;case D.Run:!function(e,t){if(!e.allowed)return;const n=Y(e,D.Run);t.forEach(t=>{(0,b.tryCatch)(t,t=>G(e,"run",t))(void 0,n)})}(e,n);break;case D.Session:!function(e,t){if(!e.session)return;const n=Y(e,D.Session);t.forEach(t=>{(0,b.tryCatch)(t,t=>G(e,"session",t))(e.session,n)})}(e,n);break;default:{const o=Y(e,t),r=U(t);n.forEach(n=>{"function"==typeof n&&(r&&!L(e,n)||r&&!J(e,n,t)||((0,b.tryCatch)(n,n=>G(e,"generic",n,{type:t}))(s,o),r&&W(e,n)))});break}}}function Z(e,t,n){switch(t){case D.Consent:return n||e.consent;case D.Session:return e.session;case D.User:return n||e.user;case D.Custom:return n||e.custom;case D.Globals:return n||e.globals;case D.Config:return n||e.config;default:return}}async function ee(e,t,n,o,s){if(!t.on)return!1;if(U(o)&&!L(e,t))return!1;if(U(o)&&!J(e,t,o))return!1;const r=await(0,b.tryCatchAsync)(t.on,t=>G(e,"source",t,{sourceId:n,type:o}))(o,s);return U(o)&&W(e,t),!1===r}function te(e,t,n,o){var s;if(!Number.isFinite(n.max)||n.max<=0)throw new Error(`pushBounded: max must be > 0 (got ${n.max})`);if("dropNewest"===(null!=(s=n.onOverflow)?s:"dropOldest"))return e.length>=n.max?(o&&o([t]),{appended:!1,dropped:1}):(e.push(t),{appended:!0,dropped:0});const r=[];for(;e.length>=n.max;)r.push(e.shift());return e.push(t),r.length>0&&o&&o(r),{appended:!0,dropped:r.length}}var ne=new WeakMap;function oe(e,t,n,o){ne.get(e)||(ne.set(e,!0),t.warn(n,o))}function se(e){ne.delete(e)}var re=Object.freeze({batched:!0});function ie(e){return e===re}function ae(e){return void 0===e?{}:"number"==typeof e?{wait:e}:{wait:e.wait,size:e.size,age:e.age}}function ce(e,t){return e.status.destinations[t]||(e.status.destinations[t]={count:0,failed:0,duration:0,queuePushSize:0,dlqSize:0}),e.status.destinations[t]}function le(e,t,n,o){var s;e.dropped[t]||(e.dropped[t]={});const r=e.dropped[t];return r[n]=(null!=(s=r[n])?s:0)+o,r[n]}function ue(e,t,n){if(!e)return[];if(Array.isArray(e)&&e.every(e=>"string"==typeof e))return T(e,t);if("string"==typeof e)return T(e,t);const o=(0,y.getNextSteps)(e,(0,y.buildCacheContext)(n));return 0===o.length?[]:1===o.length?T(o[0],t):T(o,t)}async function de(e,t,n={},o){var s,r,i,a,c,l;const{allowed:u,consent:d,globals:p,user:f}=e;if(!u)return ge({ok:!1});if(t){const n=e.config.queueMax;if(void 0===n)throw new Error("Collector.Config.queueMax is undefined; defaults must be seeded by collector()");const o=te(e.queue,t,{max:n});if(o.dropped>0){const t=le(e.status,(0,y.stepId)("collector"),"queue",o.dropped);oe(e.queue,e.logger,"collector.queue overflow; oldest events dropped",{buffer:"queue",cap:n,droppedCount:t})}else e.queue.length<n&&se(e.queue);e.status.in++}o||(o=e.destinations);const g=e.transformers?$(e.transformers):{},h=await Promise.all(Object.entries(o||{}).map(async([o,s])=>{var r,i,a,c,l;if(s.config.disabled)return{id:o,destination:s,skipped:!0};let u=(s.queuePush||[]).map(e=>({...e,consent:d}));s.queuePush=[],t&&u.push((0,y.clone)(t));const h=n.ingest?{...n.ingest,_meta:{...n.ingest._meta,path:[...n.ingest._meta.path]}}:(0,y.createIngest)("unknown");if(!u.length&&!(null==(r=s.queueOn)?void 0:r.length))return{id:o,destination:s,skipped:!0};if(!u.length&&(null==(i=s.queueOn)?void 0:i.length)){let t=!1;try{t=await pe(e,s,o)}catch(t){e.status.failed++;const n=s.type||"unknown";e.logger.scope(n).error("destination init failed",{error:t instanceof Error?t.message:String(t)})}return{id:o,destination:s,skipped:!t}}const m=[],v=u.filter(t=>{const n=(0,y.getGrantedConsent)(s.config.consent,d,t.consent);if(n)return t.consent=n,m.push(t),!1;const r=A(e,{stepId:(0,y.stepId)("destination",o),stepType:"destination",phase:"skip",eventId:"string"==typeof t.id?t.id:"",now:Date.now()});return r.skipReason="consent",d&&(r.consent={...d}),s.config.consent&&(r.meta={required:{...s.config.consent}}),(0,y.emitStep)(e,r),!0});if(v.length>0){const t=s.queuePush,n=s.config.id||o,r={max:null!=(a=s.config.queueMax)?a:1e3};let i=0;for(const e of v)i+=te(t,e,r).dropped;if(i>0){ce(e,n);const o=le(e.status,(0,y.stepId)("destination",n),"queue",i);oe(t,e.logger.scope(s.type||"unknown"),"destination.queuePush overflow; oldest events dropped",{buffer:"queuePush",destination:n,cap:r.max,droppedCount:o})}else t.length<r.max&&se(t)}if(!m.length)return{id:o,destination:s,queue:u};let w,b,k=!1;try{k=await pe(e,s,o)}catch(t){e.status.failed++;const n=s.type||"unknown";e.logger.scope(n).error("destination init failed",{error:t instanceof Error?t.message:String(t)})}if(!k)return{id:o,destination:s,queue:u};s.dlq||(s.dlq=[]);const I=ue(s.config.before,g,h),S=s.config.next,C=null==(c=s.config)?void 0:c.cache,q=C?(0,y.compileCache)(C):void 0,O=q?E(q,e):void 0,x=(null==(l=s.config)?void 0:l.state)?(0,y.compileState)(s.config.state):void 0,j=null==x?void 0:x.filter(e=>"get"===e.mode),D=null==x?void 0:x.filter(e=>"set"===e.mode);let $=0,_=0;return await Promise.all(m.map(async t=>{let r;if(t.globals=(0,y.assign)(p,t.globals),t.user=(0,y.assign)(f,t.user),(null==q?void 0:q.stop)&&O){const e=(0,y.buildCacheContext)(h,t),n=await(0,y.checkCache)(q,O,e);if("HIT"===(null==n?void 0:n.status))return t;"MISS"===(null==n?void 0:n.status)&&(r={key:n.key,ttl:n.rule.ttl})}let i=t,a=n.respond;if(I.length>0&&e.transformers&&Object.keys(e.transformers).length>0){const s=await H(e,e.transformers,I,t,h,n.respond,`destination.${o}.before`);if(null===s.event)return t;s.respond&&(a=s.respond),i=Array.isArray(s.event)?s.event[0]:s.event}if(q&&!q.stop&&O){const e=(0,y.buildCacheContext)(h,i),n=await(0,y.checkCache)(q,O,e);if("HIT"===(null==n?void 0:n.status))return t;"MISS"===(null==n?void 0:n.status)&&(r={key:n.key,ttl:n.rule.ttl})}j&&j.length>0&&i&&(i=await(0,y.applyState)(j,t=>M(t,e),i,e));const c=Date.now();let l=!1;const u=await(0,y.tryCatchAsync)(fe,t=>{var n;const r=s.type||"unknown";e.logger.scope(r).error("Push failed",{error:t,event:i.name}),w=t,l=!0;const a=s.dlq,c=s.config.id||o,u={max:null!=(n=s.config.dlqMax)?n:100},d=te(a,[i,t],u);if(d.dropped>0){ce(e,c);const t=le(e.status,(0,y.stepId)("destination",c),"dlq",d.dropped);oe(a,e.logger.scope(s.type||"unknown"),"destination.dlq overflow; oldest entries dropped",{buffer:"dlq",destination:c,cap:u.max,droppedCount:t})}else a.length<u.max&&se(a)})(e,s,o,i,h,a);if($+=Date.now()-c,r&&O&&void 0===s.config.mock&&(0,y.storeCache)(O,r.key,null==u||u,r.ttl),!l&&!ie(u)&&D&&D.length>0&&i&&(i=await(0,y.applyState)(D,t=>M(t,e),i,e)),void 0===u||ie(u)||(b=u),ie(u)&&_++,!l&&S){void 0!==u&&(h._response=u);const t=ue(S,g,h);if(t.length>0&&e.transformers&&Object.keys(e.transformers).length>0){const n=await H(e,e.transformers,t,i,h,a,`destination.${o}.next`);n.respond&&(a=n.respond)}}return t})),{id:o,destination:s,error:w,response:b,totalDuration:$,batchedCount:_,allowedCount:m.length}})),m={},v={},w={};for(const t of h){if(t.skipped)continue;const n=t.destination,o={type:n.type||"unknown",data:t.response};ce(e,t.id);const u=e.status.destinations[t.id],d=Date.now();if(u.queuePushSize=null!=(r=null==(s=n.queuePush)?void 0:s.length)?r:0,u.dlqSize=null!=(a=null==(i=n.dlq)?void 0:i.length)?a:0,t.error)o.error=t.error,w[t.id]=o,u.failed++,u.lastAt=d,u.duration+=t.totalDuration||0,e.status.failed++;else if(t.queue&&t.queue.length)v[t.id]=o;else{const n=null!=(c=t.batchedCount)?c:0,s=null!=(l=t.allowedCount)?l:0;(Math.max(0,s-n)>0||0===s)&&(m[t.id]=o,u.count++,u.lastAt=d,u.duration+=t.totalDuration||0,e.status.out++)}}return ge({event:t,...Object.keys(m).length&&{done:m},...Object.keys(v).length&&{queued:v},...Object.keys(w).length&&{failed:w}})}async function pe(e,t,n){var o;if(t.init&&!t.config.init){const s=t.type||"unknown",r=e.logger.scope(s),i={collector:e,logger:r,id:n,config:t.config,env:me(t.env,t.config.env)};r.debug("init");const a=Date.now();let c;(0,y.emitStep)(e,A(e,{stepId:(0,y.stepId)("destination",n),stepType:"destination",phase:"init",eventId:"",now:a}));try{c=await(0,y.useHooks)(t.init,"DestinationInit",e.hooks,e.logger)(i)}catch(t){const o=Date.now(),s=A(e,{stepId:(0,y.stepId)("destination",n),stepType:"destination",phase:"error",eventId:"",now:o});throw s.durationMs=o-a,s.error=t instanceof Error?{name:t.name,message:t.message}:{message:String(t)},(0,y.emitStep)(e,s),t}if(!1===c)return c;if(t.config={...c||t.config,init:!0},null==(o=t.queueOn)?void 0:o.length){const o=t.queueOn;t.queueOn=[];for(const{type:s,data:r}of o)Q(e,t,n,s,r)}r.debug("init done")}return!0}async function fe(e,t,n,o,s,r){var i,a,c,l,u,d,p;const{config:f}=t,g=await(0,y.processEventMapping)(o,f,e);if(g.ignore)return!1;const h=t.type||"unknown",m=e.logger.scope(h),v={collector:e,logger:m,id:n,config:f,data:g.data,rule:g.mapping,ingest:s,env:{...me(t.env,f.env),...r?{respond:r}:{}}};if(void 0!==f.mock)return m.debug("mock",{event:g.event.name}),f.mock;const w=g.mapping,b=g.mappingKey||"* *";if((null==w?void 0:w.batch)&&t.pushBatch&&void 0===f.mock){if(t.batches=t.batches||{},!t.batches[b]){const o={key:b,entries:[],events:[],data:[]},s=ae(w.batch),r=ae(f.batch),p=null!=(a=null!=(i=s.wait)?i:r.wait)?a:3e4,g=null!=(l=null!=(c=s.size)?c:r.size)?l:1e3,h=null!=(d=null!=(u=s.age)?u:r.age)?d:3e4,v=me(t.env,f.env),k=(0,y.debounce)(async()=>{var o;const s=t.batches[b].batched;if(0===s.entries.length)return;const r={key:s.key,entries:s.entries,events:s.events,data:s.data};s.entries=[],s.events=[],s.data=[];const i=r.entries[0],a={collector:e,logger:m,id:n,config:f,data:void 0,rule:i.rule,ingest:i.ingest,env:{...v,...i.respond?{respond:i.respond}:{}}};m.debug("push batch",{events:r.entries.length});const c=t.config.id||n,l=ce(e,c),u=Date.now(),d=A(e,{stepId:(0,y.stepId)("destination",n),stepType:"destination",phase:"flush",eventId:"",now:u});d.batch={size:r.entries.length,index:0},(0,y.emitStep)(e,d);let p=!0;await(0,y.tryCatchAsync)((0,y.useHooks)(t.pushBatch,"DestinationPushBatch",e.hooks,e.logger),o=>{var s;p=!1;const i=Date.now(),a=A(e,{stepId:(0,y.stepId)("destination",n),stepType:"destination",phase:"error",eventId:"",now:i});a.durationMs=i-u,a.error=o instanceof Error?{name:o.name,message:o.message}:{message:String(o)},a.batch={size:r.entries.length,index:0},(0,y.emitStep)(e,a);const d=t.dlq=t.dlq||[],f={max:null!=(s=t.config.dlqMax)?s:100};let g=0;for(const e of r.entries)g+=te(d,[e.event,o],f).dropped;if(g>0){const t=le(e.status,(0,y.stepId)("destination",c),"dlq",g);oe(d,m,"destination.dlq overflow; oldest entries dropped",{buffer:"dlq",destination:c,cap:f.max,droppedCount:t})}else d.length<f.max&&se(d);l.failed+=r.entries.length,l.dlqSize=d.length,e.status.failed+=r.entries.length,m.error("Push batch failed",{error:o instanceof Error?o.message:String(o),entries:r.entries.length})})(r,a),m.debug("push batch done"),l.inFlightBatch=Math.max(0,(null!=(o=l.inFlightBatch)?o:0)-r.entries.length),p&&(l.count+=r.entries.length,l.lastAt=Date.now(),e.status.out+=r.entries.length)},{wait:p,size:g,age:h});t.batches[b]={batched:o,batchFn:()=>{k()},flush:async()=>{await k.flush()}}}const o=t.batches[b];o.batched.entries.push({event:g.event,ingest:s,respond:r,rule:w,data:g.data}),o.batched.events.push(g.event),(0,y.isDefined)(g.data)&&o.batched.data.push(g.data);const h=t.config.id||n,v=ce(e,h);return v.inFlightBatch=(null!=(p=v.inFlightBatch)?p:0)+1,o.batchFn(),re}{m.debug("push",{event:g.event.name});const o="string"==typeof g.event.id?g.event.id:"",s=Date.now(),r=A(e,{stepId:(0,y.stepId)("destination",n),stepType:"destination",phase:"in",eventId:o,now:s});g.mappingKey&&(r.mappingKey=g.mappingKey),g.event.consent&&(r.consent={...g.event.consent}),(0,y.emitStep)(e,r);try{const r=await(0,y.useHooks)(t.push,"DestinationPush",e.hooks,e.logger)(g.event,v),i=Date.now(),a=A(e,{stepId:(0,y.stepId)("destination",n),stepType:"destination",phase:"out",eventId:o,now:i});return a.durationMs=i-s,a.outEvent=r,g.mappingKey&&(a.mappingKey=g.mappingKey),(0,y.emitStep)(e,a),m.debug("push done"),r}catch(t){const r=Date.now(),i=A(e,{stepId:(0,y.stepId)("destination",n),stepType:"destination",phase:"error",eventId:o,now:r});throw i.durationMs=r-s,i.error=t instanceof Error?{name:t.name,message:t.message}:{message:String(t)},g.mappingKey&&(i.mappingKey=g.mappingKey),(0,y.emitStep)(e,i),t}}}function ge(e){return{ok:!(null==e?void 0:e.failed),...e}}function he(e){const{code:t,config:n={},env:o={},cache:s,state:r}=e,{config:i}=_(e,"before"),{config:a}=_({...e,config:i},"next"),c={...t.config,...n,...a};s&&(c.cache=s),void 0!==r&&void 0===c.state&&(c.state=r);const l=me(t.env,o);return{...t,config:c,env:l}}function me(e,t){return e||t?t?e&&(0,y.isObject)(e)&&(0,y.isObject)(t)?{...e,...t}:t:e:{}}async function ve(e,t,n){const o=Object.entries(e).map(async([e,o])=>{var s;const r=o.destroy;if(!r)return;const i=o.type||"unknown",a=n.scope(i),c={id:e,config:o.config,env:null!=(s=o.env)?s:{},logger:a};try{await Promise.race([r(c),new Promise((n,o)=>setTimeout(()=>o(new Error(`${t} '${e}' destroy timed out`)),5e3))])}catch(n){a.error(`${t} '${e}' destroy failed: ${n}`)}});await Promise.allSettled(o)}async function ye(e,t,n){let o,s,r=!1;const i=function(e){return e.cascade?()=>{}:(e.cascade={counts:new WeakMap},()=>{e.cascade=void 0})}(e);try{return await async function(){switch(t){case D.Config:(0,C.isObject)(n)&&((0,S.assign)(e.config,n,{shallow:!1}),s=n,r=!0);break;case D.Consent:if((0,C.isObject)(n)){const{update:t}=function(e,t){const n={};return Object.entries(t).forEach(([e,t])=>{n[e]=!!t}),e.consent=(0,m.assign)(e.consent,n),{update:n}}(e,n);e.stateVersion++,s=t,r=!0}break;case D.Custom:(0,C.isObject)(n)&&(e.custom=(0,S.assign)(e.custom,n),e.stateVersion++,s=n,r=!0);break;case D.Destination:(0,C.isObject)(n)&&"code"in n&&(0,C.isObject)(n.code)&&(o=await async function(e,t){const{code:n,config:o={},env:s={},before:r,next:i,cache:a,state:c}=t;if(!(0,y.isFunction)(n.push))return ge({ok:!1,failed:{invalid:{type:"invalid",error:"Destination code must have a push method"}}});const l=o||{init:!1};let u=r?{...l,before:r}:{...l};i&&(u={...u,next:i}),a&&(u={...u,cache:a}),void 0!==c&&void 0===u.state&&(u={...u,state:c});const d={...n,config:u,env:me(n.env,s)};let p=d.config.id;if(!p)do{p=(0,y.getId)(5,"abcdefghijklmnopqrstuvwxyz")}while(e.destinations[p]);return e.destinations[p]=d,!1!==d.config.queue&&(d.queuePush=[...e.queue]),de(e,void 0,{},{[p]:d})}(e,n));break;case D.Globals:(0,C.isObject)(n)&&(e.globals=(0,S.assign)(e.globals,n),e.stateVersion++,s=n,r=!0);break;case D.Hook:if((0,C.isObject)(n)&&(0,S.isString)(n.name)&&(0,S.isFunction)(n.fn)){const{name:t,fn:o}=n;e.hooks[t]=o,s=n,r=!0}break;case D.On:if((0,C.isObject)(n)&&(0,S.isString)(n.type)){const{type:t,rules:o}=n;await async function(e,t,n){const o=e.on,s=o[t]||[],r=(0,w.isArray)(n)?n:[n];r.forEach(e=>{s.push(e)}),o[t]=s,X(e,t,r)}(e,t,o)}break;case D.Ready:r=!0;break;case D.Run:o=await async function(e,t){return e.allowed=!0,e.timing=Date.now(),t&&(t.consent&&(e.consent=(0,S.assign)(e.consent,t.consent),e.stateVersion++),t.user&&(e.user=(0,S.assign)(e.user,t.user),e.stateVersion++),t.globals&&(e.globals=(0,S.assign)(e.config.globalsStatic||{},t.globals),e.stateVersion++),t.custom&&(e.custom=(0,S.assign)(e.custom,t.custom),e.stateVersion++)),Object.values(e.destinations).forEach(e=>{e.queuePush=[]}),e.queue=[],e.round++,await async function(e){const t=[{type:D.Consent,nonEmpty:Object.keys(e.consent).length>0},{type:D.User,nonEmpty:Object.keys(e.user).length>0},{type:D.Globals,nonEmpty:Object.keys(e.globals).length>0},{type:D.Custom,nonEmpty:Object.keys(e.custom).length>0}];for(const{type:n,nonEmpty:o}of t){if(!o)continue;const t=Z(e,n);X(e,n,e.on[n]||[]);for(const[o,s]of Object.entries(e.sources))V(s)&&await ee(e,s,o,n,t)}}(e),await de(e)}(e,n),r=!0;break;case D.Session:r=!0;break;case D.Shutdown:await async function(e){const t=e.logger;await ve(e.sources,"source",t),await ve(e.destinations,"destination",t),await ve(e.transformers,"transformer",t),await ve(e.stores,"store",t)}(e);break;case D.User:(0,C.isObject)(n)&&((0,S.assign)(e.user,n,{shallow:!1}),e.stateVersion++,s=n,r=!0)}return r&&(await async function(e,t,n,o){var s,r;let i,a=n||[];switch(n||(a=e.on[t]||[]),t){case D.Consent:i=o||e.consent;break;case D.Session:i=e.session;break;case D.User:i=o||e.user;break;case D.Custom:i=o||e.custom;break;case D.Globals:i=o||e.globals;break;case D.Config:i=o||e.config;break;case D.Ready:case D.Run:default:i=void 0}let c=!1;for(const[n,o]of Object.entries(e.sources)){if(null==(s=o.config.require)?void 0:s.length){const e=o.config.require.indexOf(t);-1!==e&&o.config.require.splice(e,1)}o.on&&(V(o)?await ee(e,o,n,t,i)&&(c=!0):(o.queueOn=o.queueOn||[],o.queueOn.push({type:t,data:i})))}Object.entries(e.destinations).forEach(([n,o])=>{if(o.on){if(!o.config.init)return o.queueOn=o.queueOn||[],void o.queueOn.push({type:t,data:i});Q(e,o,n,t,i)}});for(const[t,n]of Object.entries(e.sources))V(n)&&(null==(r=n.queueOn)?void 0:r.length)&&await F(e,n,t);return Object.keys(e.pending.destinations).length>0&&await async function(e,t){var n;for(const[o,s]of Object.entries(e.pending.destinations)){if(!e.pending.destinations[o]||e.destinations[o])continue;const r=null==(n=s.config)?void 0:n.require;if(!r)continue;const i=r.indexOf(t);if(-1===i)continue;if(r.splice(i,1),r.length>0)continue;delete e.pending.destinations[o];const a=he(s);!1!==a.config.queue&&(a.queuePush=[...e.queue]),e.destinations[o]=a}}(e,t),X(e,t,a,o),!c}(e,t,void 0,s),o=await de(e)),o||ge({ok:!0})}()}finally{i()}}function we(e,t){if(!t.name)throw new Error("Event name is required");const[n,o]=t.name.split(" ");if(!n||!o)throw new Error("Event name is invalid");const{timestamp:s=Date.now(),name:r=`${n} ${o}`,data:i={},context:a={},globals:c=e.globals,custom:l={},user:u=e.user,nested:d=[],consent:p=e.consent,id:f=(0,S.getSpanId)(),trigger:g="",entity:h=n,action:m=o,timing:v=0,source:y={type:"collector",schema:"4"}}=t;return{name:r,data:i,context:a,globals:c,custom:l,user:u,nested:d,consent:p,id:f,trigger:g,entity:h,action:m,timestamp:s,timing:v,source:y}}function be(e={}){var t,n,o;const s=null!=(t=e.maxEntries)?t:1e4,r=null!=(n=e.lowWaterMark)?n:.8,i=null!=(o=e.sweepIntervalMs)?o:6e4,a=Math.floor(s*r),c=new Map,l={hits:0,misses:0,populates:0,writes:0,deletes:0,evictions_entries:0,evictions_ttl:0};let u;return i>0&&(u=setInterval(function(){const e=Date.now();let t=0;for(const[n,o]of c)void 0!==o.expires&&o.expires<=e&&(c.delete(n),t++);l.evictions_ttl+=t},i),u&&"function"==typeof u.unref&&u.unref()),{type:"memory",config:{},get(e){const t=c.get(e);if(t)return void 0!==t.expires&&t.expires<=Date.now()?(c.delete(e),l.evictions_ttl++,void l.misses++):(c.delete(e),c.set(e,t),l.hits++,t.value);l.misses++},set(e,t,n){const o=!c.has(e);o||c.delete(e),c.set(e,{value:t,expires:void 0!==n?Date.now()+n:void 0}),l.writes++,o&&l.populates++,c.size>s&&function(){if(c.size<=s)return;const e=c.size-a;let t=0;for(const n of c.keys()){if(t>=e)break;c.delete(n),t++}l.evictions_entries+=t}()},delete(e){c.delete(e)&&l.deletes++},get counters(){return{...l}},destroy(){void 0!==u&&(clearInterval(u),u=void 0),c.clear()}}}function ke(e,t){const{cacheConfig:n,cacheStore:o,namespace:s,logger:r,storeId:i,collector:a}=t,c=(e,t)=>{if(!a)return;const n=A(a,{stepId:`store.${i}`,stepType:"store",phase:"in",eventId:"",now:Date.now()});n.meta={op:"cache",cached:"hit"===t,status:t,key:e},(0,j.emitStep)(a,n)},l={hits:0,misses:0,populates:0,writes:0,deletes:0,inflight_dedups:0},u=n.rules.map(e=>({match:e.match?(0,j.compileMatcher)(e.match):()=>!0,ttl:e.ttl})),d=e=>`${s}:${e}`;function p(e,t){const n=void 0===t?{key:e}:{key:e,value:t};return u.find(e=>e.match(n))}const f=new Map;return{type:e.type,config:e.config,setup:e.setup,get counters(){return{...l}},async get(t){const n=d(t),s=await o.get(n);if(void 0!==s)return l.hits++,c(t,"hit"),s;const r=f.get(n);if(r)return l.inflight_dedups++,c(t,"hit"),r;l.misses++,c(t,"miss");const i=(async()=>{try{const s=await e.get(t);if(void 0===s)return;const r=p(t,s);if(r)try{await o.set(n,s,1e3*r.ttl),l.populates++}catch(e){g("set",t,e)}return s}finally{f.delete(n)}})();return f.set(n,i),i},async set(t,n,s){l.writes++,await e.set(t,n,s);const r=p(t,n);if(r)try{await o.set(d(t),n,1e3*r.ttl)}catch(e){g("set",t,e)}},async delete(t){l.deletes++,await e.delete(t);try{await o.delete(d(t))}catch(e){g("delete",t,e)}}};function g(e,t,n){const o=`store-cache(${i}): cache ${e} failed for "${t}"; backing succeeded, continuing`;r?r.warn(o,{error:n}):console.warn(o,n)}}function Ie(e,t,n){const o=`store.${n}`,s=(0,x.useHooks)(t.get,"StoreGet",e.hooks,e.logger),r=(0,x.useHooks)(t.set,"StoreSet",e.hooks,e.logger),i=(0,x.useHooks)(t.delete,"StoreDelete",e.hooks,e.logger);t.get=async t=>{const n=Date.now(),r=A(e,{stepId:o,stepType:"store",phase:"in",eventId:"",now:n});r.meta={op:"get",key:t},(0,x.emitStep)(e,r);try{const r=await s(t),i=Date.now(),a=A(e,{stepId:o,stepType:"store",phase:"out",eventId:"",now:i});return a.durationMs=i-n,a.meta={op:"get",key:t},(0,x.emitStep)(e,a),r}catch(s){const r=Date.now(),i=A(e,{stepId:o,stepType:"store",phase:"error",eventId:"",now:r});throw i.durationMs=r-n,i.meta={op:"get",key:t},i.error=s instanceof Error?{name:s.name,message:s.message}:{message:String(s)},(0,x.emitStep)(e,i),s}},t.set=async(t,n,s)=>{const i=Date.now(),a=A(e,{stepId:o,stepType:"store",phase:"in",eventId:"",now:i});a.meta={op:"set",key:t},(0,x.emitStep)(e,a);try{await r(t,n,s);const a=Date.now(),c=A(e,{stepId:o,stepType:"store",phase:"out",eventId:"",now:a});c.durationMs=a-i,c.meta={op:"set",key:t},(0,x.emitStep)(e,c)}catch(n){const s=Date.now(),r=A(e,{stepId:o,stepType:"store",phase:"error",eventId:"",now:s});throw r.durationMs=s-i,r.meta={op:"set",key:t},r.error=n instanceof Error?{name:n.name,message:n.message}:{message:String(n)},(0,x.emitStep)(e,r),n}},t.delete=async t=>{const n=Date.now(),s=A(e,{stepId:o,stepType:"store",phase:"in",eventId:"",now:n});s.meta={op:"delete",key:t},(0,x.emitStep)(e,s);try{await i(t);const s=Date.now(),r=A(e,{stepId:o,stepType:"store",phase:"out",eventId:"",now:s});r.durationMs=s-n,r.meta={op:"delete",key:t},(0,x.emitStep)(e,r)}catch(s){const r=Date.now(),i=A(e,{stepId:o,stepType:"store",phase:"error",eventId:"",now:r});throw i.durationMs=r-n,i.meta={op:"delete",key:t},i.error=s instanceof Error?{name:s.name,message:s.message}:{message:String(s)},(0,x.emitStep)(e,i),s}}}async function Se(e){var t,n;const o=(0,v.assign)({globalsStatic:{},sessionStatic:{},run:!0,queueMax:1e3},e,{merge:!1,extend:!1}),s={level:null==(t=e.logger)?void 0:t.level,handler:null==(n=e.logger)?void 0:n.handler},r=(0,v.createLogger)(s),i={...o.globalsStatic,...e.globals},a={allowed:!1,config:o,consent:e.consent||{},custom:e.custom||{},destinations:{},transformers:{},stores:{},globals:i,hooks:e.hooks||{},observers:new Set,logger:r,on:{},queue:[],round:0,stateVersion:0,delivery:new WeakMap,session:void 0,status:{startedAt:Date.now(),in:0,out:0,failed:0,sources:{},destinations:{},dropped:{}},timing:Date.now(),user:e.user||{},sources:{},pending:{destinations:{}},push:void 0,command:void 0};var c,l;a.push=function(e,t){const n=(0,q.useHooks)(async(n,o={})=>await(0,q.tryCatchAsync)(async()=>{var s;const r=Date.now(),{id:i,ingest:a,respond:c,mapping:l,preChain:u,include:d,exclude:p}=o;let f=c,g=n;const h=d||p?function(e,t,n){let o=e;return t&&(o=Object.fromEntries(Object.entries(o).filter(([e])=>t.includes(e)))),n&&(o=Object.fromEntries(Object.entries(o).filter(([e])=>!n.includes(e)))),o}(e.destinations,d,p):void 0,m=null!=a?a:(0,q.createIngest)(i||"unknown");if(l){const t=await(0,q.processEventMapping)(g,l,e);if(t.ignore)return ge({ok:!0});if(l.consent&&!(0,q.getGrantedConsent)(l.consent,e.consent,t.event.consent))return ge({ok:!0});g=t.event}if((null==u?void 0:u.length)&&e.transformers&&Object.keys(e.transformers).length>0){const n=await H(e,e.transformers,u,g,m,f,i?`source.${i}.next`:void 0);if(null===n.event)return ge({ok:!0});if(n.stopped)return n.respond&&(f=n.respond),ge({ok:!0});if(n.respond&&(f=n.respond),Array.isArray(n.event)){const o=await Promise.all(n.event.map(async n=>{const o=t(n),s=we(e,o);return de(e,s,{id:i,ingest:m,respond:f},h)}));if(i){e.status.sources[i]||(e.status.sources[i]={count:0,duration:0});const t=e.status.sources[i];t.count+=n.event.length,t.lastAt=Date.now(),t.duration+=Date.now()-r}return null!=(s=o[0])?s:ge({ok:!0})}g=n.event}const v=t(g),y=we(e,v),w=await de(e,y,{id:i,ingest:m,respond:f},h);if(i){e.status.sources[i]||(e.status.sources[i]={count:0,duration:0});const t=e.status.sources[i];t.count++,t.lastAt=Date.now(),t.duration+=Date.now()-r}return w},t=>{if(t instanceof q.FatalError)throw t;return e.status.failed++,e.logger.error("push failed",{event:n,ingest:o.ingest,error:t}),ge({ok:!1})})(),"Push",e.hooks,e.logger);return async(t,o)=>{const s="string"==typeof t.id?t.id:"",r=Date.now();(0,q.emitStep)(e,A(e,{stepId:"collector.push",stepType:"collector",phase:"in",eventId:s,now:r}));try{const i=await n(t,o),a=Date.now(),c=A(e,{stepId:"collector.push",stepType:"collector",phase:"out",eventId:s,now:a});return c.durationMs=a-r,c.outEvent=i,(0,q.emitStep)(e,c),i}catch(t){const n=Date.now(),o=A(e,{stepId:"collector.push",stepType:"collector",phase:"error",eventId:s,now:n});throw o.durationMs=n-r,o.error=t instanceof Error?{name:t.name,message:t.message}:{message:String(t)},(0,q.emitStep)(e,o),t}}}(a,e=>({timing:Math.round((Date.now()-a.timing)/10)/100,source:{type:"collector",schema:"4",version:"4.2.0-next-1780387694663"},...e})),a.command=(c=a,l=ye,(0,O.useHooks)(async(e,t,n)=>await(0,O.tryCatchAsync)(async()=>await l(c,e,t,n),n=>{if(n instanceof O.FatalError)throw n;return c.status.failed++,c.logger.error("command failed",{command:e,data:t,error:n}),ge({ok:!1})})(),"Command",c.hooks,c.logger));const u=e.stores||{};return a.stores=await async function(e,t={}){var n;const o={};for(const[n,s]of Object.entries(t)){const{code:t,config:r={},env:i={}}=s,a=e.logger.scope("store").scope(n),c={collector:e,logger:a,id:n,config:r,env:i},l=await t(c);o[n]=l}const s=t,r=function(e){const t={};for(const n of Object.keys(e))t[n]="WHITE";const n=[],o=[];function s(r){var i;const a=t[r];if("BLACK"===a)return;if("GRAY"===a){const e=o.indexOf(r),t=o.slice(-1===e?0:e).concat(r).join(" -> ");throw new Error(`Cycle in cache.store chain: ${t}`)}t[r]="GRAY",o.push(r);const c=null==(i=e[r].cache)?void 0:i.store;if(void 0!==c){if(!(c in e))throw new Error(`Store "${r}" cache.store references "${c}", which is not declared in flow.stores`);s(c)}o.pop(),t[r]="BLACK",n.push(r)}for(const n of Object.keys(e))"WHITE"===t[n]&&s(n);return n}(s);for(const t of r){const r=s[t].cache;if(!r)continue;let i,a;void 0!==r.store?(i=o[r.store],a=r.store):(o.__cache||(o.__cache=be()),i=o.__cache,a="__cache");const c=null!=(n=r.namespace)?n:t;e.logger.scope("store-cache").scope(t).info(`store "${t}" caches with namespace "${c}:" via ${a}`),o[t]=ke(o[t],{storeId:t,cacheConfig:r,cacheStore:i,namespace:c,logger:e.logger.scope("store-cache").scope(t),collector:e})}for(const[t,n]of Object.entries(o))"__cache"!==t&&Ie(e,n,t);return o}(a,u),function(e,t,n){const o=new Map;for(const[n,s]of Object.entries(e))t[n]&&o.set(s,t[n]);if(0!==o.size)for(const e of[n.transformers,n.destinations,n.sources])if(e)for(const t of Object.values(e))s(t.env);function s(e){if(e)for(const[t,n]of Object.entries(e))if("object"==typeof n&&null!==n){const s=o.get(n);s&&(e[t]=s)}}}(u,a.stores,e),a.stores.__cache||(a.stores.__cache=be()),a.destinations=await async function(e,t={}){var n,o;const s={};for(const[r,i]of Object.entries(t))(null==(o=null==(n=i.config)?void 0:n.require)?void 0:o.length)?e.pending.destinations[r]=i:s[r]=he(i);return s}(a,e.destinations||{}),a.transformers=await async function(e,t={}){var n,o,s,r,i,a,c,l;const u={};for(const[d,p]of Object.entries(t)){const{code:t,env:f={}}=p,g=(0,I.validateStepEntry)(p,"Transformer");if(!g.ok){e.logger.warn(`Transformer ${d} invalid (${g.code}): ${g.reason}. Skipping.`);continue}const{config:h}=_(p,"before"),{config:m}=_({...p,config:h},"next"),v=Object.keys(f).length>0?{...m,env:f}:m,{cache:y}=p,w=y?{...v,cache:y}:v,b=null!=(o=null==(n=p.config)?void 0:n.state)?o:p.state,k=void 0!==b&&void 0===w.state?{...w,state:b}:w,S=e.logger.scope("transformer").scope(d),C={collector:e,logger:S,id:d,ingest:(0,I.createIngest)(d),config:k,env:f},q=null!=t?t:e=>{const t=p.mapping;if(t){const n=[];if(void 0!==t.data&&n.push("data"),t.mapping)for(const[e,o]of Object.entries(t.mapping))if("object"==typeof o&&null!==o)for(const[t,s]of Object.entries(o)){if("object"!=typeof s||null===s)continue;const o=s;void 0!==o.data&&n.push(`mapping[${e}][${t}].data`),void 0!==o.silent&&n.push(`mapping[${e}][${t}].silent`)}return n.length>0&&e.collector.logger.warn(`Transformer ${d}: \`${n.join(", ")}\` ignored at transformer position (only event-mutating fields apply).`),{type:"pass",config:e.config,push:async n=>{const o=await(0,I.processEventMapping)(n,t,e.collector);return!o.ignore&&{event:o.event}}}}return{type:"pass",config:e.config,push:e=>({event:e})}},O=await q(C);void 0!==p.before&&void 0===(null==(s=O.config)?void 0:s.before)&&(O.config={...null!=(r=O.config)?r:{},before:p.before}),void 0!==p.next&&void 0===(null==(i=O.config)?void 0:i.next)&&(O.config={...null!=(a=O.config)?a:{},next:p.next}),void 0!==b&&void 0===(null==(c=O.config)?void 0:c.state)&&(O.config={...null!=(l=O.config)?l:{},state:b}),u[d]=O}return u}(a,e.transformers||{}),a}async function Ce(e){e=e||{};const t=await Se(e),n=(o=t,{type:"elb",config:{},push:async(e,t,n,s,r)=>{if("string"==typeof e&&e.startsWith("walker ")){const n=e.replace("walker ","");return o.command(n,t)}let i;if("string"==typeof e)i={name:e},t&&"object"==typeof t&&!Array.isArray(t)&&(i.data=t);else{if(!e||"object"!=typeof e)return ge({ok:!1});i=e,t&&"object"==typeof t&&!Array.isArray(t)&&(i.data={...i.data||{},...t})}return n&&"object"==typeof n&&(i.context=n),s&&Array.isArray(s)&&(i.nested=s),r&&"object"==typeof r&&(i.custom=r),o.push(i)}});var o;t.sources.elb=n,await async function(e,t={}){var n;const o={};for(const[s,r]of Object.entries(t)){const t=await B(e,s,r);if(!t)continue;const i=null==(n=r.config)?void 0:n.require;t.config={...t.config,init:!1,...i?{require:[...i]}:{}},o[s]=t}Object.assign(e.sources,o);for(const t of Object.keys(o)){const n=e.sources[t];let o=!1;n.init&&await(0,k.tryCatchAsync)(n.init.bind(n),n=>{if(n instanceof k.FatalError)throw n;o=!0,e.status.failed++,e.logger.scope("source").error("source init failed",{sourceId:t,error:n})})(),o||(n.config.init=!0,V(n)&&await F(e,n,t))}return o}(t,e.sources||{});const{consent:s,user:r,globals:i,custom:a}=e;s&&await t.command("consent",s),r&&await t.command("user",r),i&&Object.assign(t.globals,i),a&&Object.assign(t.custom,a),t.config.run&&await t.command("run");let c=n.push;const l=Object.values(t.sources).filter(e=>"elb"!==e.type),u=l.find(e=>e.config.primary);return u?c=u.push:l.length>0&&(c=l[0].push),{collector:t,elb:c}}var qe=async e=>{let t;return{get flow(){return t},trigger:(n,o)=>async n=>{var s,r,i,a,c,l,u,d,p;const f=o||{};if(f.url){const e=new URL(f.url);window.history.replaceState({},"",e.pathname+e.search)}if(f.referrer&&Object.defineProperty(document,"referrer",{value:f.referrer,configurable:!0}),f.sessionData){const e=f.sessionKey||"elbSessionId";localStorage.setItem(e,JSON.stringify(f.sessionData))}if(f.deviceId){const e=f.deviceKey||"elbDeviceId";localStorage.setItem(e,f.deviceId)}if(!t){const n=await Ce({...e,run:null==(s=e.run)||s});t={collector:n.collector,elb:n.elb};const o=f.sessionKey||(null==(c=null==(a=null==(i=null==(r=e.sources)?void 0:r.session)?void 0:i.config)?void 0:a.settings)?void 0:c.sessionKey)||"elbSessionId",g=f.deviceKey||(null==(p=null==(d=null==(u=null==(l=e.sources)?void 0:l.session)?void 0:u.config)?void 0:d.settings)?void 0:p.deviceKey)||"elbDeviceId";localStorage.removeItem(o),localStorage.removeItem(g),f.sessionData&&localStorage.setItem(o,JSON.stringify(f.sessionData)),f.deviceId&&localStorage.setItem(g,f.deviceId),e.consent&&await t.collector.command("consent",e.consent)}}}},Oe=(e,t)=>{if(!e||"object"!=typeof e)return;const n=e,o=t.localStorage;if(n.sessionData&&"object"==typeof n.sessionData){const e="string"==typeof n.sessionKey?n.sessionKey:"elbSessionId";o.setItem(e,JSON.stringify(n.sessionData))}if("string"==typeof n.deviceId){const e="string"==typeof n.deviceKey?n.deviceKey:"elbDeviceId";o.setItem(e,n.deviceId)}};//# sourceMappingURL=dev.js.map
package/dist/dev.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/dev.ts","../src/schemas/index.ts","../src/schemas/settings.ts","../src/examples/index.ts","../src/examples/step.ts","../src/examples/trigger.ts"],"sourcesContent":["export * as schemas from './schemas';\nexport * as examples from './examples';\n","import { zodToSchema } from '@walkeros/core/dev';\nimport { SettingsSchema } from './settings';\n\n// Export Zod schemas and types\nexport { SettingsSchema, type Settings } from './settings';\n\n// JSON Schema exports (for website PropertyTable)\nexport const settings = zodToSchema(SettingsSchema);\n","import { z, ClickIdEntrySchema } from '@walkeros/core/dev';\n\n/**\n * Session source settings schema\n */\nexport const SettingsSchema = z.object({\n storage: z\n .boolean()\n .default(false)\n .describe('Enable persistent storage for session/device IDs')\n .optional(),\n\n consent: z\n .union([z.string(), z.array(z.string())])\n .describe('Consent key(s) required to enable storage mode')\n .optional(),\n\n length: z\n .number()\n .default(30)\n .describe('Session timeout in minutes')\n .optional(),\n\n pulse: z\n .boolean()\n .default(false)\n .describe('Keep session alive on each event')\n .optional(),\n\n sessionKey: z\n .string()\n .default('elbSessionId')\n .describe('Storage key for session ID')\n .optional(),\n\n sessionStorage: z\n .enum(['local', 'session'])\n .default('local')\n .describe('Storage type for session')\n .optional(),\n\n deviceKey: z\n .string()\n .default('elbDeviceId')\n .describe('Storage key for device ID')\n .optional(),\n\n deviceStorage: z\n .enum(['local', 'session'])\n .default('local')\n .describe('Storage type for device')\n .optional(),\n\n deviceAge: z\n .number()\n .default(30)\n .describe('Device ID age in days')\n .optional(),\n\n // Note: Using z.any() because z.custom() cannot be converted to JSON Schema\n // TypeScript types provide compile-time safety; runtime accepts function or false\n cb: z\n .any()\n .describe('Custom session callback function or false to disable')\n .optional(),\n\n clickIds: z\n .array(ClickIdEntrySchema)\n .describe(\n 'Custom click-ID registry. Entries with a `param` matching a default override the platform name in place; new params append to the end of the priority list.',\n )\n .optional(),\n});\n\nexport type Settings = z.infer<typeof SettingsSchema>;\n","export * as step from './step';\nexport { createTrigger, trigger } from './trigger';\n","import type { Flow } from '@walkeros/core';\n\n/**\n * Session source emits three elb calls on start:\n * 1. command('user', { session, device? })\n * 2. command('session', <full session data>)\n * 3. push({ name: 'session start', data: <full session data> })\n */\n\nexport const newMarketingSession: Flow.StepExample = {\n title: 'New marketing session',\n description:\n 'A visit with UTM parameters starts a new session and emits walker user, session, and session start calls.',\n trigger: {\n type: 'load',\n options: {\n url: 'https://example.com/?utm_source=google&utm_medium=cpc&utm_campaign=winter-sale',\n },\n },\n in: { storage: true },\n out: [\n ['elb', 'user', { session: 's3ss10n-id', device: 'd3v1c3-id' }],\n [\n 'elb',\n 'session',\n {\n id: 's3ss10n-id',\n start: 1700000000000,\n isNew: true,\n count: 1,\n runs: 1,\n marketing: true,\n source: 'google',\n medium: 'cpc',\n campaign: 'winter-sale',\n referrer: '',\n device: 'd3v1c3-id',\n isStart: true,\n storage: true,\n updated: 1700000000000,\n },\n ],\n [\n 'elb',\n {\n name: 'session start',\n data: {\n id: 's3ss10n-id',\n start: 1700000000000,\n isNew: true,\n count: 1,\n runs: 1,\n marketing: true,\n source: 'google',\n medium: 'cpc',\n campaign: 'winter-sale',\n referrer: '',\n device: 'd3v1c3-id',\n isStart: true,\n storage: true,\n updated: 1700000000000,\n },\n },\n ],\n ],\n};\n\nexport const returningVisitor: Flow.StepExample = {\n title: 'Returning visitor',\n description:\n 'A returning visit with a google referrer reuses the stored device id and increments the session count.',\n trigger: {\n type: 'load',\n options: {\n referrer: 'https://google.com',\n },\n },\n in: { storage: true },\n out: [\n ['elb', 'user', { session: 'n3w-s3ss10n', device: 'd3v1c3-id' }],\n [\n 'elb',\n 'session',\n {\n id: 'n3w-s3ss10n',\n start: 1700001000000,\n isNew: false,\n count: 3,\n runs: 1,\n referrer: 'google.com',\n device: 'd3v1c3-id',\n isStart: true,\n storage: true,\n updated: 1700001000000,\n },\n ],\n [\n 'elb',\n {\n name: 'session start',\n data: {\n id: 'n3w-s3ss10n',\n start: 1700001000000,\n isNew: false,\n count: 3,\n runs: 1,\n referrer: 'google.com',\n device: 'd3v1c3-id',\n isStart: true,\n storage: true,\n updated: 1700001000000,\n },\n },\n ],\n ],\n};\n","import type { Trigger, Collector } from '@walkeros/core';\nimport { startFlow } from '@walkeros/collector';\n\ninterface SessionTriggerOptions {\n url?: string;\n referrer?: string;\n sessionData?: Record<string, unknown>;\n deviceId?: string;\n sessionKey?: string;\n deviceKey?: string;\n}\n\nconst createTrigger: Trigger.CreateFn<Record<string, unknown>, void> = async (\n config: Collector.InitConfig,\n) => {\n let flow: Trigger.FlowHandle | undefined;\n\n const trigger: Trigger.Fn<Record<string, unknown>, void> =\n (type?: string, opts?: unknown) =>\n async (content: Record<string, unknown>) => {\n const options = (opts || {}) as SessionTriggerOptions;\n\n // Pre-init: seed world state before source reads it\n if (options.url) {\n const urlObj = new URL(options.url);\n window.history.replaceState({}, '', urlObj.pathname + urlObj.search);\n }\n if (options.referrer) {\n Object.defineProperty(document, 'referrer', {\n value: options.referrer,\n configurable: true,\n });\n }\n if (options.sessionData) {\n const key = options.sessionKey || 'elbSessionId';\n localStorage.setItem(key, JSON.stringify(options.sessionData));\n }\n if (options.deviceId) {\n const key = options.deviceKey || 'elbDeviceId';\n localStorage.setItem(key, options.deviceId);\n }\n\n // Lazy startFlow — session source fires events during init, but\n // collector.allowed is false until command('run'). The initial\n // session event is dropped. After startFlow, clear the session\n // data written by the dropped init, re-seed, and trigger a consent\n // update to cause session re-init with allowed=true.\n if (!flow) {\n const result = await startFlow({ ...config, run: config.run ?? true });\n flow = { collector: result.collector, elb: result.elb };\n\n // Clear session data written by the dropped init\n const sessionKey =\n options.sessionKey ||\n ((\n config.sources?.session?.config?.settings as Record<string, unknown>\n )?.sessionKey as string) ||\n 'elbSessionId';\n const deviceKey =\n options.deviceKey ||\n ((\n config.sources?.session?.config?.settings as Record<string, unknown>\n )?.deviceKey as string) ||\n 'elbDeviceId';\n localStorage.removeItem(sessionKey);\n localStorage.removeItem(deviceKey);\n\n // Re-seed localStorage if trigger options specified session data\n if (options.sessionData) {\n localStorage.setItem(sessionKey, JSON.stringify(options.sessionData));\n }\n if (options.deviceId) {\n localStorage.setItem(deviceKey, options.deviceId);\n }\n\n // Re-apply consent to trigger session source on('consent') handler.\n // Now allowed=true so the session start event reaches destinations.\n if (config.consent) {\n await flow.collector.command('consent', config.consent);\n }\n }\n };\n\n return {\n get flow() {\n return flow;\n },\n trigger,\n };\n};\n\n/** Prepares localStorage with session/device data before source init. */\nconst trigger = (input: unknown, env: Record<string, unknown>): void => {\n if (!input || typeof input !== 'object') return;\n const data = input as Record<string, unknown>;\n const storage = env.localStorage as Storage;\n\n if (data.sessionData && typeof data.sessionData === 'object') {\n const key =\n typeof data.sessionKey === 'string' ? data.sessionKey : 'elbSessionId';\n storage.setItem(key, JSON.stringify(data.sessionData));\n }\n\n if (typeof data.deviceId === 'string') {\n const key =\n typeof data.deviceKey === 'string' ? data.deviceKey : 'elbDeviceId';\n storage.setItem(key, data.deviceId);\n }\n};\n\nexport { createTrigger, trigger };\n"],"mappings":"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","names":["import_dev","trigger","_e"]}
1
+ {"version":3,"sources":["../src/dev.ts","../src/schemas/index.ts","../src/schemas/settings.ts","../src/examples/index.ts","../src/examples/step.ts","../src/examples/trigger.ts"],"sourcesContent":["export * as schemas from './schemas';\nexport * as examples from './examples';\n","import { zodToSchema } from '@walkeros/core/dev';\nimport { SettingsSchema } from './settings';\n\n// Export Zod schemas and types\nexport { SettingsSchema, type Settings } from './settings';\n\n// JSON Schema exports (for website PropertyTable)\nexport const settings = zodToSchema(SettingsSchema);\n","import { z, ClickIdEntrySchema } from '@walkeros/core/dev';\n\n/**\n * Session source settings schema\n */\nexport const SettingsSchema = z.object({\n storage: z\n .boolean()\n .default(false)\n .describe('Enable persistent storage for session/device IDs')\n .optional(),\n\n consent: z\n .union([z.string(), z.array(z.string())])\n .describe('Consent key(s) required to enable storage mode')\n .optional(),\n\n length: z\n .number()\n .default(30)\n .describe('Session timeout in minutes')\n .optional(),\n\n pulse: z\n .boolean()\n .default(false)\n .describe('Keep session alive on each event')\n .optional(),\n\n sessionKey: z\n .string()\n .default('elbSessionId')\n .describe('Storage key for session ID')\n .optional(),\n\n sessionStorage: z\n .enum(['local', 'session'])\n .default('local')\n .describe('Storage type for session')\n .optional(),\n\n deviceKey: z\n .string()\n .default('elbDeviceId')\n .describe('Storage key for device ID')\n .optional(),\n\n deviceStorage: z\n .enum(['local', 'session'])\n .default('local')\n .describe('Storage type for device')\n .optional(),\n\n deviceAge: z\n .number()\n .default(30)\n .describe('Device ID age in days')\n .optional(),\n\n // Note: Using z.any() because z.custom() cannot be converted to JSON Schema\n // TypeScript types provide compile-time safety; runtime accepts function or false\n cb: z\n .any()\n .describe('Custom session callback function or false to disable')\n .optional(),\n\n clickIds: z\n .array(ClickIdEntrySchema)\n .describe(\n 'Custom click-ID registry. Entries with a `param` matching a default override the platform name in place; new params append to the end of the priority list.',\n )\n .optional(),\n});\n\nexport type Settings = z.infer<typeof SettingsSchema>;\n","export * as step from './step';\nexport { createTrigger, trigger } from './trigger';\n","import type { Flow } from '@walkeros/core';\n\n/**\n * Session source emits three elb calls on start:\n * 1. command('user', { session, device? })\n * 2. command('session', <full session data>)\n * 3. push({ name: 'session start', data: <full session data> })\n */\n\nexport const newMarketingSession: Flow.StepExample = {\n title: 'New marketing session',\n description:\n 'A visit with UTM parameters starts a new session and emits walker user, session, and session start calls.',\n trigger: {\n type: 'load',\n options: {\n url: 'https://example.com/?utm_source=google&utm_medium=cpc&utm_campaign=winter-sale',\n },\n },\n in: { storage: true },\n out: [\n ['elb', 'user', { session: 's3ss10n-id', device: 'd3v1c3-id' }],\n [\n 'elb',\n 'session',\n {\n id: 's3ss10n-id',\n start: 1700000000000,\n isNew: true,\n count: 1,\n runs: 1,\n marketing: true,\n source: 'google',\n medium: 'cpc',\n campaign: 'winter-sale',\n referrer: '',\n device: 'd3v1c3-id',\n isStart: true,\n storage: true,\n updated: 1700000000000,\n },\n ],\n [\n 'elb',\n {\n name: 'session start',\n data: {\n id: 's3ss10n-id',\n start: 1700000000000,\n isNew: true,\n count: 1,\n runs: 1,\n marketing: true,\n source: 'google',\n medium: 'cpc',\n campaign: 'winter-sale',\n referrer: '',\n device: 'd3v1c3-id',\n isStart: true,\n storage: true,\n updated: 1700000000000,\n },\n },\n ],\n ],\n};\n\nexport const returningVisitor: Flow.StepExample = {\n title: 'Returning visitor',\n description:\n 'A returning visit with a google referrer reuses the stored device id and increments the session count.',\n trigger: {\n type: 'load',\n options: {\n referrer: 'https://google.com',\n },\n },\n in: { storage: true },\n out: [\n ['elb', 'user', { session: 'n3w-s3ss10n', device: 'd3v1c3-id' }],\n [\n 'elb',\n 'session',\n {\n id: 'n3w-s3ss10n',\n start: 1700001000000,\n isNew: false,\n count: 3,\n runs: 1,\n referrer: 'google.com',\n device: 'd3v1c3-id',\n isStart: true,\n storage: true,\n updated: 1700001000000,\n },\n ],\n [\n 'elb',\n {\n name: 'session start',\n data: {\n id: 'n3w-s3ss10n',\n start: 1700001000000,\n isNew: false,\n count: 3,\n runs: 1,\n referrer: 'google.com',\n device: 'd3v1c3-id',\n isStart: true,\n storage: true,\n updated: 1700001000000,\n },\n },\n ],\n ],\n};\n","import type { Trigger, Collector } from '@walkeros/core';\nimport { startFlow } from '@walkeros/collector';\n\ninterface SessionTriggerOptions {\n url?: string;\n referrer?: string;\n sessionData?: Record<string, unknown>;\n deviceId?: string;\n sessionKey?: string;\n deviceKey?: string;\n}\n\nconst createTrigger: Trigger.CreateFn<Record<string, unknown>, void> = async (\n config: Collector.InitConfig,\n) => {\n let flow: Trigger.FlowHandle | undefined;\n\n const trigger: Trigger.Fn<Record<string, unknown>, void> =\n (type?: string, opts?: unknown) =>\n async (content: Record<string, unknown>) => {\n const options = (opts || {}) as SessionTriggerOptions;\n\n // Pre-init: seed world state before source reads it\n if (options.url) {\n const urlObj = new URL(options.url);\n window.history.replaceState({}, '', urlObj.pathname + urlObj.search);\n }\n if (options.referrer) {\n Object.defineProperty(document, 'referrer', {\n value: options.referrer,\n configurable: true,\n });\n }\n if (options.sessionData) {\n const key = options.sessionKey || 'elbSessionId';\n localStorage.setItem(key, JSON.stringify(options.sessionData));\n }\n if (options.deviceId) {\n const key = options.deviceKey || 'elbDeviceId';\n localStorage.setItem(key, options.deviceId);\n }\n\n // Lazy startFlow — session source fires events during init, but\n // collector.allowed is false until command('run'). The initial\n // session event is dropped. After startFlow, clear the session\n // data written by the dropped init, re-seed, and trigger a consent\n // update to cause session re-init with allowed=true.\n if (!flow) {\n const result = await startFlow({ ...config, run: config.run ?? true });\n flow = { collector: result.collector, elb: result.elb };\n\n // Clear session data written by the dropped init\n const sessionKey =\n options.sessionKey ||\n ((\n config.sources?.session?.config?.settings as Record<string, unknown>\n )?.sessionKey as string) ||\n 'elbSessionId';\n const deviceKey =\n options.deviceKey ||\n ((\n config.sources?.session?.config?.settings as Record<string, unknown>\n )?.deviceKey as string) ||\n 'elbDeviceId';\n localStorage.removeItem(sessionKey);\n localStorage.removeItem(deviceKey);\n\n // Re-seed localStorage if trigger options specified session data\n if (options.sessionData) {\n localStorage.setItem(sessionKey, JSON.stringify(options.sessionData));\n }\n if (options.deviceId) {\n localStorage.setItem(deviceKey, options.deviceId);\n }\n\n // Re-apply consent to trigger session source on('consent') handler.\n // Now allowed=true so the session start event reaches destinations.\n if (config.consent) {\n await flow.collector.command('consent', config.consent);\n }\n }\n };\n\n return {\n get flow() {\n return flow;\n },\n trigger,\n };\n};\n\n/** Prepares localStorage with session/device data before source init. */\nconst trigger = (input: unknown, env: Record<string, unknown>): void => {\n if (!input || typeof input !== 'object') return;\n const data = input as Record<string, unknown>;\n const storage = env.localStorage as Storage;\n\n if (data.sessionData && typeof data.sessionData === 'object') {\n const key =\n typeof data.sessionKey === 'string' ? data.sessionKey : 'elbSessionId';\n storage.setItem(key, JSON.stringify(data.sessionData));\n }\n\n if (typeof data.deviceId === 'string') {\n const key =\n typeof data.deviceKey === 'string' ? data.deviceKey : 'elbDeviceId';\n storage.setItem(key, data.deviceId);\n }\n};\n\nexport { createTrigger, trigger };\n"],"mappings":"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","names":["import_dev","trigger","_e"]}
package/dist/dev.mjs CHANGED
@@ -1 +1 @@
1
- var e=Object.defineProperty,t=(t,n)=>{for(var o in n)e(t,o,{get:n[o],enumerable:!0})},n={};t(n,{SettingsSchema:()=>i,settings:()=>a});import{zodToSchema as o}from"@walkeros/core/dev";import{z as s,ClickIdEntrySchema as r}from"@walkeros/core/dev";var i=s.object({storage:s.boolean().default(!1).describe("Enable persistent storage for session/device IDs").optional(),consent:s.union([s.string(),s.array(s.string())]).describe("Consent key(s) required to enable storage mode").optional(),length:s.number().default(30).describe("Session timeout in minutes").optional(),pulse:s.boolean().default(!1).describe("Keep session alive on each event").optional(),sessionKey:s.string().default("elbSessionId").describe("Storage key for session ID").optional(),sessionStorage:s.enum(["local","session"]).default("local").describe("Storage type for session").optional(),deviceKey:s.string().default("elbDeviceId").describe("Storage key for device ID").optional(),deviceStorage:s.enum(["local","session"]).default("local").describe("Storage type for device").optional(),deviceAge:s.number().default(30).describe("Device ID age in days").optional(),cb:s.any().describe("Custom session callback function or false to disable").optional(),clickIds:s.array(r).describe("Custom click-ID registry. Entries with a `param` matching a default override the platform name in place; new params append to the end of the priority list.").optional()}),a=o(i),c={};t(c,{createTrigger:()=>vt,step:()=>l,trigger:()=>yt});var l={};t(l,{newMarketingSession:()=>u,returningVisitor:()=>d});var u={title:"New marketing session",description:"A visit with UTM parameters starts a new session and emits walker user, session, and session start calls.",trigger:{type:"load",options:{url:"https://example.com/?utm_source=google&utm_medium=cpc&utm_campaign=winter-sale"}},in:{storage:!0},out:[["elb","user",{session:"s3ss10n-id",device:"d3v1c3-id"}],["elb","session",{id:"s3ss10n-id",start:17e11,isNew:!0,count:1,runs:1,marketing:!0,source:"google",medium:"cpc",campaign:"winter-sale",referrer:"",device:"d3v1c3-id",isStart:!0,storage:!0,updated:17e11}],["elb",{name:"session start",data:{id:"s3ss10n-id",start:17e11,isNew:!0,count:1,runs:1,marketing:!0,source:"google",medium:"cpc",campaign:"winter-sale",referrer:"",device:"d3v1c3-id",isStart:!0,storage:!0,updated:17e11}}]]},d={title:"Returning visitor",description:"A returning visit with a google referrer reuses the stored device id and increments the session count.",trigger:{type:"load",options:{referrer:"https://google.com"}},in:{storage:!0},out:[["elb","user",{session:"n3w-s3ss10n",device:"d3v1c3-id"}],["elb","session",{id:"n3w-s3ss10n",start:1700001e6,isNew:!1,count:3,runs:1,referrer:"google.com",device:"d3v1c3-id",isStart:!0,storage:!0,updated:1700001e6}],["elb",{name:"session start",data:{id:"n3w-s3ss10n",start:1700001e6,isNew:!1,count:3,runs:1,referrer:"google.com",device:"d3v1c3-id",isStart:!0,storage:!0,updated:1700001e6}}]]};import{assign as f}from"@walkeros/core";import{assign as p,createLogger as g}from"@walkeros/core";import{assign as h,buildCacheContext as m,clone as v,compileCache as y,checkCache as w,storeCache as b,createIngest as k,debounce as I,emitStep as S,getId as q,getGrantedConsent as x,getNextSteps as O,isDefined as D,isFunction as C,isObject as j,processEventMapping as A,stepId as E,tryCatchAsync as $,useHooks as M}from"@walkeros/core";import{emitStep as T}from"@walkeros/core";import{isArray as _,FatalError as P}from"@walkeros/core";import{tryCatch as K,tryCatchAsync as z}from"@walkeros/core";import{createIngest as R,FatalError as F,getMappingValue as H,tryCatchAsync as N,getNextSteps as B,compileCache as G,checkCache as U,storeCache as W,applyUpdate as L,buildCacheContext as J}from"@walkeros/core";import{createIngest as V,emitStep as Y,FatalError as Q,isObject as X,stepId as Z,tryCatchAsync as ee,useHooks as te,getNextSteps as ne,compileCache as oe,checkCache as se,storeCache as re,buildCacheContext as ie,validateStepEntry as ae,processEventMapping as ce}from"@walkeros/core";import{assign as le,getSpanId as ue,isFunction as de,isString as fe}from"@walkeros/core";import{isObject as pe}from"@walkeros/core";import{createIngest as ge,emitStep as he,FatalError as me,getGrantedConsent as ve,processEventMapping as ye,tryCatchAsync as we,useHooks as be}from"@walkeros/core";import{FatalError as ke,useHooks as Ie,tryCatchAsync as Se}from"@walkeros/core";import{emitStep as qe,useHooks as xe}from"@walkeros/core";import{compileMatcher as Oe,emitStep as De}from"@walkeros/core";var Ce={Action:"action",Actions:"actions",Config:"config",Consent:"consent",Context:"context",Custom:"custom",Destination:"destination",Elb:"elb",Globals:"globals",Hook:"hook",Init:"init",Link:"link",On:"on",Prefix:"data-elb",Ready:"ready",Run:"run",Session:"session",Shutdown:"shutdown",User:"user",Walker:"walker"};function je(e,t){const n=e.status.startedAt;return{flowId:"default",stepId:t.stepId,stepType:t.stepType,phase:t.phase,eventId:t.eventId,timestamp:new Date(t.now).toISOString(),elapsedMs:t.now-n}}function Ae(e,t){return e.storeId&&t.stores[e.storeId]?t.stores[e.storeId]:t.stores.__cache}function Ee(e){var t;const n={};for(const[o,s]of Object.entries(e)){const e=null==(t=s.config)?void 0:t.next;"string"==typeof e||Array.isArray(e)&&e.every(e=>"string"==typeof e)?n[o]={next:e}:n[o]={}}return n}function $e(e,t){const n=e.config||{},o=e[t];return void 0!==o?{config:{...n,[t]:o},chainValue:o}:{config:n,chainValue:void 0}}function Me(e,t={}){if(!e)return[];if(Array.isArray(e))return e;const n=[],o=new Set;let s=e;for(;s&&t[s]&&!o.has(s);){o.add(s),n.push(s);const e=t[s].next;if(Array.isArray(e)){n.push(...e);break}s=e}return n}async function Te(e,t,n){if(t.init&&!t.config.init){const o=t.type||"unknown",s=e.logger.scope(`transformer:${o}`),r={collector:e,logger:s,id:n,ingest:V(n),config:t.config,env:ze(t.config.env)};s.debug("init");const i=await te(t.init,"TransformerInit",e.hooks,e.logger)(r);if(!1===i)return!1;t.config={...i||t.config,env:(null==i?void 0:i.env)||t.config.env,init:!0},s.debug("init done")}return!0}async function _e(e,t,n,o,s,r){const i=t.type||"unknown",a=e.logger.scope(`transformer:${i}`),c={collector:e,logger:a,id:n,ingest:s,config:t.config,env:{...ze(t.config.env),...r?{respond:r}:{}}};a.debug("push",{event:o.name});const l="string"==typeof o.id?o.id:"",u=Date.now(),d=je(e,{stepId:Z("transformer",n),stepType:"transformer",phase:"in",eventId:l,now:u});Y(e,d);try{const s=await te(t.push,"TransformerPush",e.hooks,e.logger)(o,c),r=Date.now(),i=je(e,{stepId:Z("transformer",n),stepType:"transformer",phase:"out",eventId:l,now:r});return i.durationMs=r-u,i.outEvent=s,Y(e,i),a.debug("push done"),s}catch(t){const o=Date.now(),s=je(e,{stepId:Z("transformer",n),stepType:"transformer",phase:"error",eventId:l,now:o});throw s.durationMs=o-u,s.error=t instanceof Error?{name:t.name,message:t.message}:{message:String(t)},Y(e,s),t}}function Pe(e,t){return e?{...e,_meta:{...e._meta,path:[...e._meta.path]}}:V(t)}async function Ke(e,t,n,o,s,r,i){var a,c,l,u,d,f,p,g;s||(s=V(null!=(a=n[0])?a:"chain")),i&&s._meta&&(s._meta.chainPath=i);let h=o,m=r;for(const o of n){const r=t[o];if(!r){e.logger.warn(`Transformer not found: ${o}`);continue}if(s&&s._meta&&s._meta.path.length>256)return e.logger.error(`Max path length exceeded at ${o}`),{event:null,respond:m};if(s&&s._meta&&(s._meta.hops++,s._meta.path.push(o)),!await ee(Te,t=>{if(t instanceof Q)throw t;return e.status.failed++,e.logger.scope(`transformer:${r.type||"unknown"}`).error("transformer init failed",{transformer:o,error:t}),!1})(e,r,o))return{event:null,respond:m};if(i&&void 0!==(null==(l=null==(c=r.config)?void 0:c.chainMocks)?void 0:l[i])){const t=r.config.chainMocks[i];e.logger.scope(`transformer:${r.type||"unknown"}`).debug("chainMock",{chain:i}),h=t;continue}if(void 0!==(null==(u=r.config)?void 0:u.mock)){e.logger.scope(`transformer:${r.type||"unknown"}`).debug("mock"),h=r.config.mock;continue}if(null==(d=r.config)?void 0:d.disabled)continue;const a=null==(f=r.config)?void 0:f.cache,v=a?oe(a):void 0,y=v?Ae(v,e):void 0;let w;if(v&&y){const e=ie(s,h),t=await se(v,y,e);if("HIT"===(null==t?void 0:t.status)&&t.value){if(h=t.value,v.stop)return{event:h,respond:m,stopped:!0};continue}"MISS"===(null==t?void 0:t.status)&&(w={key:t.key,ttl:t.rule.ttl})}const b=r.config.before;if(b){const n=ne(b,ie(s,h));if(1===n.length){const o=Me(n[0],Ee(t));if(o.length>0){const n=await Ke(e,t,o,h,s,m,i);if(null===n.event)return{event:null,respond:null!=(p=n.respond)?p:m};if(n.stopped)return{event:Array.isArray(n.event)?n.event[0]:n.event,respond:null!=(g=n.respond)?g:m,stopped:!0};n.respond&&(m=n.respond),h=Array.isArray(n.event)?n.event[0]:n.event}}else n.length>1&&await Promise.all(n.map(n=>ee(Ke,t=>(e.logger.scope("transformer:many").error(`many branch ${n} failed`,{error:t}),{event:null,respond:void 0}))(e,t,Me(n,Ee(t)),h,Pe(s,n),void 0,i)))}const k=await ee(_e,t=>(e.logger.scope(`transformer:${r.type||"unknown"}`).error("Push failed",{error:t}),!1))(e,r,o,h,s,m);if(!1===k)return{event:null,respond:m};if(Array.isArray(k)){const r=n.slice(n.indexOf(o)+1),a=await Promise.all(k.map(async n=>{const o=n.event||h,a=Pe(s,"unknown");if(n.next){const s=ne(n.next,ie(a,o));if(0===s.length)return{event:o,respond:m};if(1===s.length){const n=Me(s[0],Ee(t));return n.length>0?Ke(e,t,n,o,a,m,i):{event:o,respond:m}}return(await Promise.all(s.map(n=>ee(Ke,t=>(e.logger.scope("transformer:many").error(`many branch ${n} failed`,{error:t}),{event:null,respond:void 0}))(e,t,Me(n,Ee(t)),o,Pe(a,n),void 0,i)))).map(e=>({event:e.event,respond:void 0}))}return r.length>0?Ke(e,t,r,o,a,m,i):{event:o,respond:m}}));let c=m;const l=[];for(const e of a.flat())if(null!==e)if(e&&"object"==typeof e&&"event"in e){const t=e;if(t.respond&&(c=t.respond),null===t.event)continue;Array.isArray(t.event)?l.push(...t.event):l.push(t.event)}else l.push(e);return 0===l.length?{event:null,respond:c}:1===l.length?{event:l[0],respond:c}:{event:l,respond:c}}if(k&&"object"==typeof k){const{event:n,respond:o,next:r}=k;if(o&&(m=o),void 0!==r){const o=ne(r,ie(s,h));if(0===o.length){n&&(h=n);continue}if(1===o.length){const a=Me(o[0],Ee(t));return a.length>0?Ke(e,t,a,n||h,s,m,i):(e.logger.warn(`Branch target not found: ${JSON.stringify(r)}`),{event:null,respond:m})}return await Promise.all(o.map(o=>ee(Ke,t=>(e.logger.scope("transformer:many").error(`many branch ${o} failed`,{error:t}),{event:null,respond:void 0}))(e,t,Me(o,Ee(t)),n||h,Pe(s,o),void 0,i))),{event:null,respond:void 0}}n&&(h=n)}w&&y&&re(y,w.key,h,w.ttl);const I=r.config.next,S="string"==typeof I||Array.isArray(I)&&I.every(e=>"string"==typeof e),q=void 0!==I&&!S;if((!k||"object"==typeof k&&!k.next)&&q){const n=ne(r.config.next,ie(s,h));if(1===n.length){const o=Me(n[0],Ee(t));return o.length>0?Ke(e,t,o,h,s,m,i):{event:h,respond:m}}return n.length>1?(await Promise.all(n.map(n=>ee(Ke,t=>(e.logger.scope("transformer:many").error(`many branch ${n} failed`,{error:t}),{event:null,respond:void 0}))(e,t,Me(n,Ee(t)),h,Pe(s,n),void 0,i))),{event:null,respond:void 0}):{event:h,respond:m}}}return{event:h,respond:m}}function ze(e){return e&&X(e)?e:{}}function Re(e){return"string"==typeof e||!(!Array.isArray(e)||!e.every(e=>"string"==typeof e))}async function Fe(e,t,n){var o,s;if(!t.on||!(null==(o=t.queueOn)?void 0:o.length))return;const r=t.queueOn;t.queueOn=[];const i=n||(null==(s=t.config)?void 0:s.id)||"unknown";for(const{type:n,data:o}of r)await N(t.on,t=>{if(t instanceof F)throw t;e.status.failed++,e.logger.scope("source").error("source on flush failed",{sourceId:i,type:n,error:t})})(n,o)}function He(e){var t;return Boolean(e.config.init)&&!(null==(t=e.config.require)?void 0:t.length)}async function Ne(e,t,n){var o;const{code:s,config:r={},env:i={},primary:a,next:c,before:l,cache:u}=n,d=u,f=d?G({...d,stop:null==(o=d.stop)||o}):void 0,p=Re(c)?Me(c,Ee(e.transformers)):void 0,g=Re(l)?Me(l,Ee(e.transformers)):void 0,h=i.push,m=null!=h?h:e.push,v=Boolean(h),y=async(n,o,s)=>{var i;let a;const u=null!=g?g:void 0!==l?(()=>{const t=B(l,J(s.ingest));return 0===t.length?[]:Me(1===t.length?t[0]:t,Ee(e.transformers))})():[];let d=[n];if(u.length>0&&e.transformers&&Object.keys(e.transformers).length>0){const o=await Ke(e,e.transformers,u,n,s.ingest,s.respond,`source.${t}.before`);if(null===o.event)return{ok:!0};if(o.stopped)return o.respond&&(s.respond=o.respond),{ok:!0};o.respond&&(s.respond=o.respond),d=Array.isArray(o.event)?o.event:[o.event]}if(f){const t=Ae(f,e);if(t){const n=J(s.ingest),o=await U(f,t,n);if(o){if("HIT"===o.status&&void 0!==o.value&&f.stop){let t=o.value;return o.rule.update&&(t=await L(t,o.rule.update,{...n,cache:{status:"HIT"}},e)),null==(i=s.respond)||i.call(s,t),{ok:!0}}if("MISS"===o.status&&f.stop&&s.respond){const r=s.respond,i=o.rule.update,c={...n,cache:{status:"MISS"}},l=o.key,u=o.rule.ttl,d=n=>{W(t,l,n,u),i?a=(async()=>{const t=await L(n,i,c,e);r(t)})():r(n)};s.respond=d}"MISS"!==o.status||f.stop||W(t,o.key,!0,o.rule.ttl)}}}const h=p?{kind:"single",preChain:p}:void 0!==c?(()=>{const t=B(c,J(s.ingest));return 0===t.length?{kind:"single",preChain:[]}:1===t.length?{kind:"single",preChain:Me(t[0],Ee(e.transformers))}:{kind:"many",branches:t.map(t=>Me(t,Ee(e.transformers)))}})():{kind:"single",preChain:[]};let y={ok:!0};for(const n of d)"many"===h.kind?(await Promise.all(h.branches.map((i,a)=>N(async()=>v?m(n):m(n,{...o,id:t,ingest:Pe(s.ingest,`${t}.${a}`),respond:void 0,mapping:r,preChain:i}),t=>(e.logger.scope("source:many").error(`many branch ${a} failed`,{error:t}),{ok:!0}))())),y={ok:!0}):y=v?await m(n):await m(n,{...o,id:t,ingest:s.ingest,respond:s.respond,mapping:r,preChain:h.preChain});return a&&await a,y},w=async n=>{const o=R(t);if(!r.ingest||void 0===n)return o;const s=await H(n,r.ingest,{collector:e});return{...o,...s,_meta:o._meta}},b=e.logger.scope("source").scope(t),k={command:e.command,sources:e.sources,elb:e.sources.elb.push,logger:b,...i,push:async(e,n={})=>{const o={ingest:R(t),respond:void 0};return y(e,n,o)}},I={collector:e,logger:b,id:t,config:r,env:k,withScope:async(e,t,n)=>{const o={ingest:await w(e),respond:t};return n({...k,push:(e,t={})=>y(e,t,o),ingest:o.ingest,respond:o.respond})}},S=await N(s,n=>{if(n instanceof F)throw n;e.status.failed++,e.logger.scope("source").error("source factory failed",{sourceId:t,error:n})})(I);if(!S)return;const q=S.type||"unknown",x=e.logger.scope(q).scope(t);return k.logger=x,a&&(S.config={...S.config,primary:a}),S}function Be(e,t,n,o){if(n instanceof P)throw n;e.logger.scope("on").error("on callback failed",{kind:t,...o,error:n})}function Ge(e,t){return{collector:e,logger:e.logger.scope("on").scope(String(t))}}function Ue(e,t,n,o,s){if(!t.on)return;const r=t.type||"unknown",i=e.logger.scope(r).scope("on").scope(o),a={collector:e,logger:i,id:n,config:t.config,data:s,env:ct(t.env,t.config.env)};K(t.on,t=>Be(e,"destination",t,{destId:n,type:o}))(o,a)}function We(e,t,n,o){let s;switch(t){case Ce.Consent:s=o||e.consent;break;case Ce.Session:s=e.session;break;case Ce.User:s=o||e.user;break;case Ce.Custom:s=o||e.custom;break;case Ce.Globals:s=o||e.globals;break;case Ce.Config:s=o||e.config;break;case Ce.Ready:case Ce.Run:default:s=void 0}if(n.length)switch(t){case Ce.Consent:!function(e,t,n){const o=n||e.consent,s=Ge(e,Ce.Consent);t.forEach(t=>{Object.keys(o).filter(e=>e in t).forEach(n=>{K(t[n],t=>Be(e,"consent",t,{key:n}))(o,s)})})}(e,n,o);break;case Ce.Ready:!function(e,t){if(!e.allowed)return;const n=Ge(e,Ce.Ready);t.forEach(t=>{K(t,t=>Be(e,"ready",t))(void 0,n)})}(e,n);break;case Ce.Run:!function(e,t){if(!e.allowed)return;const n=Ge(e,Ce.Run);t.forEach(t=>{K(t,t=>Be(e,"run",t))(void 0,n)})}(e,n);break;case Ce.Session:!function(e,t){if(!e.session)return;const n=Ge(e,Ce.Session);t.forEach(t=>{K(t,t=>Be(e,"session",t))(e.session,n)})}(e,n);break;default:{const o=Ge(e,t);n.forEach(n=>{"function"==typeof n&&K(n,n=>Be(e,"generic",n,{type:t}))(s,o)});break}}}function Le(e,t,n,o){var s;if(!Number.isFinite(n.max)||n.max<=0)throw new Error(`pushBounded: max must be > 0 (got ${n.max})`);if("dropNewest"===(null!=(s=n.onOverflow)?s:"dropOldest"))return e.length>=n.max?(o&&o([t]),{appended:!1,dropped:1}):(e.push(t),{appended:!0,dropped:0});const r=[];for(;e.length>=n.max;)r.push(e.shift());return e.push(t),r.length>0&&o&&o(r),{appended:!0,dropped:r.length}}var Je=new WeakMap;function Ve(e,t,n,o){Je.get(e)||(Je.set(e,!0),t.warn(n,o))}function Ye(e){Je.delete(e)}var Qe=Object.freeze({batched:!0});function Xe(e){return e===Qe}function Ze(e){return void 0===e?{}:"number"==typeof e?{wait:e}:{wait:e.wait,size:e.size,age:e.age}}function et(e,t){return e.status.destinations[t]||(e.status.destinations[t]={count:0,failed:0,duration:0,queuePushSize:0,dlqSize:0}),e.status.destinations[t]}function tt(e,t,n,o){var s;e.dropped[t]||(e.dropped[t]={});const r=e.dropped[t];return r[n]=(null!=(s=r[n])?s:0)+o,r[n]}function nt(e,t,n){if(!e)return[];if(Array.isArray(e)&&e.every(e=>"string"==typeof e))return Me(e,t);if("string"==typeof e)return Me(e,t);const o=O(e,m(n));return 0===o.length?[]:1===o.length?Me(o[0],t):Me(o,t)}async function ot(e,t,n={},o){var s,r,i,a,c,l;const{allowed:u,consent:d,globals:f,user:p}=e;if(!u)return it({ok:!1});if(t){const n=e.config.queueMax;if(void 0===n)throw new Error("Collector.Config.queueMax is undefined; defaults must be seeded by collector()");const o=Le(e.queue,t,{max:n});if(o.dropped>0){const t=tt(e.status,E("collector"),"queue",o.dropped);Ve(e.queue,e.logger,"collector.queue overflow; oldest events dropped",{buffer:"queue",cap:n,droppedCount:t})}else e.queue.length<n&&Ye(e.queue);e.status.in++}o||(o=e.destinations);const g=e.transformers?Ee(e.transformers):{},I=await Promise.all(Object.entries(o||{}).map(async([o,s])=>{var r,i,a,c;if(s.config.disabled)return{id:o,destination:s,skipped:!0};let l=(s.queuePush||[]).map(e=>({...e,consent:d}));s.queuePush=[],t&&l.push(v(t));const u=n.ingest?{...n.ingest,_meta:{...n.ingest._meta,path:[...n.ingest._meta.path]}}:k("unknown");if(!l.length&&!(null==(r=s.queueOn)?void 0:r.length))return{id:o,destination:s,skipped:!0};if(!l.length&&(null==(i=s.queueOn)?void 0:i.length)){let t=!1;try{t=await st(e,s,o)}catch(t){e.status.failed++;const n=s.type||"unknown";e.logger.scope(n).error("destination init failed",{error:t instanceof Error?t.message:String(t)})}return{id:o,destination:s,skipped:!t}}const I=[],q=l.filter(t=>{const n=x(s.config.consent,d,t.consent);if(n)return t.consent=n,I.push(t),!1;const r=je(e,{stepId:E("destination",o),stepType:"destination",phase:"skip",eventId:"string"==typeof t.id?t.id:"",now:Date.now()});return r.skipReason="consent",d&&(r.consent={...d}),s.config.consent&&(r.meta={required:{...s.config.consent}}),S(e,r),!0});if(q.length>0){const t=s.queuePush,n=s.config.id||o,r={max:null!=(a=s.config.queueMax)?a:1e3};let i=0;for(const e of q)i+=Le(t,e,r).dropped;if(i>0){et(e,n);const o=tt(e.status,E("destination",n),"queue",i);Ve(t,e.logger.scope(s.type||"unknown"),"destination.queuePush overflow; oldest events dropped",{buffer:"queuePush",destination:n,cap:r.max,droppedCount:o})}else t.length<r.max&&Ye(t)}if(!I.length)return{id:o,destination:s,queue:l};let O,D,C=!1;try{C=await st(e,s,o)}catch(t){e.status.failed++;const n=s.type||"unknown";e.logger.scope(n).error("destination init failed",{error:t instanceof Error?t.message:String(t)})}if(!C)return{id:o,destination:s,queue:l};s.dlq||(s.dlq=[]);const j=nt(s.config.before,g,u),A=s.config.next,M=null==(c=s.config)?void 0:c.cache,T=M?y(M):void 0,_=T?Ae(T,e):void 0;let P=0,K=0;return await Promise.all(I.map(async t=>{let r;if(t.globals=h(f,t.globals),t.user=h(p,t.user),(null==T?void 0:T.stop)&&_){const e=m(u,t),n=await w(T,_,e);if("HIT"===(null==n?void 0:n.status))return t;"MISS"===(null==n?void 0:n.status)&&(r={key:n.key,ttl:n.rule.ttl})}let i=t,a=n.respond;if(j.length>0&&e.transformers&&Object.keys(e.transformers).length>0){const s=await Ke(e,e.transformers,j,t,u,n.respond,`destination.${o}.before`);if(null===s.event)return t;s.respond&&(a=s.respond),i=Array.isArray(s.event)?s.event[0]:s.event}if(T&&!T.stop&&_){const e=m(u,i),n=await w(T,_,e);if("HIT"===(null==n?void 0:n.status))return t;"MISS"===(null==n?void 0:n.status)&&(r={key:n.key,ttl:n.rule.ttl})}const c=Date.now();let l=!1;const d=await $(rt,t=>{var n;const r=s.type||"unknown";e.logger.scope(r).error("Push failed",{error:t,event:i.name}),O=t,l=!0;const a=s.dlq,c=s.config.id||o,u={max:null!=(n=s.config.dlqMax)?n:100},d=Le(a,[i,t],u);if(d.dropped>0){et(e,c);const t=tt(e.status,E("destination",c),"dlq",d.dropped);Ve(a,e.logger.scope(s.type||"unknown"),"destination.dlq overflow; oldest entries dropped",{buffer:"dlq",destination:c,cap:u.max,droppedCount:t})}else a.length<u.max&&Ye(a)})(e,s,o,i,u,a);if(P+=Date.now()-c,r&&_&&void 0===s.config.mock&&b(_,r.key,null==d||d,r.ttl),void 0===d||Xe(d)||(D=d),Xe(d)&&K++,!l&&A){void 0!==d&&(u._response=d);const t=nt(A,g,u);if(t.length>0&&e.transformers&&Object.keys(e.transformers).length>0){const n=await Ke(e,e.transformers,t,i,u,a,`destination.${o}.next`);n.respond&&(a=n.respond)}}return t})),{id:o,destination:s,error:O,response:D,totalDuration:P,batchedCount:K,allowedCount:I.length}})),q={},O={},D={};for(const t of I){if(t.skipped)continue;const n=t.destination,o={type:n.type||"unknown",data:t.response};et(e,t.id);const u=e.status.destinations[t.id],d=Date.now();if(u.queuePushSize=null!=(r=null==(s=n.queuePush)?void 0:s.length)?r:0,u.dlqSize=null!=(a=null==(i=n.dlq)?void 0:i.length)?a:0,t.error)o.error=t.error,D[t.id]=o,u.failed++,u.lastAt=d,u.duration+=t.totalDuration||0,e.status.failed++;else if(t.queue&&t.queue.length)O[t.id]=o;else{const n=null!=(c=t.batchedCount)?c:0,s=null!=(l=t.allowedCount)?l:0;(Math.max(0,s-n)>0||0===s)&&(q[t.id]=o,u.count++,u.lastAt=d,u.duration+=t.totalDuration||0,e.status.out++)}}return it({event:t,...Object.keys(q).length&&{done:q},...Object.keys(O).length&&{queued:O},...Object.keys(D).length&&{failed:D}})}async function st(e,t,n){var o;if(t.init&&!t.config.init){const s=t.type||"unknown",r=e.logger.scope(s),i={collector:e,logger:r,id:n,config:t.config,env:ct(t.env,t.config.env)};r.debug("init");const a=Date.now();let c;S(e,je(e,{stepId:E("destination",n),stepType:"destination",phase:"init",eventId:"",now:a}));try{c=await M(t.init,"DestinationInit",e.hooks,e.logger)(i)}catch(t){const o=Date.now(),s=je(e,{stepId:E("destination",n),stepType:"destination",phase:"error",eventId:"",now:o});throw s.durationMs=o-a,s.error=t instanceof Error?{name:t.name,message:t.message}:{message:String(t)},S(e,s),t}if(!1===c)return c;if(t.config={...c||t.config,init:!0},null==(o=t.queueOn)?void 0:o.length){const o=t.queueOn;t.queueOn=[];for(const{type:s,data:r}of o)Ue(e,t,n,s,r)}r.debug("init done")}return!0}async function rt(e,t,n,o,s,r){var i,a,c,l,u,d,f;const{config:p}=t,g=await A(o,p,e);if(g.ignore)return!1;const h=t.type||"unknown",m=e.logger.scope(h),v={collector:e,logger:m,id:n,config:p,data:g.data,rule:g.mapping,ingest:s,env:{...ct(t.env,p.env),...r?{respond:r}:{}}};if(void 0!==p.mock)return m.debug("mock",{event:g.event.name}),p.mock;const y=g.mapping,w=g.mappingKey||"* *";if((null==y?void 0:y.batch)&&t.pushBatch&&void 0===p.mock){if(t.batches=t.batches||{},!t.batches[w]){const o={key:w,entries:[],events:[],data:[]},s=Ze(y.batch),r=Ze(p.batch),f=null!=(a=null!=(i=s.wait)?i:r.wait)?a:3e4,g=null!=(l=null!=(c=s.size)?c:r.size)?l:1e3,h=null!=(d=null!=(u=s.age)?u:r.age)?d:3e4,v=ct(t.env,p.env),b=I(async()=>{var o;const s=t.batches[w].batched;if(0===s.entries.length)return;const r={key:s.key,entries:s.entries,events:s.events,data:s.data};s.entries=[],s.events=[],s.data=[];const i=r.entries[0],a={collector:e,logger:m,id:n,config:p,data:void 0,rule:i.rule,ingest:i.ingest,env:{...v,...i.respond?{respond:i.respond}:{}}};m.debug("push batch",{events:r.entries.length});const c=t.config.id||n,l=et(e,c),u=Date.now(),d=je(e,{stepId:E("destination",n),stepType:"destination",phase:"flush",eventId:"",now:u});d.batch={size:r.entries.length,index:0},S(e,d);let f=!0;await $(M(t.pushBatch,"DestinationPushBatch",e.hooks,e.logger),o=>{var s;f=!1;const i=Date.now(),a=je(e,{stepId:E("destination",n),stepType:"destination",phase:"error",eventId:"",now:i});a.durationMs=i-u,a.error=o instanceof Error?{name:o.name,message:o.message}:{message:String(o)},a.batch={size:r.entries.length,index:0},S(e,a);const d=t.dlq=t.dlq||[],p={max:null!=(s=t.config.dlqMax)?s:100};let g=0;for(const e of r.entries)g+=Le(d,[e.event,o],p).dropped;if(g>0){const t=tt(e.status,E("destination",c),"dlq",g);Ve(d,m,"destination.dlq overflow; oldest entries dropped",{buffer:"dlq",destination:c,cap:p.max,droppedCount:t})}else d.length<p.max&&Ye(d);l.failed+=r.entries.length,l.dlqSize=d.length,e.status.failed+=r.entries.length,m.error("Push batch failed",{error:o instanceof Error?o.message:String(o),entries:r.entries.length})})(r,a),m.debug("push batch done"),l.inFlightBatch=Math.max(0,(null!=(o=l.inFlightBatch)?o:0)-r.entries.length),f&&(l.count+=r.entries.length,l.lastAt=Date.now(),e.status.out+=r.entries.length)},{wait:f,size:g,age:h});t.batches[w]={batched:o,batchFn:()=>{b()},flush:async()=>{await b.flush()}}}const o=t.batches[w];o.batched.entries.push({event:g.event,ingest:s,respond:r,rule:y,data:g.data}),o.batched.events.push(g.event),D(g.data)&&o.batched.data.push(g.data);const h=t.config.id||n,v=et(e,h);return v.inFlightBatch=(null!=(f=v.inFlightBatch)?f:0)+1,o.batchFn(),Qe}{m.debug("push",{event:g.event.name});const o="string"==typeof g.event.id?g.event.id:"",s=Date.now(),r=je(e,{stepId:E("destination",n),stepType:"destination",phase:"in",eventId:o,now:s});g.mappingKey&&(r.mappingKey=g.mappingKey),g.event.consent&&(r.consent={...g.event.consent}),S(e,r);try{const r=await M(t.push,"DestinationPush",e.hooks,e.logger)(g.event,v),i=Date.now(),a=je(e,{stepId:E("destination",n),stepType:"destination",phase:"out",eventId:o,now:i});return a.durationMs=i-s,a.outEvent=r,g.mappingKey&&(a.mappingKey=g.mappingKey),S(e,a),m.debug("push done"),r}catch(t){const r=Date.now(),i=je(e,{stepId:E("destination",n),stepType:"destination",phase:"error",eventId:o,now:r});throw i.durationMs=r-s,i.error=t instanceof Error?{name:t.name,message:t.message}:{message:String(t)},g.mappingKey&&(i.mappingKey=g.mappingKey),S(e,i),t}}}function it(e){return{ok:!(null==e?void 0:e.failed),...e}}function at(e){const{code:t,config:n={},env:o={},cache:s}=e,{config:r}=$e(e,"before"),{config:i}=$e({...e,config:r},"next"),a={...t.config,...n,...i};s&&(a.cache=s);const c=ct(t.env,o);return{...t,config:a,env:c}}function ct(e,t){return e||t?t?e&&j(e)&&j(t)?{...e,...t}:t:e:{}}async function lt(e,t,n){const o=Object.entries(e).map(async([e,o])=>{var s;const r=o.destroy;if(!r)return;const i=o.type||"unknown",a=n.scope(i),c={id:e,config:o.config,env:null!=(s=o.env)?s:{},logger:a};try{await Promise.race([r(c),new Promise((n,o)=>setTimeout(()=>o(new Error(`${t} '${e}' destroy timed out`)),5e3))])}catch(n){a.error(`${t} '${e}' destroy failed: ${n}`)}});await Promise.allSettled(o)}async function ut(e,t,n){let o,s,r=!1;switch(t){case Ce.Config:pe(n)&&(le(e.config,n,{shallow:!1}),s=n,r=!0);break;case Ce.Consent:if(pe(n)){const{update:t}=function(e,t){const n={};return Object.entries(t).forEach(([e,t])=>{n[e]=!!t}),e.consent=f(e.consent,n),{update:n}}(e,n);s=t,r=!0}break;case Ce.Custom:pe(n)&&(e.custom=le(e.custom,n),s=n,r=!0);break;case Ce.Destination:pe(n)&&"code"in n&&pe(n.code)&&(o=await async function(e,t){const{code:n,config:o={},env:s={},before:r,next:i,cache:a}=t;if(!C(n.push))return it({ok:!1,failed:{invalid:{type:"invalid",error:"Destination code must have a push method"}}});const c=o||{init:!1};let l=r?{...c,before:r}:{...c};i&&(l={...l,next:i}),a&&(l={...l,cache:a});const u={...n,config:l,env:ct(n.env,s)};let d=u.config.id;if(!d)do{d=q(5,"abcdefghijklmnopqrstuvwxyz")}while(e.destinations[d]);return e.destinations[d]=u,!1!==u.config.queue&&(u.queuePush=[...e.queue]),ot(e,void 0,{},{[d]:u})}(e,n));break;case Ce.Globals:pe(n)&&(e.globals=le(e.globals,n),s=n,r=!0);break;case Ce.Hook:if(pe(n)&&fe(n.name)&&de(n.fn)){const{name:t,fn:o}=n;e.hooks[t]=o,s=n,r=!0}break;case Ce.On:if(pe(n)&&fe(n.type)){const{type:t,rules:o}=n;await async function(e,t,n){const o=e.on,s=o[t]||[],r=_(n)?n:[n];r.forEach(e=>{s.push(e)}),o[t]=s,We(e,t,r)}(e,t,o)}break;case Ce.Ready:r=!0;break;case Ce.Run:o=await async function(e,t){return e.allowed=!0,e.timing=Date.now(),t&&(t.consent&&(e.consent=le(e.consent,t.consent)),t.user&&(e.user=le(e.user,t.user)),t.globals&&(e.globals=le(e.config.globalsStatic||{},t.globals)),t.custom&&(e.custom=le(e.custom,t.custom))),Object.values(e.destinations).forEach(e=>{e.queuePush=[]}),e.queue=[],e.round++,await ot(e)}(e,n),r=!0;break;case Ce.Session:r=!0;break;case Ce.Shutdown:await async function(e){const t=e.logger;await lt(e.sources,"source",t),await lt(e.destinations,"destination",t),await lt(e.transformers,"transformer",t),await lt(e.stores,"store",t)}(e);break;case Ce.User:pe(n)&&(le(e.user,n,{shallow:!1}),s=n,r=!0)}return r&&(await async function(e,t,n,o){var s,r;let i,a=n||[];switch(n||(a=e.on[t]||[]),t){case Ce.Consent:i=o||e.consent;break;case Ce.Session:i=e.session;break;case Ce.User:i=o||e.user;break;case Ce.Custom:i=o||e.custom;break;case Ce.Globals:i=o||e.globals;break;case Ce.Config:i=o||e.config;break;case Ce.Ready:case Ce.Run:default:i=void 0}let c=!1;for(const[n,o]of Object.entries(e.sources)){if(null==(s=o.config.require)?void 0:s.length){const e=o.config.require.indexOf(t);-1!==e&&o.config.require.splice(e,1)}o.on&&(He(o)?!1===await z(o.on,o=>Be(e,"source",o,{sourceId:n,type:t}))(t,i)&&(c=!0):(o.queueOn=o.queueOn||[],o.queueOn.push({type:t,data:i})))}Object.entries(e.destinations).forEach(([n,o])=>{if(o.on){if(!o.config.init)return o.queueOn=o.queueOn||[],void o.queueOn.push({type:t,data:i});Ue(e,o,n,t,i)}});for(const[t,n]of Object.entries(e.sources))He(n)&&(null==(r=n.queueOn)?void 0:r.length)&&await Fe(e,n,t);return Object.keys(e.pending.destinations).length>0&&await async function(e,t){var n;for(const[o,s]of Object.entries(e.pending.destinations)){if(!e.pending.destinations[o]||e.destinations[o])continue;const r=null==(n=s.config)?void 0:n.require;if(!r)continue;const i=r.indexOf(t);if(-1===i)continue;if(r.splice(i,1),r.length>0)continue;delete e.pending.destinations[o];const a=at(s);!1!==a.config.queue&&(a.queuePush=[...e.queue]),e.destinations[o]=a}}(e,t),We(e,t,a,o),!c}(e,t,void 0,s),o=await ot(e)),o||it({ok:!0})}function dt(e,t){if(!t.name)throw new Error("Event name is required");const[n,o]=t.name.split(" ");if(!n||!o)throw new Error("Event name is invalid");const{timestamp:s=Date.now(),name:r=`${n} ${o}`,data:i={},context:a={},globals:c=e.globals,custom:l={},user:u=e.user,nested:d=[],consent:f=e.consent,id:p=ue(),trigger:g="",entity:h=n,action:m=o,timing:v=0,source:y={type:"collector",schema:"4"}}=t;return{name:r,data:i,context:a,globals:c,custom:l,user:u,nested:d,consent:f,id:p,trigger:g,entity:h,action:m,timestamp:s,timing:v,source:y}}function ft(e={}){var t,n,o;const s=null!=(t=e.maxEntries)?t:1e4,r=null!=(n=e.lowWaterMark)?n:.8,i=null!=(o=e.sweepIntervalMs)?o:6e4,a=Math.floor(s*r),c=new Map,l={hits:0,misses:0,populates:0,writes:0,deletes:0,evictions_entries:0,evictions_ttl:0};let u;return i>0&&(u=setInterval(function(){const e=Date.now();let t=0;for(const[n,o]of c)void 0!==o.expires&&o.expires<=e&&(c.delete(n),t++);l.evictions_ttl+=t},i),u&&"function"==typeof u.unref&&u.unref()),{type:"memory",config:{},get(e){const t=c.get(e);if(t)return void 0!==t.expires&&t.expires<=Date.now()?(c.delete(e),l.evictions_ttl++,void l.misses++):(c.delete(e),c.set(e,t),l.hits++,t.value);l.misses++},set(e,t,n){const o=!c.has(e);o||c.delete(e),c.set(e,{value:t,expires:void 0!==n?Date.now()+n:void 0}),l.writes++,o&&l.populates++,c.size>s&&function(){if(c.size<=s)return;const e=c.size-a;let t=0;for(const n of c.keys()){if(t>=e)break;c.delete(n),t++}l.evictions_entries+=t}()},delete(e){c.delete(e)&&l.deletes++},get counters(){return{...l}},destroy(){void 0!==u&&(clearInterval(u),u=void 0),c.clear()}}}function pt(e,t){const{cacheConfig:n,cacheStore:o,namespace:s,logger:r,storeId:i,collector:a}=t,c=(e,t)=>{if(!a)return;const n=je(a,{stepId:`store.${i}`,stepType:"store",phase:"in",eventId:"",now:Date.now()});n.meta={op:"cache",cached:"hit"===t,status:t,key:e},De(a,n)},l={hits:0,misses:0,populates:0,writes:0,deletes:0,inflight_dedups:0},u=n.rules.map(e=>({match:e.match?Oe(e.match):()=>!0,ttl:e.ttl})),d=e=>`${s}:${e}`;function f(e,t){const n=void 0===t?{key:e}:{key:e,value:t};return u.find(e=>e.match(n))}const p=new Map;return{type:e.type,config:e.config,setup:e.setup,get counters(){return{...l}},async get(t){const n=d(t),s=await o.get(n);if(void 0!==s)return l.hits++,c(t,"hit"),s;const r=p.get(n);if(r)return l.inflight_dedups++,c(t,"hit"),r;l.misses++,c(t,"miss");const i=(async()=>{try{const s=await e.get(t);if(void 0===s)return;const r=f(t,s);if(r)try{await o.set(n,s,1e3*r.ttl),l.populates++}catch(e){g("set",t,e)}return s}finally{p.delete(n)}})();return p.set(n,i),i},async set(t,n,s){l.writes++,await e.set(t,n,s);const r=f(t,n);if(r)try{await o.set(d(t),n,1e3*r.ttl)}catch(e){g("set",t,e)}},async delete(t){l.deletes++,await e.delete(t);try{await o.delete(d(t))}catch(e){g("delete",t,e)}}};function g(e,t,n){const o=`store-cache(${i}): cache ${e} failed for "${t}"; backing succeeded, continuing`;r?r.warn(o,{error:n}):console.warn(o,n)}}function gt(e,t,n){const o=`store.${n}`,s=xe(t.get,"StoreGet",e.hooks,e.logger),r=xe(t.set,"StoreSet",e.hooks,e.logger),i=xe(t.delete,"StoreDelete",e.hooks,e.logger);t.get=async t=>{const n=Date.now(),r=je(e,{stepId:o,stepType:"store",phase:"in",eventId:"",now:n});r.meta={op:"get",key:t},qe(e,r);try{const r=await s(t),i=Date.now(),a=je(e,{stepId:o,stepType:"store",phase:"out",eventId:"",now:i});return a.durationMs=i-n,a.meta={op:"get",key:t},qe(e,a),r}catch(s){const r=Date.now(),i=je(e,{stepId:o,stepType:"store",phase:"error",eventId:"",now:r});throw i.durationMs=r-n,i.meta={op:"get",key:t},i.error=s instanceof Error?{name:s.name,message:s.message}:{message:String(s)},qe(e,i),s}},t.set=async(t,n,s)=>{const i=Date.now(),a=je(e,{stepId:o,stepType:"store",phase:"in",eventId:"",now:i});a.meta={op:"set",key:t},qe(e,a);try{await r(t,n,s);const a=Date.now(),c=je(e,{stepId:o,stepType:"store",phase:"out",eventId:"",now:a});c.durationMs=a-i,c.meta={op:"set",key:t},qe(e,c)}catch(n){const s=Date.now(),r=je(e,{stepId:o,stepType:"store",phase:"error",eventId:"",now:s});throw r.durationMs=s-i,r.meta={op:"set",key:t},r.error=n instanceof Error?{name:n.name,message:n.message}:{message:String(n)},qe(e,r),n}},t.delete=async t=>{const n=Date.now(),s=je(e,{stepId:o,stepType:"store",phase:"in",eventId:"",now:n});s.meta={op:"delete",key:t},qe(e,s);try{await i(t);const s=Date.now(),r=je(e,{stepId:o,stepType:"store",phase:"out",eventId:"",now:s});r.durationMs=s-n,r.meta={op:"delete",key:t},qe(e,r)}catch(s){const r=Date.now(),i=je(e,{stepId:o,stepType:"store",phase:"error",eventId:"",now:r});throw i.durationMs=r-n,i.meta={op:"delete",key:t},i.error=s instanceof Error?{name:s.name,message:s.message}:{message:String(s)},qe(e,i),s}}}async function ht(e){var t,n;const o=p({globalsStatic:{},sessionStatic:{},run:!0,queueMax:1e3},e,{merge:!1,extend:!1}),s={level:null==(t=e.logger)?void 0:t.level,handler:null==(n=e.logger)?void 0:n.handler},r=g(s),i={...o.globalsStatic,...e.globals},a={allowed:!1,config:o,consent:e.consent||{},custom:e.custom||{},destinations:{},transformers:{},stores:{},globals:i,hooks:e.hooks||{},observers:new Set,logger:r,on:{},queue:[],round:0,session:void 0,status:{startedAt:Date.now(),in:0,out:0,failed:0,sources:{},destinations:{},dropped:{}},timing:Date.now(),user:e.user||{},sources:{},pending:{destinations:{}},push:void 0,command:void 0};var c,l;a.push=function(e,t){const n=be(async(n,o={})=>await we(async()=>{var s;const r=Date.now(),{id:i,ingest:a,respond:c,mapping:l,preChain:u,include:d,exclude:f}=o;let p=c,g=n;const h=d||f?function(e,t,n){let o=e;return t&&(o=Object.fromEntries(Object.entries(o).filter(([e])=>t.includes(e)))),n&&(o=Object.fromEntries(Object.entries(o).filter(([e])=>!n.includes(e)))),o}(e.destinations,d,f):void 0,m=null!=a?a:ge(i||"unknown");if(l){const t=await ye(g,l,e);if(t.ignore)return it({ok:!0});if(l.consent&&!ve(l.consent,e.consent,t.event.consent))return it({ok:!0});g=t.event}if((null==u?void 0:u.length)&&e.transformers&&Object.keys(e.transformers).length>0){const n=await Ke(e,e.transformers,u,g,m,p,i?`source.${i}.next`:void 0);if(null===n.event)return it({ok:!0});if(n.stopped)return n.respond&&(p=n.respond),it({ok:!0});if(n.respond&&(p=n.respond),Array.isArray(n.event)){const o=await Promise.all(n.event.map(async n=>{const o=t(n),s=dt(e,o);return ot(e,s,{id:i,ingest:m,respond:p},h)}));if(i){e.status.sources[i]||(e.status.sources[i]={count:0,duration:0});const t=e.status.sources[i];t.count+=n.event.length,t.lastAt=Date.now(),t.duration+=Date.now()-r}return null!=(s=o[0])?s:it({ok:!0})}g=n.event}const v=t(g),y=dt(e,v),w=await ot(e,y,{id:i,ingest:m,respond:p},h);if(i){e.status.sources[i]||(e.status.sources[i]={count:0,duration:0});const t=e.status.sources[i];t.count++,t.lastAt=Date.now(),t.duration+=Date.now()-r}return w},t=>{if(t instanceof me)throw t;return e.status.failed++,e.logger.error("push failed",{event:n,ingest:o.ingest,error:t}),it({ok:!1})})(),"Push",e.hooks,e.logger);return async(t,o)=>{const s="string"==typeof t.id?t.id:"",r=Date.now();he(e,je(e,{stepId:"collector.push",stepType:"collector",phase:"in",eventId:s,now:r}));try{const i=await n(t,o),a=Date.now(),c=je(e,{stepId:"collector.push",stepType:"collector",phase:"out",eventId:s,now:a});return c.durationMs=a-r,c.outEvent=i,he(e,c),i}catch(t){const n=Date.now(),o=je(e,{stepId:"collector.push",stepType:"collector",phase:"error",eventId:s,now:n});throw o.durationMs=n-r,o.error=t instanceof Error?{name:t.name,message:t.message}:{message:String(t)},he(e,o),t}}}(a,e=>({timing:Math.round((Date.now()-a.timing)/10)/100,source:{type:"collector",schema:"4",version:"4.1.3-next-1779963694449"},...e})),a.command=(l=ut,Ie(async(e,t,n)=>await Se(async()=>await l(c,e,t,n),n=>{if(n instanceof ke)throw n;return c.status.failed++,c.logger.error("command failed",{command:e,data:t,error:n}),it({ok:!1})})(),"Command",(c=a).hooks,c.logger));const u=e.stores||{};return a.stores=await async function(e,t={}){var n;const o={};for(const[n,s]of Object.entries(t)){const{code:t,config:r={},env:i={}}=s,a=e.logger.scope("store").scope(n),c={collector:e,logger:a,id:n,config:r,env:i},l=await t(c);o[n]=l}const s=t,r=function(e){const t={};for(const n of Object.keys(e))t[n]="WHITE";const n=[],o=[];function s(r){var i;const a=t[r];if("BLACK"===a)return;if("GRAY"===a){const e=o.indexOf(r),t=o.slice(-1===e?0:e).concat(r).join(" -> ");throw new Error(`Cycle in cache.store chain: ${t}`)}t[r]="GRAY",o.push(r);const c=null==(i=e[r].cache)?void 0:i.store;if(void 0!==c){if(!(c in e))throw new Error(`Store "${r}" cache.store references "${c}", which is not declared in flow.stores`);s(c)}o.pop(),t[r]="BLACK",n.push(r)}for(const n of Object.keys(e))"WHITE"===t[n]&&s(n);return n}(s);for(const t of r){const r=s[t].cache;if(!r)continue;let i,a;void 0!==r.store?(i=o[r.store],a=r.store):(o.__cache||(o.__cache=ft()),i=o.__cache,a="__cache");const c=null!=(n=r.namespace)?n:t;e.logger.scope("store-cache").scope(t).info(`store "${t}" caches with namespace "${c}:" via ${a}`),o[t]=pt(o[t],{storeId:t,cacheConfig:r,cacheStore:i,namespace:c,logger:e.logger.scope("store-cache").scope(t),collector:e})}for(const[t,n]of Object.entries(o))"__cache"!==t&&gt(e,n,t);return o}(a,u),function(e,t,n){const o=new Map;for(const[n,s]of Object.entries(e))t[n]&&o.set(s,t[n]);if(0!==o.size)for(const e of[n.transformers,n.destinations,n.sources])if(e)for(const t of Object.values(e))s(t.env);function s(e){if(e)for(const[t,n]of Object.entries(e))if("object"==typeof n&&null!==n){const s=o.get(n);s&&(e[t]=s)}}}(u,a.stores,e),a.stores.__cache||(a.stores.__cache=ft()),a.destinations=await async function(e,t={}){var n,o;const s={};for(const[r,i]of Object.entries(t))(null==(o=null==(n=i.config)?void 0:n.require)?void 0:o.length)?e.pending.destinations[r]=i:s[r]=at(i);return s}(a,e.destinations||{}),a.transformers=await async function(e,t={}){var n,o,s,r;const i={};for(const[a,c]of Object.entries(t)){const{code:t,env:l={}}=c,u=ae(c,"Transformer");if(!u.ok){e.logger.warn(`Transformer ${a} invalid (${u.code}): ${u.reason}. Skipping.`);continue}const{config:d}=$e(c,"before"),{config:f}=$e({...c,config:d},"next"),p=Object.keys(l).length>0?{...f,env:l}:f,{cache:g}=c,h=g?{...p,cache:g}:p,m=e.logger.scope("transformer").scope(a),v={collector:e,logger:m,id:a,ingest:V(a),config:h,env:l},y=null!=t?t:e=>{const t=c.mapping;if(t){const n=[];if(void 0!==t.data&&n.push("data"),t.mapping)for(const[e,o]of Object.entries(t.mapping))if("object"==typeof o&&null!==o)for(const[t,s]of Object.entries(o)){if("object"!=typeof s||null===s)continue;const o=s;void 0!==o.data&&n.push(`mapping[${e}][${t}].data`),void 0!==o.silent&&n.push(`mapping[${e}][${t}].silent`)}return n.length>0&&e.collector.logger.warn(`Transformer ${a}: \`${n.join(", ")}\` ignored at transformer position (only event-mutating fields apply).`),{type:"pass",config:e.config,push:async n=>{const o=await ce(n,t,e.collector);return!o.ignore&&{event:o.event}}}}return{type:"pass",config:e.config,push:e=>({event:e})}},w=await y(v);void 0!==c.before&&void 0===(null==(n=w.config)?void 0:n.before)&&(w.config={...null!=(o=w.config)?o:{},before:c.before}),void 0!==c.next&&void 0===(null==(s=w.config)?void 0:s.next)&&(w.config={...null!=(r=w.config)?r:{},next:c.next}),i[a]=w}return i}(a,e.transformers||{}),a}async function mt(e){e=e||{};const t=await ht(e),n=(o=t,{type:"elb",config:{},push:async(e,t,n,s,r)=>{if("string"==typeof e&&e.startsWith("walker ")){const n=e.replace("walker ","");return o.command(n,t)}let i;if("string"==typeof e)i={name:e},t&&"object"==typeof t&&!Array.isArray(t)&&(i.data=t);else{if(!e||"object"!=typeof e)return it({ok:!1});i=e,t&&"object"==typeof t&&!Array.isArray(t)&&(i.data={...i.data||{},...t})}return n&&"object"==typeof n&&(i.context=n),s&&Array.isArray(s)&&(i.nested=s),r&&"object"==typeof r&&(i.custom=r),o.push(i)}});var o;t.sources.elb=n,await async function(e,t={}){var n;const o={};for(const[s,r]of Object.entries(t)){const t=await Ne(e,s,r);if(!t)continue;const i=null==(n=r.config)?void 0:n.require;t.config={...t.config,init:!1,...i?{require:[...i]}:{}},o[s]=t}Object.assign(e.sources,o);for(const t of Object.keys(o)){const n=e.sources[t];let o=!1;n.init&&await N(n.init.bind(n),n=>{if(n instanceof F)throw n;o=!0,e.status.failed++,e.logger.scope("source").error("source init failed",{sourceId:t,error:n})})(),o||(n.config.init=!0,He(n)&&await Fe(e,n,t))}return o}(t,e.sources||{});const{consent:s,user:r,globals:i,custom:a}=e;s&&await t.command("consent",s),r&&await t.command("user",r),i&&Object.assign(t.globals,i),a&&Object.assign(t.custom,a),t.config.run&&await t.command("run");let c=n.push;const l=Object.values(t.sources).filter(e=>"elb"!==e.type),u=l.find(e=>e.config.primary);return u?c=u.push:l.length>0&&(c=l[0].push),{collector:t,elb:c}}var vt=async e=>{let t;return{get flow(){return t},trigger:(n,o)=>async n=>{var s,r,i,a,c,l,u,d,f;const p=o||{};if(p.url){const e=new URL(p.url);window.history.replaceState({},"",e.pathname+e.search)}if(p.referrer&&Object.defineProperty(document,"referrer",{value:p.referrer,configurable:!0}),p.sessionData){const e=p.sessionKey||"elbSessionId";localStorage.setItem(e,JSON.stringify(p.sessionData))}if(p.deviceId){const e=p.deviceKey||"elbDeviceId";localStorage.setItem(e,p.deviceId)}if(!t){const n=await mt({...e,run:null==(s=e.run)||s});t={collector:n.collector,elb:n.elb};const o=p.sessionKey||(null==(c=null==(a=null==(i=null==(r=e.sources)?void 0:r.session)?void 0:i.config)?void 0:a.settings)?void 0:c.sessionKey)||"elbSessionId",g=p.deviceKey||(null==(f=null==(d=null==(u=null==(l=e.sources)?void 0:l.session)?void 0:u.config)?void 0:d.settings)?void 0:f.deviceKey)||"elbDeviceId";localStorage.removeItem(o),localStorage.removeItem(g),p.sessionData&&localStorage.setItem(o,JSON.stringify(p.sessionData)),p.deviceId&&localStorage.setItem(g,p.deviceId),e.consent&&await t.collector.command("consent",e.consent)}}}},yt=(e,t)=>{if(!e||"object"!=typeof e)return;const n=e,o=t.localStorage;if(n.sessionData&&"object"==typeof n.sessionData){const e="string"==typeof n.sessionKey?n.sessionKey:"elbSessionId";o.setItem(e,JSON.stringify(n.sessionData))}if("string"==typeof n.deviceId){const e="string"==typeof n.deviceKey?n.deviceKey:"elbDeviceId";o.setItem(e,n.deviceId)}};export{c as examples,n as schemas};//# sourceMappingURL=dev.mjs.map
1
+ var e=Object.defineProperty,t=(t,n)=>{for(var o in n)e(t,o,{get:n[o],enumerable:!0})},n={};t(n,{SettingsSchema:()=>i,settings:()=>a});import{zodToSchema as o}from"@walkeros/core/dev";import{z as s,ClickIdEntrySchema as r}from"@walkeros/core/dev";var i=s.object({storage:s.boolean().default(!1).describe("Enable persistent storage for session/device IDs").optional(),consent:s.union([s.string(),s.array(s.string())]).describe("Consent key(s) required to enable storage mode").optional(),length:s.number().default(30).describe("Session timeout in minutes").optional(),pulse:s.boolean().default(!1).describe("Keep session alive on each event").optional(),sessionKey:s.string().default("elbSessionId").describe("Storage key for session ID").optional(),sessionStorage:s.enum(["local","session"]).default("local").describe("Storage type for session").optional(),deviceKey:s.string().default("elbDeviceId").describe("Storage key for device ID").optional(),deviceStorage:s.enum(["local","session"]).default("local").describe("Storage type for device").optional(),deviceAge:s.number().default(30).describe("Device ID age in days").optional(),cb:s.any().describe("Custom session callback function or false to disable").optional(),clickIds:s.array(r).describe("Custom click-ID registry. Entries with a `param` matching a default override the platform name in place; new params append to the end of the priority list.").optional()}),a=o(i),c={};t(c,{createTrigger:()=>At,step:()=>l,trigger:()=>Et});var l={};t(l,{newMarketingSession:()=>u,returningVisitor:()=>d});var u={title:"New marketing session",description:"A visit with UTM parameters starts a new session and emits walker user, session, and session start calls.",trigger:{type:"load",options:{url:"https://example.com/?utm_source=google&utm_medium=cpc&utm_campaign=winter-sale"}},in:{storage:!0},out:[["elb","user",{session:"s3ss10n-id",device:"d3v1c3-id"}],["elb","session",{id:"s3ss10n-id",start:17e11,isNew:!0,count:1,runs:1,marketing:!0,source:"google",medium:"cpc",campaign:"winter-sale",referrer:"",device:"d3v1c3-id",isStart:!0,storage:!0,updated:17e11}],["elb",{name:"session start",data:{id:"s3ss10n-id",start:17e11,isNew:!0,count:1,runs:1,marketing:!0,source:"google",medium:"cpc",campaign:"winter-sale",referrer:"",device:"d3v1c3-id",isStart:!0,storage:!0,updated:17e11}}]]},d={title:"Returning visitor",description:"A returning visit with a google referrer reuses the stored device id and increments the session count.",trigger:{type:"load",options:{referrer:"https://google.com"}},in:{storage:!0},out:[["elb","user",{session:"n3w-s3ss10n",device:"d3v1c3-id"}],["elb","session",{id:"n3w-s3ss10n",start:1700001e6,isNew:!1,count:3,runs:1,referrer:"google.com",device:"d3v1c3-id",isStart:!0,storage:!0,updated:1700001e6}],["elb",{name:"session start",data:{id:"n3w-s3ss10n",start:1700001e6,isNew:!1,count:3,runs:1,referrer:"google.com",device:"d3v1c3-id",isStart:!0,storage:!0,updated:1700001e6}}]]};import{assign as f}from"@walkeros/core";import{assign as p,createLogger as g}from"@walkeros/core";import{assign as h,buildCacheContext as m,clone as v,compileCache as y,checkCache as w,storeCache as b,createIngest as k,debounce as I,emitStep as S,getId as O,getGrantedConsent as q,getNextSteps as x,isDefined as C,isFunction as D,isObject as j,processEventMapping as A,stepId as E,tryCatchAsync as M,useHooks as $,compileState as _,applyState as T}from"@walkeros/core";import{emitStep as P}from"@walkeros/core";import{isArray as K,FatalError as z}from"@walkeros/core";import{tryCatch as R,tryCatchAsync as V}from"@walkeros/core";import{createIngest as F,FatalError as H,getMappingValue as N,tryCatchAsync as B,getNextSteps as G,compileCache as U,checkCache as W,storeCache as L,applyUpdate as J,buildCacheContext as Y,compileState as Q,applyState as X}from"@walkeros/core";import{createIngest as Z,emitStep as ee,FatalError as te,isObject as ne,stepId as oe,tryCatchAsync as se,useHooks as re,getNextSteps as ie,compileCache as ae,checkCache as ce,storeCache as le,buildCacheContext as ue,validateStepEntry as de,processEventMapping as fe,compileState as pe,applyState as ge}from"@walkeros/core";import{assign as he,getSpanId as me,isFunction as ve,isString as ye}from"@walkeros/core";import{isObject as we}from"@walkeros/core";import{createIngest as be,emitStep as ke,FatalError as Ie,getGrantedConsent as Se,processEventMapping as Oe,tryCatchAsync as qe,useHooks as xe}from"@walkeros/core";import{FatalError as Ce,useHooks as De,tryCatchAsync as je}from"@walkeros/core";import{emitStep as Ae,useHooks as Ee}from"@walkeros/core";import{compileMatcher as Me,emitStep as $e}from"@walkeros/core";var _e={Action:"action",Actions:"actions",Config:"config",Consent:"consent",Context:"context",Custom:"custom",Destination:"destination",Elb:"elb",Globals:"globals",Hook:"hook",Init:"init",Link:"link",On:"on",Prefix:"data-elb",Ready:"ready",Run:"run",Session:"session",Shutdown:"shutdown",User:"user",Walker:"walker"};function Te(e,t){const n=e.status.startedAt;return{flowId:"default",stepId:t.stepId,stepType:t.stepType,phase:t.phase,eventId:t.eventId,timestamp:new Date(t.now).toISOString(),elapsedMs:t.now-n}}function Pe(e,t){return e.storeId&&t.stores[e.storeId]?t.stores[e.storeId]:t.stores.__cache}function Ke(e,t){return e?t.stores[e]:t.stores.__cache}function ze(e){var t;const n={};for(const[o,s]of Object.entries(e)){const e=null==(t=s.config)?void 0:t.next;"string"==typeof e||Array.isArray(e)&&e.every(e=>"string"==typeof e)?n[o]={next:e}:n[o]={}}return n}function Re(e,t){const n=e.config||{},o=e[t];return void 0!==o?{config:{...n,[t]:o},chainValue:o}:{config:n,chainValue:void 0}}function Ve(e,t={}){if(!e)return[];if(Array.isArray(e))return e;const n=[],o=new Set;let s=e;for(;s&&t[s]&&!o.has(s);){o.add(s),n.push(s);const e=t[s].next;if(Array.isArray(e)){n.push(...e);break}s=e}return n}async function Fe(e,t,n){if(t.init&&!t.config.init){const o=t.type||"unknown",s=e.logger.scope(`transformer:${o}`),r={collector:e,logger:s,id:n,ingest:Z(n),config:t.config,env:Ge(t.config.env)};s.debug("init");const i=await re(t.init,"TransformerInit",e.hooks,e.logger)(r);if(!1===i)return!1;t.config={...i||t.config,env:(null==i?void 0:i.env)||t.config.env,init:!0},s.debug("init done")}return!0}async function He(e,t,n,o,s,r){const i=t.type||"unknown",a=e.logger.scope(`transformer:${i}`),c={collector:e,logger:a,id:n,ingest:s,config:t.config,env:{...Ge(t.config.env),...r?{respond:r}:{}}};a.debug("push",{event:o.name});const l="string"==typeof o.id?o.id:"",u=Date.now(),d=Te(e,{stepId:oe("transformer",n),stepType:"transformer",phase:"in",eventId:l,now:u});ee(e,d);try{const s=await re(t.push,"TransformerPush",e.hooks,e.logger)(o,c),r=Date.now(),i=Te(e,{stepId:oe("transformer",n),stepType:"transformer",phase:"out",eventId:l,now:r});return i.durationMs=r-u,i.outEvent=s,ee(e,i),a.debug("push done"),s}catch(t){const o=Date.now(),s=Te(e,{stepId:oe("transformer",n),stepType:"transformer",phase:"error",eventId:l,now:o});throw s.durationMs=o-u,s.error=t instanceof Error?{name:t.name,message:t.message}:{message:String(t)},ee(e,s),t}}function Ne(e,t){return e?{...e,_meta:{...e._meta,path:[...e._meta.path]}}:Z(t)}async function Be(e,t,n,o,s,r,i){var a,c,l,u,d,f,p,g,h;s||(s=Z(null!=(a=n[0])?a:"chain")),i&&s._meta&&(s._meta.chainPath=i);let m=o,v=r;for(const o of n){const r=t[o];if(!r){e.logger.warn(`Transformer not found: ${o}`);continue}if(s&&s._meta&&s._meta.path.length>256)return e.logger.error(`Max path length exceeded at ${o}`),{event:null,respond:v};if(s&&s._meta&&(s._meta.hops++,s._meta.path.push(o)),!await se(Fe,t=>{if(t instanceof te)throw t;return e.status.failed++,e.logger.scope(`transformer:${r.type||"unknown"}`).error("transformer init failed",{transformer:o,error:t}),!1})(e,r,o))return{event:null,respond:v};if(i&&void 0!==(null==(l=null==(c=r.config)?void 0:c.chainMocks)?void 0:l[i])){const t=r.config.chainMocks[i];e.logger.scope(`transformer:${r.type||"unknown"}`).debug("chainMock",{chain:i}),m=t;continue}if(void 0!==(null==(u=r.config)?void 0:u.mock)){e.logger.scope(`transformer:${r.type||"unknown"}`).debug("mock"),m=r.config.mock;continue}if(null==(d=r.config)?void 0:d.disabled)continue;const a=null==(f=r.config)?void 0:f.cache,y=a?ae(a):void 0,w=y?Pe(y,e):void 0,b=(null==(p=r.config)?void 0:p.state)?pe(r.config.state):void 0,k=null==b?void 0:b.filter(e=>"get"===e.mode),I=null==b?void 0:b.filter(e=>"set"===e.mode),S=async t=>I&&0!==I.length?ge(I,t=>Ke(t,e),t,e):t;let O;if(y&&w){const e=ue(s,m),t=await ce(y,w,e);if("HIT"===(null==t?void 0:t.status)&&t.value){if(m=t.value,y.stop)return{event:m,respond:v,stopped:!0};continue}"MISS"===(null==t?void 0:t.status)&&(O={key:t.key,ttl:t.rule.ttl})}const q=r.config.before;if(q){const n=ie(q,ue(s,m));if(1===n.length){const o=Ve(n[0],ze(t));if(o.length>0){const n=await Be(e,t,o,m,s,v,i);if(null===n.event)return{event:null,respond:null!=(g=n.respond)?g:v};if(n.stopped)return{event:Array.isArray(n.event)?n.event[0]:n.event,respond:null!=(h=n.respond)?h:v,stopped:!0};n.respond&&(v=n.respond),m=Array.isArray(n.event)?n.event[0]:n.event}}else n.length>1&&await Promise.all(n.map(n=>se(Be,t=>(e.logger.scope("transformer:many").error(`many branch ${n} failed`,{error:t}),{event:null,respond:void 0}))(e,t,Ve(n,ze(t)),m,Ne(s,n),void 0,i)))}k&&k.length>0&&(m=await ge(k,t=>Ke(t,e),m,e));const x=await se(He,t=>(e.logger.scope(`transformer:${r.type||"unknown"}`).error("Push failed",{error:t}),!1))(e,r,o,m,s,v);if(!1===x)return{event:null,respond:v};if(Array.isArray(x)){const r=n.slice(n.indexOf(o)+1),a=await Promise.all(x.map(async n=>{const o=await S(n.event||m),a=Ne(s,"unknown");if(n.next){const s=ie(n.next,ue(a,o));if(0===s.length)return{event:o,respond:v};if(1===s.length){const n=Ve(s[0],ze(t));return n.length>0?Be(e,t,n,o,a,v,i):{event:o,respond:v}}return(await Promise.all(s.map(n=>se(Be,t=>(e.logger.scope("transformer:many").error(`many branch ${n} failed`,{error:t}),{event:null,respond:void 0}))(e,t,Ve(n,ze(t)),o,Ne(a,n),void 0,i)))).map(e=>({event:e.event,respond:void 0}))}return r.length>0?Be(e,t,r,o,a,v,i):{event:o,respond:v}}));let c=v;const l=[];for(const e of a.flat())if(null!==e)if(e&&"object"==typeof e&&"event"in e){const t=e;if(t.respond&&(c=t.respond),null===t.event)continue;Array.isArray(t.event)?l.push(...t.event):l.push(t.event)}else l.push(e);return 0===l.length?{event:null,respond:c}:1===l.length?{event:l[0],respond:c}:{event:l,respond:c}}if(x&&"object"==typeof x){const{event:n,respond:o,next:r}=x;if(o&&(v=o),void 0!==r){const o=await S(n||m),a=ie(r,ue(s,o));if(0===a.length){m=o;continue}if(1===a.length){const n=Ve(a[0],ze(t));return n.length>0?Be(e,t,n,o,s,v,i):(e.logger.warn(`Branch target not found: ${JSON.stringify(r)}`),{event:null,respond:v})}return await Promise.all(a.map(n=>se(Be,t=>(e.logger.scope("transformer:many").error(`many branch ${n} failed`,{error:t}),{event:null,respond:void 0}))(e,t,Ve(n,ze(t)),o,Ne(s,n),void 0,i))),{event:null,respond:void 0}}n&&(m=n)}I&&I.length>0&&(m=await ge(I,t=>Ke(t,e),m,e)),O&&w&&le(w,O.key,m,O.ttl);const C=r.config.next,D="string"==typeof C||Array.isArray(C)&&C.every(e=>"string"==typeof e),j=void 0!==C&&!D;if((!x||"object"==typeof x&&!x.next)&&j){const n=ie(r.config.next,ue(s,m));if(1===n.length){const o=Ve(n[0],ze(t));return o.length>0?Be(e,t,o,m,s,v,i):{event:m,respond:v}}return n.length>1?(await Promise.all(n.map(n=>se(Be,t=>(e.logger.scope("transformer:many").error(`many branch ${n} failed`,{error:t}),{event:null,respond:void 0}))(e,t,Ve(n,ze(t)),m,Ne(s,n),void 0,i))),{event:null,respond:void 0}):{event:m,respond:v}}}return{event:m,respond:v}}function Ge(e){return e&&ne(e)?e:{}}function Ue(e){return"string"==typeof e||!(!Array.isArray(e)||!e.every(e=>"string"==typeof e))}async function We(e,t,n){var o,s;if(!t.on||!(null==(o=t.queueOn)?void 0:o.length))return;const r=t.queueOn;t.queueOn=[];const i=n||(null==(s=t.config)?void 0:s.id)||"unknown";for(const{type:n,data:o}of r)Qe(n)&&!Ze(e,t)||(await B(t.on,t=>{if(t instanceof H)throw t;e.status.failed++,e.logger.scope("source").error("source on flush failed",{sourceId:i,type:n,error:t})})(n,o),Qe(n)&&Xe(e,t))}function Le(e){var t;return Boolean(e.config.init)&&!(null==(t=e.config.require)?void 0:t.length)}async function Je(e,t,n){var o,s;const{code:r,config:i={},env:a={},primary:c,next:l,before:u,cache:d}=n,f=null!=(o=i.state)?o:n.state,p=f?Q(f):void 0,g=d,h=g?U({...g,stop:null==(s=g.stop)||s}):void 0,m=Ue(l)?Ve(l,ze(e.transformers)):void 0,v=Ue(u)?Ve(u,ze(e.transformers)):void 0,y=a.push,w=null!=y?y:e.push,b=Boolean(y),k=async(n,o,s)=>{var r;let a;const c=null!=v?v:void 0!==u?(()=>{const t=G(u,Y(s.ingest));return 0===t.length?[]:Ve(1===t.length?t[0]:t,ze(e.transformers))})():[];let d=[n];if(c.length>0&&e.transformers&&Object.keys(e.transformers).length>0){const o=await Be(e,e.transformers,c,n,s.ingest,s.respond,`source.${t}.before`);if(null===o.event)return{ok:!0};if(o.stopped)return o.respond&&(s.respond=o.respond),{ok:!0};o.respond&&(s.respond=o.respond),d=Array.isArray(o.event)?o.event:[o.event]}if(h){const t=Pe(h,e);if(t){const n=Y(s.ingest),o=await W(h,t,n);if(o){if("HIT"===o.status&&void 0!==o.value&&h.stop){let t=o.value;return o.rule.update&&(t=await J(t,o.rule.update,{...n,cache:{status:"HIT"}},e)),null==(r=s.respond)||r.call(s,t),{ok:!0}}if("MISS"===o.status&&h.stop&&s.respond){const r=s.respond,i=o.rule.update,c={...n,cache:{status:"MISS"}},l=o.key,u=o.rule.ttl,d=n=>{L(t,l,n,u),i?a=(async()=>{const t=await J(n,i,c,e);r(t)})():r(n)};s.respond=d}"MISS"!==o.status||h.stop||L(t,o.key,!0,o.rule.ttl)}}}const f=m?{kind:"single",preChain:m}:void 0!==l?(()=>{const t=G(l,Y(s.ingest));return 0===t.length?{kind:"single",preChain:[]}:1===t.length?{kind:"single",preChain:Ve(t[0],ze(e.transformers))}:{kind:"many",branches:t.map(t=>Ve(t,ze(e.transformers)))}})():{kind:"single",preChain:[]};!b&&p&&p.length>0&&(d=await Promise.all(d.map(t=>X(p,t=>Ke(t,e),t,e))));let g={ok:!0};for(const n of d)"many"===f.kind?(await Promise.all(f.branches.map((r,a)=>B(async()=>b?w(n):w(n,{...o,id:t,ingest:Ne(s.ingest,`${t}.${a}`),respond:void 0,mapping:i,preChain:r}),t=>(e.logger.scope("source:many").error(`many branch ${a} failed`,{error:t}),{ok:!0}))())),g={ok:!0}):g=b?await w(n):await w(n,{...o,id:t,ingest:s.ingest,respond:s.respond,mapping:i,preChain:f.preChain});return a&&await a,g},I=async n=>{const o=F(t);if(!i.ingest||void 0===n)return o;const s=await N(n,i.ingest,{collector:e});return{...o,...s,_meta:o._meta}},S=e.logger.scope("source").scope(t),O={command:e.command,sources:e.sources,elb:e.sources.elb.push,logger:S,...a,push:async(e,n={})=>{const o={ingest:F(t),respond:void 0};return k(e,n,o)}},q={collector:e,logger:S,id:t,config:i,env:O,withScope:async(e,t,n)=>{const o={ingest:await I(e),respond:t};return n({...O,push:(e,t={})=>k(e,t,o),ingest:o.ingest,respond:o.respond})}},x=await B(r,n=>{if(n instanceof H)throw n;e.status.failed++,e.logger.scope("source").error("source factory failed",{sourceId:t,error:n})})(q);if(!x)return;const C=x.type||"unknown",D=e.logger.scope(C).scope(t);return O.logger=D,c&&(x.config={...x.config,primary:c}),x}function Ye(e,t,n,o){if(n instanceof z)throw n;e.logger.scope("on").error("on callback failed",{kind:t,...o,error:n})}function Qe(e){return e===_e.Consent||e===_e.User||e===_e.Globals||e===_e.Custom}function Xe(e,t){e.delivery.set(t,e.stateVersion)}function Ze(e,t){return e.allowed&&e.stateVersion>function(e,t){const n=e.delivery.get(t);return void 0===n?-1:n}(e,t)}function et(e,t,n){const o=e.cascade;if(!o)return!0;let s=o.counts.get(t);s||(s={},o.counts.set(t,s));const r=String(n),i=(s[r]||0)+1;return s[r]=i,i<=8||(9===i&&e.logger.error("state delivery did not converge",{type:r}),!1)}function tt(e,t){return{collector:e,logger:e.logger.scope("on").scope(String(t))}}function nt(e,t,n,o,s){if(!t.on)return;const r=t.type||"unknown",i=e.logger.scope(r).scope("on").scope(o),a={collector:e,logger:i,id:n,config:t.config,data:s,env:kt(t.env,t.config.env)};R(t.on,t=>Ye(e,"destination",t,{destId:n,type:o}))(o,a)}function ot(e,t,n,o){let s;switch(t){case _e.Consent:s=o||e.consent;break;case _e.Session:s=e.session;break;case _e.User:s=o||e.user;break;case _e.Custom:s=o||e.custom;break;case _e.Globals:s=o||e.globals;break;case _e.Config:s=o||e.config;break;case _e.Ready:case _e.Run:default:s=void 0}if(n.length)switch(t){case _e.Consent:!function(e,t,n){const o=n||e.consent,s=tt(e,_e.Consent);t.forEach(t=>{Ze(e,t)&&et(e,t,_e.Consent)&&(Object.keys(o).filter(e=>e in t).forEach(n=>{R(t[n],t=>Ye(e,"consent",t,{key:n}))(o,s)}),Xe(e,t))})}(e,n,o);break;case _e.Ready:!function(e,t){if(!e.allowed)return;const n=tt(e,_e.Ready);t.forEach(t=>{R(t,t=>Ye(e,"ready",t))(void 0,n)})}(e,n);break;case _e.Run:!function(e,t){if(!e.allowed)return;const n=tt(e,_e.Run);t.forEach(t=>{R(t,t=>Ye(e,"run",t))(void 0,n)})}(e,n);break;case _e.Session:!function(e,t){if(!e.session)return;const n=tt(e,_e.Session);t.forEach(t=>{R(t,t=>Ye(e,"session",t))(e.session,n)})}(e,n);break;default:{const o=tt(e,t),r=Qe(t);n.forEach(n=>{"function"==typeof n&&(r&&!Ze(e,n)||r&&!et(e,n,t)||(R(n,n=>Ye(e,"generic",n,{type:t}))(s,o),r&&Xe(e,n)))});break}}}function st(e,t,n){switch(t){case _e.Consent:return n||e.consent;case _e.Session:return e.session;case _e.User:return n||e.user;case _e.Custom:return n||e.custom;case _e.Globals:return n||e.globals;case _e.Config:return n||e.config;default:return}}async function rt(e,t,n,o,s){if(!t.on)return!1;if(Qe(o)&&!Ze(e,t))return!1;if(Qe(o)&&!et(e,t,o))return!1;const r=await V(t.on,t=>Ye(e,"source",t,{sourceId:n,type:o}))(o,s);return Qe(o)&&Xe(e,t),!1===r}function it(e,t,n,o){var s;if(!Number.isFinite(n.max)||n.max<=0)throw new Error(`pushBounded: max must be > 0 (got ${n.max})`);if("dropNewest"===(null!=(s=n.onOverflow)?s:"dropOldest"))return e.length>=n.max?(o&&o([t]),{appended:!1,dropped:1}):(e.push(t),{appended:!0,dropped:0});const r=[];for(;e.length>=n.max;)r.push(e.shift());return e.push(t),r.length>0&&o&&o(r),{appended:!0,dropped:r.length}}var at=new WeakMap;function ct(e,t,n,o){at.get(e)||(at.set(e,!0),t.warn(n,o))}function lt(e){at.delete(e)}var ut=Object.freeze({batched:!0});function dt(e){return e===ut}function ft(e){return void 0===e?{}:"number"==typeof e?{wait:e}:{wait:e.wait,size:e.size,age:e.age}}function pt(e,t){return e.status.destinations[t]||(e.status.destinations[t]={count:0,failed:0,duration:0,queuePushSize:0,dlqSize:0}),e.status.destinations[t]}function gt(e,t,n,o){var s;e.dropped[t]||(e.dropped[t]={});const r=e.dropped[t];return r[n]=(null!=(s=r[n])?s:0)+o,r[n]}function ht(e,t,n){if(!e)return[];if(Array.isArray(e)&&e.every(e=>"string"==typeof e))return Ve(e,t);if("string"==typeof e)return Ve(e,t);const o=x(e,m(n));return 0===o.length?[]:1===o.length?Ve(o[0],t):Ve(o,t)}async function mt(e,t,n={},o){var s,r,i,a,c,l;const{allowed:u,consent:d,globals:f,user:p}=e;if(!u)return wt({ok:!1});if(t){const n=e.config.queueMax;if(void 0===n)throw new Error("Collector.Config.queueMax is undefined; defaults must be seeded by collector()");const o=it(e.queue,t,{max:n});if(o.dropped>0){const t=gt(e.status,E("collector"),"queue",o.dropped);ct(e.queue,e.logger,"collector.queue overflow; oldest events dropped",{buffer:"queue",cap:n,droppedCount:t})}else e.queue.length<n&&lt(e.queue);e.status.in++}o||(o=e.destinations);const g=e.transformers?ze(e.transformers):{},I=await Promise.all(Object.entries(o||{}).map(async([o,s])=>{var r,i,a,c,l;if(s.config.disabled)return{id:o,destination:s,skipped:!0};let u=(s.queuePush||[]).map(e=>({...e,consent:d}));s.queuePush=[],t&&u.push(v(t));const I=n.ingest?{...n.ingest,_meta:{...n.ingest._meta,path:[...n.ingest._meta.path]}}:k("unknown");if(!u.length&&!(null==(r=s.queueOn)?void 0:r.length))return{id:o,destination:s,skipped:!0};if(!u.length&&(null==(i=s.queueOn)?void 0:i.length)){let t=!1;try{t=await vt(e,s,o)}catch(t){e.status.failed++;const n=s.type||"unknown";e.logger.scope(n).error("destination init failed",{error:t instanceof Error?t.message:String(t)})}return{id:o,destination:s,skipped:!t}}const O=[],x=u.filter(t=>{const n=q(s.config.consent,d,t.consent);if(n)return t.consent=n,O.push(t),!1;const r=Te(e,{stepId:E("destination",o),stepType:"destination",phase:"skip",eventId:"string"==typeof t.id?t.id:"",now:Date.now()});return r.skipReason="consent",d&&(r.consent={...d}),s.config.consent&&(r.meta={required:{...s.config.consent}}),S(e,r),!0});if(x.length>0){const t=s.queuePush,n=s.config.id||o,r={max:null!=(a=s.config.queueMax)?a:1e3};let i=0;for(const e of x)i+=it(t,e,r).dropped;if(i>0){pt(e,n);const o=gt(e.status,E("destination",n),"queue",i);ct(t,e.logger.scope(s.type||"unknown"),"destination.queuePush overflow; oldest events dropped",{buffer:"queuePush",destination:n,cap:r.max,droppedCount:o})}else t.length<r.max&&lt(t)}if(!O.length)return{id:o,destination:s,queue:u};let C,D,j=!1;try{j=await vt(e,s,o)}catch(t){e.status.failed++;const n=s.type||"unknown";e.logger.scope(n).error("destination init failed",{error:t instanceof Error?t.message:String(t)})}if(!j)return{id:o,destination:s,queue:u};s.dlq||(s.dlq=[]);const A=ht(s.config.before,g,I),$=s.config.next,P=null==(c=s.config)?void 0:c.cache,K=P?y(P):void 0,z=K?Pe(K,e):void 0,R=(null==(l=s.config)?void 0:l.state)?_(s.config.state):void 0,V=null==R?void 0:R.filter(e=>"get"===e.mode),F=null==R?void 0:R.filter(e=>"set"===e.mode);let H=0,N=0;return await Promise.all(O.map(async t=>{let r;if(t.globals=h(f,t.globals),t.user=h(p,t.user),(null==K?void 0:K.stop)&&z){const e=m(I,t),n=await w(K,z,e);if("HIT"===(null==n?void 0:n.status))return t;"MISS"===(null==n?void 0:n.status)&&(r={key:n.key,ttl:n.rule.ttl})}let i=t,a=n.respond;if(A.length>0&&e.transformers&&Object.keys(e.transformers).length>0){const s=await Be(e,e.transformers,A,t,I,n.respond,`destination.${o}.before`);if(null===s.event)return t;s.respond&&(a=s.respond),i=Array.isArray(s.event)?s.event[0]:s.event}if(K&&!K.stop&&z){const e=m(I,i),n=await w(K,z,e);if("HIT"===(null==n?void 0:n.status))return t;"MISS"===(null==n?void 0:n.status)&&(r={key:n.key,ttl:n.rule.ttl})}V&&V.length>0&&i&&(i=await T(V,t=>Ke(t,e),i,e));const c=Date.now();let l=!1;const u=await M(yt,t=>{var n;const r=s.type||"unknown";e.logger.scope(r).error("Push failed",{error:t,event:i.name}),C=t,l=!0;const a=s.dlq,c=s.config.id||o,u={max:null!=(n=s.config.dlqMax)?n:100},d=it(a,[i,t],u);if(d.dropped>0){pt(e,c);const t=gt(e.status,E("destination",c),"dlq",d.dropped);ct(a,e.logger.scope(s.type||"unknown"),"destination.dlq overflow; oldest entries dropped",{buffer:"dlq",destination:c,cap:u.max,droppedCount:t})}else a.length<u.max&&lt(a)})(e,s,o,i,I,a);if(H+=Date.now()-c,r&&z&&void 0===s.config.mock&&b(z,r.key,null==u||u,r.ttl),!l&&!dt(u)&&F&&F.length>0&&i&&(i=await T(F,t=>Ke(t,e),i,e)),void 0===u||dt(u)||(D=u),dt(u)&&N++,!l&&$){void 0!==u&&(I._response=u);const t=ht($,g,I);if(t.length>0&&e.transformers&&Object.keys(e.transformers).length>0){const n=await Be(e,e.transformers,t,i,I,a,`destination.${o}.next`);n.respond&&(a=n.respond)}}return t})),{id:o,destination:s,error:C,response:D,totalDuration:H,batchedCount:N,allowedCount:O.length}})),O={},x={},C={};for(const t of I){if(t.skipped)continue;const n=t.destination,o={type:n.type||"unknown",data:t.response};pt(e,t.id);const u=e.status.destinations[t.id],d=Date.now();if(u.queuePushSize=null!=(r=null==(s=n.queuePush)?void 0:s.length)?r:0,u.dlqSize=null!=(a=null==(i=n.dlq)?void 0:i.length)?a:0,t.error)o.error=t.error,C[t.id]=o,u.failed++,u.lastAt=d,u.duration+=t.totalDuration||0,e.status.failed++;else if(t.queue&&t.queue.length)x[t.id]=o;else{const n=null!=(c=t.batchedCount)?c:0,s=null!=(l=t.allowedCount)?l:0;(Math.max(0,s-n)>0||0===s)&&(O[t.id]=o,u.count++,u.lastAt=d,u.duration+=t.totalDuration||0,e.status.out++)}}return wt({event:t,...Object.keys(O).length&&{done:O},...Object.keys(x).length&&{queued:x},...Object.keys(C).length&&{failed:C}})}async function vt(e,t,n){var o;if(t.init&&!t.config.init){const s=t.type||"unknown",r=e.logger.scope(s),i={collector:e,logger:r,id:n,config:t.config,env:kt(t.env,t.config.env)};r.debug("init");const a=Date.now();let c;S(e,Te(e,{stepId:E("destination",n),stepType:"destination",phase:"init",eventId:"",now:a}));try{c=await $(t.init,"DestinationInit",e.hooks,e.logger)(i)}catch(t){const o=Date.now(),s=Te(e,{stepId:E("destination",n),stepType:"destination",phase:"error",eventId:"",now:o});throw s.durationMs=o-a,s.error=t instanceof Error?{name:t.name,message:t.message}:{message:String(t)},S(e,s),t}if(!1===c)return c;if(t.config={...c||t.config,init:!0},null==(o=t.queueOn)?void 0:o.length){const o=t.queueOn;t.queueOn=[];for(const{type:s,data:r}of o)nt(e,t,n,s,r)}r.debug("init done")}return!0}async function yt(e,t,n,o,s,r){var i,a,c,l,u,d,f;const{config:p}=t,g=await A(o,p,e);if(g.ignore)return!1;const h=t.type||"unknown",m=e.logger.scope(h),v={collector:e,logger:m,id:n,config:p,data:g.data,rule:g.mapping,ingest:s,env:{...kt(t.env,p.env),...r?{respond:r}:{}}};if(void 0!==p.mock)return m.debug("mock",{event:g.event.name}),p.mock;const y=g.mapping,w=g.mappingKey||"* *";if((null==y?void 0:y.batch)&&t.pushBatch&&void 0===p.mock){if(t.batches=t.batches||{},!t.batches[w]){const o={key:w,entries:[],events:[],data:[]},s=ft(y.batch),r=ft(p.batch),f=null!=(a=null!=(i=s.wait)?i:r.wait)?a:3e4,g=null!=(l=null!=(c=s.size)?c:r.size)?l:1e3,h=null!=(d=null!=(u=s.age)?u:r.age)?d:3e4,v=kt(t.env,p.env),b=I(async()=>{var o;const s=t.batches[w].batched;if(0===s.entries.length)return;const r={key:s.key,entries:s.entries,events:s.events,data:s.data};s.entries=[],s.events=[],s.data=[];const i=r.entries[0],a={collector:e,logger:m,id:n,config:p,data:void 0,rule:i.rule,ingest:i.ingest,env:{...v,...i.respond?{respond:i.respond}:{}}};m.debug("push batch",{events:r.entries.length});const c=t.config.id||n,l=pt(e,c),u=Date.now(),d=Te(e,{stepId:E("destination",n),stepType:"destination",phase:"flush",eventId:"",now:u});d.batch={size:r.entries.length,index:0},S(e,d);let f=!0;await M($(t.pushBatch,"DestinationPushBatch",e.hooks,e.logger),o=>{var s;f=!1;const i=Date.now(),a=Te(e,{stepId:E("destination",n),stepType:"destination",phase:"error",eventId:"",now:i});a.durationMs=i-u,a.error=o instanceof Error?{name:o.name,message:o.message}:{message:String(o)},a.batch={size:r.entries.length,index:0},S(e,a);const d=t.dlq=t.dlq||[],p={max:null!=(s=t.config.dlqMax)?s:100};let g=0;for(const e of r.entries)g+=it(d,[e.event,o],p).dropped;if(g>0){const t=gt(e.status,E("destination",c),"dlq",g);ct(d,m,"destination.dlq overflow; oldest entries dropped",{buffer:"dlq",destination:c,cap:p.max,droppedCount:t})}else d.length<p.max&&lt(d);l.failed+=r.entries.length,l.dlqSize=d.length,e.status.failed+=r.entries.length,m.error("Push batch failed",{error:o instanceof Error?o.message:String(o),entries:r.entries.length})})(r,a),m.debug("push batch done"),l.inFlightBatch=Math.max(0,(null!=(o=l.inFlightBatch)?o:0)-r.entries.length),f&&(l.count+=r.entries.length,l.lastAt=Date.now(),e.status.out+=r.entries.length)},{wait:f,size:g,age:h});t.batches[w]={batched:o,batchFn:()=>{b()},flush:async()=>{await b.flush()}}}const o=t.batches[w];o.batched.entries.push({event:g.event,ingest:s,respond:r,rule:y,data:g.data}),o.batched.events.push(g.event),C(g.data)&&o.batched.data.push(g.data);const h=t.config.id||n,v=pt(e,h);return v.inFlightBatch=(null!=(f=v.inFlightBatch)?f:0)+1,o.batchFn(),ut}{m.debug("push",{event:g.event.name});const o="string"==typeof g.event.id?g.event.id:"",s=Date.now(),r=Te(e,{stepId:E("destination",n),stepType:"destination",phase:"in",eventId:o,now:s});g.mappingKey&&(r.mappingKey=g.mappingKey),g.event.consent&&(r.consent={...g.event.consent}),S(e,r);try{const r=await $(t.push,"DestinationPush",e.hooks,e.logger)(g.event,v),i=Date.now(),a=Te(e,{stepId:E("destination",n),stepType:"destination",phase:"out",eventId:o,now:i});return a.durationMs=i-s,a.outEvent=r,g.mappingKey&&(a.mappingKey=g.mappingKey),S(e,a),m.debug("push done"),r}catch(t){const r=Date.now(),i=Te(e,{stepId:E("destination",n),stepType:"destination",phase:"error",eventId:o,now:r});throw i.durationMs=r-s,i.error=t instanceof Error?{name:t.name,message:t.message}:{message:String(t)},g.mappingKey&&(i.mappingKey=g.mappingKey),S(e,i),t}}}function wt(e){return{ok:!(null==e?void 0:e.failed),...e}}function bt(e){const{code:t,config:n={},env:o={},cache:s,state:r}=e,{config:i}=Re(e,"before"),{config:a}=Re({...e,config:i},"next"),c={...t.config,...n,...a};s&&(c.cache=s),void 0!==r&&void 0===c.state&&(c.state=r);const l=kt(t.env,o);return{...t,config:c,env:l}}function kt(e,t){return e||t?t?e&&j(e)&&j(t)?{...e,...t}:t:e:{}}async function It(e,t,n){const o=Object.entries(e).map(async([e,o])=>{var s;const r=o.destroy;if(!r)return;const i=o.type||"unknown",a=n.scope(i),c={id:e,config:o.config,env:null!=(s=o.env)?s:{},logger:a};try{await Promise.race([r(c),new Promise((n,o)=>setTimeout(()=>o(new Error(`${t} '${e}' destroy timed out`)),5e3))])}catch(n){a.error(`${t} '${e}' destroy failed: ${n}`)}});await Promise.allSettled(o)}async function St(e,t,n){let o,s,r=!1;const i=function(e){return e.cascade?()=>{}:(e.cascade={counts:new WeakMap},()=>{e.cascade=void 0})}(e);try{return await async function(){switch(t){case _e.Config:we(n)&&(he(e.config,n,{shallow:!1}),s=n,r=!0);break;case _e.Consent:if(we(n)){const{update:t}=function(e,t){const n={};return Object.entries(t).forEach(([e,t])=>{n[e]=!!t}),e.consent=f(e.consent,n),{update:n}}(e,n);e.stateVersion++,s=t,r=!0}break;case _e.Custom:we(n)&&(e.custom=he(e.custom,n),e.stateVersion++,s=n,r=!0);break;case _e.Destination:we(n)&&"code"in n&&we(n.code)&&(o=await async function(e,t){const{code:n,config:o={},env:s={},before:r,next:i,cache:a,state:c}=t;if(!D(n.push))return wt({ok:!1,failed:{invalid:{type:"invalid",error:"Destination code must have a push method"}}});const l=o||{init:!1};let u=r?{...l,before:r}:{...l};i&&(u={...u,next:i}),a&&(u={...u,cache:a}),void 0!==c&&void 0===u.state&&(u={...u,state:c});const d={...n,config:u,env:kt(n.env,s)};let f=d.config.id;if(!f)do{f=O(5,"abcdefghijklmnopqrstuvwxyz")}while(e.destinations[f]);return e.destinations[f]=d,!1!==d.config.queue&&(d.queuePush=[...e.queue]),mt(e,void 0,{},{[f]:d})}(e,n));break;case _e.Globals:we(n)&&(e.globals=he(e.globals,n),e.stateVersion++,s=n,r=!0);break;case _e.Hook:if(we(n)&&ye(n.name)&&ve(n.fn)){const{name:t,fn:o}=n;e.hooks[t]=o,s=n,r=!0}break;case _e.On:if(we(n)&&ye(n.type)){const{type:t,rules:o}=n;await async function(e,t,n){const o=e.on,s=o[t]||[],r=K(n)?n:[n];r.forEach(e=>{s.push(e)}),o[t]=s,ot(e,t,r)}(e,t,o)}break;case _e.Ready:r=!0;break;case _e.Run:o=await async function(e,t){return e.allowed=!0,e.timing=Date.now(),t&&(t.consent&&(e.consent=he(e.consent,t.consent),e.stateVersion++),t.user&&(e.user=he(e.user,t.user),e.stateVersion++),t.globals&&(e.globals=he(e.config.globalsStatic||{},t.globals),e.stateVersion++),t.custom&&(e.custom=he(e.custom,t.custom),e.stateVersion++)),Object.values(e.destinations).forEach(e=>{e.queuePush=[]}),e.queue=[],e.round++,await async function(e){const t=[{type:_e.Consent,nonEmpty:Object.keys(e.consent).length>0},{type:_e.User,nonEmpty:Object.keys(e.user).length>0},{type:_e.Globals,nonEmpty:Object.keys(e.globals).length>0},{type:_e.Custom,nonEmpty:Object.keys(e.custom).length>0}];for(const{type:n,nonEmpty:o}of t){if(!o)continue;const t=st(e,n);ot(e,n,e.on[n]||[]);for(const[o,s]of Object.entries(e.sources))Le(s)&&await rt(e,s,o,n,t)}}(e),await mt(e)}(e,n),r=!0;break;case _e.Session:r=!0;break;case _e.Shutdown:await async function(e){const t=e.logger;await It(e.sources,"source",t),await It(e.destinations,"destination",t),await It(e.transformers,"transformer",t),await It(e.stores,"store",t)}(e);break;case _e.User:we(n)&&(he(e.user,n,{shallow:!1}),e.stateVersion++,s=n,r=!0)}return r&&(await async function(e,t,n,o){var s,r;let i,a=n||[];switch(n||(a=e.on[t]||[]),t){case _e.Consent:i=o||e.consent;break;case _e.Session:i=e.session;break;case _e.User:i=o||e.user;break;case _e.Custom:i=o||e.custom;break;case _e.Globals:i=o||e.globals;break;case _e.Config:i=o||e.config;break;case _e.Ready:case _e.Run:default:i=void 0}let c=!1;for(const[n,o]of Object.entries(e.sources)){if(null==(s=o.config.require)?void 0:s.length){const e=o.config.require.indexOf(t);-1!==e&&o.config.require.splice(e,1)}o.on&&(Le(o)?await rt(e,o,n,t,i)&&(c=!0):(o.queueOn=o.queueOn||[],o.queueOn.push({type:t,data:i})))}Object.entries(e.destinations).forEach(([n,o])=>{if(o.on){if(!o.config.init)return o.queueOn=o.queueOn||[],void o.queueOn.push({type:t,data:i});nt(e,o,n,t,i)}});for(const[t,n]of Object.entries(e.sources))Le(n)&&(null==(r=n.queueOn)?void 0:r.length)&&await We(e,n,t);return Object.keys(e.pending.destinations).length>0&&await async function(e,t){var n;for(const[o,s]of Object.entries(e.pending.destinations)){if(!e.pending.destinations[o]||e.destinations[o])continue;const r=null==(n=s.config)?void 0:n.require;if(!r)continue;const i=r.indexOf(t);if(-1===i)continue;if(r.splice(i,1),r.length>0)continue;delete e.pending.destinations[o];const a=bt(s);!1!==a.config.queue&&(a.queuePush=[...e.queue]),e.destinations[o]=a}}(e,t),ot(e,t,a,o),!c}(e,t,void 0,s),o=await mt(e)),o||wt({ok:!0})}()}finally{i()}}function Ot(e,t){if(!t.name)throw new Error("Event name is required");const[n,o]=t.name.split(" ");if(!n||!o)throw new Error("Event name is invalid");const{timestamp:s=Date.now(),name:r=`${n} ${o}`,data:i={},context:a={},globals:c=e.globals,custom:l={},user:u=e.user,nested:d=[],consent:f=e.consent,id:p=me(),trigger:g="",entity:h=n,action:m=o,timing:v=0,source:y={type:"collector",schema:"4"}}=t;return{name:r,data:i,context:a,globals:c,custom:l,user:u,nested:d,consent:f,id:p,trigger:g,entity:h,action:m,timestamp:s,timing:v,source:y}}function qt(e={}){var t,n,o;const s=null!=(t=e.maxEntries)?t:1e4,r=null!=(n=e.lowWaterMark)?n:.8,i=null!=(o=e.sweepIntervalMs)?o:6e4,a=Math.floor(s*r),c=new Map,l={hits:0,misses:0,populates:0,writes:0,deletes:0,evictions_entries:0,evictions_ttl:0};let u;return i>0&&(u=setInterval(function(){const e=Date.now();let t=0;for(const[n,o]of c)void 0!==o.expires&&o.expires<=e&&(c.delete(n),t++);l.evictions_ttl+=t},i),u&&"function"==typeof u.unref&&u.unref()),{type:"memory",config:{},get(e){const t=c.get(e);if(t)return void 0!==t.expires&&t.expires<=Date.now()?(c.delete(e),l.evictions_ttl++,void l.misses++):(c.delete(e),c.set(e,t),l.hits++,t.value);l.misses++},set(e,t,n){const o=!c.has(e);o||c.delete(e),c.set(e,{value:t,expires:void 0!==n?Date.now()+n:void 0}),l.writes++,o&&l.populates++,c.size>s&&function(){if(c.size<=s)return;const e=c.size-a;let t=0;for(const n of c.keys()){if(t>=e)break;c.delete(n),t++}l.evictions_entries+=t}()},delete(e){c.delete(e)&&l.deletes++},get counters(){return{...l}},destroy(){void 0!==u&&(clearInterval(u),u=void 0),c.clear()}}}function xt(e,t){const{cacheConfig:n,cacheStore:o,namespace:s,logger:r,storeId:i,collector:a}=t,c=(e,t)=>{if(!a)return;const n=Te(a,{stepId:`store.${i}`,stepType:"store",phase:"in",eventId:"",now:Date.now()});n.meta={op:"cache",cached:"hit"===t,status:t,key:e},$e(a,n)},l={hits:0,misses:0,populates:0,writes:0,deletes:0,inflight_dedups:0},u=n.rules.map(e=>({match:e.match?Me(e.match):()=>!0,ttl:e.ttl})),d=e=>`${s}:${e}`;function f(e,t){const n=void 0===t?{key:e}:{key:e,value:t};return u.find(e=>e.match(n))}const p=new Map;return{type:e.type,config:e.config,setup:e.setup,get counters(){return{...l}},async get(t){const n=d(t),s=await o.get(n);if(void 0!==s)return l.hits++,c(t,"hit"),s;const r=p.get(n);if(r)return l.inflight_dedups++,c(t,"hit"),r;l.misses++,c(t,"miss");const i=(async()=>{try{const s=await e.get(t);if(void 0===s)return;const r=f(t,s);if(r)try{await o.set(n,s,1e3*r.ttl),l.populates++}catch(e){g("set",t,e)}return s}finally{p.delete(n)}})();return p.set(n,i),i},async set(t,n,s){l.writes++,await e.set(t,n,s);const r=f(t,n);if(r)try{await o.set(d(t),n,1e3*r.ttl)}catch(e){g("set",t,e)}},async delete(t){l.deletes++,await e.delete(t);try{await o.delete(d(t))}catch(e){g("delete",t,e)}}};function g(e,t,n){const o=`store-cache(${i}): cache ${e} failed for "${t}"; backing succeeded, continuing`;r?r.warn(o,{error:n}):console.warn(o,n)}}function Ct(e,t,n){const o=`store.${n}`,s=Ee(t.get,"StoreGet",e.hooks,e.logger),r=Ee(t.set,"StoreSet",e.hooks,e.logger),i=Ee(t.delete,"StoreDelete",e.hooks,e.logger);t.get=async t=>{const n=Date.now(),r=Te(e,{stepId:o,stepType:"store",phase:"in",eventId:"",now:n});r.meta={op:"get",key:t},Ae(e,r);try{const r=await s(t),i=Date.now(),a=Te(e,{stepId:o,stepType:"store",phase:"out",eventId:"",now:i});return a.durationMs=i-n,a.meta={op:"get",key:t},Ae(e,a),r}catch(s){const r=Date.now(),i=Te(e,{stepId:o,stepType:"store",phase:"error",eventId:"",now:r});throw i.durationMs=r-n,i.meta={op:"get",key:t},i.error=s instanceof Error?{name:s.name,message:s.message}:{message:String(s)},Ae(e,i),s}},t.set=async(t,n,s)=>{const i=Date.now(),a=Te(e,{stepId:o,stepType:"store",phase:"in",eventId:"",now:i});a.meta={op:"set",key:t},Ae(e,a);try{await r(t,n,s);const a=Date.now(),c=Te(e,{stepId:o,stepType:"store",phase:"out",eventId:"",now:a});c.durationMs=a-i,c.meta={op:"set",key:t},Ae(e,c)}catch(n){const s=Date.now(),r=Te(e,{stepId:o,stepType:"store",phase:"error",eventId:"",now:s});throw r.durationMs=s-i,r.meta={op:"set",key:t},r.error=n instanceof Error?{name:n.name,message:n.message}:{message:String(n)},Ae(e,r),n}},t.delete=async t=>{const n=Date.now(),s=Te(e,{stepId:o,stepType:"store",phase:"in",eventId:"",now:n});s.meta={op:"delete",key:t},Ae(e,s);try{await i(t);const s=Date.now(),r=Te(e,{stepId:o,stepType:"store",phase:"out",eventId:"",now:s});r.durationMs=s-n,r.meta={op:"delete",key:t},Ae(e,r)}catch(s){const r=Date.now(),i=Te(e,{stepId:o,stepType:"store",phase:"error",eventId:"",now:r});throw i.durationMs=r-n,i.meta={op:"delete",key:t},i.error=s instanceof Error?{name:s.name,message:s.message}:{message:String(s)},Ae(e,i),s}}}async function Dt(e){var t,n;const o=p({globalsStatic:{},sessionStatic:{},run:!0,queueMax:1e3},e,{merge:!1,extend:!1}),s={level:null==(t=e.logger)?void 0:t.level,handler:null==(n=e.logger)?void 0:n.handler},r=g(s),i={...o.globalsStatic,...e.globals},a={allowed:!1,config:o,consent:e.consent||{},custom:e.custom||{},destinations:{},transformers:{},stores:{},globals:i,hooks:e.hooks||{},observers:new Set,logger:r,on:{},queue:[],round:0,stateVersion:0,delivery:new WeakMap,session:void 0,status:{startedAt:Date.now(),in:0,out:0,failed:0,sources:{},destinations:{},dropped:{}},timing:Date.now(),user:e.user||{},sources:{},pending:{destinations:{}},push:void 0,command:void 0};var c,l;a.push=function(e,t){const n=xe(async(n,o={})=>await qe(async()=>{var s;const r=Date.now(),{id:i,ingest:a,respond:c,mapping:l,preChain:u,include:d,exclude:f}=o;let p=c,g=n;const h=d||f?function(e,t,n){let o=e;return t&&(o=Object.fromEntries(Object.entries(o).filter(([e])=>t.includes(e)))),n&&(o=Object.fromEntries(Object.entries(o).filter(([e])=>!n.includes(e)))),o}(e.destinations,d,f):void 0,m=null!=a?a:be(i||"unknown");if(l){const t=await Oe(g,l,e);if(t.ignore)return wt({ok:!0});if(l.consent&&!Se(l.consent,e.consent,t.event.consent))return wt({ok:!0});g=t.event}if((null==u?void 0:u.length)&&e.transformers&&Object.keys(e.transformers).length>0){const n=await Be(e,e.transformers,u,g,m,p,i?`source.${i}.next`:void 0);if(null===n.event)return wt({ok:!0});if(n.stopped)return n.respond&&(p=n.respond),wt({ok:!0});if(n.respond&&(p=n.respond),Array.isArray(n.event)){const o=await Promise.all(n.event.map(async n=>{const o=t(n),s=Ot(e,o);return mt(e,s,{id:i,ingest:m,respond:p},h)}));if(i){e.status.sources[i]||(e.status.sources[i]={count:0,duration:0});const t=e.status.sources[i];t.count+=n.event.length,t.lastAt=Date.now(),t.duration+=Date.now()-r}return null!=(s=o[0])?s:wt({ok:!0})}g=n.event}const v=t(g),y=Ot(e,v),w=await mt(e,y,{id:i,ingest:m,respond:p},h);if(i){e.status.sources[i]||(e.status.sources[i]={count:0,duration:0});const t=e.status.sources[i];t.count++,t.lastAt=Date.now(),t.duration+=Date.now()-r}return w},t=>{if(t instanceof Ie)throw t;return e.status.failed++,e.logger.error("push failed",{event:n,ingest:o.ingest,error:t}),wt({ok:!1})})(),"Push",e.hooks,e.logger);return async(t,o)=>{const s="string"==typeof t.id?t.id:"",r=Date.now();ke(e,Te(e,{stepId:"collector.push",stepType:"collector",phase:"in",eventId:s,now:r}));try{const i=await n(t,o),a=Date.now(),c=Te(e,{stepId:"collector.push",stepType:"collector",phase:"out",eventId:s,now:a});return c.durationMs=a-r,c.outEvent=i,ke(e,c),i}catch(t){const n=Date.now(),o=Te(e,{stepId:"collector.push",stepType:"collector",phase:"error",eventId:s,now:n});throw o.durationMs=n-r,o.error=t instanceof Error?{name:t.name,message:t.message}:{message:String(t)},ke(e,o),t}}}(a,e=>({timing:Math.round((Date.now()-a.timing)/10)/100,source:{type:"collector",schema:"4",version:"4.2.0-next-1780387694663"},...e})),a.command=(l=St,De(async(e,t,n)=>await je(async()=>await l(c,e,t,n),n=>{if(n instanceof Ce)throw n;return c.status.failed++,c.logger.error("command failed",{command:e,data:t,error:n}),wt({ok:!1})})(),"Command",(c=a).hooks,c.logger));const u=e.stores||{};return a.stores=await async function(e,t={}){var n;const o={};for(const[n,s]of Object.entries(t)){const{code:t,config:r={},env:i={}}=s,a=e.logger.scope("store").scope(n),c={collector:e,logger:a,id:n,config:r,env:i},l=await t(c);o[n]=l}const s=t,r=function(e){const t={};for(const n of Object.keys(e))t[n]="WHITE";const n=[],o=[];function s(r){var i;const a=t[r];if("BLACK"===a)return;if("GRAY"===a){const e=o.indexOf(r),t=o.slice(-1===e?0:e).concat(r).join(" -> ");throw new Error(`Cycle in cache.store chain: ${t}`)}t[r]="GRAY",o.push(r);const c=null==(i=e[r].cache)?void 0:i.store;if(void 0!==c){if(!(c in e))throw new Error(`Store "${r}" cache.store references "${c}", which is not declared in flow.stores`);s(c)}o.pop(),t[r]="BLACK",n.push(r)}for(const n of Object.keys(e))"WHITE"===t[n]&&s(n);return n}(s);for(const t of r){const r=s[t].cache;if(!r)continue;let i,a;void 0!==r.store?(i=o[r.store],a=r.store):(o.__cache||(o.__cache=qt()),i=o.__cache,a="__cache");const c=null!=(n=r.namespace)?n:t;e.logger.scope("store-cache").scope(t).info(`store "${t}" caches with namespace "${c}:" via ${a}`),o[t]=xt(o[t],{storeId:t,cacheConfig:r,cacheStore:i,namespace:c,logger:e.logger.scope("store-cache").scope(t),collector:e})}for(const[t,n]of Object.entries(o))"__cache"!==t&&Ct(e,n,t);return o}(a,u),function(e,t,n){const o=new Map;for(const[n,s]of Object.entries(e))t[n]&&o.set(s,t[n]);if(0!==o.size)for(const e of[n.transformers,n.destinations,n.sources])if(e)for(const t of Object.values(e))s(t.env);function s(e){if(e)for(const[t,n]of Object.entries(e))if("object"==typeof n&&null!==n){const s=o.get(n);s&&(e[t]=s)}}}(u,a.stores,e),a.stores.__cache||(a.stores.__cache=qt()),a.destinations=await async function(e,t={}){var n,o;const s={};for(const[r,i]of Object.entries(t))(null==(o=null==(n=i.config)?void 0:n.require)?void 0:o.length)?e.pending.destinations[r]=i:s[r]=bt(i);return s}(a,e.destinations||{}),a.transformers=await async function(e,t={}){var n,o,s,r,i,a,c,l;const u={};for(const[d,f]of Object.entries(t)){const{code:t,env:p={}}=f,g=de(f,"Transformer");if(!g.ok){e.logger.warn(`Transformer ${d} invalid (${g.code}): ${g.reason}. Skipping.`);continue}const{config:h}=Re(f,"before"),{config:m}=Re({...f,config:h},"next"),v=Object.keys(p).length>0?{...m,env:p}:m,{cache:y}=f,w=y?{...v,cache:y}:v,b=null!=(o=null==(n=f.config)?void 0:n.state)?o:f.state,k=void 0!==b&&void 0===w.state?{...w,state:b}:w,I=e.logger.scope("transformer").scope(d),S={collector:e,logger:I,id:d,ingest:Z(d),config:k,env:p},O=null!=t?t:e=>{const t=f.mapping;if(t){const n=[];if(void 0!==t.data&&n.push("data"),t.mapping)for(const[e,o]of Object.entries(t.mapping))if("object"==typeof o&&null!==o)for(const[t,s]of Object.entries(o)){if("object"!=typeof s||null===s)continue;const o=s;void 0!==o.data&&n.push(`mapping[${e}][${t}].data`),void 0!==o.silent&&n.push(`mapping[${e}][${t}].silent`)}return n.length>0&&e.collector.logger.warn(`Transformer ${d}: \`${n.join(", ")}\` ignored at transformer position (only event-mutating fields apply).`),{type:"pass",config:e.config,push:async n=>{const o=await fe(n,t,e.collector);return!o.ignore&&{event:o.event}}}}return{type:"pass",config:e.config,push:e=>({event:e})}},q=await O(S);void 0!==f.before&&void 0===(null==(s=q.config)?void 0:s.before)&&(q.config={...null!=(r=q.config)?r:{},before:f.before}),void 0!==f.next&&void 0===(null==(i=q.config)?void 0:i.next)&&(q.config={...null!=(a=q.config)?a:{},next:f.next}),void 0!==b&&void 0===(null==(c=q.config)?void 0:c.state)&&(q.config={...null!=(l=q.config)?l:{},state:b}),u[d]=q}return u}(a,e.transformers||{}),a}async function jt(e){e=e||{};const t=await Dt(e),n=(o=t,{type:"elb",config:{},push:async(e,t,n,s,r)=>{if("string"==typeof e&&e.startsWith("walker ")){const n=e.replace("walker ","");return o.command(n,t)}let i;if("string"==typeof e)i={name:e},t&&"object"==typeof t&&!Array.isArray(t)&&(i.data=t);else{if(!e||"object"!=typeof e)return wt({ok:!1});i=e,t&&"object"==typeof t&&!Array.isArray(t)&&(i.data={...i.data||{},...t})}return n&&"object"==typeof n&&(i.context=n),s&&Array.isArray(s)&&(i.nested=s),r&&"object"==typeof r&&(i.custom=r),o.push(i)}});var o;t.sources.elb=n,await async function(e,t={}){var n;const o={};for(const[s,r]of Object.entries(t)){const t=await Je(e,s,r);if(!t)continue;const i=null==(n=r.config)?void 0:n.require;t.config={...t.config,init:!1,...i?{require:[...i]}:{}},o[s]=t}Object.assign(e.sources,o);for(const t of Object.keys(o)){const n=e.sources[t];let o=!1;n.init&&await B(n.init.bind(n),n=>{if(n instanceof H)throw n;o=!0,e.status.failed++,e.logger.scope("source").error("source init failed",{sourceId:t,error:n})})(),o||(n.config.init=!0,Le(n)&&await We(e,n,t))}return o}(t,e.sources||{});const{consent:s,user:r,globals:i,custom:a}=e;s&&await t.command("consent",s),r&&await t.command("user",r),i&&Object.assign(t.globals,i),a&&Object.assign(t.custom,a),t.config.run&&await t.command("run");let c=n.push;const l=Object.values(t.sources).filter(e=>"elb"!==e.type),u=l.find(e=>e.config.primary);return u?c=u.push:l.length>0&&(c=l[0].push),{collector:t,elb:c}}var At=async e=>{let t;return{get flow(){return t},trigger:(n,o)=>async n=>{var s,r,i,a,c,l,u,d,f;const p=o||{};if(p.url){const e=new URL(p.url);window.history.replaceState({},"",e.pathname+e.search)}if(p.referrer&&Object.defineProperty(document,"referrer",{value:p.referrer,configurable:!0}),p.sessionData){const e=p.sessionKey||"elbSessionId";localStorage.setItem(e,JSON.stringify(p.sessionData))}if(p.deviceId){const e=p.deviceKey||"elbDeviceId";localStorage.setItem(e,p.deviceId)}if(!t){const n=await jt({...e,run:null==(s=e.run)||s});t={collector:n.collector,elb:n.elb};const o=p.sessionKey||(null==(c=null==(a=null==(i=null==(r=e.sources)?void 0:r.session)?void 0:i.config)?void 0:a.settings)?void 0:c.sessionKey)||"elbSessionId",g=p.deviceKey||(null==(f=null==(d=null==(u=null==(l=e.sources)?void 0:l.session)?void 0:u.config)?void 0:d.settings)?void 0:f.deviceKey)||"elbDeviceId";localStorage.removeItem(o),localStorage.removeItem(g),p.sessionData&&localStorage.setItem(o,JSON.stringify(p.sessionData)),p.deviceId&&localStorage.setItem(g,p.deviceId),e.consent&&await t.collector.command("consent",e.consent)}}}},Et=(e,t)=>{if(!e||"object"!=typeof e)return;const n=e,o=t.localStorage;if(n.sessionData&&"object"==typeof n.sessionData){const e="string"==typeof n.sessionKey?n.sessionKey:"elbSessionId";o.setItem(e,JSON.stringify(n.sessionData))}if("string"==typeof n.deviceId){const e="string"==typeof n.deviceKey?n.deviceKey:"elbDeviceId";o.setItem(e,n.deviceId)}};export{c as examples,n as schemas};//# sourceMappingURL=dev.mjs.map
package/dist/dev.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/schemas/index.ts","../src/schemas/settings.ts","../src/examples/index.ts","../src/examples/step.ts","../src/examples/trigger.ts"],"sourcesContent":["import { zodToSchema } from '@walkeros/core/dev';\nimport { SettingsSchema } from './settings';\n\n// Export Zod schemas and types\nexport { SettingsSchema, type Settings } from './settings';\n\n// JSON Schema exports (for website PropertyTable)\nexport const settings = zodToSchema(SettingsSchema);\n","import { z, ClickIdEntrySchema } from '@walkeros/core/dev';\n\n/**\n * Session source settings schema\n */\nexport const SettingsSchema = z.object({\n storage: z\n .boolean()\n .default(false)\n .describe('Enable persistent storage for session/device IDs')\n .optional(),\n\n consent: z\n .union([z.string(), z.array(z.string())])\n .describe('Consent key(s) required to enable storage mode')\n .optional(),\n\n length: z\n .number()\n .default(30)\n .describe('Session timeout in minutes')\n .optional(),\n\n pulse: z\n .boolean()\n .default(false)\n .describe('Keep session alive on each event')\n .optional(),\n\n sessionKey: z\n .string()\n .default('elbSessionId')\n .describe('Storage key for session ID')\n .optional(),\n\n sessionStorage: z\n .enum(['local', 'session'])\n .default('local')\n .describe('Storage type for session')\n .optional(),\n\n deviceKey: z\n .string()\n .default('elbDeviceId')\n .describe('Storage key for device ID')\n .optional(),\n\n deviceStorage: z\n .enum(['local', 'session'])\n .default('local')\n .describe('Storage type for device')\n .optional(),\n\n deviceAge: z\n .number()\n .default(30)\n .describe('Device ID age in days')\n .optional(),\n\n // Note: Using z.any() because z.custom() cannot be converted to JSON Schema\n // TypeScript types provide compile-time safety; runtime accepts function or false\n cb: z\n .any()\n .describe('Custom session callback function or false to disable')\n .optional(),\n\n clickIds: z\n .array(ClickIdEntrySchema)\n .describe(\n 'Custom click-ID registry. Entries with a `param` matching a default override the platform name in place; new params append to the end of the priority list.',\n )\n .optional(),\n});\n\nexport type Settings = z.infer<typeof SettingsSchema>;\n","export * as step from './step';\nexport { createTrigger, trigger } from './trigger';\n","import type { Flow } from '@walkeros/core';\n\n/**\n * Session source emits three elb calls on start:\n * 1. command('user', { session, device? })\n * 2. command('session', <full session data>)\n * 3. push({ name: 'session start', data: <full session data> })\n */\n\nexport const newMarketingSession: Flow.StepExample = {\n title: 'New marketing session',\n description:\n 'A visit with UTM parameters starts a new session and emits walker user, session, and session start calls.',\n trigger: {\n type: 'load',\n options: {\n url: 'https://example.com/?utm_source=google&utm_medium=cpc&utm_campaign=winter-sale',\n },\n },\n in: { storage: true },\n out: [\n ['elb', 'user', { session: 's3ss10n-id', device: 'd3v1c3-id' }],\n [\n 'elb',\n 'session',\n {\n id: 's3ss10n-id',\n start: 1700000000000,\n isNew: true,\n count: 1,\n runs: 1,\n marketing: true,\n source: 'google',\n medium: 'cpc',\n campaign: 'winter-sale',\n referrer: '',\n device: 'd3v1c3-id',\n isStart: true,\n storage: true,\n updated: 1700000000000,\n },\n ],\n [\n 'elb',\n {\n name: 'session start',\n data: {\n id: 's3ss10n-id',\n start: 1700000000000,\n isNew: true,\n count: 1,\n runs: 1,\n marketing: true,\n source: 'google',\n medium: 'cpc',\n campaign: 'winter-sale',\n referrer: '',\n device: 'd3v1c3-id',\n isStart: true,\n storage: true,\n updated: 1700000000000,\n },\n },\n ],\n ],\n};\n\nexport const returningVisitor: Flow.StepExample = {\n title: 'Returning visitor',\n description:\n 'A returning visit with a google referrer reuses the stored device id and increments the session count.',\n trigger: {\n type: 'load',\n options: {\n referrer: 'https://google.com',\n },\n },\n in: { storage: true },\n out: [\n ['elb', 'user', { session: 'n3w-s3ss10n', device: 'd3v1c3-id' }],\n [\n 'elb',\n 'session',\n {\n id: 'n3w-s3ss10n',\n start: 1700001000000,\n isNew: false,\n count: 3,\n runs: 1,\n referrer: 'google.com',\n device: 'd3v1c3-id',\n isStart: true,\n storage: true,\n updated: 1700001000000,\n },\n ],\n [\n 'elb',\n {\n name: 'session start',\n data: {\n id: 'n3w-s3ss10n',\n start: 1700001000000,\n isNew: false,\n count: 3,\n runs: 1,\n referrer: 'google.com',\n device: 'd3v1c3-id',\n isStart: true,\n storage: true,\n updated: 1700001000000,\n },\n },\n ],\n ],\n};\n","import type { Trigger, Collector } from '@walkeros/core';\nimport { startFlow } from '@walkeros/collector';\n\ninterface SessionTriggerOptions {\n url?: string;\n referrer?: string;\n sessionData?: Record<string, unknown>;\n deviceId?: string;\n sessionKey?: string;\n deviceKey?: string;\n}\n\nconst createTrigger: Trigger.CreateFn<Record<string, unknown>, void> = async (\n config: Collector.InitConfig,\n) => {\n let flow: Trigger.FlowHandle | undefined;\n\n const trigger: Trigger.Fn<Record<string, unknown>, void> =\n (type?: string, opts?: unknown) =>\n async (content: Record<string, unknown>) => {\n const options = (opts || {}) as SessionTriggerOptions;\n\n // Pre-init: seed world state before source reads it\n if (options.url) {\n const urlObj = new URL(options.url);\n window.history.replaceState({}, '', urlObj.pathname + urlObj.search);\n }\n if (options.referrer) {\n Object.defineProperty(document, 'referrer', {\n value: options.referrer,\n configurable: true,\n });\n }\n if (options.sessionData) {\n const key = options.sessionKey || 'elbSessionId';\n localStorage.setItem(key, JSON.stringify(options.sessionData));\n }\n if (options.deviceId) {\n const key = options.deviceKey || 'elbDeviceId';\n localStorage.setItem(key, options.deviceId);\n }\n\n // Lazy startFlow — session source fires events during init, but\n // collector.allowed is false until command('run'). The initial\n // session event is dropped. After startFlow, clear the session\n // data written by the dropped init, re-seed, and trigger a consent\n // update to cause session re-init with allowed=true.\n if (!flow) {\n const result = await startFlow({ ...config, run: config.run ?? true });\n flow = { collector: result.collector, elb: result.elb };\n\n // Clear session data written by the dropped init\n const sessionKey =\n options.sessionKey ||\n ((\n config.sources?.session?.config?.settings as Record<string, unknown>\n )?.sessionKey as string) ||\n 'elbSessionId';\n const deviceKey =\n options.deviceKey ||\n ((\n config.sources?.session?.config?.settings as Record<string, unknown>\n )?.deviceKey as string) ||\n 'elbDeviceId';\n localStorage.removeItem(sessionKey);\n localStorage.removeItem(deviceKey);\n\n // Re-seed localStorage if trigger options specified session data\n if (options.sessionData) {\n localStorage.setItem(sessionKey, JSON.stringify(options.sessionData));\n }\n if (options.deviceId) {\n localStorage.setItem(deviceKey, options.deviceId);\n }\n\n // Re-apply consent to trigger session source on('consent') handler.\n // Now allowed=true so the session start event reaches destinations.\n if (config.consent) {\n await flow.collector.command('consent', config.consent);\n }\n }\n };\n\n return {\n get flow() {\n return flow;\n },\n trigger,\n };\n};\n\n/** Prepares localStorage with session/device data before source init. */\nconst trigger = (input: unknown, env: Record<string, unknown>): void => {\n if (!input || typeof input !== 'object') return;\n const data = input as Record<string, unknown>;\n const storage = env.localStorage as Storage;\n\n if (data.sessionData && typeof data.sessionData === 'object') {\n const key =\n typeof data.sessionKey === 'string' ? data.sessionKey : 'elbSessionId';\n storage.setItem(key, JSON.stringify(data.sessionData));\n }\n\n if (typeof data.deviceId === 'string') {\n const key =\n typeof data.deviceKey === 'string' ? data.deviceKey : 'elbDeviceId';\n storage.setItem(key, data.deviceId);\n }\n};\n\nexport { createTrigger, trigger };\n"],"mappings":";;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,SAAS,mBAAmB;;;ACA5B,SAAS,GAAG,0BAA0B;AAK/B,IAAM,iBAAiB,EAAE,OAAO;AAAA,EACrC,SAAS,EACN,QAAQ,EACR,QAAQ,KAAK,EACb,SAAS,kDAAkD,EAC3D,SAAS;AAAA,EAEZ,SAAS,EACN,MAAM,CAAC,EAAE,OAAO,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,EACvC,SAAS,gDAAgD,EACzD,SAAS;AAAA,EAEZ,QAAQ,EACL,OAAO,EACP,QAAQ,EAAE,EACV,SAAS,4BAA4B,EACrC,SAAS;AAAA,EAEZ,OAAO,EACJ,QAAQ,EACR,QAAQ,KAAK,EACb,SAAS,kCAAkC,EAC3C,SAAS;AAAA,EAEZ,YAAY,EACT,OAAO,EACP,QAAQ,cAAc,EACtB,SAAS,4BAA4B,EACrC,SAAS;AAAA,EAEZ,gBAAgB,EACb,KAAK,CAAC,SAAS,SAAS,CAAC,EACzB,QAAQ,OAAO,EACf,SAAS,0BAA0B,EACnC,SAAS;AAAA,EAEZ,WAAW,EACR,OAAO,EACP,QAAQ,aAAa,EACrB,SAAS,2BAA2B,EACpC,SAAS;AAAA,EAEZ,eAAe,EACZ,KAAK,CAAC,SAAS,SAAS,CAAC,EACzB,QAAQ,OAAO,EACf,SAAS,yBAAyB,EAClC,SAAS;AAAA,EAEZ,WAAW,EACR,OAAO,EACP,QAAQ,EAAE,EACV,SAAS,uBAAuB,EAChC,SAAS;AAAA;AAAA;AAAA,EAIZ,IAAI,EACD,IAAI,EACJ,SAAS,sDAAsD,EAC/D,SAAS;AAAA,EAEZ,UAAU,EACP,MAAM,kBAAkB,EACxB;AAAA,IACC;AAAA,EACF,EACC,SAAS;AACd,CAAC;;;ADjEM,IAAM,WAAW,YAAY,cAAc;;;AEPlD;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA;AAAA;AAAA;AAAA;AAAA;AASO,IAAM,sBAAwC;AAAA,EACnD,OAAO;AAAA,EACP,aACE;AAAA,EACF,SAAS;AAAA,IACP,MAAM;AAAA,IACN,SAAS;AAAA,MACP,KAAK;AAAA,IACP;AAAA,EACF;AAAA,EACA,IAAI,EAAE,SAAS,KAAK;AAAA,EACpB,KAAK;AAAA,IACH,CAAC,OAAO,QAAQ,EAAE,SAAS,cAAc,QAAQ,YAAY,CAAC;AAAA,IAC9D;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,QACE,IAAI;AAAA,QACJ,OAAO;AAAA,QACP,OAAO;AAAA,QACP,OAAO;AAAA,QACP,MAAM;AAAA,QACN,WAAW;AAAA,QACX,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,UAAU;AAAA,QACV,UAAU;AAAA,QACV,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,SAAS;AAAA,QACT,SAAS;AAAA,MACX;AAAA,IACF;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,UACJ,IAAI;AAAA,UACJ,OAAO;AAAA,UACP,OAAO;AAAA,UACP,OAAO;AAAA,UACP,MAAM;AAAA,UACN,WAAW;AAAA,UACX,QAAQ;AAAA,UACR,QAAQ;AAAA,UACR,UAAU;AAAA,UACV,UAAU;AAAA,UACV,QAAQ;AAAA,UACR,SAAS;AAAA,UACT,SAAS;AAAA,UACT,SAAS;AAAA,QACX;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAEO,IAAM,mBAAqC;AAAA,EAChD,OAAO;AAAA,EACP,aACE;AAAA,EACF,SAAS;AAAA,IACP,MAAM;AAAA,IACN,SAAS;AAAA,MACP,UAAU;AAAA,IACZ;AAAA,EACF;AAAA,EACA,IAAI,EAAE,SAAS,KAAK;AAAA,EACpB,KAAK;AAAA,IACH,CAAC,OAAO,QAAQ,EAAE,SAAS,eAAe,QAAQ,YAAY,CAAC;AAAA,IAC/D;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,QACE,IAAI;AAAA,QACJ,OAAO;AAAA,QACP,OAAO;AAAA,QACP,OAAO;AAAA,QACP,MAAM;AAAA,QACN,UAAU;AAAA,QACV,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,SAAS;AAAA,QACT,SAAS;AAAA,MACX;AAAA,IACF;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,UACJ,IAAI;AAAA,UACJ,OAAO;AAAA,UACP,OAAO;AAAA,UACP,OAAO;AAAA,UACP,MAAM;AAAA,UACN,UAAU;AAAA,UACV,QAAQ;AAAA,UACR,SAAS;AAAA,UACT,SAAS;AAAA,UACT,SAAS;AAAA,QACX;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;A;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACvGA,IAAM,gBAAiE,OACrE,WACG;AACH,MAAI;AAEJ,QAAMA,WACJ,CAAC,MAAe,SAChB,OAAO,YAAqC;AAnBhD,wBAAAC,KAAA;AAoBM,UAAM,UAAW,QAAQ,CAAC;AAG1B,QAAI,QAAQ,KAAK;AACf,YAAM,SAAS,IAAI,IAAI,QAAQ,GAAG;AAClC,aAAO,QAAQ,aAAa,CAAC,GAAG,IAAI,OAAO,WAAW,OAAO,MAAM;AAAA,IACrE;AACA,QAAI,QAAQ,UAAU;AACpB,aAAO,eAAe,UAAU,YAAY;AAAA,QAC1C,OAAO,QAAQ;AAAA,QACf,cAAc;AAAA,MAChB,CAAC;AAAA,IACH;AACA,QAAI,QAAQ,aAAa;AACvB,YAAM,MAAM,QAAQ,cAAc;AAClC,mBAAa,QAAQ,KAAK,KAAK,UAAU,QAAQ,WAAW,CAAC;AAAA,IAC/D;AACA,QAAI,QAAQ,UAAU;AACpB,YAAM,MAAM,QAAQ,aAAa;AACjC,mBAAa,QAAQ,KAAK,QAAQ,QAAQ;AAAA,IAC5C;AAOA,QAAI,CAAC,MAAM;AACT,YAAM,SAAS,MAAM,GAAU,EAAE,GAAG,QAAQ,MAAK,YAAO,QAAP,YAAc,KAAK,CAAC;AACrE,aAAO,EAAE,WAAW,OAAO,WAAW,KAAK,OAAO,IAAI;AAGtD,YAAM,aACJ,QAAQ,gBAENA,OAAA,wBAAO,YAAP,mBAAgB,YAAhB,mBAAyB,WAAzB,mBAAiC,aAAjC,gBAAAA,IACC,eACH;AACF,YAAM,YACJ,QAAQ,eAEN,8BAAO,YAAP,mBAAgB,YAAhB,mBAAyB,WAAzB,mBAAiC,aAAjC,mBACC,cACH;AACF,mBAAa,WAAW,UAAU;AAClC,mBAAa,WAAW,SAAS;AAGjC,UAAI,QAAQ,aAAa;AACvB,qBAAa,QAAQ,YAAY,KAAK,UAAU,QAAQ,WAAW,CAAC;AAAA,MACtE;AACA,UAAI,QAAQ,UAAU;AACpB,qBAAa,QAAQ,WAAW,QAAQ,QAAQ;AAAA,MAClD;AAIA,UAAI,OAAO,SAAS;AAClB,cAAM,KAAK,UAAU,QAAQ,WAAW,OAAO,OAAO;AAAA,MACxD;AAAA,IACF;AAAA,EACF;AAEF,SAAO;AAAA,IACL,IAAI,OAAO;AACT,aAAO;AAAA,IACT;AAAA,IACA,SAAAD;AAAA,EACF;AACF;AAGA,IAAM,UAAU,CAAC,OAAgB,QAAuC;AACtE,MAAI,CAAC,SAAS,OAAO,UAAU,SAAU;AACzC,QAAM,OAAO;AACb,QAAM,UAAU,IAAI;AAEpB,MAAI,KAAK,eAAe,OAAO,KAAK,gBAAgB,UAAU;AAC5D,UAAM,MACJ,OAAO,KAAK,eAAe,WAAW,KAAK,aAAa;AAC1D,YAAQ,QAAQ,KAAK,KAAK,UAAU,KAAK,WAAW,CAAC;AAAA,EACvD;AAEA,MAAI,OAAO,KAAK,aAAa,UAAU;AACrC,UAAM,MACJ,OAAO,KAAK,cAAc,WAAW,KAAK,YAAY;AACxD,YAAQ,QAAQ,KAAK,KAAK,QAAQ;AAAA,EACpC;AACF;","names":["trigger","_e"]}
1
+ {"version":3,"sources":["../src/schemas/index.ts","../src/schemas/settings.ts","../src/examples/index.ts","../src/examples/step.ts","../src/examples/trigger.ts"],"sourcesContent":["import { zodToSchema } from '@walkeros/core/dev';\nimport { SettingsSchema } from './settings';\n\n// Export Zod schemas and types\nexport { SettingsSchema, type Settings } from './settings';\n\n// JSON Schema exports (for website PropertyTable)\nexport const settings = zodToSchema(SettingsSchema);\n","import { z, ClickIdEntrySchema } from '@walkeros/core/dev';\n\n/**\n * Session source settings schema\n */\nexport const SettingsSchema = z.object({\n storage: z\n .boolean()\n .default(false)\n .describe('Enable persistent storage for session/device IDs')\n .optional(),\n\n consent: z\n .union([z.string(), z.array(z.string())])\n .describe('Consent key(s) required to enable storage mode')\n .optional(),\n\n length: z\n .number()\n .default(30)\n .describe('Session timeout in minutes')\n .optional(),\n\n pulse: z\n .boolean()\n .default(false)\n .describe('Keep session alive on each event')\n .optional(),\n\n sessionKey: z\n .string()\n .default('elbSessionId')\n .describe('Storage key for session ID')\n .optional(),\n\n sessionStorage: z\n .enum(['local', 'session'])\n .default('local')\n .describe('Storage type for session')\n .optional(),\n\n deviceKey: z\n .string()\n .default('elbDeviceId')\n .describe('Storage key for device ID')\n .optional(),\n\n deviceStorage: z\n .enum(['local', 'session'])\n .default('local')\n .describe('Storage type for device')\n .optional(),\n\n deviceAge: z\n .number()\n .default(30)\n .describe('Device ID age in days')\n .optional(),\n\n // Note: Using z.any() because z.custom() cannot be converted to JSON Schema\n // TypeScript types provide compile-time safety; runtime accepts function or false\n cb: z\n .any()\n .describe('Custom session callback function or false to disable')\n .optional(),\n\n clickIds: z\n .array(ClickIdEntrySchema)\n .describe(\n 'Custom click-ID registry. Entries with a `param` matching a default override the platform name in place; new params append to the end of the priority list.',\n )\n .optional(),\n});\n\nexport type Settings = z.infer<typeof SettingsSchema>;\n","export * as step from './step';\nexport { createTrigger, trigger } from './trigger';\n","import type { Flow } from '@walkeros/core';\n\n/**\n * Session source emits three elb calls on start:\n * 1. command('user', { session, device? })\n * 2. command('session', <full session data>)\n * 3. push({ name: 'session start', data: <full session data> })\n */\n\nexport const newMarketingSession: Flow.StepExample = {\n title: 'New marketing session',\n description:\n 'A visit with UTM parameters starts a new session and emits walker user, session, and session start calls.',\n trigger: {\n type: 'load',\n options: {\n url: 'https://example.com/?utm_source=google&utm_medium=cpc&utm_campaign=winter-sale',\n },\n },\n in: { storage: true },\n out: [\n ['elb', 'user', { session: 's3ss10n-id', device: 'd3v1c3-id' }],\n [\n 'elb',\n 'session',\n {\n id: 's3ss10n-id',\n start: 1700000000000,\n isNew: true,\n count: 1,\n runs: 1,\n marketing: true,\n source: 'google',\n medium: 'cpc',\n campaign: 'winter-sale',\n referrer: '',\n device: 'd3v1c3-id',\n isStart: true,\n storage: true,\n updated: 1700000000000,\n },\n ],\n [\n 'elb',\n {\n name: 'session start',\n data: {\n id: 's3ss10n-id',\n start: 1700000000000,\n isNew: true,\n count: 1,\n runs: 1,\n marketing: true,\n source: 'google',\n medium: 'cpc',\n campaign: 'winter-sale',\n referrer: '',\n device: 'd3v1c3-id',\n isStart: true,\n storage: true,\n updated: 1700000000000,\n },\n },\n ],\n ],\n};\n\nexport const returningVisitor: Flow.StepExample = {\n title: 'Returning visitor',\n description:\n 'A returning visit with a google referrer reuses the stored device id and increments the session count.',\n trigger: {\n type: 'load',\n options: {\n referrer: 'https://google.com',\n },\n },\n in: { storage: true },\n out: [\n ['elb', 'user', { session: 'n3w-s3ss10n', device: 'd3v1c3-id' }],\n [\n 'elb',\n 'session',\n {\n id: 'n3w-s3ss10n',\n start: 1700001000000,\n isNew: false,\n count: 3,\n runs: 1,\n referrer: 'google.com',\n device: 'd3v1c3-id',\n isStart: true,\n storage: true,\n updated: 1700001000000,\n },\n ],\n [\n 'elb',\n {\n name: 'session start',\n data: {\n id: 'n3w-s3ss10n',\n start: 1700001000000,\n isNew: false,\n count: 3,\n runs: 1,\n referrer: 'google.com',\n device: 'd3v1c3-id',\n isStart: true,\n storage: true,\n updated: 1700001000000,\n },\n },\n ],\n ],\n};\n","import type { Trigger, Collector } from '@walkeros/core';\nimport { startFlow } from '@walkeros/collector';\n\ninterface SessionTriggerOptions {\n url?: string;\n referrer?: string;\n sessionData?: Record<string, unknown>;\n deviceId?: string;\n sessionKey?: string;\n deviceKey?: string;\n}\n\nconst createTrigger: Trigger.CreateFn<Record<string, unknown>, void> = async (\n config: Collector.InitConfig,\n) => {\n let flow: Trigger.FlowHandle | undefined;\n\n const trigger: Trigger.Fn<Record<string, unknown>, void> =\n (type?: string, opts?: unknown) =>\n async (content: Record<string, unknown>) => {\n const options = (opts || {}) as SessionTriggerOptions;\n\n // Pre-init: seed world state before source reads it\n if (options.url) {\n const urlObj = new URL(options.url);\n window.history.replaceState({}, '', urlObj.pathname + urlObj.search);\n }\n if (options.referrer) {\n Object.defineProperty(document, 'referrer', {\n value: options.referrer,\n configurable: true,\n });\n }\n if (options.sessionData) {\n const key = options.sessionKey || 'elbSessionId';\n localStorage.setItem(key, JSON.stringify(options.sessionData));\n }\n if (options.deviceId) {\n const key = options.deviceKey || 'elbDeviceId';\n localStorage.setItem(key, options.deviceId);\n }\n\n // Lazy startFlow — session source fires events during init, but\n // collector.allowed is false until command('run'). The initial\n // session event is dropped. After startFlow, clear the session\n // data written by the dropped init, re-seed, and trigger a consent\n // update to cause session re-init with allowed=true.\n if (!flow) {\n const result = await startFlow({ ...config, run: config.run ?? true });\n flow = { collector: result.collector, elb: result.elb };\n\n // Clear session data written by the dropped init\n const sessionKey =\n options.sessionKey ||\n ((\n config.sources?.session?.config?.settings as Record<string, unknown>\n )?.sessionKey as string) ||\n 'elbSessionId';\n const deviceKey =\n options.deviceKey ||\n ((\n config.sources?.session?.config?.settings as Record<string, unknown>\n )?.deviceKey as string) ||\n 'elbDeviceId';\n localStorage.removeItem(sessionKey);\n localStorage.removeItem(deviceKey);\n\n // Re-seed localStorage if trigger options specified session data\n if (options.sessionData) {\n localStorage.setItem(sessionKey, JSON.stringify(options.sessionData));\n }\n if (options.deviceId) {\n localStorage.setItem(deviceKey, options.deviceId);\n }\n\n // Re-apply consent to trigger session source on('consent') handler.\n // Now allowed=true so the session start event reaches destinations.\n if (config.consent) {\n await flow.collector.command('consent', config.consent);\n }\n }\n };\n\n return {\n get flow() {\n return flow;\n },\n trigger,\n };\n};\n\n/** Prepares localStorage with session/device data before source init. */\nconst trigger = (input: unknown, env: Record<string, unknown>): void => {\n if (!input || typeof input !== 'object') return;\n const data = input as Record<string, unknown>;\n const storage = env.localStorage as Storage;\n\n if (data.sessionData && typeof data.sessionData === 'object') {\n const key =\n typeof data.sessionKey === 'string' ? data.sessionKey : 'elbSessionId';\n storage.setItem(key, JSON.stringify(data.sessionData));\n }\n\n if (typeof data.deviceId === 'string') {\n const key =\n typeof data.deviceKey === 'string' ? data.deviceKey : 'elbDeviceId';\n storage.setItem(key, data.deviceId);\n }\n};\n\nexport { createTrigger, trigger };\n"],"mappings":"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","names":["trigger","_e"]}
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- "use strict";var e,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,o=Object.prototype.hasOwnProperty,s={};((e,n)=>{for(var r in n)t(e,r,{get:n[r],enumerable:!0})})(s,{SourceSession:()=>f,default:()=>v,sessionStart:()=>g,sessionStorage:()=>u,sessionWindow:()=>d,sourceSession:()=>p}),module.exports=(e=s,((e,s,i,c)=>{if(s&&"object"==typeof s||"function"==typeof s)for(let a of r(s))o.call(e,a)||a===i||t(e,a,{get:()=>s[a],enumerable:!(c=n(s,a))||c.enumerable});return e})(t({},"__esModule",{value:!0}),e));var i=require("@walkeros/core"),c=require("@walkeros/web-core"),a=require("@walkeros/core");function d(e={}){var t,n;let r=e.isStart||!1;const o={isStart:r,storage:!1};if(!1===e.isStart)return o;const s=null!=(t=e.window)?t:window,i=null!=(n=e.document)?n:document;if(!r){const[e]=s.performance.getEntriesByType("navigation");if("navigate"!==e.type)return o}const c=new URL(e.url||s.location.href),d=e.referrer||i.referrer,u=d&&new URL(d).hostname,l=(0,a.getMarketingParameters)(c,e.parameters,e.clickIds);if(Object.keys(l).length&&(l.marketing||(l.marketing=!0),r=!0),!r){const t=e.domains||[];t.push(c.hostname),r=!t.includes(u)}return r?Object.assign({isStart:r,storage:!1,start:Date.now(),id:(0,a.getId)(12),referrer:u},l,e.data):o}function u(e={}){const t=Date.now(),{length:n=30,deviceKey:r="elbDeviceId",deviceStorage:o="local",deviceAge:s=30,sessionKey:a="elbSessionId",sessionStorage:u="local",pulse:l=!1}=e,g=e.window||e.document?{window:e.window,document:e.document}:void 0,m=d(e);let w=!1;const f=(0,i.tryCatch)((e,t,n)=>{let r=(0,c.storageRead)(e,n,g);return r||(r=(0,i.getId)(8),(0,c.storageWrite)(e,r,1440*t,n,void 0,g)),String(r)})(r,s,o),p=(0,i.tryCatch)((e,r)=>{const o=JSON.parse(String((0,c.storageRead)(e,r,g)));return l||(o.isNew=!1,m.marketing&&(Object.assign(o,m),w=!0),w||o.updated+6e4*n<t?(delete o.id,delete o.referrer,o.start=t,o.count++,o.runs=1,w=!0):o.runs++),o},()=>{w=!0})(a,u)||{},v={id:(0,i.getId)(12),start:t,isNew:!0,count:1,runs:1},y=Object.assign(v,m,p,{device:f},{isStart:w,storage:!0,updated:t},e.data);return(0,c.storageWrite)(a,JSON.stringify(y),2*n,u,void 0,g),y}var l=require("@walkeros/core");function g(e={}){const{cb:t,consent:n,collector:r,storage:o}=e;if(!n)return m((o?u:d)(e),r,t);{const o=function(e,t){let n;const r=(r,o)=>{const s=o.collector;if((0,l.isDefined)(n)&&n===(null==s?void 0:s.round))return;n=null==s?void 0:s.round;let i=()=>d(e);if(e.consent){const t=((0,l.isArray)(e.consent)?e.consent:[e.consent]).reduce((e,t)=>({...e,[t]:!0}),{});(0,l.getGrantedConsent)(t,r)&&(i=()=>u(e))}m(i(),s,t)};return r}(e,t),s=((0,l.isArray)(n)?n:[n]).reduce((e,t)=>({...e,[t]:o}),{});r&&r.command("on",{type:"consent",rules:s})}}function m(e,t,n){return!1===n?e:(n||(n=w),n(e,t,w))}var w=(e,t)=>{const n={};return e.id&&(n.session=e.id),e.storage&&e.device&&(n.device=e.device),t&&(t.command("user",n),t.command("session",e)),e.isStart&&t&&t.push({name:"session start",data:e}),e},f={},p=async e=>{const{config:t,env:n}=e,{elb:r,command:o}=n,s={...null==t?void 0:t.settings},i={settings:s},c={push:r,command:o};g({...s,window:n.window,document:n.document,collector:c});return{type:"session",config:i,push:r,on:async e=>{"consent"===e&&g({...s,window:n.window,document:n.document,collector:c})}}},v=p;//# sourceMappingURL=index.js.map
1
+ "use strict";var e,t=Object.defineProperty,r=Object.getOwnPropertyDescriptor,n=Object.getOwnPropertyNames,o=Object.prototype.hasOwnProperty,s={};((e,r)=>{for(var n in r)t(e,n,{get:r[n],enumerable:!0})})(s,{SourceSession:()=>w,default:()=>v,sessionStart:()=>g,sessionStorage:()=>u,sessionWindow:()=>d,sourceSession:()=>p}),module.exports=(e=s,((e,s,i,a)=>{if(s&&"object"==typeof s||"function"==typeof s)for(let c of n(s))o.call(e,c)||c===i||t(e,c,{get:()=>s[c],enumerable:!(a=r(s,c))||a.enumerable});return e})(t({},"__esModule",{value:!0}),e));var i=require("@walkeros/core"),a=require("@walkeros/web-core"),c=require("@walkeros/core");function d(e={}){var t,r;let n=e.isStart||!1;const o={isStart:n,storage:!1};if(!1===e.isStart)return o;const s=null!=(t=e.window)?t:window,i=null!=(r=e.document)?r:document;if(!n){const[e]=s.performance.getEntriesByType("navigation");if("navigate"!==e.type)return o}const a=new URL(e.url||s.location.href),d=e.referrer||i.referrer,u=d&&new URL(d).hostname,l=(0,c.getMarketingParameters)(a,e.parameters,e.clickIds);if(Object.keys(l).length&&(l.marketing||(l.marketing=!0),n=!0),!n){const t=e.domains||[];t.push(a.hostname),n=!t.includes(u)}return n?Object.assign({isStart:n,storage:!1,start:Date.now(),id:(0,c.getId)(12),referrer:u},l,e.data):o}function u(e={}){const t=Date.now(),{length:r=30,deviceKey:n="elbDeviceId",deviceStorage:o="local",deviceAge:s=30,sessionKey:c="elbSessionId",sessionStorage:u="local",pulse:l=!1}=e,g=e.window||e.document?{window:e.window,document:e.document}:void 0,m=d(e);let f=!1;const w=(0,i.tryCatch)((e,t,r)=>{let n=(0,a.storageRead)(e,r,g);return n||(n=(0,i.getId)(8),(0,a.storageWrite)(e,n,1440*t,r,void 0,g)),String(n)})(n,s,o),p=(0,i.tryCatch)((e,n)=>{const o=JSON.parse(String((0,a.storageRead)(e,n,g)));return l||(o.isNew=!1,m.marketing&&(Object.assign(o,m),f=!0),f||o.updated+6e4*r<t?(delete o.id,delete o.referrer,o.start=t,o.count++,o.runs=1,f=!0):o.runs++),o},()=>{f=!0})(c,u)||{},v={id:(0,i.getId)(12),start:t,isNew:!0,count:1,runs:1},y=Object.assign(v,m,p,{device:w},{isStart:f,storage:!0,updated:t},e.data);return(0,a.storageWrite)(c,JSON.stringify(y),2*r,u,void 0,g),y}var l=require("@walkeros/core");function g(e={}){const{cb:t,consent:r,collector:n,storage:o}=e;if(!r)return m((o?u:d)(e),n,t);{const o=function(e,t){const r=(r,n)=>{const o=n.collector;let s=()=>d(e);if(e.consent){const t=((0,l.isArray)(e.consent)?e.consent:[e.consent]).reduce((e,t)=>({...e,[t]:!0}),{});(0,l.getGrantedConsent)(t,r)&&(s=()=>u(e))}m(s(),o,t)};return r}(e,t),s=((0,l.isArray)(r)?r:[r]).reduce((e,t)=>({...e,[t]:o}),{});n&&n.command("on",{type:"consent",rules:s})}}function m(e,t,r){return!1===r?e:(r||(r=f),r(e,t,f))}var f=(e,t)=>{const r={};return e.id&&(r.session=e.id),e.storage&&e.device&&(r.device=e.device),t&&(t.command("user",r),t.command("session",e)),e.isStart&&t&&t.push({name:"session start",data:e}),e},w={},p=async e=>{const{config:t,env:r}=e,{elb:n,command:o}=r,s={...null==t?void 0:t.settings},i={settings:s},a={push:n,command:o};return g({...s,window:r.window,document:r.document,collector:a}),{type:"session",config:i,push:n}},v=p;//# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/lib/sessionStorage.ts","../src/lib/sessionWindow.ts","../src/lib/sessionStart.ts","../src/types/index.ts"],"sourcesContent":["import type { Source, On, Collector } from '@walkeros/core';\nimport type { Types, Settings } from './types';\nimport { sessionStart } from './lib';\n\n// Export types for external usage\nexport * as SourceSession from './types';\n\n// Export lib functions for direct usage\nexport { sessionStart, sessionStorage, sessionWindow } from './lib';\nexport type {\n SessionConfig,\n SessionCallback,\n SessionFunction,\n SessionStorageConfig,\n SessionWindowConfig,\n} from './lib';\n\n/**\n * Session source implementation.\n *\n * This source handles session detection and management.\n */\nexport const sourceSession: Source.Init<Types> = async (context) => {\n const { config, env } = context;\n const { elb, command } = env;\n\n const settings: Settings = {\n ...config?.settings,\n };\n\n const fullConfig: Source.Config<Types> = {\n settings,\n };\n\n // Create minimal collector interface for sessionStart\n const collectorInterface: Partial<Collector.Instance> = {\n push: elb,\n command,\n };\n\n // Initialize session using local lib\n sessionStart({\n ...settings,\n window: env.window,\n document: env.document,\n collector: collectorInterface as Collector.Instance,\n });\n\n // Handle events pushed from collector (consent, session, ready, run)\n const handleEvent = async (event: On.Types) => {\n if (event === 'consent') {\n // Re-initialize session on consent changes\n sessionStart({\n ...settings,\n window: env.window,\n document: env.document,\n collector: collectorInterface as Collector.Instance,\n });\n }\n };\n\n return {\n type: 'session',\n config: fullConfig,\n push: elb,\n on: handleEvent,\n };\n};\n\nexport default sourceSession;\n","import type { Collector } from '@walkeros/core';\nimport type { SessionWindowConfig } from './sessionWindow';\nimport type { StorageType } from '@walkeros/core';\nimport type { StorageEnv } from '@walkeros/web-core';\nimport { getId, tryCatch } from '@walkeros/core';\nimport { storageRead, storageWrite } from '@walkeros/web-core';\nimport { sessionWindow } from './sessionWindow';\n\nexport interface SessionStorageConfig extends SessionWindowConfig {\n deviceKey?: string;\n deviceStorage?: StorageType;\n deviceAge?: number;\n sessionKey?: string;\n sessionStorage?: StorageType;\n length?: number; // Minutes after last update to consider session as expired (default: 30)\n pulse?: boolean;\n}\n\nexport function sessionStorage(\n config: SessionStorageConfig = {},\n): Collector.SessionData {\n const now = Date.now();\n const {\n length = 30, // Session length in minutes\n deviceKey = 'elbDeviceId',\n deviceStorage = 'local',\n deviceAge = 30, // Device ID age in days\n sessionKey = 'elbSessionId',\n sessionStorage = 'local',\n pulse = false, // Handle the counting\n } = config;\n const storageEnv: StorageEnv | undefined =\n config.window || config.document\n ? { window: config.window, document: config.document }\n : undefined;\n const windowSession = sessionWindow(config); // Status based on window only\n let isStart = false;\n\n // Retrieve or create device ID\n const device = tryCatch((key: string, age: number, storage: StorageType) => {\n let id = storageRead(key, storage, storageEnv);\n if (!id) {\n id = getId(8); // Create a new device ID\n storageWrite(key, id, age * 1440, storage, undefined, storageEnv); // Write device ID to storage\n }\n return String(id);\n })(deviceKey, deviceAge, deviceStorage);\n\n // Retrieve or initialize session data\n const existingSession: Collector.SessionData =\n tryCatch(\n (key: string, storage?: StorageType) => {\n const session = JSON.parse(\n String(storageRead(key, storage, storageEnv)),\n );\n\n // Only update session if it's not a pulse check\n if (pulse) return session;\n\n // Mark session as not new by default\n session.isNew = false;\n\n // Handle new marketing entry\n if (windowSession.marketing) {\n Object.assign(session, windowSession); // Overwrite existing session with marketing data\n isStart = true; // This is a session start\n }\n\n // Check if session is still active\n if (isStart || session.updated + length * 60000 < now) {\n // Session has expired\n delete session.id; // Unset session ID\n delete session.referrer; // Unset referrer\n session.start = now; // Set new session start\n session.count++; // Increase session count\n session.runs = 1; // Reset runs\n isStart = true; // It's a new session\n } else {\n // Session is still active\n session.runs++; // Increase number of runs\n }\n\n return session;\n },\n () => {\n // No existing session or something went wrong\n isStart = true; // Start a new session\n },\n )(sessionKey, sessionStorage) || {};\n\n // Default session data\n const defaultSession: Partial<Collector.SessionData> = {\n id: getId(12),\n start: now,\n isNew: true,\n count: 1,\n runs: 1,\n };\n\n // Merge session data\n const session = Object.assign(\n defaultSession, // Default session values\n windowSession, // Basic session data based on window\n existingSession, // (Updated) existing session\n { device }, // Device ID\n { isStart, storage: true, updated: now }, // Status of the session\n config.data, // Given data has the highest priority\n );\n\n // Write (updated) session to storage\n storageWrite(\n sessionKey,\n JSON.stringify(session),\n length * 2,\n sessionStorage,\n undefined,\n storageEnv,\n );\n\n return session;\n}\n","import type { Collector, WalkerOS } from '@walkeros/core';\nimport {\n getId,\n getMarketingParameters,\n type ClickIdEntry,\n type MarketingParameters,\n} from '@walkeros/core';\n\nexport interface SessionWindowConfig {\n clickIds?: ClickIdEntry[];\n data?: WalkerOS.Properties;\n domains?: string[];\n isStart?: boolean;\n parameters?: MarketingParameters;\n referrer?: string;\n url?: string;\n window?: Window & typeof globalThis;\n document?: Document;\n}\n\nexport function sessionWindow(\n config: SessionWindowConfig = {},\n): Collector.SessionData {\n let isStart = config.isStart || false;\n const known = { isStart, storage: false };\n\n // If session has explicitly started, return known\n if (config.isStart === false) return known;\n\n const win = config.window ?? window;\n const doc = config.document ?? document;\n\n // Entry type\n if (!isStart) {\n // Only focus on linked or direct navigation types\n // and ignore reloads and all others\n const [perf] = win.performance.getEntriesByType(\n 'navigation',\n ) as PerformanceNavigationTiming[];\n if (perf.type !== 'navigate') return known;\n }\n\n const url = new URL(config.url || win.location.href);\n const ref = config.referrer || doc.referrer;\n const referrer = ref && new URL(ref).hostname;\n\n // Marketing\n const marketing = getMarketingParameters(\n url,\n config.parameters,\n config.clickIds,\n );\n if (Object.keys(marketing).length) {\n // Check for marketing parameters like UTM and add existing\n if (!marketing.marketing)\n // Flag as a marketing session without overwriting\n marketing.marketing = true;\n\n isStart = true;\n }\n\n // Referrer\n if (!isStart) {\n // Small chance of multiple unintended events for same users\n // https://en.wikipedia.org/wiki/HTTP_referer#Referrer_hiding\n // Use domains: [''] to disable direct or hidden referrer\n\n const domains = config.domains || [];\n domains.push(url.hostname);\n isStart = !domains.includes(referrer);\n }\n\n return isStart\n ? // It's a session start, moin\n Object.assign(\n {\n isStart,\n storage: false,\n start: Date.now(),\n id: getId(12),\n referrer,\n },\n marketing,\n config.data,\n )\n : // No session start\n known;\n}\n","import type { Collector, WalkerOS, On, ClickIdEntry } from '@walkeros/core';\nimport type { SessionStorageConfig } from './sessionStorage';\nimport { sessionStorage } from './sessionStorage';\nimport { sessionWindow } from './sessionWindow';\nimport { getGrantedConsent, isArray, isDefined } from '@walkeros/core';\n\nexport interface SessionConfig extends SessionStorageConfig {\n clickIds?: ClickIdEntry[];\n consent?: string | string[];\n storage?: boolean;\n cb?: SessionCallback | false;\n collector?: Collector.Instance;\n}\n\nexport type SessionFunction = typeof sessionStorage | typeof sessionWindow;\nexport type SessionCallback = (\n session: Collector.SessionData,\n collector: Collector.Instance | undefined,\n defaultCb: SessionCallback,\n) => void;\n\nexport function sessionStart(\n config: SessionConfig = {},\n): Collector.SessionData | void {\n const { cb, consent, collector, storage } = config;\n const sessionFn: SessionFunction = storage ? sessionStorage : sessionWindow;\n\n // Consent\n if (consent) {\n const consentHandler = onConsentFn(config, cb);\n\n const consentConfig = (\n isArray(consent) ? consent : [consent]\n ).reduce<On.ConsentRule>(\n (acc, key) => ({ ...acc, [key]: consentHandler }),\n {},\n );\n // Register consent handlers with the collector\n if (collector) {\n collector.command('on', { type: 'consent', rules: consentConfig });\n }\n // No fallback - session source always provides collector\n } else {\n // just do it\n return callFuncAndCb(sessionFn(config), collector, cb);\n }\n}\n\nfunction callFuncAndCb(\n session: Collector.SessionData,\n collector?: Collector.Instance,\n cb?: SessionCallback | false,\n) {\n if (cb === false) return session; // Callback is disabled\n if (!cb) cb = defaultCb; // Default callback if none is provided\n return cb(session, collector, defaultCb);\n}\n\nfunction onConsentFn(\n config: SessionConfig,\n cb?: SessionCallback | false,\n): On.ConsentFn {\n // Track the last processed round to prevent duplicate processing\n let lastProcessedRound: number | undefined;\n\n const func: On.ConsentFn = (consent, context) => {\n const collector = context.collector;\n\n // Skip if we've already processed this round\n if (\n isDefined(lastProcessedRound) &&\n lastProcessedRound === collector?.round\n )\n return;\n\n // Remember this round has been processed\n lastProcessedRound = collector?.round;\n\n let sessionFn: SessionFunction = () => sessionWindow(config); // Window by default\n\n if (config.consent) {\n const consentKeys = (\n isArray(config.consent) ? config.consent : [config.consent]\n ).reduce<WalkerOS.Consent>((acc, key) => ({ ...acc, [key]: true }), {});\n\n if (getGrantedConsent(consentKeys, consent))\n // Use storage if consent is granted\n sessionFn = () => sessionStorage(config);\n }\n\n callFuncAndCb(sessionFn(), collector, cb);\n };\n\n return func;\n}\n\nconst defaultCb: SessionCallback = (\n session,\n collector,\n): Collector.SessionData => {\n const user: WalkerOS.User = {};\n\n // User.session is the session ID\n if (session.id) user.session = session.id;\n\n // Set device ID only in storage mode\n if (session.storage && session.device) user.device = session.device;\n\n // Set user IDs and broadcast session data\n if (collector) {\n collector.command('user', user);\n collector.command('session', session);\n }\n // No fallback - session source always provides collector\n\n if (session.isStart) {\n // Convert session start to an event object\n if (collector) {\n collector.push({\n name: 'session start',\n data: session,\n });\n }\n // No fallback - session source always provides collector\n }\n\n return session;\n};\n","import type { Source, Elb } from '@walkeros/core';\nimport type { SessionConfig, SessionCallback } from '../lib';\n\ndeclare module '@walkeros/core' {\n interface SourceMap {\n session: { type: 'session'; platform?: 'web' };\n }\n}\n\n// Settings: configuration for session source\nexport interface Settings extends SessionConfig {\n // All settings inherited from SessionConfig:\n // - consent?: string | string[]\n // - storage?: boolean\n // - cb?: SessionCallback | false\n // - pulse?: boolean\n // - sessionStorage?: 'local' | 'session'\n // - deviceStorage?: 'local' | 'session'\n // - sessionKey?: string\n // - deviceKey?: string\n // - length?: number (session timeout in minutes)\n}\n\n// InitSettings: user input (all optional)\nexport type InitSettings = Partial<Settings>;\n\nexport interface Mapping {}\n\nexport type Push = Elb.Fn;\n\nexport interface Env extends Source.BaseEnv {\n window?: Window & typeof globalThis;\n document?: Document;\n}\n\nexport type Types = Source.Types<Settings, Mapping, Push, Env, InitSettings>;\n\nexport type Config = Source.Config<Types>;\n\n// Re-export session types from lib\nexport type {\n SessionConfig,\n SessionCallback,\n SessionFunction,\n SessionStorageConfig,\n SessionWindowConfig,\n} from '../lib';\n"],"mappings":"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","names":["import_core","sessionStorage","session","import_core"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/lib/sessionStorage.ts","../src/lib/sessionWindow.ts","../src/lib/sessionStart.ts","../src/types/index.ts"],"sourcesContent":["import type { Source, Collector } from '@walkeros/core';\nimport type { Types, Settings } from './types';\nimport { sessionStart } from './lib';\n\n// Export types for external usage\nexport * as SourceSession from './types';\n\n// Export lib functions for direct usage\nexport { sessionStart, sessionStorage, sessionWindow } from './lib';\nexport type {\n SessionConfig,\n SessionCallback,\n SessionFunction,\n SessionStorageConfig,\n SessionWindowConfig,\n} from './lib';\n\n/**\n * Session source implementation.\n *\n * This source handles session detection and management.\n */\nexport const sourceSession: Source.Init<Types> = async (context) => {\n const { config, env } = context;\n const { elb, command } = env;\n\n const settings: Settings = {\n ...config?.settings,\n };\n\n const fullConfig: Source.Config<Types> = {\n settings,\n };\n\n // Create minimal collector interface for sessionStart\n const collectorInterface: Partial<Collector.Instance> = {\n push: elb,\n command,\n };\n\n // Initialize session using local lib. When `settings.consent` is set this\n // registers a single consent rule with the collector; the collector then\n // guarantees exactly-once delivery per state change, so the source does not\n // need to react to consent events itself.\n sessionStart({\n ...settings,\n window: env.window,\n document: env.document,\n collector: collectorInterface as Collector.Instance,\n });\n\n return {\n type: 'session',\n config: fullConfig,\n push: elb,\n };\n};\n\nexport default sourceSession;\n","import type { Collector } from '@walkeros/core';\nimport type { SessionWindowConfig } from './sessionWindow';\nimport type { StorageType } from '@walkeros/core';\nimport type { StorageEnv } from '@walkeros/web-core';\nimport { getId, tryCatch } from '@walkeros/core';\nimport { storageRead, storageWrite } from '@walkeros/web-core';\nimport { sessionWindow } from './sessionWindow';\n\nexport interface SessionStorageConfig extends SessionWindowConfig {\n deviceKey?: string;\n deviceStorage?: StorageType;\n deviceAge?: number;\n sessionKey?: string;\n sessionStorage?: StorageType;\n length?: number; // Minutes after last update to consider session as expired (default: 30)\n pulse?: boolean;\n}\n\nexport function sessionStorage(\n config: SessionStorageConfig = {},\n): Collector.SessionData {\n const now = Date.now();\n const {\n length = 30, // Session length in minutes\n deviceKey = 'elbDeviceId',\n deviceStorage = 'local',\n deviceAge = 30, // Device ID age in days\n sessionKey = 'elbSessionId',\n sessionStorage = 'local',\n pulse = false, // Handle the counting\n } = config;\n const storageEnv: StorageEnv | undefined =\n config.window || config.document\n ? { window: config.window, document: config.document }\n : undefined;\n const windowSession = sessionWindow(config); // Status based on window only\n let isStart = false;\n\n // Retrieve or create device ID\n const device = tryCatch((key: string, age: number, storage: StorageType) => {\n let id = storageRead(key, storage, storageEnv);\n if (!id) {\n id = getId(8); // Create a new device ID\n storageWrite(key, id, age * 1440, storage, undefined, storageEnv); // Write device ID to storage\n }\n return String(id);\n })(deviceKey, deviceAge, deviceStorage);\n\n // Retrieve or initialize session data\n const existingSession: Collector.SessionData =\n tryCatch(\n (key: string, storage?: StorageType) => {\n const session = JSON.parse(\n String(storageRead(key, storage, storageEnv)),\n );\n\n // Only update session if it's not a pulse check\n if (pulse) return session;\n\n // Mark session as not new by default\n session.isNew = false;\n\n // Handle new marketing entry\n if (windowSession.marketing) {\n Object.assign(session, windowSession); // Overwrite existing session with marketing data\n isStart = true; // This is a session start\n }\n\n // Check if session is still active\n if (isStart || session.updated + length * 60000 < now) {\n // Session has expired\n delete session.id; // Unset session ID\n delete session.referrer; // Unset referrer\n session.start = now; // Set new session start\n session.count++; // Increase session count\n session.runs = 1; // Reset runs\n isStart = true; // It's a new session\n } else {\n // Session is still active\n session.runs++; // Increase number of runs\n }\n\n return session;\n },\n () => {\n // No existing session or something went wrong\n isStart = true; // Start a new session\n },\n )(sessionKey, sessionStorage) || {};\n\n // Default session data\n const defaultSession: Partial<Collector.SessionData> = {\n id: getId(12),\n start: now,\n isNew: true,\n count: 1,\n runs: 1,\n };\n\n // Merge session data\n const session = Object.assign(\n defaultSession, // Default session values\n windowSession, // Basic session data based on window\n existingSession, // (Updated) existing session\n { device }, // Device ID\n { isStart, storage: true, updated: now }, // Status of the session\n config.data, // Given data has the highest priority\n );\n\n // Write (updated) session to storage\n storageWrite(\n sessionKey,\n JSON.stringify(session),\n length * 2,\n sessionStorage,\n undefined,\n storageEnv,\n );\n\n return session;\n}\n","import type { Collector, WalkerOS } from '@walkeros/core';\nimport {\n getId,\n getMarketingParameters,\n type ClickIdEntry,\n type MarketingParameters,\n} from '@walkeros/core';\n\nexport interface SessionWindowConfig {\n clickIds?: ClickIdEntry[];\n data?: WalkerOS.Properties;\n domains?: string[];\n isStart?: boolean;\n parameters?: MarketingParameters;\n referrer?: string;\n url?: string;\n window?: Window & typeof globalThis;\n document?: Document;\n}\n\nexport function sessionWindow(\n config: SessionWindowConfig = {},\n): Collector.SessionData {\n let isStart = config.isStart || false;\n const known = { isStart, storage: false };\n\n // If session has explicitly started, return known\n if (config.isStart === false) return known;\n\n const win = config.window ?? window;\n const doc = config.document ?? document;\n\n // Entry type\n if (!isStart) {\n // Only focus on linked or direct navigation types\n // and ignore reloads and all others\n const [perf] = win.performance.getEntriesByType(\n 'navigation',\n ) as PerformanceNavigationTiming[];\n if (perf.type !== 'navigate') return known;\n }\n\n const url = new URL(config.url || win.location.href);\n const ref = config.referrer || doc.referrer;\n const referrer = ref && new URL(ref).hostname;\n\n // Marketing\n const marketing = getMarketingParameters(\n url,\n config.parameters,\n config.clickIds,\n );\n if (Object.keys(marketing).length) {\n // Check for marketing parameters like UTM and add existing\n if (!marketing.marketing)\n // Flag as a marketing session without overwriting\n marketing.marketing = true;\n\n isStart = true;\n }\n\n // Referrer\n if (!isStart) {\n // Small chance of multiple unintended events for same users\n // https://en.wikipedia.org/wiki/HTTP_referer#Referrer_hiding\n // Use domains: [''] to disable direct or hidden referrer\n\n const domains = config.domains || [];\n domains.push(url.hostname);\n isStart = !domains.includes(referrer);\n }\n\n return isStart\n ? // It's a session start, moin\n Object.assign(\n {\n isStart,\n storage: false,\n start: Date.now(),\n id: getId(12),\n referrer,\n },\n marketing,\n config.data,\n )\n : // No session start\n known;\n}\n","import type { Collector, WalkerOS, On, ClickIdEntry } from '@walkeros/core';\nimport type { SessionStorageConfig } from './sessionStorage';\nimport { sessionStorage } from './sessionStorage';\nimport { sessionWindow } from './sessionWindow';\nimport { getGrantedConsent, isArray } from '@walkeros/core';\n\nexport interface SessionConfig extends SessionStorageConfig {\n clickIds?: ClickIdEntry[];\n consent?: string | string[];\n storage?: boolean;\n cb?: SessionCallback | false;\n collector?: Collector.Instance;\n}\n\nexport type SessionFunction = typeof sessionStorage | typeof sessionWindow;\nexport type SessionCallback = (\n session: Collector.SessionData,\n collector: Collector.Instance | undefined,\n defaultCb: SessionCallback,\n) => void;\n\nexport function sessionStart(\n config: SessionConfig = {},\n): Collector.SessionData | void {\n const { cb, consent, collector, storage } = config;\n const sessionFn: SessionFunction = storage ? sessionStorage : sessionWindow;\n\n // Consent\n if (consent) {\n const consentHandler = onConsentFn(config, cb);\n\n const consentConfig = (\n isArray(consent) ? consent : [consent]\n ).reduce<On.ConsentRule>(\n (acc, key) => ({ ...acc, [key]: consentHandler }),\n {},\n );\n // Register consent handlers with the collector\n if (collector) {\n collector.command('on', { type: 'consent', rules: consentConfig });\n }\n // No fallback - session source always provides collector\n } else {\n // just do it\n return callFuncAndCb(sessionFn(config), collector, cb);\n }\n}\n\nfunction callFuncAndCb(\n session: Collector.SessionData,\n collector?: Collector.Instance,\n cb?: SessionCallback | false,\n) {\n if (cb === false) return session; // Callback is disabled\n if (!cb) cb = defaultCb; // Default callback if none is provided\n return cb(session, collector, defaultCb);\n}\n\nfunction onConsentFn(\n config: SessionConfig,\n cb?: SessionCallback | false,\n): On.ConsentFn {\n const func: On.ConsentFn = (consent, context) => {\n const collector = context.collector;\n\n let sessionFn: SessionFunction = () => sessionWindow(config); // Window by default\n\n if (config.consent) {\n const consentKeys = (\n isArray(config.consent) ? config.consent : [config.consent]\n ).reduce<WalkerOS.Consent>((acc, key) => ({ ...acc, [key]: true }), {});\n\n if (getGrantedConsent(consentKeys, consent))\n // Use storage if consent is granted\n sessionFn = () => sessionStorage(config);\n }\n\n callFuncAndCb(sessionFn(), collector, cb);\n };\n\n return func;\n}\n\nconst defaultCb: SessionCallback = (\n session,\n collector,\n): Collector.SessionData => {\n const user: WalkerOS.User = {};\n\n // User.session is the session ID\n if (session.id) user.session = session.id;\n\n // Set device ID only in storage mode\n if (session.storage && session.device) user.device = session.device;\n\n // Set user IDs and broadcast session data\n if (collector) {\n collector.command('user', user);\n collector.command('session', session);\n }\n // No fallback - session source always provides collector\n\n if (session.isStart) {\n // Convert session start to an event object\n if (collector) {\n collector.push({\n name: 'session start',\n data: session,\n });\n }\n // No fallback - session source always provides collector\n }\n\n return session;\n};\n","import type { Source, Elb } from '@walkeros/core';\nimport type { SessionConfig, SessionCallback } from '../lib';\n\ndeclare module '@walkeros/core' {\n interface SourceMap {\n session: { type: 'session'; platform?: 'web' };\n }\n}\n\n// Settings: configuration for session source\nexport interface Settings extends SessionConfig {\n // All settings inherited from SessionConfig:\n // - consent?: string | string[]\n // - storage?: boolean\n // - cb?: SessionCallback | false\n // - pulse?: boolean\n // - sessionStorage?: 'local' | 'session'\n // - deviceStorage?: 'local' | 'session'\n // - sessionKey?: string\n // - deviceKey?: string\n // - length?: number (session timeout in minutes)\n}\n\n// InitSettings: user input (all optional)\nexport type InitSettings = Partial<Settings>;\n\nexport interface Mapping {}\n\nexport type Push = Elb.Fn;\n\nexport interface Env extends Source.BaseEnv {\n window?: Window & typeof globalThis;\n document?: Document;\n}\n\nexport type Types = Source.Types<Settings, Mapping, Push, Env, InitSettings>;\n\nexport type Config = Source.Config<Types>;\n\n// Re-export session types from lib\nexport type {\n SessionConfig,\n SessionCallback,\n SessionFunction,\n SessionStorageConfig,\n SessionWindowConfig,\n} from '../lib';\n"],"mappings":"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","names":["import_core","sessionStorage","session","import_core"]}
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- import{getId as e,tryCatch as n}from"@walkeros/core";import{storageRead as t,storageWrite as o}from"@walkeros/web-core";import{getId as r,getMarketingParameters as s}from"@walkeros/core";function c(e={}){var n,t;let o=e.isStart||!1;const c={isStart:o,storage:!1};if(!1===e.isStart)return c;const i=null!=(n=e.window)?n:window,a=null!=(t=e.document)?t:document;if(!o){const[e]=i.performance.getEntriesByType("navigation");if("navigate"!==e.type)return c}const d=new URL(e.url||i.location.href),u=e.referrer||a.referrer,l=u&&new URL(u).hostname,m=s(d,e.parameters,e.clickIds);if(Object.keys(m).length&&(m.marketing||(m.marketing=!0),o=!0),!o){const n=e.domains||[];n.push(d.hostname),o=!n.includes(l)}return o?Object.assign({isStart:o,storage:!1,start:Date.now(),id:r(12),referrer:l},m,e.data):c}function i(r={}){const s=Date.now(),{length:i=30,deviceKey:a="elbDeviceId",deviceStorage:d="local",deviceAge:u=30,sessionKey:l="elbSessionId",sessionStorage:m="local",pulse:w=!1}=r,g=r.window||r.document?{window:r.window,document:r.document}:void 0,f=c(r);let p=!1;const v=n((n,r,s)=>{let c=t(n,s,g);return c||(c=e(8),o(n,c,1440*r,s,void 0,g)),String(c)})(a,u,d),S=n((e,n)=>{const o=JSON.parse(String(t(e,n,g)));return w||(o.isNew=!1,f.marketing&&(Object.assign(o,f),p=!0),p||o.updated+6e4*i<s?(delete o.id,delete o.referrer,o.start=s,o.count++,o.runs=1,p=!0):o.runs++),o},()=>{p=!0})(l,m)||{},y={id:e(12),start:s,isNew:!0,count:1,runs:1},b=Object.assign(y,f,S,{device:v},{isStart:p,storage:!0,updated:s},r.data);return o(l,JSON.stringify(b),2*i,m,void 0,g),b}import{getGrantedConsent as a,isArray as d,isDefined as u}from"@walkeros/core";function l(e={}){const{cb:n,consent:t,collector:o,storage:r}=e;if(!t)return m((r?i:c)(e),o,n);{const r=function(e,n){let t;const o=(o,r)=>{const s=r.collector;if(u(t)&&t===(null==s?void 0:s.round))return;t=null==s?void 0:s.round;let l=()=>c(e);if(e.consent){const n=(d(e.consent)?e.consent:[e.consent]).reduce((e,n)=>({...e,[n]:!0}),{});a(n,o)&&(l=()=>i(e))}m(l(),s,n)};return o}(e,n),s=(d(t)?t:[t]).reduce((e,n)=>({...e,[n]:r}),{});o&&o.command("on",{type:"consent",rules:s})}}function m(e,n,t){return!1===t?e:(t||(t=w),t(e,n,w))}var w=(e,n)=>{const t={};return e.id&&(t.session=e.id),e.storage&&e.device&&(t.device=e.device),n&&(n.command("user",t),n.command("session",e)),e.isStart&&n&&n.push({name:"session start",data:e}),e},g={},f=async e=>{const{config:n,env:t}=e,{elb:o,command:r}=t,s={...null==n?void 0:n.settings},c={settings:s},i={push:o,command:r};l({...s,window:t.window,document:t.document,collector:i});return{type:"session",config:c,push:o,on:async e=>{"consent"===e&&l({...s,window:t.window,document:t.document,collector:i})}}},p=f;export{g as SourceSession,p as default,l as sessionStart,i as sessionStorage,c as sessionWindow,f as sourceSession};//# sourceMappingURL=index.mjs.map
1
+ import{getId as e,tryCatch as t}from"@walkeros/core";import{storageRead as n,storageWrite as o}from"@walkeros/web-core";import{getId as r,getMarketingParameters as s}from"@walkeros/core";function i(e={}){var t,n;let o=e.isStart||!1;const i={isStart:o,storage:!1};if(!1===e.isStart)return i;const c=null!=(t=e.window)?t:window,a=null!=(n=e.document)?n:document;if(!o){const[e]=c.performance.getEntriesByType("navigation");if("navigate"!==e.type)return i}const d=new URL(e.url||c.location.href),u=e.referrer||a.referrer,l=u&&new URL(u).hostname,m=s(d,e.parameters,e.clickIds);if(Object.keys(m).length&&(m.marketing||(m.marketing=!0),o=!0),!o){const t=e.domains||[];t.push(d.hostname),o=!t.includes(l)}return o?Object.assign({isStart:o,storage:!1,start:Date.now(),id:r(12),referrer:l},m,e.data):i}function c(r={}){const s=Date.now(),{length:c=30,deviceKey:a="elbDeviceId",deviceStorage:d="local",deviceAge:u=30,sessionKey:l="elbSessionId",sessionStorage:m="local",pulse:g=!1}=r,f=r.window||r.document?{window:r.window,document:r.document}:void 0,w=i(r);let p=!1;const v=t((t,r,s)=>{let i=n(t,s,f);return i||(i=e(8),o(t,i,1440*r,s,void 0,f)),String(i)})(a,u,d),S=t((e,t)=>{const o=JSON.parse(String(n(e,t,f)));return g||(o.isNew=!1,w.marketing&&(Object.assign(o,w),p=!0),p||o.updated+6e4*c<s?(delete o.id,delete o.referrer,o.start=s,o.count++,o.runs=1,p=!0):o.runs++),o},()=>{p=!0})(l,m)||{},y={id:e(12),start:s,isNew:!0,count:1,runs:1},b=Object.assign(y,w,S,{device:v},{isStart:p,storage:!0,updated:s},r.data);return o(l,JSON.stringify(b),2*c,m,void 0,f),b}import{getGrantedConsent as a,isArray as d}from"@walkeros/core";function u(e={}){const{cb:t,consent:n,collector:o,storage:r}=e;if(!n)return l((r?c:i)(e),o,t);{const r=function(e,t){const n=(n,o)=>{const r=o.collector;let s=()=>i(e);if(e.consent){const t=(d(e.consent)?e.consent:[e.consent]).reduce((e,t)=>({...e,[t]:!0}),{});a(t,n)&&(s=()=>c(e))}l(s(),r,t)};return n}(e,t),s=(d(n)?n:[n]).reduce((e,t)=>({...e,[t]:r}),{});o&&o.command("on",{type:"consent",rules:s})}}function l(e,t,n){return!1===n?e:(n||(n=m),n(e,t,m))}var m=(e,t)=>{const n={};return e.id&&(n.session=e.id),e.storage&&e.device&&(n.device=e.device),t&&(t.command("user",n),t.command("session",e)),e.isStart&&t&&t.push({name:"session start",data:e}),e},g={},f=async e=>{const{config:t,env:n}=e,{elb:o,command:r}=n,s={...null==t?void 0:t.settings},i={settings:s},c={push:o,command:r};return u({...s,window:n.window,document:n.document,collector:c}),{type:"session",config:i,push:o}},w=f;export{g as SourceSession,w as default,u as sessionStart,c as sessionStorage,i as sessionWindow,f as sourceSession};//# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/lib/sessionStorage.ts","../src/lib/sessionWindow.ts","../src/lib/sessionStart.ts","../src/types/index.ts","../src/index.ts"],"sourcesContent":["import type { Collector } from '@walkeros/core';\nimport type { SessionWindowConfig } from './sessionWindow';\nimport type { StorageType } from '@walkeros/core';\nimport type { StorageEnv } from '@walkeros/web-core';\nimport { getId, tryCatch } from '@walkeros/core';\nimport { storageRead, storageWrite } from '@walkeros/web-core';\nimport { sessionWindow } from './sessionWindow';\n\nexport interface SessionStorageConfig extends SessionWindowConfig {\n deviceKey?: string;\n deviceStorage?: StorageType;\n deviceAge?: number;\n sessionKey?: string;\n sessionStorage?: StorageType;\n length?: number; // Minutes after last update to consider session as expired (default: 30)\n pulse?: boolean;\n}\n\nexport function sessionStorage(\n config: SessionStorageConfig = {},\n): Collector.SessionData {\n const now = Date.now();\n const {\n length = 30, // Session length in minutes\n deviceKey = 'elbDeviceId',\n deviceStorage = 'local',\n deviceAge = 30, // Device ID age in days\n sessionKey = 'elbSessionId',\n sessionStorage = 'local',\n pulse = false, // Handle the counting\n } = config;\n const storageEnv: StorageEnv | undefined =\n config.window || config.document\n ? { window: config.window, document: config.document }\n : undefined;\n const windowSession = sessionWindow(config); // Status based on window only\n let isStart = false;\n\n // Retrieve or create device ID\n const device = tryCatch((key: string, age: number, storage: StorageType) => {\n let id = storageRead(key, storage, storageEnv);\n if (!id) {\n id = getId(8); // Create a new device ID\n storageWrite(key, id, age * 1440, storage, undefined, storageEnv); // Write device ID to storage\n }\n return String(id);\n })(deviceKey, deviceAge, deviceStorage);\n\n // Retrieve or initialize session data\n const existingSession: Collector.SessionData =\n tryCatch(\n (key: string, storage?: StorageType) => {\n const session = JSON.parse(\n String(storageRead(key, storage, storageEnv)),\n );\n\n // Only update session if it's not a pulse check\n if (pulse) return session;\n\n // Mark session as not new by default\n session.isNew = false;\n\n // Handle new marketing entry\n if (windowSession.marketing) {\n Object.assign(session, windowSession); // Overwrite existing session with marketing data\n isStart = true; // This is a session start\n }\n\n // Check if session is still active\n if (isStart || session.updated + length * 60000 < now) {\n // Session has expired\n delete session.id; // Unset session ID\n delete session.referrer; // Unset referrer\n session.start = now; // Set new session start\n session.count++; // Increase session count\n session.runs = 1; // Reset runs\n isStart = true; // It's a new session\n } else {\n // Session is still active\n session.runs++; // Increase number of runs\n }\n\n return session;\n },\n () => {\n // No existing session or something went wrong\n isStart = true; // Start a new session\n },\n )(sessionKey, sessionStorage) || {};\n\n // Default session data\n const defaultSession: Partial<Collector.SessionData> = {\n id: getId(12),\n start: now,\n isNew: true,\n count: 1,\n runs: 1,\n };\n\n // Merge session data\n const session = Object.assign(\n defaultSession, // Default session values\n windowSession, // Basic session data based on window\n existingSession, // (Updated) existing session\n { device }, // Device ID\n { isStart, storage: true, updated: now }, // Status of the session\n config.data, // Given data has the highest priority\n );\n\n // Write (updated) session to storage\n storageWrite(\n sessionKey,\n JSON.stringify(session),\n length * 2,\n sessionStorage,\n undefined,\n storageEnv,\n );\n\n return session;\n}\n","import type { Collector, WalkerOS } from '@walkeros/core';\nimport {\n getId,\n getMarketingParameters,\n type ClickIdEntry,\n type MarketingParameters,\n} from '@walkeros/core';\n\nexport interface SessionWindowConfig {\n clickIds?: ClickIdEntry[];\n data?: WalkerOS.Properties;\n domains?: string[];\n isStart?: boolean;\n parameters?: MarketingParameters;\n referrer?: string;\n url?: string;\n window?: Window & typeof globalThis;\n document?: Document;\n}\n\nexport function sessionWindow(\n config: SessionWindowConfig = {},\n): Collector.SessionData {\n let isStart = config.isStart || false;\n const known = { isStart, storage: false };\n\n // If session has explicitly started, return known\n if (config.isStart === false) return known;\n\n const win = config.window ?? window;\n const doc = config.document ?? document;\n\n // Entry type\n if (!isStart) {\n // Only focus on linked or direct navigation types\n // and ignore reloads and all others\n const [perf] = win.performance.getEntriesByType(\n 'navigation',\n ) as PerformanceNavigationTiming[];\n if (perf.type !== 'navigate') return known;\n }\n\n const url = new URL(config.url || win.location.href);\n const ref = config.referrer || doc.referrer;\n const referrer = ref && new URL(ref).hostname;\n\n // Marketing\n const marketing = getMarketingParameters(\n url,\n config.parameters,\n config.clickIds,\n );\n if (Object.keys(marketing).length) {\n // Check for marketing parameters like UTM and add existing\n if (!marketing.marketing)\n // Flag as a marketing session without overwriting\n marketing.marketing = true;\n\n isStart = true;\n }\n\n // Referrer\n if (!isStart) {\n // Small chance of multiple unintended events for same users\n // https://en.wikipedia.org/wiki/HTTP_referer#Referrer_hiding\n // Use domains: [''] to disable direct or hidden referrer\n\n const domains = config.domains || [];\n domains.push(url.hostname);\n isStart = !domains.includes(referrer);\n }\n\n return isStart\n ? // It's a session start, moin\n Object.assign(\n {\n isStart,\n storage: false,\n start: Date.now(),\n id: getId(12),\n referrer,\n },\n marketing,\n config.data,\n )\n : // No session start\n known;\n}\n","import type { Collector, WalkerOS, On, ClickIdEntry } from '@walkeros/core';\nimport type { SessionStorageConfig } from './sessionStorage';\nimport { sessionStorage } from './sessionStorage';\nimport { sessionWindow } from './sessionWindow';\nimport { getGrantedConsent, isArray, isDefined } from '@walkeros/core';\n\nexport interface SessionConfig extends SessionStorageConfig {\n clickIds?: ClickIdEntry[];\n consent?: string | string[];\n storage?: boolean;\n cb?: SessionCallback | false;\n collector?: Collector.Instance;\n}\n\nexport type SessionFunction = typeof sessionStorage | typeof sessionWindow;\nexport type SessionCallback = (\n session: Collector.SessionData,\n collector: Collector.Instance | undefined,\n defaultCb: SessionCallback,\n) => void;\n\nexport function sessionStart(\n config: SessionConfig = {},\n): Collector.SessionData | void {\n const { cb, consent, collector, storage } = config;\n const sessionFn: SessionFunction = storage ? sessionStorage : sessionWindow;\n\n // Consent\n if (consent) {\n const consentHandler = onConsentFn(config, cb);\n\n const consentConfig = (\n isArray(consent) ? consent : [consent]\n ).reduce<On.ConsentRule>(\n (acc, key) => ({ ...acc, [key]: consentHandler }),\n {},\n );\n // Register consent handlers with the collector\n if (collector) {\n collector.command('on', { type: 'consent', rules: consentConfig });\n }\n // No fallback - session source always provides collector\n } else {\n // just do it\n return callFuncAndCb(sessionFn(config), collector, cb);\n }\n}\n\nfunction callFuncAndCb(\n session: Collector.SessionData,\n collector?: Collector.Instance,\n cb?: SessionCallback | false,\n) {\n if (cb === false) return session; // Callback is disabled\n if (!cb) cb = defaultCb; // Default callback if none is provided\n return cb(session, collector, defaultCb);\n}\n\nfunction onConsentFn(\n config: SessionConfig,\n cb?: SessionCallback | false,\n): On.ConsentFn {\n // Track the last processed round to prevent duplicate processing\n let lastProcessedRound: number | undefined;\n\n const func: On.ConsentFn = (consent, context) => {\n const collector = context.collector;\n\n // Skip if we've already processed this round\n if (\n isDefined(lastProcessedRound) &&\n lastProcessedRound === collector?.round\n )\n return;\n\n // Remember this round has been processed\n lastProcessedRound = collector?.round;\n\n let sessionFn: SessionFunction = () => sessionWindow(config); // Window by default\n\n if (config.consent) {\n const consentKeys = (\n isArray(config.consent) ? config.consent : [config.consent]\n ).reduce<WalkerOS.Consent>((acc, key) => ({ ...acc, [key]: true }), {});\n\n if (getGrantedConsent(consentKeys, consent))\n // Use storage if consent is granted\n sessionFn = () => sessionStorage(config);\n }\n\n callFuncAndCb(sessionFn(), collector, cb);\n };\n\n return func;\n}\n\nconst defaultCb: SessionCallback = (\n session,\n collector,\n): Collector.SessionData => {\n const user: WalkerOS.User = {};\n\n // User.session is the session ID\n if (session.id) user.session = session.id;\n\n // Set device ID only in storage mode\n if (session.storage && session.device) user.device = session.device;\n\n // Set user IDs and broadcast session data\n if (collector) {\n collector.command('user', user);\n collector.command('session', session);\n }\n // No fallback - session source always provides collector\n\n if (session.isStart) {\n // Convert session start to an event object\n if (collector) {\n collector.push({\n name: 'session start',\n data: session,\n });\n }\n // No fallback - session source always provides collector\n }\n\n return session;\n};\n","import type { Source, Elb } from '@walkeros/core';\nimport type { SessionConfig, SessionCallback } from '../lib';\n\ndeclare module '@walkeros/core' {\n interface SourceMap {\n session: { type: 'session'; platform?: 'web' };\n }\n}\n\n// Settings: configuration for session source\nexport interface Settings extends SessionConfig {\n // All settings inherited from SessionConfig:\n // - consent?: string | string[]\n // - storage?: boolean\n // - cb?: SessionCallback | false\n // - pulse?: boolean\n // - sessionStorage?: 'local' | 'session'\n // - deviceStorage?: 'local' | 'session'\n // - sessionKey?: string\n // - deviceKey?: string\n // - length?: number (session timeout in minutes)\n}\n\n// InitSettings: user input (all optional)\nexport type InitSettings = Partial<Settings>;\n\nexport interface Mapping {}\n\nexport type Push = Elb.Fn;\n\nexport interface Env extends Source.BaseEnv {\n window?: Window & typeof globalThis;\n document?: Document;\n}\n\nexport type Types = Source.Types<Settings, Mapping, Push, Env, InitSettings>;\n\nexport type Config = Source.Config<Types>;\n\n// Re-export session types from lib\nexport type {\n SessionConfig,\n SessionCallback,\n SessionFunction,\n SessionStorageConfig,\n SessionWindowConfig,\n} from '../lib';\n","import type { Source, On, Collector } from '@walkeros/core';\nimport type { Types, Settings } from './types';\nimport { sessionStart } from './lib';\n\n// Export types for external usage\nexport * as SourceSession from './types';\n\n// Export lib functions for direct usage\nexport { sessionStart, sessionStorage, sessionWindow } from './lib';\nexport type {\n SessionConfig,\n SessionCallback,\n SessionFunction,\n SessionStorageConfig,\n SessionWindowConfig,\n} from './lib';\n\n/**\n * Session source implementation.\n *\n * This source handles session detection and management.\n */\nexport const sourceSession: Source.Init<Types> = async (context) => {\n const { config, env } = context;\n const { elb, command } = env;\n\n const settings: Settings = {\n ...config?.settings,\n };\n\n const fullConfig: Source.Config<Types> = {\n settings,\n };\n\n // Create minimal collector interface for sessionStart\n const collectorInterface: Partial<Collector.Instance> = {\n push: elb,\n command,\n };\n\n // Initialize session using local lib\n sessionStart({\n ...settings,\n window: env.window,\n document: env.document,\n collector: collectorInterface as Collector.Instance,\n });\n\n // Handle events pushed from collector (consent, session, ready, run)\n const handleEvent = async (event: On.Types) => {\n if (event === 'consent') {\n // Re-initialize session on consent changes\n sessionStart({\n ...settings,\n window: env.window,\n document: env.document,\n collector: collectorInterface as Collector.Instance,\n });\n }\n };\n\n return {\n type: 'session',\n config: fullConfig,\n push: elb,\n on: handleEvent,\n };\n};\n\nexport default sourceSession;\n"],"mappings":"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","names":["getId","sessionStorage","getId","session"]}
1
+ {"version":3,"sources":["../src/lib/sessionStorage.ts","../src/lib/sessionWindow.ts","../src/lib/sessionStart.ts","../src/types/index.ts","../src/index.ts"],"sourcesContent":["import type { Collector } from '@walkeros/core';\nimport type { SessionWindowConfig } from './sessionWindow';\nimport type { StorageType } from '@walkeros/core';\nimport type { StorageEnv } from '@walkeros/web-core';\nimport { getId, tryCatch } from '@walkeros/core';\nimport { storageRead, storageWrite } from '@walkeros/web-core';\nimport { sessionWindow } from './sessionWindow';\n\nexport interface SessionStorageConfig extends SessionWindowConfig {\n deviceKey?: string;\n deviceStorage?: StorageType;\n deviceAge?: number;\n sessionKey?: string;\n sessionStorage?: StorageType;\n length?: number; // Minutes after last update to consider session as expired (default: 30)\n pulse?: boolean;\n}\n\nexport function sessionStorage(\n config: SessionStorageConfig = {},\n): Collector.SessionData {\n const now = Date.now();\n const {\n length = 30, // Session length in minutes\n deviceKey = 'elbDeviceId',\n deviceStorage = 'local',\n deviceAge = 30, // Device ID age in days\n sessionKey = 'elbSessionId',\n sessionStorage = 'local',\n pulse = false, // Handle the counting\n } = config;\n const storageEnv: StorageEnv | undefined =\n config.window || config.document\n ? { window: config.window, document: config.document }\n : undefined;\n const windowSession = sessionWindow(config); // Status based on window only\n let isStart = false;\n\n // Retrieve or create device ID\n const device = tryCatch((key: string, age: number, storage: StorageType) => {\n let id = storageRead(key, storage, storageEnv);\n if (!id) {\n id = getId(8); // Create a new device ID\n storageWrite(key, id, age * 1440, storage, undefined, storageEnv); // Write device ID to storage\n }\n return String(id);\n })(deviceKey, deviceAge, deviceStorage);\n\n // Retrieve or initialize session data\n const existingSession: Collector.SessionData =\n tryCatch(\n (key: string, storage?: StorageType) => {\n const session = JSON.parse(\n String(storageRead(key, storage, storageEnv)),\n );\n\n // Only update session if it's not a pulse check\n if (pulse) return session;\n\n // Mark session as not new by default\n session.isNew = false;\n\n // Handle new marketing entry\n if (windowSession.marketing) {\n Object.assign(session, windowSession); // Overwrite existing session with marketing data\n isStart = true; // This is a session start\n }\n\n // Check if session is still active\n if (isStart || session.updated + length * 60000 < now) {\n // Session has expired\n delete session.id; // Unset session ID\n delete session.referrer; // Unset referrer\n session.start = now; // Set new session start\n session.count++; // Increase session count\n session.runs = 1; // Reset runs\n isStart = true; // It's a new session\n } else {\n // Session is still active\n session.runs++; // Increase number of runs\n }\n\n return session;\n },\n () => {\n // No existing session or something went wrong\n isStart = true; // Start a new session\n },\n )(sessionKey, sessionStorage) || {};\n\n // Default session data\n const defaultSession: Partial<Collector.SessionData> = {\n id: getId(12),\n start: now,\n isNew: true,\n count: 1,\n runs: 1,\n };\n\n // Merge session data\n const session = Object.assign(\n defaultSession, // Default session values\n windowSession, // Basic session data based on window\n existingSession, // (Updated) existing session\n { device }, // Device ID\n { isStart, storage: true, updated: now }, // Status of the session\n config.data, // Given data has the highest priority\n );\n\n // Write (updated) session to storage\n storageWrite(\n sessionKey,\n JSON.stringify(session),\n length * 2,\n sessionStorage,\n undefined,\n storageEnv,\n );\n\n return session;\n}\n","import type { Collector, WalkerOS } from '@walkeros/core';\nimport {\n getId,\n getMarketingParameters,\n type ClickIdEntry,\n type MarketingParameters,\n} from '@walkeros/core';\n\nexport interface SessionWindowConfig {\n clickIds?: ClickIdEntry[];\n data?: WalkerOS.Properties;\n domains?: string[];\n isStart?: boolean;\n parameters?: MarketingParameters;\n referrer?: string;\n url?: string;\n window?: Window & typeof globalThis;\n document?: Document;\n}\n\nexport function sessionWindow(\n config: SessionWindowConfig = {},\n): Collector.SessionData {\n let isStart = config.isStart || false;\n const known = { isStart, storage: false };\n\n // If session has explicitly started, return known\n if (config.isStart === false) return known;\n\n const win = config.window ?? window;\n const doc = config.document ?? document;\n\n // Entry type\n if (!isStart) {\n // Only focus on linked or direct navigation types\n // and ignore reloads and all others\n const [perf] = win.performance.getEntriesByType(\n 'navigation',\n ) as PerformanceNavigationTiming[];\n if (perf.type !== 'navigate') return known;\n }\n\n const url = new URL(config.url || win.location.href);\n const ref = config.referrer || doc.referrer;\n const referrer = ref && new URL(ref).hostname;\n\n // Marketing\n const marketing = getMarketingParameters(\n url,\n config.parameters,\n config.clickIds,\n );\n if (Object.keys(marketing).length) {\n // Check for marketing parameters like UTM and add existing\n if (!marketing.marketing)\n // Flag as a marketing session without overwriting\n marketing.marketing = true;\n\n isStart = true;\n }\n\n // Referrer\n if (!isStart) {\n // Small chance of multiple unintended events for same users\n // https://en.wikipedia.org/wiki/HTTP_referer#Referrer_hiding\n // Use domains: [''] to disable direct or hidden referrer\n\n const domains = config.domains || [];\n domains.push(url.hostname);\n isStart = !domains.includes(referrer);\n }\n\n return isStart\n ? // It's a session start, moin\n Object.assign(\n {\n isStart,\n storage: false,\n start: Date.now(),\n id: getId(12),\n referrer,\n },\n marketing,\n config.data,\n )\n : // No session start\n known;\n}\n","import type { Collector, WalkerOS, On, ClickIdEntry } from '@walkeros/core';\nimport type { SessionStorageConfig } from './sessionStorage';\nimport { sessionStorage } from './sessionStorage';\nimport { sessionWindow } from './sessionWindow';\nimport { getGrantedConsent, isArray } from '@walkeros/core';\n\nexport interface SessionConfig extends SessionStorageConfig {\n clickIds?: ClickIdEntry[];\n consent?: string | string[];\n storage?: boolean;\n cb?: SessionCallback | false;\n collector?: Collector.Instance;\n}\n\nexport type SessionFunction = typeof sessionStorage | typeof sessionWindow;\nexport type SessionCallback = (\n session: Collector.SessionData,\n collector: Collector.Instance | undefined,\n defaultCb: SessionCallback,\n) => void;\n\nexport function sessionStart(\n config: SessionConfig = {},\n): Collector.SessionData | void {\n const { cb, consent, collector, storage } = config;\n const sessionFn: SessionFunction = storage ? sessionStorage : sessionWindow;\n\n // Consent\n if (consent) {\n const consentHandler = onConsentFn(config, cb);\n\n const consentConfig = (\n isArray(consent) ? consent : [consent]\n ).reduce<On.ConsentRule>(\n (acc, key) => ({ ...acc, [key]: consentHandler }),\n {},\n );\n // Register consent handlers with the collector\n if (collector) {\n collector.command('on', { type: 'consent', rules: consentConfig });\n }\n // No fallback - session source always provides collector\n } else {\n // just do it\n return callFuncAndCb(sessionFn(config), collector, cb);\n }\n}\n\nfunction callFuncAndCb(\n session: Collector.SessionData,\n collector?: Collector.Instance,\n cb?: SessionCallback | false,\n) {\n if (cb === false) return session; // Callback is disabled\n if (!cb) cb = defaultCb; // Default callback if none is provided\n return cb(session, collector, defaultCb);\n}\n\nfunction onConsentFn(\n config: SessionConfig,\n cb?: SessionCallback | false,\n): On.ConsentFn {\n const func: On.ConsentFn = (consent, context) => {\n const collector = context.collector;\n\n let sessionFn: SessionFunction = () => sessionWindow(config); // Window by default\n\n if (config.consent) {\n const consentKeys = (\n isArray(config.consent) ? config.consent : [config.consent]\n ).reduce<WalkerOS.Consent>((acc, key) => ({ ...acc, [key]: true }), {});\n\n if (getGrantedConsent(consentKeys, consent))\n // Use storage if consent is granted\n sessionFn = () => sessionStorage(config);\n }\n\n callFuncAndCb(sessionFn(), collector, cb);\n };\n\n return func;\n}\n\nconst defaultCb: SessionCallback = (\n session,\n collector,\n): Collector.SessionData => {\n const user: WalkerOS.User = {};\n\n // User.session is the session ID\n if (session.id) user.session = session.id;\n\n // Set device ID only in storage mode\n if (session.storage && session.device) user.device = session.device;\n\n // Set user IDs and broadcast session data\n if (collector) {\n collector.command('user', user);\n collector.command('session', session);\n }\n // No fallback - session source always provides collector\n\n if (session.isStart) {\n // Convert session start to an event object\n if (collector) {\n collector.push({\n name: 'session start',\n data: session,\n });\n }\n // No fallback - session source always provides collector\n }\n\n return session;\n};\n","import type { Source, Elb } from '@walkeros/core';\nimport type { SessionConfig, SessionCallback } from '../lib';\n\ndeclare module '@walkeros/core' {\n interface SourceMap {\n session: { type: 'session'; platform?: 'web' };\n }\n}\n\n// Settings: configuration for session source\nexport interface Settings extends SessionConfig {\n // All settings inherited from SessionConfig:\n // - consent?: string | string[]\n // - storage?: boolean\n // - cb?: SessionCallback | false\n // - pulse?: boolean\n // - sessionStorage?: 'local' | 'session'\n // - deviceStorage?: 'local' | 'session'\n // - sessionKey?: string\n // - deviceKey?: string\n // - length?: number (session timeout in minutes)\n}\n\n// InitSettings: user input (all optional)\nexport type InitSettings = Partial<Settings>;\n\nexport interface Mapping {}\n\nexport type Push = Elb.Fn;\n\nexport interface Env extends Source.BaseEnv {\n window?: Window & typeof globalThis;\n document?: Document;\n}\n\nexport type Types = Source.Types<Settings, Mapping, Push, Env, InitSettings>;\n\nexport type Config = Source.Config<Types>;\n\n// Re-export session types from lib\nexport type {\n SessionConfig,\n SessionCallback,\n SessionFunction,\n SessionStorageConfig,\n SessionWindowConfig,\n} from '../lib';\n","import type { Source, Collector } from '@walkeros/core';\nimport type { Types, Settings } from './types';\nimport { sessionStart } from './lib';\n\n// Export types for external usage\nexport * as SourceSession from './types';\n\n// Export lib functions for direct usage\nexport { sessionStart, sessionStorage, sessionWindow } from './lib';\nexport type {\n SessionConfig,\n SessionCallback,\n SessionFunction,\n SessionStorageConfig,\n SessionWindowConfig,\n} from './lib';\n\n/**\n * Session source implementation.\n *\n * This source handles session detection and management.\n */\nexport const sourceSession: Source.Init<Types> = async (context) => {\n const { config, env } = context;\n const { elb, command } = env;\n\n const settings: Settings = {\n ...config?.settings,\n };\n\n const fullConfig: Source.Config<Types> = {\n settings,\n };\n\n // Create minimal collector interface for sessionStart\n const collectorInterface: Partial<Collector.Instance> = {\n push: elb,\n command,\n };\n\n // Initialize session using local lib. When `settings.consent` is set this\n // registers a single consent rule with the collector; the collector then\n // guarantees exactly-once delivery per state change, so the source does not\n // need to react to consent events itself.\n sessionStart({\n ...settings,\n window: env.window,\n document: env.document,\n collector: collectorInterface as Collector.Instance,\n });\n\n return {\n type: 'session',\n config: fullConfig,\n push: elb,\n };\n};\n\nexport default sourceSession;\n"],"mappings":"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","names":["getId","sessionStorage","getId","session"]}
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$meta": {
3
3
  "package": "@walkeros/web-source-session",
4
- "version": "4.1.3-next-1779963694449",
4
+ "version": "4.2.0-next-1780387694663",
5
5
  "type": "source",
6
6
  "platform": [
7
7
  "web"
@@ -108,7 +108,7 @@
108
108
  },
109
109
  "examples": {
110
110
  "createTrigger": {
111
- "$code": "async e=>{let t;return{get flow(){return t},trigger:(n,o)=>async n=>{var s,r,i,a,c,l,u,d,f;const p=o||{};if(p.url){const e=new URL(p.url);window.history.replaceState({},\"\",e.pathname+e.search)}if(p.referrer&&Object.defineProperty(document,\"referrer\",{value:p.referrer,configurable:!0}),p.sessionData){const e=p.sessionKey||\"elbSessionId\";localStorage.setItem(e,JSON.stringify(p.sessionData))}if(p.deviceId){const e=p.deviceKey||\"elbDeviceId\";localStorage.setItem(e,p.deviceId)}if(!t){const n=await mt({...e,run:null==(s=e.run)||s});t={collector:n.collector,elb:n.elb};const o=p.sessionKey||(null==(c=null==(a=null==(i=null==(r=e.sources)?void 0:r.session)?void 0:i.config)?void 0:a.settings)?void 0:c.sessionKey)||\"elbSessionId\",g=p.deviceKey||(null==(f=null==(d=null==(u=null==(l=e.sources)?void 0:l.session)?void 0:u.config)?void 0:d.settings)?void 0:f.deviceKey)||\"elbDeviceId\";localStorage.removeItem(o),localStorage.removeItem(g),p.sessionData&&localStorage.setItem(o,JSON.stringify(p.sessionData)),p.deviceId&&localStorage.setItem(g,p.deviceId),e.consent&&await t.collector.command(\"consent\",e.consent)}}}}"
111
+ "$code": "async e=>{let t;return{get flow(){return t},trigger:(n,o)=>async n=>{var s,r,i,a,c,l,u,d,f;const p=o||{};if(p.url){const e=new URL(p.url);window.history.replaceState({},\"\",e.pathname+e.search)}if(p.referrer&&Object.defineProperty(document,\"referrer\",{value:p.referrer,configurable:!0}),p.sessionData){const e=p.sessionKey||\"elbSessionId\";localStorage.setItem(e,JSON.stringify(p.sessionData))}if(p.deviceId){const e=p.deviceKey||\"elbDeviceId\";localStorage.setItem(e,p.deviceId)}if(!t){const n=await jt({...e,run:null==(s=e.run)||s});t={collector:n.collector,elb:n.elb};const o=p.sessionKey||(null==(c=null==(a=null==(i=null==(r=e.sources)?void 0:r.session)?void 0:i.config)?void 0:a.settings)?void 0:c.sessionKey)||\"elbSessionId\",g=p.deviceKey||(null==(f=null==(d=null==(u=null==(l=e.sources)?void 0:l.session)?void 0:u.config)?void 0:d.settings)?void 0:f.deviceKey)||\"elbDeviceId\";localStorage.removeItem(o),localStorage.removeItem(g),p.sessionData&&localStorage.setItem(o,JSON.stringify(p.sessionData)),p.deviceId&&localStorage.setItem(g,p.deviceId),e.consent&&await t.collector.command(\"consent\",e.consent)}}}}"
112
112
  },
113
113
  "step": {
114
114
  "newMarketingSession": {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@walkeros/web-source-session",
3
3
  "description": "Session source for walkerOS",
4
- "version": "4.1.3-next-1779963694449",
4
+ "version": "4.2.0-next-1780387694663",
5
5
  "license": "MIT",
6
6
  "main": "./dist/index.js",
7
7
  "module": "./dist/index.mjs",
@@ -33,11 +33,11 @@
33
33
  "update": "npx npm-check-updates -u && npm update"
34
34
  },
35
35
  "dependencies": {
36
- "@walkeros/core": "4.1.3-next-1779963694449",
37
- "@walkeros/web-core": "4.1.3-next-1779963694449"
36
+ "@walkeros/core": "4.2.0-next-1780387694663",
37
+ "@walkeros/web-core": "4.2.0-next-1780387694663"
38
38
  },
39
39
  "devDependencies": {
40
- "@walkeros/collector": "4.1.3-next-1779963694449"
40
+ "@walkeros/collector": "4.2.0-next-1780387694663"
41
41
  },
42
42
  "repository": {
43
43
  "url": "git+https://github.com/elbwalker/walkerOS.git",