@nylorun/runtime 0.21.1-beta → 0.23.0-beta

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 (84) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/README.md +17 -3
  3. package/dist/adapters/execution/restate.d.ts +15 -3
  4. package/dist/adapters/execution/restate.js +77 -83
  5. package/dist/adapters/sandbox/local.js +1 -1
  6. package/dist/adapters/sandbox/virtual.js +1 -1
  7. package/dist/adapters/streams/s2.js +1 -13
  8. package/dist/api/components.d.ts +42 -2
  9. package/dist/core/flow-host.d.ts +1 -19
  10. package/dist/core/flow-host.js +8 -37
  11. package/dist/execution/types.d.ts +10 -8
  12. package/dist/execution/types.js +5 -7
  13. package/dist/gates/egress-credentials.d.ts +48 -0
  14. package/dist/gates/egress-credentials.js +147 -0
  15. package/dist/gates/egress.d.ts +3 -0
  16. package/dist/gates/egress.js +14 -1
  17. package/dist/gates/tenant-vaults.d.ts +4 -0
  18. package/dist/gates/tenant-vaults.js +2 -0
  19. package/dist/harness/calls.d.ts +2 -0
  20. package/dist/harness/calls.js +1 -0
  21. package/dist/harness/executors.js +1 -0
  22. package/dist/harness/main.js +4 -1
  23. package/dist/harness/pod.d.ts +2 -0
  24. package/dist/harness/pod.js +36 -1
  25. package/dist/harness-api/start.d.ts +2 -0
  26. package/dist/harness-api/start.js +4 -2
  27. package/dist/harness-api/ws-server.js +2 -2
  28. package/dist/host/execution.d.ts +8 -6
  29. package/dist/host/gates.js +11 -0
  30. package/dist/host/main.js +10 -16
  31. package/dist/host/stack-config.d.ts +6 -0
  32. package/dist/host/stack-config.js +6 -0
  33. package/dist/infra/execution.d.ts +18 -1
  34. package/dist/infra/execution.js +28 -4
  35. package/dist/infra/index.d.ts +1 -1
  36. package/dist/keys/egress-ca.d.ts +15 -0
  37. package/dist/keys/egress-ca.js +66 -0
  38. package/dist/keys/keys.d.ts +8 -1
  39. package/dist/keys/keys.js +6 -0
  40. package/dist/keys/x509.d.ts +29 -0
  41. package/dist/keys/x509.js +160 -0
  42. package/dist/management-openapi.json +195 -9
  43. package/dist/openapi.json +2 -1
  44. package/dist/retry.d.ts +21 -0
  45. package/dist/retry.js +34 -0
  46. package/dist/sandbox/join.d.ts +2 -0
  47. package/dist/sandbox/join.js +14 -10
  48. package/dist/sandbox/manager.d.ts +2 -0
  49. package/dist/sandbox/manager.js +1 -1
  50. package/dist/sandbox/pods/reconcile.js +3 -3
  51. package/dist/sandbox/tools.d.ts +3 -1
  52. package/dist/sandbox/tools.js +4 -2
  53. package/dist/sandbox/types.d.ts +5 -0
  54. package/dist/store/postgres/control.js +8 -1
  55. package/dist/store/postgres/drizzle/0018_wake_outbox_retries.sql +3 -0
  56. package/dist/store/postgres/drizzle/0019_sandbox_signal_outbox.sql +18 -0
  57. package/dist/store/postgres/drizzle/meta/_journal.json +14 -0
  58. package/dist/store/postgres/schema.d.ts +265 -4
  59. package/dist/store/postgres/schema.js +35 -4
  60. package/dist/store/postgres/store.js +165 -52
  61. package/dist/store/types.d.ts +96 -39
  62. package/dist/streams/relay/core.js +1 -13
  63. package/dist/tenant/advance.js +6 -7
  64. package/dist/tenant/commands.js +1 -2
  65. package/dist/tenant/context.d.ts +19 -11
  66. package/dist/tenant/control.d.ts +8 -1
  67. package/dist/tenant/control.js +2 -0
  68. package/dist/tenant/runtime.js +23 -3
  69. package/dist/tenant/sandboxes.d.ts +2 -1
  70. package/dist/tenant/sandboxes.js +23 -19
  71. package/dist/tenant/scheduler.d.ts +7 -0
  72. package/dist/tenant/scheduler.js +38 -7
  73. package/dist/tenant/session-streams.d.ts +0 -1
  74. package/dist/tenant/session-streams.js +1 -13
  75. package/dist/tenant/sessions.js +26 -0
  76. package/dist/tenant/streams.js +14 -29
  77. package/dist/tenant/sweep.d.ts +39 -12
  78. package/dist/tenant/sweep.js +157 -58
  79. package/dist/tenant/transcript.d.ts +8 -8
  80. package/dist/vault/service.d.ts +34 -0
  81. package/dist/vault/service.js +148 -15
  82. package/dist/version.d.ts +1 -1
  83. package/dist/version.js +1 -1
  84. package/package.json +4 -3
