@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,748 @@
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 — Transport Advanced (Etapa 9C)</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
+ .actions {
25
+ display: flex;
26
+ flex-wrap: wrap;
27
+ gap: 0.5rem;
28
+ margin: 1rem 0;
29
+ align-items: center;
30
+ }
31
+
32
+ button,
33
+ select {
34
+ padding: 0.5rem 1rem;
35
+ cursor: pointer;
36
+ }
37
+
38
+ input[type='number'],
39
+ input[type='text'] {
40
+ padding: 0.35rem 0.5rem;
41
+ }
42
+
43
+ label {
44
+ font-size: 13px;
45
+ display: inline-flex;
46
+ align-items: center;
47
+ gap: 0.35rem;
48
+ }
49
+
50
+ .panels {
51
+ display: grid;
52
+ grid-template-columns: repeat(3, 1fr);
53
+ gap: 1rem;
54
+ margin: 1rem 0;
55
+ }
56
+
57
+ @media (max-width: 900px) {
58
+ .panels {
59
+ grid-template-columns: 1fr 1fr;
60
+ }
61
+ }
62
+
63
+ @media (max-width: 600px) {
64
+ .panels {
65
+ grid-template-columns: 1fr;
66
+ }
67
+ }
68
+
69
+ .panel {
70
+ font-family: ui-monospace, monospace;
71
+ font-size: 11px;
72
+ border-radius: 8px;
73
+ padding: 0.75rem;
74
+ background: #f4f4f5;
75
+ border: 1px solid #e4e4e7;
76
+ }
77
+
78
+ .panel.wide {
79
+ grid-column: 1 / -1;
80
+ }
81
+
82
+ .panel h3 {
83
+ margin: 0 0 0.5rem;
84
+ font-size: 12px;
85
+ font-family: system-ui, sans-serif;
86
+ }
87
+
88
+ .panel pre {
89
+ margin: 0;
90
+ white-space: pre-wrap;
91
+ word-break: break-word;
92
+ }
93
+
94
+ #logs {
95
+ background: #18181b;
96
+ color: #fafafa;
97
+ min-height: 180px;
98
+ overflow: auto;
99
+ margin-top: 1rem;
100
+ border-radius: 8px;
101
+ padding: 1rem;
102
+ font-family: ui-monospace, monospace;
103
+ font-size: 12px;
104
+ }
105
+
106
+ .flow {
107
+ font-family: ui-monospace, monospace;
108
+ font-size: 11px;
109
+ background: #fafafa;
110
+ border: 1px solid #e4e4e7;
111
+ border-radius: 8px;
112
+ padding: 1rem;
113
+ margin: 1rem 0;
114
+ line-height: 1.6;
115
+ }
116
+
117
+ .section-title {
118
+ margin-top: 1.5rem;
119
+ margin-bottom: 0.25rem;
120
+ }
121
+ </style>
122
+ </head>
123
+ <body>
124
+ <h1>Pixel v2 — Transport Advanced (Etapa 9C)</h1>
125
+
126
+ <div class="hint">
127
+ Endpoint oficial de testes:
128
+ <code>https://micro-service-pixel-production-4826.up.railway.app</code> ·
129
+ Pixel ID: <code>pix_8580907</code>. Alterne entre MockSender e HttpSender,
130
+ storage adapters, replay, circuit breaker, DLQ e fila persistida.
131
+ </div>
132
+
133
+ <div class="flow">
134
+ Dispatcher → TransportEngine → Pipeline → PersistentQueue →
135
+ OrderingManager → BackpressureManager → BatchManager → CircuitBreaker →
136
+ RetryEngine → TimedSender → (MockSender | HttpSender) → API → ACK → Replay
137
+ / DLQ
138
+ </div>
139
+
140
+ <h2 class="section-title">Configuração</h2>
141
+ <div class="actions">
142
+ <label>
143
+ Sender
144
+ <select id="cfg-sender-mode">
145
+ <option value="mock">Mock Sender</option>
146
+ <option value="http">HTTP Sender</option>
147
+ </select>
148
+ </label>
149
+ <label>
150
+ Storage
151
+ <select id="cfg-storage">
152
+ <option value="memory">Memory</option>
153
+ <option value="localStorage">LocalStorage</option>
154
+ <option value="indexedDB">IndexedDB</option>
155
+ </select>
156
+ </label>
157
+ <label>
158
+ batchSize
159
+ <input id="cfg-batch-size" type="number" min="1" max="50" value="3" />
160
+ </label>
161
+ <label>
162
+ timeoutMs
163
+ <input
164
+ id="cfg-timeout-ms"
165
+ type="number"
166
+ min="100"
167
+ max="30000"
168
+ value="10000"
169
+ />
170
+ </label>
171
+ <label>
172
+ maxAttempts
173
+ <input id="cfg-max-attempts" type="number" min="1" max="10" value="4" />
174
+ </label>
175
+ <button id="apply-config" type="button">Aplicar config + reinit</button>
176
+ <button id="reinit" type="button">Reinitialize</button>
177
+ <button id="destroy" type="button">Destroy</button>
178
+ </div>
179
+
180
+ <h2 class="section-title">9C — Advanced Controls</h2>
181
+ <div class="actions">
182
+ <button id="btn-reload" type="button">Simular reload</button>
183
+ <button id="btn-restart" type="button">Simular restart</button>
184
+ <button id="btn-offline" type="button">Simular offline</button>
185
+ <button id="btn-online" type="button">Voltar online</button>
186
+ <button id="btn-flush" type="button">Flush manual</button>
187
+ <button id="btn-replay" type="button">Replay manual</button>
188
+ <button id="btn-circuit-open" type="button">Abrir circuito</button>
189
+ <button id="btn-circuit-close" type="button">Fechar circuito</button>
190
+ <button id="btn-dlq-replay" type="button">Replay DLQ</button>
191
+ <button id="btn-dlq-clear" type="button">Limpar DLQ</button>
192
+ <button id="btn-export-queue" type="button">Exportar fila</button>
193
+ <button id="btn-import-queue" type="button">Importar fila</button>
194
+ <button id="btn-force-retry" type="button">Forçar retry</button>
195
+ <button id="btn-sim-timeout" type="button">Simular timeout</button>
196
+ <button id="btn-reset-sender" type="button">Reset MockSender</button>
197
+ <button id="btn-burst" type="button">Burst (5 eventos)</button>
198
+ </div>
199
+
200
+ <h2 class="section-title">Eventos</h2>
201
+ <div class="actions">
202
+ <button id="btn-purchase" type="button">purchase()</button>
203
+ <button id="btn-lead" type="button">lead()</button>
204
+ <button id="btn-search" type="button">search()</button>
205
+ </div>
206
+
207
+ <div class="panels">
208
+ <div class="panel">
209
+ <h3>Storage State</h3>
210
+ <pre id="storage-state">—</pre>
211
+ </div>
212
+ <div class="panel">
213
+ <h3>Replay State</h3>
214
+ <pre id="replay-state">—</pre>
215
+ </div>
216
+ <div class="panel">
217
+ <h3>Ordering State</h3>
218
+ <pre id="ordering-state">—</pre>
219
+ </div>
220
+ <div class="panel">
221
+ <h3>Coordination State</h3>
222
+ <pre id="coordination-state">—</pre>
223
+ </div>
224
+ <div class="panel">
225
+ <h3>Circuit Breaker</h3>
226
+ <pre id="circuit-state">—</pre>
227
+ </div>
228
+ <div class="panel">
229
+ <h3>Backpressure</h3>
230
+ <pre id="backpressure-state">—</pre>
231
+ </div>
232
+ <div class="panel">
233
+ <h3>Dead Letter</h3>
234
+ <pre id="dlq-state">—</pre>
235
+ </div>
236
+ <div class="panel">
237
+ <h3>Compression</h3>
238
+ <pre id="compression-state">—</pre>
239
+ </div>
240
+ <div class="panel">
241
+ <h3>HTTP Sender / API</h3>
242
+ <pre id="http-state">—</pre>
243
+ </div>
244
+ <div class="panel">
245
+ <h3>Queue State</h3>
246
+ <pre id="queue-state">—</pre>
247
+ </div>
248
+ <div class="panel">
249
+ <h3>Batch State</h3>
250
+ <pre id="batch-state">—</pre>
251
+ </div>
252
+ <div class="panel">
253
+ <h3>Retry State</h3>
254
+ <pre id="retry-state">—</pre>
255
+ </div>
256
+ <div class="panel">
257
+ <h3>Offline State</h3>
258
+ <pre id="offline-state">—</pre>
259
+ </div>
260
+ <div class="panel">
261
+ <h3>Flush State</h3>
262
+ <pre id="flush-state">—</pre>
263
+ </div>
264
+ <div class="panel">
265
+ <h3>Timeout State</h3>
266
+ <pre id="timeout-state">—</pre>
267
+ </div>
268
+ <div class="panel">
269
+ <h3>Sender State</h3>
270
+ <pre id="sender-state">—</pre>
271
+ </div>
272
+ <div class="panel">
273
+ <h3>Transport Metrics</h3>
274
+ <pre id="transport-metrics">—</pre>
275
+ </div>
276
+ <div class="panel">
277
+ <h3>Runtime Metrics</h3>
278
+ <pre id="runtime-metrics">—</pre>
279
+ </div>
280
+ <div class="panel wide">
281
+ <h3>Queue Persistida</h3>
282
+ <pre id="queue-contents">[]</pre>
283
+ </div>
284
+ <div class="panel wide">
285
+ <h3>Pipeline Steps</h3>
286
+ <pre id="pipeline-steps">—</pre>
287
+ </div>
288
+ <div class="panel wide">
289
+ <h3>API Responses</h3>
290
+ <pre id="api-responses">[]</pre>
291
+ </div>
292
+ </div>
293
+
294
+ <h2>Dispatcher Logs</h2>
295
+ <pre id="logs"></pre>
296
+
297
+ <script src="../../dist/v2/global.global.js"></script>
298
+ <script>
299
+ const { Pixel, DEFAULT_PIXEL_CONFIG } = window.PixelV2;
300
+
301
+ const API_ENDPOINT =
302
+ 'https://micro-service-pixel-production-4826.up.railway.app';
303
+ const PIXEL_ID = 'pix_7315610';
304
+
305
+ const logsEl = document.getElementById('logs');
306
+
307
+ let pixel = null;
308
+ let unsubscribe = null;
309
+ let initCount = 0;
310
+ let destroyCount = 0;
311
+ let refreshTimer = null;
312
+
313
+ function readConfigInputs() {
314
+ return {
315
+ senderMode: document.getElementById('cfg-sender-mode').value,
316
+ storage: document.getElementById('cfg-storage').value,
317
+ batchSize:
318
+ Number(document.getElementById('cfg-batch-size').value) || 3,
319
+ timeoutMs:
320
+ Number(document.getElementById('cfg-timeout-ms').value) || 10000,
321
+ maxAttempts:
322
+ Number(document.getElementById('cfg-max-attempts').value) || 4,
323
+ };
324
+ }
325
+
326
+ function transportConfig() {
327
+ const cfg = readConfigInputs();
328
+ const useHttp = cfg.senderMode === 'http';
329
+
330
+ return {
331
+ ...DEFAULT_PIXEL_CONFIG,
332
+ app: { ...DEFAULT_PIXEL_CONFIG.app, debug: true },
333
+ identity: { pixelId: PIXEL_ID },
334
+ transport: {
335
+ ...DEFAULT_PIXEL_CONFIG.transport,
336
+ apiEndpoint: API_ENDPOINT,
337
+ timeoutMs: cfg.timeoutMs,
338
+ },
339
+ storage: {
340
+ ...DEFAULT_PIXEL_CONFIG.storage,
341
+ queue: {
342
+ enabled: true,
343
+ persistence: cfg.storage,
344
+ index: true,
345
+ },
346
+ },
347
+ modules: {
348
+ ...DEFAULT_PIXEL_CONFIG.modules,
349
+ core: { ...DEFAULT_PIXEL_CONFIG.modules.core, enabled: false },
350
+ behavior: {
351
+ ...DEFAULT_PIXEL_CONFIG.modules.behavior,
352
+ enabled: false,
353
+ },
354
+ conversion: {
355
+ enabled: true,
356
+ manual: {
357
+ pageView: { enabled: false },
358
+ purchase: { enabled: true },
359
+ lead: { enabled: true },
360
+ addToCart: { enabled: false },
361
+ removeFromCart: { enabled: false },
362
+ initiateCheckout: { enabled: false },
363
+ addPaymentInfo: { enabled: false },
364
+ search: { enabled: true },
365
+ viewContent: { enabled: false },
366
+ },
367
+ auto: {
368
+ enabled: false,
369
+ detectors:
370
+ DEFAULT_PIXEL_CONFIG.modules.conversion.auto.detectors,
371
+ },
372
+ rules: {
373
+ ...DEFAULT_PIXEL_CONFIG.modules.conversion.rules,
374
+ enabled: false,
375
+ },
376
+ },
377
+ transport: {
378
+ enabled: true,
379
+ mockSender: { enabled: !useHttp },
380
+ sender: { mode: useHttp ? 'http' : 'mock' },
381
+ persistence: { enabled: true },
382
+ replay: { enabled: true },
383
+ ordering: { enabled: true },
384
+ coordination: { enabled: true },
385
+ circuitBreaker: {
386
+ enabled: true,
387
+ failureThreshold: 5,
388
+ resetTimeoutMs: 30000,
389
+ halfOpenMaxAttempts: 2,
390
+ },
391
+ backpressure: {
392
+ enabled: true,
393
+ maxQueueSize: 500,
394
+ policy: 'drop_oldest',
395
+ sampleRate: 0.5,
396
+ },
397
+ deadLetter: { enabled: true, maxEntries: 200 },
398
+ compression: { enabled: true, strategy: 'identity' },
399
+ retry: {
400
+ enabled: true,
401
+ maxAttempts: cfg.maxAttempts,
402
+ baseDelayMs: 500,
403
+ maxDelayMs: 4000,
404
+ multiplier: 2,
405
+ },
406
+ batch: {
407
+ enabled: true,
408
+ batchSize: cfg.batchSize,
409
+ flushIntervalMs: 2000,
410
+ maxWaitMs: 5000,
411
+ },
412
+ timeout: { enabled: true, timeoutMs: cfg.timeoutMs },
413
+ offline: { enabled: true },
414
+ flush: {
415
+ enabled: true,
416
+ flushIntervalMs: 2000,
417
+ flushOnDestroy: true,
418
+ prepareUnloadHooks: true,
419
+ },
420
+ },
421
+ },
422
+ };
423
+ }
424
+
425
+ function appendLog(message) {
426
+ const line = '[' + new Date().toISOString() + '] ' + message;
427
+ logsEl.textContent = line + '\n' + logsEl.textContent;
428
+ }
429
+
430
+ function formatJson(value) {
431
+ return JSON.stringify(value, null, 2);
432
+ }
433
+
434
+ function renderTransportPanels() {
435
+ const state =
436
+ pixel && pixel.getDebugTransportState
437
+ ? pixel.getDebugTransportState()
438
+ : null;
439
+ const services = pixel ? pixel.getDebugServices() : null;
440
+ const delivery = state && state.delivery ? state.delivery : null;
441
+ const advanced = state && state.advanced ? state.advanced : null;
442
+
443
+ document.getElementById('storage-state').textContent = advanced
444
+ ? formatJson(advanced.storage)
445
+ : '—';
446
+ document.getElementById('replay-state').textContent = advanced
447
+ ? formatJson(advanced.replay)
448
+ : '—';
449
+ document.getElementById('ordering-state').textContent = advanced
450
+ ? formatJson(advanced.ordering)
451
+ : '—';
452
+ document.getElementById('coordination-state').textContent = advanced
453
+ ? formatJson(advanced.coordination)
454
+ : '—';
455
+ document.getElementById('circuit-state').textContent = advanced
456
+ ? formatJson(advanced.circuitBreaker)
457
+ : '—';
458
+ document.getElementById('backpressure-state').textContent = advanced
459
+ ? formatJson(advanced.backpressure)
460
+ : '—';
461
+ document.getElementById('dlq-state').textContent = advanced
462
+ ? formatJson(advanced.deadLetter)
463
+ : '—';
464
+ document.getElementById('compression-state').textContent = advanced
465
+ ? formatJson(advanced.compression)
466
+ : '—';
467
+
468
+ const httpResponses =
469
+ state && state.sender && state.sender.responses
470
+ ? state.sender.responses
471
+ : [];
472
+ document.getElementById('http-state').textContent = advanced
473
+ ? 'mode: ' +
474
+ advanced.senderMode +
475
+ '\nendpoint: ' +
476
+ API_ENDPOINT +
477
+ '\nresponses: ' +
478
+ httpResponses.length
479
+ : '—';
480
+ document.getElementById('api-responses').textContent =
481
+ formatJson(httpResponses);
482
+
483
+ document.getElementById('queue-state').textContent = state
484
+ ? 'size: ' + state.queueSize
485
+ : 'Transport inactive';
486
+ document.getElementById('batch-state').textContent = delivery
487
+ ? formatJson(delivery.batch)
488
+ : '—';
489
+ document.getElementById('retry-state').textContent = delivery
490
+ ? formatJson(delivery.retry)
491
+ : '—';
492
+ document.getElementById('offline-state').textContent = delivery
493
+ ? formatJson(delivery.offline)
494
+ : '—';
495
+ document.getElementById('flush-state').textContent = delivery
496
+ ? formatJson(delivery.flush)
497
+ : '—';
498
+ document.getElementById('timeout-state').textContent = delivery
499
+ ? 'timeoutMs: ' +
500
+ delivery.timeoutMs +
501
+ '\ninFlight: ' +
502
+ delivery.inFlight
503
+ : '—';
504
+ document.getElementById('sender-state').textContent =
505
+ state && state.sender ? formatJson(state.sender) : '—';
506
+ document.getElementById('transport-metrics').textContent = state
507
+ ? 'sentCount: ' +
508
+ state.sentCount +
509
+ '\npipeline: ' +
510
+ state.pipelineSteps.join(' → ')
511
+ : '—';
512
+ document.getElementById('runtime-metrics').textContent =
513
+ 'initialized: ' +
514
+ (pixel ? pixel.isInitialized() : false) +
515
+ '\ninit: ' +
516
+ initCount +
517
+ '\ndestroy: ' +
518
+ destroyCount +
519
+ '\nlisteners: ' +
520
+ (services ? services.dispatcher.getListenerCount() : 0);
521
+ document.getElementById('queue-contents').textContent = state
522
+ ? formatJson(
523
+ state.queueContents.map(function (e) {
524
+ return { type: e.type, timestamp: e.timestamp };
525
+ })
526
+ )
527
+ : '[]';
528
+ document.getElementById('pipeline-steps').textContent = state
529
+ ? state.pipelineSteps.join('\n')
530
+ : '—';
531
+ }
532
+
533
+ function startRefreshLoop() {
534
+ if (refreshTimer) clearInterval(refreshTimer);
535
+ refreshTimer = setInterval(renderTransportPanels, 500);
536
+ }
537
+
538
+ async function initPixel() {
539
+ if (pixel) {
540
+ await pixel.destroy();
541
+ destroyCount += 1;
542
+ pixel = null;
543
+ }
544
+ if (unsubscribe) {
545
+ unsubscribe();
546
+ unsubscribe = null;
547
+ }
548
+
549
+ pixel = new Pixel(transportConfig());
550
+ await pixel.init();
551
+ initCount += 1;
552
+
553
+ const services = pixel.getDebugServices();
554
+ if (services) {
555
+ unsubscribe = services.dispatcher.subscribe(function (event) {
556
+ appendLog('Dispatcher: ' + event.type);
557
+ });
558
+ }
559
+
560
+ appendLog(
561
+ 'Transport 9C playground initialized (' +
562
+ readConfigInputs().senderMode +
563
+ ')'
564
+ );
565
+ renderTransportPanels();
566
+ startRefreshLoop();
567
+ }
568
+
569
+ document
570
+ .getElementById('apply-config')
571
+ .addEventListener('click', function () {
572
+ initPixel().catch(function (e) {
573
+ appendLog('Config error: ' + String(e));
574
+ });
575
+ });
576
+ document.getElementById('reinit').addEventListener('click', function () {
577
+ initPixel().catch(function (e) {
578
+ appendLog('Init error: ' + String(e));
579
+ });
580
+ });
581
+ document
582
+ .getElementById('destroy')
583
+ .addEventListener('click', async function () {
584
+ if (!pixel) return;
585
+ await pixel.destroy();
586
+ destroyCount += 1;
587
+ pixel = null;
588
+ if (unsubscribe) unsubscribe();
589
+ appendLog('Pixel destroyed');
590
+ renderTransportPanels();
591
+ });
592
+
593
+ document
594
+ .getElementById('btn-reload')
595
+ .addEventListener('click', async function () {
596
+ if (!pixel) return;
597
+ await pixel.simulateTransportReload();
598
+ appendLog('Simulated reload');
599
+ renderTransportPanels();
600
+ });
601
+ document
602
+ .getElementById('btn-restart')
603
+ .addEventListener('click', async function () {
604
+ if (!pixel) return;
605
+ await pixel.simulateTransportRestart();
606
+ appendLog('Simulated restart');
607
+ renderTransportPanels();
608
+ });
609
+ document
610
+ .getElementById('btn-offline')
611
+ .addEventListener('click', function () {
612
+ pixel?.simulateTransportOffline(true);
613
+ appendLog('Offline');
614
+ renderTransportPanels();
615
+ });
616
+ document
617
+ .getElementById('btn-online')
618
+ .addEventListener('click', function () {
619
+ pixel?.simulateTransportOffline(false);
620
+ appendLog('Online');
621
+ renderTransportPanels();
622
+ });
623
+ document
624
+ .getElementById('btn-flush')
625
+ .addEventListener('click', function () {
626
+ pixel?.flushTransport();
627
+ appendLog('Manual flush');
628
+ });
629
+ document
630
+ .getElementById('btn-replay')
631
+ .addEventListener('click', async function () {
632
+ if (!pixel) return;
633
+ const count = await pixel.manualTransportReplay();
634
+ appendLog('Manual replay: ' + count + ' events');
635
+ });
636
+ document
637
+ .getElementById('btn-circuit-open')
638
+ .addEventListener('click', function () {
639
+ pixel?.forceTransportCircuitOpen();
640
+ appendLog('Circuit opened');
641
+ });
642
+ document
643
+ .getElementById('btn-circuit-close')
644
+ .addEventListener('click', function () {
645
+ pixel?.forceTransportCircuitClose();
646
+ appendLog('Circuit closed');
647
+ });
648
+ document
649
+ .getElementById('btn-dlq-replay')
650
+ .addEventListener('click', function () {
651
+ const events = pixel?.replayTransportDeadLetter();
652
+ appendLog('DLQ replay: ' + (events ? events.length : 0) + ' events');
653
+ });
654
+ document
655
+ .getElementById('btn-dlq-clear')
656
+ .addEventListener('click', function () {
657
+ pixel?.clearTransportDeadLetter();
658
+ appendLog('DLQ cleared');
659
+ });
660
+ document
661
+ .getElementById('btn-export-queue')
662
+ .addEventListener('click', function () {
663
+ const data = pixel?.exportTransportQueue();
664
+ appendLog('Queue exported (' + (data ? data.length : 0) + ' chars)');
665
+ console.log('Exported queue:', data);
666
+ window.prompt('Queue export (copie do console se necessário):', data);
667
+ });
668
+ document
669
+ .getElementById('btn-import-queue')
670
+ .addEventListener('click', function () {
671
+ const raw = window.prompt('Cole o JSON da fila:');
672
+ if (!raw || !pixel) return;
673
+ const count = pixel.importTransportQueue(raw);
674
+ appendLog('Queue imported: ' + count + ' items');
675
+ });
676
+ document
677
+ .getElementById('btn-force-retry')
678
+ .addEventListener('click', function () {
679
+ pixel?.configureTransportMockSender({
680
+ failUntilAttempt: 3,
681
+ delayMs: 0,
682
+ });
683
+ pixel?.purchase({
684
+ value: 42,
685
+ currency: 'BRL',
686
+ orderId: 'RETRY-' + Date.now(),
687
+ });
688
+ appendLog('Retry demo triggered');
689
+ });
690
+ document
691
+ .getElementById('btn-sim-timeout')
692
+ .addEventListener('click', function () {
693
+ pixel?.configureTransportMockSender({ delayMs: 5000 });
694
+ pixel?.purchase({
695
+ value: 1,
696
+ currency: 'BRL',
697
+ orderId: 'TIMEOUT-' + Date.now(),
698
+ });
699
+ appendLog('Timeout demo triggered');
700
+ });
701
+ document
702
+ .getElementById('btn-reset-sender')
703
+ .addEventListener('click', function () {
704
+ pixel?.configureTransportMockSender({
705
+ delayMs: 0,
706
+ failUntilAttempt: undefined,
707
+ });
708
+ appendLog('MockSender reset');
709
+ });
710
+ document
711
+ .getElementById('btn-burst')
712
+ .addEventListener('click', function () {
713
+ if (!pixel) return;
714
+ for (let i = 0; i < 5; i += 1) {
715
+ pixel.purchase({
716
+ value: 10 + i,
717
+ currency: 'BRL',
718
+ orderId: 'BURST-' + Date.now() + '-' + i,
719
+ });
720
+ }
721
+ appendLog('Burst: 5 events');
722
+ });
723
+ document
724
+ .getElementById('btn-purchase')
725
+ .addEventListener('click', function () {
726
+ pixel?.purchase({
727
+ value: 99,
728
+ currency: 'BRL',
729
+ orderId: 'ORD-' + Date.now(),
730
+ });
731
+ });
732
+ document
733
+ .getElementById('btn-lead')
734
+ .addEventListener('click', function () {
735
+ pixel?.lead({ email: 'lead@example.com' });
736
+ });
737
+ document
738
+ .getElementById('btn-search')
739
+ .addEventListener('click', function () {
740
+ pixel?.search({ query: 'transport 9c test' });
741
+ });
742
+
743
+ initPixel().catch(function (e) {
744
+ appendLog('Bootstrap error: ' + String(e));
745
+ });
746
+ </script>
747
+ </body>
748
+ </html>