Path: blob/master/src/packages/project/conat/browser-websocket-api.ts
1447 views
/*1Implement the same protocol as browser-websocket was built on using primus,2but instead using NATS.34How to do development (so in a dev project doing cc-in-cc dev):560. From the browser, send a terminate-handler message, so the handler running in the project stops:78await cc.client.conat_client.projectWebsocketApi({project_id:cc.current().project_id, mesg:{cmd:"terminate"}})9101. Open a terminal in the project itself, which sets up the required environment variables. See api/index.ts for details!!11122. cd to your dev packages/project source code, e.g., ../cocalc/src/packages/project13143. Do this:1516echo 'require("@cocalc/project/client").init(); require("@cocalc/project/conat/browser-websocket-api").init()' | DEBUG=cocalc:* DEBUG_CONSOLE=yes node1718Or just run node then paste in1920require("@cocalc/project/client").init(); require("@cocalc/project/conat/browser-websocket-api").init()2122A nice thing about doing that is if you write this deep in some code:2324global.x = { t: this };2526then after that code runs you can access x from the node console!27284. Use the browser to see the project is on conat and works:2930await cc.client.conat_client.projectWebsocketApi({project_id:'56eb622f-d398-489a-83ef-c09f1a1e8094', mesg:{cmd:"listing"}})31325. In a terminal you can always tap into the message stream for a particular project:3334cd packages/backend35pnpm conat-watch project.56eb622f-d398-489a-83ef-c09f1a1e8094.browser-api --match-replies3637*/3839import { getLogger } from "@cocalc/project/logger";40import { connectToConat } from "./connection";41import { handleApiCall } from "@cocalc/project/browser-websocket/api";42import { getSubject } from "./names";4344const logger = getLogger("project:conat:browser-websocket-api");4546export async function init() {47const client = connectToConat();48const subject = getSubject({49service: "browser-api",50});51logger.debug(`initAPI -- project subject '${subject}'`);52const sub = await client.subscribe(subject);53logger.debug(`browser primus subject: ${getSubject({ service: "primus" })}`);54const primus = client.socket.listen(getSubject({ service: "primus" }));55primus.on("connection", (spark) => {56logger.debug("got a spark");57spark.on("data", (data) => {58spark.write(`${data}`.repeat(3));59});60});61for await (const mesg of sub) {62const data = mesg.data ?? ({} as any);63if (data.cmd == "terminate") {64logger.debug(65"received terminate-handler, so will not handle any further messages",66);67mesg.respond({ exiting: true });68return;69}70handleRequest({ data, mesg, primus });71}72}7374async function handleRequest({ data, mesg, primus }) {75let resp;76logger.debug("received cmd:", data?.cmd);77try {78resp = await handleApiCall({ data, spark: {} as any, primus });79} catch (err) {80resp = { error: `${err}` };81}82//logger.debug("responded", resp);83mesg.respond(resp ?? null);84}858687