@beworke/pixel 0.1.0-rc.1

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 (123) hide show
  1. package/CHANGELOG.md +194 -0
  2. package/README.md +163 -0
  3. package/RELEASE_CANDIDATE.md +256 -0
  4. package/dist/PixelLogger-B21lEjep.d.mts +8 -0
  5. package/dist/PixelLogger-B21lEjep.d.ts +8 -0
  6. package/dist/StorageFactory-BhpbB6Jj.d.mts +8 -0
  7. package/dist/StorageFactory-CAkJJqVD.d.ts +8 -0
  8. package/dist/config/index.cjs.js +3 -0
  9. package/dist/config/index.cjs.js.map +1 -0
  10. package/dist/config/index.d.mts +19 -0
  11. package/dist/config/index.d.ts +19 -0
  12. package/dist/config/index.esm.js +3 -0
  13. package/dist/config/index.esm.js.map +1 -0
  14. package/dist/events/index.cjs.js +3 -0
  15. package/dist/events/index.cjs.js.map +1 -0
  16. package/dist/events/index.d.mts +1 -0
  17. package/dist/events/index.d.ts +1 -0
  18. package/dist/events/index.esm.js +3 -0
  19. package/dist/events/index.esm.js.map +1 -0
  20. package/dist/examples/html-script/README.md +71 -0
  21. package/dist/examples/html-script/RELEASE_CANDIDATE.md +121 -0
  22. package/dist/examples/html-script/add-payment-info/README.md +46 -0
  23. package/dist/examples/html-script/add-payment-info/example-add-payment-info-card-autocomplete.html +494 -0
  24. package/dist/examples/html-script/add-payment-info/example-add-payment-info-card-disabled.html +478 -0
  25. package/dist/examples/html-script/add-payment-info/example-add-payment-info-card-fields.html +486 -0
  26. package/dist/examples/html-script/add-payment-info/example-add-payment-info-data-track.html +479 -0
  27. package/dist/examples/html-script/add-payment-info/example-add-payment-info-dedupe.html +492 -0
  28. package/dist/examples/html-script/add-payment-info/example-add-payment-info-manual.html +495 -0
  29. package/dist/examples/html-script/add-payment-info/example-add-payment-info-rules-card.html +469 -0
  30. package/dist/examples/html-script/add-payment-info/example-add-payment-info-security.html +489 -0
  31. package/dist/examples/html-script/add-to-cart/README.md +36 -0
  32. package/dist/examples/html-script/add-to-cart/example-add-to-cart-attribute.html +517 -0
  33. package/dist/examples/html-script/add-to-cart/example-add-to-cart-auto.html +512 -0
  34. package/dist/examples/html-script/add-to-cart/example-add-to-cart-click.html +519 -0
  35. package/dist/examples/html-script/add-to-cart/example-add-to-cart-dedupe.html +514 -0
  36. package/dist/examples/html-script/add-to-cart/example-add-to-cart-manual.html +517 -0
  37. package/dist/examples/html-script/add-to-cart/example-add-to-cart-order-bump.html +527 -0
  38. package/dist/examples/html-script/add-to-cart/example-add-to-cart-text.html +524 -0
  39. package/dist/examples/html-script/example-basic.html +350 -0
  40. package/dist/examples/html-script/example-behavior.html +435 -0
  41. package/dist/examples/html-script/example-conversion.html +479 -0
  42. package/dist/examples/html-script/example-integration.html +709 -0
  43. package/dist/examples/html-script/example-transport.html +748 -0
  44. package/dist/examples/html-script/initiate-checkout/README.md +38 -0
  45. package/dist/examples/html-script/initiate-checkout/example-initiate-checkout-attribute.html +485 -0
  46. package/dist/examples/html-script/initiate-checkout/example-initiate-checkout-auto.html +491 -0
  47. package/dist/examples/html-script/initiate-checkout/example-initiate-checkout-click.html +493 -0
  48. package/dist/examples/html-script/initiate-checkout/example-initiate-checkout-manual.html +494 -0
  49. package/dist/examples/html-script/initiate-checkout/example-initiate-checkout-snapshot.html +497 -0
  50. package/dist/examples/html-script/initiate-checkout/example-initiate-checkout-submit.html +502 -0
  51. package/dist/examples/html-script/initiate-checkout/example-initiate-checkout-text.html +496 -0
  52. package/dist/examples/html-script/lead/README.md +25 -0
  53. package/dist/examples/html-script/lead/example-lead-trigger-attribute.html +594 -0
  54. package/dist/examples/html-script/lead/example-lead-trigger-auto.html +431 -0
  55. package/dist/examples/html-script/lead/example-lead-trigger-click.html +587 -0
  56. package/dist/examples/html-script/release-candidate.html +726 -0
  57. package/dist/examples/html-script/remove-from-cart/README.md +36 -0
  58. package/dist/examples/html-script/remove-from-cart/example-remove-from-cart-attribute.html +532 -0
  59. package/dist/examples/html-script/remove-from-cart/example-remove-from-cart-css.html +524 -0
  60. package/dist/examples/html-script/remove-from-cart/example-remove-from-cart-dedupe.html +540 -0
  61. package/dist/examples/html-script/remove-from-cart/example-remove-from-cart-manual.html +533 -0
  62. package/dist/examples/html-script/remove-from-cart/example-remove-from-cart-multi.html +557 -0
  63. package/dist/examples/html-script/remove-from-cart/example-remove-from-cart-state.html +539 -0
  64. package/dist/examples/html-script/remove-from-cart/example-remove-from-cart-text.html +524 -0
  65. package/dist/examples/html-script/search/README.md +41 -0
  66. package/dist/examples/html-script/search/example-search-attribute.html +454 -0
  67. package/dist/examples/html-script/search/example-search-button-sync.html +455 -0
  68. package/dist/examples/html-script/search/example-search-dedupe.html +466 -0
  69. package/dist/examples/html-script/search/example-search-input.html +456 -0
  70. package/dist/examples/html-script/search/example-search-manual.html +473 -0
  71. package/dist/examples/html-script/search/example-search-submit.html +450 -0
  72. package/dist/examples/html-script/search/example-search-text.html +441 -0
  73. package/dist/examples/html-script/view-content/README.md +48 -0
  74. package/dist/examples/html-script/view-content/example-view-content-attribute.html +488 -0
  75. package/dist/examples/html-script/view-content/example-view-content-css.html +467 -0
  76. package/dist/examples/html-script/view-content/example-view-content-dedupe.html +485 -0
  77. package/dist/examples/html-script/view-content/example-view-content-empty.html +469 -0
  78. package/dist/examples/html-script/view-content/example-view-content-manual.html +496 -0
  79. package/dist/examples/html-script/view-content/example-view-content-product-card.html +478 -0
  80. package/dist/examples/html-script/view-content/example-view-content-text.html +473 -0
  81. package/dist/examples/release-candidate/README.md +14 -0
  82. package/dist/examples/v2/README.md +33 -0
  83. package/dist/index-DUfFzniE.d.mts +274 -0
  84. package/dist/index-DUfFzniE.d.ts +274 -0
  85. package/dist/index.cjs.js +3 -0
  86. package/dist/index.cjs.js.map +1 -0
  87. package/dist/index.d.mts +364 -0
  88. package/dist/index.d.ts +364 -0
  89. package/dist/index.esm.js +3 -0
  90. package/dist/index.esm.js.map +1 -0
  91. package/dist/logger/index.cjs.js +3 -0
  92. package/dist/logger/index.cjs.js.map +1 -0
  93. package/dist/logger/index.d.mts +12 -0
  94. package/dist/logger/index.d.ts +12 -0
  95. package/dist/logger/index.esm.js +3 -0
  96. package/dist/logger/index.esm.js.map +1 -0
  97. package/dist/pixel-CbeF25mD.d.mts +555 -0
  98. package/dist/pixel-CbeF25mD.d.ts +555 -0
  99. package/dist/pixel-default-config-1VgLFOiL.d.mts +5 -0
  100. package/dist/pixel-default-config-Bxb-Vdd8.d.ts +5 -0
  101. package/dist/runtime/index.cjs.js +3 -0
  102. package/dist/runtime/index.cjs.js.map +1 -0
  103. package/dist/runtime/index.d.mts +48 -0
  104. package/dist/runtime/index.d.ts +48 -0
  105. package/dist/runtime/index.esm.js +3 -0
  106. package/dist/runtime/index.esm.js.map +1 -0
  107. package/dist/services/index.cjs.js +3 -0
  108. package/dist/services/index.cjs.js.map +1 -0
  109. package/dist/services/index.d.mts +169 -0
  110. package/dist/services/index.d.ts +169 -0
  111. package/dist/services/index.esm.js +3 -0
  112. package/dist/services/index.esm.js.map +1 -0
  113. package/dist/types-CTpRvFKZ.d.ts +71 -0
  114. package/dist/types-DGlBdsAy.d.mts +71 -0
  115. package/dist/v2/global.global.js +3 -0
  116. package/dist/v2/global.global.js.map +1 -0
  117. package/dist/v2/index.cjs.js +3 -0
  118. package/dist/v2/index.cjs.js.map +1 -0
  119. package/dist/v2/index.d.mts +7 -0
  120. package/dist/v2/index.d.ts +7 -0
  121. package/dist/v2/index.esm.js +3 -0
  122. package/dist/v2/index.esm.js.map +1 -0
  123. package/package.json +101 -0
