orez 0.2.27 → 0.2.29

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.
Files changed (150) hide show
  1. package/package.json +3 -4
  2. package/src/admin/admin-data.test.ts +0 -348
  3. package/src/admin/http-proxy.ts +0 -252
  4. package/src/admin/log-store.ts +0 -192
  5. package/src/admin/server.ts +0 -471
  6. package/src/admin/ui.ts +0 -1322
  7. package/src/bench/proxy-throughput.bench.ts +0 -343
  8. package/src/bench/serial-mutations.bench.ts +0 -270
  9. package/src/browser.ts +0 -203
  10. package/src/cf-do/.wrangler/cache/cf.json +0 -1
  11. package/src/cf-do/.wrangler/state/v3/cache/miniflare-CacheObject/metadata.sqlite +0 -0
  12. package/src/cf-do/.wrangler/state/v3/cache/miniflare-CacheObject/metadata.sqlite-shm +0 -0
  13. package/src/cf-do/.wrangler/state/v3/cache/miniflare-CacheObject/metadata.sqlite-wal +0 -0
  14. package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/0ffaabee41a60e04dd0eb7db3073f0a40139e6a97ccd26823967acb652b89a7b.sqlite +0 -0
  15. package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/metadata.sqlite +0 -0
  16. package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/metadata.sqlite-shm +0 -0
  17. package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/metadata.sqlite-wal +0 -0
  18. package/src/cf-do/.wrangler/tmp/bundle-0z4CpE/middleware-insertion-facade.js +0 -11
  19. package/src/cf-do/.wrangler/tmp/bundle-0z4CpE/middleware-loader.entry.ts +0 -134
  20. package/src/cf-do/.wrangler/tmp/bundle-vYmw0E/middleware-insertion-facade.js +0 -11
  21. package/src/cf-do/.wrangler/tmp/bundle-vYmw0E/middleware-loader.entry.ts +0 -134
  22. package/src/cf-do/.wrangler/tmp/dev-cbILNo/worker.js +0 -1059
  23. package/src/cf-do/.wrangler/tmp/dev-cbILNo/worker.js.map +0 -8
  24. package/src/cf-do/.wrangler/tmp/dev-qbho19/worker.js +0 -1059
  25. package/src/cf-do/.wrangler/tmp/dev-qbho19/worker.js.map +0 -8
  26. package/src/cf-do/ARCHITECTURE.md +0 -93
  27. package/src/cf-do/CHAT_E2E.md +0 -213
  28. package/src/cf-do/watermark.test.ts +0 -103
  29. package/src/cf-do/watermark.ts +0 -118
  30. package/src/cf-do/worker.ts +0 -1041
  31. package/src/cf-do/wrangler.toml +0 -11
  32. package/src/cf-pglite/README.md +0 -19
  33. package/src/change-tracking.ts +0 -25
  34. package/src/child-process.test.ts +0 -147
  35. package/src/child-process.ts +0 -90
  36. package/src/cli-entry.ts +0 -72
  37. package/src/cli.test.ts +0 -40
  38. package/src/cli.ts +0 -1214
  39. package/src/config.ts +0 -150
  40. package/src/do-sql-tracking.test.ts +0 -19
  41. package/src/do-sql-tracking.ts +0 -19
  42. package/src/index.ts +0 -1215
  43. package/src/integration/integration.test.ts +0 -517
  44. package/src/integration/native-binary.guard.test.ts +0 -13
  45. package/src/integration/native-startup.test.ts +0 -44
  46. package/src/integration/replication-latency.test.ts +0 -428
  47. package/src/integration/restore-live-stress.test.ts +0 -433
  48. package/src/integration/restore-reset.test.ts +0 -400
  49. package/src/integration/restore.test.ts +0 -274
  50. package/src/integration/test-permissions.ts +0 -147
  51. package/src/load-config.ts +0 -46
  52. package/src/log.ts +0 -96
  53. package/src/mutex.ts +0 -47
  54. package/src/pg-proxy-browser.singledb.test.ts +0 -233
  55. package/src/pg-proxy-browser.ts +0 -2022
  56. package/src/pg-proxy-do-backend.test.ts +0 -3890
  57. package/src/pg-proxy-do-backend.ts +0 -7191
  58. package/src/pg-proxy.ts +0 -1087
  59. package/src/pg-sqlite-compiler/README.md +0 -53
  60. package/src/pg-sqlite-compiler/catalog/seed.ts +0 -524
  61. package/src/pg-sqlite-compiler/fixtures/pgsqlite/arithmetic.json +0 -307
  62. package/src/pg-sqlite-compiler/fixtures/pgsqlite/array.json +0 -377
  63. package/src/pg-sqlite-compiler/fixtures/pgsqlite/cast.json +0 -12
  64. package/src/pg-sqlite-compiler/fixtures/pgsqlite/catalog.json +0 -447
  65. package/src/pg-sqlite-compiler/fixtures/pgsqlite/create-table.json +0 -32
  66. package/src/pg-sqlite-compiler/fixtures/pgsqlite/datetime.json +0 -397
  67. package/src/pg-sqlite-compiler/fixtures/pgsqlite/enum.json +0 -337
  68. package/src/pg-sqlite-compiler/fixtures/pgsqlite/insert.json +0 -337
  69. package/src/pg-sqlite-compiler/fixtures/pgsqlite/json.json +0 -537
  70. package/src/pg-sqlite-compiler/fixtures/pgsqlite/misc.json +0 -1837
  71. package/src/pg-sqlite-compiler/index.ts +0 -73
  72. package/src/pg-sqlite-compiler/integration.test.ts +0 -136
  73. package/src/pg-sqlite-compiler/passes/ast-utils.ts +0 -113
  74. package/src/pg-sqlite-compiler/passes/catalog.ts +0 -65
  75. package/src/pg-sqlite-compiler/passes/datetime.ts +0 -74
  76. package/src/pg-sqlite-compiler/passes/index.ts +0 -49
  77. package/src/pg-sqlite-compiler/passes/types.ts +0 -156
  78. package/src/pg-sqlite-compiler/smoke.test.ts +0 -69
  79. package/src/pg-sqlite-compiler/test/catalog.test.ts +0 -171
  80. package/src/pg-sqlite-compiler/test/corpus.test.ts +0 -161
  81. package/src/pg-sqlite-compiler/test/datetime.oracle.test.ts +0 -102
  82. package/src/pg-sqlite-compiler/test/oracle.ts +0 -237
  83. package/src/pg-sqlite-compiler/test/types.test.ts +0 -109
  84. package/src/pg-sqlite-compiler/types.ts +0 -63
  85. package/src/pglite-ipc.test.ts +0 -116
  86. package/src/pglite-ipc.ts +0 -266
  87. package/src/pglite-manager.ts +0 -557
  88. package/src/pglite-web-proxy.test.ts +0 -57
  89. package/src/pglite-web-proxy.ts +0 -221
  90. package/src/pglite-web-worker.ts +0 -152
  91. package/src/pglite-worker-thread.ts +0 -253
  92. package/src/port.ts +0 -25
  93. package/src/process-title.ts +0 -9
  94. package/src/recovery.ts +0 -155
  95. package/src/replication/change-tracker.test.ts +0 -357
  96. package/src/replication/change-tracker.ts +0 -279
  97. package/src/replication/handler.test.ts +0 -511
  98. package/src/replication/handler.ts +0 -1190
  99. package/src/replication/pgoutput-encoder.test.ts +0 -697
  100. package/src/replication/pgoutput-encoder.ts +0 -373
  101. package/src/replication/tcp-replication.test.ts +0 -876
  102. package/src/replication/zero-compat.test.ts +0 -1150
  103. package/src/restore-stress.test.ts +0 -188
  104. package/src/s3-local.ts +0 -203
  105. package/src/shim/hooks.mjs +0 -120
  106. package/src/shim/register.mjs +0 -4
  107. package/src/sqlite-mode/apply-mode.ts +0 -224
  108. package/src/sqlite-mode/index.ts +0 -15
  109. package/src/sqlite-mode/native-binary.ts +0 -89
  110. package/src/sqlite-mode/package-resolve.ts +0 -17
  111. package/src/sqlite-mode/resolve-mode.ts +0 -80
  112. package/src/sqlite-mode/shim-template.ts +0 -159
  113. package/src/sqlite-mode/sqlite-mode.test.ts +0 -427
  114. package/src/sqlite-mode/types.ts +0 -30
  115. package/src/vite-plugin.ts +0 -67
  116. package/src/wasm-sqlite.test.ts +0 -537
  117. package/src/worker/browser-admin.ts +0 -52
  118. package/src/worker/browser-build-config.test.ts +0 -71
  119. package/src/worker/browser-build-config.ts +0 -109
  120. package/src/worker/browser-embed-admin.test.ts +0 -75
  121. package/src/worker/browser-embed.ts +0 -345
  122. package/src/worker/cf-patches.ts +0 -384
  123. package/src/worker/embed-integration.test.ts +0 -321
  124. package/src/worker/index.ts +0 -138
  125. package/src/worker/shims/fastify.test.ts +0 -255
  126. package/src/worker/shims/fastify.ts +0 -306
  127. package/src/worker/shims/http-service.test.ts +0 -355
  128. package/src/worker/shims/http-service.ts +0 -293
  129. package/src/worker/shims/node-stub.ts +0 -290
  130. package/src/worker/shims/oxfmt.ts +0 -3
  131. package/src/worker/shims/postgres-browser.ts +0 -59
  132. package/src/worker/shims/postgres-socket.test.ts +0 -576
  133. package/src/worker/shims/postgres-socket.ts +0 -310
  134. package/src/worker/shims/postgres.test.ts +0 -364
  135. package/src/worker/shims/postgres.ts +0 -1454
  136. package/src/worker/shims/sqlite-browser.test.ts +0 -233
  137. package/src/worker/shims/sqlite-browser.ts +0 -175
  138. package/src/worker/shims/sqlite.test.ts +0 -786
  139. package/src/worker/shims/sqlite.ts +0 -978
  140. package/src/worker/shims/stream-browser.ts +0 -15
  141. package/src/worker/shims/ws-browser.test.ts +0 -205
  142. package/src/worker/shims/ws-browser.ts +0 -248
  143. package/src/worker/shims/ws.test.ts +0 -288
  144. package/src/worker/shims/ws.ts +0 -467
  145. package/src/worker/shims/zero-process-env.ts +0 -11
  146. package/src/worker/types.ts +0 -75
  147. package/src/worker/worker-integration.test.ts +0 -223
  148. package/src/worker/worker.test.ts +0 -136
  149. package/src/worker/zero-cache-embed-cf.ts +0 -463
  150. package/src/worker/zero-cache-embed.ts +0 -277
