tina4-nodejs 3.10.76 → 3.10.83
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/CLAUDE.md +1 -1
- package/package.json +1 -1
- package/packages/core/src/auth.ts +0 -11
- package/packages/core/src/index.ts +4 -1
- package/packages/core/src/job.ts +86 -0
- package/packages/core/src/queue.ts +60 -463
- package/packages/core/src/queueBackends/liteBackend.ts +369 -0
- package/packages/core/src/websocket.ts +81 -0
- package/packages/orm/src/baseModel.ts +84 -6
package/CLAUDE.md
CHANGED
|
@@ -121,7 +121,7 @@ The HTTP foundation. Handles request/response lifecycle, route matching, middlew
|
|
|
121
121
|
- `auth.ts` — Authentication helpers
|
|
122
122
|
- `cache.ts` — In-memory caching
|
|
123
123
|
- `session.ts` — Session management with pluggable handlers. `TINA4_SESSION_SAMESITE` env var (default: Lax)
|
|
124
|
-
- `websocket.ts` — WebSocket support with backplane for scaling via Redis pub/sub (`TINA4_WS_BACKPLANE`, `TINA4_WS_BACKPLANE_URL`)
|
|
124
|
+
- `websocket.ts` — WebSocket support with backplane for scaling via Redis pub/sub (`TINA4_WS_BACKPLANE`, `TINA4_WS_BACKPLANE_URL`). Rooms API: `wss.joinRoom(clientId, room)`, `wss.leaveRoom(clientId, room)`, `wss.broadcastToRoom(room, msg, excludeIds?)`, `wss.getRoomConnections(room)`, `wss.roomCount(room)`, `wss.getClientRooms(clientId)`
|
|
125
125
|
- `queue.ts` — Queue system with pluggable backends
|
|
126
126
|
- `graphql.ts` — GraphQL engine
|
|
127
127
|
- `i18n.ts` — Internationalization / localization
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tina4-nodejs",
|
|
3
|
-
"version": "3.10.
|
|
3
|
+
"version": "3.10.83",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Tina4 for Node.js/TypeScript — 54 built-in features, zero dependencies",
|
|
6
6
|
"keywords": ["tina4", "framework", "web", "api", "orm", "graphql", "websocket", "typescript"],
|
|
@@ -287,14 +287,6 @@ export function authenticateRequest(
|
|
|
287
287
|
return null;
|
|
288
288
|
}
|
|
289
289
|
|
|
290
|
-
// ── Backward-Compatible Aliases ──────────────────────────────────
|
|
291
|
-
|
|
292
|
-
/** Alias for getToken() — kept for backward compatibility. */
|
|
293
|
-
export const createToken = getToken;
|
|
294
|
-
|
|
295
|
-
/** Alias for validToken() — kept for backward compatibility. */
|
|
296
|
-
export const validateToken = validToken;
|
|
297
|
-
|
|
298
290
|
// ── API Key Validation ───────────────────────────────────────────
|
|
299
291
|
|
|
300
292
|
/**
|
|
@@ -341,7 +333,4 @@ export class Auth {
|
|
|
341
333
|
static refreshToken = refreshToken;
|
|
342
334
|
static authenticateRequest = authenticateRequest;
|
|
343
335
|
static validateApiKey = validateApiKey;
|
|
344
|
-
// Legacy aliases
|
|
345
|
-
static createToken = getToken;
|
|
346
|
-
static validateToken = validToken;
|
|
347
336
|
}
|
|
@@ -38,7 +38,7 @@ export {
|
|
|
38
38
|
APPLICATION_OCTET, TEXT_HTML, TEXT_PLAIN, TEXT_CSV, TEXT_XML,
|
|
39
39
|
} from "./constants.js";
|
|
40
40
|
export {
|
|
41
|
-
getToken, validToken,
|
|
41
|
+
getToken, validToken, getPayload,
|
|
42
42
|
hashPassword, checkPassword,
|
|
43
43
|
authMiddleware,
|
|
44
44
|
refreshToken, authenticateRequest, validateApiKey,
|
|
@@ -52,6 +52,8 @@ export { ScssCompiler } from "./scss.js";
|
|
|
52
52
|
export type { ScssConfig } from "./scss.js";
|
|
53
53
|
export { Queue } from "./queue.js";
|
|
54
54
|
export type { QueueConfig, QueueJob, ProcessOptions } from "./queue.js";
|
|
55
|
+
export { createJob } from "./job.js";
|
|
56
|
+
export type { JobData, JobQueueBridge } from "./job.js";
|
|
55
57
|
export { GraphQL, ParseError } from "./graphql.js";
|
|
56
58
|
export type { GraphQLField, ResolverFn, GraphQLResult } from "./graphql.js";
|
|
57
59
|
export {
|
|
@@ -79,6 +81,7 @@ export { renderErrorOverlay, renderProductionError, isDebugMode } from "./errorO
|
|
|
79
81
|
export { AI_TOOLS, isInstalled, showMenu, installSelected, installAll, generateContext } from "./ai.js";
|
|
80
82
|
export type { AiTool } from "./ai.js";
|
|
81
83
|
export type { ImapMessage, ImapFullMessage } from "./messenger.js";
|
|
84
|
+
export { LiteBackend } from "./queueBackends/liteBackend.js";
|
|
82
85
|
export { RabbitMQBackend } from "./queueBackends/rabbitmqBackend.js";
|
|
83
86
|
export type { RabbitMQConfig } from "./queueBackends/rabbitmqBackend.js";
|
|
84
87
|
export { KafkaBackend } from "./queueBackends/kafkaBackend.js";
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tina4 Queue Job — a single queue job with lifecycle methods.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
// ── Types ────────────────────────────────────────────────────
|
|
6
|
+
|
|
7
|
+
export interface JobData {
|
|
8
|
+
id: string;
|
|
9
|
+
payload: unknown;
|
|
10
|
+
status: "pending" | "reserved" | "failed" | "dead" | "completed";
|
|
11
|
+
createdAt: string;
|
|
12
|
+
attempts: number;
|
|
13
|
+
delayUntil: string | null;
|
|
14
|
+
priority: number;
|
|
15
|
+
topic: string;
|
|
16
|
+
error?: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface JobLifecycle {
|
|
20
|
+
/** Mark this job as completed. */
|
|
21
|
+
complete(): void;
|
|
22
|
+
/** Mark this job as failed with a reason. */
|
|
23
|
+
fail(reason?: string): void;
|
|
24
|
+
/** Reject this job with a reason. Alias for fail(). */
|
|
25
|
+
reject(reason?: string): void;
|
|
26
|
+
/** Re-queue this job with incremented attempts and optional delay. */
|
|
27
|
+
retry(delaySeconds?: number): void;
|
|
28
|
+
/** Return job fields as a flat array of values. */
|
|
29
|
+
toArray(): unknown[];
|
|
30
|
+
/** Return job as a plain object. */
|
|
31
|
+
toHash(): Record<string, unknown>;
|
|
32
|
+
/** Return job as a JSON string. */
|
|
33
|
+
toJson(): string;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export type QueueJob = JobData & JobLifecycle;
|
|
37
|
+
|
|
38
|
+
// ── Job factory ──────────────────────────────────────────────
|
|
39
|
+
|
|
40
|
+
export interface JobQueueBridge {
|
|
41
|
+
_failJob(topic: string, job: QueueJob, reason: string, maxRetries: number): void;
|
|
42
|
+
_retryJob(topic: string, job: QueueJob, delaySeconds?: number): void;
|
|
43
|
+
getMaxRetries(): number;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** Create a QueueJob with lifecycle methods bound to a Queue instance. */
|
|
47
|
+
export function createJob(data: JobData, queue: JobQueueBridge): QueueJob {
|
|
48
|
+
const job: QueueJob = {
|
|
49
|
+
...data,
|
|
50
|
+
complete() {
|
|
51
|
+
job.status = "completed";
|
|
52
|
+
},
|
|
53
|
+
fail(reason = "") {
|
|
54
|
+
job.status = "failed";
|
|
55
|
+
job.error = reason;
|
|
56
|
+
job.attempts = (job.attempts || 0) + 1;
|
|
57
|
+
queue._failJob(job.topic, job, reason, queue.getMaxRetries());
|
|
58
|
+
},
|
|
59
|
+
reject(reason = "") {
|
|
60
|
+
job.fail(reason);
|
|
61
|
+
},
|
|
62
|
+
retry(delaySeconds?: number) {
|
|
63
|
+
queue._retryJob(job.topic, job, delaySeconds);
|
|
64
|
+
},
|
|
65
|
+
toArray() {
|
|
66
|
+
return [job.id, job.topic, job.payload, job.priority, job.attempts];
|
|
67
|
+
},
|
|
68
|
+
toHash() {
|
|
69
|
+
return {
|
|
70
|
+
id: job.id,
|
|
71
|
+
topic: job.topic,
|
|
72
|
+
payload: job.payload,
|
|
73
|
+
priority: job.priority,
|
|
74
|
+
attempts: job.attempts,
|
|
75
|
+
status: job.status,
|
|
76
|
+
createdAt: job.createdAt,
|
|
77
|
+
delayUntil: job.delayUntil,
|
|
78
|
+
error: job.error,
|
|
79
|
+
};
|
|
80
|
+
},
|
|
81
|
+
toJson() {
|
|
82
|
+
return JSON.stringify(job.toHash());
|
|
83
|
+
},
|
|
84
|
+
};
|
|
85
|
+
return job;
|
|
86
|
+
}
|