From 863e3fe94eede6f7b2cc286df0b2c12763de5c05 Mon Sep 17 00:00:00 2001 From: Nikita Sivukhin Date: Thu, 2 Oct 2025 16:01:23 +0400 Subject: [PATCH] make url parameter to accept either string or function --- .../javascript/sync/packages/common/run.ts | 14 ++++++++++++-- .../javascript/sync/packages/common/types.ts | 18 +++++++++++------- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/bindings/javascript/sync/packages/common/run.ts b/bindings/javascript/sync/packages/common/run.ts index 4d1d1c969..554c5ff61 100644 --- a/bindings/javascript/sync/packages/common/run.ts +++ b/bindings/javascript/sync/packages/common/run.ts @@ -22,15 +22,25 @@ async function process(opts: RunOpts, io: ProtocolIo, request: any) { const requestType = request.request(); const completion = request.completion(); if (requestType.type == 'Http') { + let url: string | null = null; + if (typeof opts.url == "function") { + url = opts.url(); + } else { + url = opts.url; + } + if (url == null) { + completion.poison(`url is empty - sync is paused`); + return; + } try { - let headers = typeof opts.headers === "function" ? opts.headers() : opts.headers; + let headers = typeof opts.headers === "function" ? await opts.headers() : opts.headers; if (requestType.headers != null && requestType.headers.length > 0) { headers = { ...opts.headers }; for (let header of requestType.headers) { headers[header[0]] = header[1]; } } - const response = await fetch(`${opts.url}${requestType.path}`, { + const response = await fetch(`${url}${requestType.path}`, { method: requestType.method, headers: headers, body: requestType.body != null ? new Uint8Array(requestType.body) : null, diff --git a/bindings/javascript/sync/packages/common/types.ts b/bindings/javascript/sync/packages/common/types.ts index ee3e77a87..98f0f0c69 100644 --- a/bindings/javascript/sync/packages/common/types.ts +++ b/bindings/javascript/sync/packages/common/types.ts @@ -61,7 +61,7 @@ export interface EncryptionOpts { // base64 encoded encryption key (must be either 16 or 32 bytes depending on the cipher) key: string, // encryption cipher algorithm - cipher: 'aes256gcm' | 'aes128gcm' | 'chacha20poly1305' + cipher: 'aes256gcm' | 'aes128gcm' | 'chacha20poly1305' | 'aegis256' } export interface DatabaseOpts { /** @@ -73,22 +73,26 @@ export interface DatabaseOpts { /** * optional url of the remote database (e.g. libsql://db-org.turso.io) * (if omitted - local-only database will be created) + * + * you can also promide function which will return URL or null + * in this case local database will be created and sync will be "switched-on" whenever the url will return non-empty value + * note, that all other parameters (like encryption) must be set in advance in order for the "deferred" sync to work properly */ - url?: string; + url?: string | (() => string | null); /** * auth token for the remote database * (can be either static string or function which will provide short-lived credentials for every new request) */ - authToken?: string | (() => string); + authToken?: string | (() => Promise); /** * arbitrary client name which can be used to distinguish clients internally * the library will gurantee uniquiness of the clientId by appending unique suffix to the clientName */ clientName?: string; /** - * optional encryption parameters if cloud database were encrypted by default + * optional remote encryption parameters if cloud database were encrypted by default */ - encryption?: EncryptionOpts; + remoteEncryption?: EncryptionOpts; /** * optional callback which will be called for every mutation before sending it to the remote * this callback can transform the update in order to support complex conflict resolution strategy @@ -136,8 +140,8 @@ export interface DatabaseStats { export interface RunOpts { preemptionMs: number, - url: string, - headers: { [K: string]: string } | (() => { [K: string]: string }) + url: string | (() => string | null), + headers: { [K: string]: string } | (() => Promise<{ [K: string]: string }>) transform?: Transform, }