{"id":20277526,"url":"https://github.com/udamir/wsapix","last_synced_at":"2025-04-11T05:50:40.771Z","repository":{"id":36970341,"uuid":"389671049","full_name":"udamir/wsapix","owner":"udamir","description":"Next generation Websocket framework for nodejs","archived":false,"fork":false,"pushed_at":"2025-03-04T05:27:52.000Z","size":1432,"stargazers_count":27,"open_issues_count":2,"forks_count":2,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-25T03:51:15.724Z","etag":null,"topics":["api","asyncapi","pubsub","rpc","uwebsockets","uwebsocketsjs","websocket","ws"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/udamir.png","metadata":{"files":{"readme":"readme.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"code-of-conduct.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-07-26T14:57:15.000Z","updated_at":"2025-01-23T08:19:07.000Z","dependencies_parsed_at":"2023-10-02T05:30:20.282Z","dependency_job_id":"8bc55063-e553-4a64-8182-f33c1b5eeeb9","html_url":"https://github.com/udamir/wsapix","commit_stats":{"total_commits":202,"total_committers":2,"mean_commits":101.0,"dds":"0.44059405940594054","last_synced_commit":"c19bdd0c5dd9547b84c4cc1f0f3daaa02ee72e27"},"previous_names":[],"tags_count":23,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/udamir%2Fwsapix","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/udamir%2Fwsapix/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/udamir%2Fwsapix/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/udamir%2Fwsapix/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/udamir","download_url":"https://codeload.github.com/udamir/wsapix/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248190403,"owners_count":21062276,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","asyncapi","pubsub","rpc","uwebsockets","uwebsocketsjs","websocket","ws"],"created_at":"2024-11-14T13:18:48.995Z","updated_at":"2025-04-11T05:50:40.751Z","avatar_url":"https://github.com/udamir.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Wsapix\n\u003cimg alt=\"npm\" src=\"https://img.shields.io/npm/v/wsapix\"\u003e \u003cimg alt=\"npm type definitions\" src=\"https://img.shields.io/npm/types/wsapix\"\u003e \u003cimg alt=\"NPM\" src=\"https://img.shields.io/npm/l/wsapix\"\u003e\n\nNext generation Websocket framework for nodejs\n\n## Summary\nWsapix provides to you:\n- Channel/message approach for websocket API \n- uWebsockets.js engine support \n- Middlewares and hooks support\n- Custom schema parser/serializer support\n- Message paylaod validation\n- AsyncAPI specification generation\n- Mock server with websocket client injection\n- Typescript syntax support out of the box\n\n# Quick start\n\n## Installation\n\n```\nnpm install --save wsapix\n```\n\n## Create websocket server over http(s) or uWebSockets\n\n```ts\nimport * as http from \"http\"\nimport { Wsapix } from \"wsapix\"\n\nconst server = new http.Server()\nconst wsx = Wsapix.WS({ server })\n\n// uWebSockets.js supported\n// import uWebSockets from \"uWebsockets.js\"\n//\n// const server = uWebSockets.App()\n// const wsx = Wsapix.uWS({ server })\n\ninterface IChatMessage {\n  type: \"chat:message\"\n  text: string\n}\n\n// handle messages from client with payload { type: \"chat:message\", ... }\nwsx.clientMessage({ type: \"chat:message\" }, (client: Client, data: IChatMessage) =\u003e {\n  // data - deserialized by JSON.Parse\n  \n  // JSON.stringify user for send payload \n  client.send({ type: \"echo\", text: data.text })\n})\n\nserver.listen(port, () =\u003e {\n  console.log(`Server listen port ${port}`)\n})\n\n```\n\n## Add auth middleware\n```ts\n\n// define client context state\ninterface IClientState {\n  userId: string\n}\n\nconst wsx = Wsapix.WS\u003cIClientState\u003e({ server })\n\n// connection hook middleware\nwsx.use((client: WsapixClient) =\u003e {\n  // check auth\n  const user = authUser(client.query)\n\n  // store user id in state \n  client.state.userId = data.userId\n})\n```\n\n## Add custom parser/serializer\nDefault message payload parser/serializer is JSON parse/stringify. \nWsapix support custom parser/serializer:\n\n```ts\nconst notepack = require(\"notepack.io\")\n\nconst wsx = Wsapix.WS({ server }, { \n  serializer: notepack.encode, \n  parser: notepack.decode\n})\n```\nParser/Serializer can be removed in any channel:\n```ts\nwsx.route(\"/raw\", { parser: null, serializer: null })\n\n```\n\n## Add payload validation\n\n```ts\nimport * as http from \"http\"\nimport Ajv from \"ajv\"\nimport { Wsapix } from \"wsapix\"\n\nconst ajv = new Ajv({ strict: false })\n\nconst wsx = Wsapix.WS({ server }, { \n  validator: (schema, data, error) =\u003e {\n    const valid = ajv.validate(schema)\n    if (!valid \u0026\u0026 ajv.errors) { \n      error \u0026\u0026 error(ajv.errors.map(({ message }) =\u003e message).join(\", \")) \n    }\n    return valid\n  }\n})\n\n// define message schema (for validation and documentation)\nconst chatMessageSchema = { \n  $id: \"chat:message\", // id for $ref\n  description: \"Message from user\",\n  payload: {\n    // Json schema\n    type: {\n      type: \"string\",\n      const: \"chat:message\"\n    },\n    text: {\n      type: \"string\"\n    }\n  },\n}\n\ninterface IChatMessage {\n  type: \"chat:message\"\n  text: string\n}\n\nwsx.clientMessage({ type: \"chat:message\" }, chatMessageSchema, (client: Client, data: IChatMessage) =\u003e {\n  // message handler\n})\n\nconst errorSchema = {\n  $id: \"error\", // id for $ref\n  description: \"Error message\", \n  payload: {\n    // Json schema\n    type: {\n      type: \"string\",\n      const: \"error\"\n    },\n    message: {\n      type: \"string\"\n    }\n  }\n}\n\n// define channel server message (for validation and documentation)\nwsx.serverMessage({ type: \"error\" }, errorSchema)\n\nwsx.onError((client, error) =\u003e {\n  // handle errors, incuding request validation errors\n  client.send({ type: \"error\", message: error })\n})\n```\n\n## Add channels\n```ts\nconst v1 = wsx.route(\"/v1\")\n\nv1.use(/* ... */)\nv1.clientMessage(/* ... */)\nv1.serverMessage(/* ... */)\n```\n\n## Add plugin\n```ts\n\nconst plugin = (wsx: Wsapix) =\u003e {\n  const v2 = wsx.route(\"/v2\")\n\n  v2.clientMessage(/* ... */)\n  v2.serverMessage(/* ... */)  \n}\n\nwsx.register(plugin)\n\n```\n\n## Generate AsyncApi schema\n\n```ts\nconst asyncApi = wsx.asyncapi({\n  info: {\n    version: \"1.0.0\",\n    title: \"Chat websocket API\"\n  }\n})\n```\n\n## Generate html documentation\n\n```ts\nconst html = wsx.htmlDocTemplate(\"/asyncapi\", \"Chat websocket API\")\n```\n\n## Testing\n\nWsapix comes with built-in Mock Transport and Fake WebSocket client injection:\n\n```ts\n// replace existing wsapix transport\nwsx.setTransport(new MockTransport())\n\n// or create wsapix server with mock transport\n// const wsx = new Wsapix(new MockTransport())\n\nconst ws1 = mwx.inject(\"/v1?token=12345\")\n\n// handle server messages\nws1.onmessage = ({ data }) =\u003e {\n  // decode message from server\n  const message = notepack.decode(data)\n  \n  // handle server message\n  if (message.type === \"error\") {\n    // ...\n  }\n}\n\n// encode and send message to injected client\nws1.send(notepack.encode({ type: \"chat:message\", chatId, text: \"Hello\" }))\n\n// close connection\nws1.close()\n```\n\n# License\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fudamir%2Fwsapix","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fudamir%2Fwsapix","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fudamir%2Fwsapix/lists"}