orez 0.2.26 → 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 (172) hide show
  1. package/dist/cf-do/worker.d.ts.map +1 -1
  2. package/dist/cf-do/worker.js +9 -1
  3. package/dist/cf-do/worker.js.map +1 -1
  4. package/dist/pg-proxy-do-backend.d.ts +2 -0
  5. package/dist/pg-proxy-do-backend.d.ts.map +1 -1
  6. package/dist/pg-proxy-do-backend.js +49 -7
  7. package/dist/pg-proxy-do-backend.js.map +1 -1
  8. package/dist/pg-sqlite-compiler/catalog/seed.d.ts +67 -0
  9. package/dist/pg-sqlite-compiler/catalog/seed.d.ts.map +1 -0
  10. package/dist/pg-sqlite-compiler/catalog/seed.js +436 -0
  11. package/dist/pg-sqlite-compiler/catalog/seed.js.map +1 -0
  12. package/dist/pg-sqlite-compiler/index.d.ts +12 -0
  13. package/dist/pg-sqlite-compiler/index.d.ts.map +1 -0
  14. package/dist/pg-sqlite-compiler/index.js +59 -0
  15. package/dist/pg-sqlite-compiler/index.js.map +1 -0
  16. package/dist/pg-sqlite-compiler/passes/ast-utils.d.ts +48 -0
  17. package/dist/pg-sqlite-compiler/passes/ast-utils.d.ts.map +1 -0
  18. package/dist/pg-sqlite-compiler/passes/ast-utils.js +93 -0
  19. package/dist/pg-sqlite-compiler/passes/ast-utils.js.map +1 -0
  20. package/dist/pg-sqlite-compiler/passes/catalog.d.ts +34 -0
  21. package/dist/pg-sqlite-compiler/passes/catalog.d.ts.map +1 -0
  22. package/dist/pg-sqlite-compiler/passes/catalog.js +30 -0
  23. package/dist/pg-sqlite-compiler/passes/catalog.js.map +1 -0
  24. package/dist/pg-sqlite-compiler/passes/datetime.d.ts +21 -0
  25. package/dist/pg-sqlite-compiler/passes/datetime.d.ts.map +1 -0
  26. package/dist/pg-sqlite-compiler/passes/datetime.js +53 -0
  27. package/dist/pg-sqlite-compiler/passes/datetime.js.map +1 -0
  28. package/dist/pg-sqlite-compiler/passes/index.d.ts +21 -0
  29. package/dist/pg-sqlite-compiler/passes/index.d.ts.map +1 -0
  30. package/dist/pg-sqlite-compiler/passes/index.js +39 -0
  31. package/dist/pg-sqlite-compiler/passes/index.js.map +1 -0
  32. package/dist/pg-sqlite-compiler/passes/types.d.ts +41 -0
  33. package/dist/pg-sqlite-compiler/passes/types.d.ts.map +1 -0
  34. package/dist/pg-sqlite-compiler/passes/types.js +103 -0
  35. package/dist/pg-sqlite-compiler/passes/types.js.map +1 -0
  36. package/dist/pg-sqlite-compiler/test/oracle.d.ts +34 -0
  37. package/dist/pg-sqlite-compiler/test/oracle.d.ts.map +1 -0
  38. package/dist/pg-sqlite-compiler/test/oracle.js +204 -0
  39. package/dist/pg-sqlite-compiler/test/oracle.js.map +1 -0
  40. package/dist/pg-sqlite-compiler/types.d.ts +55 -0
  41. package/dist/pg-sqlite-compiler/types.d.ts.map +1 -0
  42. package/dist/pg-sqlite-compiler/types.js +2 -0
  43. package/dist/pg-sqlite-compiler/types.js.map +1 -0
  44. package/package.json +8 -4
  45. package/src/admin/admin-data.test.ts +0 -348
  46. package/src/admin/http-proxy.ts +0 -252
  47. package/src/admin/log-store.ts +0 -192
  48. package/src/admin/server.ts +0 -471
  49. package/src/admin/ui.ts +0 -1322
  50. package/src/bench/proxy-throughput.bench.ts +0 -343
  51. package/src/bench/serial-mutations.bench.ts +0 -270
  52. package/src/browser.ts +0 -203
  53. package/src/cf-do/.wrangler/cache/cf.json +0 -1
  54. package/src/cf-do/.wrangler/state/v3/cache/miniflare-CacheObject/metadata.sqlite +0 -0
  55. package/src/cf-do/.wrangler/state/v3/cache/miniflare-CacheObject/metadata.sqlite-shm +0 -0
  56. package/src/cf-do/.wrangler/state/v3/cache/miniflare-CacheObject/metadata.sqlite-wal +0 -0
  57. package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/0f0f3bdf0abda097eb6f1246db4657d9fc622081362d894d82c1a1ce067b05b6.sqlite +0 -0
  58. package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/1ddd3a4a48a11b51658444f5458a1fb175194b1d5b6a5bda20ef3fe3205b900c.sqlite +0 -0
  59. package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/204a39120310d37e972c5914cfd71ad55c151bdb9e8ed289a5f8c5b052dd60e4.sqlite +0 -0
  60. package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/3835f242df9728adba3d127a238793fd054ed3e51df3f60749ee744c469bf2a2.sqlite +0 -0
  61. package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/4aa9c80eb716cf55b8995ccf7afab0b36c683e6da07d7c37a3f9c570136036df.sqlite +0 -0
  62. package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/533e2fd1d6ea46e7a9a0017916ef341802d438d72583462755f2c1f8225e9bf2.sqlite +0 -0
  63. package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/5ffa1aced1225ecaeac6366f7586aa3de92761cdff8711d81fbd81f248076abd.sqlite +0 -0
  64. package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/686c3a9f0d7e59ed2ab607efd4b76d779c97cafeb3818380033bf7c7eb86c819.sqlite +0 -0
  65. package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/6e8214e8dcfadd0deb52d64e5e9ca85c6b329ace11193909845995396914c473.sqlite +0 -0
  66. package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/78d9ec9ff873d3fe3507ff53c2a6f6dfc408b4268eb0db3f2a146c0678965366.sqlite +0 -0
  67. package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/7eff9f0ed7e27ad0d3f9d923de0682fab1928591172c1ba336c5f79a134a5d85.sqlite +0 -0
  68. package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/836cda5b995b25867d722ed4f4c2292167e80351a3c6038db626648eb247dd8b.sqlite +0 -0
  69. package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/91ef63b112209ab30172763acd8a0935106c248f7f1bcae5545ce37a9f201551.sqlite +0 -0
  70. package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/a66ea4293a5f5938bc6d116edfa2522bb85bc37aea3541fbc09c3b613b9b32c0.sqlite +0 -0
  71. package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/ceb2ab26b80590840b65651deb6e948d3bf81565c6751f3a58752cf4bf4aecae.sqlite +0 -0
  72. package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/metadata.sqlite +0 -0
  73. package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/metadata.sqlite-shm +0 -0
  74. package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/metadata.sqlite-wal +0 -0
  75. package/src/cf-do/ARCHITECTURE.md +0 -83
  76. package/src/cf-do/watermark.test.ts +0 -103
  77. package/src/cf-do/watermark.ts +0 -118
  78. package/src/cf-do/worker.ts +0 -1033
  79. package/src/cf-do/wrangler.toml +0 -11
  80. package/src/cf-pglite/README.md +0 -19
  81. package/src/change-tracking.ts +0 -25
  82. package/src/child-process.test.ts +0 -147
  83. package/src/child-process.ts +0 -90
  84. package/src/cli-entry.ts +0 -72
  85. package/src/cli.test.ts +0 -38
  86. package/src/cli.ts +0 -1214
  87. package/src/config.ts +0 -150
  88. package/src/do-sql-tracking.test.ts +0 -19
  89. package/src/do-sql-tracking.ts +0 -19
  90. package/src/index.ts +0 -1215
  91. package/src/integration/integration.test.ts +0 -517
  92. package/src/integration/native-binary.guard.test.ts +0 -13
  93. package/src/integration/native-startup.test.ts +0 -44
  94. package/src/integration/replication-latency.test.ts +0 -428
  95. package/src/integration/restore-live-stress.test.ts +0 -433
  96. package/src/integration/restore-reset.test.ts +0 -400
  97. package/src/integration/restore.test.ts +0 -274
  98. package/src/integration/test-permissions.ts +0 -147
  99. package/src/load-config.ts +0 -46
  100. package/src/log.ts +0 -96
  101. package/src/mutex.ts +0 -47
  102. package/src/pg-proxy-browser.singledb.test.ts +0 -233
  103. package/src/pg-proxy-browser.ts +0 -2022
  104. package/src/pg-proxy-do-backend.test.ts +0 -3890
  105. package/src/pg-proxy-do-backend.ts +0 -7157
  106. package/src/pg-proxy.ts +0 -1087
  107. package/src/pglite-ipc.test.ts +0 -116
  108. package/src/pglite-ipc.ts +0 -266
  109. package/src/pglite-manager.ts +0 -557
  110. package/src/pglite-web-proxy.test.ts +0 -57
  111. package/src/pglite-web-proxy.ts +0 -221
  112. package/src/pglite-web-worker.ts +0 -152
  113. package/src/pglite-worker-thread.ts +0 -253
  114. package/src/port.ts +0 -25
  115. package/src/process-title.ts +0 -9
  116. package/src/recovery.ts +0 -155
  117. package/src/replication/change-tracker.test.ts +0 -357
  118. package/src/replication/change-tracker.ts +0 -279
  119. package/src/replication/handler.test.ts +0 -511
  120. package/src/replication/handler.ts +0 -1190
  121. package/src/replication/pgoutput-encoder.test.ts +0 -697
  122. package/src/replication/pgoutput-encoder.ts +0 -373
  123. package/src/replication/tcp-replication.test.ts +0 -876
  124. package/src/replication/zero-compat.test.ts +0 -1150
  125. package/src/restore-stress.test.ts +0 -188
  126. package/src/s3-local.ts +0 -203
  127. package/src/shim/hooks.mjs +0 -120
  128. package/src/shim/register.mjs +0 -4
  129. package/src/sqlite-mode/apply-mode.ts +0 -224
  130. package/src/sqlite-mode/index.ts +0 -15
  131. package/src/sqlite-mode/native-binary.ts +0 -89
  132. package/src/sqlite-mode/package-resolve.ts +0 -17
  133. package/src/sqlite-mode/resolve-mode.ts +0 -80
  134. package/src/sqlite-mode/shim-template.ts +0 -159
  135. package/src/sqlite-mode/sqlite-mode.test.ts +0 -427
  136. package/src/sqlite-mode/types.ts +0 -30
  137. package/src/vite-plugin.ts +0 -67
  138. package/src/wasm-sqlite.test.ts +0 -537
  139. package/src/worker/browser-admin.ts +0 -52
  140. package/src/worker/browser-build-config.test.ts +0 -71
  141. package/src/worker/browser-build-config.ts +0 -109
  142. package/src/worker/browser-embed-admin.test.ts +0 -75
  143. package/src/worker/browser-embed.ts +0 -345
  144. package/src/worker/cf-patches.ts +0 -384
  145. package/src/worker/embed-integration.test.ts +0 -321
  146. package/src/worker/index.ts +0 -138
  147. package/src/worker/shims/fastify.test.ts +0 -255
  148. package/src/worker/shims/fastify.ts +0 -306
  149. package/src/worker/shims/http-service.test.ts +0 -355
  150. package/src/worker/shims/http-service.ts +0 -293
  151. package/src/worker/shims/node-stub.ts +0 -290
  152. package/src/worker/shims/oxfmt.ts +0 -3
  153. package/src/worker/shims/postgres-browser.ts +0 -59
  154. package/src/worker/shims/postgres-socket.test.ts +0 -576
  155. package/src/worker/shims/postgres-socket.ts +0 -310
  156. package/src/worker/shims/postgres.test.ts +0 -364
  157. package/src/worker/shims/postgres.ts +0 -1454
  158. package/src/worker/shims/sqlite-browser.test.ts +0 -233
  159. package/src/worker/shims/sqlite-browser.ts +0 -175
  160. package/src/worker/shims/sqlite.test.ts +0 -786
  161. package/src/worker/shims/sqlite.ts +0 -978
  162. package/src/worker/shims/stream-browser.ts +0 -15
  163. package/src/worker/shims/ws-browser.test.ts +0 -205
  164. package/src/worker/shims/ws-browser.ts +0 -248
  165. package/src/worker/shims/ws.test.ts +0 -288
  166. package/src/worker/shims/ws.ts +0 -467
  167. package/src/worker/shims/zero-process-env.ts +0 -11
  168. package/src/worker/types.ts +0 -75
  169. package/src/worker/worker-integration.test.ts +0 -223
  170. package/src/worker/worker.test.ts +0 -136
  171. package/src/worker/zero-cache-embed-cf.ts +0 -463
  172. package/src/worker/zero-cache-embed.ts +0 -277
