{"id":17026091,"url":"https://github.com/replit/crosis","last_synced_at":"2025-04-05T04:09:21.765Z","repository":{"id":38802001,"uuid":"209905706","full_name":"replit/crosis","owner":"replit","description":"A JavaScript client that speaks Replit's container protocol ","archived":false,"fork":false,"pushed_at":"2025-02-21T00:11:24.000Z","size":2116,"stargazers_count":113,"open_issues_count":7,"forks_count":24,"subscribers_count":39,"default_branch":"main","last_synced_at":"2025-03-29T03:04:23.803Z","etag":null,"topics":["containers","protobuf3","repl"],"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/replit.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":"2019-09-21T01:13:17.000Z","updated_at":"2025-03-24T13:52:20.000Z","dependencies_parsed_at":"2023-02-06T10:17:00.386Z","dependency_job_id":"5de0a116-99c7-4013-9b45-b2f3d0b6a2ac","html_url":"https://github.com/replit/crosis","commit_stats":null,"previous_names":[],"tags_count":108,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/replit%2Fcrosis","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/replit%2Fcrosis/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/replit%2Fcrosis/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/replit%2Fcrosis/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/replit","download_url":"https://codeload.github.com/replit/crosis/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247284948,"owners_count":20913704,"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":["containers","protobuf3","repl"],"created_at":"2024-10-14T07:30:27.851Z","updated_at":"2025-04-05T04:09:21.728Z","avatar_url":"https://github.com/replit.png","language":"TypeScript","readme":"### Installation\n\n`yarn add @replit/crosis @replit/protocol`\n\nCrosis relies on the `@replit/protocol` package as a peer dependency.\n\n### Prerequisites\n\nYou should probably familiarize yourself with the protocol before trying to use it. Crosis is just a client that helps you connect and communicate with the container using the protocol.\n\nRead about the protocol here https://crosis-doc.util.repl.co/\n\n### Usage and concepts\n\nThe central concept is a \"channel\" that you can send commands to and receive commands from. Communicating with channels requires a network connection. The goal of this client is to provide an API to manage the connection (including disconnects and reconnects), opening channels, and a way to send a receive messages/commands on channels. How you handle this is up to you and depends on the desired UX. In some cases you'll want to disable UI to prevent any new messages from being sent when offline and then re-enable once connected again. In other cases you might want to give the user the illusion that they are connected and queue messages locally while disconnected and send them once reconnected.\n\nHere is an example usage, for more details on usage please refer to the API docs at https://crosisdoc.util.repl.co/\n\n```typescript\nimport { Client } from '@replit/crosis';\n\nconst client = new Client\u003c{ user: { name: string }; repl: { id: string } }\u003e();\n\nconst repl = { id: 'someuuid' };\n\nasync function fetchConnectionMetadata(\n  signal: AbortSignal,\n): Promise\u003cFetchConnectionMetadataResult\u003e {\n  let res: Response;\n  try {\n    res = await fetch(CONNECTION_METADATA_URL + repl.id, { signal });\n  } catch (error) {\n    if (error.name === 'AbortError') {\n      return {\n        error: FetchConnectionMetadataError.Aborted,\n      };\n    }\n\n    throw error;\n  }\n\n  if (!res.ok) {\n    if (res.status \u003e 500) {\n      // Network or server error, try again\n      return {\n        error: FetchConnectionMetadataError.Retriable,\n      };\n    }\n\n    const errorText = await res.text();\n    throw new Error(errorText || res.statusText);\n  }\n\n  const connectionMetadata = await res.json();\n\n  return {\n    token: connectionMetadata.token,\n    gurl: connectionMetadata.gurl,\n    conmanURL: connectionMetadata.conmanURL,\n    error: null,\n  };\n}\n\nconst user = { name: 'tim' };\n\nconst context = { user, repl };\n\nclient.open({ context, fetchConnectionMetadata }, function onOpen({ channel, context }) {\n  //  The client is now connected (or reconnected in the event that it encountered an unexpected disconnect)\n  // `channel` here is channel0 (more info at https://crosis-doc.util.repl.co/protov2)\n  // - send commands using `channel.send`\n  // - listen for commands using `channel.onCommand(cmd =\u003e ...)`\n\n  return function cleanup({ willReconnect }) {\n    // The client was closed and might reconnect if it was closed unexpectedly\n  };\n});\n\n// See docs for exec service here https://crosis-doc.util.repl.co/services#exec\nconst closeChannel = client.openChannel({ service: 'exec' }, function open({ channel, context }) {\n  channel.onCommand((cmd) =\u003e {\n    if (cmd.output) {\n      terminal.write(cmd.output);\n    }\n  });\n\n  const intervalId = setInterval(() =\u003e {\n    channel.send({\n      exec: { args: ['echo', 'hello', context.user.name] },\n      blocking: true,\n    });\n  }, 100);\n\n  return function cleanup({ willReconnect }) {\n    clearInterval(intervalId);\n  };\n});\n```\n\n### Developing\n\nTo run tests, in your Replit devvm check out the goval repository and run `process-compose up`, then\nrun\n\n```bash\nyarn test\n```\n\nTo interact with a connected client in the browser run\n\n```bash\nyarn debug\n```\n\nYou can then access the client from the console an send messages like:\n\n```javascript\nwindow.client.send({ exec: { args: ['kill', '1'] } });\n```\n\n### Releasing\n\nTo release, just run `USER_KEY_ID=XXXX USER_PRIVATE_KEY=XXXX yarn version`, it will prompt you for a version, then it will push to github and release to npm.\n\nTo update documentation, go to https://crosisdoc.util.repl.co/__repl and run `. ./updatedocs.sh`\n","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Freplit%2Fcrosis","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Freplit%2Fcrosis","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Freplit%2Fcrosis/lists"}