on-zero 0.6.18 → 0.6.19
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/asyncTasks.native.js.map +1 -1
- package/dist/cjs/createZeroClient.cjs +1 -28
- package/dist/cjs/createZeroClient.connection.test.cjs +11 -40
- package/dist/cjs/createZeroClient.connection.test.native.js +11 -40
- package/dist/cjs/createZeroClient.connection.test.native.js.map +1 -1
- package/dist/cjs/createZeroClient.native.js +1 -29
- package/dist/cjs/createZeroClient.native.js.map +1 -1
- package/dist/cjs/createZeroDirectServer.cjs +1 -1
- package/dist/cjs/createZeroDirectServer.native.js +1 -1
- package/dist/cjs/createZeroDirectServer.native.js.map +1 -1
- package/dist/cjs/createZeroServer.test.cjs +6 -0
- package/dist/cjs/createZeroServer.test.native.js +6 -0
- package/dist/cjs/createZeroServer.test.native.js.map +1 -1
- package/dist/cjs/createZeroServerCore.cjs +29 -1
- package/dist/cjs/createZeroServerCore.native.js +153 -1
- package/dist/cjs/createZeroServerCore.native.js.map +1 -1
- package/dist/cjs/httpPull/transport.test.cjs +127 -15
- package/dist/cjs/httpPull/transport.test.native.js +161 -16
- package/dist/cjs/httpPull/transport.test.native.js.map +1 -1
- package/dist/cjs/httpPullTransport.cjs +48 -18
- package/dist/cjs/httpPullTransport.native.js +57 -20
- package/dist/cjs/httpPullTransport.native.js.map +1 -1
- package/dist/cjs/modelRegistry.cjs +7 -4
- package/dist/cjs/modelRegistry.native.js +8 -4
- package/dist/cjs/modelRegistry.native.js.map +1 -1
- package/dist/cjs/mutations.cjs +15 -11
- package/dist/cjs/mutations.native.js +17 -11
- package/dist/cjs/mutations.native.js.map +1 -1
- package/dist/cjs/state.cjs +2 -3
- package/dist/cjs/state.native.js +2 -3
- package/dist/cjs/state.native.js.map +1 -1
- package/dist/cjs/syncHost.cjs +2 -1
- package/dist/cjs/syncHost.native.js +2 -1
- package/dist/cjs/syncHost.native.js.map +1 -1
- package/dist/cjs/usePermission.test.cjs +4 -2
- package/dist/cjs/usePermission.test.native.js +4 -2
- package/dist/cjs/usePermission.test.native.js.map +1 -1
- package/dist/esm/asyncTasks.mjs.map +1 -1
- package/dist/esm/asyncTasks.native.js.map +1 -1
- package/dist/esm/createZeroClient.connection.test.mjs +11 -40
- package/dist/esm/createZeroClient.connection.test.mjs.map +1 -1
- package/dist/esm/createZeroClient.connection.test.native.js +11 -40
- package/dist/esm/createZeroClient.connection.test.native.js.map +1 -1
- package/dist/esm/createZeroClient.mjs +2 -29
- package/dist/esm/createZeroClient.mjs.map +1 -1
- package/dist/esm/createZeroClient.native.js +2 -30
- package/dist/esm/createZeroClient.native.js.map +1 -1
- package/dist/esm/createZeroDirectServer.mjs +2 -2
- package/dist/esm/createZeroDirectServer.mjs.map +1 -1
- package/dist/esm/createZeroDirectServer.native.js +2 -2
- package/dist/esm/createZeroDirectServer.native.js.map +1 -1
- package/dist/esm/createZeroServer.test.mjs +6 -0
- package/dist/esm/createZeroServer.test.mjs.map +1 -1
- package/dist/esm/createZeroServer.test.native.js +6 -0
- package/dist/esm/createZeroServer.test.native.js.map +1 -1
- package/dist/esm/createZeroServerCore.mjs +29 -1
- package/dist/esm/createZeroServerCore.mjs.map +1 -1
- package/dist/esm/createZeroServerCore.native.js +153 -1
- package/dist/esm/createZeroServerCore.native.js.map +1 -1
- package/dist/esm/httpPull/transport.test.mjs +127 -15
- package/dist/esm/httpPull/transport.test.mjs.map +1 -1
- package/dist/esm/httpPull/transport.test.native.js +161 -16
- package/dist/esm/httpPull/transport.test.native.js.map +1 -1
- package/dist/esm/httpPullTransport.mjs +48 -18
- package/dist/esm/httpPullTransport.mjs.map +1 -1
- package/dist/esm/httpPullTransport.native.js +57 -20
- package/dist/esm/httpPullTransport.native.js.map +1 -1
- package/dist/esm/modelRegistry.mjs +7 -4
- package/dist/esm/modelRegistry.mjs.map +1 -1
- package/dist/esm/modelRegistry.native.js +8 -4
- package/dist/esm/modelRegistry.native.js.map +1 -1
- package/dist/esm/mutations.mjs +15 -11
- package/dist/esm/mutations.mjs.map +1 -1
- package/dist/esm/mutations.native.js +17 -11
- package/dist/esm/mutations.native.js.map +1 -1
- package/dist/esm/state.mjs +2 -3
- package/dist/esm/state.mjs.map +1 -1
- package/dist/esm/state.native.js +2 -3
- package/dist/esm/state.native.js.map +1 -1
- package/dist/esm/syncHost.mjs +2 -1
- package/dist/esm/syncHost.mjs.map +1 -1
- package/dist/esm/syncHost.native.js +2 -1
- package/dist/esm/syncHost.native.js.map +1 -1
- package/dist/esm/usePermission.test.mjs +6 -4
- package/dist/esm/usePermission.test.mjs.map +1 -1
- package/dist/esm/usePermission.test.native.js +6 -4
- package/dist/esm/usePermission.test.native.js.map +1 -1
- package/package.json +2 -2
- package/src/asyncTasks.ts +4 -1
- package/src/createZeroClient.connection.test.tsx +11 -35
- package/src/createZeroClient.tsx +7 -40
- package/src/createZeroDirectServer.ts +2 -2
- package/src/createZeroServer.test.ts +10 -0
- package/src/createZeroServerCore.ts +38 -1
- package/src/httpPull/transport.test.ts +143 -16
- package/src/httpPullTransport.ts +67 -30
- package/src/modelRegistry.ts +9 -4
- package/src/mutations.ts +19 -15
- package/src/state.ts +3 -3
- package/src/syncHost.ts +2 -2
- package/src/usePermission.test.ts +9 -3
- package/test-fixtures/server-return-types.ts +13 -1
- package/types/asyncTasks.d.ts +5 -1
- package/types/asyncTasks.d.ts.map +1 -1
- package/types/createZeroClient.d.ts.map +1 -1
- package/types/createZeroServerCore.d.ts.map +1 -1
- package/types/httpPullTransport.d.ts +13 -0
- package/types/httpPullTransport.d.ts.map +1 -1
- package/types/modelRegistry.d.ts.map +1 -1
- package/types/mutations.d.ts.map +1 -1
- package/types/state.d.ts +2 -2
- package/types/state.d.ts.map +1 -1
- package/types/syncHost.d.ts +1 -1
- package/types/syncHost.d.ts.map +1 -1
|
@@ -2,7 +2,11 @@ import { Zero } from '@rocicorp/zero'
|
|
|
2
2
|
import { afterEach, describe, expect, test, vi } from 'vitest'
|
|
3
3
|
|
|
4
4
|
import { zeroHttpFixtureMutators, zeroHttpFixtureSchema } from './fixtureSchema'
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
ensureHttpPullTransport,
|
|
7
|
+
installHttpPullTransport,
|
|
8
|
+
type HttpPullLifecycleEvent,
|
|
9
|
+
} from '../httpPullTransport'
|
|
6
10
|
|
|
7
11
|
const ORIGIN = 'https://zero-http.local'
|
|
8
12
|
|
|
@@ -429,23 +433,133 @@ describe('zero-http transport', () => {
|
|
|
429
433
|
view.destroy()
|
|
430
434
|
})
|
|
431
435
|
|
|
432
|
-
test('
|
|
433
|
-
const
|
|
436
|
+
test('pull and push 500 reconnects keep socket opens on their current Zero attempt', async () => {
|
|
437
|
+
const lifecycle: HttpPullLifecycleEvent[] = []
|
|
438
|
+
const zeroLogs: Array<{ context: Record<string, unknown>; args: unknown[] }> = []
|
|
439
|
+
let failPull = false
|
|
440
|
+
let failPush = false
|
|
434
441
|
const fetch = vi.fn(async (input: RequestInfo | URL, init?: RequestInit) => {
|
|
435
442
|
const request = recordRequest(input, init)
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
443
|
+
if (request.path === '/pull') {
|
|
444
|
+
if (failPull) {
|
|
445
|
+
failPull = false
|
|
446
|
+
return jsonResponse({ error: 'injected pull outage' }, { status: 500 })
|
|
447
|
+
}
|
|
448
|
+
return jsonResponse({ cookie: request.body.cookie, unchanged: true })
|
|
449
|
+
}
|
|
450
|
+
if (failPush) {
|
|
451
|
+
failPush = false
|
|
452
|
+
return jsonResponse({ error: 'injected push outage' }, { status: 500 })
|
|
453
|
+
}
|
|
454
|
+
const mutation = request.body.mutations[0]
|
|
455
|
+
return jsonResponse({
|
|
456
|
+
pushResponse: {
|
|
457
|
+
mutations: [
|
|
458
|
+
{
|
|
459
|
+
id: { clientID: mutation.clientID, id: mutation.id },
|
|
460
|
+
result: {},
|
|
461
|
+
},
|
|
462
|
+
],
|
|
463
|
+
},
|
|
464
|
+
})
|
|
465
|
+
})
|
|
466
|
+
const transport = installHttpPullTransport({
|
|
467
|
+
origin: ORIGIN,
|
|
468
|
+
fetch,
|
|
469
|
+
lifecycle: (event) => lifecycle.push(event),
|
|
470
|
+
})
|
|
471
|
+
transports.push(transport)
|
|
472
|
+
const zero = createZero({
|
|
473
|
+
logSink: {
|
|
474
|
+
log: (_level, context, ...args) => {
|
|
475
|
+
zeroLogs.push({ context: context ?? {}, args })
|
|
476
|
+
},
|
|
477
|
+
},
|
|
439
478
|
})
|
|
440
|
-
install(fetch)
|
|
441
|
-
createZero()
|
|
442
479
|
|
|
443
|
-
await eventually(() => expect(
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
await eventually(
|
|
447
|
-
|
|
448
|
-
|
|
480
|
+
await eventually(() => expect(zero.connection.state.current.name).toBe('connected'))
|
|
481
|
+
failPull = true
|
|
482
|
+
await transport.pull().catch(() => {})
|
|
483
|
+
await eventually(
|
|
484
|
+
() => expect(lifecycle.filter((event) => event.type === 'open')).toHaveLength(2),
|
|
485
|
+
5_000,
|
|
486
|
+
)
|
|
487
|
+
|
|
488
|
+
failPush = true
|
|
489
|
+
const mutation = zero.mutate.project.create({
|
|
490
|
+
id: 'p1',
|
|
491
|
+
ownerId: 'u1',
|
|
492
|
+
name: 'after reconnect',
|
|
493
|
+
})
|
|
494
|
+
await mutation.client
|
|
495
|
+
await mutation.server.catch(() => {})
|
|
496
|
+
await eventually(
|
|
497
|
+
() => expect(lifecycle.filter((event) => event.type === 'open')).toHaveLength(3),
|
|
498
|
+
5_000,
|
|
499
|
+
)
|
|
500
|
+
await eventually(
|
|
501
|
+
() => expect(zero.connection.state.current.name).toBe('connected'),
|
|
502
|
+
5_000,
|
|
503
|
+
)
|
|
504
|
+
|
|
505
|
+
const opens = lifecycle.filter((event) => event.type === 'open')
|
|
506
|
+
expect(
|
|
507
|
+
opens.map(({ generation, activeGeneration }) => [generation, activeGeneration]),
|
|
508
|
+
).toEqual([
|
|
509
|
+
[1, 1],
|
|
510
|
+
[2, 2],
|
|
511
|
+
[3, 3],
|
|
512
|
+
])
|
|
513
|
+
expect(
|
|
514
|
+
zeroLogs.some(({ args }) =>
|
|
515
|
+
args.some((arg) => String(arg).includes('connect start time is undefined')),
|
|
516
|
+
),
|
|
517
|
+
).toBe(false)
|
|
518
|
+
})
|
|
519
|
+
|
|
520
|
+
test('a replacement socket supersedes stale open and connected events for the same client', async () => {
|
|
521
|
+
vi.useFakeTimers()
|
|
522
|
+
const lifecycle: HttpPullLifecycleEvent[] = []
|
|
523
|
+
const transport = installHttpPullTransport({
|
|
524
|
+
origin: ORIGIN,
|
|
525
|
+
fetch: vi.fn(async () => jsonResponse({ cookie: null, unchanged: true })),
|
|
526
|
+
lifecycle: (event) => lifecycle.push(event),
|
|
527
|
+
})
|
|
528
|
+
transports.push(transport)
|
|
529
|
+
|
|
530
|
+
let connectStart: number | undefined = Date.now()
|
|
531
|
+
const errors: string[] = []
|
|
532
|
+
const attachStockLifecycle = (socket: WebSocket) => {
|
|
533
|
+
socket.addEventListener('open', () => {
|
|
534
|
+
if (connectStart === undefined) {
|
|
535
|
+
errors.push('Got open event but connect start time is undefined.')
|
|
536
|
+
}
|
|
537
|
+
})
|
|
538
|
+
socket.addEventListener('message', (event) => {
|
|
539
|
+
const message = JSON.parse(String(event.data)) as [string, unknown]
|
|
540
|
+
if (message[0] === 'connected') connectStart = undefined
|
|
541
|
+
})
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
const stale = openRawSocketWithMessages({ wsid: 'stale' }).socket
|
|
545
|
+
attachStockLifecycle(stale)
|
|
546
|
+
const current = openRawSocketWithMessages({ wsid: 'current' }).socket
|
|
547
|
+
attachStockLifecycle(current)
|
|
548
|
+
await vi.advanceTimersByTimeAsync(1)
|
|
549
|
+
|
|
550
|
+
expect(
|
|
551
|
+
lifecycle
|
|
552
|
+
.filter((event) => event.type === 'open')
|
|
553
|
+
.map(({ generation, activeGeneration, wsid }) => [
|
|
554
|
+
generation,
|
|
555
|
+
activeGeneration,
|
|
556
|
+
wsid,
|
|
557
|
+
]),
|
|
558
|
+
).toEqual([[2, 2, 'current']])
|
|
559
|
+
expect(lifecycle).toContainEqual(
|
|
560
|
+
expect.objectContaining({ type: 'superseded', generation: 1, wsid: 'stale' }),
|
|
561
|
+
)
|
|
562
|
+
expect(errors).toEqual([])
|
|
449
563
|
})
|
|
450
564
|
|
|
451
565
|
test('non-origin WebSockets pass through to the native implementation', () => {
|
|
@@ -557,7 +671,17 @@ function install(fetch: typeof globalThis.fetch) {
|
|
|
557
671
|
}
|
|
558
672
|
|
|
559
673
|
function createZero(
|
|
560
|
-
options: {
|
|
674
|
+
options: {
|
|
675
|
+
pingTimeoutMs?: number
|
|
676
|
+
onClientStateNotFound?: () => void
|
|
677
|
+
logSink?: {
|
|
678
|
+
log(
|
|
679
|
+
level: string,
|
|
680
|
+
context: Record<string, unknown> | undefined,
|
|
681
|
+
...args: unknown[]
|
|
682
|
+
): void
|
|
683
|
+
}
|
|
684
|
+
} = {},
|
|
561
685
|
) {
|
|
562
686
|
const zero = new Zero({
|
|
563
687
|
server: ORIGIN,
|
|
@@ -569,6 +693,8 @@ function createZero(
|
|
|
569
693
|
mutators: zeroHttpFixtureMutators,
|
|
570
694
|
pingTimeoutMs: options.pingTimeoutMs,
|
|
571
695
|
onClientStateNotFound: options.onClientStateNotFound,
|
|
696
|
+
logLevel: options.logSink ? 'debug' : undefined,
|
|
697
|
+
logSink: options.logSink,
|
|
572
698
|
})
|
|
573
699
|
zeros.push(zero)
|
|
574
700
|
return zero
|
|
@@ -644,6 +770,7 @@ function openRawSocket() {
|
|
|
644
770
|
function openRawSocketWithMessages(opts?: {
|
|
645
771
|
authToken?: string
|
|
646
772
|
desiredQueriesPatch?: unknown[]
|
|
773
|
+
wsid?: string
|
|
647
774
|
}) {
|
|
648
775
|
const url = new URL(`${ORIGIN}/sync/v51/connect`)
|
|
649
776
|
url.protocol = 'wss:'
|
|
@@ -652,7 +779,7 @@ function openRawSocketWithMessages(opts?: {
|
|
|
652
779
|
url.searchParams.set('userID', 'u1')
|
|
653
780
|
url.searchParams.set('baseCookie', '')
|
|
654
781
|
url.searchParams.set('lmid', '0')
|
|
655
|
-
url.searchParams.set('wsid', 'ws-test')
|
|
782
|
+
url.searchParams.set('wsid', opts?.wsid ?? 'ws-test')
|
|
656
783
|
const messages: Array<[string, any]> = []
|
|
657
784
|
const socket = new WebSocket(
|
|
658
785
|
url,
|
package/src/httpPullTransport.ts
CHANGED
|
@@ -71,12 +71,13 @@ type TransportState = {
|
|
|
71
71
|
readonly queryForward: boolean
|
|
72
72
|
readonly queryAware: boolean
|
|
73
73
|
nextPokeID: number
|
|
74
|
-
|
|
74
|
+
nextSocketGeneration: number
|
|
75
|
+
readonly activeSocketGenerationByClient: Map<string, number>
|
|
76
|
+
readonly activeSocketByClient: Map<string, ZeroHttpSocket>
|
|
77
|
+
readonly lifecycle: ((event: HttpPullLifecycleEvent) => void) | undefined
|
|
75
78
|
}
|
|
76
79
|
|
|
77
80
|
const COOKIE_WIDTH = 20
|
|
78
|
-
const TRANSIENT_RECONNECT_BACKOFF_BASE_MS = 1_000
|
|
79
|
-
const TRANSIENT_RECONNECT_BACKOFF_MAX_MS = 30_000
|
|
80
81
|
|
|
81
82
|
export type HttpPullTransport = {
|
|
82
83
|
pull(): Promise<void>
|
|
@@ -108,6 +109,19 @@ export type HttpPullTransportOptions = {
|
|
|
108
109
|
// queries ship as name+args for the SERVER (consumer worker) to resolve with
|
|
109
110
|
// auth. the production path for permission-transformed queries.
|
|
110
111
|
queryForward?: boolean
|
|
112
|
+
// optional generation trace for connection-lifecycle diagnostics
|
|
113
|
+
lifecycle?: (event: HttpPullLifecycleEvent) => void
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export type HttpPullLifecycleEvent = {
|
|
117
|
+
type: 'created' | 'listener' | 'open' | 'close' | 'failure' | 'superseded'
|
|
118
|
+
generation: number
|
|
119
|
+
activeGeneration: number
|
|
120
|
+
clientID: string
|
|
121
|
+
wsid: string
|
|
122
|
+
listener?: SocketEventType
|
|
123
|
+
code?: number
|
|
124
|
+
reason?: string
|
|
111
125
|
}
|
|
112
126
|
|
|
113
127
|
export function installHttpPullTransport(
|
|
@@ -140,7 +154,10 @@ export function installHttpPullTransport(
|
|
|
140
154
|
queryForward: opts.queryForward === true,
|
|
141
155
|
queryAware: opts.queryTransform !== undefined || opts.queryForward === true,
|
|
142
156
|
nextPokeID: 0,
|
|
143
|
-
|
|
157
|
+
nextSocketGeneration: 0,
|
|
158
|
+
activeSocketGenerationByClient: new Map(),
|
|
159
|
+
activeSocketByClient: new Map(),
|
|
160
|
+
lifecycle: opts.lifecycle,
|
|
144
161
|
}
|
|
145
162
|
|
|
146
163
|
const Shim = class {
|
|
@@ -231,6 +248,7 @@ class ZeroHttpSocket {
|
|
|
231
248
|
private pullTimer: ReturnType<typeof setInterval> | undefined
|
|
232
249
|
private wakeSocket: { close(): void } | undefined
|
|
233
250
|
private wakeReconnectTimer: ReturnType<typeof setTimeout> | undefined
|
|
251
|
+
private readonly generation: number
|
|
234
252
|
|
|
235
253
|
constructor(
|
|
236
254
|
private readonly state: TransportState,
|
|
@@ -242,6 +260,11 @@ class ZeroHttpSocket {
|
|
|
242
260
|
this.clientID = this.connectURL.searchParams.get('clientID') ?? ''
|
|
243
261
|
this.clientGroupID = this.connectURL.searchParams.get('clientGroupID') ?? ''
|
|
244
262
|
this.wsid = this.connectURL.searchParams.get('wsid') ?? `zero-http-${Date.now()}`
|
|
263
|
+
this.generation = ++this.state.nextSocketGeneration
|
|
264
|
+
this.state.activeSocketByClient.get(this.clientID)?.supersede()
|
|
265
|
+
this.state.activeSocketGenerationByClient.set(this.clientID, this.generation)
|
|
266
|
+
this.state.activeSocketByClient.set(this.clientID, this)
|
|
267
|
+
this.emitLifecycle('created')
|
|
245
268
|
const baseCookie = this.connectURL.searchParams.get('baseCookie')
|
|
246
269
|
this.cookie = baseCookie ? baseCookie : null
|
|
247
270
|
// the local cookie ID is encoded into the suffix of any cookie we
|
|
@@ -258,11 +281,17 @@ class ZeroHttpSocket {
|
|
|
258
281
|
this.queueDesiredQueries(decoded.initConnectionMessage?.[1])
|
|
259
282
|
|
|
260
283
|
this.state.sockets.add(this)
|
|
261
|
-
|
|
284
|
+
// open on the next task so Zero can attach its listeners. Zero owns the
|
|
285
|
+
// connection timeout and retry cadence; delaying this synthetic open here
|
|
286
|
+
// can outlive Zero's 10s attempt and deliver an event to abandoned state.
|
|
287
|
+
this.openTimer = setTimeout(() => this.open(), 0)
|
|
262
288
|
}
|
|
263
289
|
|
|
264
290
|
addEventListener(type: SocketEventType, listener: SocketListener | null) {
|
|
265
|
-
if (listener)
|
|
291
|
+
if (listener) {
|
|
292
|
+
this.listeners[type]?.add(listener)
|
|
293
|
+
this.emitLifecycle('listener', { listener: type })
|
|
294
|
+
}
|
|
266
295
|
}
|
|
267
296
|
|
|
268
297
|
removeEventListener(type: SocketEventType, listener: SocketListener | null) {
|
|
@@ -312,6 +341,11 @@ class ZeroHttpSocket {
|
|
|
312
341
|
this.closeWakeChannel()
|
|
313
342
|
this.readyState = this.CLOSED
|
|
314
343
|
this.state.sockets.delete(this)
|
|
344
|
+
if (this.state.activeSocketByClient.get(this.clientID) === this) {
|
|
345
|
+
this.state.activeSocketByClient.delete(this.clientID)
|
|
346
|
+
this.state.activeSocketGenerationByClient.delete(this.clientID)
|
|
347
|
+
}
|
|
348
|
+
this.emitLifecycle('close', { code, reason })
|
|
315
349
|
this.emit('close', { code, reason, wasClean: code <= 1001 })
|
|
316
350
|
}
|
|
317
351
|
|
|
@@ -343,6 +377,7 @@ class ZeroHttpSocket {
|
|
|
343
377
|
private open() {
|
|
344
378
|
if (this.readyState !== this.CONNECTING) return
|
|
345
379
|
this.readyState = this.OPEN
|
|
380
|
+
this.emitLifecycle('open')
|
|
346
381
|
this.emit('open', {})
|
|
347
382
|
this.emitMessage(['connected', { wsid: this.wsid, timestamp: Date.now() }])
|
|
348
383
|
setTimeout(() => this.run(this.pull()), 0)
|
|
@@ -557,7 +592,6 @@ class ZeroHttpSocket {
|
|
|
557
592
|
if (!response.ok) {
|
|
558
593
|
throw new ZeroHttpResponseError(path, response.status)
|
|
559
594
|
}
|
|
560
|
-
resetTransientFailures(this.state)
|
|
561
595
|
return response.json()
|
|
562
596
|
}
|
|
563
597
|
|
|
@@ -567,6 +601,7 @@ class ZeroHttpSocket {
|
|
|
567
601
|
|
|
568
602
|
private fail(error: unknown) {
|
|
569
603
|
if (this.readyState === this.CLOSED) return
|
|
604
|
+
this.emitLifecycle('failure', { reason: errorMessage(error) })
|
|
570
605
|
if (isAuthHTTPError(error)) {
|
|
571
606
|
this.emitMessage([
|
|
572
607
|
'error',
|
|
@@ -596,7 +631,6 @@ class ZeroHttpSocket {
|
|
|
596
631
|
if (this.readyState !== this.CLOSED) this.close(1000, error.message)
|
|
597
632
|
return
|
|
598
633
|
}
|
|
599
|
-
recordTransientFailure(this.state)
|
|
600
634
|
this.emit('error', { error })
|
|
601
635
|
this.close(1011, errorMessage(error))
|
|
602
636
|
}
|
|
@@ -704,6 +738,31 @@ class ZeroHttpSocket {
|
|
|
704
738
|
else listener.handleEvent(event)
|
|
705
739
|
}
|
|
706
740
|
}
|
|
741
|
+
|
|
742
|
+
private supersede() {
|
|
743
|
+
if (this.readyState === this.CLOSED) return
|
|
744
|
+
if (this.openTimer !== undefined) clearTimeout(this.openTimer)
|
|
745
|
+
if (this.pullTimer !== undefined) clearInterval(this.pullTimer)
|
|
746
|
+
this.closeWakeChannel()
|
|
747
|
+
this.readyState = this.CLOSED
|
|
748
|
+
this.state.sockets.delete(this)
|
|
749
|
+
this.emitLifecycle('superseded')
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
private emitLifecycle(
|
|
753
|
+
type: HttpPullLifecycleEvent['type'],
|
|
754
|
+
detail: Pick<HttpPullLifecycleEvent, 'listener' | 'code' | 'reason'> = {},
|
|
755
|
+
) {
|
|
756
|
+
this.state.lifecycle?.({
|
|
757
|
+
type,
|
|
758
|
+
generation: this.generation,
|
|
759
|
+
activeGeneration:
|
|
760
|
+
this.state.activeSocketGenerationByClient.get(this.clientID) ?? this.generation,
|
|
761
|
+
clientID: this.clientID,
|
|
762
|
+
wsid: this.wsid,
|
|
763
|
+
...detail,
|
|
764
|
+
})
|
|
765
|
+
}
|
|
707
766
|
}
|
|
708
767
|
|
|
709
768
|
function shouldIntercept(origin: URL, url: string | URL) {
|
|
@@ -823,25 +882,3 @@ function isStaleClientCookieError(error: unknown): error is ZeroHttpResponseErro
|
|
|
823
882
|
error.status === 409
|
|
824
883
|
)
|
|
825
884
|
}
|
|
826
|
-
|
|
827
|
-
function reconnectDelayMs(state: TransportState) {
|
|
828
|
-
if (state.transientFailureCount === 0) return 0
|
|
829
|
-
return Math.min(
|
|
830
|
-
TRANSIENT_RECONNECT_BACKOFF_BASE_MS * 2 ** (state.transientFailureCount - 1),
|
|
831
|
-
TRANSIENT_RECONNECT_BACKOFF_MAX_MS,
|
|
832
|
-
)
|
|
833
|
-
}
|
|
834
|
-
|
|
835
|
-
function recordTransientFailure(state: TransportState) {
|
|
836
|
-
const maxExponent = Math.log2(
|
|
837
|
-
TRANSIENT_RECONNECT_BACKOFF_MAX_MS / TRANSIENT_RECONNECT_BACKOFF_BASE_MS,
|
|
838
|
-
)
|
|
839
|
-
state.transientFailureCount = Math.min(
|
|
840
|
-
state.transientFailureCount + 1,
|
|
841
|
-
Math.ceil(maxExponent) + 1,
|
|
842
|
-
)
|
|
843
|
-
}
|
|
844
|
-
|
|
845
|
-
function resetTransientFailures(state: TransportState) {
|
|
846
|
-
state.transientFailureCount = 0
|
|
847
|
-
}
|
package/src/modelRegistry.ts
CHANGED
|
@@ -1,15 +1,20 @@
|
|
|
1
1
|
import type { Where } from './types'
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
function mutationsToPermissionsRegistry(): Map<string, Where> {
|
|
4
|
+
const global = globalThis as typeof globalThis & {
|
|
5
|
+
__onZeroMutationPermissionsRegistry__?: Map<string, Where>
|
|
6
|
+
}
|
|
7
|
+
return (global.__onZeroMutationPermissionsRegistry__ ||= new Map())
|
|
8
|
+
}
|
|
4
9
|
|
|
5
10
|
export function setMutationsPermissions(tableName: string, permissions: Where) {
|
|
6
|
-
mutationsToPermissionsRegistry.set(tableName, permissions)
|
|
11
|
+
mutationsToPermissionsRegistry().set(tableName, permissions)
|
|
7
12
|
}
|
|
8
13
|
|
|
9
14
|
export function getMutationsPermissions(tableName: string): Where | undefined {
|
|
10
|
-
return mutationsToPermissionsRegistry.get(tableName)
|
|
15
|
+
return mutationsToPermissionsRegistry().get(tableName)
|
|
11
16
|
}
|
|
12
17
|
|
|
13
18
|
export function getAllMutationsPermissions(): Map<string, Where> {
|
|
14
|
-
return mutationsToPermissionsRegistry
|
|
19
|
+
return mutationsToPermissionsRegistry()
|
|
15
20
|
}
|
package/src/mutations.ts
CHANGED
|
@@ -20,15 +20,19 @@ type SchemaTableBuilder<TName extends TableName> = TableBuilderWithColumns<
|
|
|
20
20
|
// HMR registry - stores mutation implementations and proxies by table name
|
|
21
21
|
// allows hot-swapping implementations without changing object references
|
|
22
22
|
// stored on globalThis to persist across HMR module reloads
|
|
23
|
-
|
|
24
|
-
const
|
|
23
|
+
function mutationRegistry(): Map<string, Record<string, Function>> {
|
|
24
|
+
const global = globalThis as typeof globalThis & {
|
|
25
|
+
__onZeroMutationRegistry__?: Map<string, Record<string, Function>>
|
|
26
|
+
}
|
|
27
|
+
return (global.__onZeroMutationRegistry__ ||= new Map())
|
|
28
|
+
}
|
|
25
29
|
|
|
26
|
-
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
function proxyRegistry(): Map<string, any> {
|
|
31
|
+
const global = globalThis as typeof globalThis & {
|
|
32
|
+
__onZeroProxyRegistry__?: Map<string, any>
|
|
33
|
+
}
|
|
34
|
+
return (global.__onZeroProxyRegistry__ ||= new Map())
|
|
35
|
+
}
|
|
32
36
|
|
|
33
37
|
// get or create a proxy that delegates to the registry
|
|
34
38
|
// returns the SAME proxy object on subsequent calls so HMR works
|
|
@@ -37,10 +41,10 @@ function getOrCreateMutationProxy<T extends Record<string, Function>>(
|
|
|
37
41
|
implementations: T,
|
|
38
42
|
): T {
|
|
39
43
|
// always update implementations (supports HMR)
|
|
40
|
-
mutationRegistry.set(tableName, implementations)
|
|
44
|
+
mutationRegistry().set(tableName, implementations)
|
|
41
45
|
|
|
42
46
|
// return existing proxy if we have one (HMR case)
|
|
43
|
-
const existing = proxyRegistry.get(tableName)
|
|
47
|
+
const existing = proxyRegistry().get(tableName)
|
|
44
48
|
if (existing) {
|
|
45
49
|
return existing as T
|
|
46
50
|
}
|
|
@@ -48,25 +52,25 @@ function getOrCreateMutationProxy<T extends Record<string, Function>>(
|
|
|
48
52
|
// first time - create the proxy
|
|
49
53
|
const proxy = new Proxy({} as T, {
|
|
50
54
|
get(_, key: string) {
|
|
51
|
-
return mutationRegistry.get(tableName)?.[key]
|
|
55
|
+
return mutationRegistry().get(tableName)?.[key]
|
|
52
56
|
},
|
|
53
57
|
ownKeys() {
|
|
54
|
-
const current = mutationRegistry.get(tableName)
|
|
58
|
+
const current = mutationRegistry().get(tableName)
|
|
55
59
|
return current ? Object.keys(current) : []
|
|
56
60
|
},
|
|
57
61
|
getOwnPropertyDescriptor(_, key: string) {
|
|
58
|
-
const current = mutationRegistry.get(tableName)
|
|
62
|
+
const current = mutationRegistry().get(tableName)
|
|
59
63
|
if (current && key in current) {
|
|
60
64
|
return { enumerable: true, configurable: true, value: current[key] }
|
|
61
65
|
}
|
|
62
66
|
},
|
|
63
67
|
has(_, key: string) {
|
|
64
|
-
const current = mutationRegistry.get(tableName)
|
|
68
|
+
const current = mutationRegistry().get(tableName)
|
|
65
69
|
return current ? key in current : false
|
|
66
70
|
},
|
|
67
71
|
})
|
|
68
72
|
|
|
69
|
-
proxyRegistry.set(tableName, proxy)
|
|
73
|
+
proxyRegistry().set(tableName, proxy)
|
|
70
74
|
return proxy
|
|
71
75
|
}
|
|
72
76
|
|
package/src/state.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { Schema, SchemaQuery } from '@rocicorp/zero'
|
|
2
2
|
import { globalValue } from '@take-out/helpers'
|
|
3
3
|
|
|
4
4
|
import type { AuthData, QueryBuilder } from './types'
|
|
@@ -32,10 +32,10 @@ export const getSchema = () => {
|
|
|
32
32
|
return schema
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
export const setSchema = (_:
|
|
35
|
+
export const setSchema = <S extends Schema>(_: S, zql: SchemaQuery<S>) => {
|
|
36
36
|
const state = getState()
|
|
37
37
|
state.schema = _
|
|
38
|
-
state.zql =
|
|
38
|
+
state.zql = zql as QueryBuilder
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
export const getAuthData = () => {
|
package/src/syncHost.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { asQueryInternals } from '@rocicorp/zero/bindings'
|
|
2
|
+
import { createBuilder, type Schema as ZeroSchema } from '@rocicorp/zero'
|
|
2
3
|
|
|
3
4
|
import { createPermissions } from './createPermissions'
|
|
4
5
|
import {
|
|
@@ -24,7 +25,6 @@ import { runWithQueryContext } from './helpers/queryContext'
|
|
|
24
25
|
import { setEnvironment, setSchema } from './state'
|
|
25
26
|
|
|
26
27
|
import type { AsyncTaskEntry, AuthData, GenericModels } from './types'
|
|
27
|
-
import type { Schema as ZeroSchema } from '@rocicorp/zero'
|
|
28
28
|
|
|
29
29
|
export type SyncHostJsonValue =
|
|
30
30
|
| string
|
|
@@ -129,7 +129,7 @@ export function createZeroSyncHostAdapter<
|
|
|
129
129
|
Schema,
|
|
130
130
|
Models
|
|
131
131
|
> {
|
|
132
|
-
setSchema(options.schema)
|
|
132
|
+
setSchema(options.schema, createBuilder(options.schema))
|
|
133
133
|
setEnvironment('server')
|
|
134
134
|
|
|
135
135
|
const permissions = createPermissions({
|
|
@@ -1,7 +1,11 @@
|
|
|
1
|
-
import { boolean, string, table } from '@rocicorp/zero'
|
|
1
|
+
import { boolean, createBuilder, string, table } from '@rocicorp/zero'
|
|
2
2
|
import { describe, expect, test } from 'vitest'
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
getAllMutationsPermissions,
|
|
6
|
+
getMutationsPermissions,
|
|
7
|
+
setMutationsPermissions,
|
|
8
|
+
} from './modelRegistry'
|
|
5
9
|
import { registerQuery, getQueryName } from './queryRegistry'
|
|
6
10
|
import { setEnvironment, setSchema } from './state'
|
|
7
11
|
|
|
@@ -25,7 +29,8 @@ describe('usePermission _uid query identity', () => {
|
|
|
25
29
|
})
|
|
26
30
|
.primaryKey('id')
|
|
27
31
|
|
|
28
|
-
|
|
32
|
+
const schema = { tables: { testEntity: testTable }, version: 1 } as any
|
|
33
|
+
setSchema(schema, createBuilder(schema) as any)
|
|
29
34
|
setEnvironment('client')
|
|
30
35
|
|
|
31
36
|
// simulate what createPermissionCheckFn does:
|
|
@@ -73,6 +78,7 @@ describe('usePermission _uid query identity', () => {
|
|
|
73
78
|
const perm = getMutationsPermissions('testEntity')
|
|
74
79
|
expect(perm).toBeDefined()
|
|
75
80
|
expect(perm).toBe(mockWhere)
|
|
81
|
+
expect(getAllMutationsPermissions().get('testEntity')).toBe(mockWhere)
|
|
76
82
|
})
|
|
77
83
|
|
|
78
84
|
test('query name registration preserves permission namespace', () => {
|
|
@@ -7,7 +7,12 @@ import {
|
|
|
7
7
|
} from 'on-zero/server'
|
|
8
8
|
import { createZeroSQLiteServer, type SqlStatementMetadata } from 'on-zero/sqlite'
|
|
9
9
|
|
|
10
|
-
import
|
|
10
|
+
import {
|
|
11
|
+
runAsyncTaskEntries as runAsyncTaskEntriesFromRoot,
|
|
12
|
+
type Config,
|
|
13
|
+
type MutatorContext,
|
|
14
|
+
type RunAsyncTaskEntriesOptions,
|
|
15
|
+
} from 'on-zero'
|
|
11
16
|
import type { Schema as ZeroSchema } from '@rocicorp/zero'
|
|
12
17
|
|
|
13
18
|
type AppAuthData = {
|
|
@@ -57,6 +62,13 @@ void runAsyncTaskEntries(taskEntries, {
|
|
|
57
62
|
},
|
|
58
63
|
})
|
|
59
64
|
|
|
65
|
+
const rootTaskOptions: RunAsyncTaskEntriesOptions = {
|
|
66
|
+
background(promise) {
|
|
67
|
+
void promise
|
|
68
|
+
},
|
|
69
|
+
}
|
|
70
|
+
void runAsyncTaskEntriesFromRoot(taskEntries, rootTaskOptions)
|
|
71
|
+
|
|
60
72
|
const scheduleBackgroundTask: BackgroundTaskScheduler = (promise) => {
|
|
61
73
|
void promise
|
|
62
74
|
}
|
package/types/asyncTasks.d.ts
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
|
-
|
|
1
|
+
type AsyncTaskEntry = {
|
|
2
|
+
task: () => Promise<void>;
|
|
3
|
+
barrier: boolean;
|
|
4
|
+
};
|
|
2
5
|
export type RunAsyncTaskEntriesOptions = {
|
|
3
6
|
/** Receives the background-task promise. Omit this to await all entries. */
|
|
4
7
|
background?: (promise: Promise<void>) => void;
|
|
5
8
|
};
|
|
6
9
|
export declare function runAsyncTaskEntries(entries: readonly AsyncTaskEntry[], { background }?: RunAsyncTaskEntriesOptions): Promise<void>;
|
|
10
|
+
export {};
|
|
7
11
|
//# sourceMappingURL=asyncTasks.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"asyncTasks.d.ts","sourceRoot":"","sources":["../src/asyncTasks.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"asyncTasks.d.ts","sourceRoot":"","sources":["../src/asyncTasks.ts"],"names":[],"mappings":"AAAA,KAAK,cAAc,GAAG;IACpB,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IACzB,OAAO,EAAE,OAAO,CAAA;CACjB,CAAA;AAED,MAAM,MAAM,0BAA0B,GAAG;IACvC,4EAA4E;IAC5E,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,IAAI,CAAA;CAC9C,CAAA;AAED,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,SAAS,cAAc,EAAE,EAClC,EAAE,UAAU,EAAE,GAAE,0BAA+B,GAC9C,OAAO,CAAC,IAAI,CAAC,CAsBf"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createZeroClient.d.ts","sourceRoot":"","sources":["../src/createZeroClient.tsx"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"createZeroClient.d.ts","sourceRoot":"","sources":["../src/createZeroClient.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createZeroServerCore.d.ts","sourceRoot":"","sources":["../src/createZeroServerCore.ts"],"names":[],"mappings":"AAMA,OAAO,EAKL,KAAK,uBAAuB,EAC5B,KAAK,kBAAkB,EACxB,MAAM,0BAA0B,CAAA;AAKjC,OAAO,KAAK,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AACtD,OAAO,KAAK,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAE1D,KAAK,wBAAwB,GAAG;IAC9B,EAAE,EAAE;QACF,QAAQ,EAAE,MAAM,CAAA;QAChB,EAAE,EAAE,MAAM,CAAA;KACX,CAAA;IACD,MAAM,EAAE;QACN,KAAK,EAAE,kBAAkB,CAAA;QACzB,OAAO,CAAC,EAAE,OAAO,CAAA;KAClB,CAAA;CACF,CAAA;AAMD,MAAM,MAAM,uBAAuB,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,IAAI,CAAA;AAEtE,MAAM,MAAM,4BAA4B,GAAG;IACzC,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAA;IACzB,OAAO,EAAE,OAAO,CAAA;IAChB,sBAAsB,CAAC,EAAE,uBAAuB,CAAA;IAChD,cAAc,CAAC,EAAE,OAAO,CAAA;CACzB,CAAA;AAED,MAAM,MAAM,2BAA2B,GAAG;IACxC,aAAa,EAAE,MAAM,CAAA;IACrB,SAAS,EAAE,wBAAwB,EAAE,CAAA;IACrC,cAAc,EAAE,MAAM,CAAA;CACvB,CAAA;AAED,KAAK,qBAAqB,CACxB,MAAM,SAAS,UAAU,EACzB,MAAM,SAAS,aAAa,EAC5B,aAAa,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAC3C,uBAAuB,CAAC,MAAM,EAAE,MAAM,EAAE,aAAa,CAAC,GAAG;IAC3D,cAAc,EAAE,MAAM,kBAAkB,CAAA;IACxC,uBAAuB,CAAC,EAAE,CAAC,IAAI,EAAE,2BAA2B,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;CAC/E,CAAA;AAED,wBAAgB,oBAAoB,CAClC,MAAM,SAAS,UAAU,EACzB,MAAM,SAAS,aAAa,EAC5B,aAAa,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7C,EACA,cAAc,EACd,mBAAmB,EACnB,qBAA6B,EAC7B,qBAAqB,EACrB,MAAM,EACN,SAAS,EAAE,kBAAkB,EAC7B,uBAAuB,EACvB,OAAO,EACP,MAAM,EACN,gBAAgB,EAChB,aAAa,GACd,EAAE,qBAAqB,CAAC,MAAM,EAAE,MAAM,EAAE,aAAa,CAAC;;;;4FAmBlD,4BAA4B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iDAwC5B;QACD,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAA;QACzB,OAAO,EAAE,OAAO,CAAA;KACjB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoCF;AAED,MAAM,MAAM,UAAU,CACpB,MAAM,SAAS,UAAU,EACzB,MAAM,SAAS,aAAa,EAC5B,aAAa,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAC3C,UAAU,CAAC,OAAO,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,aAAa,CAAC,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"createZeroServerCore.d.ts","sourceRoot":"","sources":["../src/createZeroServerCore.ts"],"names":[],"mappings":"AAMA,OAAO,EAKL,KAAK,uBAAuB,EAC5B,KAAK,kBAAkB,EACxB,MAAM,0BAA0B,CAAA;AAKjC,OAAO,KAAK,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AACtD,OAAO,KAAK,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAE1D,KAAK,wBAAwB,GAAG;IAC9B,EAAE,EAAE;QACF,QAAQ,EAAE,MAAM,CAAA;QAChB,EAAE,EAAE,MAAM,CAAA;KACX,CAAA;IACD,MAAM,EAAE;QACN,KAAK,EAAE,kBAAkB,CAAA;QACzB,OAAO,CAAC,EAAE,OAAO,CAAA;KAClB,CAAA;CACF,CAAA;AAMD,MAAM,MAAM,uBAAuB,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,IAAI,CAAA;AAEtE,MAAM,MAAM,4BAA4B,GAAG;IACzC,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAA;IACzB,OAAO,EAAE,OAAO,CAAA;IAChB,sBAAsB,CAAC,EAAE,uBAAuB,CAAA;IAChD,cAAc,CAAC,EAAE,OAAO,CAAA;CACzB,CAAA;AAED,MAAM,MAAM,2BAA2B,GAAG;IACxC,aAAa,EAAE,MAAM,CAAA;IACrB,SAAS,EAAE,wBAAwB,EAAE,CAAA;IACrC,cAAc,EAAE,MAAM,CAAA;CACvB,CAAA;AAED,KAAK,qBAAqB,CACxB,MAAM,SAAS,UAAU,EACzB,MAAM,SAAS,aAAa,EAC5B,aAAa,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAC3C,uBAAuB,CAAC,MAAM,EAAE,MAAM,EAAE,aAAa,CAAC,GAAG;IAC3D,cAAc,EAAE,MAAM,kBAAkB,CAAA;IACxC,uBAAuB,CAAC,EAAE,CAAC,IAAI,EAAE,2BAA2B,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;CAC/E,CAAA;AAED,wBAAgB,oBAAoB,CAClC,MAAM,SAAS,UAAU,EACzB,MAAM,SAAS,aAAa,EAC5B,aAAa,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7C,EACA,cAAc,EACd,mBAAmB,EACnB,qBAA6B,EAC7B,qBAAqB,EACrB,MAAM,EACN,SAAS,EAAE,kBAAkB,EAC7B,uBAAuB,EACvB,OAAO,EACP,MAAM,EACN,gBAAgB,EAChB,aAAa,GACd,EAAE,qBAAqB,CAAC,MAAM,EAAE,MAAM,EAAE,aAAa,CAAC;;;;4FAmBlD,4BAA4B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iDAwC5B;QACD,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAA;QACzB,OAAO,EAAE,OAAO,CAAA;KACjB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoCF;AAED,MAAM,MAAM,UAAU,CACpB,MAAM,SAAS,UAAU,EACzB,MAAM,SAAS,aAAa,EAC5B,aAAa,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAC3C,UAAU,CAAC,OAAO,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,aAAa,CAAC,CAAC,CAAA;AA4G1E,YAAY,EACV,oBAAoB,EACpB,kBAAkB,EAClB,iBAAiB,EACjB,eAAe,EACf,uBAAuB,EACvB,kBAAkB,GACnB,MAAM,0BAA0B,CAAA"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
type SocketEventType = 'open' | 'message' | 'close' | 'error';
|
|
1
2
|
export type QueryTransform = (name: string, args: readonly unknown[]) => unknown;
|
|
2
3
|
export type HttpPullTransport = {
|
|
3
4
|
pull(): Promise<void>;
|
|
@@ -13,7 +14,19 @@ export type HttpPullTransportOptions = {
|
|
|
13
14
|
wake?: boolean;
|
|
14
15
|
queryTransform?: QueryTransform;
|
|
15
16
|
queryForward?: boolean;
|
|
17
|
+
lifecycle?: (event: HttpPullLifecycleEvent) => void;
|
|
18
|
+
};
|
|
19
|
+
export type HttpPullLifecycleEvent = {
|
|
20
|
+
type: 'created' | 'listener' | 'open' | 'close' | 'failure' | 'superseded';
|
|
21
|
+
generation: number;
|
|
22
|
+
activeGeneration: number;
|
|
23
|
+
clientID: string;
|
|
24
|
+
wsid: string;
|
|
25
|
+
listener?: SocketEventType;
|
|
26
|
+
code?: number;
|
|
27
|
+
reason?: string;
|
|
16
28
|
};
|
|
17
29
|
export declare function installHttpPullTransport(opts: HttpPullTransportOptions): HttpPullTransport;
|
|
18
30
|
export declare function ensureHttpPullTransport(opts: HttpPullTransportOptions): HttpPullTransport;
|
|
31
|
+
export {};
|
|
19
32
|
//# sourceMappingURL=httpPullTransport.d.ts.map
|