@nmtjs/ws-transport 0.10.2 → 0.10.3
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/dist/server.js +1 -2
- package/dist/server.js.map +1 -1
- package/dist/utils.js +1 -1
- package/dist/utils.js.map +1 -1
- package/package.json +7 -7
- package/src/server.ts +1 -2
- package/src/utils.ts +1 -1
package/dist/server.js
CHANGED
|
@@ -169,7 +169,7 @@ export class WsTransportServer {
|
|
|
169
169
|
acceptType,
|
|
170
170
|
contentType: isBlob ? "*/*" : contentType
|
|
171
171
|
});
|
|
172
|
-
let payload
|
|
172
|
+
let payload;
|
|
173
173
|
if (body) {
|
|
174
174
|
if (isBlob) {
|
|
175
175
|
const type = contentType || "application/octet-stream";
|
|
@@ -227,7 +227,6 @@ export class WsTransportServer {
|
|
|
227
227
|
});
|
|
228
228
|
ac.signal.addEventListener("abort", () => stream.destroy(), { once: true });
|
|
229
229
|
stream.on("data", (chunk) => {
|
|
230
|
-
console.log({ chunk });
|
|
231
230
|
if (ac.signal.aborted) return;
|
|
232
231
|
const buf = Buffer.from(chunk);
|
|
233
232
|
const ab = buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);
|
package/dist/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"mappings":"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","names":["context: TransportPluginContext","options: WsTransportOptions","ws: WsTransportSocket","error: any","connection: Connection<WsConnectionData>","messageType: ServerMessageType","buffer: ArrayBuffer","res: HttpResponse","req: HttpRequest","metadata: ProtocolApiCallOptions['metadata']","format: ReturnType<typeof getFormat>","payload: any","stream: Readable","cause: any"],"sources":["../src/server.ts"],"sourcesContent":["import {\n App,\n type HttpRequest,\n type HttpResponse,\n SSLApp,\n type TemplatedApp,\n us_socket_local_port,\n} from 'uWebSockets.js'\nimport { randomUUID } from 'node:crypto'\nimport { once } from 'node:events'\nimport { Duplex, Readable } from 'node:stream'\nimport { Scope } from '@nmtjs/core'\nimport {\n ClientMessageType,\n decodeNumber,\n ErrorCode,\n ProtocolBlob,\n type ServerMessageType,\n} from '@nmtjs/protocol'\nimport {\n Connection,\n getFormat,\n isIterableResult,\n isSubscriptionResult,\n type ProtocolApiCallOptions,\n ProtocolClientStream,\n ProtocolError,\n ProtocolInjectables,\n type Transport,\n type TransportPluginContext,\n UnsupportedContentTypeError,\n UnsupportedFormatError,\n} from '@nmtjs/protocol/server'\nimport {\n AllowedHttpMethod,\n HttpCode,\n HttpCodeMap,\n HttpStatusText,\n} from './http.ts'\nimport { WsTransportInjectables } from './injectables.ts'\nimport type {\n WsConnectionData,\n WsTransportOptions,\n WsTransportSocket,\n WsUserData,\n} from './types.ts'\nimport {\n getRequestBody,\n getRequestData,\n readableToArrayBuffer,\n send,\n setHeaders,\n} from './utils.ts'\n\nconst DEFAULT_ALLOWED_METHODS = ['post'] as ('get' | 'post')[]\n\nexport class WsTransportServer implements Transport<WsConnectionData> {\n protected server!: TemplatedApp\n protected clients: Map<string, WsTransportSocket> = new Map()\n\n constructor(\n protected readonly context: TransportPluginContext,\n protected readonly options: WsTransportOptions,\n ) {\n this.server = this.options.tls ? SSLApp(options.tls!) : App()\n this.server\n .options('/*', (res, req) => {\n this.applyCors(res, req)\n res.writeStatus('200 OK')\n res.endWithoutBody()\n })\n .get('/healthy', (res, req) => {\n this.applyCors(res, req)\n res.writeHeader('Content-Type', 'text/plain')\n res.end('OK')\n })\n .ws<WsUserData>('/api', {\n sendPingsAutomatically: true,\n maxPayloadLength: this.options.maxPayloadLength,\n upgrade: async (res, req, socketContext) => {\n const ac = new AbortController()\n\n res.onAborted(ac.abort.bind(ac))\n\n const requestData = getRequestData(req, res)\n const contentType =\n requestData.query.get('content-type') ||\n requestData.headers.get('content-type')\n const acceptType =\n requestData.query.get('accept') || requestData.headers.get('accept')\n\n const connectionId = randomUUID()\n\n try {\n const { context } = await this.protocol.addConnection(\n this,\n { id: connectionId, data: { type: 'ws' } },\n { acceptType, contentType },\n )\n context.container.provide(\n WsTransportInjectables.connectionData,\n requestData,\n )\n if (!ac.signal.aborted) {\n res.cork(() => {\n res.upgrade(\n {\n id: connectionId,\n request: requestData,\n contentType,\n acceptType,\n backpressure: null,\n context,\n } as WsUserData,\n req.getHeader('sec-websocket-key'),\n req.getHeader('sec-websocket-protocol'),\n req.getHeader('sec-websocket-extensions'),\n socketContext,\n )\n })\n }\n } catch (error) {\n this.logger.debug(\n new Error('Failed to upgrade connection', { cause: error }),\n )\n if (!ac.signal.aborted) {\n res.cork(() => {\n res.writeStatus('500 Internal Server Error')\n res.endWithoutBody()\n })\n }\n }\n },\n open: (ws: WsTransportSocket) => {\n const { id } = ws.getUserData()\n this.logger.debug('Connection %s opened', id)\n this.clients.set(id, ws)\n },\n message: async (ws: WsTransportSocket, buffer) => {\n const messageType = decodeNumber(buffer, 'Uint8')\n if (messageType in this === false) {\n ws.end(1011, 'Unknown message type')\n } else {\n try {\n await this[messageType](\n ws,\n buffer.slice(Uint8Array.BYTES_PER_ELEMENT),\n )\n } catch (error: any) {\n this.logError(error, 'Error while processing message')\n }\n }\n },\n drain: (ws: WsTransportSocket) => {\n const data = ws.getUserData()\n data.backpressure?.resolve()\n data.backpressure = null\n },\n close: async (ws: WsTransportSocket, code, message) => {\n const { id } = ws.getUserData()\n\n this.logger.debug(\n 'Connection %s closed with code %s: %s',\n id,\n code,\n Buffer.from(message).toString(),\n )\n this.clients.delete(id)\n await this.protocol.removeConnection(id)\n },\n })\n .get('/api/:namespace/:procedure', this.httpHandler.bind(this))\n .post('/api/:namespace/:procedure', this.httpHandler.bind(this))\n }\n\n send(\n connection: Connection<WsConnectionData>,\n messageType: ServerMessageType,\n buffer: ArrayBuffer,\n ) {\n const ws = this.clients.get(connection.id)\n if (ws) send(ws, messageType, buffer)\n }\n\n async start() {\n return new Promise<void>((resolve, reject) => {\n const { hostname = '127.0.0.1', port = 0, unix } = this.options\n if (unix) {\n this.server.listen_unix((socket) => {\n if (socket) {\n this.logger.info('Server started on unix://%s', unix)\n resolve()\n } else {\n reject(new Error('Failed to start WebSockets server'))\n }\n }, unix)\n } else {\n this.server.listen(hostname, port, (socket) => {\n if (socket) {\n this.logger.info(\n 'WebSocket Server started on %s:%s',\n hostname,\n us_socket_local_port(socket),\n )\n resolve()\n } else {\n reject(new Error('Failed to start WebSockets server'))\n }\n })\n }\n })\n }\n\n async stop() {\n this.server.close()\n }\n\n // TODO: decompose this mess\n protected async httpHandler(res: HttpResponse, req: HttpRequest) {\n this.applyCors(res, req)\n\n const ac = new AbortController()\n\n res.onAborted(ac.abort.bind(ac))\n\n const method = req.getMethod() as 'get' | 'post'\n const namespace = req.getParameter('namespace')\n const procedure = req.getParameter('procedure')\n const requestData = getRequestData(req, res)\n\n if (!namespace || !procedure) {\n const status = HttpCode.NotFound\n const text = HttpStatusText[status]\n return void res.cork(() => {\n if (ac.signal.aborted) return\n res.writeStatus(`${status} ${text}`)\n res.endWithoutBody()\n })\n }\n\n const isBlob = requestData.headers.get('x-neemata-blob') === 'true'\n\n const contentType = requestData.headers.get('content-type')\n const acceptType = requestData.headers.get('accept')\n const connectionId = randomUUID()\n const connection = new Connection<WsConnectionData>({\n id: connectionId,\n data: { type: 'http' },\n })\n const responseHeaders = new Headers()\n const container = this.context.container.fork(Scope.Call)\n container.provide(ProtocolInjectables.connection, connection)\n container.provide(WsTransportInjectables.connectionData, requestData)\n container.provide(\n WsTransportInjectables.httpResponseHeaders,\n responseHeaders,\n )\n\n const body = method === 'post' ? getRequestBody(res) : undefined\n\n const metadata: ProtocolApiCallOptions['metadata'] = (metadata) => {\n const allowHttpMethod =\n metadata.get(AllowedHttpMethod) ?? DEFAULT_ALLOWED_METHODS\n if (!allowHttpMethod.includes(method)) {\n throw new ProtocolError(ErrorCode.NotFound)\n }\n }\n let format: ReturnType<typeof getFormat>\n try {\n format = getFormat(this.context.format, {\n acceptType,\n contentType: isBlob ? '*/*' : contentType,\n })\n\n let payload: any = undefined\n\n if (body) {\n if (isBlob) {\n const type = contentType || 'application/octet-stream'\n const contentLength = requestData.headers.get('content-length')\n const size = contentLength\n ? Number.parseInt(contentLength)\n : undefined\n const stream = new ProtocolClientStream(-1, { size, type })\n body.pipe(stream)\n payload = stream\n } else {\n const buffer = await readableToArrayBuffer(body)\n if (buffer.byteLength > 0) {\n payload = format.decoder.decode(buffer)\n }\n }\n }\n\n const result = await this.protocol.call({\n connection,\n namespace,\n procedure,\n payload,\n metadata,\n container,\n signal: ac.signal,\n })\n\n if (isIterableResult(result) || isSubscriptionResult(result)) {\n res.cork(() => {\n if (ac.signal.aborted) return\n const status = HttpCode.NotImplemented\n const text = HttpStatusText[status]\n res.writeStatus(`${status} ${text}`)\n res.end()\n })\n } else {\n const { output } = result\n\n if (output instanceof ProtocolBlob) {\n const { source, metadata } = output\n const { type } = metadata\n\n let stream: Readable\n\n if (source instanceof ReadableStream) {\n stream = Readable.fromWeb(source as any)\n } else if (source instanceof Readable || source instanceof Duplex) {\n stream = Readable.from(source)\n } else {\n throw new Error('Invalid stream source')\n }\n\n res.cork(() => {\n if (ac.signal.aborted) return\n responseHeaders.set('X-Neemata-Blob', 'true')\n responseHeaders.set('Content-Type', type)\n if (metadata.size)\n res.writeHeader('Content-Length', metadata.size.toString())\n setHeaders(res, responseHeaders)\n })\n\n ac.signal.addEventListener('abort', () => stream.destroy(), {\n once: true,\n })\n\n stream.on('data', (chunk) => {\n console.log({ chunk })\n if (ac.signal.aborted) return\n const buf = Buffer.from(chunk)\n const ab = buf.buffer.slice(\n buf.byteOffset,\n buf.byteOffset + buf.byteLength,\n )\n const ok = res.write(ab)\n if (!ok) {\n stream.pause()\n res.onWritable(() => {\n stream.resume()\n return true\n })\n }\n })\n await once(stream, 'end')\n if (stream.readableAborted) {\n res.end(undefined, true)\n } else {\n res.end()\n }\n } else {\n res.cork(() => {\n if (ac.signal.aborted) return\n const status = HttpCode.OK\n const text = HttpStatusText[status]\n const buffer = format.encoder.encode(output)\n res.writeStatus(`${status} ${text}`)\n responseHeaders.set('Content-Type', format.encoder.contentType)\n setHeaders(res, responseHeaders)\n res.end(buffer)\n })\n }\n }\n } catch (error) {\n if (ac.signal.aborted) return\n if (error instanceof UnsupportedFormatError) {\n res.cork(() => {\n if (ac.signal.aborted) return\n const status =\n error instanceof UnsupportedContentTypeError\n ? HttpCode.UnsupportedMediaType\n : HttpCode.NotAcceptable\n const text = HttpStatusText[status]\n res.writeStatus(`${status} ${text}`)\n res.end()\n })\n } else if (error instanceof ProtocolError) {\n res.cork(() => {\n if (ac.signal.aborted) return\n const status =\n error.code in HttpCodeMap\n ? HttpCodeMap[error.code]\n : HttpCode.InternalServerError\n const text = HttpStatusText[status]\n res.writeStatus(`${status} ${text}`)\n res.end(format!.encoder.encode(error))\n })\n } else {\n this.logError(error, 'Unknown error while processing request')\n res.cork(() => {\n if (ac.signal.aborted) return\n const status = HttpCode.InternalServerError\n const text = HttpStatusText[status]\n const payload = format!.encoder.encode(\n new ProtocolError(\n ErrorCode.InternalServerError,\n 'Internal Server Error',\n ),\n )\n res.writeStatus(`${status} ${text}`)\n res.end(payload)\n })\n }\n } finally {\n container.dispose().catch((error) => {\n this.logError(error, 'Error while disposing call container')\n })\n }\n }\n\n protected get protocol() {\n return this.context.protocol\n }\n\n protected get logger() {\n return this.context.logger\n }\n\n protected async logError(\n cause: any,\n message = 'Unknown error while processing request',\n ) {\n this.logger.error(new Error(message, { cause }))\n }\n\n protected applyCors(res: HttpResponse, req: HttpRequest) {\n if (this.options.cors === false) return\n\n const origin = req.getHeader('origin')\n if (!origin) return\n\n let allowed = false\n\n if (this.options.cors === undefined || this.options.cors === true) {\n allowed = true\n } else if (Array.isArray(this.options.cors)) {\n allowed = this.options.cors.includes(origin)\n } else {\n allowed = this.options.cors(origin)\n }\n\n if (!allowed) return\n\n res.writeHeader('Access-Control-Allow-Origin', origin)\n res.writeHeader('Access-Control-Allow-Headers', 'Content-Type')\n res.writeHeader('Access-Control-Allow-Methods', 'GET, POST')\n res.writeHeader('Access-Control-Allow-Credentials', 'true')\n }\n\n protected [ClientMessageType.Rpc](\n ws: WsTransportSocket,\n buffer: ArrayBuffer,\n ) {\n const { id } = ws.getUserData()\n this.protocol.rpcRaw(id, buffer)\n }\n\n protected [ClientMessageType.RpcAbort](\n ws: WsTransportSocket,\n buffer: ArrayBuffer,\n ) {\n const { id } = ws.getUserData()\n this.protocol.rpcAbortRaw(id, buffer)\n }\n\n protected [ClientMessageType.RpcStreamAbort](\n ws: WsTransportSocket,\n buffer: ArrayBuffer,\n ) {\n const { id } = ws.getUserData()\n this.protocol.rpcStreamAbortRaw(id, buffer)\n }\n\n protected [ClientMessageType.ClientStreamPush](\n ws: WsTransportSocket,\n buffer: ArrayBuffer,\n ) {\n const { id } = ws.getUserData()\n const streamId = decodeNumber(buffer, 'Uint32')\n this.protocol.pushClientStream(\n id,\n streamId,\n buffer.slice(Uint32Array.BYTES_PER_ELEMENT),\n )\n }\n\n protected [ClientMessageType.ClientStreamEnd](\n ws: WsTransportSocket,\n buffer: ArrayBuffer,\n ) {\n const { id } = ws.getUserData()\n const streamId = decodeNumber(buffer, 'Uint32')\n this.protocol.endClientStream(id, streamId)\n }\n\n protected [ClientMessageType.ClientStreamAbort](\n ws: WsTransportSocket,\n buffer: ArrayBuffer,\n ) {\n const { id } = ws.getUserData()\n const streamId = decodeNumber(buffer, 'Uint32')\n this.protocol.abortClientStream(id, streamId)\n }\n\n protected [ClientMessageType.ServerStreamPull](\n ws: WsTransportSocket,\n buffer: ArrayBuffer,\n ) {\n const { id } = ws.getUserData()\n const streamId = decodeNumber(buffer, 'Uint32')\n this.protocol.pullServerStream(id, streamId)\n }\n\n protected [ClientMessageType.ServerStreamAbort](\n ws: WsTransportSocket,\n buffer: ArrayBuffer,\n ) {\n const { id } = ws.getUserData()\n const streamId = decodeNumber(buffer, 'Uint32')\n this.protocol.abortServerStream(id, streamId)\n }\n}\n"],"version":3,"file":"server.js"}
|
|
1
|
+
{"mappings":"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","names":["context: TransportPluginContext","options: WsTransportOptions","ws: WsTransportSocket","error: any","connection: Connection<WsConnectionData>","messageType: ServerMessageType","buffer: ArrayBuffer","res: HttpResponse","req: HttpRequest","metadata: ProtocolApiCallOptions['metadata']","format: ReturnType<typeof getFormat>","payload: any","stream: Readable","cause: any"],"sources":["../src/server.ts"],"sourcesContent":["import {\n App,\n type HttpRequest,\n type HttpResponse,\n SSLApp,\n type TemplatedApp,\n us_socket_local_port,\n} from 'uWebSockets.js'\nimport { randomUUID } from 'node:crypto'\nimport { once } from 'node:events'\nimport { Duplex, Readable } from 'node:stream'\nimport { Scope } from '@nmtjs/core'\nimport {\n ClientMessageType,\n decodeNumber,\n ErrorCode,\n ProtocolBlob,\n type ServerMessageType,\n} from '@nmtjs/protocol'\nimport {\n Connection,\n getFormat,\n isIterableResult,\n isSubscriptionResult,\n type ProtocolApiCallOptions,\n ProtocolClientStream,\n ProtocolError,\n ProtocolInjectables,\n type Transport,\n type TransportPluginContext,\n UnsupportedContentTypeError,\n UnsupportedFormatError,\n} from '@nmtjs/protocol/server'\nimport {\n AllowedHttpMethod,\n HttpCode,\n HttpCodeMap,\n HttpStatusText,\n} from './http.ts'\nimport { WsTransportInjectables } from './injectables.ts'\nimport type {\n WsConnectionData,\n WsTransportOptions,\n WsTransportSocket,\n WsUserData,\n} from './types.ts'\nimport {\n getRequestBody,\n getRequestData,\n readableToArrayBuffer,\n send,\n setHeaders,\n} from './utils.ts'\n\nconst DEFAULT_ALLOWED_METHODS = ['post'] as ('get' | 'post')[]\n\nexport class WsTransportServer implements Transport<WsConnectionData> {\n protected server!: TemplatedApp\n protected clients: Map<string, WsTransportSocket> = new Map()\n\n constructor(\n protected readonly context: TransportPluginContext,\n protected readonly options: WsTransportOptions,\n ) {\n this.server = this.options.tls ? SSLApp(options.tls!) : App()\n this.server\n .options('/*', (res, req) => {\n this.applyCors(res, req)\n res.writeStatus('200 OK')\n res.endWithoutBody()\n })\n .get('/healthy', (res, req) => {\n this.applyCors(res, req)\n res.writeHeader('Content-Type', 'text/plain')\n res.end('OK')\n })\n .ws<WsUserData>('/api', {\n sendPingsAutomatically: true,\n maxPayloadLength: this.options.maxPayloadLength,\n upgrade: async (res, req, socketContext) => {\n const ac = new AbortController()\n\n res.onAborted(ac.abort.bind(ac))\n\n const requestData = getRequestData(req, res)\n const contentType =\n requestData.query.get('content-type') ||\n requestData.headers.get('content-type')\n const acceptType =\n requestData.query.get('accept') || requestData.headers.get('accept')\n\n const connectionId = randomUUID()\n\n try {\n const { context } = await this.protocol.addConnection(\n this,\n { id: connectionId, data: { type: 'ws' } },\n { acceptType, contentType },\n )\n context.container.provide(\n WsTransportInjectables.connectionData,\n requestData,\n )\n if (!ac.signal.aborted) {\n res.cork(() => {\n res.upgrade(\n {\n id: connectionId,\n request: requestData,\n contentType,\n acceptType,\n backpressure: null,\n context,\n } as WsUserData,\n req.getHeader('sec-websocket-key'),\n req.getHeader('sec-websocket-protocol'),\n req.getHeader('sec-websocket-extensions'),\n socketContext,\n )\n })\n }\n } catch (error) {\n this.logger.debug(\n new Error('Failed to upgrade connection', { cause: error }),\n )\n if (!ac.signal.aborted) {\n res.cork(() => {\n res.writeStatus('500 Internal Server Error')\n res.endWithoutBody()\n })\n }\n }\n },\n open: (ws: WsTransportSocket) => {\n const { id } = ws.getUserData()\n this.logger.debug('Connection %s opened', id)\n this.clients.set(id, ws)\n },\n message: async (ws: WsTransportSocket, buffer) => {\n const messageType = decodeNumber(buffer, 'Uint8')\n if (messageType in this === false) {\n ws.end(1011, 'Unknown message type')\n } else {\n try {\n await this[messageType](\n ws,\n buffer.slice(Uint8Array.BYTES_PER_ELEMENT),\n )\n } catch (error: any) {\n this.logError(error, 'Error while processing message')\n }\n }\n },\n drain: (ws: WsTransportSocket) => {\n const data = ws.getUserData()\n data.backpressure?.resolve()\n data.backpressure = null\n },\n close: async (ws: WsTransportSocket, code, message) => {\n const { id } = ws.getUserData()\n\n this.logger.debug(\n 'Connection %s closed with code %s: %s',\n id,\n code,\n Buffer.from(message).toString(),\n )\n this.clients.delete(id)\n await this.protocol.removeConnection(id)\n },\n })\n .get('/api/:namespace/:procedure', this.httpHandler.bind(this))\n .post('/api/:namespace/:procedure', this.httpHandler.bind(this))\n }\n\n send(\n connection: Connection<WsConnectionData>,\n messageType: ServerMessageType,\n buffer: ArrayBuffer,\n ) {\n const ws = this.clients.get(connection.id)\n if (ws) send(ws, messageType, buffer)\n }\n\n async start() {\n return new Promise<void>((resolve, reject) => {\n const { hostname = '127.0.0.1', port = 0, unix } = this.options\n if (unix) {\n this.server.listen_unix((socket) => {\n if (socket) {\n this.logger.info('Server started on unix://%s', unix)\n resolve()\n } else {\n reject(new Error('Failed to start WebSockets server'))\n }\n }, unix)\n } else {\n this.server.listen(hostname, port, (socket) => {\n if (socket) {\n this.logger.info(\n 'WebSocket Server started on %s:%s',\n hostname,\n us_socket_local_port(socket),\n )\n resolve()\n } else {\n reject(new Error('Failed to start WebSockets server'))\n }\n })\n }\n })\n }\n\n async stop() {\n this.server.close()\n }\n\n // TODO: decompose this mess\n protected async httpHandler(res: HttpResponse, req: HttpRequest) {\n this.applyCors(res, req)\n\n const ac = new AbortController()\n\n res.onAborted(ac.abort.bind(ac))\n\n const method = req.getMethod() as 'get' | 'post'\n const namespace = req.getParameter('namespace')\n const procedure = req.getParameter('procedure')\n const requestData = getRequestData(req, res)\n\n if (!namespace || !procedure) {\n const status = HttpCode.NotFound\n const text = HttpStatusText[status]\n return void res.cork(() => {\n if (ac.signal.aborted) return\n res.writeStatus(`${status} ${text}`)\n res.endWithoutBody()\n })\n }\n\n const isBlob = requestData.headers.get('x-neemata-blob') === 'true'\n\n const contentType = requestData.headers.get('content-type')\n const acceptType = requestData.headers.get('accept')\n const connectionId = randomUUID()\n const connection = new Connection<WsConnectionData>({\n id: connectionId,\n data: { type: 'http' },\n })\n const responseHeaders = new Headers()\n const container = this.context.container.fork(Scope.Call)\n container.provide(ProtocolInjectables.connection, connection)\n container.provide(WsTransportInjectables.connectionData, requestData)\n container.provide(\n WsTransportInjectables.httpResponseHeaders,\n responseHeaders,\n )\n\n const body = method === 'post' ? getRequestBody(res) : undefined\n\n const metadata: ProtocolApiCallOptions['metadata'] = (metadata) => {\n const allowHttpMethod =\n metadata.get(AllowedHttpMethod) ?? DEFAULT_ALLOWED_METHODS\n if (!allowHttpMethod.includes(method)) {\n throw new ProtocolError(ErrorCode.NotFound)\n }\n }\n let format: ReturnType<typeof getFormat>\n try {\n format = getFormat(this.context.format, {\n acceptType,\n contentType: isBlob ? '*/*' : contentType,\n })\n\n let payload: any\n\n if (body) {\n if (isBlob) {\n const type = contentType || 'application/octet-stream'\n const contentLength = requestData.headers.get('content-length')\n const size = contentLength\n ? Number.parseInt(contentLength)\n : undefined\n const stream = new ProtocolClientStream(-1, { size, type })\n body.pipe(stream)\n payload = stream\n } else {\n const buffer = await readableToArrayBuffer(body)\n if (buffer.byteLength > 0) {\n payload = format.decoder.decode(buffer)\n }\n }\n }\n\n const result = await this.protocol.call({\n connection,\n namespace,\n procedure,\n payload,\n metadata,\n container,\n signal: ac.signal,\n })\n\n if (isIterableResult(result) || isSubscriptionResult(result)) {\n res.cork(() => {\n if (ac.signal.aborted) return\n const status = HttpCode.NotImplemented\n const text = HttpStatusText[status]\n res.writeStatus(`${status} ${text}`)\n res.end()\n })\n } else {\n const { output } = result\n\n if (output instanceof ProtocolBlob) {\n const { source, metadata } = output\n const { type } = metadata\n\n let stream: Readable\n\n if (source instanceof ReadableStream) {\n stream = Readable.fromWeb(source as any)\n } else if (source instanceof Readable || source instanceof Duplex) {\n stream = Readable.from(source)\n } else {\n throw new Error('Invalid stream source')\n }\n\n res.cork(() => {\n if (ac.signal.aborted) return\n responseHeaders.set('X-Neemata-Blob', 'true')\n responseHeaders.set('Content-Type', type)\n if (metadata.size)\n res.writeHeader('Content-Length', metadata.size.toString())\n setHeaders(res, responseHeaders)\n })\n\n ac.signal.addEventListener('abort', () => stream.destroy(), {\n once: true,\n })\n\n stream.on('data', (chunk) => {\n if (ac.signal.aborted) return\n const buf = Buffer.from(chunk)\n const ab = buf.buffer.slice(\n buf.byteOffset,\n buf.byteOffset + buf.byteLength,\n )\n const ok = res.write(ab)\n if (!ok) {\n stream.pause()\n res.onWritable(() => {\n stream.resume()\n return true\n })\n }\n })\n await once(stream, 'end')\n if (stream.readableAborted) {\n res.end(undefined, true)\n } else {\n res.end()\n }\n } else {\n res.cork(() => {\n if (ac.signal.aborted) return\n const status = HttpCode.OK\n const text = HttpStatusText[status]\n const buffer = format.encoder.encode(output)\n res.writeStatus(`${status} ${text}`)\n responseHeaders.set('Content-Type', format.encoder.contentType)\n setHeaders(res, responseHeaders)\n res.end(buffer)\n })\n }\n }\n } catch (error) {\n if (ac.signal.aborted) return\n if (error instanceof UnsupportedFormatError) {\n res.cork(() => {\n if (ac.signal.aborted) return\n const status =\n error instanceof UnsupportedContentTypeError\n ? HttpCode.UnsupportedMediaType\n : HttpCode.NotAcceptable\n const text = HttpStatusText[status]\n res.writeStatus(`${status} ${text}`)\n res.end()\n })\n } else if (error instanceof ProtocolError) {\n res.cork(() => {\n if (ac.signal.aborted) return\n const status =\n error.code in HttpCodeMap\n ? HttpCodeMap[error.code]\n : HttpCode.InternalServerError\n const text = HttpStatusText[status]\n res.writeStatus(`${status} ${text}`)\n res.end(format!.encoder.encode(error))\n })\n } else {\n this.logError(error, 'Unknown error while processing request')\n res.cork(() => {\n if (ac.signal.aborted) return\n const status = HttpCode.InternalServerError\n const text = HttpStatusText[status]\n const payload = format!.encoder.encode(\n new ProtocolError(\n ErrorCode.InternalServerError,\n 'Internal Server Error',\n ),\n )\n res.writeStatus(`${status} ${text}`)\n res.end(payload)\n })\n }\n } finally {\n container.dispose().catch((error) => {\n this.logError(error, 'Error while disposing call container')\n })\n }\n }\n\n protected get protocol() {\n return this.context.protocol\n }\n\n protected get logger() {\n return this.context.logger\n }\n\n protected async logError(\n cause: any,\n message = 'Unknown error while processing request',\n ) {\n this.logger.error(new Error(message, { cause }))\n }\n\n protected applyCors(res: HttpResponse, req: HttpRequest) {\n if (this.options.cors === false) return\n\n const origin = req.getHeader('origin')\n if (!origin) return\n\n let allowed = false\n\n if (this.options.cors === undefined || this.options.cors === true) {\n allowed = true\n } else if (Array.isArray(this.options.cors)) {\n allowed = this.options.cors.includes(origin)\n } else {\n allowed = this.options.cors(origin)\n }\n\n if (!allowed) return\n\n res.writeHeader('Access-Control-Allow-Origin', origin)\n res.writeHeader('Access-Control-Allow-Headers', 'Content-Type')\n res.writeHeader('Access-Control-Allow-Methods', 'GET, POST')\n res.writeHeader('Access-Control-Allow-Credentials', 'true')\n }\n\n protected [ClientMessageType.Rpc](\n ws: WsTransportSocket,\n buffer: ArrayBuffer,\n ) {\n const { id } = ws.getUserData()\n this.protocol.rpcRaw(id, buffer)\n }\n\n protected [ClientMessageType.RpcAbort](\n ws: WsTransportSocket,\n buffer: ArrayBuffer,\n ) {\n const { id } = ws.getUserData()\n this.protocol.rpcAbortRaw(id, buffer)\n }\n\n protected [ClientMessageType.RpcStreamAbort](\n ws: WsTransportSocket,\n buffer: ArrayBuffer,\n ) {\n const { id } = ws.getUserData()\n this.protocol.rpcStreamAbortRaw(id, buffer)\n }\n\n protected [ClientMessageType.ClientStreamPush](\n ws: WsTransportSocket,\n buffer: ArrayBuffer,\n ) {\n const { id } = ws.getUserData()\n const streamId = decodeNumber(buffer, 'Uint32')\n this.protocol.pushClientStream(\n id,\n streamId,\n buffer.slice(Uint32Array.BYTES_PER_ELEMENT),\n )\n }\n\n protected [ClientMessageType.ClientStreamEnd](\n ws: WsTransportSocket,\n buffer: ArrayBuffer,\n ) {\n const { id } = ws.getUserData()\n const streamId = decodeNumber(buffer, 'Uint32')\n this.protocol.endClientStream(id, streamId)\n }\n\n protected [ClientMessageType.ClientStreamAbort](\n ws: WsTransportSocket,\n buffer: ArrayBuffer,\n ) {\n const { id } = ws.getUserData()\n const streamId = decodeNumber(buffer, 'Uint32')\n this.protocol.abortClientStream(id, streamId)\n }\n\n protected [ClientMessageType.ServerStreamPull](\n ws: WsTransportSocket,\n buffer: ArrayBuffer,\n ) {\n const { id } = ws.getUserData()\n const streamId = decodeNumber(buffer, 'Uint32')\n this.protocol.pullServerStream(id, streamId)\n }\n\n protected [ClientMessageType.ServerStreamAbort](\n ws: WsTransportSocket,\n buffer: ArrayBuffer,\n ) {\n const { id } = ws.getUserData()\n const streamId = decodeNumber(buffer, 'Uint32')\n this.protocol.abortServerStream(id, streamId)\n }\n}\n"],"version":3,"file":"server.js"}
|
package/dist/utils.js
CHANGED
package/dist/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"mappings":"AACA,SAAS,mBAAkC,aAAa;AACxD,SAAS,qBAAqB,eAAe;AAC7C,SAAS,QAAQ,WAAW,oBAAoB,iBAAiB;AACjE,SAAS,qBAAqB,wBAAwB;AAGtD,OAAO,MAAM,OAAO,CAClBA,IACAC,MACA,GAAG,YACgB;CACnB,MAAM,OAAO,GAAG,aAAa;AAC7B,KAAI;EACF,MAAM,SAAS,OAAO,aAAa,MAAM,QAAQ,EAAE,GAAG,QAAQ;EAC9D,MAAM,SAAS,GAAG,KAAK,QAAQ,KAAK;AACpC,MAAI,WAAW,GAAG;AAChB,QAAK,eAAe,eAAe;AACnC,UAAO;EACR;AACD,MAAI,WAAW,GAAG;AAChB,UAAO;EACR;AACD,SAAO;CACR,
|
|
1
|
+
{"mappings":"AACA,SAAS,mBAAkC,aAAa;AACxD,SAAS,qBAAqB,eAAe;AAC7C,SAAS,QAAQ,WAAW,oBAAoB,iBAAiB;AACjE,SAAS,qBAAqB,wBAAwB;AAGtD,OAAO,MAAM,OAAO,CAClBA,IACAC,MACA,GAAG,YACgB;CACnB,MAAM,OAAO,GAAG,aAAa;AAC7B,KAAI;EACF,MAAM,SAAS,OAAO,aAAa,MAAM,QAAQ,EAAE,GAAG,QAAQ;EAC9D,MAAM,SAAS,GAAG,KAAK,QAAQ,KAAK;AACpC,MAAI,WAAW,GAAG;AAChB,QAAK,eAAe,eAAe;AACnC,UAAO;EACR;AACD,MAAI,WAAW,GAAG;AAChB,UAAO;EACR;AACD,SAAO;CACR,QAAO;AACN,SAAO;CACR;AACF;AAED,OAAO,MAAM,WAAW,CAACC,UAEnB;CACJ,MAAMC,MAA8B,CAAE;AACtC,OAAM,QAAQ,CAAC,OAAO,QAAQ;AAC5B,MAAI,OAAO;CACZ,EAAC;AACF,QAAO;AACR;AAaD,OAAO,MAAM,iBAAiB,CAC5BC,KACAC,QACgB;CAChB,MAAM,MAAM,IAAI,QAAQ;CACxB,MAAM,SAAS,IAAI,WAAW;CAC9B,MAAM,UAAU,IAAI;CACpB,MAAM,cAAc,IAAI,UAAU;CAClC,MAAM,QAAQ,IAAI,gBAAgB;CAClC,MAAM,SAAS,QAAQ,IAAI,SAAS;CACpC,MAAM,uBAAuB,IAAI,+BAA+B;CAChE,MAAM,gBAAgB,IAAI,wBAAwB;AAElD,KAAI,QAAQ,CAAC,KAAK,UAAU,QAAQ,OAAO,KAAK,MAAM,CAAC;AAEvD,QAAO,OAAO,OAAO;EACnB;EACA,QAAQ,SAAS,IAAI,IAAI,KAAK,UAAU;EACxC;EACA;EACA;EACA;EACA,eAAe,OAAO,KAAK,cAAc,CAAC,UAAU;EACpD,sBAAsB,OAAO,KAAK,qBAAqB,CAAC,UAAU;CACnE,EAAC;AACH;AAED,OAAO,SAAS,eAAeA,KAAmB;CAChD,MAAM,SAAS,IAAI;AACnB,KAAI,OAAO,CAAC,OAAO,WAAW;AAC5B,SAAO,MAAM,OAAO,KAAK,MAAM,CAAC;AAChC,MAAI,OAAQ,QAAO,KAAK;CACzB,EAAC;AACF,KAAI,UAAU,MAAM,OAAO,SAAS,CAAC;AACrC,QAAO;AACR;AAED,OAAO,SAAS,WAAWA,KAAmBC,SAAkB;AAC9D,SAAQ,QAAQ,CAAC,OAAO,QAAQ;AAC9B,MAAI,QAAQ,aAAc;AAC1B,MAAI,YAAY,KAAK,MAAM;CAC5B,EAAC;CACF,MAAM,UAAU,QAAQ,cAAc;AACtC,KAAI,SAAS;AACX,OAAK,MAAM,UAAU,SAAS;AAC5B,OAAI,YAAY,cAAc,OAAO;EACtC;CACF;AACF;AAED,OAAO,SAAS,sBAAsBC,QAAwC;AAC5E,QAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;EACtC,MAAMC,SAAmB,CAAE;AAC3B,SAAO,GAAG,QAAQ,CAAC,UAAU;AAC3B,UAAO,KAAK,MAAM;EACnB,EAAC;AACF,SAAO,GAAG,OAAO,MAAM;AACrB,WAAQ,OAAO,OAAO,OAAO,CAAC,OAAO;EACtC,EAAC;AACF,SAAO,GAAG,SAAS,CAAC,UAAU;AAC5B,UAAO,MAAM;EACd,EAAC;CACH;AACF;AAED,OAAO,MAAM,gBAAgB,CAAC,UAAU,4BACtC,IAAI,cAAc,UAAU,qBAAqB;AAEnD,OAAO,MAAM,gBAAgB,CAAC,UAAU,gBACtC,IAAI,cAAc,UAAU,UAAU;AAExC,OAAO,MAAM,iBAAiB,CAAC,UAAU,gBACvC,IAAI,cAAc,UAAU,WAAW;AAEzC,OAAO,MAAM,sBAAsB,CAAC,UAAU,sBAC5C,IAAI,cAAc,UAAU,gBAAgB","names":["ws: WsTransportSocket","type: number","input: {\n forEach: (cb: (value, key) => void) => void\n}","obj: Record<string, string>","req: HttpRequest","res: HttpResponse","headers: Headers","stream: Readable","chunks: Buffer[]"],"sources":["../src/utils.ts"],"sourcesContent":["import type { HttpRequest, HttpResponse } from 'uWebSockets.js'\nimport { PassThrough, type Readable } from 'node:stream'\nimport { createPromise } from '@nmtjs/common'\nimport { concat, ErrorCode, encodeNumber } from '@nmtjs/protocol'\nimport { ProtocolError } from '@nmtjs/protocol/server'\nimport type { WsTransportSocket } from './types.ts'\n\nexport const send = (\n ws: WsTransportSocket,\n type: number,\n ...buffers: ArrayBuffer[]\n): boolean | null => {\n const data = ws.getUserData()\n try {\n const buffer = concat(encodeNumber(type, 'Uint8'), ...buffers)\n const result = ws.send(buffer, true)\n if (result === 0) {\n data.backpressure = createPromise()\n return false\n }\n if (result === 2) {\n return null\n }\n return true\n } catch {\n return null\n }\n}\n\nexport const toRecord = (input: {\n forEach: (cb: (value, key) => void) => void\n}) => {\n const obj: Record<string, string> = {}\n input.forEach((value, key) => {\n obj[key] = value\n })\n return obj\n}\n\nexport type RequestData = Readonly<{\n url: string\n origin: URL | null\n method: string\n headers: Headers\n querystring: string\n query: URLSearchParams\n remoteAddress: string\n proxiedRemoteAddress: string\n}>\n\nexport const getRequestData = (\n req: HttpRequest,\n res: HttpResponse,\n): RequestData => {\n const url = req.getUrl()\n const method = req.getMethod()\n const headers = new Headers()\n const querystring = req.getQuery()\n const query = new URLSearchParams(querystring)\n const origin = headers.get('origin')\n const proxiedRemoteAddress = res.getProxiedRemoteAddressAsText()\n const remoteAddress = res.getRemoteAddressAsText()\n\n req.forEach((key, value) => headers.append(key, value))\n\n return Object.freeze({\n url,\n origin: origin ? new URL(url, origin) : null,\n method,\n headers,\n querystring,\n query,\n remoteAddress: Buffer.from(remoteAddress).toString(),\n proxiedRemoteAddress: Buffer.from(proxiedRemoteAddress).toString(),\n })\n}\n\nexport function getRequestBody(res: HttpResponse) {\n const stream = new PassThrough()\n res.onData((chunk, isLast) => {\n stream.write(Buffer.from(chunk))\n if (isLast) stream.end()\n })\n res.onAborted(() => stream.destroy())\n return stream\n}\n\nexport function setHeaders(res: HttpResponse, headers: Headers) {\n headers.forEach((value, key) => {\n if (key === 'set-cookie') return\n res.writeHeader(key, value)\n })\n const cookies = headers.getSetCookie()\n if (cookies) {\n for (const cookie of cookies) {\n res.writeHeader('set-cookie', cookie)\n }\n }\n}\n\nexport function readableToArrayBuffer(stream: Readable): Promise<ArrayBuffer> {\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = []\n stream.on('data', (chunk) => {\n chunks.push(chunk)\n })\n stream.on('end', () => {\n resolve(Buffer.concat(chunks).buffer)\n })\n stream.on('error', (error) => {\n reject(error)\n })\n })\n}\n\nexport const InternalError = (message = 'Internal Server Error') =>\n new ProtocolError(ErrorCode.InternalServerError, message)\n\nexport const NotFoundError = (message = 'Not Found') =>\n new ProtocolError(ErrorCode.NotFound, message)\n\nexport const ForbiddenError = (message = 'Forbidden') =>\n new ProtocolError(ErrorCode.Forbidden, message)\n\nexport const RequestTimeoutError = (message = 'Request Timeout') =>\n new ProtocolError(ErrorCode.RequestTimeout, message)\n"],"version":3,"file":"utils.js"}
|
package/package.json
CHANGED
|
@@ -11,15 +11,15 @@
|
|
|
11
11
|
"uWebSockets.js": "github:uNetworking/uWebSockets.js#v20.51.0"
|
|
12
12
|
},
|
|
13
13
|
"peerDependencies": {
|
|
14
|
-
"@nmtjs/
|
|
15
|
-
"@nmtjs/
|
|
16
|
-
"@nmtjs/
|
|
14
|
+
"@nmtjs/common": "0.10.3",
|
|
15
|
+
"@nmtjs/protocol": "0.10.3",
|
|
16
|
+
"@nmtjs/core": "0.10.3"
|
|
17
17
|
},
|
|
18
18
|
"devDependencies": {
|
|
19
19
|
"@types/node": "^18",
|
|
20
|
-
"@nmtjs/
|
|
21
|
-
"@nmtjs/
|
|
22
|
-
"@nmtjs/
|
|
20
|
+
"@nmtjs/common": "0.10.3",
|
|
21
|
+
"@nmtjs/protocol": "0.10.3",
|
|
22
|
+
"@nmtjs/client": "0.10.3"
|
|
23
23
|
},
|
|
24
24
|
"engines": {
|
|
25
25
|
"node": ">=18"
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"LICENSE.md",
|
|
31
31
|
"README.md"
|
|
32
32
|
],
|
|
33
|
-
"version": "0.10.
|
|
33
|
+
"version": "0.10.3",
|
|
34
34
|
"scripts": {
|
|
35
35
|
"build": "neemata-build --root ./src './**/*.ts'",
|
|
36
36
|
"type-check": "tsc --noEmit"
|
package/src/server.ts
CHANGED
|
@@ -272,7 +272,7 @@ export class WsTransportServer implements Transport<WsConnectionData> {
|
|
|
272
272
|
contentType: isBlob ? '*/*' : contentType,
|
|
273
273
|
})
|
|
274
274
|
|
|
275
|
-
let payload: any
|
|
275
|
+
let payload: any
|
|
276
276
|
|
|
277
277
|
if (body) {
|
|
278
278
|
if (isBlob) {
|
|
@@ -341,7 +341,6 @@ export class WsTransportServer implements Transport<WsConnectionData> {
|
|
|
341
341
|
})
|
|
342
342
|
|
|
343
343
|
stream.on('data', (chunk) => {
|
|
344
|
-
console.log({ chunk })
|
|
345
344
|
if (ac.signal.aborted) return
|
|
346
345
|
const buf = Buffer.from(chunk)
|
|
347
346
|
const ab = buf.buffer.slice(
|