@@ -1,15 +0,0 @@
1
- /**
2
- * stream shim — re-exports readable-stream with missing Node.js stream functions.
3
- *
4
- * readable-stream/stream-browserify don't include getDefaultHighWaterMark
5
- * which zero-cache uses (added in Node.js 18+).
6
- */
7
-
8
- // @ts-expect-error — readable-stream is CJS
9
- export * from 'readable-stream'
10
- // @ts-expect-error — readable-stream is CJS
11
- export { default } from 'readable-stream'
12
-
13
- export function getDefaultHighWaterMark(objectMode: boolean): number {
14
- return objectMode ? 16 : 16 * 1024
15
- }
@@ -1,205 +0,0 @@
1
- import { describe, it, expect, vi } from 'vitest'
2
-
3
- import { messagePortToWs, browserWsToWs, createInProcessPair } from './ws-browser.js'
4
-
5
- describe('messagePortToWs', () => {
6
- // create a mock MessagePort pair
7
- function createMockPorts() {
8
- type Handler = (event: MessageEvent) => void
9
- let handler1: Handler | null = null
10
- let handler2: Handler | null = null
11
- let closed1 = false
12
- let closed2 = false
13
-
14
- const port1 = {
15
- set onmessage(h: Handler | null) {
16
- handler1 = h
17
- },
18
- get onmessage() {
19
- return handler1
20
- },
21
- onmessageerror: null as Handler | null,
22
- postMessage(data: unknown) {
23
- if (closed2) return
24
- // deliver to port2's handler
25
- handler2?.({ data } as MessageEvent)
26
- },
27
- close() {
28
- closed1 = true
29
- },
30
- }
31
-
32
- const port2 = {
33
- set onmessage(h: Handler | null) {
34
- handler2 = h
35
- },
36
- get onmessage() {
37
- return handler2
38
- },
39
- onmessageerror: null as Handler | null,
40
- postMessage(data: unknown) {
41
- if (closed1) return
42
- handler1?.({ data } as MessageEvent)
43
- },
44
- close() {
45
- closed2 = true
46
- },
47
- }
48
-
49
- return [port1, port2] as [typeof port1, typeof port2]
50
- }
51
-
52
- it('wraps a MessagePort as WebSocket-like', () => {
53
- const [port1] = createMockPorts()
54
- const ws = messagePortToWs(port1 as any)
55
- expect(ws.readyState).toBe(1) // OPEN
56
- expect(ws.send).toBeInstanceOf(Function)
57
- expect(ws.close).toBeInstanceOf(Function)
58
- })
59
-
60
- it('send() calls port.postMessage', () => {
61
- const [port1] = createMockPorts()
62
- const spy = vi.spyOn(port1, 'postMessage')
63
- const ws = messagePortToWs(port1 as any)
64
-
65
- ws.send('hello')
66
- expect(spy).toHaveBeenCalledWith('hello')
67
- })
68
-
69
- it('send() invokes the ws callback after posting', () => {
70
- const [port1] = createMockPorts()
71
- const ws = messagePortToWs(port1 as any)
72
- const callback = vi.fn()
73
-
74
- ws.send('hello', callback)
75
-
76
- expect(callback).toHaveBeenCalledWith()
77
- })
78
-
79
- it('send() reports an error to the callback after close', () => {
80
- const [port1] = createMockPorts()
81
- const ws = messagePortToWs(port1 as any)
82
- const callback = vi.fn()
83
-
84
- ws.close()
85
- ws.send('ignored', callback)
86
-
87
- expect(callback).toHaveBeenCalledWith(expect.any(Error))
88
- })
89
-
90
- it('forwards port messages as ws message events', () => {
91
- const [port1, port2] = createMockPorts()
92
- const ws1 = messagePortToWs(port1 as any)
93
-
94
- const handler = vi.fn()
95
- ws1.addEventListener('message', handler)
96
-
97
- // send from port2 → should arrive at ws1
98
- port2.postMessage('world')
99
- expect(handler).toHaveBeenCalledWith({ data: 'world' })
100
- })
101
-
102
- it('close() sets readyState to CLOSED and fires event', () => {
103
- const [port1] = createMockPorts()
104
- const ws = messagePortToWs(port1 as any)
105
-
106
- const closeHandler = vi.fn()
107
- ws.addEventListener('close', closeHandler)
108
-
109
- ws.close(1000)
110
- expect(ws.readyState).toBe(3) // CLOSED
111
- expect(closeHandler).toHaveBeenCalledWith(
112
- expect.objectContaining({ code: 1000, wasClean: true })
113
- )
114
- })
115
-
116
- it('send() is no-op after close', () => {
117
- const [port1] = createMockPorts()
118
- const spy = vi.spyOn(port1, 'postMessage')
119
- const ws = messagePortToWs(port1 as any)
120
-
121
- ws.close()
122
- ws.send('ignored')
123
- // postMessage should not be called after close
124
- expect(spy).not.toHaveBeenCalled()
125
- })
126
-
127
- it('removeEventListener works', () => {
128
- const [port1] = createMockPorts()
129
- const ws = messagePortToWs(port1 as any)
130
-
131
- const handler = vi.fn()
132
- ws.addEventListener('message', handler)
133
- ws.removeEventListener('message', handler)
134
-
135
- // simulate message — handler should not be called
136
- ;(port1 as any).onmessage?.({ data: 'test' })
137
- // the handler was removed from ws listeners but port.onmessage still fires
138
- // however ws.addEventListener wraps the handler, so the original shouldn't fire
139
- // ... actually the port.onmessage fires the ws internal handler which checks listeners
140
- // this is an implementation detail. just verify no error is thrown.
141
- })
142
- })
143
-
144
- describe('browserWsToWs', () => {
145
- it('wraps a browser WebSocket', () => {
146
- const mockWs = {
147
- readyState: 1,
148
- send: vi.fn(),
149
- close: vi.fn(),
150
- addEventListener: vi.fn(),
151
- removeEventListener: vi.fn(),
152
- }
153
-
154
- const ws = browserWsToWs(mockWs as any)
155
- expect(ws.readyState).toBe(1)
156
-
157
- ws.send('test')
158
- expect(mockWs.send).toHaveBeenCalledWith('test')
159
-
160
- ws.close(1000, 'bye')
161
- expect(mockWs.close).toHaveBeenCalledWith(1000, 'bye')
162
- })
163
- })
164
-
165
- describe('createInProcessPair', () => {
166
- it('creates a connected pair', () => {
167
- const [client, server] = createInProcessPair()
168
- expect(client.readyState).toBe(1)
169
- expect(server.readyState).toBe(1)
170
- })
171
-
172
- it('messages flow between client and server', async () => {
173
- const [client, server] = createInProcessPair()
174
-
175
- // MessageChannel delivers messages asynchronously in Node.js
176
- const serverReceived = new Promise<string>((resolve) => {
177
- server.addEventListener('message', (event: any) => {
178
- resolve(event.data)
179
- })
180
- })
181
-
182
- client.send('hello from client')
183
- expect(await serverReceived).toBe('hello from client')
184
-
185
- const clientReceived = new Promise<string>((resolve) => {
186
- client.addEventListener('message', (event: any) => {
187
- resolve(event.data)
188
- })
189
- })
190
-
191
- server.send('hello from server')
192
- expect(await clientReceived).toBe('hello from server')
193
- })
194
-
195
- it('close sets readyState', () => {
196
- const [client] = createInProcessPair()
197
-
198
- const closeHandler = vi.fn()
199
- client.addEventListener('close', closeHandler)
200
-
201
- client.close(1000)
202
- expect(client.readyState).toBe(3)
203
- expect(closeHandler).toHaveBeenCalled()
204
- })
205
- })
@@ -1,248 +0,0 @@
1
- /**
2
- * browser WebSocket/MessagePort adapter for the ws shim.
3
- *
4
- * wraps a browser WebSocket or MessagePort to match the interface
5
- * that the existing ws shim (orez/worker/shims/ws) expects. this lets
6
- * zero-cache handle WebSocket connections in browser Web Workers.
7
- *
8
- * usage:
9
- * import { messagePortToWs, browserWsToWs } from 'orez/worker/shims/ws-browser'
10
- *
11
- * // from a MessageChannel (worker ↔ main thread)
12
- * const channel = new MessageChannel()
13
- * const serverWs = messagePortToWs(channel.port2)
14
- *
15
- * // from a browser WebSocket
16
- * const ws = new WebSocket('ws://...')
17
- * const shimWs = browserWsToWs(ws)
18
- */
19
-
20
- // the interface that the ws shim expects (same as CF WebSocket)
21
- // on/off are needed because createWebSocketStream uses ws.on('message')
22
- interface WsCompatible {
23
- // ws constants — zero-cache uses ws.OPEN / ws.CONNECTING in switch statements
24
- CONNECTING: number
25
- OPEN: number
26
- CLOSING: number
27
- CLOSED: number
28
- readyState: number
29
- send(
30
- data: string | ArrayBuffer | ArrayBufferView,
31
- callback?: (err?: Error) => void
32
- ): void
33
- close(code?: number, reason?: string): void
34
- addEventListener(type: string, handler: (event: any) => void): void
35
- removeEventListener(type: string, handler: (event: any) => void): void
36
- on(type: string, handler: (event: any) => void): void
37
- off(type: string, handler: (event: any) => void): void
38
- }
39
-
40
- /**
41
- * wrap a MessagePort to look like a WebSocket.
42
- *
43
- * MessagePort uses postMessage/onmessage, while the ws shim expects
44
- * send/addEventListener('message'). this bridges the two.
45
- *
46
- * messages that arrive before any listener is registered are buffered
47
- * and replayed when the first 'message' listener is added. this prevents
48
- * a race where the port starts receiving data before the connection
49
- * handler (e.g. createWebSocketStream / proxyInbound) has set up its
50
- * listener — which would silently drop messages.
51
- */
52
- export function messagePortToWs(port: MessagePort): WsCompatible {
53
- // separate listener sets for on() vs addEventListener() to match real ws behavior.
54
- // in the ws package, on() is EventEmitter-style and addEventListener() is DOM-style.
55
- // createWebSocketStream uses ws.on('message') exclusively for inbound data.
56
- // streamOut uses ws.addEventListener('message') for ack handling.
57
- // if they share the same set, ack messages reach both handlers and
58
- // handleMessage tries to parse acks as protocol messages, closing the connection.
59
- const onListeners = new Map<string, Set<(event: any) => void>>()
60
- const domListeners = new Map<string, Set<(event: any) => void>>()
61
- let closed = false
62
-
63
- // buffer messages until a 'message' listener is registered (either kind)
64
- const pendingMessages: any[] = []
65
-
66
- function addOnListener(type: string, handler: (event: any) => void) {
67
- if (!onListeners.has(type)) onListeners.set(type, new Set())
68
- onListeners.get(type)!.add(handler)
69
- if (type === 'message' && pendingMessages.length > 0) {
70
- const queued = pendingMessages.splice(0)
71
- for (const event of queued) handler(event)
72
- }
73
- }
74
-
75
- function removeOnListener(type: string, handler: (event: any) => void) {
76
- onListeners.get(type)?.delete(handler)
77
- }
78
-
79
- function addDomListener(type: string, handler: (event: any) => void) {
80
- if (!domListeners.has(type)) domListeners.set(type, new Set())
81
- domListeners.get(type)!.add(handler)
82
- if (type === 'message' && pendingMessages.length > 0) {
83
- const queued = pendingMessages.splice(0)
84
- for (const event of queued) handler(event)
85
- }
86
- }
87
-
88
- function removeDomListener(type: string, handler: (event: any) => void) {
89
- domListeners.get(type)?.delete(handler)
90
- }
91
-
92
- function emit(type: string, event: any) {
93
- const onHandlers = onListeners.get(type)
94
- const domHandlers = domListeners.get(type)
95
- const hasAny =
96
- (onHandlers && onHandlers.size > 0) || (domHandlers && domHandlers.size > 0)
97
- if (!hasAny) {
98
- if (type === 'message') pendingMessages.push(event)
99
- return
100
- }
101
- if (onHandlers) for (const h of onHandlers) h(event)
102
- if (domHandlers) for (const h of domHandlers) h(event)
103
- }
104
-
105
- // forward port messages → ws 'message' events
106
- // filter out control messages from sync-ws-patch.js (__close, __open)
107
- port.onmessage = (event: MessageEvent) => {
108
- const data = event.data
109
- // control messages from sync-ws-patch.js — handle as close/open events
110
- if (
111
- data &&
112
- typeof data === 'object' &&
113
- !ArrayBuffer.isView(data) &&
114
- !(data instanceof ArrayBuffer)
115
- ) {
116
- if (data.__close) {
117
- closed = true
118
- port.close()
119
- emit('close', {
120
- code: data.code ?? 1000,
121
- reason: data.reason ?? '',
122
- wasClean: true,
123
- })
124
- return
125
- }
126
- if (data.__open) {
127
- // already open, ignore
128
- return
129
- }
130
- }
131
- emit('message', { data })
132
- }
133
-
134
- port.onmessageerror = (event: MessageEvent) => {
135
- emit('error', { message: 'MessagePort error', error: event })
136
- }
137
-
138
- return {
139
- // ws constants — zero-cache uses ws.OPEN / ws.CONNECTING in switch statements
140
- CONNECTING: 0,
141
- OPEN: 1,
142
- CLOSING: 2,
143
- CLOSED: 3,
144
-
145
- get readyState() {
146
- return closed ? 3 : 1 // CLOSED or OPEN
147
- },
148
-
149
- send(data: string | ArrayBuffer | ArrayBufferView, callback?: (err?: Error) => void) {
150
- if (closed) {
151
- callback?.(new Error('WebSocket is closed'))
152
- return
153
- }
154
-
155
- try {
156
- port.postMessage(data)
157
- } catch (error) {
158
- const err = error instanceof Error ? error : new Error(String(error))
159
- if (callback) {
160
- callback(err)
161
- return
162
- }
163
- throw err
164
- }
165
-
166
- callback?.()
167
- },
168
-
169
- close(code?: number, _reason?: string) {
170
- if (closed) return
171
- closed = true
172
- port.close()
173
- emit('close', { code: code ?? 1000, reason: '', wasClean: true })
174
- },
175
-
176
- addEventListener: addDomListener,
177
- removeEventListener: removeDomListener,
178
- on: addOnListener,
179
- off: removeOnListener,
180
- }
181
- }
182
-
183
- /**
184
- * wrap a browser WebSocket to match the ws shim's expected interface.
185
- *
186
- * browser WebSocket and the ws shim's CFWebSocket interface are very
187
- * similar but have subtle differences. this normalizes them.
188
- */
189
- export function browserWsToWs(ws: WebSocket): WsCompatible {
190
- return {
191
- CONNECTING: 0,
192
- OPEN: 1,
193
- CLOSING: 2,
194
- CLOSED: 3,
195
-
196
- get readyState() {
197
- return ws.readyState
198
- },
199
-
200
- send(data: string | ArrayBuffer | ArrayBufferView, callback?: (err?: Error) => void) {
201
- try {
202
- ws.send(data)
203
- } catch (error) {
204
- const err = error instanceof Error ? error : new Error(String(error))
205
- if (callback) {
206
- callback(err)
207
- return
208
- }
209
- throw err
210
- }
211
-
212
- callback?.()
213
- },
214
-
215
- close(code?: number, reason?: string) {
216
- ws.close(code, reason)
217
- },
218
-
219
- addEventListener(type: string, handler: (event: any) => void) {
220
- ws.addEventListener(type, handler)
221
- },
222
-
223
- removeEventListener(type: string, handler: (event: any) => void) {
224
- ws.removeEventListener(type, handler)
225
- },
226
-
227
- on(type: string, handler: (event: any) => void) {
228
- ws.addEventListener(type, handler)
229
- },
230
-
231
- off(type: string, handler: (event: any) => void) {
232
- ws.removeEventListener(type, handler)
233
- },
234
- }
235
- }
236
-
237
- /**
238
- * create a connected pair of WebSocket-like objects for in-process
239
- * communication (e.g., when zero-cache and Zero client are in the
240
- * same browser context). uses MessageChannel internally.
241
- *
242
- * returns [client, server] — client goes to Zero client, server
243
- * goes to the browser embed's handleWebSocket().
244
- */
245
- export function createInProcessPair(): [WsCompatible, WsCompatible] {
246
- const channel = new MessageChannel()
247
- return [messagePortToWs(channel.port1), messagePortToWs(channel.port2)]
248
- }