@@ -1,576 +0,0 @@
1
- import { Buffer } from 'buffer'
2
-
3
- import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'
4
-
5
- import { createSocketFactory } from './postgres-socket.js'
6
-
7
- // helper: create a socket via factory, capturing the proxy-side port
8
- function createTestSocket() {
9
- let proxyPort: MessagePort | null = null
10
- const factory = createSocketFactory((port) => {
11
- proxyPort = port
12
- })
13
- const socket = factory()
14
- return {
15
- socket,
16
- get proxyPort() {
17
- return proxyPort!
18
- },
19
- }
20
- }
21
-
22
- // helper: wait for next microtask
23
- function tick() {
24
- return new Promise<void>((r) => queueMicrotask(r))
25
- }
26
-
27
- // helper: wait for next macrotask
28
- function nextTick(ms = 0) {
29
- return new Promise<void>((r) => setTimeout(r, ms))
30
- }
31
-
32
- describe('MessagePortSocket', () => {
33
- describe('readyState lifecycle', () => {
34
- it('starts as opening, transitions to open after microtask', async () => {
35
- const { socket } = createTestSocket()
36
- expect(socket.readyState).toBe('opening')
37
- expect(socket.connecting).toBe(true)
38
- expect(socket.pending).toBe(true)
39
-
40
- await tick()
41
-
42
- expect(socket.readyState).toBe('open')
43
- expect(socket.connecting).toBe(false)
44
- expect(socket.pending).toBe(false)
45
- })
46
-
47
- it('transitions to closed after destroy', async () => {
48
- const { socket } = createTestSocket()
49
- await tick()
50
- expect(socket.readyState).toBe('open')
51
-
52
- socket.destroy()
53
- expect(socket.readyState).toBe('closed')
54
- expect(socket.destroyed).toBe(true)
55
- })
56
-
57
- it('stays closed if destroyed before open', () => {
58
- const { socket } = createTestSocket()
59
- socket.destroy()
60
- expect(socket.readyState).toBe('closed')
61
- })
62
- })
63
-
64
- describe('connect and ready events', () => {
65
- it('emits connect and ready after microtask', async () => {
66
- const { socket } = createTestSocket()
67
- const events: string[] = []
68
- socket.on('connect', () => events.push('connect'))
69
- socket.on('ready', () => events.push('ready'))
70
-
71
- await tick()
72
- expect(events).toEqual(['connect', 'ready'])
73
- })
74
-
75
- it('does not emit connect/ready if destroyed before microtask', async () => {
76
- const { socket } = createTestSocket()
77
- const events: string[] = []
78
- socket.on('connect', () => events.push('connect'))
79
- socket.on('ready', () => events.push('ready'))
80
-
81
- socket.destroy()
82
- await tick()
83
- expect(events).toEqual([])
84
- })
85
- })
86
-
87
- describe('write', () => {
88
- it('sends data to proxy port as ArrayBuffer', async () => {
89
- const { socket, proxyPort } = createTestSocket()
90
- await tick()
91
-
92
- const received: ArrayBuffer[] = []
93
- proxyPort.onmessage = (ev: MessageEvent) => {
94
- received.push(ev.data)
95
- }
96
- proxyPort.start()
97
-
98
- const data = Buffer.from([0x51, 0x00, 0x00, 0x00, 0x04])
99
- socket.write(data)
100
-
101
- await nextTick(10)
102
- expect(received.length).toBe(1)
103
- expect(new Uint8Array(received[0])).toEqual(
104
- new Uint8Array([0x51, 0x00, 0x00, 0x00, 0x04])
105
- )
106
- })
107
-
108
- it('returns true on successful write', async () => {
109
- const { socket } = createTestSocket()
110
- await tick()
111
- expect(socket.write(Buffer.from([1, 2, 3]))).toBe(true)
112
- })
113
-
114
- it('returns false when destroyed', async () => {
115
- const { socket } = createTestSocket()
116
- await tick()
117
- socket.destroy()
118
- expect(socket.write(Buffer.from([1, 2, 3]))).toBe(false)
119
- })
120
-
121
- it('calls callback (as encoding arg)', async () => {
122
- const { socket } = createTestSocket()
123
- await tick()
124
- const cb = vi.fn()
125
- socket.write(Buffer.from([1]), cb)
126
- expect(cb).toHaveBeenCalled()
127
- })
128
-
129
- it('calls callback (as third arg)', async () => {
130
- const { socket } = createTestSocket()
131
- await tick()
132
- const cb = vi.fn()
133
- socket.write(Buffer.from([1]), 'utf8', cb)
134
- expect(cb).toHaveBeenCalled()
135
- })
136
-
137
- it('tracks bytesWritten', async () => {
138
- const { socket } = createTestSocket()
139
- await tick()
140
- expect(socket.bytesWritten).toBe(0)
141
- socket.write(Buffer.from([1, 2, 3]))
142
- expect(socket.bytesWritten).toBe(3)
143
- socket.write(Buffer.from([4, 5]))
144
- expect(socket.bytesWritten).toBe(5)
145
- })
146
-
147
- it('handles string data', async () => {
148
- const { socket, proxyPort } = createTestSocket()
149
- await tick()
150
-
151
- const received: ArrayBuffer[] = []
152
- proxyPort.onmessage = (ev: MessageEvent) => received.push(ev.data)
153
- proxyPort.start()
154
-
155
- socket.write('hello')
156
- await nextTick(10)
157
- expect(received.length).toBe(1)
158
- expect(Buffer.from(new Uint8Array(received[0])).toString()).toBe('hello')
159
- })
160
- })
161
-
162
- describe('data reception', () => {
163
- it('emits data as Buffer when proxy sends ArrayBuffer', async () => {
164
- const { socket, proxyPort } = createTestSocket()
165
- await tick()
166
-
167
- const chunks: Buffer[] = []
168
- socket.on('data', (buf: Buffer) => chunks.push(buf))
169
-
170
- const data = new Uint8Array([0x52, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00])
171
- const copy = new Uint8Array(data)
172
- proxyPort.postMessage(copy.buffer, [copy.buffer])
173
-
174
- await nextTick(10)
175
- expect(chunks.length).toBe(1)
176
- expect(chunks[0]).toBeInstanceOf(Buffer)
177
- expect(chunks[0].readUInt8(0)).toBe(0x52)
178
- })
179
-
180
- it('emits data as Buffer when proxy sends Uint8Array', async () => {
181
- const { socket, proxyPort } = createTestSocket()
182
- await tick()
183
-
184
- const chunks: Buffer[] = []
185
- socket.on('data', (buf: Buffer) => chunks.push(buf))
186
-
187
- const data = new Uint8Array([1, 2, 3])
188
- proxyPort.postMessage(data)
189
-
190
- await nextTick(10)
191
- expect(chunks.length).toBe(1)
192
- expect(chunks[0]).toBeInstanceOf(Buffer)
193
- })
194
-
195
- it('tracks bytesRead', async () => {
196
- const { socket, proxyPort } = createTestSocket()
197
- await tick()
198
-
199
- socket.on('data', () => {}) // must have listener
200
- expect(socket.bytesRead).toBe(0)
201
-
202
- const data = new Uint8Array([1, 2, 3, 4, 5])
203
- proxyPort.postMessage(data)
204
-
205
- await nextTick(10)
206
- expect(socket.bytesRead).toBe(5)
207
- })
208
-
209
- it('ignores data after destroy', async () => {
210
- const { socket, proxyPort } = createTestSocket()
211
- await tick()
212
-
213
- const chunks: Buffer[] = []
214
- socket.on('data', (buf: Buffer) => chunks.push(buf))
215
-
216
- socket.destroy()
217
- proxyPort.postMessage(new Uint8Array([1, 2, 3]))
218
-
219
- await nextTick(10)
220
- expect(chunks.length).toBe(0)
221
- })
222
- })
223
-
224
- describe('pause/resume', () => {
225
- it('buffers data while paused', async () => {
226
- const { socket, proxyPort } = createTestSocket()
227
- await tick()
228
-
229
- const chunks: Buffer[] = []
230
- socket.on('data', (buf: Buffer) => chunks.push(buf))
231
-
232
- socket.pause()
233
- proxyPort.postMessage(new Uint8Array([1]))
234
- proxyPort.postMessage(new Uint8Array([2]))
235
- proxyPort.postMessage(new Uint8Array([3]))
236
-
237
- await nextTick(10)
238
- expect(chunks.length).toBe(0)
239
-
240
- socket.resume()
241
- expect(chunks.length).toBe(3)
242
- expect(chunks[0][0]).toBe(1)
243
- expect(chunks[1][0]).toBe(2)
244
- expect(chunks[2][0]).toBe(3)
245
- })
246
-
247
- it('handles re-entrant pause during resume flush', async () => {
248
- const { socket, proxyPort } = createTestSocket()
249
- await tick()
250
-
251
- const chunks: Buffer[] = []
252
- let pauseAfter = 2
253
- socket.on('data', (buf: Buffer) => {
254
- chunks.push(buf)
255
- if (chunks.length === pauseAfter) {
256
- socket.pause()
257
- }
258
- })
259
-
260
- socket.pause()
261
- proxyPort.postMessage(new Uint8Array([1]))
262
- proxyPort.postMessage(new Uint8Array([2]))
263
- proxyPort.postMessage(new Uint8Array([3]))
264
- proxyPort.postMessage(new Uint8Array([4]))
265
-
266
- await nextTick(10)
267
-
268
- // resume flushes first 2, then re-pauses
269
- socket.resume()
270
- expect(chunks.length).toBe(2)
271
- expect(chunks[0][0]).toBe(1)
272
- expect(chunks[1][0]).toBe(2)
273
-
274
- // resume again to get remaining
275
- pauseAfter = 999
276
- socket.resume()
277
- expect(chunks.length).toBe(4)
278
- expect(chunks[2][0]).toBe(3)
279
- expect(chunks[3][0]).toBe(4)
280
- })
281
-
282
- it('resume returns this for chaining', async () => {
283
- const { socket } = createTestSocket()
284
- expect(socket.resume()).toBe(socket)
285
- })
286
-
287
- it('pause returns this for chaining', async () => {
288
- const { socket } = createTestSocket()
289
- expect(socket.pause()).toBe(socket)
290
- })
291
- })
292
-
293
- describe('end', () => {
294
- it('writes final data then destroys via microtask', async () => {
295
- const { socket, proxyPort } = createTestSocket()
296
- await tick()
297
-
298
- const received: ArrayBuffer[] = []
299
- proxyPort.onmessage = (ev: MessageEvent) => received.push(ev.data)
300
- proxyPort.start()
301
-
302
- const terminateMsg = Buffer.from([0x58, 0x00, 0x00, 0x00, 0x04])
303
- socket.end(terminateMsg)
304
-
305
- // not yet destroyed (deferred)
306
- expect(socket.destroyed).toBe(false)
307
-
308
- await tick()
309
- expect(socket.destroyed).toBe(true)
310
-
311
- await nextTick(10)
312
- expect(received.length).toBe(1)
313
- })
314
-
315
- it('terminate flow: end(X) then once(close) resolves', async () => {
316
- // regression test: postgres terminate() calls socket.end(X_msg)
317
- // then registers socket.once('close', resolve). the close event
318
- // must fire AFTER the listener is registered, not before.
319
- const { socket } = createTestSocket()
320
- await tick()
321
-
322
- const terminateMsg = Buffer.from([0x58, 0x00, 0x00, 0x00, 0x04])
323
- socket.end(terminateMsg)
324
-
325
- // this is what postgres does right after socket.end():
326
- const closed = await Promise.race([
327
- new Promise<boolean>((r) => socket.once('close', () => r(true))),
328
- nextTick(500).then(() => false),
329
- ])
330
-
331
- expect(closed).toBe(true)
332
- })
333
-
334
- it('calls callback', async () => {
335
- const { socket } = createTestSocket()
336
- await tick()
337
- const cb = vi.fn()
338
- socket.end(cb)
339
- expect(cb).toHaveBeenCalled()
340
- })
341
- })
342
-
343
- describe('destroy', () => {
344
- it('emits end then close', async () => {
345
- const { socket } = createTestSocket()
346
- await tick()
347
-
348
- const events: string[] = []
349
- socket.on('end', () => events.push('end'))
350
- socket.on('close', () => events.push('close'))
351
-
352
- socket.destroy()
353
- expect(events).toEqual(['end', 'close'])
354
- })
355
-
356
- it('emits error before close when err passed', async () => {
357
- const { socket } = createTestSocket()
358
- await tick()
359
-
360
- const events: string[] = []
361
- socket.on('error', () => events.push('error'))
362
- socket.on('close', (hadError: boolean) => events.push(`close:${hadError}`))
363
-
364
- socket.destroy(new Error('test'))
365
- expect(events).toEqual(['error', 'close:true'])
366
- })
367
-
368
- it('close event has hadError=false without error', async () => {
369
- const { socket } = createTestSocket()
370
- await tick()
371
-
372
- let hadError: boolean | undefined
373
- socket.on('close', (h: boolean) => {
374
- hadError = h
375
- })
376
-
377
- socket.destroy()
378
- expect(hadError).toBe(false)
379
- })
380
-
381
- it('double destroy does not emit duplicate events', async () => {
382
- const { socket } = createTestSocket()
383
- await tick()
384
-
385
- let closeCount = 0
386
- socket.on('close', () => closeCount++)
387
-
388
- socket.destroy()
389
- socket.destroy()
390
- expect(closeCount).toBe(1)
391
- })
392
-
393
- it('returns this for chaining', async () => {
394
- const { socket } = createTestSocket()
395
- expect(socket.destroy()).toBe(socket)
396
- })
397
-
398
- it('sets writable and readable to false', async () => {
399
- const { socket } = createTestSocket()
400
- await tick()
401
- expect(socket.writable).toBe(true)
402
- expect(socket.readable).toBe(true)
403
-
404
- socket.destroy()
405
- expect(socket.writable).toBe(false)
406
- expect(socket.readable).toBe(false)
407
- })
408
-
409
- it('clears pause buffer', async () => {
410
- const { socket, proxyPort } = createTestSocket()
411
- await tick()
412
-
413
- const chunks: Buffer[] = []
414
- socket.on('data', (buf: Buffer) => chunks.push(buf))
415
-
416
- socket.pause()
417
- proxyPort.postMessage(new Uint8Array([1, 2, 3]))
418
- await nextTick(10)
419
-
420
- socket.destroy()
421
-
422
- // resume after destroy should not emit buffered data
423
- socket.resume()
424
- expect(chunks.length).toBe(0)
425
- })
426
- })
427
-
428
- describe('setTimeout', () => {
429
- it('emits timeout after inactivity', async () => {
430
- const { socket } = createTestSocket()
431
- await tick()
432
-
433
- const cb = vi.fn()
434
- socket.setTimeout(50, cb)
435
-
436
- await nextTick(100)
437
- expect(cb).toHaveBeenCalled()
438
- })
439
-
440
- it('resets timeout on write', async () => {
441
- const { socket } = createTestSocket()
442
- await tick()
443
-
444
- const cb = vi.fn()
445
- socket.setTimeout(80, cb)
446
-
447
- // write at 30ms to reset
448
- await nextTick(30)
449
- socket.write(Buffer.from([1]))
450
-
451
- // at 60ms from start (30ms from last write), should not have fired
452
- await nextTick(30)
453
- expect(cb).not.toHaveBeenCalled()
454
-
455
- // at 130ms from start (100ms from last write), should have fired
456
- await nextTick(70)
457
- expect(cb).toHaveBeenCalled()
458
- })
459
-
460
- it('resets timeout on data receive', async () => {
461
- const { socket, proxyPort } = createTestSocket()
462
- await tick()
463
-
464
- const cb = vi.fn()
465
- socket.on('data', () => {}) // need listener
466
- socket.setTimeout(80, cb)
467
-
468
- await nextTick(30)
469
- proxyPort.postMessage(new Uint8Array([1]))
470
-
471
- await nextTick(30)
472
- expect(cb).not.toHaveBeenCalled()
473
-
474
- await nextTick(70)
475
- expect(cb).toHaveBeenCalled()
476
- })
477
-
478
- it('clears timeout when set to 0', async () => {
479
- const { socket } = createTestSocket()
480
- await tick()
481
-
482
- const cb = vi.fn()
483
- socket.setTimeout(50, cb)
484
- socket.setTimeout(0)
485
-
486
- await nextTick(100)
487
- expect(cb).not.toHaveBeenCalled()
488
- })
489
-
490
- it('returns this for chaining', () => {
491
- const { socket } = createTestSocket()
492
- expect(socket.setTimeout(0)).toBe(socket)
493
- })
494
- })
495
-
496
- describe('no-op methods return this', () => {
497
- it('setKeepAlive', () => {
498
- const { socket } = createTestSocket()
499
- expect(socket.setKeepAlive()).toBe(socket)
500
- })
501
-
502
- it('setNoDelay', () => {
503
- const { socket } = createTestSocket()
504
- expect(socket.setNoDelay()).toBe(socket)
505
- })
506
-
507
- it('ref/unref', () => {
508
- const { socket } = createTestSocket()
509
- expect(socket.ref()).toBe(socket)
510
- expect(socket.unref()).toBe(socket)
511
- })
512
-
513
- it('connect', () => {
514
- const { socket } = createTestSocket()
515
- expect(socket.connect()).toBe(socket)
516
- })
517
- })
518
-
519
- describe('address info', () => {
520
- it('remoteAddress is 127.0.0.1', () => {
521
- const { socket } = createTestSocket()
522
- expect(socket.remoteAddress).toBe('127.0.0.1')
523
- })
524
-
525
- it('remotePort is 0', () => {
526
- const { socket } = createTestSocket()
527
- expect(socket.remotePort).toBe(0)
528
- })
529
-
530
- it('remoteFamily is IPv4', () => {
531
- const { socket } = createTestSocket()
532
- expect(socket.remoteFamily).toBe('IPv4')
533
- })
534
-
535
- it('localAddress is 127.0.0.1', () => {
536
- const { socket } = createTestSocket()
537
- expect(socket.localAddress).toBe('127.0.0.1')
538
- })
539
-
540
- it('localPort is 0', () => {
541
- const { socket } = createTestSocket()
542
- expect(socket.localPort).toBe(0)
543
- })
544
-
545
- it('address() returns AddressInfo', () => {
546
- const { socket } = createTestSocket()
547
- expect(socket.address()).toEqual({ address: '127.0.0.1', family: 'IPv4', port: 0 })
548
- })
549
- })
550
-
551
- describe('write error handling', () => {
552
- it('emits error and returns false if postMessage throws', async () => {
553
- const { socket } = createTestSocket()
554
- await tick()
555
-
556
- // destroy the port to force postMessage to throw
557
- // (accessing internals via the factory is not possible, so we'll
558
- // test this by closing the port first)
559
- socket.destroy()
560
-
561
- // after destroy, write returns false (but doesn't throw)
562
- const result = socket.write(Buffer.from([1]))
563
- expect(result).toBe(false)
564
- })
565
- })
566
-
567
- describe('custom properties', () => {
568
- it('allows setting ssl, host properties', () => {
569
- const { socket } = createTestSocket()
570
- socket.ssl = true
571
- socket.host = 'localhost'
572
- expect(socket.ssl).toBe(true)
573
- expect(socket.host).toBe('localhost')
574
- })
575
- })
576
- })