@walkeros/web-source-datalayer 4.5.0 → 4.5.1-next-1788726985928
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 +13 -0
- package/dist/dev.js +1 -1
- package/dist/dev.js.map +1 -1
- package/dist/dev.mjs +1 -1
- package/dist/dev.mjs.map +1 -1
- package/dist/examples/index.js +10 -5
- package/dist/examples/index.mjs +10 -5
- package/dist/index.browser.js +1 -1
- package/dist/index.es5.js +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/walkerOS.json +22 -2
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# @walkeros/web-source-datalayer
|
|
2
2
|
|
|
3
|
+
## 4.5.1-next-1788726985928
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 403ff6c: The dataLayer source now stamps every event it captures with its own
|
|
8
|
+
identity, so events arrive carrying `source.type: 'dataLayer'` and
|
|
9
|
+
`source.platform: 'web'` instead of defaulting to the collector. Destinations
|
|
10
|
+
that echo events back into the dataLayer can now guard against feedback loops,
|
|
11
|
+
and mappings can tell dataLayer-captured events apart.
|
|
12
|
+
- Updated dependencies [8802281]
|
|
13
|
+
- @walkeros/collector@4.5.1-next-1788726985928
|
|
14
|
+
- @walkeros/core@4.5.1-next-1788726985928
|
|
15
|
+
|
|
3
16
|
## 4.5.0
|
|
4
17
|
|
|
5
18
|
### Patch Changes
|
package/dist/dev.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var e,t=Object.defineProperty,a=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.prototype.hasOwnProperty,n=(e,a)=>{for(var r in a)t(e,r,{get:a[r],enumerable:!0})},o={};n(o,{examples:()=>
|
|
1
|
+
"use strict";var e,t=Object.defineProperty,a=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.prototype.hasOwnProperty,n=(e,a)=>{for(var r in a)t(e,r,{get:a[r],enumerable:!0})},o={};n(o,{examples:()=>_,schemas:()=>d}),module.exports=(e=o,((e,n,o,d)=>{if(n&&"object"==typeof n||"function"==typeof n)for(let s of r(n))i.call(e,s)||s===o||t(e,s,{get:()=>n[s],enumerable:!(d=a(n,s))||d.enumerable});return e})(t({},"__esModule",{value:!0}),e));var d={};n(d,{EventPrefix:()=>g,JavaScriptVarName:()=>u,MappingSchema:()=>y,SettingsSchema:()=>p,mapping:()=>w,settings:()=>v});var s=require("@walkeros/core/dev"),c=require("@walkeros/core/dev"),l=require("@walkeros/core/dev"),u=l.z.string().min(1).regex(/^[a-zA-Z_$][a-zA-Z0-9_$]*$/,"Must be a valid JavaScript identifier").describe("JavaScript variable name"),g=l.z.string().min(1).describe("Prefix for filtering dataLayer events"),p=c.z.object({name:u.default("dataLayer").describe("DataLayer variable name (default: dataLayer)").optional(),prefix:g.default("dataLayer").describe("Event prefix for filtering which events to process").optional(),filter:c.z.any().describe("Custom filter function: (event: unknown) => boolean | Promise<boolean>").optional()}),m=require("@walkeros/core/dev"),y=m.z.object({command:m.z.unknown().describe("Mapping.Value evaluated against the raw dataLayer arguments to build walker command data (e.g. consent updates).").optional()}),v=(0,s.zodToSchema)(p),w=(0,s.zodToSchema)(y),_={};n(_,{createTrigger:()=>P,env:()=>b,step:()=>k,trigger:()=>A});var b={};n(b,{push:()=>S});var f=()=>{},h=()=>()=>Promise.resolve({ok:!0}),L={error:f,warn:f,info:f,debug:f,throw:e=>{throw"string"==typeof e?new Error(e):e},json:f,scope:()=>L},S={get push(){return h()},get command(){return h()},get elb(){return h()},get window(){return{dataLayer:[],addEventListener:f,removeEventListener:f}},logger:L},k={};n(k,{consentUpdate:()=>E,directEvent:()=>T,gtagAddToCart:()=>j,gtagPurchase:()=>U,gtagViewItem:()=>z});var U={title:"gtag purchase",description:"A gtag purchase call pushed to the dataLayer is captured as a walker dataLayer purchase event with item details.",trigger:{type:"gtag"},in:["event","purchase",{transaction_id:"T-12345",value:25.42,currency:"EUR",items:[{item_id:"SKU-1",item_name:"T-Shirt",quantity:1}]}],out:[["elb",{name:"dataLayer purchase",data:{transaction_id:"T-12345",value:25.42,currency:"EUR",items:[{item_id:"SKU-1",item_name:"T-Shirt",quantity:1}]},source:{type:"dataLayer",platform:"web"}}]]},E={title:"Consent update",description:"A gtag consent update is captured from the dataLayer as a walker dataLayer consent update event.",trigger:{type:"gtag"},in:["consent","update",{ad_storage:"granted",analytics_storage:"granted"}],out:[["elb",{name:"dataLayer consent update",data:{ad_storage:"granted",analytics_storage:"granted"},source:{type:"dataLayer",platform:"web"}}]]},j={title:"gtag add_to_cart",description:"A gtag add_to_cart call pushed to the dataLayer is captured as a walker dataLayer add_to_cart event.",trigger:{type:"gtag"},in:["event","add_to_cart",{currency:"EUR",value:15.25,items:[{item_id:"SKU_12345",item_name:"T-Shirt",item_variant:"red",quantity:1,price:15.25}]}],out:[["elb",{name:"dataLayer add_to_cart",data:{currency:"EUR",value:15.25,items:[{item_id:"SKU_12345",item_name:"T-Shirt",item_variant:"red",quantity:1,price:15.25}]},source:{type:"dataLayer",platform:"web"}}]]},z={title:"gtag view_item",description:"A gtag view_item call pushed to the dataLayer is captured as a walker dataLayer view_item event with item data.",trigger:{type:"gtag"},in:["event","view_item",{currency:"EUR",value:29.99,items:[{item_id:"SKU_67890",item_name:"Sneakers",item_category:"Footwear",price:29.99}]}],out:[["elb",{name:"dataLayer view_item",data:{currency:"EUR",value:29.99,items:[{item_id:"SKU_67890",item_name:"Sneakers",item_category:"Footwear",price:29.99}]},source:{type:"dataLayer",platform:"web"}}]]},T={title:"Direct dataLayer event",description:"A plain object pushed directly onto the dataLayer is captured as a walker dataLayer custom event.",trigger:{type:"direct"},in:{event:"custom_event",category:"engagement",label:"video_play"},out:[["elb",{name:"dataLayer custom_event",data:{category:"engagement",label:"video_play"},source:{type:"dataLayer",platform:"web"}}]]},q=require("@walkeros/collector"),P=async e=>{let t;return{get flow(){return t},trigger:()=>async a=>{var r,i;if(!t){const a={...e};if(a.sources){a.sources={...a.sources};for(const[e,t]of Object.entries(a.sources))(null==(r=t.env)?void 0:r.window)||(a.sources[e]={...t,env:{...t.env,window:window}})}const n=await(0,q.startFlow)({...a,run:null==(i=a.run)||i});t={collector:n.collector,elb:n.elb}}const n=window;n.dataLayer||(n.dataLayer=[]),n.dataLayer.push(a)}}},A=(e,t)=>{const a=t.window;a.dataLayer||(a.dataLayer=[]),a.dataLayer.push(e)};//# 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/schemas/primitives.ts","../src/schemas/mapping.ts","../src/examples/index.ts","../src/examples/env.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';\nimport { MappingSchema } from './mapping';\n\n// Export primitives\nexport * from './primitives';\n\n// Export Zod schemas and types\nexport { SettingsSchema, type Settings } from './settings';\nexport { MappingSchema, type Mapping } from './mapping';\n\n// JSON Schema exports (for website PropertyTable and documentation tools)\nexport const settings = zodToSchema(SettingsSchema);\nexport const mapping = zodToSchema(MappingSchema);\n","import { z } from '@walkeros/core/dev';\nimport { JavaScriptVarName, EventPrefix } from './primitives';\n\n/**\n * DataLayer source settings schema\n */\nexport const SettingsSchema = z.object({\n name: JavaScriptVarName.default('dataLayer')\n .describe('DataLayer variable name (default: dataLayer)')\n .optional(),\n\n prefix: EventPrefix.default('dataLayer')\n .describe('Event prefix for filtering which events to process')\n .optional(),\n\n filter: z\n .any()\n .describe(\n 'Custom filter function: (event: unknown) => boolean | Promise<boolean>',\n )\n .optional(),\n});\n\nexport type Settings = z.infer<typeof SettingsSchema>;\n","import { z } from '@walkeros/core/dev';\n\n/**\n * JavaScript variable name\n * Used for dataLayer variable naming\n */\nexport const JavaScriptVarName = z\n .string()\n .min(1)\n .regex(/^[a-zA-Z_$][a-zA-Z0-9_$]*$/, 'Must be a valid JavaScript identifier')\n .describe('JavaScript variable name');\n\n/**\n * Event prefix\n * Used for filtering dataLayer events\n */\nexport const EventPrefix = z\n .string()\n .min(1)\n .describe('Prefix for filtering dataLayer events');\n","import { z } from '@walkeros/core/dev';\n\n/**\n * dataLayer source rule.settings — describes how to translate an incoming\n * dataLayer push (gtag command, ecommerce event, etc.) into walker command\n * arguments. `command` is a walkerOS Mapping.Value evaluated against the raw\n * dataLayer arguments at capture time.\n */\nexport const MappingSchema = z.object({\n command: z\n .unknown()\n .describe(\n 'Mapping.Value evaluated against the raw dataLayer arguments to build walker command data (e.g. consent updates).',\n )\n .optional(),\n});\n\nexport type Mapping = z.infer<typeof MappingSchema>;\n","export * as env from './env';\nexport * as step from './step';\nexport { createTrigger, trigger } from './trigger';\n","import type { Source, Elb, Logger } from '@walkeros/core';\n\n/**\n * Example environment configurations for dataLayer source\n *\n * These environments provide standardized mock structures for testing\n * dataLayer interception without requiring a real window object.\n */\n\n// Simple no-op function for mocking\nconst noop = () => {};\n\n// Create a properly typed elb/push/command function that returns a promise with PushResult\nconst createMockElbFn = (): Elb.Fn => {\n const fn = (() =>\n Promise.resolve({\n ok: true,\n })) as Elb.Fn;\n return fn;\n};\n\n// Simple no-op logger for demo purposes\nconst noopLogger: Logger.Instance = {\n error: noop,\n warn: noop,\n info: noop,\n debug: noop,\n throw: (message: string | Error) => {\n throw typeof message === 'string' ? new Error(message) : message;\n },\n json: noop,\n scope: () => noopLogger,\n};\n\n/**\n * Environment interface for dataLayer source\n */\ninterface DataLayerEnv extends Source.BaseEnv {\n window?: typeof window;\n}\n\n/**\n * Mock window object with dataLayer array\n */\nconst createMockWindow = () => ({\n dataLayer: [] as unknown[],\n addEventListener: noop,\n removeEventListener: noop,\n});\n\n/**\n * Standard mock environment for testing dataLayer source\n *\n * Use this for testing dataLayer.push interception and event transformation\n * without requiring a real browser environment.\n */\nexport const push: DataLayerEnv = {\n get push() {\n return createMockElbFn();\n },\n get command() {\n return createMockElbFn();\n },\n get elb() {\n return createMockElbFn();\n },\n get window() {\n return createMockWindow() as unknown as typeof window;\n },\n logger: noopLogger,\n};\n","import type { Flow } from '@walkeros/core';\n\nexport const gtagPurchase: Flow.StepExample = {\n title: 'gtag purchase',\n description:\n 'A gtag purchase call pushed to the dataLayer is captured as a walker dataLayer purchase event with item details.',\n trigger: { type: 'gtag' },\n in: [\n 'event',\n 'purchase',\n {\n transaction_id: 'T-12345',\n value: 25.42,\n currency: 'EUR',\n items: [{ item_id: 'SKU-1', item_name: 'T-Shirt', quantity: 1 }],\n },\n ],\n out: [\n [\n 'elb',\n {\n name: 'dataLayer purchase',\n data: {\n transaction_id: 'T-12345',\n value: 25.42,\n currency: 'EUR',\n items: [{ item_id: 'SKU-1', item_name: 'T-Shirt', quantity: 1 }],\n },\n },\n ],\n ],\n};\n\nexport const consentUpdate: Flow.StepExample = {\n title: 'Consent update',\n description:\n 'A gtag consent update is captured from the dataLayer as a walker dataLayer consent update event.',\n trigger: { type: 'gtag' },\n in: [\n 'consent',\n 'update',\n {\n ad_storage: 'granted',\n analytics_storage: 'granted',\n },\n ],\n out: [\n [\n 'elb',\n {\n name: 'dataLayer consent update',\n data: {\n ad_storage: 'granted',\n analytics_storage: 'granted',\n },\n },\n ],\n ],\n};\n\nexport const gtagAddToCart: Flow.StepExample = {\n title: 'gtag add_to_cart',\n description:\n 'A gtag add_to_cart call pushed to the dataLayer is captured as a walker dataLayer add_to_cart event.',\n trigger: { type: 'gtag' },\n in: [\n 'event',\n 'add_to_cart',\n {\n currency: 'EUR',\n value: 15.25,\n items: [\n {\n item_id: 'SKU_12345',\n item_name: 'T-Shirt',\n item_variant: 'red',\n quantity: 1,\n price: 15.25,\n },\n ],\n },\n ],\n out: [\n [\n 'elb',\n {\n name: 'dataLayer add_to_cart',\n data: {\n currency: 'EUR',\n value: 15.25,\n items: [\n {\n item_id: 'SKU_12345',\n item_name: 'T-Shirt',\n item_variant: 'red',\n quantity: 1,\n price: 15.25,\n },\n ],\n },\n },\n ],\n ],\n};\n\nexport const gtagViewItem: Flow.StepExample = {\n title: 'gtag view_item',\n description:\n 'A gtag view_item call pushed to the dataLayer is captured as a walker dataLayer view_item event with item data.',\n trigger: { type: 'gtag' },\n in: [\n 'event',\n 'view_item',\n {\n currency: 'EUR',\n value: 29.99,\n items: [\n {\n item_id: 'SKU_67890',\n item_name: 'Sneakers',\n item_category: 'Footwear',\n price: 29.99,\n },\n ],\n },\n ],\n out: [\n [\n 'elb',\n {\n name: 'dataLayer view_item',\n data: {\n currency: 'EUR',\n value: 29.99,\n items: [\n {\n item_id: 'SKU_67890',\n item_name: 'Sneakers',\n item_category: 'Footwear',\n price: 29.99,\n },\n ],\n },\n },\n ],\n ],\n};\n\nexport const directEvent: Flow.StepExample = {\n title: 'Direct dataLayer event',\n description:\n 'A plain object pushed directly onto the dataLayer is captured as a walker dataLayer custom event.',\n trigger: { type: 'direct' },\n in: {\n event: 'custom_event',\n category: 'engagement',\n label: 'video_play',\n },\n out: [\n [\n 'elb',\n {\n name: 'dataLayer custom_event',\n data: {\n category: 'engagement',\n label: 'video_play',\n },\n },\n ],\n ],\n};\n","import type { Trigger, Collector } from '@walkeros/core';\nimport { startFlow } from '@walkeros/collector';\n\nconst createTrigger: Trigger.CreateFn<unknown, void> = async (\n config: Collector.InitConfig,\n) => {\n let flow: Trigger.FlowHandle | undefined;\n\n const trigger: Trigger.Fn<unknown, void> = () => async (content: unknown) => {\n // Lazy startFlow — source patches window.dataLayer.push during init\n if (!flow) {\n // Ensure dataLayer sources get the window env for interception\n const enrichedConfig = { ...config };\n if (enrichedConfig.sources) {\n enrichedConfig.sources = { ...enrichedConfig.sources };\n for (const [id, source] of Object.entries(enrichedConfig.sources)) {\n if (!source.env?.window) {\n enrichedConfig.sources[id] = {\n ...source,\n env: { ...source.env, window },\n };\n }\n }\n }\n const result = await startFlow({\n ...enrichedConfig,\n run: enrichedConfig.run ?? true,\n });\n flow = { collector: result.collector, elb: result.elb };\n }\n\n // Push to dataLayer — the interceptor catches it\n const win = window as Window & { dataLayer?: unknown[] };\n if (!win.dataLayer) win.dataLayer = [];\n win.dataLayer.push(content);\n };\n\n return {\n get flow() {\n return flow;\n },\n trigger,\n };\n};\n\n/** Pushes step example input to window.dataLayer after source init. */\nconst trigger = (input: unknown, env: Record<string, unknown>): void => {\n const win = env.window as Window & { dataLayer?: unknown[] };\n if (!win.dataLayer) win.dataLayer = [];\n win.dataLayer.push(input);\n};\n\nexport { createTrigger, trigger };\n"],"mappings":"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","names":["import_dev","import_dev","import_dev","trigger"]}
|
|
1
|
+
{"version":3,"sources":["../src/dev.ts","../src/schemas/index.ts","../src/schemas/settings.ts","../src/schemas/primitives.ts","../src/schemas/mapping.ts","../src/examples/index.ts","../src/examples/env.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';\nimport { MappingSchema } from './mapping';\n\n// Export primitives\nexport * from './primitives';\n\n// Export Zod schemas and types\nexport { SettingsSchema, type Settings } from './settings';\nexport { MappingSchema, type Mapping } from './mapping';\n\n// JSON Schema exports (for website PropertyTable and documentation tools)\nexport const settings = zodToSchema(SettingsSchema);\nexport const mapping = zodToSchema(MappingSchema);\n","import { z } from '@walkeros/core/dev';\nimport { JavaScriptVarName, EventPrefix } from './primitives';\n\n/**\n * DataLayer source settings schema\n */\nexport const SettingsSchema = z.object({\n name: JavaScriptVarName.default('dataLayer')\n .describe('DataLayer variable name (default: dataLayer)')\n .optional(),\n\n prefix: EventPrefix.default('dataLayer')\n .describe('Event prefix for filtering which events to process')\n .optional(),\n\n filter: z\n .any()\n .describe(\n 'Custom filter function: (event: unknown) => boolean | Promise<boolean>',\n )\n .optional(),\n});\n\nexport type Settings = z.infer<typeof SettingsSchema>;\n","import { z } from '@walkeros/core/dev';\n\n/**\n * JavaScript variable name\n * Used for dataLayer variable naming\n */\nexport const JavaScriptVarName = z\n .string()\n .min(1)\n .regex(/^[a-zA-Z_$][a-zA-Z0-9_$]*$/, 'Must be a valid JavaScript identifier')\n .describe('JavaScript variable name');\n\n/**\n * Event prefix\n * Used for filtering dataLayer events\n */\nexport const EventPrefix = z\n .string()\n .min(1)\n .describe('Prefix for filtering dataLayer events');\n","import { z } from '@walkeros/core/dev';\n\n/**\n * dataLayer source rule.settings — describes how to translate an incoming\n * dataLayer push (gtag command, ecommerce event, etc.) into walker command\n * arguments. `command` is a walkerOS Mapping.Value evaluated against the raw\n * dataLayer arguments at capture time.\n */\nexport const MappingSchema = z.object({\n command: z\n .unknown()\n .describe(\n 'Mapping.Value evaluated against the raw dataLayer arguments to build walker command data (e.g. consent updates).',\n )\n .optional(),\n});\n\nexport type Mapping = z.infer<typeof MappingSchema>;\n","export * as env from './env';\nexport * as step from './step';\nexport { createTrigger, trigger } from './trigger';\n","import type { Source, Elb, Logger } from '@walkeros/core';\n\n/**\n * Example environment configurations for dataLayer source\n *\n * These environments provide standardized mock structures for testing\n * dataLayer interception without requiring a real window object.\n */\n\n// Simple no-op function for mocking\nconst noop = () => {};\n\n// Create a properly typed elb/push/command function that returns a promise with PushResult\nconst createMockElbFn = (): Elb.Fn => {\n const fn = (() =>\n Promise.resolve({\n ok: true,\n })) as Elb.Fn;\n return fn;\n};\n\n// Simple no-op logger for demo purposes\nconst noopLogger: Logger.Instance = {\n error: noop,\n warn: noop,\n info: noop,\n debug: noop,\n throw: (message: string | Error) => {\n throw typeof message === 'string' ? new Error(message) : message;\n },\n json: noop,\n scope: () => noopLogger,\n};\n\n/**\n * Environment interface for dataLayer source\n */\ninterface DataLayerEnv extends Source.BaseEnv {\n window?: typeof window;\n}\n\n/**\n * Mock window object with dataLayer array\n */\nconst createMockWindow = () => ({\n dataLayer: [] as unknown[],\n addEventListener: noop,\n removeEventListener: noop,\n});\n\n/**\n * Standard mock environment for testing dataLayer source\n *\n * Use this for testing dataLayer.push interception and event transformation\n * without requiring a real browser environment.\n */\nexport const push: DataLayerEnv = {\n get push() {\n return createMockElbFn();\n },\n get command() {\n return createMockElbFn();\n },\n get elb() {\n return createMockElbFn();\n },\n get window() {\n return createMockWindow() as unknown as typeof window;\n },\n logger: noopLogger,\n};\n","import type { Flow } from '@walkeros/core';\n\nexport const gtagPurchase: Flow.StepExample = {\n title: 'gtag purchase',\n description:\n 'A gtag purchase call pushed to the dataLayer is captured as a walker dataLayer purchase event with item details.',\n trigger: { type: 'gtag' },\n in: [\n 'event',\n 'purchase',\n {\n transaction_id: 'T-12345',\n value: 25.42,\n currency: 'EUR',\n items: [{ item_id: 'SKU-1', item_name: 'T-Shirt', quantity: 1 }],\n },\n ],\n out: [\n [\n 'elb',\n {\n name: 'dataLayer purchase',\n data: {\n transaction_id: 'T-12345',\n value: 25.42,\n currency: 'EUR',\n items: [{ item_id: 'SKU-1', item_name: 'T-Shirt', quantity: 1 }],\n },\n source: { type: 'dataLayer', platform: 'web' },\n },\n ],\n ],\n};\n\nexport const consentUpdate: Flow.StepExample = {\n title: 'Consent update',\n description:\n 'A gtag consent update is captured from the dataLayer as a walker dataLayer consent update event.',\n trigger: { type: 'gtag' },\n in: [\n 'consent',\n 'update',\n {\n ad_storage: 'granted',\n analytics_storage: 'granted',\n },\n ],\n out: [\n [\n 'elb',\n {\n name: 'dataLayer consent update',\n data: {\n ad_storage: 'granted',\n analytics_storage: 'granted',\n },\n source: { type: 'dataLayer', platform: 'web' },\n },\n ],\n ],\n};\n\nexport const gtagAddToCart: Flow.StepExample = {\n title: 'gtag add_to_cart',\n description:\n 'A gtag add_to_cart call pushed to the dataLayer is captured as a walker dataLayer add_to_cart event.',\n trigger: { type: 'gtag' },\n in: [\n 'event',\n 'add_to_cart',\n {\n currency: 'EUR',\n value: 15.25,\n items: [\n {\n item_id: 'SKU_12345',\n item_name: 'T-Shirt',\n item_variant: 'red',\n quantity: 1,\n price: 15.25,\n },\n ],\n },\n ],\n out: [\n [\n 'elb',\n {\n name: 'dataLayer add_to_cart',\n data: {\n currency: 'EUR',\n value: 15.25,\n items: [\n {\n item_id: 'SKU_12345',\n item_name: 'T-Shirt',\n item_variant: 'red',\n quantity: 1,\n price: 15.25,\n },\n ],\n },\n source: { type: 'dataLayer', platform: 'web' },\n },\n ],\n ],\n};\n\nexport const gtagViewItem: Flow.StepExample = {\n title: 'gtag view_item',\n description:\n 'A gtag view_item call pushed to the dataLayer is captured as a walker dataLayer view_item event with item data.',\n trigger: { type: 'gtag' },\n in: [\n 'event',\n 'view_item',\n {\n currency: 'EUR',\n value: 29.99,\n items: [\n {\n item_id: 'SKU_67890',\n item_name: 'Sneakers',\n item_category: 'Footwear',\n price: 29.99,\n },\n ],\n },\n ],\n out: [\n [\n 'elb',\n {\n name: 'dataLayer view_item',\n data: {\n currency: 'EUR',\n value: 29.99,\n items: [\n {\n item_id: 'SKU_67890',\n item_name: 'Sneakers',\n item_category: 'Footwear',\n price: 29.99,\n },\n ],\n },\n source: { type: 'dataLayer', platform: 'web' },\n },\n ],\n ],\n};\n\nexport const directEvent: Flow.StepExample = {\n title: 'Direct dataLayer event',\n description:\n 'A plain object pushed directly onto the dataLayer is captured as a walker dataLayer custom event.',\n trigger: { type: 'direct' },\n in: {\n event: 'custom_event',\n category: 'engagement',\n label: 'video_play',\n },\n out: [\n [\n 'elb',\n {\n name: 'dataLayer custom_event',\n data: {\n category: 'engagement',\n label: 'video_play',\n },\n source: { type: 'dataLayer', platform: 'web' },\n },\n ],\n ],\n};\n","import type { Trigger, Collector } from '@walkeros/core';\nimport { startFlow } from '@walkeros/collector';\n\nconst createTrigger: Trigger.CreateFn<unknown, void> = async (\n config: Collector.InitConfig,\n) => {\n let flow: Trigger.FlowHandle | undefined;\n\n const trigger: Trigger.Fn<unknown, void> = () => async (content: unknown) => {\n // Lazy startFlow — source patches window.dataLayer.push during init\n if (!flow) {\n // Ensure dataLayer sources get the window env for interception\n const enrichedConfig = { ...config };\n if (enrichedConfig.sources) {\n enrichedConfig.sources = { ...enrichedConfig.sources };\n for (const [id, source] of Object.entries(enrichedConfig.sources)) {\n if (!source.env?.window) {\n enrichedConfig.sources[id] = {\n ...source,\n env: { ...source.env, window },\n };\n }\n }\n }\n const result = await startFlow({\n ...enrichedConfig,\n run: enrichedConfig.run ?? true,\n });\n flow = { collector: result.collector, elb: result.elb };\n }\n\n // Push to dataLayer — the interceptor catches it\n const win = window as Window & { dataLayer?: unknown[] };\n if (!win.dataLayer) win.dataLayer = [];\n win.dataLayer.push(content);\n };\n\n return {\n get flow() {\n return flow;\n },\n trigger,\n };\n};\n\n/** Pushes step example input to window.dataLayer after source init. */\nconst trigger = (input: unknown, env: Record<string, unknown>): void => {\n const win = env.window as Window & { dataLayer?: unknown[] };\n if (!win.dataLayer) win.dataLayer = [];\n win.dataLayer.push(input);\n};\n\nexport { createTrigger, trigger };\n"],"mappings":"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","names":["import_dev","import_dev","import_dev","trigger"]}
|
package/dist/dev.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var e=Object.defineProperty,a=(a,t)=>{for(var r in t)e(a,r,{get:t[r],enumerable:!0})},t={};a(t,{EventPrefix:()=>d,JavaScriptVarName:()=>o,MappingSchema:()=>
|
|
1
|
+
var e=Object.defineProperty,a=(a,t)=>{for(var r in t)e(a,r,{get:t[r],enumerable:!0})},t={};a(t,{EventPrefix:()=>d,JavaScriptVarName:()=>o,MappingSchema:()=>l,SettingsSchema:()=>s,mapping:()=>g,settings:()=>m});import{zodToSchema as r}from"@walkeros/core/dev";import{z as i}from"@walkeros/core/dev";import{z as n}from"@walkeros/core/dev";var o=n.string().min(1).regex(/^[a-zA-Z_$][a-zA-Z0-9_$]*$/,"Must be a valid JavaScript identifier").describe("JavaScript variable name"),d=n.string().min(1).describe("Prefix for filtering dataLayer events"),s=i.object({name:o.default("dataLayer").describe("DataLayer variable name (default: dataLayer)").optional(),prefix:d.default("dataLayer").describe("Event prefix for filtering which events to process").optional(),filter:i.any().describe("Custom filter function: (event: unknown) => boolean | Promise<boolean>").optional()});import{z as c}from"@walkeros/core/dev";var l=c.object({command:c.unknown().describe("Mapping.Value evaluated against the raw dataLayer arguments to build walker command data (e.g. consent updates).").optional()}),m=r(s),g=r(l),u={};a(u,{createTrigger:()=>E,env:()=>p,step:()=>L,trigger:()=>A});var p={};a(p,{push:()=>_});var y=()=>{},v=()=>()=>Promise.resolve({ok:!0}),w={error:y,warn:y,info:y,debug:y,throw:e=>{throw"string"==typeof e?new Error(e):e},json:y,scope:()=>w},_={get push(){return v()},get command(){return v()},get elb(){return v()},get window(){return{dataLayer:[],addEventListener:y,removeEventListener:y}},logger:w},L={};a(L,{consentUpdate:()=>b,directEvent:()=>k,gtagAddToCart:()=>h,gtagPurchase:()=>f,gtagViewItem:()=>S});var f={title:"gtag purchase",description:"A gtag purchase call pushed to the dataLayer is captured as a walker dataLayer purchase event with item details.",trigger:{type:"gtag"},in:["event","purchase",{transaction_id:"T-12345",value:25.42,currency:"EUR",items:[{item_id:"SKU-1",item_name:"T-Shirt",quantity:1}]}],out:[["elb",{name:"dataLayer purchase",data:{transaction_id:"T-12345",value:25.42,currency:"EUR",items:[{item_id:"SKU-1",item_name:"T-Shirt",quantity:1}]},source:{type:"dataLayer",platform:"web"}}]]},b={title:"Consent update",description:"A gtag consent update is captured from the dataLayer as a walker dataLayer consent update event.",trigger:{type:"gtag"},in:["consent","update",{ad_storage:"granted",analytics_storage:"granted"}],out:[["elb",{name:"dataLayer consent update",data:{ad_storage:"granted",analytics_storage:"granted"},source:{type:"dataLayer",platform:"web"}}]]},h={title:"gtag add_to_cart",description:"A gtag add_to_cart call pushed to the dataLayer is captured as a walker dataLayer add_to_cart event.",trigger:{type:"gtag"},in:["event","add_to_cart",{currency:"EUR",value:15.25,items:[{item_id:"SKU_12345",item_name:"T-Shirt",item_variant:"red",quantity:1,price:15.25}]}],out:[["elb",{name:"dataLayer add_to_cart",data:{currency:"EUR",value:15.25,items:[{item_id:"SKU_12345",item_name:"T-Shirt",item_variant:"red",quantity:1,price:15.25}]},source:{type:"dataLayer",platform:"web"}}]]},S={title:"gtag view_item",description:"A gtag view_item call pushed to the dataLayer is captured as a walker dataLayer view_item event with item data.",trigger:{type:"gtag"},in:["event","view_item",{currency:"EUR",value:29.99,items:[{item_id:"SKU_67890",item_name:"Sneakers",item_category:"Footwear",price:29.99}]}],out:[["elb",{name:"dataLayer view_item",data:{currency:"EUR",value:29.99,items:[{item_id:"SKU_67890",item_name:"Sneakers",item_category:"Footwear",price:29.99}]},source:{type:"dataLayer",platform:"web"}}]]},k={title:"Direct dataLayer event",description:"A plain object pushed directly onto the dataLayer is captured as a walker dataLayer custom event.",trigger:{type:"direct"},in:{event:"custom_event",category:"engagement",label:"video_play"},out:[["elb",{name:"dataLayer custom_event",data:{category:"engagement",label:"video_play"},source:{type:"dataLayer",platform:"web"}}]]};import{startFlow as U}from"@walkeros/collector";var E=async e=>{let a;return{get flow(){return a},trigger:()=>async t=>{var r,i;if(!a){const t={...e};if(t.sources){t.sources={...t.sources};for(const[e,a]of Object.entries(t.sources))(null==(r=a.env)?void 0:r.window)||(t.sources[e]={...a,env:{...a.env,window:window}})}const n=await U({...t,run:null==(i=t.run)||i});a={collector:n.collector,elb:n.elb}}const n=window;n.dataLayer||(n.dataLayer=[]),n.dataLayer.push(t)}}},A=(e,a)=>{const t=a.window;t.dataLayer||(t.dataLayer=[]),t.dataLayer.push(e)};export{u as examples,t 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/schemas/primitives.ts","../src/schemas/mapping.ts","../src/examples/index.ts","../src/examples/env.ts","../src/examples/step.ts","../src/examples/trigger.ts"],"sourcesContent":["import { zodToSchema } from '@walkeros/core/dev';\nimport { SettingsSchema } from './settings';\nimport { MappingSchema } from './mapping';\n\n// Export primitives\nexport * from './primitives';\n\n// Export Zod schemas and types\nexport { SettingsSchema, type Settings } from './settings';\nexport { MappingSchema, type Mapping } from './mapping';\n\n// JSON Schema exports (for website PropertyTable and documentation tools)\nexport const settings = zodToSchema(SettingsSchema);\nexport const mapping = zodToSchema(MappingSchema);\n","import { z } from '@walkeros/core/dev';\nimport { JavaScriptVarName, EventPrefix } from './primitives';\n\n/**\n * DataLayer source settings schema\n */\nexport const SettingsSchema = z.object({\n name: JavaScriptVarName.default('dataLayer')\n .describe('DataLayer variable name (default: dataLayer)')\n .optional(),\n\n prefix: EventPrefix.default('dataLayer')\n .describe('Event prefix for filtering which events to process')\n .optional(),\n\n filter: z\n .any()\n .describe(\n 'Custom filter function: (event: unknown) => boolean | Promise<boolean>',\n )\n .optional(),\n});\n\nexport type Settings = z.infer<typeof SettingsSchema>;\n","import { z } from '@walkeros/core/dev';\n\n/**\n * JavaScript variable name\n * Used for dataLayer variable naming\n */\nexport const JavaScriptVarName = z\n .string()\n .min(1)\n .regex(/^[a-zA-Z_$][a-zA-Z0-9_$]*$/, 'Must be a valid JavaScript identifier')\n .describe('JavaScript variable name');\n\n/**\n * Event prefix\n * Used for filtering dataLayer events\n */\nexport const EventPrefix = z\n .string()\n .min(1)\n .describe('Prefix for filtering dataLayer events');\n","import { z } from '@walkeros/core/dev';\n\n/**\n * dataLayer source rule.settings — describes how to translate an incoming\n * dataLayer push (gtag command, ecommerce event, etc.) into walker command\n * arguments. `command` is a walkerOS Mapping.Value evaluated against the raw\n * dataLayer arguments at capture time.\n */\nexport const MappingSchema = z.object({\n command: z\n .unknown()\n .describe(\n 'Mapping.Value evaluated against the raw dataLayer arguments to build walker command data (e.g. consent updates).',\n )\n .optional(),\n});\n\nexport type Mapping = z.infer<typeof MappingSchema>;\n","export * as env from './env';\nexport * as step from './step';\nexport { createTrigger, trigger } from './trigger';\n","import type { Source, Elb, Logger } from '@walkeros/core';\n\n/**\n * Example environment configurations for dataLayer source\n *\n * These environments provide standardized mock structures for testing\n * dataLayer interception without requiring a real window object.\n */\n\n// Simple no-op function for mocking\nconst noop = () => {};\n\n// Create a properly typed elb/push/command function that returns a promise with PushResult\nconst createMockElbFn = (): Elb.Fn => {\n const fn = (() =>\n Promise.resolve({\n ok: true,\n })) as Elb.Fn;\n return fn;\n};\n\n// Simple no-op logger for demo purposes\nconst noopLogger: Logger.Instance = {\n error: noop,\n warn: noop,\n info: noop,\n debug: noop,\n throw: (message: string | Error) => {\n throw typeof message === 'string' ? new Error(message) : message;\n },\n json: noop,\n scope: () => noopLogger,\n};\n\n/**\n * Environment interface for dataLayer source\n */\ninterface DataLayerEnv extends Source.BaseEnv {\n window?: typeof window;\n}\n\n/**\n * Mock window object with dataLayer array\n */\nconst createMockWindow = () => ({\n dataLayer: [] as unknown[],\n addEventListener: noop,\n removeEventListener: noop,\n});\n\n/**\n * Standard mock environment for testing dataLayer source\n *\n * Use this for testing dataLayer.push interception and event transformation\n * without requiring a real browser environment.\n */\nexport const push: DataLayerEnv = {\n get push() {\n return createMockElbFn();\n },\n get command() {\n return createMockElbFn();\n },\n get elb() {\n return createMockElbFn();\n },\n get window() {\n return createMockWindow() as unknown as typeof window;\n },\n logger: noopLogger,\n};\n","import type { Flow } from '@walkeros/core';\n\nexport const gtagPurchase: Flow.StepExample = {\n title: 'gtag purchase',\n description:\n 'A gtag purchase call pushed to the dataLayer is captured as a walker dataLayer purchase event with item details.',\n trigger: { type: 'gtag' },\n in: [\n 'event',\n 'purchase',\n {\n transaction_id: 'T-12345',\n value: 25.42,\n currency: 'EUR',\n items: [{ item_id: 'SKU-1', item_name: 'T-Shirt', quantity: 1 }],\n },\n ],\n out: [\n [\n 'elb',\n {\n name: 'dataLayer purchase',\n data: {\n transaction_id: 'T-12345',\n value: 25.42,\n currency: 'EUR',\n items: [{ item_id: 'SKU-1', item_name: 'T-Shirt', quantity: 1 }],\n },\n },\n ],\n ],\n};\n\nexport const consentUpdate: Flow.StepExample = {\n title: 'Consent update',\n description:\n 'A gtag consent update is captured from the dataLayer as a walker dataLayer consent update event.',\n trigger: { type: 'gtag' },\n in: [\n 'consent',\n 'update',\n {\n ad_storage: 'granted',\n analytics_storage: 'granted',\n },\n ],\n out: [\n [\n 'elb',\n {\n name: 'dataLayer consent update',\n data: {\n ad_storage: 'granted',\n analytics_storage: 'granted',\n },\n },\n ],\n ],\n};\n\nexport const gtagAddToCart: Flow.StepExample = {\n title: 'gtag add_to_cart',\n description:\n 'A gtag add_to_cart call pushed to the dataLayer is captured as a walker dataLayer add_to_cart event.',\n trigger: { type: 'gtag' },\n in: [\n 'event',\n 'add_to_cart',\n {\n currency: 'EUR',\n value: 15.25,\n items: [\n {\n item_id: 'SKU_12345',\n item_name: 'T-Shirt',\n item_variant: 'red',\n quantity: 1,\n price: 15.25,\n },\n ],\n },\n ],\n out: [\n [\n 'elb',\n {\n name: 'dataLayer add_to_cart',\n data: {\n currency: 'EUR',\n value: 15.25,\n items: [\n {\n item_id: 'SKU_12345',\n item_name: 'T-Shirt',\n item_variant: 'red',\n quantity: 1,\n price: 15.25,\n },\n ],\n },\n },\n ],\n ],\n};\n\nexport const gtagViewItem: Flow.StepExample = {\n title: 'gtag view_item',\n description:\n 'A gtag view_item call pushed to the dataLayer is captured as a walker dataLayer view_item event with item data.',\n trigger: { type: 'gtag' },\n in: [\n 'event',\n 'view_item',\n {\n currency: 'EUR',\n value: 29.99,\n items: [\n {\n item_id: 'SKU_67890',\n item_name: 'Sneakers',\n item_category: 'Footwear',\n price: 29.99,\n },\n ],\n },\n ],\n out: [\n [\n 'elb',\n {\n name: 'dataLayer view_item',\n data: {\n currency: 'EUR',\n value: 29.99,\n items: [\n {\n item_id: 'SKU_67890',\n item_name: 'Sneakers',\n item_category: 'Footwear',\n price: 29.99,\n },\n ],\n },\n },\n ],\n ],\n};\n\nexport const directEvent: Flow.StepExample = {\n title: 'Direct dataLayer event',\n description:\n 'A plain object pushed directly onto the dataLayer is captured as a walker dataLayer custom event.',\n trigger: { type: 'direct' },\n in: {\n event: 'custom_event',\n category: 'engagement',\n label: 'video_play',\n },\n out: [\n [\n 'elb',\n {\n name: 'dataLayer custom_event',\n data: {\n category: 'engagement',\n label: 'video_play',\n },\n },\n ],\n ],\n};\n","import type { Trigger, Collector } from '@walkeros/core';\nimport { startFlow } from '@walkeros/collector';\n\nconst createTrigger: Trigger.CreateFn<unknown, void> = async (\n config: Collector.InitConfig,\n) => {\n let flow: Trigger.FlowHandle | undefined;\n\n const trigger: Trigger.Fn<unknown, void> = () => async (content: unknown) => {\n // Lazy startFlow — source patches window.dataLayer.push during init\n if (!flow) {\n // Ensure dataLayer sources get the window env for interception\n const enrichedConfig = { ...config };\n if (enrichedConfig.sources) {\n enrichedConfig.sources = { ...enrichedConfig.sources };\n for (const [id, source] of Object.entries(enrichedConfig.sources)) {\n if (!source.env?.window) {\n enrichedConfig.sources[id] = {\n ...source,\n env: { ...source.env, window },\n };\n }\n }\n }\n const result = await startFlow({\n ...enrichedConfig,\n run: enrichedConfig.run ?? true,\n });\n flow = { collector: result.collector, elb: result.elb };\n }\n\n // Push to dataLayer — the interceptor catches it\n const win = window as Window & { dataLayer?: unknown[] };\n if (!win.dataLayer) win.dataLayer = [];\n win.dataLayer.push(content);\n };\n\n return {\n get flow() {\n return flow;\n },\n trigger,\n };\n};\n\n/** Pushes step example input to window.dataLayer after source init. */\nconst trigger = (input: unknown, env: Record<string, unknown>): void => {\n const win = env.window as Window & { dataLayer?: unknown[] };\n if (!win.dataLayer) win.dataLayer = [];\n win.dataLayer.push(input);\n};\n\nexport { createTrigger, trigger };\n"],"mappings":"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","names":["z","z","z","trigger"]}
|
|
1
|
+
{"version":3,"sources":["../src/schemas/index.ts","../src/schemas/settings.ts","../src/schemas/primitives.ts","../src/schemas/mapping.ts","../src/examples/index.ts","../src/examples/env.ts","../src/examples/step.ts","../src/examples/trigger.ts"],"sourcesContent":["import { zodToSchema } from '@walkeros/core/dev';\nimport { SettingsSchema } from './settings';\nimport { MappingSchema } from './mapping';\n\n// Export primitives\nexport * from './primitives';\n\n// Export Zod schemas and types\nexport { SettingsSchema, type Settings } from './settings';\nexport { MappingSchema, type Mapping } from './mapping';\n\n// JSON Schema exports (for website PropertyTable and documentation tools)\nexport const settings = zodToSchema(SettingsSchema);\nexport const mapping = zodToSchema(MappingSchema);\n","import { z } from '@walkeros/core/dev';\nimport { JavaScriptVarName, EventPrefix } from './primitives';\n\n/**\n * DataLayer source settings schema\n */\nexport const SettingsSchema = z.object({\n name: JavaScriptVarName.default('dataLayer')\n .describe('DataLayer variable name (default: dataLayer)')\n .optional(),\n\n prefix: EventPrefix.default('dataLayer')\n .describe('Event prefix for filtering which events to process')\n .optional(),\n\n filter: z\n .any()\n .describe(\n 'Custom filter function: (event: unknown) => boolean | Promise<boolean>',\n )\n .optional(),\n});\n\nexport type Settings = z.infer<typeof SettingsSchema>;\n","import { z } from '@walkeros/core/dev';\n\n/**\n * JavaScript variable name\n * Used for dataLayer variable naming\n */\nexport const JavaScriptVarName = z\n .string()\n .min(1)\n .regex(/^[a-zA-Z_$][a-zA-Z0-9_$]*$/, 'Must be a valid JavaScript identifier')\n .describe('JavaScript variable name');\n\n/**\n * Event prefix\n * Used for filtering dataLayer events\n */\nexport const EventPrefix = z\n .string()\n .min(1)\n .describe('Prefix for filtering dataLayer events');\n","import { z } from '@walkeros/core/dev';\n\n/**\n * dataLayer source rule.settings — describes how to translate an incoming\n * dataLayer push (gtag command, ecommerce event, etc.) into walker command\n * arguments. `command` is a walkerOS Mapping.Value evaluated against the raw\n * dataLayer arguments at capture time.\n */\nexport const MappingSchema = z.object({\n command: z\n .unknown()\n .describe(\n 'Mapping.Value evaluated against the raw dataLayer arguments to build walker command data (e.g. consent updates).',\n )\n .optional(),\n});\n\nexport type Mapping = z.infer<typeof MappingSchema>;\n","export * as env from './env';\nexport * as step from './step';\nexport { createTrigger, trigger } from './trigger';\n","import type { Source, Elb, Logger } from '@walkeros/core';\n\n/**\n * Example environment configurations for dataLayer source\n *\n * These environments provide standardized mock structures for testing\n * dataLayer interception without requiring a real window object.\n */\n\n// Simple no-op function for mocking\nconst noop = () => {};\n\n// Create a properly typed elb/push/command function that returns a promise with PushResult\nconst createMockElbFn = (): Elb.Fn => {\n const fn = (() =>\n Promise.resolve({\n ok: true,\n })) as Elb.Fn;\n return fn;\n};\n\n// Simple no-op logger for demo purposes\nconst noopLogger: Logger.Instance = {\n error: noop,\n warn: noop,\n info: noop,\n debug: noop,\n throw: (message: string | Error) => {\n throw typeof message === 'string' ? new Error(message) : message;\n },\n json: noop,\n scope: () => noopLogger,\n};\n\n/**\n * Environment interface for dataLayer source\n */\ninterface DataLayerEnv extends Source.BaseEnv {\n window?: typeof window;\n}\n\n/**\n * Mock window object with dataLayer array\n */\nconst createMockWindow = () => ({\n dataLayer: [] as unknown[],\n addEventListener: noop,\n removeEventListener: noop,\n});\n\n/**\n * Standard mock environment for testing dataLayer source\n *\n * Use this for testing dataLayer.push interception and event transformation\n * without requiring a real browser environment.\n */\nexport const push: DataLayerEnv = {\n get push() {\n return createMockElbFn();\n },\n get command() {\n return createMockElbFn();\n },\n get elb() {\n return createMockElbFn();\n },\n get window() {\n return createMockWindow() as unknown as typeof window;\n },\n logger: noopLogger,\n};\n","import type { Flow } from '@walkeros/core';\n\nexport const gtagPurchase: Flow.StepExample = {\n title: 'gtag purchase',\n description:\n 'A gtag purchase call pushed to the dataLayer is captured as a walker dataLayer purchase event with item details.',\n trigger: { type: 'gtag' },\n in: [\n 'event',\n 'purchase',\n {\n transaction_id: 'T-12345',\n value: 25.42,\n currency: 'EUR',\n items: [{ item_id: 'SKU-1', item_name: 'T-Shirt', quantity: 1 }],\n },\n ],\n out: [\n [\n 'elb',\n {\n name: 'dataLayer purchase',\n data: {\n transaction_id: 'T-12345',\n value: 25.42,\n currency: 'EUR',\n items: [{ item_id: 'SKU-1', item_name: 'T-Shirt', quantity: 1 }],\n },\n source: { type: 'dataLayer', platform: 'web' },\n },\n ],\n ],\n};\n\nexport const consentUpdate: Flow.StepExample = {\n title: 'Consent update',\n description:\n 'A gtag consent update is captured from the dataLayer as a walker dataLayer consent update event.',\n trigger: { type: 'gtag' },\n in: [\n 'consent',\n 'update',\n {\n ad_storage: 'granted',\n analytics_storage: 'granted',\n },\n ],\n out: [\n [\n 'elb',\n {\n name: 'dataLayer consent update',\n data: {\n ad_storage: 'granted',\n analytics_storage: 'granted',\n },\n source: { type: 'dataLayer', platform: 'web' },\n },\n ],\n ],\n};\n\nexport const gtagAddToCart: Flow.StepExample = {\n title: 'gtag add_to_cart',\n description:\n 'A gtag add_to_cart call pushed to the dataLayer is captured as a walker dataLayer add_to_cart event.',\n trigger: { type: 'gtag' },\n in: [\n 'event',\n 'add_to_cart',\n {\n currency: 'EUR',\n value: 15.25,\n items: [\n {\n item_id: 'SKU_12345',\n item_name: 'T-Shirt',\n item_variant: 'red',\n quantity: 1,\n price: 15.25,\n },\n ],\n },\n ],\n out: [\n [\n 'elb',\n {\n name: 'dataLayer add_to_cart',\n data: {\n currency: 'EUR',\n value: 15.25,\n items: [\n {\n item_id: 'SKU_12345',\n item_name: 'T-Shirt',\n item_variant: 'red',\n quantity: 1,\n price: 15.25,\n },\n ],\n },\n source: { type: 'dataLayer', platform: 'web' },\n },\n ],\n ],\n};\n\nexport const gtagViewItem: Flow.StepExample = {\n title: 'gtag view_item',\n description:\n 'A gtag view_item call pushed to the dataLayer is captured as a walker dataLayer view_item event with item data.',\n trigger: { type: 'gtag' },\n in: [\n 'event',\n 'view_item',\n {\n currency: 'EUR',\n value: 29.99,\n items: [\n {\n item_id: 'SKU_67890',\n item_name: 'Sneakers',\n item_category: 'Footwear',\n price: 29.99,\n },\n ],\n },\n ],\n out: [\n [\n 'elb',\n {\n name: 'dataLayer view_item',\n data: {\n currency: 'EUR',\n value: 29.99,\n items: [\n {\n item_id: 'SKU_67890',\n item_name: 'Sneakers',\n item_category: 'Footwear',\n price: 29.99,\n },\n ],\n },\n source: { type: 'dataLayer', platform: 'web' },\n },\n ],\n ],\n};\n\nexport const directEvent: Flow.StepExample = {\n title: 'Direct dataLayer event',\n description:\n 'A plain object pushed directly onto the dataLayer is captured as a walker dataLayer custom event.',\n trigger: { type: 'direct' },\n in: {\n event: 'custom_event',\n category: 'engagement',\n label: 'video_play',\n },\n out: [\n [\n 'elb',\n {\n name: 'dataLayer custom_event',\n data: {\n category: 'engagement',\n label: 'video_play',\n },\n source: { type: 'dataLayer', platform: 'web' },\n },\n ],\n ],\n};\n","import type { Trigger, Collector } from '@walkeros/core';\nimport { startFlow } from '@walkeros/collector';\n\nconst createTrigger: Trigger.CreateFn<unknown, void> = async (\n config: Collector.InitConfig,\n) => {\n let flow: Trigger.FlowHandle | undefined;\n\n const trigger: Trigger.Fn<unknown, void> = () => async (content: unknown) => {\n // Lazy startFlow — source patches window.dataLayer.push during init\n if (!flow) {\n // Ensure dataLayer sources get the window env for interception\n const enrichedConfig = { ...config };\n if (enrichedConfig.sources) {\n enrichedConfig.sources = { ...enrichedConfig.sources };\n for (const [id, source] of Object.entries(enrichedConfig.sources)) {\n if (!source.env?.window) {\n enrichedConfig.sources[id] = {\n ...source,\n env: { ...source.env, window },\n };\n }\n }\n }\n const result = await startFlow({\n ...enrichedConfig,\n run: enrichedConfig.run ?? true,\n });\n flow = { collector: result.collector, elb: result.elb };\n }\n\n // Push to dataLayer — the interceptor catches it\n const win = window as Window & { dataLayer?: unknown[] };\n if (!win.dataLayer) win.dataLayer = [];\n win.dataLayer.push(content);\n };\n\n return {\n get flow() {\n return flow;\n },\n trigger,\n };\n};\n\n/** Pushes step example input to window.dataLayer after source init. */\nconst trigger = (input: unknown, env: Record<string, unknown>): void => {\n const win = env.window as Window & { dataLayer?: unknown[] };\n if (!win.dataLayer) win.dataLayer = [];\n win.dataLayer.push(input);\n};\n\nexport { createTrigger, trigger };\n"],"mappings":"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","names":["z","z","z","trigger"]}
|
package/dist/examples/index.js
CHANGED
|
@@ -105,7 +105,8 @@ var gtagPurchase = {
|
|
|
105
105
|
value: 25.42,
|
|
106
106
|
currency: "EUR",
|
|
107
107
|
items: [{ item_id: "SKU-1", item_name: "T-Shirt", quantity: 1 }]
|
|
108
|
-
}
|
|
108
|
+
},
|
|
109
|
+
source: { type: "dataLayer", platform: "web" }
|
|
109
110
|
}
|
|
110
111
|
]
|
|
111
112
|
]
|
|
@@ -130,7 +131,8 @@ var consentUpdate = {
|
|
|
130
131
|
data: {
|
|
131
132
|
ad_storage: "granted",
|
|
132
133
|
analytics_storage: "granted"
|
|
133
|
-
}
|
|
134
|
+
},
|
|
135
|
+
source: { type: "dataLayer", platform: "web" }
|
|
134
136
|
}
|
|
135
137
|
]
|
|
136
138
|
]
|
|
@@ -173,7 +175,8 @@ var gtagAddToCart = {
|
|
|
173
175
|
price: 15.25
|
|
174
176
|
}
|
|
175
177
|
]
|
|
176
|
-
}
|
|
178
|
+
},
|
|
179
|
+
source: { type: "dataLayer", platform: "web" }
|
|
177
180
|
}
|
|
178
181
|
]
|
|
179
182
|
]
|
|
@@ -214,7 +217,8 @@ var gtagViewItem = {
|
|
|
214
217
|
price: 29.99
|
|
215
218
|
}
|
|
216
219
|
]
|
|
217
|
-
}
|
|
220
|
+
},
|
|
221
|
+
source: { type: "dataLayer", platform: "web" }
|
|
218
222
|
}
|
|
219
223
|
]
|
|
220
224
|
]
|
|
@@ -236,7 +240,8 @@ var directEvent = {
|
|
|
236
240
|
data: {
|
|
237
241
|
category: "engagement",
|
|
238
242
|
label: "video_play"
|
|
239
|
-
}
|
|
243
|
+
},
|
|
244
|
+
source: { type: "dataLayer", platform: "web" }
|
|
240
245
|
}
|
|
241
246
|
]
|
|
242
247
|
]
|
package/dist/examples/index.mjs
CHANGED
|
@@ -82,7 +82,8 @@ var gtagPurchase = {
|
|
|
82
82
|
value: 25.42,
|
|
83
83
|
currency: "EUR",
|
|
84
84
|
items: [{ item_id: "SKU-1", item_name: "T-Shirt", quantity: 1 }]
|
|
85
|
-
}
|
|
85
|
+
},
|
|
86
|
+
source: { type: "dataLayer", platform: "web" }
|
|
86
87
|
}
|
|
87
88
|
]
|
|
88
89
|
]
|
|
@@ -107,7 +108,8 @@ var consentUpdate = {
|
|
|
107
108
|
data: {
|
|
108
109
|
ad_storage: "granted",
|
|
109
110
|
analytics_storage: "granted"
|
|
110
|
-
}
|
|
111
|
+
},
|
|
112
|
+
source: { type: "dataLayer", platform: "web" }
|
|
111
113
|
}
|
|
112
114
|
]
|
|
113
115
|
]
|
|
@@ -150,7 +152,8 @@ var gtagAddToCart = {
|
|
|
150
152
|
price: 15.25
|
|
151
153
|
}
|
|
152
154
|
]
|
|
153
|
-
}
|
|
155
|
+
},
|
|
156
|
+
source: { type: "dataLayer", platform: "web" }
|
|
154
157
|
}
|
|
155
158
|
]
|
|
156
159
|
]
|
|
@@ -191,7 +194,8 @@ var gtagViewItem = {
|
|
|
191
194
|
price: 29.99
|
|
192
195
|
}
|
|
193
196
|
]
|
|
194
|
-
}
|
|
197
|
+
},
|
|
198
|
+
source: { type: "dataLayer", platform: "web" }
|
|
195
199
|
}
|
|
196
200
|
]
|
|
197
201
|
]
|
|
@@ -213,7 +217,8 @@ var directEvent = {
|
|
|
213
217
|
data: {
|
|
214
218
|
category: "engagement",
|
|
215
219
|
label: "video_play"
|
|
216
|
-
}
|
|
220
|
+
},
|
|
221
|
+
source: { type: "dataLayer", platform: "web" }
|
|
217
222
|
}
|
|
218
223
|
]
|
|
219
224
|
]
|
package/dist/index.browser.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var Destination=(()=>{var r=Object.defineProperty,t=Object.getOwnPropertyDescriptor,
|
|
1
|
+
"use strict";var Destination=(()=>{var r=Object.defineProperty,t=Object.getOwnPropertyDescriptor,e=Object.getOwnPropertyNames,n=Object.prototype.hasOwnProperty,o={};((t,e)=>{for(var n in e)r(t,n,{get:e[n],enumerable:!0})})(o,{SourceDataLayer:()=>A,default:()=>j,sourceDataLayer:()=>L});var a=Object.defineProperty,u=(r,t)=>{for(var e in t)a(r,e,{get:t[e],enumerable:!0})};function i(r,t){if("collector"===r)return"collector";if(!t)throw new Error(`stepId(${r}) requires an id`);return`${r}.${t}`}u({},{stepId:()=>i});function f(r,t){const e=r.destinations[t];if(!e)throw new Error(`Destination not found: ${t}`);return e}u({},{getDestination:()=>f});u({},{Level:()=>c});var l,c=((l=c||{})[l.ERROR=0]="ERROR",l[l.WARN=1]="WARN",l[l.INFO=2]="INFO",l[l.DEBUG=3]="DEBUG",l);function s(r,t){const e=r.transformers[t];if(!e)throw new Error(`Transformer not found: ${t}`);return e}u({},{getTransformer:()=>s});function y(r,t){const e=r.sources[t];if(!e)throw new Error(`Source not found: ${t}`);return e}u({},{getSource:()=>y});function d(r,t){const e=r.stores[t];if(!e)throw new Error(`Store not found: ${t}`);return e}async function g(r,t){return await r.get(t)}function p(r){return Array.isArray(r)}function b(r){return"object"==typeof r&&null!==r&&!p(r)&&"[object Object]"===Object.prototype.toString.call(r)}function m(r){return"string"==typeof r}function w(r,t,e){return function(...n){try{return r(...n)}catch(r){if(!t)return;return t(r)}finally{null==e||e()}}}u({},{getStore:()=>d,getStoreValue:()=>g});var h=!1;function v(r,t={},e){if(t.filter){if(!0===w(()=>t.filter(e),()=>!1)())return}const n=function(r){if(b(r)&&m(r.event)){const{event:t,...e}=r;return{name:t,...e}}if(p(r)&&r.length>=2)return $(r);if(t=r,null!=t&&"object"==typeof t&&"length"in t&&"number"==typeof t.length&&t.length>0){return $(Array.from(r))}var t;return null}(e);if(!n)return;const o=`${t.prefix||"dataLayer"} ${n.name}`,{name:a,...u}=n,i={name:o,data:u,source:{type:"dataLayer",platform:"web"}};w(()=>r(i),()=>{})()}function $(r){const[t,e,n]=r;if(!m(t))return null;let o,a={};switch(t){case"consent":if(!m(e)||r.length<3)return null;if("default"!==e&&"update"!==e)return null;if(!b(n)||null===n)return null;o=`${t} ${e}`,a={...n};break;case"event":if(!m(e))return null;o=e,b(n)&&(a={...n});break;case"config":if(!m(e))return null;o=`${t} ${e}`,b(n)&&(a={...n});break;case"set":if(m(e))o=`${t} ${e}`,b(n)&&(a={...n});else{if(!b(e))return null;o=`${t} custom`,a={...e}}break;default:return null}return{name:o,...a}}var O,A={},L=async r=>{const{config:t,env:e}=r,{elb:n,push:o,window:a}=e,u={name:"dataLayer",prefix:"dataLayer",...null==t?void 0:t.settings},i={settings:u};let f=0;return{type:"dataLayer",config:i,push:n,on:async r=>{if("run"===r&&a&&f>0){!function(r,t,e,n=globalThis.window){const o=t.settings,a=n[(null==o?void 0:o.name)||"dataLayer"];if(Array.isArray(a)&&!h){h=!0;try{const t=null!=e?e:a.length;for(let e=0;e<t;e++)v(r,o,a[e])}finally{h=!1}}}(o,i,f,a),f=0}},init:()=>{if(!a)return;const r=u.name||"dataLayer",t=a[r];f=Array.isArray(t)?t.length:0;!function(r,t,e=globalThis.window){const n=t.settings,o=(null==n?void 0:n.name)||"dataLayer";e[o]||(e[o]=[]);const a=e[o];if(!Array.isArray(a))return;const u=a.push.bind(a);a.push=function(...t){if(h)return u(...t);h=!0;try{for(const e of t)v(r,n,e)}finally{h=!1}return u(...t)}}(o,i,a)},destroy:async()=>{const r=u.name||"dataLayer";a&&a[r]&&Array.isArray(a[r])}}},j=L;return O=o,((o,a,u,i)=>{if(a&&"object"==typeof a||"function"==typeof a)for(let f of e(a))n.call(o,f)||f===u||r(o,f,{get:()=>a[f],enumerable:!(i=t(a,f))||i.enumerable});return o})(r({},"__esModule",{value:!0}),O)})();
|
package/dist/index.es5.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";function _array_like_to_array(r,t){(null==t||t>r.length)&&(t=r.length);for(var e=0,n=new Array(t);e<t;e++)n[e]=r[e];return n}function _array_with_holes(r){if(Array.isArray(r))return r}function _array_without_holes(r){if(Array.isArray(r))return _array_like_to_array(r)}function asyncGeneratorStep(r,t,e,n,o,a,u){try{var i=r[a](u),c=i.value}catch(r){return void e(r)}i.done?t(c):Promise.resolve(c).then(n,o)}function _async_to_generator(r){return function(){var t=this,e=arguments;return new Promise(function(n,o){var a=r.apply(t,e);function u(r){asyncGeneratorStep(a,n,o,u,i,"next",r)}function i(r){asyncGeneratorStep(a,n,o,u,i,"throw",r)}u(void 0)})}}function _define_property(r,t,e){return t in r?Object.defineProperty(r,t,{value:e,enumerable:!0,configurable:!0,writable:!0}):r[t]=e,r}function _iterable_to_array(r){if("undefined"!=typeof Symbol&&null!=r[Symbol.iterator]||null!=r["@@iterator"])return Array.from(r)}function _iterable_to_array_limit(r,t){var e=null==r?null:"undefined"!=typeof Symbol&&r[Symbol.iterator]||r["@@iterator"];if(null!=e){var n,o,a=[],u=!0,i=!1;try{for(e=e.call(r);!(u=(n=e.next()).done)&&(a.push(n.value),!t||a.length!==t);u=!0);}catch(r){i=!0,o=r}finally{try{u||null==e.return||e.return()}finally{if(i)throw o}}return a}}function _non_iterable_rest(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _non_iterable_spread(){throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _object_spread(r){for(var t=1;t<arguments.length;t++){var e=null!=arguments[t]?arguments[t]:{},n=Object.keys(e);"function"==typeof Object.getOwnPropertySymbols&&(n=n.concat(Object.getOwnPropertySymbols(e).filter(function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),n.forEach(function(t){_define_property(r,t,e[t])})}return r}function _object_without_properties(r,t){if(null==r)return{};var e,n,o,a={};if("undefined"!=typeof Reflect&&Reflect.ownKeys){for(e=Reflect.ownKeys(Object(r)),o=0;o<e.length;o++)n=e[o],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(r,n)&&(a[n]=r[n]);return a}if(a=_object_without_properties_loose(r,t),Object.getOwnPropertySymbols)for(e=Object.getOwnPropertySymbols(r),o=0;o<e.length;o++)n=e[o],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(r,n)&&(a[n]=r[n]);return a}function _object_without_properties_loose(r,t){if(null==r)return{};var e,n,o={},a=Object.getOwnPropertyNames(r);for(n=0;n<a.length;n++)e=a[n],t.indexOf(e)>=0||Object.prototype.propertyIsEnumerable.call(r,e)&&(o[e]=r[e]);return o}function _sliced_to_array(r,t){return _array_with_holes(r)||_iterable_to_array_limit(r,t)||_unsupported_iterable_to_array(r,t)||_non_iterable_rest()}function _to_consumable_array(r){return _array_without_holes(r)||_iterable_to_array(r)||_unsupported_iterable_to_array(r)||_non_iterable_spread()}function _type_of(r){return r&&"undefined"!=typeof Symbol&&r.constructor===Symbol?"symbol":typeof r}function _unsupported_iterable_to_array(r,t){if(r){if("string"==typeof r)return _array_like_to_array(r,t);var e=Object.prototype.toString.call(r).slice(8,-1);return"Object"===e&&r.constructor&&(e=r.constructor.name),"Map"===e||"Set"===e?Array.from(e):"Arguments"===e||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(e)?_array_like_to_array(r,t):void 0}}function _ts_generator(r,t){var e,n,o,a={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]},u=Object.create(("function"==typeof Iterator?Iterator:Object).prototype),i=Object.defineProperty;return i(u,"next",{value:c(0)}),i(u,"throw",{value:c(1)}),i(u,"return",{value:c(2)}),"function"==typeof Symbol&&i(u,Symbol.iterator,{value:function(){return this}}),u;function c(i){return function(c){return function(i){if(e)throw new TypeError("Generator is already executing.");for(;u&&(u=0,i[0]&&(a=0)),a;)try{if(e=1,n&&(o=2&i[0]?n.return:i[0]?n.throw||((o=n.return)&&o.call(n),0):n.next)&&!(o=o.call(n,i[1])).done)return o;switch(n=0,o&&(i=[2&i[0],o.value]),i[0]){case 0:case 1:o=i;break;case 4:return a.label++,{value:i[1],done:!1};case 5:a.label++,n=i[1],i=[0];continue;case 7:i=a.ops.pop(),a.trys.pop();continue;default:if(!(o=a.trys,(o=o.length>0&&o[o.length-1])||6!==i[0]&&2!==i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]<o[3])){a.label=i[1];break}if(6===i[0]&&a.label<o[1]){a.label=o[1],o=i;break}if(o&&a.label<o[2]){a.label=o[2],a.ops.push(i);break}o[2]&&a.ops.pop(),a.trys.pop();continue}i=t.call(r,a)}catch(r){i=[6,r],n=0}finally{e=o=0}if(5&i[0])throw i[1];return{value:i[0]?i[1]:void 0,done:!0}}([i,c])}}}var Destination=function(){var r=function(r,t){if("collector"===r)return"collector";if(!t)throw new Error("stepId(".concat(r,") requires an id"));return"".concat(r,".").concat(t)},t=function(r,t){var e=r.destinations[t];if(!e)throw new Error("Destination not found: ".concat(t));return e},e=function(r,t){var e=r.transformers[t];if(!e)throw new Error("Transformer not found: ".concat(t));return e},n=function(r,t){var e=r.sources[t];if(!e)throw new Error("Source not found: ".concat(t));return e},o=function(r,t){var e=r.stores[t];if(!e)throw new Error("Store not found: ".concat(t));return e},a=function(r,t){return _async_to_generator(function(){return _ts_generator(this,function(e){switch(e.label){case 0:return[4,r.get(t)];case 1:return[2,e.sent()]}})})()},u=function(r){return Array.isArray(r)},i=function(r){return"object"==(void 0===r?"undefined":_type_of(r))&&null!==r&&!u(r)&&"[object Object]"===Object.prototype.toString.call(r)},c=function(r){return"string"==typeof r},l=function(r,t,e){return function(){for(var n=arguments.length,o=new Array(n),a=0;a<n;a++)o[a]=arguments[a];try{return r.apply(void 0,_to_consumable_array(o))}catch(r){if(!t)return;return t(r)}finally{null==e||e()}}},f=function(r){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},e=arguments.length>2?arguments[2]:void 0;if(t.filter&&!0===l(function(){return t.filter(e)},function(){return!1})())return;var n=y(e);if(n){var o=t.prefix||"dataLayer",a="".concat(o," ").concat(n.name),u=(n.name,{name:a,data:_object_without_properties(n,["name"])});l(function(){return r(u)},function(){})()}},y=function(r){if(i(r)&&c(r.event))return _object_spread({name:r.event},_object_without_properties(r,["event"]));if(u(r)&&r.length>=2)return s(r);if(_(r)){var t=Array.from(r);return s(t)}return null},s=function(r){var t,e=_sliced_to_array(r,3),n=e[0],o=e[1],a=e[2];if(!c(n))return null;var u={};switch(n){case"consent":if(!c(o)||r.length<3)return null;if("default"!==o&&"update"!==o)return null;if(!i(a)||null===a)return null;t="".concat(n," ").concat(o),u=_object_spread({},a);break;case"event":if(!c(o))return null;t=o,i(a)&&(u=_object_spread({},a));break;case"config":if(!c(o))return null;t="".concat(n," ").concat(o),i(a)&&(u=_object_spread({},a));break;case"set":if(c(o))t="".concat(n," ").concat(o),i(a)&&(u=_object_spread({},a));else{if(!i(o))return null;t="".concat(n," custom"),u=_object_spread({},o)}break;default:return null}return _object_spread({name:t},u)},_=function(r){return null!=r&&"object"===(void 0===r?"undefined":_type_of(r))&&"length"in r&&"number"==typeof r.length&&r.length>0},p=Object.defineProperty,b=Object.getOwnPropertyDescriptor,d=Object.getOwnPropertyNames,v=Object.prototype.hasOwnProperty,h={};!function(r,t){for(var e in t)p(r,e,{get:t[e],enumerable:!0})}(h,{SourceDataLayer:function(){return A},default:function(){return P},sourceDataLayer:function(){return E}});var g=Object.defineProperty,m=function(r,t){for(var e in t)g(r,e,{get:t[e],enumerable:!0})};m({},{stepId:function(){return r}});m({},{getDestination:function(){return t}});m({},{Level:function(){return j}});var w,j=((w=j||{})[w.ERROR=0]="ERROR",w[w.WARN=1]="WARN",w[w.INFO=2]="INFO",w[w.DEBUG=3]="DEBUG",w);m({},{getTransformer:function(){return e}});m({},{getSource:function(){return n}});m({},{getStore:function(){return o},getStoreValue:function(){return a}});var O,S=!1,A={},E=function(r){return _async_to_generator(function(){var t,e,n,o,a,u,i,c,l,y;return _ts_generator(this,function(s){return t=r.config,e=r.env,n=e.elb,o=e.push,a=e.window,u=_object_spread({name:"dataLayer",prefix:"dataLayer"},null==t?void 0:t.settings),c=0,l=function(){if(a){var r=u.name||"dataLayer",t=a[r];c=Array.isArray(t)?t.length:0,function(r,t){var e=arguments.length>2&&void 0!==arguments[2]?arguments[2]:globalThis.window,n=t.settings,o=(null==n?void 0:n.name)||"dataLayer";e[o]||(e[o]=[]);var a=e[o];if(Array.isArray(a)){var u=a.push.bind(a);a.push=function(){for(var t=arguments.length,e=new Array(t),o=0;o<t;o++)e[o]=arguments[o];if(S)return u.apply(void 0,_to_consumable_array(e));S=!0;try{var a=!0,i=!1,c=void 0;try{for(var l,y=e[Symbol.iterator]();!(a=(l=y.next()).done);a=!0){var s=l.value;f(r,n,s)}}catch(r){i=!0,c=r}finally{try{a||null==y.return||y.return()}finally{if(i)throw c}}}finally{S=!1}return u.apply(void 0,_to_consumable_array(e))}}}(o,i,a)}},y=function(r){return _async_to_generator(function(){return _ts_generator(this,function(t){return"run"===r&&a&&c>0&&(function(r,t,e){var n=arguments.length>3&&void 0!==arguments[3]?arguments[3]:globalThis.window,o=t.settings,a=n[(null==o?void 0:o.name)||"dataLayer"];if(Array.isArray(a)&&!S){S=!0;try{for(var u=null!=e?e:a.length,i=0;i<u;i++)f(r,o,a[i])}finally{S=!1}}}(o,i,c,a),c=0),[2]})})()},[2,{type:"dataLayer",config:i={settings:u},push:n,on:y,init:l,destroy:function(){return _async_to_generator(function(){var r;return _ts_generator(this,function(t){return r=u.name||"dataLayer",a&&a[r]&&Array.isArray(a[r]),[2]})})()}}]})})()},P=E;return O=h,function(r,t,e,n){if(t&&"object"===(void 0===t?"undefined":_type_of(t))||"function"==typeof t){var o=!0,a=!1,u=void 0;try{for(var i,c=function(){var o=i.value;v.call(r,o)||o===e||p(r,o,{get:function(){return t[o]},enumerable:!(n=b(t,o))||n.enumerable})},l=d(t)[Symbol.iterator]();!(o=(i=l.next()).done);o=!0)c()}catch(r){a=!0,u=r}finally{try{o||null==l.return||l.return()}finally{if(a)throw u}}}return r}(p({},"__esModule",{value:!0}),O)}();
|
|
1
|
+
"use strict";function _array_like_to_array(r,t){(null==t||t>r.length)&&(t=r.length);for(var e=0,n=new Array(t);e<t;e++)n[e]=r[e];return n}function _array_with_holes(r){if(Array.isArray(r))return r}function _array_without_holes(r){if(Array.isArray(r))return _array_like_to_array(r)}function asyncGeneratorStep(r,t,e,n,o,a,u){try{var i=r[a](u),c=i.value}catch(r){return void e(r)}i.done?t(c):Promise.resolve(c).then(n,o)}function _async_to_generator(r){return function(){var t=this,e=arguments;return new Promise(function(n,o){var a=r.apply(t,e);function u(r){asyncGeneratorStep(a,n,o,u,i,"next",r)}function i(r){asyncGeneratorStep(a,n,o,u,i,"throw",r)}u(void 0)})}}function _define_property(r,t,e){return t in r?Object.defineProperty(r,t,{value:e,enumerable:!0,configurable:!0,writable:!0}):r[t]=e,r}function _iterable_to_array(r){if("undefined"!=typeof Symbol&&null!=r[Symbol.iterator]||null!=r["@@iterator"])return Array.from(r)}function _iterable_to_array_limit(r,t){var e=null==r?null:"undefined"!=typeof Symbol&&r[Symbol.iterator]||r["@@iterator"];if(null!=e){var n,o,a=[],u=!0,i=!1;try{for(e=e.call(r);!(u=(n=e.next()).done)&&(a.push(n.value),!t||a.length!==t);u=!0);}catch(r){i=!0,o=r}finally{try{u||null==e.return||e.return()}finally{if(i)throw o}}return a}}function _non_iterable_rest(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _non_iterable_spread(){throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _object_spread(r){for(var t=1;t<arguments.length;t++){var e=null!=arguments[t]?arguments[t]:{},n=Object.keys(e);"function"==typeof Object.getOwnPropertySymbols&&(n=n.concat(Object.getOwnPropertySymbols(e).filter(function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),n.forEach(function(t){_define_property(r,t,e[t])})}return r}function _object_without_properties(r,t){if(null==r)return{};var e,n,o,a={};if("undefined"!=typeof Reflect&&Reflect.ownKeys){for(e=Reflect.ownKeys(Object(r)),o=0;o<e.length;o++)n=e[o],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(r,n)&&(a[n]=r[n]);return a}if(a=_object_without_properties_loose(r,t),Object.getOwnPropertySymbols)for(e=Object.getOwnPropertySymbols(r),o=0;o<e.length;o++)n=e[o],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(r,n)&&(a[n]=r[n]);return a}function _object_without_properties_loose(r,t){if(null==r)return{};var e,n,o={},a=Object.getOwnPropertyNames(r);for(n=0;n<a.length;n++)e=a[n],t.indexOf(e)>=0||Object.prototype.propertyIsEnumerable.call(r,e)&&(o[e]=r[e]);return o}function _sliced_to_array(r,t){return _array_with_holes(r)||_iterable_to_array_limit(r,t)||_unsupported_iterable_to_array(r,t)||_non_iterable_rest()}function _to_consumable_array(r){return _array_without_holes(r)||_iterable_to_array(r)||_unsupported_iterable_to_array(r)||_non_iterable_spread()}function _type_of(r){return r&&"undefined"!=typeof Symbol&&r.constructor===Symbol?"symbol":typeof r}function _unsupported_iterable_to_array(r,t){if(r){if("string"==typeof r)return _array_like_to_array(r,t);var e=Object.prototype.toString.call(r).slice(8,-1);return"Object"===e&&r.constructor&&(e=r.constructor.name),"Map"===e||"Set"===e?Array.from(e):"Arguments"===e||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(e)?_array_like_to_array(r,t):void 0}}function _ts_generator(r,t){var e,n,o,a={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]},u=Object.create(("function"==typeof Iterator?Iterator:Object).prototype),i=Object.defineProperty;return i(u,"next",{value:c(0)}),i(u,"throw",{value:c(1)}),i(u,"return",{value:c(2)}),"function"==typeof Symbol&&i(u,Symbol.iterator,{value:function(){return this}}),u;function c(i){return function(c){return function(i){if(e)throw new TypeError("Generator is already executing.");for(;u&&(u=0,i[0]&&(a=0)),a;)try{if(e=1,n&&(o=2&i[0]?n.return:i[0]?n.throw||((o=n.return)&&o.call(n),0):n.next)&&!(o=o.call(n,i[1])).done)return o;switch(n=0,o&&(i=[2&i[0],o.value]),i[0]){case 0:case 1:o=i;break;case 4:return a.label++,{value:i[1],done:!1};case 5:a.label++,n=i[1],i=[0];continue;case 7:i=a.ops.pop(),a.trys.pop();continue;default:if(!(o=a.trys,(o=o.length>0&&o[o.length-1])||6!==i[0]&&2!==i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]<o[3])){a.label=i[1];break}if(6===i[0]&&a.label<o[1]){a.label=o[1],o=i;break}if(o&&a.label<o[2]){a.label=o[2],a.ops.push(i);break}o[2]&&a.ops.pop(),a.trys.pop();continue}i=t.call(r,a)}catch(r){i=[6,r],n=0}finally{e=o=0}if(5&i[0])throw i[1];return{value:i[0]?i[1]:void 0,done:!0}}([i,c])}}}var Destination=function(){var r=function(r,t){if("collector"===r)return"collector";if(!t)throw new Error("stepId(".concat(r,") requires an id"));return"".concat(r,".").concat(t)},t=function(r,t){var e=r.destinations[t];if(!e)throw new Error("Destination not found: ".concat(t));return e},e=function(r,t){var e=r.transformers[t];if(!e)throw new Error("Transformer not found: ".concat(t));return e},n=function(r,t){var e=r.sources[t];if(!e)throw new Error("Source not found: ".concat(t));return e},o=function(r,t){var e=r.stores[t];if(!e)throw new Error("Store not found: ".concat(t));return e},a=function(r,t){return _async_to_generator(function(){return _ts_generator(this,function(e){switch(e.label){case 0:return[4,r.get(t)];case 1:return[2,e.sent()]}})})()},u=function(r){return Array.isArray(r)},i=function(r){return"object"==(void 0===r?"undefined":_type_of(r))&&null!==r&&!u(r)&&"[object Object]"===Object.prototype.toString.call(r)},c=function(r){return"string"==typeof r},l=function(r,t,e){return function(){for(var n=arguments.length,o=new Array(n),a=0;a<n;a++)o[a]=arguments[a];try{return r.apply(void 0,_to_consumable_array(o))}catch(r){if(!t)return;return t(r)}finally{null==e||e()}}},f=function(r){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},e=arguments.length>2?arguments[2]:void 0;if(t.filter&&!0===l(function(){return t.filter(e)},function(){return!1})())return;var n=y(e);if(n){var o=t.prefix||"dataLayer",a="".concat(o," ").concat(n.name),u=(n.name,{name:a,data:_object_without_properties(n,["name"]),source:{type:"dataLayer",platform:"web"}});l(function(){return r(u)},function(){})()}},y=function(r){if(i(r)&&c(r.event))return _object_spread({name:r.event},_object_without_properties(r,["event"]));if(u(r)&&r.length>=2)return s(r);if(_(r)){var t=Array.from(r);return s(t)}return null},s=function(r){var t,e=_sliced_to_array(r,3),n=e[0],o=e[1],a=e[2];if(!c(n))return null;var u={};switch(n){case"consent":if(!c(o)||r.length<3)return null;if("default"!==o&&"update"!==o)return null;if(!i(a)||null===a)return null;t="".concat(n," ").concat(o),u=_object_spread({},a);break;case"event":if(!c(o))return null;t=o,i(a)&&(u=_object_spread({},a));break;case"config":if(!c(o))return null;t="".concat(n," ").concat(o),i(a)&&(u=_object_spread({},a));break;case"set":if(c(o))t="".concat(n," ").concat(o),i(a)&&(u=_object_spread({},a));else{if(!i(o))return null;t="".concat(n," custom"),u=_object_spread({},o)}break;default:return null}return _object_spread({name:t},u)},_=function(r){return null!=r&&"object"===(void 0===r?"undefined":_type_of(r))&&"length"in r&&"number"==typeof r.length&&r.length>0},p=Object.defineProperty,b=Object.getOwnPropertyDescriptor,d=Object.getOwnPropertyNames,v=Object.prototype.hasOwnProperty,h={};!function(r,t){for(var e in t)p(r,e,{get:t[e],enumerable:!0})}(h,{SourceDataLayer:function(){return A},default:function(){return P},sourceDataLayer:function(){return E}});var g=Object.defineProperty,m=function(r,t){for(var e in t)g(r,e,{get:t[e],enumerable:!0})};m({},{stepId:function(){return r}});m({},{getDestination:function(){return t}});m({},{Level:function(){return j}});var w,j=((w=j||{})[w.ERROR=0]="ERROR",w[w.WARN=1]="WARN",w[w.INFO=2]="INFO",w[w.DEBUG=3]="DEBUG",w);m({},{getTransformer:function(){return e}});m({},{getSource:function(){return n}});m({},{getStore:function(){return o},getStoreValue:function(){return a}});var O,S=!1,A={},E=function(r){return _async_to_generator(function(){var t,e,n,o,a,u,i,c,l,y;return _ts_generator(this,function(s){return t=r.config,e=r.env,n=e.elb,o=e.push,a=e.window,u=_object_spread({name:"dataLayer",prefix:"dataLayer"},null==t?void 0:t.settings),c=0,l=function(){if(a){var r=u.name||"dataLayer",t=a[r];c=Array.isArray(t)?t.length:0,function(r,t){var e=arguments.length>2&&void 0!==arguments[2]?arguments[2]:globalThis.window,n=t.settings,o=(null==n?void 0:n.name)||"dataLayer";e[o]||(e[o]=[]);var a=e[o];if(Array.isArray(a)){var u=a.push.bind(a);a.push=function(){for(var t=arguments.length,e=new Array(t),o=0;o<t;o++)e[o]=arguments[o];if(S)return u.apply(void 0,_to_consumable_array(e));S=!0;try{var a=!0,i=!1,c=void 0;try{for(var l,y=e[Symbol.iterator]();!(a=(l=y.next()).done);a=!0){var s=l.value;f(r,n,s)}}catch(r){i=!0,c=r}finally{try{a||null==y.return||y.return()}finally{if(i)throw c}}}finally{S=!1}return u.apply(void 0,_to_consumable_array(e))}}}(o,i,a)}},y=function(r){return _async_to_generator(function(){return _ts_generator(this,function(t){return"run"===r&&a&&c>0&&(function(r,t,e){var n=arguments.length>3&&void 0!==arguments[3]?arguments[3]:globalThis.window,o=t.settings,a=n[(null==o?void 0:o.name)||"dataLayer"];if(Array.isArray(a)&&!S){S=!0;try{for(var u=null!=e?e:a.length,i=0;i<u;i++)f(r,o,a[i])}finally{S=!1}}}(o,i,c,a),c=0),[2]})})()},[2,{type:"dataLayer",config:i={settings:u},push:n,on:y,init:l,destroy:function(){return _async_to_generator(function(){var r;return _ts_generator(this,function(t){return r=u.name||"dataLayer",a&&a[r]&&Array.isArray(a[r]),[2]})})()}}]})})()},P=E;return O=h,function(r,t,e,n){if(t&&"object"===(void 0===t?"undefined":_type_of(t))||"function"==typeof t){var o=!0,a=!1,u=void 0;try{for(var i,c=function(){var o=i.value;v.call(r,o)||o===e||p(r,o,{get:function(){return t[o]},enumerable:!(n=b(t,o))||n.enumerable})},l=d(t)[Symbol.iterator]();!(o=(i=l.next()).done);o=!0)c()}catch(r){a=!0,u=r}finally{try{o||null==l.return||l.return()}finally{if(a)throw u}}}return r}(p({},"__esModule",{value:!0}),O)}();
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var e,t=Object.defineProperty,r=Object.getOwnPropertyDescriptor,n=Object.getOwnPropertyNames,a=Object.prototype.hasOwnProperty,i={};((e,r)=>{for(var n in r)t(e,n,{get:r[n],enumerable:!0})})(i,{SourceDataLayer:()=>c,default:()=>y,sourceDataLayer:()=>f}),module.exports=(e=i,((e,i,s,l)=>{if(i&&"object"==typeof i||"function"==typeof i)for(let u of n(i))a.call(e,u)||u===s||t(e,u,{get:()=>i[u],enumerable:!(l=r(i,u))||l.enumerable});return e})(t({},"__esModule",{value:!0}),e));var s=require("@walkeros/core"),l=!1;function u(e,t={},r){if(t.filter){if(!0===(0,s.tryCatch)(()=>t.filter(r),()=>!1)())return}const n=function(e){if((0,s.isObject)(e)&&(0,s.isString)(e.event)){const{event:t,...r}=e;return{name:t,...r}}if((0,s.isArray)(e)&&e.length>=2)return o(e);if(t=e,null!=t&&"object"==typeof t&&"length"in t&&"number"==typeof t.length&&t.length>0){return o(Array.from(e))}var t;return null}(r);if(!n)return;const a=`${t.prefix||"dataLayer"} ${n.name}`,{name:i,...l}=n,u={name:a,data:l};(0,s.tryCatch)(()=>e(u),()=>{})()}function o(e){const[t,r,n]=e;if(!(0,s.isString)(t))return null;let a,i={};switch(t){case"consent":if(!(0,s.isString)(r)||e.length<3)return null;if("default"!==r&&"update"!==r)return null;if(!(0,s.isObject)(n)||null===n)return null;a=`${t} ${r}`,i={...n};break;case"event":if(!(0,s.isString)(r))return null;a=r,(0,s.isObject)(n)&&(i={...n});break;case"config":if(!(0,s.isString)(r))return null;a=`${t} ${r}`,(0,s.isObject)(n)&&(i={...n});break;case"set":if((0,s.isString)(r))a=`${t} ${r}`,(0,s.isObject)(n)&&(i={...n});else{if(!(0,s.isObject)(r))return null;a=`${t} custom`,i={...r}}break;default:return null}return{name:a,...i}}var c={},f=async e=>{const{config:t,env:r}=e,{elb:n,push:a,window:i}=r,s={name:"dataLayer",prefix:"dataLayer",...null==t?void 0:t.settings},o={settings:s};let c=0;return{type:"dataLayer",config:o,push:n,on:async e=>{if("run"===e&&i&&c>0){!function(e,t,r,n=globalThis.window){const a=t.settings,i=n[(null==a?void 0:a.name)||"dataLayer"];if(Array.isArray(i)&&!l){l=!0;try{const t=null!=r?r:i.length;for(let r=0;r<t;r++)u(e,a,i[r])}finally{l=!1}}}(a,o,c,i),c=0}},init:()=>{if(!i)return;const e=s.name||"dataLayer",t=i[e];c=Array.isArray(t)?t.length:0;!function(e,t,r=globalThis.window){const n=t.settings,a=(null==n?void 0:n.name)||"dataLayer";r[a]||(r[a]=[]);const i=r[a];if(!Array.isArray(i))return;const s=i.push.bind(i);i.push=function(...t){if(l)return s(...t);l=!0;try{for(const r of t)u(e,n,r)}finally{l=!1}return s(...t)}}(a,o,i)},destroy:async()=>{const e=s.name||"dataLayer";i&&i[e]&&Array.isArray(i[e])}}},y=f;//# sourceMappingURL=index.js.map
|
|
1
|
+
"use strict";var e,t=Object.defineProperty,r=Object.getOwnPropertyDescriptor,n=Object.getOwnPropertyNames,a=Object.prototype.hasOwnProperty,i={};((e,r)=>{for(var n in r)t(e,n,{get:r[n],enumerable:!0})})(i,{SourceDataLayer:()=>c,default:()=>y,sourceDataLayer:()=>f}),module.exports=(e=i,((e,i,s,l)=>{if(i&&"object"==typeof i||"function"==typeof i)for(let u of n(i))a.call(e,u)||u===s||t(e,u,{get:()=>i[u],enumerable:!(l=r(i,u))||l.enumerable});return e})(t({},"__esModule",{value:!0}),e));var s=require("@walkeros/core"),l=!1;function u(e,t={},r){if(t.filter){if(!0===(0,s.tryCatch)(()=>t.filter(r),()=>!1)())return}const n=function(e){if((0,s.isObject)(e)&&(0,s.isString)(e.event)){const{event:t,...r}=e;return{name:t,...r}}if((0,s.isArray)(e)&&e.length>=2)return o(e);if(t=e,null!=t&&"object"==typeof t&&"length"in t&&"number"==typeof t.length&&t.length>0){return o(Array.from(e))}var t;return null}(r);if(!n)return;const a=`${t.prefix||"dataLayer"} ${n.name}`,{name:i,...l}=n,u={name:a,data:l,source:{type:"dataLayer",platform:"web"}};(0,s.tryCatch)(()=>e(u),()=>{})()}function o(e){const[t,r,n]=e;if(!(0,s.isString)(t))return null;let a,i={};switch(t){case"consent":if(!(0,s.isString)(r)||e.length<3)return null;if("default"!==r&&"update"!==r)return null;if(!(0,s.isObject)(n)||null===n)return null;a=`${t} ${r}`,i={...n};break;case"event":if(!(0,s.isString)(r))return null;a=r,(0,s.isObject)(n)&&(i={...n});break;case"config":if(!(0,s.isString)(r))return null;a=`${t} ${r}`,(0,s.isObject)(n)&&(i={...n});break;case"set":if((0,s.isString)(r))a=`${t} ${r}`,(0,s.isObject)(n)&&(i={...n});else{if(!(0,s.isObject)(r))return null;a=`${t} custom`,i={...r}}break;default:return null}return{name:a,...i}}var c={},f=async e=>{const{config:t,env:r}=e,{elb:n,push:a,window:i}=r,s={name:"dataLayer",prefix:"dataLayer",...null==t?void 0:t.settings},o={settings:s};let c=0;return{type:"dataLayer",config:o,push:n,on:async e=>{if("run"===e&&i&&c>0){!function(e,t,r,n=globalThis.window){const a=t.settings,i=n[(null==a?void 0:a.name)||"dataLayer"];if(Array.isArray(i)&&!l){l=!0;try{const t=null!=r?r:i.length;for(let r=0;r<t;r++)u(e,a,i[r])}finally{l=!1}}}(a,o,c,i),c=0}},init:()=>{if(!i)return;const e=s.name||"dataLayer",t=i[e];c=Array.isArray(t)?t.length:0;!function(e,t,r=globalThis.window){const n=t.settings,a=(null==n?void 0:n.name)||"dataLayer";r[a]||(r[a]=[]);const i=r[a];if(!Array.isArray(i))return;const s=i.push.bind(i);i.push=function(...t){if(l)return s(...t);l=!0;try{for(const r of t)u(e,n,r)}finally{l=!1}return s(...t)}}(a,o,i)},destroy:async()=>{const e=s.name||"dataLayer";i&&i[e]&&Array.isArray(i[e])}}},y=f;//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/interceptor.ts","../src/types/index.ts"],"sourcesContent":["import type { Source, On } from '@walkeros/core';\nimport type { Types } from './types';\nimport { interceptDataLayer, processExistingEvents } from './interceptor';\n\n// Export types for external usage\nexport * as SourceDataLayer from './types';\n\n/**\n * DataLayer source implementation using environment injection.\n *\n * This source intercepts dataLayer.push calls and transforms them to WalkerOS events.\n * It works by replacing the dataLayer.push method with a custom handler.\n */\nexport const sourceDataLayer: Source.Init<Types> = async (context) => {\n const { config, env } = context;\n // Events exit via `push` (the collector's source pipeline, so this source's\n // `next`/`before`/mapping/cache/state and status apply); `elb` stays the\n // outward-facing slot on the instance below. This source emits no commands.\n const { elb, push, window: envWindow } = env;\n\n const settings: Source.Settings<Types> = {\n name: 'dataLayer',\n prefix: 'dataLayer',\n ...config?.settings,\n };\n\n const fullConfig: Source.Config<Types> = {\n settings,\n };\n\n // Captured at init time — see init below.\n let pendingReplayCount = 0;\n\n // Lifecycle setup. Called by the collector eagerly after registration,\n // regardless of `require`. The factory body above is side-effect-free.\n const init = () => {\n if (!envWindow) return;\n const dataLayerName = settings.name || 'dataLayer';\n const dl = (envWindow as Record<string, unknown>)[dataLayerName];\n pendingReplayCount = Array.isArray(dl) ? dl.length : 0;\n\n const win = envWindow as unknown as Record<string, unknown>;\n interceptDataLayer(push, fullConfig, win);\n };\n\n // Replay pre-existing entries when the run signal lands. The collector\n // strictly gates on() delivery: this fires only when the source is\n // started (`config.init === true` AND `config.require` empty). If a\n // require gate is unmet, the run event is queued in `queueOn` by\n // onApply and replayed when the source becomes started.\n const handleEvent = async (event: On.Types) => {\n if (event === 'run' && envWindow && pendingReplayCount > 0) {\n const win = envWindow as unknown as Record<string, unknown>;\n processExistingEvents(push, fullConfig, pendingReplayCount, win);\n pendingReplayCount = 0;\n }\n };\n\n return {\n type: 'dataLayer',\n config: fullConfig,\n // Deliberately `elb`, not the pipeline `push`. This slot is the source's\n // outward-facing entry (and what `startFlow` exports as its `elb` when this\n // source is primary), not the capture path: real dataLayer entries arrive\n // through the intercepted `dataLayer.push`, which routes via the pipeline.\n push: elb,\n on: handleEvent,\n init,\n destroy: async () => {\n // Cleanup: restore original dataLayer.push if possible\n const dataLayerName = settings.name || 'dataLayer';\n if (\n envWindow &&\n envWindow[dataLayerName] &&\n Array.isArray(envWindow[dataLayerName])\n ) {\n // Note: Complete restoration would require storing original push method\n // For now, we'll just document this limitation\n }\n },\n };\n};\n\nexport default sourceDataLayer;\n","import type { WalkerOS, Source, Collector } from '@walkeros/core';\nimport { isArray, isObject, isString, tryCatch } from '@walkeros/core';\n\n// Global flag to prevent infinite loops\nlet isProcessing = false;\n\n/**\n * DataLayer interceptor - handles dataLayer.push interception and event transformation\n */\nexport function interceptDataLayer(\n push: Collector.PushFn,\n config: Source.Config,\n win: Record<string, unknown> = globalThis.window as unknown as Record<\n string,\n unknown\n >,\n): void {\n const settings = config.settings as {\n name?: string;\n prefix?: string;\n filter?: (event: unknown) => boolean;\n };\n const dataLayerName = settings?.name || 'dataLayer';\n\n // Ensure dataLayer exists\n if (!win[dataLayerName]) {\n win[dataLayerName] = [];\n }\n\n const dataLayer = win[dataLayerName] as unknown[];\n if (!Array.isArray(dataLayer)) return;\n\n // Store original push\n const originalPush = dataLayer.push.bind(dataLayer);\n\n // Override push with event processing\n dataLayer.push = function (...args: unknown[]): number {\n // Prevent infinite loops\n if (isProcessing) {\n return originalPush(...args);\n }\n\n isProcessing = true;\n try {\n // Process each argument\n for (const arg of args) {\n processEvent(push, settings, arg);\n }\n } finally {\n isProcessing = false;\n }\n\n // Call original push\n return originalPush(...args);\n };\n}\n\n/**\n * Process existing events on initialization\n */\nexport function processExistingEvents(\n push: Collector.PushFn,\n config: Source.Config,\n limit?: number,\n win: Record<string, unknown> = globalThis.window as unknown as Record<\n string,\n unknown\n >,\n): void {\n const settings = config.settings as {\n name?: string;\n prefix?: string;\n filter?: (event: unknown) => boolean;\n };\n const dataLayerName = settings?.name || 'dataLayer';\n const dataLayer = win[dataLayerName] as unknown[];\n\n if (!Array.isArray(dataLayer)) return;\n\n // Prevent loops during initialization\n if (isProcessing) return;\n\n isProcessing = true;\n try {\n const count = limit ?? dataLayer.length;\n for (let i = 0; i < count; i++) {\n processEvent(push, settings, dataLayer[i]);\n }\n } finally {\n isProcessing = false;\n }\n}\n\n/**\n * Process a single event - handles filtering, transformation, and WalkerOS event creation\n */\nfunction processEvent(\n push: Collector.PushFn,\n settings: { prefix?: string; filter?: (event: unknown) => boolean } = {},\n rawEvent: unknown,\n): void {\n // Apply filter if provided\n if (settings.filter) {\n const filterFn = tryCatch(\n () => settings.filter!(rawEvent),\n () => false, // If filter throws, don't skip the event\n );\n const filterResult = filterFn();\n if (filterResult === true) {\n return; // Skip filtered events\n }\n }\n\n // Transform the event (handles gtag format and direct objects)\n const transformedEvent = transformDataLayerEvent(rawEvent);\n if (!transformedEvent) {\n return; // Skip invalid events\n }\n\n const prefix = settings.prefix || 'dataLayer';\n const eventName = `${prefix} ${transformedEvent.name}`;\n\n // Create partial WalkerOS event structure (collector will enrich it)\n const { name: _name, ...data } = transformedEvent;\n const partialEvent: WalkerOS.DeepPartialEvent = {\n name: eventName,\n data: data as WalkerOS.Properties,\n };\n\n // Push to collector\n tryCatch(\n () => push(partialEvent),\n () => {}, // Silently handle push errors\n )();\n}\n\n/**\n * Transform dataLayer events to standardized format\n * Handles: gtag arguments, direct objects, existing events\n */\nfunction transformDataLayerEvent(\n rawEvent: unknown,\n): { name: string; [key: string]: unknown } | null {\n // Handle direct object format: { event: 'test', data: 'value' }\n if (isObject(rawEvent) && isString(rawEvent.event)) {\n const { event, ...rest } = rawEvent;\n return { name: event, ...rest };\n }\n\n // Handle gtag argument format: ['consent', 'update', { ad_storage: 'granted' }]\n if (isArray(rawEvent) && rawEvent.length >= 2) {\n return transformGtagArgs(rawEvent);\n }\n\n // Handle arguments object (from gtag function calls)\n if (isGtagArguments(rawEvent)) {\n const argsArray = Array.from(rawEvent as ArrayLike<unknown>);\n return transformGtagArgs(argsArray);\n }\n\n return null;\n}\n\n/**\n * Transform gtag-style arguments to event object\n * ['consent', 'update', { ad_storage: 'granted' }] → { event: 'consent update', ad_storage: 'granted' }\n */\nfunction transformGtagArgs(\n args: unknown[],\n): { name: string; [key: string]: unknown } | null {\n const [command, action, params] = args;\n\n if (!isString(command)) return null;\n\n let eventName: string;\n let eventData: Record<string, unknown> = {};\n\n switch (command) {\n case 'consent':\n // Consent requires action and params\n if (!isString(action) || args.length < 3) return null;\n // Only allow 'default' and 'update' actions for consent\n if (action !== 'default' && action !== 'update') return null;\n // Params must be a valid object (not null)\n if (!isObject(params) || params === null) return null;\n\n eventName = `${command} ${action}`;\n eventData = { ...params };\n break;\n\n case 'event':\n // Event requires at least action parameter\n if (!isString(action)) return null;\n eventName = action;\n if (isObject(params)) {\n eventData = { ...params };\n }\n break;\n\n case 'config':\n // Config requires at least action parameter\n if (!isString(action)) return null;\n eventName = `${command} ${action}`;\n if (isObject(params)) {\n eventData = { ...params };\n }\n break;\n\n case 'set':\n if (isString(action)) {\n eventName = `${command} ${action}`;\n if (isObject(params)) {\n eventData = { ...params };\n }\n } else if (isObject(action)) {\n eventName = `${command} custom`;\n eventData = { ...action };\n } else {\n return null;\n }\n break;\n\n default:\n // Unknown command, ignore\n return null;\n }\n\n return {\n name: eventName,\n ...eventData,\n };\n}\n\n/**\n * Check if object is gtag arguments object\n */\nfunction isGtagArguments(obj: unknown): boolean {\n return (\n obj != null &&\n typeof obj === 'object' &&\n 'length' in obj &&\n typeof (obj as ArrayLike<unknown>).length === 'number' &&\n (obj as ArrayLike<unknown>).length > 0\n );\n}\n","import type { WalkerOS, Source, Elb } from '@walkeros/core';\nimport type { SettingsSchema, Mapping } from '../schemas';\nimport type { z } from '@walkeros/core/dev';\n\ndeclare module '@walkeros/core' {\n interface SourceMap {\n dataLayer: { type: 'dataLayer'; platform?: 'web' };\n }\n}\n\ndeclare global {\n interface Window {\n dataLayer?: DataLayer;\n [key: string]: DataLayer | unknown;\n }\n}\n\nexport type DataLayer = Array<unknown>;\n\n// Base settings from Zod schema\ntype BaseSettings = z.infer<typeof SettingsSchema>;\n\n// Override filter to be actual function type (not serializable in schema)\nexport interface Settings extends Omit<BaseSettings, 'filter'> {\n name?: string;\n prefix?: string;\n filter?: (event: unknown) => WalkerOS.PromiseOrValue<boolean>;\n}\n\n// InitSettings: user input (all optional)\nexport type InitSettings = Partial<Settings>;\n\nexport type { Mapping };\n\nexport type Push = Elb.Fn;\n\nexport interface Env extends Source.BaseEnv {\n window?: Window & typeof globalThis;\n}\n\nexport type Types = Source.Types<Settings, Mapping, Push, Env, InitSettings>;\n\nexport type Config = Source.Config<Types>;\n\nexport type DataLayerEvent = {\n event: string;\n [key: string]: unknown;\n};\n\nexport type MappedEvent = {\n event?: WalkerOS.DeepPartialEvent & { id: string };\n command?: {\n name: string;\n data: unknown;\n };\n};\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/interceptor.ts","../src/types/index.ts"],"sourcesContent":["import type { Source, On } from '@walkeros/core';\nimport type { Types } from './types';\nimport { interceptDataLayer, processExistingEvents } from './interceptor';\n\n// Export types for external usage\nexport * as SourceDataLayer from './types';\n\n/**\n * DataLayer source implementation using environment injection.\n *\n * This source intercepts dataLayer.push calls and transforms them to WalkerOS events.\n * It works by replacing the dataLayer.push method with a custom handler.\n */\nexport const sourceDataLayer: Source.Init<Types> = async (context) => {\n const { config, env } = context;\n // Events exit via `push` (the collector's source pipeline, so this source's\n // `next`/`before`/mapping/cache/state and status apply); `elb` stays the\n // outward-facing slot on the instance below. This source emits no commands.\n const { elb, push, window: envWindow } = env;\n\n const settings: Source.Settings<Types> = {\n name: 'dataLayer',\n prefix: 'dataLayer',\n ...config?.settings,\n };\n\n const fullConfig: Source.Config<Types> = {\n settings,\n };\n\n // Captured at init time — see init below.\n let pendingReplayCount = 0;\n\n // Lifecycle setup. Called by the collector eagerly after registration,\n // regardless of `require`. The factory body above is side-effect-free.\n const init = () => {\n if (!envWindow) return;\n const dataLayerName = settings.name || 'dataLayer';\n const dl = (envWindow as Record<string, unknown>)[dataLayerName];\n pendingReplayCount = Array.isArray(dl) ? dl.length : 0;\n\n const win = envWindow as unknown as Record<string, unknown>;\n interceptDataLayer(push, fullConfig, win);\n };\n\n // Replay pre-existing entries when the run signal lands. The collector\n // strictly gates on() delivery: this fires only when the source is\n // started (`config.init === true` AND `config.require` empty). If a\n // require gate is unmet, the run event is queued in `queueOn` by\n // onApply and replayed when the source becomes started.\n const handleEvent = async (event: On.Types) => {\n if (event === 'run' && envWindow && pendingReplayCount > 0) {\n const win = envWindow as unknown as Record<string, unknown>;\n processExistingEvents(push, fullConfig, pendingReplayCount, win);\n pendingReplayCount = 0;\n }\n };\n\n return {\n type: 'dataLayer',\n config: fullConfig,\n // Deliberately `elb`, not the pipeline `push`. This slot is the source's\n // outward-facing entry (and what `startFlow` exports as its `elb` when this\n // source is primary), not the capture path: real dataLayer entries arrive\n // through the intercepted `dataLayer.push`, which routes via the pipeline.\n push: elb,\n on: handleEvent,\n init,\n destroy: async () => {\n // Cleanup: restore original dataLayer.push if possible\n const dataLayerName = settings.name || 'dataLayer';\n if (\n envWindow &&\n envWindow[dataLayerName] &&\n Array.isArray(envWindow[dataLayerName])\n ) {\n // Note: Complete restoration would require storing original push method\n // For now, we'll just document this limitation\n }\n },\n };\n};\n\nexport default sourceDataLayer;\n","import type { WalkerOS, Source, Collector } from '@walkeros/core';\nimport { isArray, isObject, isString, tryCatch } from '@walkeros/core';\n\n// Global flag to prevent infinite loops\nlet isProcessing = false;\n\n/**\n * DataLayer interceptor - handles dataLayer.push interception and event transformation\n */\nexport function interceptDataLayer(\n push: Collector.PushFn,\n config: Source.Config,\n win: Record<string, unknown> = globalThis.window as unknown as Record<\n string,\n unknown\n >,\n): void {\n const settings = config.settings as {\n name?: string;\n prefix?: string;\n filter?: (event: unknown) => boolean;\n };\n const dataLayerName = settings?.name || 'dataLayer';\n\n // Ensure dataLayer exists\n if (!win[dataLayerName]) {\n win[dataLayerName] = [];\n }\n\n const dataLayer = win[dataLayerName] as unknown[];\n if (!Array.isArray(dataLayer)) return;\n\n // Store original push\n const originalPush = dataLayer.push.bind(dataLayer);\n\n // Override push with event processing\n dataLayer.push = function (...args: unknown[]): number {\n // Prevent infinite loops\n if (isProcessing) {\n return originalPush(...args);\n }\n\n isProcessing = true;\n try {\n // Process each argument\n for (const arg of args) {\n processEvent(push, settings, arg);\n }\n } finally {\n isProcessing = false;\n }\n\n // Call original push\n return originalPush(...args);\n };\n}\n\n/**\n * Process existing events on initialization\n */\nexport function processExistingEvents(\n push: Collector.PushFn,\n config: Source.Config,\n limit?: number,\n win: Record<string, unknown> = globalThis.window as unknown as Record<\n string,\n unknown\n >,\n): void {\n const settings = config.settings as {\n name?: string;\n prefix?: string;\n filter?: (event: unknown) => boolean;\n };\n const dataLayerName = settings?.name || 'dataLayer';\n const dataLayer = win[dataLayerName] as unknown[];\n\n if (!Array.isArray(dataLayer)) return;\n\n // Prevent loops during initialization\n if (isProcessing) return;\n\n isProcessing = true;\n try {\n const count = limit ?? dataLayer.length;\n for (let i = 0; i < count; i++) {\n processEvent(push, settings, dataLayer[i]);\n }\n } finally {\n isProcessing = false;\n }\n}\n\n/**\n * Process a single event - handles filtering, transformation, and WalkerOS event creation\n */\nfunction processEvent(\n push: Collector.PushFn,\n settings: { prefix?: string; filter?: (event: unknown) => boolean } = {},\n rawEvent: unknown,\n): void {\n // Apply filter if provided\n if (settings.filter) {\n const filterFn = tryCatch(\n () => settings.filter!(rawEvent),\n () => false, // If filter throws, don't skip the event\n );\n const filterResult = filterFn();\n if (filterResult === true) {\n return; // Skip filtered events\n }\n }\n\n // Transform the event (handles gtag format and direct objects)\n const transformedEvent = transformDataLayerEvent(rawEvent);\n if (!transformedEvent) {\n return; // Skip invalid events\n }\n\n const prefix = settings.prefix || 'dataLayer';\n const eventName = `${prefix} ${transformedEvent.name}`;\n\n // Create partial WalkerOS event structure (collector will enrich it).\n // The source identity is stamped here: without it the collector falls back to\n // `type: 'collector'`, and destinations that echo events back into the\n // dataLayer lose the `source.type !== 'dataLayer'` guard against feedback loops.\n const { name: _name, ...data } = transformedEvent;\n const partialEvent: WalkerOS.DeepPartialEvent = {\n name: eventName,\n data: data as WalkerOS.Properties,\n source: { type: 'dataLayer', platform: 'web' },\n };\n\n // Push to collector\n tryCatch(\n () => push(partialEvent),\n () => {}, // Silently handle push errors\n )();\n}\n\n/**\n * Transform dataLayer events to standardized format\n * Handles: gtag arguments, direct objects, existing events\n */\nfunction transformDataLayerEvent(\n rawEvent: unknown,\n): { name: string; [key: string]: unknown } | null {\n // Handle direct object format: { event: 'test', data: 'value' }\n if (isObject(rawEvent) && isString(rawEvent.event)) {\n const { event, ...rest } = rawEvent;\n return { name: event, ...rest };\n }\n\n // Handle gtag argument format: ['consent', 'update', { ad_storage: 'granted' }]\n if (isArray(rawEvent) && rawEvent.length >= 2) {\n return transformGtagArgs(rawEvent);\n }\n\n // Handle arguments object (from gtag function calls)\n if (isGtagArguments(rawEvent)) {\n const argsArray = Array.from(rawEvent as ArrayLike<unknown>);\n return transformGtagArgs(argsArray);\n }\n\n return null;\n}\n\n/**\n * Transform gtag-style arguments to event object\n * ['consent', 'update', { ad_storage: 'granted' }] → { event: 'consent update', ad_storage: 'granted' }\n */\nfunction transformGtagArgs(\n args: unknown[],\n): { name: string; [key: string]: unknown } | null {\n const [command, action, params] = args;\n\n if (!isString(command)) return null;\n\n let eventName: string;\n let eventData: Record<string, unknown> = {};\n\n switch (command) {\n case 'consent':\n // Consent requires action and params\n if (!isString(action) || args.length < 3) return null;\n // Only allow 'default' and 'update' actions for consent\n if (action !== 'default' && action !== 'update') return null;\n // Params must be a valid object (not null)\n if (!isObject(params) || params === null) return null;\n\n eventName = `${command} ${action}`;\n eventData = { ...params };\n break;\n\n case 'event':\n // Event requires at least action parameter\n if (!isString(action)) return null;\n eventName = action;\n if (isObject(params)) {\n eventData = { ...params };\n }\n break;\n\n case 'config':\n // Config requires at least action parameter\n if (!isString(action)) return null;\n eventName = `${command} ${action}`;\n if (isObject(params)) {\n eventData = { ...params };\n }\n break;\n\n case 'set':\n if (isString(action)) {\n eventName = `${command} ${action}`;\n if (isObject(params)) {\n eventData = { ...params };\n }\n } else if (isObject(action)) {\n eventName = `${command} custom`;\n eventData = { ...action };\n } else {\n return null;\n }\n break;\n\n default:\n // Unknown command, ignore\n return null;\n }\n\n return {\n name: eventName,\n ...eventData,\n };\n}\n\n/**\n * Check if object is gtag arguments object\n */\nfunction isGtagArguments(obj: unknown): boolean {\n return (\n obj != null &&\n typeof obj === 'object' &&\n 'length' in obj &&\n typeof (obj as ArrayLike<unknown>).length === 'number' &&\n (obj as ArrayLike<unknown>).length > 0\n );\n}\n","import type { WalkerOS, Source, Elb } from '@walkeros/core';\nimport type { SettingsSchema, Mapping } from '../schemas';\nimport type { z } from '@walkeros/core/dev';\n\ndeclare module '@walkeros/core' {\n interface SourceMap {\n dataLayer: { type: 'dataLayer'; platform?: 'web' };\n }\n}\n\ndeclare global {\n interface Window {\n dataLayer?: DataLayer;\n [key: string]: DataLayer | unknown;\n }\n}\n\nexport type DataLayer = Array<unknown>;\n\n// Base settings from Zod schema\ntype BaseSettings = z.infer<typeof SettingsSchema>;\n\n// Override filter to be actual function type (not serializable in schema)\nexport interface Settings extends Omit<BaseSettings, 'filter'> {\n name?: string;\n prefix?: string;\n filter?: (event: unknown) => WalkerOS.PromiseOrValue<boolean>;\n}\n\n// InitSettings: user input (all optional)\nexport type InitSettings = Partial<Settings>;\n\nexport type { Mapping };\n\nexport type Push = Elb.Fn;\n\nexport interface Env extends Source.BaseEnv {\n window?: Window & typeof globalThis;\n}\n\nexport type Types = Source.Types<Settings, Mapping, Push, Env, InitSettings>;\n\nexport type Config = Source.Config<Types>;\n\nexport type DataLayerEvent = {\n event: string;\n [key: string]: unknown;\n};\n\nexport type MappedEvent = {\n event?: WalkerOS.DeepPartialEvent & { id: string };\n command?: {\n name: string;\n data: unknown;\n };\n};\n"],"mappings":"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","names":[]}
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{isArray as n,isObject as
|
|
1
|
+
import{isArray as n,isObject as e,isString as r,tryCatch as t}from"@walkeros/core";var a=!1;function l(a,l={},u){if(l.filter){if(!0===t(()=>l.filter(u),()=>!1)())return}const o=function(t){if(e(t)&&r(t.event)){const{event:n,...e}=t;return{name:n,...e}}if(n(t)&&t.length>=2)return i(t);if(a=t,null!=a&&"object"==typeof a&&"length"in a&&"number"==typeof a.length&&a.length>0){return i(Array.from(t))}var a;return null}(u);if(!o)return;const s=`${l.prefix||"dataLayer"} ${o.name}`,{name:f,...c}=o,y={name:s,data:c,source:{type:"dataLayer",platform:"web"}};t(()=>a(y),()=>{})()}function i(n){const[t,a,l]=n;if(!r(t))return null;let i,u={};switch(t){case"consent":if(!r(a)||n.length<3)return null;if("default"!==a&&"update"!==a)return null;if(!e(l)||null===l)return null;i=`${t} ${a}`,u={...l};break;case"event":if(!r(a))return null;i=a,e(l)&&(u={...l});break;case"config":if(!r(a))return null;i=`${t} ${a}`,e(l)&&(u={...l});break;case"set":if(r(a))i=`${t} ${a}`,e(l)&&(u={...l});else{if(!e(a))return null;i=`${t} custom`,u={...a}}break;default:return null}return{name:i,...u}}var u={},o=async n=>{const{config:e,env:r}=n,{elb:t,push:i,window:u}=r,o={name:"dataLayer",prefix:"dataLayer",...null==e?void 0:e.settings},s={settings:o};let f=0;return{type:"dataLayer",config:s,push:t,on:async n=>{if("run"===n&&u&&f>0){!function(n,e,r,t=globalThis.window){const i=e.settings,u=t[(null==i?void 0:i.name)||"dataLayer"];if(Array.isArray(u)&&!a){a=!0;try{const e=null!=r?r:u.length;for(let r=0;r<e;r++)l(n,i,u[r])}finally{a=!1}}}(i,s,f,u),f=0}},init:()=>{if(!u)return;const n=o.name||"dataLayer",e=u[n];f=Array.isArray(e)?e.length:0;!function(n,e,r=globalThis.window){const t=e.settings,i=(null==t?void 0:t.name)||"dataLayer";r[i]||(r[i]=[]);const u=r[i];if(!Array.isArray(u))return;const o=u.push.bind(u);u.push=function(...e){if(a)return o(...e);a=!0;try{for(const r of e)l(n,t,r)}finally{a=!1}return o(...e)}}(i,s,u)},destroy:async()=>{const n=o.name||"dataLayer";u&&u[n]&&Array.isArray(u[n])}}},s=o;export{u as SourceDataLayer,s as default,o as sourceDataLayer};//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/interceptor.ts","../src/types/index.ts","../src/index.ts"],"sourcesContent":["import type { WalkerOS, Source, Collector } from '@walkeros/core';\nimport { isArray, isObject, isString, tryCatch } from '@walkeros/core';\n\n// Global flag to prevent infinite loops\nlet isProcessing = false;\n\n/**\n * DataLayer interceptor - handles dataLayer.push interception and event transformation\n */\nexport function interceptDataLayer(\n push: Collector.PushFn,\n config: Source.Config,\n win: Record<string, unknown> = globalThis.window as unknown as Record<\n string,\n unknown\n >,\n): void {\n const settings = config.settings as {\n name?: string;\n prefix?: string;\n filter?: (event: unknown) => boolean;\n };\n const dataLayerName = settings?.name || 'dataLayer';\n\n // Ensure dataLayer exists\n if (!win[dataLayerName]) {\n win[dataLayerName] = [];\n }\n\n const dataLayer = win[dataLayerName] as unknown[];\n if (!Array.isArray(dataLayer)) return;\n\n // Store original push\n const originalPush = dataLayer.push.bind(dataLayer);\n\n // Override push with event processing\n dataLayer.push = function (...args: unknown[]): number {\n // Prevent infinite loops\n if (isProcessing) {\n return originalPush(...args);\n }\n\n isProcessing = true;\n try {\n // Process each argument\n for (const arg of args) {\n processEvent(push, settings, arg);\n }\n } finally {\n isProcessing = false;\n }\n\n // Call original push\n return originalPush(...args);\n };\n}\n\n/**\n * Process existing events on initialization\n */\nexport function processExistingEvents(\n push: Collector.PushFn,\n config: Source.Config,\n limit?: number,\n win: Record<string, unknown> = globalThis.window as unknown as Record<\n string,\n unknown\n >,\n): void {\n const settings = config.settings as {\n name?: string;\n prefix?: string;\n filter?: (event: unknown) => boolean;\n };\n const dataLayerName = settings?.name || 'dataLayer';\n const dataLayer = win[dataLayerName] as unknown[];\n\n if (!Array.isArray(dataLayer)) return;\n\n // Prevent loops during initialization\n if (isProcessing) return;\n\n isProcessing = true;\n try {\n const count = limit ?? dataLayer.length;\n for (let i = 0; i < count; i++) {\n processEvent(push, settings, dataLayer[i]);\n }\n } finally {\n isProcessing = false;\n }\n}\n\n/**\n * Process a single event - handles filtering, transformation, and WalkerOS event creation\n */\nfunction processEvent(\n push: Collector.PushFn,\n settings: { prefix?: string; filter?: (event: unknown) => boolean } = {},\n rawEvent: unknown,\n): void {\n // Apply filter if provided\n if (settings.filter) {\n const filterFn = tryCatch(\n () => settings.filter!(rawEvent),\n () => false, // If filter throws, don't skip the event\n );\n const filterResult = filterFn();\n if (filterResult === true) {\n return; // Skip filtered events\n }\n }\n\n // Transform the event (handles gtag format and direct objects)\n const transformedEvent = transformDataLayerEvent(rawEvent);\n if (!transformedEvent) {\n return; // Skip invalid events\n }\n\n const prefix = settings.prefix || 'dataLayer';\n const eventName = `${prefix} ${transformedEvent.name}`;\n\n // Create partial WalkerOS event structure (collector will enrich it)\n const { name: _name, ...data } = transformedEvent;\n const partialEvent: WalkerOS.DeepPartialEvent = {\n name: eventName,\n data: data as WalkerOS.Properties,\n };\n\n // Push to collector\n tryCatch(\n () => push(partialEvent),\n () => {}, // Silently handle push errors\n )();\n}\n\n/**\n * Transform dataLayer events to standardized format\n * Handles: gtag arguments, direct objects, existing events\n */\nfunction transformDataLayerEvent(\n rawEvent: unknown,\n): { name: string; [key: string]: unknown } | null {\n // Handle direct object format: { event: 'test', data: 'value' }\n if (isObject(rawEvent) && isString(rawEvent.event)) {\n const { event, ...rest } = rawEvent;\n return { name: event, ...rest };\n }\n\n // Handle gtag argument format: ['consent', 'update', { ad_storage: 'granted' }]\n if (isArray(rawEvent) && rawEvent.length >= 2) {\n return transformGtagArgs(rawEvent);\n }\n\n // Handle arguments object (from gtag function calls)\n if (isGtagArguments(rawEvent)) {\n const argsArray = Array.from(rawEvent as ArrayLike<unknown>);\n return transformGtagArgs(argsArray);\n }\n\n return null;\n}\n\n/**\n * Transform gtag-style arguments to event object\n * ['consent', 'update', { ad_storage: 'granted' }] → { event: 'consent update', ad_storage: 'granted' }\n */\nfunction transformGtagArgs(\n args: unknown[],\n): { name: string; [key: string]: unknown } | null {\n const [command, action, params] = args;\n\n if (!isString(command)) return null;\n\n let eventName: string;\n let eventData: Record<string, unknown> = {};\n\n switch (command) {\n case 'consent':\n // Consent requires action and params\n if (!isString(action) || args.length < 3) return null;\n // Only allow 'default' and 'update' actions for consent\n if (action !== 'default' && action !== 'update') return null;\n // Params must be a valid object (not null)\n if (!isObject(params) || params === null) return null;\n\n eventName = `${command} ${action}`;\n eventData = { ...params };\n break;\n\n case 'event':\n // Event requires at least action parameter\n if (!isString(action)) return null;\n eventName = action;\n if (isObject(params)) {\n eventData = { ...params };\n }\n break;\n\n case 'config':\n // Config requires at least action parameter\n if (!isString(action)) return null;\n eventName = `${command} ${action}`;\n if (isObject(params)) {\n eventData = { ...params };\n }\n break;\n\n case 'set':\n if (isString(action)) {\n eventName = `${command} ${action}`;\n if (isObject(params)) {\n eventData = { ...params };\n }\n } else if (isObject(action)) {\n eventName = `${command} custom`;\n eventData = { ...action };\n } else {\n return null;\n }\n break;\n\n default:\n // Unknown command, ignore\n return null;\n }\n\n return {\n name: eventName,\n ...eventData,\n };\n}\n\n/**\n * Check if object is gtag arguments object\n */\nfunction isGtagArguments(obj: unknown): boolean {\n return (\n obj != null &&\n typeof obj === 'object' &&\n 'length' in obj &&\n typeof (obj as ArrayLike<unknown>).length === 'number' &&\n (obj as ArrayLike<unknown>).length > 0\n );\n}\n","import type { WalkerOS, Source, Elb } from '@walkeros/core';\nimport type { SettingsSchema, Mapping } from '../schemas';\nimport type { z } from '@walkeros/core/dev';\n\ndeclare module '@walkeros/core' {\n interface SourceMap {\n dataLayer: { type: 'dataLayer'; platform?: 'web' };\n }\n}\n\ndeclare global {\n interface Window {\n dataLayer?: DataLayer;\n [key: string]: DataLayer | unknown;\n }\n}\n\nexport type DataLayer = Array<unknown>;\n\n// Base settings from Zod schema\ntype BaseSettings = z.infer<typeof SettingsSchema>;\n\n// Override filter to be actual function type (not serializable in schema)\nexport interface Settings extends Omit<BaseSettings, 'filter'> {\n name?: string;\n prefix?: string;\n filter?: (event: unknown) => WalkerOS.PromiseOrValue<boolean>;\n}\n\n// InitSettings: user input (all optional)\nexport type InitSettings = Partial<Settings>;\n\nexport type { Mapping };\n\nexport type Push = Elb.Fn;\n\nexport interface Env extends Source.BaseEnv {\n window?: Window & typeof globalThis;\n}\n\nexport type Types = Source.Types<Settings, Mapping, Push, Env, InitSettings>;\n\nexport type Config = Source.Config<Types>;\n\nexport type DataLayerEvent = {\n event: string;\n [key: string]: unknown;\n};\n\nexport type MappedEvent = {\n event?: WalkerOS.DeepPartialEvent & { id: string };\n command?: {\n name: string;\n data: unknown;\n };\n};\n","import type { Source, On } from '@walkeros/core';\nimport type { Types } from './types';\nimport { interceptDataLayer, processExistingEvents } from './interceptor';\n\n// Export types for external usage\nexport * as SourceDataLayer from './types';\n\n/**\n * DataLayer source implementation using environment injection.\n *\n * This source intercepts dataLayer.push calls and transforms them to WalkerOS events.\n * It works by replacing the dataLayer.push method with a custom handler.\n */\nexport const sourceDataLayer: Source.Init<Types> = async (context) => {\n const { config, env } = context;\n // Events exit via `push` (the collector's source pipeline, so this source's\n // `next`/`before`/mapping/cache/state and status apply); `elb` stays the\n // outward-facing slot on the instance below. This source emits no commands.\n const { elb, push, window: envWindow } = env;\n\n const settings: Source.Settings<Types> = {\n name: 'dataLayer',\n prefix: 'dataLayer',\n ...config?.settings,\n };\n\n const fullConfig: Source.Config<Types> = {\n settings,\n };\n\n // Captured at init time — see init below.\n let pendingReplayCount = 0;\n\n // Lifecycle setup. Called by the collector eagerly after registration,\n // regardless of `require`. The factory body above is side-effect-free.\n const init = () => {\n if (!envWindow) return;\n const dataLayerName = settings.name || 'dataLayer';\n const dl = (envWindow as Record<string, unknown>)[dataLayerName];\n pendingReplayCount = Array.isArray(dl) ? dl.length : 0;\n\n const win = envWindow as unknown as Record<string, unknown>;\n interceptDataLayer(push, fullConfig, win);\n };\n\n // Replay pre-existing entries when the run signal lands. The collector\n // strictly gates on() delivery: this fires only when the source is\n // started (`config.init === true` AND `config.require` empty). If a\n // require gate is unmet, the run event is queued in `queueOn` by\n // onApply and replayed when the source becomes started.\n const handleEvent = async (event: On.Types) => {\n if (event === 'run' && envWindow && pendingReplayCount > 0) {\n const win = envWindow as unknown as Record<string, unknown>;\n processExistingEvents(push, fullConfig, pendingReplayCount, win);\n pendingReplayCount = 0;\n }\n };\n\n return {\n type: 'dataLayer',\n config: fullConfig,\n // Deliberately `elb`, not the pipeline `push`. This slot is the source's\n // outward-facing entry (and what `startFlow` exports as its `elb` when this\n // source is primary), not the capture path: real dataLayer entries arrive\n // through the intercepted `dataLayer.push`, which routes via the pipeline.\n push: elb,\n on: handleEvent,\n init,\n destroy: async () => {\n // Cleanup: restore original dataLayer.push if possible\n const dataLayerName = settings.name || 'dataLayer';\n if (\n envWindow &&\n envWindow[dataLayerName] &&\n Array.isArray(envWindow[dataLayerName])\n ) {\n // Note: Complete restoration would require storing original push method\n // For now, we'll just document this limitation\n }\n },\n };\n};\n\nexport default sourceDataLayer;\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/interceptor.ts","../src/types/index.ts","../src/index.ts"],"sourcesContent":["import type { WalkerOS, Source, Collector } from '@walkeros/core';\nimport { isArray, isObject, isString, tryCatch } from '@walkeros/core';\n\n// Global flag to prevent infinite loops\nlet isProcessing = false;\n\n/**\n * DataLayer interceptor - handles dataLayer.push interception and event transformation\n */\nexport function interceptDataLayer(\n push: Collector.PushFn,\n config: Source.Config,\n win: Record<string, unknown> = globalThis.window as unknown as Record<\n string,\n unknown\n >,\n): void {\n const settings = config.settings as {\n name?: string;\n prefix?: string;\n filter?: (event: unknown) => boolean;\n };\n const dataLayerName = settings?.name || 'dataLayer';\n\n // Ensure dataLayer exists\n if (!win[dataLayerName]) {\n win[dataLayerName] = [];\n }\n\n const dataLayer = win[dataLayerName] as unknown[];\n if (!Array.isArray(dataLayer)) return;\n\n // Store original push\n const originalPush = dataLayer.push.bind(dataLayer);\n\n // Override push with event processing\n dataLayer.push = function (...args: unknown[]): number {\n // Prevent infinite loops\n if (isProcessing) {\n return originalPush(...args);\n }\n\n isProcessing = true;\n try {\n // Process each argument\n for (const arg of args) {\n processEvent(push, settings, arg);\n }\n } finally {\n isProcessing = false;\n }\n\n // Call original push\n return originalPush(...args);\n };\n}\n\n/**\n * Process existing events on initialization\n */\nexport function processExistingEvents(\n push: Collector.PushFn,\n config: Source.Config,\n limit?: number,\n win: Record<string, unknown> = globalThis.window as unknown as Record<\n string,\n unknown\n >,\n): void {\n const settings = config.settings as {\n name?: string;\n prefix?: string;\n filter?: (event: unknown) => boolean;\n };\n const dataLayerName = settings?.name || 'dataLayer';\n const dataLayer = win[dataLayerName] as unknown[];\n\n if (!Array.isArray(dataLayer)) return;\n\n // Prevent loops during initialization\n if (isProcessing) return;\n\n isProcessing = true;\n try {\n const count = limit ?? dataLayer.length;\n for (let i = 0; i < count; i++) {\n processEvent(push, settings, dataLayer[i]);\n }\n } finally {\n isProcessing = false;\n }\n}\n\n/**\n * Process a single event - handles filtering, transformation, and WalkerOS event creation\n */\nfunction processEvent(\n push: Collector.PushFn,\n settings: { prefix?: string; filter?: (event: unknown) => boolean } = {},\n rawEvent: unknown,\n): void {\n // Apply filter if provided\n if (settings.filter) {\n const filterFn = tryCatch(\n () => settings.filter!(rawEvent),\n () => false, // If filter throws, don't skip the event\n );\n const filterResult = filterFn();\n if (filterResult === true) {\n return; // Skip filtered events\n }\n }\n\n // Transform the event (handles gtag format and direct objects)\n const transformedEvent = transformDataLayerEvent(rawEvent);\n if (!transformedEvent) {\n return; // Skip invalid events\n }\n\n const prefix = settings.prefix || 'dataLayer';\n const eventName = `${prefix} ${transformedEvent.name}`;\n\n // Create partial WalkerOS event structure (collector will enrich it).\n // The source identity is stamped here: without it the collector falls back to\n // `type: 'collector'`, and destinations that echo events back into the\n // dataLayer lose the `source.type !== 'dataLayer'` guard against feedback loops.\n const { name: _name, ...data } = transformedEvent;\n const partialEvent: WalkerOS.DeepPartialEvent = {\n name: eventName,\n data: data as WalkerOS.Properties,\n source: { type: 'dataLayer', platform: 'web' },\n };\n\n // Push to collector\n tryCatch(\n () => push(partialEvent),\n () => {}, // Silently handle push errors\n )();\n}\n\n/**\n * Transform dataLayer events to standardized format\n * Handles: gtag arguments, direct objects, existing events\n */\nfunction transformDataLayerEvent(\n rawEvent: unknown,\n): { name: string; [key: string]: unknown } | null {\n // Handle direct object format: { event: 'test', data: 'value' }\n if (isObject(rawEvent) && isString(rawEvent.event)) {\n const { event, ...rest } = rawEvent;\n return { name: event, ...rest };\n }\n\n // Handle gtag argument format: ['consent', 'update', { ad_storage: 'granted' }]\n if (isArray(rawEvent) && rawEvent.length >= 2) {\n return transformGtagArgs(rawEvent);\n }\n\n // Handle arguments object (from gtag function calls)\n if (isGtagArguments(rawEvent)) {\n const argsArray = Array.from(rawEvent as ArrayLike<unknown>);\n return transformGtagArgs(argsArray);\n }\n\n return null;\n}\n\n/**\n * Transform gtag-style arguments to event object\n * ['consent', 'update', { ad_storage: 'granted' }] → { event: 'consent update', ad_storage: 'granted' }\n */\nfunction transformGtagArgs(\n args: unknown[],\n): { name: string; [key: string]: unknown } | null {\n const [command, action, params] = args;\n\n if (!isString(command)) return null;\n\n let eventName: string;\n let eventData: Record<string, unknown> = {};\n\n switch (command) {\n case 'consent':\n // Consent requires action and params\n if (!isString(action) || args.length < 3) return null;\n // Only allow 'default' and 'update' actions for consent\n if (action !== 'default' && action !== 'update') return null;\n // Params must be a valid object (not null)\n if (!isObject(params) || params === null) return null;\n\n eventName = `${command} ${action}`;\n eventData = { ...params };\n break;\n\n case 'event':\n // Event requires at least action parameter\n if (!isString(action)) return null;\n eventName = action;\n if (isObject(params)) {\n eventData = { ...params };\n }\n break;\n\n case 'config':\n // Config requires at least action parameter\n if (!isString(action)) return null;\n eventName = `${command} ${action}`;\n if (isObject(params)) {\n eventData = { ...params };\n }\n break;\n\n case 'set':\n if (isString(action)) {\n eventName = `${command} ${action}`;\n if (isObject(params)) {\n eventData = { ...params };\n }\n } else if (isObject(action)) {\n eventName = `${command} custom`;\n eventData = { ...action };\n } else {\n return null;\n }\n break;\n\n default:\n // Unknown command, ignore\n return null;\n }\n\n return {\n name: eventName,\n ...eventData,\n };\n}\n\n/**\n * Check if object is gtag arguments object\n */\nfunction isGtagArguments(obj: unknown): boolean {\n return (\n obj != null &&\n typeof obj === 'object' &&\n 'length' in obj &&\n typeof (obj as ArrayLike<unknown>).length === 'number' &&\n (obj as ArrayLike<unknown>).length > 0\n );\n}\n","import type { WalkerOS, Source, Elb } from '@walkeros/core';\nimport type { SettingsSchema, Mapping } from '../schemas';\nimport type { z } from '@walkeros/core/dev';\n\ndeclare module '@walkeros/core' {\n interface SourceMap {\n dataLayer: { type: 'dataLayer'; platform?: 'web' };\n }\n}\n\ndeclare global {\n interface Window {\n dataLayer?: DataLayer;\n [key: string]: DataLayer | unknown;\n }\n}\n\nexport type DataLayer = Array<unknown>;\n\n// Base settings from Zod schema\ntype BaseSettings = z.infer<typeof SettingsSchema>;\n\n// Override filter to be actual function type (not serializable in schema)\nexport interface Settings extends Omit<BaseSettings, 'filter'> {\n name?: string;\n prefix?: string;\n filter?: (event: unknown) => WalkerOS.PromiseOrValue<boolean>;\n}\n\n// InitSettings: user input (all optional)\nexport type InitSettings = Partial<Settings>;\n\nexport type { Mapping };\n\nexport type Push = Elb.Fn;\n\nexport interface Env extends Source.BaseEnv {\n window?: Window & typeof globalThis;\n}\n\nexport type Types = Source.Types<Settings, Mapping, Push, Env, InitSettings>;\n\nexport type Config = Source.Config<Types>;\n\nexport type DataLayerEvent = {\n event: string;\n [key: string]: unknown;\n};\n\nexport type MappedEvent = {\n event?: WalkerOS.DeepPartialEvent & { id: string };\n command?: {\n name: string;\n data: unknown;\n };\n};\n","import type { Source, On } from '@walkeros/core';\nimport type { Types } from './types';\nimport { interceptDataLayer, processExistingEvents } from './interceptor';\n\n// Export types for external usage\nexport * as SourceDataLayer from './types';\n\n/**\n * DataLayer source implementation using environment injection.\n *\n * This source intercepts dataLayer.push calls and transforms them to WalkerOS events.\n * It works by replacing the dataLayer.push method with a custom handler.\n */\nexport const sourceDataLayer: Source.Init<Types> = async (context) => {\n const { config, env } = context;\n // Events exit via `push` (the collector's source pipeline, so this source's\n // `next`/`before`/mapping/cache/state and status apply); `elb` stays the\n // outward-facing slot on the instance below. This source emits no commands.\n const { elb, push, window: envWindow } = env;\n\n const settings: Source.Settings<Types> = {\n name: 'dataLayer',\n prefix: 'dataLayer',\n ...config?.settings,\n };\n\n const fullConfig: Source.Config<Types> = {\n settings,\n };\n\n // Captured at init time — see init below.\n let pendingReplayCount = 0;\n\n // Lifecycle setup. Called by the collector eagerly after registration,\n // regardless of `require`. The factory body above is side-effect-free.\n const init = () => {\n if (!envWindow) return;\n const dataLayerName = settings.name || 'dataLayer';\n const dl = (envWindow as Record<string, unknown>)[dataLayerName];\n pendingReplayCount = Array.isArray(dl) ? dl.length : 0;\n\n const win = envWindow as unknown as Record<string, unknown>;\n interceptDataLayer(push, fullConfig, win);\n };\n\n // Replay pre-existing entries when the run signal lands. The collector\n // strictly gates on() delivery: this fires only when the source is\n // started (`config.init === true` AND `config.require` empty). If a\n // require gate is unmet, the run event is queued in `queueOn` by\n // onApply and replayed when the source becomes started.\n const handleEvent = async (event: On.Types) => {\n if (event === 'run' && envWindow && pendingReplayCount > 0) {\n const win = envWindow as unknown as Record<string, unknown>;\n processExistingEvents(push, fullConfig, pendingReplayCount, win);\n pendingReplayCount = 0;\n }\n };\n\n return {\n type: 'dataLayer',\n config: fullConfig,\n // Deliberately `elb`, not the pipeline `push`. This slot is the source's\n // outward-facing entry (and what `startFlow` exports as its `elb` when this\n // source is primary), not the capture path: real dataLayer entries arrive\n // through the intercepted `dataLayer.push`, which routes via the pipeline.\n push: elb,\n on: handleEvent,\n init,\n destroy: async () => {\n // Cleanup: restore original dataLayer.push if possible\n const dataLayerName = settings.name || 'dataLayer';\n if (\n envWindow &&\n envWindow[dataLayerName] &&\n Array.isArray(envWindow[dataLayerName])\n ) {\n // Note: Complete restoration would require storing original push method\n // For now, we'll just document this limitation\n }\n },\n };\n};\n\nexport default sourceDataLayer;\n"],"mappings":";AACA,SAAS,SAAS,UAAU,UAAU,gBAAgB;AAGtD,IAAI,eAAe;AAKZ,SAAS,mBACd,MACA,QACA,MAA+B,WAAW,QAIpC;AACN,QAAM,WAAW,OAAO;AAKxB,QAAM,iBAAgB,qCAAU,SAAQ;AAGxC,MAAI,CAAC,IAAI,aAAa,GAAG;AACvB,QAAI,aAAa,IAAI,CAAC;AAAA,EACxB;AAEA,QAAM,YAAY,IAAI,aAAa;AACnC,MAAI,CAAC,MAAM,QAAQ,SAAS,EAAG;AAG/B,QAAM,eAAe,UAAU,KAAK,KAAK,SAAS;AAGlD,YAAU,OAAO,YAAa,MAAyB;AAErD,QAAI,cAAc;AAChB,aAAO,aAAa,GAAG,IAAI;AAAA,IAC7B;AAEA,mBAAe;AACf,QAAI;AAEF,iBAAW,OAAO,MAAM;AACtB,qBAAa,MAAM,UAAU,GAAG;AAAA,MAClC;AAAA,IACF,UAAE;AACA,qBAAe;AAAA,IACjB;AAGA,WAAO,aAAa,GAAG,IAAI;AAAA,EAC7B;AACF;AAKO,SAAS,sBACd,MACA,QACA,OACA,MAA+B,WAAW,QAIpC;AACN,QAAM,WAAW,OAAO;AAKxB,QAAM,iBAAgB,qCAAU,SAAQ;AACxC,QAAM,YAAY,IAAI,aAAa;AAEnC,MAAI,CAAC,MAAM,QAAQ,SAAS,EAAG;AAG/B,MAAI,aAAc;AAElB,iBAAe;AACf,MAAI;AACF,UAAM,QAAQ,wBAAS,UAAU;AACjC,aAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC9B,mBAAa,MAAM,UAAU,UAAU,CAAC,CAAC;AAAA,IAC3C;AAAA,EACF,UAAE;AACA,mBAAe;AAAA,EACjB;AACF;AAKA,SAAS,aACP,MACA,WAAsE,CAAC,GACvE,UACM;AAEN,MAAI,SAAS,QAAQ;AACnB,UAAM,WAAW;AAAA,MACf,MAAM,SAAS,OAAQ,QAAQ;AAAA,MAC/B,MAAM;AAAA;AAAA,IACR;AACA,UAAM,eAAe,SAAS;AAC9B,QAAI,iBAAiB,MAAM;AACzB;AAAA,IACF;AAAA,EACF;AAGA,QAAM,mBAAmB,wBAAwB,QAAQ;AACzD,MAAI,CAAC,kBAAkB;AACrB;AAAA,EACF;AAEA,QAAM,SAAS,SAAS,UAAU;AAClC,QAAM,YAAY,GAAG,MAAM,IAAI,iBAAiB,IAAI;AAMpD,QAAM,EAAE,MAAM,OAAO,GAAG,KAAK,IAAI;AACjC,QAAM,eAA0C;AAAA,IAC9C,MAAM;AAAA,IACN;AAAA,IACA,QAAQ,EAAE,MAAM,aAAa,UAAU,MAAM;AAAA,EAC/C;AAGA;AAAA,IACE,MAAM,KAAK,YAAY;AAAA,IACvB,MAAM;AAAA,IAAC;AAAA;AAAA,EACT,EAAE;AACJ;AAMA,SAAS,wBACP,UACiD;AAEjD,MAAI,SAAS,QAAQ,KAAK,SAAS,SAAS,KAAK,GAAG;AAClD,UAAM,EAAE,OAAO,GAAG,KAAK,IAAI;AAC3B,WAAO,EAAE,MAAM,OAAO,GAAG,KAAK;AAAA,EAChC;AAGA,MAAI,QAAQ,QAAQ,KAAK,SAAS,UAAU,GAAG;AAC7C,WAAO,kBAAkB,QAAQ;AAAA,EACnC;AAGA,MAAI,gBAAgB,QAAQ,GAAG;AAC7B,UAAM,YAAY,MAAM,KAAK,QAA8B;AAC3D,WAAO,kBAAkB,SAAS;AAAA,EACpC;AAEA,SAAO;AACT;AAMA,SAAS,kBACP,MACiD;AACjD,QAAM,CAAC,SAAS,QAAQ,MAAM,IAAI;AAElC,MAAI,CAAC,SAAS,OAAO,EAAG,QAAO;AAE/B,MAAI;AACJ,MAAI,YAAqC,CAAC;AAE1C,UAAQ,SAAS;AAAA,IACf,KAAK;AAEH,UAAI,CAAC,SAAS,MAAM,KAAK,KAAK,SAAS,EAAG,QAAO;AAEjD,UAAI,WAAW,aAAa,WAAW,SAAU,QAAO;AAExD,UAAI,CAAC,SAAS,MAAM,KAAK,WAAW,KAAM,QAAO;AAEjD,kBAAY,GAAG,OAAO,IAAI,MAAM;AAChC,kBAAY,EAAE,GAAG,OAAO;AACxB;AAAA,IAEF,KAAK;AAEH,UAAI,CAAC,SAAS,MAAM,EAAG,QAAO;AAC9B,kBAAY;AACZ,UAAI,SAAS,MAAM,GAAG;AACpB,oBAAY,EAAE,GAAG,OAAO;AAAA,MAC1B;AACA;AAAA,IAEF,KAAK;AAEH,UAAI,CAAC,SAAS,MAAM,EAAG,QAAO;AAC9B,kBAAY,GAAG,OAAO,IAAI,MAAM;AAChC,UAAI,SAAS,MAAM,GAAG;AACpB,oBAAY,EAAE,GAAG,OAAO;AAAA,MAC1B;AACA;AAAA,IAEF,KAAK;AACH,UAAI,SAAS,MAAM,GAAG;AACpB,oBAAY,GAAG,OAAO,IAAI,MAAM;AAChC,YAAI,SAAS,MAAM,GAAG;AACpB,sBAAY,EAAE,GAAG,OAAO;AAAA,QAC1B;AAAA,MACF,WAAW,SAAS,MAAM,GAAG;AAC3B,oBAAY,GAAG,OAAO;AACtB,oBAAY,EAAE,GAAG,OAAO;AAAA,MAC1B,OAAO;AACL,eAAO;AAAA,MACT;AACA;AAAA,IAEF;AAEE,aAAO;AAAA,EACX;AAEA,SAAO;AAAA,IACL,MAAM;AAAA,IACN,GAAG;AAAA,EACL;AACF;AAKA,SAAS,gBAAgB,KAAuB;AAC9C,SACE,OAAO,QACP,OAAO,QAAQ,YACf,YAAY,OACZ,OAAQ,IAA2B,WAAW,YAC7C,IAA2B,SAAS;AAEzC;;;ACxPA;;;ACaO,IAAM,kBAAsC,OAAO,YAAY;AACpE,QAAM,EAAE,QAAQ,IAAI,IAAI;AAIxB,QAAM,EAAE,KAAK,MAAM,QAAQ,UAAU,IAAI;AAEzC,QAAM,WAAmC;AAAA,IACvC,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,GAAG,iCAAQ;AAAA,EACb;AAEA,QAAM,aAAmC;AAAA,IACvC;AAAA,EACF;AAGA,MAAI,qBAAqB;AAIzB,QAAM,OAAO,MAAM;AACjB,QAAI,CAAC,UAAW;AAChB,UAAM,gBAAgB,SAAS,QAAQ;AACvC,UAAM,KAAM,UAAsC,aAAa;AAC/D,yBAAqB,MAAM,QAAQ,EAAE,IAAI,GAAG,SAAS;AAErD,UAAM,MAAM;AACZ,uBAAmB,MAAM,YAAY,GAAG;AAAA,EAC1C;AAOA,QAAM,cAAc,OAAO,UAAoB;AAC7C,QAAI,UAAU,SAAS,aAAa,qBAAqB,GAAG;AAC1D,YAAM,MAAM;AACZ,4BAAsB,MAAM,YAAY,oBAAoB,GAAG;AAC/D,2BAAqB;AAAA,IACvB;AAAA,EACF;AAEA,SAAO;AAAA,IACL,MAAM;AAAA,IACN,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA,IAKR,MAAM;AAAA,IACN,IAAI;AAAA,IACJ;AAAA,IACA,SAAS,YAAY;AAEnB,YAAM,gBAAgB,SAAS,QAAQ;AACvC,UACE,aACA,UAAU,aAAa,KACvB,MAAM,QAAQ,UAAU,aAAa,CAAC,GACtC;AAAA,MAGF;AAAA,IACF;AAAA,EACF;AACF;AAEA,IAAO,gBAAQ;","names":[]}
|
package/dist/walkerOS.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$meta": {
|
|
3
3
|
"package": "@walkeros/web-source-datalayer",
|
|
4
|
-
"version": "4.5.
|
|
4
|
+
"version": "4.5.1-next-1788726985928",
|
|
5
5
|
"type": "source",
|
|
6
6
|
"platform": [
|
|
7
7
|
"web"
|
|
@@ -89,7 +89,7 @@
|
|
|
89
89
|
"$code": "()=>{}"
|
|
90
90
|
},
|
|
91
91
|
"scope": {
|
|
92
|
-
"$code": "()=>
|
|
92
|
+
"$code": "()=>w"
|
|
93
93
|
}
|
|
94
94
|
}
|
|
95
95
|
}
|
|
@@ -117,6 +117,10 @@
|
|
|
117
117
|
"data": {
|
|
118
118
|
"ad_storage": "granted",
|
|
119
119
|
"analytics_storage": "granted"
|
|
120
|
+
},
|
|
121
|
+
"source": {
|
|
122
|
+
"type": "dataLayer",
|
|
123
|
+
"platform": "web"
|
|
120
124
|
}
|
|
121
125
|
}
|
|
122
126
|
]
|
|
@@ -141,6 +145,10 @@
|
|
|
141
145
|
"data": {
|
|
142
146
|
"category": "engagement",
|
|
143
147
|
"label": "video_play"
|
|
148
|
+
},
|
|
149
|
+
"source": {
|
|
150
|
+
"type": "dataLayer",
|
|
151
|
+
"platform": "web"
|
|
144
152
|
}
|
|
145
153
|
}
|
|
146
154
|
]
|
|
@@ -186,6 +194,10 @@
|
|
|
186
194
|
"price": 15.25
|
|
187
195
|
}
|
|
188
196
|
]
|
|
197
|
+
},
|
|
198
|
+
"source": {
|
|
199
|
+
"type": "dataLayer",
|
|
200
|
+
"platform": "web"
|
|
189
201
|
}
|
|
190
202
|
}
|
|
191
203
|
]
|
|
@@ -229,6 +241,10 @@
|
|
|
229
241
|
"quantity": 1
|
|
230
242
|
}
|
|
231
243
|
]
|
|
244
|
+
},
|
|
245
|
+
"source": {
|
|
246
|
+
"type": "dataLayer",
|
|
247
|
+
"platform": "web"
|
|
232
248
|
}
|
|
233
249
|
}
|
|
234
250
|
]
|
|
@@ -272,6 +288,10 @@
|
|
|
272
288
|
"price": 29.99
|
|
273
289
|
}
|
|
274
290
|
]
|
|
291
|
+
},
|
|
292
|
+
"source": {
|
|
293
|
+
"type": "dataLayer",
|
|
294
|
+
"platform": "web"
|
|
275
295
|
}
|
|
276
296
|
}
|
|
277
297
|
]
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@walkeros/web-source-datalayer",
|
|
3
3
|
"description": "DataLayer source for walkerOS",
|
|
4
|
-
"version": "4.5.
|
|
4
|
+
"version": "4.5.1-next-1788726985928",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
7
|
"module": "./dist/index.mjs",
|
|
@@ -38,8 +38,8 @@
|
|
|
38
38
|
"update": "npx npm-check-updates -u && npm update"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@walkeros/core": "4.5.
|
|
42
|
-
"@walkeros/collector": "4.5.
|
|
41
|
+
"@walkeros/core": "4.5.1-next-1788726985928",
|
|
42
|
+
"@walkeros/collector": "4.5.1-next-1788726985928"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
45
|
"@types/gtag.js": "^0.0.20"
|