alepha 0.13.8 → 0.14.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/audits/index.d.ts +418 -338
- package/dist/api/audits/index.d.ts.map +1 -0
- package/dist/api/files/index.d.ts +81 -1
- package/dist/api/files/index.d.ts.map +1 -0
- package/dist/api/jobs/index.d.ts +107 -27
- package/dist/api/jobs/index.d.ts.map +1 -0
- package/dist/api/notifications/index.d.ts +21 -1
- package/dist/api/notifications/index.d.ts.map +1 -0
- package/dist/api/parameters/index.d.ts +455 -8
- package/dist/api/parameters/index.d.ts.map +1 -0
- package/dist/api/users/index.d.ts +844 -840
- package/dist/api/users/index.d.ts.map +1 -0
- package/dist/api/verifications/index.d.ts.map +1 -0
- package/dist/batch/index.d.ts.map +1 -0
- package/dist/bucket/index.d.ts.map +1 -0
- package/dist/cache/core/index.d.ts.map +1 -0
- package/dist/cache/redis/index.d.ts.map +1 -0
- package/dist/cli/index.d.ts +254 -59
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +499 -127
- package/dist/cli/index.js.map +1 -1
- package/dist/command/index.d.ts +217 -10
- package/dist/command/index.d.ts.map +1 -0
- package/dist/command/index.js +350 -74
- package/dist/command/index.js.map +1 -1
- package/dist/core/index.browser.js +1334 -1318
- package/dist/core/index.browser.js.map +1 -1
- package/dist/core/index.d.ts +76 -72
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +1337 -1321
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.native.js +1337 -1321
- package/dist/core/index.native.js.map +1 -1
- package/dist/datetime/index.d.ts.map +1 -0
- package/dist/email/index.d.ts.map +1 -0
- package/dist/fake/index.d.ts.map +1 -0
- package/dist/file/index.d.ts.map +1 -0
- package/dist/file/index.js.map +1 -1
- package/dist/lock/core/index.d.ts.map +1 -0
- package/dist/lock/redis/index.d.ts.map +1 -0
- package/dist/logger/index.d.ts +1 -0
- package/dist/logger/index.d.ts.map +1 -0
- package/dist/mcp/index.d.ts +820 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +978 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/orm/index.d.ts +234 -107
- package/dist/orm/index.d.ts.map +1 -0
- package/dist/orm/index.js +376 -316
- package/dist/orm/index.js.map +1 -1
- package/dist/queue/core/index.d.ts +4 -4
- package/dist/queue/core/index.d.ts.map +1 -0
- package/dist/queue/redis/index.d.ts.map +1 -0
- package/dist/queue/redis/index.js +2 -4
- package/dist/queue/redis/index.js.map +1 -1
- package/dist/redis/index.d.ts +400 -29
- package/dist/redis/index.d.ts.map +1 -0
- package/dist/redis/index.js +412 -21
- package/dist/redis/index.js.map +1 -1
- package/dist/retry/index.d.ts.map +1 -0
- package/dist/router/index.d.ts.map +1 -0
- package/dist/scheduler/index.d.ts +6 -6
- package/dist/scheduler/index.d.ts.map +1 -0
- package/dist/security/index.d.ts +28 -28
- package/dist/security/index.d.ts.map +1 -0
- package/dist/server/auth/index.d.ts +155 -155
- package/dist/server/auth/index.d.ts.map +1 -0
- package/dist/server/cache/index.d.ts.map +1 -0
- package/dist/server/compress/index.d.ts.map +1 -0
- package/dist/server/cookies/index.d.ts.map +1 -0
- package/dist/server/core/index.d.ts +0 -1
- package/dist/server/core/index.d.ts.map +1 -0
- package/dist/server/core/index.js.map +1 -1
- package/dist/server/cors/index.d.ts.map +1 -0
- package/dist/server/health/index.d.ts +17 -17
- package/dist/server/health/index.d.ts.map +1 -0
- package/dist/server/helmet/index.d.ts +4 -1
- package/dist/server/helmet/index.d.ts.map +1 -0
- package/dist/server/links/index.d.ts +33 -33
- package/dist/server/links/index.d.ts.map +1 -0
- package/dist/server/metrics/index.d.ts.map +1 -0
- package/dist/server/multipart/index.d.ts.map +1 -0
- package/dist/server/multipart/index.js.map +1 -1
- package/dist/server/proxy/index.d.ts.map +1 -0
- package/dist/server/proxy/index.js.map +1 -1
- package/dist/server/rate-limit/index.d.ts.map +1 -0
- package/dist/server/security/index.d.ts +9 -9
- package/dist/server/security/index.d.ts.map +1 -0
- package/dist/server/static/index.d.ts.map +1 -0
- package/dist/server/swagger/index.d.ts.map +1 -0
- package/dist/sms/index.d.ts.map +1 -0
- package/dist/thread/index.d.ts.map +1 -0
- package/dist/topic/core/index.d.ts.map +1 -0
- package/dist/topic/redis/index.d.ts.map +1 -0
- package/dist/topic/redis/index.js +3 -3
- package/dist/topic/redis/index.js.map +1 -1
- package/dist/vite/index.d.ts +10 -2
- package/dist/vite/index.d.ts.map +1 -0
- package/dist/vite/index.js +45 -20
- package/dist/vite/index.js.map +1 -1
- package/dist/websocket/index.d.ts.map +1 -0
- package/package.json +9 -4
- package/src/cli/apps/AlephaCli.ts +10 -3
- package/src/cli/apps/AlephaPackageBuilderCli.ts +15 -8
- package/src/cli/assets/mainTs.ts +9 -10
- package/src/cli/atoms/changelogOptions.ts +45 -0
- package/src/cli/commands/ChangelogCommands.ts +259 -0
- package/src/cli/commands/DeployCommands.ts +118 -0
- package/src/cli/commands/DrizzleCommands.ts +230 -10
- package/src/cli/commands/ViteCommands.ts +47 -23
- package/src/cli/defineConfig.ts +15 -0
- package/src/cli/index.ts +3 -0
- package/src/cli/services/AlephaCliUtils.ts +10 -154
- package/src/cli/services/GitMessageParser.ts +77 -0
- package/src/command/helpers/EnvUtils.ts +37 -0
- package/src/command/index.ts +3 -1
- package/src/command/primitives/$command.ts +172 -6
- package/src/command/providers/CliProvider.ts +499 -95
- package/src/core/Alepha.ts +1 -1
- package/src/core/providers/SchemaValidator.ts +23 -1
- package/src/file/providers/NodeFileSystemProvider.ts +3 -1
- package/src/mcp/errors/McpError.ts +72 -0
- package/src/mcp/helpers/jsonrpc.ts +163 -0
- package/src/mcp/index.ts +132 -0
- package/src/mcp/interfaces/McpTypes.ts +248 -0
- package/src/mcp/primitives/$prompt.ts +188 -0
- package/src/mcp/primitives/$resource.ts +171 -0
- package/src/mcp/primitives/$tool.ts +285 -0
- package/src/mcp/providers/McpServerProvider.ts +382 -0
- package/src/mcp/transports/SseMcpTransport.ts +172 -0
- package/src/mcp/transports/StdioMcpTransport.ts +126 -0
- package/src/orm/index.ts +20 -4
- package/src/orm/interfaces/PgQueryWhere.ts +1 -26
- package/src/orm/providers/drivers/BunPostgresProvider.ts +225 -0
- package/src/orm/providers/drivers/BunSqliteProvider.ts +180 -0
- package/src/orm/providers/drivers/CloudflareD1Provider.ts +164 -0
- package/src/orm/providers/drivers/DatabaseProvider.ts +25 -0
- package/src/orm/providers/drivers/NodePostgresProvider.ts +0 -25
- package/src/orm/providers/drivers/NodeSqliteProvider.ts +3 -1
- package/src/orm/services/QueryManager.ts +10 -125
- package/src/queue/redis/providers/RedisQueueProvider.ts +2 -7
- package/src/redis/index.ts +65 -3
- package/src/redis/providers/BunRedisProvider.ts +304 -0
- package/src/redis/providers/BunRedisSubscriberProvider.ts +94 -0
- package/src/redis/providers/NodeRedisProvider.ts +280 -0
- package/src/redis/providers/NodeRedisSubscriberProvider.ts +94 -0
- package/src/redis/providers/RedisProvider.ts +134 -140
- package/src/redis/providers/RedisSubscriberProvider.ts +58 -49
- package/src/server/core/providers/BunHttpServerProvider.ts +0 -3
- package/src/server/core/providers/ServerBodyParserProvider.ts +3 -1
- package/src/server/core/providers/ServerProvider.ts +7 -4
- package/src/server/multipart/providers/ServerMultipartProvider.ts +3 -1
- package/src/server/proxy/providers/ServerProxyProvider.ts +1 -1
- package/src/topic/redis/providers/RedisTopicProvider.ts +3 -3
- package/src/vite/plugins/viteAlephaBuild.ts +8 -2
- package/src/vite/plugins/viteAlephaDev.ts +6 -2
- package/src/vite/tasks/buildServer.ts +2 -1
- package/src/vite/tasks/generateCloudflare.ts +43 -15
- package/src/vite/tasks/runAlepha.ts +1 -0
- package/src/orm/services/PgJsonQueryManager.ts +0 -511
package/dist/redis/index.js
CHANGED
|
@@ -1,17 +1,304 @@
|
|
|
1
|
-
import { $env, $hook, $inject, $module, Alepha, t } from "alepha";
|
|
2
|
-
import { RESP_TYPES, createClient } from "@redis/client";
|
|
1
|
+
import { $env, $hook, $inject, $module, Alepha, AlephaError, t } from "alepha";
|
|
3
2
|
import { $logger } from "alepha/logger";
|
|
3
|
+
import { RESP_TYPES, createClient } from "@redis/client";
|
|
4
4
|
|
|
5
5
|
//#region ../../src/redis/providers/RedisProvider.ts
|
|
6
|
+
/**
|
|
7
|
+
* Abstract Redis provider interface.
|
|
8
|
+
*
|
|
9
|
+
* This abstract class defines the common interface for Redis operations.
|
|
10
|
+
* Implementations include:
|
|
11
|
+
* - {@link NodeRedisProvider} - Uses `@redis/client` for Node.js runtime
|
|
12
|
+
* - {@link BunRedisProvider} - Uses Bun's native `RedisClient` for Bun runtime
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```ts
|
|
16
|
+
* // Inject the abstract provider - runtime selects the implementation
|
|
17
|
+
* const redis = alepha.inject(RedisProvider);
|
|
18
|
+
*
|
|
19
|
+
* // Use common operations
|
|
20
|
+
* await redis.set("key", "value");
|
|
21
|
+
* const value = await redis.get("key");
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
var RedisProvider = class {};
|
|
25
|
+
|
|
26
|
+
//#endregion
|
|
27
|
+
//#region ../../src/redis/providers/BunRedisProvider.ts
|
|
28
|
+
const envSchema$1 = t.object({
|
|
29
|
+
REDIS_URL: t.optional(t.text()),
|
|
30
|
+
REDIS_PORT: t.integer({ default: "6379" }),
|
|
31
|
+
REDIS_HOST: t.text({ default: "localhost" }),
|
|
32
|
+
REDIS_PASSWORD: t.optional(t.text())
|
|
33
|
+
});
|
|
34
|
+
/**
|
|
35
|
+
* Bun Redis client provider using Bun's native Redis client.
|
|
36
|
+
*
|
|
37
|
+
* This provider uses Bun's built-in `RedisClient` class for Redis connections,
|
|
38
|
+
* which provides excellent performance (7.9x faster than ioredis) on the Bun runtime.
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* ```ts
|
|
42
|
+
* // Set REDIS_URL environment variable
|
|
43
|
+
* // REDIS_URL=redis://localhost:6379
|
|
44
|
+
*
|
|
45
|
+
* // Or configure via REDIS_HOST, REDIS_PORT, REDIS_PASSWORD
|
|
46
|
+
*
|
|
47
|
+
* // Or configure programmatically
|
|
48
|
+
* alepha.with({
|
|
49
|
+
* provide: RedisProvider,
|
|
50
|
+
* use: BunRedisProvider,
|
|
51
|
+
* });
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
54
|
+
var BunRedisProvider = class extends RedisProvider {
|
|
55
|
+
log = $logger();
|
|
56
|
+
alepha = $inject(Alepha);
|
|
57
|
+
env = $env(envSchema$1);
|
|
58
|
+
client;
|
|
59
|
+
get publisher() {
|
|
60
|
+
if (!this.client?.connected) throw new AlephaError("Redis client is not ready");
|
|
61
|
+
return this.client;
|
|
62
|
+
}
|
|
63
|
+
get isReady() {
|
|
64
|
+
return this.client?.connected ?? false;
|
|
65
|
+
}
|
|
66
|
+
start = $hook({
|
|
67
|
+
on: "start",
|
|
68
|
+
handler: () => this.connect()
|
|
69
|
+
});
|
|
70
|
+
stop = $hook({
|
|
71
|
+
on: "stop",
|
|
72
|
+
handler: () => this.close()
|
|
73
|
+
});
|
|
74
|
+
/**
|
|
75
|
+
* Connect to the Redis server.
|
|
76
|
+
*/
|
|
77
|
+
async connect() {
|
|
78
|
+
if (typeof Bun === "undefined") throw new AlephaError("BunRedisProvider requires the Bun runtime. Use NodeRedisProvider for Node.js.");
|
|
79
|
+
this.log.debug("Connecting...");
|
|
80
|
+
const { RedisClient } = await import("bun");
|
|
81
|
+
this.client = new RedisClient(this.getUrl(), {
|
|
82
|
+
autoReconnect: true,
|
|
83
|
+
enableAutoPipelining: true
|
|
84
|
+
});
|
|
85
|
+
this.client.onconnect = () => {
|
|
86
|
+
this.log.trace("Redis connected");
|
|
87
|
+
};
|
|
88
|
+
this.client.onclose = (error) => {
|
|
89
|
+
if (this.alepha.isStarted() && error) this.log.error("Redis connection closed", error);
|
|
90
|
+
};
|
|
91
|
+
await this.client.connect();
|
|
92
|
+
this.log.info("Connection OK");
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Close the connection to the Redis server.
|
|
96
|
+
*/
|
|
97
|
+
async close() {
|
|
98
|
+
if (this.client) {
|
|
99
|
+
this.log.debug("Closing connection...");
|
|
100
|
+
this.client.close();
|
|
101
|
+
this.client = void 0;
|
|
102
|
+
this.log.info("Connection closed");
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Create a duplicate connection for pub/sub or other isolated operations.
|
|
107
|
+
*/
|
|
108
|
+
async duplicate() {
|
|
109
|
+
if (typeof Bun === "undefined") throw new AlephaError("BunRedisProvider requires the Bun runtime.");
|
|
110
|
+
const { RedisClient } = await import("bun");
|
|
111
|
+
const client = new RedisClient(this.getUrl(), {
|
|
112
|
+
autoReconnect: true,
|
|
113
|
+
enableAutoPipelining: true
|
|
114
|
+
});
|
|
115
|
+
client.onclose = (error) => {
|
|
116
|
+
if (this.alepha.isStarted() && error) this.log.error("Redis duplicate connection closed", error);
|
|
117
|
+
};
|
|
118
|
+
await client.connect();
|
|
119
|
+
return client;
|
|
120
|
+
}
|
|
121
|
+
async get(key) {
|
|
122
|
+
this.log.trace(`Getting key ${key}`);
|
|
123
|
+
const resp = await this.publisher.getBuffer(key);
|
|
124
|
+
if (resp === null) return;
|
|
125
|
+
return Buffer.from(resp);
|
|
126
|
+
}
|
|
127
|
+
async set(key, value, options) {
|
|
128
|
+
const buf = Buffer.isBuffer(value) ? value : Buffer.from(value, "utf-8");
|
|
129
|
+
const args = [key, buf.toString("binary")];
|
|
130
|
+
if (options?.expiration) if (options.expiration.type === "KEEPTTL") args.push("KEEPTTL");
|
|
131
|
+
else args.push(options.expiration.type, String(options.expiration.value));
|
|
132
|
+
if (options?.EX !== void 0) args.push("EX", String(options.EX));
|
|
133
|
+
if (options?.PX !== void 0) args.push("PX", String(options.PX));
|
|
134
|
+
if (options?.EXAT !== void 0) args.push("EXAT", String(options.EXAT));
|
|
135
|
+
if (options?.PXAT !== void 0) args.push("PXAT", String(options.PXAT));
|
|
136
|
+
if (options?.KEEPTTL) args.push("KEEPTTL");
|
|
137
|
+
if (options?.condition === "NX") args.push("NX");
|
|
138
|
+
else if (options?.condition === "XX") args.push("XX");
|
|
139
|
+
if (options?.NX) args.push("NX");
|
|
140
|
+
if (options?.XX) args.push("XX");
|
|
141
|
+
if (options?.GET) args.push("GET");
|
|
142
|
+
if (args.length === 2) await this.publisher.set(key, buf);
|
|
143
|
+
else await this.publisher.send("SET", args);
|
|
144
|
+
return buf;
|
|
145
|
+
}
|
|
146
|
+
async has(key) {
|
|
147
|
+
return this.publisher.exists(key);
|
|
148
|
+
}
|
|
149
|
+
async keys(pattern) {
|
|
150
|
+
const keys = await this.publisher.send("KEYS", [pattern]);
|
|
151
|
+
if (!Array.isArray(keys)) return [];
|
|
152
|
+
return keys.map((key) => key instanceof Uint8Array ? Buffer.from(key).toString() : String(key));
|
|
153
|
+
}
|
|
154
|
+
async del(keys) {
|
|
155
|
+
if (keys.length === 0) return;
|
|
156
|
+
await this.publisher.send("DEL", keys);
|
|
157
|
+
}
|
|
158
|
+
async lpush(key, value) {
|
|
159
|
+
await this.publisher.send("LPUSH", [key, value]);
|
|
160
|
+
}
|
|
161
|
+
async rpop(key) {
|
|
162
|
+
const value = await this.publisher.send("RPOP", [key]);
|
|
163
|
+
if (value == null) return;
|
|
164
|
+
if (value instanceof Uint8Array) return Buffer.from(value).toString();
|
|
165
|
+
return String(value);
|
|
166
|
+
}
|
|
167
|
+
async publish(channel, message) {
|
|
168
|
+
await this.publisher.publish(channel, message);
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Get the Redis connection URL.
|
|
172
|
+
*/
|
|
173
|
+
getUrl() {
|
|
174
|
+
if (this.env.REDIS_URL) return this.env.REDIS_URL;
|
|
175
|
+
const url = new URL("redis://127.0.0.1:6379");
|
|
176
|
+
if (this.env.REDIS_PASSWORD) url.password = this.env.REDIS_PASSWORD;
|
|
177
|
+
if (this.env.REDIS_HOST) url.hostname = this.env.REDIS_HOST;
|
|
178
|
+
if (this.env.REDIS_PORT) url.port = String(this.env.REDIS_PORT);
|
|
179
|
+
return url.toString();
|
|
180
|
+
}
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
//#endregion
|
|
184
|
+
//#region ../../src/redis/providers/RedisSubscriberProvider.ts
|
|
185
|
+
/**
|
|
186
|
+
* Abstract Redis subscriber provider interface.
|
|
187
|
+
*
|
|
188
|
+
* This abstract class defines the common interface for Redis pub/sub subscriptions.
|
|
189
|
+
* Implementations include:
|
|
190
|
+
* - {@link NodeRedisSubscriberProvider} - Uses `@redis/client` for Node.js runtime
|
|
191
|
+
* - {@link BunRedisSubscriberProvider} - Uses Bun's native `RedisClient` for Bun runtime
|
|
192
|
+
*
|
|
193
|
+
* Redis requires separate connections for pub/sub operations, so this provider
|
|
194
|
+
* creates a dedicated connection for subscriptions.
|
|
195
|
+
*
|
|
196
|
+
* @example
|
|
197
|
+
* ```ts
|
|
198
|
+
* // Inject the abstract provider - runtime selects the implementation
|
|
199
|
+
* const subscriber = alepha.inject(RedisSubscriberProvider);
|
|
200
|
+
*
|
|
201
|
+
* // Subscribe to a channel
|
|
202
|
+
* await subscriber.subscribe("my-channel", (message, channel) => {
|
|
203
|
+
* console.log(`Received: ${message} on ${channel}`);
|
|
204
|
+
* });
|
|
205
|
+
* ```
|
|
206
|
+
*/
|
|
207
|
+
var RedisSubscriberProvider = class {};
|
|
208
|
+
|
|
209
|
+
//#endregion
|
|
210
|
+
//#region ../../src/redis/providers/BunRedisSubscriberProvider.ts
|
|
211
|
+
/**
|
|
212
|
+
* Bun Redis subscriber provider for pub/sub operations.
|
|
213
|
+
*
|
|
214
|
+
* This provider creates a dedicated Redis connection for subscriptions,
|
|
215
|
+
* as Redis requires separate connections for pub/sub operations.
|
|
216
|
+
*
|
|
217
|
+
* @example
|
|
218
|
+
* ```ts
|
|
219
|
+
* const subscriber = alepha.inject(RedisSubscriberProvider);
|
|
220
|
+
* await subscriber.subscribe("channel", (message, channel) => {
|
|
221
|
+
* console.log(`Received: ${message} on ${channel}`);
|
|
222
|
+
* });
|
|
223
|
+
* ```
|
|
224
|
+
*/
|
|
225
|
+
var BunRedisSubscriberProvider = class extends RedisSubscriberProvider {
|
|
226
|
+
log = $logger();
|
|
227
|
+
alepha = $inject(Alepha);
|
|
228
|
+
redisProvider = $inject(BunRedisProvider);
|
|
229
|
+
client;
|
|
230
|
+
get subscriber() {
|
|
231
|
+
if (!this.client?.connected) throw new AlephaError("Redis subscriber client is not ready");
|
|
232
|
+
return this.client;
|
|
233
|
+
}
|
|
234
|
+
get isReady() {
|
|
235
|
+
return this.client?.connected ?? false;
|
|
236
|
+
}
|
|
237
|
+
start = $hook({
|
|
238
|
+
on: "start",
|
|
239
|
+
handler: () => this.connect()
|
|
240
|
+
});
|
|
241
|
+
stop = $hook({
|
|
242
|
+
on: "stop",
|
|
243
|
+
handler: () => this.close()
|
|
244
|
+
});
|
|
245
|
+
/**
|
|
246
|
+
* Connect to the Redis server for subscriptions.
|
|
247
|
+
*/
|
|
248
|
+
async connect() {
|
|
249
|
+
this.log.debug("Connecting subscriber...");
|
|
250
|
+
this.client = await this.redisProvider.duplicate();
|
|
251
|
+
this.log.info("Subscriber connection OK");
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Close the subscriber connection.
|
|
255
|
+
*/
|
|
256
|
+
async close() {
|
|
257
|
+
if (this.client) {
|
|
258
|
+
this.log.debug("Closing subscriber connection...");
|
|
259
|
+
this.client.close();
|
|
260
|
+
this.client = void 0;
|
|
261
|
+
this.log.info("Subscriber connection closed");
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
async subscribe(channel, callback) {
|
|
265
|
+
await this.subscriber.subscribe(channel, (message, ch) => {
|
|
266
|
+
callback(typeof message === "object" && message !== null ? Buffer.from(message).toString() : String(message), ch);
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
async unsubscribe(channel, _callback) {
|
|
270
|
+
await this.subscriber.unsubscribe(channel);
|
|
271
|
+
}
|
|
272
|
+
};
|
|
273
|
+
|
|
274
|
+
//#endregion
|
|
275
|
+
//#region ../../src/redis/providers/NodeRedisProvider.ts
|
|
6
276
|
const envSchema = t.object({
|
|
277
|
+
REDIS_URL: t.optional(t.text()),
|
|
7
278
|
REDIS_PORT: t.integer({ default: "6379" }),
|
|
8
279
|
REDIS_HOST: t.text({ default: "localhost" }),
|
|
9
280
|
REDIS_PASSWORD: t.optional(t.text())
|
|
10
281
|
});
|
|
11
282
|
/**
|
|
12
|
-
* Redis client provider
|
|
283
|
+
* Node.js Redis client provider using `@redis/client`.
|
|
284
|
+
*
|
|
285
|
+
* This provider uses the official Redis client for Node.js runtime.
|
|
286
|
+
*
|
|
287
|
+
* @example
|
|
288
|
+
* ```ts
|
|
289
|
+
* // Set REDIS_URL environment variable
|
|
290
|
+
* // REDIS_URL=redis://localhost:6379
|
|
291
|
+
*
|
|
292
|
+
* // Or configure via REDIS_HOST, REDIS_PORT, REDIS_PASSWORD
|
|
293
|
+
*
|
|
294
|
+
* // Or configure programmatically
|
|
295
|
+
* alepha.with({
|
|
296
|
+
* provide: RedisProvider,
|
|
297
|
+
* use: NodeRedisProvider,
|
|
298
|
+
* });
|
|
299
|
+
* ```
|
|
13
300
|
*/
|
|
14
|
-
var
|
|
301
|
+
var NodeRedisProvider = class extends RedisProvider {
|
|
15
302
|
log = $logger();
|
|
16
303
|
alepha = $inject(Alepha);
|
|
17
304
|
env = $env(envSchema);
|
|
@@ -20,6 +307,9 @@ var RedisProvider = class {
|
|
|
20
307
|
if (!this.client.isReady) throw new Error("Redis client is not ready");
|
|
21
308
|
return this.client;
|
|
22
309
|
}
|
|
310
|
+
get isReady() {
|
|
311
|
+
return this.client.isReady;
|
|
312
|
+
}
|
|
23
313
|
start = $hook({
|
|
24
314
|
on: "start",
|
|
25
315
|
handler: () => this.connect()
|
|
@@ -58,7 +348,20 @@ var RedisProvider = class {
|
|
|
58
348
|
}
|
|
59
349
|
async set(key, value, options) {
|
|
60
350
|
const buf = Buffer.isBuffer(value) ? value : Buffer.from(value, "utf-8");
|
|
61
|
-
const
|
|
351
|
+
const setOptions = {};
|
|
352
|
+
if (options?.expiration) if (options.expiration.type === "KEEPTTL") setOptions.KEEPTTL = true;
|
|
353
|
+
else setOptions[options.expiration.type] = options.expiration.value;
|
|
354
|
+
if (options?.EX !== void 0) setOptions.EX = options.EX;
|
|
355
|
+
if (options?.PX !== void 0) setOptions.PX = options.PX;
|
|
356
|
+
if (options?.EXAT !== void 0) setOptions.EXAT = options.EXAT;
|
|
357
|
+
if (options?.PXAT !== void 0) setOptions.PXAT = options.PXAT;
|
|
358
|
+
if (options?.KEEPTTL) setOptions.KEEPTTL = true;
|
|
359
|
+
if (options?.condition === "NX") setOptions.NX = true;
|
|
360
|
+
else if (options?.condition === "XX") setOptions.XX = true;
|
|
361
|
+
if (options?.NX) setOptions.NX = true;
|
|
362
|
+
if (options?.XX) setOptions.XX = true;
|
|
363
|
+
if (options?.GET) setOptions.GET = true;
|
|
364
|
+
const resp = await this.publisher.set(key, buf, Object.keys(setOptions).length > 0 ? setOptions : void 0);
|
|
62
365
|
if (resp === "OK" || !resp) return buf;
|
|
63
366
|
return Buffer.from(resp);
|
|
64
367
|
}
|
|
@@ -72,16 +375,34 @@ var RedisProvider = class {
|
|
|
72
375
|
if (keys.length === 0) return;
|
|
73
376
|
await this.publisher.del(keys);
|
|
74
377
|
}
|
|
378
|
+
async lpush(key, value) {
|
|
379
|
+
await this.publisher.LPUSH(key, value);
|
|
380
|
+
}
|
|
381
|
+
async rpop(key) {
|
|
382
|
+
const value = await this.publisher.RPOP(key);
|
|
383
|
+
if (value == null) return;
|
|
384
|
+
return String(value);
|
|
385
|
+
}
|
|
386
|
+
async publish(channel, message) {
|
|
387
|
+
await this.publisher.publish(channel, message);
|
|
388
|
+
}
|
|
75
389
|
/**
|
|
76
|
-
*
|
|
390
|
+
* Get the Redis connection URL.
|
|
77
391
|
*/
|
|
78
|
-
|
|
392
|
+
getUrl() {
|
|
393
|
+
if (this.env.REDIS_URL) return this.env.REDIS_URL;
|
|
79
394
|
const url = new URL("redis://127.0.0.1:6379");
|
|
80
395
|
if (this.env.REDIS_PASSWORD) url.password = this.env.REDIS_PASSWORD;
|
|
81
396
|
if (this.env.REDIS_HOST) url.hostname = this.env.REDIS_HOST;
|
|
82
397
|
if (this.env.REDIS_PORT) url.port = String(this.env.REDIS_PORT);
|
|
398
|
+
return url.toString();
|
|
399
|
+
}
|
|
400
|
+
/**
|
|
401
|
+
* Redis client factory method.
|
|
402
|
+
*/
|
|
403
|
+
createClient() {
|
|
83
404
|
const client = createClient({
|
|
84
|
-
url:
|
|
405
|
+
url: this.getUrl(),
|
|
85
406
|
RESP: 3
|
|
86
407
|
}).withTypeMapping({ [RESP_TYPES.BLOB_STRING]: Buffer });
|
|
87
408
|
client.on("error", (error) => {
|
|
@@ -92,16 +413,33 @@ var RedisProvider = class {
|
|
|
92
413
|
};
|
|
93
414
|
|
|
94
415
|
//#endregion
|
|
95
|
-
//#region ../../src/redis/providers/
|
|
96
|
-
|
|
416
|
+
//#region ../../src/redis/providers/NodeRedisSubscriberProvider.ts
|
|
417
|
+
/**
|
|
418
|
+
* Node.js Redis subscriber provider using `@redis/client`.
|
|
419
|
+
*
|
|
420
|
+
* This provider creates a dedicated Redis connection for subscriptions,
|
|
421
|
+
* as Redis requires separate connections for pub/sub operations.
|
|
422
|
+
*
|
|
423
|
+
* @example
|
|
424
|
+
* ```ts
|
|
425
|
+
* const subscriber = alepha.inject(RedisSubscriberProvider);
|
|
426
|
+
* await subscriber.subscribe("channel", (message, channel) => {
|
|
427
|
+
* console.log(`Received: ${message} on ${channel}`);
|
|
428
|
+
* });
|
|
429
|
+
* ```
|
|
430
|
+
*/
|
|
431
|
+
var NodeRedisSubscriberProvider = class extends RedisSubscriberProvider {
|
|
97
432
|
log = $logger();
|
|
98
433
|
alepha = $inject(Alepha);
|
|
99
|
-
redisProvider = $inject(
|
|
434
|
+
redisProvider = $inject(NodeRedisProvider);
|
|
100
435
|
client = this.createClient();
|
|
101
436
|
get subscriber() {
|
|
102
|
-
if (!this.client.isReady) throw new Error("Redis client is not ready");
|
|
437
|
+
if (!this.client.isReady) throw new Error("Redis subscriber client is not ready");
|
|
103
438
|
return this.client;
|
|
104
439
|
}
|
|
440
|
+
get isReady() {
|
|
441
|
+
return this.client.isReady;
|
|
442
|
+
}
|
|
105
443
|
start = $hook({
|
|
106
444
|
on: "start",
|
|
107
445
|
handler: () => this.connect()
|
|
@@ -111,14 +449,20 @@ var RedisSubscriberProvider = class {
|
|
|
111
449
|
handler: () => this.close()
|
|
112
450
|
});
|
|
113
451
|
async connect() {
|
|
114
|
-
this.log.debug("Connecting...");
|
|
452
|
+
this.log.debug("Connecting subscriber...");
|
|
115
453
|
await this.client.connect();
|
|
116
|
-
this.log.info("
|
|
454
|
+
this.log.info("Subscriber connection OK");
|
|
117
455
|
}
|
|
118
456
|
async close() {
|
|
119
|
-
this.log.debug("Closing connection...");
|
|
120
|
-
this.subscriber.close();
|
|
121
|
-
this.log.info("
|
|
457
|
+
this.log.debug("Closing subscriber connection...");
|
|
458
|
+
await this.subscriber.close();
|
|
459
|
+
this.log.info("Subscriber connection closed");
|
|
460
|
+
}
|
|
461
|
+
async subscribe(channel, callback) {
|
|
462
|
+
await this.subscriber.subscribe(channel, callback);
|
|
463
|
+
}
|
|
464
|
+
async unsubscribe(channel, callback) {
|
|
465
|
+
await this.subscriber.unsubscribe(channel, callback);
|
|
122
466
|
}
|
|
123
467
|
/**
|
|
124
468
|
* Redis subscriber client factory method.
|
|
@@ -137,15 +481,62 @@ var RedisSubscriberProvider = class {
|
|
|
137
481
|
/**
|
|
138
482
|
* Redis client provider for Alepha applications.
|
|
139
483
|
*
|
|
140
|
-
*
|
|
484
|
+
* Automatically selects the appropriate provider based on runtime:
|
|
485
|
+
* - Bun: Uses `BunRedisProvider` with Bun's native Redis client (7.9x faster than ioredis)
|
|
486
|
+
* - Node.js: Uses `NodeRedisProvider` with `@redis/client`
|
|
487
|
+
*
|
|
488
|
+
* @example
|
|
489
|
+
* ```ts
|
|
490
|
+
* // Inject the abstract provider - runtime selects the implementation
|
|
491
|
+
* const redis = alepha.inject(RedisProvider);
|
|
492
|
+
*
|
|
493
|
+
* // Use common operations
|
|
494
|
+
* await redis.set("key", "value");
|
|
495
|
+
* const value = await redis.get("key");
|
|
496
|
+
*
|
|
497
|
+
* // For pub/sub
|
|
498
|
+
* const subscriber = alepha.inject(RedisSubscriberProvider);
|
|
499
|
+
* await subscriber.subscribe("channel", (message, channel) => {
|
|
500
|
+
* console.log(`Received: ${message} on ${channel}`);
|
|
501
|
+
* });
|
|
502
|
+
* ```
|
|
503
|
+
*
|
|
504
|
+
* @see {@link RedisProvider} - Abstract base class
|
|
505
|
+
* @see {@link NodeRedisProvider} - Node.js implementation
|
|
506
|
+
* @see {@link BunRedisProvider} - Bun implementation
|
|
507
|
+
* @see {@link RedisSubscriberProvider} - Abstract subscriber base class
|
|
508
|
+
* @see {@link NodeRedisSubscriberProvider} - Node.js subscriber implementation
|
|
509
|
+
* @see {@link BunRedisSubscriberProvider} - Bun subscriber implementation
|
|
141
510
|
* @module alepha.redis
|
|
142
511
|
*/
|
|
143
512
|
const AlephaRedis = $module({
|
|
144
513
|
name: "alepha.redis",
|
|
145
|
-
services: [
|
|
146
|
-
|
|
514
|
+
services: [
|
|
515
|
+
NodeRedisProvider,
|
|
516
|
+
NodeRedisSubscriberProvider,
|
|
517
|
+
BunRedisProvider,
|
|
518
|
+
BunRedisSubscriberProvider,
|
|
519
|
+
RedisProvider,
|
|
520
|
+
RedisSubscriberProvider
|
|
521
|
+
],
|
|
522
|
+
register: (alepha) => {
|
|
523
|
+
if (alepha.isBun()) alepha.with({
|
|
524
|
+
provide: RedisProvider,
|
|
525
|
+
use: BunRedisProvider
|
|
526
|
+
}).with({
|
|
527
|
+
provide: RedisSubscriberProvider,
|
|
528
|
+
use: BunRedisSubscriberProvider
|
|
529
|
+
});
|
|
530
|
+
else alepha.with({
|
|
531
|
+
provide: RedisProvider,
|
|
532
|
+
use: NodeRedisProvider
|
|
533
|
+
}).with({
|
|
534
|
+
provide: RedisSubscriberProvider,
|
|
535
|
+
use: NodeRedisSubscriberProvider
|
|
536
|
+
});
|
|
537
|
+
}
|
|
147
538
|
});
|
|
148
539
|
|
|
149
540
|
//#endregion
|
|
150
|
-
export { AlephaRedis, RedisProvider, RedisSubscriberProvider };
|
|
541
|
+
export { AlephaRedis, BunRedisProvider, BunRedisSubscriberProvider, NodeRedisProvider, NodeRedisSubscriberProvider, RedisProvider, RedisSubscriberProvider };
|
|
151
542
|
//# sourceMappingURL=index.js.map
|
package/dist/redis/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../src/redis/providers/RedisProvider.ts","../../src/redis/providers/RedisSubscriberProvider.ts","../../src/redis/index.ts"],"sourcesContent":["import {\n createClient,\n RESP_TYPES,\n type RedisClientType,\n type SetOptions,\n} from \"@redis/client\";\nimport { $env, $hook, $inject, Alepha, type Static, t } from \"alepha\";\nimport { $logger } from \"alepha/logger\";\n\nconst envSchema = t.object({\n REDIS_PORT: t.integer({\n default: \"6379\",\n }),\n REDIS_HOST: t.text({\n default: \"localhost\",\n }),\n REDIS_PASSWORD: t.optional(t.text()),\n});\n\ndeclare module \"alepha\" {\n interface Env extends Partial<Static<typeof envSchema>> {}\n}\n\nexport type RedisClient = RedisClientType<\n {},\n {},\n {},\n 3,\n { 36: BufferConstructor }\n>;\nexport type RedisClientOptions = Parameters<typeof createClient>[0];\nexport type RedisSetOptions = SetOptions;\n\n/**\n * Redis client provider.\n */\nexport class RedisProvider {\n protected readonly log = $logger();\n protected readonly alepha = $inject(Alepha);\n protected readonly env = $env(envSchema);\n protected readonly client = this.createClient();\n\n public get publisher(): RedisClient {\n if (!this.client.isReady) {\n throw new Error(\"Redis client is not ready\");\n }\n\n return this.client;\n }\n\n protected readonly start = $hook({\n on: \"start\",\n handler: () => this.connect(),\n });\n\n protected readonly stop = $hook({\n on: \"stop\",\n handler: () => this.close(),\n });\n\n /**\n * Connect to the Redis server.\n */\n public async connect(): Promise<void> {\n this.log.debug(\"Connecting...\");\n await this.client.connect();\n this.log.info(\"Connection OK\");\n }\n\n /**\n * Close the connection to the Redis server.\n */\n public async close(): Promise<void> {\n this.log.debug(\"Closing connection...\");\n await this.client.close();\n this.log.info(\"Connection closed\");\n }\n\n public duplicate(options?: Partial<RedisClientOptions>): RedisClient {\n return this.client\n .duplicate({\n ...options,\n RESP: 3,\n })\n .withTypeMapping({\n [RESP_TYPES.BLOB_STRING]: Buffer,\n });\n }\n\n public async get(key: string): Promise<Buffer | undefined> {\n this.log.trace(`Getting key ${key}`);\n const resp = await this.publisher.get(key);\n\n if (resp === null) {\n return undefined;\n }\n\n return Buffer.from(resp);\n }\n\n public async set(\n key: string,\n value: Buffer | string,\n options?: RedisSetOptions,\n ): Promise<Buffer> {\n const buf = Buffer.isBuffer(value) ? value : Buffer.from(value, \"utf-8\");\n const resp = await this.publisher.set(key, buf, options);\n\n if (resp === \"OK\" || !resp) {\n return buf;\n }\n\n return Buffer.from(resp);\n }\n\n public async has(key: string): Promise<boolean> {\n const resp = await this.publisher.exists(key);\n return resp > 0;\n }\n\n public async keys(pattern: string): Promise<string[]> {\n const keys = await this.publisher.keys(pattern);\n return keys.map((key) => key.toString());\n }\n\n public async del(keys: string[]): Promise<void> {\n if (keys.length === 0) {\n return;\n }\n\n await this.publisher.del(keys);\n }\n\n /**\n * Redis subscriber client factory method.\n */\n protected createClient(): RedisClient {\n const url = new URL(\"redis://127.0.0.1:6379\");\n\n if (this.env.REDIS_PASSWORD) {\n url.password = this.env.REDIS_PASSWORD;\n }\n\n if (this.env.REDIS_HOST) {\n url.hostname = this.env.REDIS_HOST;\n }\n\n if (this.env.REDIS_PORT) {\n url.port = String(this.env.REDIS_PORT);\n }\n\n const client = createClient({\n url: url.toString(),\n RESP: 3,\n }).withTypeMapping({\n [RESP_TYPES.BLOB_STRING]: Buffer,\n });\n\n client.on(\"error\", (error) => {\n if (this.alepha.isStarted()) {\n this.log.error(error);\n }\n });\n\n return client;\n }\n}\n","import { $hook, $inject, Alepha } from \"alepha\";\nimport { $logger } from \"alepha/logger\";\nimport type { RedisClient } from \"./RedisProvider.ts\";\nimport { RedisProvider } from \"./RedisProvider.ts\";\n\nexport class RedisSubscriberProvider {\n protected readonly log = $logger();\n protected readonly alepha = $inject(Alepha);\n protected readonly redisProvider: RedisProvider = $inject(RedisProvider);\n protected readonly client: RedisClient = this.createClient();\n\n public get subscriber(): RedisClient {\n if (!this.client.isReady) {\n throw new Error(\"Redis client is not ready\");\n }\n\n return this.client;\n }\n\n protected readonly start = $hook({\n on: \"start\",\n handler: () => this.connect(),\n });\n\n protected readonly stop = $hook({\n on: \"stop\",\n handler: () => this.close(),\n });\n\n public async connect(): Promise<void> {\n this.log.debug(\"Connecting...\");\n await this.client.connect();\n this.log.info(\"Connection OK\");\n }\n\n public async close(): Promise<void> {\n this.log.debug(\"Closing connection...\");\n this.subscriber.close();\n this.log.info(\"Connection closed\");\n }\n\n /**\n * Redis subscriber client factory method.\n */\n protected createClient(): RedisClient {\n const client = this.redisProvider.duplicate();\n\n client.on(\"error\", (error) => {\n if (this.alepha.isStarted()) {\n this.log.error(error);\n }\n });\n\n return client;\n }\n}\n","import { $module, type Alepha } from \"alepha\";\nimport { RedisProvider } from \"./providers/RedisProvider.ts\";\nimport { RedisSubscriberProvider } from \"./providers/RedisSubscriberProvider.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport * from \"./providers/RedisProvider.ts\";\nexport * from \"./providers/RedisSubscriberProvider.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\n/**\n * Redis client provider for Alepha applications.\n *\n * @see {@link RedisProvider}\n * @module alepha.redis\n */\nexport const AlephaRedis = $module({\n name: \"alepha.redis\",\n services: [RedisProvider, RedisSubscriberProvider],\n register: (alepha: Alepha) => alepha.with(RedisProvider),\n});\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["envSchema","args: string[]","setOptions: SetOptions"],"sources":["../../src/redis/providers/RedisProvider.ts","../../src/redis/providers/BunRedisProvider.ts","../../src/redis/providers/RedisSubscriberProvider.ts","../../src/redis/providers/BunRedisSubscriberProvider.ts","../../src/redis/providers/NodeRedisProvider.ts","../../src/redis/providers/NodeRedisSubscriberProvider.ts","../../src/redis/index.ts"],"sourcesContent":["/**\n * Abstract Redis provider interface.\n *\n * This abstract class defines the common interface for Redis operations.\n * Implementations include:\n * - {@link NodeRedisProvider} - Uses `@redis/client` for Node.js runtime\n * - {@link BunRedisProvider} - Uses Bun's native `RedisClient` for Bun runtime\n *\n * @example\n * ```ts\n * // Inject the abstract provider - runtime selects the implementation\n * const redis = alepha.inject(RedisProvider);\n *\n * // Use common operations\n * await redis.set(\"key\", \"value\");\n * const value = await redis.get(\"key\");\n * ```\n */\nexport abstract class RedisProvider {\n /**\n * Whether the Redis client is ready to accept commands.\n */\n public abstract readonly isReady: boolean;\n\n /**\n * Connect to the Redis server.\n */\n public abstract connect(): Promise<void>;\n\n /**\n * Close the connection to the Redis server.\n */\n public abstract close(): Promise<void>;\n\n /**\n * Get the value of a key.\n *\n * @param key The key to get.\n * @returns The value as a Buffer, or undefined if the key does not exist.\n */\n public abstract get(key: string): Promise<Buffer | undefined>;\n\n /**\n * Set the value of a key.\n *\n * @param key The key to set.\n * @param value The value to set (Buffer or string).\n * @param options Optional set options (EX, PX, NX, XX, etc.).\n * @returns The value as a Buffer.\n */\n public abstract set(\n key: string,\n value: Buffer | string,\n options?: RedisSetOptions,\n ): Promise<Buffer>;\n\n /**\n * Check if a key exists.\n *\n * @param key The key to check.\n * @returns True if the key exists.\n */\n public abstract has(key: string): Promise<boolean>;\n\n /**\n * Get all keys matching a pattern.\n *\n * @param pattern The glob-style pattern to match.\n * @returns Array of matching key names.\n */\n public abstract keys(pattern: string): Promise<string[]>;\n\n /**\n * Delete one or more keys.\n *\n * @param keys The keys to delete.\n */\n public abstract del(keys: string[]): Promise<void>;\n\n // ---------------------------------------------------------\n // Queue operations (for alepha/queue-redis)\n // ---------------------------------------------------------\n\n /**\n * Push a value to the left (head) of a list.\n *\n * @param key The list key.\n * @param value The value to push.\n */\n public abstract lpush(key: string, value: string): Promise<void>;\n\n /**\n * Pop a value from the right (tail) of a list.\n *\n * @param key The list key.\n * @returns The value, or undefined if the list is empty.\n */\n public abstract rpop(key: string): Promise<string | undefined>;\n\n // ---------------------------------------------------------\n // Pub/Sub operations (for alepha/topic-redis)\n // ---------------------------------------------------------\n\n /**\n * Publish a message to a channel.\n *\n * @param channel The channel name.\n * @param message The message to publish.\n */\n public abstract publish(channel: string, message: string): Promise<void>;\n}\n\n/**\n * Common Redis SET command options.\n * Compatible with @redis/client SetOptions format.\n */\nexport interface RedisSetOptions {\n /**\n * Set the specified expire time, in seconds.\n */\n EX?: number;\n /**\n * Set the specified expire time, in milliseconds.\n */\n PX?: number;\n /**\n * Set the specified Unix time at which the key will expire, in seconds.\n */\n EXAT?: number;\n /**\n * Set the specified Unix time at which the key will expire, in milliseconds.\n */\n PXAT?: number;\n /**\n * Only set the key if it does not already exist.\n */\n NX?: boolean;\n /**\n * Only set the key if it already exists.\n */\n XX?: boolean;\n /**\n * Retain the time to live associated with the key.\n */\n KEEPTTL?: boolean;\n /**\n * Return the old string stored at key, or nil if key did not exist.\n */\n GET?: boolean;\n /**\n * Alternative expiration format (compatible with @redis/client).\n */\n expiration?: {\n type: \"EX\" | \"PX\" | \"EXAT\" | \"PXAT\" | \"KEEPTTL\";\n value: number;\n };\n /**\n * Alternative condition format (compatible with @redis/client).\n */\n condition?: \"NX\" | \"XX\";\n}\n","import {\n $env,\n $hook,\n $inject,\n Alepha,\n AlephaError,\n type Static,\n t,\n} from \"alepha\";\nimport { $logger } from \"alepha/logger\";\nimport type { RedisClient as BunRedisClient } from \"bun\";\nimport { RedisProvider, type RedisSetOptions } from \"./RedisProvider.ts\";\n\nconst envSchema = t.object({\n REDIS_URL: t.optional(t.text()),\n REDIS_PORT: t.integer({\n default: \"6379\",\n }),\n REDIS_HOST: t.text({\n default: \"localhost\",\n }),\n REDIS_PASSWORD: t.optional(t.text()),\n});\n\ndeclare module \"alepha\" {\n interface Env extends Partial<Static<typeof envSchema>> {}\n}\n\n/**\n * Bun Redis client provider using Bun's native Redis client.\n *\n * This provider uses Bun's built-in `RedisClient` class for Redis connections,\n * which provides excellent performance (7.9x faster than ioredis) on the Bun runtime.\n *\n * @example\n * ```ts\n * // Set REDIS_URL environment variable\n * // REDIS_URL=redis://localhost:6379\n *\n * // Or configure via REDIS_HOST, REDIS_PORT, REDIS_PASSWORD\n *\n * // Or configure programmatically\n * alepha.with({\n * provide: RedisProvider,\n * use: BunRedisProvider,\n * });\n * ```\n */\nexport class BunRedisProvider extends RedisProvider {\n protected readonly log = $logger();\n protected readonly alepha = $inject(Alepha);\n protected readonly env = $env(envSchema);\n protected client?: BunRedisClient;\n\n public get publisher(): BunRedisClient {\n if (!this.client?.connected) {\n throw new AlephaError(\"Redis client is not ready\");\n }\n\n return this.client;\n }\n\n public override get isReady(): boolean {\n return this.client?.connected ?? false;\n }\n\n protected readonly start = $hook({\n on: \"start\",\n handler: () => this.connect(),\n });\n\n protected readonly stop = $hook({\n on: \"stop\",\n handler: () => this.close(),\n });\n\n /**\n * Connect to the Redis server.\n */\n public override async connect(): Promise<void> {\n // Check if we're running in Bun\n if (typeof Bun === \"undefined\") {\n throw new AlephaError(\n \"BunRedisProvider requires the Bun runtime. Use NodeRedisProvider for Node.js.\",\n );\n }\n\n this.log.debug(\"Connecting...\");\n\n const { RedisClient } = await import(\"bun\");\n\n this.client = new RedisClient(this.getUrl(), {\n autoReconnect: true,\n enableAutoPipelining: true,\n });\n\n this.client.onconnect = () => {\n this.log.trace(\"Redis connected\");\n };\n\n this.client.onclose = (error) => {\n if (this.alepha.isStarted() && error) {\n this.log.error(\"Redis connection closed\", error);\n }\n };\n\n await this.client.connect();\n\n this.log.info(\"Connection OK\");\n }\n\n /**\n * Close the connection to the Redis server.\n */\n public override async close(): Promise<void> {\n if (this.client) {\n this.log.debug(\"Closing connection...\");\n this.client.close();\n this.client = undefined;\n this.log.info(\"Connection closed\");\n }\n }\n\n /**\n * Create a duplicate connection for pub/sub or other isolated operations.\n */\n public async duplicate(): Promise<BunRedisClient> {\n if (typeof Bun === \"undefined\") {\n throw new AlephaError(\"BunRedisProvider requires the Bun runtime.\");\n }\n\n const { RedisClient } = await import(\"bun\");\n\n const client = new RedisClient(this.getUrl(), {\n autoReconnect: true,\n enableAutoPipelining: true,\n });\n\n client.onclose = (error) => {\n if (this.alepha.isStarted() && error) {\n this.log.error(\"Redis duplicate connection closed\", error);\n }\n };\n\n await client.connect();\n\n return client;\n }\n\n public override async get(key: string): Promise<Buffer | undefined> {\n this.log.trace(`Getting key ${key}`);\n const resp = await this.publisher.getBuffer(key);\n\n if (resp === null) {\n return undefined;\n }\n\n return Buffer.from(resp);\n }\n\n public override async set(\n key: string,\n value: Buffer | string,\n options?: RedisSetOptions,\n ): Promise<Buffer> {\n const buf = Buffer.isBuffer(value) ? value : Buffer.from(value, \"utf-8\");\n\n // Build SET command arguments\n const args: string[] = [key, buf.toString(\"binary\")];\n\n // Handle expiration object format (from alepha/cache-redis, alepha/lock-redis)\n if (options?.expiration) {\n if (options.expiration.type === \"KEEPTTL\") {\n args.push(\"KEEPTTL\");\n } else {\n args.push(options.expiration.type, String(options.expiration.value));\n }\n }\n\n // Handle direct expiration properties\n if (options?.EX !== undefined) {\n args.push(\"EX\", String(options.EX));\n }\n if (options?.PX !== undefined) {\n args.push(\"PX\", String(options.PX));\n }\n if (options?.EXAT !== undefined) {\n args.push(\"EXAT\", String(options.EXAT));\n }\n if (options?.PXAT !== undefined) {\n args.push(\"PXAT\", String(options.PXAT));\n }\n if (options?.KEEPTTL) {\n args.push(\"KEEPTTL\");\n }\n\n // Handle condition object format\n if (options?.condition === \"NX\") {\n args.push(\"NX\");\n } else if (options?.condition === \"XX\") {\n args.push(\"XX\");\n }\n\n // Handle direct condition properties\n if (options?.NX) {\n args.push(\"NX\");\n }\n if (options?.XX) {\n args.push(\"XX\");\n }\n if (options?.GET) {\n args.push(\"GET\");\n }\n\n if (args.length === 2) {\n // Simple set without options\n await this.publisher.set(key, buf);\n } else {\n // Set with options via raw command\n await this.publisher.send(\"SET\", args);\n }\n\n return buf;\n }\n\n public override async has(key: string): Promise<boolean> {\n return this.publisher.exists(key);\n }\n\n public override async keys(pattern: string): Promise<string[]> {\n const keys = await this.publisher.send(\"KEYS\", [pattern]);\n if (!Array.isArray(keys)) {\n return [];\n }\n return keys.map((key) =>\n key instanceof Uint8Array ? Buffer.from(key).toString() : String(key),\n );\n }\n\n public override async del(keys: string[]): Promise<void> {\n if (keys.length === 0) {\n return;\n }\n\n await this.publisher.send(\"DEL\", keys);\n }\n\n // ---------------------------------------------------------\n // Queue operations\n // ---------------------------------------------------------\n\n public override async lpush(key: string, value: string): Promise<void> {\n await this.publisher.send(\"LPUSH\", [key, value]);\n }\n\n public override async rpop(key: string): Promise<string | undefined> {\n const value = await this.publisher.send(\"RPOP\", [key]);\n if (value == null) {\n return undefined;\n }\n if (value instanceof Uint8Array) {\n return Buffer.from(value).toString();\n }\n return String(value);\n }\n\n // ---------------------------------------------------------\n // Pub/Sub operations\n // ---------------------------------------------------------\n\n public override async publish(\n channel: string,\n message: string,\n ): Promise<void> {\n await this.publisher.publish(channel, message);\n }\n\n /**\n * Get the Redis connection URL.\n */\n protected getUrl(): string {\n // Prefer REDIS_URL if set\n if (this.env.REDIS_URL) {\n return this.env.REDIS_URL;\n }\n\n // Build URL from components\n const url = new URL(\"redis://127.0.0.1:6379\");\n\n if (this.env.REDIS_PASSWORD) {\n url.password = this.env.REDIS_PASSWORD;\n }\n\n if (this.env.REDIS_HOST) {\n url.hostname = this.env.REDIS_HOST;\n }\n\n if (this.env.REDIS_PORT) {\n url.port = String(this.env.REDIS_PORT);\n }\n\n return url.toString();\n }\n}\n","/**\n * Abstract Redis subscriber provider interface.\n *\n * This abstract class defines the common interface for Redis pub/sub subscriptions.\n * Implementations include:\n * - {@link NodeRedisSubscriberProvider} - Uses `@redis/client` for Node.js runtime\n * - {@link BunRedisSubscriberProvider} - Uses Bun's native `RedisClient` for Bun runtime\n *\n * Redis requires separate connections for pub/sub operations, so this provider\n * creates a dedicated connection for subscriptions.\n *\n * @example\n * ```ts\n * // Inject the abstract provider - runtime selects the implementation\n * const subscriber = alepha.inject(RedisSubscriberProvider);\n *\n * // Subscribe to a channel\n * await subscriber.subscribe(\"my-channel\", (message, channel) => {\n * console.log(`Received: ${message} on ${channel}`);\n * });\n * ```\n */\nexport abstract class RedisSubscriberProvider {\n /**\n * Whether the Redis subscriber client is ready to accept commands.\n */\n public abstract readonly isReady: boolean;\n\n /**\n * Connect to the Redis server for subscriptions.\n */\n public abstract connect(): Promise<void>;\n\n /**\n * Close the subscriber connection.\n */\n public abstract close(): Promise<void>;\n\n /**\n * Subscribe to a channel.\n *\n * @param channel The channel name.\n * @param callback The callback to invoke when a message is received.\n */\n public abstract subscribe(\n channel: string,\n callback: SubscribeCallback,\n ): Promise<void>;\n\n /**\n * Unsubscribe from a channel.\n *\n * @param channel The channel name.\n * @param callback Optional specific callback to remove.\n */\n public abstract unsubscribe(\n channel: string,\n callback?: SubscribeCallback,\n ): Promise<void>;\n}\n\n/**\n * Callback for subscription messages.\n */\nexport type SubscribeCallback = (message: string, channel: string) => void;\n","import { $hook, $inject, Alepha, AlephaError } from \"alepha\";\nimport { $logger } from \"alepha/logger\";\nimport type { RedisClient as BunRedisClient } from \"bun\";\nimport { BunRedisProvider } from \"./BunRedisProvider.ts\";\nimport {\n RedisSubscriberProvider,\n type SubscribeCallback,\n} from \"./RedisSubscriberProvider.ts\";\n\n/**\n * Bun Redis subscriber provider for pub/sub operations.\n *\n * This provider creates a dedicated Redis connection for subscriptions,\n * as Redis requires separate connections for pub/sub operations.\n *\n * @example\n * ```ts\n * const subscriber = alepha.inject(RedisSubscriberProvider);\n * await subscriber.subscribe(\"channel\", (message, channel) => {\n * console.log(`Received: ${message} on ${channel}`);\n * });\n * ```\n */\nexport class BunRedisSubscriberProvider extends RedisSubscriberProvider {\n protected readonly log = $logger();\n protected readonly alepha = $inject(Alepha);\n protected readonly redisProvider = $inject(BunRedisProvider);\n protected client?: BunRedisClient;\n\n public get subscriber(): BunRedisClient {\n if (!this.client?.connected) {\n throw new AlephaError(\"Redis subscriber client is not ready\");\n }\n\n return this.client;\n }\n\n public override get isReady(): boolean {\n return this.client?.connected ?? false;\n }\n\n protected readonly start = $hook({\n on: \"start\",\n handler: () => this.connect(),\n });\n\n protected readonly stop = $hook({\n on: \"stop\",\n handler: () => this.close(),\n });\n\n /**\n * Connect to the Redis server for subscriptions.\n */\n public override async connect(): Promise<void> {\n this.log.debug(\"Connecting subscriber...\");\n this.client = await this.redisProvider.duplicate();\n this.log.info(\"Subscriber connection OK\");\n }\n\n /**\n * Close the subscriber connection.\n */\n public override async close(): Promise<void> {\n if (this.client) {\n this.log.debug(\"Closing subscriber connection...\");\n this.client.close();\n this.client = undefined;\n this.log.info(\"Subscriber connection closed\");\n }\n }\n\n public override async subscribe(\n channel: string,\n callback: SubscribeCallback,\n ): Promise<void> {\n await this.subscriber.subscribe(channel, (message, ch) => {\n // Bun's callback provides Buffer or string, normalize to string\n const msg =\n typeof message === \"object\" && message !== null\n ? Buffer.from(message as Uint8Array).toString()\n : String(message);\n callback(msg, ch);\n });\n }\n\n public override async unsubscribe(\n channel: string,\n _callback?: SubscribeCallback,\n ): Promise<void> {\n // Bun's unsubscribe doesn't support callback filtering\n await this.subscriber.unsubscribe(channel);\n }\n}\n","import {\n createClient,\n RESP_TYPES,\n type RedisClientType,\n type SetOptions,\n} from \"@redis/client\";\nimport { $env, $hook, $inject, Alepha, type Static, t } from \"alepha\";\nimport { $logger } from \"alepha/logger\";\nimport { RedisProvider, type RedisSetOptions } from \"./RedisProvider.ts\";\n\nconst envSchema = t.object({\n REDIS_URL: t.optional(t.text()),\n REDIS_PORT: t.integer({\n default: \"6379\",\n }),\n REDIS_HOST: t.text({\n default: \"localhost\",\n }),\n REDIS_PASSWORD: t.optional(t.text()),\n});\n\ndeclare module \"alepha\" {\n interface Env extends Partial<Static<typeof envSchema>> {}\n}\n\nexport type NodeRedisClient = RedisClientType<\n {},\n {},\n {},\n 3,\n { 36: BufferConstructor }\n>;\nexport type NodeRedisClientOptions = Parameters<typeof createClient>[0];\n\n/**\n * Node.js Redis client provider using `@redis/client`.\n *\n * This provider uses the official Redis client for Node.js runtime.\n *\n * @example\n * ```ts\n * // Set REDIS_URL environment variable\n * // REDIS_URL=redis://localhost:6379\n *\n * // Or configure via REDIS_HOST, REDIS_PORT, REDIS_PASSWORD\n *\n * // Or configure programmatically\n * alepha.with({\n * provide: RedisProvider,\n * use: NodeRedisProvider,\n * });\n * ```\n */\nexport class NodeRedisProvider extends RedisProvider {\n protected readonly log = $logger();\n protected readonly alepha = $inject(Alepha);\n protected readonly env = $env(envSchema);\n protected readonly client = this.createClient();\n\n public get publisher(): NodeRedisClient {\n if (!this.client.isReady) {\n throw new Error(\"Redis client is not ready\");\n }\n\n return this.client;\n }\n\n public override get isReady(): boolean {\n return this.client.isReady;\n }\n\n protected readonly start = $hook({\n on: \"start\",\n handler: () => this.connect(),\n });\n\n protected readonly stop = $hook({\n on: \"stop\",\n handler: () => this.close(),\n });\n\n /**\n * Connect to the Redis server.\n */\n public override async connect(): Promise<void> {\n this.log.debug(\"Connecting...\");\n await this.client.connect();\n this.log.info(\"Connection OK\");\n }\n\n /**\n * Close the connection to the Redis server.\n */\n public override async close(): Promise<void> {\n this.log.debug(\"Closing connection...\");\n await this.client.close();\n this.log.info(\"Connection closed\");\n }\n\n public duplicate(options?: Partial<NodeRedisClientOptions>): NodeRedisClient {\n return this.client\n .duplicate({\n ...options,\n RESP: 3,\n })\n .withTypeMapping({\n [RESP_TYPES.BLOB_STRING]: Buffer,\n });\n }\n\n public override async get(key: string): Promise<Buffer | undefined> {\n this.log.trace(`Getting key ${key}`);\n const resp = await this.publisher.get(key);\n\n if (resp === null) {\n return undefined;\n }\n\n return Buffer.from(resp);\n }\n\n public override async set(\n key: string,\n value: Buffer | string,\n options?: RedisSetOptions,\n ): Promise<Buffer> {\n const buf = Buffer.isBuffer(value) ? value : Buffer.from(value, \"utf-8\");\n\n // Convert RedisSetOptions to @redis/client SetOptions\n const setOptions: SetOptions = {};\n\n // Handle expiration object format (from alepha/cache-redis, alepha/lock-redis)\n if (options?.expiration) {\n if (options.expiration.type === \"KEEPTTL\") {\n setOptions.KEEPTTL = true;\n } else {\n setOptions[options.expiration.type] = options.expiration.value;\n }\n }\n\n // Handle direct expiration properties\n if (options?.EX !== undefined) {\n setOptions.EX = options.EX;\n }\n if (options?.PX !== undefined) {\n setOptions.PX = options.PX;\n }\n if (options?.EXAT !== undefined) {\n setOptions.EXAT = options.EXAT;\n }\n if (options?.PXAT !== undefined) {\n setOptions.PXAT = options.PXAT;\n }\n if (options?.KEEPTTL) {\n setOptions.KEEPTTL = true;\n }\n\n // Handle condition object format\n if (options?.condition === \"NX\") {\n setOptions.NX = true;\n } else if (options?.condition === \"XX\") {\n setOptions.XX = true;\n }\n\n // Handle direct condition properties\n if (options?.NX) {\n setOptions.NX = true;\n }\n if (options?.XX) {\n setOptions.XX = true;\n }\n if (options?.GET) {\n setOptions.GET = true;\n }\n\n const resp = await this.publisher.set(\n key,\n buf,\n Object.keys(setOptions).length > 0 ? setOptions : undefined,\n );\n\n if (resp === \"OK\" || !resp) {\n return buf;\n }\n\n return Buffer.from(resp);\n }\n\n public override async has(key: string): Promise<boolean> {\n const resp = await this.publisher.exists(key);\n return resp > 0;\n }\n\n public override async keys(pattern: string): Promise<string[]> {\n const keys = await this.publisher.keys(pattern);\n return keys.map((key) => key.toString());\n }\n\n public override async del(keys: string[]): Promise<void> {\n if (keys.length === 0) {\n return;\n }\n\n await this.publisher.del(keys);\n }\n\n // ---------------------------------------------------------\n // Queue operations\n // ---------------------------------------------------------\n\n public override async lpush(key: string, value: string): Promise<void> {\n await this.publisher.LPUSH(key, value);\n }\n\n public override async rpop(key: string): Promise<string | undefined> {\n const value = await this.publisher.RPOP(key);\n if (value == null) {\n return undefined;\n }\n return String(value);\n }\n\n // ---------------------------------------------------------\n // Pub/Sub operations\n // ---------------------------------------------------------\n\n public override async publish(\n channel: string,\n message: string,\n ): Promise<void> {\n await this.publisher.publish(channel, message);\n }\n\n /**\n * Get the Redis connection URL.\n */\n protected getUrl(): string {\n // Prefer REDIS_URL if set\n if (this.env.REDIS_URL) {\n return this.env.REDIS_URL;\n }\n\n // Build URL from components\n const url = new URL(\"redis://127.0.0.1:6379\");\n\n if (this.env.REDIS_PASSWORD) {\n url.password = this.env.REDIS_PASSWORD;\n }\n\n if (this.env.REDIS_HOST) {\n url.hostname = this.env.REDIS_HOST;\n }\n\n if (this.env.REDIS_PORT) {\n url.port = String(this.env.REDIS_PORT);\n }\n\n return url.toString();\n }\n\n /**\n * Redis client factory method.\n */\n protected createClient(): NodeRedisClient {\n const client = createClient({\n url: this.getUrl(),\n RESP: 3,\n }).withTypeMapping({\n [RESP_TYPES.BLOB_STRING]: Buffer,\n });\n\n client.on(\"error\", (error) => {\n if (this.alepha.isStarted()) {\n this.log.error(error);\n }\n });\n\n return client;\n }\n}\n","import { $hook, $inject, Alepha } from \"alepha\";\nimport { $logger } from \"alepha/logger\";\nimport {\n type NodeRedisClient,\n NodeRedisProvider,\n} from \"./NodeRedisProvider.ts\";\nimport {\n RedisSubscriberProvider,\n type SubscribeCallback,\n} from \"./RedisSubscriberProvider.ts\";\n\n/**\n * Node.js Redis subscriber provider using `@redis/client`.\n *\n * This provider creates a dedicated Redis connection for subscriptions,\n * as Redis requires separate connections for pub/sub operations.\n *\n * @example\n * ```ts\n * const subscriber = alepha.inject(RedisSubscriberProvider);\n * await subscriber.subscribe(\"channel\", (message, channel) => {\n * console.log(`Received: ${message} on ${channel}`);\n * });\n * ```\n */\nexport class NodeRedisSubscriberProvider extends RedisSubscriberProvider {\n protected readonly log = $logger();\n protected readonly alepha = $inject(Alepha);\n protected readonly redisProvider = $inject(NodeRedisProvider);\n protected readonly client: NodeRedisClient = this.createClient();\n\n public get subscriber(): NodeRedisClient {\n if (!this.client.isReady) {\n throw new Error(\"Redis subscriber client is not ready\");\n }\n\n return this.client;\n }\n\n public override get isReady(): boolean {\n return this.client.isReady;\n }\n\n protected readonly start = $hook({\n on: \"start\",\n handler: () => this.connect(),\n });\n\n protected readonly stop = $hook({\n on: \"stop\",\n handler: () => this.close(),\n });\n\n public override async connect(): Promise<void> {\n this.log.debug(\"Connecting subscriber...\");\n await this.client.connect();\n this.log.info(\"Subscriber connection OK\");\n }\n\n public override async close(): Promise<void> {\n this.log.debug(\"Closing subscriber connection...\");\n await this.subscriber.close();\n this.log.info(\"Subscriber connection closed\");\n }\n\n public override async subscribe(\n channel: string,\n callback: SubscribeCallback,\n ): Promise<void> {\n await this.subscriber.subscribe(channel, callback);\n }\n\n public override async unsubscribe(\n channel: string,\n callback?: SubscribeCallback,\n ): Promise<void> {\n await this.subscriber.unsubscribe(channel, callback);\n }\n\n /**\n * Redis subscriber client factory method.\n */\n protected createClient(): NodeRedisClient {\n const client = this.redisProvider.duplicate();\n\n client.on(\"error\", (error) => {\n if (this.alepha.isStarted()) {\n this.log.error(error);\n }\n });\n\n return client;\n }\n}\n","import { $module, type Alepha } from \"alepha\";\nimport { BunRedisProvider } from \"./providers/BunRedisProvider.ts\";\nimport { BunRedisSubscriberProvider } from \"./providers/BunRedisSubscriberProvider.ts\";\nimport { NodeRedisProvider } from \"./providers/NodeRedisProvider.ts\";\nimport { NodeRedisSubscriberProvider } from \"./providers/NodeRedisSubscriberProvider.ts\";\nimport { RedisProvider } from \"./providers/RedisProvider.ts\";\nimport { RedisSubscriberProvider } from \"./providers/RedisSubscriberProvider.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport * from \"./providers/BunRedisProvider.ts\";\nexport * from \"./providers/BunRedisSubscriberProvider.ts\";\nexport * from \"./providers/NodeRedisProvider.ts\";\nexport * from \"./providers/NodeRedisSubscriberProvider.ts\";\nexport * from \"./providers/RedisProvider.ts\";\nexport * from \"./providers/RedisSubscriberProvider.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\n/**\n * Redis client provider for Alepha applications.\n *\n * Automatically selects the appropriate provider based on runtime:\n * - Bun: Uses `BunRedisProvider` with Bun's native Redis client (7.9x faster than ioredis)\n * - Node.js: Uses `NodeRedisProvider` with `@redis/client`\n *\n * @example\n * ```ts\n * // Inject the abstract provider - runtime selects the implementation\n * const redis = alepha.inject(RedisProvider);\n *\n * // Use common operations\n * await redis.set(\"key\", \"value\");\n * const value = await redis.get(\"key\");\n *\n * // For pub/sub\n * const subscriber = alepha.inject(RedisSubscriberProvider);\n * await subscriber.subscribe(\"channel\", (message, channel) => {\n * console.log(`Received: ${message} on ${channel}`);\n * });\n * ```\n *\n * @see {@link RedisProvider} - Abstract base class\n * @see {@link NodeRedisProvider} - Node.js implementation\n * @see {@link BunRedisProvider} - Bun implementation\n * @see {@link RedisSubscriberProvider} - Abstract subscriber base class\n * @see {@link NodeRedisSubscriberProvider} - Node.js subscriber implementation\n * @see {@link BunRedisSubscriberProvider} - Bun subscriber implementation\n * @module alepha.redis\n */\nexport const AlephaRedis = $module({\n name: \"alepha.redis\",\n services: [\n NodeRedisProvider,\n NodeRedisSubscriberProvider,\n BunRedisProvider,\n BunRedisSubscriberProvider,\n RedisProvider,\n RedisSubscriberProvider,\n ],\n register: (alepha: Alepha) => {\n if (alepha.isBun()) {\n alepha\n .with({\n provide: RedisProvider,\n use: BunRedisProvider,\n })\n .with({\n provide: RedisSubscriberProvider,\n use: BunRedisSubscriberProvider,\n });\n } else {\n alepha\n .with({\n provide: RedisProvider,\n use: NodeRedisProvider,\n })\n .with({\n provide: RedisSubscriberProvider,\n use: NodeRedisSubscriberProvider,\n });\n }\n },\n});\n"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../../src/retry/errors/RetryCancelError.ts","../../src/retry/errors/RetryTimeoutError.ts","../../src/retry/providers/RetryProvider.ts","../../src/retry/primitives/$retry.ts","../../src/retry/index.ts"],"sourcesContent":[],"mappings":";;;;;;cAEa,gBAAA,SAAyB,WAAA;;;;;cCAzB,iBAAA,SAA0B,WAAA;;;;;UCItB;;;;WAIN;EFRE;;;;ACAb;;;;ACIA;;;;EAiCiB,OAAA,CAAA,EAAA,MAAA,GAdI,mBAcJ;EAMG;;;;;EAWY,WAAA,CAAA,EAxBhB,YAwBgB;EAGf;AAgCjB;;;;EAQa,IAAA,CAAA,EAAA,CAAA,KAAA,EA5DI,KA4DJ,EAAA,GAAA,OAAA;EACW;;;;EACnB,OAAA,CAAA,EAAA,CAAA,KAAA,EAxDe,KAwDf,EAAA,OAAA,EAAA,MAAA,EAAA,GAAA,IAAA,EAxDgD,UAwDhD,CAxD2D,CAwD3D,CAAA,EAAA,GAAA,IAAA;EAgHkB;;;WAnKZ;;ACnCX;;;EAEoB,gBAAA,CAAA,EDuCC,WCvCD;;UD0CH,mBAAA;;;AClCjB;;;EA0BgB,OAAA,CAAA,EAAA,MAAA;EAOC;;;;;EAWK,MAAA,CAAA,EAAA,MAAA;EAKT;;;EAGqB,GAAA,CAAA,EAAA,MAAA;EACD;;;;;EAUZ,MAAA,CAAA,EAAA,OAAA;;;;;;AAcJ,cDXJ,aAAA,CCWoB;EACR,mBAAA,GAAA,EDZC,cAAA,CACF,MCWC;EACF,mBAAA,QAAA,EDXM,gBCWN;EAAX;;;EAAgB,KAAA,CAAA,UAAA,CAAA,GAAA,IAAA,EAAA,GAAA,EAAA,EAAA,GAAA,GAAA,CAAA,CAAA,OAAA,EDLf,YCKe,CDLF,CCKE,CAAA,EAAA,GAAA,IAAA,EDJf,UCIe,CDJJ,CCII,CAAA,CAAA,EDHvB,OCGuB,CDHf,UCGe,CDHJ,CCGI,CAAA,CAAA;EADlB;;;iED8Ga;;;;;;AFnNvB;;cGaa;+CACF,sBAAsB,KAC9B,iBAAiB;EFfP,MAAA,EAAA,qBAAkB;;UEuBd;;ADnBjB;;EAmBqB,OAAA,ECIV,CDJU;EAOL;;;;;EAkBL,GAAA,CAAA,EAAA,MAAA;EAMU;;AAGrB;AAgCA;;;EAQ0B,OAAA,CAAA,EAAA,MAAA,GCvDL,mBDuDK;EAAb;;;;;EAER,WAAA,CAAA,EClDW,YDkDX;EAgHkB;;;;;ECtMV,IAAA,CAAA,EAAA,CAAA,KAMZ,EAqCgB,KArChB,EAAA,GAAA,OAAA;EALgC;;;;oBAgDb,iCAAiC,WAAW;;;AAvChE;EAIW,MAAA,CAAA,EAwCA,WAxCA;;AAsBK,cAuBH,cAvBG,CAAA,UAAA,CAAA,GAAA,IAAA,EAAA,GAAA,EAAA,EAAA,GAAA,GAAA,CAAA,SAyBN,SAzBM,CAyBI,qBAzBJ,CAyB0B,CAzB1B,CAAA,CAAA,CAAA;EAOC,mBAAA,aAAA,EAmBiB,aAnBjB;EAMG,UAAA,kBAAA,CAAA,EAca,eAdb;EAA4C,WAAA,CAAA,IAAA,EAgB5C,aAhB4C,CAgB9B,qBAhB8B,CAgBR,CAhBQ,CAAA,CAAA;EAAX,GAAA,CAAA,GAAA,IAAA,EAwBhC,UAxBgC,CAwBrB,CAxBqB,CAAA,CAAA,EAwBhB,OAxBgB,CAwBR,UAxBQ,CAwBG,CAxBH,CAAA,CAAA;;AAK/B,UAiCL,gBAjCK,CAAA,UAAA,CAAA,GAAA,IAAA,EAAA,GAAA,EAAA,EAAA,GAAA,GAAA,CAAA,SAkCZ,cAlCY,CAkCG,CAlCH,CAAA,CAAA;EAKT,CAAA,GAAA,IAAA,EA8BD,UA9Be,CA8BJ,CA9BI,CAAA,CAAA,EA8BC,OA9BD,CA8BS,UA9BT,CA8BoB,CA9BpB,CAAA,CAAA;;;;;;AHxE3B;;;;ACAa,cGiBA,WHjBkB,EGiBP,OAAA,CAAA,OHjB0B,CGqBhD,OAAA,CAJsB,MAAA,CHjB0B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../../src/router/providers/RouterProvider.ts"],"sourcesContent":[],"mappings":";uBAEsB,yBAAyB,QAAQ;EAAjC,UAAA,cAAc,EACR,MADQ;EAAW,UAAA,IAAA,EAG7B,IAH6B,CAGxB,CAHwB,CAAA;EAAQ,UAAA,KAAA,EAItC,GAJsC,CAAA,MAAA,EAItC,UAJsC,CAItC,CAJsC,CAAA,CAAA;EAC3B,KAAA,CAAA,IAAA,EAAA,MAAA,CAAA,EAKE,UALF,CAKa,CALb,CAAA;EAEL,UAAA,IAAA,CAAA,IAAA,EAAA,MAAA,CAAA,EAAA,IAAA;EAAL,UAAA,IAAA,CAAA,KAAA,EAkBM,CAlBN,CAAA,EAAA,IAAA;EACD,UAAA,gBAAA,CAAA,IAAA,EAAA,MAAA,CAAA,EA+E2B,UA/E3B,CA+EsC,CA/EtC,CAAA;EAAA,UAAA,SAAA,CAAA,KAAA,EA2HY,UA3HZ,CA2HuB,CA3HvB,CAAA,CAAA,EA2H4B,UA3H5B,CA2HuC,CA3HvC,CAAA;EAAA,UAAA,WAAA,CAAA,IAAA,EAAA,MAAA,CAAA,EAAA,MAAA,EAAA;;AAEa,UAkJb,UAlJa,CAAA,UAkJQ,KAlJR,CAAA,CAAA;EAeN,KAAA,CAAA,EAoId,CApIc;EA8D+B,MAAA,CAAA,EAuE5C,MAvE4C,CAAA,MAAA,EAAA,MAAA,CAAA;;AA4Cf,UA8BvB,KAAA,CA9BuB;EAAX,IAAA,EAAA,MAAA;EAA2B;;;AAyBxD;;;;EAEiB,SAAA,CAAA,EAaH,MAbG,CAAA,MAAA,EAAA,MAAA,CAAA;AAGjB;AAaiB,UAAA,IAAI,CAAA,UAAW,KAAX,CAAA,CAAA;EAAW,KAAA,CAAA,EACtB,CADsB;EACtB,QAAA,EAAA;IAEc,CAAA,GAAA,EAAA,MAAA,CAAA,EAAL,IAAK,CAAA,CAAA,CAAA;EAAL,CAAA;EAGP,KAAA,CAAA,EAAA;IAGc,KAAA,CAAA,EAHd,CAGc;IAAL,IAAA,EAAA,MAAA;IAIV,QAAA,EAAA;MAAC,CAAA,GAAA,EAAA,MAAA,CAAA,EAJS,IAIT,CAJc,CAId,CAAA;;;;WAAD"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as alepha4 from "alepha";
|
|
2
2
|
import { Alepha, Async, KIND, Primitive, Static } from "alepha";
|
|
3
3
|
import * as alepha_lock0 from "alepha/lock";
|
|
4
4
|
import { DateTime, DateTimeProvider, DurationLike } from "alepha/datetime";
|
|
@@ -23,8 +23,8 @@ declare class CronProvider {
|
|
|
23
23
|
protected readonly log: alepha_logger0.Logger;
|
|
24
24
|
protected readonly cronJobs: Array<CronJob>;
|
|
25
25
|
getCronJobs(): Array<CronJob>;
|
|
26
|
-
protected readonly start:
|
|
27
|
-
protected readonly stop:
|
|
26
|
+
protected readonly start: alepha4.HookPrimitive<"start">;
|
|
27
|
+
protected readonly stop: alepha4.HookPrimitive<"stop">;
|
|
28
28
|
protected boot(name: string | CronJob): void;
|
|
29
29
|
abort(name: string | CronJob): void;
|
|
30
30
|
/**
|
|
@@ -87,8 +87,8 @@ type SchedulerPrimitiveOptions = {
|
|
|
87
87
|
*/
|
|
88
88
|
lock?: boolean;
|
|
89
89
|
};
|
|
90
|
-
declare const envSchema:
|
|
91
|
-
SCHEDULER_PREFIX:
|
|
90
|
+
declare const envSchema: alepha4.TObject<{
|
|
91
|
+
SCHEDULER_PREFIX: alepha4.TOptional<alepha4.TString>;
|
|
92
92
|
}>;
|
|
93
93
|
declare module "alepha" {
|
|
94
94
|
interface Env extends Partial<Static<typeof envSchema>> {}
|
|
@@ -139,7 +139,7 @@ declare module "alepha" {
|
|
|
139
139
|
* @see {@link $scheduler}
|
|
140
140
|
* @module alepha.scheduler
|
|
141
141
|
*/
|
|
142
|
-
declare const AlephaScheduler:
|
|
142
|
+
declare const AlephaScheduler: alepha4.Service<alepha4.Module>;
|
|
143
143
|
//#endregion
|
|
144
144
|
export { $scheduler, AlephaScheduler, CRON, CronJob, CronProvider, SchedulerHandlerArguments, SchedulerPrimitive, SchedulerPrimitiveOptions };
|
|
145
145
|
//# sourceMappingURL=index.d.ts.map
|