@walkeros/collector 0.7.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -43,6 +43,18 @@ Sources capture events and send them to the collector, which processes and
43
43
  routes them to your chosen destinations like Google Analytics, custom APIs, or
44
44
  data warehouses.
45
45
 
46
+ ### Operating Modes
47
+
48
+ The collector can be used in two ways:
49
+
50
+ | Mode | Usage | Config |
51
+ | -------------- | ---------------------------------- | -------------------------- |
52
+ | **Integrated** | Import directly in your app | `code: sourceBrowser` |
53
+ | **Bundled** | Bundle with CLI, deploy separately | `package: "@walkeros/..."` |
54
+
55
+ This README shows **Integrated mode**. For Bundled mode, see the
56
+ [CLI documentation](../cli/).
57
+
46
58
  ## Event Naming Convention
47
59
 
48
60
  walkerOS enforces a **"entity action"** naming convention for all events. It
@@ -75,7 +87,7 @@ action by space the collector won't process it.
75
87
  npm install @walkeros/collector
76
88
  ```
77
89
 
78
- ## Quick Start
90
+ ## Quick Start (Integrated Mode)
79
91
 
80
92
  ### Basic setup
81
93
 
@@ -83,7 +95,6 @@ npm install @walkeros/collector
83
95
  import { startFlow } from '@walkeros/collector';
84
96
 
85
97
  const config = {
86
- run: true,
87
98
  consent: { functional: true },
88
99
  sources: [
89
100
  // add your event sources
@@ -100,7 +111,6 @@ const { collector, elb } = await startFlow(config);
100
111
  import { startFlow } from '@walkeros/collector';
101
112
 
102
113
  const { collector, elb } = await startFlow({
103
- run: true,
104
114
  consent: { functional: true },
105
115
  sources: [
106
116
  // add your event sources
@@ -127,6 +137,20 @@ const { collector, elb } = await startFlow({
127
137
  | `consent` | `object` | Initial consent state to control routing of events | No | `{ analytics: true, marketing: false }` |
128
138
  | `logger` | `object` | Logger configuration with level and custom handler | No | `{ level: 'info', handler: fn }` |
129
139
 
140
+ ### Using with CLI (Bundled Mode)
141
+
142
+ For Bundled mode, the collector is configured via JSON:
143
+
144
+ ```json
145
+ {
146
+ "collector": {
147
+ "consent": { "functional": true }
148
+ }
149
+ }
150
+ ```
151
+
152
+ See [CLI documentation](../cli/) for complete flow configuration.
153
+
130
154
  ## Type Definitions
131
155
 
132
156
  See [src/types/](./src/types/) for TypeScript interfaces:
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- "use strict";var e,n=Object.defineProperty,t=Object.getOwnPropertyDescriptor,o=Object.getOwnPropertyNames,s=Object.prototype.hasOwnProperty,r={};((e,t)=>{for(var o in t)n(e,o,{get:t[o],enumerable:!0})})(r,{Code:()=>i,Commands:()=>c,Const:()=>a,addDestination:()=>w,commonHandleCommand:()=>R,createEvent:()=>F,createPush:()=>M,createPushResult:()=>j,destinationCode:()=>l,destinationInit:()=>k,destinationPush:()=>C,initDestinations:()=>O,initSources:()=>U,mergeEnvironments:()=>q,on:()=>x,onApply:()=>P,pushToDestinations:()=>v,runCollector:()=>B,setConsent:()=>D,startFlow:()=>W}),module.exports=(e=r,((e,r,i,c)=>{if(r&&"object"==typeof r||"function"==typeof r)for(let a of o(r))s.call(e,a)||a===i||n(e,a,{get:()=>r[a],enumerable:!(c=t(r,a))||c.enumerable});return e})(n({},"__esModule",{value:!0}),e));var i={},c={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",User:"user",Walker:"walker"},a={Commands:c,Utils:{Storage:{Cookie:"cookie",Local:"local",Session:"session"}}},u=require("@walkeros/core"),g=require("@walkeros/core"),l={type:"code",config:{},init(e){const{config:n,logger:t}=e,o=n.settings,s=o?.scripts;if(s&&"undefined"!=typeof document)for(const e of s){const n=document.createElement("script");n.src=e,n.async=!0,document.head.appendChild(n)}const r=o?.init;if(r)try{new Function("context",r)(e)}catch(e){t.error("Code destination init error:",e)}},push(e,n){const{rule:t,config:o,logger:s}=n,r=t?.push??o.settings?.push;if(r)try{new Function("event","context",r)(e,n)}catch(e){s.error("Code destination push error:",e)}},pushBatch(e,n){const{rule:t,config:o,logger:s}=n,r=t?.pushBatch??o.settings?.pushBatch;if(r)try{new Function("batch","context",r)(e,n)}catch(e){s.error("Code destination pushBatch error:",e)}},on(e,n){const{config:t,logger:o}=n,s=t.settings?.on;if(s)try{new Function("type","context",s)(e,n)}catch(e){o.error("Code destination on error:",e)}}},f=require("@walkeros/core");function d(e,n={}){if(!e)return[];const t=[],o=new Set;let s=e;for(;s&&n[s]&&!o.has(s);)o.add(s),t.push(s),s=n[s].next;return t}async function m(e,n,t){if(n.init&&!n.config.init){const o=n.type||"unknown",s=e.logger.scope(`transformer:${o}`),r={collector:e,logger:s,id:t,config:n.config,env:b(n.config.env)};s.debug("init");const i=await(0,f.useHooks)(n.init,"TransformerInit",e.hooks)(r);if(!1===i)return!1;n.config={...i||n.config,init:!0},s.debug("init done")}return!0}async function p(e,n,t,o,s){const r=n.type||"unknown",i=e.logger.scope(`transformer:${r}`),c={collector:e,logger:i,id:t,ingest:s,config:n.config,env:b(n.config.env)};i.debug("push",{event:o.name});const a=await(0,f.useHooks)(n.push,"TransformerPush",e.hooks)(o,c);return i.debug("push done"),a}async function h(e,n,t,o,s){let r=o;for(const o of t){const t=n[o];if(!t){e.logger.info(`Transformer not found: ${o}`);continue}if(!await(0,f.tryCatchAsync)(m)(e,t,o))return e.logger.info(`Transformer init failed: ${o}`),null;const i=await(0,f.tryCatchAsync)(p,n=>(e.logger.scope(`transformer:${t.type||"unknown"}`).error("Push failed",{error:n}),!1))(e,t,o,r,s);if(!1===i)return null;void 0!==i&&(r=i)}return r}function b(e){return e&&(0,f.isObject)(e)?e:{}}function y(e){return!0===e?l:e}async function w(e,n,t){const{code:o,config:s={},env:r={}}=n,i=t||s||{init:!1},c=y(o),a={...c,config:i,env:q(c.env,r)};let u=a.config.id;if(!u)do{u=(0,g.getId)(4)}while(e.destinations[u]);return e.destinations[u]=a,!1!==a.config.queue&&(a.queue=[...e.queue]),v(e,void 0,{},{[u]:a})}async function v(e,n,t={},o){const{allowed:s,consent:r,globals:i,user:c}=e;if(!s)return j({ok:!1});n&&e.queue.push(n),o||(o=e.destinations);const a=await Promise.all(Object.entries(o||{}).map(async([o,s])=>{let a=(s.queue||[]).map(e=>({...e,consent:r}));if(s.queue=[],n){const e=(0,g.clone)(n);a.push(e)}if(!a.length)return{id:o,destination:s,skipped:!0};const u=[],l=a.filter(e=>{const n=(0,g.getGrantedConsent)(s.config.consent,r,e.consent);return!n||(e.consent=n,u.push(e),!1)});if(s.queue.concat(l),!u.length)return{id:o,destination:s,queue:a};if(!await(0,g.tryCatchAsync)(k)(e,s,o))return{id:o,destination:s,queue:a};let f,d;s.dlq||(s.dlq=[]);const m=e.transformerChain?.post?.[o]||[];return await Promise.all(u.map(async n=>{n.globals=(0,g.assign)(i,n.globals),n.user=(0,g.assign)(c,n.user);let r=n;if(m.length>0&&e.transformers&&Object.keys(e.transformers).length>0){const o=await h(e,e.transformers,m,n,t.ingest);if(null===o)return n;r=o}const a=await(0,g.tryCatchAsync)(C,n=>{const t=s.type||"unknown";e.logger.scope(t).error("Push failed",{error:n,event:r.name}),f=n,s.dlq.push([r,n])})(e,s,o,r,t.ingest);return void 0!==a&&(d=a),n})),{id:o,destination:s,error:f,response:d}})),u={},l={},f={};for(const e of a){if(e.skipped)continue;const n=e.destination,t={type:n.type||"unknown",data:e.response};e.error?(t.error=e.error,f[e.id]=t):e.queue&&e.queue.length?(n.queue=(n.queue||[]).concat(e.queue),l[e.id]=t):u[e.id]=t}return j({event:n,...Object.keys(u).length&&{done:u},...Object.keys(l).length&&{queued:l},...Object.keys(f).length&&{failed:f}})}async function k(e,n,t){if(n.init&&!n.config.init){const o=n.type||"unknown",s=e.logger.scope(o),r={collector:e,logger:s,id:t,config:n.config,env:q(n.env,n.config.env)};s.debug("init");const i=await(0,g.useHooks)(n.init,"DestinationInit",e.hooks)(r);if(!1===i)return i;n.config={...i||n.config,init:!0},s.debug("init done")}return!0}async function C(e,n,t,o,s){const{config:r}=n,i=await(0,g.processEventMapping)(o,r,e);if(i.ignore)return!1;const c=n.type||"unknown",a=e.logger.scope(c),u={collector:e,logger:a,id:t,config:r,data:i.data,rule:i.mapping,ingest:s,env:q(n.env,r.env)},l=i.mapping,f=i.mappingKey||"* *";if(!l?.batch||!n.pushBatch){a.debug("push",{event:i.event.name});const t=await(0,g.useHooks)(n.push,"DestinationPush",e.hooks)(i.event,u);return a.debug("push done"),t}{if(n.batches=n.batches||{},!n.batches[f]){const o={key:f,events:[],data:[]};n.batches[f]={batched:o,batchFn:(0,g.debounce)(()=>{const o=n.batches[f].batched,i={collector:e,logger:a,id:t,config:r,data:void 0,rule:l,ingest:s,env:q(n.env,r.env)};a.debug("push batch",{events:o.events.length}),(0,g.useHooks)(n.pushBatch,"DestinationPushBatch",e.hooks)(o,i),a.debug("push batch done"),o.events=[],o.data=[]},l.batch)}}const o=n.batches[f];o.batched.events.push(i.event),(0,g.isDefined)(i.data)&&o.batched.data.push(i.data),o.batchFn()}return!0}function j(e){return{ok:!e?.failed,...e}}async function O(e,n={}){const t={};for(const[e,o]of Object.entries(n)){const{code:n,config:s={},env:r={}}=o,i=y(n),c={...i.config,...s},a=q(i.env,r);t[e]={...i,config:c,env:a}}return t}function q(e,n){return e||n?n?e&&(0,g.isObject)(e)&&(0,g.isObject)(n)?{...e,...n}:n:e:{}}var E=require("@walkeros/core"),A=require("@walkeros/core");function x(e,n,t){const o=e.on,s=o[n]||[],r=(0,E.isArray)(t)?t:[t];r.forEach(e=>{s.push(e)}),o[n]=s,P(e,n,r)}function P(e,n,t,o){let s,r=t||[];switch(t||(r=e.on[n]||[]),n){case a.Commands.Consent:s=o||e.consent;break;case a.Commands.Session:s=e.session;break;case a.Commands.Ready:case a.Commands.Run:default:s=void 0}if(Object.values(e.sources).forEach(e=>{e.on&&(0,A.tryCatch)(e.on)(n,s)}),Object.entries(e.destinations).forEach(([t,o])=>{if(o.on){const r=o.type||"unknown",i=e.logger.scope(r).scope("on").scope(n),c={collector:e,logger:i,id:t,config:o.config,data:s,env:q(o.env,o.config.env)};(0,A.tryCatch)(o.on)(n,c)}}),r.length)switch(n){case a.Commands.Consent:!function(e,n,t){const o=t||e.consent;n.forEach(n=>{Object.keys(o).filter(e=>e in n).forEach(t=>{(0,A.tryCatch)(n[t])(e,o)})})}(e,r,o);break;case a.Commands.Ready:case a.Commands.Run:!function(e,n){e.allowed&&n.forEach(n=>{(0,A.tryCatch)(n)(e)})}(e,r);break;case a.Commands.Session:!function(e,n){if(!e.session)return;n.forEach(n=>{(0,A.tryCatch)(n)(e,e.session)})}(e,r)}}async function D(e,n){const{consent:t}=e;let o=!1;const s={};return Object.entries(n).forEach(([e,n])=>{const t=!!n;s[e]=t,o=o||t}),e.consent=(0,u.assign)(t,s),P(e,"consent",void 0,s),o?v(e):j({ok:!0})}var S=require("@walkeros/core"),$=require("@walkeros/core"),H=require("@walkeros/core");async function R(e,n,t,o){let s;switch(n){case a.Commands.Config:(0,H.isObject)(t)&&(0,$.assign)(e.config,t,{shallow:!1});break;case a.Commands.Consent:(0,H.isObject)(t)&&(s=await D(e,t));break;case a.Commands.Custom:(0,H.isObject)(t)&&(e.custom=(0,$.assign)(e.custom,t));break;case a.Commands.Destination:(0,H.isObject)(t)&&(0,$.isFunction)(t.push)&&(s=await w(e,{code:t},o));break;case a.Commands.Globals:(0,H.isObject)(t)&&(e.globals=(0,$.assign)(e.globals,t));break;case a.Commands.On:(0,$.isString)(t)&&x(e,t,o);break;case a.Commands.Ready:P(e,"ready");break;case a.Commands.Run:s=await B(e,t);break;case a.Commands.Session:P(e,"session");break;case a.Commands.User:(0,H.isObject)(t)&&(0,$.assign)(e.user,t,{shallow:!1})}return s||j({ok:!0})}function F(e,n){if(!n.name)throw new Error("Event name is required");const[t,o]=n.name.split(" ");if(!t||!o)throw new Error("Event name is invalid");++e.count;const{timestamp:s=Date.now(),group:r=e.group,count:i=e.count}=n,{name:c=`${t} ${o}`,data:a={},context:u={},globals:g=e.globals,custom:l={},user:f=e.user,nested:d=[],consent:m=e.consent,id:p=`${s}-${r}-${i}`,trigger:h="",entity:b=t,action:y=o,timing:w=0,version:v={source:e.version,tagging:e.config.tagging||0},source:k={type:"collector",id:"",previous_id:""}}=n;return{name:c,data:a,context:u,globals:g,custom:l,user:f,nested:d,consent:m,id:p,trigger:h,entity:b,action:y,timestamp:s,timing:w,group:r,count:i,version:v,source:k}}async function B(e,n){e.allowed=!0,e.count=0,e.group=(0,$.getId)(),e.timing=Date.now(),n&&(n.consent&&(e.consent=(0,$.assign)(e.consent,n.consent)),n.user&&(e.user=(0,$.assign)(e.user,n.user)),n.globals&&(e.globals=(0,$.assign)(e.config.globalsStatic||{},n.globals)),n.custom&&(e.custom=(0,$.assign)(e.custom,n.custom))),Object.values(e.destinations).forEach(e=>{e.queue=[]}),e.queue=[],e.round++;const t=await v(e);return P(e,"run"),t}var I=require("@walkeros/core");function M(e,n){return(0,I.useHooks)(async(t,o={})=>await(0,I.tryCatchAsync)(async()=>{const{id:s,ingest:r,mapping:i,preChain:c}=o;let a=t;const u=r?Object.freeze(r):void 0;if(i){const n=await(0,I.processEventMapping)(a,i,e);if(n.ignore)return j({ok:!0});if(i.consent){if(!(0,I.getGrantedConsent)(i.consent,e.consent,n.event.consent))return j({ok:!0})}a=n.event}if(c?.length&&e.transformers&&Object.keys(e.transformers).length>0){const n=await h(e,e.transformers,c,a,u);if(null===n)return j({ok:!0});a=n}const g=n(a),l=F(e,g);return await v(e,l,{id:s,ingest:u})},()=>j({ok:!1}))(),"Push",e.hooks)}var T=require("@walkeros/core");async function G(e){const n=(0,S.assign)({globalsStatic:{},sessionStatic:{},tagging:0,run:!0},e,{merge:!1,extend:!1}),t={level:e.logger?.level,handler:e.logger?.handler},o=(0,S.createLogger)(t),s={...n.globalsStatic,...e.globals},r={allowed:!1,config:n,consent:e.consent||{},count:0,custom:e.custom||{},destinations:{},transformers:{},transformerChain:{pre:[],post:{}},globals:s,group:"",hooks:{},logger:o,on:{},queue:[],round:0,session:void 0,timing:Date.now(),user:e.user||{},version:"0.6.0",sources:{},push:void 0,command:void 0};return r.push=M(r,e=>({timing:Math.round((Date.now()-r.timing)/10)/100,source:{type:"collector",id:"",previous_id:""},...e})),r.command=function(e,n){return(0,T.useHooks)(async(t,o,s)=>await(0,T.tryCatchAsync)(async()=>await n(e,t,o,s),()=>j({ok:!1}))(),"Command",e.hooks)}(r,R),r.destinations=await O(0,e.destinations||{}),r.transformers=await async function(e,n={}){const t={};for(const[o,s]of Object.entries(n)){const{code:n,config:r={},env:i={}}=s,c=e.logger.scope("transformer").scope(o),a={collector:e,logger:c,id:o,config:r,env:i},u=await n(a);t[o]=u}return t}(r,e.transformers||{}),r}var _=require("@walkeros/core");function L(e){const n={};for(const[t,o]of Object.entries(e))n[t]={next:o.config.next};return n}async function U(e,n={}){const t={};for(const[o,s]of Object.entries(n)){const{code:n,config:r={},env:i={},primary:c,next:a}=s;let u;const g=d(a,L(e.transformers)),l=(n,t={})=>e.push(n,{...t,id:o,ingest:u,mapping:r,preChain:g}),f=e.logger.scope("source").scope(o),m={push:l,command:e.command,sources:e.sources,elb:e.sources.elb.push,logger:f,...i},p={collector:e,logger:f,id:o,config:r,env:m,setIngest:async n=>{u=r.ingest?await(0,_.getMappingValue)(n,r.ingest,{collector:e}):void 0}},h=await(0,_.tryCatchAsync)(n)(p);if(!h)continue;const b=h.type||"unknown",y=e.logger.scope(b).scope(o);m.logger=y,c&&(h.config={...h.config,primary:c}),t[o]=h}return t}async function W(e){e=e||{};const n=await G(e),t=(o=n,{type:"elb",config:{},push:async(e,n,t,s,r,i)=>{if("string"==typeof e&&e.startsWith("walker ")){const s=e.replace("walker ","");return o.command(s,n,t)}let c;if("string"==typeof e)c={name:e},n&&"object"==typeof n&&!Array.isArray(n)&&(c.data=n);else{if(!e||"object"!=typeof e)return j({ok:!1});c=e,n&&"object"==typeof n&&!Array.isArray(n)&&(c.data={...c.data||{},...n})}return s&&"object"==typeof s&&(c.context=s),r&&Array.isArray(r)&&(c.nested=r),i&&"object"==typeof i&&(c.custom=i),o.push(c)}});var o;n.sources.elb=t;const s=await U(n,e.sources||{});Object.assign(n.sources,s);const{consent:r,user:i,globals:c,custom:a}=e;r&&await n.command("consent",r),i&&await n.command("user",i),c&&Object.assign(n.globals,c),a&&Object.assign(n.custom,a),n.config.run&&await n.command("run");let u=t.push;const g=Object.values(n.sources).filter(e=>"elb"!==e.type),l=g.find(e=>e.config.primary);return l?u=l.push:g.length>0&&(u=g[0].push),{collector:n,elb:u}}//# sourceMappingURL=index.js.map
1
+ "use strict";var e,n=Object.defineProperty,t=Object.getOwnPropertyDescriptor,o=Object.getOwnPropertyNames,s=Object.prototype.hasOwnProperty,r={};((e,t)=>{for(var o in t)n(e,o,{get:t[o],enumerable:!0})})(r,{Code:()=>i,Commands:()=>c,Const:()=>a,addDestination:()=>w,commonHandleCommand:()=>R,createEvent:()=>F,createPush:()=>M,createPushResult:()=>j,destinationCode:()=>l,destinationInit:()=>k,destinationPush:()=>C,initDestinations:()=>O,initSources:()=>U,mergeEnvironments:()=>q,on:()=>x,onApply:()=>P,pushToDestinations:()=>v,runCollector:()=>B,setConsent:()=>D,startFlow:()=>W}),module.exports=(e=r,((e,r,i,c)=>{if(r&&"object"==typeof r||"function"==typeof r)for(let a of o(r))s.call(e,a)||a===i||n(e,a,{get:()=>r[a],enumerable:!(c=t(r,a))||c.enumerable});return e})(n({},"__esModule",{value:!0}),e));var i={},c={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",User:"user",Walker:"walker"},a={Commands:c,Utils:{Storage:{Cookie:"cookie",Local:"local",Session:"session"}}},u=require("@walkeros/core"),g=require("@walkeros/core"),l={type:"code",config:{},init(e){const{config:n,logger:t}=e,o=n.settings,s=o?.scripts;if(s&&"undefined"!=typeof document)for(const e of s){const n=document.createElement("script");n.src=e,n.async=!0,document.head.appendChild(n)}const r=o?.init;if(r)try{new Function("context",r)(e)}catch(e){t.error("Code destination init error:",e)}},push(e,n){const{rule:t,config:o,logger:s}=n,r=t?.push??o.settings?.push;if(r)try{new Function("event","context",r)(e,n)}catch(e){s.error("Code destination push error:",e)}},pushBatch(e,n){const{rule:t,config:o,logger:s}=n,r=t?.pushBatch??o.settings?.pushBatch;if(r)try{new Function("batch","context",r)(e,n)}catch(e){s.error("Code destination pushBatch error:",e)}},on(e,n){const{config:t,logger:o}=n,s=t.settings?.on;if(s)try{new Function("type","context",s)(e,n)}catch(e){o.error("Code destination on error:",e)}}},f=require("@walkeros/core");function d(e,n={}){if(!e)return[];const t=[],o=new Set;let s=e;for(;s&&n[s]&&!o.has(s);)o.add(s),t.push(s),s=n[s].next;return t}async function m(e,n,t){if(n.init&&!n.config.init){const o=n.type||"unknown",s=e.logger.scope(`transformer:${o}`),r={collector:e,logger:s,id:t,config:n.config,env:b(n.config.env)};s.debug("init");const i=await(0,f.useHooks)(n.init,"TransformerInit",e.hooks)(r);if(!1===i)return!1;n.config={...i||n.config,init:!0},s.debug("init done")}return!0}async function p(e,n,t,o,s){const r=n.type||"unknown",i=e.logger.scope(`transformer:${r}`),c={collector:e,logger:i,id:t,ingest:s,config:n.config,env:b(n.config.env)};i.debug("push",{event:o.name});const a=await(0,f.useHooks)(n.push,"TransformerPush",e.hooks)(o,c);return i.debug("push done"),a}async function h(e,n,t,o,s){let r=o;for(const o of t){const t=n[o];if(!t){e.logger.info(`Transformer not found: ${o}`);continue}if(!await(0,f.tryCatchAsync)(m)(e,t,o))return e.logger.info(`Transformer init failed: ${o}`),null;const i=await(0,f.tryCatchAsync)(p,n=>(e.logger.scope(`transformer:${t.type||"unknown"}`).error("Push failed",{error:n}),!1))(e,t,o,r,s);if(!1===i)return null;void 0!==i&&(r=i)}return r}function b(e){return e&&(0,f.isObject)(e)?e:{}}function y(e){return!0===e?l:e}async function w(e,n,t){const{code:o,config:s={},env:r={}}=n,i=t||s||{init:!1},c=y(o),a={...c,config:i,env:q(c.env,r)};let u=a.config.id;if(!u)do{u=(0,g.getId)(4)}while(e.destinations[u]);return e.destinations[u]=a,!1!==a.config.queue&&(a.queue=[...e.queue]),v(e,void 0,{},{[u]:a})}async function v(e,n,t={},o){const{allowed:s,consent:r,globals:i,user:c}=e;if(!s)return j({ok:!1});n&&e.queue.push(n),o||(o=e.destinations);const a=await Promise.all(Object.entries(o||{}).map(async([o,s])=>{let a=(s.queue||[]).map(e=>({...e,consent:r}));if(s.queue=[],n){const e=(0,g.clone)(n);a.push(e)}if(!a.length)return{id:o,destination:s,skipped:!0};const u=[],l=a.filter(e=>{const n=(0,g.getGrantedConsent)(s.config.consent,r,e.consent);return!n||(e.consent=n,u.push(e),!1)});if(s.queue.concat(l),!u.length)return{id:o,destination:s,queue:a};if(!await(0,g.tryCatchAsync)(k)(e,s,o))return{id:o,destination:s,queue:a};let f,d;s.dlq||(s.dlq=[]);const m=e.transformerChain?.post?.[o]||[];return await Promise.all(u.map(async n=>{n.globals=(0,g.assign)(i,n.globals),n.user=(0,g.assign)(c,n.user);let r=n;if(m.length>0&&e.transformers&&Object.keys(e.transformers).length>0){const o=await h(e,e.transformers,m,n,t.ingest);if(null===o)return n;r=o}const a=await(0,g.tryCatchAsync)(C,n=>{const t=s.type||"unknown";e.logger.scope(t).error("Push failed",{error:n,event:r.name}),f=n,s.dlq.push([r,n])})(e,s,o,r,t.ingest);return void 0!==a&&(d=a),n})),{id:o,destination:s,error:f,response:d}})),u={},l={},f={};for(const e of a){if(e.skipped)continue;const n=e.destination,t={type:n.type||"unknown",data:e.response};e.error?(t.error=e.error,f[e.id]=t):e.queue&&e.queue.length?(n.queue=(n.queue||[]).concat(e.queue),l[e.id]=t):u[e.id]=t}return j({event:n,...Object.keys(u).length&&{done:u},...Object.keys(l).length&&{queued:l},...Object.keys(f).length&&{failed:f}})}async function k(e,n,t){if(n.init&&!n.config.init){const o=n.type||"unknown",s=e.logger.scope(o),r={collector:e,logger:s,id:t,config:n.config,env:q(n.env,n.config.env)};s.debug("init");const i=await(0,g.useHooks)(n.init,"DestinationInit",e.hooks)(r);if(!1===i)return i;n.config={...i||n.config,init:!0},s.debug("init done")}return!0}async function C(e,n,t,o,s){const{config:r}=n,i=await(0,g.processEventMapping)(o,r,e);if(i.ignore)return!1;const c=n.type||"unknown",a=e.logger.scope(c),u={collector:e,logger:a,id:t,config:r,data:i.data,rule:i.mapping,ingest:s,env:q(n.env,r.env)},l=i.mapping,f=i.mappingKey||"* *";if(!l?.batch||!n.pushBatch){a.debug("push",{event:i.event.name});const t=await(0,g.useHooks)(n.push,"DestinationPush",e.hooks)(i.event,u);return a.debug("push done"),t}{if(n.batches=n.batches||{},!n.batches[f]){const o={key:f,events:[],data:[]};n.batches[f]={batched:o,batchFn:(0,g.debounce)(()=>{const o=n.batches[f].batched,i={collector:e,logger:a,id:t,config:r,data:void 0,rule:l,ingest:s,env:q(n.env,r.env)};a.debug("push batch",{events:o.events.length}),(0,g.useHooks)(n.pushBatch,"DestinationPushBatch",e.hooks)(o,i),a.debug("push batch done"),o.events=[],o.data=[]},l.batch)}}const o=n.batches[f];o.batched.events.push(i.event),(0,g.isDefined)(i.data)&&o.batched.data.push(i.data),o.batchFn()}return!0}function j(e){return{ok:!e?.failed,...e}}async function O(e,n={}){const t={};for(const[e,o]of Object.entries(n)){const{code:n,config:s={},env:r={}}=o,i=y(n),c={...i.config,...s},a=q(i.env,r);t[e]={...i,config:c,env:a}}return t}function q(e,n){return e||n?n?e&&(0,g.isObject)(e)&&(0,g.isObject)(n)?{...e,...n}:n:e:{}}var E=require("@walkeros/core"),A=require("@walkeros/core");function x(e,n,t){const o=e.on,s=o[n]||[],r=(0,E.isArray)(t)?t:[t];r.forEach(e=>{s.push(e)}),o[n]=s,P(e,n,r)}function P(e,n,t,o){let s,r=t||[];switch(t||(r=e.on[n]||[]),n){case a.Commands.Consent:s=o||e.consent;break;case a.Commands.Session:s=e.session;break;case a.Commands.Ready:case a.Commands.Run:default:s=void 0}if(Object.values(e.sources).forEach(e=>{e.on&&(0,A.tryCatch)(e.on)(n,s)}),Object.entries(e.destinations).forEach(([t,o])=>{if(o.on){const r=o.type||"unknown",i=e.logger.scope(r).scope("on").scope(n),c={collector:e,logger:i,id:t,config:o.config,data:s,env:q(o.env,o.config.env)};(0,A.tryCatch)(o.on)(n,c)}}),r.length)switch(n){case a.Commands.Consent:!function(e,n,t){const o=t||e.consent;n.forEach(n=>{Object.keys(o).filter(e=>e in n).forEach(t=>{(0,A.tryCatch)(n[t])(e,o)})})}(e,r,o);break;case a.Commands.Ready:case a.Commands.Run:!function(e,n){e.allowed&&n.forEach(n=>{(0,A.tryCatch)(n)(e)})}(e,r);break;case a.Commands.Session:!function(e,n){if(!e.session)return;n.forEach(n=>{(0,A.tryCatch)(n)(e,e.session)})}(e,r)}}async function D(e,n){const{consent:t}=e;let o=!1;const s={};return Object.entries(n).forEach(([e,n])=>{const t=!!n;s[e]=t,o=o||t}),e.consent=(0,u.assign)(t,s),P(e,"consent",void 0,s),o?v(e):j({ok:!0})}var S=require("@walkeros/core"),$=require("@walkeros/core"),H=require("@walkeros/core");async function R(e,n,t,o){let s;switch(n){case a.Commands.Config:(0,H.isObject)(t)&&(0,$.assign)(e.config,t,{shallow:!1});break;case a.Commands.Consent:(0,H.isObject)(t)&&(s=await D(e,t));break;case a.Commands.Custom:(0,H.isObject)(t)&&(e.custom=(0,$.assign)(e.custom,t));break;case a.Commands.Destination:(0,H.isObject)(t)&&(0,$.isFunction)(t.push)&&(s=await w(e,{code:t},o));break;case a.Commands.Globals:(0,H.isObject)(t)&&(e.globals=(0,$.assign)(e.globals,t));break;case a.Commands.On:(0,$.isString)(t)&&x(e,t,o);break;case a.Commands.Ready:P(e,"ready");break;case a.Commands.Run:s=await B(e,t);break;case a.Commands.Session:P(e,"session");break;case a.Commands.User:(0,H.isObject)(t)&&(0,$.assign)(e.user,t,{shallow:!1})}return s||j({ok:!0})}function F(e,n){if(!n.name)throw new Error("Event name is required");const[t,o]=n.name.split(" ");if(!t||!o)throw new Error("Event name is invalid");++e.count;const{timestamp:s=Date.now(),group:r=e.group,count:i=e.count}=n,{name:c=`${t} ${o}`,data:a={},context:u={},globals:g=e.globals,custom:l={},user:f=e.user,nested:d=[],consent:m=e.consent,id:p=`${s}-${r}-${i}`,trigger:h="",entity:b=t,action:y=o,timing:w=0,version:v={source:e.version,tagging:e.config.tagging||0},source:k={type:"collector",id:"",previous_id:""}}=n;return{name:c,data:a,context:u,globals:g,custom:l,user:f,nested:d,consent:m,id:p,trigger:h,entity:b,action:y,timestamp:s,timing:w,group:r,count:i,version:v,source:k}}async function B(e,n){e.allowed=!0,e.count=0,e.group=(0,$.getId)(),e.timing=Date.now(),n&&(n.consent&&(e.consent=(0,$.assign)(e.consent,n.consent)),n.user&&(e.user=(0,$.assign)(e.user,n.user)),n.globals&&(e.globals=(0,$.assign)(e.config.globalsStatic||{},n.globals)),n.custom&&(e.custom=(0,$.assign)(e.custom,n.custom))),Object.values(e.destinations).forEach(e=>{e.queue=[]}),e.queue=[],e.round++;const t=await v(e);return P(e,"run"),t}var I=require("@walkeros/core");function M(e,n){return(0,I.useHooks)(async(t,o={})=>await(0,I.tryCatchAsync)(async()=>{const{id:s,ingest:r,mapping:i,preChain:c}=o;let a=t;const u=r?Object.freeze(r):void 0;if(i){const n=await(0,I.processEventMapping)(a,i,e);if(n.ignore)return j({ok:!0});if(i.consent){if(!(0,I.getGrantedConsent)(i.consent,e.consent,n.event.consent))return j({ok:!0})}a=n.event}if(c?.length&&e.transformers&&Object.keys(e.transformers).length>0){const n=await h(e,e.transformers,c,a,u);if(null===n)return j({ok:!0});a=n}const g=n(a),l=F(e,g);return await v(e,l,{id:s,ingest:u})},()=>j({ok:!1}))(),"Push",e.hooks)}var T=require("@walkeros/core");async function G(e){const n=(0,S.assign)({globalsStatic:{},sessionStatic:{},tagging:0,run:!0},e,{merge:!1,extend:!1}),t={level:e.logger?.level,handler:e.logger?.handler},o=(0,S.createLogger)(t),s={...n.globalsStatic,...e.globals},r={allowed:!1,config:n,consent:e.consent||{},count:0,custom:e.custom||{},destinations:{},transformers:{},transformerChain:{pre:[],post:{}},globals:s,group:"",hooks:{},logger:o,on:{},queue:[],round:0,session:void 0,timing:Date.now(),user:e.user||{},version:"0.9.0",sources:{},push:void 0,command:void 0};return r.push=M(r,e=>({timing:Math.round((Date.now()-r.timing)/10)/100,source:{type:"collector",id:"",previous_id:""},...e})),r.command=function(e,n){return(0,T.useHooks)(async(t,o,s)=>await(0,T.tryCatchAsync)(async()=>await n(e,t,o,s),()=>j({ok:!1}))(),"Command",e.hooks)}(r,R),r.destinations=await O(0,e.destinations||{}),r.transformers=await async function(e,n={}){const t={};for(const[o,s]of Object.entries(n)){const{code:n,config:r={},env:i={}}=s,c=e.logger.scope("transformer").scope(o),a={collector:e,logger:c,id:o,config:r,env:i},u=await n(a);t[o]=u}return t}(r,e.transformers||{}),r}var _=require("@walkeros/core");function L(e){const n={};for(const[t,o]of Object.entries(e))n[t]={next:o.config.next};return n}async function U(e,n={}){const t={};for(const[o,s]of Object.entries(n)){const{code:n,config:r={},env:i={},primary:c,next:a}=s;let u;const g=d(a,L(e.transformers)),l=(n,t={})=>e.push(n,{...t,id:o,ingest:u,mapping:r,preChain:g}),f=e.logger.scope("source").scope(o),m={push:l,command:e.command,sources:e.sources,elb:e.sources.elb.push,logger:f,...i},p={collector:e,logger:f,id:o,config:r,env:m,setIngest:async n=>{u=r.ingest?await(0,_.getMappingValue)(n,r.ingest,{collector:e}):void 0}},h=await(0,_.tryCatchAsync)(n)(p);if(!h)continue;const b=h.type||"unknown",y=e.logger.scope(b).scope(o);m.logger=y,c&&(h.config={...h.config,primary:c}),t[o]=h}return t}async function W(e){e=e||{};const n=await G(e),t=(o=n,{type:"elb",config:{},push:async(e,n,t,s,r,i)=>{if("string"==typeof e&&e.startsWith("walker ")){const s=e.replace("walker ","");return o.command(s,n,t)}let c;if("string"==typeof e)c={name:e},n&&"object"==typeof n&&!Array.isArray(n)&&(c.data=n);else{if(!e||"object"!=typeof e)return j({ok:!1});c=e,n&&"object"==typeof n&&!Array.isArray(n)&&(c.data={...c.data||{},...n})}return s&&"object"==typeof s&&(c.context=s),r&&Array.isArray(r)&&(c.nested=r),i&&"object"==typeof i&&(c.custom=i),o.push(c)}});var o;n.sources.elb=t;const s=await U(n,e.sources||{});Object.assign(n.sources,s);const{consent:r,user:i,globals:c,custom:a}=e;r&&await n.command("consent",r),i&&await n.command("user",i),c&&Object.assign(n.globals,c),a&&Object.assign(n.custom,a),n.config.run&&await n.command("run");let u=t.push;const g=Object.values(n.sources).filter(e=>"elb"!==e.type),l=g.find(e=>e.config.primary);return l?u=l.push:g.length>0&&(u=g[0].push),{collector:n,elb:u}}//# sourceMappingURL=index.js.map
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- var n={},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",User:"user",Walker:"walker"},o={Commands:e,Utils:{Storage:{Cookie:"cookie",Local:"local",Session:"session"}}};import{assign as t}from"@walkeros/core";import{assign as s,clone as r,debounce as c,getId as i,getGrantedConsent as a,isDefined as u,isObject as g,processEventMapping as l,tryCatchAsync as f,useHooks as d}from"@walkeros/core";var m={type:"code",config:{},init(n){const{config:e,logger:o}=n,t=e.settings,s=t?.scripts;if(s&&"undefined"!=typeof document)for(const n of s){const e=document.createElement("script");e.src=n,e.async=!0,document.head.appendChild(e)}const r=t?.init;if(r)try{new Function("context",r)(n)}catch(n){o.error("Code destination init error:",n)}},push(n,e){const{rule:o,config:t,logger:s}=e,r=o?.push??t.settings?.push;if(r)try{new Function("event","context",r)(n,e)}catch(n){s.error("Code destination push error:",n)}},pushBatch(n,e){const{rule:o,config:t,logger:s}=e,r=o?.pushBatch??t.settings?.pushBatch;if(r)try{new Function("batch","context",r)(n,e)}catch(n){s.error("Code destination pushBatch error:",n)}},on(n,e){const{config:o,logger:t}=e,s=o.settings?.on;if(s)try{new Function("type","context",s)(n,e)}catch(n){t.error("Code destination on error:",n)}}};import{isObject as p,tryCatchAsync as h,useHooks as b}from"@walkeros/core";function y(n,e={}){if(!n)return[];const o=[],t=new Set;let s=n;for(;s&&e[s]&&!t.has(s);)t.add(s),o.push(s),s=e[s].next;return o}async function w(n,e,o){if(e.init&&!e.config.init){const t=e.type||"unknown",s=n.logger.scope(`transformer:${t}`),r={collector:n,logger:s,id:o,config:e.config,env:C(e.config.env)};s.debug("init");const c=await b(e.init,"TransformerInit",n.hooks)(r);if(!1===c)return!1;e.config={...c||e.config,init:!0},s.debug("init done")}return!0}async function k(n,e,o,t,s){const r=e.type||"unknown",c=n.logger.scope(`transformer:${r}`),i={collector:n,logger:c,id:o,ingest:s,config:e.config,env:C(e.config.env)};c.debug("push",{event:t.name});const a=await b(e.push,"TransformerPush",n.hooks)(t,i);return c.debug("push done"),a}async function v(n,e,o,t,s){let r=t;for(const t of o){const o=e[t];if(!o){n.logger.info(`Transformer not found: ${t}`);continue}if(!await h(w)(n,o,t))return n.logger.info(`Transformer init failed: ${t}`),null;const c=await h(k,e=>(n.logger.scope(`transformer:${o.type||"unknown"}`).error("Push failed",{error:e}),!1))(n,o,t,r,s);if(!1===c)return null;void 0!==c&&(r=c)}return r}function C(n){return n&&p(n)?n:{}}function j(n){return!0===n?m:n}async function O(n,e,o){const{code:t,config:s={},env:r={}}=e,c=o||s||{init:!1},a=j(t),u={...a,config:c,env:$(a.env,r)};let g=u.config.id;if(!g)do{g=i(4)}while(n.destinations[g]);return n.destinations[g]=u,!1!==u.config.queue&&(u.queue=[...n.queue]),q(n,void 0,{},{[g]:u})}async function q(n,e,o={},t){const{allowed:c,consent:i,globals:u,user:g}=n;if(!c)return A({ok:!1});e&&n.queue.push(e),t||(t=n.destinations);const l=await Promise.all(Object.entries(t||{}).map(async([t,c])=>{let l=(c.queue||[]).map(n=>({...n,consent:i}));if(c.queue=[],e){const n=r(e);l.push(n)}if(!l.length)return{id:t,destination:c,skipped:!0};const d=[],m=l.filter(n=>{const e=a(c.config.consent,i,n.consent);return!e||(n.consent=e,d.push(n),!1)});if(c.queue.concat(m),!d.length)return{id:t,destination:c,queue:l};if(!await f(x)(n,c,t))return{id:t,destination:c,queue:l};let p,h;c.dlq||(c.dlq=[]);const b=n.transformerChain?.post?.[t]||[];return await Promise.all(d.map(async e=>{e.globals=s(u,e.globals),e.user=s(g,e.user);let r=e;if(b.length>0&&n.transformers&&Object.keys(n.transformers).length>0){const t=await v(n,n.transformers,b,e,o.ingest);if(null===t)return e;r=t}const i=await f(E,e=>{const o=c.type||"unknown";n.logger.scope(o).error("Push failed",{error:e,event:r.name}),p=e,c.dlq.push([r,e])})(n,c,t,r,o.ingest);return void 0!==i&&(h=i),e})),{id:t,destination:c,error:p,response:h}})),d={},m={},p={};for(const n of l){if(n.skipped)continue;const e=n.destination,o={type:e.type||"unknown",data:n.response};n.error?(o.error=n.error,p[n.id]=o):n.queue&&n.queue.length?(e.queue=(e.queue||[]).concat(n.queue),m[n.id]=o):d[n.id]=o}return A({event:e,...Object.keys(d).length&&{done:d},...Object.keys(m).length&&{queued:m},...Object.keys(p).length&&{failed:p}})}async function x(n,e,o){if(e.init&&!e.config.init){const t=e.type||"unknown",s=n.logger.scope(t),r={collector:n,logger:s,id:o,config:e.config,env:$(e.env,e.config.env)};s.debug("init");const c=await d(e.init,"DestinationInit",n.hooks)(r);if(!1===c)return c;e.config={...c||e.config,init:!0},s.debug("init done")}return!0}async function E(n,e,o,t,s){const{config:r}=e,i=await l(t,r,n);if(i.ignore)return!1;const a=e.type||"unknown",g=n.logger.scope(a),f={collector:n,logger:g,id:o,config:r,data:i.data,rule:i.mapping,ingest:s,env:$(e.env,r.env)},m=i.mapping,p=i.mappingKey||"* *";if(!m?.batch||!e.pushBatch){g.debug("push",{event:i.event.name});const o=await d(e.push,"DestinationPush",n.hooks)(i.event,f);return g.debug("push done"),o}{if(e.batches=e.batches||{},!e.batches[p]){const t={key:p,events:[],data:[]};e.batches[p]={batched:t,batchFn:c(()=>{const t=e.batches[p].batched,c={collector:n,logger:g,id:o,config:r,data:void 0,rule:m,ingest:s,env:$(e.env,r.env)};g.debug("push batch",{events:t.events.length}),d(e.pushBatch,"DestinationPushBatch",n.hooks)(t,c),g.debug("push batch done"),t.events=[],t.data=[]},m.batch)}}const t=e.batches[p];t.batched.events.push(i.event),u(i.data)&&t.batched.data.push(i.data),t.batchFn()}return!0}function A(n){return{ok:!n?.failed,...n}}async function S(n,e={}){const o={};for(const[n,t]of Object.entries(e)){const{code:e,config:s={},env:r={}}=t,c=j(e),i={...c.config,...s},a=$(c.env,r);o[n]={...c,config:i,env:a}}return o}function $(n,e){return n||e?e?n&&g(n)&&g(e)?{...n,...e}:e:n:{}}import{isArray as D}from"@walkeros/core";import{tryCatch as P}from"@walkeros/core";function R(n,e,o){const t=n.on,s=t[e]||[],r=D(o)?o:[o];r.forEach(n=>{s.push(n)}),t[e]=s,B(n,e,r)}function B(n,e,t,s){let r,c=t||[];switch(t||(c=n.on[e]||[]),e){case o.Commands.Consent:r=s||n.consent;break;case o.Commands.Session:r=n.session;break;case o.Commands.Ready:case o.Commands.Run:default:r=void 0}if(Object.values(n.sources).forEach(n=>{n.on&&P(n.on)(e,r)}),Object.entries(n.destinations).forEach(([o,t])=>{if(t.on){const s=t.type||"unknown",c=n.logger.scope(s).scope("on").scope(e),i={collector:n,logger:c,id:o,config:t.config,data:r,env:$(t.env,t.config.env)};P(t.on)(e,i)}}),c.length)switch(e){case o.Commands.Consent:!function(n,e,o){const t=o||n.consent;e.forEach(e=>{Object.keys(t).filter(n=>n in e).forEach(o=>{P(e[o])(n,t)})})}(n,c,s);break;case o.Commands.Ready:case o.Commands.Run:!function(n,e){n.allowed&&e.forEach(e=>{P(e)(n)})}(n,c);break;case o.Commands.Session:!function(n,e){if(!n.session)return;e.forEach(e=>{P(e)(n,n.session)})}(n,c)}}async function F(n,e){const{consent:o}=n;let s=!1;const r={};return Object.entries(e).forEach(([n,e])=>{const o=!!e;r[n]=o,s=s||o}),n.consent=t(o,r),B(n,"consent",void 0,r),s?q(n):A({ok:!0})}import{assign as I,createLogger as H}from"@walkeros/core";import{assign as T,getId as G,isFunction as U,isString as L}from"@walkeros/core";import{isObject as M}from"@walkeros/core";async function W(n,e,t,s){let r;switch(e){case o.Commands.Config:M(t)&&T(n.config,t,{shallow:!1});break;case o.Commands.Consent:M(t)&&(r=await F(n,t));break;case o.Commands.Custom:M(t)&&(n.custom=T(n.custom,t));break;case o.Commands.Destination:M(t)&&U(t.push)&&(r=await O(n,{code:t},s));break;case o.Commands.Globals:M(t)&&(n.globals=T(n.globals,t));break;case o.Commands.On:L(t)&&R(n,t,s);break;case o.Commands.Ready:B(n,"ready");break;case o.Commands.Run:r=await z(n,t);break;case o.Commands.Session:B(n,"session");break;case o.Commands.User:M(t)&&T(n.user,t,{shallow:!1})}return r||A({ok:!0})}function _(n,e){if(!e.name)throw new Error("Event name is required");const[o,t]=e.name.split(" ");if(!o||!t)throw new Error("Event name is invalid");++n.count;const{timestamp:s=Date.now(),group:r=n.group,count:c=n.count}=e,{name:i=`${o} ${t}`,data:a={},context:u={},globals:g=n.globals,custom:l={},user:f=n.user,nested:d=[],consent:m=n.consent,id:p=`${s}-${r}-${c}`,trigger:h="",entity:b=o,action:y=t,timing:w=0,version:k={source:n.version,tagging:n.config.tagging||0},source:v={type:"collector",id:"",previous_id:""}}=e;return{name:i,data:a,context:u,globals:g,custom:l,user:f,nested:d,consent:m,id:p,trigger:h,entity:b,action:y,timestamp:s,timing:w,group:r,count:c,version:k,source:v}}async function z(n,e){n.allowed=!0,n.count=0,n.group=G(),n.timing=Date.now(),e&&(e.consent&&(n.consent=T(n.consent,e.consent)),e.user&&(n.user=T(n.user,e.user)),e.globals&&(n.globals=T(n.config.globalsStatic||{},e.globals)),e.custom&&(n.custom=T(n.custom,e.custom))),Object.values(n.destinations).forEach(n=>{n.queue=[]}),n.queue=[],n.round++;const o=await q(n);return B(n,"run"),o}import{getGrantedConsent as K,processEventMapping as J,tryCatchAsync as N,useHooks as Q}from"@walkeros/core";function V(n,e){return Q(async(o,t={})=>await N(async()=>{const{id:s,ingest:r,mapping:c,preChain:i}=t;let a=o;const u=r?Object.freeze(r):void 0;if(c){const e=await J(a,c,n);if(e.ignore)return A({ok:!0});if(c.consent){if(!K(c.consent,n.consent,e.event.consent))return A({ok:!0})}a=e.event}if(i?.length&&n.transformers&&Object.keys(n.transformers).length>0){const e=await v(n,n.transformers,i,a,u);if(null===e)return A({ok:!0});a=e}const g=e(a),l=_(n,g);return await q(n,l,{id:s,ingest:u})},()=>A({ok:!1}))(),"Push",n.hooks)}import{useHooks as X,tryCatchAsync as Y}from"@walkeros/core";async function Z(n){const e=I({globalsStatic:{},sessionStatic:{},tagging:0,run:!0},n,{merge:!1,extend:!1}),o={level:n.logger?.level,handler:n.logger?.handler},t=H(o),s={...e.globalsStatic,...n.globals},r={allowed:!1,config:e,consent:n.consent||{},count:0,custom:n.custom||{},destinations:{},transformers:{},transformerChain:{pre:[],post:{}},globals:s,group:"",hooks:{},logger:t,on:{},queue:[],round:0,session:void 0,timing:Date.now(),user:n.user||{},version:"0.6.0",sources:{},push:void 0,command:void 0};return r.push=V(r,n=>({timing:Math.round((Date.now()-r.timing)/10)/100,source:{type:"collector",id:"",previous_id:""},...n})),r.command=function(n,e){return X(async(o,t,s)=>await Y(async()=>await e(n,o,t,s),()=>A({ok:!1}))(),"Command",n.hooks)}(r,W),r.destinations=await S(0,n.destinations||{}),r.transformers=await async function(n,e={}){const o={};for(const[t,s]of Object.entries(e)){const{code:e,config:r={},env:c={}}=s,i=n.logger.scope("transformer").scope(t),a={collector:n,logger:i,id:t,config:r,env:c},u=await e(a);o[t]=u}return o}(r,n.transformers||{}),r}import{getMappingValue as nn,tryCatchAsync as en}from"@walkeros/core";function on(n){const e={};for(const[o,t]of Object.entries(n))e[o]={next:t.config.next};return e}async function tn(n,e={}){const o={};for(const[t,s]of Object.entries(e)){const{code:e,config:r={},env:c={},primary:i,next:a}=s;let u;const g=y(a,on(n.transformers)),l=(e,o={})=>n.push(e,{...o,id:t,ingest:u,mapping:r,preChain:g}),f=n.logger.scope("source").scope(t),d={push:l,command:n.command,sources:n.sources,elb:n.sources.elb.push,logger:f,...c},m={collector:n,logger:f,id:t,config:r,env:d,setIngest:async e=>{u=r.ingest?await nn(e,r.ingest,{collector:n}):void 0}},p=await en(e)(m);if(!p)continue;const h=p.type||"unknown",b=n.logger.scope(h).scope(t);d.logger=b,i&&(p.config={...p.config,primary:i}),o[t]=p}return o}async function sn(n){n=n||{};const e=await Z(n),o=(t=e,{type:"elb",config:{},push:async(n,e,o,s,r,c)=>{if("string"==typeof n&&n.startsWith("walker ")){const s=n.replace("walker ","");return t.command(s,e,o)}let i;if("string"==typeof n)i={name:n},e&&"object"==typeof e&&!Array.isArray(e)&&(i.data=e);else{if(!n||"object"!=typeof n)return A({ok:!1});i=n,e&&"object"==typeof e&&!Array.isArray(e)&&(i.data={...i.data||{},...e})}return s&&"object"==typeof s&&(i.context=s),r&&Array.isArray(r)&&(i.nested=r),c&&"object"==typeof c&&(i.custom=c),t.push(i)}});var t;e.sources.elb=o;const s=await tn(e,n.sources||{});Object.assign(e.sources,s);const{consent:r,user:c,globals:i,custom:a}=n;r&&await e.command("consent",r),c&&await e.command("user",c),i&&Object.assign(e.globals,i),a&&Object.assign(e.custom,a),e.config.run&&await e.command("run");let u=o.push;const g=Object.values(e.sources).filter(n=>"elb"!==n.type),l=g.find(n=>n.config.primary);return l?u=l.push:g.length>0&&(u=g[0].push),{collector:e,elb:u}}export{n as Code,e as Commands,o as Const,O as addDestination,W as commonHandleCommand,_ as createEvent,V as createPush,A as createPushResult,m as destinationCode,x as destinationInit,E as destinationPush,S as initDestinations,tn as initSources,$ as mergeEnvironments,R as on,B as onApply,q as pushToDestinations,z as runCollector,F as setConsent,sn as startFlow};//# sourceMappingURL=index.mjs.map
1
+ var n={},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",User:"user",Walker:"walker"},o={Commands:e,Utils:{Storage:{Cookie:"cookie",Local:"local",Session:"session"}}};import{assign as t}from"@walkeros/core";import{assign as s,clone as r,debounce as c,getId as i,getGrantedConsent as a,isDefined as u,isObject as g,processEventMapping as l,tryCatchAsync as f,useHooks as d}from"@walkeros/core";var m={type:"code",config:{},init(n){const{config:e,logger:o}=n,t=e.settings,s=t?.scripts;if(s&&"undefined"!=typeof document)for(const n of s){const e=document.createElement("script");e.src=n,e.async=!0,document.head.appendChild(e)}const r=t?.init;if(r)try{new Function("context",r)(n)}catch(n){o.error("Code destination init error:",n)}},push(n,e){const{rule:o,config:t,logger:s}=e,r=o?.push??t.settings?.push;if(r)try{new Function("event","context",r)(n,e)}catch(n){s.error("Code destination push error:",n)}},pushBatch(n,e){const{rule:o,config:t,logger:s}=e,r=o?.pushBatch??t.settings?.pushBatch;if(r)try{new Function("batch","context",r)(n,e)}catch(n){s.error("Code destination pushBatch error:",n)}},on(n,e){const{config:o,logger:t}=e,s=o.settings?.on;if(s)try{new Function("type","context",s)(n,e)}catch(n){t.error("Code destination on error:",n)}}};import{isObject as p,tryCatchAsync as h,useHooks as b}from"@walkeros/core";function y(n,e={}){if(!n)return[];const o=[],t=new Set;let s=n;for(;s&&e[s]&&!t.has(s);)t.add(s),o.push(s),s=e[s].next;return o}async function w(n,e,o){if(e.init&&!e.config.init){const t=e.type||"unknown",s=n.logger.scope(`transformer:${t}`),r={collector:n,logger:s,id:o,config:e.config,env:C(e.config.env)};s.debug("init");const c=await b(e.init,"TransformerInit",n.hooks)(r);if(!1===c)return!1;e.config={...c||e.config,init:!0},s.debug("init done")}return!0}async function k(n,e,o,t,s){const r=e.type||"unknown",c=n.logger.scope(`transformer:${r}`),i={collector:n,logger:c,id:o,ingest:s,config:e.config,env:C(e.config.env)};c.debug("push",{event:t.name});const a=await b(e.push,"TransformerPush",n.hooks)(t,i);return c.debug("push done"),a}async function v(n,e,o,t,s){let r=t;for(const t of o){const o=e[t];if(!o){n.logger.info(`Transformer not found: ${t}`);continue}if(!await h(w)(n,o,t))return n.logger.info(`Transformer init failed: ${t}`),null;const c=await h(k,e=>(n.logger.scope(`transformer:${o.type||"unknown"}`).error("Push failed",{error:e}),!1))(n,o,t,r,s);if(!1===c)return null;void 0!==c&&(r=c)}return r}function C(n){return n&&p(n)?n:{}}function j(n){return!0===n?m:n}async function O(n,e,o){const{code:t,config:s={},env:r={}}=e,c=o||s||{init:!1},a=j(t),u={...a,config:c,env:$(a.env,r)};let g=u.config.id;if(!g)do{g=i(4)}while(n.destinations[g]);return n.destinations[g]=u,!1!==u.config.queue&&(u.queue=[...n.queue]),q(n,void 0,{},{[g]:u})}async function q(n,e,o={},t){const{allowed:c,consent:i,globals:u,user:g}=n;if(!c)return A({ok:!1});e&&n.queue.push(e),t||(t=n.destinations);const l=await Promise.all(Object.entries(t||{}).map(async([t,c])=>{let l=(c.queue||[]).map(n=>({...n,consent:i}));if(c.queue=[],e){const n=r(e);l.push(n)}if(!l.length)return{id:t,destination:c,skipped:!0};const d=[],m=l.filter(n=>{const e=a(c.config.consent,i,n.consent);return!e||(n.consent=e,d.push(n),!1)});if(c.queue.concat(m),!d.length)return{id:t,destination:c,queue:l};if(!await f(x)(n,c,t))return{id:t,destination:c,queue:l};let p,h;c.dlq||(c.dlq=[]);const b=n.transformerChain?.post?.[t]||[];return await Promise.all(d.map(async e=>{e.globals=s(u,e.globals),e.user=s(g,e.user);let r=e;if(b.length>0&&n.transformers&&Object.keys(n.transformers).length>0){const t=await v(n,n.transformers,b,e,o.ingest);if(null===t)return e;r=t}const i=await f(E,e=>{const o=c.type||"unknown";n.logger.scope(o).error("Push failed",{error:e,event:r.name}),p=e,c.dlq.push([r,e])})(n,c,t,r,o.ingest);return void 0!==i&&(h=i),e})),{id:t,destination:c,error:p,response:h}})),d={},m={},p={};for(const n of l){if(n.skipped)continue;const e=n.destination,o={type:e.type||"unknown",data:n.response};n.error?(o.error=n.error,p[n.id]=o):n.queue&&n.queue.length?(e.queue=(e.queue||[]).concat(n.queue),m[n.id]=o):d[n.id]=o}return A({event:e,...Object.keys(d).length&&{done:d},...Object.keys(m).length&&{queued:m},...Object.keys(p).length&&{failed:p}})}async function x(n,e,o){if(e.init&&!e.config.init){const t=e.type||"unknown",s=n.logger.scope(t),r={collector:n,logger:s,id:o,config:e.config,env:$(e.env,e.config.env)};s.debug("init");const c=await d(e.init,"DestinationInit",n.hooks)(r);if(!1===c)return c;e.config={...c||e.config,init:!0},s.debug("init done")}return!0}async function E(n,e,o,t,s){const{config:r}=e,i=await l(t,r,n);if(i.ignore)return!1;const a=e.type||"unknown",g=n.logger.scope(a),f={collector:n,logger:g,id:o,config:r,data:i.data,rule:i.mapping,ingest:s,env:$(e.env,r.env)},m=i.mapping,p=i.mappingKey||"* *";if(!m?.batch||!e.pushBatch){g.debug("push",{event:i.event.name});const o=await d(e.push,"DestinationPush",n.hooks)(i.event,f);return g.debug("push done"),o}{if(e.batches=e.batches||{},!e.batches[p]){const t={key:p,events:[],data:[]};e.batches[p]={batched:t,batchFn:c(()=>{const t=e.batches[p].batched,c={collector:n,logger:g,id:o,config:r,data:void 0,rule:m,ingest:s,env:$(e.env,r.env)};g.debug("push batch",{events:t.events.length}),d(e.pushBatch,"DestinationPushBatch",n.hooks)(t,c),g.debug("push batch done"),t.events=[],t.data=[]},m.batch)}}const t=e.batches[p];t.batched.events.push(i.event),u(i.data)&&t.batched.data.push(i.data),t.batchFn()}return!0}function A(n){return{ok:!n?.failed,...n}}async function S(n,e={}){const o={};for(const[n,t]of Object.entries(e)){const{code:e,config:s={},env:r={}}=t,c=j(e),i={...c.config,...s},a=$(c.env,r);o[n]={...c,config:i,env:a}}return o}function $(n,e){return n||e?e?n&&g(n)&&g(e)?{...n,...e}:e:n:{}}import{isArray as D}from"@walkeros/core";import{tryCatch as P}from"@walkeros/core";function R(n,e,o){const t=n.on,s=t[e]||[],r=D(o)?o:[o];r.forEach(n=>{s.push(n)}),t[e]=s,B(n,e,r)}function B(n,e,t,s){let r,c=t||[];switch(t||(c=n.on[e]||[]),e){case o.Commands.Consent:r=s||n.consent;break;case o.Commands.Session:r=n.session;break;case o.Commands.Ready:case o.Commands.Run:default:r=void 0}if(Object.values(n.sources).forEach(n=>{n.on&&P(n.on)(e,r)}),Object.entries(n.destinations).forEach(([o,t])=>{if(t.on){const s=t.type||"unknown",c=n.logger.scope(s).scope("on").scope(e),i={collector:n,logger:c,id:o,config:t.config,data:r,env:$(t.env,t.config.env)};P(t.on)(e,i)}}),c.length)switch(e){case o.Commands.Consent:!function(n,e,o){const t=o||n.consent;e.forEach(e=>{Object.keys(t).filter(n=>n in e).forEach(o=>{P(e[o])(n,t)})})}(n,c,s);break;case o.Commands.Ready:case o.Commands.Run:!function(n,e){n.allowed&&e.forEach(e=>{P(e)(n)})}(n,c);break;case o.Commands.Session:!function(n,e){if(!n.session)return;e.forEach(e=>{P(e)(n,n.session)})}(n,c)}}async function F(n,e){const{consent:o}=n;let s=!1;const r={};return Object.entries(e).forEach(([n,e])=>{const o=!!e;r[n]=o,s=s||o}),n.consent=t(o,r),B(n,"consent",void 0,r),s?q(n):A({ok:!0})}import{assign as I,createLogger as H}from"@walkeros/core";import{assign as T,getId as G,isFunction as U,isString as L}from"@walkeros/core";import{isObject as M}from"@walkeros/core";async function W(n,e,t,s){let r;switch(e){case o.Commands.Config:M(t)&&T(n.config,t,{shallow:!1});break;case o.Commands.Consent:M(t)&&(r=await F(n,t));break;case o.Commands.Custom:M(t)&&(n.custom=T(n.custom,t));break;case o.Commands.Destination:M(t)&&U(t.push)&&(r=await O(n,{code:t},s));break;case o.Commands.Globals:M(t)&&(n.globals=T(n.globals,t));break;case o.Commands.On:L(t)&&R(n,t,s);break;case o.Commands.Ready:B(n,"ready");break;case o.Commands.Run:r=await z(n,t);break;case o.Commands.Session:B(n,"session");break;case o.Commands.User:M(t)&&T(n.user,t,{shallow:!1})}return r||A({ok:!0})}function _(n,e){if(!e.name)throw new Error("Event name is required");const[o,t]=e.name.split(" ");if(!o||!t)throw new Error("Event name is invalid");++n.count;const{timestamp:s=Date.now(),group:r=n.group,count:c=n.count}=e,{name:i=`${o} ${t}`,data:a={},context:u={},globals:g=n.globals,custom:l={},user:f=n.user,nested:d=[],consent:m=n.consent,id:p=`${s}-${r}-${c}`,trigger:h="",entity:b=o,action:y=t,timing:w=0,version:k={source:n.version,tagging:n.config.tagging||0},source:v={type:"collector",id:"",previous_id:""}}=e;return{name:i,data:a,context:u,globals:g,custom:l,user:f,nested:d,consent:m,id:p,trigger:h,entity:b,action:y,timestamp:s,timing:w,group:r,count:c,version:k,source:v}}async function z(n,e){n.allowed=!0,n.count=0,n.group=G(),n.timing=Date.now(),e&&(e.consent&&(n.consent=T(n.consent,e.consent)),e.user&&(n.user=T(n.user,e.user)),e.globals&&(n.globals=T(n.config.globalsStatic||{},e.globals)),e.custom&&(n.custom=T(n.custom,e.custom))),Object.values(n.destinations).forEach(n=>{n.queue=[]}),n.queue=[],n.round++;const o=await q(n);return B(n,"run"),o}import{getGrantedConsent as K,processEventMapping as J,tryCatchAsync as N,useHooks as Q}from"@walkeros/core";function V(n,e){return Q(async(o,t={})=>await N(async()=>{const{id:s,ingest:r,mapping:c,preChain:i}=t;let a=o;const u=r?Object.freeze(r):void 0;if(c){const e=await J(a,c,n);if(e.ignore)return A({ok:!0});if(c.consent){if(!K(c.consent,n.consent,e.event.consent))return A({ok:!0})}a=e.event}if(i?.length&&n.transformers&&Object.keys(n.transformers).length>0){const e=await v(n,n.transformers,i,a,u);if(null===e)return A({ok:!0});a=e}const g=e(a),l=_(n,g);return await q(n,l,{id:s,ingest:u})},()=>A({ok:!1}))(),"Push",n.hooks)}import{useHooks as X,tryCatchAsync as Y}from"@walkeros/core";async function Z(n){const e=I({globalsStatic:{},sessionStatic:{},tagging:0,run:!0},n,{merge:!1,extend:!1}),o={level:n.logger?.level,handler:n.logger?.handler},t=H(o),s={...e.globalsStatic,...n.globals},r={allowed:!1,config:e,consent:n.consent||{},count:0,custom:n.custom||{},destinations:{},transformers:{},transformerChain:{pre:[],post:{}},globals:s,group:"",hooks:{},logger:t,on:{},queue:[],round:0,session:void 0,timing:Date.now(),user:n.user||{},version:"0.9.0",sources:{},push:void 0,command:void 0};return r.push=V(r,n=>({timing:Math.round((Date.now()-r.timing)/10)/100,source:{type:"collector",id:"",previous_id:""},...n})),r.command=function(n,e){return X(async(o,t,s)=>await Y(async()=>await e(n,o,t,s),()=>A({ok:!1}))(),"Command",n.hooks)}(r,W),r.destinations=await S(0,n.destinations||{}),r.transformers=await async function(n,e={}){const o={};for(const[t,s]of Object.entries(e)){const{code:e,config:r={},env:c={}}=s,i=n.logger.scope("transformer").scope(t),a={collector:n,logger:i,id:t,config:r,env:c},u=await e(a);o[t]=u}return o}(r,n.transformers||{}),r}import{getMappingValue as nn,tryCatchAsync as en}from"@walkeros/core";function on(n){const e={};for(const[o,t]of Object.entries(n))e[o]={next:t.config.next};return e}async function tn(n,e={}){const o={};for(const[t,s]of Object.entries(e)){const{code:e,config:r={},env:c={},primary:i,next:a}=s;let u;const g=y(a,on(n.transformers)),l=(e,o={})=>n.push(e,{...o,id:t,ingest:u,mapping:r,preChain:g}),f=n.logger.scope("source").scope(t),d={push:l,command:n.command,sources:n.sources,elb:n.sources.elb.push,logger:f,...c},m={collector:n,logger:f,id:t,config:r,env:d,setIngest:async e=>{u=r.ingest?await nn(e,r.ingest,{collector:n}):void 0}},p=await en(e)(m);if(!p)continue;const h=p.type||"unknown",b=n.logger.scope(h).scope(t);d.logger=b,i&&(p.config={...p.config,primary:i}),o[t]=p}return o}async function sn(n){n=n||{};const e=await Z(n),o=(t=e,{type:"elb",config:{},push:async(n,e,o,s,r,c)=>{if("string"==typeof n&&n.startsWith("walker ")){const s=n.replace("walker ","");return t.command(s,e,o)}let i;if("string"==typeof n)i={name:n},e&&"object"==typeof e&&!Array.isArray(e)&&(i.data=e);else{if(!n||"object"!=typeof n)return A({ok:!1});i=n,e&&"object"==typeof e&&!Array.isArray(e)&&(i.data={...i.data||{},...e})}return s&&"object"==typeof s&&(i.context=s),r&&Array.isArray(r)&&(i.nested=r),c&&"object"==typeof c&&(i.custom=c),t.push(i)}});var t;e.sources.elb=o;const s=await tn(e,n.sources||{});Object.assign(e.sources,s);const{consent:r,user:c,globals:i,custom:a}=n;r&&await e.command("consent",r),c&&await e.command("user",c),i&&Object.assign(e.globals,i),a&&Object.assign(e.custom,a),e.config.run&&await e.command("run");let u=o.push;const g=Object.values(e.sources).filter(n=>"elb"!==n.type),l=g.find(n=>n.config.primary);return l?u=l.push:g.length>0&&(u=g[0].push),{collector:e,elb:u}}export{n as Code,e as Commands,o as Const,O as addDestination,W as commonHandleCommand,_ as createEvent,V as createPush,A as createPushResult,m as destinationCode,x as destinationInit,E as destinationPush,S as initDestinations,tn as initSources,$ as mergeEnvironments,R as on,B as onApply,q as pushToDestinations,z as runCollector,F as setConsent,sn as startFlow};//# sourceMappingURL=index.mjs.map
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@walkeros/collector",
3
3
  "description": "Unified platform-agnostic collector for walkerOS",
4
- "version": "0.7.0",
4
+ "version": "1.0.0",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
7
7
  "types": "./dist/index.d.ts",
@@ -30,7 +30,7 @@
30
30
  "update": "npx npm-check-updates -u && npm update"
31
31
  },
32
32
  "dependencies": {
33
- "@walkeros/core": "0.7.0"
33
+ "@walkeros/core": "1.0.0"
34
34
  },
35
35
  "devDependencies": {},
36
36
  "repository": {