@@ -0,0 +1,709 @@
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 — Integration + Attribution (Etapa 10C)</title>
7
+ <style>
8
+ body {
9
+ font-family: system-ui, sans-serif;
10
+ margin: 0;
11
+ padding: 2rem;
12
+ max-width: 1200px;
13
+ }
14
+
15
+ .hint {
16
+ background: #eff6ff;
17
+ border: 1px solid #bfdbfe;
18
+ border-radius: 8px;
19
+ padding: 1rem;
20
+ margin-bottom: 1rem;
21
+ font-size: 14px;
22
+ }
23
+
24
+ .hint.warn {
25
+ background: #fffbeb;
26
+ border-color: #fde68a;
27
+ }
28
+
29
+ .actions {
30
+ display: flex;
31
+ flex-wrap: wrap;
32
+ gap: 0.5rem;
33
+ margin: 1rem 0;
34
+ align-items: center;
35
+ }
36
+
37
+ button,
38
+ select {
39
+ padding: 0.5rem 1rem;
40
+ cursor: pointer;
41
+ }
42
+
43
+ input[type='text'],
44
+ input[type='number'] {
45
+ padding: 0.35rem 0.5rem;
46
+ min-width: 180px;
47
+ }
48
+
49
+ label {
50
+ font-size: 13px;
51
+ display: inline-flex;
52
+ align-items: center;
53
+ gap: 0.35rem;
54
+ }
55
+
56
+ .field {
57
+ display: flex;
58
+ flex-direction: column;
59
+ gap: 0.2rem;
60
+ font-size: 12px;
61
+ }
62
+
63
+ .panels {
64
+ display: grid;
65
+ grid-template-columns: repeat(3, 1fr);
66
+ gap: 1rem;
67
+ margin: 1rem 0;
68
+ }
69
+
70
+ @media (max-width: 900px) {
71
+ .panels {
72
+ grid-template-columns: 1fr 1fr;
73
+ }
74
+ }
75
+
76
+ @media (max-width: 600px) {
77
+ .panels {
78
+ grid-template-columns: 1fr;
79
+ }
80
+ }
81
+
82
+ .panel {
83
+ font-family: ui-monospace, monospace;
84
+ font-size: 11px;
85
+ border-radius: 8px;
86
+ padding: 0.75rem;
87
+ background: #f4f4f5;
88
+ border: 1px solid #e4e4e7;
89
+ }
90
+
91
+ .panel.wide {
92
+ grid-column: 1 / -1;
93
+ }
94
+
95
+ .panel h3 {
96
+ margin: 0 0 0.5rem;
97
+ font-size: 12px;
98
+ font-family: system-ui, sans-serif;
99
+ }
100
+
101
+ .panel pre {
102
+ margin: 0;
103
+ white-space: pre-wrap;
104
+ word-break: break-word;
105
+ }
106
+
107
+ #logs {
108
+ background: #18181b;
109
+ color: #fafafa;
110
+ min-height: 180px;
111
+ overflow: auto;
112
+ margin-top: 1rem;
113
+ border-radius: 8px;
114
+ padding: 1rem;
115
+ font-family: ui-monospace, monospace;
116
+ font-size: 12px;
117
+ }
118
+
119
+ .flow {
120
+ font-family: ui-monospace, monospace;
121
+ font-size: 11px;
122
+ background: #fafafa;
123
+ border: 1px solid #e4e4e7;
124
+ border-radius: 8px;
125
+ padding: 1rem;
126
+ margin: 1rem 0;
127
+ line-height: 1.6;
128
+ }
129
+
130
+ .section-title {
131
+ margin-top: 1.5rem;
132
+ margin-bottom: 0.25rem;
133
+ }
134
+
135
+ .ids-grid {
136
+ display: grid;
137
+ grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
138
+ gap: 0.5rem;
139
+ margin: 0.5rem 0 1rem;
140
+ font-family: ui-monospace, monospace;
141
+ font-size: 12px;
142
+ }
143
+
144
+ .ids-grid .id-item {
145
+ background: #f4f4f5;
146
+ border: 1px solid #e4e4e7;
147
+ border-radius: 6px;
148
+ padding: 0.5rem;
149
+ }
150
+
151
+ .ids-grid .id-key {
152
+ color: #71717a;
153
+ font-size: 10px;
154
+ text-transform: uppercase;
155
+ }
156
+
157
+ .ids-grid .id-val {
158
+ word-break: break-all;
159
+ margin-top: 0.15rem;
160
+ }
161
+
162
+ .ids-grid .id-val.empty {
163
+ color: #a1a1aa;
164
+ }
165
+ </style>
166
+ </head>
167
+ <body>
168
+ <h1>Pixel v2 — Integration + Attribution (Etapa 10C)</h1>
169
+
170
+ <div class="hint">
171
+ Attribution é um <strong>service independente</strong> (não faz parte do
172
+ Integration Engine). Browser destinations (Meta / Google / TikTok) recebem
173
+ apenas <code>PAGE_VIEW</code>. Conversões (PURCHASE, LEAD, …) vão ao
174
+ Transport / API — CAPI e server-side ficam no backend.
175
+ <br />
176
+ Pixel ID: <code>pix_8580907</code> · Endpoint:
177
+ <code>https://micro-service-pixel-production-4826.up.railway.app</code>
178
+ </div>
179
+
180
+ <div class="flow">
181
+ Dispatcher<br />
182
+ ├── TransportModule (PURCHASE / conversões → API / backend CAPI)<br />
183
+ ├── IntegrationsModule → IntegrationEngine → browser PAGE_VIEW only<br />
184
+ │&nbsp;&nbsp;&nbsp;&nbsp;├── MetaBrowserDestination (fbq)<br />
185
+ │&nbsp;&nbsp;&nbsp;&nbsp;├── GoogleBrowserDestination (gtag)<br />
186
+ │&nbsp;&nbsp;&nbsp;&nbsp;├── TikTokBrowserDestination (ttq)<br />
187
+ │&nbsp;&nbsp;&nbsp;&nbsp;└── Console / Memory / Mock (debug)<br />
188
+ └── AttributionService (URL + cookies → snapshot; independente)
189
+ </div>
190
+
191
+ <h2 class="section-title">Módulos</h2>
192
+ <div class="actions">
193
+ <label
194
+ ><input id="cfg-core" type="checkbox" checked /> Core (PAGE_VIEW)</label
195
+ >
196
+ <label
197
+ ><input id="cfg-conversion" type="checkbox" checked /> Conversion</label
198
+ >
199
+ <label><input id="cfg-transport" type="checkbox" /> Transport</label>
200
+ <label
201
+ ><input id="cfg-integrations" type="checkbox" checked />
202
+ Integrations</label
203
+ >
204
+ <label
205
+ ><input id="cfg-memory" type="checkbox" checked /> Memory
206
+ destination</label
207
+ >
208
+ <label
209
+ ><input id="cfg-console" type="checkbox" /> Console destination</label
210
+ >
211
+ <label><input id="cfg-mock" type="checkbox" /> Mock destination</label>
212
+ </div>
213
+
214
+ <h2 class="section-title">Browser Destinations</h2>
215
+ <div class="actions">
216
+ <label><input id="cfg-meta" type="checkbox" /> Meta</label>
217
+ <div class="field">
218
+ Meta pixelIds (CSV)
219
+ <input id="cfg-meta-ids" type="text" value="877074838786597" placeholder="1234567890" />
220
+ </div>
221
+ <label><input id="cfg-google" type="checkbox" /> Google</label>
222
+ <div class="field">
223
+ Google tagIds (CSV)
224
+ <input id="cfg-google-ids" type="text" placeholder="G-XXXXXXXX" />
225
+ </div>
226
+ <label><input id="cfg-tiktok" type="checkbox" /> TikTok</label>
227
+ <div class="field">
228
+ TikTok pixelIds (CSV)
229
+ <input id="cfg-tiktok-ids" type="text" placeholder="CXXXXXXXX" />
230
+ </div>
231
+ </div>
232
+ <div class="actions">
233
+ <button id="apply-config" type="button">Aplicar + reinit</button>
234
+ <button id="reinit" type="button">Reinitialize</button>
235
+ <button id="destroy" type="button">Destroy</button>
236
+ </div>
237
+
238
+ <h2 class="section-title">Attribution</h2>
239
+ <div class="hint warn">
240
+ Para simular click IDs, adicione parâmetros na URL (ex.:
241
+ <code>?fbclid=TEST_FB&amp;gclid=TEST_G&amp;ttclid=TEST_TT</code>) e clique
242
+ em <strong>Aplicar + reinit</strong> ou
243
+ <strong>Collect attribution</strong>. Cookies como <code>_fbp</code> /
244
+ <code>_ga</code> só aparecem se existirem no domínio atual.
245
+ </div>
246
+ <div class="actions">
247
+ <button id="btn-collect-attr" type="button">Collect attribution</button>
248
+ <button id="btn-clear-attr" type="button">Clear attribution</button>
249
+ <button id="btn-url-hint" type="button">Mostrar URL de teste</button>
250
+ </div>
251
+ <div class="ids-grid" id="identifiers-grid"></div>
252
+
253
+ <h2 class="section-title">Eventos</h2>
254
+ <div class="actions">
255
+ <button id="btn-purchase" type="button">purchase() → Transport</button>
256
+ <button id="btn-lead" type="button">lead()</button>
257
+ <button id="btn-search" type="button">search()</button>
258
+ <button id="btn-burst" type="button">Burst purchase (5)</button>
259
+ </div>
260
+ <div class="hint">
261
+ <code>PAGE_VIEW</code> é emitido pelo Core no init (quando Core está
262
+ ligado) e dispara os browser destinations. <code>purchase()</code> NÃO vai
263
+ para Meta/Google/TikTok no SDK — apenas Dispatcher → Transport.
264
+ </div>
265
+
266
+ <div class="panels">
267
+ <div class="panel">
268
+ <h3>Attribution Snapshot</h3>
269
+ <pre id="attribution-state">—</pre>
270
+ </div>
271
+ <div class="panel">
272
+ <h3>Destinations</h3>
273
+ <pre id="destinations-state">—</pre>
274
+ </div>
275
+ <div class="panel">
276
+ <h3>Metrics</h3>
277
+ <pre id="metrics-state">—</pre>
278
+ </div>
279
+ <div class="panel wide">
280
+ <h3>Last Results</h3>
281
+ <pre id="results-state">[]</pre>
282
+ </div>
283
+ <div class="panel">
284
+ <h3>Memory Records</h3>
285
+ <pre id="memory-state">[]</pre>
286
+ </div>
287
+ <div class="panel">
288
+ <h3>Runtime</h3>
289
+ <pre id="runtime-state">—</pre>
290
+ </div>
291
+ <div class="panel">
292
+ <h3>Transport</h3>
293
+ <pre id="transport-state">—</pre>
294
+ </div>
295
+ </div>
296
+
297
+ <h2>Dispatcher Logs</h2>
298
+ <pre id="logs"></pre>
299
+
300
+ <script src="../../dist/v2/global.global.js"></script>
301
+ <script>
302
+ const { Pixel, DEFAULT_PIXEL_CONFIG } = window.PixelV2;
303
+
304
+ const API_ENDPOINT =
305
+ 'https://micro-service-pixel-production-4826.up.railway.app';
306
+ const PIXEL_ID = 'pix_7315610';
307
+
308
+ const IDENTIFIER_KEYS = [
309
+ 'fbclid',
310
+ 'fbp',
311
+ 'fbc',
312
+ 'gclid',
313
+ 'gbraid',
314
+ 'wbraid',
315
+ 'ga',
316
+ 'gid',
317
+ 'gclAu',
318
+ 'ttclid',
319
+ 'ttp',
320
+ 'msclkid',
321
+ 'liFatId',
322
+ 'epik',
323
+ ];
324
+
325
+ let pixel = null;
326
+ let unsubscribe = null;
327
+ let initCount = 0;
328
+ let destroyCount = 0;
329
+ let refreshTimer = null;
330
+
331
+ const logsEl = document.getElementById('logs');
332
+
333
+ function appendLog(message) {
334
+ logsEl.textContent =
335
+ '[' +
336
+ new Date().toISOString() +
337
+ '] ' +
338
+ message +
339
+ '\n' +
340
+ logsEl.textContent;
341
+ }
342
+
343
+ function formatJson(value) {
344
+ return JSON.stringify(value, null, 2);
345
+ }
346
+
347
+ function parseCsv(raw) {
348
+ return String(raw || '')
349
+ .split(',')
350
+ .map(function (s) {
351
+ return s.trim();
352
+ })
353
+ .filter(Boolean);
354
+ }
355
+
356
+ function readFlags() {
357
+ return {
358
+ core: document.getElementById('cfg-core').checked,
359
+ conversion: document.getElementById('cfg-conversion').checked,
360
+ transport: document.getElementById('cfg-transport').checked,
361
+ integrations: document.getElementById('cfg-integrations').checked,
362
+ console: document.getElementById('cfg-console').checked,
363
+ memory: document.getElementById('cfg-memory').checked,
364
+ mock: document.getElementById('cfg-mock').checked,
365
+ meta: document.getElementById('cfg-meta').checked,
366
+ metaIds: parseCsv(document.getElementById('cfg-meta-ids').value),
367
+ google: document.getElementById('cfg-google').checked,
368
+ googleIds: parseCsv(document.getElementById('cfg-google-ids').value),
369
+ tiktok: document.getElementById('cfg-tiktok').checked,
370
+ tiktokIds: parseCsv(document.getElementById('cfg-tiktok-ids').value),
371
+ };
372
+ }
373
+
374
+ function playgroundConfig() {
375
+ const flags = readFlags();
376
+ return {
377
+ ...DEFAULT_PIXEL_CONFIG,
378
+ app: { ...DEFAULT_PIXEL_CONFIG.app, debug: true },
379
+ identity: { pixelId: PIXEL_ID },
380
+ transport: {
381
+ ...DEFAULT_PIXEL_CONFIG.transport,
382
+ apiEndpoint: API_ENDPOINT,
383
+ },
384
+ attribution: { ...DEFAULT_PIXEL_CONFIG.attribution },
385
+ modules: {
386
+ ...DEFAULT_PIXEL_CONFIG.modules,
387
+ core: {
388
+ ...DEFAULT_PIXEL_CONFIG.modules.core,
389
+ enabled: flags.core,
390
+ },
391
+ behavior: {
392
+ ...DEFAULT_PIXEL_CONFIG.modules.behavior,
393
+ enabled: false,
394
+ },
395
+ conversion: {
396
+ enabled: true,
397
+ manual: {
398
+ pageView: { enabled: false },
399
+ purchase: { enabled: true },
400
+ lead: { enabled: true },
401
+ addToCart: { enabled: false },
402
+ removeFromCart: { enabled: false },
403
+ initiateCheckout: { enabled: false },
404
+ addPaymentInfo: { enabled: false },
405
+ search: { enabled: true },
406
+ viewContent: { enabled: false },
407
+ },
408
+ auto: {
409
+ enabled: false,
410
+ detectors:
411
+ DEFAULT_PIXEL_CONFIG.modules.conversion.auto.detectors,
412
+ },
413
+ rules: {
414
+ ...DEFAULT_PIXEL_CONFIG.modules.conversion.rules,
415
+ enabled: false,
416
+ },
417
+ },
418
+ transport: {
419
+ enabled: true,
420
+ mockSender: { enabled: false },
421
+ sender: { mode: 'http' },
422
+ persistence: { enabled: true },
423
+ replay: { enabled: true },
424
+ ordering: { enabled: true },
425
+ coordination: { enabled: true },
426
+ circuitBreaker: {
427
+ enabled: true,
428
+ failureThreshold: 5,
429
+ resetTimeoutMs: 30000,
430
+ halfOpenMaxAttempts: 2,
431
+ },
432
+ backpressure: {
433
+ enabled: true,
434
+ maxQueueSize: 500,
435
+ policy: 'drop_oldest',
436
+ sampleRate: 0.5,
437
+ },
438
+ deadLetter: { enabled: true, maxEntries: 200 },
439
+ compression: { enabled: true, strategy: 'identity' },
440
+ retry: {
441
+ enabled: true,
442
+ maxAttempts: 4,
443
+ baseDelayMs: 500,
444
+ maxDelayMs: 4000,
445
+ multiplier: 2,
446
+ },
447
+ batch: {
448
+ enabled: true,
449
+ batchSize: 3,
450
+ flushIntervalMs: 2000,
451
+ maxWaitMs: 5000,
452
+ },
453
+ timeout: { enabled: true, timeoutMs: 10000 },
454
+ offline: { enabled: true },
455
+ flush: {
456
+ enabled: true,
457
+ flushIntervalMs: 2000,
458
+ flushOnDestroy: true,
459
+ prepareUnloadHooks: true,
460
+ },
461
+ },
462
+ integrations: {
463
+ enabled: true,
464
+ debug: true,
465
+ concurrency: 8,
466
+ timeoutMs: 8000,
467
+ continueOnError: true,
468
+ destinations: {
469
+ console: { enabled: flags.console },
470
+ memory: { enabled: flags.memory },
471
+ mock: { enabled: flags.mock },
472
+ meta: {
473
+ enabled: flags.meta,
474
+ pixelIds: flags.metaIds,
475
+ autoPageView: true,
476
+ loadScript: true,
477
+ },
478
+ google: {
479
+ enabled: flags.google,
480
+ tagIds: flags.googleIds,
481
+ autoPageView: true,
482
+ loadScript: true,
483
+ },
484
+ tiktok: {
485
+ enabled: flags.tiktok,
486
+ pixelIds: flags.tiktokIds,
487
+ autoPageView: true,
488
+ loadScript: true,
489
+ },
490
+ },
491
+ },
492
+ },
493
+ };
494
+ }
495
+
496
+ function renderIdentifiers(snapshot) {
497
+ const grid = document.getElementById('identifiers-grid');
498
+ grid.innerHTML = '';
499
+ IDENTIFIER_KEYS.forEach(function (key) {
500
+ const val = snapshot && snapshot[key];
501
+ const item = document.createElement('div');
502
+ item.className = 'id-item';
503
+ item.innerHTML =
504
+ '<div class="id-key">' +
505
+ key +
506
+ '</div><div class="id-val' +
507
+ (val ? '' : ' empty') +
508
+ '">' +
509
+ (val || '—') +
510
+ '</div>';
511
+ grid.appendChild(item);
512
+ });
513
+ }
514
+
515
+ function renderPanels() {
516
+ const attribution =
517
+ pixel && pixel.getDebugAttributionSnapshot
518
+ ? pixel.getDebugAttributionSnapshot()
519
+ : null;
520
+ const state =
521
+ pixel && pixel.getDebugIntegrationState
522
+ ? pixel.getDebugIntegrationState()
523
+ : null;
524
+ const memory =
525
+ pixel && pixel.getDebugIntegrationMemoryRecords
526
+ ? pixel.getDebugIntegrationMemoryRecords()
527
+ : [];
528
+ const transport =
529
+ pixel && pixel.getDebugTransportState
530
+ ? pixel.getDebugTransportState()
531
+ : null;
532
+ const services = pixel ? pixel.getDebugServices() : null;
533
+
534
+ document.getElementById('attribution-state').textContent = attribution
535
+ ? formatJson(attribution)
536
+ : 'null (runtime inactive)';
537
+
538
+ renderIdentifiers(attribution);
539
+
540
+ document.getElementById('destinations-state').textContent = state
541
+ ? formatJson({
542
+ active: state.active,
543
+ destinations: state.destinationNames,
544
+ })
545
+ : 'inactive';
546
+
547
+ document.getElementById('metrics-state').textContent = state
548
+ ? formatJson(state.metrics)
549
+ : '—';
550
+
551
+ document.getElementById('memory-state').textContent =
552
+ formatJson(memory);
553
+
554
+ document.getElementById('results-state').textContent = state
555
+ ? formatJson(state.lastResults.slice(-20))
556
+ : '[]';
557
+
558
+ document.getElementById('runtime-state').textContent =
559
+ 'initialized: ' +
560
+ (pixel ? pixel.isInitialized() : false) +
561
+ '\ninit: ' +
562
+ initCount +
563
+ '\ndestroy: ' +
564
+ destroyCount +
565
+ '\nlisteners: ' +
566
+ (services ? services.dispatcher.getListenerCount() : 0) +
567
+ '\nmoduleOrder: Privacy → Transport → Integrations → Core → Behavior → Conversion';
568
+
569
+ document.getElementById('transport-state').textContent = transport
570
+ ? formatJson({
571
+ sentCount: transport.sentCount,
572
+ queueSize: transport.queueSize,
573
+ pipelineSteps: transport.pipelineSteps,
574
+ delivery: transport.delivery,
575
+ })
576
+ : readFlags().transport
577
+ ? 'enabled but no state yet'
578
+ : 'transport disabled';
579
+ }
580
+
581
+ function startRefresh() {
582
+ if (refreshTimer) clearInterval(refreshTimer);
583
+ refreshTimer = setInterval(renderPanels, 400);
584
+ }
585
+
586
+ async function initPixel() {
587
+ if (pixel) {
588
+ await pixel.destroy();
589
+ destroyCount += 1;
590
+ pixel = null;
591
+ }
592
+ if (unsubscribe) {
593
+ unsubscribe();
594
+ unsubscribe = null;
595
+ }
596
+
597
+ pixel = new Pixel(playgroundConfig());
598
+ await pixel.init();
599
+ initCount += 1;
600
+
601
+ const services = pixel.getDebugServices();
602
+ if (services) {
603
+ unsubscribe = services.dispatcher.subscribe(function (event) {
604
+ appendLog('Dispatcher: ' + event.type);
605
+ });
606
+ }
607
+
608
+ appendLog('Playground initialized (Etapa 10C)');
609
+ renderPanels();
610
+ startRefresh();
611
+ }
612
+
613
+ document.getElementById('reinit').addEventListener('click', function () {
614
+ initPixel().catch(function (e) {
615
+ appendLog('Init error: ' + String(e));
616
+ });
617
+ });
618
+
619
+ document
620
+ .getElementById('apply-config')
621
+ .addEventListener('click', function () {
622
+ initPixel().catch(function (e) {
623
+ appendLog('Config error: ' + String(e));
624
+ });
625
+ });
626
+
627
+ document
628
+ .getElementById('destroy')
629
+ .addEventListener('click', async function () {
630
+ if (!pixel) return;
631
+ await pixel.destroy();
632
+ destroyCount += 1;
633
+ pixel = null;
634
+ if (unsubscribe) unsubscribe();
635
+ appendLog('Destroyed');
636
+ renderPanels();
637
+ });
638
+
639
+ document
640
+ .getElementById('btn-collect-attr')
641
+ .addEventListener('click', function () {
642
+ if (!pixel) return;
643
+ const snap = pixel.collectAttribution();
644
+ appendLog('collectAttribution() → ' + JSON.stringify(snap));
645
+ renderPanels();
646
+ });
647
+
648
+ document
649
+ .getElementById('btn-clear-attr')
650
+ .addEventListener('click', function () {
651
+ if (!pixel) return;
652
+ pixel.clearAttribution();
653
+ appendLog('clearAttribution()');
654
+ renderPanels();
655
+ });
656
+
657
+ document
658
+ .getElementById('btn-url-hint')
659
+ .addEventListener('click', function () {
660
+ const base = location.origin + location.pathname;
661
+ const sample =
662
+ base + '?fbclid=TEST_FBCLID&gclid=TEST_GCLID&ttclid=TEST_TTCLID';
663
+ appendLog('URL de teste: ' + sample);
664
+ appendLog(
665
+ 'Abra essa URL (ou edite a barra de endereço) e depois Reinitialize / Collect'
666
+ );
667
+ });
668
+
669
+ document
670
+ .getElementById('btn-purchase')
671
+ .addEventListener('click', function () {
672
+ pixel?.purchase({
673
+ value: 99,
674
+ currency: 'BRL',
675
+ orderId: 'ORD-' + Date.now(),
676
+ });
677
+ });
678
+
679
+ document
680
+ .getElementById('btn-lead')
681
+ .addEventListener('click', function () {
682
+ pixel?.lead({ email: 'lead@example.com' });
683
+ });
684
+
685
+ document
686
+ .getElementById('btn-search')
687
+ .addEventListener('click', function () {
688
+ pixel?.search({ query: 'integration engine' });
689
+ });
690
+
691
+ document
692
+ .getElementById('btn-burst')
693
+ .addEventListener('click', function () {
694
+ if (!pixel) return;
695
+ for (let i = 0; i < 5; i += 1) {
696
+ pixel.purchase({
697
+ value: 10 + i,
698
+ currency: 'BRL',
699
+ orderId: 'BURST-' + Date.now() + '-' + i,
700
+ });
701
+ }
702
+ });
703
+
704
+ initPixel().catch(function (e) {
705
+ appendLog('Bootstrap error: ' + String(e));
706
+ });
707
+ </script>
708
+ </body>
709
+ </html>