@central-ticket/queue-sdk 0.0.3 → 0.0.4

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.
@@ -1,3 +1,90 @@
1
+ type QueueJoinResponse = {
2
+ status: "ACTIVE";
3
+ token: string;
4
+ expiresAt: number;
5
+ } | {
6
+ status: "WAITING";
7
+ position: number;
8
+ ahead: number;
9
+ } | {
10
+ status: "PAUSED";
11
+ message: string;
12
+ retryAfterSeconds: number;
13
+ } | {
14
+ status: "ERROR";
15
+ message: string;
16
+ };
17
+ interface QueueInitResponse {
18
+ userId: string;
19
+ queueInitToken: string;
20
+ expiresAt: number;
21
+ }
22
+ interface QueueBypassResponse {
23
+ status: "ACTIVE";
24
+ token: string;
25
+ expiresAt: number;
26
+ bypass: true;
27
+ }
28
+ type AdmissionMode = "PUBLIC" | "MANAGED" | "TRUSTED";
29
+ interface QueueProtectionResponse {
30
+ eventId: string;
31
+ configured: boolean;
32
+ protected: boolean;
33
+ isActive: boolean;
34
+ isPaused: boolean;
35
+ admissionMode: AdmissionMode;
36
+ challengeRequired: boolean;
37
+ }
38
+ type AdmissionChallengeResponse = {
39
+ required: false;
40
+ } | {
41
+ required: true;
42
+ publicKey: string;
43
+ appearance: "interaction-only";
44
+ };
45
+ type QueueVerifyResponse = {
46
+ valid: true;
47
+ userId: string;
48
+ eventId: string;
49
+ expiresAt: string;
50
+ } | {
51
+ valid: false;
52
+ reason: string;
53
+ };
54
+ declare const CENTRALQ_DEFAULT_API_URL = "http://localhost:3001";
55
+ /** @internal — HTTP client usado internamente por CentralQ */
56
+ declare class QueueHttpClient {
57
+ apiUrl: string;
58
+ private apiKey?;
59
+ private queueInitToken?;
60
+ constructor(apiUrl?: string, apiKey?: string | undefined, queueInitToken?: string | undefined);
61
+ private get headers();
62
+ /**
63
+ * Intenta unir a un usuario a la cola de un evento.
64
+ * Llama a POST /api/queue/:eventId/join en el worker.
65
+ */
66
+ joinQueue(eventId: string, userId: string): Promise<QueueJoinResponse>;
67
+ /**
68
+ * Canjea un código de bypass por un token de acceso activo.
69
+ * El worker descuenta un uso únicamente cuando el canje es exitoso.
70
+ */
71
+ redeemBypassCode(eventId: string, code: string, userId?: string): Promise<QueueBypassResponse>;
72
+ /**
73
+ * Envía un heartbeat para mantener vivo el slot (waiting o active).
74
+ * El SDK lo llama cada 10s automáticamente.
75
+ */
76
+ sendHeartbeat(eventId: string, userId: string): Promise<void>;
77
+ /**
78
+ * Libera el slot del usuario inmediatamente.
79
+ * Llamar al completar la compra o al salir voluntariamente.
80
+ */
81
+ leaveQueue(eventId: string, userId: string): Promise<void>;
82
+ issueQueueInitToken(eventId: string, userId?: string, admissionProof?: string): Promise<QueueInitResponse>;
83
+ getProtection(eventId: string): Promise<QueueProtectionResponse>;
84
+ getAdmissionChallenge(eventId: string): Promise<AdmissionChallengeResponse>;
85
+ verifyToken(eventId: string, token: string): Promise<QueueVerifyResponse>;
86
+ }
87
+
1
88
  interface CentralQOptions {
2
89
  /** URL del queue worker. */
3
90
  apiUrl?: string;
@@ -64,15 +151,22 @@ interface ErrorDetail {
64
151
  userId: string;
65
152
  eventId: string;
66
153
  }
154
+ interface PausedDetail {
155
+ message: string;
156
+ retryAfterSeconds: number;
157
+ userId: string;
158
+ eventId: string;
159
+ }
67
160
  type EventMap = {
68
161
  passed: PassedDetail;
69
162
  expired: ExpiredDetail;
70
163
  position: PositionDetail;
164
+ paused: PausedDetail;
71
165
  error: ErrorDetail;
72
166
  };
73
167
  type EventName = keyof EventMap;
74
168
  type Listener<T> = (detail: T) => void;
75
- type QueueStatus = "idle" | "joining" | "waiting" | "passed" | "expired" | "error";
169
+ type QueueStatus = "idle" | "joining" | "waiting" | "paused" | "passed" | "expired" | "error";
76
170
  declare class CentralQ {
77
171
  private client;
78
172
  private element;
@@ -121,6 +215,7 @@ declare class CentralQ {
121
215
  declare class CentralQClient {
122
216
  private defaults;
123
217
  constructor(defaults: CentralQClientOptions);
218
+ redeemBypassCode(eventId: string, code: string, userId?: string): Promise<QueueBypassResponse>;
124
219
  issueQueueInitToken(eventId: string, userId?: string): Promise<{
125
220
  userId: string;
126
221
  queueInitToken: string;
@@ -131,4 +226,4 @@ declare class CentralQClient {
131
226
  }
132
227
  declare function createCentralQClient(options: CentralQClientOptions): CentralQClient;
133
228
 
134
- export { CentralQ as C, type ErrorDetail as E, type PassedDetail as P, type QueueStatus as Q, CentralQClient as a, type CentralQClientOptions as b, type CentralQCreateOptions as c, type CentralQOptions as d, type ExpiredDetail as e, type PositionDetail as f, createCentralQClient as g };
229
+ export { type AdmissionChallengeResponse as A, CENTRALQ_DEFAULT_API_URL as C, type ErrorDetail as E, type PassedDetail as P, type QueueBypassResponse as Q, type AdmissionMode as a, CentralQ as b, CentralQClient as c, type CentralQClientOptions as d, type CentralQCreateOptions as e, type CentralQOptions as f, type ExpiredDetail as g, type PausedDetail as h, type PositionDetail as i, QueueHttpClient as j, type QueueJoinResponse as k, type QueueProtectionResponse as l, type QueueStatus as m, type QueueVerifyResponse as n, createCentralQClient as o };
@@ -1,3 +1,90 @@
1
+ type QueueJoinResponse = {
2
+ status: "ACTIVE";
3
+ token: string;
4
+ expiresAt: number;
5
+ } | {
6
+ status: "WAITING";
7
+ position: number;
8
+ ahead: number;
9
+ } | {
10
+ status: "PAUSED";
11
+ message: string;
12
+ retryAfterSeconds: number;
13
+ } | {
14
+ status: "ERROR";
15
+ message: string;
16
+ };
17
+ interface QueueInitResponse {
18
+ userId: string;
19
+ queueInitToken: string;
20
+ expiresAt: number;
21
+ }
22
+ interface QueueBypassResponse {
23
+ status: "ACTIVE";
24
+ token: string;
25
+ expiresAt: number;
26
+ bypass: true;
27
+ }
28
+ type AdmissionMode = "PUBLIC" | "MANAGED" | "TRUSTED";
29
+ interface QueueProtectionResponse {
30
+ eventId: string;
31
+ configured: boolean;
32
+ protected: boolean;
33
+ isActive: boolean;
34
+ isPaused: boolean;
35
+ admissionMode: AdmissionMode;
36
+ challengeRequired: boolean;
37
+ }
38
+ type AdmissionChallengeResponse = {
39
+ required: false;
40
+ } | {
41
+ required: true;
42
+ publicKey: string;
43
+ appearance: "interaction-only";
44
+ };
45
+ type QueueVerifyResponse = {
46
+ valid: true;
47
+ userId: string;
48
+ eventId: string;
49
+ expiresAt: string;
50
+ } | {
51
+ valid: false;
52
+ reason: string;
53
+ };
54
+ declare const CENTRALQ_DEFAULT_API_URL = "http://localhost:3001";
55
+ /** @internal — HTTP client usado internamente por CentralQ */
56
+ declare class QueueHttpClient {
57
+ apiUrl: string;
58
+ private apiKey?;
59
+ private queueInitToken?;
60
+ constructor(apiUrl?: string, apiKey?: string | undefined, queueInitToken?: string | undefined);
61
+ private get headers();
62
+ /**
63
+ * Intenta unir a un usuario a la cola de un evento.
64
+ * Llama a POST /api/queue/:eventId/join en el worker.
65
+ */
66
+ joinQueue(eventId: string, userId: string): Promise<QueueJoinResponse>;
67
+ /**
68
+ * Canjea un código de bypass por un token de acceso activo.
69
+ * El worker descuenta un uso únicamente cuando el canje es exitoso.
70
+ */
71
+ redeemBypassCode(eventId: string, code: string, userId?: string): Promise<QueueBypassResponse>;
72
+ /**
73
+ * Envía un heartbeat para mantener vivo el slot (waiting o active).
74
+ * El SDK lo llama cada 10s automáticamente.
75
+ */
76
+ sendHeartbeat(eventId: string, userId: string): Promise<void>;
77
+ /**
78
+ * Libera el slot del usuario inmediatamente.
79
+ * Llamar al completar la compra o al salir voluntariamente.
80
+ */
81
+ leaveQueue(eventId: string, userId: string): Promise<void>;
82
+ issueQueueInitToken(eventId: string, userId?: string, admissionProof?: string): Promise<QueueInitResponse>;
83
+ getProtection(eventId: string): Promise<QueueProtectionResponse>;
84
+ getAdmissionChallenge(eventId: string): Promise<AdmissionChallengeResponse>;
85
+ verifyToken(eventId: string, token: string): Promise<QueueVerifyResponse>;
86
+ }
87
+
1
88
  interface CentralQOptions {
2
89
  /** URL del queue worker. */
3
90
  apiUrl?: string;
@@ -64,15 +151,22 @@ interface ErrorDetail {
64
151
  userId: string;
65
152
  eventId: string;
66
153
  }
154
+ interface PausedDetail {
155
+ message: string;
156
+ retryAfterSeconds: number;
157
+ userId: string;
158
+ eventId: string;
159
+ }
67
160
  type EventMap = {
68
161
  passed: PassedDetail;
69
162
  expired: ExpiredDetail;
70
163
  position: PositionDetail;
164
+ paused: PausedDetail;
71
165
  error: ErrorDetail;
72
166
  };
73
167
  type EventName = keyof EventMap;
74
168
  type Listener<T> = (detail: T) => void;
75
- type QueueStatus = "idle" | "joining" | "waiting" | "passed" | "expired" | "error";
169
+ type QueueStatus = "idle" | "joining" | "waiting" | "paused" | "passed" | "expired" | "error";
76
170
  declare class CentralQ {
77
171
  private client;
78
172
  private element;
@@ -121,6 +215,7 @@ declare class CentralQ {
121
215
  declare class CentralQClient {
122
216
  private defaults;
123
217
  constructor(defaults: CentralQClientOptions);
218
+ redeemBypassCode(eventId: string, code: string, userId?: string): Promise<QueueBypassResponse>;
124
219
  issueQueueInitToken(eventId: string, userId?: string): Promise<{
125
220
  userId: string;
126
221
  queueInitToken: string;
@@ -131,4 +226,4 @@ declare class CentralQClient {
131
226
  }
132
227
  declare function createCentralQClient(options: CentralQClientOptions): CentralQClient;
133
228
 
134
- export { CentralQ as C, type ErrorDetail as E, type PassedDetail as P, type QueueStatus as Q, CentralQClient as a, type CentralQClientOptions as b, type CentralQCreateOptions as c, type CentralQOptions as d, type ExpiredDetail as e, type PositionDetail as f, createCentralQClient as g };
229
+ export { type AdmissionChallengeResponse as A, CENTRALQ_DEFAULT_API_URL as C, type ErrorDetail as E, type PassedDetail as P, type QueueBypassResponse as Q, type AdmissionMode as a, CentralQ as b, CentralQClient as c, type CentralQClientOptions as d, type CentralQCreateOptions as e, type CentralQOptions as f, type ExpiredDetail as g, type PausedDetail as h, type PositionDetail as i, QueueHttpClient as j, type QueueJoinResponse as k, type QueueProtectionResponse as l, type QueueStatus as m, type QueueVerifyResponse as n, createCentralQClient as o };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  CENTRALQ_DEFAULT_API_URL
3
- } from "./chunk-P73Q2ZIO.mjs";
3
+ } from "./chunk-OR3GGW4J.mjs";
4
4
 
5
5
  // src/server.ts
6
6
  var DEFAULT_TIMEOUT_MS = 5e3;
@@ -38,6 +38,30 @@ var QueueHttpClient = class {
38
38
  }
39
39
  return res.json();
40
40
  }
41
+ /**
42
+ * Canjea un código de bypass por un token de acceso activo.
43
+ * El worker descuenta un uso únicamente cuando el canje es exitoso.
44
+ */
45
+ async redeemBypassCode(eventId, code, userId) {
46
+ const res = await fetch(
47
+ `${this.apiUrl}/api/queue/${encodeURIComponent(eventId)}/bypass`,
48
+ {
49
+ method: "POST",
50
+ headers: this.headers,
51
+ body: JSON.stringify({ code, userId })
52
+ }
53
+ );
54
+ const body = await res.json().catch(() => ({}));
55
+ if (!res.ok) {
56
+ throw new Error(
57
+ body.message ?? `Error ${res.status} al canjear c\xF3digo bypass`
58
+ );
59
+ }
60
+ if (body.status !== "ACTIVE" || !body.token || !body.expiresAt || body.bypass !== true) {
61
+ throw new Error("Respuesta inv\xE1lida al canjear c\xF3digo bypass");
62
+ }
63
+ return body;
64
+ }
41
65
  /**
42
66
  * Envía un heartbeat para mantener vivo el slot (waiting o active).
43
67
  * El SDK lo llama cada 10s automáticamente.
@@ -107,6 +131,7 @@ var QueueHttpClient = class {
107
131
  configured: body.configured === true,
108
132
  protected: body.protected === true,
109
133
  isActive: body.isActive === true,
134
+ isPaused: body.isPaused === true,
110
135
  admissionMode: body.admissionMode ?? "PUBLIC",
111
136
  challengeRequired: body.challengeRequired === true
112
137
  };
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  CENTRALQ_DEFAULT_API_URL,
3
3
  QueueHttpClient
4
- } from "./chunk-P73Q2ZIO.mjs";
4
+ } from "./chunk-OR3GGW4J.mjs";
5
5
 
6
6
  // src/admission.ts
7
7
  var turnstileScript = null;
@@ -171,7 +171,7 @@ var CentralQ = class _CentralQ {
171
171
  }
172
172
  // UI: montar/desmontar el Web Component
173
173
  mount() {
174
- import("./queue-element-DXBW64U2.mjs");
174
+ import("./queue-element-QDDGTF6K.mjs");
175
175
  this.element = document.createElement("central-q");
176
176
  this.element.onRetry = () => {
177
177
  this.updateUI("LOADING");
@@ -266,6 +266,24 @@ var CentralQ = class _CentralQ {
266
266
  this.pollInterval
267
267
  );
268
268
  }
269
+ } else if (res.status === "PAUSED") {
270
+ this.updateUI("PAUSED");
271
+ this.emit("paused", {
272
+ message: res.message,
273
+ retryAfterSeconds: res.retryAfterSeconds,
274
+ userId: this.userId,
275
+ eventId: this.eventId
276
+ });
277
+ if (!this.pollingTimer) {
278
+ const retryInterval = Math.max(
279
+ this.pollInterval,
280
+ res.retryAfterSeconds * 1e3
281
+ );
282
+ this.pollingTimer = setInterval(
283
+ () => this.checkQueue(),
284
+ retryInterval
285
+ );
286
+ }
269
287
  }
270
288
  } catch {
271
289
  this.updateUI("ERROR");
@@ -281,6 +299,13 @@ var CentralQClient = class {
281
299
  constructor(defaults) {
282
300
  this.defaults = defaults;
283
301
  }
302
+ redeemBypassCode(eventId, code, userId) {
303
+ const client = new QueueHttpClient(
304
+ this.defaults.apiUrl,
305
+ this.defaults.apiKey
306
+ );
307
+ return client.redeemBypassCode(eventId, code, userId);
308
+ }
284
309
  issueQueueInitToken(eventId, userId) {
285
310
  const client = new QueueHttpClient(
286
311
  this.defaults.apiUrl,
package/dist/index.d.mts CHANGED
@@ -1,86 +1,15 @@
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-C3ukDo0x.mjs';
1
+ export { A as AdmissionChallengeResponse, a as AdmissionMode, C as CENTRALQ_DEFAULT_API_URL, b as CentralQ, c as CentralQClient, d as CentralQClientOptions, e as CentralQCreateOptions, f as CentralQOptions, E as ErrorDetail, g as ExpiredDetail, P as PassedDetail, h as PausedDetail, i as PositionDetail, Q as QueueBypassResponse, j as QueueHttpClient, k as QueueJoinResponse, l as QueueProtectionResponse, m as QueueStatus, n as QueueVerifyResponse, o as createCentralQClient } from './centralq-CCw_Cqam.mjs';
2
2
  export { CentralQServerClient, CentralQServerClientOptions, CentralQServerRequestError, CentralQServerRequestErrorCode, CompleteQueueAccessServerOptions, QueueAccessCompletionResult, QueueAccessValidationResult, QueueTokenValidationResult, ValidateQueueTokenServerOptions, VerifyQueueAccessServerOptions, completeQueueAccessServer, createCentralQServerClient, validateQueueTokenServer, verifyQueueAccessServer } from './server.mjs';
3
3
  import * as lit from 'lit';
4
4
  import { LitElement } from 'lit';
5
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
- type AdmissionMode = "PUBLIC" | "MANAGED" | "TRUSTED";
24
- interface QueueProtectionResponse {
25
- eventId: string;
26
- configured: boolean;
27
- protected: boolean;
28
- isActive: boolean;
29
- admissionMode: AdmissionMode;
30
- challengeRequired: boolean;
31
- }
32
- type AdmissionChallengeResponse = {
33
- required: false;
34
- } | {
35
- required: true;
36
- publicKey: string;
37
- appearance: "interaction-only";
38
- };
39
- type QueueVerifyResponse = {
40
- valid: true;
41
- userId: string;
42
- eventId: string;
43
- expiresAt: string;
44
- } | {
45
- valid: false;
46
- reason: string;
47
- };
48
- declare const CENTRALQ_DEFAULT_API_URL = "http://localhost:3001";
49
- /** @internal — HTTP client usado internamente por CentralQ */
50
- declare class QueueHttpClient {
51
- apiUrl: string;
52
- private apiKey?;
53
- private queueInitToken?;
54
- constructor(apiUrl?: string, apiKey?: string | undefined, queueInitToken?: string | undefined);
55
- private get headers();
56
- /**
57
- * Intenta unir a un usuario a la cola de un evento.
58
- * Llama a POST /api/queue/:eventId/join en el worker.
59
- */
60
- joinQueue(eventId: string, userId: string): Promise<QueueJoinResponse>;
61
- /**
62
- * Envía un heartbeat para mantener vivo el slot (waiting o active).
63
- * El SDK lo llama cada 10s automáticamente.
64
- */
65
- sendHeartbeat(eventId: string, userId: string): Promise<void>;
66
- /**
67
- * Libera el slot del usuario inmediatamente.
68
- * Llamar al completar la compra o al salir voluntariamente.
69
- */
70
- leaveQueue(eventId: string, userId: string): Promise<void>;
71
- issueQueueInitToken(eventId: string, userId?: string, admissionProof?: string): Promise<QueueInitResponse>;
72
- getProtection(eventId: string): Promise<QueueProtectionResponse>;
73
- getAdmissionChallenge(eventId: string): Promise<AdmissionChallengeResponse>;
74
- verifyToken(eventId: string, token: string): Promise<QueueVerifyResponse>;
75
- }
76
-
77
6
  /**
78
7
  * <central-q> — Web Component de UI puro (internal).
79
8
  * Solo renderiza el overlay de la fila. Toda la lógica la maneja CentralQ.
80
9
  * No usar directamente — instanciar CentralQ en su lugar.
81
10
  */
82
11
  declare class CentralQElement extends LitElement {
83
- status: "LOADING" | "WAITING" | "ACTIVE" | "EXPIRED" | "ERROR";
12
+ status: "LOADING" | "WAITING" | "PAUSED" | "ACTIVE" | "EXPIRED" | "ERROR";
84
13
  position: number;
85
14
  ahead: number;
86
15
  /** Callback que CentralQ inyecta para manejar "Volver a la fila" */
@@ -89,4 +18,4 @@ declare class CentralQElement extends LitElement {
89
18
  render(): lit.TemplateResult<1>;
90
19
  }
91
20
 
92
- export { type AdmissionChallengeResponse, type AdmissionMode, CENTRALQ_DEFAULT_API_URL, CentralQElement, QueueHttpClient, type QueueJoinResponse, type QueueProtectionResponse, type QueueVerifyResponse };
21
+ export { CentralQElement };
package/dist/index.d.ts CHANGED
@@ -1,86 +1,15 @@
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-C3ukDo0x.js';
1
+ export { A as AdmissionChallengeResponse, a as AdmissionMode, C as CENTRALQ_DEFAULT_API_URL, b as CentralQ, c as CentralQClient, d as CentralQClientOptions, e as CentralQCreateOptions, f as CentralQOptions, E as ErrorDetail, g as ExpiredDetail, P as PassedDetail, h as PausedDetail, i as PositionDetail, Q as QueueBypassResponse, j as QueueHttpClient, k as QueueJoinResponse, l as QueueProtectionResponse, m as QueueStatus, n as QueueVerifyResponse, o as createCentralQClient } from './centralq-CCw_Cqam.js';
2
2
  export { CentralQServerClient, CentralQServerClientOptions, CentralQServerRequestError, CentralQServerRequestErrorCode, CompleteQueueAccessServerOptions, QueueAccessCompletionResult, QueueAccessValidationResult, QueueTokenValidationResult, ValidateQueueTokenServerOptions, VerifyQueueAccessServerOptions, completeQueueAccessServer, createCentralQServerClient, validateQueueTokenServer, verifyQueueAccessServer } from './server.js';
3
3
  import * as lit from 'lit';
4
4
  import { LitElement } from 'lit';
5
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
- type AdmissionMode = "PUBLIC" | "MANAGED" | "TRUSTED";
24
- interface QueueProtectionResponse {
25
- eventId: string;
26
- configured: boolean;
27
- protected: boolean;
28
- isActive: boolean;
29
- admissionMode: AdmissionMode;
30
- challengeRequired: boolean;
31
- }
32
- type AdmissionChallengeResponse = {
33
- required: false;
34
- } | {
35
- required: true;
36
- publicKey: string;
37
- appearance: "interaction-only";
38
- };
39
- type QueueVerifyResponse = {
40
- valid: true;
41
- userId: string;
42
- eventId: string;
43
- expiresAt: string;
44
- } | {
45
- valid: false;
46
- reason: string;
47
- };
48
- declare const CENTRALQ_DEFAULT_API_URL = "http://localhost:3001";
49
- /** @internal — HTTP client usado internamente por CentralQ */
50
- declare class QueueHttpClient {
51
- apiUrl: string;
52
- private apiKey?;
53
- private queueInitToken?;
54
- constructor(apiUrl?: string, apiKey?: string | undefined, queueInitToken?: string | undefined);
55
- private get headers();
56
- /**
57
- * Intenta unir a un usuario a la cola de un evento.
58
- * Llama a POST /api/queue/:eventId/join en el worker.
59
- */
60
- joinQueue(eventId: string, userId: string): Promise<QueueJoinResponse>;
61
- /**
62
- * Envía un heartbeat para mantener vivo el slot (waiting o active).
63
- * El SDK lo llama cada 10s automáticamente.
64
- */
65
- sendHeartbeat(eventId: string, userId: string): Promise<void>;
66
- /**
67
- * Libera el slot del usuario inmediatamente.
68
- * Llamar al completar la compra o al salir voluntariamente.
69
- */
70
- leaveQueue(eventId: string, userId: string): Promise<void>;
71
- issueQueueInitToken(eventId: string, userId?: string, admissionProof?: string): Promise<QueueInitResponse>;
72
- getProtection(eventId: string): Promise<QueueProtectionResponse>;
73
- getAdmissionChallenge(eventId: string): Promise<AdmissionChallengeResponse>;
74
- verifyToken(eventId: string, token: string): Promise<QueueVerifyResponse>;
75
- }
76
-
77
6
  /**
78
7
  * <central-q> — Web Component de UI puro (internal).
79
8
  * Solo renderiza el overlay de la fila. Toda la lógica la maneja CentralQ.
80
9
  * No usar directamente — instanciar CentralQ en su lugar.
81
10
  */
82
11
  declare class CentralQElement extends LitElement {
83
- status: "LOADING" | "WAITING" | "ACTIVE" | "EXPIRED" | "ERROR";
12
+ status: "LOADING" | "WAITING" | "PAUSED" | "ACTIVE" | "EXPIRED" | "ERROR";
84
13
  position: number;
85
14
  ahead: number;
86
15
  /** Callback que CentralQ inyecta para manejar "Volver a la fila" */
@@ -89,4 +18,4 @@ declare class CentralQElement extends LitElement {
89
18
  render(): lit.TemplateResult<1>;
90
19
  }
91
20
 
92
- export { type AdmissionChallengeResponse, type AdmissionMode, CENTRALQ_DEFAULT_API_URL, CentralQElement, QueueHttpClient, type QueueJoinResponse, type QueueProtectionResponse, type QueueVerifyResponse };
21
+ export { CentralQElement };
package/dist/index.js CHANGED
@@ -68,6 +68,11 @@ var init_queue_element = __esm({
68
68
  Por favor, no cierres esta ventana.
69
69
  </p>
70
70
  ` : ""}
71
+ ${this.status === "PAUSED" ? import_lit.html`
72
+ <h2>La fila está temporalmente cerrada</h2>
73
+ <p>Volveremos a intentar automáticamente.</p>
74
+ <div class="spinner"></div>
75
+ ` : ""}
71
76
  ${this.status === "EXPIRED" ? import_lit.html`
72
77
  <h2 style="color: #f59e0b;">Tu sesión ha expirado</h2>
73
78
  <p>El tiempo para completar la compra terminó.</p>
@@ -200,6 +205,30 @@ var QueueHttpClient = class {
200
205
  }
201
206
  return res.json();
202
207
  }
208
+ /**
209
+ * Canjea un código de bypass por un token de acceso activo.
210
+ * El worker descuenta un uso únicamente cuando el canje es exitoso.
211
+ */
212
+ async redeemBypassCode(eventId, code, userId) {
213
+ const res = await fetch(
214
+ `${this.apiUrl}/api/queue/${encodeURIComponent(eventId)}/bypass`,
215
+ {
216
+ method: "POST",
217
+ headers: this.headers,
218
+ body: JSON.stringify({ code, userId })
219
+ }
220
+ );
221
+ const body = await res.json().catch(() => ({}));
222
+ if (!res.ok) {
223
+ throw new Error(
224
+ body.message ?? `Error ${res.status} al canjear c\xF3digo bypass`
225
+ );
226
+ }
227
+ if (body.status !== "ACTIVE" || !body.token || !body.expiresAt || body.bypass !== true) {
228
+ throw new Error("Respuesta inv\xE1lida al canjear c\xF3digo bypass");
229
+ }
230
+ return body;
231
+ }
203
232
  /**
204
233
  * Envía un heartbeat para mantener vivo el slot (waiting o active).
205
234
  * El SDK lo llama cada 10s automáticamente.
@@ -269,6 +298,7 @@ var QueueHttpClient = class {
269
298
  configured: body.configured === true,
270
299
  protected: body.protected === true,
271
300
  isActive: body.isActive === true,
301
+ isPaused: body.isPaused === true,
272
302
  admissionMode: body.admissionMode ?? "PUBLIC",
273
303
  challengeRequired: body.challengeRequired === true
274
304
  };
@@ -586,6 +616,24 @@ var CentralQ = class _CentralQ {
586
616
  this.pollInterval
587
617
  );
588
618
  }
619
+ } else if (res.status === "PAUSED") {
620
+ this.updateUI("PAUSED");
621
+ this.emit("paused", {
622
+ message: res.message,
623
+ retryAfterSeconds: res.retryAfterSeconds,
624
+ userId: this.userId,
625
+ eventId: this.eventId
626
+ });
627
+ if (!this.pollingTimer) {
628
+ const retryInterval = Math.max(
629
+ this.pollInterval,
630
+ res.retryAfterSeconds * 1e3
631
+ );
632
+ this.pollingTimer = setInterval(
633
+ () => this.checkQueue(),
634
+ retryInterval
635
+ );
636
+ }
589
637
  }
590
638
  } catch {
591
639
  this.updateUI("ERROR");
@@ -601,6 +649,13 @@ var CentralQClient = class {
601
649
  constructor(defaults) {
602
650
  this.defaults = defaults;
603
651
  }
652
+ redeemBypassCode(eventId, code, userId) {
653
+ const client = new QueueHttpClient(
654
+ this.defaults.apiUrl,
655
+ this.defaults.apiKey
656
+ );
657
+ return client.redeemBypassCode(eventId, code, userId);
658
+ }
604
659
  issueQueueInitToken(eventId, userId) {
605
660
  const client = new QueueHttpClient(
606
661
  this.defaults.apiUrl,
package/dist/index.mjs CHANGED
@@ -5,16 +5,16 @@ import {
5
5
  createCentralQServerClient,
6
6
  validateQueueTokenServer,
7
7
  verifyQueueAccessServer
8
- } from "./chunk-FAJWYFUK.mjs";
8
+ } from "./chunk-CFWLZCAR.mjs";
9
9
  import {
10
10
  CentralQ,
11
11
  CentralQClient,
12
12
  createCentralQClient
13
- } from "./chunk-BVCZFNM3.mjs";
13
+ } from "./chunk-OVV3CIZZ.mjs";
14
14
  import {
15
15
  CENTRALQ_DEFAULT_API_URL,
16
16
  QueueHttpClient
17
- } from "./chunk-P73Q2ZIO.mjs";
17
+ } from "./chunk-OR3GGW4J.mjs";
18
18
  import "./chunk-XRJFNASX.mjs";
19
19
  export {
20
20
  CENTRALQ_DEFAULT_API_URL,
@@ -34,6 +34,11 @@ var CentralQElement = class extends LitElement {
34
34
  Por favor, no cierres esta ventana.
35
35
  </p>
36
36
  ` : ""}
37
+ ${this.status === "PAUSED" ? html`
38
+ <h2>La fila está temporalmente cerrada</h2>
39
+ <p>Volveremos a intentar automáticamente.</p>
40
+ <div class="spinner"></div>
41
+ ` : ""}
37
42
  ${this.status === "EXPIRED" ? html`
38
43
  <h2 style="color: #f59e0b;">Tu sesión ha expirado</h2>
39
44
  <p>El tiempo para completar la compra terminó.</p>