{"_id":"@atlanwave/checkout-friction-detector","_rev":"4-cda440f67cae4c32c5d43d385e3ed603","name":"@atlanwave/checkout-friction-detector","dist-tags":{"latest":"1.3.0"},"versions":{"1.0.0":{"name":"@atlanwave/checkout-friction-detector","version":"1.0.0","keywords":["checkout","friction","analytics","form","ux","abandonment","rage-click"],"author":{"url":"Samuel Adoga","name":"Atlanwave"},"license":"MIT","_id":"@atlanwave/checkout-friction-detector@1.0.0","maintainers":[{"name":"xiden001","email":"samuel.adoga1@gmail.com"}],"homepage":"https://github.com/xiden001/checkout-friction-detector#readme","bugs":{"url":"https://github.com/xiden001/checkout-friction-detector/issues"},"dist":{"shasum":"76b810f88e69b1b592b4b8f5d5559bb4ee0da6c8","tarball":"https://registry.npmjs.org/@atlanwave/checkout-friction-detector/-/checkout-friction-detector-1.0.0.tgz","fileCount":36,"integrity":"sha512-gE4aPOCjGdkAl+urHQHgADobOtRGSun1v+hON3GHp15dMtsnejyQlfivZecxX8oWA9spoIwIY4rYDm9yoX1O2Q==","signatures":[{"sig":"MEYCIQCtL401My+SAF09KX/nSZrvlvw4XG4sNO6usawH8UmxlgIhAPEPxRGAah0/1KBUqICco40FzsH/lT7vVBy0l6tIe1mD","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":655690},"main":"dist/checkout-friction-detector.umd.js","type":"module","unpkg":"dist/checkout-friction-detector.umd.min.js","module":"dist/checkout-friction-detector.esm.js","browser":"dist/checkout-friction-detector.umd.js","gitHead":"209b428047edd6967616c7ad26888bc6311930e5","scripts":{"dev":"rollup -c -w","test":"vitest run","build":"rollup -c","test:watch":"vitest","mock-server":"node examples/mock-server.js"},"_npmUser":{"name":"xiden001","email":"samuel.adoga1@gmail.com"},"repository":{"url":"git+https://github.com/xiden001/checkout-friction-detector.git","type":"git"},"_npmVersion":"11.11.0","description":"Lightweight browser library that detects checkout and form friction, reporting structured events to a backend API.","directories":{"test":"tests","example":"examples"},"_nodeVersion":"22.19.0","dependencies":{"ms":"^2.0.0","qs":"^6.14.2","ws":"^8.20.0","cac":"^6.7.14","psl":"^1.15.0","ufo":"^1.6.3","chai":"^4.5.0","depd":"^2.0.0","etag":"^1.8.1","gopd":"^1.2.0","mime":"^1.6.0","mlly":"^1.8.2","send":"^0.19.2","smob":"^1.6.1","tr46":"^5.1.1","vary":"^1.1.2","vite":"^5.4.21","acorn":"^8.16.0","bytes":"^3.1.2","debug":"^2.6.9","execa":"^8.0.1","fresh":"^0.5.2","isexe":"^2.0.0","loupe":"^2.3.7","pathe":"^1.1.2","saxes":"^6.0.0","which":"^2.0.2","cookie":"^0.7.2","hasown":"^2.0.2","nanoid":"^3.3.11","nwsapi":"^2.2.23","parse5":"^7.3.0","terser":"^5.46.1","unpipe":"^1.0.0","accepts":"^1.3.8","confbox":"^0.1.8","destroy":"^1.2.0","esbuild":"^0.21.5","methods":"^1.1.2","mime-db":"^1.52.0","onetime":"^6.0.0","p-limit":"^5.0.0","pathval":"^1.1.1","postcss":"^8.5.8","siginfo":"^2.0.0","std-env":"^3.10.0","tinyspy":"^2.2.1","type-is":"^1.6.18","asynckit":"^0.4.0","cssstyle":"^4.6.0","deep-eql":"^4.1.4","ee-first":"^1.1.1","entities":"^6.0.1","inherits":"^2.0.4","mimic-fn":"^4.0.0","parseurl":"^1.3.3","path-key":"^3.1.1","punycode":"^2.3.1","raw-body":"^2.5.3","react-is":"^18.3.1","statuses":"^2.0.2","tinypool":"^0.8.4","xmlchars":"^2.2.0","commander":"^2.20.3","data-urls":"^5.0.0","encodeurl":"^2.0.0","es-errors":"^1.3.0","form-data":"^4.0.5","forwarded":"^0.2.0","get-proto":"^1.0.1","ipaddr.js":"^1.9.1","is-stream":"^3.0.0","js-tokens":"^9.0.1","local-pkg":"^0.5.1","lru-cache":"^10.4.3","pkg-types":"^1.3.1","stackback":"^0.0.2","tinybench":"^2.9.0","url-parse":"^1.5.10","vite-node":"^1.6.1","acorn-walk":"^8.3.5","agent-base":"^7.1.4","call-bound":"^1.0.4","decimal.js":"^10.6.0","get-stream":"^8.0.1","iconv-lite":"^0.4.24","mime-types":"^2.1.35","negotiator":"^0.6.3","picocolors":"^1.1.1","proxy-addr":"^2.0.7","source-map":"^0.6.1","whatwg-url":"^14.2.0","ansi-styles":"^5.2.0","body-parser":"^1.20.4","buffer-from":"^1.1.2","check-error":"^1.0.3","cross-spawn":"^7.0.6","escape-html":"^1.0.3","has-symbols":"^1.1.0","http-errors":"^2.0.1","media-typer":"^0.3.0","on-finished":"^2.4.1","randombytes":"^2.1.0","rrweb-cssom":"^0.7.1","safe-buffer":"^5.2.1","signal-exit":"^4.1.0","symbol-tree":"^3.2.4","type-detect":"^4.1.0","utils-merge":"^1.0.1","yocto-queue":"^1.2.2","content-type":"^1.0.5","dunder-proto":"^1.0.1","finalhandler":"^1.3.2","magic-string":"^0.30.21","merge-stream":"^2.0.0","npm-run-path":"^5.3.0","range-parser":"^1.2.1","safer-buffer":"^2.1.2","serve-static":"^1.16.3","side-channel":"^1.1.0","toidentifier":"^1.0.1","tough-cookie":"^4.1.4","universalify":"^0.2.0","array-flatten":"^1.1.1","estree-walker":"^3.0.3","function-bind":"^1.1.2","get-func-name":"^2.0.2","get-intrinsic":"^1.3.0","human-signals":"^5.0.0","object-assign":"^4.1.1","pretty-format":"^29.7.0","requires-port":"^1.0.0","shebang-regex":"^3.0.0","source-map-js":"^1.2.1","strip-literal":"^2.1.1","delayed-stream":"^1.0.0","diff-sequences":"^29.6.3","object-inspect":"^1.13.4","path-to-regexp":"^0.1.13","querystringify":"^2.2.0","setprototypeof":"^1.2.0","assertion-error":"^1.1.0","combined-stream":"^1.0.8","es-object-atoms":"^1.1.1","has-tostringtag":"^1.0.2","math-intrinsics":"^1.1.0","shebang-command":"^2.0.0","whatwg-encoding":"^3.1.1","whatwg-mimetype":"^4.0.0","cookie-signature":"^1.0.7","http-proxy-agent":"^7.0.2","side-channel-map":"^1.0.1","https-proxy-agent":"^7.0.6","merge-descriptors":"^1.0.3","side-channel-list":"^1.0.0","w3c-xmlserializer":"^5.0.0","es-define-property":"^1.0.1","es-set-tostringtag":"^2.1.0","source-map-support":"^0.5.21","webidl-conversions":"^7.0.0","xml-name-validator":"^5.0.0","content-disposition":"^0.5.4","strip-final-newline":"^3.0.0","why-is-node-running":"^2.3.0","serialize-javascript":"^6.0.2","side-channel-weakmap":"^1.0.2","html-encoding-sniffer":"^4.0.0","call-bind-apply-helpers":"^1.0.2","is-potential-custom-element-name":"^1.0.1"},"_hasShrinkwrap":false,"devDependencies":{"cors":"^2.8.5","jsdom":"^24.0.0","rollup":"^4.9.0","vitest":"^1.2.0","express":"^4.18.2","@rollup/plugin-terser":"^0.4.4"},"_npmOperationalInternal":{"tmp":"tmp/checkout-friction-detector_1.0.0_1777414651704_0.9041845330965594","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"@atlanwave/checkout-friction-detector","version":"1.1.0","keywords":["checkout","friction","analytics","form","ux","abandonment","rage-click"],"author":{"url":"Samuel Adoga","name":"Atlanwave"},"license":"MIT","_id":"@atlanwave/checkout-friction-detector@1.1.0","maintainers":[{"name":"xiden001","email":"samuel.adoga1@gmail.com"}],"homepage":"https://github.com/xiden001/checkout-friction-detector#readme","bugs":{"url":"https://github.com/xiden001/checkout-friction-detector/issues"},"dist":{"shasum":"c087b26164ce9c7adaa1fcbb31643730aba0028e","tarball":"https://registry.npmjs.org/@atlanwave/checkout-friction-detector/-/checkout-friction-detector-1.1.0.tgz","fileCount":37,"integrity":"sha512-V9ItU39PIOjWJHG+1iCefnfpWosDAaD7o1g7Hmr/dGyqU+xtxXDBPcztaMdqe4+2YaJJBL6zHESgyyw0izc+JQ==","signatures":[{"sig":"MEUCIQDcn+6S37fN+ucFOP9+sP4fVlrJTjUHENgpM1nIwHbDVAIgMEsGCHXY1f8T+l+cyf6deFN8yMu0YFlb9HLTuVelTP8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":734146},"main":"dist/checkout-friction-detector.umd.js","type":"module","unpkg":"dist/checkout-friction-detector.umd.min.js","module":"dist/checkout-friction-detector.esm.js","browser":"dist/checkout-friction-detector.umd.js","gitHead":"a3aea7192a3c1e9b62a244c034e1510c3a99f7f9","scripts":{"dev":"rollup -c -w","test":"vitest run","build":"rollup -c","test:watch":"vitest","mock-server":"node examples/mock-server.js"},"_npmUser":{"name":"xiden001","email":"samuel.adoga1@gmail.com"},"repository":{"url":"git+https://github.com/xiden001/checkout-friction-detector.git","type":"git"},"_npmVersion":"11.11.0","description":"Lightweight browser library that detects checkout and form friction, reporting structured events to a backend API.","directories":{"test":"tests","example":"examples"},"_nodeVersion":"22.19.0","dependencies":{"ms":"^2.0.0","qs":"^6.14.2","ws":"^8.20.0","cac":"^6.7.14","psl":"^1.15.0","ufo":"^1.6.3","chai":"^4.5.0","depd":"^2.0.0","etag":"^1.8.1","gopd":"^1.2.0","mime":"^1.6.0","mlly":"^1.8.2","send":"^0.19.2","smob":"^1.6.1","tr46":"^5.1.1","vary":"^1.1.2","vite":"^5.4.21","acorn":"^8.16.0","bytes":"^3.1.2","debug":"^2.6.9","execa":"^8.0.1","fresh":"^0.5.2","isexe":"^2.0.0","loupe":"^2.3.7","pathe":"^1.1.2","saxes":"^6.0.0","which":"^2.0.2","cookie":"^0.7.2","hasown":"^2.0.2","nanoid":"^3.3.11","nwsapi":"^2.2.23","parse5":"^7.3.0","terser":"^5.46.1","unpipe":"^1.0.0","accepts":"^1.3.8","confbox":"^0.1.8","destroy":"^1.2.0","esbuild":"^0.21.5","methods":"^1.1.2","mime-db":"^1.52.0","onetime":"^6.0.0","p-limit":"^5.0.0","pathval":"^1.1.1","postcss":"^8.5.8","siginfo":"^2.0.0","std-env":"^3.10.0","tinyspy":"^2.2.1","type-is":"^1.6.18","asynckit":"^0.4.0","cssstyle":"^4.6.0","deep-eql":"^4.1.4","ee-first":"^1.1.1","entities":"^6.0.1","inherits":"^2.0.4","mimic-fn":"^4.0.0","parseurl":"^1.3.3","path-key":"^3.1.1","punycode":"^2.3.1","raw-body":"^2.5.3","react-is":"^18.3.1","statuses":"^2.0.2","tinypool":"^0.8.4","xmlchars":"^2.2.0","commander":"^2.20.3","data-urls":"^5.0.0","encodeurl":"^2.0.0","es-errors":"^1.3.0","form-data":"^4.0.5","forwarded":"^0.2.0","get-proto":"^1.0.1","ipaddr.js":"^1.9.1","is-stream":"^3.0.0","js-tokens":"^9.0.1","local-pkg":"^0.5.1","lru-cache":"^10.4.3","pkg-types":"^1.3.1","stackback":"^0.0.2","tinybench":"^2.9.0","url-parse":"^1.5.10","vite-node":"^1.6.1","acorn-walk":"^8.3.5","agent-base":"^7.1.4","call-bound":"^1.0.4","decimal.js":"^10.6.0","get-stream":"^8.0.1","iconv-lite":"^0.4.24","mime-types":"^2.1.35","negotiator":"^0.6.3","picocolors":"^1.1.1","proxy-addr":"^2.0.7","source-map":"^0.6.1","whatwg-url":"^14.2.0","ansi-styles":"^5.2.0","body-parser":"^1.20.4","buffer-from":"^1.1.2","check-error":"^1.0.3","cross-spawn":"^7.0.6","escape-html":"^1.0.3","has-symbols":"^1.1.0","http-errors":"^2.0.1","media-typer":"^0.3.0","on-finished":"^2.4.1","randombytes":"^2.1.0","rrweb-cssom":"^0.7.1","safe-buffer":"^5.2.1","signal-exit":"^4.1.0","symbol-tree":"^3.2.4","type-detect":"^4.1.0","utils-merge":"^1.0.1","yocto-queue":"^1.2.2","content-type":"^1.0.5","dunder-proto":"^1.0.1","finalhandler":"^1.3.2","magic-string":"^0.30.21","merge-stream":"^2.0.0","npm-run-path":"^5.3.0","range-parser":"^1.2.1","safer-buffer":"^2.1.2","serve-static":"^1.16.3","side-channel":"^1.1.0","toidentifier":"^1.0.1","tough-cookie":"^4.1.4","universalify":"^0.2.0","array-flatten":"^1.1.1","estree-walker":"^3.0.3","function-bind":"^1.1.2","get-func-name":"^2.0.2","get-intrinsic":"^1.3.0","human-signals":"^5.0.0","object-assign":"^4.1.1","pretty-format":"^29.7.0","requires-port":"^1.0.0","shebang-regex":"^3.0.0","source-map-js":"^1.2.1","strip-literal":"^2.1.1","delayed-stream":"^1.0.0","diff-sequences":"^29.6.3","object-inspect":"^1.13.4","path-to-regexp":"^0.1.13","querystringify":"^2.2.0","setprototypeof":"^1.2.0","assertion-error":"^1.1.0","combined-stream":"^1.0.8","es-object-atoms":"^1.1.1","has-tostringtag":"^1.0.2","math-intrinsics":"^1.1.0","shebang-command":"^2.0.0","whatwg-encoding":"^3.1.1","whatwg-mimetype":"^4.0.0","cookie-signature":"^1.0.7","http-proxy-agent":"^7.0.2","side-channel-map":"^1.0.1","https-proxy-agent":"^7.0.6","merge-descriptors":"^1.0.3","side-channel-list":"^1.0.0","w3c-xmlserializer":"^5.0.0","es-define-property":"^1.0.1","es-set-tostringtag":"^2.1.0","source-map-support":"^0.5.21","webidl-conversions":"^7.0.0","xml-name-validator":"^5.0.0","content-disposition":"^0.5.4","strip-final-newline":"^3.0.0","why-is-node-running":"^2.3.0","serialize-javascript":"^6.0.2","side-channel-weakmap":"^1.0.2","html-encoding-sniffer":"^4.0.0","call-bind-apply-helpers":"^1.0.2","is-potential-custom-element-name":"^1.0.1"},"_hasShrinkwrap":false,"devDependencies":{"cors":"^2.8.5","jsdom":"^24.0.0","rollup":"^4.9.0","vitest":"^1.2.0","express":"^4.18.2","@rollup/plugin-terser":"^0.4.4"},"_npmOperationalInternal":{"tmp":"tmp/checkout-friction-detector_1.1.0_1778158179887_0.703916099560371","host":"s3://npm-registry-packages-npm-production"}},"1.2.0":{"name":"@atlanwave/checkout-friction-detector","version":"1.2.0","keywords":["checkout","friction","analytics","form","ux","abandonment","rage-click"],"author":{"url":"Samuel Adoga","name":"Atlanwave"},"license":"MIT","_id":"@atlanwave/checkout-friction-detector@1.2.0","maintainers":[{"name":"xiden001","email":"samuel.adoga1@gmail.com"}],"homepage":"https://github.com/xiden001/checkout-friction-detector#readme","bugs":{"url":"https://github.com/xiden001/checkout-friction-detector/issues"},"dist":{"shasum":"ef7971595a20915c464ba59501a7ad0a64e050ea","tarball":"https://registry.npmjs.org/@atlanwave/checkout-friction-detector/-/checkout-friction-detector-1.2.0.tgz","fileCount":37,"integrity":"sha512-5SYR7p9I26ObI0NJLCvz8qsOvzIg+tRqCpcBug/Ve1PnBkX3WJuBLd9AfpBjWTRQBOzsa8zXkeEq5wOZcd8yjw==","signatures":[{"sig":"MEYCIQCGJ8gVGt4turI6lNR6HJ4bqBypoQky2dPVGlfzJRmuVQIhAN32JauXDQH3sR/TpHzAC2SC2acE/CnT54dBDzBaV7WN","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":742018},"main":"dist/checkout-friction-detector.umd.js","type":"module","unpkg":"dist/checkout-friction-detector.umd.min.js","module":"dist/checkout-friction-detector.esm.js","browser":"dist/checkout-friction-detector.umd.js","gitHead":"c612cb0e8a36d946ce5f97c797798f2c681c9f95","scripts":{"dev":"rollup -c -w","test":"vitest run","build":"rollup -c","test:watch":"vitest","mock-server":"node examples/mock-server.js"},"_npmUser":{"name":"xiden001","email":"samuel.adoga1@gmail.com"},"repository":{"url":"git+https://github.com/xiden001/checkout-friction-detector.git","type":"git"},"_npmVersion":"11.11.0","description":"Lightweight browser library that detects checkout and form friction, reporting structured events to a backend API.","directories":{"test":"tests","example":"examples"},"_nodeVersion":"22.19.0","dependencies":{"ms":"^2.0.0","qs":"^6.14.2","ws":"^8.20.0","cac":"^6.7.14","psl":"^1.15.0","ufo":"^1.6.3","chai":"^4.5.0","depd":"^2.0.0","etag":"^1.8.1","gopd":"^1.2.0","mime":"^1.6.0","mlly":"^1.8.2","send":"^0.19.2","smob":"^1.6.1","tr46":"^5.1.1","vary":"^1.1.2","vite":"^5.4.21","acorn":"^8.16.0","bytes":"^3.1.2","debug":"^2.6.9","execa":"^8.0.1","fresh":"^0.5.2","isexe":"^2.0.0","loupe":"^2.3.7","pathe":"^1.1.2","saxes":"^6.0.0","which":"^2.0.2","cookie":"^0.7.2","hasown":"^2.0.2","nanoid":"^3.3.11","nwsapi":"^2.2.23","parse5":"^7.3.0","terser":"^5.46.1","unpipe":"^1.0.0","accepts":"^1.3.8","confbox":"^0.1.8","destroy":"^1.2.0","esbuild":"^0.21.5","methods":"^1.1.2","mime-db":"^1.52.0","onetime":"^6.0.0","p-limit":"^5.0.0","pathval":"^1.1.1","postcss":"^8.5.8","siginfo":"^2.0.0","std-env":"^3.10.0","tinyspy":"^2.2.1","type-is":"^1.6.18","asynckit":"^0.4.0","cssstyle":"^4.6.0","deep-eql":"^4.1.4","ee-first":"^1.1.1","entities":"^6.0.1","inherits":"^2.0.4","mimic-fn":"^4.0.0","parseurl":"^1.3.3","path-key":"^3.1.1","punycode":"^2.3.1","raw-body":"^2.5.3","react-is":"^18.3.1","statuses":"^2.0.2","tinypool":"^0.8.4","xmlchars":"^2.2.0","commander":"^2.20.3","data-urls":"^5.0.0","encodeurl":"^2.0.0","es-errors":"^1.3.0","form-data":"^4.0.5","forwarded":"^0.2.0","get-proto":"^1.0.1","ipaddr.js":"^1.9.1","is-stream":"^3.0.0","js-tokens":"^9.0.1","local-pkg":"^0.5.1","lru-cache":"^10.4.3","pkg-types":"^1.3.1","stackback":"^0.0.2","tinybench":"^2.9.0","url-parse":"^1.5.10","vite-node":"^1.6.1","acorn-walk":"^8.3.5","agent-base":"^7.1.4","call-bound":"^1.0.4","decimal.js":"^10.6.0","get-stream":"^8.0.1","iconv-lite":"^0.4.24","mime-types":"^2.1.35","negotiator":"^0.6.3","picocolors":"^1.1.1","proxy-addr":"^2.0.7","source-map":"^0.6.1","whatwg-url":"^14.2.0","ansi-styles":"^5.2.0","body-parser":"^1.20.4","buffer-from":"^1.1.2","check-error":"^1.0.3","cross-spawn":"^7.0.6","escape-html":"^1.0.3","has-symbols":"^1.1.0","http-errors":"^2.0.1","media-typer":"^0.3.0","on-finished":"^2.4.1","randombytes":"^2.1.0","rrweb-cssom":"^0.7.1","safe-buffer":"^5.2.1","signal-exit":"^4.1.0","symbol-tree":"^3.2.4","type-detect":"^4.1.0","utils-merge":"^1.0.1","yocto-queue":"^1.2.2","content-type":"^1.0.5","dunder-proto":"^1.0.1","finalhandler":"^1.3.2","magic-string":"^0.30.21","merge-stream":"^2.0.0","npm-run-path":"^5.3.0","range-parser":"^1.2.1","safer-buffer":"^2.1.2","serve-static":"^1.16.3","side-channel":"^1.1.0","toidentifier":"^1.0.1","tough-cookie":"^4.1.4","universalify":"^0.2.0","array-flatten":"^1.1.1","estree-walker":"^3.0.3","function-bind":"^1.1.2","get-func-name":"^2.0.2","get-intrinsic":"^1.3.0","human-signals":"^5.0.0","object-assign":"^4.1.1","pretty-format":"^29.7.0","requires-port":"^1.0.0","shebang-regex":"^3.0.0","source-map-js":"^1.2.1","strip-literal":"^2.1.1","delayed-stream":"^1.0.0","diff-sequences":"^29.6.3","object-inspect":"^1.13.4","path-to-regexp":"^0.1.13","querystringify":"^2.2.0","setprototypeof":"^1.2.0","assertion-error":"^1.1.0","combined-stream":"^1.0.8","es-object-atoms":"^1.1.1","has-tostringtag":"^1.0.2","math-intrinsics":"^1.1.0","shebang-command":"^2.0.0","whatwg-encoding":"^3.1.1","whatwg-mimetype":"^4.0.0","cookie-signature":"^1.0.7","http-proxy-agent":"^7.0.2","side-channel-map":"^1.0.1","https-proxy-agent":"^7.0.6","merge-descriptors":"^1.0.3","side-channel-list":"^1.0.0","w3c-xmlserializer":"^5.0.0","es-define-property":"^1.0.1","es-set-tostringtag":"^2.1.0","source-map-support":"^0.5.21","webidl-conversions":"^7.0.0","xml-name-validator":"^5.0.0","content-disposition":"^0.5.4","strip-final-newline":"^3.0.0","why-is-node-running":"^2.3.0","serialize-javascript":"^6.0.2","side-channel-weakmap":"^1.0.2","html-encoding-sniffer":"^4.0.0","call-bind-apply-helpers":"^1.0.2","is-potential-custom-element-name":"^1.0.1"},"_hasShrinkwrap":false,"devDependencies":{"cors":"^2.8.5","jsdom":"^24.0.0","rollup":"^4.9.0","vitest":"^1.2.0","express":"^4.18.2","@rollup/plugin-terser":"^0.4.4"},"_npmOperationalInternal":{"tmp":"tmp/checkout-friction-detector_1.2.0_1779268956080_0.515612966903314","host":"s3://npm-registry-packages-npm-production"}},"1.3.0":{"name":"@atlanwave/checkout-friction-detector","version":"1.3.0","description":"Lightweight browser library that detects checkout and form friction, reporting structured events to a backend API.","keywords":["checkout","friction","analytics","form","ux","abandonment","rage-click"],"homepage":"https://github.com/xiden001/checkout-friction-detector#readme","bugs":{"url":"https://github.com/xiden001/checkout-friction-detector/issues"},"repository":{"type":"git","url":"git+https://github.com/xiden001/checkout-friction-detector.git"},"license":"SEE LICENSE IN LICENSE","author":{"name":"Atlanwave","url":"Samuel Adoga"},"type":"module","main":"dist/checkout-friction-detector.umd.js","browser":"dist/checkout-friction-detector.umd.js","directories":{"example":"examples","test":"tests"},"scripts":{"build":"rollup -c","dev":"rollup -c -w","test":"vitest run","test:watch":"vitest","mock-server":"node examples/mock-server.js"},"dependencies":{"accepts":"^1.3.8","acorn":"^8.16.0","acorn-walk":"^8.3.5","agent-base":"^7.1.4","ansi-styles":"^5.2.0","array-flatten":"^1.1.1","assertion-error":"^1.1.0","asynckit":"^0.4.0","body-parser":"^1.20.4","buffer-from":"^1.1.2","bytes":"^3.1.2","cac":"^6.7.14","call-bind-apply-helpers":"^1.0.2","call-bound":"^1.0.4","chai":"^4.5.0","check-error":"^1.0.3","combined-stream":"^1.0.8","commander":"^2.20.3","confbox":"^0.1.8","content-disposition":"^0.5.4","content-type":"^1.0.5","cookie":"^0.7.2","cookie-signature":"^1.0.7","cross-spawn":"^7.0.6","cssstyle":"^4.6.0","data-urls":"^5.0.0","debug":"^2.6.9","decimal.js":"^10.6.0","deep-eql":"^4.1.4","delayed-stream":"^1.0.0","depd":"^2.0.0","destroy":"^1.2.0","diff-sequences":"^29.6.3","dunder-proto":"^1.0.1","ee-first":"^1.1.1","encodeurl":"^2.0.0","entities":"^6.0.1","es-define-property":"^1.0.1","es-errors":"^1.3.0","es-object-atoms":"^1.1.1","es-set-tostringtag":"^2.1.0","esbuild":"^0.21.5","escape-html":"^1.0.3","estree-walker":"^3.0.3","etag":"^1.8.1","execa":"^8.0.1","finalhandler":"^1.3.2","form-data":"^4.0.5","forwarded":"^0.2.0","fresh":"^0.5.2","function-bind":"^1.1.2","get-func-name":"^2.0.2","get-intrinsic":"^1.3.0","get-proto":"^1.0.1","get-stream":"^8.0.1","gopd":"^1.2.0","has-symbols":"^1.1.0","has-tostringtag":"^1.0.2","hasown":"^2.0.2","html-encoding-sniffer":"^4.0.0","http-errors":"^2.0.1","http-proxy-agent":"^7.0.2","https-proxy-agent":"^7.0.6","human-signals":"^5.0.0","iconv-lite":"^0.4.24","inherits":"^2.0.4","ipaddr.js":"^1.9.1","is-potential-custom-element-name":"^1.0.1","is-stream":"^3.0.0","isexe":"^2.0.0","js-tokens":"^9.0.1","local-pkg":"^0.5.1","loupe":"^2.3.7","lru-cache":"^10.4.3","magic-string":"^0.30.21","math-intrinsics":"^1.1.0","media-typer":"^0.3.0","merge-descriptors":"^1.0.3","merge-stream":"^2.0.0","methods":"^1.1.2","mime":"^1.6.0","mime-db":"^1.52.0","mime-types":"^2.1.35","mimic-fn":"^4.0.0","mlly":"^1.8.2","ms":"^2.0.0","nanoid":"^3.3.11","negotiator":"^0.6.3","npm-run-path":"^5.3.0","nwsapi":"^2.2.23","object-assign":"^4.1.1","object-inspect":"^1.13.4","on-finished":"^2.4.1","onetime":"^6.0.0","p-limit":"^5.0.0","parse5":"^7.3.0","parseurl":"^1.3.3","path-key":"^3.1.1","path-to-regexp":"^0.1.13","pathe":"^1.1.2","pathval":"^1.1.1","picocolors":"^1.1.1","pkg-types":"^1.3.1","postcss":"^8.5.8","pretty-format":"^29.7.0","proxy-addr":"^2.0.7","psl":"^1.15.0","punycode":"^2.3.1","qs":"^6.14.2","querystringify":"^2.2.0","randombytes":"^2.1.0","range-parser":"^1.2.1","raw-body":"^2.5.3","react-is":"^18.3.1","requires-port":"^1.0.0","rrweb-cssom":"^0.7.1","safe-buffer":"^5.2.1","safer-buffer":"^2.1.2","saxes":"^6.0.0","send":"^0.19.2","serialize-javascript":"^6.0.2","serve-static":"^1.16.3","setprototypeof":"^1.2.0","shebang-command":"^2.0.0","shebang-regex":"^3.0.0","side-channel":"^1.1.0","side-channel-list":"^1.0.0","side-channel-map":"^1.0.1","side-channel-weakmap":"^1.0.2","siginfo":"^2.0.0","signal-exit":"^4.1.0","smob":"^1.6.1","source-map":"^0.6.1","source-map-js":"^1.2.1","source-map-support":"^0.5.21","stackback":"^0.0.2","statuses":"^2.0.2","std-env":"^3.10.0","strip-final-newline":"^3.0.0","strip-literal":"^2.1.1","symbol-tree":"^3.2.4","terser":"^5.46.1","tinybench":"^2.9.0","tinypool":"^0.8.4","tinyspy":"^2.2.1","toidentifier":"^1.0.1","tough-cookie":"^4.1.4","tr46":"^5.1.1","type-detect":"^4.1.0","type-is":"^1.6.18","ufo":"^1.6.3","universalify":"^0.2.0","unpipe":"^1.0.0","url-parse":"^1.5.10","utils-merge":"^1.0.1","vary":"^1.1.2","vite":"^5.4.21","vite-node":"^1.6.1","w3c-xmlserializer":"^5.0.0","webidl-conversions":"^7.0.0","whatwg-encoding":"^3.1.1","whatwg-mimetype":"^4.0.0","whatwg-url":"^14.2.0","which":"^2.0.2","why-is-node-running":"^2.3.0","ws":"^8.20.0","xml-name-validator":"^5.0.0","xmlchars":"^2.2.0","yocto-queue":"^1.2.2"},"devDependencies":{"@rollup/plugin-terser":"^0.4.4","express":"^4.18.2","cors":"^2.8.5","jsdom":"^24.0.0","rollup":"^4.9.0","vitest":"^1.2.0"},"module":"dist/checkout-friction-detector.esm.js","unpkg":"dist/checkout-friction-detector.umd.min.js","gitHead":"6a01ec00c9c905587ae8c04940e2f9d3c63f41b0","_id":"@atlanwave/checkout-friction-detector@1.3.0","_nodeVersion":"22.19.0","_npmVersion":"11.11.0","dist":{"integrity":"sha512-t/SEOaf2B+imXKs+NYIeesu+kekm2DcQrOKSl/3w1Mhf9oFRPs7JWnbkD/or7F1SfR35OBYkGDDunB6EpwxHwQ==","shasum":"abc02307dc7d9d66f0b9c00816f019c878a8c8cd","tarball":"https://registry.npmjs.org/@atlanwave/checkout-friction-detector/-/checkout-friction-detector-1.3.0.tgz","fileCount":38,"unpackedSize":745867,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCICyyb0ue3VzghVAY+i82SEHaInh72puC7BTNXggGISwYAiBE7lFVIeg+6B7oOQImgAjd4WC0hd5iBr8hU5U8B0guBA=="}]},"_npmUser":{"name":"xiden001","email":"samuel.adoga1@gmail.com"},"maintainers":[{"name":"xiden001","email":"samuel.adoga1@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/checkout-friction-detector_1.3.0_1781812420619_0.4090009629346505"},"_hasShrinkwrap":false}},"time":{"created":"2026-04-28T22:17:31.599Z","modified":"2026-06-18T19:53:40.997Z","1.0.0":"2026-04-28T22:17:31.867Z","1.1.0":"2026-05-07T12:49:40.057Z","1.2.0":"2026-05-20T09:22:36.245Z","1.3.0":"2026-06-18T19:53:40.849Z"},"bugs":{"url":"https://github.com/xiden001/checkout-friction-detector/issues"},"author":{"name":"Atlanwave","url":"Samuel Adoga"},"license":"SEE LICENSE IN LICENSE","homepage":"https://github.com/xiden001/checkout-friction-detector#readme","keywords":["checkout","friction","analytics","form","ux","abandonment","rage-click"],"repository":{"type":"git","url":"git+https://github.com/xiden001/checkout-friction-detector.git"},"description":"Lightweight browser library that detects checkout and form friction, reporting structured events to a backend API.","maintainers":[{"name":"xiden001","email":"samuel.adoga1@gmail.com"}],"readme":"# checkout-friction-detector\r\n\r\nLightweight, framework-agnostic browser library that detects checkout and form friction — hesitation, repeated edits, validation failures, abandonment, rage clicks, and more — and reports structured events to a backend API.\r\n\r\n## Installation\r\n\r\n### npm\r\n\r\n```bash\r\nnpm install checkout-friction-detector\r\n```\r\n\r\n```js\r\nimport CheckoutFrictionDetector from \"checkout-friction-detector\";\r\n\r\nCheckoutFrictionDetector.init({\r\n  publicKey: \"pk_live_xxx\",\r\n});\r\n```\r\n\r\n### Script tag\r\n\r\n```html\r\n<script src=\"https://cfd.atlanwave.com/js/checkout-friction-detector.umd.min.js\"></script>\r\n<script>\r\n  CheckoutFrictionDetector.init({\r\n    publicKey: \"pk_live_xxx\",\r\n  });\r\n</script>\r\n```\r\n\r\n## Quick start\r\n\r\n```js\r\nCheckoutFrictionDetector.init({\r\n  publicKey: \"pk_live_xxx\",\r\n  debug: true,\r\n  formSelector: \"form, .checkout-container\",\r\n  hesitationThresholdMs: 2000,\r\n  hooks: {\r\n    onSignal(event) {\r\n      console.log(event.eventType, event.signal);\r\n    },\r\n  },\r\n});\r\n```\r\n\r\n## Public API\r\n\r\n| Method                             | Description                                        |\r\n| ---------------------------------- | -------------------------------------------------- |\r\n| `init(config)`                     | Initialize the detector with configuration options |\r\n| `destroy()`                        | Remove all listeners and clean up state            |\r\n| `pause()`                          | Temporarily stop emitting signals                  |\r\n| `resume()`                         | Resume signal emission after pause                 |\r\n| `trackCustomEvent(name, payload?)` | Emit a custom event                                |\r\n| `trackCartView(opts)`              | Emit a `cart_view` event with the current cart total |\r\n| `trackOrderCompleted(opts)`        | Emit an `order_completed` event on the success page  |\r\n| `flush()`                          | Manually flush the event queue to the backend      |\r\n| `getState()`                       | Return safe diagnostic metadata                    |\r\n\r\n## Configuration\r\n\r\n```js\r\nCheckoutFrictionDetector.init({\r\n  // Required\r\n  publicKey: \"pk_live_xxx\",\r\n\r\n  // General\r\n  debug: false, // Enable console logging\r\n  autoTrack: true, // Auto-attach detectors on init\r\n\r\n  // Form discovery\r\n  formSelector: \"form\", // CSS selector for forms\r\n  excludeSelector: \"[data-cfd-ignore]\", // Exclude matching elements\r\n  trackContentEditable: false,\r\n\r\n  // Multi-step forms\r\n  stepSelectors: [\".checkout-step\", \"[data-step]\"],\r\n\r\n  // Detection thresholds\r\n  hesitationThresholdMs: 2000, // Focus-to-input delay\r\n  longCompletionThresholdMs: 8000, // Time in a single field\r\n  repeatedEditThreshold: 3, // Direction changes before emitting\r\n  inactivityTimeoutMs: 180000, // Abandonment inactivity window\r\n\r\n  // Rage clicks\r\n  rageClickThreshold: {\r\n    clicks: 3,\r\n    windowMs: 1000,\r\n    radiusPx: 30,\r\n  },\r\n\r\n  // Dead clicks\r\n  deadClickWindowMs: 500,\r\n\r\n  // Validation\r\n  validationErrorClasses: [\"error\", \"is-invalid\", \"input-error\"],\r\n\r\n  // Conversion detection\r\n  successUrlPatterns: [\"/thank-you\", \"/order-confirmation\"],\r\n  successElementSelectors: [\".order-success\", \"[data-checkout-success]\"],\r\n\r\n  // Privacy (privacy-first defaults)\r\n  maskFields: ['input[type=\"password\"]', '[name*=\"card\"]', '[name*=\"cvv\"]'],\r\n  allowValueCapture: false, // Never capture field values by default\r\n  sensitiveFieldPatterns: [/password/i, /card/i, /cvv/i, /ssn/i],\r\n\r\n  // Transport\r\n  flushIntervalMs: 10000,\r\n  batchSize: 20,\r\n  requestTimeoutMs: 10000,\r\n  retryCount: 3,\r\n  maxQueueSize: 500,\r\n  useLocalStorageQueue: false,\r\n\r\n  // Hooks\r\n  hooks: {\r\n    beforeSend(eventBatch) {},\r\n    afterSend(response) {},\r\n    onSignal(event) {},\r\n    isFieldSensitive(fieldInfo) {}, // Return boolean\r\n    extractValidationState(fieldEl) {}, // Return 'invalid' or falsy\r\n  },\r\n});\r\n```\r\n\r\n## Event types\r\n\r\n| Event                    | Trigger                                              |\r\n| ------------------------ | ---------------------------------------------------- |\r\n| `form_discovered`        | Form element found on page or dynamically added      |\r\n| `form_started`           | First meaningful field interaction in a form         |\r\n| `field_hesitation`       | User focuses field, no input for threshold duration  |\r\n| `field_long_completion`  | Time in a single field exceeds threshold             |\r\n| `field_repeated_edits`   | Value changed (direction changes) exceeds threshold  |\r\n| `field_validation_error` | Native invalid, aria-invalid, or CSS class detected  |\r\n| `step_viewed`            | Multi-step form step becomes visible                 |\r\n| `step_revisited`         | User returns to a previously viewed step             |\r\n| `step_blocked`           | Submit attempt blocked on current step               |\r\n| `submit_attempt`         | Click on submit button detected                      |\r\n| `rage_click`             | Rapid repeated clicks in small area                  |\r\n| `dead_click`             | Click on control with no DOM change after window     |\r\n| `backtracking`           | User moves backward in field sequence                |\r\n| `form_abandoned`         | Started form not completed (page exit or inactivity) |\r\n| `form_completed`         | Form successfully submitted or success detected      |\r\n| `cart_view`              | Cart total reported via `trackCartView()`            |\r\n| `order_completed`        | Order completion reported via `trackOrderCompleted()`|\r\n| `custom_event`           | Manually tracked via `trackCustomEvent()`            |\r\n\r\n## Event schema\r\n\r\nEvery event includes:\r\n\r\n```json\r\n{\r\n  \"eventId\": \"uuid\",\r\n  \"sessionId\": \"uuid\",\r\n  \"pageViewId\": \"uuid\",\r\n  \"formInstanceId\": \"uuid\",\r\n  \"eventType\": \"field_hesitation\",\r\n  \"eventTimestamp\": 1712345678000,\r\n  \"page\": {\r\n    \"url\": \"https://example.com/checkout\",\r\n    \"path\": \"/checkout\",\r\n    \"referrer\": \"https://example.com/cart\",\r\n    \"title\": \"Checkout\",\r\n    \"viewport\": { \"width\": 1440, \"height\": 900 },\r\n    \"screen\": { \"width\": 1920, \"height\": 1080 },\r\n    \"timezone\": \"America/New_York\",\r\n    \"userAgent\": \"...\",\r\n    \"language\": \"en-US\",\r\n    \"deviceType\": \"desktop\"\r\n  },\r\n  \"form\": {\r\n    \"cssPath\": \"form#checkout\",\r\n    \"started\": true,\r\n    \"submitAttempts\": 0,\r\n    \"currentStep\": \"shipping\"\r\n  },\r\n  \"field\": {\r\n    \"tagName\": \"input\",\r\n    \"type\": \"email\",\r\n    \"name\": \"email\",\r\n    \"id\": \"email\",\r\n    \"label\": \"Email Address\",\r\n    \"cssPath\": \"form#checkout > input#email\",\r\n    \"fingerprint\": \"a1b2c3d4\"\r\n  },\r\n  \"signal\": {\r\n    \"hesitationDurationMs\": 2000,\r\n    \"previouslyVisited\": false\r\n  },\r\n  \"libraryVersion\": \"1.0.0\"\r\n}\r\n```\r\n\r\n## Revenue tracking\r\n\r\nThe library can attribute revenue impact to the friction it detects. Two\r\nevents: `cart_view` (fired when a checkout page loads with a known cart\r\ntotal) and `order_completed` (fired on the post-purchase success page).\r\n\r\nBoth go through the existing `/api/v1/ingest` endpoint with the same\r\nsession and pageView envelope.\r\n\r\n`valueMinor` is the cart total in minor units (cents/pence) as an integer\r\n— never floats. Without it the backend can only show event-count framing\r\nin reports, not revenue impact.\r\n\r\n### API\r\n\r\n```js\r\nCheckoutFrictionDetector.trackCartView({\r\n  valueMinor: 4999, // preferred — integer in cents\r\n  // value: 49.99,  // alternative — float, library will × 100\r\n  currency: \"USD\",\r\n  itemCount: 3, // optional\r\n});\r\n\r\nCheckoutFrictionDetector.trackOrderCompleted({\r\n  valueMinor: 4999,\r\n  currency: \"USD\",\r\n  orderRef: \"ord_abc123\", // optional, must be a non-PII id\r\n});\r\n```\r\n\r\n`orderRef` must be an opaque order identifier — never an email, name, or\r\nanything that identifies the customer. If the value looks like an email\r\nthe library drops it and emits a `console.warn`.\r\n\r\n### Vanilla JS\r\n\r\n```html\r\n<script src=\"https://cfd.atlanwave.com/js/checkout-friction-detector.umd.min.js\"></script>\r\n<script>\r\n  CheckoutFrictionDetector.init({ publicKey: \"pk_live_xxx\" });\r\n  CheckoutFrictionDetector.trackCartView({\r\n    valueMinor: 4999,\r\n    currency: \"USD\",\r\n    itemCount: 3,\r\n  });\r\n</script>\r\n```\r\n\r\n### React\r\n\r\n```jsx\r\nimport { useEffect } from \"react\";\r\nimport CheckoutFrictionDetector from \"checkout-friction-detector\";\r\n\r\nfunction CheckoutPage({ cart }) {\r\n  useEffect(() => {\r\n    CheckoutFrictionDetector.trackCartView({\r\n      valueMinor: cart.totalCents,\r\n      currency: cart.currency,\r\n      itemCount: cart.items.length,\r\n    });\r\n  }, [cart.totalCents, cart.currency, cart.items.length]);\r\n\r\n  return /* ... */;\r\n}\r\n\r\nfunction OrderSuccessPage({ order }) {\r\n  useEffect(() => {\r\n    CheckoutFrictionDetector.trackOrderCompleted({\r\n      valueMinor: order.totalCents,\r\n      currency: order.currency,\r\n      orderRef: order.number,\r\n    });\r\n  }, [order.number]);\r\n\r\n  return /* ... */;\r\n}\r\n```\r\n\r\n### Shopify Liquid\r\n\r\n```liquid\r\n<script>\r\n  CheckoutFrictionDetector.trackCartView({\r\n    valueMinor: {{ cart.total_price }},\r\n    currency: {{ cart.currency.iso_code | json }},\r\n    itemCount: {{ cart.item_count }}\r\n  });\r\n</script>\r\n\r\n{% comment %} On the order status page: {% endcomment %}\r\n<script>\r\n  CheckoutFrictionDetector.trackOrderCompleted({\r\n    valueMinor: {{ checkout.total_price }},\r\n    currency: {{ checkout.currency | json }},\r\n    orderRef: {{ checkout.order_number | json }}\r\n  });\r\n</script>\r\n```\r\n\r\n### Auto-detection (opt-in)\r\n\r\nSet `autoDetectCart: true` in the init config and the library will make a\r\nbest-effort attempt to fire `cart_view` / `order_completed` on init from:\r\n\r\n- Schema.org JSON-LD `Product` / `Order` blocks\r\n- Shopify checkout: `window.Shopify.checkout.total_price` (already in minor units)\r\n- Stripe Checkout success page: a `?session_id=` query param triggers a\r\n  presence-only `order_completed` (no value — your backend reconciles via\r\n  the Stripe webhook)\r\n\r\n```js\r\nCheckoutFrictionDetector.init({\r\n  publicKey: \"pk_live_xxx\",\r\n  autoDetectCart: true,\r\n});\r\n```\r\n\r\nThe library deliberately does **not** parse arbitrary DOM cart totals —\r\ntoo easy to grab the wrong element. The explicit `trackCartView` API is\r\nthe recommended path.\r\n\r\n## Privacy model\r\n\r\n**Privacy-first by default:**\r\n\r\n- Field values are **never captured** unless `allowValueCapture: true` is set\r\n- Even with value capture enabled, sensitive fields (password, card, CVV, SSN) are always masked\r\n- Fields matching `maskFields` selectors or `sensitiveFieldPatterns` are treated as sensitive\r\n- The `isFieldSensitive` hook allows custom sensitivity logic\r\n- No `innerText` capture beyond safe label extraction\r\n- No keystroke-level recording\r\n- Outgoing payloads are sanitized and size-limited\r\n\r\n## SPA support\r\n\r\nThe library automatically detects route changes via History API (`pushState`/`replaceState`) and `popstate`. On navigation:\r\n\r\n- `pageViewId` is refreshed\r\n- `sessionId` is preserved\r\n- Forms are re-scanned\r\n- Success URL patterns are re-checked\r\n\r\nNo additional configuration needed for most SPAs.\r\n\r\n## Examples\r\n\r\n- `examples/simple-checkout.html` — Basic single-page checkout form\r\n- `examples/multi-step-checkout.html` — Multi-step wizard with step tracking\r\n- `examples/spa-checkout.html` — SPA with client-side routing\r\n- `examples/test-harness.html` — Interactive friction scenario simulator\r\n\r\nStart the mock server and open examples in your browser:\r\n\r\n```bash\r\nnpm run mock-server\r\n# Open http://localhost:3333/simple-checkout.html\r\n```\r\n\r\n## Build outputs\r\n\r\n| File                                         | Format       | Use case                         |\r\n| -------------------------------------------- | ------------ | -------------------------------- |\r\n| `dist/checkout-friction-detector.esm.js`     | ESM          | Bundlers (webpack, vite, rollup) |\r\n| `dist/checkout-friction-detector.umd.js`     | UMD          | Script tag, RequireJS            |\r\n| `dist/checkout-friction-detector.umd.min.js` | UMD minified | Production script tag            |\r\n\r\n## License\r\n\r\nProprietary and confidential. Copyright (c) 2026 Atlanwave (Samuel Adoga). All\r\nrights reserved. This software may not be copied, redistributed, resold, or used\r\nwithout a valid commercial license. See [LICENSE](LICENSE) for the full terms.\r\n","readmeFilename":"README.md"}