{"_id":"y-crossws","_rev":"2-2ec6fe362ac11f79c5a52d7bb7bf4625","name":"y-crossws","dist-tags":{"latest":"0.0.2"},"versions":{"0.0.0":{"name":"y-crossws","version":"0.0.0","_id":"y-crossws@0.0.0","maintainers":[{"name":"pi0","email":"pyapar@gmail.com"}],"dist":{"shasum":"a3f5ec506cc8bb55d2d2d0a28eb342fa602f3854","tarball":"https://registry.npmjs.org/y-crossws/-/y-crossws-0.0.0.tgz","fileCount":1,"integrity":"sha512-/mGetttYW2E1XudEa7UOXNvidVOnR3GYeAfFEFhhqV4zMFY8YVdGAekaos8Dlr4q7LT5Fah+hD4XjBHcfdxP/A==","signatures":[{"sig":"MEUCIQDdnxEYneJPND1iab1tigj7/+/ytpCRiIkVASJEaPXtHAIgEuYEUVIj3K2xDUcon5L9nkgu/j/moAKoh2HZFUU5nd0=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":38},"_npmUser":{"name":"pi0","email":"pyapar@gmail.com"},"_npmVersion":"10.7.0","directories":{},"_nodeVersion":"20.15.1","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/y-crossws_0.0.0_1723631838593_0.4288248016755043","host":"s3://npm-registry-packages"}},"0.0.1":{"name":"y-crossws","version":"0.0.1","keywords":["yjs","unjs","crossws","websocket","server","node","deno","bun","cloudflare","workers"],"license":"MIT","_id":"y-crossws@0.0.1","maintainers":[{"name":"pi0","email":"pyapar@gmail.com"}],"homepage":"https://github.com/pi0/y-crossws#readme","bugs":{"url":"https://github.com/pi0/y-crossws/issues"},"dist":{"shasum":"4de3c3706441b0af2df037b0de09e1d3821bea41","tarball":"https://registry.npmjs.org/y-crossws/-/y-crossws-0.0.1.tgz","fileCount":9,"integrity":"sha512-XijB+9vJ01bdaC+S1mhdevLcg+xIBZXSwJ4YBZbZcq6lmmdfW2v2JY6WrDcfnNlNKk+T8Gvna/G9+d+RYpkgmg==","signatures":[{"sig":"MEUCIQCIYqLIG6zlXZlZ09T9UEZ6BbgXXaLNK1A7nl/LaPbmmAIgJxsm/ZkXaU7qd+EwZmxlp+20H61+m4xcbxevVzKujRk=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":33551},"main":"./dist/index.mjs","type":"module","types":"./dist/index.d.mts","module":"./dist/index.mjs","exports":{".":{"types":"./dist/index.d.mts","default":"./dist/index.mjs"},"./provider":{"types":"./dist/provider.d.mts","default":"./dist/provider.mjs"}},"gitHead":"16968b35ba253efbd2a918c1bc3c74df31983732","scripts":{"lint":"eslint . && prettier -c src playground","test":"pnpm lint && pnpm test:types","build":"unbuild","play:cf":"wrangler dev -c ./playground/wrangler.toml --port 3000","prepack":"pnpm build","release":"pnpm test && changelogen --release && npm publish && git push --follow-tags","lint:fix":"automd && eslint . --fix && prettier -w src playground","play:bun":"PORT=3000 bun run --watch ./playground/bun.ts","play:deno":"PORT=3000 deno run --unstable-byonm -A ./playground/deno.ts","play:node":"PORT=3000 jiti ./playground/node.ts","test:types":"tsc --noEmit --skipLibCheck"},"_npmUser":{"name":"pi0","email":"pyapar@gmail.com"},"repository":{"url":"git+https://github.com/pi0/y-crossws.git","type":"git"},"_npmVersion":"10.8.2","description":"yjs websocket server powered by crossws, works on Node.js, Deno, Bun, Cloudflare Workers and more without any framework dependency and compatible with unmodified y-websocket client provider.","directories":{},"sideEffects":false,"_nodeVersion":"20.17.0","dependencies":{"lib0":"^0.2.98","y-protocols":"^1.0.6"},"_hasShrinkwrap":false,"packageManager":"pnpm@9.12.0","devDependencies":{"ws":"^8.18.0","yjs":"^13.6.19","jiti":"^2.3.1","automd":"^0.3.10","eslint":"^9.12.0","crossws":"^0.3.1","unbuild":"^2.0.0","prettier":"^3.3.3","wrangler":"^3.80.0","@types/ws":"^8.5.12","typescript":"^5.6.2","@types/deno":"^2.0.0","@types/node":"^22.7.4","changelogen":"^0.5.7","eslint-config-unjs":"^0.4.1","@cloudflare/workers-types":"^4.20241004.0","@cloudflare/kv-asset-handler":"^0.3.4"},"peerDependencies":{"yjs":"^13.5.6","crossws":"^0.2.4"},"_npmOperationalInternal":{"tmp":"tmp/y-crossws_0.0.1_1728258110759_0.3298776025408108","host":"s3://npm-registry-packages"}},"0.0.2":{"name":"y-crossws","version":"0.0.2","description":"yjs websocket server powered by crossws, works on Node.js, Deno, Bun, Cloudflare Workers and more without any framework dependency and compatible with unmodified y-websocket client provider.","keywords":["yjs","unjs","crossws","websocket","server","node","deno","bun","cloudflare","workers"],"repository":{"type":"git","url":"git+https://github.com/pi0/y-crossws.git"},"license":"MIT","sideEffects":false,"type":"module","exports":{".":{"types":"./dist/index.d.mts","default":"./dist/index.mjs"},"./provider":{"types":"./dist/provider.d.mts","default":"./dist/provider.mjs"}},"main":"./dist/index.mjs","module":"./dist/index.mjs","types":"./dist/index.d.mts","scripts":{"build":"unbuild","lint":"eslint . && prettier -c src playground","lint:fix":"automd && eslint . --fix && prettier -w src playground","prepack":"pnpm build","play:bun":"PORT=3000 bun run --watch ./playground/bun.ts","play:cf":"wrangler dev -c ./playground/wrangler.toml --port 3000","play:deno":"PORT=3000 deno run --unstable-byonm -A ./playground/deno.ts","play:node":"PORT=3000 jiti ./playground/node.ts","release":"pnpm test && changelogen --release && npm publish && git push --follow-tags","test":"pnpm lint && pnpm test:types","test:types":"tsc --noEmit --skipLibCheck"},"dependencies":{"lib0":"^0.2.98","y-protocols":"^1.0.6"},"devDependencies":{"@cloudflare/kv-asset-handler":"^0.3.4","@cloudflare/workers-types":"^4.20241011.0","@types/deno":"^2.0.0","@types/node":"^22.7.6","@types/ws":"^8.5.12","automd":"^0.3.12","changelogen":"^0.5.7","crossws":">=0.2.0 <0.4.0","eslint":"^9.12.0","eslint-config-unjs":"^0.4.1","jiti":"^2.3.3","prettier":"^3.3.3","typescript":"^5.6.3","unbuild":"^2.0.0","wrangler":"^3.81.0","ws":"^8.18.0","yjs":"^13.6.20"},"peerDependencies":{"crossws":">=0.2.0 <0.4.0","yjs":"^13.5.6"},"packageManager":"pnpm@9.12.0","_id":"y-crossws@0.0.2","gitHead":"22fa9404e6495c8ae5d3e6d22437d2941baef9c8","bugs":{"url":"https://github.com/pi0/y-crossws/issues"},"homepage":"https://github.com/pi0/y-crossws#readme","_nodeVersion":"20.18.0","_npmVersion":"10.8.2","dist":{"integrity":"sha512-XUGrm8XhhtNaZJ1OX+QtdJG5YGjk71hNQdNlMiUsomIzNlPp0+WtZ4qxtVOXSbjhuJeR5w9EAn2hSCQvPeHFYA==","shasum":"892186a4b71b59281d6a26a9d741bb607fb45e5b","tarball":"https://registry.npmjs.org/y-crossws/-/y-crossws-0.0.2.tgz","fileCount":9,"unpackedSize":33567,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIEIKzJKCp7u8O0W3XneEpQGB8onzWGkKi9hvxLUkCOWEAiBv7tz9LEpFyrwRMRYpy7xcDgugcMrX19sMALC527xuxg=="}]},"_npmUser":{"name":"pi0","email":"pyapar@gmail.com"},"directories":{},"maintainers":[{"name":"pi0","email":"pyapar@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/y-crossws_0.0.2_1729274092515_0.8081634661464159"},"_hasShrinkwrap":false}},"time":{"created":"2024-08-14T10:37:18.593Z","modified":"2024-10-18T17:54:52.909Z","0.0.0":"2024-08-14T10:37:18.714Z","0.0.1":"2024-10-06T23:41:50.961Z","0.0.2":"2024-10-18T17:54:52.718Z"},"bugs":{"url":"https://github.com/pi0/y-crossws/issues"},"license":"MIT","homepage":"https://github.com/pi0/y-crossws#readme","keywords":["yjs","unjs","crossws","websocket","server","node","deno","bun","cloudflare","workers"],"repository":{"type":"git","url":"git+https://github.com/pi0/y-crossws.git"},"description":"yjs websocket server powered by crossws, works on Node.js, Deno, Bun, Cloudflare Workers and more without any framework dependency and compatible with unmodified y-websocket client provider.","maintainers":[{"name":"pi0","email":"pyapar@gmail.com"}],"readme":"# y-crossws\n\n<!-- automd:badges color=yellow -->\n\n[![npm version](https://img.shields.io/npm/v/y-crossws?color=yellow)](https://npmjs.com/package/y-crossws)\n[![npm downloads](https://img.shields.io/npm/dm/y-crossws?color=yellow)](https://npm.chart.dev/y-crossws)\n\n<!-- /automd -->\n\n[yjs](https://docs.yjs.dev/) websocket server powered by [crossws](https://crossws.unjs.io/), works with Node.js, Deno, Bun, Cloudflare Workers and more without any framework dependency and compatible with unmodified [y-websocket](https://github.com/yjs/y-websocket) client provider.\n\n> [!IMPORTANT]\n> 🚧 This is still a work in progress. Feedback and contributions are welcome!\n\n## 🍿 Demo\n\n[tiptap](https://tiptap.dev/) editor with collaborative editing deployed on Cloudflare workers with durable objects.\n\n- [online deployment](https://y-crossws.pi0.workers.dev/tiptap/)\n- [source code](./playground/)\n\n## Usage\n\nWe first need to initiate universal cross-hooks:\n\n```js\nimport { createHandler } from \"y-crossws\";\n\nconst crosswsHandler = createHandler();\n```\n\nDepending on your server choice, use any of the [crossws supported adapters](https://crossws.unjs.io/adapters).\n\n### Node.js\n\n```js\nimport { createServer } from \"node:http\";\nimport { createHandler } from \"y-crossws\";\nimport crossws from \"crossws/adapters/node\";\n\nconst server = createServer((req, res) => {\n  res.statusCode = 426;\n  res.end(\"\");\n});\n\nconst ws = crossws(createHandler());\n\nserver.on(\"upgrade\", ws.handleUpgrade);\n\nserver.listen(3000);\n```\n\n> [!NOTE]\n> Read more about Node.js adapter in [crossws docs](https://crossws.unjs.io/adapters/node).\n\n### Bun\n\n```js\nimport { createHandler } from \"y-crossws\";\nimport crossws from \"crossws/adapters/bun\";\n\nconst ws = crossws(createHandler());\n\nBun.serve({\n  port: 3000,\n  websocket: ws.websocket,\n  fetch(req, server) {\n    if (request.headers.get(\"upgrade\") === \"websocket\") {\n      return ws.handleUpgrade(request, server);\n    }\n    return new Response(\"\", { status: 426 });\n  },\n});\n```\n\n> [!NOTE]\n> Read more about Bun adapter in [crossws docs](https://crossws.unjs.io/adapters/bun).\n\n### Deno\n\n```js\nimport { createHandler } from \"y-crossws\";\nimport crossws from \"crossws/adapters/deno\";\n\nconst ws = crossws(createHandler());\n\nDeno.serve({ port: 3000 }, (request, info) => {\n  if (request.headers.get(\"upgrade\") === \"websocket\") {\n    return ws.handleUpgrade(request, server);\n  }\n  return new Response(\"\", { status: 426 });\n});\n```\n\n> [!NOTE]\n> Read more about Deno adapter in [crossws docs](https://crossws.unjs.io/adapters/deno).\n\n### Cloudflare (with durable objects)\n\n```js\nimport { createHandler } from \"y-crossws\";\nimport { DurableObject } from \"cloudflare:workers\";\nimport crossws from \"crossws/adapters/cloudflare-durable\";\n\nconst ws = crossws(createHandler());\n\nexport default {\n  async fetch(request, env, context) {\n    if (request.headers.get(\"upgrade\") === \"websocket\") {\n      return ws.handleUpgrade(request, env, context);\n    }\n    return new Response(\"\", { status: 426 });\n  },\n};\n\nexport class $DurableObject extends DurableObject {\n  fetch(request) {\n    return ws.handleDurableUpgrade(this, request);\n  }\n  webSocketMessage(client, message) {\n    return ws.handleDurableMessage(this, client, message);\n  }\n  webSocketClose(client, code, reason, wasClean) {\n    return ws.handleDurableClose(this, client, code, reason, wasClean);\n  }\n}\n```\n\nUpdate your `wrangler.toml` config to specify Durable object:\n\n```toml\ndurable_objects.bindings = [\n  { name = \"$DurableObject\", class_name = \"$DurableObject\" }\n]\n\nmigrations = [\n  { tag = \"v1\", new_classes = [\"$DurableObject\"] }\n]\n```\n\n> [!NOTE]\n> Read more about Cloudflare adapter in [crossws docs](https://crossws.unjs.io/adapters/cloudflare#durable-objects).\n\n## Websocket provider\n\nYou can use `WebsocketProvider` from legacy [y-websocket](https://github.com/yjs/y-websocket) or a native one from `y-crossws`. Both are almost identical in terms of API at the moment, however, the y-crossws version has better typescript refactors and might introduce more enhancements in sync with the server provider in the future.\n\n```js\nimport * as Y from \"yjs\";\nimport { WebsocketProvider } from \"y-crossws/provider\";\n\nconst ydoc = new Y.Doc();\nconst roomName = \"default\";\n\nconst wsProto = window.location.protocol === \"https:\" ? \"wss:\" : \"ws:\";\nconst wsUrl = `${wsProto}://${window.location.host}/_ws`;\n\nconst provider = new WebsocketProvider(wsURL, roomName, ydoc, {\n  /* options */\n});\n```\n\n### Provider options\n\n- `params`: URL parameters to append.\n- `protocols`: Specify websocket protocols.\n- `WebSocketPolyfill`: WebSocket polyfill.\n- `maxBackoffTime`: Maximum amount of time to wait before trying to reconnect (we try to reconnect using exponential (default `2500`).\n- `resyncInterval`: Request server state every `resyncInterval` milliseconds (default `-1`).\n- `connect`: Whether to connect to other peers or not (default: `true`).\n- `awareness`: Awareness instance.\n- `disableBc`: Disable cross-tab BroadcastChannel communication (default: `false`).\n\n## Development\n\n<details>\n\n<summary>local development</summary>\n\n- Clone this repository\n- Install the latest LTS version of [Node.js](https://nodejs.org/en/)\n- Enable [Corepack](https://github.com/nodejs/corepack) using `corepack enable`\n- Install dependencies using `pnpm install`\n- Build in stub mode using `pnpm build --stub`\n- Run playgrounds with `pnpm dev:*` commands.\n\n</details>\n\n## License\n\n💛 Published under the [MIT](https://github.com/pi0/y-crossws/blob/main/LICENSE) license.\n","readmeFilename":"README.md"}