@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.
- package/CHANGELOG.md +32 -0
- package/README.md +17 -3
- package/dist/adapters/execution/restate.d.ts +15 -3
- package/dist/adapters/execution/restate.js +77 -83
- package/dist/adapters/sandbox/local.js +1 -1
- package/dist/adapters/sandbox/virtual.js +1 -1
- package/dist/adapters/streams/s2.js +1 -13
- package/dist/api/components.d.ts +42 -2
- package/dist/core/flow-host.d.ts +1 -19
- package/dist/core/flow-host.js +8 -37
- package/dist/execution/types.d.ts +10 -8
- package/dist/execution/types.js +5 -7
- package/dist/gates/egress-credentials.d.ts +48 -0
- package/dist/gates/egress-credentials.js +147 -0
- package/dist/gates/egress.d.ts +3 -0
- package/dist/gates/egress.js +14 -1
- package/dist/gates/tenant-vaults.d.ts +4 -0
- package/dist/gates/tenant-vaults.js +2 -0
- package/dist/harness/calls.d.ts +2 -0
- package/dist/harness/calls.js +1 -0
- package/dist/harness/executors.js +1 -0
- package/dist/harness/main.js +4 -1
- package/dist/harness/pod.d.ts +2 -0
- package/dist/harness/pod.js +36 -1
- package/dist/harness-api/start.d.ts +2 -0
- package/dist/harness-api/start.js +4 -2
- package/dist/harness-api/ws-server.js +2 -2
- package/dist/host/execution.d.ts +8 -6
- package/dist/host/gates.js +11 -0
- package/dist/host/main.js +10 -16
- package/dist/host/stack-config.d.ts +6 -0
- package/dist/host/stack-config.js +6 -0
- package/dist/infra/execution.d.ts +18 -1
- package/dist/infra/execution.js +28 -4
- package/dist/infra/index.d.ts +1 -1
- package/dist/keys/egress-ca.d.ts +15 -0
- package/dist/keys/egress-ca.js +66 -0
- package/dist/keys/keys.d.ts +8 -1
- package/dist/keys/keys.js +6 -0
- package/dist/keys/x509.d.ts +29 -0
- package/dist/keys/x509.js +160 -0
- package/dist/management-openapi.json +195 -9
- package/dist/openapi.json +2 -1
- package/dist/retry.d.ts +21 -0
- package/dist/retry.js +34 -0
- package/dist/sandbox/join.d.ts +2 -0
- package/dist/sandbox/join.js +14 -10
- package/dist/sandbox/manager.d.ts +2 -0
- package/dist/sandbox/manager.js +1 -1
- package/dist/sandbox/pods/reconcile.js +3 -3
- package/dist/sandbox/tools.d.ts +3 -1
- package/dist/sandbox/tools.js +4 -2
- package/dist/sandbox/types.d.ts +5 -0
- package/dist/store/postgres/control.js +8 -1
- package/dist/store/postgres/drizzle/0018_wake_outbox_retries.sql +3 -0
- package/dist/store/postgres/drizzle/0019_sandbox_signal_outbox.sql +18 -0
- package/dist/store/postgres/drizzle/meta/_journal.json +14 -0
- package/dist/store/postgres/schema.d.ts +265 -4
- package/dist/store/postgres/schema.js +35 -4
- package/dist/store/postgres/store.js +165 -52
- package/dist/store/types.d.ts +96 -39
- package/dist/streams/relay/core.js +1 -13
- package/dist/tenant/advance.js +6 -7
- package/dist/tenant/commands.js +1 -2
- package/dist/tenant/context.d.ts +19 -11
- package/dist/tenant/control.d.ts +8 -1
- package/dist/tenant/control.js +2 -0
- package/dist/tenant/runtime.js +23 -3
- package/dist/tenant/sandboxes.d.ts +2 -1
- package/dist/tenant/sandboxes.js +23 -19
- package/dist/tenant/scheduler.d.ts +7 -0
- package/dist/tenant/scheduler.js +38 -7
- package/dist/tenant/session-streams.d.ts +0 -1
- package/dist/tenant/session-streams.js +1 -13
- package/dist/tenant/sessions.js +26 -0
- package/dist/tenant/streams.js +14 -29
- package/dist/tenant/sweep.d.ts +39 -12
- package/dist/tenant/sweep.js +157 -58
- package/dist/tenant/transcript.d.ts +8 -8
- package/dist/vault/service.d.ts +34 -0
- package/dist/vault/service.js +148 -15
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- 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
|
/**
|