@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
|
@@ -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"}
|
package/dist/declare/mod.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
// NOTE We have a separate module for type level declarations as those are only available in CF worker environments
|
|
2
2
|
// and we need to avoid importing them from other environments.
|
|
3
|
-
export * as CfDeclare from
|
|
3
|
+
export * as CfDeclare from './cf-declare.js';
|
|
4
4
|
//# sourceMappingURL=mod.js.map
|
package/dist/do-rpc/client.d.ts
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import { Layer, RpcClient } from '@livestore/utils/effect';
|
|
2
2
|
import type * as CfTypes from '../cf-types.ts';
|
|
3
|
+
declare const DoRpcReadError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
|
|
4
|
+
readonly _tag: "DoRpcReadError";
|
|
5
|
+
} & Readonly<A>;
|
|
6
|
+
/** A transferred stream can lose Cloudflare's RPC error flags when its connection breaks. */
|
|
7
|
+
export declare class DoRpcReadError extends DoRpcReadError_base<{
|
|
8
|
+
cause: unknown;
|
|
9
|
+
}> {
|
|
10
|
+
}
|
|
3
11
|
interface MakeDoRpcProtocolArgs {
|
|
4
12
|
callRpc: (payload: Uint8Array) => Promise<Uint8Array | CfTypes.ReadableStream>;
|
|
5
13
|
callerContext: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/do-rpc/client.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/do-rpc/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,EAEL,SAAS,EAMV,MAAM,yBAAyB,CAAA;AAEhC,OAAO,KAAK,KAAK,OAAO,MAAM,gBAAgB,CAAA;;;;AAE9C,6FAA6F;AAC7F,qBAAa,cAAe,SAAQ,oBAAmC;IAAE,KAAK,EAAE,OAAO,CAAA;CAAE,CAAC;CAAG;AA8D7F,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,SAAU,qBAAqB,KAAG,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,QAAQ,CAGpG,CAAA"}
|
package/dist/do-rpc/client.js
CHANGED
|
@@ -1,94 +1,114 @@
|
|
|
1
|
-
import { Effect, Fiber, FiberMap, Layer, RpcClient, RpcSerialization, } from '@livestore/utils/effect';
|
|
2
|
-
/**
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import { Data, Effect, Fiber, FiberMap, Layer, Option, RpcClient, RpcClientError, RpcMessage, RpcSerialization, Schema, } from '@livestore/utils/effect';
|
|
2
|
+
/** A transferred stream can lose Cloudflare's RPC error flags when its connection breaks. */
|
|
3
|
+
export class DoRpcReadError extends Data.TaggedError('DoRpcReadError') {
|
|
4
|
+
}
|
|
5
|
+
const isEncodedRpcMessage = Schema.is(RpcMessage.EncodedSchema);
|
|
6
|
+
const isFromServerEncoded = (message) => {
|
|
7
|
+
if (isEncodedRpcMessage(message) === false)
|
|
8
|
+
return false;
|
|
9
|
+
return (message._tag === 'Chunk' ||
|
|
10
|
+
message._tag === 'Exit' ||
|
|
11
|
+
message._tag === 'Defect' ||
|
|
12
|
+
message._tag === 'Pong' ||
|
|
13
|
+
message._tag === 'Request');
|
|
14
|
+
};
|
|
15
|
+
/** Decodes a streaming-RPC `ReadableStream`'s binary frames, writing each out as it arrives. */
|
|
6
16
|
const processReadableStream = (stream, parser, writeResponse) => Effect.gen(function* () {
|
|
7
17
|
const reader = stream.getReader();
|
|
8
18
|
yield* Effect.gen(function* () {
|
|
9
19
|
while (true) {
|
|
10
|
-
const { done, value } = yield* Effect.tryPromise(
|
|
20
|
+
const { done, value } = yield* Effect.tryPromise({
|
|
21
|
+
try: () => reader.read(),
|
|
22
|
+
catch: (cause) => transportFailure(new DoRpcReadError({ cause })),
|
|
23
|
+
});
|
|
11
24
|
if (done === true) {
|
|
12
|
-
|
|
13
|
-
}
|
|
14
|
-
// Decode the chunk
|
|
15
|
-
const decoded = parser.decode(value);
|
|
16
|
-
// Handle array of messages from server.
|
|
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);
|
|
25
|
+
return yield* transportFailure(new DoRpcReadError({ cause: new Error('RPC stream ended before its exit') }));
|
|
23
26
|
}
|
|
24
|
-
|
|
25
|
-
|
|
27
|
+
if (value instanceof Uint8Array === false) {
|
|
28
|
+
return yield* Effect.die('Received a non-binary RPC response');
|
|
26
29
|
}
|
|
27
|
-
|
|
28
|
-
|
|
30
|
+
for (const message of parser.decode(value)) {
|
|
31
|
+
if (isFromServerEncoded(message) === false) {
|
|
32
|
+
return yield* Effect.die('Received an invalid RPC response');
|
|
33
|
+
}
|
|
29
34
|
yield* writeResponse(message);
|
|
35
|
+
// The RPC exit completes the request; do not wait for the transferred stream to close too.
|
|
36
|
+
if (message._tag === 'Exit')
|
|
37
|
+
return;
|
|
30
38
|
}
|
|
31
39
|
}
|
|
32
|
-
}).pipe(Effect.withSpan('do-rpc-client:processReadableStream'),
|
|
40
|
+
}).pipe(Effect.withSpan('do-rpc-client:processReadableStream'),
|
|
41
|
+
// Cancelling an errored stream rejects with that same error; ignore it so the original failure surfaces.
|
|
42
|
+
Effect.ensuring(Effect.sync(() => {
|
|
43
|
+
// Cancellation is best effort: a disconnected remote producer may never acknowledge it.
|
|
44
|
+
void reader.cancel().catch(() => { });
|
|
45
|
+
reader.releaseLock();
|
|
46
|
+
})));
|
|
33
47
|
});
|
|
34
48
|
/**
|
|
35
49
|
* Creates a Protocol layer that uses Cloudflare Durable Object RPC calls.
|
|
36
50
|
* This enables direct RPC communication with Durable Objects using Cloudflare's native RPC.
|
|
37
51
|
*/
|
|
38
|
-
export const layerProtocolDurableObject = (args) => Layer.
|
|
52
|
+
export const layerProtocolDurableObject = (args) => Layer.effect(RpcClient.Protocol, makeProtocolDurableObject(args)).pipe(Layer.provide(RpcSerialization.layerSchemaBinary()));
|
|
39
53
|
/**
|
|
40
54
|
* Implementation of the RPC Protocol interface using Cloudflare Durable Object RPC calls.
|
|
41
55
|
* Provides the core protocol methods required by @effect/rpc.
|
|
42
56
|
*/
|
|
43
57
|
const makeProtocolDurableObject = ({ callRpc, }) => RpcClient.Protocol.make(Effect.fnUntraced(function* (writeResponse) {
|
|
44
|
-
const
|
|
58
|
+
const serialization = yield* RpcSerialization.RpcSerialization;
|
|
45
59
|
// Not using an actual `FiberMap` here because it seems to shutdown to early
|
|
46
|
-
// const fiberMap = new Map<string, Fiber.
|
|
60
|
+
// const fiberMap = new Map<string, Fiber.Fiber<void, never>>()
|
|
47
61
|
const fiberMap = yield* FiberMap.make();
|
|
48
|
-
const send = (message) => {
|
|
62
|
+
const send = (clientId, message) => {
|
|
49
63
|
if (message._tag !== 'Request') {
|
|
50
64
|
if (message._tag === 'Interrupt') {
|
|
51
65
|
return Effect.gen(function* () {
|
|
52
66
|
const fiber = yield* FiberMap.get(fiberMap, message.requestId);
|
|
53
|
-
|
|
67
|
+
if (Option.isSome(fiber) === true) {
|
|
68
|
+
yield* Fiber.interrupt(fiber.value);
|
|
69
|
+
}
|
|
54
70
|
}).pipe(Effect.orDie);
|
|
55
71
|
}
|
|
56
72
|
return Effect.void;
|
|
57
73
|
}
|
|
74
|
+
// Binary parsers hold stream framing state, so scope one parser to one DO RPC call.
|
|
75
|
+
const parser = serialization.makeUnsafe();
|
|
58
76
|
// Wrap single Request in array to match server expected format
|
|
59
77
|
const serializedPayload = parser.encode([message]);
|
|
78
|
+
if (serializedPayload instanceof Uint8Array === false) {
|
|
79
|
+
return Effect.die('SchemaBinary RPC serialization did not produce bytes');
|
|
80
|
+
}
|
|
60
81
|
return Effect.gen(function* () {
|
|
61
|
-
const serializedResponse = yield* Effect.tryPromise(
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
82
|
+
const serializedResponse = yield* Effect.tryPromise({
|
|
83
|
+
try: () => callRpc(serializedPayload),
|
|
84
|
+
catch: transportFailure,
|
|
85
|
+
});
|
|
86
|
+
if (serializedResponse instanceof Uint8Array) {
|
|
87
|
+
for (const response of parser.decode(serializedResponse)) {
|
|
88
|
+
if (isFromServerEncoded(response) === false) {
|
|
89
|
+
return yield* Effect.die('Received an invalid RPC response');
|
|
90
|
+
}
|
|
91
|
+
yield* writeResponse(clientId, response);
|
|
92
|
+
}
|
|
70
93
|
return;
|
|
71
94
|
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
if (Array.isArray(decoded) === true) {
|
|
77
|
-
responseArray = decoded.flat(1);
|
|
78
|
-
}
|
|
79
|
-
else {
|
|
80
|
-
responseArray = [decoded];
|
|
81
|
-
}
|
|
82
|
-
// Process each response
|
|
83
|
-
for (const response of responseArray) {
|
|
84
|
-
yield* writeResponse(response);
|
|
85
|
-
}
|
|
86
|
-
}).pipe(Effect.withSpan('do-rpc-client:send'), Effect.orDie); // Ensure never error type
|
|
95
|
+
const fiber = yield* processReadableStream(serializedResponse, parser, (response) => writeResponse(clientId, response)).pipe(Effect.forkChild);
|
|
96
|
+
yield* FiberMap.set(fiberMap, message.id, fiber);
|
|
97
|
+
yield* Fiber.join(fiber);
|
|
98
|
+
}).pipe(Effect.withSpan('do-rpc-client:send'));
|
|
87
99
|
};
|
|
88
100
|
return {
|
|
89
101
|
send,
|
|
90
102
|
supportsAck: false, // DO RPC doesn't support ack mechanism like WebSockets
|
|
91
103
|
supportsTransferables: false, // DO RPC doesn't support transferables yet
|
|
104
|
+
codecFor: serialization.codecFor,
|
|
92
105
|
};
|
|
93
106
|
}));
|
|
107
|
+
/**
|
|
108
|
+
* A rejected DO call or stream read fails only the request that made it (Effect RPC routes `send` failures per
|
|
109
|
+
* request). `RpcClientError` reasons are a closed union, so the original rejection rides as `RpcClientDefect.cause`.
|
|
110
|
+
*/
|
|
111
|
+
const transportFailure = (cause) => new RpcClientError.RpcClientError({
|
|
112
|
+
reason: new RpcClientError.RpcClientDefect({ message: 'Durable Object RPC call failed', cause }),
|
|
113
|
+
});
|
|
94
114
|
//# sourceMappingURL=client.js.map
|
|
@@ -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,
|
|
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,189 @@
|
|
|
1
|
+
import { Vitest } from '@livestore/utils-dev/node-vitest';
|
|
2
|
+
import { Cause, Effect, Exit, Fiber, Option, Rpc, RpcClient, RpcClientError, RpcGroup, Schema, Stream, } from '@livestore/utils/effect';
|
|
3
|
+
import { DoRpcReadError, 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
|
+
Vitest.describe('transport failures', () => {
|
|
76
|
+
Vitest.live('fails a unary call with an RpcClientError that keeps the rejected error', () => Effect.gen(function* () {
|
|
77
|
+
const rejected = cloudflareError();
|
|
78
|
+
const exit = yield* RpcClient.make(Rpcs).pipe(Effect.flatMap((client) => client.Echo({ text: 'hi' })), Effect.exit, Effect.provide(protocolWith(() => Promise.reject(rejected))), Effect.timeout('2 seconds'));
|
|
79
|
+
Vitest.expect(transportFailureCause(exit)).toBe(rejected);
|
|
80
|
+
}));
|
|
81
|
+
Vitest.live('preserves a read failure through rejected cancellation and releases the reader lock', () => Effect.gen(function* () {
|
|
82
|
+
const rejected = cloudflareError();
|
|
83
|
+
let failedStream;
|
|
84
|
+
const failAfterFirstRead = (bytes) => {
|
|
85
|
+
let isFirstRead = true;
|
|
86
|
+
const stream = new ReadableStream({
|
|
87
|
+
pull(controller) {
|
|
88
|
+
if (isFirstRead === false)
|
|
89
|
+
return controller.error(rejected);
|
|
90
|
+
isFirstRead = false;
|
|
91
|
+
controller.enqueue(bytes.subarray(0, READ_CHUNK_SIZE));
|
|
92
|
+
},
|
|
93
|
+
});
|
|
94
|
+
failedStream = stream;
|
|
95
|
+
// oxlint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- bridge platform ReadableStream to the CF type, like server.ts
|
|
96
|
+
return stream;
|
|
97
|
+
};
|
|
98
|
+
const exit = yield* RpcClient.make(Rpcs).pipe(Effect.flatMap((client) => client.BigStream({ n: expectedRows.length }).pipe(Stream.runCollect)), Effect.exit, Effect.provide(protocolWith(makeGatedCallRpc(failAfterFirstRead))), Effect.timeout('2 seconds'));
|
|
99
|
+
Vitest.expect(transportFailureCause(exit)).toBe(rejected);
|
|
100
|
+
Vitest.expect(failedStream?.locked).toBe(false);
|
|
101
|
+
}));
|
|
102
|
+
Vitest.live('fails only the request whose call rejected', () => Effect.gen(function* () {
|
|
103
|
+
let releaseStream = () => { };
|
|
104
|
+
const streamReleased = new Promise((resolve) => {
|
|
105
|
+
releaseStream = resolve;
|
|
106
|
+
});
|
|
107
|
+
const gatedUntilReleased = (bytes) => {
|
|
108
|
+
const stream = new ReadableStream({
|
|
109
|
+
async start(controller) {
|
|
110
|
+
await streamReleased;
|
|
111
|
+
controller.enqueue(bytes);
|
|
112
|
+
controller.close();
|
|
113
|
+
},
|
|
114
|
+
});
|
|
115
|
+
// oxlint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- bridge platform ReadableStream to the CF type, like server.ts
|
|
116
|
+
return stream;
|
|
117
|
+
};
|
|
118
|
+
const callStream = makeGatedCallRpc(gatedUntilReleased);
|
|
119
|
+
let calls = 0;
|
|
120
|
+
const callRpc = (payload) => {
|
|
121
|
+
calls++;
|
|
122
|
+
return calls === 1 ? callStream(payload) : Promise.reject(cloudflareError());
|
|
123
|
+
};
|
|
124
|
+
const result = yield* Effect.gen(function* () {
|
|
125
|
+
const client = yield* RpcClient.make(Rpcs);
|
|
126
|
+
const streamFiber = yield* client
|
|
127
|
+
.BigStream({ n: expectedRows.length })
|
|
128
|
+
.pipe(Stream.runCollect, Effect.forkChild);
|
|
129
|
+
yield* Effect.yieldNow;
|
|
130
|
+
const echoExit = yield* client.Echo({ text: 'hi' }).pipe(Effect.exit);
|
|
131
|
+
yield* Effect.sync(() => releaseStream());
|
|
132
|
+
const rows = yield* Fiber.join(streamFiber);
|
|
133
|
+
return { echoExit, rows: Array.from(rows) };
|
|
134
|
+
}).pipe(Effect.provide(protocolWith(callRpc)), Effect.timeout('2 seconds'));
|
|
135
|
+
Vitest.expect(transportFailureCause(result.echoExit)).toBeInstanceOf(Error);
|
|
136
|
+
Vitest.expect(result.rows).toEqual(expectedRows);
|
|
137
|
+
}));
|
|
138
|
+
Vitest.live('interruption releases the reader even when remote cancellation never completes', () => Effect.gen(function* () {
|
|
139
|
+
const stream = new ReadableStream({ cancel: () => new Promise(() => { }) });
|
|
140
|
+
const exit = yield* RpcClient.make(Rpcs).pipe(Effect.flatMap((client) => client.BigStream({ n: 1 }).pipe(Stream.runDrain, Effect.timeout('20 millis'))), Effect.exit,
|
|
141
|
+
// oxlint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- bridge the platform stream to the CF type
|
|
142
|
+
Effect.provide(protocolWith(async () => stream)), Effect.timeout('2 seconds'));
|
|
143
|
+
Vitest.expect(Exit.isFailure(exit)).toBe(true);
|
|
144
|
+
Vitest.expect(stream.locked).toBe(false);
|
|
145
|
+
}));
|
|
146
|
+
Vitest.live('reports a truncated response as a read failure instead of waiting forever for an RPC exit', () => Effect.gen(function* () {
|
|
147
|
+
const stream = new ReadableStream({ start: (controller) => controller.close() });
|
|
148
|
+
const exit = yield* RpcClient.make(Rpcs).pipe(Effect.flatMap((client) => client.BigStream({ n: 1 }).pipe(Stream.runCollect)), Effect.exit,
|
|
149
|
+
// oxlint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- bridge the platform stream to the CF type
|
|
150
|
+
Effect.provide(protocolWith(async () => stream)), Effect.timeout('2 seconds'));
|
|
151
|
+
Vitest.expect(transportFailureCause(exit)).toEqual(new Error('RPC stream ended before its exit'));
|
|
152
|
+
}));
|
|
153
|
+
});
|
|
154
|
+
const cloudflareError = () => Object.assign(new Error('Network connection lost.'), { retryable: true });
|
|
155
|
+
const protocolWith = (callRpc) => layerProtocolDurableObject({ callRpc, callerContext: { bindingName: 'TEST', durableObjectId: 'id' } });
|
|
156
|
+
/** The rejected error carried by a typed transport failure, or `undefined` for any other outcome (including a defect). */
|
|
157
|
+
const transportFailureCause = (exit) => {
|
|
158
|
+
if (Exit.isSuccess(exit) === true)
|
|
159
|
+
return undefined;
|
|
160
|
+
const error = Option.getOrUndefined(Cause.findErrorOption(exit.cause));
|
|
161
|
+
if (error instanceof RpcClientError.RpcClientError === false)
|
|
162
|
+
return undefined;
|
|
163
|
+
if (error.reason._tag !== 'RpcClientDefect')
|
|
164
|
+
return undefined;
|
|
165
|
+
return error.reason.cause instanceof DoRpcReadError ? error.reason.cause.cause : error.reason.cause;
|
|
166
|
+
};
|
|
167
|
+
const makeGatedCallRpc = (gateStream) => (payload) => toDurableObjectHandler(Rpcs, { layer: ServerLive })(new Uint8Array(payload)).pipe(Effect.filterOrElse(
|
|
168
|
+
// Narrow on `Uint8Array`; the `ReadableStream` global differs from `CfTypes` across envs.
|
|
169
|
+
(result) => result instanceof Uint8Array, (result) => Effect.promise(() => collectBytes(result)).pipe(Effect.map(gateStream))), Effect.runPromise);
|
|
170
|
+
const collectBytes = async (stream) => {
|
|
171
|
+
const reader = stream.getReader();
|
|
172
|
+
const parts = [];
|
|
173
|
+
let total = 0;
|
|
174
|
+
for (;;) {
|
|
175
|
+
const { done, value } = await reader.read();
|
|
176
|
+
if (done === true)
|
|
177
|
+
break;
|
|
178
|
+
parts.push(value);
|
|
179
|
+
total += value.length;
|
|
180
|
+
}
|
|
181
|
+
const out = new Uint8Array(total);
|
|
182
|
+
let offset = 0;
|
|
183
|
+
for (const part of parts) {
|
|
184
|
+
out.set(part, offset);
|
|
185
|
+
offset += part.length;
|
|
186
|
+
}
|
|
187
|
+
return out;
|
|
188
|
+
};
|
|
189
|
+
//# 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/mod.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { layerProtocolDurableObject } from './client.ts';
|
|
1
|
+
export { DoRpcReadError, layerProtocolDurableObject } from './client.ts';
|
|
2
2
|
export { type ClientDoWithRpcCallback, emitStreamResponse, toDurableObjectHandler } from './server.ts';
|
|
3
3
|
//# sourceMappingURL=mod.d.ts.map
|
package/dist/do-rpc/mod.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../../src/do-rpc/mod.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../../src/do-rpc/mod.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAA;AACxE,OAAO,EAAE,KAAK,uBAAuB,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAA"}
|
package/dist/do-rpc/mod.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
// Re-export client and server implementations for backward compatibility
|
|
2
|
-
export { layerProtocolDurableObject } from
|
|
3
|
-
export { emitStreamResponse, toDurableObjectHandler } from
|
|
2
|
+
export { DoRpcReadError, layerProtocolDurableObject } from './client.js';
|
|
3
|
+
export { emitStreamResponse, toDurableObjectHandler } from './server.js';
|
|
4
4
|
//# sourceMappingURL=mod.js.map
|
package/dist/do-rpc/mod.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mod.js","sourceRoot":"","sources":["../../src/do-rpc/mod.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,OAAO,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"mod.js","sourceRoot":"","sources":["../../src/do-rpc/mod.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,OAAO,EAAE,cAAc,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAA;AACxE,OAAO,EAAgC,kBAAkB,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAA"}
|