@replit/river 0.216.0 → 0.217.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 +2 -2
- package/dist/{adapter-BXCk-dmy.d.ts → adapter-Dl5Mewp3.d.ts} +1 -1
- package/dist/{chunk-ZLMQQI43.js → chunk-JFFRB3SS.js} +57 -27
- package/dist/chunk-JFFRB3SS.js.map +1 -0
- package/dist/{chunk-75ZMPCKC.js → chunk-VK3VJZGG.js} +19 -18
- package/dist/chunk-VK3VJZGG.js.map +1 -0
- package/dist/chunk-WMPWPIA4.js +72 -0
- package/dist/chunk-WMPWPIA4.js.map +1 -0
- package/dist/{client-BNc5Pj_4.d.ts → client-YP9bECp8.d.ts} +2 -2
- package/dist/codec/index.d.ts +3 -3
- package/dist/codec/index.js +2 -2
- package/dist/{connection-ou9w2dSY.d.ts → connection-D_HE_YQB.d.ts} +3 -3
- package/dist/customSchemas/index.d.ts +34 -0
- package/dist/customSchemas/index.js +9 -0
- package/dist/customSchemas/index.js.map +1 -0
- package/dist/{index-ZWkoesQD.d.ts → index-DgUMnNOi.d.ts} +1 -1
- package/dist/logging/index.d.ts +3 -3
- package/dist/{message-CpXWqmJw.d.ts → message-DxS8db8A.d.ts} +30 -31
- package/dist/protobuf/index.d.ts +11 -15
- package/dist/protobuf/index.js +7 -5
- package/dist/protobuf/index.js.map +1 -1
- package/dist/router/index.d.ts +11 -11
- package/dist/router/index.js +1 -1
- package/dist/{server-BPu7Td80.d.ts → server-BfM3_JLq.d.ts} +5 -5
- package/dist/{services-cwGAC2rB.d.cts → services-CL6k3HMH.d.ts} +19 -10
- package/dist/testUtil/index.d.ts +8 -8
- package/dist/testUtil/index.js +2 -2
- package/dist/testUtil/index.js.map +1 -1
- package/dist/transport/impls/ws/client.d.ts +7 -7
- package/dist/transport/impls/ws/client.js +2 -2
- package/dist/transport/impls/ws/server.d.ts +7 -7
- package/dist/transport/impls/ws/server.js +2 -2
- package/dist/transport/impls/ws/server.js.map +1 -1
- package/dist/transport/index.d.ts +8 -8
- package/dist/transport/index.js +2 -2
- package/dist/{transport-B1MUtXL7.d.ts → transport-CUpXnch7.d.ts} +4 -4
- package/package.json +14 -39
- package/dist/adapter-D5X11kmP.d.cts +0 -29
- package/dist/chunk-75ZMPCKC.js.map +0 -1
- package/dist/chunk-ZLMQQI43.js.map +0 -1
- package/dist/client-BZUvFL6B.d.cts +0 -54
- package/dist/codec/index.cjs +0 -268
- package/dist/codec/index.cjs.map +0 -1
- package/dist/codec/index.d.cts +0 -19
- package/dist/connection-xxgJHs2o.d.cts +0 -40
- package/dist/index-BAGGleT3.d.cts +0 -37
- package/dist/logging/index.cjs +0 -55
- package/dist/logging/index.cjs.map +0 -1
- package/dist/logging/index.d.cts +0 -4
- package/dist/message-CpXWqmJw.d.cts +0 -119
- package/dist/protobuf/codec.cjs +0 -107
- package/dist/protobuf/codec.cjs.map +0 -1
- package/dist/protobuf/codec.d.cts +0 -13
- package/dist/protobuf/index.cjs +0 -1877
- package/dist/protobuf/index.cjs.map +0 -1
- package/dist/protobuf/index.d.cts +0 -488
- package/dist/router/index.cjs +0 -2035
- package/dist/router/index.cjs.map +0 -1
- package/dist/router/index.d.cts +0 -80
- package/dist/server-JdnoVO11.d.cts +0 -72
- package/dist/services-BrTFTO5Q.d.ts +0 -1125
- package/dist/testUtil/index.cjs +0 -3051
- package/dist/testUtil/index.cjs.map +0 -1
- package/dist/testUtil/index.d.cts +0 -122
- package/dist/transport/impls/ws/client.cjs +0 -2308
- package/dist/transport/impls/ws/client.cjs.map +0 -1
- package/dist/transport/impls/ws/client.d.cts +0 -33
- package/dist/transport/impls/ws/server.cjs +0 -2179
- package/dist/transport/impls/ws/server.cjs.map +0 -1
- package/dist/transport/impls/ws/server.d.cts +0 -21
- package/dist/transport/index.cjs +0 -2727
- package/dist/transport/index.cjs.map +0 -1
- package/dist/transport/index.d.cts +0 -11
- package/dist/transport-BnU3Zb0Q.d.cts +0 -590
- package/dist/types-BGGvYIJM.d.cts +0 -20
- package/dist/wslike-Dng9H1C7.d.cts +0 -40
package/dist/router/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { C as Connection, t as CommonSession, j as SessionState, u as CommonSessionProps, T as Transport, v as ServerTransportOptions, q as ServerHandshakeOptions, w as ServerSession, e as ProvidedServerTransportOptions, D as DeleteSessionOptions } from './transport-
|
|
2
|
-
import { O as OpaqueTransportMessage, H as HandshakeErrorResponseCodes, P as ProtocolVersion, b as TransportMessage, T as TransportClientId } from './message-
|
|
3
|
-
import { Static, TSchema } from '
|
|
4
|
-
import { T as Tags } from './index-
|
|
5
|
-
import { S as SendResult } from './adapter-
|
|
1
|
+
import { C as Connection, t as CommonSession, j as SessionState, u as CommonSessionProps, T as Transport, v as ServerTransportOptions, q as ServerHandshakeOptions, w as ServerSession, e as ProvidedServerTransportOptions, D as DeleteSessionOptions } from './transport-CUpXnch7.js';
|
|
2
|
+
import { O as OpaqueTransportMessage, H as HandshakeErrorResponseCodes, P as ProtocolVersion, b as TransportMessage, T as TransportClientId } from './message-DxS8db8A.js';
|
|
3
|
+
import { Static, TSchema } from 'typebox';
|
|
4
|
+
import { T as Tags } from './index-DgUMnNOi.js';
|
|
5
|
+
import { S as SendResult } from './adapter-Dl5Mewp3.js';
|
|
6
6
|
|
|
7
7
|
interface SessionWaitingForHandshakeListeners {
|
|
8
8
|
onConnectionErrored: (err: unknown) => void;
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { TObject, TLiteral, TEnum, TString, TSchema, TNever, TUnion, Static } from '@sinclair/typebox';
|
|
1
|
+
import { TObject, TLiteral, TEnum, TString, TSchema, TNever, TUnion, Type, Static } from 'typebox';
|
|
3
2
|
import { Span } from '@opentelemetry/api';
|
|
4
|
-
import { T as TransportClientId } from './message-
|
|
5
|
-
import { C as Connection, n as ClientHandshakeOptions, z as SessionId } from './transport-
|
|
6
|
-
import { C as ClientTransport } from './client-
|
|
3
|
+
import { T as TransportClientId } from './message-DxS8db8A.js';
|
|
4
|
+
import { C as Connection, n as ClientHandshakeOptions, z as SessionId } from './transport-CUpXnch7.js';
|
|
5
|
+
import { C as ClientTransport } from './client-YP9bECp8.js';
|
|
7
6
|
|
|
8
7
|
declare const ReadableBrokenError: {
|
|
9
8
|
readonly code: "READABLE_BROKEN";
|
|
@@ -225,6 +224,16 @@ type Client<Services extends AnyServiceSchemaMap<any>, IS extends InstantiatedSe
|
|
|
225
224
|
interface ClientOptions {
|
|
226
225
|
connectOnInvoke: boolean;
|
|
227
226
|
eagerlyConnect: boolean;
|
|
227
|
+
/**
|
|
228
|
+
* Default options merged into every leaf call (`rpc`, `stream`,
|
|
229
|
+
* `upload`, `subscribe`). Caller-supplied `options` win field-by-field,
|
|
230
|
+
* so a caller can override `signal` while keeping other defaults.
|
|
231
|
+
*
|
|
232
|
+
* Pass a function form when the default needs to be re-resolved per
|
|
233
|
+
* call (e.g. an ambient signal that changes between invocations of
|
|
234
|
+
* the same client).
|
|
235
|
+
*/
|
|
236
|
+
defaultCallOptions?: CallOptions | (() => CallOptions);
|
|
228
237
|
}
|
|
229
238
|
/**
|
|
230
239
|
* Creates a client for a given server using the provided transport.
|
|
@@ -264,7 +273,7 @@ declare const INVALID_REQUEST_CODE = "INVALID_REQUEST";
|
|
|
264
273
|
*/
|
|
265
274
|
declare const CANCEL_CODE = "CANCEL";
|
|
266
275
|
type TLiteralString = TLiteral<string>;
|
|
267
|
-
type TEnumString = TEnum<
|
|
276
|
+
type TEnumString = TEnum<Array<string>>;
|
|
268
277
|
type BaseErrorSchemaType = TObject<{
|
|
269
278
|
code: TLiteralString | TEnumString;
|
|
270
279
|
message: TLiteralString | TString;
|
|
@@ -294,12 +303,12 @@ declare const ReaderErrorSchema: TUnion<[TObject<{
|
|
|
294
303
|
}>, TObject<{
|
|
295
304
|
code: TLiteral<"INVALID_REQUEST">;
|
|
296
305
|
message: TString;
|
|
297
|
-
extras:
|
|
298
|
-
firstValidationErrors:
|
|
306
|
+
extras: Type.TOptional<TObject<{
|
|
307
|
+
firstValidationErrors: Type.TArray<TObject<{
|
|
299
308
|
path: TString;
|
|
300
309
|
message: TString;
|
|
301
310
|
}>>;
|
|
302
|
-
totalErrors:
|
|
311
|
+
totalErrors: Type.TNumber;
|
|
303
312
|
}>>;
|
|
304
313
|
}>, TObject<{
|
|
305
314
|
code: TLiteral<"CANCEL">;
|
|
@@ -1122,4 +1131,4 @@ declare class ServiceScaffold<Context extends MaybeDisposable, State extends obj
|
|
|
1122
1131
|
};
|
|
1123
1132
|
}
|
|
1124
1133
|
|
|
1125
|
-
export {
|
|
1134
|
+
export { serializeSchema as $, type AnyServiceSchemaMap as A, type BaseErrorSchemaType as B, CANCEL_CODE as C, type SerializedProcedureSchemaProtocolv1 as D, Err as E, type SerializedServerSchema as F, type SerializedServerSchemaProtocolv1 as G, type SerializedServiceSchema as H, type InstantiatedServiceSchemaMap as I, type SerializedServiceSchemaProtocolv1 as J, type Service as K, type ServiceConfiguration as L, type MaybeDisposable as M, type StreamProcedure as N, Ok as O, type ProcedureHandlerContext as P, type SubscriptionProcedure as Q, type RpcProcedure as R, type SerializedProcedureSchema as S, UNEXPECTED_DISCONNECT_CODE as T, UNCAUGHT_ERROR_CODE as U, type UploadProcedure as V, type ValidProcType as W, type Writable as X, createClient as Y, createServiceSchema as Z, flattenErrorType as _, type PayloadType as a, serializeSchemaV1Compat as a0, type ReadableIterator as a1, type ErrorPayload as a2, type AnyProcedure as b, type CallOptions as c, type Client as d, type ClientOptions as e, type ErrResult as f, INVALID_REQUEST_CODE as g, type OkResult as h, type ProcErrors as i, type ProcHandler as j, type ProcInit as k, type ProcRequest as l, type ProcResponse as m, type ProcType as n, Procedure as o, type ProcedureErrorSchemaType as p, type ProcedureMap as q, ReadableImpl as r, type Readable as s, ReadableBrokenError as t, type ReadableResult as u, ReaderErrorSchema as v, type ResponseData as w, type Result as x, type ResultUnwrapErr as y, type ResultUnwrapOk as z };
|
package/dist/testUtil/index.d.ts
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import { P as ProvidedClientTransportOptions, e as ProvidedServerTransportOptions, n as ClientHandshakeOptions, C as Connection, q as ServerHandshakeOptions, T as Transport, i as SessionNoConnection, x as SessionBoundSendFn, m as ClientTransportOptions, y as SessionOptions } from '../transport-
|
|
2
|
-
import { C as ClientTransport } from '../client-
|
|
3
|
-
import { S as ServerTransport } from '../server-
|
|
4
|
-
import { T as TransportClientId, e as PartialTransportMessage, O as OpaqueTransportMessage } from '../message-
|
|
5
|
-
import { TSchema, Static } from '
|
|
6
|
-
import { B as BaseErrorSchemaType,
|
|
1
|
+
import { P as ProvidedClientTransportOptions, e as ProvidedServerTransportOptions, n as ClientHandshakeOptions, C as Connection, q as ServerHandshakeOptions, T as Transport, i as SessionNoConnection, x as SessionBoundSendFn, m as ClientTransportOptions, y as SessionOptions } from '../transport-CUpXnch7.js';
|
|
2
|
+
import { C as ClientTransport } from '../client-YP9bECp8.js';
|
|
3
|
+
import { S as ServerTransport } from '../server-BfM3_JLq.js';
|
|
4
|
+
import { T as TransportClientId, e as PartialTransportMessage, O as OpaqueTransportMessage } from '../message-DxS8db8A.js';
|
|
5
|
+
import { TSchema, Static } from 'typebox';
|
|
6
|
+
import { B as BaseErrorSchemaType, s as Readable, a1 as ReadableIterator, u as ReadableResult } from '../services-CL6k3HMH.js';
|
|
7
7
|
import { W as WsLike } from '../wslike-Dng9H1C7.js';
|
|
8
8
|
import NodeWs from 'ws';
|
|
9
9
|
import http from 'node:http';
|
|
10
10
|
import { Duplex } from 'node:stream';
|
|
11
|
-
import '../index-
|
|
11
|
+
import '../index-DgUMnNOi.js';
|
|
12
12
|
import '../types-BGGvYIJM.js';
|
|
13
|
-
import '../adapter-
|
|
13
|
+
import '../adapter-Dl5Mewp3.js';
|
|
14
14
|
import '@opentelemetry/api';
|
|
15
15
|
|
|
16
16
|
interface TestTransportOptions {
|
package/dist/testUtil/index.js
CHANGED
|
@@ -5,12 +5,12 @@ import {
|
|
|
5
5
|
SessionStateGraph,
|
|
6
6
|
defaultClientTransportOptions,
|
|
7
7
|
defaultTransportOptions
|
|
8
|
-
} from "../chunk-
|
|
8
|
+
} from "../chunk-VK3VJZGG.js";
|
|
9
9
|
import "../chunk-CC7RN7GI.js";
|
|
10
10
|
import {
|
|
11
11
|
currentProtocolVersion,
|
|
12
12
|
getTracer
|
|
13
|
-
} from "../chunk-
|
|
13
|
+
} from "../chunk-JFFRB3SS.js";
|
|
14
14
|
|
|
15
15
|
// testUtil/index.ts
|
|
16
16
|
import NodeWs, { WebSocketServer } from "ws";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../testUtil/index.ts","../../testUtil/observable/observable.ts","../../testUtil/duplex/duplexPair.ts","../../testUtil/fixtures/mockTransport.ts"],"sourcesContent":["import NodeWs, { WebSocketServer } from 'ws';\nimport http from 'node:http';\nimport { Static } from '@sinclair/typebox';\nimport {\n OpaqueTransportMessage,\n PartialTransportMessage,\n currentProtocolVersion,\n} from '../transport/message';\nimport { Transport } from '../transport/transport';\nimport { Readable, ReadableResult, ReadableIterator } from '../router/streams';\nimport { WsLike } from '../transport/impls/ws/wslike';\nimport {\n defaultClientTransportOptions,\n defaultTransportOptions,\n} from '../transport/options';\nimport { Connection } from '../transport/connection';\nimport { SessionState } from '../transport/sessionStateMachine/common';\nimport { SessionStateGraph } from '../transport/sessionStateMachine/transitions';\nimport { BaseErrorSchemaType } from '../router/errors';\nimport { ClientTransport } from '../transport/client';\nimport { ServerTransport } from '../transport/server';\nimport { getTracer } from '../tracing';\n\nexport {\n createMockTransportNetwork,\n InMemoryConnection,\n} from './fixtures/mockTransport';\n\n/**\n * Creates a WebSocket client that connects to a local server at the specified port.\n * This should only be used for testing.\n * @param port - The port number to connect to.\n * @returns A Promise that resolves to a WebSocket instance.\n */\nexport function createLocalWebSocketClient(port: number): WsLike {\n const sock = new NodeWs(`ws://localhost:${port}`);\n sock.binaryType = 'arraybuffer';\n\n return sock;\n}\n\n/**\n * Creates a WebSocket server instance using the provided HTTP server.\n * Only used as helper for testing.\n * @param server - The HTTP server instance to use for the WebSocket server.\n * @returns A Promise that resolves to the created WebSocket server instance.\n */\nexport function createWebSocketServer(server: http.Server) {\n return new WebSocketServer({ server });\n}\n\n/**\n * Starts listening on the given server and returns the automatically allocated port number.\n * This should only be used for testing.\n * @param server - The http server to listen on.\n * @returns A promise that resolves with the allocated port number.\n * @throws An error if a port cannot be allocated.\n */\nexport function onWsServerReady(server: http.Server): Promise<number> {\n return new Promise((resolve, reject) => {\n server.listen(() => {\n const addr = server.address();\n if (typeof addr === 'object' && addr) {\n resolve(addr.port);\n } else {\n reject(new Error(\"couldn't find a port to allocate\"));\n }\n });\n });\n}\n\nconst readableIterators = new WeakMap<\n Readable<unknown, Static<BaseErrorSchemaType>>,\n ReadableIterator<unknown, Static<BaseErrorSchemaType>>\n>();\n\n/**\n * A safe way to access {@link Readble}'s iterator multiple times in test helpers.\n *\n * If there are other iteration attempts outside of the test helpers\n * (this function, {@link readNextResult}, and {@link isReadableDone})\n * it will throw an error.\n */\nexport function getReadableIterator<T, E extends Static<BaseErrorSchemaType>>(\n readable: Readable<T, E>,\n): ReadableIterator<T, E> {\n let iter = readableIterators.get(readable) as\n | ReadableIterator<T, E>\n | undefined;\n\n if (!iter) {\n iter = readable[Symbol.asyncIterator]();\n readableIterators.set(readable, iter);\n }\n\n return iter;\n}\n\n/**\n * Retrieves the next value from {@link Readable}, or throws an error if the Readable is done.\n *\n * Calling semantics are similar to {@link getReadableIterator}\n */\nexport async function readNextResult<T, E extends Static<BaseErrorSchemaType>>(\n readable: Readable<T, E>,\n): Promise<ReadableResult<T, E>> {\n const res = await getReadableIterator(readable).next();\n\n if (res.done) {\n throw new Error('readNext from a done Readable');\n }\n\n return res.value;\n}\n\n/**\n * Checks if the readable is done iterating, it consumes an iteration in the process.\n *\n * Calling semantics are similar to {@link getReadableIterator}\n */\nexport async function isReadableDone<T, E extends Static<BaseErrorSchemaType>>(\n readable: Readable<T, E>,\n) {\n const res = await getReadableIterator(readable).next();\n\n return res.done;\n}\n\nexport function payloadToTransportMessage<Payload>(\n payload: Payload,\n): PartialTransportMessage<Payload> {\n return {\n streamId: 'stream',\n controlFlags: 0,\n payload,\n };\n}\n\nexport function createDummyTransportMessage() {\n return payloadToTransportMessage({\n msg: 'cool',\n test: Math.random(),\n });\n}\n\n/**\n * Waits for a message on the transport.\n * @param {Transport} t - The transport to listen to.\n * @param filter - An optional filter function to apply to the received messages.\n * @returns A promise that resolves with the payload of the first message that passes the filter.\n */\nexport async function waitForMessage(\n t: Transport<Connection>,\n filter?: (msg: OpaqueTransportMessage) => boolean,\n rejectMismatch?: boolean,\n) {\n return new Promise((resolve, reject) => {\n function cleanup() {\n t.removeEventListener('message', onMessage);\n }\n\n function onMessage(msg: OpaqueTransportMessage) {\n if (!filter || filter(msg)) {\n cleanup();\n resolve(msg.payload);\n } else if (rejectMismatch) {\n cleanup();\n reject(new Error('message didnt match the filter'));\n }\n }\n\n t.addEventListener('message', onMessage);\n });\n}\n\nexport const testingSessionOptions = defaultTransportOptions;\nexport const testingClientSessionOptions = defaultClientTransportOptions;\n\nexport function dummySession() {\n return SessionStateGraph.entrypoints.NoConnection(\n 'client',\n 'server',\n {\n onSessionGracePeriodElapsed: () => {\n /* noop */\n },\n onMessageSendFailure: () => {\n /* noop */\n },\n },\n testingSessionOptions,\n currentProtocolVersion,\n getTracer(),\n );\n}\n\nexport function getClientSendFn(\n clientTransport: ClientTransport<Connection>,\n serverTransport: ServerTransport<Connection>,\n) {\n const session =\n clientTransport.sessions.get(serverTransport.clientId) ??\n clientTransport.createUnconnectedSession(serverTransport.clientId);\n\n return clientTransport.getSessionBoundSendFn(\n serverTransport.clientId,\n session.id,\n );\n}\n\nexport function getServerSendFn(\n serverTransport: ServerTransport<Connection>,\n clientTransport: ClientTransport<Connection>,\n) {\n const session = serverTransport.sessions.get(clientTransport.clientId);\n if (!session) {\n throw new Error('session not found');\n }\n\n return serverTransport.getSessionBoundSendFn(\n clientTransport.clientId,\n session.id,\n );\n}\n\nexport function getTransportConnections<ConnType extends Connection>(\n transport: Transport<ConnType>,\n): Array<ConnType> {\n const connections = [];\n for (const session of transport.sessions.values()) {\n if (session.state === SessionState.Connected) {\n connections.push(session.conn);\n }\n }\n\n return connections;\n}\n\nexport function numberOfConnections<ConnType extends Connection>(\n transport: Transport<ConnType>,\n): number {\n return getTransportConnections(transport).length;\n}\n\nexport function closeAllConnections<ConnType extends Connection>(\n transport: Transport<ConnType>,\n) {\n for (const conn of getTransportConnections(transport)) {\n conn.close();\n }\n}\n\n/**\n * Wraps a partial context object in a proxy that throws when accessing\n * properties that weren't provided. This is useful for test contexts where\n * you only want to mock the dependencies a test actually uses.\n *\n * Symbols and `then` are allowed through without throwing — river checks\n * for `Symbol.asyncDispose` / `Symbol.dispose` on context values during\n * `server.close()`, and `then` is checked by the JS runtime when the\n * proxy is returned from an async function.\n *\n * @example\n * ```ts\n * const ctx = createPartialContext<MyContext>({\n * database: mockDb,\n * // accessing ctx.redis will throw\n * });\n *\n * const server = createServer(transport, services, {\n * extendedContext: ctx,\n * });\n * ```\n */\nexport function createPartialContext<T extends Record<string, unknown>>(\n partial: Partial<T>,\n): T {\n return new Proxy(partial as T, {\n get(target, prop, receiver) {\n if (prop in target) {\n return Reflect.get(target, prop, receiver);\n }\n\n if (typeof prop === 'string' && prop !== 'then') {\n throw new Error(\n `${prop} is not mocked in the test context. Provide it via createPartialContext if your test needs it.`,\n );\n }\n\n return undefined;\n },\n });\n}\n","/**\n * Represents an observable value that can be subscribed to for changes.\n * This should only be used in tests\n * @template T - The type of the value being observed.\n */\nexport class Observable<T> {\n value: T;\n private listeners: Set<(val: T) => void>;\n\n constructor(initialValue: T) {\n this.value = initialValue;\n this.listeners = new Set();\n }\n\n /**\n * Gets the current value of the observable.\n */\n get() {\n return this.value;\n }\n\n /**\n * Sets the current value of the observable. All listeners will get an update with this value.\n * @param newValue - The new value to set.\n */\n set(tx: (preValue: T) => T) {\n const newValue = tx(this.value);\n this.value = newValue;\n this.listeners.forEach((listener) => listener(newValue));\n }\n\n /**\n * Subscribes to changes in the observable value.\n * @param listener - A callback function that will be called when the value changes.\n * @returns A function that can be called to unsubscribe from further notifications.\n */\n observe(listener: (val: T) => void) {\n this.listeners.add(listener);\n listener(this.get());\n\n return () => this.listeners.delete(listener);\n }\n\n /**\n * Returns the number of listeners currently observing the observable\n */\n get listenerCount(): number {\n return this.listeners.size;\n }\n}\n","import { Duplex } from 'node:stream';\nimport assert from 'assert';\n\nconst kCallback = Symbol('Callback');\nconst kInitOtherSide = Symbol('InitOtherSide');\n\n// yoinked from https://github.com/nodejs/node/blob/c3a7b29e56a5ada6327ebb622ba746d022685742/lib/internal/streams/duplexpair.js#L55\n// but with types\nclass DuplexSide extends Duplex {\n private otherSide: DuplexSide | null;\n private [kCallback]: (() => void) | null;\n\n constructor() {\n super();\n this[kCallback] = null;\n this.otherSide = null;\n }\n\n [kInitOtherSide](otherSide: DuplexSide) {\n if (this.otherSide === null) {\n this.otherSide = otherSide;\n }\n }\n\n _read() {\n const callback = this[kCallback];\n if (callback) {\n this[kCallback] = null;\n callback();\n }\n }\n\n _write(\n chunk: Uint8Array,\n _encoding: BufferEncoding,\n callback: (error?: Error | null) => void,\n ) {\n assert(this.otherSide !== null);\n assert(this.otherSide[kCallback] === null);\n if (chunk.length === 0) {\n process.nextTick(callback);\n } else {\n this.otherSide.push(chunk);\n this.otherSide[kCallback] = callback;\n }\n }\n\n _final(callback: (error?: Error | null) => void) {\n this.otherSide?.on('end', callback);\n this.otherSide?.push(null);\n }\n}\n\nexport function duplexPair(): [DuplexSide, DuplexSide] {\n const side0 = new DuplexSide();\n const side1 = new DuplexSide();\n side0[kInitOtherSide](side1);\n side1[kInitOtherSide](side0);\n side0.on('close', () => {\n setImmediate(() => {\n side1.destroy();\n });\n });\n\n side1.on('close', () => {\n setImmediate(() => {\n side0.destroy();\n });\n });\n\n return [side0, side1];\n}\n","import { Transport, TransportClientId } from '../../transport';\nimport { ClientTransport } from '../../transport/client';\nimport { Connection } from '../../transport/connection';\nimport { ServerTransport } from '../../transport/server';\nimport { Observable } from '../observable/observable';\nimport { ProvidedServerTransportOptions } from '../../transport/options';\nimport { TestSetupHelpers, TestTransportOptions } from './transports';\nimport { Duplex } from 'node:stream';\nimport { duplexPair } from '../duplex/duplexPair';\nimport { nanoid } from 'nanoid';\nimport { TSchema } from '@sinclair/typebox';\nimport { ServerHandshakeOptions } from '../../router/handshake';\n\nexport class InMemoryConnection extends Connection {\n conn: Duplex;\n\n constructor(pipe: Duplex) {\n super();\n this.conn = pipe;\n this.conn.allowHalfOpen = false;\n\n this.conn.on('data', (data: Uint8Array) => {\n this.dataListener?.(data);\n });\n\n this.conn.on('close', () => {\n this.closeListener?.();\n });\n\n this.conn.on('error', (err) => {\n this.errorListener?.(err);\n });\n }\n\n send(payload: Uint8Array): boolean {\n setImmediate(() => {\n this.conn.write(payload);\n });\n\n return true;\n }\n\n close(): void {\n setImmediate(() => {\n this.conn.end();\n this.conn.emit('close');\n });\n }\n}\n\ninterface BidiConnection {\n id: string;\n clientToServer: Duplex;\n serverToClient: Duplex;\n clientId: TransportClientId;\n serverId: TransportClientId;\n handled: boolean;\n}\n\n// we construct a network of transports connected by node streams here\n// so that we can test the transport layer without needing to actually\n// use real network/websocket connections\n// this is useful for testing the transport layer in isolation\n// and allows us to control network conditions in a way that would be\n// difficult with real network connections (e.g. simulating a phantom\n// disconnect, .pause() vs .removeAllListeners('data'), congestion,\n// latency, differences in ws implementations between node and browsers, etc.)\nexport function createMockTransportNetwork(\n opts?: TestTransportOptions,\n): TestSetupHelpers {\n // conn id -> [client->server, server->client]\n const connections = new Observable<Record<string, BidiConnection>>({});\n\n const transports: Array<Transport<InMemoryConnection>> = [];\n class MockClientTransport extends ClientTransport<InMemoryConnection> {\n async createNewOutgoingConnection(\n to: TransportClientId,\n ): Promise<InMemoryConnection> {\n const [clientToServer, serverToClient] = duplexPair();\n await new Promise((resolve) => setImmediate(resolve));\n\n const connId = nanoid();\n connections.set((prev) => ({\n ...prev,\n [connId]: {\n id: connId,\n clientToServer,\n serverToClient,\n clientId: this.clientId,\n serverId: to,\n handled: false,\n },\n }));\n\n return new InMemoryConnection(clientToServer);\n }\n }\n\n class MockServerTransport<\n MetadataSchema extends TSchema = TSchema,\n ParsedMetadata extends object = object,\n > extends ServerTransport<\n InMemoryConnection,\n MetadataSchema,\n ParsedMetadata\n > {\n subscribeCleanup: () => void;\n\n constructor(\n clientId: TransportClientId,\n options?: ProvidedServerTransportOptions,\n ) {\n super(clientId, options);\n\n this.subscribeCleanup = connections.observe((conns) => {\n // look for any unhandled connections\n for (const conn of Object.values(conns)) {\n // if we've already handled this connection, skip it\n // or if it's not for us, skip it\n if (conn.handled || conn.serverId !== this.clientId) {\n continue;\n }\n\n conn.handled = true;\n const connection = new InMemoryConnection(conn.serverToClient);\n this.handleConnection(connection);\n }\n });\n }\n\n close() {\n this.subscribeCleanup();\n super.close();\n }\n }\n\n return {\n getClientTransport: (id, handshakeOptions) => {\n const clientTransport = new MockClientTransport(id, opts?.client);\n if (handshakeOptions) {\n clientTransport.extendHandshake(handshakeOptions);\n }\n\n transports.push(clientTransport);\n\n return clientTransport;\n },\n getServerTransport: <\n MetadataSchema extends TSchema = TSchema,\n ParsedMetadata extends object = object,\n >(\n id = 'SERVER',\n handshakeOptions:\n | ServerHandshakeOptions<MetadataSchema, ParsedMetadata>\n | undefined,\n ) => {\n const serverTransport = new MockServerTransport<\n MetadataSchema,\n ParsedMetadata\n >(id, opts?.server);\n if (handshakeOptions) {\n serverTransport.extendHandshake(handshakeOptions);\n }\n\n transports.push(serverTransport);\n\n return serverTransport;\n },\n simulatePhantomDisconnect() {\n for (const conn of Object.values(connections.get())) {\n conn.serverToClient.pause();\n conn.clientToServer.pause();\n }\n },\n async restartServer() {\n for (const transport of transports) {\n if (transport.clientId !== 'SERVER') continue;\n transport.close();\n }\n\n // kill all connections while we're at it\n for (const conn of Object.values(connections.get())) {\n conn.serverToClient.destroy();\n conn.clientToServer.destroy();\n }\n },\n cleanup() {\n for (const conn of Object.values(connections.get())) {\n conn.serverToClient.destroy();\n conn.clientToServer.destroy();\n }\n },\n };\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../testUtil/index.ts","../../testUtil/observable/observable.ts","../../testUtil/duplex/duplexPair.ts","../../testUtil/fixtures/mockTransport.ts"],"sourcesContent":["import NodeWs, { WebSocketServer } from 'ws';\nimport http from 'node:http';\nimport type { Static } from 'typebox';\nimport {\n OpaqueTransportMessage,\n PartialTransportMessage,\n currentProtocolVersion,\n} from '../transport/message';\nimport { Transport } from '../transport/transport';\nimport { Readable, ReadableResult, ReadableIterator } from '../router/streams';\nimport { WsLike } from '../transport/impls/ws/wslike';\nimport {\n defaultClientTransportOptions,\n defaultTransportOptions,\n} from '../transport/options';\nimport { Connection } from '../transport/connection';\nimport { SessionState } from '../transport/sessionStateMachine/common';\nimport { SessionStateGraph } from '../transport/sessionStateMachine/transitions';\nimport { BaseErrorSchemaType } from '../router/errors';\nimport { ClientTransport } from '../transport/client';\nimport { ServerTransport } from '../transport/server';\nimport { getTracer } from '../tracing';\n\nexport {\n createMockTransportNetwork,\n InMemoryConnection,\n} from './fixtures/mockTransport';\n\n/**\n * Creates a WebSocket client that connects to a local server at the specified port.\n * This should only be used for testing.\n * @param port - The port number to connect to.\n * @returns A Promise that resolves to a WebSocket instance.\n */\nexport function createLocalWebSocketClient(port: number): WsLike {\n const sock = new NodeWs(`ws://localhost:${port}`);\n sock.binaryType = 'arraybuffer';\n\n return sock;\n}\n\n/**\n * Creates a WebSocket server instance using the provided HTTP server.\n * Only used as helper for testing.\n * @param server - The HTTP server instance to use for the WebSocket server.\n * @returns A Promise that resolves to the created WebSocket server instance.\n */\nexport function createWebSocketServer(server: http.Server) {\n return new WebSocketServer({ server });\n}\n\n/**\n * Starts listening on the given server and returns the automatically allocated port number.\n * This should only be used for testing.\n * @param server - The http server to listen on.\n * @returns A promise that resolves with the allocated port number.\n * @throws An error if a port cannot be allocated.\n */\nexport function onWsServerReady(server: http.Server): Promise<number> {\n return new Promise((resolve, reject) => {\n server.listen(() => {\n const addr = server.address();\n if (typeof addr === 'object' && addr) {\n resolve(addr.port);\n } else {\n reject(new Error(\"couldn't find a port to allocate\"));\n }\n });\n });\n}\n\nconst readableIterators = new WeakMap<\n Readable<unknown, Static<BaseErrorSchemaType>>,\n ReadableIterator<unknown, Static<BaseErrorSchemaType>>\n>();\n\n/**\n * A safe way to access {@link Readble}'s iterator multiple times in test helpers.\n *\n * If there are other iteration attempts outside of the test helpers\n * (this function, {@link readNextResult}, and {@link isReadableDone})\n * it will throw an error.\n */\nexport function getReadableIterator<T, E extends Static<BaseErrorSchemaType>>(\n readable: Readable<T, E>,\n): ReadableIterator<T, E> {\n let iter = readableIterators.get(readable) as\n | ReadableIterator<T, E>\n | undefined;\n\n if (!iter) {\n iter = readable[Symbol.asyncIterator]();\n readableIterators.set(readable, iter);\n }\n\n return iter;\n}\n\n/**\n * Retrieves the next value from {@link Readable}, or throws an error if the Readable is done.\n *\n * Calling semantics are similar to {@link getReadableIterator}\n */\nexport async function readNextResult<T, E extends Static<BaseErrorSchemaType>>(\n readable: Readable<T, E>,\n): Promise<ReadableResult<T, E>> {\n const res = await getReadableIterator(readable).next();\n\n if (res.done) {\n throw new Error('readNext from a done Readable');\n }\n\n return res.value;\n}\n\n/**\n * Checks if the readable is done iterating, it consumes an iteration in the process.\n *\n * Calling semantics are similar to {@link getReadableIterator}\n */\nexport async function isReadableDone<T, E extends Static<BaseErrorSchemaType>>(\n readable: Readable<T, E>,\n) {\n const res = await getReadableIterator(readable).next();\n\n return res.done;\n}\n\nexport function payloadToTransportMessage<Payload>(\n payload: Payload,\n): PartialTransportMessage<Payload> {\n return {\n streamId: 'stream',\n controlFlags: 0,\n payload,\n };\n}\n\nexport function createDummyTransportMessage() {\n return payloadToTransportMessage({\n msg: 'cool',\n test: Math.random(),\n });\n}\n\n/**\n * Waits for a message on the transport.\n * @param {Transport} t - The transport to listen to.\n * @param filter - An optional filter function to apply to the received messages.\n * @returns A promise that resolves with the payload of the first message that passes the filter.\n */\nexport async function waitForMessage(\n t: Transport<Connection>,\n filter?: (msg: OpaqueTransportMessage) => boolean,\n rejectMismatch?: boolean,\n) {\n return new Promise((resolve, reject) => {\n function cleanup() {\n t.removeEventListener('message', onMessage);\n }\n\n function onMessage(msg: OpaqueTransportMessage) {\n if (!filter || filter(msg)) {\n cleanup();\n resolve(msg.payload);\n } else if (rejectMismatch) {\n cleanup();\n reject(new Error('message didnt match the filter'));\n }\n }\n\n t.addEventListener('message', onMessage);\n });\n}\n\nexport const testingSessionOptions = defaultTransportOptions;\nexport const testingClientSessionOptions = defaultClientTransportOptions;\n\nexport function dummySession() {\n return SessionStateGraph.entrypoints.NoConnection(\n 'client',\n 'server',\n {\n onSessionGracePeriodElapsed: () => {\n /* noop */\n },\n onMessageSendFailure: () => {\n /* noop */\n },\n },\n testingSessionOptions,\n currentProtocolVersion,\n getTracer(),\n );\n}\n\nexport function getClientSendFn(\n clientTransport: ClientTransport<Connection>,\n serverTransport: ServerTransport<Connection>,\n) {\n const session =\n clientTransport.sessions.get(serverTransport.clientId) ??\n clientTransport.createUnconnectedSession(serverTransport.clientId);\n\n return clientTransport.getSessionBoundSendFn(\n serverTransport.clientId,\n session.id,\n );\n}\n\nexport function getServerSendFn(\n serverTransport: ServerTransport<Connection>,\n clientTransport: ClientTransport<Connection>,\n) {\n const session = serverTransport.sessions.get(clientTransport.clientId);\n if (!session) {\n throw new Error('session not found');\n }\n\n return serverTransport.getSessionBoundSendFn(\n clientTransport.clientId,\n session.id,\n );\n}\n\nexport function getTransportConnections<ConnType extends Connection>(\n transport: Transport<ConnType>,\n): Array<ConnType> {\n const connections = [];\n for (const session of transport.sessions.values()) {\n if (session.state === SessionState.Connected) {\n connections.push(session.conn);\n }\n }\n\n return connections;\n}\n\nexport function numberOfConnections<ConnType extends Connection>(\n transport: Transport<ConnType>,\n): number {\n return getTransportConnections(transport).length;\n}\n\nexport function closeAllConnections<ConnType extends Connection>(\n transport: Transport<ConnType>,\n) {\n for (const conn of getTransportConnections(transport)) {\n conn.close();\n }\n}\n\n/**\n * Wraps a partial context object in a proxy that throws when accessing\n * properties that weren't provided. This is useful for test contexts where\n * you only want to mock the dependencies a test actually uses.\n *\n * Symbols and `then` are allowed through without throwing — river checks\n * for `Symbol.asyncDispose` / `Symbol.dispose` on context values during\n * `server.close()`, and `then` is checked by the JS runtime when the\n * proxy is returned from an async function.\n *\n * @example\n * ```ts\n * const ctx = createPartialContext<MyContext>({\n * database: mockDb,\n * // accessing ctx.redis will throw\n * });\n *\n * const server = createServer(transport, services, {\n * extendedContext: ctx,\n * });\n * ```\n */\nexport function createPartialContext<T extends Record<string, unknown>>(\n partial: Partial<T>,\n): T {\n return new Proxy(partial as T, {\n get(target, prop, receiver) {\n if (prop in target) {\n return Reflect.get(target, prop, receiver);\n }\n\n if (typeof prop === 'string' && prop !== 'then') {\n throw new Error(\n `${prop} is not mocked in the test context. Provide it via createPartialContext if your test needs it.`,\n );\n }\n\n return undefined;\n },\n });\n}\n","/**\n * Represents an observable value that can be subscribed to for changes.\n * This should only be used in tests\n * @template T - The type of the value being observed.\n */\nexport class Observable<T> {\n value: T;\n private listeners: Set<(val: T) => void>;\n\n constructor(initialValue: T) {\n this.value = initialValue;\n this.listeners = new Set();\n }\n\n /**\n * Gets the current value of the observable.\n */\n get() {\n return this.value;\n }\n\n /**\n * Sets the current value of the observable. All listeners will get an update with this value.\n * @param newValue - The new value to set.\n */\n set(tx: (preValue: T) => T) {\n const newValue = tx(this.value);\n this.value = newValue;\n this.listeners.forEach((listener) => listener(newValue));\n }\n\n /**\n * Subscribes to changes in the observable value.\n * @param listener - A callback function that will be called when the value changes.\n * @returns A function that can be called to unsubscribe from further notifications.\n */\n observe(listener: (val: T) => void) {\n this.listeners.add(listener);\n listener(this.get());\n\n return () => this.listeners.delete(listener);\n }\n\n /**\n * Returns the number of listeners currently observing the observable\n */\n get listenerCount(): number {\n return this.listeners.size;\n }\n}\n","import { Duplex } from 'node:stream';\nimport assert from 'assert';\n\nconst kCallback = Symbol('Callback');\nconst kInitOtherSide = Symbol('InitOtherSide');\n\n// yoinked from https://github.com/nodejs/node/blob/c3a7b29e56a5ada6327ebb622ba746d022685742/lib/internal/streams/duplexpair.js#L55\n// but with types\nclass DuplexSide extends Duplex {\n private otherSide: DuplexSide | null;\n private [kCallback]: (() => void) | null;\n\n constructor() {\n super();\n this[kCallback] = null;\n this.otherSide = null;\n }\n\n [kInitOtherSide](otherSide: DuplexSide) {\n if (this.otherSide === null) {\n this.otherSide = otherSide;\n }\n }\n\n _read() {\n const callback = this[kCallback];\n if (callback) {\n this[kCallback] = null;\n callback();\n }\n }\n\n _write(\n chunk: Uint8Array,\n _encoding: BufferEncoding,\n callback: (error?: Error | null) => void,\n ) {\n assert(this.otherSide !== null);\n assert(this.otherSide[kCallback] === null);\n if (chunk.length === 0) {\n process.nextTick(callback);\n } else {\n this.otherSide.push(chunk);\n this.otherSide[kCallback] = callback;\n }\n }\n\n _final(callback: (error?: Error | null) => void) {\n this.otherSide?.on('end', callback);\n this.otherSide?.push(null);\n }\n}\n\nexport function duplexPair(): [DuplexSide, DuplexSide] {\n const side0 = new DuplexSide();\n const side1 = new DuplexSide();\n side0[kInitOtherSide](side1);\n side1[kInitOtherSide](side0);\n side0.on('close', () => {\n setImmediate(() => {\n side1.destroy();\n });\n });\n\n side1.on('close', () => {\n setImmediate(() => {\n side0.destroy();\n });\n });\n\n return [side0, side1];\n}\n","import { Transport, TransportClientId } from '../../transport';\nimport { ClientTransport } from '../../transport/client';\nimport { Connection } from '../../transport/connection';\nimport { ServerTransport } from '../../transport/server';\nimport { Observable } from '../observable/observable';\nimport { ProvidedServerTransportOptions } from '../../transport/options';\nimport { TestSetupHelpers, TestTransportOptions } from './transports';\nimport { Duplex } from 'node:stream';\nimport { duplexPair } from '../duplex/duplexPair';\nimport { nanoid } from 'nanoid';\nimport type { TSchema } from 'typebox';\nimport { ServerHandshakeOptions } from '../../router/handshake';\n\nexport class InMemoryConnection extends Connection {\n conn: Duplex;\n\n constructor(pipe: Duplex) {\n super();\n this.conn = pipe;\n this.conn.allowHalfOpen = false;\n\n this.conn.on('data', (data: Uint8Array) => {\n this.dataListener?.(data);\n });\n\n this.conn.on('close', () => {\n this.closeListener?.();\n });\n\n this.conn.on('error', (err) => {\n this.errorListener?.(err);\n });\n }\n\n send(payload: Uint8Array): boolean {\n setImmediate(() => {\n this.conn.write(payload);\n });\n\n return true;\n }\n\n close(): void {\n setImmediate(() => {\n this.conn.end();\n this.conn.emit('close');\n });\n }\n}\n\ninterface BidiConnection {\n id: string;\n clientToServer: Duplex;\n serverToClient: Duplex;\n clientId: TransportClientId;\n serverId: TransportClientId;\n handled: boolean;\n}\n\n// we construct a network of transports connected by node streams here\n// so that we can test the transport layer without needing to actually\n// use real network/websocket connections\n// this is useful for testing the transport layer in isolation\n// and allows us to control network conditions in a way that would be\n// difficult with real network connections (e.g. simulating a phantom\n// disconnect, .pause() vs .removeAllListeners('data'), congestion,\n// latency, differences in ws implementations between node and browsers, etc.)\nexport function createMockTransportNetwork(\n opts?: TestTransportOptions,\n): TestSetupHelpers {\n // conn id -> [client->server, server->client]\n const connections = new Observable<Record<string, BidiConnection>>({});\n\n const transports: Array<Transport<InMemoryConnection>> = [];\n class MockClientTransport extends ClientTransport<InMemoryConnection> {\n async createNewOutgoingConnection(\n to: TransportClientId,\n ): Promise<InMemoryConnection> {\n const [clientToServer, serverToClient] = duplexPair();\n await new Promise((resolve) => setImmediate(resolve));\n\n const connId = nanoid();\n connections.set((prev) => ({\n ...prev,\n [connId]: {\n id: connId,\n clientToServer,\n serverToClient,\n clientId: this.clientId,\n serverId: to,\n handled: false,\n },\n }));\n\n return new InMemoryConnection(clientToServer);\n }\n }\n\n class MockServerTransport<\n MetadataSchema extends TSchema = TSchema,\n ParsedMetadata extends object = object,\n > extends ServerTransport<\n InMemoryConnection,\n MetadataSchema,\n ParsedMetadata\n > {\n subscribeCleanup: () => void;\n\n constructor(\n clientId: TransportClientId,\n options?: ProvidedServerTransportOptions,\n ) {\n super(clientId, options);\n\n this.subscribeCleanup = connections.observe((conns) => {\n // look for any unhandled connections\n for (const conn of Object.values(conns)) {\n // if we've already handled this connection, skip it\n // or if it's not for us, skip it\n if (conn.handled || conn.serverId !== this.clientId) {\n continue;\n }\n\n conn.handled = true;\n const connection = new InMemoryConnection(conn.serverToClient);\n this.handleConnection(connection);\n }\n });\n }\n\n close() {\n this.subscribeCleanup();\n super.close();\n }\n }\n\n return {\n getClientTransport: (id, handshakeOptions) => {\n const clientTransport = new MockClientTransport(id, opts?.client);\n if (handshakeOptions) {\n clientTransport.extendHandshake(handshakeOptions);\n }\n\n transports.push(clientTransport);\n\n return clientTransport;\n },\n getServerTransport: <\n MetadataSchema extends TSchema = TSchema,\n ParsedMetadata extends object = object,\n >(\n id = 'SERVER',\n handshakeOptions:\n | ServerHandshakeOptions<MetadataSchema, ParsedMetadata>\n | undefined,\n ) => {\n const serverTransport = new MockServerTransport<\n MetadataSchema,\n ParsedMetadata\n >(id, opts?.server);\n if (handshakeOptions) {\n serverTransport.extendHandshake(handshakeOptions);\n }\n\n transports.push(serverTransport);\n\n return serverTransport;\n },\n simulatePhantomDisconnect() {\n for (const conn of Object.values(connections.get())) {\n conn.serverToClient.pause();\n conn.clientToServer.pause();\n }\n },\n async restartServer() {\n for (const transport of transports) {\n if (transport.clientId !== 'SERVER') continue;\n transport.close();\n }\n\n // kill all connections while we're at it\n for (const conn of Object.values(connections.get())) {\n conn.serverToClient.destroy();\n conn.clientToServer.destroy();\n }\n },\n cleanup() {\n for (const conn of Object.values(connections.get())) {\n conn.serverToClient.destroy();\n conn.clientToServer.destroy();\n }\n },\n };\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { C as ClientTransport } from '../../../client-
|
|
2
|
-
import { T as TransportClientId } from '../../../message-
|
|
3
|
-
import { P as ProvidedClientTransportOptions } from '../../../transport-
|
|
4
|
-
import { a as WebSocketConnection } from '../../../connection-
|
|
1
|
+
import { C as ClientTransport } from '../../../client-YP9bECp8.js';
|
|
2
|
+
import { T as TransportClientId } from '../../../message-DxS8db8A.js';
|
|
3
|
+
import { P as ProvidedClientTransportOptions } from '../../../transport-CUpXnch7.js';
|
|
4
|
+
import { a as WebSocketConnection } from '../../../connection-D_HE_YQB.js';
|
|
5
5
|
import { W as WsLike } from '../../../wslike-Dng9H1C7.js';
|
|
6
|
-
import '
|
|
6
|
+
import 'typebox';
|
|
7
7
|
import '@opentelemetry/api';
|
|
8
|
-
import '../../../index-
|
|
8
|
+
import '../../../index-DgUMnNOi.js';
|
|
9
9
|
import '../../../types-BGGvYIJM.js';
|
|
10
|
-
import '../../../adapter-
|
|
10
|
+
import '../../../adapter-Dl5Mewp3.js';
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* A transport implementation that uses a WebSocket connection with automatic reconnection.
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ClientTransport,
|
|
3
3
|
WebSocketConnection
|
|
4
|
-
} from "../../../chunk-
|
|
4
|
+
} from "../../../chunk-VK3VJZGG.js";
|
|
5
5
|
import "../../../chunk-CC7RN7GI.js";
|
|
6
|
-
import "../../../chunk-
|
|
6
|
+
import "../../../chunk-JFFRB3SS.js";
|
|
7
7
|
|
|
8
8
|
// transport/impls/ws/client.ts
|
|
9
9
|
var WebSocketClientTransport = class extends ClientTransport {
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import { T as TransportClientId } from '../../../message-
|
|
1
|
+
import { T as TransportClientId } from '../../../message-DxS8db8A.js';
|
|
2
2
|
import { WebSocketServer } from 'ws';
|
|
3
|
-
import { a as WebSocketConnection } from '../../../connection-
|
|
3
|
+
import { a as WebSocketConnection } from '../../../connection-D_HE_YQB.js';
|
|
4
4
|
import { W as WsLike } from '../../../wslike-Dng9H1C7.js';
|
|
5
|
-
import { S as ServerTransport } from '../../../server-
|
|
6
|
-
import { e as ProvidedServerTransportOptions } from '../../../transport-
|
|
5
|
+
import { S as ServerTransport } from '../../../server-BfM3_JLq.js';
|
|
6
|
+
import { e as ProvidedServerTransportOptions } from '../../../transport-CUpXnch7.js';
|
|
7
7
|
import { IncomingMessage } from 'http';
|
|
8
|
-
import { TSchema } from '
|
|
8
|
+
import { TSchema } from 'typebox';
|
|
9
9
|
import '@opentelemetry/api';
|
|
10
|
-
import '../../../index-
|
|
11
|
-
import '../../../adapter-
|
|
10
|
+
import '../../../index-DgUMnNOi.js';
|
|
11
|
+
import '../../../adapter-Dl5Mewp3.js';
|
|
12
12
|
import '../../../types-BGGvYIJM.js';
|
|
13
13
|
|
|
14
14
|
declare class WebSocketServerTransport<MetadataSchema extends TSchema = TSchema, ParsedMetadata extends object = object> extends ServerTransport<WebSocketConnection, MetadataSchema, ParsedMetadata> {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ServerTransport,
|
|
3
3
|
WebSocketConnection
|
|
4
|
-
} from "../../../chunk-
|
|
4
|
+
} from "../../../chunk-VK3VJZGG.js";
|
|
5
5
|
import "../../../chunk-CC7RN7GI.js";
|
|
6
|
-
import "../../../chunk-
|
|
6
|
+
import "../../../chunk-JFFRB3SS.js";
|
|
7
7
|
|
|
8
8
|
// transport/impls/ws/server.ts
|
|
9
9
|
function cleanHeaders(headers) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../transport/impls/ws/server.ts"],"sourcesContent":["import { TransportClientId } from '../../message';\nimport { WebSocketServer } from 'ws';\nimport { WebSocketConnection } from './connection';\nimport { WsLike } from './wslike';\nimport { ServerTransport } from '../../server';\nimport { ProvidedServerTransportOptions } from '../../options';\nimport { type IncomingMessage } from 'http';\nimport { TSchema } from '
|
|
1
|
+
{"version":3,"sources":["../../../../transport/impls/ws/server.ts"],"sourcesContent":["import { TransportClientId } from '../../message';\nimport { WebSocketServer } from 'ws';\nimport { WebSocketConnection } from './connection';\nimport { WsLike } from './wslike';\nimport { ServerTransport } from '../../server';\nimport { ProvidedServerTransportOptions } from '../../options';\nimport { type IncomingMessage } from 'http';\nimport type { TSchema } from 'typebox';\n\nfunction cleanHeaders(\n headers: IncomingMessage['headers'],\n): Record<string, string> {\n const cleanedHeaders: Record<string, string> = {};\n\n for (const [key, value] of Object.entries(headers)) {\n if (!key.startsWith('sec-') && value) {\n const cleanedValue = Array.isArray(value) ? value[0] : value;\n cleanedHeaders[key] = cleanedValue;\n }\n }\n\n return cleanedHeaders;\n}\n\nexport class WebSocketServerTransport<\n MetadataSchema extends TSchema = TSchema,\n ParsedMetadata extends object = object,\n> extends ServerTransport<WebSocketConnection, MetadataSchema, ParsedMetadata> {\n wss: WebSocketServer;\n\n constructor(\n wss: WebSocketServer,\n clientId: TransportClientId,\n providedOptions?: ProvidedServerTransportOptions,\n ) {\n super(clientId, providedOptions);\n this.wss = wss;\n this.wss.on('connection', this.connectionHandler);\n }\n\n connectionHandler = (ws: WsLike, req: IncomingMessage) => {\n const conn = new WebSocketConnection(ws, {\n headers: cleanHeaders(req.headersDistinct),\n });\n\n this.handleConnection(conn);\n };\n\n close() {\n super.close();\n this.wss.off('connection', this.connectionHandler);\n }\n}\n"],"mappings":";;;;;;;;AASA,SAAS,aACP,SACwB;AACxB,QAAM,iBAAyC,CAAC;AAEhD,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,OAAO,GAAG;AAClD,QAAI,CAAC,IAAI,WAAW,MAAM,KAAK,OAAO;AACpC,YAAM,eAAe,MAAM,QAAQ,KAAK,IAAI,MAAM,CAAC,IAAI;AACvD,qBAAe,GAAG,IAAI;AAAA,IACxB;AAAA,EACF;AAEA,SAAO;AACT;AAEO,IAAM,2BAAN,cAGG,gBAAqE;AAAA,EAC7E;AAAA,EAEA,YACE,KACA,UACA,iBACA;AACA,UAAM,UAAU,eAAe;AAC/B,SAAK,MAAM;AACX,SAAK,IAAI,GAAG,cAAc,KAAK,iBAAiB;AAAA,EAClD;AAAA,EAEA,oBAAoB,CAAC,IAAY,QAAyB;AACxD,UAAM,OAAO,IAAI,oBAAoB,IAAI;AAAA,MACvC,SAAS,aAAa,IAAI,eAAe;AAAA,IAC3C,CAAC;AAED,SAAK,iBAAiB,IAAI;AAAA,EAC5B;AAAA,EAEA,QAAQ;AACN,UAAM,MAAM;AACZ,SAAK,IAAI,IAAI,cAAc,KAAK,iBAAiB;AAAA,EACnD;AACF;","names":[]}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
export { P as ClientTransportOptions, C as Connection, E as EventHandler, a as EventMap, b as EventTypes, c as ProtocolError, d as ProtocolErrorType, e as ServerTransportOptions, S as Session, f as SessionConnected, g as SessionConnecting, h as SessionHandshaking, i as SessionNoConnection, j as SessionState, T as Transport, k as TransportOptions, l as TransportStatus } from '../transport-
|
|
2
|
-
export { C as ClientTransport } from '../client-
|
|
3
|
-
export { S as ServerTransport, a as SessionWaitingForHandshake } from '../server-
|
|
4
|
-
export { W as WebSocketCloseError, a as WebSocketConnection } from '../connection-
|
|
5
|
-
export { O as OpaqueTransportMessage, a as OpaqueTransportMessageSchema, T as TransportClientId, b as TransportMessage, c as TransportMessageSchema, i as isStreamClose, d as isStreamOpen } from '../message-
|
|
6
|
-
import '
|
|
7
|
-
import '../index-
|
|
1
|
+
export { P as ClientTransportOptions, C as Connection, E as EventHandler, a as EventMap, b as EventTypes, c as ProtocolError, d as ProtocolErrorType, e as ServerTransportOptions, S as Session, f as SessionConnected, g as SessionConnecting, h as SessionHandshaking, i as SessionNoConnection, j as SessionState, T as Transport, k as TransportOptions, l as TransportStatus } from '../transport-CUpXnch7.js';
|
|
2
|
+
export { C as ClientTransport } from '../client-YP9bECp8.js';
|
|
3
|
+
export { S as ServerTransport, a as SessionWaitingForHandshake } from '../server-BfM3_JLq.js';
|
|
4
|
+
export { W as WebSocketCloseError, a as WebSocketConnection } from '../connection-D_HE_YQB.js';
|
|
5
|
+
export { O as OpaqueTransportMessage, a as OpaqueTransportMessageSchema, T as TransportClientId, b as TransportMessage, c as TransportMessageSchema, i as isStreamClose, d as isStreamOpen } from '../message-DxS8db8A.js';
|
|
6
|
+
import 'typebox';
|
|
7
|
+
import '../index-DgUMnNOi.js';
|
|
8
8
|
import '../types-BGGvYIJM.js';
|
|
9
|
-
import '../adapter-
|
|
9
|
+
import '../adapter-Dl5Mewp3.js';
|
|
10
10
|
import '@opentelemetry/api';
|
|
11
11
|
import '../wslike-Dng9H1C7.js';
|
package/dist/transport/index.js
CHANGED
|
@@ -7,12 +7,12 @@ import {
|
|
|
7
7
|
Transport,
|
|
8
8
|
WebSocketCloseError,
|
|
9
9
|
WebSocketConnection
|
|
10
|
-
} from "../chunk-
|
|
10
|
+
} from "../chunk-VK3VJZGG.js";
|
|
11
11
|
import "../chunk-CC7RN7GI.js";
|
|
12
12
|
import {
|
|
13
13
|
OpaqueTransportMessageSchema,
|
|
14
14
|
TransportMessageSchema
|
|
15
|
-
} from "../chunk-
|
|
15
|
+
} from "../chunk-JFFRB3SS.js";
|
|
16
16
|
export {
|
|
17
17
|
ClientTransport,
|
|
18
18
|
Connection,
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { TSchema, Static } from '
|
|
2
|
-
import { T as TransportClientId, g as TelemetryInfo, P as ProtocolVersion, e as PartialTransportMessage, E as EncodedTransportMessage, f as HandshakeErrorCustomHandlerFatalResponseCodes, O as OpaqueTransportMessage, H as HandshakeErrorResponseCodes, b as TransportMessage } from './message-
|
|
3
|
-
import { L as Logger, M as MessageMetadata, T as Tags, a as LogFn, b as LoggingLevel } from './index-
|
|
1
|
+
import { TSchema, Static } from 'typebox';
|
|
2
|
+
import { T as TransportClientId, g as TelemetryInfo, P as ProtocolVersion, e as PartialTransportMessage, E as EncodedTransportMessage, f as HandshakeErrorCustomHandlerFatalResponseCodes, O as OpaqueTransportMessage, H as HandshakeErrorResponseCodes, b as TransportMessage } from './message-DxS8db8A.js';
|
|
3
|
+
import { L as Logger, M as MessageMetadata, T as Tags, a as LogFn, b as LoggingLevel } from './index-DgUMnNOi.js';
|
|
4
4
|
import { C as Codec } from './types-BGGvYIJM.js';
|
|
5
|
-
import { C as CodecMessageAdapter, E as EncodeResult, S as SendResult, a as SendBufferResult } from './adapter-
|
|
5
|
+
import { C as CodecMessageAdapter, E as EncodeResult, S as SendResult, a as SendBufferResult } from './adapter-Dl5Mewp3.js';
|
|
6
6
|
import { Tracer } from '@opentelemetry/api';
|
|
7
7
|
|
|
8
8
|
declare const enum SessionState {
|
package/package.json
CHANGED
|
@@ -1,45 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@replit/river",
|
|
3
3
|
"description": "It's like tRPC but... with JSON Schema Support, duplex streaming and support for service multiplexing. Transport agnostic!",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.217.1",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
7
|
-
".":
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
"./
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
"./
|
|
16
|
-
|
|
17
|
-
"require": "./dist/protobuf/index.cjs"
|
|
18
|
-
},
|
|
19
|
-
"./protobuf/codec": {
|
|
20
|
-
"import": "./dist/protobuf/codec.js",
|
|
21
|
-
"require": "./dist/protobuf/codec.cjs"
|
|
22
|
-
},
|
|
23
|
-
"./codec": {
|
|
24
|
-
"import": "./dist/codec/index.js",
|
|
25
|
-
"require": "./dist/codec/index.cjs"
|
|
26
|
-
},
|
|
27
|
-
"./transport": {
|
|
28
|
-
"import": "./dist/transport/index.js",
|
|
29
|
-
"require": "./dist/transport/index.cjs"
|
|
30
|
-
},
|
|
31
|
-
"./transport/ws/client": {
|
|
32
|
-
"import": "./dist/transport/impls/ws/client.js",
|
|
33
|
-
"require": "./dist/transport/impls/ws/client.cjs"
|
|
34
|
-
},
|
|
35
|
-
"./transport/ws/server": {
|
|
36
|
-
"import": "./dist/transport/impls/ws/server.js",
|
|
37
|
-
"require": "./dist/transport/impls/ws/server.cjs"
|
|
38
|
-
},
|
|
39
|
-
"./test-util": {
|
|
40
|
-
"import": "./dist/testUtil/index.js",
|
|
41
|
-
"require": "./dist/testUtil/index.cjs"
|
|
42
|
-
}
|
|
7
|
+
".": "./dist/router/index.js",
|
|
8
|
+
"./logging": "./dist/logging/index.js",
|
|
9
|
+
"./protobuf": "./dist/protobuf/index.js",
|
|
10
|
+
"./protobuf/codec": "./dist/protobuf/codec.js",
|
|
11
|
+
"./codec": "./dist/codec/index.js",
|
|
12
|
+
"./transport": "./dist/transport/index.js",
|
|
13
|
+
"./transport/ws/client": "./dist/transport/impls/ws/client.js",
|
|
14
|
+
"./transport/ws/server": "./dist/transport/impls/ws/server.js",
|
|
15
|
+
"./test-util": "./dist/testUtil/index.js",
|
|
16
|
+
"./customSchemas": "./dist/customSchemas/index.js"
|
|
43
17
|
},
|
|
44
18
|
"sideEffects": [
|
|
45
19
|
"./dist/logging/index.js"
|
|
@@ -55,7 +29,7 @@
|
|
|
55
29
|
},
|
|
56
30
|
"peerDependencies": {
|
|
57
31
|
"@opentelemetry/api": "^1.7.0",
|
|
58
|
-
"
|
|
32
|
+
"typebox": "^1.1.0"
|
|
59
33
|
},
|
|
60
34
|
"devDependencies": {
|
|
61
35
|
"@bufbuild/buf": "^1.67.0",
|
|
@@ -63,7 +37,6 @@
|
|
|
63
37
|
"@opentelemetry/context-async-hooks": "^1.26.0",
|
|
64
38
|
"@opentelemetry/core": "^1.7.0",
|
|
65
39
|
"@opentelemetry/sdk-trace-base": "^1.24.1",
|
|
66
|
-
"@sinclair/typebox": "~0.34.0",
|
|
67
40
|
"@stylistic/eslint-plugin": "^2.6.4",
|
|
68
41
|
"@types/ws": "^8.5.5",
|
|
69
42
|
"@typescript-eslint/eslint-plugin": "^7.8.0",
|
|
@@ -72,8 +45,10 @@
|
|
|
72
45
|
"eslint": "^8.57.0",
|
|
73
46
|
"eslint-config-prettier": "^9.1.0",
|
|
74
47
|
"eslint-plugin-prettier": "^5.1.3",
|
|
48
|
+
"legacyTypebox": "npm:@sinclair/typebox@^0.34.49",
|
|
75
49
|
"prettier": "^3.0.0",
|
|
76
50
|
"tsup": "^8.4.0",
|
|
51
|
+
"typebox": "^1.1.38",
|
|
77
52
|
"typescript": "^5.4.5",
|
|
78
53
|
"vitest": "^3.1.1"
|
|
79
54
|
},
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { O as OpaqueTransportMessage, E as EncodedTransportMessage } from './message-CpXWqmJw.cjs';
|
|
2
|
-
import { C as Codec } from './types-BGGvYIJM.cjs';
|
|
3
|
-
|
|
4
|
-
type SessionApiResult<T> = {
|
|
5
|
-
ok: true;
|
|
6
|
-
value: T;
|
|
7
|
-
} | {
|
|
8
|
-
ok: false;
|
|
9
|
-
reason: string;
|
|
10
|
-
};
|
|
11
|
-
type SendResult = SessionApiResult<string>;
|
|
12
|
-
type SendBufferResult = SessionApiResult<undefined>;
|
|
13
|
-
type EncodeResult = SessionApiResult<EncodedTransportMessage>;
|
|
14
|
-
type SerializeResult = SessionApiResult<Uint8Array>;
|
|
15
|
-
type DeserializeResult = SessionApiResult<OpaqueTransportMessage>;
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Adapts a {@link Codec} to the {@link OpaqueTransportMessage} format,
|
|
19
|
-
* accounting for fallibility of toBuffer and fromBuffer and wrapping
|
|
20
|
-
* it with a Result type.
|
|
21
|
-
*/
|
|
22
|
-
declare class CodecMessageAdapter {
|
|
23
|
-
private readonly codec;
|
|
24
|
-
constructor(codec: Codec);
|
|
25
|
-
toBuffer(msg: OpaqueTransportMessage): SerializeResult;
|
|
26
|
-
fromBuffer(buf: Uint8Array): DeserializeResult;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export { CodecMessageAdapter as C, type EncodeResult as E, type SendResult as S, type SendBufferResult as a };
|