semola 0.5.4 → 0.6.0

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.
Files changed (36) hide show
  1. package/README.md +18 -45
  2. package/dist/chunk-CKQMccvm.cjs +28 -0
  3. package/dist/lib/api/index.cjs +29 -15
  4. package/dist/lib/api/index.mjs +30 -16
  5. package/dist/lib/cache/index.cjs +47 -22
  6. package/dist/lib/cache/index.d.cts +3 -24
  7. package/dist/lib/cache/index.d.mts +3 -24
  8. package/dist/lib/cache/index.mjs +48 -23
  9. package/dist/lib/cron/index.cjs +117 -117
  10. package/dist/lib/cron/index.mjs +118 -118
  11. package/dist/lib/errors/index.d.cts +12 -1
  12. package/dist/lib/errors/index.d.mts +12 -1
  13. package/dist/lib/logging/index.cjs +1 -0
  14. package/dist/lib/orm/index.cjs +1642 -0
  15. package/dist/lib/orm/index.d.cts +402 -0
  16. package/dist/lib/orm/index.d.mts +402 -0
  17. package/dist/lib/orm/index.mjs +1630 -0
  18. package/dist/lib/prompts/index.cjs +89 -89
  19. package/dist/lib/prompts/index.d.cts +12 -33
  20. package/dist/lib/prompts/index.d.mts +12 -33
  21. package/dist/lib/prompts/index.mjs +89 -90
  22. package/dist/lib/pubsub/index.cjs +43 -19
  23. package/dist/lib/pubsub/index.d.cts +3 -18
  24. package/dist/lib/pubsub/index.d.mts +3 -18
  25. package/dist/lib/pubsub/index.mjs +44 -20
  26. package/dist/lib/queue/index.cjs +40 -10
  27. package/dist/lib/queue/index.d.cts +11 -4
  28. package/dist/lib/queue/index.d.mts +11 -4
  29. package/dist/lib/queue/index.mjs +39 -11
  30. package/dist/lib/workflow/index.cjs +285 -282
  31. package/dist/lib/workflow/index.d.cts +76 -11
  32. package/dist/lib/workflow/index.d.mts +76 -11
  33. package/dist/lib/workflow/index.mjs +278 -284
  34. package/package.json +11 -1
  35. package/dist/index-BhGNDjPq.d.mts +0 -13
  36. package/dist/index-DxSbeGP-.d.cts +0 -13
package/README.md CHANGED
@@ -27,11 +27,11 @@ Type-safe APIs, Redis queues, pub/sub, i18n, caching & auth with tree-shakeable
27
27
  | **🌍 i18n** | Compile-time validated internationalization | `semola/i18n` |
28
28
  | **💾 Cache** | Redis cache wrapper with TTL & automatic serialization | `semola/cache` |
29
29
  | **⏰ Cron** | In-memory cron scheduler for periodic task execution | `semola/cron` |
30
- | **🔁 Workflow** | Durable resumable workflows with step persistence | `semola/workflow` |
30
+ | **🔁 Workflow** | Durable resumable workflows with retries and hooks | `semola/workflow` |
31
31
  | **⚠️ Errors** | Result-based error handling without try/catch | `semola/errors` |
32
32
  | **📃 Logging** | A simple logging utility | `semola/logging` |
33
33
  | **⌨️ Prompts** | Interactive zero-dependency CLI prompts | `semola/prompts` |
34
- | **🗄️ ORM** | Type-safe data layer with query APIs + migrations | `semola/orm` |
34
+ | **🗄️ ORM** | Type-safe data layer with query APIs | `semola/orm` |
35
35
 
36
36
  ---
37
37
 
@@ -122,16 +122,14 @@ const pubsub = new PubSub({
122
122
  });
123
123
 
124
124
  // Subscribe to messages
