@beworke/pixel 0.1.0-rc.6 → 0.1.0-rc.8

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.
Files changed (166) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/README.md +71 -56
  3. package/RELEASE_CANDIDATE.md +47 -75
  4. package/dist/Pixel-CCgGk43j.d.ts +797 -0
  5. package/dist/Pixel-CqbgC_72.d.mts +797 -0
  6. package/dist/{StorageFactory-tjfzk57c.d.ts → StorageFactory-BRBsnnH7.d.ts} +2 -2
  7. package/dist/{StorageFactory-CPghDPBj.d.mts → StorageFactory-Dp19Wecr.d.mts} +2 -2
  8. package/dist/browser/index.cjs.js +3 -0
  9. package/dist/browser/index.cjs.js.map +1 -0
  10. package/dist/browser/index.d.mts +55 -0
  11. package/dist/browser/index.d.ts +55 -0
  12. package/dist/browser/index.esm.js +3 -0
  13. package/dist/browser/index.esm.js.map +1 -0
  14. package/dist/browser/pixel.global.js +4 -0
  15. package/dist/browser/pixel.global.js.map +1 -0
  16. package/dist/config/index.cjs.js +1 -1
  17. package/dist/config/index.cjs.js.map +1 -1
  18. package/dist/config/index.d.mts +16 -6
  19. package/dist/config/index.d.ts +16 -6
  20. package/dist/config/index.esm.js +1 -1
  21. package/dist/config/index.esm.js.map +1 -1
  22. package/dist/events/index.cjs.js.map +1 -1
  23. package/dist/events/index.d.mts +2 -2
  24. package/dist/events/index.d.ts +2 -2
  25. package/dist/events/index.esm.js.map +1 -1
  26. package/dist/examples/html-script/README.md +20 -76
  27. package/dist/examples/html-script/RELEASE_CANDIDATE.md +20 -21
  28. package/dist/examples/html-script/add-payment-info/example-add-payment-info-card-autocomplete.html +41 -48
  29. package/dist/examples/html-script/add-payment-info/example-add-payment-info-card-disabled.html +41 -48
  30. package/dist/examples/html-script/add-payment-info/example-add-payment-info-card-fields.html +41 -48
  31. package/dist/examples/html-script/add-payment-info/example-add-payment-info-data-track.html +41 -48
  32. package/dist/examples/html-script/add-payment-info/example-add-payment-info-dedupe.html +41 -48
  33. package/dist/examples/html-script/add-payment-info/example-add-payment-info-manual.html +41 -48
  34. package/dist/examples/html-script/add-payment-info/example-add-payment-info-rules-card.html +41 -48
  35. package/dist/examples/html-script/add-payment-info/example-add-payment-info-security.html +41 -48
  36. package/dist/examples/html-script/add-to-cart/README.md +6 -3
  37. package/dist/examples/html-script/add-to-cart/example-add-to-cart-attribute.html +43 -49
  38. package/dist/examples/html-script/add-to-cart/example-add-to-cart-auto.html +43 -49
  39. package/dist/examples/html-script/add-to-cart/example-add-to-cart-click.html +43 -49
  40. package/dist/examples/html-script/add-to-cart/example-add-to-cart-dedupe.html +43 -49
  41. package/dist/examples/html-script/add-to-cart/example-add-to-cart-link.html +590 -0
  42. package/dist/examples/html-script/add-to-cart/example-add-to-cart-manual.html +43 -49
  43. package/dist/examples/html-script/add-to-cart/example-add-to-cart-order-bump.html +43 -49
  44. package/dist/examples/html-script/add-to-cart/example-add-to-cart-text.html +43 -49
  45. package/dist/examples/html-script/behavior/example-behavior-engagement.html +5 -5
  46. package/dist/examples/html-script/behavior/example-behavior-heartbeat.html +5 -5
  47. package/dist/examples/html-script/behavior/example-behavior-runtime-intelligence.html +5 -5
  48. package/dist/examples/html-script/behavior/example-behavior-viewport.html +5 -5
  49. package/dist/examples/html-script/behavior/example-behavior.html +1 -1
  50. package/dist/examples/html-script/buygoods/example-buygoods-checkout.html +83 -0
  51. package/dist/examples/html-script/example-basic.html +1 -1
  52. package/dist/examples/html-script/example-checkout-commerce.html +32 -31
  53. package/dist/examples/html-script/example-conversion.html +42 -49
  54. package/dist/examples/html-script/example-global-factory-classic.html +45 -0
  55. package/dist/examples/html-script/example-global-factory.html +40 -0
  56. package/dist/examples/html-script/example-integration.html +40 -46
  57. package/dist/examples/html-script/example-landing-commerce.html +45 -9
  58. package/dist/examples/html-script/example-runtime-diagnostics.html +5 -5
  59. package/dist/examples/html-script/example-transport.html +65 -58
  60. package/dist/examples/html-script/full-funnel/README.md +1 -1
  61. package/dist/examples/html-script/full-funnel/checkout.html +4 -2
  62. package/dist/examples/html-script/full-funnel/downsell.html +4 -2
  63. package/dist/examples/html-script/full-funnel/landing.html +57 -3
  64. package/dist/examples/html-script/full-funnel/thank-you.html +4 -2
  65. package/dist/examples/html-script/full-funnel/upsell.html +4 -2
  66. package/dist/examples/html-script/initiate-checkout/example-initiate-checkout-attribute.html +41 -48
  67. package/dist/examples/html-script/initiate-checkout/example-initiate-checkout-auto.html +41 -48
  68. package/dist/examples/html-script/initiate-checkout/example-initiate-checkout-click.html +41 -48
  69. package/dist/examples/html-script/initiate-checkout/example-initiate-checkout-manual.html +41 -48
  70. package/dist/examples/html-script/initiate-checkout/example-initiate-checkout-snapshot.html +41 -48
  71. package/dist/examples/html-script/initiate-checkout/example-initiate-checkout-submit.html +41 -48
  72. package/dist/examples/html-script/initiate-checkout/example-initiate-checkout-text.html +41 -48
  73. package/dist/examples/html-script/lead/example-lead-trigger-attribute.html +41 -48
  74. package/dist/examples/html-script/lead/example-lead-trigger-auto.html +41 -48
  75. package/dist/examples/html-script/lead/example-lead-trigger-click.html +41 -48
  76. package/dist/examples/html-script/release-candidate.html +32 -31
  77. package/dist/examples/html-script/remove-from-cart/README.md +3 -3
  78. package/dist/examples/html-script/remove-from-cart/example-remove-from-cart-attribute.html +41 -48
  79. package/dist/examples/html-script/remove-from-cart/example-remove-from-cart-css.html +41 -48
  80. package/dist/examples/html-script/remove-from-cart/example-remove-from-cart-dedupe.html +48 -55
  81. package/dist/examples/html-script/remove-from-cart/example-remove-from-cart-manual.html +41 -48
  82. package/dist/examples/html-script/remove-from-cart/example-remove-from-cart-multi.html +41 -48
  83. package/dist/examples/html-script/remove-from-cart/example-remove-from-cart-state.html +41 -48
  84. package/dist/examples/html-script/remove-from-cart/example-remove-from-cart-text.html +41 -48
  85. package/dist/examples/html-script/search/example-search-attribute.html +41 -48
  86. package/dist/examples/html-script/search/example-search-button-sync.html +41 -48
  87. package/dist/examples/html-script/search/example-search-dedupe.html +41 -48
  88. package/dist/examples/html-script/search/example-search-input.html +41 -48
  89. package/dist/examples/html-script/search/example-search-manual.html +41 -48
  90. package/dist/examples/html-script/search/example-search-submit.html +41 -48
  91. package/dist/examples/html-script/search/example-search-text.html +41 -48
  92. package/dist/examples/html-script/url-context/example-url-context-allowed-domains.html +38 -9
  93. package/dist/examples/html-script/url-context/example-url-context-landing.html +53 -13
  94. package/dist/examples/html-script/url-context/example-url-context-upsell.html +48 -10
  95. package/dist/examples/html-script/url-context/example-url-context.html +55 -21
  96. package/dist/examples/html-script/view-content/example-view-content-attribute.html +41 -48
  97. package/dist/examples/html-script/view-content/example-view-content-css.html +41 -48
  98. package/dist/examples/html-script/view-content/example-view-content-dedupe.html +41 -48
  99. package/dist/examples/html-script/view-content/example-view-content-empty.html +41 -48
  100. package/dist/examples/html-script/view-content/example-view-content-manual.html +41 -48
  101. package/dist/examples/html-script/view-content/example-view-content-product-card.html +41 -48
  102. package/dist/examples/html-script/view-content/example-view-content-text.html +41 -48
  103. package/dist/examples/release-candidate/README.md +2 -1
  104. package/dist/examples/v2/README.md +15 -15
  105. package/dist/{index-CQAyT5Od.d.ts → index-B8u_3PGG.d.ts} +21 -2
  106. package/dist/{index-JlKPz4pp.d.mts → index-BxT2d-TK.d.mts} +21 -2
  107. package/dist/index.cjs.js +1 -1
  108. package/dist/index.cjs.js.map +1 -1
  109. package/dist/index.d.mts +21 -782
  110. package/dist/index.d.ts +21 -782
  111. package/dist/index.esm.js +1 -1
  112. package/dist/index.esm.js.map +1 -1
  113. package/dist/{pixel-CKc4OQUx.d.mts → pixel-C93c-0M2.d.mts} +234 -101
  114. package/dist/{pixel-BxZZx8l5.d.ts → pixel-DVy4rzj8.d.ts} +234 -101
  115. package/dist/pixel-default-config-BkAjriVH.d.mts +21 -0
  116. package/dist/pixel-default-config-Co69vDP3.d.ts +21 -0
  117. package/dist/pixel-settings-BhfJqA92.d.mts +40 -0
  118. package/dist/pixel-settings-C0qPFTii.d.ts +40 -0
  119. package/dist/runtime/index.cjs.js +1 -1
  120. package/dist/runtime/index.cjs.js.map +1 -1
  121. package/dist/runtime/index.d.mts +6 -6
  122. package/dist/runtime/index.d.ts +6 -6
  123. package/dist/runtime/index.esm.js +1 -1
  124. package/dist/runtime/index.esm.js.map +1 -1
  125. package/dist/services/index.cjs.js +1 -1
  126. package/dist/services/index.cjs.js.map +1 -1
  127. package/dist/services/index.d.mts +7 -7
  128. package/dist/services/index.d.ts +7 -7
  129. package/dist/services/index.esm.js +1 -1
  130. package/dist/services/index.esm.js.map +1 -1
  131. package/dist/{types-C75pQP31.d.ts → types-B2aUNHb3.d.ts} +2 -2
  132. package/dist/{types-BP8dz1gP.d.mts → types-C0J9KUQg.d.mts} +2 -2
  133. package/dist/{types-DMhzHSVC.d.mts → types-C2dsBog1.d.mts} +2 -2
  134. package/dist/{types-D_SsCur9.d.ts → types-DcaBYgVI.d.ts} +2 -2
  135. package/dist/{url-context-BjAsQoVl.d.mts → url-context-Ck2LK18V.d.mts} +4 -2
  136. package/dist/{url-context-BjAsQoVl.d.ts → url-context-Ck2LK18V.d.ts} +4 -2
  137. package/dist/v2/global.global.js +1 -1
  138. package/dist/v2/global.global.js.map +1 -1
  139. package/dist/v2/index.cjs.js +1 -1
  140. package/dist/v2/index.cjs.js.map +1 -1
  141. package/dist/v2/index.d.mts +26 -8
  142. package/dist/v2/index.d.ts +26 -8
  143. package/dist/v2/index.esm.js +1 -1
  144. package/dist/v2/index.esm.js.map +1 -1
  145. package/docs/public/README.md +20 -15
  146. package/docs/public/api/exports.md +12 -8
  147. package/docs/public/api/pixel.md +28 -7
  148. package/docs/public/configuration/commerce.md +3 -3
  149. package/docs/public/configuration/modules.md +11 -14
  150. package/docs/public/configuration/overview.md +41 -25
  151. package/docs/public/configuration/transport.md +127 -0
  152. package/docs/public/events/catalog.md +3 -1
  153. package/docs/public/getting-started/installation.md +20 -15
  154. package/docs/public/getting-started/quick-start.md +95 -30
  155. package/docs/public/getting-started/react-nextjs.md +57 -34
  156. package/docs/public/getting-started/script-tag.md +55 -32
  157. package/docs/public/guides/funnel-checkout.md +2 -2
  158. package/docs/public/guides/funnel-full.md +3 -3
  159. package/docs/public/guides/funnel-landing.md +10 -8
  160. package/docs/public/limitations.md +6 -5
  161. package/docs/public/privacy/limitations.md +6 -6
  162. package/docs/public/release-candidate/validation.md +24 -19
  163. package/docs/public/troubleshooting.md +7 -6
  164. package/package.json +15 -14
  165. package/dist/pixel-default-config-CJl-eypl.d.mts +0 -5
  166. package/dist/pixel-default-config-aAOujzwp.d.ts +0 -5
