@lunora/queue 1.0.0-alpha.6 → 1.0.0-alpha.8

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/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
- export { createQueueCaptureSink, shouldCaptureQueue } from './packem_shared/createQueueCaptureSink-CRacRMqV.mjs';
1
+ export { createQueueCaptureSink, shouldCaptureQueue } from './packem_shared/createQueueCaptureSink-B8WE0eHf.mjs';
2
2
  export { createQueueContext } from './packem_shared/createQueueContext-D0XCdCsd.mjs';
3
3
  export { default as createQueues } from './packem_shared/createQueues-14-vSICK.mjs';
4
4
  export { defineQueue, isQueueDefinition, queueBindingName, queueDefaultName } from './packem_shared/defineQueue-D40gREfg.mjs';
5
- export { dispatchQueueBatch } from './packem_shared/dispatchQueueBatch-BjWnrUuU.mjs';
6
- export { createQueueRunContext } from './packem_shared/createQueueRunContext-_2hD-TK7.mjs';
5
+ export { dispatchQueueBatch } from './packem_shared/dispatchQueueBatch-DSEWhEy8.mjs';
6
+ export { createQueueRunContext } from './packem_shared/createQueueRunContext-C8jboCk6.mjs';
@@ -1,3 +1,5 @@
1
+ import { LunoraError } from '@lunora/errors';
2
+
1
3
  const RECORD_QUEUE_MESSAGE_OP = "__lunora_admin__:recordQueueMessage";
2
4
  const DEFAULT_ROOT_SHARD = "__root__";
3
5
  const DEV_ENVIRONMENT_PATTERN = /^(?:dev(?:elopment)?|local(?:host)?|test)$/iu;
@@ -39,12 +41,20 @@ const createQueueCaptureSink = (env, options = {}) => {
39
41
  controller.abort();
40
42
  }, CAPTURE_FETCH_TIMEOUT_MS);
