@rebasepro/types 0.12.0 → 0.12.1-canary.g181d0fe
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/controllers/client.d.ts +34 -0
- package/dist/index.es.js +1 -1
- package/dist/index.es.js.map +1 -1
- package/dist/types/backend.d.ts +19 -0
- package/dist/types/cron.d.ts +31 -0
- package/dist/types/database_adapter.d.ts +26 -0
- package/package.json +4 -4
- package/src/controllers/client.ts +37 -0
- package/src/types/backend.ts +22 -0
- package/src/types/cron.ts +32 -0
- package/src/types/database_adapter.ts +32 -0
package/dist/types/backend.d.ts
CHANGED
|
@@ -611,6 +611,25 @@ export interface BackendBootstrapper {
|
|
|
611
611
|
ensureCollectionSchema?(collections: unknown[], driverResult: InitializedDriver, log?: (message: string) => void): Promise<{
|
|
612
612
|
applied: number;
|
|
613
613
|
}>;
|
|
614
|
+
/**
|
|
615
|
+
* Apply the collections' row-level-security policies, additively and
|
|
616
|
+
* idempotently — the companion to {@link ensureCollectionSchema}.
|
|
617
|
+
*
|
|
618
|
+
* That method creates the tables; a table with RLS disabled and no policies
|
|
619
|
+
* is not servable, because authenticated requests run as a restricted role:
|
|
620
|
+
* a read with no `SELECT` policy returns nothing (a public collection
|
|
621
|
+
* answers 401) and a write with no `INSERT`/`UPDATE` policy is denied. The
|
|
622
|
+
* `db push` CLI applies these from the same collections, but it cannot reach
|
|
623
|
+
* a managed tenant's in-cluster database — the runtime, already connected,
|
|
624
|
+
* is the only thing that can.
|
|
625
|
+
*
|
|
626
|
+
* MUST be idempotent (re-run on every boot) and MUST NOT be destructive.
|
|
627
|
+
* Runs after auth initialization, because the generated policies call the
|
|
628
|
+
* `auth.*` helper functions and `CREATE POLICY` validates they exist.
|
|
629
|
+
*/
|
|
630
|
+
ensureCollectionPolicies?(collections: unknown[], driverResult: InitializedDriver, log?: (message: string) => void): Promise<{
|
|
631
|
+
applied: number;
|
|
632
|
+
}>;
|
|
614
633
|
/**
|
|
615
634
|
* Initialize WebSocket server for realtime operations.
|
|
616
635
|
*/
|
package/dist/types/cron.d.ts
CHANGED
|
@@ -26,6 +26,37 @@ export interface CronJobDefinition {
|
|
|
26
26
|
* considered timed-out. Default: 300 (5 min).
|
|
27
27
|
*/
|
|
28
28
|
timeoutSeconds?: number;
|
|
29
|
+
/**
|
|
30
|
+
* How far back to look, on startup, for a slot that elapsed while no
|
|
31
|
+
* instance was holding a timer for it. Off by default.
|
|
32
|
+
*
|
|
33
|
+
* The scheduler drives jobs with in-process `setTimeout` and computes the
|
|
34
|
+
* next slot from *now* on every boot, so a slot only fires if some instance
|
|
35
|
+
* happened to be alive and ticking when it came round. That is not a
|
|
36
|
+
* scale-to-zero problem: a platform that recycles containers — Cloud Run
|
|
37
|
+
* rotating an instance under `--min-instances 1`, a rolling deploy, a crash
|
|
38
|
+
* loop — drops any slot that falls inside the changeover, and the
|
|
39
|
+
* replacement schedules the slot *after* it. The run is skipped in silence.
|
|
40
|
+
*
|
|
41
|
+
* Set this to a window comfortably wider than a restart (a few minutes for
|
|
42
|
+
* a frequent job; an hour or more for a daily one) and startup will run a
|
|
43
|
+
* slot it finds unclaimed inside that window.
|
|
44
|
+
*
|
|
45
|
+
* Two deliberate limits:
|
|
46
|
+
*
|
|
47
|
+
* - **Only the most recent missed slot runs.** Booting after a six-hour
|
|
48
|
+
* outage catches an hourly job up once, not six times. Catch-up exists to
|
|
49
|
+
* stop a run going missing, not to replay history.
|
|
50
|
+
* - **A claims-capable store is required.** Catch-up is skipped entirely
|
|
51
|
+
* when the store has no `tryClaimRun` (or no store is attached), because
|
|
52
|
+
* the claim is the only thing that distinguishes "this slot never ran"
|
|
53
|
+
* from "this slot already ran on the instance I am replacing". Without
|
|
54
|
+
* it, an instance recycled every 30 minutes would re-run the same hourly
|
|
55
|
+
* job every time it booted.
|
|
56
|
+
*
|
|
57
|
+
* @example catchUpWindowSeconds: 3600 // daily job: tolerate an hour of downtime
|
|
58
|
+
*/
|
|
59
|
+
catchUpWindowSeconds?: number;
|
|
29
60
|
/**
|
|
30
61
|
* The handler function executed on each tick.
|
|
31
62
|
* Receives a context object with the data driver and logger.
|
|
@@ -67,6 +67,32 @@ export interface DatabaseAdapter {
|
|
|
67
67
|
* Initialize WebSocket server for realtime operations.
|
|
68
68
|
*/
|
|
69
69
|
initializeWebsockets?(server: unknown, realtimeService: RealtimeProvider, driver: DataDriver, config?: unknown): Promise<void> | void;
|
|
70
|
+
/**
|
|
71
|
+
* Bring the database's collection tables up to date, additively — the boot
|
|
72
|
+
* companion to `db push`. See `BackendBootstrapper.ensureCollectionSchema`
|
|
73
|
+
* for the contract (create-only; never drop, narrow, or rewrite).
|
|
74
|
+
*
|
|
75
|
+
* Optional, and MUST be forwarded by any wrapper that turns this adapter
|
|
76
|
+
* into a `BackendBootstrapper`: the runtime calls it through the bootstrapper
|
|
77
|
+
* at boot, and a wrapper that silently omits it leaves a managed tenant
|
|
78
|
+
* 500ing every data route with no create step ever having run.
|
|
79
|
+
*/
|
|
80
|
+
ensureCollectionSchema?(collections: unknown[], driverResult: InitializedDriver, log?: (message: string) => void): Promise<{
|
|
81
|
+
applied: number;
|
|
82
|
+
}>;
|
|
83
|
+
/**
|
|
84
|
+
* Apply the collections' RLS policies (ENABLE ROW LEVEL SECURITY + the
|
|
85
|
+
* `securityRules` compiled to `CREATE POLICY`) — the boot companion to the
|
|
86
|
+
* policy half of `db push`. Idempotent; see
|
|
87
|
+
* `BackendBootstrapper.ensureCollectionPolicies`.
|
|
88
|
+
*
|
|
89
|
+
* Same forwarding requirement as `ensureCollectionSchema`: without the
|
|
90
|
+
* policies, tables exist but every user-context read is denied (a public
|
|
91
|
+
* collection answers 401).
|
|
92
|
+
*/
|
|
93
|
+
ensureCollectionPolicies?(collections: unknown[], driverResult: InitializedDriver, log?: (message: string) => void): Promise<{
|
|
94
|
+
applied: number;
|
|
95
|
+
}>;
|
|
70
96
|
/**
|
|
71
97
|
* Return admin capabilities for this database (SQL editor, schema browser, branching).
|
|
72
98
|
*/
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rebasepro/types",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.12.
|
|
4
|
+
"version": "0.12.1-canary.g181d0fe",
|
|
5
5
|
"description": "Rebase type definitions — shared interfaces and controller types",
|
|
6
6
|
"funding": {
|
|
7
7
|
"url": "https://github.com/sponsors/rebaseco"
|
|
@@ -39,14 +39,14 @@
|
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
41
|
"@types/jest": "^30.0.0",
|
|
42
|
-
"@types/node": "^
|
|
42
|
+
"@types/node": "^26.1.2",
|
|
43
43
|
"@types/object-hash": "^3.0.6",
|
|
44
44
|
"@types/react-measure": "^2.0.12",
|
|
45
45
|
"hono": "^4.12.27",
|
|
46
46
|
"jest": "^30.4.2",
|
|
47
|
-
"ts-jest": "^29.4.
|
|
47
|
+
"ts-jest": "^29.4.12",
|
|
48
48
|
"typescript": "^6.0.3",
|
|
49
|
-
"vite": "^8.
|
|
49
|
+
"vite": "^8.1.5"
|
|
50
50
|
},
|
|
51
51
|
"peerDependencies": {
|
|
52
52
|
"hono": "^4.12.27"
|
|
@@ -94,6 +94,21 @@ export interface AuthClient {
|
|
|
94
94
|
* Manually refresh the session token
|
|
95
95
|
*/
|
|
96
96
|
refreshSession(): Promise<RebaseSession>;
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Whether a session could exist that this client has not loaded yet.
|
|
100
|
+
*
|
|
101
|
+
* `false` means the only way this client can hold a session is an explicit
|
|
102
|
+
* sign-in during this page's lifetime: it neither persists sessions nor
|
|
103
|
+
* carries an httpOnly auth cookie, so there is nothing on disk or in the
|
|
104
|
+
* browser to restore from. A caller that would otherwise probe the server
|
|
105
|
+
* — `getUser()` on mount, say — can skip it, because the answer is already
|
|
106
|
+
* known and the request can only ever fail.
|
|
107
|
+
*
|
|
108
|
+
* Optional so that alternative {@link AuthClient} implementations need not
|
|
109
|
+
* supply it; treat a missing implementation as "unknown, go ahead and ask".
|
|
110
|
+
*/
|
|
111
|
+
canRestoreSession?: () => boolean;
|
|
97
112
|
}
|
|
98
113
|
|
|
99
114
|
// ─── Admin API ───────────────────────────────────────────────────────────────
|
|
@@ -321,6 +336,17 @@ export interface RebaseClient<DB = unknown> {
|
|
|
321
336
|
/** Base HTTP URL of the backend server */
|
|
322
337
|
baseUrl?: string;
|
|
323
338
|
|
|
339
|
+
/**
|
|
340
|
+
* The path every API route is mounted under, appended to {@link baseUrl}.
|
|
341
|
+
*
|
|
342
|
+
* `"/api"` unless the backend was configured with a different `basePath`
|
|
343
|
+
* and the client told to match. Exposed because code that builds a URL by
|
|
344
|
+
* hand — rather than going through the client's own methods — otherwise has
|
|
345
|
+
* to guess, and guessing `/api` is wrong for exactly the projects that set
|
|
346
|
+
* the option.
|
|
347
|
+
*/
|
|
348
|
+
apiPath?: string;
|
|
349
|
+
|
|
324
350
|
/** WebSocket client for realtime subscriptions */
|
|
325
351
|
ws?: RebaseWebSocket;
|
|
326
352
|
|
|
@@ -439,6 +465,17 @@ export interface RebaseBrowserClient<DB = unknown> {
|
|
|
439
465
|
/** Base HTTP URL of the backend server */
|
|
440
466
|
baseUrl?: string;
|
|
441
467
|
|
|
468
|
+
/**
|
|
469
|
+
* The path every API route is mounted under, appended to {@link baseUrl}.
|
|
470
|
+
*
|
|
471
|
+
* `"/api"` unless the backend was configured with a different `basePath`
|
|
472
|
+
* and the client told to match. Exposed because code that builds a URL by
|
|
473
|
+
* hand — rather than going through the client's own methods — otherwise has
|
|
474
|
+
* to guess, and guessing `/api` is wrong for exactly the projects that set
|
|
475
|
+
* the option.
|
|
476
|
+
*/
|
|
477
|
+
apiPath?: string;
|
|
478
|
+
|
|
442
479
|
/** WebSocket client for realtime subscriptions */
|
|
443
480
|
ws?: RebaseWebSocket;
|
|
444
481
|
|
package/src/types/backend.ts
CHANGED
|
@@ -798,6 +798,28 @@ export interface BackendBootstrapper {
|
|
|
798
798
|
log?: (message: string) => void
|
|
799
799
|
): Promise<{ applied: number }>;
|
|
800
800
|
|
|
801
|
+
/**
|
|
802
|
+
* Apply the collections' row-level-security policies, additively and
|
|
803
|
+
* idempotently — the companion to {@link ensureCollectionSchema}.
|
|
804
|
+
*
|
|
805
|
+
* That method creates the tables; a table with RLS disabled and no policies
|
|
806
|
+
* is not servable, because authenticated requests run as a restricted role:
|
|
807
|
+
* a read with no `SELECT` policy returns nothing (a public collection
|
|
808
|
+
* answers 401) and a write with no `INSERT`/`UPDATE` policy is denied. The
|
|
809
|
+
* `db push` CLI applies these from the same collections, but it cannot reach
|
|
810
|
+
* a managed tenant's in-cluster database — the runtime, already connected,
|
|
811
|
+
* is the only thing that can.
|
|
812
|
+
*
|
|
813
|
+
* MUST be idempotent (re-run on every boot) and MUST NOT be destructive.
|
|
814
|
+
* Runs after auth initialization, because the generated policies call the
|
|
815
|
+
* `auth.*` helper functions and `CREATE POLICY` validates they exist.
|
|
816
|
+
*/
|
|
817
|
+
ensureCollectionPolicies?(
|
|
818
|
+
collections: unknown[],
|
|
819
|
+
driverResult: InitializedDriver,
|
|
820
|
+
log?: (message: string) => void
|
|
821
|
+
): Promise<{ applied: number }>;
|
|
822
|
+
|
|
801
823
|
/**
|
|
802
824
|
* Initialize WebSocket server for realtime operations.
|
|
803
825
|
*/
|
package/src/types/cron.ts
CHANGED
|
@@ -38,6 +38,38 @@ export interface CronJobDefinition {
|
|
|
38
38
|
*/
|
|
39
39
|
timeoutSeconds?: number;
|
|
40
40
|
|
|
41
|
+
/**
|
|
42
|
+
* How far back to look, on startup, for a slot that elapsed while no
|
|
43
|
+
* instance was holding a timer for it. Off by default.
|
|
44
|
+
*
|
|
45
|
+
* The scheduler drives jobs with in-process `setTimeout` and computes the
|
|
46
|
+
* next slot from *now* on every boot, so a slot only fires if some instance
|
|
47
|
+
* happened to be alive and ticking when it came round. That is not a
|
|
48
|
+
* scale-to-zero problem: a platform that recycles containers — Cloud Run
|
|
49
|
+
* rotating an instance under `--min-instances 1`, a rolling deploy, a crash
|
|
50
|
+
* loop — drops any slot that falls inside the changeover, and the
|
|
51
|
+
* replacement schedules the slot *after* it. The run is skipped in silence.
|
|
52
|
+
*
|
|
53
|
+
* Set this to a window comfortably wider than a restart (a few minutes for
|
|
54
|
+
* a frequent job; an hour or more for a daily one) and startup will run a
|
|
55
|
+
* slot it finds unclaimed inside that window.
|
|
56
|
+
*
|
|
57
|
+
* Two deliberate limits:
|
|
58
|
+
*
|
|
59
|
+
* - **Only the most recent missed slot runs.** Booting after a six-hour
|
|
60
|
+
* outage catches an hourly job up once, not six times. Catch-up exists to
|
|
61
|
+
* stop a run going missing, not to replay history.
|
|
62
|
+
* - **A claims-capable store is required.** Catch-up is skipped entirely
|
|
63
|
+
* when the store has no `tryClaimRun` (or no store is attached), because
|
|
64
|
+
* the claim is the only thing that distinguishes "this slot never ran"
|
|
65
|
+
* from "this slot already ran on the instance I am replacing". Without
|
|
66
|
+
* it, an instance recycled every 30 minutes would re-run the same hourly
|
|
67
|
+
* job every time it booted.
|
|
68
|
+
*
|
|
69
|
+
* @example catchUpWindowSeconds: 3600 // daily job: tolerate an hour of downtime
|
|
70
|
+
*/
|
|
71
|
+
catchUpWindowSeconds?: number;
|
|
72
|
+
|
|
41
73
|
/**
|
|
42
74
|
* The handler function executed on each tick.
|
|
43
75
|
* Receives a context object with the data driver and logger.
|
|
@@ -90,6 +90,38 @@ export interface DatabaseAdapter {
|
|
|
90
90
|
config?: unknown,
|
|
91
91
|
): Promise<void> | void;
|
|
92
92
|
|
|
93
|
+
/**
|
|
94
|
+
* Bring the database's collection tables up to date, additively — the boot
|
|
95
|
+
* companion to `db push`. See `BackendBootstrapper.ensureCollectionSchema`
|
|
96
|
+
* for the contract (create-only; never drop, narrow, or rewrite).
|
|
97
|
+
*
|
|
98
|
+
* Optional, and MUST be forwarded by any wrapper that turns this adapter
|
|
99
|
+
* into a `BackendBootstrapper`: the runtime calls it through the bootstrapper
|
|
100
|
+
* at boot, and a wrapper that silently omits it leaves a managed tenant
|
|
101
|
+
* 500ing every data route with no create step ever having run.
|
|
102
|
+
*/
|
|
103
|
+
ensureCollectionSchema?(
|
|
104
|
+
collections: unknown[],
|
|
105
|
+
driverResult: InitializedDriver,
|
|
106
|
+
log?: (message: string) => void,
|
|
107
|
+
): Promise<{ applied: number }>;
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Apply the collections' RLS policies (ENABLE ROW LEVEL SECURITY + the
|
|
111
|
+
* `securityRules` compiled to `CREATE POLICY`) — the boot companion to the
|
|
112
|
+
* policy half of `db push`. Idempotent; see
|
|
113
|
+
* `BackendBootstrapper.ensureCollectionPolicies`.
|
|
114
|
+
*
|
|
115
|
+
* Same forwarding requirement as `ensureCollectionSchema`: without the
|
|
116
|
+
* policies, tables exist but every user-context read is denied (a public
|
|
117
|
+
* collection answers 401).
|
|
118
|
+
*/
|
|
119
|
+
ensureCollectionPolicies?(
|
|
120
|
+
collections: unknown[],
|
|
121
|
+
driverResult: InitializedDriver,
|
|
122
|
+
log?: (message: string) => void,
|
|
123
|
+
): Promise<{ applied: number }>;
|
|
124
|
+
|
|
93
125
|
/**
|
|
94
126
|
* Return admin capabilities for this database (SQL editor, schema browser, branching).
|
|
95
127
|
*/
|