@instantdb/core 1.0.42 → 1.0.43-branch-drewh-cli-email.26904178974.1
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/__tests__/src/cookieSync.e2e.test.ts +163 -0
- package/__tests__/src/utils/e2e.ts +23 -0
- package/__tests__/src/utils/msw.ts +3 -0
- package/dist/commonjs/Reactor.d.ts +2 -0
- package/dist/commonjs/Reactor.d.ts.map +1 -1
- package/dist/commonjs/Reactor.js +34 -16
- package/dist/commonjs/Reactor.js.map +1 -1
- package/dist/esm/Reactor.d.ts +2 -0
- package/dist/esm/Reactor.d.ts.map +1 -1
- package/dist/esm/Reactor.js +34 -16
- package/dist/esm/Reactor.js.map +1 -1
- package/dist/standalone/index.js +593 -579
- package/dist/standalone/index.umd.cjs +3 -3
- package/package.json +7 -2
- package/src/Reactor.js +37 -18
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { expect, type TestContext, vi } from 'vitest';
|
|
2
|
+
import { http, HttpResponse, ws } from 'msw';
|
|
3
|
+
import { i, init, type User } from '../../src';
|
|
4
|
+
import { apiUrl, makeE2ETest } from './utils/e2e';
|
|
5
|
+
import { COOKIE_SYNC_LAST_UPDATED_KEY } from '../../src/Reactor';
|
|
6
|
+
|
|
7
|
+
const FIRST_PARTY_PATH = 'https://example.com';
|
|
8
|
+
const ONE_DAY_MS = 1_000 * 60 * 60 * 24;
|
|
9
|
+
const websocketURI = `${apiUrl.replace(/^http/, 'ws')}/runtime/session`;
|
|
10
|
+
const runtimeSession = ws.link(websocketURI);
|
|
11
|
+
const rules = {
|
|
12
|
+
code: {},
|
|
13
|
+
};
|
|
14
|
+
const schema = i.schema({
|
|
15
|
+
entities: {
|
|
16
|
+
animal: i.entity({}),
|
|
17
|
+
},
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
const test = makeE2ETest({
|
|
21
|
+
rules,
|
|
22
|
+
schema,
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
type InitDbConfig = {
|
|
26
|
+
firstPartyPath?: string;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
type SyncUserRequest = {
|
|
30
|
+
type: 'sync-user';
|
|
31
|
+
appId: string;
|
|
32
|
+
user: User | null;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
async function createApp(task: TestContext['task'], signal: AbortSignal) {
|
|
36
|
+
const response = await fetch(`${apiUrl}/dash/apps/ephemeral`, {
|
|
37
|
+
body: JSON.stringify({ title: `e2e-${task.id}`, schema, rules }),
|
|
38
|
+
headers: { 'Content-Type': 'application/json' },
|
|
39
|
+
method: 'POST',
|
|
40
|
+
signal: AbortSignal.any([signal, AbortSignal.timeout(4000)]),
|
|
41
|
+
});
|
|
42
|
+
if (!response.ok) {
|
|
43
|
+
throw new Error(await response.text());
|
|
44
|
+
}
|
|
45
|
+
const { app } = await response.json();
|
|
46
|
+
return app;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function initDb(appId: string, config: InitDbConfig = {}) {
|
|
50
|
+
return init({
|
|
51
|
+
...config,
|
|
52
|
+
appId,
|
|
53
|
+
apiURI: apiUrl,
|
|
54
|
+
websocketURI,
|
|
55
|
+
schema,
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
async function primeCookieSync(
|
|
60
|
+
appId: string,
|
|
61
|
+
user: User,
|
|
62
|
+
requests: SyncUserRequest[],
|
|
63
|
+
) {
|
|
64
|
+
const db = initDb(appId, { firstPartyPath: FIRST_PARTY_PATH });
|
|
65
|
+
try {
|
|
66
|
+
await expect.poll(() => requests.length).toBe(1);
|
|
67
|
+
await db._reactor.setCurrentUser(user);
|
|
68
|
+
await db._reactor.syncUserToEndpoint(user);
|
|
69
|
+
await expect.poll(() => requests.length).toBe(2);
|
|
70
|
+
await db._reactor.kv.flush();
|
|
71
|
+
} finally {
|
|
72
|
+
db.shutdown();
|
|
73
|
+
}
|
|
74
|
+
requests.length = 0;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
test('syncs user cookie on startup when last sync is at least a day old', async ({
|
|
78
|
+
worker,
|
|
79
|
+
task,
|
|
80
|
+
signal,
|
|
81
|
+
}) => {
|
|
82
|
+
const startTime = new Date('2026-01-01T00:00:00.000Z');
|
|
83
|
+
vi.setSystemTime(startTime);
|
|
84
|
+
let db: ReturnType<typeof initDb> | undefined;
|
|
85
|
+
|
|
86
|
+
try {
|
|
87
|
+
const app = await createApp(task, signal);
|
|
88
|
+
const user: User = {
|
|
89
|
+
id: 'user-id',
|
|
90
|
+
refresh_token: 'refresh-token',
|
|
91
|
+
isGuest: false,
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
const requests: SyncUserRequest[] = [];
|
|
95
|
+
worker.use(
|
|
96
|
+
runtimeSession.addEventListener('connection', () => {}),
|
|
97
|
+
http.post(
|
|
98
|
+
`${FIRST_PARTY_PATH}/`,
|
|
99
|
+
async ({ request }: { request: Request }) => {
|
|
100
|
+
requests.push((await request.json()) as SyncUserRequest);
|
|
101
|
+
return new HttpResponse(null, { status: 200 });
|
|
102
|
+
},
|
|
103
|
+
),
|
|
104
|
+
);
|
|
105
|
+
|
|
106
|
+
await primeCookieSync(app.id, user, requests);
|
|
107
|
+
vi.setSystemTime(new Date(startTime.getTime() + ONE_DAY_MS));
|
|
108
|
+
|
|
109
|
+
db = initDb(app.id, { firstPartyPath: FIRST_PARTY_PATH });
|
|
110
|
+
await expect.poll(() => requests.length).toBe(1);
|
|
111
|
+
expect(requests).toHaveLength(1);
|
|
112
|
+
expect(requests[0]).toMatchObject({
|
|
113
|
+
type: 'sync-user',
|
|
114
|
+
appId: app.id,
|
|
115
|
+
user,
|
|
116
|
+
});
|
|
117
|
+
} finally {
|
|
118
|
+
db?.shutdown();
|
|
119
|
+
vi.useRealTimers();
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
test('does not sync user cookie on startup when last sync is recent', async ({
|
|
124
|
+
worker,
|
|
125
|
+
task,
|
|
126
|
+
signal,
|
|
127
|
+
}) => {
|
|
128
|
+
const startTime = new Date('2026-01-01T00:00:00.000Z');
|
|
129
|
+
vi.setSystemTime(startTime);
|
|
130
|
+
let db: ReturnType<typeof initDb> | undefined;
|
|
131
|
+
|
|
132
|
+
try {
|
|
133
|
+
const app = await createApp(task, signal);
|
|
134
|
+
const user: User = {
|
|
135
|
+
id: 'user-id',
|
|
136
|
+
refresh_token: 'refresh-token',
|
|
137
|
+
isGuest: false,
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
const requests: SyncUserRequest[] = [];
|
|
141
|
+
worker.use(
|
|
142
|
+
runtimeSession.addEventListener('connection', () => {}),
|
|
143
|
+
http.post(
|
|
144
|
+
`${FIRST_PARTY_PATH}/`,
|
|
145
|
+
async ({ request }: { request: Request }) => {
|
|
146
|
+
requests.push((await request.json()) as SyncUserRequest);
|
|
147
|
+
return new HttpResponse(null, { status: 200 });
|
|
148
|
+
},
|
|
149
|
+
),
|
|
150
|
+
);
|
|
151
|
+
|
|
152
|
+
await primeCookieSync(app.id, user, requests);
|
|
153
|
+
vi.setSystemTime(new Date(startTime.getTime() + ONE_DAY_MS - 1));
|
|
154
|
+
|
|
155
|
+
db = initDb(app.id, { firstPartyPath: FIRST_PARTY_PATH });
|
|
156
|
+
await db._reactor.kv.waitForKeyToLoad(COOKIE_SYNC_LAST_UPDATED_KEY);
|
|
157
|
+
await new Promise<void>((resolve) => setTimeout(resolve, 50));
|
|
158
|
+
expect(requests).toHaveLength(0);
|
|
159
|
+
} finally {
|
|
160
|
+
db?.shutdown();
|
|
161
|
+
vi.useRealTimers();
|
|
162
|
+
}
|
|
163
|
+
});
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { test as baseTest } from 'vitest';
|
|
2
2
|
import {
|
|
3
3
|
init,
|
|
4
|
+
InstantConfig,
|
|
4
5
|
InstantCoreDatabase,
|
|
5
6
|
InstantRules,
|
|
6
7
|
InstantSchemaDef,
|
|
7
8
|
} from '../../../src';
|
|
9
|
+
import { worker } from './msw';
|
|
8
10
|
|
|
9
11
|
// __DEV_LOCAL_PORT__ is set by vitest.config.ts.
|
|
10
12
|
// This allows us to run tests against mulutple checkouts
|
|
@@ -24,16 +26,19 @@ const websocketURI = __DEV_LOCAL_PORT__
|
|
|
24
26
|
export function makeE2ETest<Schema extends InstantSchemaDef<any, any, any>>({
|
|
25
27
|
schema,
|
|
26
28
|
rules,
|
|
29
|
+
config,
|
|
27
30
|
}: {
|
|
28
31
|
schema?: Schema;
|
|
29
32
|
rules?: {
|
|
30
33
|
code: InstantRules;
|
|
31
34
|
};
|
|
35
|
+
config?: Partial<InstantConfig<Schema, any>>;
|
|
32
36
|
}) {
|
|
33
37
|
return baseTest.extend<{
|
|
34
38
|
db: InstantCoreDatabase<Schema, false>;
|
|
35
39
|
appId: string;
|
|
36
40
|
adminToken: string;
|
|
41
|
+
worker: typeof worker;
|
|
37
42
|
}>({
|
|
38
43
|
db: async ({ task, signal }, use) => {
|
|
39
44
|
const response = await fetch(`${apiUrl}/dash/apps/ephemeral`, {
|
|
@@ -47,6 +52,7 @@ export function makeE2ETest<Schema extends InstantSchemaDef<any, any, any>>({
|
|
|
47
52
|
}
|
|
48
53
|
const { app } = await response.json();
|
|
49
54
|
const db = init<Schema>({
|
|
55
|
+
...config,
|
|
50
56
|
appId: app.id,
|
|
51
57
|
apiURI: apiUrl,
|
|
52
58
|
websocketURI,
|
|
@@ -61,6 +67,23 @@ export function makeE2ETest<Schema extends InstantSchemaDef<any, any, any>>({
|
|
|
61
67
|
adminToken: async ({ db }, use) => {
|
|
62
68
|
await use((db as any)._testApp['admin-token']);
|
|
63
69
|
},
|
|
70
|
+
// https://mswjs.io/docs/integrations/browser
|
|
71
|
+
worker: [
|
|
72
|
+
async ({}, use) => {
|
|
73
|
+
// Start the worker before the test.
|
|
74
|
+
await worker.start({ quiet: true });
|
|
75
|
+
|
|
76
|
+
// Expose the worker object on the test's context.
|
|
77
|
+
await use(worker);
|
|
78
|
+
|
|
79
|
+
// Remove any request handlers added in individual test cases.
|
|
80
|
+
// This prevents them from affecting unrelated tests.
|
|
81
|
+
worker.resetHandlers();
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
auto: true,
|
|
85
|
+
},
|
|
86
|
+
],
|
|
64
87
|
});
|
|
65
88
|
}
|
|
66
89
|
|
|
@@ -5,6 +5,7 @@ export namespace STATUS {
|
|
|
5
5
|
let CLOSED: string;
|
|
6
6
|
let ERRORED: string;
|
|
7
7
|
}
|
|
8
|
+
export const COOKIE_SYNC_LAST_UPDATED_KEY: "lastSyncedUserCookie";
|
|
8
9
|
/**
|
|
9
10
|
* @template {import('./presence.ts').RoomSchemaShape} [RoomSchema = {}]
|
|
10
11
|
*/
|
|
@@ -289,6 +290,7 @@ export default class Reactor<RoomSchema extends import("./presence.ts").RoomSche
|
|
|
289
290
|
}): Promise<AuthState>;
|
|
290
291
|
_hasCurrentUser(): Promise<boolean>;
|
|
291
292
|
changeCurrentUser(newUser: any): Promise<void>;
|
|
293
|
+
setupUserSyncTimer(): Promise<void>;
|
|
292
294
|
syncUserToEndpoint(user: any): Promise<void>;
|
|
293
295
|
updateUser(newUser: any): Promise<void>;
|
|
294
296
|
sendMagicCode({ email }: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Reactor.d.ts","sourceRoot":"","sources":["../../src/Reactor.js"],"names":[],"mappings":";;;;;;;
|
|
1
|
+
{"version":3,"file":"Reactor.d.ts","sourceRoot":"","sources":["../../src/Reactor.js"],"names":[],"mappings":"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"}
|
package/dist/commonjs/Reactor.js
CHANGED
|
@@ -36,7 +36,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
36
36
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
37
|
};
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
-
exports.STATUS = void 0;
|
|
39
|
+
exports.COOKIE_SYNC_LAST_UPDATED_KEY = exports.STATUS = void 0;
|
|
40
40
|
// @ts-check
|
|
41
41
|
const weakHash_ts_1 = __importDefault(require("./utils/weakHash.js"));
|
|
42
42
|
const weakHashLegacy_ts_1 = __importDefault(require("./utils/weakHashLegacy.js"));
|
|
@@ -86,6 +86,8 @@ const QUERY_ONCE_TIMEOUT = 30_000;
|
|
|
86
86
|
const PENDING_TX_CLEANUP_TIMEOUT = 30_000;
|
|
87
87
|
const PENDING_MUTATION_CLEANUP_THRESHOLD = 200;
|
|
88
88
|
const ONE_MIN_MS = 1_000 * 60;
|
|
89
|
+
const ONE_DAY_MS = ONE_MIN_MS * 60 * 24;
|
|
90
|
+
exports.COOKIE_SYNC_LAST_UPDATED_KEY = 'lastSyncedUserCookie';
|
|
89
91
|
const defaultConfig = {
|
|
90
92
|
apiURI: 'https://api.instantdb.com',
|
|
91
93
|
websocketURI: 'wss://api.instantdb.com/runtime/session',
|
|
@@ -325,14 +327,7 @@ class Reactor {
|
|
|
325
327
|
log: this._log,
|
|
326
328
|
});
|
|
327
329
|
this._oauthCallbackResponse = this._oauthLoginInit();
|
|
328
|
-
|
|
329
|
-
this.getCurrentUser().then((userInfo) => {
|
|
330
|
-
this.syncUserToEndpoint(userInfo.user);
|
|
331
|
-
});
|
|
332
|
-
setInterval(async () => {
|
|
333
|
-
const currentUser = await this.getCurrentUser();
|
|
334
|
-
this.syncUserToEndpoint(currentUser.user);
|
|
335
|
-
}, ONE_MIN_MS);
|
|
330
|
+
this.setupUserSyncTimer();
|
|
336
331
|
NetworkListener.getIsOnline().then((isOnline) => {
|
|
337
332
|
this._isOnline = isOnline;
|
|
338
333
|
this._startSocket();
|
|
@@ -1841,11 +1836,28 @@ class Reactor {
|
|
|
1841
1836
|
console.error('Error posting message to broadcast channel', error);
|
|
1842
1837
|
}
|
|
1843
1838
|
}
|
|
1839
|
+
async setupUserSyncTimer() {
|
|
1840
|
+
if (!this.config.firstPartyPath)
|
|
1841
|
+
return;
|
|
1842
|
+
try {
|
|
1843
|
+
const lastSynced = await this.kv.waitForKeyToLoad(exports.COOKIE_SYNC_LAST_UPDATED_KEY);
|
|
1844
|
+
const lastSyncTime = lastSynced ? new Date(lastSynced).getTime() : 0;
|
|
1845
|
+
const shouldSync = !Number.isFinite(lastSyncTime) ||
|
|
1846
|
+
Date.now() - lastSyncTime >= ONE_DAY_MS;
|
|
1847
|
+
if (!shouldSync)
|
|
1848
|
+
return;
|
|
1849
|
+
const { user } = await this.getCurrentUser();
|
|
1850
|
+
await this.syncUserToEndpoint(user ?? null);
|
|
1851
|
+
}
|
|
1852
|
+
catch (error) {
|
|
1853
|
+
this._log.error('Error syncing user cookie on startup', error);
|
|
1854
|
+
}
|
|
1855
|
+
}
|
|
1844
1856
|
async syncUserToEndpoint(user) {
|
|
1845
1857
|
if (!this.config.firstPartyPath)
|
|
1846
1858
|
return;
|
|
1847
1859
|
try {
|
|
1848
|
-
await fetch(this.config.firstPartyPath + '/', {
|
|
1860
|
+
const response = await fetch(this.config.firstPartyPath + '/', {
|
|
1849
1861
|
method: 'POST',
|
|
1850
1862
|
body: JSON.stringify({
|
|
1851
1863
|
type: 'sync-user',
|
|
@@ -1856,18 +1868,18 @@ class Reactor {
|
|
|
1856
1868
|
'Content-Type': 'application/json',
|
|
1857
1869
|
},
|
|
1858
1870
|
});
|
|
1871
|
+
if (!response.ok) {
|
|
1872
|
+
throw new Error(`HTTP error! status: ${response.status}`);
|
|
1873
|
+
}
|
|
1859
1874
|
}
|
|
1860
1875
|
catch (error) {
|
|
1861
1876
|
this._log.error('Error syncing user with external endpoint', error);
|
|
1862
1877
|
}
|
|
1878
|
+
this.kv.updateInPlace((prev) => {
|
|
1879
|
+
prev[exports.COOKIE_SYNC_LAST_UPDATED_KEY] = new Date().toISOString();
|
|
1880
|
+
});
|
|
1863
1881
|
}
|
|
1864
1882
|
async updateUser(newUser) {
|
|
1865
|
-
try {
|
|
1866
|
-
await this.syncUserToEndpoint(newUser);
|
|
1867
|
-
}
|
|
1868
|
-
catch (error) {
|
|
1869
|
-
this._log.error('Error syncing user with external endpoint', error);
|
|
1870
|
-
}
|
|
1871
1883
|
const newV = { error: undefined, user: newUser };
|
|
1872
1884
|
this._currentUserCached = { isLoading: false, ...newV };
|
|
1873
1885
|
this._dataForQueryCache = {};
|
|
@@ -1894,6 +1906,12 @@ class Reactor {
|
|
|
1894
1906
|
this._transport.close();
|
|
1895
1907
|
this._oauthCallbackResponse = null;
|
|
1896
1908
|
this.notifyAuthSubs(newV);
|
|
1909
|
+
try {
|
|
1910
|
+
await this.syncUserToEndpoint(newUser);
|
|
1911
|
+
}
|
|
1912
|
+
catch (error) {
|
|
1913
|
+
this._log.error('Error syncing user with external endpoint', error);
|
|
1914
|
+
}
|
|
1897
1915
|
}
|
|
1898
1916
|
sendMagicCode({ email }) {
|
|
1899
1917
|
return authAPI.sendMagicCode({
|