@livestore/common-cf 0.4.0 → 0.5.0-dev.0
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/declare/cf-declare.d.ts +1 -21
- package/dist/declare/cf-declare.d.ts.map +1 -1
- package/dist/do-rpc/client.d.ts.map +1 -1
- package/dist/do-rpc/client.js +17 -27
- package/dist/do-rpc/client.js.map +1 -1
- package/dist/do-rpc/client.test.d.ts +2 -0
- package/dist/do-rpc/client.test.d.ts.map +1 -0
- package/dist/do-rpc/client.test.js +99 -0
- package/dist/do-rpc/client.test.js.map +1 -0
- package/dist/do-rpc/rpc.test.js +25 -57
- package/dist/do-rpc/rpc.test.js.map +1 -1
- package/dist/do-rpc/server.d.ts +9 -4
- package/dist/do-rpc/server.d.ts.map +1 -1
- package/dist/do-rpc/server.js +84 -43
- package/dist/do-rpc/server.js.map +1 -1
- package/dist/do-rpc/test-fixtures/rpc-schema.d.ts +27 -27
- package/dist/do-rpc/test-fixtures/rpc-schema.js +11 -11
- package/dist/do-rpc/test-fixtures/worker.d.ts.map +1 -1
- package/dist/do-rpc/test-fixtures/worker.js +9 -9
- package/dist/do-rpc/test-fixtures/worker.js.map +1 -1
- package/dist/ws-rpc/test-fixtures/rpc-schema.d.ts +27 -27
- package/dist/ws-rpc/test-fixtures/rpc-schema.js +9 -9
- package/dist/ws-rpc/ws-rpc-server.d.ts +6 -5
- package/dist/ws-rpc/ws-rpc-server.d.ts.map +1 -1
- package/dist/ws-rpc/ws-rpc-server.js +17 -17
- package/dist/ws-rpc/ws-rpc-server.js.map +1 -1
- package/dist/ws-rpc/ws-rpc.test.js +27 -59
- package/dist/ws-rpc/ws-rpc.test.js.map +1 -1
- package/package.json +11 -20
- package/src/declare/cf-declare.ts +1 -1
- package/src/do-rpc/client.test.ts +122 -0
- package/src/do-rpc/client.ts +21 -31
- package/src/do-rpc/rpc.test.ts +29 -59
- package/src/do-rpc/server.ts +119 -54
- package/src/do-rpc/test-fixtures/rpc-schema.ts +11 -11
- package/src/do-rpc/test-fixtures/worker.ts +9 -12
- package/src/ws-rpc/test-fixtures/rpc-schema.ts +9 -9
- package/src/ws-rpc/ws-rpc-server.ts +37 -28
- package/src/ws-rpc/ws-rpc.test.ts +31 -61
|
@@ -5,19 +5,10 @@ export declare const ReadableStream: {
|
|
|
5
5
|
prototype: CF.ReadableStream;
|
|
6
6
|
};
|
|
7
7
|
export declare const Request: {
|
|
8
|
-
new <CfHostMetadata = unknown, Cf = CfProperties<CfHostMetadata>>(input: RequestInfo<CfProperties> | URL, init?: RequestInit<Cf>): Request<CfHostMetadata, Cf>;
|
|
9
|
-
prototype: Request;
|
|
10
|
-
} & {
|
|
11
8
|
new <CfHostMetadata = unknown, Cf = CF.CfProperties<CfHostMetadata>>(input: CF.RequestInfo<CF.CfProperties> | CF.URL, init?: CF.RequestInit<Cf>): CF.Request<CfHostMetadata, Cf>;
|
|
12
9
|
prototype: CF.Request;
|
|
13
10
|
};
|
|
14
11
|
export declare const Response: {
|
|
15
|
-
new (body?: BodyInit | null, init?: ResponseInit): Response;
|
|
16
|
-
prototype: Response;
|
|
17
|
-
error(): Response;
|
|
18
|
-
redirect(url: string, status?: number): Response;
|
|
19
|
-
json(any: any, maybeInit?: ResponseInit | Response): Response;
|
|
20
|
-
} & {
|
|
21
12
|
new (body?: CF.BodyInit | null, init?: CF.ResponseInit): CF.Response;
|
|
22
13
|
prototype: CF.Response;
|
|
23
14
|
error(): CF.Response;
|
|
@@ -25,17 +16,6 @@ export declare const Response: {
|
|
|
25
16
|
json(any: any, maybeInit?: CF.ResponseInit | CF.Response): CF.Response;
|
|
26
17
|
};
|
|
27
18
|
export declare const WebSocket: {
|
|
28
|
-
new (url: string, protocols?: string[] | string): WebSocket;
|
|
29
|
-
prototype: WebSocket;
|
|
30
|
-
readonly READY_STATE_CONNECTING: number;
|
|
31
|
-
readonly CONNECTING: number;
|
|
32
|
-
readonly READY_STATE_OPEN: number;
|
|
33
|
-
readonly OPEN: number;
|
|
34
|
-
readonly READY_STATE_CLOSING: number;
|
|
35
|
-
readonly CLOSING: number;
|
|
36
|
-
readonly READY_STATE_CLOSED: number;
|
|
37
|
-
readonly CLOSED: number;
|
|
38
|
-
} & {
|
|
39
19
|
new (url: string, protocols?: string[] | string): CF.WebSocket;
|
|
40
20
|
prototype: CF.WebSocket;
|
|
41
21
|
readonly READY_STATE_CONNECTING: number;
|
|
@@ -47,7 +27,7 @@ export declare const WebSocket: {
|
|
|
47
27
|
readonly READY_STATE_CLOSED: number;
|
|
48
28
|
readonly CLOSED: number;
|
|
49
29
|
};
|
|
50
|
-
export declare const Rpc: typeof
|
|
30
|
+
export declare const Rpc: typeof CF.Rpc;
|
|
51
31
|
export declare const WebSocketPair: new () => {
|
|
52
32
|
0: CF.WebSocket;
|
|
53
33
|
1: CF.WebSocket;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cf-declare.d.ts","sourceRoot":"","sources":["../../src/declare/cf-declare.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,KAAK,EAAE,MAAM,2BAA2B,CAAA;AAapD,eAAO,MAAM,cAAc;;;;CAA8B,CAAA;AACzD,eAAO,MAAM,OAAO
|
|
1
|
+
{"version":3,"file":"cf-declare.d.ts","sourceRoot":"","sources":["../../src/declare/cf-declare.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,KAAK,EAAE,MAAM,2BAA2B,CAAA;AAapD,eAAO,MAAM,cAAc;;;;CAA8B,CAAA;AACzD,eAAO,MAAM,OAAO;;;CAAuB,CAAA;AAC3C,eAAO,MAAM,QAAQ;;;;;;CAAwB,CAAA;AAC7C,eAAO,MAAM,SAAS;;;;;;;;;;;CAAyB,CAAA;AAC/C,eAAO,MAAM,GAAG,eAAmB,CAAA;AACnC,eAAO,MAAM,aAAa;;;CAA6B,CAAA;AACvD,eAAO,MAAM,4BAA4B,wCAA4C,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/do-rpc/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/do-rpc/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,EAEL,SAAS,EAIV,MAAM,yBAAyB,CAAA;AAEhC,OAAO,KAAK,KAAK,OAAO,MAAM,gBAAgB,CAAA;AAmC9C,UAAU,qBAAqB;IAC7B,OAAO,EAAE,CAAC,OAAO,EAAE,UAAU,KAAK,OAAO,CAAC,UAAU,GAAG,OAAO,CAAC,cAAc,CAAC,CAAA;IAC9E,aAAa,EAAE;QACb,WAAW,EAAE,MAAM,CAAA;QACnB,eAAe,EAAE,MAAM,CAAA;KACxB,CAAA;CACF;AAED;;;GAGG;AACH,eAAO,MAAM,0BAA0B,GAAI,MAAM,qBAAqB,KAAG,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,QAAQ,CACpC,CAAA"}
|
package/dist/do-rpc/client.js
CHANGED
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
import { Effect, Fiber, FiberMap, Layer, RpcClient, RpcSerialization, } from '@livestore/utils/effect';
|
|
2
|
-
/**
|
|
3
|
-
* Processes a ReadableStream response from streaming RPCs.
|
|
4
|
-
* Reads chunks from the stream and writes them as RPC responses.
|
|
5
|
-
*/
|
|
1
|
+
import { Effect, Fiber, FiberMap, Layer, Option, RpcClient, RpcSerialization, } from '@livestore/utils/effect';
|
|
2
|
+
/** Decodes a streaming-RPC `ReadableStream`'s msgpack frames, writing each out as it arrives. */
|
|
6
3
|
const processReadableStream = (stream, parser, writeResponse) => Effect.gen(function* () {
|
|
7
4
|
const reader = stream.getReader();
|
|
8
5
|
yield* Effect.gen(function* () {
|
|
@@ -11,20 +8,10 @@ const processReadableStream = (stream, parser, writeResponse) => Effect.gen(func
|
|
|
11
8
|
if (done === true) {
|
|
12
9
|
break;
|
|
13
10
|
}
|
|
14
|
-
//
|
|
11
|
+
// Server encodes `[message]` per enqueue; merged enqueues arrive as
|
|
12
|
+
// `[[msg1], [msg2], ...]`. `flat(1)` normalizes both to `[msg1, ...]`.
|
|
15
13
|
const decoded = parser.decode(value);
|
|
16
|
-
|
|
17
|
-
// Server sends `parser.encode([message])` per enqueue, so each decoded value is `[message]`.
|
|
18
|
-
// When CF DO RPC merges enqueues in production, we get `[[msg1], [msg2], ...]`.
|
|
19
|
-
// `flat(1)` normalizes both single and merged cases to `[msg1, msg2, ...]`.
|
|
20
|
-
let messages;
|
|
21
|
-
if (Array.isArray(decoded) === true) {
|
|
22
|
-
messages = decoded.flat(1);
|
|
23
|
-
}
|
|
24
|
-
else {
|
|
25
|
-
messages = [decoded];
|
|
26
|
-
}
|
|
27
|
-
// Write each message
|
|
14
|
+
const messages = Array.isArray(decoded) === true ? decoded.flat(1) : [decoded];
|
|
28
15
|
for (const message of messages) {
|
|
29
16
|
yield* writeResponse(message);
|
|
30
17
|
}
|
|
@@ -35,38 +22,41 @@ const processReadableStream = (stream, parser, writeResponse) => Effect.gen(func
|
|
|
35
22
|
* Creates a Protocol layer that uses Cloudflare Durable Object RPC calls.
|
|
36
23
|
* This enables direct RPC communication with Durable Objects using Cloudflare's native RPC.
|
|
37
24
|
*/
|
|
38
|
-
export const layerProtocolDurableObject = (args) => Layer.
|
|
25
|
+
export const layerProtocolDurableObject = (args) => Layer.effect(RpcClient.Protocol, makeProtocolDurableObject(args));
|
|
39
26
|
/**
|
|
40
27
|
* Implementation of the RPC Protocol interface using Cloudflare Durable Object RPC calls.
|
|
41
28
|
* Provides the core protocol methods required by @effect/rpc.
|
|
42
29
|
*/
|
|
43
30
|
const makeProtocolDurableObject = ({ callRpc, }) => RpcClient.Protocol.make(Effect.fnUntraced(function* (writeResponse) {
|
|
44
|
-
const parser = RpcSerialization.msgPack.unsafeMake();
|
|
45
31
|
// Not using an actual `FiberMap` here because it seems to shutdown to early
|
|
46
|
-
// const fiberMap = new Map<string, Fiber.
|
|
32
|
+
// const fiberMap = new Map<string, Fiber.Fiber<void, never>>()
|
|
47
33
|
const fiberMap = yield* FiberMap.make();
|
|
48
|
-
const send = (message) => {
|
|
34
|
+
const send = (clientId, message) => {
|
|
49
35
|
if (message._tag !== 'Request') {
|
|
50
36
|
if (message._tag === 'Interrupt') {
|
|
51
37
|
return Effect.gen(function* () {
|
|
52
38
|
const fiber = yield* FiberMap.get(fiberMap, message.requestId);
|
|
53
|
-
|
|
39
|
+
if (Option.isSome(fiber) === true) {
|
|
40
|
+
yield* Fiber.interrupt(fiber.value);
|
|
41
|
+
}
|
|
54
42
|
}).pipe(Effect.orDie);
|
|
55
43
|
}
|
|
56
44
|
return Effect.void;
|
|
57
45
|
}
|
|
46
|
+
// MessagePack parsers buffer incomplete frames, so scope one parser to one DO RPC call.
|
|
47
|
+
const parser = RpcSerialization.msgPack.makeUnsafe();
|
|
58
48
|
// Wrap single Request in array to match server expected format
|
|
59
49
|
const serializedPayload = parser.encode([message]);
|
|
60
50
|
return Effect.gen(function* () {
|
|
61
51
|
const serializedResponse = yield* Effect.tryPromise(() => callRpc(serializedPayload)).pipe(Effect.orDie); // Convert errors to defects to match never error type
|
|
62
52
|
// Handle ReadableStream for streaming responses
|
|
63
53
|
if (serializedResponse instanceof ReadableStream) {
|
|
64
|
-
const fiber = yield* processReadableStream(serializedResponse, parser, writeResponse).pipe(
|
|
54
|
+
const fiber = yield* processReadableStream(serializedResponse, parser, (response) => writeResponse(clientId, response)).pipe(
|
|
65
55
|
// Effect.tapCauseLogPretty,
|
|
66
|
-
Effect.
|
|
56
|
+
Effect.forkChild);
|
|
67
57
|
// fiberMap.set(message.id, fiber)
|
|
68
58
|
yield* FiberMap.set(fiberMap, message.id, fiber);
|
|
69
|
-
yield* fiber;
|
|
59
|
+
yield* Fiber.join(fiber);
|
|
70
60
|
return;
|
|
71
61
|
}
|
|
72
62
|
// Handle regular Uint8Array responses
|
|
@@ -81,7 +71,7 @@ const makeProtocolDurableObject = ({ callRpc, }) => RpcClient.Protocol.make(Effe
|
|
|
81
71
|
}
|
|
82
72
|
// Process each response
|
|
83
73
|
for (const response of responseArray) {
|
|
84
|
-
yield* writeResponse(response);
|
|
74
|
+
yield* writeResponse(clientId, response);
|
|
85
75
|
}
|
|
86
76
|
}).pipe(Effect.withSpan('do-rpc-client:send'), Effect.orDie); // Ensure never error type
|
|
87
77
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/do-rpc/client.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,MAAM,EACN,KAAK,EACL,QAAQ,EACR,KAAK,EACL,SAAS,EAET,gBAAgB,GAEjB,MAAM,yBAAyB,CAAA;AAIhC
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/do-rpc/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.test.d.ts","sourceRoot":"","sources":["../../src/do-rpc/client.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { Vitest } from '@livestore/utils-dev/node-vitest';
|
|
2
|
+
import { Effect, Fiber, Rpc, RpcClient, RpcGroup, Schema, Stream } from '@livestore/utils/effect';
|
|
3
|
+
import { layerProtocolDurableObject } from "./client.js";
|
|
4
|
+
import { toDurableObjectHandler } from "./server.js";
|
|
5
|
+
class Rpcs extends RpcGroup.make(Rpc.make('BigStream', {
|
|
6
|
+
payload: Schema.Struct({ n: Schema.Finite }),
|
|
7
|
+
success: Schema.Struct({
|
|
8
|
+
seqNum: Schema.Finite,
|
|
9
|
+
name: Schema.String,
|
|
10
|
+
args: Schema.Struct({ a: Schema.Finite, b: Schema.String }),
|
|
11
|
+
}),
|
|
12
|
+
stream: true,
|
|
13
|
+
}), Rpc.make('Echo', {
|
|
14
|
+
payload: Schema.Struct({ text: Schema.String }),
|
|
15
|
+
success: Schema.Struct({ echo: Schema.String }),
|
|
16
|
+
})) {
|
|
17
|
+
}
|
|
18
|
+
const READ_CHUNK_SIZE = 4096;
|
|
19
|
+
const expectedRows = [
|
|
20
|
+
{
|
|
21
|
+
seqNum: 0,
|
|
22
|
+
name: 'event-0',
|
|
23
|
+
args: { a: 0, b: 'x'.repeat(READ_CHUNK_SIZE) },
|
|
24
|
+
},
|
|
25
|
+
];
|
|
26
|
+
const ServerLive = Rpcs.toLayer({
|
|
27
|
+
BigStream: ({ n }) => Stream.fromIterable(expectedRows.slice(0, n)),
|
|
28
|
+
Echo: ({ text }) => Effect.succeed({ echo: `Echo: ${text}` }),
|
|
29
|
+
});
|
|
30
|
+
Vitest.live('keeps a straddling stream frame isolated from a concurrent unary response', () => Effect.gen(function* () {
|
|
31
|
+
let signalFirstStreamRead = () => { };
|
|
32
|
+
const firstStreamReadDone = new Promise((resolve) => {
|
|
33
|
+
signalFirstStreamRead = resolve;
|
|
34
|
+
});
|
|
35
|
+
let releaseStreamTail = () => { };
|
|
36
|
+
const streamTailReleased = new Promise((resolve) => {
|
|
37
|
+
releaseStreamTail = resolve;
|
|
38
|
+
});
|
|
39
|
+
const streamWithGatedTail = (bytes) => {
|
|
40
|
+
let pos = 0;
|
|
41
|
+
let isFirstRead = true;
|
|
42
|
+
const stream = new ReadableStream({
|
|
43
|
+
async pull(controller) {
|
|
44
|
+
if (pos >= bytes.length)
|
|
45
|
+
return controller.close();
|
|
46
|
+
if (isFirstRead === false)
|
|
47
|
+
await streamTailReleased;
|
|
48
|
+
controller.enqueue(bytes.subarray(pos, pos + READ_CHUNK_SIZE));
|
|
49
|
+
pos += READ_CHUNK_SIZE;
|
|
50
|
+
if (isFirstRead === true) {
|
|
51
|
+
isFirstRead = false;
|
|
52
|
+
signalFirstStreamRead();
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
});
|
|
56
|
+
// oxlint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- bridge platform ReadableStream to the CF type, like server.ts
|
|
57
|
+
return stream;
|
|
58
|
+
};
|
|
59
|
+
const ProtocolLive = layerProtocolDurableObject({
|
|
60
|
+
callRpc: makeGatedCallRpc(streamWithGatedTail),
|
|
61
|
+
callerContext: { bindingName: 'TEST', durableObjectId: 'id' },
|
|
62
|
+
});
|
|
63
|
+
const result = yield* Effect.gen(function* () {
|
|
64
|
+
const client = yield* RpcClient.make(Rpcs);
|
|
65
|
+
const streamFiber = yield* client.BigStream({ n: expectedRows.length }).pipe(Stream.runCollect, Effect.forkChild);
|
|
66
|
+
yield* Effect.promise(() => firstStreamReadDone);
|
|
67
|
+
const echo = yield* client.Echo({ text: 'hi' }).pipe(Effect.timeout('500 millis'));
|
|
68
|
+
yield* Effect.sync(() => releaseStreamTail());
|
|
69
|
+
const rows = yield* Fiber.join(streamFiber);
|
|
70
|
+
return { rows: Array.from(rows), echo };
|
|
71
|
+
}).pipe(Effect.provide(ProtocolLive), Effect.timeout('2 seconds'));
|
|
72
|
+
Vitest.expect(result.echo).toEqual({ echo: 'Echo: hi' });
|
|
73
|
+
Vitest.expect(result.rows).toEqual(expectedRows);
|
|
74
|
+
}));
|
|
75
|
+
const makeGatedCallRpc = (gateStream) => (payload) => toDurableObjectHandler(Rpcs, { layer: ServerLive })(new Uint8Array(payload)).pipe(Effect.flatMap(
|
|
76
|
+
// Narrow on `Uint8Array`; the `ReadableStream` global differs from `CfTypes` across envs.
|
|
77
|
+
(result) => result instanceof Uint8Array
|
|
78
|
+
? Effect.succeed(result)
|
|
79
|
+
: Effect.promise(() => collectBytes(result)).pipe(Effect.map(gateStream))), Effect.runPromise);
|
|
80
|
+
const collectBytes = async (stream) => {
|
|
81
|
+
const reader = stream.getReader();
|
|
82
|
+
const parts = [];
|
|
83
|
+
let total = 0;
|
|
84
|
+
for (;;) {
|
|
85
|
+
const { done, value } = await reader.read();
|
|
86
|
+
if (done === true)
|
|
87
|
+
break;
|
|
88
|
+
parts.push(value);
|
|
89
|
+
total += value.length;
|
|
90
|
+
}
|
|
91
|
+
const out = new Uint8Array(total);
|
|
92
|
+
let offset = 0;
|
|
93
|
+
for (const part of parts) {
|
|
94
|
+
out.set(part, offset);
|
|
95
|
+
offset += part.length;
|
|
96
|
+
}
|
|
97
|
+
return out;
|
|
98
|
+
};
|
|
99
|
+
//# sourceMappingURL=client.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.test.js","sourceRoot":"","sources":["../../src/do-rpc/client.test.ts"],"names":[],"mappings":"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"}
|
package/dist/do-rpc/rpc.test.js
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
import { expect } from 'vitest';
|
|
2
2
|
import { Vitest } from '@livestore/utils-dev/node-vitest';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { WranglerDevServer } from '@livestore/utils-dev/wrangler';
|
|
4
|
+
import { Effect, FetchHttpClient, Layer, Option, References, RpcClient, RpcSerialization, Stream, } from '@livestore/utils/effect';
|
|
5
5
|
import { PlatformNode } from '@livestore/utils/node';
|
|
6
6
|
import { TestRpcs } from "./test-fixtures/rpc-schema.js";
|
|
7
7
|
const testTimeout = 60_000;
|
|
8
8
|
const withWranglerTest = Vitest.makeWithTestCtx({
|
|
9
9
|
timeout: testTimeout,
|
|
10
|
-
makeLayer: () =>
|
|
10
|
+
makeLayer: () => WranglerDevServer.layer({
|
|
11
11
|
cwd: `${import.meta.dirname}/test-fixtures`,
|
|
12
|
-
}).pipe(Layer.provide(Layer.mergeAll(PlatformNode.
|
|
12
|
+
}).pipe(Layer.provide(Layer.mergeAll(PlatformNode.NodeServices.layer, FetchHttpClient.layer, Layer.succeed(References.MinimumLogLevel, 'Debug')))),
|
|
13
13
|
});
|
|
14
14
|
const ProtocolLive = Layer.suspend(() => Effect.gen(function* () {
|
|
15
|
-
const server = yield*
|
|
15
|
+
const server = yield* WranglerDevServer.WranglerDevServer;
|
|
16
16
|
return RpcClient.layerProtocolHttp({
|
|
17
17
|
url: `${server.url}/rpc`,
|
|
18
18
|
}).pipe(Layer.provide([FetchHttpClient.layer, RpcSerialization.layerJson]));
|
|
19
|
-
}).pipe(Layer.
|
|
19
|
+
}).pipe(Layer.unwrap));
|
|
20
20
|
/**
|
|
21
21
|
* Test Architecture - Effect RPC via HTTP
|
|
22
22
|
*
|
|
@@ -36,97 +36,65 @@ const ProtocolLive = Layer.suspend(() => Effect.gen(function* () {
|
|
|
36
36
|
*/
|
|
37
37
|
Vitest.describe('Durable Object RPC', { timeout: testTimeout }, () => {
|
|
38
38
|
// Direct HTTP RPC client tests
|
|
39
|
-
Vitest.
|
|
39
|
+
Vitest.live('should call ping method', (test) => Effect.gen(function* () {
|
|
40
40
|
const client = yield* RpcClient.make(TestRpcs);
|
|
41
41
|
const result = yield* client.Ping({ message: 'Hello HTTP RPC' });
|
|
42
42
|
expect(result).toEqual({ response: 'Pong: Hello HTTP RPC' });
|
|
43
43
|
}).pipe(Effect.provide(ProtocolLive), withWranglerTest(test)));
|
|
44
|
-
Vitest.
|
|
44
|
+
Vitest.live('should call echo method', (test) => Effect.gen(function* () {
|
|
45
45
|
const client = yield* RpcClient.make(TestRpcs);
|
|
46
46
|
const result = yield* client.Echo({ text: 'Echo' });
|
|
47
47
|
expect(result).toEqual({ echo: 'Echo: Echo' });
|
|
48
48
|
}).pipe(Effect.provide(ProtocolLive), withWranglerTest(test)));
|
|
49
|
-
Vitest.
|
|
49
|
+
Vitest.live('should call add method', (test) => Effect.gen(function* () {
|
|
50
50
|
const client = yield* RpcClient.make(TestRpcs);
|
|
51
51
|
const result = yield* client.Add({ a: 15, b: 25 });
|
|
52
52
|
expect(result).toEqual({ result: 40 });
|
|
53
53
|
}).pipe(Effect.provide(ProtocolLive), withWranglerTest(test)));
|
|
54
|
-
Vitest.
|
|
54
|
+
Vitest.live('should handle RPC fail method', (test) => Effect.gen(function* () {
|
|
55
55
|
const client = yield* RpcClient.make(TestRpcs);
|
|
56
56
|
const error = yield* client.Fail({ message: 'test http failure' }).pipe(Effect.exit);
|
|
57
57
|
expect(error.toString()).toMatchInlineSnapshot(`
|
|
58
|
-
"
|
|
59
|
-
"_id": "Exit",
|
|
60
|
-
"_tag": "Failure",
|
|
61
|
-
"cause": {
|
|
62
|
-
"_id": "Cause",
|
|
63
|
-
"_tag": "Die",
|
|
64
|
-
"defect": "RPC failure: test http failure"
|
|
65
|
-
}
|
|
66
|
-
}"
|
|
58
|
+
"Failure(Cause([Die("RPC failure: test http failure")]))"
|
|
67
59
|
`);
|
|
68
60
|
}).pipe(Effect.provide(ProtocolLive), withWranglerTest(test)));
|
|
69
|
-
Vitest.
|
|
61
|
+
Vitest.live('should handle defect method', (test) => Effect.gen(function* () {
|
|
70
62
|
const client = yield* RpcClient.make(TestRpcs);
|
|
71
63
|
const error = yield* client.Defect({ message: 'test http defect' }).pipe(Effect.exit);
|
|
72
64
|
expect(error.toString()).toMatchInlineSnapshot(`
|
|
73
|
-
"
|
|
74
|
-
"_id": "Exit",
|
|
75
|
-
"_tag": "Failure",
|
|
76
|
-
"cause": {
|
|
77
|
-
"_id": "Cause",
|
|
78
|
-
"_tag": "Die",
|
|
79
|
-
"defect": "some defect: test http defect"
|
|
80
|
-
}
|
|
81
|
-
}"
|
|
65
|
+
"Failure(Cause([Die("some defect: test http defect")]))"
|
|
82
66
|
`);
|
|
83
67
|
}).pipe(Effect.provide(ProtocolLive), withWranglerTest(test)));
|
|
84
|
-
Vitest.
|
|
68
|
+
Vitest.live('should handle streaming RPC via HTTP', (test) => Effect.gen(function* () {
|
|
85
69
|
const client = yield* RpcClient.make(TestRpcs);
|
|
86
70
|
const stream = client.Stream({}).pipe(Stream.take(4), Stream.map((c) => c.maybeNumber.pipe(Option.getOrUndefined)));
|
|
87
|
-
const
|
|
88
|
-
expect(
|
|
71
|
+
const result = yield* Stream.runCollect(stream);
|
|
72
|
+
expect(result).toEqual([1, 4, 9, 16]); // squares of 1,2,3,4
|
|
89
73
|
}).pipe(Effect.provide(ProtocolLive), withWranglerTest(test)));
|
|
90
|
-
Vitest.
|
|
74
|
+
Vitest.live('should handle streaming RPC with error via HTTP', (test) => Effect.gen(function* () {
|
|
91
75
|
const client = yield* RpcClient.make(TestRpcs);
|
|
92
76
|
const stream = client.StreamError({ count: 5, errorAfter: 4 });
|
|
93
77
|
const error = yield* Stream.runCollect(stream).pipe(Effect.exit);
|
|
94
78
|
expect(error.toString()).toMatchInlineSnapshot(`
|
|
95
|
-
"
|
|
96
|
-
"_id": "Exit",
|
|
97
|
-
"_tag": "Failure",
|
|
98
|
-
"cause": {
|
|
99
|
-
"_id": "Cause",
|
|
100
|
-
"_tag": "Fail",
|
|
101
|
-
"failure": "Stream error after 4: got 9"
|
|
102
|
-
}
|
|
103
|
-
}"
|
|
79
|
+
"Failure(Cause([Fail("Stream error after 4: got 9")]))"
|
|
104
80
|
`);
|
|
105
81
|
}).pipe(Effect.provide(ProtocolLive), withWranglerTest(test)));
|
|
106
|
-
Vitest.
|
|
82
|
+
Vitest.live('should handle streaming RPC with defect via HTTP', (test) => Effect.gen(function* () {
|
|
107
83
|
const client = yield* RpcClient.make(TestRpcs);
|
|
108
84
|
const stream = client.StreamDefect({ count: 4, defectAfter: 1 });
|
|
109
85
|
const error = yield* Stream.runCollect(stream).pipe(Effect.exit);
|
|
110
86
|
expect(error.toString()).toMatchInlineSnapshot(`
|
|
111
|
-
"
|
|
112
|
-
"_id": "Exit",
|
|
113
|
-
"_tag": "Failure",
|
|
114
|
-
"cause": {
|
|
115
|
-
"_id": "Cause",
|
|
116
|
-
"_tag": "Die",
|
|
117
|
-
"defect": "Stream defect after 1: got 4"
|
|
118
|
-
}
|
|
119
|
-
}"
|
|
87
|
+
"Failure(Cause([Die("Stream defect after 1: got 4")]))"
|
|
120
88
|
`);
|
|
121
89
|
}).pipe(Effect.provide(ProtocolLive), withWranglerTest(test)));
|
|
122
|
-
Vitest.
|
|
90
|
+
Vitest.live('should handle stream interruption via HTTP', (test) => Effect.gen(function* () {
|
|
123
91
|
const client = yield* RpcClient.make(TestRpcs);
|
|
124
92
|
const stream = client.StreamInterruptible({ delay: 50, interruptAfterCount: 3 }).pipe(Stream.take(3));
|
|
125
|
-
const
|
|
126
|
-
expect(
|
|
93
|
+
const result = yield* Stream.runCollect(stream);
|
|
94
|
+
expect(result).toEqual([1, 2, 3]);
|
|
127
95
|
}).pipe(Effect.provide(ProtocolLive), withWranglerTest(test)));
|
|
128
96
|
// TODO @IMax153
|
|
129
|
-
Vitest.
|
|
97
|
+
Vitest.live.skip('should handle streaming RPC bug scenario', (test) => Effect.gen(function* () {
|
|
130
98
|
const client = yield* RpcClient.make(TestRpcs);
|
|
131
99
|
yield* client.StreamBugScenarioDoClient({});
|
|
132
100
|
/*
|
|
@@ -169,7 +137,7 @@ Vitest.describe('Durable Object RPC', { timeout: testTimeout }, () => {
|
|
|
169
137
|
errorSchema: [Function: Never],
|
|
170
138
|
annotations: { _id: 'Context', services: [] },
|
|
171
139
|
middlewares: Set(0) {},
|
|
172
|
-
key: '
|
|
140
|
+
key: 'effect/unstable/rpc/Rpc/StreamBugScenarioDoServer'
|
|
173
141
|
} {}
|
|
174
142
|
|
|
175
143
|
Killing wrangler process...
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rpc.test.js","sourceRoot":"","sources":["../../src/do-rpc/rpc.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAE/B,OAAO,EAAE,MAAM,EAAE,MAAM,kCAAkC,CAAA;AACzD,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"rpc.test.js","sourceRoot":"","sources":["../../src/do-rpc/rpc.test.ts"],"names":[],"mappings":"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"}
|
package/dist/do-rpc/server.d.ts
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
|
-
import { Effect, type Layer, type
|
|
1
|
+
import { Effect, type Layer, type ReadonlyArray, Rpc, type RpcGroup } from '@livestore/utils/effect';
|
|
2
2
|
import type * as CfTypes from '../cf-types.ts';
|
|
3
3
|
export interface ClientDoWithRpcCallback {
|
|
4
4
|
__DURABLE_OBJECT_BRAND: never;
|
|
5
|
-
|
|
5
|
+
/**
|
|
6
|
+
* The sync backend calls this to deliver a live update; `storeId` lets a rebuilt DO reload its
|
|
7
|
+
* store before delivering. See the Cloudflare Durable Object adapter docs for the recovery options.
|
|
8
|
+
*/
|
|
9
|
+
syncUpdateRpc: (payload: Uint8Array<ArrayBuffer>, storeId: string) => Promise<void>;
|
|
6
10
|
}
|
|
7
11
|
/**
|
|
8
12
|
* Construct a Durable Object RPC handler from an `RpcGroup`.
|
|
@@ -22,6 +26,7 @@ export declare const emitStreamResponse: (args_0: {
|
|
|
22
26
|
durableObjectId: string;
|
|
23
27
|
};
|
|
24
28
|
requestId: string;
|
|
25
|
-
|
|
26
|
-
|
|
29
|
+
storeId: string;
|
|
30
|
+
values: ReadonlyArray.NonEmptyReadonlyArray<any>;
|
|
31
|
+
}) => Effect.Effect<void, import("effect/Cause").UnknownError, never>;
|
|
27
32
|
//# sourceMappingURL=server.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/do-rpc/server.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/do-rpc/server.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,MAAM,EAGN,KAAK,KAAK,EAEV,KAAK,aAAa,EAClB,GAAG,EACH,KAAK,QAAQ,EASd,MAAM,yBAAyB,CAAA;AAEhC,OAAO,KAAK,KAAK,OAAO,MAAM,gBAAgB,CAAA;AAc9C,MAAM,WAAW,uBAAuB;IACtC,sBAAsB,EAAE,KAAK,CAAA;IAC7B;;;OAGG;IACH,aAAa,EAAE,CAAC,OAAO,EAAE,UAAU,CAAC,WAAW,CAAC,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;CACpF;AAED;;;GAGG;AACH,eAAO,MAAM,sBAAsB,GAChC,IAAI,SAAS,GAAG,CAAC,GAAG,EAAE,EAAE,EACvB,OAAO,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,EAC9B,SAAS;IACP,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAA;IAC3E,QAAQ,CAAC,cAAc,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IAC7C,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACxC,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAA;CAC9D,KACA,CAAC,CACF,iBAAiB,EAAE,UAAU,CAAC,WAAW,CAAC,KACvC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,WAAW,CAAC,GAAG,OAAO,CAAC,cAAc,CAAC,CAuJjE,CAAA;AAEL,qEAAqE;AACrE,eAAO,MAAM,kBAAkB;SAOxB,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;mBACT;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,eAAe,EAAE,MAAM,CAAA;KAAE;eACpD,MAAM;aACR,MAAM;YACP,aAAa,CAAC,qBAAqB,CAAC,GAAG,CAAC;qEAqBhD,CAAA"}
|