@beworke/pixel 0.1.0-rc.13 → 0.1.0-rc.14

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 (41) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/dist/browser/index.cjs.js +1 -1
  3. package/dist/browser/index.cjs.js.map +1 -1
  4. package/dist/browser/index.esm.js +1 -1
  5. package/dist/browser/index.esm.js.map +1 -1
  6. package/dist/browser/pixel.buygoods-checkout.global.js +1 -1
  7. package/dist/browser/pixel.buygoods-checkout.global.js.map +1 -1
  8. package/dist/browser/pixel.buygoods-landing.global.js +1 -1
  9. package/dist/browser/pixel.buygoods-landing.global.js.map +1 -1
  10. package/dist/browser/pixel.global.js +1 -1
  11. package/dist/browser/pixel.global.js.map +1 -1
  12. package/dist/browser/pixel.internal-checkout.global.js +1 -1
  13. package/dist/browser/pixel.internal-checkout.global.js.map +1 -1
  14. package/dist/events/index.cjs.js +1 -1
  15. package/dist/events/index.esm.js +1 -1
  16. package/dist/examples/html-script/README.md +11 -0
  17. package/dist/examples/html-script/customer/README.md +29 -0
  18. package/dist/examples/html-script/customer/example-customer-css.html +383 -0
  19. package/dist/examples/html-script/customer/example-customer-defaults.html +408 -0
  20. package/dist/examples/html-script/customer/example-customer-events.html +428 -0
  21. package/dist/examples/html-script/customer/example-customer-extra-fields.html +385 -0
  22. package/dist/index.cjs.js +1 -1
  23. package/dist/index.cjs.js.map +1 -1
  24. package/dist/index.esm.js +1 -1
  25. package/dist/index.esm.js.map +1 -1
  26. package/dist/runtime/index.cjs.js +1 -1
  27. package/dist/runtime/index.cjs.js.map +1 -1
  28. package/dist/runtime/index.esm.js +1 -1
  29. package/dist/runtime/index.esm.js.map +1 -1
  30. package/dist/services/index.cjs.js +1 -1
  31. package/dist/services/index.cjs.js.map +1 -1
  32. package/dist/services/index.esm.js +1 -1
  33. package/dist/services/index.esm.js.map +1 -1
  34. package/dist/v2/global.global.js +1 -1
  35. package/dist/v2/global.global.js.map +1 -1
  36. package/dist/v2/index.cjs.js +1 -1
  37. package/dist/v2/index.cjs.js.map +1 -1
  38. package/dist/v2/index.esm.js +1 -1
  39. package/dist/v2/index.esm.js.map +1 -1
  40. package/docs/public/configuration/commerce.md +3 -1
  41. package/package.json +1 -1