41
43
  try {
42
- await stub.fetch("https://shard.internal/rpc", {
44
+ const response = await stub.fetch("https://shard.internal/rpc", {
43
45
  body: JSON.stringify({ args: { messages }, functionPath: RECORD_QUEUE_MESSAGE_OP }),
44
46
  headers: { authorization: `Bearer ${adminToken}`, "content-type": "application/json" },
45
47
  method: "POST",
46
48
  signal: controller.signal
47
49
  });
50
+ if (!response.ok) {
51
+ const detail = await response.text().catch(() => "");
52
+ throw new LunoraError(
53
+ "INTERNAL",
54
+ `@lunora/queue: capture write to the root shard failed (${String(response.status)} ${response.statusText})${detail === "" ? "" : `: ${detail}`}`
55
+ );
56
+ }
57
+ await response.body?.cancel();
48
58
  } finally {
49
59
  clearTimeout(timeout);
50
60
  }
@@ -25,6 +25,18 @@ const trimTrailingSlashes = (value) => {
25
25
  }
26
26
  return value.slice(0, end);
27
27
  };
28
+ const toDispatchError = (label, status, rawBody) => {
29
+ try {
30
+ const parsed = JSON.parse(rawBody);
31
+ const errorBody = parsed?.error;
32
+ if (typeof errorBody === "object" && errorBody !== null && typeof errorBody.code === "string") {
33
+ const { code, data, message } = errorBody;
34
+ return new LunoraError(code, typeof message === "string" ? message : void 0, { data, status });
35
+ }
36
+ } catch {
37
+ }
38
+ return new LunoraError("INTERNAL", `${label}: function dispatch failed (${String(status)}): ${rawBody}`, { status });
39
+ };
28
40
  const createDispatchRunner = (options) => {
29
41
  const { label } = options;
30
42
  const globalFetch = globalThis.fetch;
@@ -42,13 +54,20 @@ const createDispatchRunner = (options) => {
42
54
  throw new LunoraError("INTERNAL", `${label}: \`LUNORA_ADMIN_TOKEN\` must be set on the Worker env to authenticate function dispatch`);
43
55
  }
44
56
  const url = `${trimTrailingSlashes(origin)}${SCHEDULER_DISPATCH_PATH}`;
57
+ const headers = { authorization: `Bearer ${token}`, "content-type": "application/json" };
58
+ if (options.identity?.userId !== void 0) {
59
+ headers["x-lunora-userid"] = options.identity.userId;
60
+ }
61
+ if (options.identity?.claims !== void 0) {
62
+ headers["x-lunora-identity"] = JSON.stringify(options.identity.claims);
63
+ }
45
64
  const response = await fetchImpl(url, {
46
65
  body: JSON.stringify({ args: args ?? {}, functionPath: function_.__lunoraRef, shardKey: runOptions.shardKey }),
47
- headers: { authorization: `Bearer ${token}`, "content-type": "application/json" },
66
+ headers,
48
67
  method: "POST"
49
68
  });
50
69
  if (!response.ok) {
51
- throw new LunoraError("INTERNAL", `${label}: function dispatch failed (${String(response.status)}): ${await response.text()}`);
70
+ throw toDispatchError(label, response.status, await response.text());
52
71
  }
53
72
  const text = await response.text();
54
73
  if (text.length === 0) {
@@ -57,7 +76,9 @@ const createDispatchRunner = (options) => {
57
76
  try {
58
77
  return JSON.parse(text);
59
78
  } catch {
60
- return text;
79
+ throw new LunoraError("INTERNAL", `${label}: function dispatch returned a non-JSON body (${String(response.status)}): ${text}`, {
80
+ status: response.status
81
+ });
61
82
  }
62
83
  };
63
84
  };
@@ -1,5 +1,5 @@
1
1
  import { LunoraError } from '@lunora/errors';
2
- import { createQueueRunContext } from './createQueueRunContext-_2hD-TK7.mjs';
2
+ import { createQueueRunContext } from './createQueueRunContext-C8jboCk6.mjs';
3
3
 
4
4
  const DEFAULT_MAX_RETRIES = 3;
5
5
  const timestampToMs = (value) => {
@@ -94,7 +94,7 @@ const buildCaptureRecords = (harness, entry, queue, threw, handlerError) => {
94
94
  });
95
95
  };
96
96
  const dispatchQueueBatch = async (batch, registry, options) => {
97
- const entry = registry[batch.queue];
97
+ const entry = Object.hasOwn(registry, batch.queue) ? registry[batch.queue] : void 0;
98
98
  if (entry === void 0) {
99
99
  const known = Object.keys(registry);
100
100
  const suffix = known.length === 0 ? "no push queues are declared" : `known push queues: ${known.join(", ")}`;
@@ -121,7 +121,8 @@ const dispatchQueueBatch = async (batch, registry, options) => {
121
121
  try {
122
122
  const records = buildCaptureRecords(harness, entry, batch.queue, threw, handlerError);
123
123
  await options.capture(records);
124
- } catch {
124
+ } catch (captureError) {
125
+ console.warn("@lunora/queue: capture sink failed (delivery unaffected):", captureError);
125
126
  }
126
127
  if (threw) {
127
128
  throw handlerError;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lunora/queue",
3
- "version": "1.0.0-alpha.6",
3
+ "version": "1.0.0-alpha.8",
4
4
  "description": "Cloudflare Queues for Lunora: defineQueue producers + consumers, the ctx.queues surface, and the generated queue() worker handler",
5
5
  "keywords": [
6
6
  "background-jobs",
@@ -44,7 +44,7 @@
44
44
  "access": "public"
45
45
  },
46
46
  "dependencies": {
47
- "@lunora/errors": "1.0.0-alpha.3"
47
+ "@lunora/errors": "1.0.0-alpha.5"
48
48
  },
49
49
  "engines": {
50
50
  "node": "^22.15.0 || >=24.11.0"