125
- const [, unsubscribeHandler] = await pubsub.subscribe((message) => {
125
+ const unsubscribe = await pubsub.subscribe((message) => {
126
126
  console.log("Received:", message);
127
127
  });
128
128
 
129
129
  // Publish a message
130
130
  await pubsub.publish({ userId: 123, text: "New alert!" });
131
131
 
132
- if (unsubscribeHandler) {
133
- await unsubscribeHandler();
134
- }
132
+ await unsubscribe();
135
133
  ```
136
134
 
137
135
  ### Cache Data with TTL
@@ -148,8 +146,8 @@ const cache = new Cache({
148
146
  await cache.set("user:123", { name: "John", age: 30 });
149
147
 
150
148
  // Retrieve data
151
- const [error, user] = await cache.get("user:123");
152
- if (!error) console.log(user);
149
+ const user = await cache.get("user:123");
150
+ console.log(user);
153
151
  ```
154
152
 
155
153
  ### Schedule Recurring Tasks
@@ -172,60 +170,35 @@ cleanup.start();
172
170
  ### Query a Database
173
171
 
174
172
  ```typescript
175
- import { createOrm, createTable, string, uuid } from "semola/orm";
173
+ import { createOrm, defineTable, json, string, uuid } from "semola/orm";
176
174
 
177
- const users = createTable("users", {
178
- id: uuid("id").primaryKey(),
175
+ const users = defineTable("users", {
176
+ id: uuid("id").primaryKey().notNull(),
179
177
  name: string("name").notNull(),
180
178
  email: string("email").unique().notNull(),
179
+ metadata: json<{ plan: string }>("metadata"),
181
180
  });
182
181
 
183
182
  const db = createOrm({
184
- url: "sqlite::memory:",
183
+ adapter: "sqlite",
184
+ url: ":memory:",
185
185
  tables: { users },
186
186
  });
187
187
 
188
- // Result-pattern query
189
- const [findErr, rows] = await db.users.findMany({
188
+ const rows = await db.users.findMany({
190
189
  where: { name: { contains: "John" } },
191
190
  take: 10,
192
191
  });
193
192
 
194
- if (findErr) {
195
- console.error(findErr.type, findErr.message);
196
- }
197
-
198
- // Create record (result pattern)
199
- const [createErr, user] = await db.users.create({
193
+ const user = await db.users.create({
200
194
  data: {
195
+ id: "1",
201
196
  name: "John Doe",
202
197
  email: "john@example.com",
203
198
  },
204
199
  });
205
200
 
206
- // Low-level SQL-style methods are also available
207
- const insertedRows = await db.users.insert({
208
- data: {
209
- name: "Jane Doe",
210
- email: "jane@example.com",
211
- },
212
- returning: true,
213
- });
214
-
215
- console.log(rows, user, createErr, insertedRows);
216
- ```
217
-
218
- ### Run ORM Migrations
219
-
220
- ```bash
221
- # create migration from schema diff
222
- semola orm migrations create add-users
223
-
224
- # apply pending migrations
225
- semola orm migrations apply
226
-
227
- # rollback last applied migration
228
- semola orm migrations rollback
201
+ console.log(rows, user);
229
202
  ```
230
203
 
231
204
  ### Check Permissions
@@ -345,14 +318,14 @@ _Higher is better for req/sec, lower is better for latency._
345
318
  - [Queue](./docs/queue.md) - Redis-backed job queue with timeouts & concurrency
346
319
  - [PubSub](./docs/pubsub.md) - Type-safe Redis pub/sub
347
320
  - [Cron](./docs/cron.md) - In-memory cron scheduler for periodic task execution
348
- - [Workflow](./docs/workflow.md) - Durable and resumable workflows with step persistence
321
+ - [Workflow](./docs/workflow.md) - Durable and resumable workflows with retries and hooks
349
322
  - [Policy](./docs/policy.md) - Policy-based authorization
350
323
  - [i18n](./docs/i18n.md) - Type-safe internationalization
351
324
  - [Cache](./docs/cache.md) - Redis cache wrapper with TTL
352
325
  - [Errors](./docs/errors.md) - Result-based error handling
353
326
  - [Logging](./docs/logging.md) - Logging utility
354
327
  - [Prompts](./docs/prompts.md) - Interactive CLI prompts
355
- - [ORM](./docs/orm.md) - Type-safe data layer, result-pattern DX, and migrations
328
+ - [ORM](./docs/orm.md) - Type-safe data layer with SQLite support
356
329
 
357
330
  ---
358
331
 
@@ -0,0 +1,28 @@
1
+ //#region \0rolldown/runtime.js
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __copyProps = (to, from, except, desc) => {
9
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
10
+ key = keys[i];
11
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
12
+ get: ((k) => from[k]).bind(null, key),
13
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
14
+ });
15
+ }
16
+ return to;
17
+ };
18
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
19
+ value: mod,
20
+ enumerable: true
21
+ }) : target, mod));
22
+ //#endregion
23
+ Object.defineProperty(exports, "__toESM", {
24
+ enumerable: true,
25
+ get: function() {
26
+ return __toESM;
27
+ }
28
+ });
@@ -253,22 +253,36 @@ const generateOpenApiSpec = async (options) => {
253
253
  return spec;
254
254
  };
