@vastblast/capnweb 0.4.1 → 0.4.2

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/LICENSE.txt CHANGED
File without changes
package/README.md CHANGED
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
package/dist/index.cjs CHANGED
File without changes
File without changes
package/dist/index.d.cts CHANGED
@@ -1,184 +1,226 @@
1
1
  import { IncomingMessage, ServerResponse, OutgoingHttpHeaders, OutgoingHttpHeader } from 'node:http';
2
2
 
3
- // Copyright (c) 2025 Cloudflare, Inc.
4
- // Licensed under the MIT license found in the LICENSE.txt file or at:
5
- // https://opensource.org/license/mit
6
-
7
- // This file borrows heavily from `types/defines/rpc.d.ts` in workerd.
8
-
9
- // Branded types for identifying `WorkerEntrypoint`/`DurableObject`/`Target`s.
10
- // TypeScript uses *structural* typing meaning anything with the same shape as type `T` is a `T`.
11
- // For the classes exported by `cloudflare:workers` we want *nominal* typing (i.e. we only want to
12
- // accept `WorkerEntrypoint` from `cloudflare:workers`, not any other class with the same shape)
13
- declare const __RPC_STUB_BRAND: '__RPC_STUB_BRAND';
14
- declare const __RPC_TARGET_BRAND: '__RPC_TARGET_BRAND';
15
- interface RpcTargetBranded {
16
- [__RPC_TARGET_BRAND]: never;
17
- }
18
-
19
- // Types that can be used through `Stub`s
20
- type Stubable = RpcTargetBranded | ((...args: any[]) => any);
21
-
22
- // Types that can be passed over RPC
23
- // The reason for using a generic type here is to build a serializable subset of structured
24
- // cloneable composite types. This allows types defined with the "interface" keyword to pass the
25
- // serializable check as well. Otherwise, only types defined with the "type" keyword would pass.
26
- type RpcCompatible<T> =
27
- // Structured cloneables
28
- | BaseType
29
- // Structured cloneable composites
30
- | Map<
31
- T extends Map<infer U, unknown> ? RpcCompatible<U> : never,
32
- T extends Map<unknown, infer U> ? RpcCompatible<U> : never
33
- >
34
- | Set<T extends Set<infer U> ? RpcCompatible<U> : never>
35
- | Array<T extends Array<infer U> ? RpcCompatible<U> : never>
36
- | ReadonlyArray<T extends ReadonlyArray<infer U> ? RpcCompatible<U> : never>
37
- | {
38
- [K in keyof T as K extends string | number ? K : never]: RpcCompatible<T[K]>;
39
- }
40
- | Promise<T extends Promise<infer U> ? RpcCompatible<U> : never>
41
- // Special types
42
- | Stub<Stubable>
43
- // Serialized as stubs, see `Stubify`
44
- | Stubable;
45
-
46
- // Base type for all RPC stubs, including common memory management methods.
47
- // `T` is used as a marker type for unwrapping `Stub`s later.
48
- interface StubBase<T extends RpcCompatible<T>> extends Disposable {
49
- [__RPC_STUB_BRAND]: T;
50
- dup(): this;
51
- onRpcBroken(callback: (error: any) => void): void;
52
- }
53
- type Stub<T extends RpcCompatible<T>> =
54
- T extends object ? Provider<T> & StubBase<T> : StubBase<T>;
55
-
56
- type TypedArray =
57
- | Uint8Array
58
- | Uint8ClampedArray
59
- | Uint16Array
60
- | Uint32Array
61
- | Int8Array
62
- | Int16Array
63
- | Int32Array
64
- | BigUint64Array
65
- | BigInt64Array
66
- | Float32Array
67
- | Float64Array;
68
-
69
- // This represents all the types that can be sent as-is over an RPC boundary
70
- type BaseType =
71
- | void
72
- | undefined
73
- | null
74
- | boolean
75
- | number
76
- | bigint
77
- | string
78
- | TypedArray
79
- | ArrayBuffer
80
- | DataView
81
- | Date
82
- | Error
83
- | RegExp
84
- | ReadableStream<Uint8Array>
85
- | WritableStream<any> // Chunk type can be any RPC-compatible type
86
- | Request
87
- | Response
88
- | Headers;
89
- // Recursively rewrite all `Stubable` types with `Stub`s, and resolve promises.
90
- // prettier-ignore
91
- type Stubify<T> =
92
- T extends Stubable ? Stub<T>
93
- : T extends Promise<infer U> ? Stubify<U>
94
- : T extends StubBase<any> ? T
95
- : T extends Map<infer K, infer V> ? Map<Stubify<K>, Stubify<V>>
96
- : T extends Set<infer V> ? Set<Stubify<V>>
97
- : T extends [] ? []
98
- : T extends [infer Head, ...infer Tail] ? [Stubify<Head>, ...Stubify<Tail>]
99
- : T extends readonly [] ? readonly []
100
- : T extends readonly [infer Head, ...infer Tail] ? readonly [Stubify<Head>, ...Stubify<Tail>]
101
- : T extends Array<infer V> ? Array<Stubify<V>>
102
- : T extends ReadonlyArray<infer V> ? ReadonlyArray<Stubify<V>>
103
- : T extends BaseType ? T
104
- // When using "unknown" instead of "any", interfaces are not stubified.
105
- : T extends { [key: string | number]: any } ? { [K in keyof T]: Stubify<T[K]> }
106
- : T;
107
-
108
- // Recursively rewrite all `Stub<T>`s with the corresponding `T`s.
109
- // Note we use `StubBase` instead of `Stub` here to avoid circular dependencies:
110
- // `Stub` depends on `Provider`, which depends on `Unstubify`, which would depend on `Stub`.
111
- // prettier-ignore
112
- type UnstubifyInner<T> =
113
- // Keep local RpcTarget acceptance, but avoid `Stub | Value` unions when the stub
114
- // is already assignable to the value type (needed for callback contextual typing).
115
- T extends StubBase<infer V> ? (T extends V ? V : (T | V))
116
- : T extends Map<infer K, infer V> ? Map<Unstubify<K>, Unstubify<V>>
117
- : T extends Set<infer V> ? Set<Unstubify<V>>
118
- : T extends [] ? []
119
- : T extends [infer Head, ...infer Tail] ? [Unstubify<Head>, ...Unstubify<Tail>]
120
- : T extends readonly [] ? readonly []
121
- : T extends readonly [infer Head, ...infer Tail] ? readonly [Unstubify<Head>, ...Unstubify<Tail>]
122
- : T extends Array<infer V> ? Array<Unstubify<V>>
123
- : T extends ReadonlyArray<infer V> ? ReadonlyArray<Unstubify<V>>
124
- : T extends BaseType ? T
125
- : T extends { [key: string | number]: unknown } ? { [K in keyof T]: Unstubify<T[K]> }
126
- : T;
127
-
128
- // You can put promises anywhere in the params and they'll be resolved before delivery.
129
- // (This also covers RpcPromise, because it's defined as being a Promise.)
130
- type Unstubify<T> = UnstubifyInner<T> | Promise<UnstubifyInner<T>>
131
-
132
- type UnstubifyAll<A extends any[]> = { [I in keyof A]: Unstubify<A[I]> };
133
-
134
- // Utility type for adding `Disposable`s to `object` types only.
135
- // Note `unknown & T` is equivalent to `T`.
136
- type MaybeDisposable<T> = T extends object ? Disposable : unknown;
137
-
138
- // Type for method return or property on an RPC interface.
139
- // - Stubable types are replaced by stubs.
140
- // - RpcCompatible types are passed by value, with stubable types replaced by stubs
141
- // and a top-level `Disposer`.
142
- // Everything else can't be passed over RPC.
143
- // Technically, we use custom thenables here, but they quack like `Promise`s.
144
- // Intersecting with `(Maybe)Provider` allows pipelining.
145
- // prettier-ignore
146
- type Result<R> =
147
- R extends Stubable ? Promise<Stub<R>> & Provider<R> & StubBase<R>
148
- : R extends RpcCompatible<R> ? Promise<Stubify<R> & MaybeDisposable<R>> & Provider<R> & StubBase<R>
149
- : never;
150
-
151
- // Type for method or property on an RPC interface.
152
- // For methods, unwrap `Stub`s in parameters, and rewrite returns to be `Result`s.
153
- // Unwrapping `Stub`s allows calling with `Stubable` arguments.
154
- // For properties, rewrite types to be `Result`s.
155
- // In each case, unwrap `Promise`s.
156
- type MethodOrProperty<V> = V extends (...args: infer P) => infer R
157
- ? (...args: UnstubifyAll<P>) => Result<Awaited<R>>
158
- : Result<Awaited<V>>;
159
-
160
- // Type for the callable part of an `Provider` if `T` is callable.
161
- // This is intersected with methods/properties.
162
- type MaybeCallableProvider<T> = T extends (...args: any[]) => any
163
- ? MethodOrProperty<T>
164
- : unknown;
165
-
166
- // Base type for all other types providing RPC-like interfaces.
167
- // Rewrites all methods/properties to be `MethodOrProperty`s, while preserving callable types.
168
- type Provider<T> = MaybeCallableProvider<T> &
169
- (T extends Array<infer U>
170
- ? {
171
- [key: number]: MethodOrProperty<U>;
172
- } & {
173
- map<V>(callback: (elem: U) => V): Result<Array<V>>;
174
- }
175
- : {
176
- [K in Exclude<
177
- keyof T,
178
- symbol | keyof StubBase<never>
179
- >]: MethodOrProperty<T[K]>;
180
- } & {
181
- map<V>(callback: (value: NonNullable<T>) => V): Result<Array<V>>;
3
+ // Copyright (c) 2025 Cloudflare, Inc.
4
+ // Licensed under the MIT license found in the LICENSE.txt file or at:
5
+ // https://opensource.org/license/mit
6
+
7
+ // This file borrows heavily from `types/defines/rpc.d.ts` in workerd.
8
+
9
+ // Branded types for identifying `WorkerEntrypoint`/`DurableObject`/`Target`s.
10
+ // TypeScript uses *structural* typing meaning anything with the same shape as type `T` is a `T`.
11
+ // For the classes exported by `cloudflare:workers` we want *nominal* typing (i.e. we only want to
12
+ // accept `WorkerEntrypoint` from `cloudflare:workers`, not any other class with the same shape)
13
+ declare const __RPC_STUB_BRAND: '__RPC_STUB_BRAND';
14
+ declare const __RPC_TARGET_BRAND: '__RPC_TARGET_BRAND';
15
+ interface RpcTargetBranded {
16
+ [__RPC_TARGET_BRAND]: never;
17
+ }
18
+
19
+ // Recursive type transforms are bounded to avoid runaway instantiation.
20
+ type RpcDepth = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1];
21
+ type NextDepth<D extends unknown[]> = D extends [unknown, ...infer Rest] ? Rest : [];
22
+ type IsAny<T> = 0 extends (1 & T) ? true : false;
23
+ type IsUnknown<T> = unknown extends T ? ([T] extends [unknown] ? true : false) : false;
24
+
25
+ // Types that can be used through `Stub`s.
26
+ // `never[]` preserves compatibility with strongly-typed function signatures without introducing
27
+ // `any` into inference.
28
+ type Stubable = RpcTargetBranded | ((...args: never[]) => unknown);
29
+
30
+ type TypedArray =
31
+ | Uint8Array
32
+ | Uint8ClampedArray
33
+ | Uint16Array
34
+ | Uint32Array
35
+ | Int8Array
36
+ | Int16Array
37
+ | Int32Array
38
+ | BigUint64Array
39
+ | BigInt64Array
40
+ | Float32Array
41
+ | Float64Array;
42
+
43
+ // This represents all the types that can be sent as-is over an RPC boundary.
44
+ type BaseType =
45
+ | void
46
+ | undefined
47
+ | null
48
+ | boolean
49
+ | number
50
+ | bigint
51
+ | string
52
+ | TypedArray
53
+ | ArrayBuffer
54
+ | DataView
55
+ | Date
56
+ | Error
57
+ | RegExp
58
+ | ReadableStream<Uint8Array>
59
+ | WritableStream<any> // Chunk type can be any RPC-compatible type
60
+ | Request
61
+ | Response
62
+ | Headers;
63
+
64
+ // Base type for all RPC stubs, including common memory management methods.
65
+ // `T` is used as a marker type for unwrapping `Stub`s later.
66
+ interface StubBase<T = unknown> extends Disposable {
67
+ [__RPC_STUB_BRAND]: T;
68
+ dup(): this;
69
+ onRpcBroken(callback: (error: any) => void): void;
70
+ }
71
+
72
+ // Types that can be passed over RPC.
73
+ // The reason for using a generic type here is to build a serializable subset of structured
74
+ // cloneable composite types. This allows types defined with the "interface" keyword to pass the
75
+ // serializable check as well. Otherwise, only types defined with the "type" keyword would pass.
76
+ type RpcCompatible<T, D extends unknown[] = RpcDepth> =
77
+ D extends []
78
+ ? unknown
79
+ :
80
+ // Structured cloneables
81
+ | BaseType
82
+ // Structured cloneable composites
83
+ | Map<
84
+ T extends Map<infer U, unknown> ? RpcCompatible<U, NextDepth<D>> : never,
85
+ T extends Map<unknown, infer U> ? RpcCompatible<U, NextDepth<D>> : never
86
+ >
87
+ | Set<T extends Set<infer U> ? RpcCompatible<U, NextDepth<D>> : never>
88
+ | Array<T extends Array<infer U> ? RpcCompatible<U, NextDepth<D>> : never>
89
+ | ReadonlyArray<T extends ReadonlyArray<infer U> ? RpcCompatible<U, NextDepth<D>> : never>
90
+ | {
91
+ [K in keyof T as K extends string | number ? K : never]:
92
+ RpcCompatible<T[K], NextDepth<D>>;
93
+ }
94
+ | Promise<T extends Promise<infer U> ? RpcCompatible<U, NextDepth<D>> : never>
95
+ // Special types
96
+ | Stub<Stubable>
97
+ // Serialized as stubs, see `Stubify`
98
+ | Stubable;
99
+
100
+ type Stub<T extends RpcCompatible<T>> =
101
+ T extends object ? Provider<T> & StubBase<T> : StubBase<T>;
102
+
103
+ // Recursively rewrite all `Stubable` types with `Stub`s, and resolve promises.
104
+ // prettier-ignore
105
+ type Stubify<T, D extends unknown[] = RpcDepth> =
106
+ D extends [] ? T
107
+ : T extends Stubable ? Stub<T>
108
+ : T extends Promise<infer U> ? Stubify<U, NextDepth<D>>
109
+ : T extends StubBase<any> ? T
110
+ : T extends Map<infer K, infer V> ? Map<Stubify<K, NextDepth<D>>, Stubify<V, NextDepth<D>>>
111
+ : T extends Set<infer V> ? Set<Stubify<V, NextDepth<D>>>
112
+ : T extends [] ? []
113
+ : T extends [infer Head, ...infer Tail] ? [Stubify<Head, NextDepth<D>>, ...Stubify<Tail, NextDepth<D>>]
114
+ : T extends readonly [] ? readonly []
115
+ : T extends readonly [infer Head, ...infer Tail] ? readonly [Stubify<Head, NextDepth<D>>, ...Stubify<Tail, NextDepth<D>>]
116
+ : T extends Array<infer V> ? Array<Stubify<V, NextDepth<D>>>
117
+ : T extends ReadonlyArray<infer V> ? ReadonlyArray<Stubify<V, NextDepth<D>>>
118
+ : T extends BaseType ? T
119
+ // When using "unknown" instead of "any", interfaces are not stubified.
120
+ : T extends { [key: string | number]: any }
121
+ ? {
122
+ [K in keyof T as K extends string | number ? K : never]:
123
+ Stubify<T[K], NextDepth<D>>;
124
+ }
125
+ : T;
126
+
127
+ // Recursively rewrite all `Stub<T>`s with the corresponding `T`s.
128
+ // Note we use `StubBase` instead of `Stub` here to avoid circular dependencies:
129
+ // `Stub` depends on `Provider`, which depends on `Unstubify`, which would depend on `Stub`.
130
+ // prettier-ignore
131
+ type UnstubifyInner<T, D extends unknown[] = RpcDepth> =
132
+ D extends [] ? T
133
+ // Preserve local RpcTarget acceptance, but avoid needless `Stub | Value` unions when the stub
134
+ // is already assignable to the value type (important for callback contextual typing).
135
+ : T extends StubBase<infer V> ? (T extends V ? UnstubifyInner<V, NextDepth<D>> : (T | UnstubifyInner<V, NextDepth<D>>))
136
+ : T extends Promise<infer U> ? UnstubifyInner<U, NextDepth<D>>
137
+ : T extends Map<infer K, infer V> ? Map<Unstubify<K, NextDepth<D>>, Unstubify<V, NextDepth<D>>>
138
+ : T extends Set<infer V> ? Set<Unstubify<V, NextDepth<D>>>
139
+ : T extends [] ? []
140
+ : T extends [infer Head, ...infer Tail] ? [Unstubify<Head, NextDepth<D>>, ...Unstubify<Tail, NextDepth<D>>]
141
+ : T extends readonly [] ? readonly []
142
+ : T extends readonly [infer Head, ...infer Tail] ? readonly [Unstubify<Head, NextDepth<D>>, ...Unstubify<Tail, NextDepth<D>>]
143
+ : T extends Array<infer V> ? Array<Unstubify<V, NextDepth<D>>>
144
+ : T extends ReadonlyArray<infer V> ? ReadonlyArray<Unstubify<V, NextDepth<D>>>
145
+ : T extends BaseType ? T
146
+ : T extends { [key: string | number]: unknown }
147
+ ? {
148
+ [K in keyof T as K extends string | number ? K : never]:
149
+ Unstubify<T[K], NextDepth<D>>;
150
+ }
151
+ : T;
152
+
153
+ // You can put promises anywhere in the params and they'll be resolved before delivery.
154
+ // (This also covers RpcPromise, because it's defined as being a Promise.)
155
+ type Unstubify<T, D extends unknown[] = RpcDepth> =
156
+ UnstubifyInner<T, D> | Promise<UnstubifyInner<T, D>>;
157
+
158
+ type UnstubifyAll<A extends readonly unknown[], D extends unknown[] = RpcDepth> = {
159
+ [I in keyof A]: Unstubify<A[I], D>;
160
+ };
161
+
162
+ // Utility type for adding `Disposable`s to `object` types only.
163
+ // Note `unknown & T` is equivalent to `T`.
164
+ type MaybeDisposable<T> = T extends object ? Disposable : unknown;
165
+
166
+ // Type for method return or property on an RPC interface.
167
+ // - Stubable types are replaced by stubs.
168
+ // - RpcCompatible types are passed by value, with stubable types replaced by stubs
169
+ // and a top-level `Disposer`.
170
+ // Everything else can't be passed over RPC.
171
+ // Technically, we use custom thenables here, but they quack like `Promise`s.
172
+ // Intersecting with `(Maybe)Provider` allows pipelining.
173
+ // prettier-ignore
174
+ type UnknownResult<D extends unknown[]> = D extends []
175
+ ? Promise<unknown> & StubBase<unknown>
176
+ : Promise<unknown> & Provider<unknown, D> & StubBase<unknown>;
177
+
178
+ // prettier-ignore
179
+ type Result<R, D extends unknown[] = RpcDepth> =
180
+ D extends [] ? UnknownResult<D>
181
+ : IsAny<R> extends true ? UnknownResult<D>
182
+ : IsUnknown<R> extends true ? UnknownResult<D>
183
+ : R extends Stubable ? Promise<Stub<R>> & Provider<R, D> & StubBase<R>
184
+ : R extends RpcCompatible<R, D> ? Promise<Stubify<R, D> & MaybeDisposable<R>> & Provider<R, D> & StubBase<R>
185
+ : never;
186
+
187
+ type HasAnyFunctionParts<P extends readonly unknown[], R> =
188
+ IsAny<R> extends true ? true : IsAny<P[number]>;
189
+
190
+ // Type for method or property on an RPC interface.
191
+ // For methods, unwrap `Stub`s in parameters, and rewrite returns to be `Result`s.
192
+ // Unwrapping `Stub`s allows calling with `Stubable` arguments.
193
+ // For properties, rewrite types to be `Result`s.
194
+ // In each case, unwrap `Promise`s.
195
+ type MethodOrProperty<V, D extends unknown[] = RpcDepth> = V extends (...args: infer P) => infer R
196
+ ? HasAnyFunctionParts<P, R> extends true
197
+ ? (...args: unknown[]) => UnknownResult<NextDepth<D>>
198
+ : (...args: UnstubifyAll<P, NextDepth<D>>) => Result<Awaited<R>, NextDepth<D>>
199
+ : Result<Awaited<V>, NextDepth<D>>;
200
+
201
+ // Type for the callable part of a `Provider` if `T` is callable.
202
+ // This is intersected with methods/properties.
203
+ type MaybeCallableProvider<T, D extends unknown[] = RpcDepth> = T extends (...args: any[]) => any
204
+ ? MethodOrProperty<T, D>
205
+ : unknown;
206
+
207
+ // Base type for all other types providing RPC-like interfaces.
208
+ // Rewrites all methods/properties to be `MethodOrProperty`s, while preserving callable types.
209
+ type Provider<T, D extends unknown[] = RpcDepth> = MaybeCallableProvider<T, D> &
210
+ (T extends Array<infer U>
211
+ ? {
212
+ [key: number]: MethodOrProperty<U, D>;
213
+ } & {
214
+ map<V>(callback: (elem: Result<U, NextDepth<D>>) => V): Result<Array<V>, NextDepth<D>>;
215
+ }
216
+ : {
217
+ [K in Exclude<
218
+ keyof T,
219
+ symbol | keyof StubBase<never>
220
+ >]: MethodOrProperty<T[K], D>;
221
+ } & {
222
+ map<V>(callback: (value: Result<NonNullable<T>, NextDepth<D>>) => V):
223
+ Result<Array<V>, NextDepth<D>>;
182
224
  });
183
225
 
184
226
  /**
package/dist/index.d.ts CHANGED
@@ -1,184 +1,226 @@
1
1
  import { IncomingMessage, ServerResponse, OutgoingHttpHeaders, OutgoingHttpHeader } from 'node:http';
2
2
 
3
- // Copyright (c) 2025 Cloudflare, Inc.
4
- // Licensed under the MIT license found in the LICENSE.txt file or at:
5
- // https://opensource.org/license/mit
6
-
7
- // This file borrows heavily from `types/defines/rpc.d.ts` in workerd.
8
-
9
- // Branded types for identifying `WorkerEntrypoint`/`DurableObject`/`Target`s.
10
- // TypeScript uses *structural* typing meaning anything with the same shape as type `T` is a `T`.
11
- // For the classes exported by `cloudflare:workers` we want *nominal* typing (i.e. we only want to
12
- // accept `WorkerEntrypoint` from `cloudflare:workers`, not any other class with the same shape)
13
- declare const __RPC_STUB_BRAND: '__RPC_STUB_BRAND';
14
- declare const __RPC_TARGET_BRAND: '__RPC_TARGET_BRAND';
15
- interface RpcTargetBranded {
16
- [__RPC_TARGET_BRAND]: never;
17
- }
18
-
19
- // Types that can be used through `Stub`s
20
- type Stubable = RpcTargetBranded | ((...args: any[]) => any);
21
-
22
- // Types that can be passed over RPC
23
- // The reason for using a generic type here is to build a serializable subset of structured
24
- // cloneable composite types. This allows types defined with the "interface" keyword to pass the
25
- // serializable check as well. Otherwise, only types defined with the "type" keyword would pass.
26
- type RpcCompatible<T> =
27
- // Structured cloneables
28
- | BaseType
29
- // Structured cloneable composites
30
- | Map<
31
- T extends Map<infer U, unknown> ? RpcCompatible<U> : never,
32
- T extends Map<unknown, infer U> ? RpcCompatible<U> : never
33
- >
34
- | Set<T extends Set<infer U> ? RpcCompatible<U> : never>
35
- | Array<T extends Array<infer U> ? RpcCompatible<U> : never>
36
- | ReadonlyArray<T extends ReadonlyArray<infer U> ? RpcCompatible<U> : never>
37
- | {
38
- [K in keyof T as K extends string | number ? K : never]: RpcCompatible<T[K]>;
39
- }
40
- | Promise<T extends Promise<infer U> ? RpcCompatible<U> : never>
41
- // Special types
42
- | Stub<Stubable>
43
- // Serialized as stubs, see `Stubify`
44
- | Stubable;
45
-
46
- // Base type for all RPC stubs, including common memory management methods.
47
- // `T` is used as a marker type for unwrapping `Stub`s later.
48
- interface StubBase<T extends RpcCompatible<T>> extends Disposable {
49
- [__RPC_STUB_BRAND]: T;
50
- dup(): this;
51
- onRpcBroken(callback: (error: any) => void): void;
52
- }
53
- type Stub<T extends RpcCompatible<T>> =
54
- T extends object ? Provider<T> & StubBase<T> : StubBase<T>;
55
-
56
- type TypedArray =
57
- | Uint8Array
58
- | Uint8ClampedArray
59
- | Uint16Array
60
- | Uint32Array
61
- | Int8Array
62
- | Int16Array
63
- | Int32Array
64
- | BigUint64Array
65
- | BigInt64Array
66
- | Float32Array
67
- | Float64Array;
68
-
69
- // This represents all the types that can be sent as-is over an RPC boundary
70
- type BaseType =
71
- | void
72
- | undefined
73
- | null
74
- | boolean
75
- | number
76
- | bigint
77
- | string
78
- | TypedArray
79
- | ArrayBuffer
80
- | DataView
81
- | Date
82
- | Error
83
- | RegExp
84
- | ReadableStream<Uint8Array>
85
- | WritableStream<any> // Chunk type can be any RPC-compatible type
86
- | Request
87
- | Response
88
- | Headers;
89
- // Recursively rewrite all `Stubable` types with `Stub`s, and resolve promises.
90
- // prettier-ignore
91
- type Stubify<T> =
92
- T extends Stubable ? Stub<T>
93
- : T extends Promise<infer U> ? Stubify<U>
94
- : T extends StubBase<any> ? T
95
- : T extends Map<infer K, infer V> ? Map<Stubify<K>, Stubify<V>>
96
- : T extends Set<infer V> ? Set<Stubify<V>>
97
- : T extends [] ? []
98
- : T extends [infer Head, ...infer Tail] ? [Stubify<Head>, ...Stubify<Tail>]
99
- : T extends readonly [] ? readonly []
100
- : T extends readonly [infer Head, ...infer Tail] ? readonly [Stubify<Head>, ...Stubify<Tail>]
101
- : T extends Array<infer V> ? Array<Stubify<V>>
102
- : T extends ReadonlyArray<infer V> ? ReadonlyArray<Stubify<V>>
103
- : T extends BaseType ? T
104
- // When using "unknown" instead of "any", interfaces are not stubified.
105
- : T extends { [key: string | number]: any } ? { [K in keyof T]: Stubify<T[K]> }
106
- : T;
107
-
108
- // Recursively rewrite all `Stub<T>`s with the corresponding `T`s.
109
- // Note we use `StubBase` instead of `Stub` here to avoid circular dependencies:
110
- // `Stub` depends on `Provider`, which depends on `Unstubify`, which would depend on `Stub`.
111
- // prettier-ignore
112
- type UnstubifyInner<T> =
113
- // Keep local RpcTarget acceptance, but avoid `Stub | Value` unions when the stub
114
- // is already assignable to the value type (needed for callback contextual typing).
115
- T extends StubBase<infer V> ? (T extends V ? V : (T | V))
116
- : T extends Map<infer K, infer V> ? Map<Unstubify<K>, Unstubify<V>>
117
- : T extends Set<infer V> ? Set<Unstubify<V>>
118
- : T extends [] ? []
119
- : T extends [infer Head, ...infer Tail] ? [Unstubify<Head>, ...Unstubify<Tail>]
120
- : T extends readonly [] ? readonly []
121
- : T extends readonly [infer Head, ...infer Tail] ? readonly [Unstubify<Head>, ...Unstubify<Tail>]
122
- : T extends Array<infer V> ? Array<Unstubify<V>>
123
- : T extends ReadonlyArray<infer V> ? ReadonlyArray<Unstubify<V>>
124
- : T extends BaseType ? T
125
- : T extends { [key: string | number]: unknown } ? { [K in keyof T]: Unstubify<T[K]> }
126
- : T;
127
-
128
- // You can put promises anywhere in the params and they'll be resolved before delivery.
129
- // (This also covers RpcPromise, because it's defined as being a Promise.)
130
- type Unstubify<T> = UnstubifyInner<T> | Promise<UnstubifyInner<T>>
131
-
132
- type UnstubifyAll<A extends any[]> = { [I in keyof A]: Unstubify<A[I]> };
133
-
134
- // Utility type for adding `Disposable`s to `object` types only.
135
- // Note `unknown & T` is equivalent to `T`.
136
- type MaybeDisposable<T> = T extends object ? Disposable : unknown;
137
-
138
- // Type for method return or property on an RPC interface.
139
- // - Stubable types are replaced by stubs.
140
- // - RpcCompatible types are passed by value, with stubable types replaced by stubs
141
- // and a top-level `Disposer`.
142
- // Everything else can't be passed over RPC.
143
- // Technically, we use custom thenables here, but they quack like `Promise`s.
144
- // Intersecting with `(Maybe)Provider` allows pipelining.
145
- // prettier-ignore
146
- type Result<R> =
147
- R extends Stubable ? Promise<Stub<R>> & Provider<R> & StubBase<R>
148
- : R extends RpcCompatible<R> ? Promise<Stubify<R> & MaybeDisposable<R>> & Provider<R> & StubBase<R>
149
- : never;
150
-
151
- // Type for method or property on an RPC interface.
152
- // For methods, unwrap `Stub`s in parameters, and rewrite returns to be `Result`s.
153
- // Unwrapping `Stub`s allows calling with `Stubable` arguments.
154
- // For properties, rewrite types to be `Result`s.
155
- // In each case, unwrap `Promise`s.
156
- type MethodOrProperty<V> = V extends (...args: infer P) => infer R
157
- ? (...args: UnstubifyAll<P>) => Result<Awaited<R>>
158
- : Result<Awaited<V>>;
159
-
160
- // Type for the callable part of an `Provider` if `T` is callable.
161
- // This is intersected with methods/properties.
162
- type MaybeCallableProvider<T> = T extends (...args: any[]) => any
163
- ? MethodOrProperty<T>
164
- : unknown;
165
-
166
- // Base type for all other types providing RPC-like interfaces.
167
- // Rewrites all methods/properties to be `MethodOrProperty`s, while preserving callable types.
168
- type Provider<T> = MaybeCallableProvider<T> &
169
- (T extends Array<infer U>
170
- ? {
171
- [key: number]: MethodOrProperty<U>;
172
- } & {
173
- map<V>(callback: (elem: U) => V): Result<Array<V>>;
174
- }
175
- : {
176
- [K in Exclude<
177
- keyof T,
178
- symbol | keyof StubBase<never>
179
- >]: MethodOrProperty<T[K]>;
180
- } & {
181
- map<V>(callback: (value: NonNullable<T>) => V): Result<Array<V>>;
3
+ // Copyright (c) 2025 Cloudflare, Inc.
4
+ // Licensed under the MIT license found in the LICENSE.txt file or at:
5
+ // https://opensource.org/license/mit
6
+
7
+ // This file borrows heavily from `types/defines/rpc.d.ts` in workerd.
8
+
9
+ // Branded types for identifying `WorkerEntrypoint`/`DurableObject`/`Target`s.
10
+ // TypeScript uses *structural* typing meaning anything with the same shape as type `T` is a `T`.
11
+ // For the classes exported by `cloudflare:workers` we want *nominal* typing (i.e. we only want to
12
+ // accept `WorkerEntrypoint` from `cloudflare:workers`, not any other class with the same shape)
13
+ declare const __RPC_STUB_BRAND: '__RPC_STUB_BRAND';
14
+ declare const __RPC_TARGET_BRAND: '__RPC_TARGET_BRAND';
15
+ interface RpcTargetBranded {
16
+ [__RPC_TARGET_BRAND]: never;
17
+ }
18
+
19
+ // Recursive type transforms are bounded to avoid runaway instantiation.
20
+ type RpcDepth = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1];
21
+ type NextDepth<D extends unknown[]> = D extends [unknown, ...infer Rest] ? Rest : [];
22
+ type IsAny<T> = 0 extends (1 & T) ? true : false;
23
+ type IsUnknown<T> = unknown extends T ? ([T] extends [unknown] ? true : false) : false;
24
+
25
+ // Types that can be used through `Stub`s.
26
+ // `never[]` preserves compatibility with strongly-typed function signatures without introducing
27
+ // `any` into inference.
28
+ type Stubable = RpcTargetBranded | ((...args: never[]) => unknown);
29
+
30
+ type TypedArray =
31
+ | Uint8Array
32
+ | Uint8ClampedArray
33
+ | Uint16Array
34
+ | Uint32Array
35
+ | Int8Array
36
+ | Int16Array
37
+ | Int32Array
38
+ | BigUint64Array
39
+ | BigInt64Array
40
+ | Float32Array
41
+ | Float64Array;
42
+
43
+ // This represents all the types that can be sent as-is over an RPC boundary.
44
+ type BaseType =
45
+ | void
46
+ | undefined
47
+ | null
48
+ | boolean
49
+ | number
50
+ | bigint
51
+ | string
52
+ | TypedArray
53
+ | ArrayBuffer
54
+ | DataView
55
+ | Date
56
+ | Error
57
+ | RegExp
58
+ | ReadableStream<Uint8Array>
59
+ | WritableStream<any> // Chunk type can be any RPC-compatible type
60
+ | Request
61
+ | Response
62
+ | Headers;
63
+
64
+ // Base type for all RPC stubs, including common memory management methods.
65
+ // `T` is used as a marker type for unwrapping `Stub`s later.
66
+ interface StubBase<T = unknown> extends Disposable {
67
+ [__RPC_STUB_BRAND]: T;
68
+ dup(): this;
69
+ onRpcBroken(callback: (error: any) => void): void;
70
+ }
71
+
72
+ // Types that can be passed over RPC.
73
+ // The reason for using a generic type here is to build a serializable subset of structured
74
+ // cloneable composite types. This allows types defined with the "interface" keyword to pass the
75
+ // serializable check as well. Otherwise, only types defined with the "type" keyword would pass.
76
+ type RpcCompatible<T, D extends unknown[] = RpcDepth> =
77
+ D extends []
78
+ ? unknown
79
+ :
80
+ // Structured cloneables
81
+ | BaseType
82
+ // Structured cloneable composites
83
+ | Map<
84
+ T extends Map<infer U, unknown> ? RpcCompatible<U, NextDepth<D>> : never,
85
+ T extends Map<unknown, infer U> ? RpcCompatible<U, NextDepth<D>> : never
86
+ >
87
+ | Set<T extends Set<infer U> ? RpcCompatible<U, NextDepth<D>> : never>
88
+ | Array<T extends Array<infer U> ? RpcCompatible<U, NextDepth<D>> : never>
89
+ | ReadonlyArray<T extends ReadonlyArray<infer U> ? RpcCompatible<U, NextDepth<D>> : never>
90
+ | {
91
+ [K in keyof T as K extends string | number ? K : never]:
92
+ RpcCompatible<T[K], NextDepth<D>>;
93
+ }
94
+ | Promise<T extends Promise<infer U> ? RpcCompatible<U, NextDepth<D>> : never>
95
+ // Special types
96
+ | Stub<Stubable>
97
+ // Serialized as stubs, see `Stubify`
98
+ | Stubable;
99
+
100
+ type Stub<T extends RpcCompatible<T>> =
101
+ T extends object ? Provider<T> & StubBase<T> : StubBase<T>;
102
+
103
+ // Recursively rewrite all `Stubable` types with `Stub`s, and resolve promises.
104
+ // prettier-ignore
105
+ type Stubify<T, D extends unknown[] = RpcDepth> =
106
+ D extends [] ? T
107
+ : T extends Stubable ? Stub<T>
108
+ : T extends Promise<infer U> ? Stubify<U, NextDepth<D>>
109
+ : T extends StubBase<any> ? T
110
+ : T extends Map<infer K, infer V> ? Map<Stubify<K, NextDepth<D>>, Stubify<V, NextDepth<D>>>
111
+ : T extends Set<infer V> ? Set<Stubify<V, NextDepth<D>>>
112
+ : T extends [] ? []
113
+ : T extends [infer Head, ...infer Tail] ? [Stubify<Head, NextDepth<D>>, ...Stubify<Tail, NextDepth<D>>]
114
+ : T extends readonly [] ? readonly []
115
+ : T extends readonly [infer Head, ...infer Tail] ? readonly [Stubify<Head, NextDepth<D>>, ...Stubify<Tail, NextDepth<D>>]
116
+ : T extends Array<infer V> ? Array<Stubify<V, NextDepth<D>>>
117
+ : T extends ReadonlyArray<infer V> ? ReadonlyArray<Stubify<V, NextDepth<D>>>
118
+ : T extends BaseType ? T
119
+ // When using "unknown" instead of "any", interfaces are not stubified.
120
+ : T extends { [key: string | number]: any }
121
+ ? {
122
+ [K in keyof T as K extends string | number ? K : never]:
123
+ Stubify<T[K], NextDepth<D>>;
124
+ }
125
+ : T;
126
+
127
+ // Recursively rewrite all `Stub<T>`s with the corresponding `T`s.
128
+ // Note we use `StubBase` instead of `Stub` here to avoid circular dependencies:
129
+ // `Stub` depends on `Provider`, which depends on `Unstubify`, which would depend on `Stub`.
130
+ // prettier-ignore
131
+ type UnstubifyInner<T, D extends unknown[] = RpcDepth> =
132
+ D extends [] ? T
133
+ // Preserve local RpcTarget acceptance, but avoid needless `Stub | Value` unions when the stub
134
+ // is already assignable to the value type (important for callback contextual typing).
135
+ : T extends StubBase<infer V> ? (T extends V ? UnstubifyInner<V, NextDepth<D>> : (T | UnstubifyInner<V, NextDepth<D>>))
136
+ : T extends Promise<infer U> ? UnstubifyInner<U, NextDepth<D>>
137
+ : T extends Map<infer K, infer V> ? Map<Unstubify<K, NextDepth<D>>, Unstubify<V, NextDepth<D>>>
138
+ : T extends Set<infer V> ? Set<Unstubify<V, NextDepth<D>>>
139
+ : T extends [] ? []
140
+ : T extends [infer Head, ...infer Tail] ? [Unstubify<Head, NextDepth<D>>, ...Unstubify<Tail, NextDepth<D>>]
141
+ : T extends readonly [] ? readonly []
142
+ : T extends readonly [infer Head, ...infer Tail] ? readonly [Unstubify<Head, NextDepth<D>>, ...Unstubify<Tail, NextDepth<D>>]
143
+ : T extends Array<infer V> ? Array<Unstubify<V, NextDepth<D>>>
144
+ : T extends ReadonlyArray<infer V> ? ReadonlyArray<Unstubify<V, NextDepth<D>>>
145
+ : T extends BaseType ? T
146
+ : T extends { [key: string | number]: unknown }
147
+ ? {
148
+ [K in keyof T as K extends string | number ? K : never]:
149
+ Unstubify<T[K], NextDepth<D>>;
150
+ }
151
+ : T;
152
+
153
+ // You can put promises anywhere in the params and they'll be resolved before delivery.
154
+ // (This also covers RpcPromise, because it's defined as being a Promise.)
155
+ type Unstubify<T, D extends unknown[] = RpcDepth> =
156
+ UnstubifyInner<T, D> | Promise<UnstubifyInner<T, D>>;
157
+
158
+ type UnstubifyAll<A extends readonly unknown[], D extends unknown[] = RpcDepth> = {
159
+ [I in keyof A]: Unstubify<A[I], D>;
160
+ };
161
+
162
+ // Utility type for adding `Disposable`s to `object` types only.
163
+ // Note `unknown & T` is equivalent to `T`.
164
+ type MaybeDisposable<T> = T extends object ? Disposable : unknown;
165
+
166
+ // Type for method return or property on an RPC interface.
167
+ // - Stubable types are replaced by stubs.
168
+ // - RpcCompatible types are passed by value, with stubable types replaced by stubs
169
+ // and a top-level `Disposer`.
170
+ // Everything else can't be passed over RPC.
171
+ // Technically, we use custom thenables here, but they quack like `Promise`s.
172
+ // Intersecting with `(Maybe)Provider` allows pipelining.
173
+ // prettier-ignore
174
+ type UnknownResult<D extends unknown[]> = D extends []
175
+ ? Promise<unknown> & StubBase<unknown>
176
+ : Promise<unknown> & Provider<unknown, D> & StubBase<unknown>;
177
+
178
+ // prettier-ignore
179
+ type Result<R, D extends unknown[] = RpcDepth> =
180
+ D extends [] ? UnknownResult<D>
181
+ : IsAny<R> extends true ? UnknownResult<D>
182
+ : IsUnknown<R> extends true ? UnknownResult<D>
183
+ : R extends Stubable ? Promise<Stub<R>> & Provider<R, D> & StubBase<R>
184
+ : R extends RpcCompatible<R, D> ? Promise<Stubify<R, D> & MaybeDisposable<R>> & Provider<R, D> & StubBase<R>
185
+ : never;
186
+
187
+ type HasAnyFunctionParts<P extends readonly unknown[], R> =
188
+ IsAny<R> extends true ? true : IsAny<P[number]>;
189
+
190
+ // Type for method or property on an RPC interface.
191
+ // For methods, unwrap `Stub`s in parameters, and rewrite returns to be `Result`s.
192
+ // Unwrapping `Stub`s allows calling with `Stubable` arguments.
193
+ // For properties, rewrite types to be `Result`s.
194
+ // In each case, unwrap `Promise`s.
195
+ type MethodOrProperty<V, D extends unknown[] = RpcDepth> = V extends (...args: infer P) => infer R
196
+ ? HasAnyFunctionParts<P, R> extends true
197
+ ? (...args: unknown[]) => UnknownResult<NextDepth<D>>
198
+ : (...args: UnstubifyAll<P, NextDepth<D>>) => Result<Awaited<R>, NextDepth<D>>
199
+ : Result<Awaited<V>, NextDepth<D>>;
200
+
201
+ // Type for the callable part of a `Provider` if `T` is callable.
202
+ // This is intersected with methods/properties.
203
+ type MaybeCallableProvider<T, D extends unknown[] = RpcDepth> = T extends (...args: any[]) => any
204
+ ? MethodOrProperty<T, D>
205
+ : unknown;
206
+
207
+ // Base type for all other types providing RPC-like interfaces.
208
+ // Rewrites all methods/properties to be `MethodOrProperty`s, while preserving callable types.
209
+ type Provider<T, D extends unknown[] = RpcDepth> = MaybeCallableProvider<T, D> &
210
+ (T extends Array<infer U>
211
+ ? {
212
+ [key: number]: MethodOrProperty<U, D>;
213
+ } & {
214
+ map<V>(callback: (elem: Result<U, NextDepth<D>>) => V): Result<Array<V>, NextDepth<D>>;
215
+ }
216
+ : {
217
+ [K in Exclude<
218
+ keyof T,
219
+ symbol | keyof StubBase<never>
220
+ >]: MethodOrProperty<T[K], D>;
221
+ } & {
222
+ map<V>(callback: (value: Result<NonNullable<T>, NextDepth<D>>) => V):
223
+ Result<Array<V>, NextDepth<D>>;
182
224
  });
183
225
 
184
226
  /**
package/dist/index.js CHANGED
File without changes
package/dist/index.js.map CHANGED
File without changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vastblast/capnweb",
3
- "version": "0.4.1",
3
+ "version": "0.4.2",
4
4
  "description": "JavaScript/TypeScript-native RPC library with Promise Pipelining",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -30,6 +30,7 @@
30
30
  "build": "tsup --format esm,cjs",
31
31
  "build:watch": "tsup --watch --format esm,cjs",
32
32
  "test": "vitest run",
33
+ "test:types": "tsc -p type-tests/tsconfig.json --noEmit",
33
34
  "test:watch": "vitest",
34
35
  "prepublishOnly": "npm run build"
35
36
  },