on-zero 0.16.7 → 0.16.8
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/cjs/cli.native.js.map +1 -1
- package/dist/cjs/combineZeroClients.native.js.map +1 -1
- package/dist/cjs/config.native.js.map +1 -1
- package/dist/cjs/createPermissions.native.js.map +1 -1
- package/dist/cjs/createSchemaFromDrizzle.native.js.map +1 -1
- package/dist/cjs/createUseQuery.native.js.map +1 -1
- package/dist/cjs/createUseQueryDirect.native.js.map +1 -1
- package/dist/cjs/createZeroClient.authData.test.native.js.map +1 -1
- package/dist/cjs/createZeroClient.cjs +32 -6
- package/dist/cjs/createZeroClient.connection.test.cjs +52 -0
- package/dist/cjs/createZeroClient.connection.test.native.js +56 -0
- package/dist/cjs/createZeroClient.connection.test.native.js.map +1 -1
- package/dist/cjs/createZeroClient.exportProbe.test.native.js.map +1 -1
- package/dist/cjs/createZeroClient.headless.test.native.js.map +1 -1
- package/dist/cjs/createZeroClient.httpAuth.test.cjs +144 -0
- package/dist/cjs/createZeroClient.httpAuth.test.native.js +167 -0
- package/dist/cjs/createZeroClient.httpAuth.test.native.js.map +1 -0
- package/dist/cjs/createZeroClient.native.js +32 -6
- package/dist/cjs/createZeroClient.native.js.map +1 -1
- package/dist/cjs/createZeroClient.recovery.test.cjs +53 -0
- package/dist/cjs/createZeroClient.recovery.test.native.js +53 -0
- package/dist/cjs/createZeroClient.recovery.test.native.js.map +1 -1
- package/dist/cjs/generate-helpers.native.js.map +1 -1
- package/dist/cjs/generate-helpers.test.native.js.map +1 -1
- package/dist/cjs/generate-layout.native.js.map +1 -1
- package/dist/cjs/generate-lite.native.js.map +1 -1
- package/dist/cjs/generate-lite.test.native.js.map +1 -1
- package/dist/cjs/generate.native.js.map +1 -1
- package/dist/cjs/generate.test.native.js.map +1 -1
- package/dist/cjs/helpers/NullToOptional.native.js.map +1 -1
- package/dist/cjs/helpers/asyncContext.hostStorage.test.native.js.map +1 -1
- package/dist/cjs/helpers/batchQuery.native.js.map +1 -1
- package/dist/cjs/helpers/clearZeroClientData.native.js.map +1 -1
- package/dist/cjs/helpers/createMutators.native.js.map +1 -1
- package/dist/cjs/helpers/createMutators.test.native.js.map +1 -1
- package/dist/cjs/helpers/ellipsis.native.js.map +1 -1
- package/dist/cjs/helpers/emitter.native.js.map +1 -1
- package/dist/cjs/helpers/ensure.native.js.map +1 -1
- package/dist/cjs/helpers/ensureLoggedIn.native.js.map +1 -1
- package/dist/cjs/helpers/errors.native.js.map +1 -1
- package/dist/cjs/helpers/getAuth.native.js.map +1 -1
- package/dist/cjs/helpers/getCurrentComponentStack.native.js.map +1 -1
- package/dist/cjs/helpers/globalValue.native.js.map +1 -1
- package/dist/cjs/helpers/hostStorageScope.native.js.map +1 -1
- package/dist/cjs/helpers/mapObject.native.js.map +1 -1
- package/dist/cjs/helpers/mutationLifecycle.native.js.map +1 -1
- package/dist/cjs/helpers/mutationLifecycle.test.native.js.map +1 -1
- package/dist/cjs/helpers/mutatorContext.native.js.map +1 -1
- package/dist/cjs/helpers/mutatorContext.test.native.js.map +1 -1
- package/dist/cjs/helpers/prettyFormatZeroQuery.native.js.map +1 -1
- package/dist/cjs/helpers/queryContext.native.js.map +1 -1
- package/dist/cjs/helpers/recoverZeroClient.native.js.map +1 -1
- package/dist/cjs/helpers/recoverZeroClient.test.native.js.map +1 -1
- package/dist/cjs/helpers/showZeroClientError.native.js.map +1 -1
- package/dist/cjs/helpers/sleep.native.js.map +1 -1
- package/dist/cjs/helpers/time.native.js.map +1 -1
- package/dist/cjs/helpers/tuple.native.js.map +1 -1
- package/dist/cjs/helpers/useMutation.native.js.map +1 -1
- package/dist/cjs/helpers/useMutation.test.native.js.map +1 -1
- package/dist/cjs/helpers/useZeroDebug.native.js.map +1 -1
- package/dist/cjs/index.native.js.map +1 -1
- package/dist/cjs/instanceRegistry.native.js.map +1 -1
- package/dist/cjs/modelRegistry.native.js.map +1 -1
- package/dist/cjs/multi.native.js.map +1 -1
- package/dist/cjs/multiInstance.test.native.js.map +1 -1
- package/dist/cjs/multiInstanceMutations.test.native.js.map +1 -1
- package/dist/cjs/multiInstanceNested.test.native.js.map +1 -1
- package/dist/cjs/multiPartition.test.native.js.map +1 -1
- package/dist/cjs/mutations.native.js.map +1 -1
- package/dist/cjs/mutations.test.native.js.map +1 -1
- package/dist/cjs/provideZero.eagerInstance.test.native.js.map +1 -1
- package/dist/cjs/provideZero.hydration.test.native.js.map +1 -1
- package/dist/cjs/provideZero.ssr.test.native.js.map +1 -1
- package/dist/cjs/queryRegistry.native.js.map +1 -1
- package/dist/cjs/resolveQuery.native.js.map +1 -1
- package/dist/cjs/run.native.js.map +1 -1
- package/dist/cjs/server.native.js.map +1 -1
- package/dist/cjs/server.test.native.js.map +1 -1
- package/dist/cjs/serverWhere.native.js.map +1 -1
- package/dist/cjs/serverWhere.test.native.js.map +1 -1
- package/dist/cjs/state.native.js.map +1 -1
- package/dist/cjs/streaming.native.js.map +1 -1
- package/dist/cjs/testSetup.native.js.map +1 -1
- package/dist/cjs/types.native.js.map +1 -1
- package/dist/cjs/usePermission.test.native.js.map +1 -1
- package/dist/cjs/useQuery.empty.test.native.js.map +1 -1
- package/dist/cjs/useQuery.ssr.test.native.js.map +1 -1
- package/dist/cjs/useStreamingField.loop.test.native.js.map +1 -1
- package/dist/cjs/useStreamingField.native.js.map +1 -1
- package/dist/cjs/vite-plugin.native.js.map +1 -1
- package/dist/cjs/where.native.js.map +1 -1
- package/dist/cjs/zeroRunner.native.js.map +1 -1
- package/dist/cjs/zql.native.js.map +1 -1
- package/dist/esm/createZeroClient.connection.test.mjs +52 -0
- package/dist/esm/createZeroClient.connection.test.mjs.map +1 -1
- package/dist/esm/createZeroClient.connection.test.native.js +56 -0
- package/dist/esm/createZeroClient.connection.test.native.js.map +1 -1
- package/dist/esm/createZeroClient.httpAuth.test.mjs +145 -0
- package/dist/esm/createZeroClient.httpAuth.test.mjs.map +1 -0
- package/dist/esm/createZeroClient.httpAuth.test.native.js +165 -0
- package/dist/esm/createZeroClient.httpAuth.test.native.js.map +1 -0
- package/dist/esm/createZeroClient.mjs +33 -7
- package/dist/esm/createZeroClient.mjs.map +1 -1
- package/dist/esm/createZeroClient.native.js +33 -7
- package/dist/esm/createZeroClient.native.js.map +1 -1
- package/dist/esm/createZeroClient.recovery.test.mjs +54 -1
- package/dist/esm/createZeroClient.recovery.test.mjs.map +1 -1
- package/dist/esm/createZeroClient.recovery.test.native.js +54 -1
- package/dist/esm/createZeroClient.recovery.test.native.js.map +1 -1
- package/dist/esm/index.native.js.map +1 -1
- package/package.json +2 -2
- package/src/createZeroClient.connection.test.tsx +50 -1
- package/src/createZeroClient.httpAuth.test.ts +144 -0
- package/src/createZeroClient.recovery.test.tsx +61 -1
- package/src/createZeroClient.tsx +58 -14
- package/types/createZeroClient.d.ts +2 -1
- package/types/createZeroClient.d.ts.map +1 -1
- package/types/createZeroClient.httpAuth.test.d.ts +2 -0
- package/types/createZeroClient.httpAuth.test.d.ts.map +1 -0
|
@@ -142,7 +142,7 @@ test('refreshAuth reconnects in place on needs-auth, once per transition', async
|
|
|
142
142
|
const off = client.zeroEvents.listen((event) => {
|
|
143
143
|
if (event) events.push(event)
|
|
144
144
|
})
|
|
145
|
-
const instance = await mount({ refreshAuth }, 'conn-auth')
|
|
145
|
+
const instance = await mount({ auth: 'expired-token', refreshAuth }, 'conn-auth')
|
|
146
146
|
|
|
147
147
|
await act(async () => {
|
|
148
148
|
instance.connection.state.set({ name: 'needs-auth', reason: 'token expired' })
|
|
@@ -162,6 +162,55 @@ test('refreshAuth reconnects in place on needs-auth, once per transition', async
|
|
|
162
162
|
off()
|
|
163
163
|
})
|
|
164
164
|
|
|
165
|
+
test('refreshAuth leaves needs-auth parked when refresh returns the active token', async () => {
|
|
166
|
+
const refreshAuth = vi.fn(async () => 'expired-token')
|
|
167
|
+
const instance = await mount(
|
|
168
|
+
{ auth: 'expired-token', refreshAuth },
|
|
169
|
+
'conn-auth-unchanged'
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
await act(async () => {
|
|
173
|
+
instance.connection.state.set({ name: 'needs-auth', reason: 'token expired' })
|
|
174
|
+
await Promise.resolve()
|
|
175
|
+
})
|
|
176
|
+
await act(async () => {
|
|
177
|
+
await Promise.resolve()
|
|
178
|
+
})
|
|
179
|
+
|
|
180
|
+
expect(refreshAuth).toHaveBeenCalledTimes(1)
|
|
181
|
+
expect(instance.connection.connect).not.toHaveBeenCalled()
|
|
182
|
+
expect(instance.connection.state.current.name).toBe('needs-auth')
|
|
183
|
+
})
|
|
184
|
+
|
|
185
|
+
test('refreshAuth stops after three consecutively rejected replacement tokens', async () => {
|
|
186
|
+
let nextToken = 0
|
|
187
|
+
const refreshAuth = vi.fn(async () => `replacement-token-${++nextToken}`)
|
|
188
|
+
const instance = await mount(
|
|
189
|
+
{ auth: 'expired-token', refreshAuth },
|
|
190
|
+
'conn-auth-bounded'
|
|
191
|
+
)
|
|
192
|
+
|
|
193
|
+
for (let attempt = 0; attempt < 4; attempt++) {
|
|
194
|
+
await act(async () => {
|
|
195
|
+
instance.connection.state.set({ name: 'needs-auth', reason: 'token rejected' })
|
|
196
|
+
await Promise.resolve()
|
|
197
|
+
})
|
|
198
|
+
await act(async () => {
|
|
199
|
+
await Promise.resolve()
|
|
200
|
+
})
|
|
201
|
+
if (attempt < 3) {
|
|
202
|
+
await act(async () => {
|
|
203
|
+
instance.connection.state.set({ name: 'connecting' })
|
|
204
|
+
await Promise.resolve()
|
|
205
|
+
})
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
expect(refreshAuth).toHaveBeenCalledTimes(3)
|
|
210
|
+
expect(instance.connection.connect).toHaveBeenCalledTimes(3)
|
|
211
|
+
expect(instance.connection.state.current.name).toBe('needs-auth')
|
|
212
|
+
})
|
|
213
|
+
|
|
165
214
|
test('a disabled logout cannot revive its closed authenticated instance', async () => {
|
|
166
215
|
const first = await mount({ auth: 'old-token' }, 'conn-auth-cycle')
|
|
167
216
|
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { createSchema, string, table } from '@rocicorp/zero'
|
|
2
|
+
import { createZeroClientTransport } from 'orez-lite/client'
|
|
3
|
+
import { expect, test, vi } from 'vitest'
|
|
4
|
+
|
|
5
|
+
import { createZeroClient } from './createZeroClient'
|
|
6
|
+
|
|
7
|
+
const noteTable = table('note').columns({ id: string() }).primaryKey('id')
|
|
8
|
+
const schema = createSchema({ tables: [noteTable] })
|
|
9
|
+
|
|
10
|
+
function response(body: unknown, status = 200) {
|
|
11
|
+
return new Response(JSON.stringify(body), {
|
|
12
|
+
status,
|
|
13
|
+
headers: { 'content-type': 'application/json' },
|
|
14
|
+
})
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
async function eventually(assertion: () => void, timeoutMs = 2_000) {
|
|
18
|
+
const deadline = Date.now() + timeoutMs
|
|
19
|
+
let lastError: unknown
|
|
20
|
+
while (Date.now() < deadline) {
|
|
21
|
+
try {
|
|
22
|
+
assertion()
|
|
23
|
+
return
|
|
24
|
+
} catch (error) {
|
|
25
|
+
lastError = error
|
|
26
|
+
await new Promise((resolve) => setTimeout(resolve, 5))
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
throw lastError
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
test('unchanged unauthorized auth parks after one real HTTP transport request', async () => {
|
|
33
|
+
const authorizations: Array<string | null> = []
|
|
34
|
+
const fetch = vi.fn(async (_input: RequestInfo | URL, init?: RequestInit) => {
|
|
35
|
+
authorizations.push(new Headers(init?.headers).get('authorization'))
|
|
36
|
+
return response({ error: 'missing authentication' }, 401)
|
|
37
|
+
})
|
|
38
|
+
const refreshAuth = vi.fn(async () => 'expired-token')
|
|
39
|
+
const client = createZeroClient({
|
|
40
|
+
schema,
|
|
41
|
+
models: {},
|
|
42
|
+
groupedQueries: {},
|
|
43
|
+
instanceName: 'http-auth-unchanged',
|
|
44
|
+
})
|
|
45
|
+
const connection = client.connectHeadless({
|
|
46
|
+
userID: 'unauthorized-user',
|
|
47
|
+
auth: 'expired-token',
|
|
48
|
+
cacheURL: 'https://http-auth-unchanged.orez.test/zero',
|
|
49
|
+
kvStore: 'mem',
|
|
50
|
+
transport: createZeroClientTransport({ fetch }),
|
|
51
|
+
refreshAuth,
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
try {
|
|
55
|
+
await eventually(() =>
|
|
56
|
+
expect(connection.zero.connection.state.current.name).toBe('needs-auth')
|
|
57
|
+
)
|
|
58
|
+
await new Promise((resolve) => setTimeout(resolve, 100))
|
|
59
|
+
|
|
60
|
+
expect(authorizations).toEqual(['Bearer expired-token'])
|
|
61
|
+
expect(refreshAuth).toHaveBeenCalledTimes(1)
|
|
62
|
+
expect(connection.zero.connection.state.current.name).toBe('needs-auth')
|
|
63
|
+
} finally {
|
|
64
|
+
await connection.close()
|
|
65
|
+
}
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
test('warm headless client refreshes an expired bearer and reconnects', async () => {
|
|
69
|
+
const authorizations: Array<string | null> = []
|
|
70
|
+
const fetch = vi.fn(async (_input: RequestInfo | URL, init?: RequestInit) => {
|
|
71
|
+
const authorization = new Headers(init?.headers).get('authorization')
|
|
72
|
+
authorizations.push(authorization)
|
|
73
|
+
if (authorization === 'Bearer expired-token') {
|
|
74
|
+
return response({ error: 'expired bearer' }, 401)
|
|
75
|
+
}
|
|
76
|
+
return response({ cookie: 1, lastMutationIDChanges: {}, rowsPatch: [] })
|
|
77
|
+
})
|
|
78
|
+
const refreshAuth = vi.fn(async () => 'fresh-token')
|
|
79
|
+
const client = createZeroClient({
|
|
80
|
+
schema,
|
|
81
|
+
models: {},
|
|
82
|
+
groupedQueries: {},
|
|
83
|
+
instanceName: 'http-auth-refresh',
|
|
84
|
+
})
|
|
85
|
+
const connection = client.connectHeadless({
|
|
86
|
+
userID: 'authorized-user',
|
|
87
|
+
auth: 'expired-token',
|
|
88
|
+
cacheURL: 'https://http-auth-refresh.orez.test/zero',
|
|
89
|
+
kvStore: 'mem',
|
|
90
|
+
transport: createZeroClientTransport({ fetch }),
|
|
91
|
+
refreshAuth,
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
try {
|
|
95
|
+
await eventually(() =>
|
|
96
|
+
expect(connection.zero.connection.state.current.name).toBe('connected')
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
expect(refreshAuth).toHaveBeenCalledTimes(1)
|
|
100
|
+
expect(authorizations).toEqual(['Bearer expired-token', 'Bearer fresh-token'])
|
|
101
|
+
} finally {
|
|
102
|
+
await connection.close()
|
|
103
|
+
}
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
test('three rejected replacement bearers leave a real HTTP client parked', async () => {
|
|
107
|
+
const authorizations: Array<string | null> = []
|
|
108
|
+
let replacement = 0
|
|
109
|
+
const fetch = vi.fn(async (_input: RequestInfo | URL, init?: RequestInit) => {
|
|
110
|
+
authorizations.push(new Headers(init?.headers).get('authorization'))
|
|
111
|
+
return response({ error: 'project access required' }, 403)
|
|
112
|
+
})
|
|
113
|
+
const refreshAuth = vi.fn(async () => `replacement-token-${++replacement}`)
|
|
114
|
+
const client = createZeroClient({
|
|
115
|
+
schema,
|
|
116
|
+
models: {},
|
|
117
|
+
groupedQueries: {},
|
|
118
|
+
instanceName: 'http-auth-bounded',
|
|
119
|
+
})
|
|
120
|
+
const connection = client.connectHeadless({
|
|
121
|
+
userID: 'unauthorized-user',
|
|
122
|
+
auth: 'expired-token',
|
|
123
|
+
cacheURL: 'https://http-auth-bounded.orez.test/zero',
|
|
124
|
+
kvStore: 'mem',
|
|
125
|
+
transport: createZeroClientTransport({ fetch }),
|
|
126
|
+
refreshAuth,
|
|
127
|
+
})
|
|
128
|
+
|
|
129
|
+
try {
|
|
130
|
+
await eventually(() => expect(authorizations).toHaveLength(4))
|
|
131
|
+
await new Promise((resolve) => setTimeout(resolve, 100))
|
|
132
|
+
|
|
133
|
+
expect(authorizations).toEqual([
|
|
134
|
+
'Bearer expired-token',
|
|
135
|
+
'Bearer replacement-token-1',
|
|
136
|
+
'Bearer replacement-token-2',
|
|
137
|
+
'Bearer replacement-token-3',
|
|
138
|
+
])
|
|
139
|
+
expect(refreshAuth).toHaveBeenCalledTimes(3)
|
|
140
|
+
expect(connection.zero.connection.state.current.name).toBe('needs-auth')
|
|
141
|
+
} finally {
|
|
142
|
+
await connection.close()
|
|
143
|
+
}
|
|
144
|
+
})
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// @vitest-environment jsdom
|
|
2
2
|
|
|
3
3
|
import { createSchema, string, table } from '@rocicorp/zero'
|
|
4
|
-
import { act, useLayoutEffect } from 'react'
|
|
4
|
+
import { act, Suspense, useLayoutEffect } from 'react'
|
|
5
5
|
import { createRoot, type Root } from 'react-dom/client'
|
|
6
6
|
import { afterEach, beforeEach, expect, test, vi } from 'vitest'
|
|
7
7
|
|
|
@@ -188,6 +188,66 @@ test('provider generation changes with the actual instance during remint', async
|
|
|
188
188
|
expect(generations[1]?.isCurrent()).toBe(false)
|
|
189
189
|
})
|
|
190
190
|
|
|
191
|
+
test('suspense hiding keeps the mounted provider generation writable', async () => {
|
|
192
|
+
const isolated = createZeroClient({
|
|
193
|
+
schema,
|
|
194
|
+
models: {},
|
|
195
|
+
groupedQueries: {},
|
|
196
|
+
instanceName: 'suspense-hidden-provider-test',
|
|
197
|
+
})
|
|
198
|
+
let hidden = false
|
|
199
|
+
const hiddenUntil = new Promise<void>(() => {})
|
|
200
|
+
|
|
201
|
+
function MaybeHidden() {
|
|
202
|
+
if (hidden) throw hiddenUntil
|
|
203
|
+
return <span>ready</span>
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
function App() {
|
|
207
|
+
return (
|
|
208
|
+
<Suspense fallback={<span>loading</span>}>
|
|
209
|
+
<isolated.ProvideZero
|
|
210
|
+
cacheURL="http://127.0.0.1:7777/zero"
|
|
211
|
+
userID="suspense-hidden"
|
|
212
|
+
>
|
|
213
|
+
<MaybeHidden />
|
|
214
|
+
</isolated.ProvideZero>
|
|
215
|
+
</Suspense>
|
|
216
|
+
)
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
root = createRoot(container)
|
|
220
|
+
await act(async () => {
|
|
221
|
+
root?.render(<App />)
|
|
222
|
+
await Promise.resolve()
|
|
223
|
+
})
|
|
224
|
+
|
|
225
|
+
let settleServer: (value: string) => void = () => {}
|
|
226
|
+
const server = new Promise<string>((resolve) => {
|
|
227
|
+
settleServer = resolve
|
|
228
|
+
})
|
|
229
|
+
let settled = false
|
|
230
|
+
const acknowledgement = isolated
|
|
231
|
+
.awaitMutationServer(
|
|
232
|
+
{ client: Promise.resolve('client'), server },
|
|
233
|
+
'hidden provider mutation'
|
|
234
|
+
)
|
|
235
|
+
.finally(() => {
|
|
236
|
+
settled = true
|
|
237
|
+
})
|
|
238
|
+
|
|
239
|
+
hidden = true
|
|
240
|
+
await act(async () => {
|
|
241
|
+
root?.render(<App />)
|
|
242
|
+
await Promise.resolve()
|
|
243
|
+
})
|
|
244
|
+
|
|
245
|
+
expect(container.textContent).toContain('loading')
|
|
246
|
+
expect(settled).toBe(false)
|
|
247
|
+
settleServer('server')
|
|
248
|
+
await expect(acknowledgement).resolves.toBe('server')
|
|
249
|
+
})
|
|
250
|
+
|
|
191
251
|
test('remint with no provider mounted returns false without burning the guard budget', async () => {
|
|
192
252
|
// own client so the shared remint guard state is fresh for this assertion.
|
|
193
253
|
const isolated = createZeroClient({
|
package/src/createZeroClient.tsx
CHANGED
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
memo,
|
|
16
16
|
useContext,
|
|
17
17
|
useEffect,
|
|
18
|
+
useInsertionEffect,
|
|
18
19
|
useLayoutEffect,
|
|
19
20
|
useMemo,
|
|
20
21
|
useRef,
|
|
@@ -73,9 +74,12 @@ import type {
|
|
|
73
74
|
Schema as ZeroSchema,
|
|
74
75
|
} from '@rocicorp/zero'
|
|
75
76
|
import type { AggregateSet } from 'orez-lite/aggregate'
|
|
77
|
+
import type { HttpPullLifecycleEvent, HttpPullTransport } from 'orez-lite/client'
|
|
76
78
|
|
|
77
79
|
type PreloadOptions = { ttl?: 'always' | 'never' | number | undefined }
|
|
78
80
|
|
|
81
|
+
const MAX_AUTH_REFRESH_ATTEMPTS = 3
|
|
82
|
+
|
|
79
83
|
export type GroupedQueries = Record<string, Record<string, (...args: any[]) => any>>
|
|
80
84
|
|
|
81
85
|
// controls how usePermission behaves before the server responds:
|
|
@@ -85,7 +89,7 @@ export type GroupedQueries = Record<string, Record<string, (...args: any[]) => a
|
|
|
85
89
|
export type PermissionStrategy = 'optimistic' | 'optimistic-deny' | 'optimistic-allow'
|
|
86
90
|
|
|
87
91
|
export type ZeroProviderTransport = {
|
|
88
|
-
install(serverURL: string):
|
|
92
|
+
install(serverURL: string): Pick<HttpPullTransport, 'subscribeLifecycle'> | undefined
|
|
89
93
|
logClassifications?: {
|
|
90
94
|
benign?: readonly ZeroLogPattern[]
|
|
91
95
|
}
|
|
@@ -324,6 +328,10 @@ export function createZeroClientInternal<
|
|
|
324
328
|
// connectHeadless construct identical instances without either one forcing
|
|
325
329
|
// the work at createZeroClient() time.
|
|
326
330
|
let clientMutators: ReturnType<typeof createMutators> | null = null
|
|
331
|
+
const installedTransports = new WeakMap<
|
|
332
|
+
ZeroInstance,
|
|
333
|
+
Pick<HttpPullTransport, 'subscribeLifecycle'>
|
|
334
|
+
>()
|
|
327
335
|
function getClientMutators() {
|
|
328
336
|
clientMutators ??= createMutators({
|
|
329
337
|
models,
|
|
@@ -356,6 +364,7 @@ export function createZeroClientInternal<
|
|
|
356
364
|
guardStorage,
|
|
357
365
|
benignLogPatterns,
|
|
358
366
|
}: ConstructZeroInstanceArgs): ZeroInstance {
|
|
367
|
+
let installedTransport: Pick<HttpPullTransport, 'subscribeLifecycle'> | undefined
|
|
359
368
|
// install before construction so the instance's first connect goes through
|
|
360
369
|
// HTTP. ensureHttpPullTransport is per-origin idempotent by design (a
|
|
361
370
|
// rotation would otherwise chain shims), so repeat calls reuse.
|
|
@@ -366,7 +375,7 @@ export function createZeroClientInternal<
|
|
|
366
375
|
if (typeof serverURL !== 'string') {
|
|
367
376
|
throw new Error(`client transport requires a server URL`)
|
|
368
377
|
}
|
|
369
|
-
transport.install(serverURL)
|
|
378
|
+
installedTransport = transport.install(serverURL)
|
|
370
379
|
}
|
|
371
380
|
// recovery closures reach the instance through this ref so they always
|
|
372
381
|
// delete the CURRENT instance's own store (set right after construction;
|
|
@@ -406,6 +415,7 @@ export function createZeroClientInternal<
|
|
|
406
415
|
options.onClientStateNotFound ?? recovery.onClientStateNotFound,
|
|
407
416
|
})
|
|
408
417
|
instanceRef.current = createdInstance
|
|
418
|
+
if (installedTransport) installedTransports.set(createdInstance, installedTransport)
|
|
409
419
|
return createdInstance
|
|
410
420
|
}
|
|
411
421
|
|
|
@@ -1123,6 +1133,7 @@ export function createZeroClientInternal<
|
|
|
1123
1133
|
{liveInstance ? (
|
|
1124
1134
|
<ConnectionMonitor
|
|
1125
1135
|
zeroEvents={zeroEvents}
|
|
1136
|
+
auth={auth}
|
|
1126
1137
|
refreshAuth={refreshAuth}
|
|
1127
1138
|
exposeDataset={connectionDataset}
|
|
1128
1139
|
datasetCacheUrl={
|
|
@@ -1149,10 +1160,11 @@ export function createZeroClientInternal<
|
|
|
1149
1160
|
// publish before descendant effects perform imperative work.
|
|
1150
1161
|
publishZeroInstance(zeroInstance)
|
|
1151
1162
|
|
|
1152
|
-
|
|
1153
|
-
//
|
|
1154
|
-
//
|
|
1155
|
-
//
|
|
1163
|
+
useInsertionEffect(() => {
|
|
1164
|
+
// suspense disconnects layout and passive effects while hiding an
|
|
1165
|
+
// already-mounted tree. insertion effects stay attached until the
|
|
1166
|
+
// provider actually unmounts, which is the lifecycle boundary that
|
|
1167
|
+
// invalidates this generation.
|
|
1156
1168
|
publishZeroInstance(zeroInstance)
|
|
1157
1169
|
return () => {
|
|
1158
1170
|
if (!unpublishZeroInstance(zeroInstance)) return
|
|
@@ -1213,7 +1225,11 @@ export function createZeroClientInternal<
|
|
|
1213
1225
|
})
|
|
1214
1226
|
publishZeroInstance(zeroInstance)
|
|
1215
1227
|
zeroInstanceVersion?.emit(zeroInstanceVersion.value + 1)
|
|
1216
|
-
const unwatch = watchZeroConnection({
|
|
1228
|
+
const unwatch = watchZeroConnection({
|
|
1229
|
+
zeroInstance,
|
|
1230
|
+
auth: options.auth,
|
|
1231
|
+
refreshAuth,
|
|
1232
|
+
})
|
|
1217
1233
|
return {
|
|
1218
1234
|
zero: zeroInstance,
|
|
1219
1235
|
close: async () => {
|
|
@@ -1232,13 +1248,16 @@ export function createZeroClientInternal<
|
|
|
1232
1248
|
// ended as a permanent 401 with no way back.
|
|
1233
1249
|
function watchZeroConnection(args: {
|
|
1234
1250
|
zeroInstance: ZeroInstance
|
|
1251
|
+
auth?: string | null
|
|
1235
1252
|
refreshAuth?: () => Promise<string | undefined>
|
|
1236
1253
|
exposeDataset?: boolean
|
|
1237
1254
|
datasetCacheUrl?: string
|
|
1238
1255
|
}): () => void {
|
|
1239
|
-
const { zeroInstance, refreshAuth, exposeDataset, datasetCacheUrl } = args
|
|
1256
|
+
const { zeroInstance, auth, refreshAuth, exposeDataset, datasetCacheUrl } = args
|
|
1240
1257
|
let prevState = zeroInstance.connection.state.current.name
|
|
1241
1258
|
let hasConnected = false
|
|
1259
|
+
let active = true
|
|
1260
|
+
let activeAuth = auth
|
|
1242
1261
|
const currentReconnect =
|
|
1243
1262
|
zeroEvents.value?.type === 'reconnect' && zeroEvents.value.status !== 'connected'
|
|
1244
1263
|
? zeroEvents.value
|
|
@@ -1251,6 +1270,15 @@ export function createZeroClientInternal<
|
|
|
1251
1270
|
// transition, so a stuck state doesn't retry-storm.
|
|
1252
1271
|
let recoverableError: string | null = null
|
|
1253
1272
|
let needsAuth = false
|
|
1273
|
+
let authRefreshAttempts = 0
|
|
1274
|
+
const installedTransport = installedTransports.get(zeroInstance)
|
|
1275
|
+
const unsubscribeTransport = installedTransport
|
|
1276
|
+
? installedTransport.subscribeLifecycle((event: HttpPullLifecycleEvent) => {
|
|
1277
|
+
if (event.type === 'pull' && event.clientID === zeroInstance.clientID) {
|
|
1278
|
+
authRefreshAttempts = 0
|
|
1279
|
+
}
|
|
1280
|
+
})
|
|
1281
|
+
: undefined
|
|
1254
1282
|
|
|
1255
1283
|
const handle = () => {
|
|
1256
1284
|
const state = zeroInstance.connection.state.current
|
|
@@ -1272,6 +1300,7 @@ export function createZeroClientInternal<
|
|
|
1272
1300
|
if (name === 'connected') {
|
|
1273
1301
|
hasConnected = true
|
|
1274
1302
|
recoverableError = null
|
|
1303
|
+
if (!installedTransport) authRefreshAttempts = 0
|
|
1275
1304
|
if (reconnect) {
|
|
1276
1305
|
reconnect = null
|
|
1277
1306
|
emitReconnectStatus({ type: 'reconnect', status: 'connected' })
|
|
@@ -1324,14 +1353,22 @@ export function createZeroClientInternal<
|
|
|
1324
1353
|
emitReconnectStatus({ type: 'reconnect', status: 'waiting', ...reconnect })
|
|
1325
1354
|
}
|
|
1326
1355
|
|
|
1327
|
-
// needs-auth:
|
|
1328
|
-
//
|
|
1356
|
+
// needs-auth: zero is already parked, so resume only for a changed token.
|
|
1357
|
+
// repeated distinct rejected tokens get a finite budget; a successful
|
|
1358
|
+
// pull proves the replacement and resets it.
|
|
1329
1359
|
if (name === 'needs-auth') {
|
|
1330
|
-
if (
|
|
1360
|
+
if (
|
|
1361
|
+
refreshAuth &&
|
|
1362
|
+
!needsAuth &&
|
|
1363
|
+
authRefreshAttempts < MAX_AUTH_REFRESH_ATTEMPTS
|
|
1364
|
+
) {
|
|
1331
1365
|
needsAuth = true
|
|
1332
1366
|
void refreshAuth()
|
|
1333
1367
|
.then((token) => {
|
|
1334
|
-
if (token
|
|
1368
|
+
if (!active || !token || token === activeAuth) return
|
|
1369
|
+
activeAuth = token
|
|
1370
|
+
authRefreshAttempts++
|
|
1371
|
+
return zeroInstance.connection?.connect?.({ auth: token })
|
|
1335
1372
|
})
|
|
1336
1373
|
.catch(() => {})
|
|
1337
1374
|
}
|
|
@@ -1354,7 +1391,11 @@ export function createZeroClientInternal<
|
|
|
1354
1391
|
|
|
1355
1392
|
const unsubscribe = zeroInstance.connection.state.subscribe(handle)
|
|
1356
1393
|
handle()
|
|
1357
|
-
return
|
|
1394
|
+
return () => {
|
|
1395
|
+
active = false
|
|
1396
|
+
unsubscribeTransport?.()
|
|
1397
|
+
unsubscribe()
|
|
1398
|
+
}
|
|
1358
1399
|
}
|
|
1359
1400
|
|
|
1360
1401
|
// monitors connection state and emits events (replaces onError callback removed
|
|
@@ -1364,11 +1405,13 @@ export function createZeroClientInternal<
|
|
|
1364
1405
|
const ConnectionMonitor = memo(
|
|
1365
1406
|
({
|
|
1366
1407
|
zeroEvents: _zeroEvents,
|
|
1408
|
+
auth,
|
|
1367
1409
|
refreshAuth,
|
|
1368
1410
|
exposeDataset,
|
|
1369
1411
|
datasetCacheUrl,
|
|
1370
1412
|
}: {
|
|
1371
1413
|
zeroEvents: ZeroEventsEmitter
|
|
1414
|
+
auth?: string | null
|
|
1372
1415
|
refreshAuth?: () => Promise<string | undefined>
|
|
1373
1416
|
exposeDataset?: boolean
|
|
1374
1417
|
datasetCacheUrl?: string
|
|
@@ -1381,11 +1424,12 @@ export function createZeroClientInternal<
|
|
|
1381
1424
|
() =>
|
|
1382
1425
|
watchZeroConnection({
|
|
1383
1426
|
zeroInstance,
|
|
1427
|
+
auth,
|
|
1384
1428
|
refreshAuth,
|
|
1385
1429
|
exposeDataset,
|
|
1386
1430
|
datasetCacheUrl,
|
|
1387
1431
|
}),
|
|
1388
|
-
[zeroInstance, refreshAuth, exposeDataset, datasetCacheUrl]
|
|
1432
|
+
[zeroInstance, auth, refreshAuth, exposeDataset, datasetCacheUrl]
|
|
1389
1433
|
)
|
|
1390
1434
|
return null
|
|
1391
1435
|
}
|
|
@@ -7,13 +7,14 @@ import { resolveQuery, type PlainQueryFn } from './resolveQuery';
|
|
|
7
7
|
import type { AuthData, GenericModels, GetZeroMutators, ZeroEventsEmitter } from './types';
|
|
8
8
|
import type { AnyQueryRegistry, Query, Row, ZeroOptions, Schema as ZeroSchema } from '@rocicorp/zero';
|
|
9
9
|
import type { AggregateSet } from 'orez-lite/aggregate';
|
|
10
|
+
import type { HttpPullTransport } from 'orez-lite/client';
|
|
10
11
|
type PreloadOptions = {
|
|
11
12
|
ttl?: 'always' | 'never' | number | undefined;
|
|
12
13
|
};
|
|
13
14
|
export type GroupedQueries = Record<string, Record<string, (...args: any[]) => any>>;
|
|
14
15
|
export type PermissionStrategy = 'optimistic' | 'optimistic-deny' | 'optimistic-allow';
|
|
15
16
|
export type ZeroProviderTransport = {
|
|
16
|
-
install(serverURL: string):
|
|
17
|
+
install(serverURL: string): Pick<HttpPullTransport, 'subscribeLifecycle'> | undefined;
|
|
17
18
|
logClassifications?: {
|
|
18
19
|
benign?: readonly ZeroLogPattern[];
|
|
19
20
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createZeroClient.d.ts","sourceRoot":"","sources":["../src/createZeroClient.tsx"],"names":[],"mappings":"AAAA,OAAO,EAIL,IAAI,IAAI,UAAU,EACnB,MAAM,gBAAgB,CAAA;AAOvB,OAAO,
|
|
1
|
+
{"version":3,"file":"createZeroClient.d.ts","sourceRoot":"","sources":["../src/createZeroClient.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createZeroClient.httpAuth.test.d.ts","sourceRoot":"","sources":["../src/createZeroClient.httpAuth.test.ts"],"names":[],"mappings":""}
|