deepline 0.3.113 → 0.3.115

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 (50) hide show
  1. package/dist/bundling-sources/sdk/src/client.ts +3 -1
  2. package/dist/bundling-sources/sdk/src/compat.ts +167 -11
  3. package/dist/bundling-sources/sdk/src/release.ts +1 -1
  4. package/dist/bundling-sources/sdk/src/skills-version.ts +27 -1
  5. package/dist/bundling-sources/shared_libs/monitors/inbound-queue.ts +6 -2
  6. package/dist/bundling-sources/shared_libs/observability/dlq.ts +942 -0
  7. package/dist/bundling-sources/shared_libs/observability/queue-health.ts +361 -6
  8. package/dist/bundling-sources/shared_libs/observability/scheduled-jobs.json +24 -24
  9. package/dist/bundling-sources/shared_libs/observability/scheduled-work-manual.ts +2 -0
  10. package/dist/bundling-sources/shared_libs/observability/scheduled-work.ts +29 -1
  11. package/dist/bundling-sources/shared_libs/play-runtime/admission-transport-policy.ts +91 -0
  12. package/dist/bundling-sources/shared_libs/play-runtime/context.ts +2 -0
  13. package/dist/bundling-sources/shared_libs/play-runtime/direct-admission-deadline.ts +34 -0
  14. package/dist/bundling-sources/shared_libs/play-runtime/fixture-behavior.ts +1 -0
  15. package/dist/bundling-sources/shared_libs/play-runtime/internal-bootstrap-token.ts +325 -0
  16. package/dist/bundling-sources/shared_libs/play-runtime/play-admission-outcome.ts +134 -0
  17. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/admission/contracts.ts +13 -0
  18. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/admission/index.ts +4 -1
  19. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/admission/postgres-adapter.ts +13 -0
  20. package/dist/bundling-sources/shared_libs/play-runtime/play-webhook-admission-probe.ts +32 -0
  21. package/dist/bundling-sources/shared_libs/play-runtime/play-webhook-identity.ts +28 -0
  22. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backend.ts +7 -0
  23. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-cron-fire-task.ts +100 -0
  24. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-runtime-worker.ts +313 -0
  25. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-shared.ts +111 -3
  26. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd.ts +16 -0
  27. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres-pool.ts +67 -8
  28. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres.ts +1734 -147
  29. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/run-ledger-outbox-recovery.ts +74 -13
  30. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-queue-health.ts +245 -81
  31. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/submit-admission.ts +79 -15
  32. package/dist/bundling-sources/shared_libs/play-runtime/webhook-receipt-retry.ts +21 -21
  33. package/dist/bundling-sources/shared_libs/plays/bundling/index.ts +4 -1
  34. package/dist/bundling-sources/shared_libs/product-notifications/catalog.ts +64 -0
  35. package/dist/bundling-sources/shared_libs/product-notifications/default-policy.ts +1 -1
  36. package/dist/bundling-sources/shared_libs/product-notifications/events.ts +20 -1
  37. package/dist/bundling-sources/shared_libs/security/receipt-admission-token.ts +224 -0
  38. package/dist/cli/index.js +574 -114
  39. package/dist/cli/index.mjs +592 -133
  40. package/dist/index.d.mts +54 -1
  41. package/dist/index.d.ts +54 -1
  42. package/dist/index.js +8 -3
  43. package/dist/index.mjs +8 -3
  44. package/dist/install-integrity.json +8 -0
  45. package/dist/plays/bundle-play-file.mjs +1 -1
  46. package/dist/release.d.mts +1 -1
  47. package/dist/release.d.ts +1 -1
  48. package/dist/release.js +1 -1
  49. package/dist/release.mjs +1 -1
  50. package/package.json +1 -1
@@ -28,6 +28,10 @@ import {
28
28
  RuntimeSchedulerSubmissionAdmissionError,
29
29
  RuntimeSchedulerSaturatedError,
30
30
  } from './scheduler-capacity';
