@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.
- package/dist/{centralq-C3ukDo0x.d.mts → centralq-CCw_Cqam.d.mts} +97 -2
- package/dist/{centralq-C3ukDo0x.d.ts → centralq-CCw_Cqam.d.ts} +97 -2
- package/dist/{chunk-FAJWYFUK.mjs → chunk-CFWLZCAR.mjs} +1 -1
- package/dist/{chunk-P73Q2ZIO.mjs → chunk-OR3GGW4J.mjs} +25 -0
- package/dist/{chunk-BVCZFNM3.mjs → chunk-OVV3CIZZ.mjs} +27 -2
- package/dist/index.d.mts +3 -74
- package/dist/index.d.ts +3 -74
- package/dist/index.js +55 -0
- package/dist/index.mjs +3 -3
- package/dist/{queue-element-DXBW64U2.mjs → queue-element-QDDGTF6K.mjs} +5 -0
- package/dist/react.d.mts +3 -1
- package/dist/react.d.ts +3 -1
- package/dist/react.js +70 -0
- package/dist/react.mjs +24 -2
- package/dist/server.mjs +2 -2
- package/dist/svelte.d.mts +1 -1
- package/dist/svelte.d.ts +1 -1
- package/dist/svelte.js +64 -0
- package/dist/svelte.mjs +18 -2
- package/dist/vue.d.mts +1 -1
- package/dist/vue.d.ts +1 -1
- package/dist/vue.js +9 -0
- package/dist/vue.mjs +9 -0
- package/package.json +2 -2
- package/dist/centralq-I9tdL_Xr.d.mts +0 -133
- package/dist/centralq-I9tdL_Xr.d.ts +0 -133
- package/dist/chunk-4MXU7S6A.mjs +0 -235
- package/dist/chunk-A37B25XO.mjs +0 -126
- package/dist/chunk-CURBGL7P.mjs +0 -63
- package/dist/chunk-GWPLLJTU.mjs +0 -31
- package/dist/chunk-JJ33EJ65.mjs +0 -31
- package/dist/chunk-XIQ6LS62.mjs +0 -312
|
@@ -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 {
|
|
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 {
|
|
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 };
|
|
@@ -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-
|
|
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-
|
|
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,
|
|
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 {
|
|
21
|
+
export { CentralQElement };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,86 +1,15 @@
|
|
|
1
|
-
export { C as CentralQ,
|
|
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 {
|
|
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-
|
|
8
|
+
} from "./chunk-CFWLZCAR.mjs";
|
|
9
9
|
import {
|
|
10
10
|
CentralQ,
|
|
11
11
|
CentralQClient,
|
|
12
12
|
createCentralQClient
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-OVV3CIZZ.mjs";
|
|
14
14
|
import {
|
|
15
15
|
CENTRALQ_DEFAULT_API_URL,
|
|
16
16
|
QueueHttpClient
|
|
17
|
-
} from "./chunk-
|
|
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>
|