@livestore/common-cf 0.4.0 → 0.5.0-dev.1
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/declare/mod.js +1 -1
- package/dist/do-rpc/client.d.ts +8 -0
- package/dist/do-rpc/client.d.ts.map +1 -1
- package/dist/do-rpc/client.js +71 -51
- 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 +189 -0
- package/dist/do-rpc/client.test.js.map +1 -0
- package/dist/do-rpc/mod.d.ts +1 -1
- package/dist/do-rpc/mod.d.ts.map +1 -1
- package/dist/do-rpc/mod.js +2 -2
- package/dist/do-rpc/mod.js.map +1 -1
- package/dist/do-rpc/rpc.test.js +27 -59
- package/dist/do-rpc/rpc.test.js.map +1 -1
- package/dist/do-rpc/server.d.ts +10 -4
- package/dist/do-rpc/server.d.ts.map +1 -1
- package/dist/do-rpc/server.js +107 -74
- package/dist/do-rpc/server.js.map +1 -1
- package/dist/do-rpc/test-fixtures/rpc-schema.d.ts +28 -28
- 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 +10 -10
- package/dist/do-rpc/test-fixtures/worker.js.map +1 -1
- package/dist/mod.js +3 -3
- package/dist/ws-rpc/test-fixtures/rpc-schema.d.ts +28 -28
- package/dist/ws-rpc/test-fixtures/rpc-schema.js +9 -9
- package/dist/ws-rpc/test-fixtures/worker.d.ts.map +1 -1
- package/dist/ws-rpc/test-fixtures/worker.js +2 -2
- package/dist/ws-rpc/ws-rpc-server.d.ts +14 -7
- package/dist/ws-rpc/ws-rpc-server.d.ts.map +1 -1
- package/dist/ws-rpc/ws-rpc-server.js +60 -28
- package/dist/ws-rpc/ws-rpc-server.js.map +1 -1
- package/dist/ws-rpc/ws-rpc.test.js +28 -60
- package/dist/ws-rpc/ws-rpc.test.js.map +1 -1
- package/package.json +29 -38
- package/src/declare/cf-declare.ts +1 -1
- package/src/do-rpc/README.md +2 -2
- package/src/do-rpc/client.test.ts +263 -0
- package/src/do-rpc/client.ts +99 -68
- package/src/do-rpc/mod.ts +1 -1
- package/src/do-rpc/rpc.test.ts +30 -60
- package/src/do-rpc/server.ts +168 -86
- 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 +114 -39
- package/src/ws-rpc/ws-rpc.test.ts +31 -61
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
|
-
import { TestRpcs } from
|
|
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,103 +36,71 @@ 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
|
/*
|
|
133
101
|
|
|
134
102
|
|
|
135
|
-
In
|
|
103
|
+
In the installed `@effect/rpc` `RpcClient.js`:
|
|
136
104
|
add the console log
|
|
137
105
|
```
|
|
138
106
|
yield* Scope.addFinalizerExit(scope, exit => {
|
|
@@ -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, Schema } 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,8 @@ export declare const emitStreamResponse: (args_0: {
|
|
|
22
26
|
durableObjectId: string;
|
|
23
27
|
};
|
|
24
28
|
requestId: string;
|
|
25
|
-
|
|
26
|
-
|
|
29
|
+
storeId: string;
|
|
30
|
+
schema: Schema.Top;
|
|
31
|
+
values: ReadonlyArray.NonEmptyReadonlyArray<unknown>;
|
|
32
|
+
}) => Effect.Effect<void, Schema.SchemaError | import("effect/Cause").UnknownError, never>;
|
|
27
33
|
//# 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,EAIN,KAAK,KAAK,EAEV,KAAK,aAAa,EAClB,GAAG,EACH,KAAK,QAAQ,EAKb,MAAM,EAIP,MAAM,yBAAyB,CAAA;AAEhC,OAAO,KAAK,KAAK,OAAO,MAAM,gBAAgB,CAAA;AA0B9C,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,SAChB,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,WACrB;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,CA+IjE,CAAA;AAEL,qEAAqE;AACrE,eAAO,MAAM,kBAAkB;SAQxB,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;mBACT;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,eAAe,EAAE,MAAM,CAAA;KAAE;eACpD,MAAM;aACR,MAAM;YACP,MAAM,CAAC,GAAG;YACV,aAAa,CAAC,qBAAqB,CAAC,OAAO,CAAC;0FAwBpD,CAAA"}
|
package/dist/do-rpc/server.js
CHANGED
|
@@ -1,68 +1,85 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Effect, Exit, Fiber, Headers, Option, Rpc, RpcMessage, RpcSchema, RpcSerialization, Result, Schema, SchemaIssue, Stream, } from '@livestore/utils/effect';
|
|
2
|
+
const isEncodedRpcMessage = Schema.is(RpcMessage.EncodedSchema);
|
|
3
|
+
const isRequestEncoded = (message) => isEncodedRpcMessage(message) === true && message._tag === 'Request';
|
|
4
|
+
const erasedCodec = (codecFor, schema) =>
|
|
5
|
+
// oxlint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- erased RPC data schemas require no codec services
|
|
6
|
+
codecFor(schema);
|
|
7
|
+
const schemaBinarySerialization = RpcSerialization.RpcSerialization.pipe(Effect.provide(RpcSerialization.layerSchemaBinary()));
|
|
8
|
+
const encodeBytes = (parser, value) => {
|
|
9
|
+
const encoded = parser.encode(value);
|
|
10
|
+
if (encoded instanceof Uint8Array === false) {
|
|
11
|
+
throw new TypeError('SchemaBinary RPC serialization did not produce bytes');
|
|
12
|
+
}
|
|
13
|
+
if (encoded.buffer instanceof ArrayBuffer === false) {
|
|
14
|
+
throw new TypeError('SchemaBinary RPC serialization produced shared bytes');
|
|
15
|
+
}
|
|
16
|
+
return new Uint8Array(encoded.buffer, encoded.byteOffset, encoded.byteLength);
|
|
17
|
+
};
|
|
2
18
|
/**
|
|
3
19
|
* Construct a Durable Object RPC handler from an `RpcGroup`.
|
|
4
20
|
* This is the DO equivalent of `RpcServer.toWebHandler`.
|
|
5
21
|
*/
|
|
6
22
|
export const toDurableObjectHandler = (group, options) => (serializedPayload) => Effect.gen(function* () {
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
const
|
|
10
|
-
// Handle potential nested array from client serialization
|
|
11
|
-
let requests;
|
|
12
|
-
if (Array.isArray(decoded) === true && decoded.length === 1 && Array.isArray(decoded[0]) === true) {
|
|
13
|
-
// Double-wrapped array [[{...}]] -> [{...}]
|
|
14
|
-
requests = decoded[0];
|
|
15
|
-
}
|
|
16
|
-
else if (Array.isArray(decoded) === true) {
|
|
17
|
-
// Single array [{...}]
|
|
18
|
-
requests = decoded;
|
|
19
|
-
}
|
|
20
|
-
else {
|
|
21
|
-
requests = [];
|
|
22
|
-
}
|
|
23
|
+
const serialization = yield* schemaBinarySerialization;
|
|
24
|
+
const parser = serialization.makeUnsafe();
|
|
25
|
+
const requests = parser.decode(serializedPayload).filter(isRequestEncoded);
|
|
23
26
|
// Get the context with handlers
|
|
24
27
|
const context = yield* Effect.context();
|
|
25
28
|
// Process each request
|
|
26
29
|
const responses = [];
|
|
27
30
|
for (const request of requests) {
|
|
28
|
-
|
|
29
|
-
continue;
|
|
30
|
-
}
|
|
31
|
+
const requestId = RpcMessage.RequestId(request.id);
|
|
31
32
|
// Find the RPC handler
|
|
32
33
|
// oxlint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- RpcGroup.requests map returns Rpc.Any; narrowing to AnyWithProps for property access
|
|
33
34
|
const rpc = group.requests.get(request.tag);
|
|
34
|
-
// oxlint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- context.
|
|
35
|
-
const entry = context.
|
|
35
|
+
// oxlint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- context.mapUnsafe dynamic lookup; type safety ensured by RpcGroup registration
|
|
36
|
+
const entry = context.mapUnsafe.get(rpc.key);
|
|
36
37
|
if (rpc == null || entry == null) {
|
|
37
38
|
responses.push({
|
|
38
39
|
_tag: 'Exit',
|
|
39
|
-
requestId
|
|
40
|
+
requestId,
|
|
40
41
|
exit: Exit.die(`Unknown request tag: ${request.tag}`),
|
|
41
42
|
});
|
|
42
43
|
continue;
|
|
43
44
|
}
|
|
45
|
+
const payloadResult = yield* Schema.decodeUnknownEffect(erasedCodec(serialization.codecFor, rpc.payloadSchema))(request.payload).pipe(Effect.provideContext(entry.context), Effect.result);
|
|
46
|
+
if (Result.isFailure(payloadResult) === true) {
|
|
47
|
+
// oxlint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- Rpc.exitSchema requires AnyWithProps; type narrowing already done above
|
|
48
|
+
const exitSchema = Rpc.exitSchema(rpc);
|
|
49
|
+
const rawExit = Exit.die(SchemaIssue.makeFormatterDefault()(payloadResult.failure.issue));
|
|
50
|
+
const encodedExit = yield* Schema.encodeUnknownEffect(erasedCodec(serialization.codecFor, exitSchema))(rawExit).pipe(Effect.provideContext(entry.context));
|
|
51
|
+
responses.push({
|
|
52
|
+
_tag: 'Exit',
|
|
53
|
+
requestId,
|
|
54
|
+
exit: encodedExit,
|
|
55
|
+
});
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
const payload = payloadResult.success;
|
|
44
59
|
// Check if this is a streaming RPC
|
|
45
|
-
// oxlint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- Rpc.Handler doesn't expose successSchema publicly; see https://github.com/Effect-TS/effect/issues/6064
|
|
46
60
|
const isStream = RpcSchema.isStreamSchema(rpc.successSchema);
|
|
47
61
|
// For streaming RPCs with only one request, return ReadableStream directly
|
|
48
62
|
if (isStream === true && requests.length === 1) {
|
|
49
|
-
return yield* createStreamingResponse(rpc, entry,
|
|
63
|
+
return yield* createStreamingResponse(rpc, entry, requestId, payload, parser, serialization.codecFor, options.layer);
|
|
50
64
|
}
|
|
51
65
|
// Execute the handler
|
|
52
66
|
const result = yield* Effect.gen(function* () {
|
|
53
|
-
const handlerResult = entry.handler(
|
|
54
|
-
|
|
67
|
+
const handlerResult = entry.handler(payload, {
|
|
68
|
+
client: new Rpc.ServerClient(0), // TODO: add proper clientId if needed
|
|
69
|
+
requestId,
|
|
55
70
|
headers: Headers.fromInput({
|
|
56
|
-
'x-rpc-request-id':
|
|
71
|
+
'x-rpc-request-id': requestId.toString(),
|
|
57
72
|
}),
|
|
73
|
+
rpc,
|
|
58
74
|
});
|
|
75
|
+
const effectOrStream = Rpc.isWrapper(handlerResult) === true ? handlerResult.value : handlerResult;
|
|
59
76
|
let value;
|
|
60
|
-
if (Effect.isEffect(
|
|
77
|
+
if (Effect.isEffect(effectOrStream) === true) {
|
|
61
78
|
// @effect-diagnostics-next-line anyUnknownInErrorContext:off -- `Rpc.Handler.handler` returns `Effect<any, any>` due to dynamic dispatch
|
|
62
|
-
value = yield*
|
|
79
|
+
value = yield* effectOrStream;
|
|
63
80
|
}
|
|
64
81
|
else {
|
|
65
|
-
value =
|
|
82
|
+
value = effectOrStream;
|
|
66
83
|
}
|
|
67
84
|
// Get the exit schema for this RPC
|
|
68
85
|
// oxlint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- Rpc.exitSchema requires AnyWithProps; type narrowing already done above
|
|
@@ -71,7 +88,7 @@ export const toDurableObjectHandler = (group, options) => (serializedPayload) =>
|
|
|
71
88
|
if (exitSchema !== undefined) {
|
|
72
89
|
// Use schema encoding for proper serialization
|
|
73
90
|
const rawExit = Exit.succeed(value);
|
|
74
|
-
encodedExit = yield* Schema.
|
|
91
|
+
encodedExit = yield* Schema.encodeUnknownEffect(erasedCodec(serialization.codecFor, exitSchema))(rawExit);
|
|
75
92
|
}
|
|
76
93
|
else {
|
|
77
94
|
// Fallback to direct exit
|
|
@@ -79,10 +96,10 @@ export const toDurableObjectHandler = (group, options) => (serializedPayload) =>
|
|
|
79
96
|
}
|
|
80
97
|
return {
|
|
81
98
|
_tag: 'Exit',
|
|
82
|
-
requestId
|
|
99
|
+
requestId,
|
|
83
100
|
exit: encodedExit,
|
|
84
101
|
};
|
|
85
|
-
}).pipe(Effect.
|
|
102
|
+
}).pipe(Effect.catchCause((cause) => {
|
|
86
103
|
// Get the exit schema for this RPC
|
|
87
104
|
// oxlint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- Rpc.exitSchema requires AnyWithProps; type narrowing already done above
|
|
88
105
|
const exitSchema = Rpc.exitSchema(rpc);
|
|
@@ -91,7 +108,7 @@ export const toDurableObjectHandler = (group, options) => (serializedPayload) =>
|
|
|
91
108
|
if (exitSchema !== undefined) {
|
|
92
109
|
// Use schema encoding for proper serialization
|
|
93
110
|
const rawExit = Exit.failCause(cause);
|
|
94
|
-
encodedExit = yield* Schema.
|
|
111
|
+
encodedExit = yield* Schema.encodeUnknownEffect(erasedCodec(serialization.codecFor, exitSchema))(rawExit);
|
|
95
112
|
}
|
|
96
113
|
else {
|
|
97
114
|
// Fallback to direct exit
|
|
@@ -99,103 +116,119 @@ export const toDurableObjectHandler = (group, options) => (serializedPayload) =>
|
|
|
99
116
|
}
|
|
100
117
|
return {
|
|
101
118
|
_tag: 'Exit',
|
|
102
|
-
requestId
|
|
119
|
+
requestId,
|
|
103
120
|
exit: encodedExit,
|
|
104
121
|
};
|
|
105
122
|
});
|
|
106
123
|
}));
|
|
107
124
|
responses.push(result);
|
|
108
125
|
}
|
|
109
|
-
|
|
110
|
-
const encoded = parser.encode(responses);
|
|
111
|
-
return encoded;
|
|
126
|
+
return encodeBytes(parser, responses);
|
|
112
127
|
}).pipe(Effect.provide(options.layer), Effect.scoped, Effect.orDie);
|
|
113
128
|
/** Out-of-band RPC stream response emission back to the caller DO */
|
|
114
|
-
export const emitStreamResponse = Effect.fn('do-rpc/emitStreamResponse')(function* ({ callerContext, env, requestId, values, }) {
|
|
129
|
+
export const emitStreamResponse = Effect.fn('do-rpc/emitStreamResponse')(function* ({ callerContext, env, requestId, schema, storeId, values, }) {
|
|
115
130
|
// oxlint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- CF worker env bindings are typed as Record<string, any>; narrowing to known DO namespace
|
|
116
131
|
const clientDoNamespace = env[callerContext.bindingName];
|
|
117
132
|
if (clientDoNamespace === undefined) {
|
|
118
133
|
throw new Error(`Client DO namespace not found: ${callerContext.bindingName}`);
|
|
119
134
|
}
|
|
120
135
|
const clientDo = clientDoNamespace.get(clientDoNamespace.idFromString(callerContext.durableObjectId));
|
|
121
|
-
const
|
|
122
|
-
|
|
136
|
+
const serialization = yield* schemaBinarySerialization;
|
|
137
|
+
const parser = serialization.makeUnsafe();
|
|
138
|
+
const encodedValues = yield* Schema.encodeUnknownEffect(erasedCodec(serialization.codecFor, Schema.NonEmptyArray(schema)))(values);
|
|
139
|
+
const res = { _tag: 'Chunk', requestId, values: encodedValues };
|
|
140
|
+
// Native Cloudflare RPC rejects schema values with custom prototypes. Keep the callback
|
|
141
|
+
// boundary clone-safe by sending the already-encoded Effect RPC message as bytes.
|
|
142
|
+
const serializedRes = encodeBytes(parser, res);
|
|
143
|
+
yield* Effect.tryPromise(() => clientDo.syncUpdateRpc(serializedRes, storeId));
|
|
123
144
|
});
|
|
124
145
|
/**
|
|
125
146
|
* Creates a ReadableStream response for streaming RPCs.
|
|
126
147
|
* This converts an Effect Stream into a ReadableStream of serialized RPC messages.
|
|
127
148
|
*/
|
|
128
|
-
const createStreamingResponse = (rpc, entry,
|
|
149
|
+
const createStreamingResponse = (rpc, entry, requestId, payload, parser, codecFor, layer) => Effect.gen(function* () {
|
|
129
150
|
// Execute the handler to get the stream
|
|
130
|
-
const handlerResult = entry.handler(
|
|
131
|
-
|
|
151
|
+
const handlerResult = entry.handler(payload, {
|
|
152
|
+
client: new Rpc.ServerClient(0), // TODO: add proper clientId if needed
|
|
153
|
+
requestId,
|
|
132
154
|
headers: Headers.fromInput({
|
|
133
|
-
'x-rpc-request-id':
|
|
155
|
+
'x-rpc-request-id': requestId.toString(),
|
|
134
156
|
}),
|
|
157
|
+
rpc,
|
|
135
158
|
});
|
|
136
|
-
|
|
137
|
-
|
|
159
|
+
const effectOrStream = Rpc.isWrapper(handlerResult) === true ? handlerResult.value : handlerResult;
|
|
160
|
+
// @effect-diagnostics-next-line anyUnknownInErrorContext:off -- dynamically dispatched handlers have an unknown error; orDie converts it to a defect handled by the downstream catchCause
|
|
161
|
+
const result = Effect.isEffect(effectOrStream) === true ? yield* Effect.orDie(effectOrStream) : effectOrStream;
|
|
162
|
+
if (Stream.isStream(result) === false) {
|
|
163
|
+
return yield* Effect.die(`Streaming RPC ${rpc._tag} did not produce a Stream`);
|
|
164
|
+
}
|
|
165
|
+
const stream = result;
|
|
138
166
|
// Get the stream schemas for proper chunk-level encoding
|
|
139
167
|
// oxlint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- Rpc.Handler doesn't expose successSchema publicly; see https://github.com/Effect-TS/effect/issues/6064
|
|
140
|
-
const streamSchemas = RpcSchema.
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
168
|
+
const streamSchemas = RpcSchema.isStreamSchema(rpc.successSchema) === true
|
|
169
|
+
? Option.some({
|
|
170
|
+
success: rpc.successSchema.success,
|
|
171
|
+
error: rpc.successSchema.error,
|
|
172
|
+
})
|
|
173
|
+
: Option.none();
|
|
174
|
+
const arrayEncoder = Option.isSome(streamSchemas) === true
|
|
175
|
+
? Schema.encodeUnknownEffect(erasedCodec(codecFor, Schema.NonEmptyArray(streamSchemas.value.success)))
|
|
176
|
+
: Schema.encodeUnknownEffect(erasedCodec(codecFor, Schema.NonEmptyArray(Schema.Any)));
|
|
146
177
|
// Convert stream to ReadableStream
|
|
178
|
+
let producer;
|
|
179
|
+
let cancelled = false;
|
|
147
180
|
const readableStream = new ReadableStream({
|
|
148
181
|
start(controller) {
|
|
149
182
|
// Run the stream and send chunks + final exit
|
|
150
183
|
const runStream = Effect.gen(function* () {
|
|
151
184
|
// Process stream chunks - let chunk encoder handle Effect objects properly
|
|
152
|
-
yield* Stream.
|
|
153
|
-
|
|
154
|
-
if (chunkArray.length === 0)
|
|
185
|
+
yield* Stream.runForEachArray(stream, (array) => Effect.gen(function* () {
|
|
186
|
+
if (array.length === 0)
|
|
155
187
|
return;
|
|
156
188
|
// Encode the chunk using the proper chunk encoder (like official RPC)
|
|
157
|
-
const encodedValues = yield*
|
|
189
|
+
const encodedValues = yield* arrayEncoder(array);
|
|
158
190
|
const chunkMessage = {
|
|
159
191
|
_tag: 'Chunk',
|
|
160
|
-
requestId
|
|
192
|
+
requestId,
|
|
161
193
|
values: encodedValues,
|
|
162
194
|
};
|
|
163
|
-
|
|
164
|
-
const serialized = parser.encode([chunkMessage]);
|
|
165
|
-
controller.enqueue(serialized);
|
|
195
|
+
controller.enqueue(encodeBytes(parser, [chunkMessage]));
|
|
166
196
|
}));
|
|
167
197
|
// Send final exit message with proper schema encoding
|
|
168
198
|
const rawExit = Exit.void;
|
|
169
199
|
// oxlint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- Rpc.exitSchema requires AnyWithProps; type narrowing already done above
|
|
170
200
|
const exitSchema = Rpc.exitSchema(rpc);
|
|
171
|
-
const encodedExit = yield* Schema.
|
|
201
|
+
const encodedExit = yield* Schema.encodeUnknownEffect(erasedCodec(codecFor, exitSchema))(rawExit);
|
|
172
202
|
const exitMessage = {
|
|
173
203
|
_tag: 'Exit',
|
|
174
|
-
requestId
|
|
204
|
+
requestId,
|
|
175
205
|
exit: encodedExit,
|
|
176
206
|
};
|
|
177
|
-
|
|
178
|
-
const exitSerialized = parser.encode([exitMessage]);
|
|
179
|
-
controller.enqueue(exitSerialized);
|
|
207
|
+
controller.enqueue(encodeBytes(parser, [exitMessage]));
|
|
180
208
|
controller.close();
|
|
181
|
-
}).pipe(Effect.
|
|
209
|
+
}).pipe(Effect.catchCause((cause) => Effect.gen(function* () {
|
|
210
|
+
if (cancelled === true)
|
|
211
|
+
return;
|
|
182
212
|
// Send error exit with proper schema encoding
|
|
183
213
|
const rawExit = Exit.failCause(cause);
|
|
184
214
|
// oxlint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- Rpc.exitSchema requires AnyWithProps; type narrowing already done above
|
|
185
215
|
const exitSchema = Rpc.exitSchema(rpc);
|
|
186
|
-
const encodedExit = yield* Schema.
|
|
216
|
+
const encodedExit = yield* Schema.encodeUnknownEffect(erasedCodec(codecFor, exitSchema))(rawExit);
|
|
187
217
|
const exitMessage = {
|
|
188
218
|
_tag: 'Exit',
|
|
189
|
-
requestId
|
|
219
|
+
requestId,
|
|
190
220
|
exit: encodedExit,
|
|
191
221
|
};
|
|
192
|
-
|
|
193
|
-
const exitSerialized = parser.encode([exitMessage]);
|
|
194
|
-
controller.enqueue(exitSerialized);
|
|
222
|
+
controller.enqueue(encodeBytes(parser, [exitMessage]));
|
|
195
223
|
controller.close();
|
|
196
224
|
})));
|
|
197
225
|
// Run the stream processing
|
|
198
|
-
runStream.pipe(Effect.provide(layer), Effect.scoped, Effect.tapCauseLogPretty, Effect.
|
|
226
|
+
producer = runStream.pipe(Effect.provide(layer), Effect.scoped, Effect.tapCauseLogPretty, (_) => _, Effect.runFork);
|
|
227
|
+
},
|
|
228
|
+
cancel() {
|
|
229
|
+
cancelled = true;
|
|
230
|
+
// @effect-diagnostics-next-line runEffectInsideEffect:off -- native stream callback runs outside Effect; interruption needs no services
|
|
231
|
+
return producer === undefined ? undefined : Effect.runPromise(Fiber.interrupt(producer));
|
|
199
232
|
},
|
|
200
233
|
// oxlint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- bridging standard Web API ReadableStream to Cloudflare Worker ReadableStream type
|
|
201
234
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/do-rpc/server.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/do-rpc/server.ts"],"names":[],"mappings":"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"}
|