@workglow/storage 0.2.22 → 0.2.24

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 (35) hide show
  1. package/dist/browser.js +284 -55
  2. package/dist/browser.js.map +12 -12
  3. package/dist/bun.js +331 -55
  4. package/dist/bun.js.map +16 -16
  5. package/dist/node.js +331 -55
  6. package/dist/node.js.map +16 -16
  7. package/dist/queue/IQueueStorage.d.ts +9 -0
  8. package/dist/queue/IQueueStorage.d.ts.map +1 -1
  9. package/dist/queue/InMemoryQueueStorage.d.ts +5 -0
  10. package/dist/queue/InMemoryQueueStorage.d.ts.map +1 -1
  11. package/dist/queue/IndexedDbQueueStorage.d.ts +4 -0
  12. package/dist/queue/IndexedDbQueueStorage.d.ts.map +1 -1
  13. package/dist/queue/PostgresQueueStorage.d.ts +5 -0
  14. package/dist/queue/PostgresQueueStorage.d.ts.map +1 -1
  15. package/dist/queue/SqliteQueueStorage.d.ts +5 -0
  16. package/dist/queue/SqliteQueueStorage.d.ts.map +1 -1
  17. package/dist/queue/SupabaseQueueStorage.d.ts +4 -0
  18. package/dist/queue/SupabaseQueueStorage.d.ts.map +1 -1
  19. package/dist/queue/TelemetryQueueStorage.d.ts +1 -0
  20. package/dist/queue/TelemetryQueueStorage.d.ts.map +1 -1
  21. package/dist/tabular/BaseTabularStorage.d.ts +5 -0
  22. package/dist/tabular/BaseTabularStorage.d.ts.map +1 -1
  23. package/dist/tabular/ITabularStorage.d.ts +9 -1
  24. package/dist/tabular/ITabularStorage.d.ts.map +1 -1
  25. package/dist/tabular/IndexedDbTabularStorage.d.ts +40 -0
  26. package/dist/tabular/IndexedDbTabularStorage.d.ts.map +1 -1
  27. package/dist/tabular/PostgresTabularStorage.d.ts +4 -0
  28. package/dist/tabular/PostgresTabularStorage.d.ts.map +1 -1
  29. package/dist/tabular/SqliteTabularStorage.d.ts +4 -0
  30. package/dist/tabular/SqliteTabularStorage.d.ts.map +1 -1
  31. package/dist/tabular/SupabaseTabularStorage.d.ts +9 -0
  32. package/dist/tabular/SupabaseTabularStorage.d.ts.map +1 -1
  33. package/dist/tabular/TelemetryTabularStorage.d.ts +1 -0
  34. package/dist/tabular/TelemetryTabularStorage.d.ts.map +1 -1
  35. package/package.json +3 -3
