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

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 (156) hide show
  1. package/CHANGELOG.md +260 -4
  2. package/README.md +65 -118
  3. package/RELEASE_CANDIDATE.md +181 -36
  4. package/dist/{StorageFactory-BhpbB6Jj.d.mts → StorageFactory-CPghDPBj.d.mts} +2 -2
  5. package/dist/{StorageFactory-CAkJJqVD.d.ts → StorageFactory-tjfzk57c.d.ts} +2 -2
  6. package/dist/config/index.cjs.js +1 -1
  7. package/dist/config/index.cjs.js.map +1 -1
  8. package/dist/config/index.d.mts +4 -3
  9. package/dist/config/index.d.ts +4 -3
  10. package/dist/config/index.esm.js +1 -1
  11. package/dist/config/index.esm.js.map +1 -1
  12. package/dist/events/index.cjs.js +1 -1
  13. package/dist/events/index.cjs.js.map +1 -1
  14. package/dist/events/index.d.mts +2 -1
  15. package/dist/events/index.d.ts +2 -1
  16. package/dist/events/index.esm.js +1 -1
  17. package/dist/events/index.esm.js.map +1 -1
  18. package/dist/examples/html-script/README.md +24 -2
  19. package/dist/examples/html-script/RELEASE_CANDIDATE.md +20 -6
  20. package/dist/examples/html-script/add-payment-info/README.md +3 -3
  21. package/dist/examples/html-script/add-payment-info/example-add-payment-info-card-autocomplete.html +66 -48
  22. package/dist/examples/html-script/add-payment-info/example-add-payment-info-card-disabled.html +66 -48
  23. package/dist/examples/html-script/add-payment-info/example-add-payment-info-card-fields.html +65 -47
  24. package/dist/examples/html-script/add-payment-info/example-add-payment-info-data-track.html +73 -47
  25. package/dist/examples/html-script/add-payment-info/example-add-payment-info-dedupe.html +65 -47
  26. package/dist/examples/html-script/add-payment-info/example-add-payment-info-manual.html +56 -47
  27. package/dist/examples/html-script/add-payment-info/example-add-payment-info-rules-card.html +65 -47
  28. package/dist/examples/html-script/add-payment-info/example-add-payment-info-security.html +65 -47
  29. package/dist/examples/html-script/add-to-cart/README.md +3 -3
  30. package/dist/examples/html-script/add-to-cart/example-add-to-cart-attribute.html +90 -70
  31. package/dist/examples/html-script/add-to-cart/example-add-to-cart-auto.html +103 -81
  32. package/dist/examples/html-script/add-to-cart/example-add-to-cart-click.html +101 -78
  33. package/dist/examples/html-script/add-to-cart/example-add-to-cart-dedupe.html +90 -70
  34. package/dist/examples/html-script/add-to-cart/example-add-to-cart-manual.html +81 -67
  35. package/dist/examples/html-script/add-to-cart/example-add-to-cart-order-bump.html +90 -70
  36. package/dist/examples/html-script/add-to-cart/example-add-to-cart-text.html +104 -81
  37. package/dist/examples/html-script/behavior/example-behavior-engagement.html +489 -0
  38. package/dist/examples/html-script/behavior/example-behavior-heartbeat.html +350 -0
  39. package/dist/examples/html-script/behavior/example-behavior-runtime-intelligence.html +433 -0
  40. package/dist/examples/html-script/behavior/example-behavior-viewport.html +397 -0
  41. package/dist/examples/html-script/{example-behavior.html → behavior/example-behavior.html} +23 -17
  42. package/dist/examples/html-script/example-checkout-commerce.html +825 -0
  43. package/dist/examples/html-script/example-integration.html +5 -5
  44. package/dist/examples/html-script/example-landing-commerce.html +380 -0
  45. package/dist/examples/html-script/example-runtime-diagnostics.html +108 -0
  46. package/dist/examples/html-script/example-transport.html +5 -5
  47. package/dist/examples/html-script/full-funnel/README.md +64 -0
  48. package/dist/examples/html-script/full-funnel/checkout.html +116 -0
  49. package/dist/examples/html-script/full-funnel/downsell.html +58 -0
  50. package/dist/examples/html-script/full-funnel/landing.html +99 -0
  51. package/dist/examples/html-script/full-funnel/thank-you.html +85 -0
  52. package/dist/examples/html-script/full-funnel/upsell.html +64 -0
  53. package/dist/examples/html-script/initiate-checkout/README.md +6 -6
  54. package/dist/examples/html-script/initiate-checkout/example-initiate-checkout-attribute.html +94 -74
  55. package/dist/examples/html-script/initiate-checkout/example-initiate-checkout-auto.html +102 -80
  56. package/dist/examples/html-script/initiate-checkout/example-initiate-checkout-click.html +103 -80
  57. package/dist/examples/html-script/initiate-checkout/example-initiate-checkout-manual.html +86 -72
  58. package/dist/examples/html-script/initiate-checkout/example-initiate-checkout-snapshot.html +95 -75
  59. package/dist/examples/html-script/initiate-checkout/example-initiate-checkout-submit.html +103 -83
  60. package/dist/examples/html-script/initiate-checkout/example-initiate-checkout-text.html +105 -82
  61. package/dist/examples/html-script/lead/README.md +9 -7
  62. package/dist/examples/html-script/lead/example-lead-trigger-attribute.html +67 -47
  63. package/dist/examples/html-script/lead/example-lead-trigger-auto.html +78 -56
  64. package/dist/examples/html-script/lead/example-lead-trigger-click.html +78 -55
  65. package/dist/examples/html-script/release-candidate.html +187 -76
  66. package/dist/examples/html-script/remove-from-cart/README.md +1 -1
  67. package/dist/examples/html-script/remove-from-cart/example-remove-from-cart-attribute.html +93 -73
  68. package/dist/examples/html-script/remove-from-cart/example-remove-from-cart-css.html +93 -73
  69. package/dist/examples/html-script/remove-from-cart/example-remove-from-cart-dedupe.html +93 -73
  70. package/dist/examples/html-script/remove-from-cart/example-remove-from-cart-manual.html +84 -70
  71. package/dist/examples/html-script/remove-from-cart/example-remove-from-cart-multi.html +94 -74
  72. package/dist/examples/html-script/remove-from-cart/example-remove-from-cart-state.html +95 -75
  73. package/dist/examples/html-script/remove-from-cart/example-remove-from-cart-text.html +98 -76
  74. package/dist/examples/html-script/search/README.md +1 -1
  75. package/dist/examples/html-script/search/example-search-attribute.html +66 -51
  76. package/dist/examples/html-script/search/example-search-button-sync.html +66 -51
  77. package/dist/examples/html-script/search/example-search-dedupe.html +66 -51
  78. package/dist/examples/html-script/search/example-search-input.html +67 -51
  79. package/dist/examples/html-script/search/example-search-manual.html +57 -48
  80. package/dist/examples/html-script/search/example-search-submit.html +66 -51
  81. package/dist/examples/html-script/search/example-search-text.html +71 -51
  82. package/dist/examples/html-script/url-context/example-url-context-allowed-domains.html +63 -0
  83. package/dist/examples/html-script/url-context/example-url-context-landing.html +70 -0
  84. package/dist/examples/html-script/url-context/example-url-context-upsell.html +67 -0
  85. package/dist/examples/html-script/url-context/example-url-context.html +171 -0
  86. package/dist/examples/html-script/view-content/README.md +1 -1
  87. package/dist/examples/html-script/view-content/example-view-content-attribute.html +85 -70
  88. package/dist/examples/html-script/view-content/example-view-content-css.html +85 -70
  89. package/dist/examples/html-script/view-content/example-view-content-dedupe.html +85 -70
  90. package/dist/examples/html-script/view-content/example-view-content-empty.html +85 -70
  91. package/dist/examples/html-script/view-content/example-view-content-manual.html +76 -67
  92. package/dist/examples/html-script/view-content/example-view-content-product-card.html +85 -70
  93. package/dist/examples/html-script/view-content/example-view-content-text.html +90 -73
  94. package/dist/examples/v2/README.md +4 -1
  95. package/dist/{index-DUfFzniE.d.ts → index-CQAyT5Od.d.ts} +170 -3
  96. package/dist/{index-DUfFzniE.d.mts → index-JlKPz4pp.d.mts} +170 -3
  97. package/dist/index.cjs.js +1 -1
  98. package/dist/index.cjs.js.map +1 -1
  99. package/dist/index.d.mts +435 -12
  100. package/dist/index.d.ts +435 -12
  101. package/dist/index.esm.js +1 -1
  102. package/dist/index.esm.js.map +1 -1
  103. package/dist/{pixel-CbeF25mD.d.mts → pixel-BxZZx8l5.d.ts} +248 -72
  104. package/dist/{pixel-CbeF25mD.d.ts → pixel-CKc4OQUx.d.mts} +248 -72
  105. package/dist/{pixel-default-config-1VgLFOiL.d.mts → pixel-default-config-CJl-eypl.d.mts} +1 -1
  106. package/dist/{pixel-default-config-Bxb-Vdd8.d.ts → pixel-default-config-aAOujzwp.d.ts} +1 -1
  107. package/dist/runtime/index.cjs.js +1 -1
  108. package/dist/runtime/index.cjs.js.map +1 -1
  109. package/dist/runtime/index.d.mts +19 -26
  110. package/dist/runtime/index.d.ts +19 -26
  111. package/dist/runtime/index.esm.js +1 -1
  112. package/dist/runtime/index.esm.js.map +1 -1
  113. package/dist/services/index.cjs.js +1 -1
  114. package/dist/services/index.cjs.js.map +1 -1
  115. package/dist/services/index.d.mts +14 -6
  116. package/dist/services/index.d.ts +14 -6
  117. package/dist/services/index.esm.js +1 -1
  118. package/dist/services/index.esm.js.map +1 -1
  119. package/dist/types-BP8dz1gP.d.mts +19 -0
  120. package/dist/types-C75pQP31.d.ts +19 -0
  121. package/dist/types-DMhzHSVC.d.mts +293 -0
  122. package/dist/types-D_SsCur9.d.ts +293 -0
  123. package/dist/url-context-BjAsQoVl.d.mts +85 -0
  124. package/dist/url-context-BjAsQoVl.d.ts +85 -0
  125. package/dist/v2/global.global.js +1 -1
  126. package/dist/v2/global.global.js.map +1 -1
  127. package/dist/v2/index.cjs.js +1 -1
  128. package/dist/v2/index.cjs.js.map +1 -1
  129. package/dist/v2/index.d.mts +8 -6
  130. package/dist/v2/index.d.ts +8 -6
  131. package/dist/v2/index.esm.js +1 -1
  132. package/dist/v2/index.esm.js.map +1 -1
  133. package/docs/public/README.md +75 -0
  134. package/docs/public/api/exports.md +47 -0
  135. package/docs/public/api/pixel.md +65 -0
  136. package/docs/public/configuration/commerce.md +44 -0
  137. package/docs/public/configuration/modules.md +66 -0
  138. package/docs/public/configuration/overview.md +66 -0
  139. package/docs/public/events/catalog.md +65 -0
  140. package/docs/public/getting-started/installation.md +75 -0
  141. package/docs/public/getting-started/quick-start.md +77 -0
  142. package/docs/public/getting-started/react-nextjs.md +55 -0
  143. package/docs/public/getting-started/script-tag.md +57 -0
  144. package/docs/public/guides/funnel-checkout.md +52 -0
  145. package/docs/public/guides/funnel-downsell.md +53 -0
  146. package/docs/public/guides/funnel-full.md +64 -0
  147. package/docs/public/guides/funnel-landing.md +68 -0
  148. package/docs/public/guides/funnel-thank-you.md +48 -0
  149. package/docs/public/guides/funnel-upsell.md +72 -0
  150. package/docs/public/limitations.md +32 -0
  151. package/docs/public/privacy/limitations.md +33 -0
  152. package/docs/public/release-candidate/validation.md +37 -0
  153. package/docs/public/troubleshooting.md +55 -0
  154. package/package.json +13 -1
  155. package/dist/types-CTpRvFKZ.d.ts +0 -71
  156. package/dist/types-DGlBdsAy.d.mts +0 -71
