orez 0.2.27 → 0.2.30

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 (157) hide show
  1. package/dist/cf-do/worker.d.ts +3 -0
  2. package/dist/cf-do/worker.d.ts.map +1 -1
  3. package/dist/cf-do/worker.js +37 -15
  4. package/dist/cf-do/worker.js.map +1 -1
  5. package/dist/index.d.ts.map +1 -1
  6. package/dist/index.js +8 -0
  7. package/dist/index.js.map +1 -1
  8. package/package.json +3 -4
  9. package/src/admin/admin-data.test.ts +0 -348
  10. package/src/admin/http-proxy.ts +0 -252
  11. package/src/admin/log-store.ts +0 -192
  12. package/src/admin/server.ts +0 -471
  13. package/src/admin/ui.ts +0 -1322
  14. package/src/bench/proxy-throughput.bench.ts +0 -343
  15. package/src/bench/serial-mutations.bench.ts +0 -270
  16. package/src/browser.ts +0 -203
  17. package/src/cf-do/.wrangler/cache/cf.json +0 -1
  18. package/src/cf-do/.wrangler/state/v3/cache/miniflare-CacheObject/metadata.sqlite +0 -0
  19. package/src/cf-do/.wrangler/state/v3/cache/miniflare-CacheObject/metadata.sqlite-shm +0 -0
  20. package/src/cf-do/.wrangler/state/v3/cache/miniflare-CacheObject/metadata.sqlite-wal +0 -0
  21. package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/0ffaabee41a60e04dd0eb7db3073f0a40139e6a97ccd26823967acb652b89a7b.sqlite +0 -0
  22. package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/metadata.sqlite +0 -0
  23. package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/metadata.sqlite-shm +0 -0
  24. package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/metadata.sqlite-wal +0 -0
  25. package/src/cf-do/.wrangler/tmp/bundle-0z4CpE/middleware-insertion-facade.js +0 -11
  26. package/src/cf-do/.wrangler/tmp/bundle-0z4CpE/middleware-loader.entry.ts +0 -134
  27. package/src/cf-do/.wrangler/tmp/bundle-vYmw0E/middleware-insertion-facade.js +0 -11
  28. package/src/cf-do/.wrangler/tmp/bundle-vYmw0E/middleware-loader.entry.ts +0 -134
  29. package/src/cf-do/.wrangler/tmp/dev-cbILNo/worker.js +0 -1059
  30. package/src/cf-do/.wrangler/tmp/dev-cbILNo/worker.js.map +0 -8
  31. package/src/cf-do/.wrangler/tmp/dev-qbho19/worker.js +0 -1059
  32. package/src/cf-do/.wrangler/tmp/dev-qbho19/worker.js.map +0 -8
  33. package/src/cf-do/ARCHITECTURE.md +0 -93
  34. package/src/cf-do/CHAT_E2E.md +0 -213
  35. package/src/cf-do/watermark.test.ts +0 -103
  36. package/src/cf-do/watermark.ts +0 -118
  37. package/src/cf-do/worker.ts +0 -1041
  38. package/src/cf-do/wrangler.toml +0 -11
  39. package/src/cf-pglite/README.md +0 -19
  40. package/src/change-tracking.ts +0 -25
  41. package/src/child-process.test.ts +0 -147
  42. package/src/child-process.ts +0 -90
  43. package/src/cli-entry.ts +0 -72
  44. package/src/cli.test.ts +0 -40
  45. package/src/cli.ts +0 -1214
  46. package/src/config.ts +0 -150
  47. package/src/do-sql-tracking.test.ts +0 -19
  48. package/src/do-sql-tracking.ts +0 -19
  49. package/src/index.ts +0 -1215
  50. package/src/integration/integration.test.ts +0 -517
  51. package/src/integration/native-binary.guard.test.ts +0 -13
  52. package/src/integration/native-startup.test.ts +0 -44
  53. package/src/integration/replication-latency.test.ts +0 -428
  54. package/src/integration/restore-live-stress.test.ts +0 -433
  55. package/src/integration/restore-reset.test.ts +0 -400
  56. package/src/integration/restore.test.ts +0 -274
  57. package/src/integration/test-permissions.ts +0 -147
  58. package/src/load-config.ts +0 -46
  59. package/src/log.ts +0 -96
  60. package/src/mutex.ts +0 -47
  61. package/src/pg-proxy-browser.singledb.test.ts +0 -233
  62. package/src/pg-proxy-browser.ts +0 -2022
  63. package/src/pg-proxy-do-backend.test.ts +0 -3890
  64. package/src/pg-proxy-do-backend.ts +0 -7191
  65. package/src/pg-proxy.ts +0 -1087
  66. package/src/pg-sqlite-compiler/README.md +0 -53
  67. package/src/pg-sqlite-compiler/catalog/seed.ts +0 -524
  68. package/src/pg-sqlite-compiler/fixtures/pgsqlite/arithmetic.json +0 -307
  69. package/src/pg-sqlite-compiler/fixtures/pgsqlite/array.json +0 -377
  70. package/src/pg-sqlite-compiler/fixtures/pgsqlite/cast.json +0 -12
  71. package/src/pg-sqlite-compiler/fixtures/pgsqlite/catalog.json +0 -447
  72. package/src/pg-sqlite-compiler/fixtures/pgsqlite/create-table.json +0 -32
  73. package/src/pg-sqlite-compiler/fixtures/pgsqlite/datetime.json +0 -397
  74. package/src/pg-sqlite-compiler/fixtures/pgsqlite/enum.json +0 -337
  75. package/src/pg-sqlite-compiler/fixtures/pgsqlite/insert.json +0 -337
  76. package/src/pg-sqlite-compiler/fixtures/pgsqlite/json.json +0 -537
  77. package/src/pg-sqlite-compiler/fixtures/pgsqlite/misc.json +0 -1837
  78. package/src/pg-sqlite-compiler/index.ts +0 -73
  79. package/src/pg-sqlite-compiler/integration.test.ts +0 -136
  80. package/src/pg-sqlite-compiler/passes/ast-utils.ts +0 -113
  81. package/src/pg-sqlite-compiler/passes/catalog.ts +0 -65
  82. package/src/pg-sqlite-compiler/passes/datetime.ts +0 -74
  83. package/src/pg-sqlite-compiler/passes/index.ts +0 -49
  84. package/src/pg-sqlite-compiler/passes/types.ts +0 -156
  85. package/src/pg-sqlite-compiler/smoke.test.ts +0 -69
  86. package/src/pg-sqlite-compiler/test/catalog.test.ts +0 -171
  87. package/src/pg-sqlite-compiler/test/corpus.test.ts +0 -161
  88. package/src/pg-sqlite-compiler/test/datetime.oracle.test.ts +0 -102
  89. package/src/pg-sqlite-compiler/test/oracle.ts +0 -237
  90. package/src/pg-sqlite-compiler/test/types.test.ts +0 -109
  91. package/src/pg-sqlite-compiler/types.ts +0 -63
  92. package/src/pglite-ipc.test.ts +0 -116
  93. package/src/pglite-ipc.ts +0 -266
  94. package/src/pglite-manager.ts +0 -557
  95. package/src/pglite-web-proxy.test.ts +0 -57
  96. package/src/pglite-web-proxy.ts +0 -221
  97. package/src/pglite-web-worker.ts +0 -152
  98. package/src/pglite-worker-thread.ts +0 -253
  99. package/src/port.ts +0 -25
  100. package/src/process-title.ts +0 -9
  101. package/src/recovery.ts +0 -155
  102. package/src/replication/change-tracker.test.ts +0 -357
  103. package/src/replication/change-tracker.ts +0 -279
  104. package/src/replication/handler.test.ts +0 -511
  105. package/src/replication/handler.ts +0 -1190
  106. package/src/replication/pgoutput-encoder.test.ts +0 -697
  107. package/src/replication/pgoutput-encoder.ts +0 -373
  108. package/src/replication/tcp-replication.test.ts +0 -876
  109. package/src/replication/zero-compat.test.ts +0 -1150
  110. package/src/restore-stress.test.ts +0 -188
  111. package/src/s3-local.ts +0 -203
  112. package/src/shim/hooks.mjs +0 -120
  113. package/src/shim/register.mjs +0 -4
  114. package/src/sqlite-mode/apply-mode.ts +0 -224
  115. package/src/sqlite-mode/index.ts +0 -15
  116. package/src/sqlite-mode/native-binary.ts +0 -89
  117. package/src/sqlite-mode/package-resolve.ts +0 -17
  118. package/src/sqlite-mode/resolve-mode.ts +0 -80
  119. package/src/sqlite-mode/shim-template.ts +0 -159
  120. package/src/sqlite-mode/sqlite-mode.test.ts +0 -427
  121. package/src/sqlite-mode/types.ts +0 -30
  122. package/src/vite-plugin.ts +0 -67
  123. package/src/wasm-sqlite.test.ts +0 -537
  124. package/src/worker/browser-admin.ts +0 -52
  125. package/src/worker/browser-build-config.test.ts +0 -71
  126. package/src/worker/browser-build-config.ts +0 -109
  127. package/src/worker/browser-embed-admin.test.ts +0 -75
  128. package/src/worker/browser-embed.ts +0 -345
  129. package/src/worker/cf-patches.ts +0 -384
  130. package/src/worker/embed-integration.test.ts +0 -321
  131. package/src/worker/index.ts +0 -138
  132. package/src/worker/shims/fastify.test.ts +0 -255
  133. package/src/worker/shims/fastify.ts +0 -306
  134. package/src/worker/shims/http-service.test.ts +0 -355
  135. package/src/worker/shims/http-service.ts +0 -293
  136. package/src/worker/shims/node-stub.ts +0 -290
  137. package/src/worker/shims/oxfmt.ts +0 -3
  138. package/src/worker/shims/postgres-browser.ts +0 -59
  139. package/src/worker/shims/postgres-socket.test.ts +0 -576
  140. package/src/worker/shims/postgres-socket.ts +0 -310
  141. package/src/worker/shims/postgres.test.ts +0 -364
  142. package/src/worker/shims/postgres.ts +0 -1454
  143. package/src/worker/shims/sqlite-browser.test.ts +0 -233
  144. package/src/worker/shims/sqlite-browser.ts +0 -175
  145. package/src/worker/shims/sqlite.test.ts +0 -786
  146. package/src/worker/shims/sqlite.ts +0 -978
  147. package/src/worker/shims/stream-browser.ts +0 -15
  148. package/src/worker/shims/ws-browser.test.ts +0 -205
  149. package/src/worker/shims/ws-browser.ts +0 -248
  150. package/src/worker/shims/ws.test.ts +0 -288
  151. package/src/worker/shims/ws.ts +0 -467
  152. package/src/worker/shims/zero-process-env.ts +0 -11
  153. package/src/worker/types.ts +0 -75
  154. package/src/worker/worker-integration.test.ts +0 -223
  155. package/src/worker/worker.test.ts +0 -136
  156. package/src/worker/zero-cache-embed-cf.ts +0 -463
  157. 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
- }