{"_id":"@1upmonster/versus","_rev":"3-69fdd22a0566eec0fbc827621b08a765","name":"@1upmonster/versus","dist-tags":{"latest":"0.1.2"},"versions":{"0.1.0":{"name":"@1upmonster/versus","version":"0.1.0","license":"MIT","_id":"@1upmonster/versus@0.1.0","maintainers":[{"name":"valsamonte","email":"val.samonte@gmail.com"}],"dist":{"shasum":"dd3006891cd1a9ca9add8a769fb13f04ec6755ba","tarball":"https://registry.npmjs.org/@1upmonster/versus/-/versus-0.1.0.tgz","fileCount":26,"integrity":"sha512-ot0pe1G/G/LBiBDzqBq4UBNz5iRk7BBOiiSvS4NP5q5SKtY+rTFEppSyhDK/ywZuYN6EF1ANSXdnkXDZm6lQpw==","signatures":[{"sig":"MEQCIB+mGa8Do1s3xip/Fu5R3lDecaYy9d1JEgk6W6epvj/4AiAIx/a1X193PKF6wXGTXIfnE0h3n0gYDcws354DWez6BQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":75859},"type":"module","_from":"file:1upmonster-versus-0.1.0.tgz","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"scripts":{"test":"vitest run","build":"tsc","clean":"rm -rf dist","typecheck":"tsc --noEmit","test:watch":"vitest"},"_npmUser":{"name":"valsamonte","email":"val.samonte@gmail.com"},"_resolved":"/private/var/folders/7t/xxc30ftd45ngxq31sd06ds3w0000gp/T/2421bd87afdc5a4ee56fb7b4e837fe03/1upmonster-versus-0.1.0.tgz","_integrity":"sha512-ot0pe1G/G/LBiBDzqBq4UBNz5iRk7BBOiiSvS4NP5q5SKtY+rTFEppSyhDK/ywZuYN6EF1ANSXdnkXDZm6lQpw==","_npmVersion":"11.6.2","directories":{},"_nodeVersion":"24.6.0","dependencies":{"@1upmonster/sdk":"0.1.0","@1upmonster/types":"0.1.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3.0.0","typescript":"^5.7.2"},"_npmOperationalInternal":{"tmp":"tmp/versus_0.1.0_1773550975443_0.6372846272792478","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@1upmonster/versus","version":"0.1.1","license":"MIT","_id":"@1upmonster/versus@0.1.1","maintainers":[{"name":"valsamonte","email":"val.samonte@gmail.com"}],"dist":{"shasum":"de7dc8f3d657ee416c2669e68d35a3a1e4c22f88","tarball":"https://registry.npmjs.org/@1upmonster/versus/-/versus-0.1.1.tgz","fileCount":14,"integrity":"sha512-CUVXmCujk5O8nYL9xP2JcfNaMkikx4tG+zBRKQZm2LlJFH8Dj/ripmtEO8BZTRKDK82hTiuyJZX3zXQ3O+lZ7A==","signatures":[{"sig":"MEUCIHDYC03Ff5PLcVnxKjZL8U4rTVIfzPbp2PEC+Z9AfBkNAiEA7oon98r5Ye4I0i3oq19EwqtDiy00aq/l7NCKy/FimKc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":28701},"type":"module","_from":"file:1upmonster-versus-0.1.1.tgz","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"scripts":{"test":"vitest run","build":"tsc","clean":"rm -rf dist","typecheck":"tsc --noEmit","test:watch":"vitest"},"_npmUser":{"name":"valsamonte","email":"val.samonte@gmail.com"},"_resolved":"/private/var/folders/7t/xxc30ftd45ngxq31sd06ds3w0000gp/T/2f1dde4b8f313398190ed6decd8a4a06/1upmonster-versus-0.1.1.tgz","_integrity":"sha512-CUVXmCujk5O8nYL9xP2JcfNaMkikx4tG+zBRKQZm2LlJFH8Dj/ripmtEO8BZTRKDK82hTiuyJZX3zXQ3O+lZ7A==","_npmVersion":"11.6.2","directories":{},"_nodeVersion":"24.6.0","dependencies":{"@1upmonster/sdk":"0.1.1","@1upmonster/types":"0.1.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3.0.0","typescript":"^5.7.2"},"_npmOperationalInternal":{"tmp":"tmp/versus_0.1.1_1773551190576_0.038872936634098076","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@1upmonster/versus","version":"0.1.2","license":"MIT","type":"module","exports":{".":{"import":"./dist/index.js","types":"./dist/index.d.ts"}},"publishConfig":{"access":"public"},"dependencies":{"@1upmonster/sdk":"0.1.2","@1upmonster/types":"0.1.2"},"devDependencies":{"typescript":"^5.7.2","vitest":"^3.0.0"},"scripts":{"build":"tsc","typecheck":"tsc --noEmit","test":"vitest run","test:watch":"vitest","clean":"rm -rf dist"},"_id":"@1upmonster/versus@0.1.2","description":"Matchmaking and room client for 1upmonster Versus — queue players, form matches, and relay game messages over WebSocket.","_integrity":"sha512-U/XcUoJQtuvzx7KCqEPbKdkuX6hAmCMi9/DL31tdCANSZgwAlStMAriF2UOHHCb/9Jv/ANcxJYgbKmAuYmaQmA==","_resolved":"/private/var/folders/7t/xxc30ftd45ngxq31sd06ds3w0000gp/T/22545c5cf7326a328980c6c2d81b380b/1upmonster-versus-0.1.2.tgz","_from":"file:1upmonster-versus-0.1.2.tgz","_nodeVersion":"24.6.0","_npmVersion":"11.6.2","dist":{"integrity":"sha512-U/XcUoJQtuvzx7KCqEPbKdkuX6hAmCMi9/DL31tdCANSZgwAlStMAriF2UOHHCb/9Jv/ANcxJYgbKmAuYmaQmA==","shasum":"f8cfaacd6a700e58ecc0b28e932538bfc2b7baf8","tarball":"https://registry.npmjs.org/@1upmonster/versus/-/versus-0.1.2.tgz","fileCount":15,"unpackedSize":31175,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIAuKwGWllND/be9uYZPtfRgVYW+OU8+KFjeSTNxfF2KIAiEAsNZ/FWWsuguw1TbwtkUPBu/3dZ6dMr/Zok7XDkCB0nk="}]},"_npmUser":{"name":"valsamonte","email":"val.samonte@gmail.com"},"directories":{},"maintainers":[{"name":"valsamonte","email":"val.samonte@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/versus_0.1.2_1773551579656_0.7186232483136978"},"_hasShrinkwrap":false}},"time":{"created":"2026-03-15T05:02:55.371Z","modified":"2026-03-15T05:12:59.943Z","0.1.0":"2026-03-15T05:02:55.600Z","0.1.1":"2026-03-15T05:06:30.720Z","0.1.2":"2026-03-15T05:12:59.807Z"},"license":"MIT","maintainers":[{"name":"valsamonte","email":"val.samonte@gmail.com"}],"readme":"# @1upmonster/versus\n\nMatchmaking and room client for 1upmonster Versus — queue players, form matches, and relay game messages over WebSocket.\n\n## Install\n\n```bash\nnpm install @1upmonster/versus\n```\n\n## Quick Start\n\n```ts\nimport { VersusClient } from \"@1upmonster/versus\";\n\nconst versus = new VersusClient({\n  baseUrl: \"https://api.1up.monster\",\n  token: session.token,     // JWT from @1upmonster/sdk AuthClient\n  gameApiKey: \"your-api-key\", // issued per-game via CLI or TenantClient\n});\n```\n\n## Matchmaking\n\n```ts\n// Join the queue — returns a MatchProposal when a match is found\nconst proposal = await versus.matchmake(gameId, (status) => {\n  console.log(\"Queue status:\", status); // optional progress callback\n});\n\n// Accept the match\nconst room = await proposal.accept();\n\n// Or decline\nawait proposal.decline();\n```\n\n`matchmake` opens a WebSocket to the queue, waits for `match_found`, and returns a `MatchProposal`. Calling `accept()` sends the acceptance and waits for `match_ready`, then returns a connected `Room`.\n\n## Room\n\n```ts\n// Signal you're ready to play\nroom.ready();\n\n// Send game state / actions to all players\nroom.broadcast({ type: \"move\", x: 100, y: 200 });\n\n// Listen for incoming messages\nroom.on(\"game_message\", (msg) => {\n  console.log(\"From opponent:\", msg.data);\n});\n\n// Other events\nroom.on(\"room_ready\", () => { /* all players ready */ });\nroom.on(\"opponent_disconnected\", () => { /* handle drop */ });\nroom.on(\"match_expired\", () => { /* match timed out */ });\nroom.on(\"close\", () => { /* room closed */ });\n\n// Leave when done\nroom.leave();\n```\n\n## Admin Methods\n\nThese require only a JWT (no game API key needed):\n\n```ts\nconst config = await versus.getConfig(gameId);\nawait versus.setConfig(gameId, { /* VersusConfig */ });\nconst matches = await versus.listMatches(gameId);\nconst match = await versus.inspectMatch(matchId);\nawait versus.leaveQueue(gameId);\n```\n\n## ELO Configuration\n\nVersus reads ELO from on-chain accounts. Configure via `setConfig` or the CLI:\n\n```ts\nawait versus.setConfig(gameId, {\n  eloSource: {\n    account: {\n      type: \"static\",\n      address: \"<player_account_pubkey>\",\n    },\n    offset: 0,\n    type: \"u32\",\n    endian: \"little\",\n  },\n  matchFormat: {\n    playersPerTeam: 1,\n    teams: 2,\n  },\n  queueTtlSeconds: 60,\n  matchTtlSeconds: 300,\n  acceptWindowSeconds: 15,\n});\n```\n\nFor PDA-derived accounts:\n\n```ts\naccount: {\n  type: \"pda\",\n  programId: \"<your_program_id>\",\n  seeds: [{ type: \"wallet\" }],\n}\n```\n","readmeFilename":"README.md","description":"Matchmaking and room client for 1upmonster Versus — queue players, form matches, and relay game messages over WebSocket."}