@@ -0,0 +1,489 @@
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 — Behavior Engagement (Etapa 19)</title>
7
+ <style>
8
+ body {
9
+ font-family: system-ui, sans-serif;
10
+ margin: 0;
11
+ padding: 2rem;
12
+ max-width: 1000px;
13
+ }
14
+ .hint {
15
+ background: #eef2ff;
16
+ border: 1px solid #c7d2fe;
17
+ border-radius: 8px;
18
+ padding: 1rem;
19
+ margin-bottom: 1rem;
20
+ font-size: 14px;
21
+ }
22
+ .actions {
23
+ display: flex;
24
+ flex-wrap: wrap;
25
+ gap: 0.5rem;
26
+ margin: 1rem 0;
27
+ }
28
+ button {
29
+ padding: 0.5rem 1rem;
30
+ cursor: pointer;
31
+ }
32
+ .score-card {
33
+ display: flex;
34
+ align-items: center;
35
+ gap: 1.5rem;
36
+ padding: 1.25rem;
37
+ border-radius: 12px;
38
+ background: #f4f4f5;
39
+ border: 1px solid #e4e4e7;
40
+ margin-bottom: 1rem;
41
+ }
42
+ #score {
43
+ font-size: 3rem;
44
+ font-weight: 700;
45
+ font-variant-numeric: tabular-nums;
46
+ }
47
+ #level {
48
+ font-size: 1.25rem;
49
+ font-weight: 600;
50
+ padding: 0.25rem 0.75rem;
51
+ border-radius: 999px;
52
+ text-transform: uppercase;
53
+ letter-spacing: 0.05em;
54
+ }
55
+ .level-low {
56
+ background: #fee2e2;
57
+ color: #991b1b;
58
+ }
59
+ .level-medium {
60
+ background: #fef3c7;
61
+ color: #92400e;
62
+ }
63
+ .level-high {
64
+ background: #dcfce7;
65
+ color: #166534;
66
+ }
67
+ .panels {
68
+ display: grid;
69
+ grid-template-columns: 1fr 1fr;
70
+ gap: 1rem;
71
+ }
72
+ @media (max-width: 760px) {
73
+ .panels {
74
+ grid-template-columns: 1fr;
75
+ }
76
+ }
77
+ .panel {
78
+ font-family: ui-monospace, monospace;
79
+ font-size: 12px;
80
+ border-radius: 8px;
81
+ padding: 1rem;
82
+ background: #f4f4f5;
83
+ border: 1px solid #e4e4e7;
84
+ }
85
+ .panel h3 {
86
+ margin: 0 0 0.75rem;
87
+ font-size: 13px;
88
+ font-family: system-ui, sans-serif;
89
+ }
90
+ .panel pre {
91
+ margin: 0;
92
+ white-space: pre-wrap;
93
+ word-break: break-word;
94
+ }
95
+ #logs {
96
+ background: #18181b;
97
+ color: #fafafa;
98
+ min-height: 200px;
99
+ max-height: 340px;
100
+ overflow: auto;
101
+ margin-top: 1rem;
102
+ border-radius: 8px;
103
+ padding: 1rem;
104
+ font-family: ui-monospace, monospace;
105
+ font-size: 12px;
106
+ }
107
+ .zone {
108
+ min-height: 80vh;
109
+ margin: 1rem 0;
110
+ padding: 2rem;
111
+ border-radius: 12px;
112
+ background: #ecfeff;
113
+ }
114
+ </style>
115
+ </head>
116
+ <body>
117
+ <h1>Behavior Engagement Runtime</h1>
118
+ <p class="hint">
119
+ Etapa 19 — score determinístico 0..100 a partir dos sinais internos do
120
+ <code>BehaviorSignalBus</code>. Emite <code>ENGAGEMENT_UPDATE</code> e
121
+ <code>ENGAGEMENT_SUMMARY</code> via Dispatcher. Dados fictícios.
122
+ <br /><br />
123
+ <strong>Roteiro de validação manual (Hardening 19.1):</strong>
124
+ 1. Init &rarr; 2. Simulate activity &rarr; 3. Evaluate &rarr; 4. Destroy
125
+ &rarr; 5. Confirmar <code>ENGAGEMENT_SUMMARY</code> no log e no contador
126
+ &rarr; 6. Reinit &rarr; 7. Repetir. O summary da geração anterior deve
127
+ aparecer e o novo listener não deve duplicar.
128
+ </p>
129
+
130
+ <div class="actions">
131
+ <button type="button" id="btn-init">Init</button>
132
+ <button type="button" id="btn-destroy">Destroy</button>
133
+ <button type="button" id="btn-reinit">Reinit</button>
134
+ <button type="button" id="btn-snapshot">Snapshot</button>
135
+ <button type="button" id="btn-activity">Simulate activity</button>
136
+ <button type="button" id="btn-idle">Simulate idle</button>
137
+ <button type="button" id="btn-scroll">Scroll</button>
138
+ <button type="button" id="btn-viewport">Add viewport target</button>
139
+ <button type="button" id="btn-evaluate">Evaluate now</button>
140
+ <button type="button" id="btn-clear">Clear</button>
141
+ </div>
142
+
143
+ <div class="score-card">
144
+ <div id="score">0</div>
145
+ <div id="level" class="level-low">low</div>
146
+ <div>
147
+ <div>peak: <span id="peak">0</span></div>
148
+ <div>avg: <span id="avg">0</span></div>
149
+ <div>updates: <span id="updates">0</span></div>
150
+ </div>
151
+ </div>
152
+
153
+ <div class="panels">
154
+ <div class="panel">
155
+ <h3>Components / Signal counts</h3>
156
+ <pre id="counters">—</pre>
157
+ </div>
158
+ <div class="panel">
159
+ <h3>behavior.engagement (diagnostics)</h3>
160
+ <pre id="diag">—</pre>
161
+ </div>
162
+ </div>
163
+
164
+ <div id="logs"></div>
165
+
166
+ <section id="hero" class="zone" data-vp="hero">
167
+ <h2>Hero</h2>
168
+ <p>Role a página para acionar scroll / viewport.</p>
169
+ </section>
170
+ <section id="cta" class="zone" style="background: #fef9c3" data-vp="cta">
171
+ <h2>CTA</h2>
172
+ <button type="button">Clique fictício</button>
173
+ </section>
174
+ <div id="dynamic-zone"></div>
175
+
176
+ <script src="../../../dist/v2/global.global.js"></script>
177
+ <script>
178
+ (function () {
179
+ const { Pixel, DEFAULT_PIXEL_CONFIG } = window.PixelV2;
180
+ const logsEl = document.getElementById('logs');
181
+ const countersEl = document.getElementById('counters');
182
+ const diagEl = document.getElementById('diag');
183
+ const scoreEl = document.getElementById('score');
184
+ const levelEl = document.getElementById('level');
185
+ const peakEl = document.getElementById('peak');
186
+ const avgEl = document.getElementById('avg');
187
+ const updatesEl = document.getElementById('updates');
188
+
189
+ let pixel = null;
190
+ let unsubscribe = null;
191
+ let dynCounter = 0;
192
+ let lastEngagementSnapshot = null;
193
+ let lastSummary = null;
194
+ const counts = { ENGAGEMENT_UPDATE: 0, ENGAGEMENT_SUMMARY: 0 };
195
+
196
+ function log(msg, data) {
197
+ const line = document.createElement('div');
198
+ line.textContent =
199
+ '[' +
200
+ new Date().toISOString().slice(11, 23) +
201
+ '] ' +
202
+ msg +
203
+ (data !== undefined ? ' ' + JSON.stringify(data) : '');
204
+ logsEl.prepend(line);
205
+ }
206
+
207
+ function captureSnapshot() {
208
+ if (!pixel || !pixel.isInitialized || !pixel.isInitialized()) return null;
209
+ try {
210
+ const snap = pixel.getDebugSnapshot();
211
+ const e = snap && snap.behavior && snap.behavior.engagement;
212
+ if (!e) return null;
213
+ lastEngagementSnapshot = {
214
+ engagement: e,
215
+ health: snap.health ? snap.health.status : 'unknown',
216
+ };
217
+ } catch (err) {
218
+ // runtime pode estar indisponível após destroy — guard silencioso.
219
+ }
220
+ return lastEngagementSnapshot;
221
+ }
222
+
223
+ function renderFrom(state, destroyed) {
224
+ if (!state) {
225
+ diagEl.textContent = destroyed
226
+ ? 'runtime destroyed — sem snapshot anterior'
227
+ : 'null';
228
+ return;
229
+ }
230
+ const e = state.engagement;
231
+ scoreEl.textContent = String(e.score);
232
+ levelEl.textContent = e.level;
233
+ levelEl.className = 'level-' + e.level;
234
+ peakEl.textContent = String(e.peakScore);
235
+ avgEl.textContent = String(e.averageScore);
236
+ updatesEl.textContent = String(e.emittedUpdateCount);
237
+ countersEl.textContent = JSON.stringify(
238
+ {
239
+ eventCounts: counts,
240
+ signalCounts: e.signalCounts,
241
+ lastSummary: lastSummary,
242
+ },
243
+ null,
244
+ 2
245
+ );
246
+ diagEl.textContent = JSON.stringify(
247
+ {
248
+ runtime: destroyed ? 'destroyed' : 'active',
249
+ enabled: e.enabled,
250
+ running: e.running,
251
+ evaluationIntervalMs: e.evaluationIntervalMs,
252
+ evaluationCount: e.evaluationCount,
253
+ emittedUpdateCount: e.emittedUpdateCount,
254
+ emittedSummaryCount: e.emittedSummaryCount,
255
+ lastDriftMs: e.lastDriftMs,
256
+ hasError: e.hasError,
257
+ health: state.health,
258
+ },
259
+ null,
260
+ 2
261
+ );
262
+ }
263
+
264
+ function refresh() {
265
+ const live = captureSnapshot();
266
+ if (live) {
267
+ renderFrom(live, false);
268
+ } else {
269
+ // Sem runtime ativo: preserva o último estado conhecido.
270
+ renderFrom(lastEngagementSnapshot, true);
271
+ }
272
+ }
273
+
274
+ function buildConfig() {
275
+ return {
276
+ ...DEFAULT_PIXEL_CONFIG,
277
+ identity: {
278
+ ...DEFAULT_PIXEL_CONFIG.identity,
279
+ pixelId: 'engagement-demo',
280
+ },
281
+ modules: {
282
+ ...DEFAULT_PIXEL_CONFIG.modules,
283
+ core: {
284
+ ...DEFAULT_PIXEL_CONFIG.modules.core,
285
+ enabled: true,
286
+ pageView: {
287
+ ...DEFAULT_PIXEL_CONFIG.modules.core.pageView,
288
+ enabled: false,
289
+ trackInitialPageView: false,
290
+ spa: false,
291
+ },
292
+ session: {
293
+ ...DEFAULT_PIXEL_CONFIG.modules.core.session,
294
+ enabled: false,
295
+ },
296
+ },
297
+ privacy: {
298
+ ...DEFAULT_PIXEL_CONFIG.modules.privacy,
299
+ enabled: false,
300
+ },
301
+ conversion: {
302
+ ...DEFAULT_PIXEL_CONFIG.modules.conversion,
303
+ enabled: false,
304
+ },
305
+ integrations: {
306
+ ...DEFAULT_PIXEL_CONFIG.modules.integrations,
307
+ enabled: false,
308
+ },
309
+ transport: {
310
+ ...DEFAULT_PIXEL_CONFIG.modules.transport,
311
+ enabled: false,
312
+ },
313
+ behavior: {
314
+ ...DEFAULT_PIXEL_CONFIG.modules.behavior,
315
+ enabled: true,
316
+ heartbeat: {
317
+ ...DEFAULT_PIXEL_CONFIG.modules.behavior.heartbeat,
318
+ enabled: true,
319
+ intervalMs: 2000,
320
+ },
321
+ engagement: {
322
+ ...DEFAULT_PIXEL_CONFIG.modules.behavior.engagement,
323
+ enabled: true,
324
+ evaluationIntervalMs: 2000,
325
+ emitOnChange: true,
326
+ minScoreDelta: 3,
327
+ emitSummaryOnDestroy: true,
328
+ },
329
+ trackers: {
330
+ ...DEFAULT_PIXEL_CONFIG.modules.behavior.trackers,
331
+ scroll: {
332
+ ...DEFAULT_PIXEL_CONFIG.modules.behavior.trackers.scroll,
333
+ enabled: true,
334
+ },
335
+ click: {
336
+ ...DEFAULT_PIXEL_CONFIG.modules.behavior.trackers.click,
337
+ enabled: true,
338
+ },
339
+ visibility: { enabled: true },
340
+ idle: {
341
+ ...DEFAULT_PIXEL_CONFIG.modules.behavior.trackers.idle,
342
+ enabled: true,
343
+ thresholdMs: 3000,
344
+ },
345
+ exitIntent: { enabled: false },
346
+ viewport: {
347
+ enabled: true,
348
+ rootMargin: '0px',
349
+ observeMutations: true,
350
+ mutationDebounceMs: 100,
351
+ maxObservedElements: 500,
352
+ targets: [
353
+ { key: 'hero', selector: '#hero', enterThreshold: 0.4 },
354
+ { key: 'cta', selector: '#cta', enterThreshold: 0.4 },
355
+ {
356
+ key: 'dynamic',
357
+ selector: '[data-vp-dynamic]',
358
+ enterThreshold: 0.3,
359
+ },
360
+ ],
361
+ },
362
+ },
363
+ },
364
+ },
365
+ };
366
+ }
367
+
368
+ function wire() {
369
+ if (!pixel || unsubscribe) return;
370
+ const services = pixel.getDebugServices && pixel.getDebugServices();
371
+ if (!services || !services.dispatcher) return;
372
+ unsubscribe = services.dispatcher.subscribe(function (event) {
373
+ if (event.type === 'ENGAGEMENT_UPDATE') {
374
+ counts.ENGAGEMENT_UPDATE += 1;
375
+ log('ENGAGEMENT_UPDATE', {
376
+ score: event.score,
377
+ delta: event.delta,
378
+ level: event.level,
379
+ reason: event.reason,
380
+ });
381
+ refresh();
382
+ } else if (event.type === 'ENGAGEMENT_SUMMARY') {
383
+ counts.ENGAGEMENT_SUMMARY += 1;
384
+ lastSummary = {
385
+ score: event.score,
386
+ peakScore: event.peakScore,
387
+ averageScore: event.averageScore,
388
+ level: event.level,
389
+ };
390
+ // Summary chega durante destroy(): captura o snapshot ainda vivo
391
+ // antes de o runtime ser finalizado, para preservar o painel.
392
+ captureSnapshot();
393
+ log('ENGAGEMENT_SUMMARY', lastSummary);
394
+ }
395
+ });
396
+ }
397
+
398
+ async function doInit() {
399
+ if (pixel && pixel.isInitialized()) {
400
+ log('already initialized');
401
+ return;
402
+ }
403
+ pixel = new Pixel(buildConfig());
404
+ await pixel.init();
405
+ wire();
406
+ log('init ok');
407
+ refresh();
408
+ }
409
+
410
+ async function doDestroy() {
411
+ if (!pixel) return;
412
+
413
+ // Preserva o estado antes do destroy (o summary é emitido durante ele).
414
+ captureSnapshot();
415
+
416
+ // ORDEM CRÍTICA: destroy() emite ENGAGEMENT_SUMMARY. O listener precisa
417
+ // continuar ativo durante o destroy; só removemos depois.
418
+ await pixel.destroy();
419
+
420
+ if (unsubscribe) {
421
+ unsubscribe();
422
+ unsubscribe = null;
423
+ }
424
+
425
+ pixel = null;
426
+ log('destroy ok');
427
+ refresh();
428
+ }
429
+
430
+ document.getElementById('btn-init').onclick = doInit;
431
+ document.getElementById('btn-destroy').onclick = doDestroy;
432
+ document.getElementById('btn-reinit').onclick = async function () {
433
+ await doDestroy();
434
+ await doInit();
435
+ };
436
+ document.getElementById('btn-snapshot').onclick = function () {
437
+ refresh();
438
+ log('snapshot refreshed');
439
+ };
440
+ document.getElementById('btn-activity').onclick = function () {
441
+ if (!pixel) return;
442
+ pixel.debugPublishBehaviorSignal('ACTIVITY', { at: Date.now() });
443
+ for (let i = 0; i < 3; i += 1) {
444
+ pixel.debugPublishBehaviorSignal('CLICK', {});
445
+ }
446
+ pixel.debugPublishBehaviorSignal('SCROLL', { maxScrollPercent: 100 });
447
+ pixel.evaluateEngagement();
448
+ log('simulated activity');
449
+ refresh();
450
+ };
451
+ document.getElementById('btn-idle').onclick = function () {
452
+ if (!pixel) return;
453
+ pixel.debugPublishBehaviorSignal('IDLE', { idleSince: Date.now() });
454
+ pixel.evaluateEngagement();
455
+ log('simulated idle');
456
+ refresh();
457
+ };
458
+ document.getElementById('btn-scroll').onclick = function () {
459
+ document.getElementById('cta').scrollIntoView({ behavior: 'smooth' });
460
+ };
461
+ document.getElementById('btn-viewport').onclick = function () {
462
+ dynCounter += 1;
463
+ const el = document.createElement('div');
464
+ el.className = 'zone';
465
+ el.style.background = '#fce7f3';
466
+ el.setAttribute('data-vp-dynamic', '1');
467
+ el.textContent = 'Dynamic viewport target #' + dynCounter;
468
+ document.getElementById('dynamic-zone').appendChild(el);
469
+ log('added viewport target', { n: dynCounter });
470
+ };
471
+ document.getElementById('btn-evaluate').onclick = function () {
472
+ if (!pixel) return;
473
+ pixel.evaluateEngagement();
474
+ log('manual evaluation');
475
+ refresh();
476
+ };
477
+ document.getElementById('btn-clear').onclick = function () {
478
+ logsEl.textContent = '';
479
+ counts.ENGAGEMENT_UPDATE = 0;
480
+ counts.ENGAGEMENT_SUMMARY = 0;
481
+ refresh();
482
+ };
483
+
484
+ refresh();
485
+ log('ready — clique Init (requer dist/v2/global.global.js)');
486
+ })();
487
+ </script>
488
+ </body>
489
+ </html>