@livestore/common-cf 0.4.0-dev.5 โ 0.4.0-dev.6
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/.tsbuildinfo +1 -1
- package/dist/do-rpc/rpc.test.js +35 -31
- package/dist/do-rpc/rpc.test.js.map +1 -1
- package/dist/ws-rpc/ws-rpc-server.js +2 -2
- package/dist/ws-rpc/ws-rpc-server.js.map +1 -1
- package/dist/ws-rpc/ws-rpc.test.js +36 -32
- package/dist/ws-rpc/ws-rpc.test.js.map +1 -1
- package/package.json +4 -4
- package/src/do-rpc/rpc.test.ts +47 -52
- package/src/ws-rpc/ws-rpc-server.ts +2 -2
- package/src/ws-rpc/ws-rpc.test.ts +63 -59
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
* @see {@link https://developers.cloudflare.com/durable-objects/best-practices/websockets/ Cloudflare WebSocket Best Practices}
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
|
-
import { notYetImplemented } from '@livestore/utils'
|
|
18
|
+
import { notYetImplemented, omitUndefineds } from '@livestore/utils'
|
|
19
19
|
import {
|
|
20
20
|
constVoid,
|
|
21
21
|
Effect,
|
|
@@ -147,7 +147,7 @@ export const setupDurableObjectWebSocketRpc = ({
|
|
|
147
147
|
const ProtocolLive = layerRpcServerWebsocket({
|
|
148
148
|
ws,
|
|
149
149
|
incomingQueue,
|
|
150
|
-
onMessage,
|
|
150
|
+
...omitUndefineds({ onMessage }),
|
|
151
151
|
}).pipe(Layer.provide(RpcSerialization.layerJson))
|
|
152
152
|
|
|
153
153
|
const ServerLive = rpcLayer.pipe(Layer.provide(ProtocolLive))
|
|
@@ -1,58 +1,69 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import {
|
|
2
|
+
Chunk,
|
|
3
|
+
Effect,
|
|
4
|
+
FetchHttpClient,
|
|
5
|
+
Layer,
|
|
6
|
+
Option,
|
|
7
|
+
RpcClient,
|
|
8
|
+
RpcSerialization,
|
|
9
|
+
Socket,
|
|
10
|
+
Stream,
|
|
11
|
+
} from '@livestore/utils/effect'
|
|
12
|
+
import { PlatformNode } from '@livestore/utils/node'
|
|
13
|
+
import { WranglerDevServerService } from '@livestore/utils-dev/node'
|
|
3
14
|
import { Vitest } from '@livestore/utils-dev/node-vitest'
|
|
4
|
-
import {
|
|
15
|
+
import { expect } from 'vitest'
|
|
5
16
|
import { TestRpcs } from './test-fixtures/rpc-schema.ts'
|
|
6
17
|
|
|
7
|
-
|
|
18
|
+
const testTimeout = 60_000
|
|
8
19
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
20
|
+
const withWranglerTest = Vitest.makeWithTestCtx({
|
|
21
|
+
timeout: testTimeout,
|
|
22
|
+
makeLayer: () =>
|
|
23
|
+
WranglerDevServerService.Default({
|
|
24
|
+
cwd: `${import.meta.dirname}/test-fixtures`,
|
|
25
|
+
}).pipe(Layer.provide(PlatformNode.NodeContext.layer), Layer.provide(FetchHttpClient.layer)),
|
|
14
26
|
})
|
|
15
27
|
|
|
16
28
|
const ProtocolLive = Layer.suspend(() =>
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
29
|
+
Effect.gen(function* () {
|
|
30
|
+
const server = yield* WranglerDevServerService
|
|
31
|
+
return RpcClient.layerProtocolSocket().pipe(
|
|
32
|
+
Layer.provide(Socket.layerWebSocket(`ws://localhost:${server.port}`)),
|
|
33
|
+
Layer.provide(Socket.layerWebSocketConstructorGlobal),
|
|
34
|
+
Layer.provide(RpcSerialization.layerJson),
|
|
35
|
+
)
|
|
36
|
+
}).pipe(Layer.unwrapEffect),
|
|
22
37
|
)
|
|
23
38
|
|
|
24
|
-
Vitest.describe('Durable Object WebSocket RPC', { timeout:
|
|
39
|
+
Vitest.describe('Durable Object WebSocket RPC', { timeout: testTimeout }, () => {
|
|
25
40
|
// Direct HTTP RPC client tests
|
|
26
|
-
Vitest.scopedLive(
|
|
27
|
-
|
|
28
|
-
Effect.fn(function* () {
|
|
41
|
+
Vitest.scopedLive('should call ping method', (test) =>
|
|
42
|
+
Effect.gen(function* () {
|
|
29
43
|
const client = yield* RpcClient.make(TestRpcs)
|
|
30
44
|
const result = yield* client.Ping({ message: 'Hello HTTP RPC' })
|
|
31
45
|
expect(result).toEqual({ response: 'Pong: Hello HTTP RPC' })
|
|
32
|
-
}
|
|
46
|
+
}).pipe(Effect.provide(ProtocolLive), withWranglerTest(test)),
|
|
33
47
|
)
|
|
34
48
|
|
|
35
|
-
Vitest.scopedLive(
|
|
36
|
-
|
|
37
|
-
Effect.fn(function* () {
|
|
49
|
+
Vitest.scopedLive('should call echo method', (test) =>
|
|
50
|
+
Effect.gen(function* () {
|
|
38
51
|
const client = yield* RpcClient.make(TestRpcs)
|
|
39
52
|
const result = yield* client.Echo({ text: 'Echo' })
|
|
40
53
|
expect(result).toEqual({ echo: 'Echo: Echo' })
|
|
41
|
-
}
|
|
54
|
+
}).pipe(Effect.provide(ProtocolLive), withWranglerTest(test)),
|
|
42
55
|
)
|
|
43
56
|
|
|
44
|
-
Vitest.scopedLive(
|
|
45
|
-
|
|
46
|
-
Effect.fn(function* () {
|
|
57
|
+
Vitest.scopedLive('should call add method', (test) =>
|
|
58
|
+
Effect.gen(function* () {
|
|
47
59
|
const client = yield* RpcClient.make(TestRpcs)
|
|
48
60
|
const result = yield* client.Add({ a: 15, b: 25 })
|
|
49
61
|
expect(result).toEqual({ result: 40 })
|
|
50
|
-
}
|
|
62
|
+
}).pipe(Effect.provide(ProtocolLive), withWranglerTest(test)),
|
|
51
63
|
)
|
|
52
64
|
|
|
53
|
-
Vitest.scopedLive(
|
|
54
|
-
|
|
55
|
-
Effect.fn(function* () {
|
|
65
|
+
Vitest.scopedLive('should handle RPC fail method', (test) =>
|
|
66
|
+
Effect.gen(function* () {
|
|
56
67
|
const client = yield* RpcClient.make(TestRpcs)
|
|
57
68
|
const error = yield* client.Fail({ message: 'test http failure' }).pipe(Effect.exit)
|
|
58
69
|
expect(error.toString()).toMatchInlineSnapshot(`
|
|
@@ -66,12 +77,11 @@ Vitest.describe('Durable Object WebSocket RPC', { timeout: 5000 }, () => {
|
|
|
66
77
|
}
|
|
67
78
|
}"
|
|
68
79
|
`)
|
|
69
|
-
}
|
|
80
|
+
}).pipe(Effect.provide(ProtocolLive), withWranglerTest(test)),
|
|
70
81
|
)
|
|
71
82
|
|
|
72
|
-
Vitest.scopedLive(
|
|
73
|
-
|
|
74
|
-
Effect.fn(function* () {
|
|
83
|
+
Vitest.scopedLive('should handle defect method', (test) =>
|
|
84
|
+
Effect.gen(function* () {
|
|
75
85
|
const client = yield* RpcClient.make(TestRpcs)
|
|
76
86
|
const error = yield* client.Defect({ message: 'test http defect' }).pipe(Effect.exit)
|
|
77
87
|
expect(error.toString()).toMatchInlineSnapshot(`
|
|
@@ -85,12 +95,11 @@ Vitest.describe('Durable Object WebSocket RPC', { timeout: 5000 }, () => {
|
|
|
85
95
|
}
|
|
86
96
|
}"
|
|
87
97
|
`)
|
|
88
|
-
}
|
|
98
|
+
}).pipe(Effect.provide(ProtocolLive), withWranglerTest(test)),
|
|
89
99
|
)
|
|
90
100
|
|
|
91
|
-
Vitest.scopedLive(
|
|
92
|
-
|
|
93
|
-
Effect.fn(function* () {
|
|
101
|
+
Vitest.scopedLive('should handle streaming RPC via HTTP', (test) =>
|
|
102
|
+
Effect.gen(function* () {
|
|
94
103
|
const client = yield* RpcClient.make(TestRpcs)
|
|
95
104
|
const stream = client.Stream({}).pipe(
|
|
96
105
|
Stream.take(4),
|
|
@@ -98,12 +107,11 @@ Vitest.describe('Durable Object WebSocket RPC', { timeout: 5000 }, () => {
|
|
|
98
107
|
)
|
|
99
108
|
const chunks = yield* Stream.runCollect(stream)
|
|
100
109
|
expect(Chunk.toReadonlyArray(chunks)).toEqual([1, 4, 9, 16]) // squares of 1,2,3,4
|
|
101
|
-
}
|
|
110
|
+
}).pipe(Effect.provide(ProtocolLive), withWranglerTest(test)),
|
|
102
111
|
)
|
|
103
112
|
|
|
104
|
-
Vitest.scopedLive(
|
|
105
|
-
|
|
106
|
-
Effect.fn(function* () {
|
|
113
|
+
Vitest.scopedLive('should handle streaming RPC with error via HTTP', (test) =>
|
|
114
|
+
Effect.gen(function* () {
|
|
107
115
|
const client = yield* RpcClient.make(TestRpcs)
|
|
108
116
|
const stream = client.StreamError({ count: 5, errorAfter: 4 })
|
|
109
117
|
const error = yield* Stream.runCollect(stream).pipe(Effect.exit)
|
|
@@ -118,12 +126,11 @@ Vitest.describe('Durable Object WebSocket RPC', { timeout: 5000 }, () => {
|
|
|
118
126
|
}
|
|
119
127
|
}"
|
|
120
128
|
`)
|
|
121
|
-
}
|
|
129
|
+
}).pipe(Effect.provide(ProtocolLive), withWranglerTest(test)),
|
|
122
130
|
)
|
|
123
131
|
|
|
124
|
-
Vitest.scopedLive(
|
|
125
|
-
|
|
126
|
-
Effect.fn(function* () {
|
|
132
|
+
Vitest.scopedLive('should handle streaming RPC with defect via HTTP', (test) =>
|
|
133
|
+
Effect.gen(function* () {
|
|
127
134
|
const client = yield* RpcClient.make(TestRpcs)
|
|
128
135
|
const stream = client.StreamDefect({ count: 4, defectAfter: 1 })
|
|
129
136
|
const error = yield* Stream.runCollect(stream).pipe(Effect.exit)
|
|
@@ -138,24 +145,22 @@ Vitest.describe('Durable Object WebSocket RPC', { timeout: 5000 }, () => {
|
|
|
138
145
|
}
|
|
139
146
|
}"
|
|
140
147
|
`)
|
|
141
|
-
}
|
|
148
|
+
}).pipe(Effect.provide(ProtocolLive), withWranglerTest(test)),
|
|
142
149
|
)
|
|
143
150
|
|
|
144
|
-
Vitest.scopedLive(
|
|
145
|
-
|
|
146
|
-
Effect.fn(function* () {
|
|
151
|
+
Vitest.scopedLive('should handle stream interruption via HTTP', (test) =>
|
|
152
|
+
Effect.gen(function* () {
|
|
147
153
|
const client = yield* RpcClient.make(TestRpcs)
|
|
148
154
|
const stream = client.StreamInterruptible({ delay: 50, interruptAfterCount: 3 }).pipe(Stream.take(3))
|
|
149
155
|
const chunks = yield* Stream.runCollect(stream)
|
|
150
156
|
expect(Chunk.toReadonlyArray(chunks)).toEqual([1, 2, 3])
|
|
151
|
-
}
|
|
157
|
+
}).pipe(Effect.provide(ProtocolLive), withWranglerTest(test)),
|
|
152
158
|
)
|
|
153
159
|
})
|
|
154
160
|
|
|
155
161
|
Vitest.describe('Hibernation Tests', { timeout: 25000 }, () => {
|
|
156
|
-
Vitest.scopedLive(
|
|
157
|
-
|
|
158
|
-
Effect.fn(function* () {
|
|
162
|
+
Vitest.scopedLive('should maintain RPC functionality after hibernation', (test) =>
|
|
163
|
+
Effect.gen(function* () {
|
|
159
164
|
console.log('๐งช Testing RPC server persistence across hibernation...')
|
|
160
165
|
|
|
161
166
|
// Step 1: Create client and test initial functionality
|
|
@@ -214,12 +219,11 @@ Vitest.describe('Hibernation Tests', { timeout: 25000 }, () => {
|
|
|
214
219
|
console.log('โ
Streaming after hibernation successful')
|
|
215
220
|
|
|
216
221
|
console.log('๐ All RPC operations successful after hibernation!')
|
|
217
|
-
}
|
|
222
|
+
}).pipe(Effect.provide(ProtocolLive), withWranglerTest(test)),
|
|
218
223
|
)
|
|
219
224
|
|
|
220
|
-
Vitest.scopedLive(
|
|
221
|
-
|
|
222
|
-
Effect.fn(function* () {
|
|
225
|
+
Vitest.scopedLive('should handle rapid operations after hibernation', (test) =>
|
|
226
|
+
Effect.gen(function* () {
|
|
223
227
|
console.log('๐งช Testing rapid operations after hibernation...')
|
|
224
228
|
|
|
225
229
|
console.log('Step 1: Establishing initial connection...')
|
|
@@ -266,6 +270,6 @@ Vitest.describe('Hibernation Tests', { timeout: 25000 }, () => {
|
|
|
266
270
|
results.map((r) => r.operation),
|
|
267
271
|
)
|
|
268
272
|
console.log('๐ Rapid operations work correctly after hibernation!')
|
|
269
|
-
}
|
|
273
|
+
}).pipe(Effect.provide(ProtocolLive), withWranglerTest(test)),
|
|
270
274
|
)
|
|
271
275
|
})
|