255
255
  //#endregion
256
+ //#region src/lib/api/errors.ts
257
+ var ParseError = class extends Error {
258
+ constructor(message) {
259
+ super(message);
260
+ this.name = "ParseError";
261
+ }
262
+ };
263
+ var ValidationError = class extends Error {
264
+ constructor(message) {
265
+ super(message);
266
+ this.name = "ValidationError";
267
+ }
268
+ };
269
+ //#endregion
256
270
  //#region src/lib/api/validation/index.ts
257
271
  const validateSchema = async (schema, data) => {
258
272
  const result = await schema["~standard"].validate(data);
259
- if (!result.issues) return require_lib_errors_index.ok(result.value);
260
- return require_lib_errors_index.err("ValidationError", result.issues.map((issue) => {
273
+ if (!result.issues) return result.value;
274
+ throw new ValidationError(result.issues.map((issue) => {
261
275
  let path = "unknown";
262
276
  if (Array.isArray(issue.path)) path = issue.path.map(String).join(".");
263
277
  return `${path}: ${issue.message ?? "validation failed"}`;
264
278
  }).join(", "));
265
279
  };
266
280
  const validateBody = async (req, bodySchema, bodyCache) => {
267
- if (!bodySchema) return require_lib_errors_index.ok(true);
268
- if (!(req.headers.get("content-type") ?? "").includes("application/json")) return require_lib_errors_index.ok(void 0);
281
+ if (!bodySchema) return true;
282
+ if (!(req.headers.get("content-type") ?? "").includes("application/json")) return;
269
283
  if (bodyCache?.parsed) return validateSchema(bodySchema, bodyCache.value);
270
284
  const [parseError, parsedBody] = await require_lib_errors_index.mightThrow(req.json());
271
- if (parseError) return require_lib_errors_index.err("ParseError", "Invalid JSON body");
285
+ if (parseError) throw new ParseError("Invalid JSON body");
272
286
  if (bodyCache) {
273
287
  bodyCache.parsed = true;
274
288
  bodyCache.value = parsedBody;
@@ -276,7 +290,7 @@ const validateBody = async (req, bodySchema, bodyCache) => {
276
290
  return validateSchema(bodySchema, parsedBody);
277
291
  };
278
292
  const validateQuery = async (req, querySchema) => {
279
- if (!querySchema) return require_lib_errors_index.ok(true);
293
+ if (!querySchema) return true;
280
294
  const qIndex = req.url.indexOf("?");
281
295
  if (qIndex === -1) return validateSchema(querySchema, {});
282
296
  const hashIndex = req.url.indexOf("#", qIndex + 1);
@@ -292,7 +306,7 @@ const validateQuery = async (req, querySchema) => {
292
306
  return validateSchema(querySchema, queryParams);
293
307
  };
294
308
  const validateHeaders = async (req, headersSchema) => {
295
- if (!headersSchema) return require_lib_errors_index.ok(true);
309
+ if (!headersSchema) return true;
296
310
  const headers = {};
297
311
  req.headers.forEach((value, key) => {
298
312
  headers[key] = value;
@@ -300,13 +314,13 @@ const validateHeaders = async (req, headersSchema) => {
300
314
  return validateSchema(headersSchema, headers);
301
315
  };
302
316
  const validateCookies = async (req, cookiesSchema) => {
303
- if (!cookiesSchema) return require_lib_errors_index.ok(true);
317
+ if (!cookiesSchema) return true;
304
318
  const cookieHeader = req.headers.get("cookie") ?? "";
305
319
  const cookieMap = new Bun.CookieMap(cookieHeader);
306
320
  return validateSchema(cookiesSchema, Object.fromEntries(cookieMap));
307
321
  };
308
322
  const validateParams = async (req, paramsSchema) => {
309
- if (!paramsSchema) return require_lib_errors_index.ok(true);
323
+ if (!paramsSchema) return true;
310
324
  return validateSchema(paramsSchema, req.params);
311
325
  };
312
326
  //#endregion
@@ -374,7 +388,7 @@ var Api = class {
374
388
  };
375
389
  const v = {};
376
390
  if (schema.body) {
377
- const [err, val] = await validateBody(req, schema.body, bodyCache);
391
+ const [err, val] = await require_lib_errors_index.mightThrow(validateBody(req, schema.body, bodyCache));
378
392
  if (err) return {
379
393
  success: false,
380
394
  error: err
@@ -382,7 +396,7 @@ var Api = class {
382
396
  v.body = val;
383
397
  }
384
398
  if (schema.query) {
385
- const [err, val] = await validateQuery(req, schema.query);
399
+ const [err, val] = await require_lib_errors_index.mightThrow(validateQuery(req, schema.query));
386
400
  if (err) return {
387
401
  success: false,
388
402
  error: err
@@ -390,7 +404,7 @@ var Api = class {
390
404
  v.query = val;
391
405
  }
392
406
  if (schema.headers) {
393
- const [err, val] = await validateHeaders(req, schema.headers);
407
+ const [err, val] = await require_lib_errors_index.mightThrow(validateHeaders(req, schema.headers));
394
408
  if (err) return {
395
409
  success: false,
396
410
  error: err
@@ -398,7 +412,7 @@ var Api = class {
398
412
  v.headers = val;
399
413
  }
400
414
  if (schema.cookies) {
401
- const [err, val] = await validateCookies(req, schema.cookies);
415
+ const [err, val] = await require_lib_errors_index.mightThrow(validateCookies(req, schema.cookies));
402
416
  if (err) return {
403
417
  success: false,
404
418
  error: err
@@ -406,7 +420,7 @@ var Api = class {
406
420
  v.cookies = val;
407
421
  }
408
422
  if (schema.params) {
409
- const [err, val] = await validateParams(req, schema.params);
423
+ const [err, val] = await require_lib_errors_index.mightThrow(validateParams(req, schema.params));
410
424
  if (err) return {
411
425
  success: false,
412
426
  error: err
@@ -433,7 +447,7 @@ var Api = class {
433
447
  if (!(response.headers.get("content-type") ?? "").includes("application/json")) return response;
434
448
  const [parseError, body] = await require_lib_errors_index.mightThrow(response.clone().json());
435
449
  if (parseError) return responseHelpers.json(400, { message: "Invalid response body" });
436
- const [validationError] = await validateSchema(statusSchema, body);
450
+ const [validationError] = await require_lib_errors_index.mightThrow(validateSchema(statusSchema, body));
437
451
  if (validationError) return responseHelpers.json(400, { message: validationError.message });
438
452
  return response;
439
453
  }
@@ -1,4 +1,4 @@
1
- import { err, mightThrow, ok } from "../errors/index.mjs";
1
+ import { mightThrow } from "../errors/index.mjs";
2
2
  //#region src/lib/api/openapi/index.ts
3
3
  const toOpenAPISchema = (schema, io = "input") => ({ schema: schema["~standard"].jsonSchema[io]({ target: "draft-2020-12" }) });
4
4
  const getSchemaDescription = (schema) => {
@@ -252,22 +252,36 @@ const generateOpenApiSpec = async (options) => {
252
252
  return spec;
253
253
  };
254
254
  //#endregion
255
+ //#region src/lib/api/errors.ts
256
+ var ParseError = class extends Error {
257
+ constructor(message) {
258
+ super(message);
259
+ this.name = "ParseError";
260
+ }
261
+ };
262
+ var ValidationError = class extends Error {
263
+ constructor(message) {
264
+ super(message);
265
+ this.name = "ValidationError";
266
+ }
267
+ };
268
+ //#endregion
255
269
  //#region src/lib/api/validation/index.ts
256
270
  const validateSchema = async (schema, data) => {
257
271
  const result = await schema["~standard"].validate(data);
258
- if (!result.issues) return ok(result.value);
259
- return err("ValidationError", result.issues.map((issue) => {
272
+ if (!result.issues) return result.value;
273
+ throw new ValidationError(result.issues.map((issue) => {
260
274
  let path = "unknown";
261
275
  if (Array.isArray(issue.path)) path = issue.path.map(String).join(".");
262
276
  return `${path}: ${issue.message ?? "validation failed"}`;
263
277
  }).join(", "));
264
278
  };
265
279
  const validateBody = async (req, bodySchema, bodyCache) => {
266
- if (!bodySchema) return ok(true);
267
- if (!(req.headers.get("content-type") ?? "").includes("application/json")) return ok(void 0);
280
+ if (!bodySchema) return true;
281
+ if (!(req.headers.get("content-type") ?? "").includes("application/json")) return;
268
282
  if (bodyCache?.parsed) return validateSchema(bodySchema, bodyCache.value);
269
283
  const [parseError, parsedBody] = await mightThrow(req.json());
270
- if (parseError) return err("ParseError", "Invalid JSON body");
284
+ if (parseError) throw new ParseError("Invalid JSON body");
271
285
  if (bodyCache) {
272
286
  bodyCache.parsed = true;
273
287
  bodyCache.value = parsedBody;
@@ -275,7 +289,7 @@ const validateBody = async (req, bodySchema, bodyCache) => {
275
289
  return validateSchema(bodySchema, parsedBody);
276
290
  };
277
291
  const validateQuery = async (req, querySchema) => {
278
- if (!querySchema) return ok(true);
292
+ if (!querySchema) return true;
279
293
  const qIndex = req.url.indexOf("?");
280
294
  if (qIndex === -1) return validateSchema(querySchema, {});
281
295
  const hashIndex = req.url.indexOf("#", qIndex + 1);
@@ -291,7 +305,7 @@ const validateQuery = async (req, querySchema) => {
291
305
  return validateSchema(querySchema, queryParams);
292
306
  };
293
307
  const validateHeaders = async (req, headersSchema) => {
294
- if (!headersSchema) return ok(true);
308
+ if (!headersSchema) return true;
295
309
  const headers = {};
296
310
  req.headers.forEach((value, key) => {
297
311
  headers[key] = value;
@@ -299,13 +313,13 @@ const validateHeaders = async (req, headersSchema) => {
299
313
  return validateSchema(headersSchema, headers);
300
314
  };
301
315
  const validateCookies = async (req, cookiesSchema) => {
302
- if (!cookiesSchema) return ok(true);
316
+ if (!cookiesSchema) return true;
303
317
  const cookieHeader = req.headers.get("cookie") ?? "";
304
318
  const cookieMap = new Bun.CookieMap(cookieHeader);
305
319
  return validateSchema(cookiesSchema, Object.fromEntries(cookieMap));
306
320
  };
307
321
  const validateParams = async (req, paramsSchema) => {
308
- if (!paramsSchema) return ok(true);
322
+ if (!paramsSchema) return true;
309
323
  return validateSchema(paramsSchema, req.params);
310
324
  };
311
325
  //#endregion
@@ -373,7 +387,7 @@ var Api = class {
373
387
  };
374
388
  const v = {};
375
389
  if (schema.body) {
376
- const [err, val] = await validateBody(req, schema.body, bodyCache);
390
+ const [err, val] = await mightThrow(validateBody(req, schema.body, bodyCache));
377
391
  if (err) return {
378
392
  success: false,
379
393
  error: err
@@ -381,7 +395,7 @@ var Api = class {
381
395
  v.body = val;
382
396
  }
383
397
  if (schema.query) {
384
- const [err, val] = await validateQuery(req, schema.query);
398
+ const [err, val] = await mightThrow(validateQuery(req, schema.query));
385
399
  if (err) return {
386
400
  success: false,
387
401
  error: err
@@ -389,7 +403,7 @@ var Api = class {
389
403
  v.query = val;
390
404
  }
391
405
  if (schema.headers) {
392
- const [err, val] = await validateHeaders(req, schema.headers);
406
+ const [err, val] = await mightThrow(validateHeaders(req, schema.headers));
393
407
  if (err) return {
394
408
  success: false,
395
409
  error: err
@@ -397,7 +411,7 @@ var Api = class {
397
411
  v.headers = val;
398
412
  }
399
413
  if (schema.cookies) {
400
- const [err, val] = await validateCookies(req, schema.cookies);
414
+ const [err, val] = await mightThrow(validateCookies(req, schema.cookies));
401
415
  if (err) return {
402
416
  success: false,
403
417
  error: err
@@ -405,7 +419,7 @@ var Api = class {
405
419
  v.cookies = val;
406
420
  }
407
421
  if (schema.params) {
408
- const [err, val] = await validateParams(req, schema.params);
422
+ const [err, val] = await mightThrow(validateParams(req, schema.params));
409
423
  if (err) return {
410
424
  success: false,
411
425
  error: err
@@ -432,7 +446,7 @@ var Api = class {
432
446
  if (!(response.headers.get("content-type") ?? "").includes("application/json")) return response;
433
447
  const [parseError, body] = await mightThrow(response.clone().json());
434
448
  if (parseError) return responseHelpers.json(400, { message: "Invalid response body" });
435
- const [validationError] = await validateSchema(statusSchema, body);
449
+ const [validationError] = await mightThrow(validateSchema(statusSchema, body));
436
450
  if (validationError) return responseHelpers.json(400, { message: validationError.message });
437
451
  return response;
438
452
  }
@@ -1,5 +1,37 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_lib_errors_index = require("../errors/index.cjs");
3
+ //#region src/lib/cache/errors.ts
4
+ var CacheError = class extends Error {
5
+ constructor(message) {
6
+ super(message);
7
+ this.name = "CacheError";
8
+ }
9
+ };
10
+ var InvalidTTLError = class extends Error {
11
+ constructor(message) {
12
+ super(message);
13
+ this.name = "InvalidTTLError";
14
+ }
15
+ };
16
+ var NotFoundError = class extends Error {
17
+ constructor(message) {
18
+ super(message);
19
+ this.name = "NotFoundError";
20
+ }
21
+ };
22
+ var SerializationError = class extends Error {
23
+ constructor(message) {
24
+ super(message);
25
+ this.name = "SerializationError";
26
+ }
27
+ };
28
+ var DeserializationError = class extends Error {
29
+ constructor(message) {
30
+ super(message);
31
+ this.name = "DeserializationError";
32
+ }
33
+ };
34
+ //#endregion
3
35
  //#region src/lib/cache/index.ts
4
36
  var Cache = class {
5
37
  options;
@@ -11,41 +43,34 @@ var Cache = class {
11
43
  this.deserialize = options.deserializer ?? ((raw) => JSON.parse(raw));
12
44
  }
13
45
  async get(key) {
14
- if (!this.isEnabled) return this.fail("NotFoundError", `Key ${key} not found`);
46
+ if (!this.isEnabled) throw new NotFoundError(`Key ${key} not found`);
15
47
  const resolvedKey = this.resolveKey(key);
16
48
  const [error, value] = await require_lib_errors_index.mightThrow(this.options.redis.get(resolvedKey));
17
- if (error) return this.fail("CacheError", `Unable to get value for key ${key}`);
18
- if (value === null || value === void 0) return this.fail("NotFoundError", `Key ${key} not found`);
49
+ if (error) throw new CacheError(`Unable to get value for key ${key}`);
50
+ if (value === null || value === void 0) throw new NotFoundError(`Key ${key} not found`);
19
51
  const [deserializeErr, deserialized] = require_lib_errors_index.mightThrowSync(() => this.deserialize(value));
20
- if (deserializeErr) return this.fail("CacheError", `Unable to deserialize value for key ${key}`);
21
- return require_lib_errors_index.ok(deserialized);
52
+ if (deserializeErr) throw new DeserializationError(`Unable to deserialize value for key ${key}`);
53
+ return deserialized;
22
54
  }
23
55
  async set(key, value) {
24
- if (!this.isEnabled) return require_lib_errors_index.ok(value);
56
+ if (!this.isEnabled) return value;
25
57
  const [serializeErr, serialized] = require_lib_errors_index.mightThrowSync(() => this.serialize(value));
26
- if (serializeErr) return this.fail("CacheError", `Unable to serialize value for key ${key}`);
27
- if (serialized === null || serialized === void 0) return this.fail("CacheError", `Unable to serialize value for key ${key}`);
58
+ if (serializeErr) throw new SerializationError(`Unable to serialize value for key ${key}`);
59
+ if (serialized === null || serialized === void 0) throw new SerializationError(`Unable to serialize value for key ${key}`);
28
60
  const [ttlErr, ttl] = require_lib_errors_index.mightThrowSync(() => this.resolveTTL(key, value));
29
- if (ttlErr) return this.fail("InvalidTTLError", `Unable to resolve ttl for key ${key}`);
30
- if (!this.isTTLValid(ttl)) return this.fail("InvalidTTLError", `Unable to save records with ttl equal to ${ttl}`);
61
+ if (ttlErr) throw new InvalidTTLError(`Unable to resolve ttl for key ${key}`);
62
+ if (!this.isTTLValid(ttl)) throw new InvalidTTLError(`Unable to save records with ttl equal to ${ttl}`);
31
63
  const resolvedKey = this.resolveKey(key);
32
64
  const [setError] = await require_lib_errors_index.mightThrow(this.getSetPromise(resolvedKey, serialized, ttl));
33
- if (setError) return this.fail("CacheError", `Unable to set value for key ${key}`);
34
- return require_lib_errors_index.ok(value);
65
+ if (setError) throw new CacheError(`Unable to set value for key ${key}`);
66
+ return value;
35
67
  }
36
68
  async delete(key) {
37
- if (!this.isEnabled) return require_lib_errors_index.ok(0);
69
+ if (!this.isEnabled) return 0;
38
70
  const resolvedKey = this.resolveKey(key);
39
71
  const [error, data] = await require_lib_errors_index.mightThrow(this.options.redis.del(resolvedKey));
40
- if (error) return this.fail("CacheError", `Unable to delete key ${key}`);
41
- return require_lib_errors_index.ok(data);
42
- }
43
- fail(type, message) {
44
- this.options.onError?.({
45
- type,
46
- message
47
- });
48
- return require_lib_errors_index.err(type, message);
72
+ if (error) throw new CacheError(`Unable to delete key ${key}`);
73
+ return data;
49
74
  }
50
75
  get isEnabled() {
51
76
  return this.options.enabled !== false;
@@ -1,5 +1,4 @@
1
1
  //#region src/lib/cache/types.d.ts
2
- type CacheError = "CacheError" | "InvalidTTLError" | "NotFoundError";
3
2
  type CacheOptions<T> = {
4
3
  redis: Bun.RedisClient;
5
4
  ttl?: number | ((key: string, value: T) => number);
@@ -7,10 +6,6 @@ type CacheOptions<T> = {
7
6
  prefix?: string;
8
7
  serializer?: (value: T) => string;
9
8
  deserializer?: (raw: string) => T;
10
- onError?: (error: {
11
- type: CacheError;
12
- message: string;
13
- }) => void;
14
9
  };
15
10
  //#endregion
16
11
  //#region src/lib/cache/index.d.ts
@@ -19,25 +14,9 @@ declare class Cache<T> {
19
14
  private serialize;
20
15
  private deserialize;
21
16
  constructor(options: CacheOptions<T>);
22
- get(key: string): Promise<readonly [{
23
- readonly type: "NotFoundError";
24
- readonly message: string;
25
- }, null] | readonly [{
26
- readonly type: "CacheError";
27
- readonly message: string;
28
- }, null] | readonly [null, T]>;
29
- set(key: string, value: T): Promise<readonly [{
30
- readonly type: "CacheError";
31
- readonly message: string;
32
- }, null] | readonly [null, T] | readonly [{
33
- readonly type: "InvalidTTLError";
34
- readonly message: string;
35
- }, null]>;
36
- delete(key: string): Promise<readonly [null, number] | readonly [{
37
- readonly type: "CacheError";
38
- readonly message: string;
39
- }, null]>;
40
- private fail;
17
+ get(key: string): Promise<T>;
18
+ set(key: string, value: T): Promise<T>;
19
+ delete(key: string): Promise<number>;
41
20
  private get isEnabled();
42
21
  private resolveKey;
43
22
  private resolveTTL;
@@ -1,5 +1,4 @@
1
1
  //#region src/lib/cache/types.d.ts
2
- type CacheError = "CacheError" | "InvalidTTLError" | "NotFoundError";
3
2
  type CacheOptions<T> = {
4
3
  redis: Bun.RedisClient;
5
4
  ttl?: number | ((key: string, value: T) => number);
@@ -7,10 +6,6 @@ type CacheOptions<T> = {
7
6
  prefix?: string;
8
7
  serializer?: (value: T) => string;
9
8
  deserializer?: (raw: string) => T;
10
- onError?: (error: {
11
- type: CacheError;
12
- message: string;
13
- }) => void;
14
9
  };
15
10
  //#endregion
16
11
  //#region src/lib/cache/index.d.ts
@@ -19,25 +14,9 @@ declare class Cache<T> {
19
14
  private serialize;
20
15
  private deserialize;
21
16
  constructor(options: CacheOptions<T>);
22
- get(key: string): Promise<readonly [{
23
- readonly type: "NotFoundError";
24
- readonly message: string;
25
- }, null] | readonly [{
26
- readonly type: "CacheError";
27
- readonly message: string;
28
- }, null] | readonly [null, T]>;
29
- set(key: string, value: T): Promise<readonly [{
30
- readonly type: "CacheError";
31
- readonly message: string;
32
- }, null] | readonly [null, T] | readonly [{
33
- readonly type: "InvalidTTLError";
34
- readonly message: string;
35
- }, null]>;
36
- delete(key: string): Promise<readonly [null, number] | readonly [{
37
- readonly type: "CacheError";
38
- readonly message: string;
39
- }, null]>;
40
- private fail;
17
+ get(key: string): Promise<T>;
18
+ set(key: string, value: T): Promise<T>;
19
+ delete(key: string): Promise<number>;
41
20
  private get isEnabled();
42
21
  private resolveKey;
43
22
  private resolveTTL;