@replit/river 0.23.18 → 0.24.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 +17 -16
- package/dist/chunk-227EQHH5.js +653 -0
- package/dist/chunk-227EQHH5.js.map +1 -0
- package/dist/chunk-6YFPHVNO.js +277 -0
- package/dist/chunk-6YFPHVNO.js.map +1 -0
- package/dist/{chunk-7MJYOL32.js → chunk-BGJDNLTJ.js} +15 -23
- package/dist/chunk-BGJDNLTJ.js.map +1 -0
- package/dist/chunk-HXOQQXL4.js +382 -0
- package/dist/chunk-HXOQQXL4.js.map +1 -0
- package/dist/{chunk-R2HAS3GM.js → chunk-IYYQ7BII.js} +55 -41
- package/dist/chunk-IYYQ7BII.js.map +1 -0
- package/dist/{chunk-AVL32IMG.js → chunk-L664A3WA.js} +20 -16
- package/dist/chunk-L664A3WA.js.map +1 -0
- package/dist/{chunk-EV5HW4IC.js → chunk-M7E6LQO2.js} +66 -53
- package/dist/chunk-M7E6LQO2.js.map +1 -0
- package/dist/{chunk-6LCL2ZZF.js → chunk-TAH2GVTJ.js} +1 -1
- package/dist/chunk-TAH2GVTJ.js.map +1 -0
- package/dist/chunk-XOFF3UPL.js +399 -0
- package/dist/chunk-XOFF3UPL.js.map +1 -0
- package/dist/{client-5776a6bb.d.ts → client-2ba72e89.d.ts} +12 -15
- package/dist/connection-55cba970.d.ts +11 -0
- package/dist/{connection-bd35d442.d.ts → connection-c6db05d9.d.ts} +1 -5
- package/dist/{handshake-a947c234.d.ts → handshake-0b88e8fc.d.ts} +150 -184
- package/dist/logging/index.cjs.map +1 -1
- package/dist/logging/index.d.cts +1 -1
- package/dist/logging/index.d.ts +1 -1
- package/dist/logging/index.js +1 -1
- package/dist/{index-ea74cdbb.d.ts → message-e6c560fd.d.ts} +2 -2
- package/dist/router/index.cjs +105 -63
- package/dist/router/index.cjs.map +1 -1
- package/dist/router/index.d.cts +11 -10
- package/dist/router/index.d.ts +11 -10
- package/dist/router/index.js +2 -2
- package/dist/server-732e7014.d.ts +42 -0
- package/dist/{services-38b3f758.d.ts → services-adfd0bc3.d.ts} +3 -3
- package/dist/transport/impls/uds/client.cjs +1246 -1230
- package/dist/transport/impls/uds/client.cjs.map +1 -1
- package/dist/transport/impls/uds/client.d.cts +4 -4
- package/dist/transport/impls/uds/client.d.ts +4 -4
- package/dist/transport/impls/uds/client.js +7 -13
- package/dist/transport/impls/uds/client.js.map +1 -1
- package/dist/transport/impls/uds/server.cjs +1298 -1151
- package/dist/transport/impls/uds/server.cjs.map +1 -1
- package/dist/transport/impls/uds/server.d.cts +4 -4
- package/dist/transport/impls/uds/server.d.ts +4 -4
- package/dist/transport/impls/uds/server.js +6 -6
- package/dist/transport/impls/ws/client.cjs +976 -965
- package/dist/transport/impls/ws/client.cjs.map +1 -1
- package/dist/transport/impls/ws/client.d.cts +4 -4
- package/dist/transport/impls/ws/client.d.ts +4 -4
- package/dist/transport/impls/ws/client.js +6 -7
- package/dist/transport/impls/ws/client.js.map +1 -1
- package/dist/transport/impls/ws/server.cjs +1182 -1047
- package/dist/transport/impls/ws/server.cjs.map +1 -1
- package/dist/transport/impls/ws/server.d.cts +4 -4
- package/dist/transport/impls/ws/server.d.ts +4 -4
- package/dist/transport/impls/ws/server.js +6 -6
- package/dist/transport/index.cjs +1433 -1360
- package/dist/transport/index.cjs.map +1 -1
- package/dist/transport/index.d.cts +5 -5
- package/dist/transport/index.d.ts +5 -5
- package/dist/transport/index.js +9 -9
- package/dist/util/testHelpers.cjs +744 -310
- package/dist/util/testHelpers.cjs.map +1 -1
- package/dist/util/testHelpers.d.cts +9 -6
- package/dist/util/testHelpers.d.ts +9 -6
- package/dist/util/testHelpers.js +34 -10
- package/dist/util/testHelpers.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-6LCL2ZZF.js.map +0 -1
- package/dist/chunk-7MJYOL32.js.map +0 -1
- package/dist/chunk-AVL32IMG.js.map +0 -1
- package/dist/chunk-DPKOJQWF.js +0 -476
- package/dist/chunk-DPKOJQWF.js.map +0 -1
- package/dist/chunk-EV5HW4IC.js.map +0 -1
- package/dist/chunk-J6N6H2WU.js +0 -476
- package/dist/chunk-J6N6H2WU.js.map +0 -1
- package/dist/chunk-MW5JXLHY.js +0 -348
- package/dist/chunk-MW5JXLHY.js.map +0 -1
- package/dist/chunk-R2HAS3GM.js.map +0 -1
- package/dist/chunk-RJOWZIWB.js +0 -335
- package/dist/chunk-RJOWZIWB.js.map +0 -1
- package/dist/connection-df85db7e.d.ts +0 -17
- package/dist/server-53cd5b7e.d.ts +0 -24
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../transport/id.ts","../transport/message.ts","../package.json","../util/stringify.ts","../tracing/index.ts"],"sourcesContent":["import { customAlphabet } from 'nanoid';\n\nconst alphabet = customAlphabet(\n '1234567890abcdefghijklmnopqrstuvxyzABCDEFGHIJKLMNOPQRSTUVXYZ',\n);\nexport const generateId = () => alphabet(12);\n","import { Type, TSchema, Static } from '@sinclair/typebox';\nimport { PropagationContext } from '../tracing';\nimport { generateId } from './id';\n\n/**\n * Control flags for transport messages.\n * An RPC message is coded with StreamOpenBit | StreamClosedBit.\n * Streams are expected to start with StreamOpenBit sent and the client SHOULD send an empty\n * message with StreamClosedBit to close the stream handler on the server, indicating that\n * it will not be using the stream anymore.\n */\nexport const enum ControlFlags {\n AckBit = 0b0001,\n StreamOpenBit = 0b0010,\n StreamClosedBit = 0b0100,\n}\n\n/**\n * Generic Typebox schema for a transport message.\n * @template T The type of the payload.\n * @param {T} t The payload schema.\n * @returns The transport message schema.\n */\nexport const TransportMessageSchema = <T extends TSchema>(t: T) =>\n Type.Object({\n id: Type.String(),\n from: Type.String(),\n to: Type.String(),\n seq: Type.Integer(),\n ack: Type.Integer(),\n serviceName: Type.Optional(Type.String()),\n procedureName: Type.Optional(Type.String()),\n streamId: Type.String(),\n controlFlags: Type.Integer(),\n tracing: Type.Optional(\n Type.Object({\n traceparent: Type.String(),\n tracestate: Type.String(),\n }),\n ),\n payload: t,\n });\n\n/**\n * Defines the schema for a transport acknowledgement message. This is never constructed manually\n * and is only used internally by the library for tracking inflight messages.\n * @returns The transport message schema.\n */\nexport const ControlMessageAckSchema = Type.Object({\n type: Type.Literal('ACK'),\n});\n\n/**\n * Defines the schema for a transport close message. This is never constructed manually and is only\n * used internally by the library for closing and cleaning up streams.\n */\nexport const ControlMessageCloseSchema = Type.Object({\n type: Type.Literal('CLOSE'),\n});\n\nexport const PROTOCOL_VERSION = 'v1.1';\nexport const ControlMessageHandshakeRequestSchema = Type.Object({\n type: Type.Literal('HANDSHAKE_REQ'),\n protocolVersion: Type.String(),\n sessionId: Type.String(),\n /**\n * Specifies what the server's expected session state (from the pov of the client). This can be\n * used by the server to know whether this is a new or a reestablished connection, and whether it\n * is compatible with what it already has.\n */\n expectedSessionState: Type.Object({\n // what the client expects the server to send next\n nextExpectedSeq: Type.Integer(),\n // TODO: remove optional once we know all servers\n // are nextSentSeq here\n // what the server expects the client to send next\n nextSentSeq: Type.Optional(Type.Integer()),\n }),\n\n metadata: Type.Optional(Type.Unknown()),\n});\n\nexport const HandshakeErrorRetriableResponseCodes = Type.Union([\n Type.Literal('SESSION_STATE_MISMATCH'),\n]);\n\nexport const HandshakeErrorFatalResponseCodes = Type.Union([\n Type.Literal('MALFORMED_HANDSHAKE_META'),\n Type.Literal('MALFORMED_HANDSHAKE'),\n Type.Literal('PROTOCOL_VERSION_MISMATCH'),\n Type.Literal('REJECTED_BY_CUSTOM_HANDLER'),\n]);\n\nexport const HandshakeErrorResponseCodes = Type.Union([\n HandshakeErrorRetriableResponseCodes,\n HandshakeErrorFatalResponseCodes,\n]);\n\nexport const ControlMessageHandshakeResponseSchema = Type.Object({\n type: Type.Literal('HANDSHAKE_RESP'),\n status: Type.Union([\n Type.Object({\n ok: Type.Literal(true),\n sessionId: Type.String(),\n }),\n Type.Object({\n ok: Type.Literal(false),\n reason: Type.String(),\n // TODO: remove optional once we know all servers\n // are sending code here\n code: Type.Optional(HandshakeErrorResponseCodes),\n }),\n ]),\n});\n\nexport const ControlMessagePayloadSchema = Type.Union([\n ControlMessageCloseSchema,\n ControlMessageAckSchema,\n ControlMessageHandshakeRequestSchema,\n ControlMessageHandshakeResponseSchema,\n]);\n\n/**\n * Defines the schema for an opaque transport message that is agnostic to any\n * procedure/service.\n * @returns The transport message schema.\n */\nexport const OpaqueTransportMessageSchema = TransportMessageSchema(\n Type.Unknown(),\n);\n\n/**\n * Represents a transport message. This is the same type as {@link TransportMessageSchema} but\n * we can't statically infer generics from generic Typebox schemas so we have to define it again here.\n *\n * TypeScript can't enforce types when a bitmask is involved, so these are the semantics of\n * `controlFlags`:\n * * If `controlFlags & StreamOpenBit == StreamOpenBit`, `streamId` must be set to a unique value\n * (suggestion: use `nanoid`).\n * * If `controlFlags & StreamOpenBit == StreamOpenBit`, `serviceName` and `procedureName` must be set.\n * * If `controlFlags & StreamClosedBit == StreamClosedBit` and the kind is `stream` or `subscription`,\n * `payload` should be discarded (usually contains a control message).\n * * If `controlFlags & AckBit == AckBit`, the message is an explicit acknowledgement message and doesn't\n * contain any payload that is relevant to the application so should not be delivered.\n * @template Payload The type of the payload.\n */\nexport interface TransportMessage<Payload = unknown> {\n id: string;\n from: string;\n to: string;\n seq: number;\n ack: number;\n serviceName?: string;\n procedureName?: string;\n streamId: string;\n controlFlags: number;\n tracing?: PropagationContext;\n payload: Payload;\n}\n\nexport type PartialTransportMessage<Payload = unknown> = Omit<\n TransportMessage<Payload>,\n 'id' | 'from' | 'to' | 'seq' | 'ack'\n>;\n\nexport function handshakeRequestMessage({\n from,\n to,\n sessionId,\n expectedSessionState,\n metadata,\n tracing,\n}: {\n from: TransportClientId;\n to: TransportClientId;\n sessionId: string;\n expectedSessionState: Static<\n typeof ControlMessageHandshakeRequestSchema\n >['expectedSessionState'];\n metadata?: unknown;\n tracing?: PropagationContext;\n}): TransportMessage<Static<typeof ControlMessageHandshakeRequestSchema>> {\n return {\n id: generateId(),\n from,\n to,\n seq: 0,\n ack: 0,\n streamId: generateId(),\n controlFlags: 0,\n tracing,\n payload: {\n type: 'HANDSHAKE_REQ',\n protocolVersion: PROTOCOL_VERSION,\n sessionId,\n expectedSessionState,\n metadata,\n } satisfies Static<typeof ControlMessageHandshakeRequestSchema>,\n };\n}\n\n/**\n * This is a reason that can be given during the handshake to indicate that the peer has the wrong\n * session state.\n */\nexport const SESSION_STATE_MISMATCH = 'session state mismatch';\n\nexport function handshakeResponseMessage({\n from,\n to,\n status,\n}: {\n from: TransportClientId;\n to: TransportClientId;\n status: Static<typeof ControlMessageHandshakeResponseSchema>['status'];\n}): TransportMessage<Static<typeof ControlMessageHandshakeResponseSchema>> {\n return {\n id: generateId(),\n from,\n to,\n seq: 0,\n ack: 0,\n streamId: generateId(),\n controlFlags: 0,\n payload: {\n type: 'HANDSHAKE_RESP',\n status,\n } satisfies Static<typeof ControlMessageHandshakeResponseSchema>,\n };\n}\n\nexport function closeStreamMessage(streamId: string): PartialTransportMessage {\n return {\n streamId,\n controlFlags: ControlFlags.StreamClosedBit,\n payload: {\n type: 'CLOSE' as const,\n } satisfies Static<typeof ControlMessagePayloadSchema>,\n };\n}\n\n/**\n * A type alias for a transport message with an opaque payload.\n * @template T - The type of the opaque payload.\n */\nexport type OpaqueTransportMessage = TransportMessage;\nexport type TransportClientId = string;\n\n/**\n * Checks if the given control flag (usually found in msg.controlFlag) is an ack message.\n * @param controlFlag - The control flag to check.\n * @returns True if the control flag contains the AckBit, false otherwise.\n */\nexport function isAck(controlFlag: number): boolean {\n /* eslint-disable-next-line @typescript-eslint/no-unsafe-enum-comparison */\n return (controlFlag & ControlFlags.AckBit) === ControlFlags.AckBit;\n}\n\n/**\n * Checks if the given control flag (usually found in msg.controlFlag) is a stream open message.\n * @param controlFlag - The control flag to check.\n * @returns True if the control flag contains the StreamOpenBit, false otherwise.\n */\nexport function isStreamOpen(controlFlag: number): boolean {\n return (\n /* eslint-disable-next-line @typescript-eslint/no-unsafe-enum-comparison */\n (controlFlag & ControlFlags.StreamOpenBit) === ControlFlags.StreamOpenBit\n );\n}\n\n/**\n * Checks if the given control flag (usually found in msg.controlFlag) is a stream close message.\n * @param controlFlag - The control flag to check.\n * @returns True if the control flag contains the StreamCloseBit, false otherwise.\n */\nexport function isStreamClose(controlFlag: number): boolean {\n return (\n /* eslint-disable-next-line @typescript-eslint/no-unsafe-enum-comparison */\n (controlFlag & ControlFlags.StreamClosedBit) ===\n ControlFlags.StreamClosedBit\n );\n}\n","{\n \"name\": \"@replit/river\",\n \"description\": \"It's like tRPC but... with JSON Schema Support, duplex streaming and support for service multiplexing. Transport agnostic!\",\n \"version\": \"0.24.1\",\n \"type\": \"module\",\n \"exports\": {\n \".\": {\n \"import\": \"./dist/router/index.js\",\n \"require\": \"./dist/router/index.cjs\"\n },\n \"./logging\": {\n \"import\": \"./dist/logging/index.js\",\n \"require\": \"./dist/logging/index.cjs\"\n },\n \"./codec\": {\n \"import\": \"./dist/codec/index.js\",\n \"require\": \"./dist/codec/index.cjs\"\n },\n \"./transport\": {\n \"import\": \"./dist/transport/index.js\",\n \"require\": \"./dist/transport/index.cjs\"\n },\n \"./transport/ws/client\": {\n \"import\": \"./dist/transport/impls/ws/client.js\",\n \"require\": \"./dist/transport/impls/ws/client.cjs\"\n },\n \"./transport/ws/server\": {\n \"import\": \"./dist/transport/impls/ws/server.js\",\n \"require\": \"./dist/transport/impls/ws/server.cjs\"\n },\n \"./transport/uds/client\": {\n \"import\": \"./dist/transport/impls/uds/client.js\",\n \"require\": \"./dist/transport/impls/uds/client.cjs\"\n },\n \"./transport/uds/server\": {\n \"import\": \"./dist/transport/impls/uds/server.js\",\n \"require\": \"./dist/transport/impls/uds/server.cjs\"\n },\n \"./test-util\": {\n \"import\": \"./dist/util/testHelpers.js\",\n \"require\": \"./dist/util/testHelpers.cjs\"\n }\n },\n \"sideEffects\": [\n \"./dist/logging/index.js\"\n ],\n \"files\": [\n \"dist\"\n ],\n \"dependencies\": {\n \"@msgpack/msgpack\": \"^3.0.0-beta2\",\n \"it-pushable\": \"^3.2.3\",\n \"nanoid\": \"^4.0.2\",\n \"ws\": \"^8.17.0\"\n },\n \"peerDependencies\": {\n \"@opentelemetry/api\": \"^1.7.0\",\n \"@sinclair/typebox\": \"~0.32.8\"\n },\n \"devDependencies\": {\n \"@opentelemetry/sdk-trace-base\": \"^1.24.1\",\n \"@opentelemetry/sdk-trace-web\": \"^1.24.1\",\n \"@opentelemetry/core\": \"^1.7.0\",\n \"@types/ws\": \"^8.5.5\",\n \"@typescript-eslint/eslint-plugin\": \"^7.8.0\",\n \"@typescript-eslint/parser\": \"^7.8.0\",\n \"@vitest/ui\": \"^1.3.1\",\n \"eslint\": \"^8.57.0\",\n \"eslint-config-prettier\": \"^9.1.0\",\n \"eslint-plugin-prettier\": \"^5.1.3\",\n \"prettier\": \"^3.0.0\",\n \"tsup\": \"^7.2.0\",\n \"typescript\": \"^5.4.5\",\n \"vitest\": \"^1.3.1\"\n },\n \"scripts\": {\n \"check\": \"tsc --noEmit && npm run format && npm run lint\",\n \"format\": \"npx prettier . --check\",\n \"format:fix\": \"npx prettier . --write\",\n \"lint\": \"eslint .\",\n \"lint:fix\": \"eslint . --fix\",\n \"fix\": \"npm run format:fix && npm run lint:fix\",\n \"build\": \"rm -rf dist && tsup && du -sh dist\",\n \"prepack\": \"npm run build\",\n \"release\": \"npm publish --access public\",\n \"test:ui\": \"echo \\\"remember to go to /__vitest__ in the webview\\\" && vitest --ui --api.host 0.0.0.0 --api.port 3000\",\n \"test\": \"vitest\",\n \"test:single\": \"vitest run --reporter=dot\",\n \"test:flake\": \"./flake.sh\",\n \"bench\": \"vitest bench\"\n },\n \"engines\": {\n \"node\": \">=16\"\n },\n \"keywords\": [\n \"rpc\",\n \"websockets\",\n \"jsonschema\"\n ],\n \"author\": \"Jacky Zhao\",\n \"license\": \"MIT\"\n}\n","export function coerceErrorString(err: unknown): string {\n if (err instanceof Error) {\n return err.message || 'unknown reason';\n }\n\n return `[coerced to error] ${String(err)}`;\n}\n","import {\n Context,\n Span,\n SpanKind,\n context,\n propagation,\n trace,\n} from '@opentelemetry/api';\nimport { version as RIVER_VERSION } from '../package.json';\nimport { ValidProcType } from '../router';\nimport {\n ClientTransport,\n Connection,\n OpaqueTransportMessage,\n} from '../transport';\n\nexport interface PropagationContext {\n traceparent: string;\n tracestate: string;\n}\n\nexport interface TelemetryInfo {\n span: Span;\n ctx: Context;\n}\n\nexport function getPropagationContext(\n ctx: Context,\n): PropagationContext | undefined {\n const tracing = {\n traceparent: '',\n tracestate: '',\n };\n propagation.inject(ctx, tracing);\n return tracing;\n}\n\nexport function createSessionTelemetryInfo(\n sessionId: string,\n to: string,\n from: string,\n propagationCtx?: PropagationContext,\n): TelemetryInfo {\n const parentCtx = propagationCtx\n ? propagation.extract(context.active(), propagationCtx)\n : context.active();\n\n const span = tracer.startSpan(\n `session ${sessionId}`,\n {\n attributes: {\n component: 'river',\n 'river.session.id': sessionId,\n 'river.session.to': to,\n 'river.session.from': from,\n },\n },\n parentCtx,\n );\n\n const ctx = trace.setSpan(parentCtx, span);\n\n return { span, ctx };\n}\n\nexport function createConnectionTelemetryInfo(\n connection: Connection,\n info: TelemetryInfo,\n): TelemetryInfo {\n const span = tracer.startSpan(\n `connection ${connection.id}`,\n {\n attributes: {\n component: 'river',\n 'river.connection.id': connection.id,\n },\n links: [{ context: info.span.spanContext() }],\n },\n info.ctx,\n );\n\n const ctx = trace.setSpan(info.ctx, span);\n\n return { span, ctx };\n}\n\nexport function createProcTelemetryInfo(\n transport: ClientTransport<Connection>,\n kind: ValidProcType,\n serviceName: string,\n procedureName: string,\n streamId: string,\n): TelemetryInfo {\n const baseCtx = context.active();\n const span = tracer.startSpan(\n `procedure call ${serviceName}.${procedureName}`,\n {\n attributes: {\n component: 'river',\n 'river.method.kind': kind,\n 'river.method.service': serviceName,\n 'river.method.name': procedureName,\n 'river.streamId': streamId,\n 'span.kind': 'client',\n },\n kind: SpanKind.CLIENT,\n },\n baseCtx,\n );\n\n const ctx = trace.setSpan(baseCtx, span);\n\n transport.log?.info(`invoked ${serviceName}.${procedureName}`, {\n clientId: transport.clientId,\n transportMessage: {\n procedureName,\n serviceName,\n },\n telemetry: {\n traceId: span.spanContext().traceId,\n spanId: span.spanContext().spanId,\n },\n });\n return { span, ctx };\n}\n\nexport function createHandlerSpan(\n kind: ValidProcType,\n message: OpaqueTransportMessage,\n fn: (span: Span) => Promise<unknown>,\n) {\n const ctx = message.tracing\n ? propagation.extract(context.active(), message.tracing)\n : context.active();\n\n return tracer.startActiveSpan(\n `procedure handler ${message.serviceName}.${message.procedureName}`,\n {\n attributes: {\n component: 'river',\n 'river.method.kind': kind,\n 'river.method.service': message.serviceName,\n 'river.method.name': message.procedureName,\n 'river.streamId': message.streamId,\n 'span.kind': 'server',\n },\n kind: SpanKind.SERVER,\n },\n ctx,\n fn,\n );\n}\n\nconst tracer = trace.getTracer('river', RIVER_VERSION);\nexport default tracer;\n"],"mappings":"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","names":[]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Connection
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-6YFPHVNO.js";
|
|
4
4
|
|
|
5
5
|
// transport/transforms/messageFraming.ts
|
|
6
6
|
import { Transform } from "node:stream";
|
|
@@ -71,22 +71,26 @@ var UdsConnection = class extends Connection {
|
|
|
71
71
|
this.framer = MessageFramer.createFramedStream();
|
|
72
72
|
this.sock = sock;
|
|
73
73
|
this.input = sock.pipe(this.framer);
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
this.input.off("data", cb);
|
|
80
|
-
}
|
|
81
|
-
addCloseListener(cb) {
|
|
82
|
-
this.sock.on("close", cb);
|
|
83
|
-
}
|
|
84
|
-
addErrorListener(cb) {
|
|
74
|
+
this.sock.on("close", () => {
|
|
75
|
+
for (const cb of this.closeListeners) {
|
|
76
|
+
cb();
|
|
77
|
+
}
|
|
78
|
+
});
|
|
85
79
|
this.sock.on("error", (err) => {
|
|
86
80
|
if (err instanceof Error && "code" in err && err.code === "EPIPE") {
|
|
87
81
|
return;
|
|
88
82
|
}
|
|
89
|
-
cb
|
|
83
|
+
for (const cb of this.errorListeners) {
|
|
84
|
+
cb(err);
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
this.input.on("data", (msg) => {
|
|
88
|
+
for (const cb of this.dataListeners) {
|
|
89
|
+
cb(msg);
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
this.sock.on("end", () => {
|
|
93
|
+
this.sock.destroy();
|
|
90
94
|
});
|
|
91
95
|
}
|
|
92
96
|
send(payload) {
|
|
@@ -97,12 +101,12 @@ var UdsConnection = class extends Connection {
|
|
|
97
101
|
return true;
|
|
98
102
|
}
|
|
99
103
|
close() {
|
|
100
|
-
this.sock.
|
|
101
|
-
this.framer.
|
|
104
|
+
this.sock.end();
|
|
105
|
+
this.framer.end();
|
|
102
106
|
}
|
|
103
107
|
};
|
|
104
108
|
|
|
105
109
|
export {
|
|
106
110
|
UdsConnection
|
|
107
111
|
};
|
|
108
|
-
//# sourceMappingURL=chunk-
|
|
112
|
+
//# sourceMappingURL=chunk-L664A3WA.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../transport/transforms/messageFraming.ts","../transport/impls/uds/connection.ts"],"sourcesContent":["import { Transform, TransformCallback, TransformOptions } from 'node:stream';\n\nexport interface LengthEncodedOptions extends TransformOptions {\n /** Maximum in-memory buffer size before we throw */\n maxBufferSizeBytes: number;\n}\n\n/**\n * A transform stream that emits data each time a message with a network/BigEndian uint32 length prefix is received.\n * @extends Transform\n */\nexport class Uint32LengthPrefixFraming extends Transform {\n receivedBuffer: Buffer;\n maxBufferSizeBytes: number;\n\n constructor({ maxBufferSizeBytes, ...options }: LengthEncodedOptions) {\n super(options);\n this.maxBufferSizeBytes = maxBufferSizeBytes;\n this.receivedBuffer = Buffer.alloc(0);\n }\n\n _transform(chunk: Buffer, _encoding: BufferEncoding, cb: TransformCallback) {\n if (\n this.receivedBuffer.byteLength + chunk.byteLength >\n this.maxBufferSizeBytes\n ) {\n const err = new Error(\n `buffer overflow: ${this.receivedBuffer.byteLength}B > ${this.maxBufferSizeBytes}B`,\n );\n\n this.emit('error', err);\n cb(err);\n return;\n }\n\n this.receivedBuffer = Buffer.concat([this.receivedBuffer, chunk]);\n\n // ensure there's enough for a length prefix\n while (this.receivedBuffer.length > 4) {\n // read length from buffer (accounting for uint32 prefix)\n const claimedMessageLength = this.receivedBuffer.readUInt32BE(0) + 4;\n if (this.receivedBuffer.length >= claimedMessageLength) {\n // slice the buffer to extract the message\n const message = this.receivedBuffer.subarray(4, claimedMessageLength);\n this.push(message);\n this.receivedBuffer =\n this.receivedBuffer.subarray(claimedMessageLength);\n } else {\n // not enough data for a complete message, wait for more data\n break;\n }\n }\n\n cb();\n }\n\n _flush(cb: TransformCallback) {\n // if there's any leftover data that doesn't form a complete message\n if (this.receivedBuffer.length) {\n this.emit('error', new Error('got incomplete message while flushing'));\n }\n\n this.receivedBuffer = Buffer.alloc(0);\n cb();\n }\n\n _destroy(error: Error | null, callback: (error: Error | null) => void): void {\n this.receivedBuffer = Buffer.alloc(0);\n super._destroy(error, callback);\n }\n}\n\nfunction createLengthEncodedStream(options?: Partial<LengthEncodedOptions>) {\n return new Uint32LengthPrefixFraming({\n maxBufferSizeBytes: options?.maxBufferSizeBytes ?? 16 * 1024 * 1024, // 16MB\n });\n}\n\nexport const MessageFramer = {\n createFramedStream: createLengthEncodedStream,\n write: (buf: Uint8Array) => {\n const lengthPrefix = Buffer.alloc(4);\n lengthPrefix.writeUInt32BE(buf.length, 0);\n return Buffer.concat([lengthPrefix, buf]);\n },\n};\n","import { type Socket } from 'node:net';\nimport stream from 'node:stream';\nimport {\n MessageFramer,\n Uint32LengthPrefixFraming,\n} from '../../transforms/messageFraming';\nimport { Connection } from '../../connection';\n\nexport class UdsConnection extends Connection {\n sock: Socket;\n input: stream.Readable;\n framer: Uint32LengthPrefixFraming;\n constructor(sock: Socket) {\n super();\n this.framer = MessageFramer.createFramedStream();\n this.sock = sock;\n this.input = sock.pipe(this.framer);\n\n this.sock.on('close', () => {\n for (const cb of this.closeListeners) {\n cb();\n }\n });\n\n this.sock.on('error', (err) => {\n if (err instanceof Error && 'code' in err && err.code === 'EPIPE') {\n // Ignore EPIPE errors\n return;\n }\n\n for (const cb of this.errorListeners) {\n cb(err);\n }\n });\n\n this.input.on('data', (msg: Uint8Array) => {\n for (const cb of this.dataListeners) {\n cb(msg);\n }\n });\n\n this.sock.on('end', () => {\n this.sock.destroy();\n });\n }\n\n send(payload: Uint8Array) {\n if (this.framer.destroyed || !this.sock.writable || this.sock.closed) {\n return false;\n }\n this.sock.write(MessageFramer.write(payload));\n return true;\n }\n\n close() {\n this.sock.end();\n this.framer.end();\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ControlMessagePayloadSchema,
|
|
3
|
+
closeStreamMessage,
|
|
3
4
|
coerceErrorString,
|
|
4
5
|
createHandlerSpan,
|
|
5
6
|
createProcTelemetryInfo,
|
|
7
|
+
generateId,
|
|
6
8
|
getPropagationContext,
|
|
7
9
|
isStreamClose,
|
|
8
10
|
isStreamOpen
|
|
9
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-IYYQ7BII.js";
|
|
10
12
|
|
|
11
13
|
// router/services.ts
|
|
12
14
|
import { Type } from "@sinclair/typebox";
|
|
@@ -583,9 +585,6 @@ function _pushable(getNext, options) {
|
|
|
583
585
|
return pushable2;
|
|
584
586
|
}
|
|
585
587
|
|
|
586
|
-
// router/client.ts
|
|
587
|
-
import { nanoid } from "nanoid";
|
|
588
|
-
|
|
589
588
|
// router/result.ts
|
|
590
589
|
import {
|
|
591
590
|
Type as Type3
|
|
@@ -643,7 +642,7 @@ function createClient(transport, serverId, providedClientOptions = {}) {
|
|
|
643
642
|
}
|
|
644
643
|
const options = { ...defaultClientOptions, ...providedClientOptions };
|
|
645
644
|
if (options.eagerlyConnect) {
|
|
646
|
-
|
|
645
|
+
transport.connect(serverId);
|
|
647
646
|
}
|
|
648
647
|
return _createRecursiveProxy(async (opts) => {
|
|
649
648
|
const [serviceName, procName, procType] = [...opts.path];
|
|
@@ -653,8 +652,8 @@ function createClient(transport, serverId, providedClientOptions = {}) {
|
|
|
653
652
|
);
|
|
654
653
|
}
|
|
655
654
|
const [input] = opts.args;
|
|
656
|
-
if (options.connectOnInvoke && !transport.
|
|
657
|
-
|
|
655
|
+
if (options.connectOnInvoke && !transport.sessions.has(serverId)) {
|
|
656
|
+
transport.connect(serverId);
|
|
658
657
|
}
|
|
659
658
|
if (procType === "rpc") {
|
|
660
659
|
return handleRpc(transport, serverId, input, serviceName, procName);
|
|
@@ -677,7 +676,7 @@ function createSessionDisconnectHandler(from, cb) {
|
|
|
677
676
|
};
|
|
678
677
|
}
|
|
679
678
|
function handleRpc(transport, serverId, input, serviceName, procedureName) {
|
|
680
|
-
const streamId =
|
|
679
|
+
const streamId = generateId();
|
|
681
680
|
const { span, ctx } = createProcTelemetryInfo(
|
|
682
681
|
transport,
|
|
683
682
|
"rpc",
|
|
@@ -722,7 +721,7 @@ function handleRpc(transport, serverId, input, serviceName, procedureName) {
|
|
|
722
721
|
return responsePromise;
|
|
723
722
|
}
|
|
724
723
|
function handleStream(transport, serverId, init, serviceName, procedureName) {
|
|
725
|
-
const streamId =
|
|
724
|
+
const streamId = generateId();
|
|
726
725
|
const { span, ctx } = createProcTelemetryInfo(
|
|
727
726
|
transport,
|
|
728
727
|
"stream",
|
|
@@ -763,7 +762,7 @@ function handleStream(transport, serverId, init, serviceName, procedureName) {
|
|
|
763
762
|
}
|
|
764
763
|
if (!healthyClose)
|
|
765
764
|
return;
|
|
766
|
-
transport.
|
|
765
|
+
transport.send(serverId, closeStreamMessage(streamId));
|
|
767
766
|
};
|
|
768
767
|
void pipeInputToTransport();
|
|
769
768
|
function onMessage(msg) {
|
|
@@ -799,7 +798,7 @@ function handleStream(transport, serverId, init, serviceName, procedureName) {
|
|
|
799
798
|
return [inputStream, outputStream, cleanup];
|
|
800
799
|
}
|
|
801
800
|
function handleSubscribe(transport, serverId, input, serviceName, procedureName) {
|
|
802
|
-
const streamId =
|
|
801
|
+
const streamId = generateId();
|
|
803
802
|
const { span, ctx } = createProcTelemetryInfo(
|
|
804
803
|
transport,
|
|
805
804
|
"subscription",
|
|
@@ -838,7 +837,7 @@ function handleSubscribe(transport, serverId, input, serviceName, procedureName)
|
|
|
838
837
|
cleanup();
|
|
839
838
|
if (!healthyClose)
|
|
840
839
|
return;
|
|
841
|
-
transport.
|
|
840
|
+
transport.send(serverId, closeStreamMessage(streamId));
|
|
842
841
|
};
|
|
843
842
|
const onSessionStatus = createSessionDisconnectHandler(serverId, () => {
|
|
844
843
|
outputStream.push(
|
|
@@ -855,7 +854,7 @@ function handleSubscribe(transport, serverId, input, serviceName, procedureName)
|
|
|
855
854
|
return [outputStream, closeHandler];
|
|
856
855
|
}
|
|
857
856
|
function handleUpload(transport, serverId, init, serviceName, procedureName) {
|
|
858
|
-
const streamId =
|
|
857
|
+
const streamId = generateId();
|
|
859
858
|
const { span, ctx } = createProcTelemetryInfo(
|
|
860
859
|
transport,
|
|
861
860
|
"upload",
|
|
@@ -895,7 +894,7 @@ function handleUpload(transport, serverId, init, serviceName, procedureName) {
|
|
|
895
894
|
}
|
|
896
895
|
if (!healthyClose)
|
|
897
896
|
return;
|
|
898
|
-
transport.
|
|
897
|
+
transport.send(serverId, closeStreamMessage(streamId));
|
|
899
898
|
};
|
|
900
899
|
void pipeInputToTransport();
|
|
901
900
|
const responsePromise = new Promise((resolve) => {
|
|
@@ -936,11 +935,11 @@ var RiverServer = class {
|
|
|
936
935
|
transport;
|
|
937
936
|
services;
|
|
938
937
|
contextMap;
|
|
939
|
-
// map of streamId to ProcStream
|
|
940
938
|
streamMap;
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
939
|
+
sessionToStreamId;
|
|
940
|
+
// streams that are in the process of being cleaned up
|
|
941
|
+
// this is to prevent output handlers from sending after the stream is cleaned up
|
|
942
|
+
sessionsBeingCleanedUp = /* @__PURE__ */ new Set();
|
|
944
943
|
log;
|
|
945
944
|
constructor(transport, services, handshakeOptions, extendedContext) {
|
|
946
945
|
const instances = {};
|
|
@@ -958,9 +957,8 @@ var RiverServer = class {
|
|
|
958
957
|
transport.extendHandshake(handshakeOptions);
|
|
959
958
|
}
|
|
960
959
|
this.transport = transport;
|
|
961
|
-
this.disconnectedSessions = /* @__PURE__ */ new Set();
|
|
962
960
|
this.streamMap = /* @__PURE__ */ new Map();
|
|
963
|
-
this.
|
|
961
|
+
this.sessionToStreamId = /* @__PURE__ */ new Map();
|
|
964
962
|
this.transport.addEventListener("message", this.onMessage);
|
|
965
963
|
this.transport.addEventListener("sessionStatus", this.onSessionStatus);
|
|
966
964
|
this.log = transport.log;
|
|
@@ -995,24 +993,35 @@ var RiverServer = class {
|
|
|
995
993
|
}
|
|
996
994
|
await this.pushToStream(procStream, message, isInitMessage);
|
|
997
995
|
};
|
|
998
|
-
// cleanup streams on session close
|
|
999
996
|
onSessionStatus = async (evt) => {
|
|
1000
|
-
|
|
997
|
+
const streamsFromThisClient = this.sessionToStreamId.get(evt.session.id);
|
|
998
|
+
const cleanupStreams = async (ids) => {
|
|
999
|
+
this.sessionsBeingCleanedUp.add(evt.session.id);
|
|
1000
|
+
await Promise.all(Array.from(ids).map(this.cleanupStream));
|
|
1001
|
+
this.sessionToStreamId.delete(evt.session.id);
|
|
1002
|
+
this.sessionsBeingCleanedUp.delete(evt.session.id);
|
|
1003
|
+
};
|
|
1004
|
+
if (evt.status === "connect") {
|
|
1005
|
+
if (streamsFromThisClient) {
|
|
1006
|
+
this.log?.error(
|
|
1007
|
+
`got session connect from ${evt.session.to} but there are still streams open from this session`,
|
|
1008
|
+
{
|
|
1009
|
+
clientId: this.transport.clientId,
|
|
1010
|
+
tags: ["invariant-violation"]
|
|
1011
|
+
}
|
|
1012
|
+
);
|
|
1013
|
+
await cleanupStreams(streamsFromThisClient);
|
|
1014
|
+
}
|
|
1015
|
+
this.sessionToStreamId.set(evt.session.id, /* @__PURE__ */ new Set());
|
|
1001
1016
|
return;
|
|
1002
|
-
|
|
1017
|
+
}
|
|
1003
1018
|
this.log?.info(
|
|
1004
|
-
`got session disconnect from ${
|
|
1019
|
+
`got session disconnect from ${evt.session.to}, cleaning up streams for session`,
|
|
1005
1020
|
evt.session.loggingMetadata
|
|
1006
1021
|
);
|
|
1007
|
-
const streamsFromThisClient = this.clientStreams.get(disconnectedClientId);
|
|
1008
1022
|
if (!streamsFromThisClient)
|
|
1009
1023
|
return;
|
|
1010
|
-
|
|
1011
|
-
await Promise.all(
|
|
1012
|
-
Array.from(streamsFromThisClient).map(this.cleanupStream)
|
|
1013
|
-
);
|
|
1014
|
-
this.disconnectedSessions.delete(disconnectedClientId);
|
|
1015
|
-
this.clientStreams.delete(disconnectedClientId);
|
|
1024
|
+
await cleanupStreams(streamsFromThisClient);
|
|
1016
1025
|
};
|
|
1017
1026
|
createNewProcStream(message) {
|
|
1018
1027
|
if (!isStreamOpen(message.controlFlags)) {
|
|
@@ -1063,26 +1072,34 @@ var RiverServer = class {
|
|
|
1063
1072
|
});
|
|
1064
1073
|
return;
|
|
1065
1074
|
}
|
|
1075
|
+
const {
|
|
1076
|
+
to,
|
|
1077
|
+
id: sessionId,
|
|
1078
|
+
loggingMetadata: sessionLoggingMetadata
|
|
1079
|
+
} = session;
|
|
1066
1080
|
const procedure = service.procedures[message.procedureName];
|
|
1067
1081
|
const incoming = pushable({ objectMode: true });
|
|
1068
1082
|
const outgoing = pushable({ objectMode: true });
|
|
1069
1083
|
const needsClose = procedure.type === "subscription" || procedure.type === "stream";
|
|
1070
1084
|
const disposables = [];
|
|
1085
|
+
const wrappedSend = (payload) => {
|
|
1086
|
+
if (!this.sessionsBeingCleanedUp.has(sessionId)) {
|
|
1087
|
+
this.transport.send(to, payload);
|
|
1088
|
+
}
|
|
1089
|
+
};
|
|
1071
1090
|
const outputHandler = (
|
|
1072
1091
|
// sending outgoing messages back to client
|
|
1073
1092
|
needsClose ? (
|
|
1074
1093
|
// subscription and stream case, we need to send a close bit after the response stream
|
|
1075
1094
|
(async () => {
|
|
1076
1095
|
for await (const response of outgoing) {
|
|
1077
|
-
|
|
1096
|
+
wrappedSend({
|
|
1078
1097
|
streamId: message.streamId,
|
|
1079
1098
|
controlFlags: 0,
|
|
1080
1099
|
payload: response
|
|
1081
1100
|
});
|
|
1082
1101
|
}
|
|
1083
|
-
|
|
1084
|
-
this.transport.sendCloseStream(session.to, message.streamId);
|
|
1085
|
-
}
|
|
1102
|
+
wrappedSend(closeStreamMessage(message.streamId));
|
|
1086
1103
|
disposables.forEach((d) => d());
|
|
1087
1104
|
})()
|
|
1088
1105
|
) : (
|
|
@@ -1090,7 +1107,7 @@ var RiverServer = class {
|
|
|
1090
1107
|
(async () => {
|
|
1091
1108
|
const response = await outgoing.next().then((res) => res.value);
|
|
1092
1109
|
if (response) {
|
|
1093
|
-
|
|
1110
|
+
wrappedSend({
|
|
1094
1111
|
streamId: message.streamId,
|
|
1095
1112
|
controlFlags: 4 /* StreamClosedBit */,
|
|
1096
1113
|
payload: response
|
|
@@ -1104,7 +1121,7 @@ var RiverServer = class {
|
|
|
1104
1121
|
const errorMsg = coerceErrorString(err);
|
|
1105
1122
|
this.log?.error(
|
|
1106
1123
|
`procedure ${message.serviceName}.${message.procedureName} threw an uncaught error: ${errorMsg}`,
|
|
1107
|
-
|
|
1124
|
+
sessionLoggingMetadata
|
|
1108
1125
|
);
|
|
1109
1126
|
span.recordException(err instanceof Error ? err : new Error(errorMsg));
|
|
1110
1127
|
span.setStatus({ code: SpanStatusCode.ERROR });
|
|
@@ -1115,10 +1132,10 @@ var RiverServer = class {
|
|
|
1115
1132
|
})
|
|
1116
1133
|
);
|
|
1117
1134
|
};
|
|
1118
|
-
const sessionMeta = this.transport.sessionHandshakeMetadata.get(
|
|
1135
|
+
const sessionMeta = this.transport.sessionHandshakeMetadata.get(to);
|
|
1119
1136
|
if (!sessionMeta) {
|
|
1120
1137
|
this.log?.error(`session doesn't have handshake metadata`, {
|
|
1121
|
-
...
|
|
1138
|
+
...sessionLoggingMetadata,
|
|
1122
1139
|
tags: ["invariant-violation"]
|
|
1123
1140
|
});
|
|
1124
1141
|
return;
|
|
@@ -1127,10 +1144,10 @@ var RiverServer = class {
|
|
|
1127
1144
|
const procHasInitMessage = "init" in procedure;
|
|
1128
1145
|
const serviceContextWithTransportInfo = {
|
|
1129
1146
|
...serviceContext,
|
|
1147
|
+
sessionId,
|
|
1130
1148
|
to: message.to,
|
|
1131
1149
|
from: message.from,
|
|
1132
1150
|
streamId: message.streamId,
|
|
1133
|
-
session,
|
|
1134
1151
|
metadata: sessionMeta
|
|
1135
1152
|
};
|
|
1136
1153
|
switch (procedure.type) {
|
|
@@ -1249,9 +1266,7 @@ var RiverServer = class {
|
|
|
1249
1266
|
initMessage.value,
|
|
1250
1267
|
incoming
|
|
1251
1268
|
);
|
|
1252
|
-
|
|
1253
|
-
outgoing.push(outputMessage);
|
|
1254
|
-
}
|
|
1269
|
+
outgoing.push(outputMessage);
|
|
1255
1270
|
} catch (err) {
|
|
1256
1271
|
errorHandler(err, span);
|
|
1257
1272
|
} finally {
|
|
@@ -1269,9 +1284,7 @@ var RiverServer = class {
|
|
|
1269
1284
|
serviceContextWithTransportInfo,
|
|
1270
1285
|
incoming
|
|
1271
1286
|
);
|
|
1272
|
-
|
|
1273
|
-
outgoing.push(outputMessage);
|
|
1274
|
-
}
|
|
1287
|
+
outgoing.push(outputMessage);
|
|
1275
1288
|
} catch (err) {
|
|
1276
1289
|
errorHandler(err, span);
|
|
1277
1290
|
} finally {
|
|
@@ -1284,7 +1297,7 @@ var RiverServer = class {
|
|
|
1284
1297
|
default:
|
|
1285
1298
|
this.log?.warn(
|
|
1286
1299
|
`got request for invalid procedure type ${procedure.type} at ${message.serviceName}.${message.procedureName}`,
|
|
1287
|
-
{ ...
|
|
1300
|
+
{ ...sessionLoggingMetadata, transportMessage: message }
|
|
1288
1301
|
);
|
|
1289
1302
|
return;
|
|
1290
1303
|
}
|
|
@@ -1297,9 +1310,9 @@ var RiverServer = class {
|
|
|
1297
1310
|
promises: { inputHandler, outputHandler }
|
|
1298
1311
|
};
|
|
1299
1312
|
this.streamMap.set(message.streamId, procStream);
|
|
1300
|
-
const
|
|
1301
|
-
|
|
1302
|
-
this.
|
|
1313
|
+
const streamsForThisSession = this.sessionToStreamId.get(sessionId) ?? /* @__PURE__ */ new Set();
|
|
1314
|
+
streamsForThisSession.add(message.streamId);
|
|
1315
|
+
this.sessionToStreamId.set(sessionId, streamsForThisSession);
|
|
1303
1316
|
return procStream;
|
|
1304
1317
|
}
|
|
1305
1318
|
async pushToStream(procStream, message, isInit) {
|
|
@@ -1335,11 +1348,11 @@ var RiverServer = class {
|
|
|
1335
1348
|
}
|
|
1336
1349
|
if (isStreamClose(message.controlFlags)) {
|
|
1337
1350
|
await this.cleanupStream(message.streamId);
|
|
1338
|
-
const streamsFromThisClient = this.
|
|
1351
|
+
const streamsFromThisClient = this.sessionToStreamId.get(message.from);
|
|
1339
1352
|
if (streamsFromThisClient) {
|
|
1340
1353
|
streamsFromThisClient.delete(message.streamId);
|
|
1341
1354
|
if (streamsFromThisClient.size === 0) {
|
|
1342
|
-
this.
|
|
1355
|
+
this.sessionToStreamId.delete(message.from);
|
|
1343
1356
|
}
|
|
1344
1357
|
}
|
|
1345
1358
|
}
|
|
@@ -1399,4 +1412,4 @@ export {
|
|
|
1399
1412
|
createClientHandshakeOptions,
|
|
1400
1413
|
createServerHandshakeOptions
|
|
1401
1414
|
};
|
|
1402
|
-
//# sourceMappingURL=chunk-
|
|
1415
|
+
//# sourceMappingURL=chunk-M7E6LQO2.js.map
|