{"_id":"@analytics-debugger/data-layer-helper-ts","_rev":"2-4ace06a6ac681e19e75aea666415feed","name":"@analytics-debugger/data-layer-helper-ts","dist-tags":{"latest":"0.0.2"},"versions":{"0.0.1":{"name":"@analytics-debugger/data-layer-helper-ts","version":"0.0.1","keywords":["data","datalayer","javascript","layer","message","queue","tool","utility"],"author":{"url":"https://github.com/thyngster","name":"David Vallejo"},"license":"Apache-2.0","_id":"@analytics-debugger/data-layer-helper-ts@0.0.1","maintainers":[{"name":"thyngster","email":"thyngster@gmail.com"}],"dist":{"shasum":"d966f9e6ec68ffe1876599eb214a8f514eb8bbe5","tarball":"https://registry.npmjs.org/@analytics-debugger/data-layer-helper-ts/-/data-layer-helper-ts-0.0.1.tgz","fileCount":16,"integrity":"sha512-LAyAmF7Vx0VimxXxOl9S5Af5e5SIDJy+ek74sWQOou1v8+6eRJwP1jxXLBpHUbBDn8q5CWD8U7o6LCFUv7puVg==","signatures":[{"sig":"MEQCIC0CldR0/O6PeniLeDer7vfZHeJwDDsH4kxlPw/vpcvhAiAq53680jUDC85dtMD2vNnAO/CuGBPrIhSBzQlNpD7+LQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":42046},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"dfc37a278f0577f0f8a9614c28241ef66f04d123","scripts":{"dev":"vp build --watch","test":"vp test","build":"vp build && npx dts-bundle-generator -o dist/index.d.ts src/index.ts","check":"vp check","release":"npm version patch && git push origin main --tags && npm publish --access public","prepublishOnly":"vp build && npx dts-bundle-generator -o dist/index.d.ts src/index.ts"},"_npmUser":{"name":"thyngster","email":"thyngster@gmail.com"},"_npmVersion":"11.9.0","description":"TypeScript port of google/data-layer-helper — monitors and processes dataLayer arrays","directories":{},"_nodeVersion":"24.14.0","_hasShrinkwrap":false,"devDependencies":{"vite-plus":"^0.1.14","typescript":"^5.9.3","dts-bundle-generator":"^9.5.1"},"_npmOperationalInternal":{"tmp":"tmp/data-layer-helper-ts_0.0.1_1774581808630_0.7029298831450272","host":"s3://npm-registry-packages-npm-production"}},"0.0.2":{"name":"@analytics-debugger/data-layer-helper-ts","version":"0.0.2","description":"TypeScript port of google/data-layer-helper — monitors and processes dataLayer arrays","keywords":["data","datalayer","javascript","layer","message","queue","tool","utility"],"license":"Apache-2.0","author":{"name":"David Vallejo","url":"https://github.com/thyngster"},"type":"module","main":"./dist/index.cjs","module":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"import":"./dist/index.js","require":"./dist/index.cjs","types":"./dist/index.d.ts"}},"scripts":{"build":"vp build && npx dts-bundle-generator -o dist/index.d.ts src/index.ts","dev":"vp build --watch","test":"vp test","check":"vp check","prepublishOnly":"vp build && npx dts-bundle-generator -o dist/index.d.ts src/index.ts","release":"npm version patch && git push origin main --tags && npm publish --access public"},"devDependencies":{"dts-bundle-generator":"^9.5.1","typescript":"^5.9.3","vite-plus":"^0.1.14"},"gitHead":"0ed1159e0959de5e6615c91321d4a99478e025ab","_id":"@analytics-debugger/data-layer-helper-ts@0.0.2","_nodeVersion":"24.14.0","_npmVersion":"11.9.0","dist":{"integrity":"sha512-bu3fRXJxJ69epeknpniJdwy60Pv5NS+CkKKYU5GkMAqTqJdWT0FhAUrlabuXSkWzKX/ZvohvalwiRoSZIS+W2Q==","shasum":"050060ef1be2506c7618692c5cd701d541e314f5","tarball":"https://registry.npmjs.org/@analytics-debugger/data-layer-helper-ts/-/data-layer-helper-ts-0.0.2.tgz","fileCount":16,"unpackedSize":42337,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIAiyBs/KMsi76caOq5xvcaSbDmowAcmyy6T9nv1zInLzAiEAs+t4deP9LgkKETrwVyqFp0f7d3R+ecLozb+a+nyFiAk="}]},"_npmUser":{"name":"thyngster","email":"thyngster@gmail.com"},"directories":{},"maintainers":[{"name":"thyngster","email":"thyngster@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/data-layer-helper-ts_0.0.2_1775597385221_0.10885896822075924"},"_hasShrinkwrap":false}},"time":{"created":"2026-03-27T03:23:28.520Z","modified":"2026-04-07T21:29:45.581Z","0.0.1":"2026-03-27T03:23:28.777Z","0.0.2":"2026-04-07T21:29:45.428Z"},"author":{"name":"David Vallejo","url":"https://github.com/thyngster"},"license":"Apache-2.0","keywords":["data","datalayer","javascript","layer","message","queue","tool","utility"],"description":"TypeScript port of google/data-layer-helper — monitors and processes dataLayer arrays","maintainers":[{"name":"thyngster","email":"thyngster@gmail.com"}],"readme":"# @analytics-debugger/data-layer-helper-ts\n\nTypeScript port of [google/data-layer-helper](https://github.com/google/data-layer-helper) by [David Vallejo](https://github.com/thyngster) — provides the ability to process messages passed onto a dataLayer queue.\n\n- [Build and Test](#build-and-test)\n- [Build Formats](#build-formats)\n- [Quick Start](#quick-start)\n- [What is a Data Layer Queue?](#what-is-a-data-layer-queue)\n- [The Abstract Data Model](#the-abstract-data-model)\n  - [Overwriting Existing Values](#overwriting-existing-values)\n  - [Recursively Merging Values](#recursively-merging-values)\n  - [Preventing Default Recursive Merge](#preventing-default-recursive-merge)\n  - [Custom Functions](#custom-functions)\n    - [The Abstract Data Model Interface](#the-abstract-data-model-interface)\n- [Listening for Messages](#listening-for-messages)\n  - [Listening to the Past](#listening-to-the-past)\n  - [Registering Processors](#registering-processors)\n  - [Delaying Processing](#delaying-processing)\n- [API Summary](#api-summary)\n- [License](#license)\n\n## Build and Test\n\nThis project uses [vite-plus](https://viteplus.dev) for building, testing, and type-checking.\n\n```bash\nnpm install        # Install dependencies\nvp build && npx dts-bundle-generator -o dist/index.d.ts src/index.ts  # Build all formats + types\nvp build --watch   # Watch mode\nvp test            # Run tests\nvp check           # Type-check\n```\n\n## Build Formats\n\n| Format | File                             | Usage                       |\n| ------ | -------------------------------- | --------------------------- |\n| ESM    | `dist/index.js`                  | `import` in modern bundlers |\n| CJS    | `dist/index.cjs`                 | `require()` in Node.js      |\n| IIFE   | `dist/data-layer-helper.iife.js` | `<script>` tag in browsers  |\n\n## Quick Start\n\n```bash\nnpm install @analytics-debugger/data-layer-helper-ts\n```\n\n### ES Module / CommonJS\n\n```ts\nimport DataLayerHelper from \"@analytics-debugger/data-layer-helper-ts\";\n\nconst dataLayer = [];\nconst helper = new DataLayerHelper(dataLayer, {\n  listener: function (model, message) {\n    // Message has been pushed.\n    console.log(model, message);\n  },\n});\n```\n\n### CDN (jsDelivr)\n\n```html\n<!-- Latest version -->\n<script src=\"https://cdn.jsdelivr.net/npm/@analytics-debugger/data-layer-helper-ts/dist/data-layer-helper.iife.js\"></script>\n\n<!-- Pinned version -->\n<script src=\"https://cdn.jsdelivr.net/npm/@analytics-debugger/data-layer-helper-ts@0.0.1/dist/data-layer-helper.iife.js\"></script>\n\n<!-- ESM import -->\n<script type=\"module\">\n  import DataLayerHelper from \"https://cdn.jsdelivr.net/npm/@analytics-debugger/data-layer-helper-ts/dist/index.js\";\n</script>\n```\n\n### IIFE (Browser)\n\n```html\n<script src=\"https://cdn.jsdelivr.net/npm/@analytics-debugger/data-layer-helper-ts/dist/data-layer-helper.iife.js\"></script>\n<script>\n  var dataLayer = [];\n  var helper = new DataLayerHelper(dataLayer, {\n    listener: function (model, message) {\n      console.log(message);\n    },\n  });\n</script>\n```\n\n## What is a Data Layer Queue?\n\nA data layer queue is simply a JavaScript array that lives on a webpage.\n\n```html\n<script>\n  dataLayer = [];\n</script>\n```\n\nPage authors can append messages onto the queue in order to emit information about the page and its state.\n\n```html\n<script>\n  dataLayer.push({\n    title: \"Migratory patterns of ducks\",\n    category: \"Science\",\n    author: \"Bradley Wogulis\",\n  });\n</script>\n```\n\nThese messages are JavaScript objects containing a hierarchy of key/value pairs. They can be metadata about the page content, information about the visitor, or data about events happening on the page. This system allows tools like analytics libraries and tag management systems to access this data in a standard way.\n\n## The Abstract Data Model\n\nWhen a `DataLayerHelper` is created, it maintains an internal \"abstract data model\". Each message pushed onto the dataLayer is merged into this model. You can retrieve values from the model using dot-notation:\n\n```js\ndataLayer.push({ one: { two: { three: 4 } } });\n\nhelper.get(\"one.two.three\"); // Returns 4\nhelper.get(\"one.two\"); // Returns {three: 4}\n```\n\nAs each message is processed, its key/value pairs are added to the abstract data model. If the key doesn't currently exist in the model, the pair is simply added. In the case of key conflicts, the action taken depends on the types of the existing and new values:\n\n- **Arrays** and **Plain Objects** — recursively merge when both values are the same type\n- **Everything else** — the new value overwrites the existing value\n\n| Existing Value        | New Value    | Action            |\n| --------------------- | ------------ | ----------------- |\n| Array                 | Array        | Recursively merge |\n| Plain Object          | Plain Object | Recursively merge |\n| Any other combination | Overwrite    |\n\n### Overwriting Existing Values\n\nWhen overwriting, the existing value is completely discarded:\n\n```js\n// model: { a: [1, 2, 3] }\ndataLayer.push({ a: \"hello\" });\n// model: { a: 'hello' }\n```\n\n### Recursively Merging Values\n\nWhen recursively merging, each property in the new value is individually merged into the existing value:\n\n```js\n// model: { one: 1, three: 3 }\ndataLayer.push({ two: 2 });\n// model: { one: 1, three: 3, two: 2 }\n\n// model: { one: { two: 3 } }\ndataLayer.push({ one: { four: 5 } });\n// model: { one: { two: 3, four: 5 } }\n```\n\n### Preventing Default Recursive Merge\n\nTo prevent the default recursive merge and overwrite instead, add a truthy `_clear` attribute to the pushed message. The `_clear` key itself is removed from the model after processing.\n\n```js\n// model: { user: { name: 'Alice', role: 'admin' } }\ndataLayer.push({ user: { name: \"Bob\" }, _clear: true });\n// model: { user: { name: 'Bob' } }  — role is gone\n```\n\nThis is especially useful for single page applications where you may not want outdated information in the data model when routing between pages.\n\n### Custom Functions\n\nPushing a function onto the dataLayer allows you to update the abstract data model with custom code. When a function is processed, the value of `this` will be the abstract data model interface.\n\n> **Note:** Arrow functions do not have their own `this`, so you must use a regular `function`.\n\n```js\ndataLayer.push(function () {\n  var name = this.get(\"user.name\");\n  this.set(\"greeting\", \"Hello, \" + name);\n});\n```\n\n#### The Abstract Data Model Interface\n\nTo safely access the abstract data model from within a custom function, an API with a getter and setter is provided:\n\n- `this.get(key)` — returns a value from the model using dot-notation\n- `this.set(key, value)` — creates or overwrites the given key with the new value\n\n## Listening for Messages\n\nWhen creating a `DataLayerHelper`, you can specify a listener callback to be called whenever a message is pushed onto the dataLayer. This allows your code to be notified immediately whenever the dataLayer has been updated.\n\n```js\nfunction listener(model, message) {\n  // Message has been pushed.\n  // The helper has merged it onto the model.\n  // Now use the message and the updated model to do something.\n}\nvar helper = new DataLayerHelper(dataLayer, { listener: listener });\n```\n\n### Listening to the Past\n\nBy default (`processNow: true`), the helper processes all existing messages in the dataLayer on construction. The listener will be called once for each existing message, with the model representing the state at the time of that message.\n\nTo defer this processing:\n\n```js\nvar helper = new DataLayerHelper(dataLayer, {\n  listener: listener,\n  processNow: false,\n});\n// ... later\nhelper.process();\n```\n\n### Registering Processors\n\nYou can register custom command processors that respond to command arrays:\n\n```js\nhelper.registerProcessor(\"event\", function (name, params) {\n  console.log(\"Event:\", name, params);\n});\n\ndataLayer.push([\"event\", \"click\", { category: \"nav\" }]);\n// Logs: Event: click {category: 'nav'}\n```\n\nMultiple processors can be registered for the same command name.\n\n### Delaying Processing\n\nUse `processNow: false` to create the helper without processing existing messages. Call `helper.process()` later when you're ready.\n\n## API Summary\n\n### `new DataLayerHelper(dataLayer, options?)`\n\n| Option          | Type       | Default       | Description                                                      |\n| --------------- | ---------- | ------------- | ---------------------------------------------------------------- |\n| `listener`      | `function` | —             | Called on every push: `(model, message, dataLayerName) => void`  |\n| `processNow`    | `boolean`  | `true`        | Process existing entries on construction                         |\n| `dataLayerName` | `string`   | `'dataLayer'` | Optional identifier passed to the listener as the third argument |\n\n### `helper.get(key)`\n\nReturns a value from the internal model using dot-notation.\n\n### `helper.flatten()`\n\nReturns the entire dataLayer history merged into a single object (re-merges from scratch, does not use the internal model).\n\n### `helper.process()`\n\nManually processes all existing entries in the dataLayer.\n\n### `helper.registerProcessor(commandName, processor)`\n\nRegisters a command processor for the given command name.\n\n## Author\n\n[David Vallejo](https://github.com/thyngster) / [Analytics Debugger S.L.U.](https://www.analytics-debugger.com)\n\n## License\n\nApache-2.0\n","readmeFilename":"README.md"}