@rebasepro/client 0.11.1-canary.gfadf355 → 0.12.0
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/api-keys.d.ts +10 -38
- package/dist/functions.d.ts +2 -8
- package/dist/index.es.js.map +1 -1
- package/dist/realtime-channel.d.ts +8 -8
- package/package.json +4 -4
- package/src/api-keys.ts +21 -44
- package/src/functions.ts +2 -8
- package/src/offline-idb-store.test.ts +35 -0
- package/src/realtime-channel.ts +8 -8
|
@@ -49,14 +49,14 @@ export interface BroadcastEvent {
|
|
|
49
49
|
*/
|
|
50
50
|
replayed?: boolean;
|
|
51
51
|
}
|
|
52
|
-
/**
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
}
|
|
52
|
+
/**
|
|
53
|
+
* One retained message, as returned by {@link RebaseRealtimeChannel.history}.
|
|
54
|
+
*
|
|
55
|
+
* Re-exported rather than re-declared: the copy that used to live here had
|
|
56
|
+
* drifted `at` to optional, while the server always sends it.
|
|
57
|
+
*/
|
|
58
|
+
export type { ChannelHistoryEntry } from "@rebasepro/types";
|
|
59
|
+
import type { ChannelHistoryEntry } from "@rebasepro/types";
|
|
60
60
|
/** The answer to a catch-up request. */
|
|
61
61
|
export interface ChannelHistoryResult {
|
|
62
62
|
messages: ChannelHistoryEntry[];
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rebasepro/client",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.12.0",
|
|
5
5
|
"description": "HTTP SDK client for the Rebase custom backend",
|
|
6
6
|
"funding": {
|
|
7
7
|
"url": "https://github.com/sponsors/rebaseco"
|
|
@@ -29,9 +29,9 @@
|
|
|
29
29
|
"./package.json": "./package.json"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@rebasepro/common": "0.
|
|
33
|
-
"@rebasepro/types": "0.
|
|
34
|
-
"@rebasepro/utils": "0.
|
|
32
|
+
"@rebasepro/common": "0.12.0",
|
|
33
|
+
"@rebasepro/types": "0.12.0",
|
|
34
|
+
"@rebasepro/utils": "0.12.0"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
37
|
"@jest/globals": "^30.4.1",
|
package/src/api-keys.ts
CHANGED
|
@@ -1,50 +1,27 @@
|
|
|
1
1
|
import type { Transport } from "./transport";
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
admin: boolean;
|
|
19
|
-
rate_limit: number | null;
|
|
20
|
-
created_by: string;
|
|
21
|
-
created_at: string;
|
|
22
|
-
updated_at: string;
|
|
23
|
-
last_used_at: string | null;
|
|
24
|
-
expires_at: string | null;
|
|
25
|
-
revoked_at: string | null;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/** An API key including the full secret (returned only on creation). */
|
|
29
|
-
export interface ApiKeyWithSecret extends ApiKeyMasked {
|
|
30
|
-
key: string;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/** Payload for creating a new API key. */
|
|
34
|
-
export interface CreateApiKeyRequest {
|
|
35
|
-
name: string;
|
|
36
|
-
permissions: ApiKeyPermission[];
|
|
37
|
-
rate_limit?: number | null;
|
|
38
|
-
expires_at?: string | null;
|
|
39
|
-
}
|
|
3
|
+
/**
|
|
4
|
+
* These were re-declared here, under a comment saying they lived in the server
|
|
5
|
+
* package rather than in `@rebasepro/types`. That stopped being true, and the
|
|
6
|
+
* copy drifted: it never gained `admin`, the flag that grants a key the `admin`
|
|
7
|
+
* role — admin routes plus the RLS `default_admin` policies — so the SDK could
|
|
8
|
+
* describe every kind of key except a privileged one, and
|
|
9
|
+
* `createKey({ …, admin: true })` was an excess-property error.
|
|
10
|
+
*/
|
|
11
|
+
export type {
|
|
12
|
+
ApiKeyPermission,
|
|
13
|
+
ApiKeyMasked,
|
|
14
|
+
ApiKeyWithSecret,
|
|
15
|
+
CreateApiKeyRequest,
|
|
16
|
+
UpdateApiKeyRequest
|
|
17
|
+
} from "@rebasepro/types";
|
|
40
18
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
}
|
|
19
|
+
import type {
|
|
20
|
+
ApiKeyMasked,
|
|
21
|
+
ApiKeyWithSecret,
|
|
22
|
+
CreateApiKeyRequest,
|
|
23
|
+
UpdateApiKeyRequest
|
|
24
|
+
} from "@rebasepro/types";
|
|
48
25
|
|
|
49
26
|
/** Options for the `createApiKeys` factory. */
|
|
50
27
|
export interface CreateApiKeysOptions {
|
package/src/functions.ts
CHANGED
|
@@ -33,14 +33,8 @@ export interface FunctionsClient {
|
|
|
33
33
|
): Promise<T>;
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
export
|
|
37
|
-
|
|
38
|
-
method?: "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
|
|
39
|
-
/** Sub-path appended after the function name, e.g. `"status/123"`. */
|
|
40
|
-
path?: string;
|
|
41
|
-
/** Extra headers merged into the request (auth is still injected automatically). */
|
|
42
|
-
headers?: Record<string, string>;
|
|
43
|
-
}
|
|
36
|
+
export type { FunctionInvokeOptions } from "@rebasepro/types";
|
|
37
|
+
import type { FunctionInvokeOptions } from "@rebasepro/types";
|
|
44
38
|
|
|
45
39
|
/**
|
|
46
40
|
* Create a `FunctionsClient` backed by the given transport.
|
|
@@ -155,7 +155,40 @@ describe("row codec round-trip", () => {
|
|
|
155
155
|
});
|
|
156
156
|
});
|
|
157
157
|
|
|
158
|
+
/**
|
|
159
|
+
* Empty the shared queue between the manager tests.
|
|
160
|
+
*
|
|
161
|
+
* `IDB_NAME` is a hardcoded `"rebase-offline"`, so every
|
|
162
|
+
* `new IndexedDBOfflineStore()` in this file opens the *same* database. The
|
|
163
|
+
* `IndexedDBOfflineStore` block above shares it deliberately — each of its
|
|
164
|
+
* tests uses its own key prefix, and one of them exists to prove that
|
|
165
|
+
* isolation holds. The two `OfflineManager` blocks below do not: a manager
|
|
166
|
+
* queues under no prefix, so without this they inherit each other's pending
|
|
167
|
+
* writes.
|
|
168
|
+
*
|
|
169
|
+
* CI failed both manager tests on 2026-07-28 with exactly the symptoms this
|
|
170
|
+
* coupling would produce — "replays them from a fresh one" asserted
|
|
171
|
+
* `flushed: 1` and got `2`, and the cross-tab read came back empty. It has not
|
|
172
|
+
* been reproduced locally (14 runs, including randomized order), so treat this
|
|
173
|
+
* as removing a real coupling rather than as a confirmed diagnosis: if CI fails
|
|
174
|
+
* here again, the shared queue is no longer the explanation and the next place
|
|
175
|
+
* to look is timing inside the manager itself.
|
|
176
|
+
*/
|
|
177
|
+
async function clearOfflineQueue(): Promise<void> {
|
|
178
|
+
await new Promise<void>((resolve, reject) => {
|
|
179
|
+
const request = indexedDB.deleteDatabase("rebase-offline");
|
|
180
|
+
request.onsuccess = () => resolve();
|
|
181
|
+
request.onerror = () => reject(request.error);
|
|
182
|
+
// A still-open connection blocks the delete; the manager tests each
|
|
183
|
+
// build their own stores, so resolving here keeps a stray one from
|
|
184
|
+
// hanging the suite rather than failing it.
|
|
185
|
+
request.onblocked = () => resolve();
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
|
|
158
189
|
describe("two tabs over one database", () => {
|
|
190
|
+
beforeEach(clearOfflineQueue);
|
|
191
|
+
|
|
159
192
|
/** BroadcastChannel delivery is asynchronous; give it a macrotask or two. */
|
|
160
193
|
const settle = async () => {
|
|
161
194
|
for (let i = 0; i < 3; i++) await new Promise((resolve) => setTimeout(resolve, 0));
|
|
@@ -240,6 +273,8 @@ describe("two tabs over one database", () => {
|
|
|
240
273
|
});
|
|
241
274
|
|
|
242
275
|
describe("OfflineManager over IndexedDB", () => {
|
|
276
|
+
beforeEach(clearOfflineQueue);
|
|
277
|
+
|
|
243
278
|
it("queues offline writes in one manager and replays them from a fresh one", async () => {
|
|
244
279
|
const table = new Map<string, Record<string, unknown>>();
|
|
245
280
|
const state = { online: true };
|
package/src/realtime-channel.ts
CHANGED
|
@@ -53,14 +53,14 @@ export interface BroadcastEvent {
|
|
|
53
53
|
replayed?: boolean;
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
-
/**
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
}
|
|
56
|
+
/**
|
|
57
|
+
* One retained message, as returned by {@link RebaseRealtimeChannel.history}.
|
|
58
|
+
*
|
|
59
|
+
* Re-exported rather than re-declared: the copy that used to live here had
|
|
60
|
+
* drifted `at` to optional, while the server always sends it.
|
|
61
|
+
*/
|
|
62
|
+
export type { ChannelHistoryEntry } from "@rebasepro/types";
|
|
63
|
+
import type { ChannelHistoryEntry } from "@rebasepro/types";
|
|
64
64
|
|
|
65
65
|
/** The answer to a catch-up request. */
|
|
66
66
|
export interface ChannelHistoryResult {
|