@central-ticket/queue-sdk 0.0.2 → 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-CFWLZCAR.mjs +115 -0
- 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 +4 -75
- package/dist/index.d.ts +4 -75
- package/dist/index.js +163 -19
- package/dist/index.mjs +15 -5
- 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.d.mts +82 -2
- package/dist/server.d.ts +82 -2
- package/dist/server.js +108 -19
- package/dist/server.mjs +14 -4
- 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-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 };
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CENTRALQ_DEFAULT_API_URL
|
|
3
|
+
} from "./chunk-OR3GGW4J.mjs";
|
|
4
|
+
|
|
5
|
+
// src/server.ts
|
|
6
|
+
var DEFAULT_TIMEOUT_MS = 5e3;
|
|
7
|
+
var CentralQServerRequestError = class extends Error {
|
|
8
|
+
constructor(code, message, options) {
|
|
9
|
+
super(message, options);
|
|
10
|
+
this.name = "CentralQServerRequestError";
|
|
11
|
+
this.code = code;
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
function normalizeApiUrl(apiUrl) {
|
|
15
|
+
const trimmed = apiUrl.trim().replace(/\/+$/, "");
|
|
16
|
+
return trimmed.endsWith("/api") ? trimmed.slice(0, -4) : trimmed;
|
|
17
|
+
}
|
|
18
|
+
function validateOptions(options) {
|
|
19
|
+
if (!options.secretKey?.trim()) {
|
|
20
|
+
throw new TypeError("CentralQ secretKey es requerida");
|
|
21
|
+
}
|
|
22
|
+
if (options.timeoutMs !== void 0 && options.timeoutMs <= 0) {
|
|
23
|
+
throw new TypeError("CentralQ timeoutMs debe ser mayor a cero");
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
var CentralQServerClient = class {
|
|
27
|
+
constructor(options) {
|
|
28
|
+
validateOptions(options);
|
|
29
|
+
this.apiUrl = normalizeApiUrl(options.apiUrl ?? CENTRALQ_DEFAULT_API_URL);
|
|
30
|
+
this.secretKey = options.secretKey.trim();
|
|
31
|
+
this.timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
32
|
+
this.fetchFn = options.fetch ?? globalThis.fetch;
|
|
33
|
+
}
|
|
34
|
+
validateToken(input) {
|
|
35
|
+
return this.post(
|
|
36
|
+
`/api/queue/verify/${encodeURIComponent(input.eventId)}`,
|
|
37
|
+
{ token: input.token },
|
|
38
|
+
{ valid: false, reason: "Respuesta inv\xE1lida" }
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
verifyAccess(input) {
|
|
42
|
+
return this.post(
|
|
43
|
+
`/api/queue/verify/${encodeURIComponent(input.eventId)}/access`,
|
|
44
|
+
{ token: input.token ?? null },
|
|
45
|
+
{
|
|
46
|
+
allowed: false,
|
|
47
|
+
reason: "invalid_response",
|
|
48
|
+
message: "Respuesta inv\xE1lida"
|
|
49
|
+
}
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
completeAccess(input) {
|
|
53
|
+
return this.post(
|
|
54
|
+
`/api/queue/verify/${encodeURIComponent(input.eventId)}/complete`,
|
|
55
|
+
{
|
|
56
|
+
token: input.token,
|
|
57
|
+
completionId: input.completionId
|
|
58
|
+
},
|
|
59
|
+
{ completed: false, reason: "invalid_response" }
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
async post(path, body, fallback) {
|
|
63
|
+
const controller = new AbortController();
|
|
64
|
+
const timeout = setTimeout(() => controller.abort(), this.timeoutMs);
|
|
65
|
+
try {
|
|
66
|
+
const response = await this.fetchFn(`${this.apiUrl}${path}`, {
|
|
67
|
+
method: "POST",
|
|
68
|
+
headers: {
|
|
69
|
+
"Content-Type": "application/json",
|
|
70
|
+
"x-api-key": this.secretKey
|
|
71
|
+
},
|
|
72
|
+
body: JSON.stringify(body),
|
|
73
|
+
signal: controller.signal
|
|
74
|
+
});
|
|
75
|
+
const data = await response.json().catch(() => fallback);
|
|
76
|
+
return { status: response.status, data };
|
|
77
|
+
} catch (error) {
|
|
78
|
+
if (controller.signal.aborted) {
|
|
79
|
+
throw new CentralQServerRequestError(
|
|
80
|
+
"timeout",
|
|
81
|
+
`CentralQ no respondi\xF3 en ${this.timeoutMs}ms`,
|
|
82
|
+
{ cause: error }
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
throw new CentralQServerRequestError(
|
|
86
|
+
"network_error",
|
|
87
|
+
"No se pudo conectar con CentralQ",
|
|
88
|
+
{ cause: error }
|
|
89
|
+
);
|
|
90
|
+
} finally {
|
|
91
|
+
clearTimeout(timeout);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
function createCentralQServerClient(options) {
|
|
96
|
+
return new CentralQServerClient(options);
|
|
97
|
+
}
|
|
98
|
+
function validateQueueTokenServer(options) {
|
|
99
|
+
return createCentralQServerClient(options).validateToken(options);
|
|
100
|
+
}
|
|
101
|
+
function verifyQueueAccessServer(options) {
|
|
102
|
+
return createCentralQServerClient(options).verifyAccess(options);
|
|
103
|
+
}
|
|
104
|
+
function completeQueueAccessServer(options) {
|
|
105
|
+
return createCentralQServerClient(options).completeAccess(options);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export {
|
|
109
|
+
CentralQServerRequestError,
|
|
110
|
+
CentralQServerClient,
|
|
111
|
+
createCentralQServerClient,
|
|
112
|
+
validateQueueTokenServer,
|
|
113
|
+
verifyQueueAccessServer,
|
|
114
|
+
completeQueueAccessServer
|
|
115
|
+
};
|
|
@@ -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,
|
|
2
|
-
export { QueueTokenValidationResult, ValidateQueueTokenServerOptions, validateQueueTokenServer } from './server.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
|
+
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,
|
|
2
|
-
export { QueueTokenValidationResult, ValidateQueueTokenServerOptions, validateQueueTokenServer } from './server.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
|
+
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 };
|