@@ -1048,14 +1048,14 @@ export declare const vaultCredentials: import("drizzle-orm/pg-core").PgTableWith
1048
1048
  tableName: "vault_credentials";
1049
1049
  dataType: "string";
1050
1050
  columnType: "PgText";
1051
- data: "bearer" | "headers" | "model";
1051
+ data: "bearer" | "environment_secret" | "environment_variable" | "headers" | "model";
1052
1052
  driverParam: string;
1053
1053
  notNull: true;
1054
1054
  hasDefault: false;
1055
1055
  isPrimaryKey: false;
1056
1056
  isAutoincrement: false;
1057
1057
  hasRuntimeDefault: false;
1058
- enumValues: ["bearer", "headers", "model"];
1058
+ enumValues: ["bearer", "headers", "environment_secret", "environment_variable", "model"];
1059
1059
  baseColumn: never;
1060
1060
  identity: undefined;
1061
1061
  generated: undefined;
@@ -3225,7 +3225,8 @@ export declare const definitionFileUses: import("drizzle-orm/pg-core").PgTableWi
3225
3225
  * written in the transaction that commits what they announce and notified on
3226
3226
  * `nylorun_control` at commit (`control.ts`). A row outlives its notification so a process
3227
3227
  * whose listener was down catches up; the Tenant sweep deletes old ones. `created_at` is the
3228
- * insert's own clock (`clock_timestamp()`), not its transaction's start.
3228
+ * insert's own clock (`clock_timestamp()`), not its transaction's start. `sandbox_id` and
3229
+ * `epoch` are a `host.revoked` signal's.
3229
3230
  */
3230
3231
  export declare const controlSignals: import("drizzle-orm/pg-core").PgTableWithColumns<{
3231
3232
  name: "control_signals";
@@ -3337,6 +3338,42 @@ export declare const controlSignals: import("drizzle-orm/pg-core").PgTableWithCo
3337
3338
  identity: undefined;
3338
3339
  generated: undefined;
3339
3340
  }, {}, {}>;
3341
+ sandboxId: import("drizzle-orm/pg-core").PgColumn<{
3342
+ name: "sandboxId";
3343
+ tableName: "control_signals";
3344
+ dataType: "custom";
3345
+ columnType: "PgCustomColumn";
3346
+ data: string;
3347
+ driverParam: string;
3348
+ notNull: false;
3349
+ hasDefault: false;
3350
+ isPrimaryKey: false;
3351
+ isAutoincrement: false;
3352
+ hasRuntimeDefault: false;
3353
+ enumValues: undefined;
3354
+ baseColumn: never;
3355
+ identity: undefined;
3356
+ generated: undefined;
3357
+ }, {}, {
3358
+ pgColumnBuilderBrand: 'PgCustomColumnBuilderBrand';
3359
+ }>;
3360
+ epoch: import("drizzle-orm/pg-core").PgColumn<{
3361
+ name: "epoch";
3362
+ tableName: "control_signals";
3363
+ dataType: "number";
3364
+ columnType: "PgInteger";
3365
+ data: number;
3366
+ driverParam: string | number;
3367
+ notNull: false;
3368
+ hasDefault: false;
3369
+ isPrimaryKey: false;
3370
+ isAutoincrement: false;
3371
+ hasRuntimeDefault: false;
3372
+ enumValues: undefined;
3373
+ baseColumn: never;
3374
+ identity: undefined;
3375
+ generated: undefined;
3376
+ }, {}, {}>;
3340
3377
  };
