Path: blob/master/src/packages/sync/client/sync-client.ts
1447 views
/*1* This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.2* License: MS-RSL – see LICENSE.md for details3*/45/*6Functionality related to Sync.7*/89import { once } from "@cocalc/util/async-utils";10import { defaults, required } from "@cocalc/util/misc";11import { SyncDoc, SyncOpts0 } from "@cocalc/sync/editor/generic/sync-doc";12import { SyncDB, SyncDBOpts0 } from "@cocalc/sync/editor/db";13import { SyncString } from "@cocalc/sync/editor/string/sync";14import {15synctable,16SyncTable,17Query,18QueryOptions,19synctable_no_changefeed,20} from "@cocalc/sync/table";21import type { AppClient } from "./types";22import { getSyncDocType } from "@cocalc/conat/sync/syncdoc-info";2324interface SyncOpts extends Omit<SyncOpts0, "client"> {25noCache?: boolean;26client?: AppClient;27}2829interface SyncDBOpts extends Omit<SyncDBOpts0, "client" | "string_cols"> {30string_cols?: string[];31noCache?: boolean;32client?: AppClient;33}3435export class SyncClient {36private client: AppClient;3738constructor(client: AppClient) {39this.client = client;40}4142public sync_table(43query: Query,44options?: QueryOptions,45throttle_changes?: number,46): SyncTable {47return synctable(query, options ?? [], this.client, throttle_changes);48}4950public async synctable_database(51query: Query,52options?: QueryOptions,53throttle_changes?: number,54): Promise<SyncTable> {55const s = this.sync_table(query, options ?? [], throttle_changes);56await once(s, "connected");57return s;58}5960public synctable_no_changefeed(61query: Query,62options?: QueryOptions,63throttle_changes?: number,64): SyncTable {65return synctable_no_changefeed(66query,67options ?? [],68this.client,69throttle_changes,70);71}7273// These are not working properly, e.g., if you close and open74// a LARGE jupyter notebook quickly (so save to disk takes a while),75// then it gets broken until browser refresh. The problem is that76// the doc is still closing right when a new one starts being created.77// So for now we just revert to the non-cached-here approach.78// There is other caching elsewhere.7980// public sync_string(opts: SyncOpts): SyncString {81// return syncstringCache({ ...opts, client: this.client });82// }8384// public sync_db(opts: SyncDBOpts): SyncDB {85// return syncdbCache({ ...opts, client: this.client });86// }8788public sync_string(opts: SyncOpts): SyncString {89const opts0: SyncOpts0 = defaults(opts, {90id: undefined,91project_id: required,92path: required,93file_use_interval: "default",94cursors: false,95patch_interval: 1000,96save_interval: 2000,97persistent: false,98data_server: undefined,99client: this.client,100ephemeral: false,101});102return new SyncString(opts0);103}104105public sync_db(opts: SyncDBOpts): SyncDoc {106const opts0: SyncDBOpts0 = defaults(opts, {107id: undefined,108project_id: required,109path: required,110file_use_interval: "default",111cursors: false,112patch_interval: 1000,113save_interval: 2000,114change_throttle: undefined,115persistent: false,116data_server: undefined,117118primary_keys: required,119string_cols: [],120121client: this.client,122123ephemeral: false,124});125return new SyncDB(opts0);126}127128public async open_existing_sync_document({129project_id,130path,131data_server,132persistent,133}: {134project_id: string;135path: string;136data_server?: string;137persistent?: boolean;138}): Promise<SyncDoc | undefined> {139const doctype = await getSyncDocType({140project_id,141path,142client: this.client,143});144const { type } = doctype;145const f = `sync_${type}`;146return (this as any)[f]({147project_id,148path,149data_server,150persistent,151...doctype.opts,152});153}154}155156/*157const syncdbCache = refCacheSync<SyncDBOpts, SyncDB>({158name: "syncdb",159160createKey: ({ project_id, path }: SyncDBOpts) => {161return JSON.stringify({ project_id, path });162},163164createObject: (opts: SyncDBOpts) => {165const opts0: SyncDBOpts0 = defaults(opts, {166id: undefined,167project_id: required,168path: required,169file_use_interval: "default",170cursors: false,171patch_interval: 1000,172save_interval: 2000,173change_throttle: undefined,174persistent: false,175data_server: undefined,176177primary_keys: required,178string_cols: [],179180client: required,181182ephemeral: false,183});184return new SyncDB(opts0);185},186});187188const syncstringCache = refCacheSync<SyncOpts, SyncString>({189name: "syncstring",190createKey: ({ project_id, path }: SyncOpts) => {191const key = JSON.stringify({ project_id, path });192return key;193},194195createObject: (opts: SyncOpts) => {196const opts0: SyncOpts0 = defaults(opts, {197id: undefined,198project_id: required,199path: required,200file_use_interval: "default",201cursors: false,202patch_interval: 1000,203save_interval: 2000,204persistent: false,205data_server: undefined,206client: required,207ephemeral: false,208});209return new SyncString(opts0);210},211});212*/213214215