@sachitv/avro-typescript 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm/_dnt.polyfills.d.ts +11 -0
- package/esm/_dnt.polyfills.js +15 -0
- package/esm/avro_reader.d.ts +156 -0
- package/esm/avro_reader.js +201 -0
- package/esm/avro_writer.d.ts +75 -0
- package/esm/avro_writer.js +105 -0
- package/esm/internal/collections/array_utils.d.ts +4 -0
- package/esm/internal/collections/array_utils.js +18 -0
- package/esm/internal/collections/circular_buffer.d.ts +48 -0
- package/esm/internal/collections/circular_buffer.js +129 -0
- package/esm/internal/crypto/md5.d.ts +12 -0
- package/esm/internal/crypto/md5.js +158 -0
- package/esm/internal/varint.d.ts +6 -0
- package/esm/internal/varint.js +30 -0
- package/esm/mod.d.ts +77 -0
- package/esm/mod.js +73 -0
- package/esm/package.json +3 -0
- package/esm/rpc/definitions/message_definition.d.ts +34 -0
- package/esm/rpc/definitions/message_definition.js +105 -0
- package/esm/rpc/definitions/protocol_definitions.d.ts +197 -0
- package/esm/rpc/definitions/protocol_definitions.js +1 -0
- package/esm/rpc/message_endpoint/base.d.ts +43 -0
- package/esm/rpc/message_endpoint/base.js +81 -0
- package/esm/rpc/message_endpoint/emitter.d.ts +96 -0
- package/esm/rpc/message_endpoint/emitter.js +245 -0
- package/esm/rpc/message_endpoint/helpers.d.ts +37 -0
- package/esm/rpc/message_endpoint/helpers.js +68 -0
- package/esm/rpc/message_endpoint/listener.d.ts +37 -0
- package/esm/rpc/message_endpoint/listener.js +212 -0
- package/esm/rpc/protocol/frame_assembler.d.ts +11 -0
- package/esm/rpc/protocol/frame_assembler.js +77 -0
- package/esm/rpc/protocol/protocol_helpers.d.ts +59 -0
- package/esm/rpc/protocol/protocol_helpers.js +123 -0
- package/esm/rpc/protocol/transports/fetch.d.ts +9 -0
- package/esm/rpc/protocol/transports/fetch.js +30 -0
- package/esm/rpc/protocol/transports/in_memory.d.ts +27 -0
- package/esm/rpc/protocol/transports/in_memory.js +125 -0
- package/esm/rpc/protocol/transports/transport_helpers.d.ts +118 -0
- package/esm/rpc/protocol/transports/transport_helpers.js +112 -0
- package/esm/rpc/protocol/transports/websocket.d.ts +9 -0
- package/esm/rpc/protocol/transports/websocket.js +102 -0
- package/esm/rpc/protocol/wire_format/framing.d.ts +44 -0
- package/esm/rpc/protocol/wire_format/framing.js +74 -0
- package/esm/rpc/protocol/wire_format/handshake.d.ts +110 -0
- package/esm/rpc/protocol/wire_format/handshake.js +239 -0
- package/esm/rpc/protocol/wire_format/messages.d.ts +192 -0
- package/esm/rpc/protocol/wire_format/messages.js +175 -0
- package/esm/rpc/protocol/wire_format/metadata.d.ts +44 -0
- package/esm/rpc/protocol/wire_format/metadata.js +74 -0
- package/esm/rpc/protocol_core.d.ts +121 -0
- package/esm/rpc/protocol_core.js +285 -0
- package/esm/schemas/base_type.d.ts +41 -0
- package/esm/schemas/base_type.js +49 -0
- package/esm/schemas/complex/array_type.d.ts +100 -0
- package/esm/schemas/complex/array_type.js +299 -0
- package/esm/schemas/complex/enum_type.d.ts +81 -0
- package/esm/schemas/complex/enum_type.js +217 -0
- package/esm/schemas/complex/fixed_type.d.ts +99 -0
- package/esm/schemas/complex/fixed_type.js +208 -0
- package/esm/schemas/complex/map_type.d.ts +97 -0
- package/esm/schemas/complex/map_type.js +290 -0
- package/esm/schemas/complex/named_type.d.ts +30 -0
- package/esm/schemas/complex/named_type.js +57 -0
- package/esm/schemas/complex/record_type.d.ts +165 -0
- package/esm/schemas/complex/record_type.js +547 -0
- package/esm/schemas/complex/resolve_names.d.ts +32 -0
- package/esm/schemas/complex/resolve_names.js +85 -0
- package/esm/schemas/complex/union_type.d.ts +116 -0
- package/esm/schemas/complex/union_type.js +392 -0
- package/esm/schemas/error.d.ts +31 -0
- package/esm/schemas/error.js +67 -0
- package/esm/schemas/json.d.ts +6 -0
- package/esm/schemas/json.js +35 -0
- package/esm/schemas/logical/decimal_logical_type.d.ts +49 -0
- package/esm/schemas/logical/decimal_logical_type.js +145 -0
- package/esm/schemas/logical/duration_logical_type.d.ts +66 -0
- package/esm/schemas/logical/duration_logical_type.js +112 -0
- package/esm/schemas/logical/logical_type.d.ts +138 -0
- package/esm/schemas/logical/logical_type.js +240 -0
- package/esm/schemas/logical/temporal_logical_types.d.ts +215 -0
- package/esm/schemas/logical/temporal_logical_types.js +364 -0
- package/esm/schemas/logical/uuid_logical_type.d.ts +63 -0
- package/esm/schemas/logical/uuid_logical_type.js +146 -0
- package/esm/schemas/primitive/boolean_type.d.ts +49 -0
- package/esm/schemas/primitive/boolean_type.js +75 -0
- package/esm/schemas/primitive/bytes_type.d.ts +49 -0
- package/esm/schemas/primitive/bytes_type.js +136 -0
- package/esm/schemas/primitive/double_type.d.ts +38 -0
- package/esm/schemas/primitive/double_type.js +98 -0
- package/esm/schemas/primitive/fixed_size_base_type.d.ts +28 -0
- package/esm/schemas/primitive/fixed_size_base_type.js +33 -0
- package/esm/schemas/primitive/float_type.d.ts +38 -0
- package/esm/schemas/primitive/float_type.js +88 -0
- package/esm/schemas/primitive/int_type.d.ts +31 -0
- package/esm/schemas/primitive/int_type.js +63 -0
- package/esm/schemas/primitive/long_type.d.ts +36 -0
- package/esm/schemas/primitive/long_type.js +95 -0
- package/esm/schemas/primitive/null_type.d.ts +45 -0
- package/esm/schemas/primitive/null_type.js +71 -0
- package/esm/schemas/primitive/primitive_type.d.ts +17 -0
- package/esm/schemas/primitive/primitive_type.js +27 -0
- package/esm/schemas/primitive/string_type.d.ts +34 -0
- package/esm/schemas/primitive/string_type.js +81 -0
- package/esm/schemas/resolver.d.ts +25 -0
- package/esm/schemas/resolver.js +25 -0
- package/esm/schemas/type.d.ts +101 -0
- package/esm/schemas/type.js +6 -0
- package/esm/serialization/avro_constants.d.ts +13 -0
- package/esm/serialization/avro_constants.js +29 -0
- package/esm/serialization/avro_file_parser.d.ts +68 -0
- package/esm/serialization/avro_file_parser.js +191 -0
- package/esm/serialization/avro_file_writer.d.ts +63 -0
- package/esm/serialization/avro_file_writer.js +235 -0
- package/esm/serialization/buffers/blob_readable_buffer.d.ts +53 -0
- package/esm/serialization/buffers/blob_readable_buffer.js +80 -0
- package/esm/serialization/buffers/buffer.d.ts +37 -0
- package/esm/serialization/buffers/buffer.js +1 -0
- package/esm/serialization/buffers/in_memory_buffer.d.ts +121 -0
- package/esm/serialization/buffers/in_memory_buffer.js +206 -0
- package/esm/serialization/clamp.d.ts +10 -0
- package/esm/serialization/clamp.js +19 -0
- package/esm/serialization/compare_bytes.d.ts +9 -0
- package/esm/serialization/compare_bytes.js +45 -0
- package/esm/serialization/conversion.d.ts +8 -0
- package/esm/serialization/conversion.js +15 -0
- package/esm/serialization/decoders/decoder.d.ts +16 -0
- package/esm/serialization/decoders/decoder.js +1 -0
- package/esm/serialization/decoders/deflate_decoder.d.ts +15 -0
- package/esm/serialization/decoders/deflate_decoder.js +26 -0
- package/esm/serialization/decoders/null_decoder.d.ts +12 -0
- package/esm/serialization/decoders/null_decoder.js +13 -0
- package/esm/serialization/encoders/deflate_encoder.d.ts +15 -0
- package/esm/serialization/encoders/deflate_encoder.js +26 -0
- package/esm/serialization/encoders/encoder.d.ts +16 -0
- package/esm/serialization/encoders/encoder.js +1 -0
- package/esm/serialization/encoders/null_encoder.d.ts +12 -0
- package/esm/serialization/encoders/null_encoder.js +13 -0
- package/esm/serialization/manipulate_bytes.d.ts +6 -0
- package/esm/serialization/manipulate_bytes.js +13 -0
- package/esm/serialization/read_uint_le.d.ts +4 -0
- package/esm/serialization/read_uint_le.js +14 -0
- package/esm/serialization/streams/fixed_size_stream_readable_buffer_adapter.d.ts +52 -0
- package/esm/serialization/streams/fixed_size_stream_readable_buffer_adapter.js +129 -0
- package/esm/serialization/streams/forward_only_stream_readable_buffer_adapter.d.ts +36 -0
- package/esm/serialization/streams/forward_only_stream_readable_buffer_adapter.js +114 -0
- package/esm/serialization/streams/stream_readable_buffer.d.ts +41 -0
- package/esm/serialization/streams/stream_readable_buffer.js +64 -0
- package/esm/serialization/streams/stream_readable_buffer_adapter.d.ts +38 -0
- package/esm/serialization/streams/stream_readable_buffer_adapter.js +105 -0
- package/esm/serialization/streams/stream_writable_buffer.d.ts +42 -0
- package/esm/serialization/streams/stream_writable_buffer.js +64 -0
- package/esm/serialization/streams/stream_writable_buffer_adapter.d.ts +36 -0
- package/esm/serialization/streams/stream_writable_buffer_adapter.js +65 -0
- package/esm/serialization/streams/streams.d.ts +29 -0
- package/esm/serialization/streams/streams.js +1 -0
- package/esm/serialization/tap.d.ts +427 -0
- package/esm/serialization/tap.js +605 -0
- package/esm/serialization/text_encoding.d.ts +12 -0
- package/esm/serialization/text_encoding.js +14 -0
- package/esm/type/create_type.d.ts +54 -0
- package/esm/type/create_type.js +401 -0
- package/package.json +33 -0
- package/sachitv-avro-typescript-0.4.0.tgz +0 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { BinaryDuplexLike, StatelessTransportFactory } from "./transport_helpers.js";
|
|
2
|
+
/**
|
|
3
|
+
* Represents a pair of in-memory transports for client-server communication,
|
|
4
|
+
* providing a client factory and a server accept method for testing or local use.
|
|
5
|
+
*/
|
|
6
|
+
export interface InMemoryTransportPair {
|
|
7
|
+
/**
|
|
8
|
+
* Factory passed to emitters to establish a new client connection.
|
|
9
|
+
*/
|
|
10
|
+
clientFactory: StatelessTransportFactory;
|
|
11
|
+
/**
|
|
12
|
+
* Accepts the next server-side connection created by the client factory.
|
|
13
|
+
*/
|
|
14
|
+
accept(): Promise<BinaryDuplexLike>;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Creates a pair of in-memory transports for testing or local communication.
|
|
18
|
+
*
|
|
19
|
+
* @returns An object containing a client factory and an accept method for the server.
|
|
20
|
+
*/
|
|
21
|
+
export declare function createInMemoryTransportPair(): InMemoryTransportPair;
|
|
22
|
+
/**
|
|
23
|
+
* Creates a simple in-memory transport factory.
|
|
24
|
+
*
|
|
25
|
+
* @returns A factory function that creates a new in-memory transport for each request.
|
|
26
|
+
*/
|
|
27
|
+
export declare function createInMemoryTransport(): StatelessTransportFactory;
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Creates a pair of in-memory transports for testing or local communication.
|
|
3
|
+
*
|
|
4
|
+
* @returns An object containing a client factory and an accept method for the server.
|
|
5
|
+
*/
|
|
6
|
+
export function createInMemoryTransportPair() {
|
|
7
|
+
const pendingServers = [];
|
|
8
|
+
const pendingAccepts = [];
|
|
9
|
+
const clientFactory = () => {
|
|
10
|
+
const pair = createDuplexPair();
|
|
11
|
+
const resolver = pendingAccepts.shift();
|
|
12
|
+
if (resolver) {
|
|
13
|
+
resolver(pair.server);
|
|
14
|
+
}
|
|
15
|
+
else {
|
|
16
|
+
pendingServers.push(pair.server);
|
|
17
|
+
}
|
|
18
|
+
return Promise.resolve(pair.client);
|
|
19
|
+
};
|
|
20
|
+
const accept = () => {
|
|
21
|
+
const queued = pendingServers.shift();
|
|
22
|
+
if (queued) {
|
|
23
|
+
return Promise.resolve(queued);
|
|
24
|
+
}
|
|
25
|
+
return new Promise((resolve) => {
|
|
26
|
+
pendingAccepts.push(resolve);
|
|
27
|
+
});
|
|
28
|
+
};
|
|
29
|
+
return { clientFactory, accept };
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Creates a simple in-memory transport factory.
|
|
33
|
+
*
|
|
34
|
+
* @returns A factory function that creates a new in-memory transport for each request.
|
|
35
|
+
*/
|
|
36
|
+
export function createInMemoryTransport() {
|
|
37
|
+
return createInMemoryTransportPair().clientFactory;
|
|
38
|
+
}
|
|
39
|
+
function createDuplexPair() {
|
|
40
|
+
const clientChannel = new MemoryChannel();
|
|
41
|
+
const serverChannel = new MemoryChannel();
|
|
42
|
+
const client = {
|
|
43
|
+
readable: clientChannel,
|
|
44
|
+
writable: new MemoryChannelWritable(serverChannel),
|
|
45
|
+
};
|
|
46
|
+
const server = {
|
|
47
|
+
readable: serverChannel,
|
|
48
|
+
writable: new MemoryChannelWritable(clientChannel),
|
|
49
|
+
};
|
|
50
|
+
return { client, server };
|
|
51
|
+
}
|
|
52
|
+
class MemoryChannel {
|
|
53
|
+
constructor() {
|
|
54
|
+
Object.defineProperty(this, "closed", {
|
|
55
|
+
enumerable: true,
|
|
56
|
+
configurable: true,
|
|
57
|
+
writable: true,
|
|
58
|
+
value: false
|
|
59
|
+
});
|
|
60
|
+
Object.defineProperty(this, "pendingResolvers", {
|
|
61
|
+
enumerable: true,
|
|
62
|
+
configurable: true,
|
|
63
|
+
writable: true,
|
|
64
|
+
value: []
|
|
65
|
+
});
|
|
66
|
+
Object.defineProperty(this, "queue", {
|
|
67
|
+
enumerable: true,
|
|
68
|
+
configurable: true,
|
|
69
|
+
writable: true,
|
|
70
|
+
value: []
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
read() {
|
|
74
|
+
if (this.queue.length > 0) {
|
|
75
|
+
const chunk = this.queue.shift();
|
|
76
|
+
return Promise.resolve(chunk);
|
|
77
|
+
}
|
|
78
|
+
if (this.closed) {
|
|
79
|
+
return Promise.resolve(null);
|
|
80
|
+
}
|
|
81
|
+
return new Promise((resolve) => {
|
|
82
|
+
this.pendingResolvers.push(resolve);
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
enqueue(chunk) {
|
|
86
|
+
if (this.closed) {
|
|
87
|
+
throw new Error("Cannot write to closed channel.");
|
|
88
|
+
}
|
|
89
|
+
if (this.pendingResolvers.length > 0) {
|
|
90
|
+
const resolver = this.pendingResolvers.shift();
|
|
91
|
+
resolver(chunk);
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
this.queue.push(chunk);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
close() {
|
|
98
|
+
if (this.closed) {
|
|
99
|
+
return Promise.resolve();
|
|
100
|
+
}
|
|
101
|
+
this.closed = true;
|
|
102
|
+
while (this.pendingResolvers.length > 0) {
|
|
103
|
+
const resolver = this.pendingResolvers.shift();
|
|
104
|
+
resolver(null);
|
|
105
|
+
}
|
|
106
|
+
return Promise.resolve();
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
class MemoryChannelWritable {
|
|
110
|
+
constructor(target) {
|
|
111
|
+
Object.defineProperty(this, "target", {
|
|
112
|
+
enumerable: true,
|
|
113
|
+
configurable: true,
|
|
114
|
+
writable: true,
|
|
115
|
+
value: target
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
write(chunk) {
|
|
119
|
+
this.target.enqueue(chunk);
|
|
120
|
+
return Promise.resolve();
|
|
121
|
+
}
|
|
122
|
+
close() {
|
|
123
|
+
return this.target.close();
|
|
124
|
+
}
|
|
125
|
+
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Represents a readable stream for binary data in the transport layer.
|
|
3
|
+
* Used for asynchronously reading chunks of binary data from a transport.
|
|
4
|
+
*/
|
|
5
|
+
export interface BinaryReadable {
|
|
6
|
+
/**
|
|
7
|
+
* Reads the next chunk of binary data from the transport.
|
|
8
|
+
* Returns a Uint8Array if data is available, or null if the stream is ended.
|
|
9
|
+
*/
|
|
10
|
+
read(): Promise<Uint8Array | null>;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Represents a writable stream for binary data in the transport layer.
|
|
14
|
+
* Used for asynchronously writing chunks of binary data to a transport.
|
|
15
|
+
*/
|
|
16
|
+
export interface BinaryWritable {
|
|
17
|
+
/**
|
|
18
|
+
* Writes a chunk of binary data to the transport.
|
|
19
|
+
* @param chunk The binary data to write.
|
|
20
|
+
*/
|
|
21
|
+
write(chunk: Uint8Array): Promise<void>;
|
|
22
|
+
/**
|
|
23
|
+
* Closes the writable stream, signaling the end of data transmission.
|
|
24
|
+
*/
|
|
25
|
+
close(): Promise<void>;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Represents a duplex stream for binary data in the transport layer.
|
|
29
|
+
* Combines readable and writable streams for bidirectional communication.
|
|
30
|
+
*/
|
|
31
|
+
export interface BinaryDuplex {
|
|
32
|
+
/** The readable side of the duplex stream. */
|
|
33
|
+
readable: BinaryReadable;
|
|
34
|
+
/** The writable side of the duplex stream. */
|
|
35
|
+
writable: BinaryWritable;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* A type that can be either a BinaryReadable interface or a standard ReadableStream.
|
|
39
|
+
* Used to accept various readable transport implementations in the transport layer.
|
|
40
|
+
*/
|
|
41
|
+
export type BinaryReadableLike = BinaryReadable | ReadableStream<Uint8Array>;
|
|
42
|
+
/**
|
|
43
|
+
* A type that can be either a BinaryWritable interface or a standard WritableStream.
|
|
44
|
+
* Used to accept various writable transport implementations in the transport layer.
|
|
45
|
+
*/
|
|
46
|
+
export type BinaryWritableLike = BinaryWritable | WritableStream<Uint8Array>;
|
|
47
|
+
/**
|
|
48
|
+
* Represents a duplex-like stream that can be composed of different readable and writable types.
|
|
49
|
+
* Used for flexible duplex transport configurations in the transport layer.
|
|
50
|
+
*/
|
|
51
|
+
export interface BinaryDuplexLike {
|
|
52
|
+
/** The readable side, which can be a BinaryReadable or ReadableStream. */
|
|
53
|
+
readable: BinaryReadableLike;
|
|
54
|
+
/** The writable side, which can be a BinaryWritable or WritableStream. */
|
|
55
|
+
writable: BinaryWritableLike;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* A factory function for creating stateless transport duplex streams.
|
|
59
|
+
* Returns a promise that resolves to a BinaryDuplexLike for establishing connections in the transport layer.
|
|
60
|
+
*/
|
|
61
|
+
export type StatelessTransportFactory = () => Promise<BinaryDuplexLike>;
|
|
62
|
+
/**
|
|
63
|
+
* Options for configuring fetch-based transports in the transport layer.
|
|
64
|
+
* Allows customization of HTTP requests for RPC communication.
|
|
65
|
+
*/
|
|
66
|
+
export interface FetchTransportOptions {
|
|
67
|
+
/** The HTTP method to use for the request (e.g., 'POST'). */
|
|
68
|
+
method?: string;
|
|
69
|
+
/** Headers to include in the request. */
|
|
70
|
+
headers?: HeadersInit;
|
|
71
|
+
/** Additional initialization options for the fetch request. */
|
|
72
|
+
init?: RequestInit;
|
|
73
|
+
/** Custom fetch function to use instead of the global fetch. */
|
|
74
|
+
fetch?: typeof fetch;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Options for configuring WebSocket-based transports in the transport layer.
|
|
78
|
+
* Allows customization of WebSocket connections for RPC communication.
|
|
79
|
+
*/
|
|
80
|
+
export interface WebSocketTransportOptions {
|
|
81
|
+
/** Subprotocols to negotiate during the WebSocket handshake. */
|
|
82
|
+
protocols?: string | string[];
|
|
83
|
+
/** The type of binary data to expect from the WebSocket (e.g., 'arraybuffer', 'blob'). */
|
|
84
|
+
binaryType?: BinaryType;
|
|
85
|
+
/** Timeout in milliseconds for establishing the WebSocket connection. */
|
|
86
|
+
connectTimeoutMs?: number;
|
|
87
|
+
/** Factory function to create a custom WebSocket instance. */
|
|
88
|
+
socketFactory?: () => WebSocket;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Converts a BinaryDuplexLike to a standardized BinaryDuplex.
|
|
92
|
+
* Ensures consistent interface for duplex transports in the transport layer.
|
|
93
|
+
* @param input The duplex-like object to convert.
|
|
94
|
+
* @returns A BinaryDuplex with standardized readable and writable properties.
|
|
95
|
+
*/
|
|
96
|
+
export declare function toBinaryDuplex(input: BinaryDuplexLike): BinaryDuplex;
|
|
97
|
+
/**
|
|
98
|
+
* Converts a BinaryReadableLike to a standardized BinaryReadable.
|
|
99
|
+
* Wraps ReadableStream or returns the interface directly for consistent reading in the transport layer.
|
|
100
|
+
* @param source The readable-like object to convert.
|
|
101
|
+
* @returns A BinaryReadable interface for asynchronous binary data reading.
|
|
102
|
+
*/
|
|
103
|
+
export declare function toBinaryReadable(source: BinaryReadableLike): BinaryReadable;
|
|
104
|
+
/**
|
|
105
|
+
* Converts a BinaryWritableLike to a standardized BinaryWritable.
|
|
106
|
+
* Wraps WritableStream or returns the interface directly for consistent writing in the transport layer.
|
|
107
|
+
* @param target The writable-like object to convert.
|
|
108
|
+
* @returns A BinaryWritable interface for asynchronous binary data writing.
|
|
109
|
+
*/
|
|
110
|
+
export declare function toBinaryWritable(target: BinaryWritableLike): BinaryWritable;
|
|
111
|
+
/**
|
|
112
|
+
* Extracts binary data from various input types into a Uint8Array.
|
|
113
|
+
* Used in the transport layer to normalize WebSocket message data for processing.
|
|
114
|
+
* @param data The input data to extract binary from (Uint8Array, ArrayBuffer, ArrayBufferView, string, etc.).
|
|
115
|
+
* @returns A Uint8Array representation of the binary data.
|
|
116
|
+
* @throws Error if the data type is unsupported or Blob (not supported for WebSocket).
|
|
117
|
+
*/
|
|
118
|
+
export declare function extractBinary(data: unknown): Uint8Array;
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
const textEncoder = new TextEncoder();
|
|
2
|
+
/**
|
|
3
|
+
* Converts a BinaryDuplexLike to a standardized BinaryDuplex.
|
|
4
|
+
* Ensures consistent interface for duplex transports in the transport layer.
|
|
5
|
+
* @param input The duplex-like object to convert.
|
|
6
|
+
* @returns A BinaryDuplex with standardized readable and writable properties.
|
|
7
|
+
*/
|
|
8
|
+
export function toBinaryDuplex(input) {
|
|
9
|
+
return {
|
|
10
|
+
readable: toBinaryReadable(input.readable),
|
|
11
|
+
writable: toBinaryWritable(input.writable),
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Converts a BinaryReadableLike to a standardized BinaryReadable.
|
|
16
|
+
* Wraps ReadableStream or returns the interface directly for consistent reading in the transport layer.
|
|
17
|
+
* @param source The readable-like object to convert.
|
|
18
|
+
* @returns A BinaryReadable interface for asynchronous binary data reading.
|
|
19
|
+
*/
|
|
20
|
+
export function toBinaryReadable(source) {
|
|
21
|
+
if (isBinaryReadable(source)) {
|
|
22
|
+
return source;
|
|
23
|
+
}
|
|
24
|
+
if (!isReadableStream(source)) {
|
|
25
|
+
throw new TypeError("Unsupported readable transport.");
|
|
26
|
+
}
|
|
27
|
+
const reader = source.getReader();
|
|
28
|
+
return {
|
|
29
|
+
async read() {
|
|
30
|
+
const { value, done } = await reader.read();
|
|
31
|
+
if (done) {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
if (value === undefined) {
|
|
36
|
+
return new Uint8Array(0);
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
return value;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Converts a BinaryWritableLike to a standardized BinaryWritable.
|
|
47
|
+
* Wraps WritableStream or returns the interface directly for consistent writing in the transport layer.
|
|
48
|
+
* @param target The writable-like object to convert.
|
|
49
|
+
* @returns A BinaryWritable interface for asynchronous binary data writing.
|
|
50
|
+
*/
|
|
51
|
+
export function toBinaryWritable(target) {
|
|
52
|
+
if (isBinaryWritable(target)) {
|
|
53
|
+
return target;
|
|
54
|
+
}
|
|
55
|
+
if (!isWritableStream(target)) {
|
|
56
|
+
throw new TypeError("Unsupported writable transport.");
|
|
57
|
+
}
|
|
58
|
+
const writer = target.getWriter();
|
|
59
|
+
return {
|
|
60
|
+
async write(chunk) {
|
|
61
|
+
await writer.write(chunk);
|
|
62
|
+
},
|
|
63
|
+
async close() {
|
|
64
|
+
await writer.close();
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Extracts binary data from various input types into a Uint8Array.
|
|
70
|
+
* Used in the transport layer to normalize WebSocket message data for processing.
|
|
71
|
+
* @param data The input data to extract binary from (Uint8Array, ArrayBuffer, ArrayBufferView, string, etc.).
|
|
72
|
+
* @returns A Uint8Array representation of the binary data.
|
|
73
|
+
* @throws Error if the data type is unsupported or Blob (not supported for WebSocket).
|
|
74
|
+
*/
|
|
75
|
+
export function extractBinary(data) {
|
|
76
|
+
if (data instanceof Uint8Array) {
|
|
77
|
+
return data;
|
|
78
|
+
}
|
|
79
|
+
if (data instanceof ArrayBuffer) {
|
|
80
|
+
return new Uint8Array(data);
|
|
81
|
+
}
|
|
82
|
+
if (ArrayBuffer.isView(data)) {
|
|
83
|
+
const view = data;
|
|
84
|
+
return new Uint8Array(view.buffer.slice(view.byteOffset, view.byteOffset + view.byteLength));
|
|
85
|
+
}
|
|
86
|
+
if (typeof Blob !== "undefined" && data instanceof Blob) {
|
|
87
|
+
throw new Error("Blob WebSocket messages are not supported.");
|
|
88
|
+
}
|
|
89
|
+
if (typeof data === "string") {
|
|
90
|
+
return textEncoder.encode(data);
|
|
91
|
+
}
|
|
92
|
+
throw new Error("Unsupported WebSocket message data.");
|
|
93
|
+
}
|
|
94
|
+
function isBinaryReadable(value) {
|
|
95
|
+
return typeof value === "object" &&
|
|
96
|
+
value !== null &&
|
|
97
|
+
typeof value.read === "function";
|
|
98
|
+
}
|
|
99
|
+
function isBinaryWritable(value) {
|
|
100
|
+
return typeof value === "object" &&
|
|
101
|
+
value !== null &&
|
|
102
|
+
typeof value.write === "function" &&
|
|
103
|
+
typeof value.close === "function";
|
|
104
|
+
}
|
|
105
|
+
function isReadableStream(value) {
|
|
106
|
+
return typeof ReadableStream !== "undefined" &&
|
|
107
|
+
value instanceof ReadableStream;
|
|
108
|
+
}
|
|
109
|
+
function isWritableStream(value) {
|
|
110
|
+
return typeof WritableStream !== "undefined" &&
|
|
111
|
+
value instanceof WritableStream;
|
|
112
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { StatelessTransportFactory, WebSocketTransportOptions } from "./transport_helpers.js";
|
|
2
|
+
/**
|
|
3
|
+
* Creates a stateless transport factory using WebSockets.
|
|
4
|
+
*
|
|
5
|
+
* @param endpoint The WebSocket URL to connect to.
|
|
6
|
+
* @param options Configuration options for the WebSocket transport.
|
|
7
|
+
* @returns A factory function that creates a new transport for each request.
|
|
8
|
+
*/
|
|
9
|
+
export declare function createWebSocketTransport(endpoint: string | URL, options?: WebSocketTransportOptions): StatelessTransportFactory;
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { extractBinary } from "./transport_helpers.js";
|
|
2
|
+
/**
|
|
3
|
+
* Creates a stateless transport factory using WebSockets.
|
|
4
|
+
*
|
|
5
|
+
* @param endpoint The WebSocket URL to connect to.
|
|
6
|
+
* @param options Configuration options for the WebSocket transport.
|
|
7
|
+
* @returns A factory function that creates a new transport for each request.
|
|
8
|
+
*/
|
|
9
|
+
export function createWebSocketTransport(endpoint, options = {}) {
|
|
10
|
+
return async () => {
|
|
11
|
+
const socket = options.socketFactory
|
|
12
|
+
? options.socketFactory()
|
|
13
|
+
: new WebSocket(typeof endpoint === "string" ? endpoint : endpoint.toString(), options.protocols);
|
|
14
|
+
socket.binaryType = options.binaryType ?? "arraybuffer";
|
|
15
|
+
await waitForOpen(socket, options.connectTimeoutMs);
|
|
16
|
+
return {
|
|
17
|
+
readable: websocketReadable(socket),
|
|
18
|
+
writable: websocketWritable(socket),
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
function waitForOpen(socket, timeout) {
|
|
23
|
+
if (socket.readyState === WebSocket.OPEN) {
|
|
24
|
+
return Promise.resolve();
|
|
25
|
+
}
|
|
26
|
+
return new Promise((resolve, reject) => {
|
|
27
|
+
let timer;
|
|
28
|
+
const cleanup = () => {
|
|
29
|
+
socket.removeEventListener("open", handleOpen);
|
|
30
|
+
socket.removeEventListener("error", handleError);
|
|
31
|
+
if (timer !== undefined) {
|
|
32
|
+
clearTimeout(timer);
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
const handleOpen = () => {
|
|
36
|
+
cleanup();
|
|
37
|
+
resolve();
|
|
38
|
+
};
|
|
39
|
+
const handleError = () => {
|
|
40
|
+
cleanup();
|
|
41
|
+
reject(new Error("WebSocket connection failed."));
|
|
42
|
+
};
|
|
43
|
+
socket.addEventListener("open", handleOpen, { once: true });
|
|
44
|
+
socket.addEventListener("error", handleError, { once: true });
|
|
45
|
+
if (timeout !== undefined) {
|
|
46
|
+
timer = setTimeout(() => {
|
|
47
|
+
cleanup();
|
|
48
|
+
reject(new Error("WebSocket connection timed out."));
|
|
49
|
+
}, timeout);
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
class WebSocketReadableStream extends ReadableStream {
|
|
54
|
+
constructor(socket) {
|
|
55
|
+
let cleanup;
|
|
56
|
+
const start = (controller) => {
|
|
57
|
+
const handleMessage = (event) => {
|
|
58
|
+
try {
|
|
59
|
+
controller.enqueue(extractBinary(event.data));
|
|
60
|
+
}
|
|
61
|
+
catch (err) {
|
|
62
|
+
controller.error(err);
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
const handleClose = () => controller.close();
|
|
66
|
+
const handleError = () => controller.error(new Error("WebSocket error."));
|
|
67
|
+
socket.addEventListener("message", handleMessage);
|
|
68
|
+
socket.addEventListener("close", handleClose, { once: true });
|
|
69
|
+
socket.addEventListener("error", handleError, { once: true });
|
|
70
|
+
cleanup = () => {
|
|
71
|
+
socket.removeEventListener("message", handleMessage);
|
|
72
|
+
socket.removeEventListener("close", handleClose);
|
|
73
|
+
socket.removeEventListener("error", handleError);
|
|
74
|
+
};
|
|
75
|
+
};
|
|
76
|
+
const cancel = () => {
|
|
77
|
+
cleanup?.();
|
|
78
|
+
socket.close();
|
|
79
|
+
return Promise.resolve();
|
|
80
|
+
};
|
|
81
|
+
super({ start, cancel });
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
function websocketReadable(socket) {
|
|
85
|
+
return new WebSocketReadableStream(socket);
|
|
86
|
+
}
|
|
87
|
+
function websocketWritable(socket) {
|
|
88
|
+
return new WritableStream({
|
|
89
|
+
write(chunk) {
|
|
90
|
+
if (socket.readyState !== WebSocket.OPEN) {
|
|
91
|
+
throw new Error("WebSocket is not open.");
|
|
92
|
+
}
|
|
93
|
+
socket.send(chunk);
|
|
94
|
+
},
|
|
95
|
+
close() {
|
|
96
|
+
socket.close();
|
|
97
|
+
},
|
|
98
|
+
abort() {
|
|
99
|
+
socket.close();
|
|
100
|
+
},
|
|
101
|
+
});
|
|
102
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Options for framing a message, specifying the frame size.
|
|
3
|
+
*/
|
|
4
|
+
export interface FrameMessageOptions {
|
|
5
|
+
/**
|
|
6
|
+
* The maximum size in bytes for each frame. Defaults to 8192.
|
|
7
|
+
*/
|
|
8
|
+
frameSize?: number;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Options for decoding a framed message, specifying the starting offset.
|
|
12
|
+
*/
|
|
13
|
+
export interface DecodeFramedMessageOptions {
|
|
14
|
+
/**
|
|
15
|
+
* The byte offset in the buffer to start decoding from. Defaults to 0.
|
|
16
|
+
*/
|
|
17
|
+
offset?: number;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Result of decoding a framed message, containing the payload and next offset.
|
|
21
|
+
*/
|
|
22
|
+
export interface DecodeFramedMessageResult {
|
|
23
|
+
/**
|
|
24
|
+
* The reassembled message payload as a Uint8Array.
|
|
25
|
+
*/
|
|
26
|
+
payload: Uint8Array;
|
|
27
|
+
/**
|
|
28
|
+
* The byte offset in the buffer after the decoded message.
|
|
29
|
+
*/
|
|
30
|
+
nextOffset: number;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Frames a message payload into a sequence of frames with size headers and a terminator frame.
|
|
34
|
+
* Splits the payload into frames of up to the specified frameSize bytes, each prefixed with a 4-byte
|
|
35
|
+
* big-endian length header, and appends a zero-length terminator frame.
|
|
36
|
+
*/
|
|
37
|
+
export declare function frameMessage(payload: ArrayBuffer | Uint8Array, options?: FrameMessageOptions): Uint8Array;
|
|
38
|
+
/**
|
|
39
|
+
* Decodes a framed message from a buffer, reassembling the payload from frames.
|
|
40
|
+
* Reads frames starting from the specified offset, each consisting of a 4-byte big-endian length
|
|
41
|
+
* header followed by the frame data, until a zero-length frame (terminator) is encountered.
|
|
42
|
+
* Concatenates the frame data into the payload.
|
|
43
|
+
*/
|
|
44
|
+
export declare function decodeFramedMessage(buffer: ArrayBuffer, options?: DecodeFramedMessageOptions): DecodeFramedMessageResult;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { concatUint8Arrays, toUint8Array, } from "../../../internal/collections/array_utils.js";
|
|
2
|
+
const DEFAULT_FRAME_SIZE = 8 * 1024;
|
|
3
|
+
const FRAME_HEADER_SIZE = 4;
|
|
4
|
+
function normalizeFrameSize(frameSize) {
|
|
5
|
+
if (frameSize === undefined) {
|
|
6
|
+
return DEFAULT_FRAME_SIZE;
|
|
7
|
+
}
|
|
8
|
+
if (!Number.isInteger(frameSize) || frameSize <= 0) {
|
|
9
|
+
throw new RangeError("frameSize must be a positive integer.");
|
|
10
|
+
}
|
|
11
|
+
return frameSize;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Frames a message payload into a sequence of frames with size headers and a terminator frame.
|
|
15
|
+
* Splits the payload into frames of up to the specified frameSize bytes, each prefixed with a 4-byte
|
|
16
|
+
* big-endian length header, and appends a zero-length terminator frame.
|
|
17
|
+
*/
|
|
18
|
+
export function frameMessage(payload, options) {
|
|
19
|
+
const bytes = toUint8Array(payload);
|
|
20
|
+
const frameSize = normalizeFrameSize(options?.frameSize);
|
|
21
|
+
const frames = [];
|
|
22
|
+
let offset = 0;
|
|
23
|
+
while (offset < bytes.length) {
|
|
24
|
+
const chunkSize = Math.min(frameSize, bytes.length - offset);
|
|
25
|
+
const header = new Uint8Array(FRAME_HEADER_SIZE);
|
|
26
|
+
// Write big-endian uint32 frame length
|
|
27
|
+
new DataView(header.buffer).setUint32(0, chunkSize, false);
|
|
28
|
+
frames.push(header);
|
|
29
|
+
frames.push(bytes.subarray(offset, offset + chunkSize));
|
|
30
|
+
offset += chunkSize;
|
|
31
|
+
}
|
|
32
|
+
frames.push(new Uint8Array(FRAME_HEADER_SIZE));
|
|
33
|
+
return frames.length === 1 ? frames[0] : concatUint8Arrays(frames);
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Decodes a framed message from a buffer, reassembling the payload from frames.
|
|
37
|
+
* Reads frames starting from the specified offset, each consisting of a 4-byte big-endian length
|
|
38
|
+
* header followed by the frame data, until a zero-length frame (terminator) is encountered.
|
|
39
|
+
* Concatenates the frame data into the payload.
|
|
40
|
+
*/
|
|
41
|
+
export function decodeFramedMessage(buffer, options = {}) {
|
|
42
|
+
const { offset = 0 } = options;
|
|
43
|
+
if (!Number.isInteger(offset) || offset < 0) {
|
|
44
|
+
throw new RangeError("offset must be a non-negative integer.");
|
|
45
|
+
}
|
|
46
|
+
const bytes = new Uint8Array(buffer);
|
|
47
|
+
if (offset > bytes.length) {
|
|
48
|
+
throw new RangeError("offset exceeds buffer length.");
|
|
49
|
+
}
|
|
50
|
+
const frames = [];
|
|
51
|
+
const view = new DataView(buffer);
|
|
52
|
+
let cursor = offset;
|
|
53
|
+
let foundTerminator = false;
|
|
54
|
+
while (cursor + FRAME_HEADER_SIZE <= bytes.length) {
|
|
55
|
+
const frameLength = view.getUint32(cursor, false);
|
|
56
|
+
cursor += FRAME_HEADER_SIZE;
|
|
57
|
+
if (frameLength === 0) {
|
|
58
|
+
foundTerminator = true;
|
|
59
|
+
break;
|
|
60
|
+
}
|
|
61
|
+
if (cursor + frameLength > bytes.length) {
|
|
62
|
+
throw new Error("Incomplete frame data.");
|
|
63
|
+
}
|
|
64
|
+
frames.push(bytes.subarray(cursor, cursor + frameLength));
|
|
65
|
+
cursor += frameLength;
|
|
66
|
+
}
|
|
67
|
+
if (!foundTerminator) {
|
|
68
|
+
throw new Error("Message terminator not found.");
|
|
69
|
+
}
|
|
70
|
+
return {
|
|
71
|
+
payload: concatUint8Arrays(frames),
|
|
72
|
+
nextOffset: cursor,
|
|
73
|
+
};
|
|
74
|
+
}
|