3341
3378
  dialect: 'pg';
3342
3379
  }>;
@@ -3345,7 +3382,9 @@ export declare const controlSignals: import("drizzle-orm/pg-core").PgTableWithCo
3345
3382
  * (`Tx.wake`), written in that transaction, so a commit never loses its wake. The row is
3346
3383
  * deleted once Durable Session Execution has accepted the wake; until then the Tenant sweep
3347
3384
  * delivers it again, with the same idempotency key (`dedupe_key`, or `wake:<id>` without
3348
- * one). `created_at` is the insert's own clock (`clock_timestamp()`).
3385
+ * one). `created_at` is the insert's own clock (`clock_timestamp()`). `attempts` counts the
3386
+ * sweep's failed deliveries, `retry_at` is when it tries the row again, and a row
3387
+ * `parked_at` is never tried again: it stays for an operator (`Tx.failOutbox`).
3349
3388
  */
3350
3389
  export declare const wakes: import("drizzle-orm/pg-core").PgTableWithColumns<{
3351
3390
  name: "wakes";
@@ -3440,6 +3479,228 @@ export declare const wakes: import("drizzle-orm/pg-core").PgTableWithColumns<{
3440
3479
  identity: undefined;
3441
3480
  generated: undefined;
3442
3481
  }, {}, {}>;
3482
+ attempts: import("drizzle-orm/pg-core").PgColumn<{
3483
+ name: "attempts";
3484
+ tableName: "wakes";
3485
+ dataType: "number";
3486
+ columnType: "PgInteger";
3487
+ data: number;
3488
+ driverParam: string | number;
3489
+ notNull: true;
3490
+ hasDefault: true;
3491
+ isPrimaryKey: false;
3492
+ isAutoincrement: false;
3493
+ hasRuntimeDefault: false;
3494
+ enumValues: undefined;
3495
+ baseColumn: never;
3496
+ identity: undefined;
3497
+ generated: undefined;
3498
+ }, {}, {}>;
3499
+ retryAt: import("drizzle-orm/pg-core").PgColumn<{
3500
+ name: "retryAt";
3501
+ tableName: "wakes";
3502
+ dataType: "date";
3503
+ columnType: "PgTimestamp";
3504
+ data: Date;
3505
+ driverParam: string;
3506
+ notNull: false;
3507
+ hasDefault: false;
3508
+ isPrimaryKey: false;
3509
+ isAutoincrement: false;
3510
+ hasRuntimeDefault: false;
3511
+ enumValues: undefined;
3512
+ baseColumn: never;
3513
+ identity: undefined;
3514
+ generated: undefined;
3515
+ }, {}, {}>;
3516
+ parkedAt: import("drizzle-orm/pg-core").PgColumn<{
3517
+ name: "parkedAt";
3518
+ tableName: "wakes";
3519
+ dataType: "date";
3520
+ columnType: "PgTimestamp";
3521
+ data: Date;
3522
+ driverParam: string;
3523
+ notNull: false;
3524
+ hasDefault: false;
3525
+ isPrimaryKey: false;
3526
+ isAutoincrement: false;
3527
+ hasRuntimeDefault: false;
3528
+ enumValues: undefined;
3529
+ baseColumn: never;
3530
+ identity: undefined;
3531
+ generated: undefined;
3532
+ }, {}, {}>;
3533
+ };
3534
+ dialect: 'pg';
3535
+ }>;
3536
+ /**
3537
+ * The sandbox signal outbox (F7.2): one row per pod sandbox reconcile or timer a committed
3538
+ * transaction asked for (`Tx.signalSandbox`), kept and delivered as the wake outbox's rows are
3539
+ * (`attempts`, `retry_at`, `parked_at`). A reconcile is sent with the idempotency key
3540
+ * `signal:<id>`; a timer (`kind` `arm`) is its `timer` at `at` (ms since the epoch). Not in
3541
+ * `wakes`, so a Runtime that delivers only wakes never reads one.
3542
+ */
3543
+ export declare const sandboxSignals: import("drizzle-orm/pg-core").PgTableWithColumns<{
3544
+ name: "sandbox_signals";
3545
+ schema: "nylorun";
3546
+ columns: {
3547
+ id: import("drizzle-orm/pg-core").PgColumn<{
3548
+ name: "id";
3549
+ tableName: "sandbox_signals";
3550
+ dataType: "custom";
3551
+ columnType: "PgCustomColumn";
3552
+ data: string;
3553
+ driverParam: string;
3554
+ notNull: true;
3555
+ hasDefault: false;
3556
+ isPrimaryKey: true;
3557
+ isAutoincrement: false;
3558
+ hasRuntimeDefault: false;
3559
+ enumValues: undefined;
3560
+ baseColumn: never;
3561
+ identity: undefined;
3562
+ generated: undefined;
3563
+ }, {}, {
3564
+ pgColumnBuilderBrand: 'PgCustomColumnBuilderBrand';
3565
+ }>;
3566
+ sandboxId: import("drizzle-orm/pg-core").PgColumn<{
3567
+ name: "sandboxId";
3568
+ tableName: "sandbox_signals";
3569
+ dataType: "custom";
3570
+ columnType: "PgCustomColumn";
3571
+ data: string;
3572
+ driverParam: string;
3573
+ notNull: true;
3574
+ hasDefault: false;
3575
+ isPrimaryKey: false;
3576
+ isAutoincrement: false;
3577
+ hasRuntimeDefault: false;
3578
+ enumValues: undefined;
3579
+ baseColumn: never;
3580
+ identity: undefined;
3581
+ generated: undefined;
3582
+ }, {}, {
3583
+ pgColumnBuilderBrand: 'PgCustomColumnBuilderBrand';
3584
+ }>;
3585
+ kind: import("drizzle-orm/pg-core").PgColumn<{
3586
+ name: "kind";
3587
+ tableName: "sandbox_signals";
3588
+ dataType: "string";
3589
+ columnType: "PgText";
3590
+ data: string;
3591
+ driverParam: string;
3592
+ notNull: true;
3593
+ hasDefault: false;
3594
+ isPrimaryKey: false;
3595
+ isAutoincrement: false;
3596
+ hasRuntimeDefault: false;
3597
+ enumValues: [string, ...string[]];
3598
+ baseColumn: never;
3599
+ identity: undefined;
3600
+ generated: undefined;
3601
+ }, {}, {}>;
3602
+ timer: import("drizzle-orm/pg-core").PgColumn<{
3603
+ name: "timer";
3604
+ tableName: "sandbox_signals";
3605
+ dataType: "string";
3606
+ columnType: "PgText";
3607
+ data: string;
3608
+ driverParam: string;
3609
+ notNull: false;
3610
+ hasDefault: false;
3611
+ isPrimaryKey: false;
3612
+ isAutoincrement: false;
3613
+ hasRuntimeDefault: false;
3614
+ enumValues: [string, ...string[]];
3615
+ baseColumn: never;
3616
+ identity: undefined;
3617
+ generated: undefined;
3618
+ }, {}, {}>;
3619
+ at: import("drizzle-orm/pg-core").PgColumn<{
3620
+ name: "at";
3621
+ tableName: "sandbox_signals";
3622
+ dataType: "number";
3623
+ columnType: "PgBigInt53";
3624
+ data: number;
3625
+ driverParam: string | number;
3626
+ notNull: false;
3627
+ hasDefault: false;
3628
+ isPrimaryKey: false;
3629
+ isAutoincrement: false;
3630
+ hasRuntimeDefault: false;
3631
+ enumValues: undefined;
3632
+ baseColumn: never;
3633
+ identity: undefined;
3634
+ generated: undefined;
3635
+ }, {}, {}>;
3636
+ createdAt: import("drizzle-orm/pg-core").PgColumn<{
3637
+ name: "createdAt";
3638
+ tableName: "sandbox_signals";
3639
+ dataType: "date";
3640
+ columnType: "PgTimestamp";
3641
+ data: Date;
3642
+ driverParam: string;
3643
+ notNull: true;
3644
+ hasDefault: true;
3645
+ isPrimaryKey: false;
3646
+ isAutoincrement: false;
3647
+ hasRuntimeDefault: false;
3648
+ enumValues: undefined;
3649
+ baseColumn: never;
3650
+ identity: undefined;
3651
+ generated: undefined;
3652
+ }, {}, {}>;
3653
+ attempts: import("drizzle-orm/pg-core").PgColumn<{
3654
+ name: "attempts";
3655
+ tableName: "sandbox_signals";
3656
+ dataType: "number";
3657
+ columnType: "PgInteger";
3658
+ data: number;
3659
+ driverParam: string | number;
3660
+ notNull: true;
3661
+ hasDefault: true;
3662
+ isPrimaryKey: false;
3663
+ isAutoincrement: false;
3664
+ hasRuntimeDefault: false;
3665
+ enumValues: undefined;
3666
+ baseColumn: never;
3667
+ identity: undefined;
3668
+ generated: undefined;
3669
+ }, {}, {}>;
3670
+ retryAt: import("drizzle-orm/pg-core").PgColumn<{
3671
+ name: "retryAt";
3672
+ tableName: "sandbox_signals";
3673
+ dataType: "date";
3674
+ columnType: "PgTimestamp";
3675
+ data: Date;
3676
+ driverParam: string;
3677
+ notNull: false;
3678
+ hasDefault: false;
3679
+ isPrimaryKey: false;
3680
+ isAutoincrement: false;
3681
+ hasRuntimeDefault: false;
3682
+ enumValues: undefined;
3683
+ baseColumn: never;
3684
+ identity: undefined;
3685
+ generated: undefined;
3686
+ }, {}, {}>;
3687
+ parkedAt: import("drizzle-orm/pg-core").PgColumn<{
3688
+ name: "parkedAt";
3689
+ tableName: "sandbox_signals";
3690
+ dataType: "date";
3691
+ columnType: "PgTimestamp";
3692
+ data: Date;
3693
+ driverParam: string;
3694
+ notNull: false;
3695
+ hasDefault: false;
3696
+ isPrimaryKey: false;
3697
+ isAutoincrement: false;
3698
+ hasRuntimeDefault: false;
3699
+ enumValues: undefined;
3700
+ baseColumn: never;
3701
+ identity: undefined;
3702
+ generated: undefined;
3703
+ }, {}, {}>;
3443
3704
  };
3444
3705
  dialect: 'pg';
3445
3706
  }>;
