@http-client-toolkit/store-sqlite 0.0.1 → 0.2.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.
package/lib/index.cjs CHANGED
@@ -7,9 +7,11 @@ var sqliteCore = require('drizzle-orm/sqlite-core');
7
7
  var crypto = require('crypto');
8
8
  var core = require('@http-client-toolkit/core');
9
9
 
10
- function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
10
+ function _interopDefault(e) {
11
+ return e && e.__esModule ? e : { default: e };
12
+ }
11
13
 
12
- var Database__default = /*#__PURE__*/_interopDefault(Database);
14
+ var Database__default = /*#__PURE__*/ _interopDefault(Database);
13
15
 
14
16
  var __async = (__this, __arguments, generator) => {
15
17
  return new Promise((resolve, reject) => {
@@ -27,48 +29,51 @@ var __async = (__this, __arguments, generator) => {
27
29
  reject(e);
28
30
  }
29
31
  };
30
- var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
32
+ var step = (x) =>
33
+ x.done
34
+ ? resolve(x.value)
35
+ : Promise.resolve(x.value).then(fulfilled, rejected);
31
36
  step((generator = generator.apply(__this, __arguments)).next());
32
37
  });
33
38
  };
34
- var cacheTable = sqliteCore.sqliteTable("cache", {
35
- hash: sqliteCore.text("hash").primaryKey(),
36
- value: sqliteCore.blob("value", { mode: "json" }).notNull(),
37
- expiresAt: sqliteCore.integer("expires_at").notNull(),
38
- createdAt: sqliteCore.integer("created_at").notNull()
39
+ var cacheTable = sqliteCore.sqliteTable('cache', {
40
+ hash: sqliteCore.text('hash').primaryKey(),
41
+ value: sqliteCore.blob('value', { mode: 'json' }).notNull(),
42
+ expiresAt: sqliteCore.integer('expires_at').notNull(),
43
+ createdAt: sqliteCore.integer('created_at').notNull(),
39
44
  });
40
- var dedupeTable = sqliteCore.sqliteTable("dedupe_jobs", {
41
- hash: sqliteCore.text("hash").primaryKey(),
42
- jobId: sqliteCore.text("job_id").notNull(),
43
- status: sqliteCore.text("status").notNull(),
45
+ var dedupeTable = sqliteCore.sqliteTable('dedupe_jobs', {
46
+ hash: sqliteCore.text('hash').primaryKey(),
47
+ jobId: sqliteCore.text('job_id').notNull(),
48
+ status: sqliteCore.text('status').notNull(),
44
49
  // 'pending', 'completed', 'failed'
45
- result: sqliteCore.blob("result", { mode: "json" }),
46
- error: sqliteCore.text("error"),
47
- createdAt: sqliteCore.integer("created_at").notNull(),
48
- updatedAt: sqliteCore.integer("updated_at").notNull()
50
+ result: sqliteCore.blob('result', { mode: 'json' }),
51
+ error: sqliteCore.text('error'),
52
+ createdAt: sqliteCore.integer('created_at').notNull(),
53
+ updatedAt: sqliteCore.integer('updated_at').notNull(),
49
54
  });
50
- var rateLimitTable = sqliteCore.sqliteTable("rate_limits", {
51
- resource: sqliteCore.text("resource").notNull(),
52
- timestamp: sqliteCore.integer("timestamp").notNull(),
53
- id: sqliteCore.integer("id").primaryKey({ autoIncrement: true })
55
+ var rateLimitTable = sqliteCore.sqliteTable('rate_limits', {
56
+ resource: sqliteCore.text('resource').notNull(),
57
+ timestamp: sqliteCore.integer('timestamp').notNull(),
58
+ id: sqliteCore.integer('id').primaryKey({ autoIncrement: true }),
54
59
  });
55
60
 
56
61
  // src/sqlite-cache-store.ts
57
62
  var SQLiteCacheStore = class {
58
63
  constructor({
59
64
  /** File path or existing `better-sqlite3` connection. Defaults to `':memory:'`. */
60
- database = ":memory:",
65
+ database = ':memory:',
61
66
  /** Cleanup interval in milliseconds. Defaults to 1 minute. */
62
67
  cleanupIntervalMs = 6e4,
63
68
  /** Maximum allowed size (in bytes) for a single cache entry. Defaults to 5 MiB. */
64
- maxEntrySizeBytes = 5 * 1024 * 1024
69
+ maxEntrySizeBytes = 5 * 1024 * 1024,
65
70
  } = {}) {
66
71
  /** Indicates whether this store is responsible for managing (and therefore closing) the SQLite connection */
67
72
  this.isConnectionManaged = false;
68
73
  this.isDestroyed = false;
69
74
  let sqliteInstance;
70
75
  let isConnectionManaged = false;
71
- if (typeof database === "string") {
76
+ if (typeof database === 'string') {
72
77
  sqliteInstance = new Database__default.default(database);
73
78
  isConnectionManaged = true;
74
79
  } else {
@@ -85,9 +90,13 @@ var SQLiteCacheStore = class {
85
90
  get(hash) {
86
91
  return __async(this, null, function* () {
87
92
  if (this.isDestroyed) {
88
- throw new Error("Cache store has been destroyed");
93
+ throw new Error('Cache store has been destroyed');
89
94
  }
90
- const result = yield this.db.select().from(cacheTable).where(drizzleOrm.eq(cacheTable.hash, hash)).limit(1);
95
+ const result = yield this.db
96
+ .select()
97
+ .from(cacheTable)
98
+ .where(drizzleOrm.eq(cacheTable.hash, hash))
99
+ .limit(1);
91
100
  if (result.length === 0) {
92
101
  return void 0;
93
102
  }
@@ -97,16 +106,20 @@ var SQLiteCacheStore = class {
97
106
  }
98
107
  const now = Date.now();
99
108
  if (item.expiresAt > 0 && now >= item.expiresAt) {
100
- yield this.db.delete(cacheTable).where(drizzleOrm.eq(cacheTable.hash, hash));
109
+ yield this.db
110
+ .delete(cacheTable)
111
+ .where(drizzleOrm.eq(cacheTable.hash, hash));
101
112
  return void 0;
102
113
  }
103
114
  try {
104
- if (item.value === "__UNDEFINED__") {
115
+ if (item.value === '__UNDEFINED__') {
105
116
  return void 0;
106
117
  }
107
118
  return JSON.parse(item.value);
108
119
  } catch (e) {
109
- yield this.db.delete(cacheTable).where(drizzleOrm.eq(cacheTable.hash, hash));
120
+ yield this.db
121
+ .delete(cacheTable)
122
+ .where(drizzleOrm.eq(cacheTable.hash, hash));
110
123
  return void 0;
111
124
  }
112
125
  });
@@ -114,52 +127,58 @@ var SQLiteCacheStore = class {
114
127
  set(hash, value, ttlSeconds) {
115
128
  return __async(this, null, function* () {
116
129
  if (this.isDestroyed) {
117
- throw new Error("Cache store has been destroyed");
130
+ throw new Error('Cache store has been destroyed');
118
131
  }
119
132
  const now = Date.now();
120
- const expiresAt = ttlSeconds < 0 ? now : ttlSeconds === 0 ? 0 : now + ttlSeconds * 1e3;
133
+ const expiresAt =
134
+ ttlSeconds < 0 ? now : ttlSeconds === 0 ? 0 : now + ttlSeconds * 1e3;
121
135
  let serializedValue;
122
136
  try {
123
137
  if (value === void 0) {
124
- serializedValue = "__UNDEFINED__";
138
+ serializedValue = '__UNDEFINED__';
125
139
  } else {
126
140
  serializedValue = JSON.stringify(value);
127
141
  }
128
142
  } catch (error) {
129
143
  throw new Error(
130
- `Failed to serialize value: ${error instanceof Error ? error.message : String(error)}`
144
+ `Failed to serialize value: ${error instanceof Error ? error.message : String(error)}`,
131
145
  );
132
146
  }
133
- if (Buffer.byteLength(serializedValue, "utf8") > this.maxEntrySizeBytes) {
147
+ if (Buffer.byteLength(serializedValue, 'utf8') > this.maxEntrySizeBytes) {
134
148
  return;
135
149
  }
136
- yield this.db.insert(cacheTable).values({
137
- hash,
138
- value: serializedValue,
139
- expiresAt,
140
- createdAt: now
141
- }).onConflictDoUpdate({
142
- target: cacheTable.hash,
143
- set: {
150
+ yield this.db
151
+ .insert(cacheTable)
152
+ .values({
153
+ hash,
144
154
  value: serializedValue,
145
155
  expiresAt,
146
- createdAt: now
147
- }
148
- });
156
+ createdAt: now,
157
+ })
158
+ .onConflictDoUpdate({
159
+ target: cacheTable.hash,
160
+ set: {
161
+ value: serializedValue,
162
+ expiresAt,
163
+ createdAt: now,
164
+ },
165
+ });
149
166
  });
150
167
  }
151
168
  delete(hash) {
152
169
  return __async(this, null, function* () {
153
170
  if (this.isDestroyed) {
154
- throw new Error("Cache store has been destroyed");
171
+ throw new Error('Cache store has been destroyed');
155
172
  }
156
- yield this.db.delete(cacheTable).where(drizzleOrm.eq(cacheTable.hash, hash));
173
+ yield this.db
174
+ .delete(cacheTable)
175
+ .where(drizzleOrm.eq(cacheTable.hash, hash));
157
176
  });
158
177
  }
159
178
  clear() {
160
179
  return __async(this, null, function* () {
161
180
  if (this.isDestroyed) {
162
- throw new Error("Cache store has been destroyed");
181
+ throw new Error('Cache store has been destroyed');
163
182
  }
164
183
  yield this.db.delete(cacheTable);
165
184
  });
@@ -171,19 +190,37 @@ var SQLiteCacheStore = class {
171
190
  return __async(this, null, function* () {
172
191
  var _a, _b, _c, _d;
173
192
  const now = Date.now();
174
- const totalResult = yield this.db.select({ count: drizzleOrm.count() }).from(cacheTable);
175
- const expiredResult = yield this.db.select({ count: drizzleOrm.count() }).from(cacheTable).where(drizzleOrm.and(drizzleOrm.gt(cacheTable.expiresAt, 0), drizzleOrm.lt(cacheTable.expiresAt, now)));
193
+ const totalResult = yield this.db
194
+ .select({ count: drizzleOrm.count() })
195
+ .from(cacheTable);
196
+ const expiredResult = yield this.db
197
+ .select({ count: drizzleOrm.count() })
198
+ .from(cacheTable)
199
+ .where(
200
+ drizzleOrm.and(
201
+ drizzleOrm.gt(cacheTable.expiresAt, 0),
202
+ drizzleOrm.lt(cacheTable.expiresAt, now),
203
+ ),
204
+ );
176
205
  const pageCount = Number(
177
- this.sqlite.pragma("page_count", { simple: true })
206
+ this.sqlite.pragma('page_count', { simple: true }),
207
+ );
208
+ const pageSize = Number(
209
+ this.sqlite.pragma('page_size', { simple: true }),
178
210
  );
179
- const pageSize = Number(this.sqlite.pragma("page_size", { simple: true }));
180
211
  const safePageCount = Number.isFinite(pageCount) ? pageCount : 0;
181
212
  const safePageSize = Number.isFinite(pageSize) ? pageSize : 0;
182
- const databaseSizeKB = Math.round(safePageCount * safePageSize / 1024);
213
+ const databaseSizeKB = Math.round((safePageCount * safePageSize) / 1024);
183
214
  return {
184
215
  databaseSizeKB,
185
- expiredItems: (_b = (_a = expiredResult[0]) == null ? void 0 : _a.count) != null ? _b : 0,
186
- totalItems: (_d = (_c = totalResult[0]) == null ? void 0 : _c.count) != null ? _d : 0
216
+ expiredItems:
217
+ (_b = (_a = expiredResult[0]) == null ? void 0 : _a.count) != null
218
+ ? _b
219
+ : 0,
220
+ totalItems:
221
+ (_d = (_c = totalResult[0]) == null ? void 0 : _c.count) != null
222
+ ? _d
223
+ : 0,
187
224
  };
188
225
  });
189
226
  }
@@ -193,7 +230,14 @@ var SQLiteCacheStore = class {
193
230
  cleanup() {
194
231
  return __async(this, null, function* () {
195
232
  const now = Date.now();
196
- yield this.db.delete(cacheTable).where(drizzleOrm.and(drizzleOrm.gt(cacheTable.expiresAt, 0), drizzleOrm.lt(cacheTable.expiresAt, now)));
233
+ yield this.db
234
+ .delete(cacheTable)
235
+ .where(
236
+ drizzleOrm.and(
237
+ drizzleOrm.gt(cacheTable.expiresAt, 0),
238
+ drizzleOrm.lt(cacheTable.expiresAt, now),
239
+ ),
240
+ );
197
241
  });
198
242
  }
199
243
  /**
@@ -206,7 +250,7 @@ var SQLiteCacheStore = class {
206
250
  this.cleanupInterval = void 0;
207
251
  }
208
252
  this.isDestroyed = true;
209
- if (this.isConnectionManaged && typeof this.sqlite.close === "function") {
253
+ if (this.isConnectionManaged && typeof this.sqlite.close === 'function') {
210
254
  this.sqlite.close();
211
255
  }
212
256
  });
@@ -234,24 +278,30 @@ var SQLiteCacheStore = class {
234
278
  if (this.cleanupIntervalMs <= 0) {
235
279
  return;
236
280
  }
237
- this.cleanupInterval = setInterval(() => __async(this, null, function* () {
238
- yield this.cleanup();
239
- }), this.cleanupIntervalMs);
240
- if (typeof this.cleanupInterval.unref === "function") {
281
+ this.cleanupInterval = setInterval(
282
+ () =>
283
+ __async(this, null, function* () {
284
+ yield this.cleanup();
285
+ }),
286
+ this.cleanupIntervalMs,
287
+ );
288
+ if (typeof this.cleanupInterval.unref === 'function') {
241
289
  this.cleanupInterval.unref();
242
290
  }
243
291
  }
244
292
  cleanupExpiredItems() {
245
293
  return __async(this, null, function* () {
246
294
  const now = Date.now();
247
- yield this.db.delete(cacheTable).where(drizzleOrm.lt(cacheTable.expiresAt, now));
295
+ yield this.db
296
+ .delete(cacheTable)
297
+ .where(drizzleOrm.lt(cacheTable.expiresAt, now));
248
298
  });
249
299
  }
250
300
  };
251
301
  var SQLiteDedupeStore = class {
252
302
  constructor({
253
303
  /** File path or existing `better-sqlite3` Database instance. Defaults to `':memory:'`. */
254
- database = ":memory:",
304
+ database = ':memory:',
255
305
  /** Job timeout in milliseconds. Preferred over timeoutMs. */
256
306
  jobTimeoutMs,
257
307
  /** Legacy alias for jobTimeoutMs. */
@@ -259,7 +309,7 @@ var SQLiteDedupeStore = class {
259
309
  /** Cleanup interval in milliseconds. Defaults to 1 minute. */
260
310
  cleanupIntervalMs = 6e4,
261
311
  /** Poll interval for checking pending jobs in milliseconds. Defaults to 100ms. */
262
- pollIntervalMs = 100
312
+ pollIntervalMs = 100,
263
313
  } = {}) {
264
314
  /** Indicates whether this store manages (and should close) the SQLite connection */
265
315
  this.isConnectionManaged = false;
@@ -269,7 +319,7 @@ var SQLiteDedupeStore = class {
269
319
  var _a;
270
320
  let sqliteInstance;
271
321
  let isConnectionManaged = false;
272
- if (typeof database === "string") {
322
+ if (typeof database === 'string') {
273
323
  sqliteInstance = new Database__default.default(database);
274
324
  isConnectionManaged = true;
275
325
  } else {
@@ -278,7 +328,8 @@ var SQLiteDedupeStore = class {
278
328
  this.sqlite = sqliteInstance;
279
329
  this.isConnectionManaged = isConnectionManaged;
280
330
  this.db = betterSqlite3.drizzle(sqliteInstance);
281
- this.jobTimeoutMs = (_a = timeoutMs != null ? timeoutMs : jobTimeoutMs) != null ? _a : 3e5;
331
+ this.jobTimeoutMs =
332
+ (_a = timeoutMs != null ? timeoutMs : jobTimeoutMs) != null ? _a : 3e5;
282
333
  this.cleanupIntervalMs = cleanupIntervalMs;
283
334
  this.pollIntervalMs = pollIntervalMs;
284
335
  this.initializeDatabase();
@@ -287,10 +338,9 @@ var SQLiteDedupeStore = class {
287
338
  startCleanupInterval() {
288
339
  if (this.cleanupIntervalMs > 0) {
289
340
  this.cleanupInterval = setInterval(() => {
290
- this.cleanupExpiredJobs().catch(() => {
291
- });
341
+ this.cleanupExpiredJobs().catch(() => {});
292
342
  }, this.cleanupIntervalMs);
293
- if (typeof this.cleanupInterval.unref === "function") {
343
+ if (typeof this.cleanupInterval.unref === 'function') {
294
344
  this.cleanupInterval.unref();
295
345
  }
296
346
  }
@@ -303,18 +353,20 @@ var SQLiteDedupeStore = class {
303
353
  }
304
354
  const now = Date.now();
305
355
  const expiredThreshold = now - this.jobTimeoutMs;
306
- yield this.db.delete(dedupeTable).where(
307
- drizzleOrm.and(
308
- drizzleOrm.eq(dedupeTable.status, "pending"),
309
- drizzleOrm.lt(dedupeTable.createdAt, expiredThreshold)
310
- )
311
- );
356
+ yield this.db
357
+ .delete(dedupeTable)
358
+ .where(
359
+ drizzleOrm.and(
360
+ drizzleOrm.eq(dedupeTable.status, 'pending'),
361
+ drizzleOrm.lt(dedupeTable.createdAt, expiredThreshold),
362
+ ),
363
+ );
312
364
  });
313
365
  }
314
366
  waitFor(hash) {
315
367
  return __async(this, null, function* () {
316
368
  if (this.isDestroyed) {
317
- throw new Error("Dedupe store has been destroyed");
369
+ throw new Error('Dedupe store has been destroyed');
318
370
  }
319
371
  const existingPromise = this.jobPromises.get(hash);
320
372
  if (existingPromise) {
@@ -322,7 +374,11 @@ var SQLiteDedupeStore = class {
322
374
  }
323
375
  let result;
324
376
  try {
325
- result = yield this.db.select().from(dedupeTable).where(drizzleOrm.eq(dedupeTable.hash, hash)).limit(1);
377
+ result = yield this.db
378
+ .select()
379
+ .from(dedupeTable)
380
+ .where(drizzleOrm.eq(dedupeTable.hash, hash))
381
+ .limit(1);
326
382
  } catch (e) {
327
383
  return void 0;
328
384
  }
@@ -333,10 +389,10 @@ var SQLiteDedupeStore = class {
333
389
  if (!job) {
334
390
  return void 0;
335
391
  }
336
- if (job.status === "completed") {
392
+ if (job.status === 'completed') {
337
393
  return this.deserializeResult(job.result);
338
394
  }
339
- if (job.status === "failed") {
395
+ if (job.status === 'failed') {
340
396
  return void 0;
341
397
  }
342
398
  const promise = new Promise((resolve) => {
@@ -356,43 +412,53 @@ var SQLiteDedupeStore = class {
356
412
  resolve(value);
357
413
  };
358
414
  this.jobSettlers.set(hash, settle);
359
- const poll = () => __async(this, null, function* () {
360
- if (this.isDestroyed) {
361
- settle(void 0);
362
- return;
363
- }
364
- try {
365
- const latest = yield this.db.select().from(dedupeTable).where(drizzleOrm.eq(dedupeTable.hash, hash)).limit(1);
366
- const latestJob = latest[0];
367
- if (!latestJob) {
368
- settle(void 0);
369
- return;
370
- }
371
- const isExpired = this.jobTimeoutMs > 0 && Date.now() - latestJob.createdAt >= this.jobTimeoutMs;
372
- if (isExpired) {
373
- yield this.db.update(dedupeTable).set({
374
- status: "failed",
375
- error: "Job timed out",
376
- updatedAt: Date.now()
377
- }).where(drizzleOrm.eq(dedupeTable.hash, hash));
415
+ const poll = () =>
416
+ __async(this, null, function* () {
417
+ if (this.isDestroyed) {
378
418
  settle(void 0);
379
419
  return;
380
420
  }
381
- if (latestJob.status === "completed") {
382
- settle(this.deserializeResult(latestJob.result));
383
- return;
384
- }
385
- if (latestJob.status === "failed") {
421
+ try {
422
+ const latest = yield this.db
423
+ .select()
424
+ .from(dedupeTable)
425
+ .where(drizzleOrm.eq(dedupeTable.hash, hash))
426
+ .limit(1);
427
+ const latestJob = latest[0];
428
+ if (!latestJob) {
429
+ settle(void 0);
430
+ return;
431
+ }
432
+ const isExpired =
433
+ this.jobTimeoutMs > 0 &&
434
+ Date.now() - latestJob.createdAt >= this.jobTimeoutMs;
435
+ if (isExpired) {
436
+ yield this.db
437
+ .update(dedupeTable)
438
+ .set({
439
+ status: 'failed',
440
+ error: 'Job timed out',
441
+ updatedAt: Date.now(),
442
+ })
443
+ .where(drizzleOrm.eq(dedupeTable.hash, hash));
444
+ settle(void 0);
445
+ return;
446
+ }
447
+ if (latestJob.status === 'completed') {
448
+ settle(this.deserializeResult(latestJob.result));
449
+ return;
450
+ }
451
+ if (latestJob.status === 'failed') {
452
+ settle(void 0);
453
+ }
454
+ } catch (e) {
386
455
  settle(void 0);
387
456
  }
388
- } catch (e) {
389
- settle(void 0);
390
- }
391
- });
457
+ });
392
458
  const pollHandle = setInterval(() => {
393
459
  void poll();
394
460
  }, this.pollIntervalMs);
395
- if (typeof pollHandle.unref === "function") {
461
+ if (typeof pollHandle.unref === 'function') {
396
462
  pollHandle.unref();
397
463
  }
398
464
  void poll();
@@ -402,20 +468,24 @@ var SQLiteDedupeStore = class {
402
468
  settle(void 0);
403
469
  return;
404
470
  }
405
- void (() => __async(this, null, function* () {
406
- try {
407
- yield this.db.update(dedupeTable).set({
408
- status: "failed",
409
- error: "Job timed out",
410
- updatedAt: Date.now()
411
- }).where(drizzleOrm.eq(dedupeTable.hash, hash));
412
- } catch (e) {
413
- } finally {
414
- settle(void 0);
415
- }
416
- }))();
471
+ void (() =>
472
+ __async(this, null, function* () {
473
+ try {
474
+ yield this.db
475
+ .update(dedupeTable)
476
+ .set({
477
+ status: 'failed',
478
+ error: 'Job timed out',
479
+ updatedAt: Date.now(),
480
+ })
481
+ .where(drizzleOrm.eq(dedupeTable.hash, hash));
482
+ } catch (e) {
483
+ } finally {
484
+ settle(void 0);
485
+ }
486
+ }))();
417
487
  }, this.jobTimeoutMs);
418
- if (typeof timeoutHandle.unref === "function") {
488
+ if (typeof timeoutHandle.unref === 'function') {
419
489
  timeoutHandle.unref();
420
490
  }
421
491
  }
@@ -433,23 +503,26 @@ var SQLiteDedupeStore = class {
433
503
  registerOrJoin(hash) {
434
504
  return __async(this, null, function* () {
435
505
  if (this.isDestroyed) {
436
- throw new Error("Dedupe store has been destroyed");
506
+ throw new Error('Dedupe store has been destroyed');
437
507
  }
438
508
  const now = Date.now();
439
509
  const candidateJobId = crypto.randomUUID();
440
510
  const registerTransaction = this.sqlite.transaction(
441
511
  (requestHash, createdAt, jobId) => {
442
- const existing = this.sqlite.prepare(
443
- "SELECT job_id as jobId, status FROM dedupe_jobs WHERE hash = ? LIMIT 1"
444
- ).get(requestHash);
445
- if (existing && existing.status === "pending") {
512
+ const existing = this.sqlite
513
+ .prepare(
514
+ 'SELECT job_id as jobId, status FROM dedupe_jobs WHERE hash = ? LIMIT 1',
515
+ )
516
+ .get(requestHash);
517
+ if (existing && existing.status === 'pending') {
446
518
  return {
447
519
  jobId: existing.jobId,
448
- isOwner: false
520
+ isOwner: false,
449
521
  };
450
522
  }
451
- this.sqlite.prepare(
452
- `
523
+ this.sqlite
524
+ .prepare(
525
+ `
453
526
  INSERT INTO dedupe_jobs (hash, job_id, status, result, error, created_at, updated_at)
454
527
  VALUES (?, ?, 'pending', NULL, NULL, ?, ?)
455
528
  ON CONFLICT(hash) DO UPDATE SET
@@ -459,13 +532,14 @@ var SQLiteDedupeStore = class {
459
532
  error = NULL,
460
533
  created_at = excluded.created_at,
461
534
  updated_at = excluded.updated_at
462
- `
463
- ).run(requestHash, jobId, createdAt, createdAt);
535
+ `,
536
+ )
537
+ .run(requestHash, jobId, createdAt, createdAt);
464
538
  return {
465
539
  jobId,
466
- isOwner: true
540
+ isOwner: true,
467
541
  };
468
- }
542
+ },
469
543
  );
470
544
  return registerTransaction(hash, now, candidateJobId);
471
545
  });
@@ -474,32 +548,42 @@ var SQLiteDedupeStore = class {
474
548
  return __async(this, null, function* () {
475
549
  var _a;
476
550
  if (this.isDestroyed) {
477
- throw new Error("Dedupe store has been destroyed");
551
+ throw new Error('Dedupe store has been destroyed');
478
552
  }
479
553
  let serializedResult;
480
554
  if (value === void 0) {
481
- serializedResult = "__UNDEFINED__";
555
+ serializedResult = '__UNDEFINED__';
482
556
  } else if (value === null) {
483
- serializedResult = "__NULL__";
557
+ serializedResult = '__NULL__';
484
558
  } else {
485
559
  try {
486
560
  serializedResult = JSON.stringify(value);
487
561
  } catch (error) {
488
562
  throw new Error(
489
- `Failed to serialize result: ${error instanceof Error ? error.message : String(error)}`
563
+ `Failed to serialize result: ${error instanceof Error ? error.message : String(error)}`,
490
564
  );
491
565
  }
492
566
  }
493
567
  const now = Date.now();
494
- const existingJob = yield this.db.select().from(dedupeTable).where(drizzleOrm.eq(dedupeTable.hash, hash)).limit(1);
495
- if (existingJob.length > 0 && ((_a = existingJob[0]) == null ? void 0 : _a.status) === "completed") {
568
+ const existingJob = yield this.db
569
+ .select()
570
+ .from(dedupeTable)
571
+ .where(drizzleOrm.eq(dedupeTable.hash, hash))
572
+ .limit(1);
573
+ if (
574
+ existingJob.length > 0 &&
575
+ ((_a = existingJob[0]) == null ? void 0 : _a.status) === 'completed'
576
+ ) {
496
577
  return;
497
578
  }
498
- yield this.db.update(dedupeTable).set({
499
- status: "completed",
500
- result: serializedResult,
501
- updatedAt: now
502
- }).where(drizzleOrm.eq(dedupeTable.hash, hash));
579
+ yield this.db
580
+ .update(dedupeTable)
581
+ .set({
582
+ status: 'completed',
583
+ result: serializedResult,
584
+ updatedAt: now,
585
+ })
586
+ .where(drizzleOrm.eq(dedupeTable.hash, hash));
503
587
  const settle = this.jobSettlers.get(hash);
504
588
  if (settle) {
505
589
  settle(value);
@@ -509,14 +593,17 @@ var SQLiteDedupeStore = class {
509
593
  fail(hash, error) {
510
594
  return __async(this, null, function* () {
511
595
  if (this.isDestroyed) {
512
- throw new Error("Dedupe store has been destroyed");
596
+ throw new Error('Dedupe store has been destroyed');
513
597
  }
514
598
  const now = Date.now();
515
- yield this.db.update(dedupeTable).set({
516
- status: "failed",
517
- error: error.message,
518
- updatedAt: now
519
- }).where(drizzleOrm.eq(dedupeTable.hash, hash));
599
+ yield this.db
600
+ .update(dedupeTable)
601
+ .set({
602
+ status: 'failed',
603
+ error: error.message,
604
+ updatedAt: now,
605
+ })
606
+ .where(drizzleOrm.eq(dedupeTable.hash, hash));
520
607
  const settle = this.jobSettlers.get(hash);
521
608
  if (settle) {
522
609
  settle(void 0);
@@ -526,9 +613,13 @@ var SQLiteDedupeStore = class {
526
613
  isInProgress(hash) {
527
614
  return __async(this, null, function* () {
528
615
  if (this.isDestroyed) {
529
- throw new Error("Dedupe store has been destroyed");
616
+ throw new Error('Dedupe store has been destroyed');
530
617
  }
531
- const result = yield this.db.select().from(dedupeTable).where(drizzleOrm.eq(dedupeTable.hash, hash)).limit(1);
618
+ const result = yield this.db
619
+ .select()
620
+ .from(dedupeTable)
621
+ .where(drizzleOrm.eq(dedupeTable.hash, hash))
622
+ .limit(1);
532
623
  if (result.length === 0) {
533
624
  return false;
534
625
  }
@@ -536,17 +627,25 @@ var SQLiteDedupeStore = class {
536
627
  if (!job) {
537
628
  return false;
538
629
  }
539
- const jobExpired = this.jobTimeoutMs > 0 && Date.now() - job.createdAt >= this.jobTimeoutMs;
630
+ const jobExpired =
631
+ this.jobTimeoutMs > 0 &&
632
+ Date.now() - job.createdAt >= this.jobTimeoutMs;
540
633
  if (jobExpired) {
541
- yield this.db.delete(dedupeTable).where(drizzleOrm.eq(dedupeTable.hash, hash));
634
+ yield this.db
635
+ .delete(dedupeTable)
636
+ .where(drizzleOrm.eq(dedupeTable.hash, hash));
542
637
  return false;
543
638
  }
544
- return job.status === "pending";
639
+ return job.status === 'pending';
545
640
  });
546
641
  }
547
642
  getResult(hash) {
548
643
  return __async(this, null, function* () {
549
- const result = yield this.db.select().from(dedupeTable).where(drizzleOrm.eq(dedupeTable.hash, hash)).limit(1);
644
+ const result = yield this.db
645
+ .select()
646
+ .from(dedupeTable)
647
+ .where(drizzleOrm.eq(dedupeTable.hash, hash))
648
+ .limit(1);
550
649
  if (result.length === 0) {
551
650
  return void 0;
552
651
  }
@@ -557,14 +656,16 @@ var SQLiteDedupeStore = class {
557
656
  const now = Date.now();
558
657
  const isExpired = now - job.createdAt > this.jobTimeoutMs;
559
658
  if (isExpired) {
560
- yield this.db.delete(dedupeTable).where(drizzleOrm.eq(dedupeTable.hash, hash));
659
+ yield this.db
660
+ .delete(dedupeTable)
661
+ .where(drizzleOrm.eq(dedupeTable.hash, hash));
561
662
  return void 0;
562
663
  }
563
- if (job.status === "completed") {
664
+ if (job.status === 'completed') {
564
665
  try {
565
- if (job.result === "__UNDEFINED__") {
666
+ if (job.result === '__UNDEFINED__') {
566
667
  return void 0;
567
- } else if (job.result === "__NULL__") {
668
+ } else if (job.result === '__NULL__') {
568
669
  return null;
569
670
  } else if (job.result) {
570
671
  return JSON.parse(job.result);
@@ -585,17 +686,32 @@ var SQLiteDedupeStore = class {
585
686
  var _a, _b, _c, _d, _e;
586
687
  const now = Date.now();
587
688
  const expiredTime = now - this.jobTimeoutMs;
588
- const totalResult = yield this.db.select({ count: drizzleOrm.count() }).from(dedupeTable);
589
- const pendingResult = yield this.db.select({ count: drizzleOrm.count() }).from(dedupeTable).where(drizzleOrm.eq(dedupeTable.status, "pending"));
590
- const completedResult = yield this.db.select({ count: drizzleOrm.count() }).from(dedupeTable).where(drizzleOrm.eq(dedupeTable.status, "completed"));
591
- const failedResult = yield this.db.select({ count: drizzleOrm.count() }).from(dedupeTable).where(drizzleOrm.eq(dedupeTable.status, "failed"));
592
- const expiredResult = yield this.db.select({ count: drizzleOrm.count() }).from(dedupeTable).where(drizzleOrm.lt(dedupeTable.createdAt, expiredTime));
689
+ const totalResult = yield this.db
690
+ .select({ count: drizzleOrm.count() })
691
+ .from(dedupeTable);
692
+ const pendingResult = yield this.db
693
+ .select({ count: drizzleOrm.count() })
694
+ .from(dedupeTable)
695
+ .where(drizzleOrm.eq(dedupeTable.status, 'pending'));
696
+ const completedResult = yield this.db
697
+ .select({ count: drizzleOrm.count() })
698
+ .from(dedupeTable)
699
+ .where(drizzleOrm.eq(dedupeTable.status, 'completed'));
700
+ const failedResult = yield this.db
701
+ .select({ count: drizzleOrm.count() })
702
+ .from(dedupeTable)
703
+ .where(drizzleOrm.eq(dedupeTable.status, 'failed'));
704
+ const expiredResult = yield this.db
705
+ .select({ count: drizzleOrm.count() })
706
+ .from(dedupeTable)
707
+ .where(drizzleOrm.lt(dedupeTable.createdAt, expiredTime));
593
708
  return {
594
709
  totalJobs: ((_a = totalResult[0]) == null ? void 0 : _a.count) || 0,
595
710
  pendingJobs: ((_b = pendingResult[0]) == null ? void 0 : _b.count) || 0,
596
- completedJobs: ((_c = completedResult[0]) == null ? void 0 : _c.count) || 0,
711
+ completedJobs:
712
+ ((_c = completedResult[0]) == null ? void 0 : _c.count) || 0,
597
713
  failedJobs: ((_d = failedResult[0]) == null ? void 0 : _d.count) || 0,
598
- expiredJobs: ((_e = expiredResult[0]) == null ? void 0 : _e.count) || 0
714
+ expiredJobs: ((_e = expiredResult[0]) == null ? void 0 : _e.count) || 0,
599
715
  };
600
716
  });
601
717
  }
@@ -606,7 +722,9 @@ var SQLiteDedupeStore = class {
606
722
  return __async(this, null, function* () {
607
723
  const now = Date.now();
608
724
  const expiredTime = now - this.jobTimeoutMs;
609
- yield this.db.delete(dedupeTable).where(drizzleOrm.lt(dedupeTable.createdAt, expiredTime));
725
+ yield this.db
726
+ .delete(dedupeTable)
727
+ .where(drizzleOrm.lt(dedupeTable.createdAt, expiredTime));
610
728
  });
611
729
  }
612
730
  /**
@@ -637,7 +755,7 @@ var SQLiteDedupeStore = class {
637
755
  }
638
756
  this.jobPromises.clear();
639
757
  this.jobSettlers.clear();
640
- if (this.isConnectionManaged && typeof this.sqlite.close === "function") {
758
+ if (this.isConnectionManaged && typeof this.sqlite.close === 'function') {
641
759
  this.sqlite.close();
642
760
  }
643
761
  });
@@ -650,10 +768,10 @@ var SQLiteDedupeStore = class {
650
768
  }
651
769
  deserializeResult(serializedResult) {
652
770
  try {
653
- if (serializedResult === "__UNDEFINED__") {
771
+ if (serializedResult === '__UNDEFINED__') {
654
772
  return void 0;
655
773
  }
656
- if (serializedResult === "__NULL__") {
774
+ if (serializedResult === '__NULL__') {
657
775
  return null;
658
776
  }
659
777
  if (serializedResult) {
@@ -684,11 +802,11 @@ var SQLiteDedupeStore = class {
684
802
  var SQLiteRateLimitStore = class {
685
803
  constructor({
686
804
  /** File path or existing `better-sqlite3` Database instance. Defaults to `':memory:'`. */
687
- database = ":memory:",
805
+ database = ':memory:',
688
806
  /** Global/default rate-limit config applied when a resource-specific override is not provided. */
689
807
  defaultConfig = core.DEFAULT_RATE_LIMIT,
690
808
  /** Optional per-resource overrides. */
691
- resourceConfigs = /* @__PURE__ */ new Map()
809
+ resourceConfigs = /* @__PURE__ */ new Map(),
692
810
  } = {}) {
693
811
  /** Indicates whether this store manages (and should close) the SQLite connection */
694
812
  this.isConnectionManaged = false;
@@ -696,7 +814,7 @@ var SQLiteRateLimitStore = class {
696
814
  this.isDestroyed = false;
697
815
  let sqliteInstance;
698
816
  let isConnectionManaged = false;
699
- if (typeof database === "string") {
817
+ if (typeof database === 'string') {
700
818
  sqliteInstance = new Database__default.default(database);
701
819
  isConnectionManaged = true;
702
820
  } else {
@@ -713,18 +831,21 @@ var SQLiteRateLimitStore = class {
713
831
  return __async(this, null, function* () {
714
832
  var _a;
715
833
  if (this.isDestroyed) {
716
- throw new Error("Rate limit store has been destroyed");
834
+ throw new Error('Rate limit store has been destroyed');
717
835
  }
718
836
  const config = this.resourceConfigs.get(resource) || this.defaultConfig;
719
837
  const now = Date.now();
720
838
  const windowStart = now - config.windowMs;
721
839
  yield this.cleanupExpiredRequests(resource, windowStart);
722
- const result = yield this.db.select({ count: drizzleOrm.count() }).from(rateLimitTable).where(
723
- drizzleOrm.and(
724
- drizzleOrm.eq(rateLimitTable.resource, resource),
725
- drizzleOrm.gte(rateLimitTable.timestamp, windowStart)
726
- )
727
- );
840
+ const result = yield this.db
841
+ .select({ count: drizzleOrm.count() })
842
+ .from(rateLimitTable)
843
+ .where(
844
+ drizzleOrm.and(
845
+ drizzleOrm.eq(rateLimitTable.resource, resource),
846
+ drizzleOrm.gte(rateLimitTable.timestamp, windowStart),
847
+ ),
848
+ );
728
849
  const currentCount = ((_a = result[0]) == null ? void 0 : _a.count) || 0;
729
850
  return currentCount < config.limit;
730
851
  });
@@ -732,12 +853,12 @@ var SQLiteRateLimitStore = class {
732
853
  record(resource) {
733
854
  return __async(this, null, function* () {
734
855
  if (this.isDestroyed) {
735
- throw new Error("Rate limit store has been destroyed");
856
+ throw new Error('Rate limit store has been destroyed');
736
857
  }
737
858
  const now = Date.now();
738
859
  yield this.db.insert(rateLimitTable).values({
739
860
  resource,
740
- timestamp: now
861
+ timestamp: now,
741
862
  });
742
863
  });
743
864
  }
@@ -745,41 +866,47 @@ var SQLiteRateLimitStore = class {
745
866
  return __async(this, null, function* () {
746
867
  var _a;
747
868
  if (this.isDestroyed) {
748
- throw new Error("Rate limit store has been destroyed");
869
+ throw new Error('Rate limit store has been destroyed');
749
870
  }
750
871
  const config = this.resourceConfigs.get(resource) || this.defaultConfig;
751
872
  const now = Date.now();
752
873
  const windowStart = now - config.windowMs;
753
874
  yield this.cleanupExpiredRequests(resource, windowStart);
754
- const result = yield this.db.select({ count: drizzleOrm.count() }).from(rateLimitTable).where(
755
- drizzleOrm.and(
756
- drizzleOrm.eq(rateLimitTable.resource, resource),
757
- drizzleOrm.gte(rateLimitTable.timestamp, windowStart)
758
- )
759
- );
760
- const currentRequests = ((_a = result[0]) == null ? void 0 : _a.count) || 0;
875
+ const result = yield this.db
876
+ .select({ count: drizzleOrm.count() })
877
+ .from(rateLimitTable)
878
+ .where(
879
+ drizzleOrm.and(
880
+ drizzleOrm.eq(rateLimitTable.resource, resource),
881
+ drizzleOrm.gte(rateLimitTable.timestamp, windowStart),
882
+ ),
883
+ );
884
+ const currentRequests =
885
+ ((_a = result[0]) == null ? void 0 : _a.count) || 0;
761
886
  const remaining = Math.max(0, config.limit - currentRequests);
762
887
  const resetTime = new Date(now + config.windowMs);
763
888
  return {
764
889
  remaining,
765
890
  resetTime,
766
- limit: config.limit
891
+ limit: config.limit,
767
892
  };
768
893
  });
769
894
  }
770
895
  reset(resource) {
771
896
  return __async(this, null, function* () {
772
897
  if (this.isDestroyed) {
773
- throw new Error("Rate limit store has been destroyed");
898
+ throw new Error('Rate limit store has been destroyed');
774
899
  }
775
- yield this.db.delete(rateLimitTable).where(drizzleOrm.eq(rateLimitTable.resource, resource));
900
+ yield this.db
901
+ .delete(rateLimitTable)
902
+ .where(drizzleOrm.eq(rateLimitTable.resource, resource));
776
903
  });
777
904
  }
778
905
  getWaitTime(resource) {
779
906
  return __async(this, null, function* () {
780
907
  var _a, _b;
781
908
  if (this.isDestroyed) {
782
- throw new Error("Rate limit store has been destroyed");
909
+ throw new Error('Rate limit store has been destroyed');
783
910
  }
784
911
  const config = this.resourceConfigs.get(resource) || this.defaultConfig;
785
912
  if (config.limit === 0) {
@@ -788,26 +915,36 @@ var SQLiteRateLimitStore = class {
788
915
  const now = Date.now();
789
916
  const windowStart = now - config.windowMs;
790
917
  yield this.cleanupExpiredRequests(resource, windowStart);
791
- const countResult = yield this.db.select({ count: drizzleOrm.count() }).from(rateLimitTable).where(
792
- drizzleOrm.and(
793
- drizzleOrm.eq(rateLimitTable.resource, resource),
794
- drizzleOrm.gte(rateLimitTable.timestamp, windowStart)
795
- )
796
- );
797
- const currentRequests = ((_a = countResult[0]) == null ? void 0 : _a.count) || 0;
918
+ const countResult = yield this.db
919
+ .select({ count: drizzleOrm.count() })
920
+ .from(rateLimitTable)
921
+ .where(
922
+ drizzleOrm.and(
923
+ drizzleOrm.eq(rateLimitTable.resource, resource),
924
+ drizzleOrm.gte(rateLimitTable.timestamp, windowStart),
925
+ ),
926
+ );
927
+ const currentRequests =
928
+ ((_a = countResult[0]) == null ? void 0 : _a.count) || 0;
798
929
  if (currentRequests < config.limit) {
799
930
  return 0;
800
931
  }
801
- const oldestResult = yield this.db.select({ timestamp: rateLimitTable.timestamp }).from(rateLimitTable).where(
802
- drizzleOrm.and(
803
- drizzleOrm.eq(rateLimitTable.resource, resource),
804
- drizzleOrm.gte(rateLimitTable.timestamp, windowStart)
932
+ const oldestResult = yield this.db
933
+ .select({ timestamp: rateLimitTable.timestamp })
934
+ .from(rateLimitTable)
935
+ .where(
936
+ drizzleOrm.and(
937
+ drizzleOrm.eq(rateLimitTable.resource, resource),
938
+ drizzleOrm.gte(rateLimitTable.timestamp, windowStart),
939
+ ),
805
940
  )
806
- ).orderBy(rateLimitTable.timestamp).limit(1);
941
+ .orderBy(rateLimitTable.timestamp)
942
+ .limit(1);
807
943
  if (oldestResult.length === 0) {
808
944
  return 0;
809
945
  }
810
- const oldestTimestamp = (_b = oldestResult[0]) == null ? void 0 : _b.timestamp;
946
+ const oldestTimestamp =
947
+ (_b = oldestResult[0]) == null ? void 0 : _b.timestamp;
811
948
  if (oldestTimestamp === void 0) {
812
949
  return 0;
813
950
  }
@@ -834,10 +971,15 @@ var SQLiteRateLimitStore = class {
834
971
  return __async(this, null, function* () {
835
972
  var _a;
836
973
  if (this.isDestroyed) {
837
- throw new Error("Rate limit store has been destroyed");
838
- }
839
- const totalResult = yield this.db.select({ count: drizzleOrm.count() }).from(rateLimitTable);
840
- const resourcesResult = yield this.db.select({ resource: rateLimitTable.resource }).from(rateLimitTable).groupBy(rateLimitTable.resource);
974
+ throw new Error('Rate limit store has been destroyed');
975
+ }
976
+ const totalResult = yield this.db
977
+ .select({ count: drizzleOrm.count() })
978
+ .from(rateLimitTable);
979
+ const resourcesResult = yield this.db
980
+ .select({ resource: rateLimitTable.resource })
981
+ .from(rateLimitTable)
982
+ .groupBy(rateLimitTable.resource);
841
983
  const uniqueResources = resourcesResult.length;
842
984
  const rateLimitedResources = [];
843
985
  for (const { resource } of resourcesResult) {
@@ -849,7 +991,7 @@ var SQLiteRateLimitStore = class {
849
991
  return {
850
992
  totalRequests: ((_a = totalResult[0]) == null ? void 0 : _a.count) || 0,
851
993
  uniqueResources,
852
- rateLimitedResources
994
+ rateLimitedResources,
853
995
  };
854
996
  });
855
997
  }
@@ -859,7 +1001,7 @@ var SQLiteRateLimitStore = class {
859
1001
  clear() {
860
1002
  return __async(this, null, function* () {
861
1003
  if (this.isDestroyed) {
862
- throw new Error("Rate limit store has been destroyed");
1004
+ throw new Error('Rate limit store has been destroyed');
863
1005
  }
864
1006
  yield this.db.delete(rateLimitTable);
865
1007
  });
@@ -870,7 +1012,10 @@ var SQLiteRateLimitStore = class {
870
1012
  cleanup() {
871
1013
  return __async(this, null, function* () {
872
1014
  const now = Date.now();
873
- const resources = yield this.db.select({ resource: rateLimitTable.resource }).from(rateLimitTable).groupBy(rateLimitTable.resource);
1015
+ const resources = yield this.db
1016
+ .select({ resource: rateLimitTable.resource })
1017
+ .from(rateLimitTable)
1018
+ .groupBy(rateLimitTable.resource);
874
1019
  for (const { resource } of resources) {
875
1020
  const config = this.resourceConfigs.get(resource) || this.defaultConfig;
876
1021
  const windowStart = now - config.windowMs;
@@ -884,7 +1029,7 @@ var SQLiteRateLimitStore = class {
884
1029
  close() {
885
1030
  return __async(this, null, function* () {
886
1031
  this.isDestroyed = true;
887
- if (this.isConnectionManaged && typeof this.sqlite.close === "function") {
1032
+ if (this.isConnectionManaged && typeof this.sqlite.close === 'function') {
888
1033
  this.sqlite.close();
889
1034
  }
890
1035
  });
@@ -897,12 +1042,14 @@ var SQLiteRateLimitStore = class {
897
1042
  }
898
1043
  cleanupExpiredRequests(resource, windowStart) {
899
1044
  return __async(this, null, function* () {
900
- yield this.db.delete(rateLimitTable).where(
901
- drizzleOrm.and(
902
- drizzleOrm.eq(rateLimitTable.resource, resource),
903
- drizzleOrm.lt(rateLimitTable.timestamp, windowStart)
904
- )
905
- );
1045
+ yield this.db
1046
+ .delete(rateLimitTable)
1047
+ .where(
1048
+ drizzleOrm.and(
1049
+ drizzleOrm.eq(rateLimitTable.resource, resource),
1050
+ drizzleOrm.lt(rateLimitTable.timestamp, windowStart),
1051
+ ),
1052
+ );
906
1053
  });
907
1054
  }
908
1055
  initializeDatabase() {
@@ -923,15 +1070,15 @@ var SQLiteRateLimitStore = class {
923
1070
  };
924
1071
  var DEFAULT_RATE_LIMIT2 = {
925
1072
  limit: 200,
926
- windowMs: 36e5
1073
+ windowMs: 36e5,
927
1074
  // 1 hour
928
1075
  };
929
1076
  var SqliteAdaptiveRateLimitStore = class {
930
1077
  constructor({
931
- database = ":memory:",
1078
+ database = ':memory:',
932
1079
  defaultConfig = DEFAULT_RATE_LIMIT2,
933
1080
  resourceConfigs = /* @__PURE__ */ new Map(),
934
- adaptiveConfig = {}
1081
+ adaptiveConfig = {},
935
1082
  } = {}) {
936
1083
  /** Indicates whether this store manages (and should close) the SQLite connection */
937
1084
  this.isConnectionManaged = false;
@@ -942,7 +1089,7 @@ var SqliteAdaptiveRateLimitStore = class {
942
1089
  this.cachedCapacity = /* @__PURE__ */ new Map();
943
1090
  let sqliteInstance;
944
1091
  let isConnectionManaged = false;
945
- if (typeof database === "string") {
1092
+ if (typeof database === 'string') {
946
1093
  sqliteInstance = new Database__default.default(database);
947
1094
  isConnectionManaged = true;
948
1095
  } else {
@@ -953,36 +1100,38 @@ var SqliteAdaptiveRateLimitStore = class {
953
1100
  this.db = betterSqlite3.drizzle(sqliteInstance);
954
1101
  this.defaultConfig = defaultConfig;
955
1102
  this.resourceConfigs = resourceConfigs;
956
- this.capacityCalculator = new core.AdaptiveCapacityCalculator(adaptiveConfig);
1103
+ this.capacityCalculator = new core.AdaptiveCapacityCalculator(
1104
+ adaptiveConfig,
1105
+ );
957
1106
  this.initializeDatabase();
958
1107
  }
959
- canProceed(resource, priority = "background") {
1108
+ canProceed(resource, priority = 'background') {
960
1109
  return __async(this, null, function* () {
961
1110
  if (this.isDestroyed) {
962
- throw new Error("Rate limit store has been destroyed");
1111
+ throw new Error('Rate limit store has been destroyed');
963
1112
  }
964
1113
  yield this.ensureActivityMetrics(resource);
965
1114
  const metrics = this.getOrCreateActivityMetrics(resource);
966
1115
  const capacity = this.calculateCurrentCapacity(resource, metrics);
967
- if (priority === "background" && capacity.backgroundPaused) {
1116
+ if (priority === 'background' && capacity.backgroundPaused) {
968
1117
  return false;
969
1118
  }
970
- const currentUserRequests = yield this.getCurrentUsage(resource, "user");
1119
+ const currentUserRequests = yield this.getCurrentUsage(resource, 'user');
971
1120
  const currentBackgroundRequests = yield this.getCurrentUsage(
972
1121
  resource,
973
- "background"
1122
+ 'background',
974
1123
  );
975
- if (priority === "user") {
1124
+ if (priority === 'user') {
976
1125
  return currentUserRequests < capacity.userReserved;
977
1126
  } else {
978
1127
  return currentBackgroundRequests < capacity.backgroundMax;
979
1128
  }
980
1129
  });
981
1130
  }
982
- record(resource, priority = "background") {
1131
+ record(resource, priority = 'background') {
983
1132
  return __async(this, null, function* () {
984
1133
  if (this.isDestroyed) {
985
- throw new Error("Rate limit store has been destroyed");
1134
+ throw new Error('Rate limit store has been destroyed');
986
1135
  }
987
1136
  const now = Date.now();
988
1137
  this.db.run(drizzleOrm.sql`
@@ -990,34 +1139,38 @@ var SqliteAdaptiveRateLimitStore = class {
990
1139
  VALUES (${resource}, ${now}, ${priority})
991
1140
  `);
992
1141
  const metrics = this.getOrCreateActivityMetrics(resource);
993
- if (priority === "user") {
1142
+ if (priority === 'user') {
994
1143
  metrics.recentUserRequests.push(now);
995
1144
  this.cleanupOldRequests(metrics.recentUserRequests);
996
1145
  } else {
997
1146
  metrics.recentBackgroundRequests.push(now);
998
1147
  this.cleanupOldRequests(metrics.recentBackgroundRequests);
999
1148
  }
1000
- metrics.userActivityTrend = this.capacityCalculator.calculateActivityTrend(
1001
- metrics.recentUserRequests
1002
- );
1149
+ metrics.userActivityTrend =
1150
+ this.capacityCalculator.calculateActivityTrend(
1151
+ metrics.recentUserRequests,
1152
+ );
1003
1153
  });
1004
1154
  }
1005
1155
  getStatus(resource) {
1006
1156
  return __async(this, null, function* () {
1007
1157
  if (this.isDestroyed) {
1008
- throw new Error("Rate limit store has been destroyed");
1158
+ throw new Error('Rate limit store has been destroyed');
1009
1159
  }
1010
1160
  yield this.ensureActivityMetrics(resource);
1011
1161
  const metrics = this.getOrCreateActivityMetrics(resource);
1012
1162
  const capacity = this.calculateCurrentCapacity(resource, metrics);
1013
- const currentUserUsage = yield this.getCurrentUsage(resource, "user");
1163
+ const currentUserUsage = yield this.getCurrentUsage(resource, 'user');
1014
1164
  const currentBackgroundUsage = yield this.getCurrentUsage(
1015
1165
  resource,
1016
- "background"
1166
+ 'background',
1017
1167
  );
1018
1168
  const config = this.resourceConfigs.get(resource) || this.defaultConfig;
1019
1169
  return {
1020
- remaining: capacity.userReserved - currentUserUsage + (capacity.backgroundMax - currentBackgroundUsage),
1170
+ remaining:
1171
+ capacity.userReserved -
1172
+ currentUserUsage +
1173
+ (capacity.backgroundMax - currentBackgroundUsage),
1021
1174
  resetTime: new Date(Date.now() + config.windowMs),
1022
1175
  limit: this.getResourceLimit(resource),
1023
1176
  adaptive: {
@@ -1025,28 +1178,30 @@ var SqliteAdaptiveRateLimitStore = class {
1025
1178
  backgroundMax: capacity.backgroundMax,
1026
1179
  backgroundPaused: capacity.backgroundPaused,
1027
1180
  recentUserActivity: this.capacityCalculator.getRecentActivity(
1028
- metrics.recentUserRequests
1181
+ metrics.recentUserRequests,
1029
1182
  ),
1030
- reason: capacity.reason
1031
- }
1183
+ reason: capacity.reason,
1184
+ },
1032
1185
  };
1033
1186
  });
1034
1187
  }
1035
1188
  reset(resource) {
1036
1189
  return __async(this, null, function* () {
1037
1190
  if (this.isDestroyed) {
1038
- throw new Error("Rate limit store has been destroyed");
1191
+ throw new Error('Rate limit store has been destroyed');
1039
1192
  }
1040
- yield this.db.delete(rateLimitTable).where(drizzleOrm.eq(rateLimitTable.resource, resource));
1193
+ yield this.db
1194
+ .delete(rateLimitTable)
1195
+ .where(drizzleOrm.eq(rateLimitTable.resource, resource));
1041
1196
  this.activityMetrics.delete(resource);
1042
1197
  this.cachedCapacity.delete(resource);
1043
1198
  this.lastCapacityUpdate.delete(resource);
1044
1199
  });
1045
1200
  }
1046
- getWaitTime(resource, priority = "background") {
1201
+ getWaitTime(resource, priority = 'background') {
1047
1202
  return __async(this, null, function* () {
1048
1203
  if (this.isDestroyed) {
1049
- throw new Error("Rate limit store has been destroyed");
1204
+ throw new Error('Rate limit store has been destroyed');
1050
1205
  }
1051
1206
  const config = this.resourceConfigs.get(resource) || this.defaultConfig;
1052
1207
  if (config.limit === 0) {
@@ -1059,20 +1214,22 @@ var SqliteAdaptiveRateLimitStore = class {
1059
1214
  yield this.ensureActivityMetrics(resource);
1060
1215
  const metrics = this.getOrCreateActivityMetrics(resource);
1061
1216
  const capacity = this.calculateCurrentCapacity(resource, metrics);
1062
- if (priority === "background" && capacity.backgroundPaused) {
1217
+ if (priority === 'background' && capacity.backgroundPaused) {
1063
1218
  return this.capacityCalculator.config.recalculationIntervalMs;
1064
1219
  }
1065
1220
  const now = Date.now();
1066
1221
  const windowStart = now - config.windowMs;
1067
- const oldestResult = this.sqlite.prepare(
1068
- `
1222
+ const oldestResult = this.sqlite
1223
+ .prepare(
1224
+ `
1069
1225
  SELECT timestamp
1070
1226
  FROM rate_limits
1071
1227
  WHERE resource = ? AND COALESCE(priority, 'background') = ? AND timestamp >= ?
1072
1228
  ORDER BY timestamp
1073
1229
  LIMIT 1
1074
- `
1075
- ).get(resource, priority, windowStart);
1230
+ `,
1231
+ )
1232
+ .get(resource, priority, windowStart);
1076
1233
  if (!oldestResult) {
1077
1234
  return 0;
1078
1235
  }
@@ -1103,10 +1260,15 @@ var SqliteAdaptiveRateLimitStore = class {
1103
1260
  return __async(this, null, function* () {
1104
1261
  var _a;
1105
1262
  if (this.isDestroyed) {
1106
- throw new Error("Rate limit store has been destroyed");
1107
- }
1108
- const totalResult = yield this.db.select({ count: drizzleOrm.count() }).from(rateLimitTable);
1109
- const resourcesResult = yield this.db.select({ resource: rateLimitTable.resource }).from(rateLimitTable).groupBy(rateLimitTable.resource);
1263
+ throw new Error('Rate limit store has been destroyed');
1264
+ }
1265
+ const totalResult = yield this.db
1266
+ .select({ count: drizzleOrm.count() })
1267
+ .from(rateLimitTable);
1268
+ const resourcesResult = yield this.db
1269
+ .select({ resource: rateLimitTable.resource })
1270
+ .from(rateLimitTable)
1271
+ .groupBy(rateLimitTable.resource);
1110
1272
  const uniqueResources = resourcesResult.length;
1111
1273
  const rateLimitedResources = [];
1112
1274
  for (const { resource } of resourcesResult) {
@@ -1118,7 +1280,7 @@ var SqliteAdaptiveRateLimitStore = class {
1118
1280
  return {
1119
1281
  totalRequests: ((_a = totalResult[0]) == null ? void 0 : _a.count) || 0,
1120
1282
  uniqueResources,
1121
- rateLimitedResources
1283
+ rateLimitedResources,
1122
1284
  };
1123
1285
  });
1124
1286
  }
@@ -1128,7 +1290,7 @@ var SqliteAdaptiveRateLimitStore = class {
1128
1290
  clear() {
1129
1291
  return __async(this, null, function* () {
1130
1292
  if (this.isDestroyed) {
1131
- throw new Error("Rate limit store has been destroyed");
1293
+ throw new Error('Rate limit store has been destroyed');
1132
1294
  }
1133
1295
  yield this.db.delete(rateLimitTable);
1134
1296
  this.activityMetrics.clear();
@@ -1142,7 +1304,10 @@ var SqliteAdaptiveRateLimitStore = class {
1142
1304
  cleanup() {
1143
1305
  return __async(this, null, function* () {
1144
1306
  const now = Date.now();
1145
- const resources = yield this.db.select({ resource: rateLimitTable.resource }).from(rateLimitTable).groupBy(rateLimitTable.resource);
1307
+ const resources = yield this.db
1308
+ .select({ resource: rateLimitTable.resource })
1309
+ .from(rateLimitTable)
1310
+ .groupBy(rateLimitTable.resource);
1146
1311
  for (const { resource } of resources) {
1147
1312
  const config = this.resourceConfigs.get(resource) || this.defaultConfig;
1148
1313
  const windowStart = now - config.windowMs;
@@ -1156,7 +1321,7 @@ var SqliteAdaptiveRateLimitStore = class {
1156
1321
  close() {
1157
1322
  return __async(this, null, function* () {
1158
1323
  this.isDestroyed = true;
1159
- if (this.isConnectionManaged && typeof this.sqlite.close === "function") {
1324
+ if (this.isConnectionManaged && typeof this.sqlite.close === 'function') {
1160
1325
  this.sqlite.close();
1161
1326
  }
1162
1327
  });
@@ -1170,15 +1335,18 @@ var SqliteAdaptiveRateLimitStore = class {
1170
1335
  // Private helper methods for adaptive functionality
1171
1336
  calculateCurrentCapacity(resource, metrics) {
1172
1337
  const lastUpdate = this.lastCapacityUpdate.get(resource) || 0;
1173
- const recalcInterval = this.capacityCalculator.config.recalculationIntervalMs;
1338
+ const recalcInterval =
1339
+ this.capacityCalculator.config.recalculationIntervalMs;
1174
1340
  if (Date.now() - lastUpdate < recalcInterval) {
1175
- return this.cachedCapacity.get(resource) || this.getDefaultCapacity(resource);
1341
+ return (
1342
+ this.cachedCapacity.get(resource) || this.getDefaultCapacity(resource)
1343
+ );
1176
1344
  }
1177
1345
  const totalLimit = this.getResourceLimit(resource);
1178
1346
  const capacity = this.capacityCalculator.calculateDynamicCapacity(
1179
1347
  resource,
1180
1348
  totalLimit,
1181
- metrics
1349
+ metrics,
1182
1350
  );
1183
1351
  this.cachedCapacity.set(resource, capacity);
1184
1352
  this.lastCapacityUpdate.set(resource, Date.now());
@@ -1189,7 +1357,7 @@ var SqliteAdaptiveRateLimitStore = class {
1189
1357
  this.activityMetrics.set(resource, {
1190
1358
  recentUserRequests: [],
1191
1359
  recentBackgroundRequests: [],
1192
- userActivityTrend: "none"
1360
+ userActivityTrend: 'none',
1193
1361
  });
1194
1362
  }
1195
1363
  return this.activityMetrics.get(resource);
@@ -1200,30 +1368,34 @@ var SqliteAdaptiveRateLimitStore = class {
1200
1368
  return;
1201
1369
  }
1202
1370
  const now = Date.now();
1203
- const windowStart = now - this.capacityCalculator.config.monitoringWindowMs;
1204
- const recentRequests = this.sqlite.prepare(
1205
- `
1371
+ const windowStart =
1372
+ now - this.capacityCalculator.config.monitoringWindowMs;
1373
+ const recentRequests = this.sqlite
1374
+ .prepare(
1375
+ `
1206
1376
  SELECT timestamp, COALESCE(priority, 'background') as priority
1207
1377
  FROM rate_limits
1208
1378
  WHERE resource = ? AND timestamp >= ?
1209
1379
  ORDER BY timestamp
1210
- `
1211
- ).all(resource, windowStart);
1380
+ `,
1381
+ )
1382
+ .all(resource, windowStart);
1212
1383
  const metrics = {
1213
1384
  recentUserRequests: [],
1214
1385
  recentBackgroundRequests: [],
1215
- userActivityTrend: "none"
1386
+ userActivityTrend: 'none',
1216
1387
  };
1217
1388
  for (const request of recentRequests) {
1218
- if (request.priority === "user") {
1389
+ if (request.priority === 'user') {
1219
1390
  metrics.recentUserRequests.push(request.timestamp);
1220
1391
  } else {
1221
1392
  metrics.recentBackgroundRequests.push(request.timestamp);
1222
1393
  }
1223
1394
  }
1224
- metrics.userActivityTrend = this.capacityCalculator.calculateActivityTrend(
1225
- metrics.recentUserRequests
1226
- );
1395
+ metrics.userActivityTrend =
1396
+ this.capacityCalculator.calculateActivityTrend(
1397
+ metrics.recentUserRequests,
1398
+ );
1227
1399
  this.activityMetrics.set(resource, metrics);
1228
1400
  });
1229
1401
  }
@@ -1233,18 +1405,21 @@ var SqliteAdaptiveRateLimitStore = class {
1233
1405
  const now = Date.now();
1234
1406
  const windowStart = now - config.windowMs;
1235
1407
  yield this.cleanupExpiredRequests(resource, windowStart);
1236
- const result = this.sqlite.prepare(
1237
- `
1408
+ const result = this.sqlite
1409
+ .prepare(
1410
+ `
1238
1411
  SELECT COUNT(*) as count
1239
1412
  FROM rate_limits
1240
1413
  WHERE resource = ? AND priority = ? AND timestamp >= ?
1241
- `
1242
- ).get(resource, priority, windowStart);
1414
+ `,
1415
+ )
1416
+ .get(resource, priority, windowStart);
1243
1417
  return result.count || 0;
1244
1418
  });
1245
1419
  }
1246
1420
  cleanupOldRequests(requests) {
1247
- const cutoff = Date.now() - this.capacityCalculator.config.monitoringWindowMs;
1421
+ const cutoff =
1422
+ Date.now() - this.capacityCalculator.config.monitoringWindowMs;
1248
1423
  while (requests.length > 0 && requests[0] < cutoff) {
1249
1424
  requests.shift();
1250
1425
  }
@@ -1259,17 +1434,19 @@ var SqliteAdaptiveRateLimitStore = class {
1259
1434
  userReserved: Math.floor(limit * 0.3),
1260
1435
  backgroundMax: Math.floor(limit * 0.7),
1261
1436
  backgroundPaused: false,
1262
- reason: "Default capacity allocation"
1437
+ reason: 'Default capacity allocation',
1263
1438
  };
1264
1439
  }
1265
1440
  cleanupExpiredRequests(resource, windowStart) {
1266
1441
  return __async(this, null, function* () {
1267
- yield this.db.delete(rateLimitTable).where(
1268
- drizzleOrm.and(
1269
- drizzleOrm.eq(rateLimitTable.resource, resource),
1270
- drizzleOrm.lt(rateLimitTable.timestamp, windowStart)
1271
- )
1272
- );
1442
+ yield this.db
1443
+ .delete(rateLimitTable)
1444
+ .where(
1445
+ drizzleOrm.and(
1446
+ drizzleOrm.eq(rateLimitTable.resource, resource),
1447
+ drizzleOrm.lt(rateLimitTable.timestamp, windowStart),
1448
+ ),
1449
+ );
1273
1450
  });
1274
1451
  }
1275
1452
  initializeDatabase() {
@@ -1285,8 +1462,7 @@ var SqliteAdaptiveRateLimitStore = class {
1285
1462
  this.db.run(drizzleOrm.sql`
1286
1463
  ALTER TABLE rate_limits ADD COLUMN priority TEXT DEFAULT 'background'
1287
1464
  `);
1288
- } catch (e) {
1289
- }
1465
+ } catch (e) {}
1290
1466
  this.db.run(drizzleOrm.sql`
1291
1467
  CREATE INDEX IF NOT EXISTS idx_rate_limit_resource ON rate_limits(resource)
1292
1468
  `);
@@ -1308,4 +1484,4 @@ exports.cacheTable = cacheTable;
1308
1484
  exports.dedupeTable = dedupeTable;
1309
1485
  exports.rateLimitTable = rateLimitTable;
1310
1486
  //# sourceMappingURL=index.cjs.map
1311
- //# sourceMappingURL=index.cjs.map
1487
+ //# sourceMappingURL=index.cjs.map