effect-cf 0.0.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/README.md +79 -0
- package/dist/chunk-CfYAbeIz.mjs +13 -0
- package/dist/index.d.mts +1362 -0
- package/dist/index.mjs +1198 -0
- package/package.json +47 -0
- package/src/Binding.ts +70 -0
- package/src/DurableObject.ts +220 -0
- package/src/DurableObjectDefinition.ts +214 -0
- package/src/DurableObjectNamespace.ts +483 -0
- package/src/DurableObjectRpcWebSocket.ts +222 -0
- package/src/DurableObjectState.ts +127 -0
- package/src/DurableObjectStorage.ts +381 -0
- package/src/DurableObjectWebSocket.ts +62 -0
- package/src/Entry.ts +259 -0
- package/src/Environment.ts +86 -0
- package/src/Kv.ts +244 -0
- package/src/Rpc.ts +127 -0
- package/src/RpcDefinition.ts +354 -0
- package/src/ServiceBinding.ts +278 -0
- package/src/Worker.ts +264 -0
- package/src/WorkerDefinition.ts +206 -0
- package/src/index.ts +15 -0
- package/src/internal/Entrypoint.ts +40 -0
- package/src/internal/RpcInvocation.ts +73 -0
package/src/Rpc.ts
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { RpcStub, RpcTarget } from "cloudflare:workers";
|
|
2
|
+
import { Effect, type Scope } from "effect";
|
|
3
|
+
|
|
4
|
+
export { RpcStub, RpcTarget };
|
|
5
|
+
|
|
6
|
+
export type Stubable = Rpc.Stubable;
|
|
7
|
+
|
|
8
|
+
export type Stub<T extends Stubable> = Rpc.Stub<T>;
|
|
9
|
+
|
|
10
|
+
export type Provider<T extends object, Reserved extends string = never> = Rpc.Provider<T, Reserved>;
|
|
11
|
+
|
|
12
|
+
type BaseType =
|
|
13
|
+
| void
|
|
14
|
+
| undefined
|
|
15
|
+
| null
|
|
16
|
+
| boolean
|
|
17
|
+
| number
|
|
18
|
+
| bigint
|
|
19
|
+
| string
|
|
20
|
+
| TypedArray
|
|
21
|
+
| ArrayBuffer
|
|
22
|
+
| DataView
|
|
23
|
+
| Date
|
|
24
|
+
| Error
|
|
25
|
+
| RegExp
|
|
26
|
+
| ReadableStream<Uint8Array>
|
|
27
|
+
| WritableStream<Uint8Array>
|
|
28
|
+
| Request
|
|
29
|
+
| Response
|
|
30
|
+
| Headers;
|
|
31
|
+
|
|
32
|
+
export type Serializable<T> =
|
|
33
|
+
| BaseType
|
|
34
|
+
| Map<
|
|
35
|
+
T extends Map<infer Key, unknown> ? Serializable<Key> : never,
|
|
36
|
+
T extends Map<unknown, infer Value> ? Serializable<Value> : never
|
|
37
|
+
>
|
|
38
|
+
| Set<T extends Set<infer Value> ? Serializable<Value> : never>
|
|
39
|
+
| ReadonlyArray<T extends ReadonlyArray<infer Value> ? Serializable<Value> : never>
|
|
40
|
+
| {
|
|
41
|
+
[Key in keyof T]: Key extends number | string ? Serializable<T[Key]> : never;
|
|
42
|
+
}
|
|
43
|
+
| Stub<Stubable>
|
|
44
|
+
| Stubable;
|
|
45
|
+
|
|
46
|
+
export type Stubify<T> = T extends Stubable
|
|
47
|
+
? Stub<T>
|
|
48
|
+
: T extends Map<infer Key, infer Value>
|
|
49
|
+
? Map<Stubify<Key>, Stubify<Value>>
|
|
50
|
+
: T extends Set<infer Value>
|
|
51
|
+
? Set<Stubify<Value>>
|
|
52
|
+
: T extends Array<infer Value>
|
|
53
|
+
? Array<Stubify<Value>>
|
|
54
|
+
: T extends ReadonlyArray<infer Value>
|
|
55
|
+
? ReadonlyArray<Stubify<Value>>
|
|
56
|
+
: T extends BaseType
|
|
57
|
+
? T
|
|
58
|
+
: T extends {
|
|
59
|
+
[key: string | number]: unknown;
|
|
60
|
+
}
|
|
61
|
+
? {
|
|
62
|
+
[Key in keyof T]: Stubify<T[Key]>;
|
|
63
|
+
}
|
|
64
|
+
: T;
|
|
65
|
+
|
|
66
|
+
type MaybeProvider<T> = T extends object ? Provider<T> : unknown;
|
|
67
|
+
type MaybeDisposable<T> = T extends object ? Disposable : unknown;
|
|
68
|
+
|
|
69
|
+
export type Result<T> = T extends Stubable
|
|
70
|
+
? Promise<Stub<T>> & Provider<T>
|
|
71
|
+
: T extends Serializable<T>
|
|
72
|
+
? Promise<Stubify<T> & MaybeDisposable<T>> & MaybeProvider<T>
|
|
73
|
+
: never;
|
|
74
|
+
|
|
75
|
+
export type MethodKey<Api> = {
|
|
76
|
+
[Key in keyof Api]-?: Key extends string
|
|
77
|
+
? Api[Key] extends (...args: Array<any>) => unknown
|
|
78
|
+
? Key
|
|
79
|
+
: never
|
|
80
|
+
: never;
|
|
81
|
+
}[keyof Api];
|
|
82
|
+
|
|
83
|
+
export type MethodArgs<Api, Method extends keyof Api> = Api[Method] extends (
|
|
84
|
+
...args: infer Args
|
|
85
|
+
) => unknown
|
|
86
|
+
? Args
|
|
87
|
+
: never;
|
|
88
|
+
|
|
89
|
+
export type MethodReturn<Api, Method extends keyof Api> = Api[Method] extends (
|
|
90
|
+
...args: Array<any>
|
|
91
|
+
) => infer Return
|
|
92
|
+
? Return
|
|
93
|
+
: never;
|
|
94
|
+
|
|
95
|
+
export type DisposableValue = {
|
|
96
|
+
[Symbol.dispose](): void;
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
export const isDisposable = (value: unknown): value is DisposableValue =>
|
|
100
|
+
(typeof value === "object" || typeof value === "function") &&
|
|
101
|
+
value !== null &&
|
|
102
|
+
Symbol.dispose in value &&
|
|
103
|
+
typeof (value as { readonly [Symbol.dispose]?: unknown })[Symbol.dispose] === "function";
|
|
104
|
+
|
|
105
|
+
export const dispose = (value: unknown): Effect.Effect<void> =>
|
|
106
|
+
Effect.sync(() => {
|
|
107
|
+
if (isDisposable(value)) {
|
|
108
|
+
value[Symbol.dispose]();
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
export const resolve = <A>(value: A): Effect.Effect<Awaited<A>, unknown> =>
|
|
113
|
+
isPromiseLike(value)
|
|
114
|
+
? Effect.tryPromise({
|
|
115
|
+
try: () => value,
|
|
116
|
+
catch: (cause) => cause,
|
|
117
|
+
})
|
|
118
|
+
: Effect.sync(() => value as Awaited<A>);
|
|
119
|
+
|
|
120
|
+
export const scoped = <A>(value: A): Effect.Effect<Awaited<A>, unknown, Scope.Scope> =>
|
|
121
|
+
Effect.acquireRelease(resolve(value), (resolved) => dispose(resolved));
|
|
122
|
+
|
|
123
|
+
const isPromiseLike = <A>(value: A): value is A & PromiseLike<Awaited<A>> =>
|
|
124
|
+
(typeof value === "object" || typeof value === "function") &&
|
|
125
|
+
value !== null &&
|
|
126
|
+
"then" in value &&
|
|
127
|
+
typeof (value as { readonly then?: unknown }).then === "function";
|
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
import { Data, Effect, Schema as S } from "effect";
|
|
2
|
+
|
|
3
|
+
import type * as Rpc from "./Rpc";
|
|
4
|
+
|
|
5
|
+
export class RpcReservedMethodNameError extends Data.TaggedError("RpcReservedMethodNameError")<{
|
|
6
|
+
readonly definition: string;
|
|
7
|
+
readonly method: string;
|
|
8
|
+
}> {}
|
|
9
|
+
|
|
10
|
+
export class RpcArgumentCountError extends Data.TaggedError("RpcArgumentCountError")<{
|
|
11
|
+
readonly definition: string;
|
|
12
|
+
readonly method: string;
|
|
13
|
+
readonly expected: number;
|
|
14
|
+
readonly actual: number;
|
|
15
|
+
}> {}
|
|
16
|
+
|
|
17
|
+
export class RpcArgumentDecodeError extends Data.TaggedError("RpcArgumentDecodeError")<{
|
|
18
|
+
readonly definition: string;
|
|
19
|
+
readonly method: string;
|
|
20
|
+
readonly index: number;
|
|
21
|
+
readonly cause: unknown;
|
|
22
|
+
}> {}
|
|
23
|
+
|
|
24
|
+
export class RpcArgumentEncodeError extends Data.TaggedError("RpcArgumentEncodeError")<{
|
|
25
|
+
readonly definition: string;
|
|
26
|
+
readonly method: string;
|
|
27
|
+
readonly index: number;
|
|
28
|
+
readonly cause: unknown;
|
|
29
|
+
}> {}
|
|
30
|
+
|
|
31
|
+
export class RpcSuccessDecodeError extends Data.TaggedError("RpcSuccessDecodeError")<{
|
|
32
|
+
readonly definition: string;
|
|
33
|
+
readonly method: string;
|
|
34
|
+
readonly cause: unknown;
|
|
35
|
+
}> {}
|
|
36
|
+
|
|
37
|
+
export class RpcSuccessEncodeError extends Data.TaggedError("RpcSuccessEncodeError")<{
|
|
38
|
+
readonly definition: string;
|
|
39
|
+
readonly method: string;
|
|
40
|
+
readonly cause: unknown;
|
|
41
|
+
}> {}
|
|
42
|
+
|
|
43
|
+
export const reservedMethodNames = new Set([
|
|
44
|
+
"constructor",
|
|
45
|
+
"fetch",
|
|
46
|
+
"connect",
|
|
47
|
+
"alarm",
|
|
48
|
+
"webSocketMessage",
|
|
49
|
+
"webSocketClose",
|
|
50
|
+
"webSocketError",
|
|
51
|
+
"then",
|
|
52
|
+
"dup",
|
|
53
|
+
"dispose",
|
|
54
|
+
"serialize",
|
|
55
|
+
"deserialize",
|
|
56
|
+
]);
|
|
57
|
+
|
|
58
|
+
export type ReservedMethodName =
|
|
59
|
+
| "constructor"
|
|
60
|
+
| "fetch"
|
|
61
|
+
| "connect"
|
|
62
|
+
| "alarm"
|
|
63
|
+
| "webSocketMessage"
|
|
64
|
+
| "webSocketClose"
|
|
65
|
+
| "webSocketError"
|
|
66
|
+
| "then"
|
|
67
|
+
| "dup"
|
|
68
|
+
| "dispose"
|
|
69
|
+
| "serialize"
|
|
70
|
+
| "deserialize";
|
|
71
|
+
|
|
72
|
+
export type ServiceFreeSchema = S.Codec<any, any, never, never>;
|
|
73
|
+
|
|
74
|
+
export interface Method<
|
|
75
|
+
Args extends ReadonlyArray<ServiceFreeSchema> = ReadonlyArray<ServiceFreeSchema>,
|
|
76
|
+
Success extends ServiceFreeSchema = ServiceFreeSchema,
|
|
77
|
+
> {
|
|
78
|
+
readonly args: Args;
|
|
79
|
+
readonly success: Success;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export namespace Method {
|
|
83
|
+
export type Any = Method<ReadonlyArray<ServiceFreeSchema>, ServiceFreeSchema>;
|
|
84
|
+
|
|
85
|
+
type ArgsFromSchemas<Args extends ReadonlyArray<ServiceFreeSchema>> = Args extends readonly []
|
|
86
|
+
? []
|
|
87
|
+
: Args extends readonly [
|
|
88
|
+
infer Head extends ServiceFreeSchema,
|
|
89
|
+
...infer Tail extends ReadonlyArray<ServiceFreeSchema>,
|
|
90
|
+
]
|
|
91
|
+
? [S.Schema.Type<Head>, ...ArgsFromSchemas<Tail>]
|
|
92
|
+
: Array<S.Schema.Type<Args[number]>>;
|
|
93
|
+
|
|
94
|
+
type EncodedArgsFromSchemas<Args extends ReadonlyArray<ServiceFreeSchema>> =
|
|
95
|
+
Args extends readonly []
|
|
96
|
+
? []
|
|
97
|
+
: Args extends readonly [
|
|
98
|
+
infer Head extends ServiceFreeSchema,
|
|
99
|
+
...infer Tail extends ReadonlyArray<ServiceFreeSchema>,
|
|
100
|
+
]
|
|
101
|
+
? [S.Codec.Encoded<Head>, ...EncodedArgsFromSchemas<Tail>]
|
|
102
|
+
: Array<S.Codec.Encoded<Args[number]>>;
|
|
103
|
+
|
|
104
|
+
export type Args<Self extends Any> = ArgsFromSchemas<Self["args"]>;
|
|
105
|
+
|
|
106
|
+
export type EncodedArgs<Self extends Any> = EncodedArgsFromSchemas<Self["args"]>;
|
|
107
|
+
|
|
108
|
+
export type Success<Self extends Any> = S.Schema.Type<Self["success"]>;
|
|
109
|
+
|
|
110
|
+
export type EncodedSuccess<Self extends Any> = S.Codec.Encoded<Self["success"]>;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export type Methods = Record<string, Method.Any>;
|
|
114
|
+
|
|
115
|
+
export type NoReservedMethods<
|
|
116
|
+
MethodsShape extends Methods,
|
|
117
|
+
Reserved extends string = ReservedMethodName,
|
|
118
|
+
> = Extract<keyof MethodsShape, Reserved> extends never ? MethodsShape : never;
|
|
119
|
+
|
|
120
|
+
export interface Definition<Id extends string = string, MethodsShape extends Methods = Methods> {
|
|
121
|
+
readonly id: Id;
|
|
122
|
+
readonly methods: MethodsShape;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export namespace Definition {
|
|
126
|
+
export type Any = Definition<string, Methods>;
|
|
127
|
+
|
|
128
|
+
export type ServerApi<Self extends Any> = {
|
|
129
|
+
readonly [Key in keyof Self["methods"]]: (
|
|
130
|
+
...args: Method.Args<Self["methods"][Key]>
|
|
131
|
+
) => Promise<Method.Success<Self["methods"][Key]>>;
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
export type Api<Self extends Any, Reserved extends string = never> = Rpc.Provider<
|
|
135
|
+
ServerApi<Self>,
|
|
136
|
+
Reserved
|
|
137
|
+
>;
|
|
138
|
+
|
|
139
|
+
export type MethodNames<Self extends Any> = Extract<keyof Self["methods"], string>;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export class ReservedMethodNameError extends Error {
|
|
143
|
+
readonly method: string;
|
|
144
|
+
readonly target: string;
|
|
145
|
+
|
|
146
|
+
constructor(target: string, method: string) {
|
|
147
|
+
super(`${target} RPC method "${method}" is reserved by Cloudflare Workers RPC`);
|
|
148
|
+
this.name = "ReservedMethodNameError";
|
|
149
|
+
this.target = target;
|
|
150
|
+
this.method = method;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
export const assertNoReservedMethods = (
|
|
155
|
+
target: string,
|
|
156
|
+
methods: Record<string, unknown>,
|
|
157
|
+
reserved: ReadonlySet<string>,
|
|
158
|
+
) => {
|
|
159
|
+
for (const method of Object.keys(methods)) {
|
|
160
|
+
if (reserved.has(method)) {
|
|
161
|
+
throw new ReservedMethodNameError(target, method);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
export function method<Success extends ServiceFreeSchema>(definition: {
|
|
167
|
+
readonly success: Success;
|
|
168
|
+
}): Method<readonly [], Success>;
|
|
169
|
+
export function method<
|
|
170
|
+
const Args extends ReadonlyArray<ServiceFreeSchema>,
|
|
171
|
+
Success extends ServiceFreeSchema,
|
|
172
|
+
>(definition: { readonly args: Args; readonly success: Success }): Method<Args, Success>;
|
|
173
|
+
export function method(definition: {
|
|
174
|
+
readonly args?: ReadonlyArray<ServiceFreeSchema>;
|
|
175
|
+
readonly success: ServiceFreeSchema;
|
|
176
|
+
}) {
|
|
177
|
+
return {
|
|
178
|
+
args: definition.args ?? [],
|
|
179
|
+
success: definition.success,
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
export const assertNoReservedMethodNames = (
|
|
184
|
+
definition: Definition.Any,
|
|
185
|
+
): Effect.Effect<void, RpcReservedMethodNameError> =>
|
|
186
|
+
Effect.forEach(Object.keys(definition.methods), (method) =>
|
|
187
|
+
reservedMethodNames.has(method)
|
|
188
|
+
? Effect.fail(new RpcReservedMethodNameError({ definition: definition.id, method }))
|
|
189
|
+
: Effect.void,
|
|
190
|
+
).pipe(Effect.asVoid);
|
|
191
|
+
|
|
192
|
+
export const decodeArgs = <
|
|
193
|
+
const Self extends Definition.Any,
|
|
194
|
+
MethodName extends Definition.MethodNames<Self>,
|
|
195
|
+
>(
|
|
196
|
+
definition: Self,
|
|
197
|
+
methodName: MethodName,
|
|
198
|
+
args: ReadonlyArray<unknown>,
|
|
199
|
+
): Effect.Effect<
|
|
200
|
+
Method.Args<Self["methods"][MethodName]>,
|
|
201
|
+
RpcArgumentCountError | RpcArgumentDecodeError
|
|
202
|
+
> =>
|
|
203
|
+
Effect.gen(function* () {
|
|
204
|
+
const methodDefinition = definition.methods[methodName];
|
|
205
|
+
|
|
206
|
+
if (args.length !== methodDefinition.args.length) {
|
|
207
|
+
return yield* Effect.fail(
|
|
208
|
+
new RpcArgumentCountError({
|
|
209
|
+
definition: definition.id,
|
|
210
|
+
method: methodName,
|
|
211
|
+
expected: methodDefinition.args.length,
|
|
212
|
+
actual: args.length,
|
|
213
|
+
}),
|
|
214
|
+
);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
const decoded: Array<unknown> = [];
|
|
218
|
+
|
|
219
|
+
for (let index = 0; index < methodDefinition.args.length; index++) {
|
|
220
|
+
const schema = methodDefinition.args[index];
|
|
221
|
+
decoded.push(
|
|
222
|
+
yield* (S.decodeUnknownEffect(schema)(args[index]) as Effect.Effect<unknown, unknown>).pipe(
|
|
223
|
+
Effect.mapError(
|
|
224
|
+
(cause) =>
|
|
225
|
+
new RpcArgumentDecodeError({
|
|
226
|
+
definition: definition.id,
|
|
227
|
+
method: methodName,
|
|
228
|
+
index,
|
|
229
|
+
cause,
|
|
230
|
+
}),
|
|
231
|
+
),
|
|
232
|
+
),
|
|
233
|
+
);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
return decoded as Method.Args<Self["methods"][MethodName]>;
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
export const encodeArgs = <
|
|
240
|
+
const Self extends Definition.Any,
|
|
241
|
+
MethodName extends Definition.MethodNames<Self>,
|
|
242
|
+
>(
|
|
243
|
+
definition: Self,
|
|
244
|
+
methodName: MethodName,
|
|
245
|
+
args: Method.Args<Self["methods"][MethodName]>,
|
|
246
|
+
): Effect.Effect<
|
|
247
|
+
Method.EncodedArgs<Self["methods"][MethodName]>,
|
|
248
|
+
RpcArgumentCountError | RpcArgumentEncodeError
|
|
249
|
+
> =>
|
|
250
|
+
Effect.gen(function* () {
|
|
251
|
+
const methodDefinition = definition.methods[methodName];
|
|
252
|
+
|
|
253
|
+
if (args.length !== methodDefinition.args.length) {
|
|
254
|
+
return yield* Effect.fail(
|
|
255
|
+
new RpcArgumentCountError({
|
|
256
|
+
definition: definition.id,
|
|
257
|
+
method: methodName,
|
|
258
|
+
expected: methodDefinition.args.length,
|
|
259
|
+
actual: args.length,
|
|
260
|
+
}),
|
|
261
|
+
);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
const encoded: Array<unknown> = [];
|
|
265
|
+
|
|
266
|
+
for (let index = 0; index < methodDefinition.args.length; index++) {
|
|
267
|
+
const schema = methodDefinition.args[index];
|
|
268
|
+
encoded.push(
|
|
269
|
+
yield* (S.encodeEffect(schema)(args[index]) as Effect.Effect<unknown, unknown>).pipe(
|
|
270
|
+
Effect.mapError(
|
|
271
|
+
(cause) =>
|
|
272
|
+
new RpcArgumentEncodeError({
|
|
273
|
+
definition: definition.id,
|
|
274
|
+
method: methodName,
|
|
275
|
+
index,
|
|
276
|
+
cause,
|
|
277
|
+
}),
|
|
278
|
+
),
|
|
279
|
+
),
|
|
280
|
+
);
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
return encoded as Method.EncodedArgs<Self["methods"][MethodName]>;
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
export const encodeSuccess = <
|
|
287
|
+
const Self extends Definition.Any,
|
|
288
|
+
MethodName extends Definition.MethodNames<Self>,
|
|
289
|
+
>(
|
|
290
|
+
definition: Self,
|
|
291
|
+
methodName: MethodName,
|
|
292
|
+
value: Method.Success<Self["methods"][MethodName]>,
|
|
293
|
+
): Effect.Effect<Method.EncodedSuccess<Self["methods"][MethodName]>, RpcSuccessEncodeError> => {
|
|
294
|
+
const methodDefinition = definition.methods[methodName];
|
|
295
|
+
|
|
296
|
+
return (
|
|
297
|
+
S.encodeEffect(methodDefinition.success)(value) as Effect.Effect<
|
|
298
|
+
Method.EncodedSuccess<Self["methods"][MethodName]>,
|
|
299
|
+
unknown
|
|
300
|
+
>
|
|
301
|
+
).pipe(
|
|
302
|
+
Effect.mapError(
|
|
303
|
+
(cause) =>
|
|
304
|
+
new RpcSuccessEncodeError({
|
|
305
|
+
definition: definition.id,
|
|
306
|
+
method: methodName,
|
|
307
|
+
cause,
|
|
308
|
+
}),
|
|
309
|
+
),
|
|
310
|
+
);
|
|
311
|
+
};
|
|
312
|
+
|
|
313
|
+
export const decodeSuccess = <
|
|
314
|
+
const Self extends Definition.Any,
|
|
315
|
+
MethodName extends Definition.MethodNames<Self>,
|
|
316
|
+
>(
|
|
317
|
+
definition: Self,
|
|
318
|
+
methodName: MethodName,
|
|
319
|
+
value: unknown,
|
|
320
|
+
): Effect.Effect<Method.Success<Self["methods"][MethodName]>, RpcSuccessDecodeError> => {
|
|
321
|
+
const methodDefinition = definition.methods[methodName];
|
|
322
|
+
|
|
323
|
+
return (
|
|
324
|
+
S.decodeUnknownEffect(methodDefinition.success)(value) as Effect.Effect<
|
|
325
|
+
Method.Success<Self["methods"][MethodName]>,
|
|
326
|
+
unknown
|
|
327
|
+
>
|
|
328
|
+
).pipe(
|
|
329
|
+
Effect.mapError(
|
|
330
|
+
(cause) =>
|
|
331
|
+
new RpcSuccessDecodeError({
|
|
332
|
+
definition: definition.id,
|
|
333
|
+
method: methodName,
|
|
334
|
+
cause,
|
|
335
|
+
}),
|
|
336
|
+
),
|
|
337
|
+
);
|
|
338
|
+
};
|
|
339
|
+
|
|
340
|
+
export const make = <Id extends string, const MethodsShape extends Methods>(
|
|
341
|
+
id: Id,
|
|
342
|
+
methods: MethodsShape,
|
|
343
|
+
): Definition<Id, MethodsShape> => {
|
|
344
|
+
const definition = { id, methods } as Definition<Id, MethodsShape>;
|
|
345
|
+
const reserved = Object.keys(definition.methods).find((methodName) =>
|
|
346
|
+
reservedMethodNames.has(methodName),
|
|
347
|
+
);
|
|
348
|
+
|
|
349
|
+
if (reserved !== undefined) {
|
|
350
|
+
throw new RpcReservedMethodNameError({ definition: id, method: reserved });
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
return definition;
|
|
354
|
+
};
|