package/dist/node.js CHANGED
@@ -164,6 +164,13 @@ class BaseTabularStorage {
164
164
  waitOn(name) {
165
165
  return this.events.waitOn(name);
166
166
  }
167
+ async count(criteria) {
168
+ if (!criteria || Object.keys(criteria).length === 0) {
169
+ return await this.size();
170
+ }
171
+ const entities = await this.query(criteria);
172
+ return entities?.length ?? 0;
173
+ }
167
174
  async* records(pageSize = 100) {
168
175
  if (pageSize <= 0) {
169
176
  throw new RangeError(`pageSize must be greater than 0, got ${pageSize}`);
@@ -1191,6 +1198,9 @@ class TelemetryTabularStorage {
1191
1198
  size() {
1192
1199
  return traced("workglow.storage.tabular.size", this.storageName, () => this.inner.size());
1193
1200
  }
1201
+ count(criteria) {
1202
+ return traced("workglow.storage.tabular.count", this.storageName, () => this.inner.count(criteria));
1203
+ }
1194
1204
  deleteSearch(criteria) {
1195
1205
  return traced("workglow.storage.tabular.deleteSearch", this.storageName, () => this.inner.deleteSearch(criteria));
1196
1206
  }
@@ -1552,6 +1562,19 @@ class InMemoryQueueStorage {
1552
1562
  this.events.emit("change", { type: "UPDATE", old: existing, new: jobWithPrefixes });
1553
1563
  }
1554
1564
  }
1565
+ async release(id) {
1566
+ await sleep(0);
1567
+ const job = this.jobQueue.find((j) => j.id === id && this.matchesPrefixes(j));
1568
+ if (job) {
1569
+ const oldJob = { ...job };
1570
+ job.status = JobStatus.PENDING;
1571
+ job.worker_id = null;
1572
+ job.progress = 0;
1573
+ job.progress_message = "";
1574
+ job.progress_details = null;
1575
+ this.events.emit("change", { type: "UPDATE", old: oldJob, new: job });
1576
+ }
1577
+ }
1555
1578
  async abort(id) {
1556
1579
  await sleep(0);
1557
1580
  const job = this.jobQueue.find((j) => j.id === id && this.matchesPrefixes(j));
@@ -1651,6 +1674,9 @@ class TelemetryQueueStorage {
1651
1674
  complete(job) {
1652
1675
  return traced("workglow.storage.queue.complete", this.storageName, () => this.inner.complete(job));
1653
1676
  }
1677
+ release(id) {
1678
+ return traced("workglow.storage.queue.release", this.storageName, () => this.inner.release(id));
1679
+ }
1654
1680
  deleteAll() {
1655
1681
  return traced("workglow.storage.queue.deleteAll", this.storageName, () => this.inner.deleteAll());
1656
1682
  }
@@ -3119,6 +3145,16 @@ class PostgresTabularStorage extends BaseSqlTabularStorage {
3119
3145
  const result = await db.query(`SELECT COUNT(*) FROM "${this.table}"`);
3120
3146
  return parseInt(result.rows[0].count, 10);
3121
3147
  }
3148
+ async count(criteria) {
3149
+ if (!criteria || Object.keys(criteria).length === 0) {
3150
+ return await this.size();
3151
+ }
3152
+ this.validateQueryParams(criteria);
3153
+ const db = this.db;
3154
+ const { whereClause, params } = this.buildDeleteSearchWhere(criteria);
3155
+ const result = await db.query(`SELECT COUNT(*) FROM "${this.table}" WHERE ${whereClause}`, params);
3156
+ return parseInt(result.rows[0].count, 10);
3157
+ }
3122
3158
  async getBulk(offset, limit) {
3123
3159
  const db = this.db;
3124
3160
  const orderByClause = this.primaryKeyColumns().map((col) => `"${String(col)}"`).join(", ");
@@ -3585,6 +3621,18 @@ class SqliteTabularStorage extends BaseSqlTabularStorage {
3585
3621
  `);
3586
3622
  return stmt.get()?.count || 0;
3587
3623
  }
3624
+ async count(criteria) {
3625
+ if (!criteria || Object.keys(criteria).length === 0) {
3626
+ return await this.size();
3627
+ }
3628
+ this.validateQueryParams(criteria);
3629
+ const db = this.db;
3630
+ const { whereClause, params } = this.buildDeleteSearchWhere(criteria);
3631
+ const stmt = db.prepare(`
3632
+ SELECT COUNT(*) AS count FROM \`${this.table}\` WHERE ${whereClause}
3633
+ `);
3634
+ return stmt.get(...params)?.count || 0;
3635
+ }
3588
3636
  async getBulk(offset, limit) {
3589
3637
  const db = this.db;
3590
3638
  const orderByClause = this.primaryKeyColumns().map((col) => `\`${String(col)}\``).join(", ");
@@ -4029,16 +4077,9 @@ class SupabaseTabularStorage extends BaseSqlTabularStorage {
4029
4077
  }
4030
4078
  return data;
4031
4079
  }
4032
- async deleteSearch(criteria) {
4033
- const criteriaKeys = Object.keys(criteria);
4034
- if (criteriaKeys.length === 0) {
4035
- return;
4036
- }
4037
- let query = this.client.from(this.table).delete();
4038
- for (const column of criteriaKeys) {
4039
- if (!(column in this.schema.properties)) {
4040
- throw new Error(`Schema must have a ${String(column)} field to use deleteSearch`);
4041
- }
4080
+ applyCriteriaToFilter(query, criteria) {
4081
+ let q = query;
4082
+ for (const column of Object.keys(criteria)) {
4042
4083
  const criterion = criteria[column];
4043
4084
  let operator = "=";
4044
4085
  let value;
@@ -4050,32 +4091,45 @@ class SupabaseTabularStorage extends BaseSqlTabularStorage {
4050
4091
  }
4051
4092
  switch (operator) {
4052
4093
  case "=":
4053
- query = query.eq(String(column), value);
4094
+ q = q.eq(String(column), value);
4054
4095
  break;
4055
4096
  case "<":
4056
- query = query.lt(String(column), value);
4097
+ q = q.lt(String(column), value);
4057
4098
  break;
4058
4099
  case "<=":
4059
- query = query.lte(String(column), value);
4100
+ q = q.lte(String(column), value);
4060
4101
  break;
4061
4102
  case ">":
4062
- query = query.gt(String(column), value);
4103
+ q = q.gt(String(column), value);
4063
4104
  break;
4064
4105
  case ">=":
4065
- query = query.gte(String(column), value);
4106
+ q = q.gte(String(column), value);
4066
4107
  break;
4067
4108
  }
4068
4109
  }
4069
- const { error } = await query;
4110
+ return q;
4111
+ }
4112
+ async count(criteria) {
4113
+ if (!criteria || Object.keys(criteria).length === 0) {
4114
+ return await this.size();
4115
+ }
4116
+ this.validateQueryParams(criteria);
4117
+ const query = this.applyCriteriaToFilter(this.client.from(this.table).select("*", { count: "exact", head: true }), criteria);
4118
+ const { count, error } = await query;
4070
4119
  if (error)
4071
4120
  throw error;
4072
- this.events.emit("delete", criteriaKeys[0]);
4121
+ return count ?? 0;
4073
4122
  }
4074
- async query(criteria, options) {
4075
- this.validateQueryParams(criteria, options);
4123
+ async deleteSearch(criteria) {
4076
4124
  const criteriaKeys = Object.keys(criteria);
4077
- let query = this.client.from(this.table).select("*");
4125
+ if (criteriaKeys.length === 0) {
4126
+ return;
4127
+ }
4128
+ let query = this.client.from(this.table).delete();
4078
4129
  for (const column of criteriaKeys) {
4130
+ if (!(column in this.schema.properties)) {
4131
+ throw new Error(`Schema must have a ${String(column)} field to use deleteSearch`);
4132
+ }
4079
4133
  const criterion = criteria[column];
4080
4134
  let operator = "=";
4081
4135
  let value;
@@ -4103,6 +4157,14 @@ class SupabaseTabularStorage extends BaseSqlTabularStorage {
4103
4157
  break;
4104
4158
  }
4105
4159
  }
4160
+ const { error } = await query;
4161
+ if (error)
4162
+ throw error;
4163
+ this.events.emit("delete", criteriaKeys[0]);
4164
+ }
4165
+ async query(criteria, options) {
4166
+ this.validateQueryParams(criteria, options);
4167
+ let query = this.applyCriteriaToFilter(this.client.from(this.table).select("*"), criteria);
4106
4168
  if (options?.orderBy) {
4107
4169
  for (const { column, direction } of options.orderBy) {
4108
4170
  query = query.order(String(column), { ascending: direction === "ASC" });
@@ -4609,6 +4671,17 @@ class PostgresQueueStorage {
4609
4671
  SET status = 'ABORTING'
4610
4672
  WHERE id = $1 AND queue = $2${prefixConditions}`, [jobId, this.queueName, ...prefixParams]);
4611
4673
  }
4674
+ async release(jobId) {
4675
+ const { conditions: prefixConditions, params: prefixParams } = this.buildPrefixWhereClause(3);
4676
+ await this.db.query(`
4677
+ UPDATE ${this.tableName}
4678
+ SET status = 'PENDING',
4679
+ worker_id = NULL,
4680
+ progress = 0,
4681
+ progress_message = '',
4682
+ progress_details = NULL
4683
+ WHERE id = $1 AND queue = $2${prefixConditions}`, [jobId, this.queueName, ...prefixParams]);
4684
+ }
4612
4685
  async getByRunId(job_run_id) {
4613
4686
  const { conditions: prefixConditions, params: prefixParams } = this.buildPrefixWhereClause(3);
4614
4687
  const result = await this.db.query(`
@@ -4821,6 +4894,20 @@ class SqliteQueueStorage {
4821
4894
  const stmt = this.db.prepare(AbortQuery);
4822
4895
  stmt.run(JobStatus.ABORTING, String(jobId), this.queueName, ...prefixParams);
4823
4896
  }
4897
+ async release(jobId) {
4898
+ const prefixConditions = this.buildPrefixWhereClause();
4899
+ const prefixParams = this.getPrefixParamValues();
4900
+ const ReleaseQuery = `
4901
+ UPDATE ${this.tableName}
4902
+ SET status = ?,
4903
+ worker_id = NULL,
4904
+ progress = 0,
4905
+ progress_message = '',
4906
+ progress_details = NULL
4907
+ WHERE id = ? AND queue = ?${prefixConditions}`;
4908
+ const stmt = this.db.prepare(ReleaseQuery);
4909
+ stmt.run(JobStatus.PENDING, String(jobId), this.queueName, ...prefixParams);
4910
+ }
4824
4911
  async getByRunId(job_run_id) {
4825
4912
  const prefixConditions = this.buildPrefixWhereClause();
4826
4913
  const prefixParams = this.getPrefixParamValues();
@@ -5304,6 +5391,19 @@ class SupabaseQueueStorage {
5304
5391
  if (error)
5305
5392
  throw error;
5306
5393
  }
5394
+ async release(jobId) {
5395
+ let query = this.client.from(this.tableName).update({
5396
+ status: JobStatus.PENDING,
5397
+ worker_id: null,
5398
+ progress: 0,
5399
+ progress_message: "",
5400
+ progress_details: null
5401
+ }).eq("id", jobId).eq("queue", this.queueName);
5402
+ query = this.applyPrefixFilters(query);
5403
+ const { error } = await query;
5404
+ if (error)
5405
+ throw error;
5406
+ }
5307
5407
  async deleteAll() {
5308
5408
  let query = this.client.from(this.tableName).delete().eq("queue", this.queueName);
5309
5409
  query = this.applyPrefixFilters(query);
@@ -6966,6 +7066,7 @@ class IndexedDbTabularStorage extends BaseTabularStorage {
6966
7066
  migrationOptions;
6967
7067
  hybridManager = null;
6968
7068
  hybridOptions;
7069
+ cursorSafeIndexes;
6969
7070
  constructor(table = "tabular_store", schema, primaryKeyNames, indexes = [], migrationOptions = {}, clientProvidedKeys = "if-missing") {
6970
7071
  super(schema, primaryKeyNames, indexes, clientProvidedKeys);
6971
7072
  this.table = table;
@@ -7191,6 +7292,83 @@ class IndexedDbTabularStorage extends BaseTabularStorage {
7191
7292
  request.onsuccess = () => resolve(request.result);
7192
7293
  });
7193
7294
  }
7295
+ getCursorSafeIndexes() {
7296
+ if (this.cursorSafeIndexes)
7297
+ return this.cursorSafeIndexes;
7298
+ const required = new Set(this.schema.required ?? []);
7299
+ this.cursorSafeIndexes = this.indexes.filter((columns) => columns.every((column) => required.has(String(column))));
7300
+ return this.cursorSafeIndexes;
7301
+ }
7302
+ createIndexedRange(store, criteria) {
7303
+ const criteriaColumns = Object.keys(criteria);
7304
+ if (criteriaColumns.length === 0)
7305
+ return;
7306
+ let best;
7307
+ for (const indexColumns of this.getCursorSafeIndexes()) {
7308
+ const prefixValues = [];
7309
+ for (const column of indexColumns) {
7310
+ const value = this.getEqualityCriterionValue(criteria, column);
7311
+ if (value === undefined)
7312
+ break;
7313
+ prefixValues.push(value);
7314
+ }
7315
+ if (prefixValues.length === 0)
7316
+ continue;
7317
+ const indexedPrefix = indexColumns.slice(0, prefixValues.length);
7318
+ const coversCriteria = criteriaColumns.every((column) => indexedPrefix.includes(column));
7319
+ const better = !best || coversCriteria && !best.coversCriteria || coversCriteria === best.coversCriteria && prefixValues.length > best.prefixValues.length;
7320
+ if (better) {
7321
+ best = {
7322
+ indexName: indexColumns.map((column) => String(column)).join("_"),
7323
+ prefixValues,
7324
+ fullMatch: prefixValues.length === indexColumns.length,
7325
+ coversCriteria
7326
+ };
7327
+ }
7328
+ }
7329
+ if (!best)
7330
+ return;
7331
+ const range = best.fullMatch ? IDBKeyRange.only(best.prefixValues.length === 1 ? best.prefixValues[0] : best.prefixValues) : IDBKeyRange.bound(best.prefixValues, [...best.prefixValues, []]);
7332
+ return {
7333
+ source: store.index(best.indexName),
7334
+ range,
7335
+ coversCriteria: best.coversCriteria
7336
+ };
7337
+ }
7338
+ async count(criteria) {
7339
+ if (!criteria || Object.keys(criteria).length === 0) {
7340
+ return await this.size();
7341
+ }
7342
+ this.validateQueryParams(criteria);
7343
+ const db = await this.getDb();
7344
+ return new Promise((resolve, reject) => {
7345
+ const transaction = db.transaction(this.table, "readonly");
7346
+ const store = transaction.objectStore(this.table);
7347
+ const plan = this.createIndexedRange(store, criteria);
7348
+ if (plan?.coversCriteria) {
7349
+ const request2 = plan.source.count(plan.range);
7350
+ request2.onerror = () => reject(request2.error);
7351
+ request2.onsuccess = () => resolve(request2.result);
7352
+ return;
7353
+ }
7354
+ const source = plan?.source ?? store;
7355
+ const range = plan?.range;
7356
+ let count = 0;
7357
+ const request = source.openCursor(range);
7358
+ request.onerror = () => reject(request.error);
7359
+ request.onsuccess = () => {
7360
+ const cursor = request.result;
7361
+ if (!cursor) {
7362
+ resolve(count);
7363
+ return;
7364
+ }
7365
+ if (this.matchesCriteria(cursor.value, criteria)) {
7366
+ count += 1;
7367
+ }
7368
+ cursor.continue();
7369
+ };
7370
+ });
7371
+ }
7194
7372
  async getBulk(offset, limit) {
7195
7373
  if (offset < 0) {
7196
7374
  throw new RangeError(`offset must be non-negative, got ${offset}`);
@@ -7312,48 +7490,135 @@ class IndexedDbTabularStorage extends BaseTabularStorage {
7312
7490
  }
7313
7491
  });
7314
7492
  }
7493
+ getEqualityCriterionValue(criteria, column) {
7494
+ const criterion = criteria[column];
7495
+ if (criterion === undefined)
7496
+ return;
7497
+ if (isSearchCondition(criterion)) {
7498
+ return criterion.operator === "=" ? criterion.value : undefined;
7499
+ }
7500
+ return criterion;
7501
+ }
7502
+ compareByOrder(a, b, options) {
7503
+ if (!options?.orderBy)
7504
+ return 0;
7505
+ for (const { column, direction } of options.orderBy) {
7506
+ const aVal = a[column];
7507
+ const bVal = b[column];
7508
+ if (aVal == null && bVal == null)
7509
+ continue;
7510
+ if (aVal == null)
7511
+ return direction === "ASC" ? -1 : 1;
7512
+ if (bVal == null)
7513
+ return direction === "ASC" ? 1 : -1;
7514
+ if (aVal < bVal)
7515
+ return direction === "ASC" ? -1 : 1;
7516
+ if (aVal > bVal)
7517
+ return direction === "ASC" ? 1 : -1;
7518
+ }
7519
+ return 0;
7520
+ }
7521
+ createIndexedQuery(store, criteria, options) {
7522
+ const orderBy = options?.orderBy ?? [];
7523
+ let best;
7524
+ for (const indexColumns of this.getCursorSafeIndexes()) {
7525
+ const prefixValues = [];
7526
+ for (const column of indexColumns) {
7527
+ const value = this.getEqualityCriterionValue(criteria, column);
7528
+ if (value === undefined)
7529
+ break;
7530
+ prefixValues.push(value);
7531
+ }
7532
+ if (prefixValues.length === 0)
7533
+ continue;
7534
+ const remainingColumns = indexColumns.slice(prefixValues.length);
7535
+ let redundantOrderPrefixLength = 0;
7536
+ while (redundantOrderPrefixLength < orderBy.length && redundantOrderPrefixLength < prefixValues.length && orderBy[redundantOrderPrefixLength]?.column === indexColumns[redundantOrderPrefixLength]) {
7537
+ redundantOrderPrefixLength++;
7538
+ }
7539
+ const normalizedOrderBy = orderBy.slice(redundantOrderPrefixLength);
7540
+ const satisfiesOrder = normalizedOrderBy.length === 0 || normalizedOrderBy.length <= remainingColumns.length && normalizedOrderBy.every((order, index) => order.column === remainingColumns[index]) && orderBy.every((order) => order.direction === orderBy[0]?.direction);
7541
+ if (!satisfiesOrder && best)
7542
+ continue;
7543
+ if (!best || satisfiesOrder && !best.satisfiesOrder || prefixValues.length > best.prefixValues.length) {
7544
+ best = {
7545
+ indexName: indexColumns.map((column) => String(column)).join("_"),
7546
+ prefixValues,
7547
+ fullMatch: prefixValues.length === indexColumns.length,
7548
+ satisfiesOrder,
7549
+ direction: orderBy[0]?.direction === "DESC" ? "prev" : "next"
7550
+ };
7551
+ }
7552
+ }
7553
+ const appliedLimit = Boolean(best?.satisfiesOrder && options?.limit !== undefined);
7554
+ const appliedOffset = Boolean(best?.satisfiesOrder && options?.offset !== undefined);
7555
+ if (!best) {
7556
+ return {
7557
+ source: store,
7558
+ range: undefined,
7559
+ direction: orderBy[0]?.direction === "DESC" ? "prev" : "next",
7560
+ satisfiesOrder: false,
7561
+ appliedLimit: false,
7562
+ appliedOffset: false,
7563
+ skipRemaining: 0
7564
+ };
7565
+ }
7566
+ const source = store.index(best.indexName);
7567
+ const keyRange = best.fullMatch ? IDBKeyRange.only(best.prefixValues.length === 1 ? best.prefixValues[0] : best.prefixValues) : IDBKeyRange.bound(best.prefixValues, [...best.prefixValues, []]);
7568
+ return {
7569
+ source,
7570
+ range: keyRange,
7571
+ direction: best.direction,
7572
+ satisfiesOrder: best.satisfiesOrder,
7573
+ appliedLimit,
7574
+ appliedOffset,
7575
+ skipRemaining: appliedOffset ? options?.offset ?? 0 : 0
7576
+ };
7577
+ }
7315
7578
  async query(criteria, options) {
7316
7579
  this.validateQueryParams(criteria, options);
7317
7580
  const db = await this.getDb();
7318
7581
  return new Promise((resolve, reject) => {
7319
7582
  const transaction = db.transaction(this.table, "readonly");
7320
7583
  const store = transaction.objectStore(this.table);
7321
- const getAllRequest = store.getAll();
7322
- getAllRequest.onsuccess = () => {
7323
- const allRecords = getAllRequest.result;
7324
- let results = allRecords.filter((record) => this.matchesCriteria(record, criteria));
7325
- if (options?.orderBy && options.orderBy.length > 0) {
7326
- results.sort((a, b) => {
7327
- for (const { column, direction } of options.orderBy) {
7328
- const aVal = a[column];
7329
- const bVal = b[column];
7330
- if (aVal == null && bVal == null)
7331
- continue;
7332
- if (aVal == null)
7333
- return direction === "ASC" ? -1 : 1;
7334
- if (bVal == null)
7335
- return direction === "ASC" ? 1 : -1;
7336
- if (aVal < bVal)
7337
- return direction === "ASC" ? -1 : 1;
7338
- if (aVal > bVal)
7339
- return direction === "ASC" ? 1 : -1;
7340
- }
7341
- return 0;
7342
- });
7343
- }
7344
- if (options?.offset !== undefined) {
7345
- results = results.slice(options.offset);
7584
+ const indexedQuery = this.createIndexedQuery(store, criteria, options);
7585
+ const results = [];
7586
+ const request = indexedQuery.source.openCursor(indexedQuery.range, indexedQuery.direction);
7587
+ request.onsuccess = () => {
7588
+ const cursor = request.result;
7589
+ if (!cursor) {
7590
+ let finalResults = results;
7591
+ if (!indexedQuery.satisfiesOrder && options?.orderBy && options.orderBy.length > 0) {
7592
+ finalResults = [...finalResults].sort((a, b) => this.compareByOrder(a, b, options));
7593
+ }
7594
+ if (!indexedQuery.appliedOffset && options?.offset !== undefined) {
7595
+ finalResults = finalResults.slice(options.offset);
7596
+ }
7597
+ if (!indexedQuery.appliedLimit && options?.limit !== undefined) {
7598
+ finalResults = finalResults.slice(0, options.limit);
7599
+ }
7600
+ const result = finalResults.length > 0 ? finalResults : undefined;
7601
+ this.events.emit("query", criteria, result);
7602
+ resolve(result);
7603
+ return;
7346
7604
  }
7347
- if (options?.limit !== undefined) {
7348
- results = results.slice(0, options.limit);
7605
+ const record = cursor.value;
7606
+ if (this.matchesCriteria(record, criteria)) {
7607
+ if (indexedQuery.skipRemaining > 0) {
7608
+ indexedQuery.skipRemaining -= 1;
7609
+ } else {
7610
+ results.push(record);
7611
+ if (indexedQuery.appliedLimit && results.length === options?.limit) {
7612
+ const result = results.length > 0 ? results : undefined;
7613
+ this.events.emit("query", criteria, result);
7614
+ resolve(result);
7615
+ return;
7616
+ }
7617
+ }
7349
7618
  }
7350
- const result = results.length > 0 ? results : undefined;
7351
- this.events.emit("query", criteria, result);
7352
- resolve(result);
7353
- };
7354
- getAllRequest.onerror = () => {
7355
- reject(getAllRequest.error);
7619
+ cursor.continue();
7356
7620
  };
7621
+ request.onerror = () => reject(request.error);
7357
7622
  });
7358
7623
  }
7359
7624
  getHybridManager() {
@@ -7788,7 +8053,7 @@ class IndexedDbQueueStorage {
7788
8053
  const prefixKeyValues = this.getPrefixKeyValues();
7789
8054
  const claimToken = workerId;
7790
8055
  const jobToReturn = await new Promise((resolve, reject) => {
7791
- const cursorRequest = index.openCursor(IDBKeyRange.bound([...prefixKeyValues, this.queueName, JobStatus.PENDING, ""], [...prefixKeyValues, this.queueName, JobStatus.PENDING, now], false, true));
8056
+ const cursorRequest = index.openCursor(IDBKeyRange.bound([...prefixKeyValues, this.queueName, JobStatus.PENDING, ""], [...prefixKeyValues, this.queueName, JobStatus.PENDING, now], false, false));
7792
8057
  let claimedJob;
7793
8058
  let cursorStopped = false;
7794
8059
  cursorRequest.onsuccess = (e) => {
@@ -7891,6 +8156,17 @@ class IndexedDbQueueStorage {
7891
8156
  tx.onerror = () => reject(tx.error);
7892
8157
  });
7893
8158
  }
8159
+ async release(id) {
8160
+ const job = await this.get(id);
8161
+ if (!job)
8162
+ return;
8163
+ job.status = JobStatus.PENDING;
8164
+ job.worker_id = null;
8165
+ job.progress = 0;
8166
+ job.progress_message = "";
8167
+ job.progress_details = null;
8168
+ await this.put(job);
8169
+ }
7894
8170
  async abort(id) {
7895
8171
  const job = await this.get(id);
7896
8172
  if (!job)
@@ -8387,4 +8663,4 @@ export {
8387
8663
  BaseTabularStorage
8388
8664
  };
8389
8665
 
8390
- //# debugId=DE2802AC74ABE49264756E2164756E21
8666
+ //# debugId=1E55C44CEF8B06B964756E2164756E21