@@ -0,0 +1,590 @@
1
+ <!doctype html>
2
+ <html lang="pt-BR">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>Pixel v2 — ADD_TO_CART source link</title>
7
+ <style>
8
+ :root {
9
+ --bg: #f8fafc; --card: #fff; --border: #e2e8f0; --text: #0f172a;
10
+ --muted: #64748b; --accent: #0f766e; --accent-soft: #ccfbf1;
11
+ --warn: #9a3412; --warn-soft: #ffedd5;
12
+ }
13
+ * { box-sizing: border-box; }
14
+ body {
15
+ margin: 0;
16
+ font-family: "Segoe UI", system-ui, sans-serif;
17
+ background:
18
+ radial-gradient(circle at top left, #ecfeff 0%, transparent 40%),
19
+ linear-gradient(180deg, #f8fafc 0%, #eef2ff 100%);
20
+ color: var(--text); line-height: 1.45;
21
+ }
22
+ .wrap { max-width: 980px; margin: 0 auto; padding: 1.5rem; }
23
+ h1 { font-size: 1.5rem; margin: 0 0 0.35rem; letter-spacing: -0.02em; }
24
+ h2 { font-size: 1.05rem; margin: 0 0 0.75rem; }
25
+ .sub { color: var(--muted); margin: 0 0 1rem; font-size: 0.92rem; }
26
+ .nav { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-bottom: 1rem; }
27
+ .nav a {
28
+ text-decoration: none; border: 1px solid var(--border); background: #fff;
29
+ color: var(--text); border-radius: 999px; padding: 0.3rem 0.7rem; font-size: 0.78rem;
30
+ }
31
+ .nav a.active { background: var(--accent); border-color: var(--accent); color: #fff; }
32
+ .grid { display: grid; grid-template-columns: 1.15fr 0.85fr; gap: 1rem; }
33
+ @media (max-width: 860px) { .grid { grid-template-columns: 1fr; } }
34
+ .card {
35
+ background: var(--card); border: 1px solid var(--border); border-radius: 12px;
36
+ padding: 1rem; margin-bottom: 1rem; box-shadow: 0 1px 0 rgba(15,23,42,.03);
37
+ }
38
+ .hint {
39
+ background: var(--accent-soft); border: 1px solid #99f6e4; border-radius: 10px;
40
+ padding: 0.85rem 1rem; font-size: 0.9rem; margin-bottom: 1rem;
41
+ }
42
+ .hint.warn { background: var(--warn-soft); border-color: #fdba74; color: var(--warn); }
43
+ .actions { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 0.75rem; }
44
+ button {
45
+ appearance: none; border: 1px solid var(--border); background: #fff; color: var(--text);
46
+ border-radius: 8px; padding: 0.5rem 0.85rem; cursor: pointer; font: inherit;
47
+ }
48
+ button.primary { background: var(--accent); border-color: var(--accent); color: #fff; }
49
+ button.danger { background: #7f1d1d; border-color: #7f1d1d; color: #fff; }
50
+ button:disabled { opacity: 0.55; cursor: not-allowed; }
51
+ label { display: block; font-size: 0.8rem; color: var(--muted); margin-bottom: 0.25rem; }
52
+ input {
53
+ width: 100%; border: 1px solid var(--border); border-radius: 8px;
54
+ padding: 0.55rem 0.7rem; font: inherit; background: #fff;
55
+ }
56
+ .row { display: grid; grid-template-columns: 1fr 1fr; gap: 0.75rem; }
57
+ @media (max-width: 560px) { .row { grid-template-columns: 1fr; } }
58
+ .status, pre {
59
+ background: #0f172a; color: #e2e8f0; border-radius: 8px; padding: 0.75rem;
60
+ font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
61
+ font-size: 0.78rem; white-space: pre-wrap; word-break: break-word;
62
+ max-height: 260px; overflow: auto;
63
+ }
64
+ .pill {
65
+ display: inline-block; border-radius: 999px; padding: 0.15rem 0.55rem;
66
+ font-size: 0.72rem; background: #e2e8f0; color: #334155; margin-left: 0.35rem;
67
+ }
68
+ .pill.ok { background: #bbf7d0; color: #166534; }
69
+ .checklist { margin: 0; padding-left: 1.1rem; font-size: 0.88rem; color: var(--muted); }
70
+ .checklist li { margin: 0.35rem 0; }
71
+ .ctx {
72
+ border-left: 3px solid var(--accent); padding-left: 0.75rem; margin-bottom: 0.85rem;
73
+ color: var(--muted); font-size: 0.88rem;
74
+ }
75
+ .product {
76
+ border: 1px dashed var(--border); border-radius: 10px; padding: 0.75rem; margin: 0.5rem 0;
77
+ }
78
+ .product strong { display: block; margin-bottom: 0.2rem; }
79
+ code { font-size: 0.85em; }
80
+ </style>
81
+ </head>
82
+ <body>
83
+ <div class="wrap">
84
+ <h1>ADD_TO_CART — source <code>link</code></h1>
85
+ <p class="sub">
86
+ Destino do &lt;a href&gt; (não a URL da página). Match + bindings + catálogo.
87
+ <span class="pill" id="init-pill">offline</span>
88
+ </p>
89
+ <div class="nav"><a href="example-add-to-cart-attribute.html" class="">1. Atributo</a>
90
+ <a href="example-add-to-cart-click.html" class="">2. Click+Form</a>
91
+ <a href="example-add-to-cart-auto.html" class="">3. Auto+Form</a>
92
+ <a href="example-add-to-cart-text.html" class="">4. Text</a>
93
+ <a href="example-add-to-cart-manual.html" class="">5. Manual API</a>
94
+ <a href="example-add-to-cart-dedupe.html" class="">6. Dedupe</a>
95
+ <a href="example-add-to-cart-order-bump.html" class="">7. Order bump</a>
96
+ <a href="example-add-to-cart-link.html" class="active">8. Link</a></div>
97
+ <div class="hint"><strong>Contexto:</strong> CTA que aponta para checkout externo.
98
+ Source <code>type: 'link'</code> casa origin/path/query, resolve
99
+ <code>productId</code> (dataset → query → pathParam) e dispara
100
+ <code>ADD_TO_CART</code> via <code>ConfiguredLinkDetector</code>.
101
+ Enrich pelo catálogo. Navegação real não é bloqueada pelo Pixel
102
+ (este playground só impede o leave da página para demo).</div>
103
+
104
+ <div class="card">
105
+ <h2>Lifecycle</h2>
106
+ <div class="actions">
107
+ <button id="btn-reinit" class="primary" type="button">Reinitialize</button>
108
+ <button id="btn-destroy" class="danger" type="button">Destroy</button>
109
+ <button id="btn-clear" type="button">Clear logs</button>
110
+ </div>
111
+ <div class="status" id="runtime-status">Aguardando init...</div>
112
+ </div>
113
+
114
+ <div class="grid">
115
+ <div>
116
+ <div class="card">
117
+ <h2>Links de checkout <span class="pill">ConfiguredLink</span></h2>
118
+ <div class="ctx">
119
+ Match: <code>https://checkout.example.com/pay/:offerId?product=…</code>
120
+ </div>
121
+ <div class="product">
122
+ <strong>Oferta Principal — query product</strong>
123
+ <span class="sub" style="margin:0">productId via query → enrich catalog</span>
124
+ <div class="actions">
125
+ <a
126
+ class="primary"
127
+ data-demo-stay
128
+ href="https://checkout.example.com/pay/offer_1?product=main_offer"
129
+ style="display:inline-block;text-decoration:none;border-radius:8px;padding:0.5rem 0.85rem;background:#0f766e;color:#fff;border:1px solid #0f766e;"
130
+ >
131
+ Comprar (query)
132
+ </a>
133
+ </div>
134
+ </div>
135
+ <div class="product">
136
+ <strong>Oferta Principal — dataset</strong>
137
+ <span class="sub" style="margin:0">data-product-id tem precedência sobre query</span>
138
+ <div class="actions">
139
+ <a
140
+ class="primary"
141
+ data-demo-stay
142
+ data-product-id="main_offer"
143
+ href="https://checkout.example.com/pay/offer_1?product=ignored_query"
144
+ style="display:inline-block;text-decoration:none;border-radius:8px;padding:0.5rem 0.85rem;background:#0f766e;color:#fff;border:1px solid #0f766e;"
145
+ >
146
+ Comprar (dataset)
147
+ </a>
148
+ </div>
149
+ </div>
150
+ <div class="product">
151
+ <strong>Negativos</strong>
152
+ <div class="actions">
153
+ <a
154
+ data-demo-stay
155
+ href="https://other.example.com/pay/offer_1?product=main_offer"
156
+ style="display:inline-block;text-decoration:none;border-radius:8px;padding:0.5rem 0.85rem;background:#fff;color:#0f172a;border:1px solid #e2e8f0;"
157
+ >
158
+ Origin diferente
159
+ </a>
160
+ <a
161
+ data-demo-stay
162
+ href="https://checkout.example.com/pay/offer_1"
163
+ style="display:inline-block;text-decoration:none;border-radius:8px;padding:0.5rem 0.85rem;background:#fff;color:#0f172a;border:1px solid #e2e8f0;"
164
+ >
165
+ Sem query product
166
+ </a>
167
+ <a
168
+ data-demo-stay
169
+ href="mailto:demo@example.com"
170
+ style="display:inline-block;text-decoration:none;border-radius:8px;padding:0.5rem 0.85rem;background:#fff;color:#0f172a;border:1px solid #e2e8f0;"
171
+ >
172
+ mailto (ignorado)
173
+ </a>
174
+ </div>
175
+ </div>
176
+ <p class="sub">
177
+ Clique em filho (&lt;span&gt;) dentro do link também dispara.
178
+ Ctrl/meta-click também rastreia (nova aba).
179
+ </p>
180
+ </div>
181
+ <div class="card">
182
+ <h2>Checklist</h2>
183
+ <ul class="checklist">
184
+ <li>[ ] Link com match → <code>ADD_TO_CART</code> + enrich catalog</li>
185
+ <li>[ ] Dataset vence query no fallback de bindings</li>
186
+ <li>[ ] Origin / mailto / sem query product → não dispara</li>
187
+ <li>[ ] Cart mirror atualiza</li>
188
+ <li>[ ] Detector: <code>ConfiguredLink(ADD_TO_CART:checkout-product-link)</code></li>
189
+ </ul>
190
+ </div>
191
+ </div>
192
+ <div>
193
+ <div class="card">
194
+ <h2>Event counts</h2>
195
+ <div class="status" id="event-counts">Nenhum evento ainda</div>
196
+ </div>
197
+ <div class="card">
198
+ <h2>Cart mirror (via eventos)</h2>
199
+ <div class="status" id="cart-mirror">{}</div>
200
+ </div>
201
+ <div class="card">
202
+ <h2>Active detectors</h2>
203
+ <div class="status" id="detectors">—</div>
204
+ </div>
205
+
206
+ <div class="card">
207
+ <h2>Last event JSON</h2>
208
+ <pre id="last-event">null</pre>
209
+ </div>
210
+ <div class="card">
211
+ <h2>Event log</h2>
212
+ <pre id="logs">Aguardando eventos...</pre>
213
+ </div>
214
+ </div>
215
+ </div>
216
+ </div>
217
+
218
+ <script src="../../../v2/global.global.js"></script>
219
+ <script>
220
+ const { Pixel, DEFAULT_PIXEL_CONFIG } = window.PixelV2;
221
+ const API_ENDPOINT =
222
+ 'https://micro-service-pixel-production-4826.up.railway.app';
223
+ const PIXEL_ID = 'pix_7315610';
224
+
225
+ const els = {
226
+ logs: document.getElementById('logs'),
227
+ last: document.getElementById('last-event'),
228
+ counts: document.getElementById('event-counts'),
229
+ cart: document.getElementById('cart-mirror'),
230
+ detectors: document.getElementById('detectors'),
231
+ dedupe: document.getElementById('dedupe-keys'),
232
+ runtime: document.getElementById('runtime-status'),
233
+ pill: document.getElementById('init-pill'),
234
+ };
235
+
236
+ let pixel = null;
237
+ let unsubscribe = null;
238
+ let initCount = 0;
239
+ let destroyCount = 0;
240
+ const counts = {};
241
+ const cartMirror = {};
242
+
243
+ function addToCartDetectorConfig() {
244
+ return {
245
+ enabled: true,
246
+ sources: [
247
+ {
248
+ name: 'checkout-product-link',
249
+ type: 'link',
250
+ enabled: true,
251
+ fireOnce: false,
252
+ match: {
253
+ protocols: ['https:'],
254
+ origins: ['https://checkout.example.com'],
255
+ path: { template: '/pay/:offerId' },
256
+ query: {
257
+ mode: 'all',
258
+ conditions: [{ key: 'product', operator: 'exists' }],
259
+ },
260
+ },
261
+ bindings: {
262
+ productId: {
263
+ from: [
264
+ { source: 'dataset', key: 'productId' },
265
+ { source: 'query', key: 'product' },
266
+ { source: 'pathParam', key: 'productId' },
267
+ ],
268
+ required: true,
269
+ },
270
+ offerId: {
271
+ from: { source: 'pathParam', key: 'offerId' },
272
+ },
273
+ destinationUrl: {
274
+ from: { source: 'href' },
275
+ },
276
+ },
277
+ },
278
+ ],
279
+ };
280
+ }
281
+
282
+ function buildConfig() {
283
+ const base = DEFAULT_PIXEL_CONFIG;
284
+ return {
285
+ ...base,
286
+ app: {
287
+ ...base.app,
288
+ source: 'custom',
289
+ environment: 'development',
290
+ debug: true,
291
+ },
292
+ transport: {
293
+ ...base.transport,
294
+ enabled: true,
295
+ sender: { mode: 'internal', baseUrl: API_ENDPOINT },
296
+ persistence: { enabled: true },
297
+ replay: { enabled: true },
298
+ ordering: { enabled: true },
299
+ coordination: { enabled: true },
300
+ circuitBreaker: {
301
+ enabled: true,
302
+ failureThreshold: 5,
303
+ resetTimeoutMs: 30000,
304
+ halfOpenMaxAttempts: 2,
305
+ },
306
+ backpressure: {
307
+ enabled: true,
308
+ maxQueueSize: 500,
309
+ policy: 'drop_oldest',
310
+ sampleRate: 0.5,
311
+ },
312
+ deadLetter: { enabled: true, maxEntries: 200 },
313
+ compression: { enabled: true, strategy: 'identity' },
314
+ retry: {
315
+ enabled: true,
316
+ maxAttempts: 4,
317
+ baseDelayMs: 500,
318
+ maxDelayMs: 4000,
319
+ multiplier: 2,
320
+ },
321
+ batch: {
322
+ enabled: true,
323
+ batchSize: 10,
324
+ maxWaitMs: 5000,
325
+ },
326
+ timeout: { enabled: true, timeoutMs: 10000 },
327
+ offline: { enabled: true },
328
+ flush: {
329
+ enabled: true,
330
+ flushOnDestroy: true,
331
+ prepareUnloadHooks: true,
332
+ },
333
+ },
334
+ identity: { ...base.identity, pixelId: PIXEL_ID },
335
+ commerce: {
336
+ enabled: true,
337
+ currency: 'BRL',
338
+ catalog: { products: [
339
+ {
340
+ id: 'main_offer',
341
+ name: 'Oferta Principal',
342
+ type: 'main',
343
+ price: 197,
344
+ currency: 'BRL',
345
+ quantity: 1,
346
+ },
347
+ {
348
+ id: 'order_bump_01',
349
+ name: 'Order Bump Especial',
350
+ type: 'order_bump',
351
+ price: 47,
352
+ currency: 'BRL',
353
+ quantity: 1,
354
+ },
355
+ {
356
+ id: 'upsell_01',
357
+ name: 'Upsell 01',
358
+ type: 'upsell',
359
+ price: 97,
360
+ currency: 'BRL',
361
+ quantity: 1,
362
+ },
363
+ ] },
364
+ cart: {
365
+ mode: 'single_product',
366
+ initialItems: [{ productId: "main_offer", quantity: 1 }],
367
+ calculateValueFrom: 'cart',
368
+ allowDynamicItems: true,
369
+ },
370
+ mappings: {
371
+ attributes: {
372
+ productId: ['data-product-id', 'data-sku', 'data-offer-id'],
373
+ productName: ['data-product-name', 'data-name'],
374
+ price: ['data-product-price', 'data-price'],
375
+ quantity: ['data-quantity', 'data-qty'],
376
+ currency: ['data-currency'],
377
+ },
378
+ fields: {
379
+ productId: ['productId', 'product_id', 'offerId', 'sku'],
380
+ productName: ['productName', 'product_name'],
381
+ price: ['price', 'amount'],
382
+ quantity: ['quantity', 'qty'],
383
+ currency: ['currency'],
384
+ email: ['email', 'customerEmail'],
385
+ phone: ['phone', 'telefone', 'customerPhone'],
386
+ },
387
+ },
388
+ enrichment: {
389
+ pageView: { enabled: false, source: 'cart' },
390
+ viewContent: { enabled: true, source: 'event_or_cart' },
391
+ lead: { enabled: false, source: 'event_or_cart' },
392
+ addToCart: { enabled: true, source: 'event_or_cart' },
393
+ removeFromCart: { enabled: true, source: 'event_or_cart' },
394
+ initiateCheckout: { enabled: true, source: 'cart' },
395
+ addPaymentInfo: { enabled: true, source: 'cart' },
396
+ purchase: { enabled: true, source: 'cart' },
397
+ }
398
+ },
399
+ modules: {
400
+ ...base.modules,
401
+ core: {
402
+ ...base.modules.core,
403
+ enabled: false,
404
+ pageView: {
405
+ ...base.modules.core.pageView,
406
+ enabled: false,
407
+ trackInitialPageView: false,
408
+ spa: false,
409
+ },
410
+ },
411
+ behavior: { ...base.modules.behavior, enabled: false },
412
+ privacy: { ...base.modules.privacy, enabled: false },
413
+ integrations: { ...base.modules.integrations, enabled: false },
414
+ conversion: {
415
+ enabled: true,
416
+ manual: {
417
+ pageView: { enabled: false },
418
+ purchase: { enabled: false, sources: [] },
419
+ lead: { enabled: false, sources: [] },
420
+ addToCart: { enabled: true },
421
+ removeFromCart: { enabled: true },
422
+ initiateCheckout: { enabled: false, sources: [] },
423
+ addPaymentInfo: { enabled: false, sources: [] },
424
+ search: { enabled: false, sources: [] },
425
+ viewContent: { enabled: false, sources: [] },
426
+ },
427
+ auto: {
428
+ enabled: true,
429
+ detectors: {
430
+ lead: { enabled: false, sources: [] },
431
+ purchase: { enabled: false, sources: [] },
432
+ addToCart: addToCartDetectorConfig(),
433
+ removeFromCart: { enabled: false, sources: [] },
434
+ initiateCheckout: { enabled: false, sources: [] },
435
+ addPaymentInfo: { enabled: false, sources: [] },
436
+ search: { enabled: false, sources: [] },
437
+ viewContent: { enabled: false, sources: [] },
438
+ },
439
+ },
440
+ rules: {
441
+ enabled: false,
442
+ selectors: [],
443
+ texts: [],
444
+ urlPatterns: [],
445
+ checkout: { enabled: false },
446
+ card: { enabled: false },
447
+ },
448
+ },
449
+ },
450
+ };
451
+ }
452
+
453
+ function appendLog(message) {
454
+ const line = '[' + new Date().toISOString() + '] ' + message;
455
+ const prev = els.logs.textContent;
456
+ els.logs.textContent =
457
+ prev === 'Aguardando eventos...' ? line : line + '\n' + prev;
458
+ }
459
+
460
+ function renderCounts() {
461
+ const lines = Object.keys(counts)
462
+ .sort()
463
+ .map(function (type) { return type + ': ' + counts[type]; });
464
+ els.counts.textContent =
465
+ lines.length > 0 ? lines.join('\n') : 'Nenhum evento ainda';
466
+ }
467
+
468
+ function renderCart() {
469
+ if (!els.cart) return;
470
+ els.cart.textContent = JSON.stringify(cartMirror, null, 2);
471
+ }
472
+
473
+ function renderDebug() {
474
+ const detectors =
475
+ pixel && pixel.getDebugActiveDetectors
476
+ ? pixel.getDebugActiveDetectors()
477
+ : [];
478
+ els.detectors.textContent =
479
+ detectors.length > 0 ? detectors.join('\n') : 'Nenhum detector ativo';
480
+ if (els.dedupe) {
481
+ const keys =
482
+ pixel && pixel.getDebugDedupeKeys ? pixel.getDebugDedupeKeys() : [];
483
+ els.dedupe.textContent =
484
+ keys.length > 0 ? keys.join('\n') : 'Nenhuma chave';
485
+ }
486
+ els.runtime.textContent =
487
+ 'initialized: ' +
488
+ (pixel ? pixel.isInitialized() : false) +
489
+ '\ninit count: ' +
490
+ initCount +
491
+ '\ndestroy count: ' +
492
+ destroyCount +
493
+ '\npixelId: ' +
494
+ PIXEL_ID +
495
+ '\nscenario: source link · checkout href';
496
+ els.pill.textContent =
497
+ pixel && pixel.isInitialized() ? 'ready' : 'offline';
498
+ els.pill.className =
499
+ 'pill' + (pixel && pixel.isInitialized() ? ' ok' : '');
500
+ }
501
+
502
+ function updateCartFromEvent(event) {
503
+ if (
504
+ event.type === 'ADD_TO_CART' &&
505
+ event.data &&
506
+ event.data.productId
507
+ ) {
508
+ cartMirror[event.data.productId] = {
509
+ productId: event.data.productId,
510
+ productName: event.data.productName,
511
+ price: event.data.price,
512
+ currency: event.data.currency,
513
+ quantity: event.data.quantity != null ? event.data.quantity : 1,
514
+ };
515
+ }
516
+ if (
517
+ event.type === 'REMOVE_FROM_CART' &&
518
+ event.data &&
519
+ event.data.productId
520
+ ) {
521
+ delete cartMirror[event.data.productId];
522
+ }
523
+ renderCart();
524
+ }
525
+
526
+ function onEvent(event) {
527
+ counts[event.type] = (counts[event.type] || 0) + 1;
528
+ renderCounts();
529
+ updateCartFromEvent(event);
530
+ els.last.textContent = JSON.stringify(event, null, 2);
531
+ appendLog(event.type + ' ' + JSON.stringify(event.data || {}));
532
+ renderDebug();
533
+ }
534
+
535
+ async function boot() {
536
+ if (unsubscribe) { unsubscribe(); unsubscribe = null; }
537
+ if (pixel) {
538
+ await pixel.destroy();
539
+ destroyCount += 1;
540
+ pixel = null;
541
+ }
542
+ Object.keys(cartMirror).forEach(function (k) { delete cartMirror[k]; });
543
+ renderCart();
544
+ pixel = new Pixel(buildConfig());
545
+ await pixel.init();
546
+ initCount += 1;
547
+ const services = pixel.getDebugServices();
548
+ if (services && services.dispatcher) {
549
+ unsubscribe = services.dispatcher.subscribe(onEvent);
550
+ }
551
+ appendLog('Pixel initialized — source link · checkout href');
552
+ renderDebug();
553
+ }
554
+
555
+ async function destroyPixel() {
556
+ if (unsubscribe) { unsubscribe(); unsubscribe = null; }
557
+ if (pixel) {
558
+ await pixel.destroy();
559
+ destroyCount += 1;
560
+ pixel = null;
561
+ }
562
+ appendLog('Pixel destroyed');
563
+ renderDebug();
564
+ }
565
+
566
+ document.getElementById('btn-reinit').onclick = function () { boot(); };
567
+ document.getElementById('btn-destroy').onclick = function () { destroyPixel(); };
568
+ document.getElementById('btn-clear').onclick = function () {
569
+ els.logs.textContent = 'Aguardando eventos...';
570
+ els.last.textContent = 'null';
571
+ Object.keys(counts).forEach(function (k) { delete counts[k]; });
572
+ Object.keys(cartMirror).forEach(function (k) { delete cartMirror[k]; });
573
+ renderCounts();
574
+ renderCart();
575
+ };
576
+
577
+ document.querySelectorAll('[data-demo-stay]').forEach(function (el) {
578
+ el.addEventListener('click', function (event) {
579
+ // Pixel escuta em capture e já trackeou; aqui só evitamos sair da página.
580
+ event.preventDefault();
581
+ appendLog(
582
+ '(playground) navegação bloqueada para demo — Pixel não chama preventDefault'
583
+ );
584
+ });
585
+ });
586
+
587
+ boot();
588
+ </script>
589
+ </body>
590
+ </html>