@@ -0,0 +1,385 @@
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 — Customer extra name/id</title>
7
+ <style>
8
+ :root {
9
+ --bg: #f8fafc; --card: #fff; --border: #e2e8f0; --text: #0f172a;
10
+ --muted: #64748b; --accent: #0f766e; --accent-soft: #ccfbf1;
11
+ }
12
+ * { box-sizing: border-box; }
13
+ body {
14
+ margin: 0;
15
+ font-family: "Segoe UI", system-ui, sans-serif;
16
+ background:
17
+ radial-gradient(circle at top left, #ecfeff 0%, transparent 40%),
18
+ linear-gradient(180deg, #f8fafc 0%, #eef2ff 100%);
19
+ color: var(--text); line-height: 1.45;
20
+ }
21
+ .wrap { max-width: 980px; margin: 0 auto; padding: 1.5rem; }
22
+ h1 { font-size: 1.5rem; margin: 0 0 0.35rem; letter-spacing: -0.02em; }
23
+ h2 { font-size: 1.05rem; margin: 0 0 0.75rem; }
24
+ .sub { color: var(--muted); margin: 0 0 1rem; font-size: 0.92rem; }
25
+ .nav { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-bottom: 1rem; }
26
+ .nav a {
27
+ text-decoration: none; border: 1px solid var(--border); background: #fff;
28
+ color: var(--text); border-radius: 999px; padding: 0.3rem 0.7rem; font-size: 0.78rem;
29
+ }
30
+ .nav a.active { background: var(--accent); border-color: var(--accent); color: #fff; }
31
+ .grid { display: grid; grid-template-columns: 1.15fr 0.85fr; gap: 1rem; }
32
+ @media (max-width: 860px) { .grid { grid-template-columns: 1fr; } }
33
+ .card {
34
+ background: var(--card); border: 1px solid var(--border); border-radius: 12px;
35
+ padding: 1rem; margin-bottom: 1rem; box-shadow: 0 1px 0 rgba(15,23,42,.03);
36
+ }
37
+ .hint {
38
+ background: var(--accent-soft); border: 1px solid #99f6e4; border-radius: 10px;
39
+ padding: 0.85rem 1rem; font-size: 0.9rem; margin-bottom: 1rem;
40
+ }
41
+ .actions { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 0.75rem; }
42
+ button {
43
+ appearance: none; border: 1px solid var(--border); background: #fff; color: var(--text);
44
+ border-radius: 8px; padding: 0.5rem 0.85rem; cursor: pointer; font: inherit;
45
+ }
46
+ button.primary { background: var(--accent); border-color: var(--accent); color: #fff; }
47
+ button.danger { background: #7f1d1d; border-color: #7f1d1d; color: #fff; }
48
+ label { display: block; font-size: 0.8rem; color: var(--muted); margin-bottom: 0.25rem; }
49
+ input {
50
+ width: 100%; border: 1px solid var(--border); border-radius: 8px;
51
+ padding: 0.55rem 0.7rem; font: inherit; background: #fff;
52
+ }
53
+ .row { display: grid; grid-template-columns: 1fr 1fr; gap: 0.75rem; }
54
+ @media (max-width: 560px) { .row { grid-template-columns: 1fr; } }
55
+ .status, pre {
56
+ background: #0f172a; color: #e2e8f0; border-radius: 8px; padding: 0.75rem;
57
+ font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
58
+ font-size: 0.78rem; white-space: pre-wrap; word-break: break-word;
59
+ max-height: 260px; overflow: auto;
60
+ }
61
+ .pill {
62
+ display: inline-block; border-radius: 999px; padding: 0.15rem 0.55rem;
63
+ font-size: 0.72rem; background: #e2e8f0; color: #334155; margin-left: 0.35rem;
64
+ }
65
+ .pill.ok { background: #bbf7d0; color: #166534; }
66
+ .checklist { margin: 0; padding-left: 1.1rem; font-size: 0.88rem; color: var(--muted); }
67
+ .checklist li { margin: 0.35rem 0; }
68
+ .ctx {
69
+ border-left: 3px solid var(--accent); padding-left: 0.75rem; margin-bottom: 0.85rem;
70
+ color: var(--muted); font-size: 0.88rem;
71
+ }
72
+ code { font-size: 0.85em; }
73
+ </style>
74
+ </head>
75
+ <body>
76
+ <div class="wrap">
77
+ <h1>Customer — extra name/id <span class="pill" id="init-pill">offline</span></h1>
78
+ <p class="sub">
79
+ Names que o default <em>não</em> conhece. Extras somam; não substituem.
80
+ </p>
81
+ <div class="nav">
82
+ <a href="example-customer-defaults.html">1. Defaults</a>
83
+ <a href="example-customer-extra-fields.html" class="active">2. Extra name/id</a>
84
+ <a href="example-customer-css.html">3. CSS</a>
85
+ <a href="example-customer-events.html">4. Eventos</a>
86
+ </div>
87
+ <div class="hint">
88
+ <code>commerce.customer.fields</code> mapeia
89
+ <code>user_email</code>, <code>whatsapp</code>,
90
+ <code>nome_completo</code>, <code>cep_entrega</code>.
91
+ O campo <code>name="email"</code> ao lado continua valendo (default).
92
+ </div>
93
+
94
+ <div class="card">
95
+ <h2>Lifecycle</h2>
96
+ <div class="actions">
97
+ <button id="btn-reinit" class="primary" type="button">Reinitialize</button>
98
+ <button id="btn-destroy" class="danger" type="button">Destroy</button>
99
+ <button id="btn-fill" type="button">Preencher extras</button>
100
+ <button id="btn-clear" type="button">Clear logs</button>
101
+ </div>
102
+ <div class="status" id="runtime-status">Aguardando init...</div>
103
+ </div>
104
+
105
+ <div class="grid">
106
+ <div>
107
+ <div class="card">
108
+ <h2>Form customizado</h2>
109
+ <div class="ctx">
110
+ ATC no par <code>user_email</code> + <code>whatsapp</code>.
111
+ </div>
112
+ <form id="customer-form">
113
+ <div class="row">
114
+ <div>
115
+ <label for="user_email">user_email (extra)</label>
116
+ <input id="user_email" name="user_email" type="text" />
117
+ </div>
118
+ <div>
119
+ <label for="whatsapp">whatsapp (extra)</label>
120
+ <input id="whatsapp" name="whatsapp" type="text" />
121
+ </div>
122
+ </div>
123
+ <div class="row">
124
+ <div>
125
+ <label for="nome_completo">nome_completo (extra)</label>
126
+ <input id="nome_completo" name="nome_completo" type="text" />
127
+ </div>
128
+ <div>
129
+ <label for="cep_entrega">cep_entrega → postalCode</label>
130
+ <input id="cep_entrega" name="cep_entrega" type="text" />
131
+ </div>
132
+ </div>
133
+ <div>
134
+ <label for="email">email (default — ainda vale)</label>
135
+ <input id="email" name="email" type="email" placeholder="preencha para ver o merge" />
136
+ </div>
137
+ </form>
138
+ </div>
139
+ <div class="card">
140
+ <h2>Checklist</h2>
141
+ <ul class="checklist">
142
+ <li>[ ] Extras sozinhos → snapshot com email/phone/name/postalCode</li>
143
+ <li>[ ] <code>ADD_TO_CART</code> ao completar user_email + whatsapp</li>
144
+ <li>[ ] Preencher <code>email</code> default também entra no snapshot</li>
145
+ </ul>
146
+ </div>
147
+ </div>
148
+ <div>
149
+ <div class="card">
150
+ <h2>Customer snapshot</h2>
151
+ <pre id="customer-snap">null</pre>
152
+ </div>
153
+ <div class="card">
154
+ <h2>Event counts</h2>
155
+ <div class="status" id="event-counts">Nenhum evento ainda</div>
156
+ </div>
157
+ <div class="card">
158
+ <h2>Last event.customer</h2>
159
+ <pre id="last-customer">null</pre>
160
+ </div>
161
+ <div class="card">
162
+ <h2>Last event JSON</h2>
163
+ <pre id="last-event">null</pre>
164
+ </div>
165
+ <div class="card">
166
+ <h2>Event log</h2>
167
+ <pre id="logs">Aguardando eventos...</pre>
168
+ </div>
169
+ </div>
170
+ </div>
171
+ </div>
172
+
173
+ <script src="../../../browser/pixel.global.js"></script>
174
+ <script>
175
+ const PIXEL_ID = 'pix_7315610';
176
+ const API_ENDPOINT =
177
+ 'https://micro-service-pixel-production-4826.up.railway.app';
178
+
179
+ const els = {
180
+ logs: document.getElementById('logs'),
181
+ last: document.getElementById('last-event'),
182
+ lastCustomer: document.getElementById('last-customer'),
183
+ customer: document.getElementById('customer-snap'),
184
+ counts: document.getElementById('event-counts'),
185
+ runtime: document.getElementById('runtime-status'),
186
+ pill: document.getElementById('init-pill'),
187
+ };
188
+
189
+ let pixel = null;
190
+ let unsubscribe = null;
191
+ let initCount = 0;
192
+ let destroyCount = 0;
193
+ const counts = {};
194
+
195
+ function disabledDetector() {
196
+ return { enabled: false, sources: [] };
197
+ }
198
+
199
+ function buildSettings() {
200
+ return {
201
+ identity: { pixelId: PIXEL_ID },
202
+ app: { source: 'custom', environment: 'development', debug: true },
203
+ transport: {
204
+ enabled: true,
205
+ sender: { mode: 'internal', baseUrl: API_ENDPOINT },
206
+ },
207
+ commerce: {
208
+ enabled: true,
209
+ currency: 'BRL',
210
+ catalog: {
211
+ products: [
212
+ { id: 'main_offer', name: 'Oferta Principal', type: 'main', price: 197, currency: 'BRL', quantity: 1 },
213
+ ],
214
+ },
215
+ cart: {
216
+ mode: 'single_product',
217
+ initialItems: [{ productId: 'main_offer', quantity: 1 }],
218
+ },
219
+ customer: {
220
+ fields: {
221
+ email: 'user_email',
222
+ phone: 'whatsapp',
223
+ name: 'nome_completo',
224
+ postalCode: 'cep_entrega',
225
+ },
226
+ },
227
+ },
228
+ modules: {
229
+ core: {
230
+ pageView: { enabled: false, trackInitialPageView: false, spa: false },
231
+ },
232
+ behavior: { enabled: false },
233
+ conversion: {
234
+ enabled: true,
235
+ auto: {
236
+ enabled: true,
237
+ detectors: {
238
+ lead: disabledDetector(),
239
+ purchase: disabledDetector(),
240
+ removeFromCart: disabledDetector(),
241
+ initiateCheckout: disabledDetector(),
242
+ addPaymentInfo: disabledDetector(),
243
+ search: disabledDetector(),
244
+ viewContent: disabledDetector(),
245
+ addToCart: {
246
+ enabled: true,
247
+ sources: [
248
+ {
249
+ name: 'customer-form',
250
+ type: 'form',
251
+ selectorForm: {
252
+ fields: ['user_email', 'whatsapp'],
253
+ mode: 'all',
254
+ formSelector: '#customer-form',
255
+ trigger: 'auto',
256
+ debounceMs: 300,
257
+ fireOnce: true,
258
+ },
259
+ selector: ['#customer-form'],
260
+ selectorType: 'css',
261
+ },
262
+ ],
263
+ },
264
+ },
265
+ },
266
+ },
267
+ },
268
+ };
269
+ }
270
+
271
+ function appendLog(message) {
272
+ const line = '[' + new Date().toISOString() + '] ' + message;
273
+ const prev = els.logs.textContent;
274
+ els.logs.textContent =
275
+ prev === 'Aguardando eventos...' ? line : line + '\n' + prev;
276
+ }
277
+
278
+ function renderCounts() {
279
+ const lines = Object.keys(counts)
280
+ .sort()
281
+ .map(function (type) { return type + ': ' + counts[type]; });
282
+ els.counts.textContent =
283
+ lines.length > 0 ? lines.join('\n') : 'Nenhum evento ainda';
284
+ }
285
+
286
+ function eventCustomer(event) {
287
+ if (event && event.customer) return event.customer;
288
+ if (event && event.data && event.data.customer) return event.data.customer;
289
+ return null;
290
+ }
291
+
292
+ function renderCustomer() {
293
+ const services = pixel && pixel.getDebugServices ? pixel.getDebugServices() : null;
294
+ const snap =
295
+ services && services.customerIdentity
296
+ ? services.customerIdentity.getSnapshot()
297
+ : null;
298
+ els.customer.textContent = snap ? JSON.stringify(snap, null, 2) : 'null';
299
+ }
300
+
301
+ function renderDebug() {
302
+ els.runtime.textContent =
303
+ 'initialized: ' +
304
+ (pixel ? pixel.isInitialized() : false) +
305
+ '\ninit count: ' +
306
+ initCount +
307
+ '\ndestroy count: ' +
308
+ destroyCount +
309
+ '\npixelId: ' +
310
+ PIXEL_ID +
311
+ '\nscenario: extra name/id';
312
+ els.pill.textContent =
313
+ pixel && pixel.isInitialized() ? 'ready' : 'offline';
314
+ els.pill.className =
315
+ 'pill' + (pixel && pixel.isInitialized() ? ' ok' : '');
316
+ renderCustomer();
317
+ }
318
+
319
+ function onEvent(event) {
320
+ counts[event.type] = (counts[event.type] || 0) + 1;
321
+ renderCounts();
322
+ els.last.textContent = JSON.stringify(event, null, 2);
323
+ const customer = eventCustomer(event);
324
+ els.lastCustomer.textContent = customer
325
+ ? JSON.stringify(customer, null, 2)
326
+ : 'null';
327
+ appendLog(event.type + ' customer=' + JSON.stringify(customer));
328
+ renderDebug();
329
+ }
330
+
331
+ async function boot() {
332
+ if (unsubscribe) { unsubscribe(); unsubscribe = null; }
333
+ if (pixel) {
334
+ await pixel.destroy();
335
+ destroyCount += 1;
336
+ pixel = null;
337
+ }
338
+ pixel = await Pixel.create(buildSettings());
339
+ initCount += 1;
340
+ const services = pixel.getDebugServices();
341
+ if (services && services.dispatcher) {
342
+ unsubscribe = services.dispatcher.subscribe(onEvent);
343
+ }
344
+ appendLog('Pixel initialized — extra name/id');
345
+ renderDebug();
346
+ }
347
+
348
+ async function destroyPixel() {
349
+ if (unsubscribe) { unsubscribe(); unsubscribe = null; }
350
+ if (pixel) {
351
+ await pixel.destroy();
352
+ destroyCount += 1;
353
+ pixel = null;
354
+ }
355
+ appendLog('Pixel destroyed');
356
+ renderDebug();
357
+ }
358
+
359
+ document.getElementById('btn-reinit').onclick = function () { boot(); };
360
+ document.getElementById('btn-destroy').onclick = function () { destroyPixel(); };
361
+ document.getElementById('btn-clear').onclick = function () {
362
+ els.logs.textContent = 'Aguardando eventos...';
363
+ els.last.textContent = 'null';
364
+ els.lastCustomer.textContent = 'null';
365
+ Object.keys(counts).forEach(function (k) { delete counts[k]; });
366
+ renderCounts();
367
+ };
368
+ document.getElementById('btn-fill').onclick = function () {
369
+ document.getElementById('user_email').value = 'lia@loja.com';
370
+ document.getElementById('whatsapp').value = '11988887777';
371
+ document.getElementById('nome_completo').value = 'Lia Costa';
372
+ document.getElementById('cep_entrega').value = '22041-080';
373
+ document.getElementById('customer-form').querySelectorAll('input').forEach(function (input) {
374
+ input.dispatchEvent(new Event('input', { bubbles: true }));
375
+ });
376
+ };
377
+
378
+ document.getElementById('customer-form').addEventListener('input', function () {
379
+ setTimeout(renderCustomer, 250);
380
+ });
381
+
382
+ boot();
383
+ </script>
384
+ </body>
385
+ </html>