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

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