@@ -129,7 +129,7 @@ export const vaultCredentials = nylorun.table("vault_credentials", {
129
129
  id: textC().primaryKey(),
130
130
  vaultId: text().notNull(),
131
131
  name: text().notNull(),
132
- type: text({ enum: ["bearer", "headers", "model"] }).notNull(),
132
+ type: text({ enum: ["bearer", "headers", "environment_secret", "environment_variable", "model"] }).notNull(),
133
133
  /** JSON text of the non-secret binding: url (and via, identity, header names), or provider and model. */
134
134
  bindingJson: text().notNull(),
135
135
  expiresAt: text(),
@@ -406,7 +406,8 @@ export const definitionFileUses = nylorun.table("definition_file_uses", {
406
406
  * written in the transaction that commits what they announce and notified on
407
407
  * `nylorun_control` at commit (`control.ts`). A row outlives its notification so a process
408
408
  * whose listener was down catches up; the Tenant sweep deletes old ones. `created_at` is the
409
- * insert's own clock (`clock_timestamp()`), not its transaction's start.
409
+ * insert's own clock (`clock_timestamp()`), not its transaction's start. `sandbox_id` and
410
+ * `epoch` are a `host.revoked` signal's.
410
411
  */
411
412
  export const controlSignals = nylorun.table("control_signals", {
412
413
  id: bigint({ mode: "number" }).primaryKey().generatedAlwaysAsIdentity(),
@@ -417,16 +418,20 @@ export const controlSignals = nylorun.table("control_signals", {
417
418
  createdAt: timestamp({ withTimezone: true, mode: "string" })
418
419
  .notNull()
419
420
  .default(sql `clock_timestamp()`),
421
+ sandboxId: textC(),
422
+ epoch: integer(),
420
423
  }, (t) => [
421
424
  index("control_signals_created_at").on(t.createdAt),
422
- check("control_signals_kind_check", sql `${t.kind} IN ('session.cancel', 'sessions.reset')`),
425
+ check("control_signals_kind_check", sql `${t.kind} IN ('session.cancel', 'sessions.reset', 'host.revoked')`),
423
426
  ]);
424
427
  /**
425
428
  * The wake outbox (architecture §12.3): one row per wake a committed transaction asked for
426
429
  * (`Tx.wake`), written in that transaction, so a commit never loses its wake. The row is
427
430
  * deleted once Durable Session Execution has accepted the wake; until then the Tenant sweep
428
431
  * delivers it again, with the same idempotency key (`dedupe_key`, or `wake:<id>` without
429
- * one). `created_at` is the insert's own clock (`clock_timestamp()`).
432
+ * one). `created_at` is the insert's own clock (`clock_timestamp()`). `attempts` counts the
433
+ * sweep's failed deliveries, `retry_at` is when it tries the row again, and a row
434
+ * `parked_at` is never tried again: it stays for an operator (`Tx.failOutbox`).
430
435
  */
431
436
  export const wakes = nylorun.table("wakes", {
432
437
  id: textC().primaryKey(),
@@ -436,7 +441,33 @@ export const wakes = nylorun.table("wakes", {
436
441
  createdAt: timestamp({ withTimezone: true, mode: "date" })
437
442
  .notNull()
438
443
  .default(sql `clock_timestamp()`),
444
+ attempts: integer().notNull().default(0),
445
+ retryAt: timestamp({ withTimezone: true, mode: "date" }),
446
+ parkedAt: timestamp({ withTimezone: true, mode: "date" }),
439
447
  }, (t) => [index("wakes_created_at").on(t.createdAt)]);
448
+ /**
449
+ * The sandbox signal outbox (F7.2): one row per pod sandbox reconcile or timer a committed
450
+ * transaction asked for (`Tx.signalSandbox`), kept and delivered as the wake outbox's rows are
451
+ * (`attempts`, `retry_at`, `parked_at`). A reconcile is sent with the idempotency key
452
+ * `signal:<id>`; a timer (`kind` `arm`) is its `timer` at `at` (ms since the epoch). Not in
453
+ * `wakes`, so a Runtime that delivers only wakes never reads one.
454
+ */
455
+ export const sandboxSignals = nylorun.table("sandbox_signals", {
456
+ id: textC().primaryKey(),
457
+ sandboxId: textC().notNull(),
458
+ kind: text().notNull(),
459
+ timer: text(),
460
+ at: bigint({ mode: "number" }),
461
+ createdAt: timestamp({ withTimezone: true, mode: "date" })
462
+ .notNull()
463
+ .default(sql `clock_timestamp()`),
464
+ attempts: integer().notNull().default(0),
465
+ retryAt: timestamp({ withTimezone: true, mode: "date" }),
466
+ parkedAt: timestamp({ withTimezone: true, mode: "date" }),
467
+ }, (t) => [
468
+ index("sandbox_signals_created_at").on(t.createdAt),
469
+ check("sandbox_signals_kind_check", sql `${t.kind} IN ('reconcile', 'arm')`),
470
+ ]);
440
471
  // ---------------------------------------------------------------------------
441
472
  // nylorun_streams: the record
442
473
  /**