{"id":15140892,"url":"https://github.com/repcomm/pubmarine","last_synced_at":"2026-01-20T00:04:35.998Z","repository":{"id":205170949,"uuid":"713071829","full_name":"RepComm/pubmarine","owner":"RepComm","description":"ephemeral pub/sub for web,lua over websocket or udp","archived":false,"fork":false,"pushed_at":"2023-11-10T02:40:45.000Z","size":5224,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2024-10-29T22:02:23.319Z","etag":null,"topics":["api","client","ephemeral","lua","luasocket","minetest","mod","pubsub","server","udp","web","websocket"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/RepComm.png","metadata":{"files":{"readme":"ReadMe.md","changelog":null,"contributing":null,"funding":null,"license":null,"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":"2023-11-01T19:27:12.000Z","updated_at":"2023-11-10T02:42:56.000Z","dependencies_parsed_at":"2023-11-09T00:22:26.010Z","dependency_job_id":"262c8542-a664-4968-9899-6b480ab68cd7","html_url":"https://github.com/RepComm/pubmarine","commit_stats":null,"previous_names":["repcomm/pubmarine"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RepComm%2Fpubmarine","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RepComm%2Fpubmarine/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RepComm%2Fpubmarine/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RepComm%2Fpubmarine/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/RepComm","download_url":"https://codeload.github.com/RepComm/pubmarine/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247493038,"owners_count":20947638,"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","client","ephemeral","lua","luasocket","minetest","mod","pubsub","server","udp","web","websocket"],"created_at":"2024-09-26T08:42:12.557Z","updated_at":"2026-01-20T00:04:35.970Z","avatar_url":"https://github.com/RepComm.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# pubmarine\npublish/subscribe over websockets and UDP\n\n### WARNING: NOT PRODUCTION READY - RUN AT OWN RISK - API SUBJECT TO CHANGE\n\nAt one point I wanted to create a big fancy realtime decentralized database, but now I realize the scope is too big.\n\nI really need a pubish/subscribe networking lib for browser/node/lua, so this is it.\n\n![img](./example.gif)\n\n## implemented\n- pubmarine node.js server\n  - $ `npm i -g @repcomm/pubmarine`\n  - $ `pubmarine`\n- web client\n  - $ `npm i @repcomm/pubmarine`\n  - subscribe , mutate, listInstances, instance\n- lua client (currently married to minetest API, will be resolved soon)\n  - subscribe , mutate, instance\n\n## requirements\n - pubmarine server tested using `node -v` -\u003e v20.6.0\n - pubmarine ts/js client uses features:\n   - Set\n   - Map\n   - WebSocket\n   - class\n   - ES module import/export\n - pubmarine minetest tested using:\n   - minetest 5.7.0 (Linux)\n   - LuaJIT 2.1.0-beta3\n   - Release Mode\n   - luasocket from:\n     - ubuntu: `apt install lua5.1-sockets`\n     - fedora: `dnf install lua5.1-sockets`\n\n\n## usage\n### web\nSee [test.ts](./src/test.ts) and [test.html](./dst/test.html)\n\u003cdetails\u003e\n\u003csummary\u003eExample\u003c/summary\u003e\n\n```ts\n  import { Client } from \"@repcomm/pubmarine\";\n\n  //create a client that should connect to a server\n  const client = new Client(window.location.host);\n\n  //wait for connection\n  await client.connect();\n\n  //you can impl your own auth model (or none)\n  const auth = { apiKey: \"blah\" };\n  //wait for authentication\n  await client.authenticate(auth);\n\n  //check if player schema exists yet\n  if(!await client.hasSchema(\"players\")) {\n\n    //if it doesn't, try to create it\n    await client.createSchema(\"players\", {\n      type: \"dict\",\n      children: {\n        \"x\": { type: \"number\" },\n        \"y\": { type: \"number\" },\n        \"name\": { type: \"string\" }\n      }\n    });\n  }\n\n  await client.subscribe(\"players\",(instanceId, updateData, isNewInstance)=\u003e{\n    //fired for instantiations and mutations of all players\n  });\n  \n  //create an instance of player on the server\n  const localId = (await client.instance(\"players\")).response.id;\n  \n  //subscribe to mutations on only it\n  await client.subscribe({\n      topic: \"players\",\n      id: localId\n    }, ( id, updateData, isNewInstance)=\u003e{\n\n    //fired for mutations of our own player instance\n  });\n\n  //publish a change to our player data\n  //any chance you make is pushed to subscribers\n  await client.mutate(\"players\", localId, {\n    name: prompt(\"Enter player name\", \"testbot\"),\n    x: 0.5,\n    y: 0.5\n  });\n```\n\u003c/details\u003e\n\n### minetest lua\nSee [mt_pubmarine/init.lua](./mt_pubmarine/init.lua)\n\n## authentication\nNo security so far, this is one of the last TODOs for MVP\n\n```ts\n// TS/JS client side\nasync client.authenticate( a: ClientAuthReq )\n```\n\n`auth.js` is responsible for authenticating a client\n```ts\nimport type { MsgReq } from \"./common\";\n\n//server side\nexport async function auth (msg: MsgReq\u003cClientAuthReq\u003e): Promise\u003cstring\u003e {\n\n  //generate a random int as the client's ID\n  return Math.floor(Math.random() * Number.MAX_SAFE_INTEGER).toString();\n}\n```\n\n`auth.js` is monitored for changes and will be reloaded when ./dst/auth.js is mutated on the disk.\n\nIn the future, I will add a basic pocketbase authentication example.\n\n`ClientAuthReq` can be an object of any shape, the only places it is used are in the above files.\n\nEssentially to add in your own auth model simply change `auth.js` (auth.ts in the source of this repo compiles to it), and pass the correct shape to `client.authenticate( v )`\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frepcomm%2Fpubmarine","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frepcomm%2Fpubmarine","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frepcomm%2Fpubmarine/lists"}