@central-ticket/queue-sdk 0.0.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.
@@ -0,0 +1,64 @@
1
+ export { C as CentralQ, a as CentralQClient, b as CentralQClientOptions, c as CentralQCreateOptions, d as CentralQOptions, E as ErrorDetail, e as ExpiredDetail, P as PassedDetail, f as PositionDetail, Q as QueueStatus, g as createCentralQClient } from './centralq-I9tdL_Xr.mjs';
2
+ export { QueueTokenValidationResult, ValidateQueueTokenServerOptions, validateQueueTokenServer } from './server.mjs';
3
+ import * as lit from 'lit';
4
+ import { LitElement } from 'lit';
5
+
6
+ type QueueJoinResponse = {
7
+ status: "ACTIVE";
8
+ token: string;
9
+ expiresAt: number;
10
+ } | {
11
+ status: "WAITING";
12
+ position: number;
13
+ ahead: number;
14
+ } | {
15
+ status: "ERROR";
16
+ message: string;
17
+ };
18
+ interface QueueInitResponse {
19
+ userId: string;
20
+ queueInitToken: string;
21
+ expiresAt: number;
22
+ }
23
+ declare const CENTRALQ_DEFAULT_API_URL = "http://localhost:3001";
24
+ /** @internal — HTTP client usado internamente por CentralQ */
25
+ declare class QueueHttpClient {
26
+ apiUrl: string;
27
+ private apiKey?;
28
+ private queueInitToken?;
29
+ constructor(apiUrl?: string, apiKey?: string | undefined, queueInitToken?: string | undefined);
30
+ private get headers();
31
+ /**
32
+ * Intenta unir a un usuario a la cola de un evento.
33
+ * Llama a POST /api/queue/:eventId/join en el worker.
34
+ */
35
+ joinQueue(eventId: string, userId: string): Promise<QueueJoinResponse>;
36
+ /**
37
+ * Envía un heartbeat para mantener vivo el slot (waiting o active).
38
+ * El SDK lo llama cada 10s automáticamente.
39
+ */
40
+ sendHeartbeat(eventId: string, userId: string): Promise<void>;
41
+ /**
42
+ * Libera el slot del usuario inmediatamente.
43
+ * Llamar al completar la compra o al salir voluntariamente.
44
+ */
45
+ leaveQueue(eventId: string, userId: string): Promise<void>;
46
+ issueQueueInitToken(eventId: string, userId?: string): Promise<QueueInitResponse>;
47
+ }
48
+
49
+ /**
50
+ * <central-q> — Web Component de UI puro (internal).
51
+ * Solo renderiza el overlay de la fila. Toda la lógica la maneja CentralQ.
52
+ * No usar directamente — instanciar CentralQ en su lugar.
53
+ */
54
+ declare class CentralQElement extends LitElement {
55
+ status: "LOADING" | "WAITING" | "ACTIVE" | "EXPIRED" | "ERROR";
56
+ position: number;
57
+ ahead: number;
58
+ /** Callback que CentralQ inyecta para manejar "Volver a la fila" */
59
+ onRetry?: () => void;
60
+ static styles: lit.CSSResult;
61
+ render(): lit.TemplateResult<1>;
62
+ }
63
+
64
+ export { CENTRALQ_DEFAULT_API_URL, CentralQElement, QueueHttpClient, type QueueJoinResponse };
@@ -0,0 +1,64 @@
1
+ export { C as CentralQ, a as CentralQClient, b as CentralQClientOptions, c as CentralQCreateOptions, d as CentralQOptions, E as ErrorDetail, e as ExpiredDetail, P as PassedDetail, f as PositionDetail, Q as QueueStatus, g as createCentralQClient } from './centralq-I9tdL_Xr.js';
2
+ export { QueueTokenValidationResult, ValidateQueueTokenServerOptions, validateQueueTokenServer } from './server.js';
3
+ import * as lit from 'lit';
4
+ import { LitElement } from 'lit';
5
+
6
+ type QueueJoinResponse = {
7
+ status: "ACTIVE";
8
+ token: string;
9
+ expiresAt: number;
10
+ } | {
11
+ status: "WAITING";
12
+ position: number;
13
+ ahead: number;
14
+ } | {
15
+ status: "ERROR";
16
+ message: string;
17
+ };
18
+ interface QueueInitResponse {
19
+ userId: string;
20
+ queueInitToken: string;
21
+ expiresAt: number;
22
+ }
23
+ declare const CENTRALQ_DEFAULT_API_URL = "http://localhost:3001";
24
+ /** @internal — HTTP client usado internamente por CentralQ */
25
+ declare class QueueHttpClient {
26
+ apiUrl: string;
27
+ private apiKey?;
28
+ private queueInitToken?;
29
+ constructor(apiUrl?: string, apiKey?: string | undefined, queueInitToken?: string | undefined);
30
+ private get headers();
31
+ /**
32
+ * Intenta unir a un usuario a la cola de un evento.
33
+ * Llama a POST /api/queue/:eventId/join en el worker.
34
+ */
35
+ joinQueue(eventId: string, userId: string): Promise<QueueJoinResponse>;
36
+ /**
37
+ * Envía un heartbeat para mantener vivo el slot (waiting o active).
38
+ * El SDK lo llama cada 10s automáticamente.
39
+ */
40
+ sendHeartbeat(eventId: string, userId: string): Promise<void>;
41
+ /**
42
+ * Libera el slot del usuario inmediatamente.
43
+ * Llamar al completar la compra o al salir voluntariamente.
44
+ */
45
+ leaveQueue(eventId: string, userId: string): Promise<void>;
46
+ issueQueueInitToken(eventId: string, userId?: string): Promise<QueueInitResponse>;
47
+ }
48
+
49
+ /**
50
+ * <central-q> — Web Component de UI puro (internal).
51
+ * Solo renderiza el overlay de la fila. Toda la lógica la maneja CentralQ.
52
+ * No usar directamente — instanciar CentralQ en su lugar.
53
+ */
54
+ declare class CentralQElement extends LitElement {
55
+ status: "LOADING" | "WAITING" | "ACTIVE" | "EXPIRED" | "ERROR";
56
+ position: number;
57
+ ahead: number;
58
+ /** Callback que CentralQ inyecta para manejar "Volver a la fila" */
59
+ onRetry?: () => void;
60
+ static styles: lit.CSSResult;
61
+ render(): lit.TemplateResult<1>;
62
+ }
63
+
64
+ export { CENTRALQ_DEFAULT_API_URL, CentralQElement, QueueHttpClient, type QueueJoinResponse };
package/dist/index.js ADDED
@@ -0,0 +1,509 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __esm = (fn, res) => function __init() {
7
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
8
+ };
9
+ var __export = (target, all) => {
10
+ for (var name in all)
11
+ __defProp(target, name, { get: all[name], enumerable: true });
12
+ };
13
+ var __copyProps = (to, from, except, desc) => {
14
+ if (from && typeof from === "object" || typeof from === "function") {
15
+ for (let key of __getOwnPropNames(from))
16
+ if (!__hasOwnProp.call(to, key) && key !== except)
17
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
18
+ }
19
+ return to;
20
+ };
21
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
22
+ var __decorateClass = (decorators, target, key, kind) => {
23
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
24
+ for (var i = decorators.length - 1, decorator; i >= 0; i--)
25
+ if (decorator = decorators[i])
26
+ result = (kind ? decorator(target, key, result) : decorator(result)) || result;
27
+ if (kind && result) __defProp(target, key, result);
28
+ return result;
29
+ };
30
+
31
+ // src/queue-element.ts
32
+ var queue_element_exports = {};
33
+ __export(queue_element_exports, {
34
+ CentralQElement: () => CentralQElement
35
+ });
36
+ var import_lit, import_decorators, CentralQElement;
37
+ var init_queue_element = __esm({
38
+ "src/queue-element.ts"() {
39
+ "use strict";
40
+ import_lit = require("lit");
41
+ import_decorators = require("lit/decorators.js");
42
+ CentralQElement = class extends import_lit.LitElement {
43
+ constructor() {
44
+ super(...arguments);
45
+ this.status = "LOADING";
46
+ this.position = 0;
47
+ this.ahead = 0;
48
+ }
49
+ render() {
50
+ if (this.status === "ACTIVE") return import_lit.html``;
51
+ return import_lit.html`
52
+ <div class="overlay">
53
+ <div class="modal">
54
+ ${this.status === "LOADING" ? import_lit.html`
55
+ <div class="spinner"></div>
56
+ <h2>Conectando a la fila...</h2>
57
+ ` : ""}
58
+ ${this.status === "WAITING" ? import_lit.html`
59
+ <div class="spinner"></div>
60
+ <h2>Estás en la fila virtual</h2>
61
+ <p>Tu posición: <strong>#${this.position}</strong></p>
62
+ ${this.ahead > 0 ? import_lit.html`<p>
63
+ Hay <strong>${this.ahead}</strong>
64
+ ${this.ahead === 1 ? "persona" : "personas"} delante de
65
+ ti.
66
+ </p>` : import_lit.html`<p>¡Eres el siguiente!</p>`}
67
+ <p style="font-size: 0.85rem; color: #aaa;">
68
+ Por favor, no cierres esta ventana.
69
+ </p>
70
+ ` : ""}
71
+ ${this.status === "EXPIRED" ? import_lit.html`
72
+ <h2 style="color: #f59e0b;">Tu sesión ha expirado</h2>
73
+ <p>El tiempo para completar la compra terminó.</p>
74
+ <button
75
+ style="margin-top: 1rem; padding: 0.75rem 2rem; font-size: 1rem;
76
+ cursor: pointer; border-radius: 8px; border: none;
77
+ background: #3b82f6; color: white;"
78
+ @click=${() => this.onRetry?.()}
79
+ >
80
+ Volver a la fila
81
+ </button>
82
+ ` : ""}
83
+ ${this.status === "ERROR" ? import_lit.html`
84
+ <h2 style="color: #ef4444;">Ocurrió un error de conexión</h2>
85
+ <p>Por favor, recarga la página.</p>
86
+ ` : ""}
87
+ </div>
88
+ </div>
89
+ `;
90
+ }
91
+ };
92
+ CentralQElement.styles = import_lit.css`
93
+ :host {
94
+ display: contents;
95
+ }
96
+ .overlay {
97
+ position: fixed;
98
+ inset: 0;
99
+ background: rgba(0, 0, 0, 0.8);
100
+ backdrop-filter: blur(5px);
101
+ display: flex;
102
+ align-items: center;
103
+ justify-content: center;
104
+ z-index: 9999;
105
+ font-family: system-ui, sans-serif;
106
+ }
107
+ .modal {
108
+ background: #1e1e1e;
109
+ color: white;
110
+ padding: 2rem;
111
+ border-radius: 12px;
112
+ text-align: center;
113
+ max-width: 400px;
114
+ box-shadow: 0 10px 25px rgba(0, 0, 0, 0.5);
115
+ }
116
+ .spinner {
117
+ margin: 1rem auto;
118
+ width: 40px;
119
+ height: 40px;
120
+ border: 4px solid #333;
121
+ border-top-color: #3b82f6;
122
+ border-radius: 50%;
123
+ animation: spin 1s linear infinite;
124
+ }
125
+ @keyframes spin {
126
+ to {
127
+ transform: rotate(360deg);
128
+ }
129
+ }
130
+ `;
131
+ __decorateClass([
132
+ (0, import_decorators.state)()
133
+ ], CentralQElement.prototype, "status", 2);
134
+ __decorateClass([
135
+ (0, import_decorators.state)()
136
+ ], CentralQElement.prototype, "position", 2);
137
+ __decorateClass([
138
+ (0, import_decorators.state)()
139
+ ], CentralQElement.prototype, "ahead", 2);
140
+ CentralQElement = __decorateClass([
141
+ (0, import_decorators.customElement)("central-q")
142
+ ], CentralQElement);
143
+ }
144
+ });
145
+
146
+ // src/index.ts
147
+ var index_exports = {};
148
+ __export(index_exports, {
149
+ CENTRALQ_DEFAULT_API_URL: () => CENTRALQ_DEFAULT_API_URL,
150
+ CentralQ: () => CentralQ,
151
+ CentralQClient: () => CentralQClient,
152
+ QueueHttpClient: () => QueueHttpClient,
153
+ createCentralQClient: () => createCentralQClient,
154
+ validateQueueTokenServer: () => validateQueueTokenServer
155
+ });
156
+ module.exports = __toCommonJS(index_exports);
157
+
158
+ // src/queue-client.ts
159
+ var CENTRALQ_DEFAULT_API_URL = "http://localhost:3001";
160
+ function normalizeApiUrl(apiUrl) {
161
+ const trimmed = apiUrl.replace(/\/+$/, "");
162
+ return trimmed.endsWith("/api") ? trimmed.slice(0, -4) : trimmed;
163
+ }
164
+ var QueueHttpClient = class {
165
+ constructor(apiUrl = CENTRALQ_DEFAULT_API_URL, apiKey, queueInitToken) {
166
+ this.apiUrl = apiUrl;
167
+ this.apiKey = apiKey;
168
+ this.queueInitToken = queueInitToken;
169
+ this.apiUrl = normalizeApiUrl(this.apiUrl);
170
+ }
171
+ get headers() {
172
+ const h = { "Content-Type": "application/json" };
173
+ if (this.apiKey) h["x-api-key"] = this.apiKey;
174
+ if (this.queueInitToken) h["x-queue-init-token"] = this.queueInitToken;
175
+ return h;
176
+ }
177
+ /**
178
+ * Intenta unir a un usuario a la cola de un evento.
179
+ * Llama a POST /api/queue/:eventId/join en el worker.
180
+ */
181
+ async joinQueue(eventId, userId) {
182
+ const res = await fetch(
183
+ `${this.apiUrl}/api/queue/${encodeURIComponent(eventId)}/join`,
184
+ {
185
+ method: "POST",
186
+ headers: this.headers,
187
+ body: JSON.stringify({ userId })
188
+ }
189
+ );
190
+ if (!res.ok) {
191
+ const body = await res.json().catch(() => ({}));
192
+ throw new Error(
193
+ body.message ?? `Error ${res.status} al conectar con el sistema de colas`
194
+ );
195
+ }
196
+ return res.json();
197
+ }
198
+ /**
199
+ * Envía un heartbeat para mantener vivo el slot (waiting o active).
200
+ * El SDK lo llama cada 10s automáticamente.
201
+ */
202
+ async sendHeartbeat(eventId, userId) {
203
+ await fetch(
204
+ `${this.apiUrl}/api/queue/${encodeURIComponent(eventId)}/heartbeat`,
205
+ {
206
+ method: "POST",
207
+ headers: this.headers,
208
+ body: JSON.stringify({ userId })
209
+ }
210
+ );
211
+ }
212
+ /**
213
+ * Libera el slot del usuario inmediatamente.
214
+ * Llamar al completar la compra o al salir voluntariamente.
215
+ */
216
+ async leaveQueue(eventId, userId) {
217
+ await fetch(
218
+ `${this.apiUrl}/api/queue/${encodeURIComponent(eventId)}/leave`,
219
+ {
220
+ method: "POST",
221
+ headers: this.headers,
222
+ body: JSON.stringify({ userId })
223
+ }
224
+ );
225
+ }
226
+ async issueQueueInitToken(eventId, userId) {
227
+ const res = await fetch(
228
+ `${this.apiUrl}/api/queue/init/${encodeURIComponent(eventId)}`,
229
+ {
230
+ method: "POST",
231
+ headers: this.headers,
232
+ body: JSON.stringify({ userId })
233
+ }
234
+ );
235
+ const body = await res.json().catch(() => ({}));
236
+ if (!res.ok) {
237
+ throw new Error(
238
+ body.message ?? `Error ${res.status} al inicializar sesi\xF3n de cola`
239
+ );
240
+ }
241
+ const token = body.queueInitToken ?? body.initToken;
242
+ if (!body.userId || !token || !body.expiresAt) {
243
+ throw new Error("Respuesta inv\xE1lida al inicializar sesi\xF3n de cola");
244
+ }
245
+ return {
246
+ userId: body.userId,
247
+ queueInitToken: token,
248
+ expiresAt: body.expiresAt
249
+ };
250
+ }
251
+ };
252
+
253
+ // src/centralq.ts
254
+ var CentralQ = class _CentralQ {
255
+ constructor(options) {
256
+ this.element = null;
257
+ this.destroyed = false;
258
+ // biome-ignore lint: allow explicit any for generic event map
259
+ this.listeners = /* @__PURE__ */ new Map();
260
+ this.client = new QueueHttpClient(
261
+ options.apiUrl,
262
+ options.apiKey,
263
+ options.queueInitToken
264
+ );
265
+ this.eventId = options.eventId;
266
+ this.pollInterval = options.pollInterval ?? 1e4;
267
+ this.container = options.container ?? document.body;
268
+ this.userId = this.resolveUserId(options.userId);
269
+ }
270
+ /**
271
+ * Inicializa CentralQ y comienza el flujo de cola automáticamente.
272
+ * Monta el overlay de UI y empieza a hacer polling.
273
+ */
274
+ static init(options) {
275
+ const instance = new _CentralQ(options);
276
+ instance.mount();
277
+ instance.checkQueue();
278
+ return instance;
279
+ }
280
+ // Event API
281
+ /** Suscribirse a un evento del ciclo de vida de la cola */
282
+ on(event, listener) {
283
+ if (!this.listeners.has(event)) {
284
+ this.listeners.set(event, /* @__PURE__ */ new Set());
285
+ }
286
+ this.listeners.get(event).add(listener);
287
+ return this;
288
+ }
289
+ /** Desuscribirse de un evento */
290
+ off(event, listener) {
291
+ this.listeners.get(event)?.delete(listener);
292
+ return this;
293
+ }
294
+ emit(event, detail) {
295
+ this.listeners.get(event)?.forEach((fn) => fn(detail));
296
+ }
297
+ // Métodos públicos
298
+ /**
299
+ * Libera el slot del usuario inmediatamente.
300
+ * Llamar cuando el usuario completa la compra.
301
+ */
302
+ leave() {
303
+ this.stopTimers();
304
+ this.updateUI("ACTIVE");
305
+ this.client.leaveQueue(this.eventId, this.userId).catch(() => {
306
+ });
307
+ }
308
+ /**
309
+ * Destruye la instancia: para todos los timers, desmonta el overlay,
310
+ * y libera el slot en el servidor.
311
+ */
312
+ destroy() {
313
+ this.destroyed = true;
314
+ this.stopTimers();
315
+ this.client.leaveQueue(this.eventId, this.userId).catch(() => {
316
+ });
317
+ this.unmount();
318
+ this.listeners.clear();
319
+ }
320
+ /** Retorna el userId resuelto (externo o autogenerado) */
321
+ getUserId() {
322
+ return this.userId;
323
+ }
324
+ // userId: genera y persiste automáticamente
325
+ resolveUserId(externalId) {
326
+ if (externalId) return externalId;
327
+ const key = `ctq_anon_${this.eventId}`;
328
+ try {
329
+ const stored = sessionStorage.getItem(key);
330
+ if (stored) return stored;
331
+ } catch {
332
+ }
333
+ const generated = `anon_${crypto.randomUUID()}`;
334
+ try {
335
+ sessionStorage.setItem(key, generated);
336
+ } catch {
337
+ }
338
+ return generated;
339
+ }
340
+ // UI: montar/desmontar el Web Component
341
+ mount() {
342
+ Promise.resolve().then(() => init_queue_element());
343
+ this.element = document.createElement("central-q");
344
+ this.element.onRetry = () => {
345
+ this.updateUI("LOADING");
346
+ this.checkQueue();
347
+ };
348
+ this.container.appendChild(this.element);
349
+ }
350
+ unmount() {
351
+ if (this.element) {
352
+ this.element.remove();
353
+ this.element = null;
354
+ }
355
+ }
356
+ updateUI(status, data) {
357
+ if (!this.element) return;
358
+ this.element.status = status;
359
+ if (data?.position !== void 0) this.element.position = data.position;
360
+ if (data?.ahead !== void 0) this.element.ahead = data.ahead;
361
+ }
362
+ // Timers
363
+ stopTimers() {
364
+ if (this.pollingTimer) {
365
+ clearInterval(this.pollingTimer);
366
+ this.pollingTimer = void 0;
367
+ }
368
+ if (this.heartbeatTimer) {
369
+ clearInterval(this.heartbeatTimer);
370
+ this.heartbeatTimer = void 0;
371
+ }
372
+ if (this.expiryTimer) {
373
+ clearTimeout(this.expiryTimer);
374
+ this.expiryTimer = void 0;
375
+ }
376
+ }
377
+ startHeartbeat() {
378
+ if (this.heartbeatTimer) return;
379
+ this.heartbeatTimer = setInterval(() => {
380
+ this.client.sendHeartbeat(this.eventId, this.userId).catch(() => {
381
+ });
382
+ }, this.pollInterval);
383
+ }
384
+ scheduleExpiry(expiresAt) {
385
+ if (this.expiryTimer) clearTimeout(this.expiryTimer);
386
+ const msLeft = expiresAt * 1e3 - Date.now();
387
+ if (msLeft <= 0) {
388
+ this.handleExpired();
389
+ return;
390
+ }
391
+ this.expiryTimer = setTimeout(() => this.handleExpired(), msLeft);
392
+ }
393
+ handleExpired() {
394
+ this.stopTimers();
395
+ this.updateUI("EXPIRED");
396
+ this.emit("expired", {
397
+ userId: this.userId,
398
+ eventId: this.eventId
399
+ });
400
+ }
401
+ // Core: polling + join
402
+ async checkQueue() {
403
+ if (this.destroyed) return;
404
+ try {
405
+ const res = await this.client.joinQueue(this.eventId, this.userId);
406
+ if (res.status === "ACTIVE") {
407
+ if (this.pollingTimer) {
408
+ clearInterval(this.pollingTimer);
409
+ this.pollingTimer = void 0;
410
+ }
411
+ this.startHeartbeat();
412
+ this.scheduleExpiry(res.expiresAt);
413
+ this.updateUI("ACTIVE");
414
+ this.emit("passed", {
415
+ token: res.token,
416
+ expiresAt: res.expiresAt,
417
+ userId: this.userId,
418
+ eventId: this.eventId
419
+ });
420
+ } else if (res.status === "WAITING") {
421
+ this.updateUI("WAITING", {
422
+ position: res.position,
423
+ ahead: res.ahead
424
+ });
425
+ this.emit("position", {
426
+ position: res.position,
427
+ ahead: res.ahead,
428
+ userId: this.userId,
429
+ eventId: this.eventId
430
+ });
431
+ if (!this.pollingTimer) {
432
+ this.pollingTimer = setInterval(
433
+ () => this.checkQueue(),
434
+ this.pollInterval
435
+ );
436
+ }
437
+ }
438
+ } catch {
439
+ this.updateUI("ERROR");
440
+ this.stopTimers();
441
+ this.emit("error", {
442
+ userId: this.userId,
443
+ eventId: this.eventId
444
+ });
445
+ }
446
+ }
447
+ };
448
+ var CentralQClient = class {
449
+ constructor(defaults) {
450
+ this.defaults = defaults;
451
+ }
452
+ issueQueueInitToken(eventId, userId) {
453
+ const client = new QueueHttpClient(
454
+ this.defaults.apiUrl,
455
+ this.defaults.apiKey
456
+ );
457
+ return client.issueQueueInitToken(eventId, userId);
458
+ }
459
+ createQueue(options) {
460
+ return CentralQ.init({
461
+ apiUrl: options.apiUrl ?? this.defaults.apiUrl,
462
+ apiKey: options.apiKey ?? this.defaults.apiKey,
463
+ eventId: options.eventId,
464
+ userId: options.userId ?? this.defaults.userId,
465
+ queueInitToken: options.queueInitToken ?? this.defaults.queueInitToken,
466
+ pollInterval: options.pollInterval ?? this.defaults.pollInterval,
467
+ container: options.container ?? this.defaults.container
468
+ });
469
+ }
470
+ };
471
+ function createCentralQClient(options) {
472
+ return new CentralQClient({
473
+ ...options,
474
+ apiUrl: options.apiUrl ?? CENTRALQ_DEFAULT_API_URL
475
+ });
476
+ }
477
+
478
+ // src/server.ts
479
+ function normalizeApiUrl2(apiUrl) {
480
+ return apiUrl.replace(/\/+$/, "");
481
+ }
482
+ async function validateQueueTokenServer(options) {
483
+ const apiUrl = options.apiUrl ?? CENTRALQ_DEFAULT_API_URL;
484
+ const response = await fetch(
485
+ `${normalizeApiUrl2(apiUrl)}/api/verify/${encodeURIComponent(options.eventId)}`,
486
+ {
487
+ method: "POST",
488
+ headers: {
489
+ "Content-Type": "application/json",
490
+ "x-api-key": options.secretKey
491
+ },
492
+ body: JSON.stringify({ token: options.token })
493
+ }
494
+ );
495
+ const data = await response.json().catch(() => ({
496
+ valid: false,
497
+ reason: "Respuesta inv\xE1lida"
498
+ }));
499
+ return { status: response.status, data };
500
+ }
501
+ // Annotate the CommonJS export names for ESM import in node:
502
+ 0 && (module.exports = {
503
+ CENTRALQ_DEFAULT_API_URL,
504
+ CentralQ,
505
+ CentralQClient,
506
+ QueueHttpClient,
507
+ createCentralQClient,
508
+ validateQueueTokenServer
509
+ });
package/dist/index.mjs ADDED
@@ -0,0 +1,21 @@
1
+ import {
2
+ validateQueueTokenServer
3
+ } from "./chunk-JR7BCYB5.mjs";
4
+ import {
5
+ CentralQ,
6
+ CentralQClient,
7
+ createCentralQClient
8
+ } from "./chunk-A4HITWM4.mjs";
9
+ import {
10
+ CENTRALQ_DEFAULT_API_URL,
11
+ QueueHttpClient
12
+ } from "./chunk-42RGFZKP.mjs";
13
+ import "./chunk-XRJFNASX.mjs";
14
+ export {
15
+ CENTRALQ_DEFAULT_API_URL,
16
+ CentralQ,
17
+ CentralQClient,
18
+ QueueHttpClient,
19
+ createCentralQClient,
20
+ validateQueueTokenServer
21
+ };