UNPKG

@cocalc/project

Version:
91 lines (81 loc) 2.32 kB
/* * This file is part of CoCalc: Copyright © 2020 Sagemath, Inc. * License: AGPLv3 s.t. "Commons Clause" – see LICENSE.md for details */ /* All SyncTables that are currently open and being managed in this project. */ import { callback } from "awaiting"; import { SyncTable } from "@cocalc/sync/table"; import { is_array } from "@cocalc/util/misc"; const open_synctables: { [key: string]: SyncTable } = {}; const wait_for: { [key: string]: Function[] } = {}; export function key(query): string { const table: string = Object.keys(query)[0]; if (!table) { throw Error("no table in query"); } let c = query[table]; if (c == null) { throw Error("invalid query format"); } if (is_array(c)) { c = c[0]; } const string_id = c.string_id; if (string_id == null) { throw Error( "open-syncstring-tables is only for queries with a specified string_id field" + "(patches, cursors, eval_inputs, eval_outputs, etc.): query=" + JSON.stringify(query) ); } return `${table}.${string_id}`; } export function register_synctable(query: any, synctable: SyncTable): void { const k = key(query); open_synctables[k] = synctable; synctable.on("closed", function () { delete open_synctables[k]; }); if (wait_for[k] != null) { handle_wait_for(k, synctable); } } export async function get_synctable(query, client): Promise<SyncTable> { const k = key(query); const log = client.dbg(`get_synctable(key=${k})`); log("open_synctables = ", Object.keys(open_synctables)); log("key=", k, "query=", query); const s = open_synctables[k]; if (s != null) { // easy - already have it. log("done"); return s; } function f(cb: Function) { log("f got called"); add_to_wait_for(k, cb); } log("waiting..."); const synctable = await callback(f); log(`got the synctable! ${JSON.stringify((synctable as any).query)}`); return synctable; } function add_to_wait_for(k: string, cb: Function): void { if (wait_for[k] == null) { wait_for[k] = [cb]; } else { wait_for[k].push(cb); } } function handle_wait_for(k: string, synctable: SyncTable): void { if (wait_for[k] == null) { return; } const v: Function[] = wait_for[k]; delete wait_for[k]; for (const cb of v) { cb(undefined, synctable); } }