{"id":18634143,"url":"https://github.com/nathandraco22/zaptools-dart","last_synced_at":"2026-01-11T04:11:41.889Z","repository":{"id":61975065,"uuid":"463739974","full_name":"NathanDraco22/zaptools-dart","owner":"NathanDraco22","description":"A toolkit for Event-Driven websocket management","archived":false,"fork":false,"pushed_at":"2024-05-29T03:15:42.000Z","size":139,"stargazers_count":11,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-05-29T16:07:28.159Z","etag":null,"topics":["dart","flutter","websocket","websocket-server","websockets"],"latest_commit_sha":null,"homepage":"","language":"Dart","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/NathanDraco22.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"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":"2022-02-26T03:11:23.000Z","updated_at":"2024-07-15T00:37:09.826Z","dependencies_parsed_at":"2023-12-10T21:25:18.867Z","dependency_job_id":"d81c5b8e-4e17-4816-b509-4f62239225a0","html_url":"https://github.com/NathanDraco22/zaptools-dart","commit_stats":null,"previous_names":["nathandraco22/zap-client-dart"],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NathanDraco22%2Fzaptools-dart","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NathanDraco22%2Fzaptools-dart/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NathanDraco22%2Fzaptools-dart/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NathanDraco22%2Fzaptools-dart/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/NathanDraco22","download_url":"https://codeload.github.com/NathanDraco22/zaptools-dart/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223460823,"owners_count":17148834,"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":["dart","flutter","websocket","websocket-server","websockets"],"created_at":"2024-11-07T05:17:28.338Z","updated_at":"2026-01-11T04:11:41.836Z","avatar_url":"https://github.com/NathanDraco22.png","language":"Dart","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ch1 align=\"center\"\u003eZaptools\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"assets/zaptools-logo-150.png\" /\u003e\n  \u003ch3 align=\"center\"\u003e\n    A toolkit for Event-Driven websocket management\n  \u003ch3\u003e\n\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://pub.dev/packages/zaptools_client\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/client-0.4.0-blue?logo=flutter\" alt=\"Client Version\" /\u003e\n  \u003c/a\u003e\n    \u003ca href=\"https://pub.dev/packages/zaptools_server\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/server-0.3.0-blue?logo=dart\" alt=\"Server Version\" /\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://github.com/invertase/melos\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/maintained%20with-melos-f700ff.svg?style=flat-square\" alt=\"Maintained with Melos\" /\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n## Packages\n\n| Name      | View Source                                                                                           |\n|-----------|:------------------------------------------------------------------------------------------------------|\n| Client    | [`zaptools_client`](https://github.com/NathanDraco22/zaptools-dart/tree/main/packages/zaptools_client)|\n| Server    | [`zaptools_server`](https://github.com/NathanDraco22/zaptools-dart/tree/main/packages/zaptools_server)|\n\n### Also Supported\n| Lang               |Side  |View Source                                                                                           |\n|:------------------:|:----:|:------------------------------------------------------------------------------------------------------|\n|\u003ca href=\"https://www.python.org\" target=\"_blank\"\u003e \u003cimg src=\"https://upload.wikimedia.org/wikipedia/commons/archive/c/c3/20220730085403%21Python-logo-notext.svg\" alt=\"python\" width=\"25\" height=\"25\"/\u003e \u003c/a\u003e| Server |[`zaptools_python`](https://github.com/NathanDraco22/zaptools-python)|\n\n## Getting started\n\nZaptools provides tools for building event-driven websocket integration. It is built on top websocket.\n\n## Usage\n\n**Server**\n\n```dart\n  final app = ZapServer();\n\n  app.onConnected((context) {\n    // when a new client joined\n    print(\"client connected\");\n  });\n\n  app.onDisconnected((context) {\n    // when a client left\n    print(\"client disconnected!\");\n  });\n\n  app.onEvent(\"myEvent\", (context) {\n    // When the event \"myEvent\" is received\n    print(\"fire!\");\n   });\n\n  final server = await app.start();\n  print(\"listen on -\u003e ${server.port}\");\n```\n\n**Client (based on callbacks)**\n\n```dart\n  final zConsumer = ZapConsumer('ws://127.0.0.1:8000/')..connect();\n\n  zConsumer.onConnected((eventData) {\n    print('connected!');\n  });\n\n  zConsumer.onDisconnected((eventData) {\n    print('disconnected!');\n  });\n\n  zConsumer.onEvent(\"myEvent\", (eventData) { \n    print(\"myEvent Received\");\n  });\n\n\n```\n\n### Integrating with other frameworks (Server Side)\n\nZaptools can integrate with other frameworks that exposes the `HttpRequest` object of the `Dart:io` library, like Alfred framework.\n\n[**Alfred**](https://github.com/rknell/alfred)\n```dart\n  final app = Alfred();\n\n  final reg = EventRegister();\n\n  reg.onConnected((contexts) {\n    // when a new client joined\n    print(\"client connected\");\n  });\n\n  reg.onDisconnected((context) {\n    // when a client left\n    print(\"client disconnected!\");\n  });\n\n  reg.onEvent(\"myEvent\", (context) {\n    // When a event the event \"myEvent\" is received\n    print(\"fire!\");\n   });\n\n  app.get(\"/ws\", (HttpRequest req, HttpResponse res) {\n    plugAndStartWithIO(req, reg);\n  });\n```\n[Alfred](https://github.com/rknell/alfred) is a great framework to make server side apps with dart.\n\n`EventRegister` has responsability to create events.\n`plugAndStartWithIO` connect the `HttpRequest` with the `EventRegister` instance and upgrade the connection to websocket.\n\nIt planning to add Shelf and Frog support in the future.\n\n**EventContext**\n\nThe `EventContext` object has the information about the current event, the `EventData` and the `WebSocketConnection` it is invoking the event.\n\n```dart\n    context.connection; // WebSocketConnection\n    context.eventName; // name of the event\n    context.payload; // payload of this event invoking\n    context.headers; // headers of this event invoking\n```\n\n`connection` property is a instance of `WebSocketConnection` it has an `id` and is able to `send` and `close` the connection with the client.\n```dart\n    context.connection.id; //connection identifier\n    context.connection.send(\"eventName\", \"payload\"); // send to client\n    context.connection.close(); // close the connection\n```\n\u003e Executing `send` or `close` method in `onDisconnected` event it will throw an `Unhandled Error`\n\n### Client Usage\n\nIn order to get a connection with the server, `zaptools-dart` provides two clients: based on callbacks and based on streams.\n\n`ZapConsumer` trigger a callback when a event is invoked\n\n```dart\n  final zConsumer = ZapConsumer('ws://127.0.0.1:8000/')..connect();\n\n  zConsumer.onConnected((eventData) {\n    print('connected!');\n  });\n\n  zConsumer.onDisconnected((eventData) {\n    print('disconnected!');\n  });\n\n  zConsumer.onEvent(\"myEvent\", (eventData) { \n    print(\"myEvent Received\");\n  });\n\n```\n\n`ZapSubscriber` provides a `Stream` of `ConnectionState` enum and a `Stream` of event received. You can subscribe to specfic event or a group of event or to all event.\n\n```dart\n  final zSubscriber = ZapSubscriber(\"ws://127.0.0.1:8000/\")..connect();\n\n  zSubscriber.connectionState.listen((event) {\n    if (event case ConnectionState.online) {\n      print(\"connected!\"); \n    }\n    if (event case ConnectionState.offline) {\n      print(\"disconnected!\"); \n    }\n  });\n\n  zSubscriber.subscribeToEvent(\"myEVent\").listen((eventData){\n    print(\"event received!\");\n    // listen when 'myEvent' is received.\n  });\n\n  zSubscriber.subscribeToEvents([\"myEvent\", \"myOtherEvent\"]).listen((event) { \n    print(\"a event is received\");\n    // listen when 'myEvent' or 'myOtherEvent' are received.\n  });\n\n  zSubscriber.subscribeToAllEvent().listen((event) {\n    print(\"whatever is received!\");\n    // listen all events \n  });\n```\n\u003e remember `cancel` stream subscription if you don't need anymore\n\n**Sending Event**\n\nBoth `ZapConsumer` and `ZapSubscriber` can send events to the servir by the method `send`\n\n```dart\nzSubscriber.sendEvent(\"eventName\", \"payload\");\n\nzConsumer.sendEvent(\"eventName\", \"payload\");\n```\n**Connect and Disconnect**\n\n`connect` method is used for both intitial connections and reconnections to the server in case connection lost.\n```dart\nzConsumer.connect();\nzSubscriber.connect();\n```\n\n`disconnect` method, close the websocket connection with the server.\n```dart\nzConsumer.disconnect();\nzSubscriber.disconnect();\n```\n\n\n**clean**\n\nWhen you call `disconnect` method in a `ZapSubscriber` you close the webosocket connection but the `ZapSubscriber` still await events to emits. If for some reason `ZapSubscriber` is disconnected from a websocket, calling the `connect` method `ZapSubscriber` will reconnect with the websocket and can emit the events received from the server, this prevents to create new subscription and prevent event duplicate in case of connection issue.\n\n```dart\n  final zSubscriber = ZapSubscriber(\"ws://127.0.0.1:8000/\")..connect();\n\n  zSubscriber.connectionState.listen((event) {\n    // code here\n    // still received event after reconnect\n  });\n\n  zSubscriber.subscribeToEvent(\"myEVent\").listen((eventData){\n    // code here\n    // still received event after reconnect\n  });\n\n  zSubscriber.disconnect();\n\n  zSubscriber.connect();\n```\n\nIf you want to close completly the `ZapSubscriber` call method `clean`, this close and clean the connection with websocket into the `ZapSubscriber`.\n\n```dart\n  final zSubscriber = ZapSubscriber(\"ws://127.0.0.1:8000/\")..connect();\n\n\n  zSubscriber.connectionState.listen((event) {\n    // code here\n    // No received event after clean\n  });\n\n  zSubscriber.subscribeToEvent(\"myEVent\").listen((eventData){\n    // code here\n    // No received event after clean\n  });\n\n  zSubscriber.clean(); // all subscriptions \"done\"\n```\n\u003e **Important: cancel all `StreamSuscription`**\n\n### Contributions are wellcome!\n\n#### What's Next?\n- [x] event management.\n- [ ] comunication between clients.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnathandraco22%2Fzaptools-dart","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnathandraco22%2Fzaptools-dart","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnathandraco22%2Fzaptools-dart/lists"}