From 3ad6be33d0a7958e4695319c4a00164ec1dec6f2 Mon Sep 17 00:00:00 2001 From: Ralf Kistner Date: Thu, 22 Aug 2024 11:17:15 +0200 Subject: [PATCH 01/14] @journeyapps/wa-sqlite 0.3.0 --- demos/angular-supabase-todolist/package.json | 2 +- demos/example-capacitor/package.json | 2 +- demos/example-electron/package.json | 2 +- demos/example-nextjs/package.json | 2 +- demos/react-multi-client/package.json | 2 +- demos/react-supabase-todolist/package.json | 2 +- .../package.json | 2 +- packages/kysely-driver/package.json | 2 +- packages/web/package.json | 4 +- pnpm-lock.yaml | 51 +++++++++---------- tools/diagnostics-app/package.json | 2 +- 11 files changed, 34 insertions(+), 39 deletions(-) diff --git a/demos/angular-supabase-todolist/package.json b/demos/angular-supabase-todolist/package.json index ae0fd108..31cee7b3 100644 --- a/demos/angular-supabase-todolist/package.json +++ b/demos/angular-supabase-todolist/package.json @@ -21,7 +21,7 @@ "@angular/platform-browser-dynamic": "^18.1.1", "@angular/router": "^18.1.1", "@angular/service-worker": "^18.1.1", - "@journeyapps/wa-sqlite": "^0.2.0", + "@journeyapps/wa-sqlite": "^0.3.0", "@powersync/web": "workspace:*", "@supabase/supabase-js": "^2.44.4", "rxjs": "~7.8.1", diff --git a/demos/example-capacitor/package.json b/demos/example-capacitor/package.json index 553afaec..3c2fd328 100644 --- a/demos/example-capacitor/package.json +++ b/demos/example-capacitor/package.json @@ -23,7 +23,7 @@ "@capacitor/core": "latest", "@capacitor/ios": "^6.0.0", "@capacitor/splash-screen": "latest", - "@journeyapps/wa-sqlite": "^0.2.0", + "@journeyapps/wa-sqlite": "^0.3.0", "@powersync/react": "workspace:*", "@powersync/web": "workspace:*", "js-logger": "^1.6.1", diff --git a/demos/example-electron/package.json b/demos/example-electron/package.json index 19a65257..7f73531d 100644 --- a/demos/example-electron/package.json +++ b/demos/example-electron/package.json @@ -21,7 +21,7 @@ "dependencies": { "@emotion/react": "^11.13.0", "@emotion/styled": "^11.13.0", - "@journeyapps/wa-sqlite": "~0.2.0", + "@journeyapps/wa-sqlite": "^0.3.0", "@mui/icons-material": "^5.15.16", "@mui/material": "^5.15.16", "@mui/x-data-grid": "^6.19.11", diff --git a/demos/example-nextjs/package.json b/demos/example-nextjs/package.json index 873b80a7..86767ab0 100644 --- a/demos/example-nextjs/package.json +++ b/demos/example-nextjs/package.json @@ -14,7 +14,7 @@ "@emotion/react": "^11.11.4", "@emotion/styled": "^11.11.5", "@fontsource/roboto": "^5.0.13", - "@journeyapps/wa-sqlite": "~0.2.0", + "@journeyapps/wa-sqlite": "^0.3.0", "@lexical/react": "^0.15.0", "@mui/icons-material": "^5.15.18", "@mui/material": "^5.15.18", diff --git a/demos/react-multi-client/package.json b/demos/react-multi-client/package.json index d01da29a..20164c4c 100644 --- a/demos/react-multi-client/package.json +++ b/demos/react-multi-client/package.json @@ -10,7 +10,7 @@ "test:build": "pnpm build" }, "dependencies": { - "@journeyapps/wa-sqlite": "~0.2.0", + "@journeyapps/wa-sqlite": "^0.3.0", "@powersync/react": "workspace:*", "@powersync/web": "workspace:*", "@supabase/supabase-js": "^2.43.1", diff --git a/demos/react-supabase-todolist/package.json b/demos/react-supabase-todolist/package.json index ed05ab60..bfebdb9e 100644 --- a/demos/react-supabase-todolist/package.json +++ b/demos/react-supabase-todolist/package.json @@ -13,7 +13,7 @@ "@powersync/web": "workspace:*", "@emotion/react": "11.11.4", "@emotion/styled": "11.11.5", - "@journeyapps/wa-sqlite": "~0.2.0", + "@journeyapps/wa-sqlite": "^0.3.0", "@mui/icons-material": "^5.15.12", "@mui/material": "^5.15.12", "@mui/x-data-grid": "^6.19.6", diff --git a/demos/yjs-react-supabase-text-collab/package.json b/demos/yjs-react-supabase-text-collab/package.json index a5cf4210..a39c80d2 100644 --- a/demos/yjs-react-supabase-text-collab/package.json +++ b/demos/yjs-react-supabase-text-collab/package.json @@ -14,7 +14,7 @@ "@fontsource/roboto": "^5.0.12", "@powersync/react": "workspace:*", "@powersync/web": "workspace:*", - "@journeyapps/wa-sqlite": "~0.1.1", + "@journeyapps/wa-sqlite": "^0.3.0", "@lexical/react": "^0.11.3", "@mui/icons-material": "^5.15.12", "@mui/material": "^5.15.12", diff --git a/packages/kysely-driver/package.json b/packages/kysely-driver/package.json index b7966150..2ba8fa4d 100644 --- a/packages/kysely-driver/package.json +++ b/packages/kysely-driver/package.json @@ -32,7 +32,7 @@ }, "devDependencies": { "@powersync/web": "workspace:*", - "@journeyapps/wa-sqlite": "^0.1.1", + "@journeyapps/wa-sqlite": "^0.3.0", "@types/node": "^20.11.17", "@vitest/browser": "^1.3.1", "ts-loader": "^9.5.1", diff --git a/packages/web/package.json b/packages/web/package.json index 94e94f9e..d2bff4be 100644 --- a/packages/web/package.json +++ b/packages/web/package.json @@ -34,7 +34,7 @@ "author": "JOURNEYAPPS", "license": "Apache-2.0", "peerDependencies": { - "@journeyapps/wa-sqlite": "~0.2.0", + "@journeyapps/wa-sqlite": "^0.3.0", "@powersync/common": "workspace:^1.16.2" }, "dependencies": { @@ -46,7 +46,7 @@ "lodash": "^4.17.21" }, "devDependencies": { - "@journeyapps/wa-sqlite": "~0.2.0", + "@journeyapps/wa-sqlite": "^0.3.0", "@rollup/plugin-commonjs": "^25.0.7", "@rollup/plugin-inject": "^5.0.5", "@rollup/plugin-json": "^6.1.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 82c16bb4..f8ef0b2c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -57,8 +57,8 @@ importers: specifier: ^18.1.1 version: 18.1.2(@angular/common@18.1.2(@angular/core@18.1.2(rxjs@7.8.1)(zone.js@0.14.8))(rxjs@7.8.1))(@angular/core@18.1.2(rxjs@7.8.1)(zone.js@0.14.8)) '@journeyapps/wa-sqlite': - specifier: ^0.2.0 - version: 0.2.0 + specifier: ^0.3.0 + version: 0.3.0 '@powersync/web': specifier: workspace:* version: link:../../packages/web @@ -245,8 +245,8 @@ importers: specifier: latest version: 6.0.2(@capacitor/core@6.1.2) '@journeyapps/wa-sqlite': - specifier: ^0.2.0 - version: 0.2.0 + specifier: ^0.3.0 + version: 0.3.0 '@powersync/react': specifier: workspace:* version: link:../../packages/react @@ -303,8 +303,8 @@ importers: specifier: ^11.13.0 version: 11.13.0(@emotion/react@11.13.0(@types/react@18.3.3)(react@18.2.0))(@types/react@18.3.3)(react@18.2.0) '@journeyapps/wa-sqlite': - specifier: ~0.2.0 - version: 0.2.0 + specifier: ^0.3.0 + version: 0.3.0 '@mui/icons-material': specifier: ^5.15.16 version: 5.16.5(@mui/material@5.16.5(@emotion/react@11.13.0(@types/react@18.3.3)(react@18.2.0))(@emotion/styled@11.13.0(@emotion/react@11.13.0(@types/react@18.3.3)(react@18.2.0))(@types/react@18.3.3)(react@18.2.0))(@types/react@18.3.3)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@types/react@18.3.3)(react@18.2.0) @@ -418,8 +418,8 @@ importers: specifier: ^5.0.13 version: 5.0.13 '@journeyapps/wa-sqlite': - specifier: ~0.2.0 - version: 0.2.0 + specifier: ^0.3.0 + version: 0.3.0 '@lexical/react': specifier: ^0.15.0 version: 0.15.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(yjs@13.6.18) @@ -538,8 +538,8 @@ importers: demos/react-multi-client: dependencies: '@journeyapps/wa-sqlite': - specifier: ~0.2.0 - version: 0.2.0 + specifier: ^0.3.0 + version: 0.3.0 '@powersync/react': specifier: workspace:* version: link:../../packages/react @@ -907,8 +907,8 @@ importers: specifier: 11.11.5 version: 11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.2.0))(@types/react@18.3.3)(react@18.2.0) '@journeyapps/wa-sqlite': - specifier: ~0.2.0 - version: 0.2.0 + specifier: ^0.3.0 + version: 0.3.0 '@mui/icons-material': specifier: ^5.15.12 version: 5.16.5(@mui/material@5.16.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.2.0))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.2.0))(@types/react@18.3.3)(react@18.2.0))(@types/react@18.3.3)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@types/react@18.3.3)(react@18.2.0) @@ -1071,8 +1071,8 @@ importers: specifier: ^5.0.12 version: 5.0.13 '@journeyapps/wa-sqlite': - specifier: ~0.1.1 - version: 0.1.1 + specifier: ^0.3.0 + version: 0.3.0 '@lexical/react': specifier: ^0.11.3 version: 0.11.3(lexical@0.11.3)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(yjs@13.6.18) @@ -1363,8 +1363,8 @@ importers: version: 0.27.4 devDependencies: '@journeyapps/wa-sqlite': - specifier: ^0.1.1 - version: 0.1.1 + specifier: ^0.3.0 + version: 0.3.0 '@powersync/web': specifier: workspace:* version: link:../web @@ -1535,8 +1535,8 @@ importers: version: 4.17.21 devDependencies: '@journeyapps/wa-sqlite': - specifier: ~0.2.0 - version: 0.2.0 + specifier: ^0.3.0 + version: 0.3.0 '@rollup/plugin-commonjs': specifier: ^25.0.7 version: 25.0.8(rollup@4.14.3) @@ -1589,8 +1589,8 @@ importers: tools/diagnostics-app: dependencies: '@journeyapps/wa-sqlite': - specifier: ~0.1.1 - version: 0.1.1 + specifier: ^0.3.0 + version: 0.3.0 '@mui/material': specifier: ^5.15.12 version: 5.16.5(@emotion/react@11.13.0(@types/react@18.3.3)(react@18.2.0))(@emotion/styled@11.13.0(@emotion/react@11.13.0(@types/react@18.3.3)(react@18.2.0))(@types/react@18.3.3)(react@18.2.0))(@types/react@18.3.3)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) @@ -3944,11 +3944,8 @@ packages: react: '*' react-native: '*' - '@journeyapps/wa-sqlite@0.1.1': - resolution: {integrity: sha512-cLPddbJYBpzII7ZBAA4fNKW2yLf3H03cGrz+JteXCfSjzxbYhnflAGD8WjefmeLXQUr2vcOYm3SgC82LJYZyzQ==} - - '@journeyapps/wa-sqlite@0.2.0': - resolution: {integrity: sha512-cZ0n1p4tteouancHulODtR3VChjp/teYhGQkAw4cCmeFytu+OcLTaMLhvFcUVoZdIT9LEu2hait/UTHx/ZaNHw==} + '@journeyapps/wa-sqlite@0.3.0': + resolution: {integrity: sha512-LQMjcMh92myqzq9kpKFJJ+t1zY7owHTq8TvVYG83luCKzaZepNk86jNB/56fb/vCEy1PQBRc/cI7BTt10SfItA==} '@jridgewell/gen-mapping@0.3.5': resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} @@ -22303,9 +22300,7 @@ snapshots: react: 18.2.0 react-native: 0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0) - '@journeyapps/wa-sqlite@0.1.1': {} - - '@journeyapps/wa-sqlite@0.2.0': {} + '@journeyapps/wa-sqlite@0.3.0': {} '@jridgewell/gen-mapping@0.3.5': dependencies: diff --git a/tools/diagnostics-app/package.json b/tools/diagnostics-app/package.json index 4190173f..cbbe2fbb 100644 --- a/tools/diagnostics-app/package.json +++ b/tools/diagnostics-app/package.json @@ -11,7 +11,7 @@ "dependencies": { "@powersync/react": "workspace:*", "@powersync/web": "workspace:*", - "@journeyapps/wa-sqlite": "~0.1.1", + "@journeyapps/wa-sqlite": "^0.3.0", "@mui/material": "^5.15.12", "@mui/x-data-grid": "^6.19.6", "js-logger": "^1.6.1", From 8bc5391c881ddad86e660e86d24dbfd632056d28 Mon Sep 17 00:00:00 2001 From: Ralf Kistner Date: Thu, 22 Aug 2024 11:32:06 +0200 Subject: [PATCH 02/14] Fix outdated test. --- packages/web/tests/bucket_storage.test.ts | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/packages/web/tests/bucket_storage.test.ts b/packages/web/tests/bucket_storage.test.ts index 4dda6dc8..d609fd32 100644 --- a/packages/web/tests/bucket_storage.test.ts +++ b/packages/web/tests/bucket_storage.test.ts @@ -338,8 +338,7 @@ describe('Bucket Storage', () => { OplogEntry.fromRow({ op_id: '1', op: new OpType(OpTypeEnum.MOVE).toJSON(), - checksum: 1, - data: '{"target": "3"}' + checksum: 1 }) ], false @@ -347,14 +346,6 @@ describe('Bucket Storage', () => { ]) ); - // At this point, we have target: 3, but don't have that op yet, so we cannot sync. - const result = await bucketStorage.syncLocalDatabase({ - last_op_id: '2', - buckets: [{ bucket: 'bucket1', checksum: 1 }] - }); - // Checksum passes, but we don't have a complete checkpoint - expect(result).deep.equals({ ready: false, checkpointValid: true }); - await bucketStorage.saveSyncData(new SyncDataBatch([new SyncDataBucket('bucket1', [putAsset1_3], false)])); await syncLocalChecked({ From 5968662d3a9feca532d65f14a143e813a29d6ec2 Mon Sep 17 00:00:00 2001 From: Ralf Kistner Date: Mon, 2 Sep 2024 11:33:10 +0200 Subject: [PATCH 03/14] Configure user agent. --- .../src/client/sync/stream/AbstractRemote.ts | 19 +++++++++++++++++-- .../src/sync/stream/ReactNativeRemote.ts | 6 ++++++ packages/web/src/db/sync/WebRemote.ts | 6 ++++++ packages/web/tsconfig.json | 2 +- 4 files changed, 30 insertions(+), 3 deletions(-) diff --git a/packages/common/src/client/sync/stream/AbstractRemote.ts b/packages/common/src/client/sync/stream/AbstractRemote.ts index fd9ba98e..d4ed38c8 100644 --- a/packages/common/src/client/sync/stream/AbstractRemote.ts +++ b/packages/common/src/client/sync/stream/AbstractRemote.ts @@ -10,6 +10,8 @@ import type { BSON } from 'bson'; import { AbortOperation } from '../../../utils/AbortOperation'; import { Buffer } from 'buffer'; +import { version as POWERSYNC_JS_VERSION } from '../../../../package.json'; + export type BSONImplementation = typeof BSON; export type RemoteConnector = { @@ -109,6 +111,10 @@ export abstract class AbstractRemote { return this.credentials; } + getUserAgent() { + return `powersync-js/${POWERSYNC_JS_VERSION}`; + } + protected async buildRequest(path: string) { const credentials = await this.getCredentials(); if (credentials != null && (credentials.endpoint == null || credentials.endpoint == '')) { @@ -119,11 +125,14 @@ export abstract class AbstractRemote { throw error; } + const userAgent = this.getUserAgent(); + return { url: credentials.endpoint + path, headers: { 'content-type': 'application/json', - Authorization: `Token ${credentials.token}` + Authorization: `Token ${credentials.token}`, + 'x-user-agent': userAgent } }; } @@ -207,6 +216,11 @@ export abstract class AbstractRemote { const bson = await this.getBSON(); + // Add the user agent in the setup payload - we can't set custom + // headers with websockets. The browser userAgent is however added + // automatically as a header. + const userAgent = this.getUserAgent(); + const connector = new RSocketConnector({ transport: new WebsocketClientTransport({ url: this.options.socketUrlTransformer(request.url) @@ -220,7 +234,8 @@ export abstract class AbstractRemote { data: null, metadata: Buffer.from( bson.serialize({ - token: request.headers.Authorization + token: request.headers.Authorization, + user_agent: userAgent }) ) } diff --git a/packages/react-native/src/sync/stream/ReactNativeRemote.ts b/packages/react-native/src/sync/stream/ReactNativeRemote.ts index 1b968a5a..b8c23cc1 100644 --- a/packages/react-native/src/sync/stream/ReactNativeRemote.ts +++ b/packages/react-native/src/sync/stream/ReactNativeRemote.ts @@ -18,6 +18,8 @@ import { BSON } from 'bson'; import { fetch } from 'react-native-fetch-api'; +import { version as POWERSYNC_RN_VERSION } from '../../../package.json'; + export const STREAMING_POST_TIMEOUT_MS = 30_000; /** @@ -43,6 +45,10 @@ export class ReactNativeRemote extends AbstractRemote { }); } + getUserAgent(): string { + return `${super.getUserAgent()} (react-native/${POWERSYNC_RN_VERSION})`; + } + async getBSON(): Promise { return BSON; } diff --git a/packages/web/src/db/sync/WebRemote.ts b/packages/web/src/db/sync/WebRemote.ts index 2c75e3e9..29622aea 100644 --- a/packages/web/src/db/sync/WebRemote.ts +++ b/packages/web/src/db/sync/WebRemote.ts @@ -10,6 +10,8 @@ import { RemoteConnector } from '@powersync/common'; +import { version as POWERSYNC_WEB_VERSION } from '../../../package.json'; + /* * Depends on browser's implementation of global fetch. */ @@ -33,6 +35,10 @@ export class WebRemote extends AbstractRemote { }); } + getUserAgent(): string { + return `${super.getUserAgent()} (web/${POWERSYNC_WEB_VERSION})`; + } + async getBSON(): Promise { if (this._bson) { return this._bson; diff --git a/packages/web/tsconfig.json b/packages/web/tsconfig.json index 1f9485c3..32cf3822 100644 --- a/packages/web/tsconfig.json +++ b/packages/web/tsconfig.json @@ -20,5 +20,5 @@ "path": "../common" } ], - "include": ["src/**/*", "tests/**/*"] + "include": ["src/**/*", "tests/**/*", "package.json"] } From 5bca641ee24c56c631030eec230e0653e1233d11 Mon Sep 17 00:00:00 2001 From: Ralf Kistner Date: Mon, 2 Sep 2024 11:38:16 +0200 Subject: [PATCH 04/14] Use powersync-sqlite-core for disconnectAndClear and deletePendingBuckets --- .../src/client/AbstractPowerSyncDatabase.ts | 22 +------------------ .../client/sync/bucket/SqliteBucketStorage.ts | 11 ++-------- packages/common/src/utils/strings.ts | 11 ---------- 3 files changed, 3 insertions(+), 41 deletions(-) delete mode 100644 packages/common/src/utils/strings.ts diff --git a/packages/common/src/client/AbstractPowerSyncDatabase.ts b/packages/common/src/client/AbstractPowerSyncDatabase.ts index cf512ae5..31cc748a 100644 --- a/packages/common/src/client/AbstractPowerSyncDatabase.ts +++ b/packages/common/src/client/AbstractPowerSyncDatabase.ts @@ -16,7 +16,6 @@ import { Schema } from '../db/schema/Schema'; import { BaseObserver } from '../utils/BaseObserver'; import { ControlledExecutor } from '../utils/ControlledExecutor'; import { mutexRunExclusive } from '../utils/mutex'; -import { quoteIdentifier } from '../utils/strings'; import { SQLOpenFactory, SQLOpenOptions, isDBAdapter, isSQLOpenFactory, isSQLOpenOptions } from './SQLOpenFactory'; import { PowerSyncBackendConnector } from './connection/PowerSyncBackendConnector'; import { BucketStorageAdapter, PSInternalTable } from './sync/bucket/BucketStorageAdapter'; @@ -400,26 +399,7 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver { - await tx.execute(`DELETE FROM ${PSInternalTable.OPLOG}`); - await tx.execute(`DELETE FROM ${PSInternalTable.CRUD}`); - await tx.execute(`DELETE FROM ${PSInternalTable.BUCKETS}`); - await tx.execute(`DELETE FROM ${PSInternalTable.UNTYPED}`); - - const tableGlob = clearLocal ? 'ps_data_*' : 'ps_data__*'; - - const existingTableRows = await tx.execute( - ` - SELECT name FROM sqlite_master WHERE type='table' AND name GLOB ? - `, - [tableGlob] - ); - - if (!existingTableRows.rows?.length) { - return; - } - for (const row of existingTableRows.rows._array) { - await tx.execute(`DELETE FROM ${quoteIdentifier(row.name)} WHERE 1`); - } + await tx.execute('SELECT powersync_clear(?)', [clearLocal ? 1 : 0]); }); // The data has been deleted - reset the sync status diff --git a/packages/common/src/client/sync/bucket/SqliteBucketStorage.ts b/packages/common/src/client/sync/bucket/SqliteBucketStorage.ts index 6a4feff5..add25c5b 100644 --- a/packages/common/src/client/sync/bucket/SqliteBucketStorage.ts +++ b/packages/common/src/client/sync/bucket/SqliteBucketStorage.ts @@ -103,9 +103,7 @@ export class SqliteBucketStorage extends BaseObserver imp */ private async deleteBucket(bucket: string) { await this.writeTransaction(async (tx) => { - await tx.execute( - 'INSERT INTO powersync_operations(op, data) VALUES(?, ?)', - ['delete_bucket', bucket]); + await tx.execute('INSERT INTO powersync_operations(op, data) VALUES(?, ?)', ['delete_bucket', bucket]); }); this.logger.debug('done deleting bucket'); @@ -219,12 +217,7 @@ export class SqliteBucketStorage extends BaseObserver imp private async deletePendingBuckets() { if (this.pendingBucketDeletes !== false) { await this.writeTransaction(async (tx) => { - await tx.execute( - 'DELETE FROM ps_oplog WHERE bucket IN (SELECT name FROM ps_buckets WHERE pending_delete = 1 AND last_applied_op = last_op AND last_op >= target_op)' - ); - await tx.execute( - 'DELETE FROM ps_buckets WHERE pending_delete = 1 AND last_applied_op = last_op AND last_op >= target_op' - ); + await tx.execute('INSERT INTO powersync_operations(op, data) VALUES (?, ?)', ['delete_pending_buckets', '']); }); // Executed once after start-up, and again when there are pending deletes. this.pendingBucketDeletes = false; diff --git a/packages/common/src/utils/strings.ts b/packages/common/src/utils/strings.ts deleted file mode 100644 index 057a2f6a..00000000 --- a/packages/common/src/utils/strings.ts +++ /dev/null @@ -1,11 +0,0 @@ -export function quoteString(s: string) { - return `'${s.replaceAll("'", "''")}'`; -} - -export function quoteJsonPath(path: string) { - return quoteString(`$.${path}`); -} - -export function quoteIdentifier(s: string) { - return `"${s.replaceAll('"', '""')}"`; -} From 9f8c8b81cf77b69b7e1d587d4d3ef5a863c030c1 Mon Sep 17 00:00:00 2001 From: Ralf Kistner Date: Mon, 2 Sep 2024 11:42:38 +0200 Subject: [PATCH 05/14] Remove outdated export. --- packages/common/src/index.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/common/src/index.ts b/packages/common/src/index.ts index d6b93809..4e55be2f 100644 --- a/packages/common/src/index.ts +++ b/packages/common/src/index.ts @@ -15,7 +15,7 @@ export * from './client/sync/bucket/OplogEntry'; export * from './client/sync/stream/AbstractRemote'; export * from './client/sync/stream/AbstractStreamingSyncImplementation'; export * from './client/sync/stream/streaming-sync-types'; -export { MAX_OP_ID } from './client/constants' +export { MAX_OP_ID } from './client/constants'; export * from './db/crud/SyncStatus'; export * from './db/crud/UploadQueueStatus'; @@ -31,7 +31,6 @@ export * from './db/schema/TableV2'; export * from './utils/AbortOperation'; export * from './utils/BaseObserver'; -export * from './utils/strings'; export * from './utils/DataStream'; export * from './utils/parseQuery'; From 6c2c3a64679074403d4d874aaca37c8aafaaa2ae Mon Sep 17 00:00:00 2001 From: Ralf Kistner Date: Mon, 2 Sep 2024 12:22:12 +0200 Subject: [PATCH 06/14] react-native-quick-sqlite 1.3.0 --- .../django-react-native-todolist/package.json | 2 +- .../package.json | 2 +- .../package.json | 2 +- packages/react-native/package.json | 4 +- pnpm-lock.yaml | 103 +++++++++--------- 5 files changed, 56 insertions(+), 57 deletions(-) diff --git a/demos/django-react-native-todolist/package.json b/demos/django-react-native-todolist/package.json index 59396c90..20205156 100644 --- a/demos/django-react-native-todolist/package.json +++ b/demos/django-react-native-todolist/package.json @@ -10,7 +10,7 @@ "dependencies": { "@azure/core-asynciterator-polyfill": "^1.0.2", "@expo/vector-icons": "^14.0.0", - "@journeyapps/react-native-quick-sqlite": "^1.1.7", + "@journeyapps/react-native-quick-sqlite": "^1.3.0", "@powersync/common": "workspace:*", "@powersync/react": "workspace:*", "@powersync/react-native": "workspace:*", diff --git a/demos/react-native-supabase-group-chat/package.json b/demos/react-native-supabase-group-chat/package.json index 8b627f32..248b6dd0 100644 --- a/demos/react-native-supabase-group-chat/package.json +++ b/demos/react-native-supabase-group-chat/package.json @@ -21,7 +21,7 @@ "dependencies": { "@azure/core-asynciterator-polyfill": "^1.0.2", "@faker-js/faker": "8.3.1", - "@journeyapps/react-native-quick-sqlite": "^1.1.7", + "@journeyapps/react-native-quick-sqlite": "^1.3.0", "@powersync/common": "workspace:*", "@powersync/react": "workspace:*", "@powersync/react-native": "workspace:*", diff --git a/demos/react-native-supabase-todolist/package.json b/demos/react-native-supabase-todolist/package.json index 09fb803a..05c80fed 100644 --- a/demos/react-native-supabase-todolist/package.json +++ b/demos/react-native-supabase-todolist/package.json @@ -10,7 +10,7 @@ "dependencies": { "@azure/core-asynciterator-polyfill": "^1.0.2", "@expo/vector-icons": "^14.0.0", - "@journeyapps/react-native-quick-sqlite": "^1.1.7", + "@journeyapps/react-native-quick-sqlite": "^1.3.0", "@powersync/attachments": "workspace:*", "@powersync/common": "workspace:*", "@powersync/react": "workspace:*", diff --git a/packages/react-native/package.json b/packages/react-native/package.json index 29344591..a4e1a526 100644 --- a/packages/react-native/package.json +++ b/packages/react-native/package.json @@ -28,7 +28,7 @@ }, "homepage": "https://docs.powersync.com/", "peerDependencies": { - "@journeyapps/react-native-quick-sqlite": "^1.1.8", + "@journeyapps/react-native-quick-sqlite": "^1.3.0", "@powersync/common": "workspace:^1.16.2", "react": "*", "react-native": "*" @@ -39,7 +39,7 @@ }, "devDependencies": { "@craftzdog/react-native-buffer": "^6.0.5", - "@journeyapps/react-native-quick-sqlite": "^1.1.8", + "@journeyapps/react-native-quick-sqlite": "^1.3.0", "@rollup/plugin-alias": "^5.1.0", "@rollup/plugin-commonjs": "^25.0.7", "@rollup/plugin-inject": "^5.0.5", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index eb6e31b5..cf352cd5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -106,8 +106,8 @@ importers: specifier: ^14.0.0 version: 14.0.2 '@journeyapps/react-native-quick-sqlite': - specifier: ^1.1.7 - version: 1.1.8(react-native@0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0) + specifier: ^1.3.0 + version: 1.3.0(react-native@0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0) '@powersync/common': specifier: workspace:* version: link:../../packages/common @@ -125,7 +125,7 @@ importers: version: 0.1.11(react-native@0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0) '@react-navigation/drawer': specifier: ^6.6.15 - version: 6.7.2(@react-navigation/native@6.1.18(react-native@0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-gesture-handler@2.16.2(react-native@0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-reanimated@3.10.1(@babel/core@7.24.9)(react-native@0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-safe-area-context@4.10.5(react-native@0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-screens@3.31.1(react-native@0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native@0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0) + version: 6.7.2(qzulpltu3lo63pjt7izylm2n5i) '@react-navigation/native': specifier: ^6.1.17 version: 6.1.18(react-native@0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0) @@ -149,7 +149,7 @@ importers: version: 1.11.1 expo-router: specifier: 3.5.21 - version: 3.5.21(@react-navigation/drawer@6.7.2(@react-navigation/native@6.1.18(react-native@0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-gesture-handler@2.16.2(react-native@0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-reanimated@3.10.1(@babel/core@7.24.9)(react-native@0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-safe-area-context@4.10.5(react-native@0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-screens@3.31.1(react-native@0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native@0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(encoding@0.1.13)(expo-constants@16.0.2(expo@51.0.27(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(encoding@0.1.13)))(expo-linking@6.3.1(expo@51.0.27(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(encoding@0.1.13)))(expo-modules-autolinking@1.11.1)(expo-status-bar@1.12.1)(expo@51.0.27(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(encoding@0.1.13))(react-native-reanimated@3.10.1(@babel/core@7.24.9)(react-native@0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-safe-area-context@4.10.5(react-native@0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-screens@3.31.1(react-native@0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native@0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0)(typescript@5.3.3) + version: 3.5.21(zeus6eibm4it6pzage7bp7blp4) expo-splash-screen: specifier: ~0.27.4 version: 0.27.5(encoding@0.1.13)(expo-modules-autolinking@1.11.1)(expo@51.0.27(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(encoding@0.1.13)) @@ -203,7 +203,7 @@ importers: version: 10.1.0 react-navigation-stack: specifier: ^2.10.4 - version: 2.10.4(@react-native-community/masked-view@0.1.11(react-native@0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-gesture-handler@2.16.2(react-native@0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-safe-area-context@4.10.5(react-native@0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-screens@3.31.1(react-native@0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native@0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react-navigation@4.4.4(react-native@0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react@18.2.0) + version: 2.10.4(pvhyv626m34wzucu26rkz7owva) typed-async-storage: specifier: ^3.1.2 version: 3.1.2 @@ -632,8 +632,8 @@ importers: specifier: 8.3.1 version: 8.3.1 '@journeyapps/react-native-quick-sqlite': - specifier: ^1.1.7 - version: 1.1.8(react-native@0.74.1(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.3.3)(encoding@0.1.13)(react@18.2.0))(react@18.2.0) + specifier: ^1.3.0 + version: 1.3.0(react-native@0.74.1(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.3.3)(encoding@0.1.13)(react@18.2.0))(react@18.2.0) '@powersync/common': specifier: workspace:* version: link:../../packages/common @@ -690,7 +690,7 @@ importers: version: 6.3.1(expo@51.0.10(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(encoding@0.1.13)) expo-router: specifier: ^3.5.15 - version: 3.5.15(@react-navigation/drawer@6.7.2(@react-navigation/native@6.1.18(react-native@0.74.1(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.3.3)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-gesture-handler@2.16.2(react-native@0.74.1(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.3.3)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-reanimated@3.10.1(@babel/core@7.24.5)(react-native@0.74.1(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.3.3)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-safe-area-context@4.10.1(react-native@0.74.1(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.3.3)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-screens@3.31.1(react-native@0.74.1(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.3.3)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native@0.74.1(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.3.3)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(encoding@0.1.13)(expo-constants@16.0.2(expo@51.0.10(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(encoding@0.1.13)))(expo-linking@6.3.1(expo@51.0.10(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(encoding@0.1.13)))(expo-modules-autolinking@1.11.1)(expo-status-bar@1.12.1)(expo@51.0.10(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(encoding@0.1.13))(react-native-reanimated@3.10.1(@babel/core@7.24.5)(react-native@0.74.1(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.3.3)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-safe-area-context@4.10.1(react-native@0.74.1(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.3.3)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-screens@3.31.1(react-native@0.74.1(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.3.3)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native@0.74.1(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.3.3)(encoding@0.1.13)(react@18.2.0))(react@18.2.0)(typescript@5.3.3) + version: 3.5.15(crofignwy33heb4ogq4isomeuy) expo-splash-screen: specifier: ~0.27.4 version: 0.27.5(encoding@0.1.13)(expo-modules-autolinking@1.11.1)(expo@51.0.10(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(encoding@0.1.13)) @@ -768,8 +768,8 @@ importers: specifier: ^14.0.0 version: 14.0.2 '@journeyapps/react-native-quick-sqlite': - specifier: ^1.1.7 - version: 1.1.8(react-native@0.74.5(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0) + specifier: ^1.3.0 + version: 1.3.0(react-native@0.74.5(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0) '@powersync/attachments': specifier: workspace:* version: link:../../packages/attachments @@ -787,7 +787,7 @@ importers: version: 0.1.11(react-native@0.74.5(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0) '@react-navigation/drawer': specifier: ^6.6.3 - version: 6.7.2(@react-navigation/native@6.1.18(react-native@0.74.5(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-gesture-handler@2.16.2(react-native@0.74.5(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-reanimated@3.10.1(@babel/core@7.24.5)(react-native@0.74.5(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-safe-area-context@4.10.5(react-native@0.74.5(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-screens@3.31.1(react-native@0.74.5(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native@0.74.5(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0) + version: 6.7.2(yxjigtmgi5w2ew3hyzeaduv44u) '@react-navigation/native': specifier: ^6.0.0 version: 6.1.18(react-native@0.74.5(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0) @@ -820,7 +820,7 @@ importers: version: 6.3.1(expo@51.0.27(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(encoding@0.1.13)) expo-router: specifier: 3.5.21 - version: 3.5.21(@react-navigation/drawer@6.7.2(@react-navigation/native@6.1.18(react-native@0.74.5(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-gesture-handler@2.16.2(react-native@0.74.5(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-reanimated@3.10.1(@babel/core@7.24.5)(react-native@0.74.5(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-safe-area-context@4.10.5(react-native@0.74.5(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-screens@3.31.1(react-native@0.74.5(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native@0.74.5(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(encoding@0.1.13)(expo-constants@16.0.2(expo@51.0.27(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(encoding@0.1.13)))(expo-linking@6.3.1(expo@51.0.27(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(encoding@0.1.13)))(expo-modules-autolinking@1.11.1)(expo-status-bar@1.12.1)(expo@51.0.27(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(encoding@0.1.13))(react-native-reanimated@3.10.1(@babel/core@7.24.5)(react-native@0.74.5(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-safe-area-context@4.10.5(react-native@0.74.5(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-screens@3.31.1(react-native@0.74.5(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native@0.74.5(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0)(typescript@5.5.4) + version: 3.5.21(hgbnujebzanrutajdi4bfceakq) expo-secure-store: specifier: ~13.0.1 version: 13.0.2(expo@51.0.27(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(encoding@0.1.13)) @@ -877,7 +877,7 @@ importers: version: 10.1.0 react-navigation-stack: specifier: ^2.10.4 - version: 2.10.4(@react-native-community/masked-view@0.1.11(react-native@0.74.5(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-gesture-handler@2.16.2(react-native@0.74.5(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-safe-area-context@4.10.5(react-native@0.74.5(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-screens@3.31.1(react-native@0.74.5(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native@0.74.5(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react-navigation@4.4.4(react-native@0.74.5(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react@18.2.0) + version: 2.10.4(evsawqdcqkvgavridqb4swxtby) devDependencies: '@babel/core': specifier: ^7.24.5 @@ -1440,8 +1440,8 @@ importers: specifier: ^6.0.5 version: 6.0.5(react-native@0.72.4(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(encoding@0.1.13)(react@18.2.0))(react@18.2.0) '@journeyapps/react-native-quick-sqlite': - specifier: ^1.1.8 - version: 1.1.8(react-native@0.72.4(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(encoding@0.1.13)(react@18.2.0))(react@18.2.0) + specifier: ^1.3.0 + version: 1.3.0(react-native@0.72.4(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(encoding@0.1.13)(react@18.2.0))(react@18.2.0) '@rollup/plugin-alias': specifier: ^5.1.0 version: 5.1.0(rollup@4.14.3) @@ -3944,9 +3944,8 @@ packages: resolution: {integrity: sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - '@journeyapps/react-native-quick-sqlite@1.1.8': - resolution: {integrity: sha512-9e85lXBMPht3mEyAKHBaag7crtrFwlEg1H+5ln1+RwORNtRELGLjOX8vA9cCTE6JoBRraEJLWRY30jmS1bmmvQ==} - deprecated: This package has moved to @powersync/react-native-quick-sqlite + '@journeyapps/react-native-quick-sqlite@1.3.0': + resolution: {integrity: sha512-nl6re7LGIjUE1+tWTMRdmoprhrzlcpZsSE+tq3kZNju7ZVAwUxmkQ5dEz8uqJ8m0y49HJ4mN7zGomTFhsEMkbA==} peerDependencies: react: '*' react-native: '*' @@ -22370,22 +22369,22 @@ snapshots: '@types/yargs': 17.0.32 chalk: 4.1.2 - '@journeyapps/react-native-quick-sqlite@1.1.8(react-native@0.72.4(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(encoding@0.1.13)(react@18.2.0))(react@18.2.0)': + '@journeyapps/react-native-quick-sqlite@1.3.0(react-native@0.72.4(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(encoding@0.1.13)(react@18.2.0))(react@18.2.0)': dependencies: react: 18.2.0 react-native: 0.72.4(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(encoding@0.1.13)(react@18.2.0) - '@journeyapps/react-native-quick-sqlite@1.1.8(react-native@0.74.1(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.3.3)(encoding@0.1.13)(react@18.2.0))(react@18.2.0)': + '@journeyapps/react-native-quick-sqlite@1.3.0(react-native@0.74.1(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.3.3)(encoding@0.1.13)(react@18.2.0))(react@18.2.0)': dependencies: react: 18.2.0 react-native: 0.74.1(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.3.3)(encoding@0.1.13)(react@18.2.0) - '@journeyapps/react-native-quick-sqlite@1.1.8(react-native@0.74.5(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0)': + '@journeyapps/react-native-quick-sqlite@1.3.0(react-native@0.74.5(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0)': dependencies: react: 18.2.0 react-native: 0.74.5(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0) - '@journeyapps/react-native-quick-sqlite@1.1.8(react-native@0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0)': + '@journeyapps/react-native-quick-sqlite@1.3.0(react-native@0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0)': dependencies: react: 18.2.0 react-native: 0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0) @@ -24603,8 +24602,21 @@ snapshots: react-is: 16.13.1 use-latest-callback: 0.2.1(react@18.2.0) - ? '@react-navigation/drawer@6.7.2(@react-navigation/native@6.1.18(react-native@0.74.1(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.3.3)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-gesture-handler@2.16.2(react-native@0.74.1(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.3.3)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-reanimated@3.10.1(@babel/core@7.24.5)(react-native@0.74.1(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.3.3)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-safe-area-context@4.10.1(react-native@0.74.1(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.3.3)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-screens@3.31.1(react-native@0.74.1(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.3.3)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native@0.74.1(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.3.3)(encoding@0.1.13)(react@18.2.0))(react@18.2.0)' - : dependencies: + '@react-navigation/drawer@6.7.2(qzulpltu3lo63pjt7izylm2n5i)': + dependencies: + '@react-navigation/elements': 1.3.31(@react-navigation/native@6.1.18(react-native@0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-safe-area-context@4.10.5(react-native@0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native@0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0) + '@react-navigation/native': 6.1.18(react-native@0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0) + color: 4.2.3 + react: 18.2.0 + react-native: 0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0) + react-native-gesture-handler: 2.16.2(react-native@0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0) + react-native-reanimated: 3.10.1(@babel/core@7.24.9)(react-native@0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0) + react-native-safe-area-context: 4.10.5(react-native@0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0) + react-native-screens: 3.31.1(react-native@0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0) + warn-once: 0.1.1 + + '@react-navigation/drawer@6.7.2(yxbharbyezt7ud7hulqyetqjta)': + dependencies: '@react-navigation/elements': 1.3.31(@react-navigation/native@6.1.18(react-native@0.74.1(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.3.3)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-safe-area-context@4.10.1(react-native@0.74.1(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.3.3)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native@0.74.1(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.3.3)(encoding@0.1.13)(react@18.2.0))(react@18.2.0) '@react-navigation/native': 6.1.18(react-native@0.74.1(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.3.3)(encoding@0.1.13)(react@18.2.0))(react@18.2.0) color: 4.2.3 @@ -24617,8 +24629,8 @@ snapshots: warn-once: 0.1.1 optional: true - ? '@react-navigation/drawer@6.7.2(@react-navigation/native@6.1.18(react-native@0.74.5(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-gesture-handler@2.16.2(react-native@0.74.5(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-reanimated@3.10.1(@babel/core@7.24.5)(react-native@0.74.5(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-safe-area-context@4.10.5(react-native@0.74.5(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-screens@3.31.1(react-native@0.74.5(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native@0.74.5(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0)' - : dependencies: + '@react-navigation/drawer@6.7.2(yxjigtmgi5w2ew3hyzeaduv44u)': + dependencies: '@react-navigation/elements': 1.3.31(@react-navigation/native@6.1.18(react-native@0.74.5(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-safe-area-context@4.10.5(react-native@0.74.5(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native@0.74.5(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0) '@react-navigation/native': 6.1.18(react-native@0.74.5(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0) color: 4.2.3 @@ -24630,19 +24642,6 @@ snapshots: react-native-screens: 3.31.1(react-native@0.74.5(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0) warn-once: 0.1.1 - ? '@react-navigation/drawer@6.7.2(@react-navigation/native@6.1.18(react-native@0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-gesture-handler@2.16.2(react-native@0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-reanimated@3.10.1(@babel/core@7.24.9)(react-native@0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-safe-area-context@4.10.5(react-native@0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-screens@3.31.1(react-native@0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native@0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0)' - : dependencies: - '@react-navigation/elements': 1.3.31(@react-navigation/native@6.1.18(react-native@0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-safe-area-context@4.10.5(react-native@0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native@0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0) - '@react-navigation/native': 6.1.18(react-native@0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0) - color: 4.2.3 - react: 18.2.0 - react-native: 0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0) - react-native-gesture-handler: 2.16.2(react-native@0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0) - react-native-reanimated: 3.10.1(@babel/core@7.24.9)(react-native@0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0) - react-native-safe-area-context: 4.10.5(react-native@0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0) - react-native-screens: 3.31.1(react-native@0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0) - warn-once: 0.1.1 - '@react-navigation/elements@1.3.31(@react-navigation/native@6.1.18(react-native@0.74.1(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.3.3)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-safe-area-context@4.10.1(react-native@0.74.1(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.3.3)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native@0.74.1(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.3.3)(encoding@0.1.13)(react@18.2.0))(react@18.2.0)': dependencies: '@react-navigation/native': 6.1.18(react-native@0.74.1(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.3.3)(encoding@0.1.13)(react@18.2.0))(react@18.2.0) @@ -30767,8 +30766,8 @@ snapshots: dependencies: invariant: 2.2.4 - ? expo-router@3.5.15(@react-navigation/drawer@6.7.2(@react-navigation/native@6.1.18(react-native@0.74.1(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.3.3)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-gesture-handler@2.16.2(react-native@0.74.1(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.3.3)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-reanimated@3.10.1(@babel/core@7.24.5)(react-native@0.74.1(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.3.3)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-safe-area-context@4.10.1(react-native@0.74.1(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.3.3)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-screens@3.31.1(react-native@0.74.1(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.3.3)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native@0.74.1(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.3.3)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(encoding@0.1.13)(expo-constants@16.0.2(expo@51.0.10(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(encoding@0.1.13)))(expo-linking@6.3.1(expo@51.0.10(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(encoding@0.1.13)))(expo-modules-autolinking@1.11.1)(expo-status-bar@1.12.1)(expo@51.0.10(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(encoding@0.1.13))(react-native-reanimated@3.10.1(@babel/core@7.24.5)(react-native@0.74.1(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.3.3)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-safe-area-context@4.10.1(react-native@0.74.1(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.3.3)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-screens@3.31.1(react-native@0.74.1(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.3.3)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native@0.74.1(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.3.3)(encoding@0.1.13)(react@18.2.0))(react@18.2.0)(typescript@5.3.3) - : dependencies: + expo-router@3.5.15(crofignwy33heb4ogq4isomeuy): + dependencies: '@expo/metro-runtime': 3.2.1(react-native@0.74.1(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.3.3)(encoding@0.1.13)(react@18.2.0)) '@expo/server': 0.4.4(typescript@5.3.3) '@radix-ui/react-slot': 1.0.1(react@18.2.0) @@ -30785,7 +30784,7 @@ snapshots: react-native-screens: 3.31.1(react-native@0.74.1(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.3.3)(encoding@0.1.13)(react@18.2.0))(react@18.2.0) schema-utils: 4.2.0 optionalDependencies: - '@react-navigation/drawer': 6.7.2(@react-navigation/native@6.1.18(react-native@0.74.1(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.3.3)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-gesture-handler@2.16.2(react-native@0.74.1(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.3.3)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-reanimated@3.10.1(@babel/core@7.24.5)(react-native@0.74.1(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.3.3)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-safe-area-context@4.10.1(react-native@0.74.1(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.3.3)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-screens@3.31.1(react-native@0.74.1(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.3.3)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native@0.74.1(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.3.3)(encoding@0.1.13)(react@18.2.0))(react@18.2.0) + '@react-navigation/drawer': 6.7.2(yxbharbyezt7ud7hulqyetqjta) react-native-reanimated: 3.10.1(@babel/core@7.24.5)(react-native@0.74.1(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.3.3)(encoding@0.1.13)(react@18.2.0))(react@18.2.0) transitivePeerDependencies: - encoding @@ -30795,8 +30794,8 @@ snapshots: - supports-color - typescript - ? expo-router@3.5.21(@react-navigation/drawer@6.7.2(@react-navigation/native@6.1.18(react-native@0.74.5(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-gesture-handler@2.16.2(react-native@0.74.5(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-reanimated@3.10.1(@babel/core@7.24.5)(react-native@0.74.5(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-safe-area-context@4.10.5(react-native@0.74.5(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-screens@3.31.1(react-native@0.74.5(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native@0.74.5(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(encoding@0.1.13)(expo-constants@16.0.2(expo@51.0.27(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(encoding@0.1.13)))(expo-linking@6.3.1(expo@51.0.27(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(encoding@0.1.13)))(expo-modules-autolinking@1.11.1)(expo-status-bar@1.12.1)(expo@51.0.27(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(encoding@0.1.13))(react-native-reanimated@3.10.1(@babel/core@7.24.5)(react-native@0.74.5(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-safe-area-context@4.10.5(react-native@0.74.5(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-screens@3.31.1(react-native@0.74.5(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native@0.74.5(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0)(typescript@5.5.4) - : dependencies: + expo-router@3.5.21(hgbnujebzanrutajdi4bfceakq): + dependencies: '@expo/metro-runtime': 3.2.1(react-native@0.74.5(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0)) '@expo/server': 0.4.4(typescript@5.5.4) '@radix-ui/react-slot': 1.0.1(react@18.2.0) @@ -30813,7 +30812,7 @@ snapshots: react-native-screens: 3.31.1(react-native@0.74.5(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0) schema-utils: 4.2.0 optionalDependencies: - '@react-navigation/drawer': 6.7.2(@react-navigation/native@6.1.18(react-native@0.74.5(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-gesture-handler@2.16.2(react-native@0.74.5(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-reanimated@3.10.1(@babel/core@7.24.5)(react-native@0.74.5(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-safe-area-context@4.10.5(react-native@0.74.5(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-screens@3.31.1(react-native@0.74.5(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native@0.74.5(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0) + '@react-navigation/drawer': 6.7.2(yxjigtmgi5w2ew3hyzeaduv44u) react-native-reanimated: 3.10.1(@babel/core@7.24.5)(react-native@0.74.5(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0) transitivePeerDependencies: - encoding @@ -30823,8 +30822,8 @@ snapshots: - supports-color - typescript - ? expo-router@3.5.21(@react-navigation/drawer@6.7.2(@react-navigation/native@6.1.18(react-native@0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-gesture-handler@2.16.2(react-native@0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-reanimated@3.10.1(@babel/core@7.24.9)(react-native@0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-safe-area-context@4.10.5(react-native@0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-screens@3.31.1(react-native@0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native@0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(encoding@0.1.13)(expo-constants@16.0.2(expo@51.0.27(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(encoding@0.1.13)))(expo-linking@6.3.1(expo@51.0.27(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(encoding@0.1.13)))(expo-modules-autolinking@1.11.1)(expo-status-bar@1.12.1)(expo@51.0.27(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(encoding@0.1.13))(react-native-reanimated@3.10.1(@babel/core@7.24.9)(react-native@0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-safe-area-context@4.10.5(react-native@0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-screens@3.31.1(react-native@0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native@0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0)(typescript@5.3.3) - : dependencies: + expo-router@3.5.21(zeus6eibm4it6pzage7bp7blp4): + dependencies: '@expo/metro-runtime': 3.2.1(react-native@0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0)) '@expo/server': 0.4.4(typescript@5.3.3) '@radix-ui/react-slot': 1.0.1(react@18.2.0) @@ -30841,7 +30840,7 @@ snapshots: react-native-screens: 3.31.1(react-native@0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0) schema-utils: 4.2.0 optionalDependencies: - '@react-navigation/drawer': 6.7.2(@react-navigation/native@6.1.18(react-native@0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-gesture-handler@2.16.2(react-native@0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-reanimated@3.10.1(@babel/core@7.24.9)(react-native@0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-safe-area-context@4.10.5(react-native@0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-screens@3.31.1(react-native@0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native@0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0) + '@react-navigation/drawer': 6.7.2(qzulpltu3lo63pjt7izylm2n5i) react-native-reanimated: 3.10.1(@babel/core@7.24.9)(react-native@0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0) transitivePeerDependencies: - encoding @@ -36621,8 +36620,8 @@ snapshots: - supports-color - utf-8-validate - ? react-navigation-stack@2.10.4(@react-native-community/masked-view@0.1.11(react-native@0.74.5(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-gesture-handler@2.16.2(react-native@0.74.5(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-safe-area-context@4.10.5(react-native@0.74.5(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-screens@3.31.1(react-native@0.74.5(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native@0.74.5(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react-navigation@4.4.4(react-native@0.74.5(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react@18.2.0) - : dependencies: + react-navigation-stack@2.10.4(evsawqdcqkvgavridqb4swxtby): + dependencies: '@react-native-community/masked-view': 0.1.11(react-native@0.74.5(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0) color: 3.2.1 react: 18.2.0 @@ -36633,8 +36632,8 @@ snapshots: react-native-screens: 3.31.1(react-native@0.74.5(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0) react-navigation: 4.4.4(react-native@0.74.5(@babel/core@7.24.5)(@babel/preset-env@7.25.2(@babel/core@7.24.5))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0) - ? react-navigation-stack@2.10.4(@react-native-community/masked-view@0.1.11(react-native@0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-gesture-handler@2.16.2(react-native@0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-safe-area-context@4.10.5(react-native@0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-screens@3.31.1(react-native@0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native@0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react-navigation@4.4.4(react-native@0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react@18.2.0) - : dependencies: + react-navigation-stack@2.10.4(pvhyv626m34wzucu26rkz7owva): + dependencies: '@react-native-community/masked-view': 0.1.11(react-native@0.74.5(@babel/core@7.24.9)(@babel/preset-env@7.25.2(@babel/core@7.24.9))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0))(react@18.2.0) color: 3.2.1 react: 18.2.0 From 7de007841a4347bb8e9412d1647f4642bb44867f Mon Sep 17 00:00:00 2001 From: Ralf Kistner Date: Mon, 2 Sep 2024 13:05:40 +0200 Subject: [PATCH 07/14] Expand RN user-agent. --- packages/react-native/src/sync/stream/ReactNativeRemote.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-native/src/sync/stream/ReactNativeRemote.ts b/packages/react-native/src/sync/stream/ReactNativeRemote.ts index b8c23cc1..2c25a112 100644 --- a/packages/react-native/src/sync/stream/ReactNativeRemote.ts +++ b/packages/react-native/src/sync/stream/ReactNativeRemote.ts @@ -46,7 +46,7 @@ export class ReactNativeRemote extends AbstractRemote { } getUserAgent(): string { - return `${super.getUserAgent()} (react-native/${POWERSYNC_RN_VERSION})`; + return `${super.getUserAgent()} (react-native/${POWERSYNC_RN_VERSION}) react-native/${Platform.constants.reactNativeVersion.major}.${Platform.constants.reactNativeVersion.minor} ${Platform.OS}/${Platform.Version} `; } async getBSON(): Promise { From 72067188682ac686d74b3664ac7e0f337561250e Mon Sep 17 00:00:00 2001 From: Ralf Kistner Date: Thu, 5 Sep 2024 11:16:04 +0200 Subject: [PATCH 08/14] Update userAgent info. --- .../src/client/sync/stream/AbstractRemote.ts | 2 +- .../src/sync/stream/ReactNativeRemote.ts | 7 +- packages/web/src/db/sync/WebRemote.ts | 9 +- packages/web/src/db/sync/userAgent.ts | 77 ++++++++++++++++ packages/web/tests/userAgent.test.ts | 91 +++++++++++++++++++ 5 files changed, 183 insertions(+), 3 deletions(-) create mode 100644 packages/web/src/db/sync/userAgent.ts create mode 100644 packages/web/tests/userAgent.test.ts diff --git a/packages/common/src/client/sync/stream/AbstractRemote.ts b/packages/common/src/client/sync/stream/AbstractRemote.ts index d4ed38c8..730d438c 100644 --- a/packages/common/src/client/sync/stream/AbstractRemote.ts +++ b/packages/common/src/client/sync/stream/AbstractRemote.ts @@ -217,7 +217,7 @@ export abstract class AbstractRemote { const bson = await this.getBSON(); // Add the user agent in the setup payload - we can't set custom - // headers with websockets. The browser userAgent is however added + // headers with websockets on web. The browser userAgent is however added // automatically as a header. const userAgent = this.getUserAgent(); diff --git a/packages/react-native/src/sync/stream/ReactNativeRemote.ts b/packages/react-native/src/sync/stream/ReactNativeRemote.ts index 2c25a112..160379e6 100644 --- a/packages/react-native/src/sync/stream/ReactNativeRemote.ts +++ b/packages/react-native/src/sync/stream/ReactNativeRemote.ts @@ -46,7 +46,12 @@ export class ReactNativeRemote extends AbstractRemote { } getUserAgent(): string { - return `${super.getUserAgent()} (react-native/${POWERSYNC_RN_VERSION}) react-native/${Platform.constants.reactNativeVersion.major}.${Platform.constants.reactNativeVersion.minor} ${Platform.OS}/${Platform.Version} `; + return [ + super.getUserAgent(), + `powersync-react-native/${POWERSYNC_RN_VERSION}`, + `react-native/${Platform.constants.reactNativeVersion.major}.${Platform.constants.reactNativeVersion.minor}`, + `${Platform.OS}/${Platform.Version}` + ].join(' '); } async getBSON(): Promise { diff --git a/packages/web/src/db/sync/WebRemote.ts b/packages/web/src/db/sync/WebRemote.ts index 29622aea..af4337dc 100644 --- a/packages/web/src/db/sync/WebRemote.ts +++ b/packages/web/src/db/sync/WebRemote.ts @@ -11,6 +11,7 @@ import { } from '@powersync/common'; import { version as POWERSYNC_WEB_VERSION } from '../../../package.json'; +import { getUserAgentInfo } from './userAgent'; /* * Depends on browser's implementation of global fetch. @@ -36,7 +37,13 @@ export class WebRemote extends AbstractRemote { } getUserAgent(): string { - return `${super.getUserAgent()} (web/${POWERSYNC_WEB_VERSION})`; + let ua = [super.getUserAgent(), `powersync-web/${POWERSYNC_WEB_VERSION}`]; + try { + ua.push(...getUserAgentInfo()); + } catch (e) { + this.logger.warn('Failed to get user agent info', e); + } + return ua.join(' '); } async getBSON(): Promise { diff --git a/packages/web/src/db/sync/userAgent.ts b/packages/web/src/db/sync/userAgent.ts new file mode 100644 index 00000000..0838d868 --- /dev/null +++ b/packages/web/src/db/sync/userAgent.ts @@ -0,0 +1,77 @@ +export interface NavigatorInfo { + userAgent: string; + + userAgentData?: { + brands?: { brand: string; version: string }[]; + platform?: string; + }; +} + +/** + * Get a minimal representation of browser, version and operating system. + * + * The goal is to get enough environemnt info to reproduce issues, but no + * more. + */ +export function getUserAgentInfo(nav?: NavigatorInfo): string[] { + nav ??= navigator; + + const browser = getBrowserInfo(nav); + const os = getOsInfo(nav); + return [browser, os].filter((v) => v != null); +} + +function getBrowserInfo(nav: NavigatorInfo): string | null { + const brands = nav.userAgentData?.brands; + if (brands != null) { + const tests = [ + { name: 'Google Chrome', value: 'Chrome' }, + { name: 'Opera', value: 'Opera' }, + { name: 'Edge', value: 'Edge' }, + { name: 'Chromium', value: 'Chromium' } + ]; + for (let { name, value } of tests) { + const brand = brands.find((b) => b.brand == name); + if (brand != null) { + return `${value}/${brand.version}`; + } + } + } + + const ua = nav.userAgent; + const regexps = [ + { re: /(?:firefox|fxios)\/(\d+)/i, value: 'Firefox' }, + { re: /(?:edg|edge|edga|edgios)\/(\d+)/i, value: 'Edge' }, + { re: /opr\/(\d+)/i, value: 'Opera' }, + { re: /(?:chrome|chromium|crios)\/(\d+)/i, value: 'Chrome' }, + { re: /version\/(\d+).*safari/i, value: 'Safari' } + ]; + for (let { re, value } of regexps) { + const match = re.exec(ua); + if (match != null) { + return `${value}/${match[1]}`; + } + } + return null; +} + +function getOsInfo(nav: NavigatorInfo): string | null { + if (nav.userAgentData?.platform != null) { + return nav.userAgentData.platform.toLowerCase(); + } + + const ua = nav.userAgent; + const regexps = [ + { re: /windows/i, value: 'windows' }, + { re: /android/i, value: 'android' }, + { re: /linux/i, value: 'linux' }, + { re: /iphone|ipad|ipod/i, value: 'ios' }, + { re: /macintosh|mac os x/i, value: 'macos' } + ]; + for (let { re, value } of regexps) { + if (re.test(ua)) { + return value; + } + } + return null; +} diff --git a/packages/web/tests/userAgent.test.ts b/packages/web/tests/userAgent.test.ts new file mode 100644 index 00000000..532ee7e0 --- /dev/null +++ b/packages/web/tests/userAgent.test.ts @@ -0,0 +1,91 @@ +import { describe, expect, it } from 'vitest'; +import { getUserAgentInfo } from '../src/db/sync/userAgent'; + +describe('userAgent', () => { + it('should get browser info from userAgent', function () { + expect( + getUserAgentInfo({ + userAgent: + 'Mozilla/5.0 (iPhone; CPU iPhone OS 17_0_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.6 Mobile/YD2FSJ Safari/617.8' + }) + ).toEqual(['Safari/16', 'ios']); + expect( + getUserAgentInfo({ + userAgent: + 'Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.6613.99 Mobile Safari/537.36' + }) + ).toEqual(['Chrome/128', 'android']); + expect( + getUserAgentInfo({ + userAgent: 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:130.0) Gecko/20100101 Firefox/130.0' + }) + ).toEqual(['Firefox/130', 'linux']); + + expect( + getUserAgentInfo({ + userAgent: + 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36' + }) + ).toEqual(['Chrome/128', 'linux']); + + expect( + getUserAgentInfo({ + userAgent: + 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36 OPR/113.0.0.0' + }) + ).toEqual(['Opera/113', 'linux']); + + expect( + getUserAgentInfo({ + userAgent: + 'Mozilla/5.0(iPad; U; CPU iPhone OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B314 Safari/531.21.10' + }) + ).toEqual(['Safari/4', 'ios']); + + expect( + getUserAgentInfo({ + userAgent: + 'Mozilla/5.0 (Linux; Android 10; HD1913) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.6613.99 Mobile Safari/537.36 EdgA/127.0.2651.111' + }) + ).toEqual(['Edge/127', 'android']); + + expect( + getUserAgentInfo({ + userAgent: + 'Mozilla/5.0 (iPhone; CPU iPhone OS 17_6_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 EdgiOS/128.2739.60 Mobile/15E148 Safari/605.1.15' + }) + ).toEqual(['Edge/128', 'ios']); + + expect( + getUserAgentInfo({ + userAgent: + 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; Xbox; Xbox One) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36 Edge/44.18363.8131' + }) + ).toEqual(['Edge/44', 'windows']); + }); + + it('should get browser info from userAgentData', function () { + expect( + getUserAgentInfo({ + userAgent: '', + userAgentData: { + platform: 'Android', + brands: [ + { + brand: 'Not)A;Brand', + version: '99' + }, + { + brand: 'Opera', + version: '113' + }, + { + brand: 'Chromium', + version: '127' + } + ] + } + }) + ).toEqual(['Opera/113', 'android']); + }); +}); From 537415a2af87ecd6a3674f5c87c62c4d50f8bb8b Mon Sep 17 00:00:00 2001 From: Ralf Kistner Date: Thu, 5 Sep 2024 11:35:16 +0200 Subject: [PATCH 09/14] Add client id. --- .../common/src/client/AbstractPowerSyncDatabase.ts | 9 +++++++++ .../src/client/sync/bucket/BucketStorageAdapter.ts | 5 +++++ .../src/client/sync/bucket/SqliteBucketStorage.ts | 14 ++++++++++++++ .../stream/AbstractStreamingSyncImplementation.ts | 9 +++++++-- .../src/client/sync/stream/streaming-sync-types.ts | 2 ++ 5 files changed, 37 insertions(+), 2 deletions(-) diff --git a/packages/common/src/client/AbstractPowerSyncDatabase.ts b/packages/common/src/client/AbstractPowerSyncDatabase.ts index 31cc748a..a2fe993b 100644 --- a/packages/common/src/client/AbstractPowerSyncDatabase.ts +++ b/packages/common/src/client/AbstractPowerSyncDatabase.ts @@ -533,6 +533,15 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver { + return this.bucketStorageAdapter.getClientId(); + } + private async handleCrudCheckpoint(lastClientId: number, writeCheckpoint?: string) { return this.writeTransaction(async (tx) => { await tx.execute(`DELETE FROM ${PSInternalTable.CRUD} WHERE id <= ?`, [lastClientId]); diff --git a/packages/common/src/client/sync/bucket/BucketStorageAdapter.ts b/packages/common/src/client/sync/bucket/BucketStorageAdapter.ts index 5cea03a2..028eb60f 100644 --- a/packages/common/src/client/sync/bucket/BucketStorageAdapter.ts +++ b/packages/common/src/client/sync/bucket/BucketStorageAdapter.ts @@ -79,4 +79,9 @@ export interface BucketStorageAdapter extends BaseObserver; getMaxOpId(): string; + + /** + * Get an unique client id. + */ + getClientId(): Promise; } diff --git a/packages/common/src/client/sync/bucket/SqliteBucketStorage.ts b/packages/common/src/client/sync/bucket/SqliteBucketStorage.ts index add25c5b..95cf30ee 100644 --- a/packages/common/src/client/sync/bucket/SqliteBucketStorage.ts +++ b/packages/common/src/client/sync/bucket/SqliteBucketStorage.ts @@ -23,6 +23,7 @@ export class SqliteBucketStorage extends BaseObserver imp private pendingBucketDeletes: boolean; private _hasCompletedSync: boolean; private updateListener: () => void; + private _clientId?: Promise; /** * Count up, and do a compact on startup. @@ -62,9 +63,22 @@ export class SqliteBucketStorage extends BaseObserver imp this.updateListener?.(); } + async _getClientId() { + const row = await this.db.get<{ client_id: string }>('SELECT powersync_client_id() as client_id'); + return row['client_id']; + } + + getClientId() { + if (this._clientId == null) { + this._clientId = this._getClientId(); + } + return this._clientId!; + } + getMaxOpId() { return MAX_OP_ID; } + /** * Reset any caches. */ diff --git a/packages/common/src/client/sync/stream/AbstractStreamingSyncImplementation.ts b/packages/common/src/client/sync/stream/AbstractStreamingSyncImplementation.ts index 0329f29a..73cce7d1 100644 --- a/packages/common/src/client/sync/stream/AbstractStreamingSyncImplementation.ts +++ b/packages/common/src/client/sync/stream/AbstractStreamingSyncImplementation.ts @@ -208,7 +208,9 @@ export abstract class AbstractStreamingSyncImplementation } async getWriteCheckpoint(): Promise { - const response = await this.options.remote.get('/write-checkpoint2.json'); + const clientId = await this.options.adapter.getClientId(); + let path = `/write-checkpoint2.json?client_id=${clientId}`; + const response = await this.options.remote.get(path); return response['data']['write_checkpoint'] as string; } @@ -456,6 +458,8 @@ The next upload iteration will be delayed.`); let bucketSet = new Set(initialBuckets.keys()); + const clientId = await this.options.adapter.getClientId(); + this.logger.debug('Requesting stream from server'); const syncOptions: SyncStreamOptions = { @@ -465,7 +469,8 @@ The next upload iteration will be delayed.`); buckets: req, include_checksum: true, raw_data: true, - parameters: resolvedOptions.params + parameters: resolvedOptions.params, + client_id: clientId } }; diff --git a/packages/common/src/client/sync/stream/streaming-sync-types.ts b/packages/common/src/client/sync/stream/streaming-sync-types.ts index fab67201..d314d912 100644 --- a/packages/common/src/client/sync/stream/streaming-sync-types.ts +++ b/packages/common/src/client/sync/stream/streaming-sync-types.ts @@ -89,6 +89,8 @@ export interface StreamingSyncRequest { * Client parameters to be passed to the sync rules. */ parameters?: Record; + + client_id?: string; } export interface StreamingSyncCheckpoint { From 1ebcce5e82d3b7cd077a20d544d407a0500bab1e Mon Sep 17 00:00:00 2001 From: Ralf Kistner Date: Thu, 5 Sep 2024 11:50:53 +0200 Subject: [PATCH 10/14] Use powersync_last_synced_at. --- packages/common/src/client/AbstractPowerSyncDatabase.ts | 9 ++++++--- .../common/src/client/sync/bucket/SqliteBucketStorage.ts | 4 ++-- tools/diagnostics-app/src/app/views/sync-diagnostics.tsx | 8 ++++++-- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/packages/common/src/client/AbstractPowerSyncDatabase.ts b/packages/common/src/client/AbstractPowerSyncDatabase.ts index a2fe993b..a8850850 100644 --- a/packages/common/src/client/AbstractPowerSyncDatabase.ts +++ b/packages/common/src/client/AbstractPowerSyncDatabase.ts @@ -301,11 +301,14 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver 0 LIMIT 1'); - const hasSynced = !!result; + const result = await this.database.get<{ synced_at: string | null }>( + 'SELECT powersync_last_synced_at() as synced_at' + ); + const hasSynced = result.synced_at != null; + const syncedAt = result.synced_at != null ? new Date(result.synced_at! + 'Z') : undefined; if (hasSynced != this.currentStatus.hasSynced) { - this.currentStatus = new SyncStatus({ ...this.currentStatus.toJSON(), hasSynced }); + this.currentStatus = new SyncStatus({ ...this.currentStatus.toJSON(), hasSynced, lastSyncedAt: syncedAt }); this.iterateListeners((l) => l.statusChanged?.(this.currentStatus)); } } diff --git a/packages/common/src/client/sync/bucket/SqliteBucketStorage.ts b/packages/common/src/client/sync/bucket/SqliteBucketStorage.ts index 95cf30ee..5944a115 100644 --- a/packages/common/src/client/sync/bucket/SqliteBucketStorage.ts +++ b/packages/common/src/client/sync/bucket/SqliteBucketStorage.ts @@ -128,8 +128,8 @@ export class SqliteBucketStorage extends BaseObserver imp if (this._hasCompletedSync) { return true; } - const r = await this.db.execute(`SELECT name, last_applied_op FROM ps_buckets WHERE last_applied_op > 0 LIMIT 1`); - const completed = !!r.rows?.length; + const r = await this.db.get<{ synced_at: string | null }>(`SELECT powersync_last_synced_at() as synced_at`); + const completed = r.synced_at != null; if (completed) { this._hasCompletedSync = true; } diff --git a/tools/diagnostics-app/src/app/views/sync-diagnostics.tsx b/tools/diagnostics-app/src/app/views/sync-diagnostics.tsx index b628ae8d..68f24d31 100644 --- a/tools/diagnostics-app/src/app/views/sync-diagnostics.tsx +++ b/tools/diagnostics-app/src/app/views/sync-diagnostics.tsx @@ -69,14 +69,16 @@ export default function SyncDiagnosticsPage() { const [bucketRows, setBucketRows] = React.useState(null); const [tableRows, setTableRows] = React.useState(null); const [syncError, setSyncError] = React.useState(syncErrorTracker.lastSyncError); + const [lastSyncedAt, setlastSyncedAt] = React.useState(null); const bucketRowsLoading = bucketRows == null; const tableRowsLoading = tableRows == null; const refreshStats = async () => { // Similar to db.currentState.hasSynced, but synchronized to the onChange events - const hasSynced = await db.getOptional('SELECT 1 FROM ps_buckets WHERE last_applied_op > 0 LIMIT 1'); - if (hasSynced != null) { + const { synced_at } = await db.get<{ synced_at: string | null }>('SELECT powersync_last_synced_at() as synced_at'); + setlastSyncedAt(synced_at ? new Date(synced_at + 'Z') : null); + if (synced_at != null) { // These are potentially expensive queries - do not run during initial sync const bucketRows = await db.getAll(BUCKETS_QUERY); const tableRows = await db.getAll(TABLES_QUERY); @@ -207,6 +209,7 @@ export default function SyncDiagnosticsPage() { Total Data Size Total Metadata Size Total Downloaded Size + Last Synced At {totals.buckets} @@ -215,6 +218,7 @@ export default function SyncDiagnosticsPage() { {formatBytes(totals.data_size)} {formatBytes(totals.metadata_size)} {formatBytes(totals.download_size)} + {lastSyncedAt?.toLocaleTimeString()} From 2864cd855045fcbdc935fc9be16190ca1eb0af4e Mon Sep 17 00:00:00 2001 From: Ralf Kistner Date: Thu, 5 Sep 2024 11:53:02 +0200 Subject: [PATCH 11/14] Cast target_op. --- .../src/client/sync/bucket/SqliteBucketStorage.ts | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/packages/common/src/client/sync/bucket/SqliteBucketStorage.ts b/packages/common/src/client/sync/bucket/SqliteBucketStorage.ts index 5944a115..3b502358 100644 --- a/packages/common/src/client/sync/bucket/SqliteBucketStorage.ts +++ b/packages/common/src/client/sync/bucket/SqliteBucketStorage.ts @@ -291,7 +291,9 @@ export class SqliteBucketStorage extends BaseObserver imp return false; } - const response = await tx.execute("UPDATE ps_buckets SET target_op = ? WHERE name='$local'", [opId]); + const response = await tx.execute("UPDATE ps_buckets SET target_op = CAST(? as INTEGER) WHERE name='$local'", [ + opId + ]); this.logger.debug(['[updateLocalTarget] Response from updating target_op ', JSON.stringify(response)]); return true; }); @@ -340,10 +342,14 @@ export class SqliteBucketStorage extends BaseObserver imp if (writeCheckpoint) { const crudResult = await tx.execute('SELECT 1 FROM ps_crud LIMIT 1'); if (crudResult.rows?.length) { - await tx.execute("UPDATE ps_buckets SET target_op = ? WHERE name='$local'", [writeCheckpoint]); + await tx.execute("UPDATE ps_buckets SET target_op = CAST(? as INTEGER) WHERE name='$local'", [ + writeCheckpoint + ]); } } else { - await tx.execute("UPDATE ps_buckets SET target_op = ? WHERE name='$local'", [this.getMaxOpId()]); + await tx.execute("UPDATE ps_buckets SET target_op = CAST(? as INTEGER) WHERE name='$local'", [ + this.getMaxOpId() + ]); } }); } From aff03ea92372ec4927317668aa31c58580ba7cce Mon Sep 17 00:00:00 2001 From: Ralf Kistner Date: Thu, 5 Sep 2024 12:00:58 +0200 Subject: [PATCH 12/14] Validate extension version number. --- .../src/client/AbstractPowerSyncDatabase.ts | 27 +++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/packages/common/src/client/AbstractPowerSyncDatabase.ts b/packages/common/src/client/AbstractPowerSyncDatabase.ts index a8850850..d97d9642 100644 --- a/packages/common/src/client/AbstractPowerSyncDatabase.ts +++ b/packages/common/src/client/AbstractPowerSyncDatabase.ts @@ -291,8 +291,7 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver cb.initialized?.()); } + private async _loadVersion() { + try { + const { version } = await this.database.get<{ version: string }>('SELECT powersync_rs_version() as version'); + this.sdkVersion = version; + } catch (e) { + throw new Error(`The powersync extension is not loaded correctly. Details: ${e.message}`); + } + let versionInts: number[]; + try { + versionInts = this.sdkVersion!.split(/[.\/]/) + .slice(0, 3) + .map((n) => parseInt(n)); + } catch (e) { + throw new Error( + `Unsupported powersync extension version. Need ^0.2.0, got: ${this.sdkVersion}. Details: ${e.message}` + ); + } + + // Validate ^0.2.0 + if (versionInts[0] != 0 || versionInts[1] != 2 || versionInts[2] < 0) { + throw new Error(`Unsupported powersync extension version. Need ^0.2.0, got: ${this.sdkVersion}`); + } + } + protected async updateHasSynced() { const result = await this.database.get<{ synced_at: string | null }>( 'SELECT powersync_last_synced_at() as synced_at' From 5d542b9a46c807215dd5727e1eefcd1ec9cd9b5d Mon Sep 17 00:00:00 2001 From: Ralf Kistner Date: Thu, 5 Sep 2024 16:39:44 +0200 Subject: [PATCH 13/14] Remove version in user agent from web and react-native. --- packages/react-native/src/sync/stream/ReactNativeRemote.ts | 4 +--- packages/web/src/db/sync/WebRemote.ts | 3 +-- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/packages/react-native/src/sync/stream/ReactNativeRemote.ts b/packages/react-native/src/sync/stream/ReactNativeRemote.ts index 092a216c..2f6f8e52 100644 --- a/packages/react-native/src/sync/stream/ReactNativeRemote.ts +++ b/packages/react-native/src/sync/stream/ReactNativeRemote.ts @@ -18,8 +18,6 @@ import { BSON } from 'bson'; import { fetch } from 'react-native-fetch-api'; -import { version as POWERSYNC_RN_VERSION } from '../../../package.json'; - export const STREAMING_POST_TIMEOUT_MS = 30_000; /** @@ -48,7 +46,7 @@ export class ReactNativeRemote extends AbstractRemote { getUserAgent(): string { return [ super.getUserAgent(), - `powersync-react-native/${POWERSYNC_RN_VERSION}`, + `powersync-react-native`, `react-native/${Platform.constants.reactNativeVersion.major}.${Platform.constants.reactNativeVersion.minor}`, `${Platform.OS}/${Platform.Version}` ].join(' '); diff --git a/packages/web/src/db/sync/WebRemote.ts b/packages/web/src/db/sync/WebRemote.ts index af4337dc..b5e8d580 100644 --- a/packages/web/src/db/sync/WebRemote.ts +++ b/packages/web/src/db/sync/WebRemote.ts @@ -10,7 +10,6 @@ import { RemoteConnector } from '@powersync/common'; -import { version as POWERSYNC_WEB_VERSION } from '../../../package.json'; import { getUserAgentInfo } from './userAgent'; /* @@ -37,7 +36,7 @@ export class WebRemote extends AbstractRemote { } getUserAgent(): string { - let ua = [super.getUserAgent(), `powersync-web/${POWERSYNC_WEB_VERSION}`]; + let ua = [super.getUserAgent(), `powersync-web`]; try { ua.push(...getUserAgentInfo()); } catch (e) { From 447f979b62b55a7b4d020affbb523874696c419e Mon Sep 17 00:00:00 2001 From: Ralf Kistner Date: Thu, 5 Sep 2024 16:49:10 +0200 Subject: [PATCH 14/14] Add changesets. --- .changeset/brown-eggs-dress.md | 5 +++++ .changeset/cuddly-paws-allow.md | 5 +++++ .changeset/popular-phones-knock.md | 5 +++++ .changeset/slow-lizards-sleep.md | 5 +++++ .changeset/small-pants-relax.md | 5 +++++ .changeset/soft-mice-type.md | 5 +++++ .changeset/tiny-worms-mate.md | 5 +++++ .changeset/two-walls-nail.md | 5 +++++ 8 files changed, 40 insertions(+) create mode 100644 .changeset/brown-eggs-dress.md create mode 100644 .changeset/cuddly-paws-allow.md create mode 100644 .changeset/popular-phones-knock.md create mode 100644 .changeset/slow-lizards-sleep.md create mode 100644 .changeset/small-pants-relax.md create mode 100644 .changeset/soft-mice-type.md create mode 100644 .changeset/tiny-worms-mate.md create mode 100644 .changeset/two-walls-nail.md diff --git a/.changeset/brown-eggs-dress.md b/.changeset/brown-eggs-dress.md new file mode 100644 index 00000000..7c649182 --- /dev/null +++ b/.changeset/brown-eggs-dress.md @@ -0,0 +1,5 @@ +--- +'@powersync/common': minor +--- + +Improve performance of MOVE and REMOVE operations. diff --git a/.changeset/cuddly-paws-allow.md b/.changeset/cuddly-paws-allow.md new file mode 100644 index 00000000..3d1b1bd7 --- /dev/null +++ b/.changeset/cuddly-paws-allow.md @@ -0,0 +1,5 @@ +--- +'@powersync/react-native': minor +--- + +Use react-native-quick-sqlite 1.3.0 / powersync-sqlite-core 0.2.1. diff --git a/.changeset/popular-phones-knock.md b/.changeset/popular-phones-knock.md new file mode 100644 index 00000000..4a520ea8 --- /dev/null +++ b/.changeset/popular-phones-knock.md @@ -0,0 +1,5 @@ +--- +'@powersync/common': patch +--- + +Always cast `target_op` (write checkpoint) to ensure it's an integer. diff --git a/.changeset/slow-lizards-sleep.md b/.changeset/slow-lizards-sleep.md new file mode 100644 index 00000000..42a4ef92 --- /dev/null +++ b/.changeset/slow-lizards-sleep.md @@ -0,0 +1,5 @@ +--- +'@powersync/common': minor +--- + +Add custom x-user-agent header and client_id parameter to requests. diff --git a/.changeset/small-pants-relax.md b/.changeset/small-pants-relax.md new file mode 100644 index 00000000..5b3b04c5 --- /dev/null +++ b/.changeset/small-pants-relax.md @@ -0,0 +1,5 @@ +--- +'@powersync/web': minor +--- + +Use wa-sqlite 0.3.0 / powersync-sqlite-core 0.2.0. diff --git a/.changeset/soft-mice-type.md b/.changeset/soft-mice-type.md new file mode 100644 index 00000000..bf0ed704 --- /dev/null +++ b/.changeset/soft-mice-type.md @@ -0,0 +1,5 @@ +--- +'@powersync/common': minor +--- + +Emit update notifications on `disconnectAndClear()`. diff --git a/.changeset/tiny-worms-mate.md b/.changeset/tiny-worms-mate.md new file mode 100644 index 00000000..70229a86 --- /dev/null +++ b/.changeset/tiny-worms-mate.md @@ -0,0 +1,5 @@ +--- +'@powersync/common': patch +--- + +Validate that the powersync-sqlite-core version number is in a compatible range of ^0.2.0. diff --git a/.changeset/two-walls-nail.md b/.changeset/two-walls-nail.md new file mode 100644 index 00000000..658bf4f2 --- /dev/null +++ b/.changeset/two-walls-nail.md @@ -0,0 +1,5 @@ +--- +'@powersync/common': minor +--- + +Persist lastSyncedAt timestamp.