@zizq-labs/zizq 0.1.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/dist/client.d.ts CHANGED
@@ -545,6 +545,16 @@ export declare class Client {
545
545
  * ```
546
546
  */
547
547
  deleteAllJobs(options?: DeleteAllJobsOptions): Promise<number>;
548
+ /**
549
+ * Count jobs matching the given filters.
550
+ *
551
+ * @example
552
+ * ```ts
553
+ * // Count all ready jobs in the emails queue
554
+ * const count = await client.countJobs({ queue: "emails", status: "ready" });
555
+ * ```
556
+ */
557
+ countJobs(where?: JobFilter): Promise<number>;
548
558
  /**
549
559
  * Update a single job's mutable fields.
550
560
  *
package/dist/client.js CHANGED
@@ -292,31 +292,36 @@ export class Client {
292
292
  assertOnlyKeys("deleteAllJobs", options, ["where"]);
293
293
  const where = options.where ?? {};
294
294
  assertOnlyKeys("deleteAllJobs.where", where, ["id", "status", "queue", "type", "filter"]);
295
- // Build the multi-value filters first so we can short-circuit if any
296
- // resolves to an empty string. An empty filter matches nothing we
297
- // don't want to pass it as "no filter" and accidentally delete everything.
298
- const id = where.id != null ? toCommaList(where.id) : undefined;
299
- const status = where.status != null ? toCommaList(where.status) : undefined;
300
- const queue = where.queue != null ? toCommaList(where.queue) : undefined;
301
- const type = where.type != null ? toCommaList(where.type) : undefined;
302
- if (id === "" || status === "" || queue === "" || type === "")
295
+ // Build the filter params, then short-circuit if any array filter resolved
296
+ // to empty an empty filter matches nothing, and we don't want to
297
+ // accidentally delete everything.
298
+ const params = buildJobFilter(where);
299
+ if (isEmptyFilter(params))
303
300
  return 0;
304
- const params = new URLSearchParams();
305
- if (id != null)
306
- params.set("id", id);
307
- if (status != null)
308
- params.set("status", status);
309
- if (queue != null)
310
- params.set("queue", queue);
311
- if (type != null)
312
- params.set("type", type);
313
- if (where.filter != null)
314
- params.set("filter", where.filter);
315
301
  const qs = params.toString();
316
302
  const path = `/jobs${qs ? "?" + qs : ""}`;
317
303
  const data = await this.handleResponse(await this.request("DELETE", path));
318
304
  return data.deleted;
319
305
  }
306
+ /**
307
+ * Count jobs matching the given filters.
308
+ *
309
+ * @example
310
+ * ```ts
311
+ * // Count all ready jobs in the emails queue
312
+ * const count = await client.countJobs({ queue: "emails", status: "ready" });
313
+ * ```
314
+ */
315
+ async countJobs(where = {}) {
316
+ assertOnlyKeys("countJobs", where, ["id", "status", "queue", "type", "filter"]);
317
+ const params = buildJobFilter(where);
318
+ if (isEmptyFilter(params))
319
+ return 0;
320
+ const qs = params.toString();
321
+ const path = `/jobs/count${qs ? "?" + qs : ""}`;
322
+ const data = await this.handleResponse(await this.request("GET", path));
323
+ return data.count;
324
+ }
320
325
  /**
321
326
  * Update a single job's mutable fields.
322
327
  *
@@ -361,23 +366,9 @@ export class Client {
361
366
  const where = options.where ?? {};
362
367
  assertOnlyKeys("updateAllJobs.where", where, ["id", "status", "queue", "type", "filter"]);
363
368
  // Same empty-filter short-circuit as deleteAllJobs.
364
- const id = where.id != null ? toCommaList(where.id) : undefined;
365
- const status = where.status != null ? toCommaList(where.status) : undefined;
366
- const queue = where.queue != null ? toCommaList(where.queue) : undefined;
367
- const type = where.type != null ? toCommaList(where.type) : undefined;
368
- if (id === "" || status === "" || queue === "" || type === "")
369
+ const params = buildJobFilter(where);
370
+ if (isEmptyFilter(params))
369
371
  return 0;
370
- const params = new URLSearchParams();
371
- if (id != null)
372
- params.set("id", id);
373
- if (status != null)
374
- params.set("status", status);
375
- if (queue != null)
376
- params.set("queue", queue);
377
- if (type != null)
378
- params.set("type", type);
379
- if (where.filter != null)
380
- params.set("filter", where.filter);
381
372
  const qs = params.toString();
382
373
  const path = `/jobs${qs ? "?" + qs : ""}`;
383
374
  const api = updateToApi(options.apply);
@@ -409,16 +400,9 @@ export class Client {
409
400
  params.set("order", options.order);
410
401
  if (options.limit != null)
411
402
  params.set("limit", String(options.limit));
412
- if (options.status)
413
- params.set("status", toCommaList(options.status));
414
- if (options.queue)
415
- params.set("queue", toCommaList(options.queue));
416
- if (options.type)
417
- params.set("type", toCommaList(options.type));
418
- if (options.id)
419
- params.set("id", toCommaList(options.id));
420
- if (options.filter != null)
421
- params.set("filter", options.filter);
403
+ buildJobFilter(options, params);
404
+ if (isEmptyFilter(params))
405
+ return new JobPage(this, [], {});
422
406
  const qs = params.toString();
423
407
  const path = `/jobs${qs ? "?" + qs : ""}`;
424
408
  return this.listJobsByPath(path);
@@ -757,6 +741,34 @@ export class Client {
757
741
  function toCommaList(value) {
758
742
  return Array.isArray(value) ? value.join(",") : value;
759
743
  }
744
+ /**
745
+ * Returns `true` when any array filter field resolved to an empty comma list,
746
+ * meaning the filter matches nothing and the caller can short-circuit.
747
+ *
748
+ * Call after {@link buildJobFilter} has populated the params.
749
+ */
750
+ function isEmptyFilter(params) {
751
+ return (params.get("id") === "" ||
752
+ params.get("status") === "" ||
753
+ params.get("queue") === "" ||
754
+ params.get("type") === "");
755
+ }
756
+ /**
757
+ * Populate a {@link URLSearchParams} with the standard job filter fields.
758
+ */
759
+ function buildJobFilter(where, params = new URLSearchParams()) {
760
+ if (where.id != null)
761
+ params.set("id", toCommaList(where.id));
762
+ if (where.status != null)
763
+ params.set("status", toCommaList(where.status));
764
+ if (where.queue != null)
765
+ params.set("queue", toCommaList(where.queue));
766
+ if (where.type != null)
767
+ params.set("type", toCommaList(where.type));
768
+ if (where.filter != null)
769
+ params.set("filter", where.filter);
770
+ return params;
771
+ }
760
772
  /**
761
773
  * Throw if `obj` contains keys not in the allowed list.
762
774
  *
package/dist/query.d.ts CHANGED
@@ -272,6 +272,16 @@ export declare class JobQuery extends Lazy<Job> {
272
272
  * Returns 1 if a job was deleted, 0 if no jobs matched.
273
273
  */
274
274
  deleteOne(): Promise<number>;
275
+ /**
276
+ * Count matching jobs using the server-side count endpoint.
277
+ *
278
+ * This overrides the base `Lazy.count()` with a single HTTP request to
279
+ * `GET /jobs/count` instead of paginating through all results.
280
+ *
281
+ * When a `limit` is set, caps the server-side count locally with
282
+ * `Math.min()` rather than paginating.
283
+ */
284
+ count(): Promise<number>;
275
285
  /**
276
286
  * Async iterator over individual jobs.
277
287
  *
package/dist/query.js CHANGED
@@ -402,6 +402,19 @@ export class JobQuery extends Lazy {
402
402
  async deleteOne() {
403
403
  return this.limit(1).deleteAll();
404
404
  }
405
+ /**
406
+ * Count matching jobs using the server-side count endpoint.
407
+ *
408
+ * This overrides the base `Lazy.count()` with a single HTTP request to
409
+ * `GET /jobs/count` instead of paginating through all results.
410
+ *
411
+ * When a `limit` is set, caps the server-side count locally with
412
+ * `Math.min()` rather than paginating.
413
+ */
414
+ async count() {
415
+ const total = await this.client.countJobs(this.toWhere());
416
+ return this._limit != null ? Math.min(total, this._limit) : total;
417
+ }
405
418
  // --- Iteration ---
406
419
  /**
407
420
  * Async iterator over individual jobs.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zizq-labs/zizq",
3
- "version": "0.1.1",
3
+ "version": "0.2.0",
4
4
  "description": "Node.js client for the Zizq job queue server",
5
5
  "homepage": "https://zizq.io",
6
6
  "repository": {
@@ -10,7 +10,13 @@
10
10
  "bugs": {
11
11
  "url": "https://github.com/zizq-labs/zizq-node/issues"
12
12
  },
13
- "keywords": ["zizq", "job-queue", "background-jobs", "worker", "queue"],
13
+ "keywords": [
14
+ "zizq",
15
+ "job-queue",
16
+ "background-jobs",
17
+ "worker",
18
+ "queue"
19
+ ],
14
20
  "type": "module",
15
21
  "main": "dist/index.js",
16
22
  "types": "dist/index.d.ts",