@rotorsoft/act 1.23.35 → 1.23.37

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.js CHANGED
@@ -209,7 +209,19 @@ var make_schema_pass = (deps) => {
209
209
  return;
210
210
  }
211
211
  const schema = state2.events[name];
212
- const parsed = schema.safeParse(event.data);
212
+ const sensitive2 = pii_fields(schema);
213
+ let parse_schema = schema;
214
+ if (sensitive2.length > 0) {
215
+ const omitter = schema.omit;
216
+ if (typeof omitter !== "function") {
217
+ return;
218
+ }
219
+ parse_schema = omitter.call(
220
+ schema,
221
+ Object.fromEntries(sensitive2.map((f) => [f, true]))
222
+ );
223
+ }
224
+ const parsed = parse_schema.safeParse(event.data);
213
225
  if (!parsed.success) {
214
226
  findings.push({
215
227
  category: "schema",
@@ -2531,6 +2543,13 @@ function trace_cycle(logger, leased, fetched, handled, acked, blocked) {
2531
2543
  }
2532
2544
 
2533
2545
  // src/internal/drain-cycle.ts
2546
+ function budget_exhausted(lease, options) {
2547
+ if (!options?.blockOnError || lease.retry <= options.maxRetries)
2548
+ return void 0;
2549
+ const error = `Blocking ${lease.stream} after ${lease.retry} claims with no acknowledged progress \u2014 the lease was lost on every attempt, so the retry budget (${options.maxRetries}) was spent without the handler ever reporting an error. Raise leaseMillis for this handler, then unblock the stream.`;
2550
+ log().error(error);
2551
+ return { lease, handled: 0, acked_at: lease.at, error, block: true };
2552
+ }
2534
2553
  async function run_drain_cycle(ops, registry, batch_handlers, handle, handle_batch, lagging, leading, eventLimit, leaseMillis, on_blocked, lane) {
2535
2554
  const leased = await ops.claim(
2536
2555
  lagging,
@@ -2563,6 +2582,8 @@ async function run_drain_cycle(ops, registry, batch_handlers, handle, handle_bat
2563
2582
  const entry = fetch_map.get(lease.stream);
2564
2583
  const at = entry.fetch.events.at(-1)?.id || fetch_window_at;
2565
2584
  const { payloads } = entry;
2585
+ const exhausted = budget_exhausted(lease, payloads[0]?.options);
2586
+ if (exhausted) return Promise.resolve(exhausted);
2566
2587
  const batchHandler = batch_handlers.get(lease.stream);
2567
2588
  if (batchHandler && payloads.length > 0) {
2568
2589
  return handle_batch({ ...lease, at }, payloads, batchHandler);
@@ -2574,12 +2595,18 @@ async function run_drain_cycle(ops, registry, batch_handlers, handle, handle_bat
2574
2595
  handled.filter(({ block: block2 }) => block2).map(({ lease, error }) => ({ ...lease, error }))
2575
2596
  );
2576
2597
  if (blocked.length) on_blocked(blocked);
2577
- const acked = await ops.ack(
2578
- handled.flatMap((h, i) => {
2579
- const advance = h.handled > 0 ? h.acked_at : leased[i].at;
2580
- return h.defer !== void 0 ? { ...h.lease, at: advance, due: h.defer, retry: -1 } : h.next_attempt_at !== void 0 ? { ...h.lease, at: advance, due: h.next_attempt_at } : h.handled > 0 || !h.error ? { ...h.lease, at: h.acked_at } : [];
2581
- })
2582
- );
2598
+ const submitted = handled.flatMap((h, i) => {
2599
+ const advance = h.handled > 0 ? h.acked_at : leased[i].at;
2600
+ return h.defer !== void 0 ? { ...h.lease, at: advance, due: h.defer, retry: -1 } : h.next_attempt_at !== void 0 ? { ...h.lease, at: advance, due: h.next_attempt_at } : h.handled > 0 || !h.error ? { ...h.lease, at: h.acked_at } : [];
2601
+ });
2602
+ const acked = await ops.ack(submitted);
2603
+ const expected = submitted.filter((l) => l.due === void 0).length;
2604
+ if (acked.length < expected)
2605
+ log().error(
2606
+ new Error(
2607
+ `drain: ${expected - acked.length} of ${expected} acks were dropped \u2014 the lease was taken by another worker mid-handler. That work will be redelivered (at-least-once), but persistent drops mean leaseMillis is too short for this handler.`
2608
+ )
2609
+ );
2583
2610
  const closeable = handled.filter((h) => h.close !== void 0).map((h) => h.close);
2584
2611
  return { leased, fetched, handled, acked, blocked, closeable };
2585
2612
  }