31
+ import {
32
+ PLAY_ADMISSION_LARGE_BATCH_SIZE,
33
+ PLAY_ADMISSION_MAX_ACQUIRE_QUEUE_WAIT_MS,
34
+ } from '../admission-transport-policy';
31
35
  import { RUNTIME_RELIABILITY_POLICY } from '../runtime-reliability-policy';
32
36
  export {
33
37
  isRuntimeSchedulerCapacityError,
@@ -163,6 +167,23 @@ export type RuntimeSchedulerPoolOptions = {
163
167
  url: string;
164
168
  applicationName?: string;
165
169
  maxClients?: number;
170
+ /**
171
+ * Serverless launchers must not pin a scarce PgBouncer client between
172
+ * requests. Long-lived workers retain the default; Vercel callers opt into
173
+ * a short idle lifetime through the shared Absurd pool resolver.
174
+ */
175
+ idleTimeoutMs?: number;
176
+ /**
177
+ * Optional request-local acquire queue capacity. The dense webhook batch
178
+ * owns a finite 256-source wave, so it may reserve enough scheduler waiters
179
+ * for that wave without widening ordinary worker/request callers.
180
+ */
181
+ maxAcquireQueueDepth?: number;
182
+ /**
183
+ * Optional request-local waiter lifetime. A bounded batch may spend longer
184
+ * than the ordinary single-launch acquire timeout draining its finite wave.
185
+ */
186
+ maxAcquireQueueWaitMs?: number;
166
187
  };
167
188
 
168
189
  export type RuntimeSchedulerQueryClient = {
@@ -328,6 +349,7 @@ export class RuntimeSchedulerPoolAdmission {
328
349
  type PoolEntry = {
329
350
  pool: Pool;
330
351
  maxClients: number;
352
+ maxAcquireQueueDepth: number;
331
353
  admission: RuntimeSchedulerPoolAdmission;
332
354
  breaker: BreakerState;
333
355
  stats: {
@@ -489,6 +511,14 @@ function getPoolEntry(options: RuntimeSchedulerPoolOptions): PoolEntry {
489
511
  assertRuntimeSchedulerHotPathUrl(options.url);
490
512
  const maxClients =
491
513
  options.maxClients ?? RUNTIME_SCHEDULER_POOL_DEFAULTS.maxClients;
514
+ const idleTimeoutMs =
515
+ options.idleTimeoutMs ?? RUNTIME_SCHEDULER_POOL_DEFAULTS.idleTimeoutMs;
516
+ const maxAcquireQueueDepth =
517
+ options.maxAcquireQueueDepth ??
518
+ RUNTIME_SCHEDULER_POOL_DEFAULTS.maxAcquireQueueDepth;
519
+ const maxAcquireQueueWaitMs =
520
+ options.maxAcquireQueueWaitMs ??
521
+ RUNTIME_SCHEDULER_POOL_DEFAULTS.acquireTimeoutMs;
492
522
  if (maxClients > RUNTIME_SCHEDULER_POOL_DEFAULTS.maxClientsHardCap) {
493
523
  throw new Error(
494
524
  `Runtime scheduler pool maxClients=${maxClients} exceeds the hard cap of ` +
@@ -496,16 +526,46 @@ function getPoolEntry(options: RuntimeSchedulerPoolOptions): PoolEntry {
496
526
  'instead of widening a single process pool.',
497
527
  );
498
528
  }
529
+ if (!Number.isSafeInteger(idleTimeoutMs) || idleTimeoutMs < 0) {
530
+ throw new Error(
531
+ `Runtime scheduler pool idleTimeoutMs=${idleTimeoutMs} must be a non-negative integer.`,
532
+ );
533
+ }
534
+ if (
535
+ !Number.isSafeInteger(maxAcquireQueueDepth) ||
536
+ maxAcquireQueueDepth < 1 ||
537
+ maxAcquireQueueDepth > PLAY_ADMISSION_LARGE_BATCH_SIZE
538
+ ) {
539
+ throw new Error(
540
+ `Runtime scheduler pool maxAcquireQueueDepth=${maxAcquireQueueDepth} ` +
541
+ `must be an integer between 1 and ${PLAY_ADMISSION_LARGE_BATCH_SIZE}.`,
542
+ );
543
+ }
544
+ if (
545
+ !Number.isSafeInteger(maxAcquireQueueWaitMs) ||
546
+ maxAcquireQueueWaitMs < RUNTIME_SCHEDULER_POOL_DEFAULTS.acquireTimeoutMs ||
547
+ maxAcquireQueueWaitMs > PLAY_ADMISSION_MAX_ACQUIRE_QUEUE_WAIT_MS
548
+ ) {
549
+ throw new Error(
550
+ `Runtime scheduler pool maxAcquireQueueWaitMs=${maxAcquireQueueWaitMs} ` +
551
+ `must be between ${RUNTIME_SCHEDULER_POOL_DEFAULTS.acquireTimeoutMs} and ` +
552
+ `${PLAY_ADMISSION_MAX_ACQUIRE_QUEUE_WAIT_MS}.`,
553
+ );
554
+ }
499
555
  const registry = getPoolRegistry();
500
556
  const connectionString = normalizePostgresConnectionStringForPg(options.url);
501
- const key = `${connectionString}::${maxClients}`;
557
+ // The connection lifetime is part of a Pool's semantics. Do not let a
558
+ // serverless short-idle caller accidentally reuse a long-lived worker pool
559
+ // merely because both target the same runtime database.
560
+ const key = `${connectionString}::${maxClients}::${idleTimeoutMs}::${maxAcquireQueueDepth}::${maxAcquireQueueWaitMs}`;
502
561
  const existing = registry.get(key);
503
562
  if (existing) {
504
563
  // Next dev can retain the process-global pool across a module hot reload.
505
564
  // Upgrade that live entry in place when this admission layer first lands.
506
565
  existing.admission ??= new RuntimeSchedulerPoolAdmission(
507
566
  maxClients,
508
- RUNTIME_SCHEDULER_POOL_DEFAULTS.maxAcquireQueueDepth,
567
+ maxAcquireQueueDepth,
568
+ maxAcquireQueueWaitMs,
509
569
  );
510
570
  return existing;
511
571
  }
@@ -515,7 +575,7 @@ function getPoolEntry(options: RuntimeSchedulerPoolOptions): PoolEntry {
515
575
  application_name:
516
576
  options.applicationName ?? 'deepline-runtime-scheduler-pool',
517
577
  max: maxClients,
518
- idleTimeoutMillis: RUNTIME_SCHEDULER_POOL_DEFAULTS.idleTimeoutMs,
578
+ idleTimeoutMillis: idleTimeoutMs,
519
579
  connectionTimeoutMillis: RUNTIME_SCHEDULER_POOL_DEFAULTS.acquireTimeoutMs,
520
580
  query_timeout: RUNTIME_SCHEDULER_POOL_DEFAULTS.queryTimeoutMs,
521
581
  keepAlive: true,
@@ -523,9 +583,11 @@ function getPoolEntry(options: RuntimeSchedulerPoolOptions): PoolEntry {
523
583
  const entry: PoolEntry = {
524
584
  pool,
525
585
  maxClients,
586
+ maxAcquireQueueDepth,
526
587
  admission: new RuntimeSchedulerPoolAdmission(
527
588
  maxClients,
528
- RUNTIME_SCHEDULER_POOL_DEFAULTS.maxAcquireQueueDepth,
589
+ maxAcquireQueueDepth,
590
+ maxAcquireQueueWaitMs,
529
591
  ),
530
592
  breaker: {
531
593
  consecutiveFailures: 0,
@@ -653,10 +715,7 @@ export async function withRuntimeSchedulerClient<T>(
653
715
  ) {
654
716
  throwIfSchedulerAborted(signal);
655
717
  breakerGate(entry);
656
- if (
657
- entry.pool.waitingCount >=
658
- RUNTIME_SCHEDULER_POOL_DEFAULTS.maxAcquireQueueDepth
659
- ) {
718
+ if (entry.pool.waitingCount >= entry.maxAcquireQueueDepth) {
660
719
  entry.stats.saturationRejections += 1;
661
720
  throw new RuntimeSchedulerSaturatedError(entry.pool.waitingCount);
662
721
  }