From 73daf4985109c0a9164fc4931914f0e5183df7b4 Mon Sep 17 00:00:00 2001 From: Steven Ontong Date: Tue, 22 Oct 2024 11:25:10 +0200 Subject: [PATCH 01/17] update watched queries when schema updated --- .changeset/itchy-years-drop.md | 5 +++ .../src/client/AbstractPowerSyncDatabase.ts | 38 +++++++++++++++++-- 2 files changed, 40 insertions(+), 3 deletions(-) create mode 100644 .changeset/itchy-years-drop.md diff --git a/.changeset/itchy-years-drop.md b/.changeset/itchy-years-drop.md new file mode 100644 index 000000000..39c9bfc38 --- /dev/null +++ b/.changeset/itchy-years-drop.md @@ -0,0 +1,5 @@ +--- +'@powersync/common': minor +--- + +Update watched queries when schema has been updated. diff --git a/packages/common/src/client/AbstractPowerSyncDatabase.ts b/packages/common/src/client/AbstractPowerSyncDatabase.ts index d587d9760..b4acfde12 100644 --- a/packages/common/src/client/AbstractPowerSyncDatabase.ts +++ b/packages/common/src/client/AbstractPowerSyncDatabase.ts @@ -103,6 +103,7 @@ export interface WatchOnChangeHandler { export interface PowerSyncDBListener extends StreamingSyncImplementationListener { initialized: () => void; + schemaChanged: (schema: Schema) => void; } export interface PowerSyncCloseOptions { @@ -359,6 +360,7 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver cb.schemaChanged?.(schema)); } /** @@ -756,7 +758,7 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver { + const watchQuery = async (abortSignal: AbortSignal) => { try { const resolvedTables = await this.resolveTables(sql, parameters, options); @@ -778,13 +780,43 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver { + const abortController = new AbortController(); + + let disposeSchemaListener: (() => void) | null = null; + + const stopWatching = () => { + abortController.abort('Abort triggered'); + disposeSchemaListener?.(); + disposeSchemaListener = null; + // Stop listening to upstream abort for this watch + options?.signal?.removeEventListener('abort', stopWatching); + }; + + options?.signal?.addEventListener('abort', stopWatching); + + disposeSchemaListener = this.registerListener({ + schemaChanged: () => { + stopWatching(); + // Re trigger the watched query (recursively) + triggerWatchedQuery(); + } + }); + + return watchQuery(abortController.signal); + }; + + triggerWatchedQuery(); } /** From 1125911940fb9f9571a5de286ee1a53c09ef660c Mon Sep 17 00:00:00 2001 From: Christiaan Landman Date: Tue, 22 Oct 2024 14:19:47 +0200 Subject: [PATCH 02/17] Using iterateAsyncListeners for schema change event. Moved optionalSync test schema to separate file. --- .../src/client/AbstractPowerSyncDatabase.ts | 17 ++-- packages/web/tests/offline.test.ts | 63 +------------- .../web/tests/utils/optionalSyncTestSchema.ts | 58 +++++++++++++ packages/web/tests/watch.test.ts | 14 +-- packages/web/tests/watchSchemaChange.test.ts | 85 +++++++++++++++++++ 5 files changed, 161 insertions(+), 76 deletions(-) create mode 100644 packages/web/tests/utils/optionalSyncTestSchema.ts create mode 100644 packages/web/tests/watchSchemaChange.test.ts diff --git a/packages/common/src/client/AbstractPowerSyncDatabase.ts b/packages/common/src/client/AbstractPowerSyncDatabase.ts index b4acfde12..7907ba460 100644 --- a/packages/common/src/client/AbstractPowerSyncDatabase.ts +++ b/packages/common/src/client/AbstractPowerSyncDatabase.ts @@ -103,7 +103,7 @@ export interface WatchOnChangeHandler { export interface PowerSyncDBListener extends StreamingSyncImplementationListener { initialized: () => void; - schemaChanged: (schema: Schema) => void; + schemaChanged: (schema: Schema) => Promise; } export interface PowerSyncCloseOptions { @@ -359,8 +359,9 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver cb.schemaChanged?.(schema)); + await this.iterateAsyncListeners(async (cb) => cb.schemaChanged?.(schema)); } /** @@ -761,7 +762,6 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver { try { const resolvedTables = await this.resolveTables(sql, parameters, options); - // Fetch initial data const result = await this.executeReadOnly(sql, parameters); onResult(result); @@ -790,11 +790,9 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver { + const triggerWatchedQuery = async () => { const abortController = new AbortController(); - let disposeSchemaListener: (() => void) | null = null; - const stopWatching = () => { abortController.abort('Abort triggered'); disposeSchemaListener?.(); @@ -804,16 +802,15 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver { + schemaChanged: async () => { stopWatching(); // Re trigger the watched query (recursively) - triggerWatchedQuery(); + await triggerWatchedQuery(); } }); - return watchQuery(abortController.signal); + await watchQuery(abortController.signal); }; triggerWatchedQuery(); diff --git a/packages/web/tests/offline.test.ts b/packages/web/tests/offline.test.ts index bf7bf6fd3..65f894e58 100644 --- a/packages/web/tests/offline.test.ts +++ b/packages/web/tests/offline.test.ts @@ -1,67 +1,12 @@ import { AbstractPowerSyncDatabase, column, Schema, Table } from '@powersync/common'; import { PowerSyncDatabase } from '@powersync/web'; import { afterEach, beforeEach, describe, expect, it } from 'vitest'; +import { makeOptionalSyncSchema } from './utils/optionalSyncTestSchema'; const assetId = '2290de4f-0488-4e50-abed-f8e8eb1d0b42'; const userId = '3390de4f-0488-4e50-abed-f8e8eb1d0b42'; const customerId = '4490de4f-0488-4e50-abed-f8e8eb1d0b42'; -const assetsDef = { - name: 'assets', - columns: { - created_at: column.text, - make: column.text, - model: column.text, - serial_number: column.text, - quantity: column.integer, - user_id: column.text, - customer_id: column.text, - description: column.text - }, - options: { indexes: { makemodel: ['make, model'] } } -}; - -const customersDef = { - name: 'customers', - columns: { - name: column.text, - email: column.text - }, - options: {} -}; - -function makeSchema(synced: boolean) { - const syncedName = (table: string): string => { - if (synced) { - return table; - } else { - return `inactive_synced_${table}`; - } - }; - - const localName = (table: string): string => { - if (synced) { - return `inactive_local_${table}`; - } else { - return table; - } - }; - return new Schema({ - assets: new Table(assetsDef.columns, { ...assetsDef.options, viewName: syncedName(assetsDef.name) }), - local_assets: new Table(assetsDef.columns, { - ...assetsDef.options, - localOnly: true, - viewName: localName(assetsDef.name) - }), - customers: new Table(customersDef.columns, { ...customersDef.options, viewName: syncedName(customersDef.name) }), - local_customers: new Table(customersDef.columns, { - ...customersDef.options, - localOnly: true, - viewName: localName(customersDef.name) - }) - }); -} - describe('Schema Tests', () => { let db: AbstractPowerSyncDatabase; @@ -73,7 +18,7 @@ describe('Schema Tests', () => { * consistent */ database: { dbFilename: 'test.db' }, - schema: makeSchema(false), + schema: makeOptionalSyncSchema(false), flags: { enableMultiTabs: false } @@ -98,7 +43,7 @@ describe('Schema Tests', () => { expect(await db.getAll('SELECT data FROM ps_crud ORDER BY id')).toEqual([]); // Now switch to the "online" schema - await db.updateSchema(makeSchema(true)); + await db.updateSchema(makeOptionalSyncSchema(true)); // Note that updateSchema cannot be called inside a transaction, and there // is a possibility of crash between updating the schema, and when the data @@ -148,7 +93,7 @@ describe('Schema Tests', () => { const customerWatchTables = await getSourceTables(db, 'SELECT * FROM customers'); expect(customerWatchTables.includes('ps_data_local__local_customers')).toBeTruthy(); - await db.updateSchema(makeSchema(true)); + await db.updateSchema(makeOptionalSyncSchema(true)); const onlineCustomerWatchTables = await getSourceTables(db, 'SELECT * FROM customers'); expect(onlineCustomerWatchTables.includes('ps_data__customers')).toBeTruthy(); diff --git a/packages/web/tests/utils/optionalSyncTestSchema.ts b/packages/web/tests/utils/optionalSyncTestSchema.ts new file mode 100644 index 000000000..7d734314c --- /dev/null +++ b/packages/web/tests/utils/optionalSyncTestSchema.ts @@ -0,0 +1,58 @@ +import { column, Schema, Table } from '@powersync/common'; + +const assetsDef = { + name: 'assets', + columns: { + created_at: column.text, + make: column.text, + model: column.text, + serial_number: column.text, + quantity: column.integer, + user_id: column.text, + customer_id: column.text, + description: column.text + }, + options: {} +}; + +const customersDef = { + name: 'customers', + columns: { + name: column.text, + email: column.text + }, + options: {} +}; + +export function makeOptionalSyncSchema(synced: boolean) { + const syncedName = (table: string): string => { + if (synced) { + return table; + } else { + return `inactive_synced_${table}`; + } + }; + + const localName = (table: string): string => { + if (synced) { + return `inactive_local_${table}`; + } else { + return table; + } + }; + + return new Schema({ + assets: new Table(assetsDef.columns, { ...assetsDef.options, viewName: syncedName(assetsDef.name) }), + local_assets: new Table(assetsDef.columns, { + ...assetsDef.options, + localOnly: true, + viewName: localName(assetsDef.name) + }), + customers: new Table(customersDef.columns, { ...customersDef.options, viewName: syncedName(customersDef.name) }), + local_customers: new Table(customersDef.columns, { + ...customersDef.options, + localOnly: true, + viewName: localName(customersDef.name) + }) + }); +} diff --git a/packages/web/tests/watch.test.ts b/packages/web/tests/watch.test.ts index 6765d80d0..cc96d691b 100644 --- a/packages/web/tests/watch.test.ts +++ b/packages/web/tests/watch.test.ts @@ -1,8 +1,9 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; import { v4 as uuid } from 'uuid'; -import { AbstractPowerSyncDatabase } from '@powersync/common'; +import { AbstractPowerSyncDatabase, QueryResult } from '@powersync/common'; import { PowerSyncDatabase } from '@powersync/web'; import { testSchema } from './utils/testDb'; +import { makeOptionalSyncSchema } from './utils/optionalSyncTestSchema'; vi.useRealTimers(); /** @@ -26,6 +27,7 @@ describe('Watch Tests', () => { enableMultiTabs: false } }); + await powersync.init(); }); afterEach(async () => { @@ -83,6 +85,7 @@ describe('Watch Tests', () => { const receivedUpdates = new Promise((resolve) => { const onUpdate = () => { receivedUpdatesCount++; + if (receivedUpdatesCount == updatesCount) { abortController.abort(); resolve(); @@ -286,8 +289,6 @@ describe('Watch Tests', () => { }); it('should throttle watch callback overflow', async () => { - const abortController = new AbortController(); - const updatesCount = 25; let receivedWithManagedOverflowCount = 0; @@ -300,7 +301,7 @@ describe('Watch Tests', () => { 'SELECT count() AS count FROM assets', [], { onResult: onResultOverflow }, - { signal: overflowAbortController.signal, throttleMs: 1 } + { signal: overflowAbortController.signal, throttleMs: 100 } ); // Allows us to count the number of updates received without the initial trigger @@ -313,10 +314,9 @@ describe('Watch Tests', () => { await new Promise((resolve) => setTimeout(resolve, 1 * throttleDuration)); - abortController.abort(); overflowAbortController.abort(); - // Initial onResult plus two left after overflow was throttled for onChange triggers - expect(receivedWithManagedOverflowCount).toBe(3); + // Initial onResult plus 1 left after overflow was throttled for onChange triggers + expect(receivedWithManagedOverflowCount).toBe(2); }); }); diff --git a/packages/web/tests/watchSchemaChange.test.ts b/packages/web/tests/watchSchemaChange.test.ts new file mode 100644 index 000000000..f032c4aea --- /dev/null +++ b/packages/web/tests/watchSchemaChange.test.ts @@ -0,0 +1,85 @@ +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; +import { v4 as uuid } from 'uuid'; +import { AbstractPowerSyncDatabase, QueryResult } from '@powersync/common'; +import { PowerSyncDatabase } from '@powersync/web'; +import { testSchema } from './utils/testDb'; +import { makeOptionalSyncSchema } from './utils/optionalSyncTestSchema'; +vi.useRealTimers(); + +/** + * There seems to be an issue with Vitest browser mode's setTimeout and + * fake timer functionality. + * e.g. calling: + * await new Promise((resolve) => setTimeout(resolve, 10)); + * waits for 1 second instead of 10ms. + * Setting this to 1 second as a work around. + */ +const throttleDuration = 1000; + +describe('Watch With Schema Change Tests', () => { + let powersync: AbstractPowerSyncDatabase; + + beforeEach(async () => { + powersync = new PowerSyncDatabase({ + database: { dbFilename: 'test-watch-optional-sync.db' }, + schema: makeOptionalSyncSchema(false), + flags: { + enableMultiTabs: false + } + }); + await powersync.init(); + }); + + afterEach(async () => { + await powersync.disconnectAndClear(); + await powersync.close(); + }); + + it('should trigger onResult after schema change', async () => { + const userId = uuid(); + const abortController = new AbortController(); + + let lastResult = 0; + + const onUpdate = (results: QueryResult) => { + lastResult = results.rows?._array[0].count; // `count` from sql output + }; + + powersync.watch( + 'SELECT count() AS count FROM assets', + [], + { onResult: onUpdate }, + { signal: abortController.signal, throttleMs: throttleDuration } + ); + + // Insert 3 records + for (let i = 0; i < 3; i++) { + await powersync.execute('INSERT INTO assets(id, make, customer_id) VALUES (uuid(), ?, ?)', ['test', userId]); + } + await new Promise((resolve) => setTimeout(resolve, throttleDuration * 2)); + + expect(lastResult).toBe(3); + + await powersync.updateSchema(makeOptionalSyncSchema(true)); + + await powersync.writeTransaction(async (tx) => { + // Copy local data to the "online" views. + + await tx.execute( + 'INSERT INTO assets(id, description, customer_id, user_id) SELECT id, description, customer_id, ? FROM inactive_local_assets', + [userId] + ); + + // Delete the "local-only" data. + await tx.execute('DELETE FROM inactive_local_customers'); + await tx.execute('DELETE FROM inactive_local_assets'); + }); + + for (let i = 0; i < 3; i++) { + await powersync.execute('INSERT INTO assets(id, make, customer_id) VALUES (uuid(), ?, ?)', ['test', uuid()]); + } + await new Promise((resolve) => setTimeout(resolve, throttleDuration * 2)); + + expect(lastResult).toBe(6); + }); +}); From 4dc0e6dc10cafbec725a5f1812beb288e4593468 Mon Sep 17 00:00:00 2001 From: Christiaan Landman Date: Tue, 22 Oct 2024 16:03:36 +0200 Subject: [PATCH 03/17] Fixed throttle overflow test breaking. --- packages/web/tests/watch.test.ts | 33 ++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/packages/web/tests/watch.test.ts b/packages/web/tests/watch.test.ts index cc96d691b..0320debf9 100644 --- a/packages/web/tests/watch.test.ts +++ b/packages/web/tests/watch.test.ts @@ -289,23 +289,27 @@ describe('Watch Tests', () => { }); it('should throttle watch callback overflow', async () => { + const overflowAbortController = new AbortController(); const updatesCount = 25; let receivedWithManagedOverflowCount = 0; - const onResultOverflow = () => { - receivedWithManagedOverflowCount++; - }; + const firstResultReceived = new Promise((resolve) => { + const onResultOverflow = () => { + if (receivedWithManagedOverflowCount === 0) { + resolve(); + } + receivedWithManagedOverflowCount++; + }; - const overflowAbortController = new AbortController(); - powersync.watch( - 'SELECT count() AS count FROM assets', - [], - { onResult: onResultOverflow }, - { signal: overflowAbortController.signal, throttleMs: 100 } - ); + powersync.watch( + 'SELECT count() AS count FROM assets', + [], + { onResult: onResultOverflow }, + { signal: overflowAbortController.signal, throttleMs: 1 } + ); + }); - // Allows us to count the number of updates received without the initial trigger - await new Promise((resolve) => setTimeout(resolve, 1 * throttleDuration)); + await firstResultReceived; // Perform a large number of inserts to trigger overflow for (let i = 0; i < updatesCount; i++) { @@ -316,7 +320,8 @@ describe('Watch Tests', () => { overflowAbortController.abort(); - // Initial onResult plus 1 left after overflow was throttled for onChange triggers - expect(receivedWithManagedOverflowCount).toBe(2); + // This fluctuates between 3 and 4 based on timing, but should never be 25 + expect(receivedWithManagedOverflowCount).greaterThan(2); + expect(receivedWithManagedOverflowCount).toBeLessThanOrEqual(4); }); }); From e27e2b6a1ccdc29bc1332c49c81172d13d71930b Mon Sep 17 00:00:00 2001 From: Christiaan Landman Date: Wed, 23 Oct 2024 12:44:41 +0200 Subject: [PATCH 04/17] Fix iterating schemaChange listeners causing infinite loop. --- .../common/src/client/AbstractPowerSyncDatabase.ts | 12 ++++++------ packages/web/tests/watchSchemaChange.test.ts | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/common/src/client/AbstractPowerSyncDatabase.ts b/packages/common/src/client/AbstractPowerSyncDatabase.ts index 7907ba460..d530d44c8 100644 --- a/packages/common/src/client/AbstractPowerSyncDatabase.ts +++ b/packages/common/src/client/AbstractPowerSyncDatabase.ts @@ -103,7 +103,7 @@ export interface WatchOnChangeHandler { export interface PowerSyncDBListener extends StreamingSyncImplementationListener { initialized: () => void; - schemaChanged: (schema: Schema) => Promise; + schemaChanged: (schema: Schema) => void; } export interface PowerSyncCloseOptions { @@ -361,7 +361,7 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver cb.schemaChanged?.(schema)); + this.iterateListeners(async (cb) => cb.schemaChanged?.(schema)); } /** @@ -790,7 +790,7 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver { + const triggerWatchedQuery = () => { const abortController = new AbortController(); let disposeSchemaListener: (() => void) | null = null; const stopWatching = () => { @@ -805,12 +805,12 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver { stopWatching(); - // Re trigger the watched query (recursively) - await triggerWatchedQuery(); + // Re trigger the watched query (recursively), setTimeout ensures that we don't modify the list of listeners while iterating through them + setTimeout(() => triggerWatchedQuery(), 0); } }); - await watchQuery(abortController.signal); + return watchQuery(abortController.signal); }; triggerWatchedQuery(); diff --git a/packages/web/tests/watchSchemaChange.test.ts b/packages/web/tests/watchSchemaChange.test.ts index f032c4aea..a22c959d6 100644 --- a/packages/web/tests/watchSchemaChange.test.ts +++ b/packages/web/tests/watchSchemaChange.test.ts @@ -60,11 +60,11 @@ describe('Watch With Schema Change Tests', () => { expect(lastResult).toBe(3); + // changes the underlying table that the `assets` and `customers` views are based on await powersync.updateSchema(makeOptionalSyncSchema(true)); await powersync.writeTransaction(async (tx) => { // Copy local data to the "online" views. - await tx.execute( 'INSERT INTO assets(id, description, customer_id, user_id) SELECT id, description, customer_id, ? FROM inactive_local_assets', [userId] From 7e8f1a16907489c99975ee14db52be0244109c67 Mon Sep 17 00:00:00 2001 From: Christiaan Landman Date: Wed, 23 Oct 2024 19:42:30 +0200 Subject: [PATCH 05/17] Broke out triggerWatchQuery to separate function. --- .../src/client/AbstractPowerSyncDatabase.ts | 7 +- packages/web/tests/watchSchemaChange.test.ts | 82 ++++++++++++++++++- 2 files changed, 87 insertions(+), 2 deletions(-) diff --git a/packages/common/src/client/AbstractPowerSyncDatabase.ts b/packages/common/src/client/AbstractPowerSyncDatabase.ts index d530d44c8..8ce281ce1 100644 --- a/packages/common/src/client/AbstractPowerSyncDatabase.ts +++ b/packages/common/src/client/AbstractPowerSyncDatabase.ts @@ -790,6 +790,10 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver void, options?: SQLWatchOptions) { const triggerWatchedQuery = () => { const abortController = new AbortController(); let disposeSchemaListener: (() => void) | null = null; @@ -810,7 +814,8 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver { const abortController = new AbortController(); let lastResult = 0; + const query = 'SELECT count() AS count FROM assets'; + + const watch = powersync.watch(query, [], { + signal: abortController.signal, + throttleMs: throttleDuration + }); + + const assetsWatchTables = await getSourceTables(powersync, query); + expect(assetsWatchTables.includes('ps_data_local__local_assets')).toBeTruthy(); + + (async () => { + for await (const results of watch) { + lastResult = results.rows?._array[0].count; // `count` from sql output + } + })(); + + // Insert 3 records + for (let i = 0; i < 3; i++) { + await powersync.execute('INSERT INTO assets(id, make, customer_id) VALUES (uuid(), ?, ?)', ['test', userId]); + } + await new Promise((resolve) => setTimeout(resolve, throttleDuration * 2)); + + expect(lastResult).toBe(3); + + // changes the underlying table that the `assets` and `customers` views are based on + await powersync.updateSchema(makeOptionalSyncSchema(true)); + + const onlineAssetsWatchTables = await getSourceTables(powersync, query); + expect(onlineAssetsWatchTables.includes('ps_data__assets')).toBeTruthy(); + + await powersync.writeTransaction(async (tx) => { + // Copy local data to the "online" views. + await tx.execute( + 'INSERT INTO assets(id, description, customer_id, user_id) SELECT id, description, customer_id, ? FROM inactive_local_assets', + [userId] + ); + + // Delete the "local-only" data. + await tx.execute('DELETE FROM inactive_local_customers'); + await tx.execute('DELETE FROM inactive_local_assets'); + }); + + for (let i = 0; i < 3; i++) { + await powersync.execute('INSERT INTO assets(id, make, customer_id) VALUES (uuid(), ?, ?)', ['test', uuid()]); + } + await new Promise((resolve) => setTimeout(resolve, throttleDuration * 2)); + + expect(lastResult).toBe(6); + }); + + it('should trigger onResult after schema change (callback)', async () => { + const userId = uuid(); + const abortController = new AbortController(); + + let lastResult = 0; + const query = 'SELECT count() AS count FROM assets'; const onUpdate = (results: QueryResult) => { lastResult = results.rows?._array[0].count; // `count` from sql output }; powersync.watch( - 'SELECT count() AS count FROM assets', + query, [], { onResult: onUpdate }, { signal: abortController.signal, throttleMs: throttleDuration } ); + const assetsWatchTables = await getSourceTables(powersync, query); + expect(assetsWatchTables.includes('ps_data_local__local_assets')).toBeTruthy(); + // Insert 3 records for (let i = 0; i < 3; i++) { await powersync.execute('INSERT INTO assets(id, make, customer_id) VALUES (uuid(), ?, ?)', ['test', userId]); @@ -63,6 +122,9 @@ describe('Watch With Schema Change Tests', () => { // changes the underlying table that the `assets` and `customers` views are based on await powersync.updateSchema(makeOptionalSyncSchema(true)); + const onlineAssetsWatchTables = await getSourceTables(powersync, query); + expect(onlineAssetsWatchTables.includes('ps_data__assets')).toBeTruthy(); + await powersync.writeTransaction(async (tx) => { // Copy local data to the "online" views. await tx.execute( @@ -83,3 +145,21 @@ describe('Watch With Schema Change Tests', () => { expect(lastResult).toBe(6); }); }); + +export async function getSourceTables(db: AbstractPowerSyncDatabase, sql: string, parameters: Array = []) { + const rows = await db.getAll<{ opcode: string; p3: number; p2: string }>(`EXPLAIN ${sql}`, parameters); + const rootpages: number[] = []; + + for (const row of rows) { + if (row.opcode === 'OpenRead' && row.p3 === 0 && typeof row.p2 === 'number') { + rootpages.push(row.p2); + } + } + + const tableRows = await db.getAll<{ tbl_name: string }>( + `SELECT tbl_name FROM sqlite_master WHERE rootpage IN (SELECT json_each.value FROM json_each(?))`, + [JSON.stringify(rootpages)] + ); + + return tableRows.map((row: { tbl_name: string }) => row.tbl_name); +} From 65f7773b8bd32f5f3bdd1ae92ff0d4d778b03632 Mon Sep 17 00:00:00 2001 From: Christiaan Landman Date: Wed, 23 Oct 2024 20:11:37 +0200 Subject: [PATCH 06/17] Updated watchWithAsyncGenerator to use watchWithCallback instead of onChangeWithAsyncGenerator. Ensuring abortControllers are called in watchSchemaChange tests. --- .../src/client/AbstractPowerSyncDatabase.ts | 23 ++++++++++--------- packages/web/tests/watchSchemaChange.test.ts | 2 ++ 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/packages/common/src/client/AbstractPowerSyncDatabase.ts b/packages/common/src/client/AbstractPowerSyncDatabase.ts index 8ce281ce1..31906a75b 100644 --- a/packages/common/src/client/AbstractPowerSyncDatabase.ts +++ b/packages/common/src/client/AbstractPowerSyncDatabase.ts @@ -828,19 +828,20 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver { return new EventIterator((eventOptions) => { - (async () => { - const resolvedTables = await this.resolveTables(sql, parameters, options); + const handler: WatchHandler = { + onResult: (result) => { + eventOptions.push(result); + }, + onError: (error) => { + eventOptions.fail(error); + } + }; - // Fetch initial data - eventOptions.push(await this.executeReadOnly(sql, parameters)); + this.watchWithCallback(sql, parameters, handler, options); - for await (const event of this.onChangeWithAsyncGenerator({ - ...(options ?? {}), - tables: resolvedTables - })) { - eventOptions.push(await this.executeReadOnly(sql, parameters)); - } - })(); + options?.signal?.addEventListener('abort', () => { + eventOptions.stop(); + }); }); } diff --git a/packages/web/tests/watchSchemaChange.test.ts b/packages/web/tests/watchSchemaChange.test.ts index cc0bbcb15..74b91b543 100644 --- a/packages/web/tests/watchSchemaChange.test.ts +++ b/packages/web/tests/watchSchemaChange.test.ts @@ -86,6 +86,7 @@ describe('Watch With Schema Change Tests', () => { await powersync.execute('INSERT INTO assets(id, make, customer_id) VALUES (uuid(), ?, ?)', ['test', uuid()]); } await new Promise((resolve) => setTimeout(resolve, throttleDuration * 2)); + abortController.abort(); expect(lastResult).toBe(6); }); @@ -141,6 +142,7 @@ describe('Watch With Schema Change Tests', () => { await powersync.execute('INSERT INTO assets(id, make, customer_id) VALUES (uuid(), ?, ?)', ['test', uuid()]); } await new Promise((resolve) => setTimeout(resolve, throttleDuration * 2)); + abortController.abort(); expect(lastResult).toBe(6); }); From 3ddc42026ae45b466875998266dc124269e01899 Mon Sep 17 00:00:00 2001 From: Christiaan Landman Date: Thu, 24 Oct 2024 09:19:34 +0200 Subject: [PATCH 07/17] Separated runOnSchemaChange from AbstractPowerSyncData. --- .../src/client/AbstractPowerSyncDatabase.ts | 31 ++----------------- .../common/src/client/runOnSchemaChange.ts | 31 +++++++++++++++++++ 2 files changed, 33 insertions(+), 29 deletions(-) create mode 100644 packages/common/src/client/runOnSchemaChange.ts diff --git a/packages/common/src/client/AbstractPowerSyncDatabase.ts b/packages/common/src/client/AbstractPowerSyncDatabase.ts index 31906a75b..158c613a4 100644 --- a/packages/common/src/client/AbstractPowerSyncDatabase.ts +++ b/packages/common/src/client/AbstractPowerSyncDatabase.ts @@ -28,6 +28,7 @@ import { StreamingSyncImplementation, StreamingSyncImplementationListener } from './sync/stream/AbstractStreamingSyncImplementation.js'; +import { runOnSchemaChange } from './runOnSchemaChange.js'; export interface DisconnectAndClearOptions { /** When set to false, data in local-only tables is preserved. */ @@ -790,35 +791,7 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver void, options?: SQLWatchOptions) { - const triggerWatchedQuery = () => { - const abortController = new AbortController(); - let disposeSchemaListener: (() => void) | null = null; - const stopWatching = () => { - abortController.abort('Abort triggered'); - disposeSchemaListener?.(); - disposeSchemaListener = null; - // Stop listening to upstream abort for this watch - options?.signal?.removeEventListener('abort', stopWatching); - }; - - options?.signal?.addEventListener('abort', stopWatching); - disposeSchemaListener = this.registerListener({ - schemaChanged: async () => { - stopWatching(); - // Re trigger the watched query (recursively), setTimeout ensures that we don't modify the list of listeners while iterating through them - setTimeout(() => triggerWatchedQuery(), 0); - } - }); - - // return watchQuery(abortController.signal); - callback(abortController.signal); - }; - - triggerWatchedQuery(); + runOnSchemaChange(watchQuery, this, options); } /** diff --git a/packages/common/src/client/runOnSchemaChange.ts b/packages/common/src/client/runOnSchemaChange.ts new file mode 100644 index 000000000..7151849a6 --- /dev/null +++ b/packages/common/src/client/runOnSchemaChange.ts @@ -0,0 +1,31 @@ +import { AbstractPowerSyncDatabase, SQLWatchOptions } from './AbstractPowerSyncDatabase.js'; + +export function runOnSchemaChange( + callback: (signal: AbortSignal) => void, + db: AbstractPowerSyncDatabase, + options?: SQLWatchOptions +): void { + const triggerWatchedQuery = () => { + const abortController = new AbortController(); + let disposeSchemaListener: (() => void) | null = null; + const stopWatching = () => { + abortController.abort('Abort triggered'); + disposeSchemaListener?.(); + disposeSchemaListener = null; + // Stop listening to upstream abort for this watch + options?.signal?.removeEventListener('abort', stopWatching); + }; + + options?.signal?.addEventListener('abort', stopWatching); + disposeSchemaListener = db.registerListener({ + schemaChanged: async () => { + stopWatching(); + // Re trigger the watched query (recursively), setTimeout ensures that we don't modify the list of listeners while iterating through them + setTimeout(() => triggerWatchedQuery(), 0); + } + }); + callback(abortController.signal); + }; + + triggerWatchedQuery(); +} From 3deaa97d59ad594e675502e695d142cfe406a7fa Mon Sep 17 00:00:00 2001 From: Christiaan Landman Date: Mon, 28 Oct 2024 11:23:47 +0200 Subject: [PATCH 08/17] useQuery will recalculate dependant tables if schema changes. Fixed auth flow issue in optional sync demo. --- .../src/app/views/layout.tsx | 2 +- .../src/library/powersync/SupabaseConnector.ts | 5 +++++ packages/react/src/hooks/useQuery.ts | 12 ++++++++++-- packages/web/tests/watchSchemaChange.test.ts | 1 - 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/demos/react-supabase-todolist-optional-sync/src/app/views/layout.tsx b/demos/react-supabase-todolist-optional-sync/src/app/views/layout.tsx index c2d152e72..fd3c787d4 100644 --- a/demos/react-supabase-todolist-optional-sync/src/app/views/layout.tsx +++ b/demos/react-supabase-todolist-optional-sync/src/app/views/layout.tsx @@ -58,7 +58,7 @@ export default function ViewsLayout({ children }: { children: React.ReactNode }) beforeNavigate: async () => { // If user is logged in, sign out and stay on the current page if (supabase?.currentSession) { - await supabase?.client.auth.signOut(); + await supabase?.logout(); await powerSync.disconnectAndClear(); setSyncEnabled(powerSync.database.name, false); diff --git a/demos/react-supabase-todolist-optional-sync/src/library/powersync/SupabaseConnector.ts b/demos/react-supabase-todolist-optional-sync/src/library/powersync/SupabaseConnector.ts index cefed43be..c999c3b17 100644 --- a/demos/react-supabase-todolist-optional-sync/src/library/powersync/SupabaseConnector.ts +++ b/demos/react-supabase-todolist-optional-sync/src/library/powersync/SupabaseConnector.ts @@ -93,6 +93,11 @@ export class SupabaseConnector extends BaseObserver i this.updateSession(session); } + async logout() { + await this.client.auth.signOut(); + this.updateSession(null); + } + async fetchCredentials() { const { data: { session }, diff --git a/packages/react/src/hooks/useQuery.ts b/packages/react/src/hooks/useQuery.ts index 7e47ff91d..6fecba38c 100644 --- a/packages/react/src/hooks/useQuery.ts +++ b/packages/react/src/hooks/useQuery.ts @@ -118,10 +118,18 @@ export const useQuery = ( }; React.useEffect(() => { - (async () => { + const updateData = async () => { await fetchTables(); await fetchData(); - })(); + }; + + updateData(); + + const l = powerSync.registerListener({ + schemaChanged: updateData + }); + + return () => l?.(); }, [powerSync, memoizedParams, sqlStatement]); React.useEffect(() => { diff --git a/packages/web/tests/watchSchemaChange.test.ts b/packages/web/tests/watchSchemaChange.test.ts index 74b91b543..a9c0e5f62 100644 --- a/packages/web/tests/watchSchemaChange.test.ts +++ b/packages/web/tests/watchSchemaChange.test.ts @@ -2,7 +2,6 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; import { v4 as uuid } from 'uuid'; import { AbstractPowerSyncDatabase, QueryResult } from '@powersync/common'; import { PowerSyncDatabase } from '@powersync/web'; -import { testSchema } from './utils/testDb'; import { makeOptionalSyncSchema } from './utils/optionalSyncTestSchema'; vi.useRealTimers(); From 9c2576b94d6bf18415501ef3a1c0bee800f386cf Mon Sep 17 00:00:00 2001 From: Christiaan Landman Date: Mon, 28 Oct 2024 21:03:39 +0200 Subject: [PATCH 09/17] useSuspenseQuery will recalculate tables on a schema change. Fix unit tests. --- packages/common/src/index.ts | 1 + packages/react/src/WatchedQuery.ts | 16 ++++++++++++---- packages/react/tests/useQuery.test.tsx | 12 +++--------- packages/react/tests/useStatus.test.tsx | 4 +--- packages/react/tests/useSuspenseQuery.test.tsx | 4 +--- 5 files changed, 18 insertions(+), 19 deletions(-) diff --git a/packages/common/src/index.ts b/packages/common/src/index.ts index 44e5c947c..b55cca847 100644 --- a/packages/common/src/index.ts +++ b/packages/common/src/index.ts @@ -4,6 +4,7 @@ export * from './client/SQLOpenFactory.js'; export * from './client/connection/PowerSyncBackendConnector.js'; export * from './client/connection/PowerSyncCredentials.js'; export * from './client/sync/bucket/BucketStorageAdapter.js'; +export { runOnSchemaChange } from './client/runOnSchemaChange.js'; export { UpdateType, CrudEntry, OpId } from './client/sync/bucket/CrudEntry.js'; export * from './client/sync/bucket/SqliteBucketStorage.js'; export * from './client/sync/bucket/CrudBatch.js'; diff --git a/packages/react/src/WatchedQuery.ts b/packages/react/src/WatchedQuery.ts index 05639ffd1..be52a0085 100644 --- a/packages/react/src/WatchedQuery.ts +++ b/packages/react/src/WatchedQuery.ts @@ -1,4 +1,11 @@ -import { AbstractPowerSyncDatabase, BaseListener, BaseObserver, CompilableQuery, Disposable } from '@powersync/common'; +import { + AbstractPowerSyncDatabase, + BaseListener, + BaseObserver, + CompilableQuery, + Disposable, + runOnSchemaChange +} from '@powersync/common'; import { AdditionalOptions } from './hooks/useQuery'; export class Query { @@ -117,7 +124,7 @@ export class WatchedQuery extends BaseObserver implements this.setError(error); }; - (async () => { + const watchQuery = async (abortSignal: AbortSignal) => { await this.fetchTables(); await this.fetchData(); @@ -131,12 +138,13 @@ export class WatchedQuery extends BaseObserver implements }, { ...this.options, - signal: this.controller.signal, + signal: abortSignal, tables: this.tables } ); } - })(); + }; + runOnSchemaChange(watchQuery, this.db, { signal: this.controller.signal }); } private setData(results: any[]) { diff --git a/packages/react/tests/useQuery.test.tsx b/packages/react/tests/useQuery.test.tsx index 2b9e61589..0941e8fb1 100644 --- a/packages/react/tests/useQuery.test.tsx +++ b/packages/react/tests/useQuery.test.tsx @@ -7,9 +7,7 @@ import { useQuery } from '../src/hooks/useQuery'; const mockPowerSync = { currentStatus: { status: 'initial' }, - registerListener: vi.fn(() => ({ - statusChanged: vi.fn(() => 'updated') - })), + registerListener: vi.fn(() => {}), resolveTables: vi.fn(() => ['table1', 'table2']), onChangeWithCallback: vi.fn(), getAll: vi.fn(() => Promise.resolve(['list1', 'list2'])) @@ -92,9 +90,7 @@ describe('useQuery', () => { it('should set error when error occurs and runQueryOnce flag is set', async () => { const mockPowerSyncError = { currentStatus: { status: 'initial' }, - registerListener: vi.fn(() => ({ - statusChanged: vi.fn(() => 'updated') - })), + registerListener: vi.fn(() => {}), onChangeWithCallback: vi.fn(), resolveTables: vi.fn(() => ['table1', 'table2']), getAll: vi.fn(() => { @@ -119,9 +115,7 @@ describe('useQuery', () => { it('should set error when error occurs', async () => { const mockPowerSyncError = { currentStatus: { status: 'initial' }, - registerListener: vi.fn(() => ({ - statusChanged: vi.fn(() => 'updated') - })), + registerListener: vi.fn(() => {}), onChangeWithCallback: vi.fn(), resolveTables: vi.fn(() => ['table1', 'table2']), getAll: vi.fn(() => { diff --git a/packages/react/tests/useStatus.test.tsx b/packages/react/tests/useStatus.test.tsx index 2fd221f29..f525e793e 100644 --- a/packages/react/tests/useStatus.test.tsx +++ b/packages/react/tests/useStatus.test.tsx @@ -33,9 +33,7 @@ describe('useStatus', () => { it.skip('should update the status when the listener is called', () => { const mockPowerSyncInTest = { currentStatus: { status: 'initial' }, - registerListener: () => ({ - statusChanged: () => 'updated' - }) + registerListener: vi.fn(() => {}) }; const wrapper = ({ children }) => ( diff --git a/packages/react/tests/useSuspenseQuery.test.tsx b/packages/react/tests/useSuspenseQuery.test.tsx index 6deca29f7..f83c164d2 100644 --- a/packages/react/tests/useSuspenseQuery.test.tsx +++ b/packages/react/tests/useSuspenseQuery.test.tsx @@ -11,9 +11,7 @@ const defaultQueryResult = ['list1', 'list2']; const createMockPowerSync = () => { return { currentStatus: { status: 'initial' }, - registerListener: vi.fn(() => ({ - statusChanged: vi.fn(() => 'updated') - })), + registerListener: vi.fn(() => {}), resolveTables: vi.fn(() => ['table1', 'table2']), onChangeWithCallback: vi.fn(), getAll: vi.fn(() => Promise.resolve(defaultQueryResult)) as Mock From 9cc05f8d817bd59bc8d3d38aa0b9d3ca5fcacf4c Mon Sep 17 00:00:00 2001 From: Christiaan Landman Date: Mon, 28 Oct 2024 21:37:12 +0200 Subject: [PATCH 10/17] Tanstack queries will nou recalculate dependent tables when schema changes. --- packages/tanstack-react-query/src/hooks/useQuery.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/packages/tanstack-react-query/src/hooks/useQuery.ts b/packages/tanstack-react-query/src/hooks/useQuery.ts index e47d7388c..8c24bc569 100644 --- a/packages/tanstack-react-query/src/hooks/useQuery.ts +++ b/packages/tanstack-react-query/src/hooks/useQuery.ts @@ -102,11 +102,20 @@ function useQueryCore< }; React.useEffect(() => { - if (!query) return; + if (!query) return () => {}; (async () => { await fetchTables(); })(); + + const l = powerSync.registerListener({ + schemaChanged: async () => { + await fetchTables(); + queryClient.invalidateQueries({ queryKey: options.queryKey }); + } + }); + + return () => l?.(); }, [powerSync, sqlStatement, stringifiedParams]); const queryFn = React.useCallback(async () => { From ab34416ac6509c4abde63ac5994d58093ebe317b Mon Sep 17 00:00:00 2001 From: Christiaan Landman Date: Mon, 28 Oct 2024 21:42:00 +0200 Subject: [PATCH 11/17] Changeset entries. --- .changeset/itchy-years-drop.md | 2 +- .changeset/tender-llamas-shop.md | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 .changeset/tender-llamas-shop.md diff --git a/.changeset/itchy-years-drop.md b/.changeset/itchy-years-drop.md index 39c9bfc38..c43e86d6f 100644 --- a/.changeset/itchy-years-drop.md +++ b/.changeset/itchy-years-drop.md @@ -2,4 +2,4 @@ '@powersync/common': minor --- -Update watched queries when schema has been updated. +Updated watch functions to recalculate depedendent tables if schema is updated. diff --git a/.changeset/tender-llamas-shop.md b/.changeset/tender-llamas-shop.md new file mode 100644 index 000000000..4a3cb39ac --- /dev/null +++ b/.changeset/tender-llamas-shop.md @@ -0,0 +1,6 @@ +--- +'@powersync/tanstack-react-query': patch +'@powersync/react': patch +--- + +Queries will recalculate dependent tables if schema is updated. From 7816d880baea251ed6b6837a7f64e4256d511c8f Mon Sep 17 00:00:00 2001 From: Christiaan Landman Date: Mon, 28 Oct 2024 21:53:08 +0200 Subject: [PATCH 12/17] Vue queries will recalculate dependent tables on schema change. --- .changeset/ten-birds-camp.md | 5 ++ packages/vue/src/composables/useQuery.ts | 71 +++++++++++++----------- packages/vue/tests/useQuery.test.ts | 10 +--- 3 files changed, 48 insertions(+), 38 deletions(-) create mode 100644 .changeset/ten-birds-camp.md diff --git a/.changeset/ten-birds-camp.md b/.changeset/ten-birds-camp.md new file mode 100644 index 000000000..60753b254 --- /dev/null +++ b/.changeset/ten-birds-camp.md @@ -0,0 +1,5 @@ +--- +'@powersync/vue': patch +--- + +Queries will recalculate dependent tables if schema is updated. diff --git a/packages/vue/src/composables/useQuery.ts b/packages/vue/src/composables/useQuery.ts index dc4509309..57295e65a 100644 --- a/packages/vue/src/composables/useQuery.ts +++ b/packages/vue/src/composables/useQuery.ts @@ -1,4 +1,10 @@ -import { type CompilableQuery, ParsedQuery, type SQLWatchOptions, parseQuery } from '@powersync/common'; +import { + type CompilableQuery, + ParsedQuery, + type SQLWatchOptions, + parseQuery, + runOnSchemaChange +} from '@powersync/common'; import { type MaybeRef, type Ref, ref, toValue, watchEffect } from 'vue'; import { usePowerSync } from './powerSync'; @@ -114,38 +120,41 @@ export const useQuery = ( } const { sqlStatement: sql, parameters } = parsedQuery; + const watchQuery = async (abortSignal: AbortSignal) => { + let resolvedTables = []; + try { + resolvedTables = await powerSync.value.resolveTables(sql, parameters, options); + } catch (e) { + console.error('Failed to fetch tables:', e); + handleError(e); + return; + } + // Fetch initial data + const executor = + typeof queryValue == 'string' ? () => powerSync.value.getAll(sql, parameters) : () => queryValue.execute(); + fetchData = () => _fetchData(executor); + await fetchData(); + + if (options.runQueryOnce) { + return; + } - let resolvedTables = []; - try { - resolvedTables = await powerSync.value.resolveTables(sql, parameters, options); - } catch (e) { - console.error('Failed to fetch tables:', e); - handleError(e); - return; - } - // Fetch initial data - const executor = - typeof queryValue == 'string' ? () => powerSync.value.getAll(sql, parameters) : () => queryValue.execute(); - fetchData = () => _fetchData(executor); - await fetchData(); - - if (options.runQueryOnce) { - return; - } - - powerSync.value.onChangeWithCallback( - { - onChange: async () => { - await fetchData(); + powerSync.value.onChangeWithCallback( + { + onChange: async () => { + await fetchData(); + }, + onError: handleError }, - onError: handleError - }, - { - ...options, - signal: abortController.signal, - tables: resolvedTables - } - ); + { + ...options, + signal: abortSignal, + tables: resolvedTables + } + ); + }; + + runOnSchemaChange(watchQuery, powerSync.value, { signal: abortController.signal }); }); return { diff --git a/packages/vue/tests/useQuery.test.ts b/packages/vue/tests/useQuery.test.ts index ceac35e2f..76549edc8 100644 --- a/packages/vue/tests/useQuery.test.ts +++ b/packages/vue/tests/useQuery.test.ts @@ -7,9 +7,7 @@ import { withSetup } from './utils'; const mockPowerSync = { currentStatus: { status: 'initial' }, - registerListener: vi.fn(() => ({ - statusChanged: vi.fn(() => 'updated') - })), + registerListener: vi.fn(() => {}), resolveTables: vi.fn(), watch: vi.fn(), onChangeWithCallback: vi.fn(), @@ -33,13 +31,11 @@ describe('useQuery', () => { }); it('should handle error in watchEffect', async () => { - vi.spyOn(PowerSync, 'usePowerSync').mockReturnValue(ref({}) as any); + vi.spyOn(PowerSync, 'usePowerSync').mockReturnValue(undefined); const [{ data, isLoading, isFetching, error }] = withSetup(() => useQuery('SELECT * from lists')); - expect(error.value).toEqual( - Error('PowerSync failed to fetch data: powerSync.value.resolveTables is not a function') - ); + expect(error.value).toEqual(Error('PowerSync not configured.')); expect(isFetching.value).toEqual(false); expect(isLoading.value).toEqual(false); expect(data.value).toEqual([]); From 515b6fcf373d7e8edacdeea0409c4459ef4a4a08 Mon Sep 17 00:00:00 2001 From: Christiaan Landman Date: Thu, 31 Oct 2024 14:49:57 +0200 Subject: [PATCH 13/17] Added refreshSchema to DBAdapter. --- packages/common/src/client/AbstractPowerSyncDatabase.ts | 1 + packages/common/src/db/DBAdapter.ts | 1 + packages/powersync-op-sqlite/src/db/OPSQLiteConnection.ts | 4 ++++ packages/powersync-op-sqlite/src/db/OPSqliteAdapter.ts | 8 ++++++++ .../adapters/react-native-quick-sqlite/RNQSDBAdapter.ts | 4 ++++ packages/web/src/db/adapters/SSRDBAdapter.ts | 2 ++ .../web/src/db/adapters/wa-sqlite/WASQLiteDBAdapter.ts | 2 ++ 7 files changed, 22 insertions(+) diff --git a/packages/common/src/client/AbstractPowerSyncDatabase.ts b/packages/common/src/client/AbstractPowerSyncDatabase.ts index 158c613a4..3672333dd 100644 --- a/packages/common/src/client/AbstractPowerSyncDatabase.ts +++ b/packages/common/src/client/AbstractPowerSyncDatabase.ts @@ -362,6 +362,7 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver cb.schemaChanged?.(schema)); } diff --git a/packages/common/src/db/DBAdapter.ts b/packages/common/src/db/DBAdapter.ts index 052ccf20d..b35652a0f 100644 --- a/packages/common/src/db/DBAdapter.ts +++ b/packages/common/src/db/DBAdapter.ts @@ -101,6 +101,7 @@ export interface DBAdapter extends BaseObserverInterface, DBG readTransaction: (fn: (tx: Transaction) => Promise, options?: DBLockOptions) => Promise; writeLock: (fn: (tx: LockContext) => Promise, options?: DBLockOptions) => Promise; writeTransaction: (fn: (tx: Transaction) => Promise, options?: DBLockOptions) => Promise; + refreshSchema: () => Promise; } export function isBatchedUpdateNotification( diff --git a/packages/powersync-op-sqlite/src/db/OPSQLiteConnection.ts b/packages/powersync-op-sqlite/src/db/OPSQLiteConnection.ts index 5c3a1cbc6..3e342b56a 100644 --- a/packages/powersync-op-sqlite/src/db/OPSQLiteConnection.ts +++ b/packages/powersync-op-sqlite/src/db/OPSQLiteConnection.ts @@ -79,4 +79,8 @@ export class OPSQLiteConnection extends BaseObserver { } return result as T; } + + async refreshSchema() { + await this.get("PRAGMA table_info('sqlite_master')"); + } } diff --git a/packages/powersync-op-sqlite/src/db/OPSqliteAdapter.ts b/packages/powersync-op-sqlite/src/db/OPSqliteAdapter.ts index 312bcdca1..16e525524 100644 --- a/packages/powersync-op-sqlite/src/db/OPSqliteAdapter.ts +++ b/packages/powersync-op-sqlite/src/db/OPSqliteAdapter.ts @@ -259,4 +259,12 @@ export class OPSQLiteDBAdapter extends BaseObserver implement throw ex; } } + + async refreshSchema(): Promise { + await this.writeConnection?.refreshSchema(); + + for (let connection of this.readConnections) { + await connection.refreshSchema(); + } + } } diff --git a/packages/react-native/src/db/adapters/react-native-quick-sqlite/RNQSDBAdapter.ts b/packages/react-native/src/db/adapters/react-native-quick-sqlite/RNQSDBAdapter.ts index d70108b94..2b82d74f2 100644 --- a/packages/react-native/src/db/adapters/react-native-quick-sqlite/RNQSDBAdapter.ts +++ b/packages/react-native/src/db/adapters/react-native-quick-sqlite/RNQSDBAdapter.ts @@ -124,4 +124,8 @@ export class RNQSDBAdapter extends BaseObserver implements DB } }; } + + async refreshSchema() { + await this.baseDB.refreshSchema(); + } } diff --git a/packages/web/src/db/adapters/SSRDBAdapter.ts b/packages/web/src/db/adapters/SSRDBAdapter.ts index a958ddede..b808d7477 100644 --- a/packages/web/src/db/adapters/SSRDBAdapter.ts +++ b/packages/web/src/db/adapters/SSRDBAdapter.ts @@ -85,4 +85,6 @@ export class SSRDBAdapter extends BaseObserver implements DBA } }; } + + async refreshSchema(): Promise {} } diff --git a/packages/web/src/db/adapters/wa-sqlite/WASQLiteDBAdapter.ts b/packages/web/src/db/adapters/wa-sqlite/WASQLiteDBAdapter.ts index c7d963f51..d8b12970a 100644 --- a/packages/web/src/db/adapters/wa-sqlite/WASQLiteDBAdapter.ts +++ b/packages/web/src/db/adapters/wa-sqlite/WASQLiteDBAdapter.ts @@ -275,4 +275,6 @@ export class WASQLiteDBAdapter extends BaseObserver implement } }; } + + async refreshSchema(): Promise {} } From 5d8fb962bbcbb87a649279b55454f56a09c9e655 Mon Sep 17 00:00:00 2001 From: Christiaan Landman Date: Thu, 31 Oct 2024 15:12:18 +0200 Subject: [PATCH 14/17] Added changeset entries for react-native, web, and op-sqlite. --- .changeset/short-owls-play.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .changeset/short-owls-play.md diff --git a/.changeset/short-owls-play.md b/.changeset/short-owls-play.md new file mode 100644 index 000000000..ba5949dd7 --- /dev/null +++ b/.changeset/short-owls-play.md @@ -0,0 +1,7 @@ +--- +'@powersync/op-sqlite': minor +'@powersync/react-native': minor +'@powersync/web': minor +--- + +Added `refreshSchema()` which will cause all connections to be aware of a schema change. From 28d0fd2549932e0a7a4109a5c82805925661bd3f Mon Sep 17 00:00:00 2001 From: Christiaan Landman Date: Tue, 5 Nov 2024 09:14:46 +0200 Subject: [PATCH 15/17] Bumped react-native rnqslite version. --- packages/react-native/package.json | 4 +- pnpm-lock.yaml | 460 +++++++++++++---------------- 2 files changed, 210 insertions(+), 254 deletions(-) diff --git a/packages/react-native/package.json b/packages/react-native/package.json index d0211fbcd..f7827c248 100644 --- a/packages/react-native/package.json +++ b/packages/react-native/package.json @@ -30,7 +30,7 @@ }, "homepage": "https://docs.powersync.com/", "peerDependencies": { - "@journeyapps/react-native-quick-sqlite": "^2.0.0", + "@journeyapps/react-native-quick-sqlite": "^2.1.0", "@powersync/common": "workspace:^1.20.1", "react": "*", "react-native": "*" @@ -46,7 +46,7 @@ }, "devDependencies": { "@craftzdog/react-native-buffer": "^6.0.5", - "@journeyapps/react-native-quick-sqlite": "^2.0.0", + "@journeyapps/react-native-quick-sqlite": "^2.1.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 6f1d18094..28cd412fe 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -77,10 +77,10 @@ importers: devDependencies: '@angular-builders/custom-webpack': specifier: ^18.0.0 - version: 18.0.0(@angular/compiler-cli@18.2.7(@angular/compiler@18.2.7(@angular/core@18.2.7(rxjs@7.8.1)(zone.js@0.14.10)))(typescript@5.5.4))(@angular/service-worker@18.2.7(@angular/common@18.2.7(@angular/core@18.2.7(rxjs@7.8.1)(zone.js@0.14.10))(rxjs@7.8.1))(@angular/core@18.2.7(rxjs@7.8.1)(zone.js@0.14.10)))(@swc/core@1.7.26)(@types/node@22.7.4)(chokidar@3.6.0)(html-webpack-plugin@5.6.0(webpack@5.94.0(@swc/core@1.7.26)))(tailwindcss@3.4.13)(typescript@5.5.4) + version: 18.0.0(@angular/compiler-cli@18.2.7(@angular/compiler@18.2.7(@angular/core@18.2.7(rxjs@7.8.1)(zone.js@0.14.10)))(typescript@5.5.4))(@angular/service-worker@18.2.7(@angular/common@18.2.7(@angular/core@18.2.7(rxjs@7.8.1)(zone.js@0.14.10))(rxjs@7.8.1))(@angular/core@18.2.7(rxjs@7.8.1)(zone.js@0.14.10)))(@swc/core@1.7.26(@swc/helpers@0.5.5))(@types/node@22.7.4)(chokidar@3.6.0)(html-webpack-plugin@5.6.0(webpack@5.94.0(@swc/core@1.7.26(@swc/helpers@0.5.5))))(tailwindcss@3.4.13(ts-node@10.9.2(@swc/core@1.7.26(@swc/helpers@0.5.5))(@types/node@22.7.4)(typescript@5.5.4)))(typescript@5.5.4) '@angular-devkit/build-angular': specifier: ^18.1.1 - version: 18.2.7(@angular/compiler-cli@18.2.7(@angular/compiler@18.2.7(@angular/core@18.2.7(rxjs@7.8.1)(zone.js@0.14.10)))(typescript@5.5.4))(@angular/service-worker@18.2.7(@angular/common@18.2.7(@angular/core@18.2.7(rxjs@7.8.1)(zone.js@0.14.10))(rxjs@7.8.1))(@angular/core@18.2.7(rxjs@7.8.1)(zone.js@0.14.10)))(@swc/core@1.7.26)(@types/node@22.7.4)(chokidar@3.6.0)(html-webpack-plugin@5.6.0(webpack@5.94.0(@swc/core@1.7.26)))(tailwindcss@3.4.13)(typescript@5.5.4) + version: 18.2.7(@angular/compiler-cli@18.2.7(@angular/compiler@18.2.7(@angular/core@18.2.7(rxjs@7.8.1)(zone.js@0.14.10)))(typescript@5.5.4))(@angular/service-worker@18.2.7(@angular/common@18.2.7(@angular/core@18.2.7(rxjs@7.8.1)(zone.js@0.14.10))(rxjs@7.8.1))(@angular/core@18.2.7(rxjs@7.8.1)(zone.js@0.14.10)))(@swc/core@1.7.26(@swc/helpers@0.5.5))(@types/node@22.7.4)(chokidar@3.6.0)(html-webpack-plugin@5.6.0(webpack@5.94.0(@swc/core@1.7.26(@swc/helpers@0.5.5))))(tailwindcss@3.4.13(ts-node@10.9.2(@swc/core@1.7.26(@swc/helpers@0.5.5))(@types/node@22.7.4)(typescript@5.5.4)))(typescript@5.5.4) '@angular/cli': specifier: ^18.1.1 version: 18.2.7(chokidar@3.6.0) @@ -474,10 +474,10 @@ importers: version: 10.4.20(postcss@8.4.47) babel-loader: specifier: ^9.1.3 - version: 9.2.1(@babel/core@7.25.7)(webpack@5.95.0) + version: 9.2.1(@babel/core@7.25.7)(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5))) css-loader: specifier: ^6.11.0 - version: 6.11.0(webpack@5.95.0) + version: 6.11.0(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5))) eslint: specifier: ^8.57.0 version: 8.57.1 @@ -492,13 +492,13 @@ importers: version: 1.79.4 sass-loader: specifier: ^13.3.3 - version: 13.3.3(sass@1.79.4)(webpack@5.95.0) + version: 13.3.3(sass@1.79.4)(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5))) style-loader: specifier: ^3.3.4 - version: 3.3.4(webpack@5.95.0) + version: 3.3.4(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5))) tailwindcss: specifier: ^3.4.3 - version: 3.4.13(ts-node@10.9.2(@types/node@20.16.10)(typescript@5.5.4)) + version: 3.4.13(ts-node@10.9.2(@swc/core@1.7.26(@swc/helpers@0.5.5))(@types/node@20.16.10)(typescript@5.5.4)) demos/example-vite: dependencies: @@ -527,10 +527,10 @@ importers: devDependencies: '@types/webpack': specifier: ^5.28.5 - version: 5.28.5(webpack-cli@5.1.4(webpack@5.95.0)) + version: 5.28.5(webpack-cli@5.1.4) html-webpack-plugin: specifier: ^5.6.0 - version: 5.6.0(webpack@5.95.0(webpack-cli@5.1.4)) + version: 5.6.0(webpack@5.95.0) serve: specifier: ^14.2.1 version: 14.2.3 @@ -745,7 +745,7 @@ importers: version: 18.3.11 eas-cli: specifier: ^7.2.0 - version: 7.8.5(@swc/core@1.7.26)(@types/node@22.7.4)(encoding@0.1.13)(expo-modules-autolinking@1.11.1)(typescript@5.3.3) + version: 7.8.5(@swc/core@1.7.26(@swc/helpers@0.5.5))(@types/node@22.7.4)(encoding@0.1.13)(expo-modules-autolinking@1.11.1)(typescript@5.3.3) eslint: specifier: 8.55.0 version: 8.55.0 @@ -1731,8 +1731,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.7(@babel/core@7.24.5))(encoding@0.1.13)(react@18.2.0))(react@18.2.0) '@journeyapps/react-native-quick-sqlite': - specifier: ^2.0.0 - version: 2.0.0(react-native@0.72.4(@babel/core@7.24.5)(@babel/preset-env@7.25.7(@babel/core@7.24.5))(encoding@0.1.13)(react@18.2.0))(react@18.2.0) + specifier: ^2.1.0 + version: 2.1.0(react-native@0.72.4(@babel/core@7.24.5)(@babel/preset-env@7.25.7(@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.1(rollup@4.14.3) @@ -1867,13 +1867,13 @@ importers: version: 4.0.1 source-map-loader: specifier: ^5.0.0 - version: 5.0.0(webpack@5.95.0(webpack-cli@5.1.4)) + version: 5.0.0(webpack@5.95.0) stream-browserify: specifier: ^3.0.0 version: 3.0.0 terser-webpack-plugin: specifier: ^5.3.9 - version: 5.3.10(webpack@5.95.0(webpack-cli@5.1.4)) + version: 5.3.10(webpack@5.95.0) typescript: specifier: ^5.5.3 version: 5.5.4 @@ -4492,6 +4492,12 @@ packages: react: '*' react-native: '*' + '@journeyapps/react-native-quick-sqlite@2.1.0': + resolution: {integrity: sha512-cZHjL6fw91KtcnAfgSutqrKd1dRaAVZKrel3btdC9xBAWpcEyu2t+6f18zZVqiAwkCe+XP1bKTtemm6p5gRP/g==} + peerDependencies: + react: '*' + react-native: '*' + '@journeyapps/wa-sqlite@0.4.1': resolution: {integrity: sha512-a964h8f+6PSVfg3kxhLF2FwAqPdlY4gaWYIV6nnwJbdUhfjUcHDdL5njkw7egwmjEIG9rbIuxRsEqANcQ/bTwQ==} @@ -18252,10 +18258,10 @@ snapshots: '@jridgewell/gen-mapping': 0.3.5 '@jridgewell/trace-mapping': 0.3.25 - '@angular-builders/common@2.0.0(@swc/core@1.7.26)(@types/node@22.7.4)(chokidar@3.6.0)(typescript@5.5.4)': + '@angular-builders/common@2.0.0(@swc/core@1.7.26(@swc/helpers@0.5.5))(@types/node@22.7.4)(chokidar@3.6.0)(typescript@5.5.4)': dependencies: '@angular-devkit/core': 18.2.7(chokidar@3.6.0) - ts-node: 10.9.2(@swc/core@1.7.26)(@types/node@22.7.4)(typescript@5.5.4) + ts-node: 10.9.2(@swc/core@1.7.26(@swc/helpers@0.5.5))(@types/node@22.7.4)(typescript@5.5.4) tsconfig-paths: 4.2.0 transitivePeerDependencies: - '@swc/core' @@ -18264,11 +18270,11 @@ snapshots: - chokidar - typescript - '@angular-builders/custom-webpack@18.0.0(@angular/compiler-cli@18.2.7(@angular/compiler@18.2.7(@angular/core@18.2.7(rxjs@7.8.1)(zone.js@0.14.10)))(typescript@5.5.4))(@angular/service-worker@18.2.7(@angular/common@18.2.7(@angular/core@18.2.7(rxjs@7.8.1)(zone.js@0.14.10))(rxjs@7.8.1))(@angular/core@18.2.7(rxjs@7.8.1)(zone.js@0.14.10)))(@swc/core@1.7.26)(@types/node@22.7.4)(chokidar@3.6.0)(html-webpack-plugin@5.6.0(webpack@5.94.0(@swc/core@1.7.26)))(tailwindcss@3.4.13)(typescript@5.5.4)': + '@angular-builders/custom-webpack@18.0.0(@angular/compiler-cli@18.2.7(@angular/compiler@18.2.7(@angular/core@18.2.7(rxjs@7.8.1)(zone.js@0.14.10)))(typescript@5.5.4))(@angular/service-worker@18.2.7(@angular/common@18.2.7(@angular/core@18.2.7(rxjs@7.8.1)(zone.js@0.14.10))(rxjs@7.8.1))(@angular/core@18.2.7(rxjs@7.8.1)(zone.js@0.14.10)))(@swc/core@1.7.26(@swc/helpers@0.5.5))(@types/node@22.7.4)(chokidar@3.6.0)(html-webpack-plugin@5.6.0(webpack@5.94.0(@swc/core@1.7.26(@swc/helpers@0.5.5))))(tailwindcss@3.4.13(ts-node@10.9.2(@swc/core@1.7.26(@swc/helpers@0.5.5))(@types/node@22.7.4)(typescript@5.5.4)))(typescript@5.5.4)': dependencies: - '@angular-builders/common': 2.0.0(@swc/core@1.7.26)(@types/node@22.7.4)(chokidar@3.6.0)(typescript@5.5.4) + '@angular-builders/common': 2.0.0(@swc/core@1.7.26(@swc/helpers@0.5.5))(@types/node@22.7.4)(chokidar@3.6.0)(typescript@5.5.4) '@angular-devkit/architect': 0.1802.7(chokidar@3.6.0) - '@angular-devkit/build-angular': 18.2.7(@angular/compiler-cli@18.2.7(@angular/compiler@18.2.7(@angular/core@18.2.7(rxjs@7.8.1)(zone.js@0.14.10)))(typescript@5.5.4))(@angular/service-worker@18.2.7(@angular/common@18.2.7(@angular/core@18.2.7(rxjs@7.8.1)(zone.js@0.14.10))(rxjs@7.8.1))(@angular/core@18.2.7(rxjs@7.8.1)(zone.js@0.14.10)))(@swc/core@1.7.26)(@types/node@22.7.4)(chokidar@3.6.0)(html-webpack-plugin@5.6.0(webpack@5.94.0(@swc/core@1.7.26)))(tailwindcss@3.4.13)(typescript@5.5.4) + '@angular-devkit/build-angular': 18.2.7(@angular/compiler-cli@18.2.7(@angular/compiler@18.2.7(@angular/core@18.2.7(rxjs@7.8.1)(zone.js@0.14.10)))(typescript@5.5.4))(@angular/service-worker@18.2.7(@angular/common@18.2.7(@angular/core@18.2.7(rxjs@7.8.1)(zone.js@0.14.10))(rxjs@7.8.1))(@angular/core@18.2.7(rxjs@7.8.1)(zone.js@0.14.10)))(@swc/core@1.7.26(@swc/helpers@0.5.5))(@types/node@22.7.4)(chokidar@3.6.0)(html-webpack-plugin@5.6.0(webpack@5.94.0(@swc/core@1.7.26(@swc/helpers@0.5.5))))(tailwindcss@3.4.13(ts-node@10.9.2(@swc/core@1.7.26(@swc/helpers@0.5.5))(@types/node@22.7.4)(typescript@5.5.4)))(typescript@5.5.4) '@angular-devkit/core': 18.2.7(chokidar@3.6.0) '@angular/compiler-cli': 18.2.7(@angular/compiler@18.2.7(@angular/core@18.2.7(rxjs@7.8.1)(zone.js@0.14.10)))(typescript@5.5.4) lodash: 4.17.21 @@ -18311,13 +18317,13 @@ snapshots: transitivePeerDependencies: - chokidar - '@angular-devkit/build-angular@18.2.7(@angular/compiler-cli@18.2.7(@angular/compiler@18.2.7(@angular/core@18.2.7(rxjs@7.8.1)(zone.js@0.14.10)))(typescript@5.5.4))(@angular/service-worker@18.2.7(@angular/common@18.2.7(@angular/core@18.2.7(rxjs@7.8.1)(zone.js@0.14.10))(rxjs@7.8.1))(@angular/core@18.2.7(rxjs@7.8.1)(zone.js@0.14.10)))(@swc/core@1.7.26)(@types/node@22.7.4)(chokidar@3.6.0)(html-webpack-plugin@5.6.0(webpack@5.94.0(@swc/core@1.7.26)))(tailwindcss@3.4.13)(typescript@5.5.4)': + '@angular-devkit/build-angular@18.2.7(@angular/compiler-cli@18.2.7(@angular/compiler@18.2.7(@angular/core@18.2.7(rxjs@7.8.1)(zone.js@0.14.10)))(typescript@5.5.4))(@angular/service-worker@18.2.7(@angular/common@18.2.7(@angular/core@18.2.7(rxjs@7.8.1)(zone.js@0.14.10))(rxjs@7.8.1))(@angular/core@18.2.7(rxjs@7.8.1)(zone.js@0.14.10)))(@swc/core@1.7.26(@swc/helpers@0.5.5))(@types/node@22.7.4)(chokidar@3.6.0)(html-webpack-plugin@5.6.0(webpack@5.94.0(@swc/core@1.7.26(@swc/helpers@0.5.5))))(tailwindcss@3.4.13(ts-node@10.9.2(@swc/core@1.7.26(@swc/helpers@0.5.5))(@types/node@22.7.4)(typescript@5.5.4)))(typescript@5.5.4)': dependencies: '@ampproject/remapping': 2.3.0 '@angular-devkit/architect': 0.1802.7(chokidar@3.6.0) - '@angular-devkit/build-webpack': 0.1802.7(chokidar@3.6.0)(webpack-dev-server@5.0.4(webpack@5.94.0(@swc/core@1.7.26)(esbuild@0.23.0)))(webpack@5.94.0(@swc/core@1.7.26)(esbuild@0.23.0)) + '@angular-devkit/build-webpack': 0.1802.7(chokidar@3.6.0)(webpack-dev-server@5.0.4(webpack@5.94.0(@swc/core@1.7.26(@swc/helpers@0.5.5))))(webpack@5.94.0(@swc/core@1.7.26(@swc/helpers@0.5.5))) '@angular-devkit/core': 18.2.7(chokidar@3.6.0) - '@angular/build': 18.2.7(@angular/compiler-cli@18.2.7(@angular/compiler@18.2.7(@angular/core@18.2.7(rxjs@7.8.1)(zone.js@0.14.10)))(typescript@5.5.4))(@angular/service-worker@18.2.7(@angular/common@18.2.7(@angular/core@18.2.7(rxjs@7.8.1)(zone.js@0.14.10))(rxjs@7.8.1))(@angular/core@18.2.7(rxjs@7.8.1)(zone.js@0.14.10)))(@types/node@22.7.4)(chokidar@3.6.0)(less@4.2.0)(postcss@8.4.41)(tailwindcss@3.4.13)(terser@5.31.6)(typescript@5.5.4) + '@angular/build': 18.2.7(@angular/compiler-cli@18.2.7(@angular/compiler@18.2.7(@angular/core@18.2.7(rxjs@7.8.1)(zone.js@0.14.10)))(typescript@5.5.4))(@angular/service-worker@18.2.7(@angular/common@18.2.7(@angular/core@18.2.7(rxjs@7.8.1)(zone.js@0.14.10))(rxjs@7.8.1))(@angular/core@18.2.7(rxjs@7.8.1)(zone.js@0.14.10)))(@types/node@22.7.4)(chokidar@3.6.0)(less@4.2.0)(postcss@8.4.41)(tailwindcss@3.4.13(ts-node@10.9.2(@swc/core@1.7.26(@swc/helpers@0.5.5))(@types/node@22.7.4)(typescript@5.5.4)))(terser@5.31.6)(typescript@5.5.4) '@angular/compiler-cli': 18.2.7(@angular/compiler@18.2.7(@angular/core@18.2.7(rxjs@7.8.1)(zone.js@0.14.10)))(typescript@5.5.4) '@babel/core': 7.25.2 '@babel/generator': 7.25.0 @@ -18329,15 +18335,15 @@ snapshots: '@babel/preset-env': 7.25.3(@babel/core@7.25.2) '@babel/runtime': 7.25.0 '@discoveryjs/json-ext': 0.6.1 - '@ngtools/webpack': 18.2.7(@angular/compiler-cli@18.2.7(@angular/compiler@18.2.7(@angular/core@18.2.7(rxjs@7.8.1)(zone.js@0.14.10)))(typescript@5.5.4))(typescript@5.5.4)(webpack@5.94.0(@swc/core@1.7.26)(esbuild@0.23.0)) + '@ngtools/webpack': 18.2.7(@angular/compiler-cli@18.2.7(@angular/compiler@18.2.7(@angular/core@18.2.7(rxjs@7.8.1)(zone.js@0.14.10)))(typescript@5.5.4))(typescript@5.5.4)(webpack@5.94.0(@swc/core@1.7.26(@swc/helpers@0.5.5))) '@vitejs/plugin-basic-ssl': 1.1.0(vite@5.4.6(@types/node@22.7.4)(less@4.2.0)(sass@1.77.6)(terser@5.31.6)) ansi-colors: 4.1.3 autoprefixer: 10.4.20(postcss@8.4.41) - babel-loader: 9.1.3(@babel/core@7.25.2)(webpack@5.94.0(@swc/core@1.7.26)(esbuild@0.23.0)) + babel-loader: 9.1.3(@babel/core@7.25.2)(webpack@5.94.0(@swc/core@1.7.26(@swc/helpers@0.5.5))) browserslist: 4.24.0 - copy-webpack-plugin: 12.0.2(webpack@5.94.0(@swc/core@1.7.26)(esbuild@0.23.0)) + copy-webpack-plugin: 12.0.2(webpack@5.94.0(@swc/core@1.7.26(@swc/helpers@0.5.5))) critters: 0.0.24 - css-loader: 7.1.2(webpack@5.94.0(@swc/core@1.7.26)(esbuild@0.23.0)) + css-loader: 7.1.2(webpack@5.94.0(@swc/core@1.7.26(@swc/helpers@0.5.5))) esbuild-wasm: 0.23.0 fast-glob: 3.3.2 http-proxy-middleware: 3.0.0 @@ -18346,11 +18352,11 @@ snapshots: jsonc-parser: 3.3.1 karma-source-map-support: 1.4.0 less: 4.2.0 - less-loader: 12.2.0(less@4.2.0)(webpack@5.94.0(@swc/core@1.7.26)(esbuild@0.23.0)) - license-webpack-plugin: 4.0.2(webpack@5.94.0(@swc/core@1.7.26)(esbuild@0.23.0)) + less-loader: 12.2.0(less@4.2.0)(webpack@5.94.0(@swc/core@1.7.26(@swc/helpers@0.5.5))) + license-webpack-plugin: 4.0.2(webpack@5.94.0(@swc/core@1.7.26(@swc/helpers@0.5.5))) loader-utils: 3.3.1 magic-string: 0.30.11 - mini-css-extract-plugin: 2.9.0(webpack@5.94.0(@swc/core@1.7.26)(esbuild@0.23.0)) + mini-css-extract-plugin: 2.9.0(webpack@5.94.0(@swc/core@1.7.26(@swc/helpers@0.5.5))) mrmime: 2.0.0 open: 10.1.0 ora: 5.4.1 @@ -18358,13 +18364,13 @@ snapshots: picomatch: 4.0.2 piscina: 4.6.1 postcss: 8.4.41 - postcss-loader: 8.1.1(postcss@8.4.41)(typescript@5.5.4)(webpack@5.94.0(@swc/core@1.7.26)(esbuild@0.23.0)) + postcss-loader: 8.1.1(postcss@8.4.41)(typescript@5.5.4)(webpack@5.94.0(@swc/core@1.7.26(@swc/helpers@0.5.5))) resolve-url-loader: 5.0.0 rxjs: 7.8.1 sass: 1.77.6 - sass-loader: 16.0.0(sass@1.77.6)(webpack@5.94.0(@swc/core@1.7.26)(esbuild@0.23.0)) + sass-loader: 16.0.0(sass@1.77.6)(webpack@5.94.0(@swc/core@1.7.26(@swc/helpers@0.5.5))) semver: 7.6.3 - source-map-loader: 5.0.0(webpack@5.94.0(@swc/core@1.7.26)(esbuild@0.23.0)) + source-map-loader: 5.0.0(webpack@5.94.0(@swc/core@1.7.26(@swc/helpers@0.5.5))) source-map-support: 0.5.21 terser: 5.31.6 tree-kill: 1.2.2 @@ -18372,15 +18378,15 @@ snapshots: typescript: 5.5.4 vite: 5.4.6(@types/node@22.7.4)(less@4.2.0)(sass@1.77.6)(terser@5.31.6) watchpack: 2.4.1 - webpack: 5.94.0(@swc/core@1.7.26)(esbuild@0.23.0) - webpack-dev-middleware: 7.4.2(webpack@5.94.0(@swc/core@1.7.26)(esbuild@0.23.0)) - webpack-dev-server: 5.0.4(webpack@5.94.0(@swc/core@1.7.26)(esbuild@0.23.0)) + webpack: 5.94.0(@swc/core@1.7.26(@swc/helpers@0.5.5))(esbuild@0.23.0) + webpack-dev-middleware: 7.4.2(webpack@5.94.0(@swc/core@1.7.26(@swc/helpers@0.5.5))) + webpack-dev-server: 5.0.4(webpack@5.94.0(@swc/core@1.7.26(@swc/helpers@0.5.5))) webpack-merge: 6.0.1 - webpack-subresource-integrity: 5.1.0(html-webpack-plugin@5.6.0(webpack@5.94.0(@swc/core@1.7.26)))(webpack@5.94.0(@swc/core@1.7.26)(esbuild@0.23.0)) + webpack-subresource-integrity: 5.1.0(html-webpack-plugin@5.6.0(webpack@5.94.0(@swc/core@1.7.26(@swc/helpers@0.5.5))))(webpack@5.94.0(@swc/core@1.7.26(@swc/helpers@0.5.5))) optionalDependencies: '@angular/service-worker': 18.2.7(@angular/common@18.2.7(@angular/core@18.2.7(rxjs@7.8.1)(zone.js@0.14.10))(rxjs@7.8.1))(@angular/core@18.2.7(rxjs@7.8.1)(zone.js@0.14.10)) esbuild: 0.23.0 - tailwindcss: 3.4.13(ts-node@10.9.2(@types/node@20.16.10)(typescript@5.5.4)) + tailwindcss: 3.4.13(ts-node@10.9.2(@swc/core@1.7.26(@swc/helpers@0.5.5))(@types/node@22.7.4)(typescript@5.5.4)) transitivePeerDependencies: - '@rspack/core' - '@swc/core' @@ -18399,12 +18405,12 @@ snapshots: - utf-8-validate - webpack-cli - '@angular-devkit/build-webpack@0.1802.7(chokidar@3.6.0)(webpack-dev-server@5.0.4(webpack@5.94.0(@swc/core@1.7.26)(esbuild@0.23.0)))(webpack@5.94.0(@swc/core@1.7.26)(esbuild@0.23.0))': + '@angular-devkit/build-webpack@0.1802.7(chokidar@3.6.0)(webpack-dev-server@5.0.4(webpack@5.94.0(@swc/core@1.7.26(@swc/helpers@0.5.5))))(webpack@5.94.0(@swc/core@1.7.26(@swc/helpers@0.5.5)))': dependencies: '@angular-devkit/architect': 0.1802.7(chokidar@3.6.0) rxjs: 7.8.1 - webpack: 5.94.0(@swc/core@1.7.26)(esbuild@0.23.0) - webpack-dev-server: 5.0.4(webpack@5.94.0(@swc/core@1.7.26)(esbuild@0.23.0)) + webpack: 5.94.0(@swc/core@1.7.26(@swc/helpers@0.5.5))(esbuild@0.23.0) + webpack-dev-server: 5.0.4(webpack@5.94.0(@swc/core@1.7.26(@swc/helpers@0.5.5))) transitivePeerDependencies: - chokidar @@ -18434,7 +18440,7 @@ snapshots: '@angular/core': 18.2.7(rxjs@7.8.1)(zone.js@0.14.10) tslib: 2.7.0 - '@angular/build@18.2.7(@angular/compiler-cli@18.2.7(@angular/compiler@18.2.7(@angular/core@18.2.7(rxjs@7.8.1)(zone.js@0.14.10)))(typescript@5.5.4))(@angular/service-worker@18.2.7(@angular/common@18.2.7(@angular/core@18.2.7(rxjs@7.8.1)(zone.js@0.14.10))(rxjs@7.8.1))(@angular/core@18.2.7(rxjs@7.8.1)(zone.js@0.14.10)))(@types/node@22.7.4)(chokidar@3.6.0)(less@4.2.0)(postcss@8.4.41)(tailwindcss@3.4.13)(terser@5.31.6)(typescript@5.5.4)': + '@angular/build@18.2.7(@angular/compiler-cli@18.2.7(@angular/compiler@18.2.7(@angular/core@18.2.7(rxjs@7.8.1)(zone.js@0.14.10)))(typescript@5.5.4))(@angular/service-worker@18.2.7(@angular/common@18.2.7(@angular/core@18.2.7(rxjs@7.8.1)(zone.js@0.14.10))(rxjs@7.8.1))(@angular/core@18.2.7(rxjs@7.8.1)(zone.js@0.14.10)))(@types/node@22.7.4)(chokidar@3.6.0)(less@4.2.0)(postcss@8.4.41)(tailwindcss@3.4.13(ts-node@10.9.2(@swc/core@1.7.26(@swc/helpers@0.5.5))(@types/node@22.7.4)(typescript@5.5.4)))(terser@5.31.6)(typescript@5.5.4)': dependencies: '@ampproject/remapping': 2.3.0 '@angular-devkit/architect': 0.1802.7(chokidar@3.6.0) @@ -18467,7 +18473,7 @@ snapshots: '@angular/service-worker': 18.2.7(@angular/common@18.2.7(@angular/core@18.2.7(rxjs@7.8.1)(zone.js@0.14.10))(rxjs@7.8.1))(@angular/core@18.2.7(rxjs@7.8.1)(zone.js@0.14.10)) less: 4.2.0 postcss: 8.4.41 - tailwindcss: 3.4.13(ts-node@10.9.2(@types/node@20.16.10)(typescript@5.5.4)) + tailwindcss: 3.4.13(ts-node@10.9.2(@swc/core@1.7.26(@swc/helpers@0.5.5))(@types/node@22.7.4)(typescript@5.5.4)) transitivePeerDependencies: - '@types/node' - chokidar @@ -18660,9 +18666,9 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/eslint-parser@7.25.8(@babel/core@7.25.7)(eslint@8.57.1)': + '@babel/eslint-parser@7.25.8(@babel/core@7.24.5)(eslint@8.57.1)': dependencies: - '@babel/core': 7.25.7 + '@babel/core': 7.24.5 '@nicolo-ribaudo/eslint-scope-5-internals': 5.1.1-v1 eslint: 8.57.1 eslint-visitor-keys: 2.1.0 @@ -21384,7 +21390,7 @@ snapshots: tslib: 2.7.0 update-notifier: 6.0.2 url-loader: 4.1.1(file-loader@6.2.0(webpack@5.95.0))(webpack@5.95.0) - webpack: 5.95.0 + webpack: 5.95.0(webpack-cli@5.1.4) webpack-bundle-analyzer: 4.10.2 webpack-dev-server: 4.15.2(webpack@5.95.0) webpack-merge: 5.10.0 @@ -21476,7 +21482,7 @@ snapshots: tslib: 2.7.0 update-notifier: 6.0.2 url-loader: 4.1.1(file-loader@6.2.0(webpack@5.95.0))(webpack@5.95.0) - webpack: 5.95.0 + webpack: 5.95.0(webpack-cli@5.1.4) webpack-bundle-analyzer: 4.10.2 webpack-dev-server: 4.15.2(webpack@5.95.0) webpack-merge: 5.10.0 @@ -21539,7 +21545,7 @@ snapshots: unist-util-visit: 5.0.0 url-loader: 4.1.1(file-loader@6.2.0(webpack@5.95.0))(webpack@5.95.0) vfile: 6.0.3 - webpack: 5.95.0 + webpack: 5.95.0(webpack-cli@5.1.4) transitivePeerDependencies: - '@docusaurus/types' - '@swc/core' @@ -21576,7 +21582,7 @@ snapshots: unist-util-visit: 5.0.0 url-loader: 4.1.1(file-loader@6.2.0(webpack@5.95.0))(webpack@5.95.0) vfile: 6.0.3 - webpack: 5.95.0 + webpack: 5.95.0(webpack-cli@5.1.4) transitivePeerDependencies: - '@docusaurus/types' - '@swc/core' @@ -21626,7 +21632,7 @@ snapshots: tslib: 2.7.0 unist-util-visit: 5.0.0 utility-types: 3.11.0 - webpack: 5.95.0 + webpack: 5.95.0(webpack-cli@5.1.4) transitivePeerDependencies: - '@mdx-js/react' - '@parcel/css' @@ -21666,7 +21672,7 @@ snapshots: react-dom: 18.2.0(react@18.2.0) tslib: 2.7.0 utility-types: 3.11.0 - webpack: 5.95.0 + webpack: 5.95.0(webpack-cli@5.1.4) transitivePeerDependencies: - '@mdx-js/react' - '@parcel/css' @@ -21697,7 +21703,7 @@ snapshots: react: 18.2.0 react-dom: 18.2.0(react@18.2.0) tslib: 2.7.0 - webpack: 5.95.0 + webpack: 5.95.0(webpack-cli@5.1.4) transitivePeerDependencies: - '@mdx-js/react' - '@parcel/css' @@ -22039,7 +22045,7 @@ snapshots: react-dom: 18.2.0(react@18.2.0) react-helmet-async: 1.3.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0) utility-types: 3.11.0 - webpack: 5.95.0 + webpack: 5.95.0(webpack-cli@5.1.4) webpack-merge: 5.10.0 transitivePeerDependencies: - '@swc/core' @@ -22059,7 +22065,7 @@ snapshots: react-dom: 18.2.0(react@18.2.0) react-helmet-async: 1.3.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0) utility-types: 3.11.0 - webpack: 5.95.0 + webpack: 5.95.0(webpack-cli@5.1.4) webpack-merge: 5.10.0 transitivePeerDependencies: - '@swc/core' @@ -22139,7 +22145,7 @@ snapshots: tslib: 2.7.0 url-loader: 4.1.1(file-loader@6.2.0(webpack@5.95.0))(webpack@5.95.0) utility-types: 3.11.0 - webpack: 5.95.0 + webpack: 5.95.0(webpack-cli@5.1.4) optionalDependencies: '@docusaurus/types': 3.4.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0) transitivePeerDependencies: @@ -22171,7 +22177,7 @@ snapshots: tslib: 2.7.0 url-loader: 4.1.1(file-loader@6.2.0(webpack@5.95.0))(webpack@5.95.0) utility-types: 3.11.0 - webpack: 5.95.0 + webpack: 5.95.0(webpack-cli@5.1.4) optionalDependencies: '@docusaurus/types': 3.5.2(react-dom@18.2.0(react@18.2.0))(react@18.2.0) transitivePeerDependencies: @@ -23425,18 +23431,18 @@ snapshots: base64-js: 1.5.1 xmlbuilder: 14.0.0 - '@expo/plugin-help@5.1.23(@swc/core@1.7.26)(@types/node@22.7.4)(typescript@5.3.3)': + '@expo/plugin-help@5.1.23(@swc/core@1.7.26(@swc/helpers@0.5.5))(@types/node@22.7.4)(typescript@5.3.3)': dependencies: - '@oclif/core': 2.16.0(@swc/core@1.7.26)(@types/node@22.7.4)(typescript@5.3.3) + '@oclif/core': 2.16.0(@swc/core@1.7.26(@swc/helpers@0.5.5))(@types/node@22.7.4)(typescript@5.3.3) transitivePeerDependencies: - '@swc/core' - '@swc/wasm' - '@types/node' - typescript - '@expo/plugin-warn-if-update-available@2.5.1(@swc/core@1.7.26)(@types/node@22.7.4)(typescript@5.3.3)': + '@expo/plugin-warn-if-update-available@2.5.1(@swc/core@1.7.26(@swc/helpers@0.5.5))(@types/node@22.7.4)(typescript@5.3.3)': dependencies: - '@oclif/core': 2.16.0(@swc/core@1.7.26)(@types/node@22.7.4)(typescript@5.3.3) + '@oclif/core': 2.16.0(@swc/core@1.7.26(@swc/helpers@0.5.5))(@types/node@22.7.4)(typescript@5.3.3) chalk: 4.1.2 debug: 4.3.7(supports-color@8.1.1) ejs: 3.1.10 @@ -23999,11 +24005,6 @@ snapshots: '@types/yargs': 17.0.33 chalk: 4.1.2 - '@journeyapps/react-native-quick-sqlite@2.0.0(react-native@0.72.4(@babel/core@7.24.5)(@babel/preset-env@7.25.7(@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.7(@babel/core@7.24.5))(encoding@0.1.13)(react@18.2.0) - '@journeyapps/react-native-quick-sqlite@2.0.0(react-native@0.74.1(@babel/core@7.24.5)(@babel/preset-env@7.25.7(@babel/core@7.24.5))(@types/react@18.3.11)(encoding@0.1.13)(react@18.2.0))(react@18.2.0)': dependencies: react: 18.2.0 @@ -24019,6 +24020,11 @@ snapshots: react: 18.2.0 react-native: 0.74.5(@babel/core@7.25.7)(@babel/preset-env@7.25.7(@babel/core@7.25.7))(@types/react@18.2.79)(encoding@0.1.13)(react@18.2.0) + '@journeyapps/react-native-quick-sqlite@2.1.0(react-native@0.72.4(@babel/core@7.24.5)(@babel/preset-env@7.25.7(@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.7(@babel/core@7.24.5))(encoding@0.1.13)(react@18.2.0) + '@journeyapps/wa-sqlite@0.4.1': {} '@jridgewell/gen-mapping@0.3.5': @@ -24683,11 +24689,11 @@ snapshots: '@next/swc-win32-x64-msvc@14.2.3': optional: true - '@ngtools/webpack@18.2.7(@angular/compiler-cli@18.2.7(@angular/compiler@18.2.7(@angular/core@18.2.7(rxjs@7.8.1)(zone.js@0.14.10)))(typescript@5.5.4))(typescript@5.5.4)(webpack@5.94.0(@swc/core@1.7.26)(esbuild@0.23.0))': + '@ngtools/webpack@18.2.7(@angular/compiler-cli@18.2.7(@angular/compiler@18.2.7(@angular/core@18.2.7(rxjs@7.8.1)(zone.js@0.14.10)))(typescript@5.5.4))(typescript@5.5.4)(webpack@5.94.0(@swc/core@1.7.26(@swc/helpers@0.5.5)))': dependencies: '@angular/compiler-cli': 18.2.7(@angular/compiler@18.2.7(@angular/core@18.2.7(rxjs@7.8.1)(zone.js@0.14.10)))(typescript@5.5.4) typescript: 5.5.4 - webpack: 5.94.0(@swc/core@1.7.26)(esbuild@0.23.0) + webpack: 5.94.0(@swc/core@1.7.26(@swc/helpers@0.5.5))(esbuild@0.23.0) '@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1': dependencies: @@ -24813,7 +24819,7 @@ snapshots: widest-line: 3.1.0 wrap-ansi: 7.0.0 - '@oclif/core@2.16.0(@swc/core@1.7.26)(@types/node@22.7.4)(typescript@5.3.3)': + '@oclif/core@2.16.0(@swc/core@1.7.26(@swc/helpers@0.5.5))(@types/node@22.7.4)(typescript@5.3.3)': dependencies: '@types/cli-progress': 3.11.6 ansi-escapes: 4.3.2 @@ -24838,7 +24844,7 @@ snapshots: strip-ansi: 6.0.1 supports-color: 8.1.1 supports-hyperlinks: 2.3.0 - ts-node: 10.9.2(@swc/core@1.7.26)(@types/node@22.7.4)(typescript@5.3.3) + ts-node: 10.9.2(@swc/core@1.7.26(@swc/helpers@0.5.5))(@types/node@22.7.4)(typescript@5.3.3) tslib: 2.7.0 widest-line: 3.1.0 wordwrap: 1.0.0 @@ -24851,9 +24857,9 @@ snapshots: '@oclif/linewrap@1.0.0': {} - '@oclif/plugin-autocomplete@2.3.10(@swc/core@1.7.26)(@types/node@22.7.4)(typescript@5.3.3)': + '@oclif/plugin-autocomplete@2.3.10(@swc/core@1.7.26(@swc/helpers@0.5.5))(@types/node@22.7.4)(typescript@5.3.3)': dependencies: - '@oclif/core': 2.16.0(@swc/core@1.7.26)(@types/node@22.7.4)(typescript@5.3.3) + '@oclif/core': 2.16.0(@swc/core@1.7.26(@swc/helpers@0.5.5))(@types/node@22.7.4)(typescript@5.3.3) chalk: 4.1.2 debug: 4.3.7(supports-color@8.1.1) transitivePeerDependencies: @@ -26276,7 +26282,7 @@ snapshots: '@react-native/eslint-config@0.73.2(eslint@8.57.1)(prettier@3.3.3)(typescript@5.5.4)': dependencies: '@babel/core': 7.24.5 - '@babel/eslint-parser': 7.25.8(@babel/core@7.25.7)(eslint@8.57.1) + '@babel/eslint-parser': 7.25.8(@babel/core@7.24.5)(eslint@8.57.1) '@react-native/eslint-plugin': 0.73.1 '@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.5.4))(eslint@8.57.1)(typescript@5.5.4) '@typescript-eslint/parser': 5.62.0(eslint@8.57.1)(typescript@5.5.4) @@ -28852,7 +28858,7 @@ snapshots: dependencies: vue: 2.7.16 - '@types/webpack@5.28.5(webpack-cli@5.1.4(webpack@5.95.0))': + '@types/webpack@5.28.5(webpack-cli@5.1.4)': dependencies: '@types/node': 20.16.10 tapable: 2.2.1 @@ -29140,14 +29146,6 @@ snapshots: vite: 5.4.8(@types/node@22.7.4)(less@4.2.0)(sass@1.79.4)(terser@5.34.1) vue: 3.4.21(typescript@5.5.4) - '@vitest/browser@1.6.0(vitest@1.6.0)': - dependencies: - '@vitest/utils': 1.6.0 - magic-string: 0.30.11 - sirv: 2.0.4 - vitest: 1.6.0(@types/node@22.7.4)(@vitest/browser@1.6.0)(jsdom@24.1.3)(less@4.2.0)(sass@1.79.4)(terser@5.34.1) - optional: true - '@vitest/browser@1.6.0(vitest@1.6.0)(webdriverio@8.40.6)': dependencies: '@vitest/utils': 1.6.0 @@ -29361,7 +29359,7 @@ snapshots: vue: 3.4.21(typescript@5.5.4) vue-demi: 0.13.11(vue@3.4.21(typescript@5.5.4)) - '@vuetify/loader-shared@2.0.3(vue@3.4.21(typescript@5.5.4))(vuetify@3.6.8(typescript@5.5.4)(vite-plugin-vuetify@2.0.4)(vue@3.4.21(typescript@5.5.4)))': + '@vuetify/loader-shared@2.0.3(vue@3.4.21(typescript@5.5.4))(vuetify@3.6.8)': dependencies: upath: 2.0.1 vue: 3.4.21(typescript@5.5.4) @@ -29503,17 +29501,17 @@ snapshots: dependencies: commander: 10.0.1 - '@webpack-cli/configtest@2.1.1(webpack-cli@5.1.4(webpack@5.95.0))(webpack@5.95.0(webpack-cli@5.1.4))': + '@webpack-cli/configtest@2.1.1(webpack-cli@5.1.4)(webpack@5.95.0)': dependencies: webpack: 5.95.0(webpack-cli@5.1.4) webpack-cli: 5.1.4(webpack@5.95.0) - '@webpack-cli/info@2.0.2(webpack-cli@5.1.4(webpack@5.95.0))(webpack@5.95.0(webpack-cli@5.1.4))': + '@webpack-cli/info@2.0.2(webpack-cli@5.1.4)(webpack@5.95.0)': dependencies: webpack: 5.95.0(webpack-cli@5.1.4) webpack-cli: 5.1.4(webpack@5.95.0) - '@webpack-cli/serve@2.0.5(webpack-cli@5.1.4(webpack@5.95.0))(webpack@5.95.0(webpack-cli@5.1.4))': + '@webpack-cli/serve@2.0.5(webpack-cli@5.1.4)(webpack@5.95.0)': dependencies: webpack: 5.95.0(webpack-cli@5.1.4) webpack-cli: 5.1.4(webpack@5.95.0) @@ -29992,19 +29990,19 @@ snapshots: transitivePeerDependencies: - supports-color - babel-loader@9.1.3(@babel/core@7.25.2)(webpack@5.94.0(@swc/core@1.7.26)(esbuild@0.23.0)): + babel-loader@9.1.3(@babel/core@7.25.2)(webpack@5.94.0(@swc/core@1.7.26(@swc/helpers@0.5.5))): dependencies: '@babel/core': 7.25.2 find-cache-dir: 4.0.0 schema-utils: 4.2.0 - webpack: 5.94.0(@swc/core@1.7.26)(esbuild@0.23.0) + webpack: 5.94.0(@swc/core@1.7.26(@swc/helpers@0.5.5))(esbuild@0.23.0) babel-loader@9.2.1(@babel/core@7.24.5)(webpack@5.95.0): dependencies: '@babel/core': 7.24.5 find-cache-dir: 4.0.0 schema-utils: 4.2.0 - webpack: 5.95.0 + webpack: 5.95.0(webpack-cli@5.1.4) babel-loader@9.2.1(@babel/core@7.25.7)(webpack@5.95.0(@swc/core@1.6.13(@swc/helpers@0.5.5))): dependencies: @@ -30013,12 +30011,12 @@ snapshots: schema-utils: 4.2.0 webpack: 5.95.0(@swc/core@1.6.13(@swc/helpers@0.5.5)) - babel-loader@9.2.1(@babel/core@7.25.7)(webpack@5.95.0): + babel-loader@9.2.1(@babel/core@7.25.7)(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5))): dependencies: '@babel/core': 7.25.7 find-cache-dir: 4.0.0 schema-utils: 4.2.0 - webpack: 5.95.0 + webpack: 5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5)) babel-plugin-dynamic-import-node@2.3.3: dependencies: @@ -31077,9 +31075,9 @@ snapshots: normalize-path: 3.0.0 schema-utils: 4.2.0 serialize-javascript: 6.0.2 - webpack: 5.95.0 + webpack: 5.95.0(webpack-cli@5.1.4) - copy-webpack-plugin@12.0.2(webpack@5.94.0(@swc/core@1.7.26)(esbuild@0.23.0)): + copy-webpack-plugin@12.0.2(webpack@5.94.0(@swc/core@1.7.26(@swc/helpers@0.5.5))): dependencies: fast-glob: 3.3.2 glob-parent: 6.0.2 @@ -31087,7 +31085,7 @@ snapshots: normalize-path: 3.0.0 schema-utils: 4.2.0 serialize-javascript: 6.0.2 - webpack: 5.94.0(@swc/core@1.7.26)(esbuild@0.23.0) + webpack: 5.94.0(@swc/core@1.7.26(@swc/helpers@0.5.5))(esbuild@0.23.0) core-js-compat@3.38.1: dependencies: @@ -31253,6 +31251,19 @@ snapshots: dependencies: hyphenate-style-name: 1.1.0 + css-loader@6.11.0(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5))): + dependencies: + icss-utils: 5.1.0(postcss@8.4.47) + postcss: 8.4.47 + postcss-modules-extract-imports: 3.1.0(postcss@8.4.47) + postcss-modules-local-by-default: 4.0.5(postcss@8.4.47) + postcss-modules-scope: 3.2.0(postcss@8.4.47) + postcss-modules-values: 4.0.0(postcss@8.4.47) + postcss-value-parser: 4.2.0 + semver: 7.6.3 + optionalDependencies: + webpack: 5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5)) + css-loader@6.11.0(webpack@5.95.0): dependencies: icss-utils: 5.1.0(postcss@8.4.47) @@ -31264,9 +31275,9 @@ snapshots: postcss-value-parser: 4.2.0 semver: 7.6.3 optionalDependencies: - webpack: 5.95.0 + webpack: 5.95.0(webpack-cli@5.1.4) - css-loader@7.1.2(webpack@5.94.0(@swc/core@1.7.26)(esbuild@0.23.0)): + css-loader@7.1.2(webpack@5.94.0(@swc/core@1.7.26(@swc/helpers@0.5.5))): dependencies: icss-utils: 5.1.0(postcss@8.4.41) postcss: 8.4.41 @@ -31277,7 +31288,7 @@ snapshots: postcss-value-parser: 4.2.0 semver: 7.6.3 optionalDependencies: - webpack: 5.94.0(@swc/core@1.7.26)(esbuild@0.23.0) + webpack: 5.94.0(@swc/core@1.7.26(@swc/helpers@0.5.5))(esbuild@0.23.0) css-minimizer-webpack-plugin@5.0.1(clean-css@5.3.3)(webpack@5.95.0): dependencies: @@ -31287,7 +31298,7 @@ snapshots: postcss: 8.4.47 schema-utils: 4.2.0 serialize-javascript: 6.0.2 - webpack: 5.95.0 + webpack: 5.95.0(webpack-cli@5.1.4) optionalDependencies: clean-css: 5.3.3 @@ -31937,7 +31948,7 @@ snapshots: duplexer@0.1.2: {} - eas-cli@7.8.5(@swc/core@1.7.26)(@types/node@22.7.4)(encoding@0.1.13)(expo-modules-autolinking@1.11.1)(typescript@5.3.3): + eas-cli@7.8.5(@swc/core@1.7.26(@swc/helpers@0.5.5))(@types/node@22.7.4)(encoding@0.1.13)(expo-modules-autolinking@1.11.1)(typescript@5.3.3): dependencies: '@expo/apple-utils': 1.7.0 '@expo/code-signing-certificates': 0.0.5 @@ -31953,8 +31964,8 @@ snapshots: '@expo/package-manager': 1.1.2 '@expo/pkcs12': 0.0.8 '@expo/plist': 0.0.20 - '@expo/plugin-help': 5.1.23(@swc/core@1.7.26)(@types/node@22.7.4)(typescript@5.3.3) - '@expo/plugin-warn-if-update-available': 2.5.1(@swc/core@1.7.26)(@types/node@22.7.4)(typescript@5.3.3) + '@expo/plugin-help': 5.1.23(@swc/core@1.7.26(@swc/helpers@0.5.5))(@types/node@22.7.4)(typescript@5.3.3) + '@expo/plugin-warn-if-update-available': 2.5.1(@swc/core@1.7.26(@swc/helpers@0.5.5))(@types/node@22.7.4)(typescript@5.3.3) '@expo/prebuild-config': 6.7.3(encoding@0.1.13)(expo-modules-autolinking@1.11.1) '@expo/results': 1.0.0 '@expo/rudder-sdk-node': 1.1.1(encoding@0.1.13) @@ -31962,7 +31973,7 @@ snapshots: '@expo/steps': 1.0.95 '@expo/timeago.js': 1.0.0 '@oclif/core': 1.26.2 - '@oclif/plugin-autocomplete': 2.3.10(@swc/core@1.7.26)(@types/node@22.7.4)(typescript@5.3.3) + '@oclif/plugin-autocomplete': 2.3.10(@swc/core@1.7.26(@swc/helpers@0.5.5))(@types/node@22.7.4)(typescript@5.3.3) '@segment/ajv-human-errors': 2.13.0(ajv@8.11.0) '@urql/core': 4.0.11(graphql@16.8.1) '@urql/exchange-retry': 1.2.0(graphql@16.8.1) @@ -32497,7 +32508,7 @@ snapshots: debug: 4.3.7(supports-color@8.1.1) enhanced-resolve: 5.17.1 eslint: 8.57.1 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1) fast-glob: 3.3.2 get-tsconfig: 4.8.1 is-bun-module: 1.2.1 @@ -32520,7 +32531,7 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1): + eslint-module-utils@2.12.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1): dependencies: debug: 3.2.7 optionalDependencies: @@ -32545,7 +32556,7 @@ snapshots: eslint-plugin-ft-flow@2.0.3(@babel/eslint-parser@7.25.8(@babel/core@7.24.5)(eslint@8.57.1))(eslint@8.57.1): dependencies: - '@babel/eslint-parser': 7.25.8(@babel/core@7.25.7)(eslint@8.57.1) + '@babel/eslint-parser': 7.25.8(@babel/core@7.24.5)(eslint@8.57.1) eslint: 8.57.1 lodash: 4.17.21 string-natural-compare: 3.0.1 @@ -32590,7 +32601,7 @@ snapshots: doctrine: 2.1.0 eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1) hasown: 2.0.2 is-core-module: 2.15.1 is-glob: 4.0.3 @@ -33635,7 +33646,7 @@ snapshots: dependencies: loader-utils: 2.0.4 schema-utils: 3.3.0 - webpack: 5.95.0 + webpack: 5.95.0(webpack-cli@5.1.4) filelist@1.0.4: dependencies: @@ -33794,7 +33805,7 @@ snapshots: semver: 7.6.3 tapable: 1.1.3 typescript: 5.5.4 - webpack: 5.95.0 + webpack: 5.95.0(webpack-cli@5.1.4) optionalDependencies: eslint: 8.57.1 @@ -34515,7 +34526,7 @@ snapshots: html-void-elements@3.0.0: {} - html-webpack-plugin@5.6.0(webpack@5.94.0(@swc/core@1.7.26)): + html-webpack-plugin@5.6.0(webpack@5.94.0(@swc/core@1.7.26(@swc/helpers@0.5.5))): dependencies: '@types/html-minifier-terser': 6.1.0 html-minifier-terser: 6.1.0 @@ -34523,19 +34534,9 @@ snapshots: pretty-error: 4.0.0 tapable: 2.2.1 optionalDependencies: - webpack: 5.94.0(@swc/core@1.7.26) + webpack: 5.94.0(@swc/core@1.7.26(@swc/helpers@0.5.5))(esbuild@0.23.0) optional: true - html-webpack-plugin@5.6.0(webpack@5.95.0(webpack-cli@5.1.4)): - dependencies: - '@types/html-minifier-terser': 6.1.0 - html-minifier-terser: 6.1.0 - lodash: 4.17.21 - pretty-error: 4.0.0 - tapable: 2.2.1 - optionalDependencies: - webpack: 5.95.0(webpack-cli@5.1.4) - html-webpack-plugin@5.6.0(webpack@5.95.0): dependencies: '@types/html-minifier-terser': 6.1.0 @@ -34544,7 +34545,7 @@ snapshots: pretty-error: 4.0.0 tapable: 2.2.1 optionalDependencies: - webpack: 5.95.0 + webpack: 5.95.0(webpack-cli@5.1.4) htmlparser2@6.1.0: dependencies: @@ -35486,11 +35487,11 @@ snapshots: dependencies: readable-stream: 2.3.8 - less-loader@12.2.0(less@4.2.0)(webpack@5.94.0(@swc/core@1.7.26)(esbuild@0.23.0)): + less-loader@12.2.0(less@4.2.0)(webpack@5.94.0(@swc/core@1.7.26(@swc/helpers@0.5.5))): dependencies: less: 4.2.0 optionalDependencies: - webpack: 5.94.0(@swc/core@1.7.26)(esbuild@0.23.0) + webpack: 5.94.0(@swc/core@1.7.26(@swc/helpers@0.5.5))(esbuild@0.23.0) less@4.2.0: dependencies: @@ -35521,11 +35522,11 @@ snapshots: dependencies: isomorphic.js: 0.2.5 - license-webpack-plugin@4.0.2(webpack@5.94.0(@swc/core@1.7.26)(esbuild@0.23.0)): + license-webpack-plugin@4.0.2(webpack@5.94.0(@swc/core@1.7.26(@swc/helpers@0.5.5))): dependencies: webpack-sources: 3.2.3 optionalDependencies: - webpack: 5.94.0(@swc/core@1.7.26)(esbuild@0.23.0) + webpack: 5.94.0(@swc/core@1.7.26(@swc/helpers@0.5.5))(esbuild@0.23.0) lie@3.3.0: dependencies: @@ -36997,17 +36998,17 @@ snapshots: min-indent@1.0.1: {} - mini-css-extract-plugin@2.9.0(webpack@5.94.0(@swc/core@1.7.26)(esbuild@0.23.0)): + mini-css-extract-plugin@2.9.0(webpack@5.94.0(@swc/core@1.7.26(@swc/helpers@0.5.5))): dependencies: schema-utils: 4.2.0 tapable: 2.2.1 - webpack: 5.94.0(@swc/core@1.7.26)(esbuild@0.23.0) + webpack: 5.94.0(@swc/core@1.7.26(@swc/helpers@0.5.5))(esbuild@0.23.0) mini-css-extract-plugin@2.9.1(webpack@5.95.0): dependencies: schema-utils: 4.2.0 tapable: 2.2.1 - webpack: 5.95.0 + webpack: 5.95.0(webpack-cli@5.1.4) minimalistic-assert@1.0.1: {} @@ -38083,7 +38084,7 @@ snapshots: camelcase-css: 2.0.1 postcss: 8.4.47 - postcss-load-config@4.0.2(postcss@8.4.47)(ts-node@10.9.2(@types/node@20.16.10)(typescript@5.5.4)): + postcss-load-config@4.0.2(postcss@8.4.47)(ts-node@10.9.2(@swc/core@1.7.26(@swc/helpers@0.5.5))(@types/node@20.16.10)(typescript@5.5.4)): dependencies: lilconfig: 3.1.2 yaml: 2.5.1 @@ -38091,24 +38092,33 @@ snapshots: postcss: 8.4.47 ts-node: 10.9.2(@swc/core@1.7.26(@swc/helpers@0.5.5))(@types/node@20.16.10)(typescript@5.5.4) + postcss-load-config@4.0.2(postcss@8.4.47)(ts-node@10.9.2(@swc/core@1.7.26(@swc/helpers@0.5.5))(@types/node@22.7.4)(typescript@5.5.4)): + dependencies: + lilconfig: 3.1.2 + yaml: 2.5.1 + optionalDependencies: + postcss: 8.4.47 + ts-node: 10.9.2(@swc/core@1.7.26(@swc/helpers@0.5.5))(@types/node@22.7.4)(typescript@5.5.4) + optional: true + postcss-loader@7.3.4(postcss@8.4.47)(typescript@5.5.4)(webpack@5.95.0): dependencies: cosmiconfig: 8.3.6(typescript@5.5.4) jiti: 1.21.6 postcss: 8.4.47 semver: 7.6.3 - webpack: 5.95.0 + webpack: 5.95.0(webpack-cli@5.1.4) transitivePeerDependencies: - typescript - postcss-loader@8.1.1(postcss@8.4.41)(typescript@5.5.4)(webpack@5.94.0(@swc/core@1.7.26)(esbuild@0.23.0)): + postcss-loader@8.1.1(postcss@8.4.41)(typescript@5.5.4)(webpack@5.94.0(@swc/core@1.7.26(@swc/helpers@0.5.5))): dependencies: cosmiconfig: 9.0.0(typescript@5.5.4) jiti: 1.21.6 postcss: 8.4.41 semver: 7.6.3 optionalDependencies: - webpack: 5.94.0(@swc/core@1.7.26)(esbuild@0.23.0) + webpack: 5.94.0(@swc/core@1.7.26(@swc/helpers@0.5.5))(esbuild@0.23.0) transitivePeerDependencies: - typescript @@ -38696,7 +38706,7 @@ snapshots: shell-quote: 1.8.1 strip-ansi: 6.0.1 text-table: 0.2.0 - webpack: 5.95.0 + webpack: 5.95.0(webpack-cli@5.1.4) optionalDependencies: typescript: 5.5.4 transitivePeerDependencies: @@ -38777,7 +38787,7 @@ snapshots: dependencies: '@babel/runtime': 7.25.7 react-loadable: '@docusaurus/react-loadable@6.0.0(react@18.2.0)' - webpack: 5.95.0 + webpack: 5.95.0(webpack-cli@5.1.4) react-native-builder-bob@0.30.2(typescript@5.5.4): dependencies: @@ -40139,19 +40149,19 @@ snapshots: safer-buffer@2.1.2: {} - sass-loader@13.3.3(sass@1.79.4)(webpack@5.95.0): + sass-loader@13.3.3(sass@1.79.4)(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5))): dependencies: neo-async: 2.6.2 - webpack: 5.95.0 + webpack: 5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5)) optionalDependencies: sass: 1.79.4 - sass-loader@16.0.0(sass@1.77.6)(webpack@5.94.0(@swc/core@1.7.26)(esbuild@0.23.0)): + sass-loader@16.0.0(sass@1.77.6)(webpack@5.94.0(@swc/core@1.7.26(@swc/helpers@0.5.5))): dependencies: neo-async: 2.6.2 optionalDependencies: sass: 1.77.6 - webpack: 5.94.0(@swc/core@1.7.26)(esbuild@0.23.0) + webpack: 5.94.0(@swc/core@1.7.26(@swc/helpers@0.5.5))(esbuild@0.23.0) sass@1.77.6: dependencies: @@ -40556,13 +40566,13 @@ snapshots: source-map-js@1.2.1: {} - source-map-loader@5.0.0(webpack@5.94.0(@swc/core@1.7.26)(esbuild@0.23.0)): + source-map-loader@5.0.0(webpack@5.94.0(@swc/core@1.7.26(@swc/helpers@0.5.5))): dependencies: iconv-lite: 0.6.3 source-map-js: 1.2.1 - webpack: 5.94.0(@swc/core@1.7.26)(esbuild@0.23.0) + webpack: 5.94.0(@swc/core@1.7.26(@swc/helpers@0.5.5))(esbuild@0.23.0) - source-map-loader@5.0.0(webpack@5.95.0(webpack-cli@5.1.4)): + source-map-loader@5.0.0(webpack@5.95.0): dependencies: iconv-lite: 0.6.3 source-map-js: 1.2.1 @@ -40853,9 +40863,9 @@ snapshots: dependencies: webpack: 5.95.0(@swc/core@1.6.13(@swc/helpers@0.5.5)) - style-loader@3.3.4(webpack@5.95.0): + style-loader@3.3.4(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5))): dependencies: - webpack: 5.95.0 + webpack: 5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5)) style-to-object@0.4.4: dependencies: @@ -40979,7 +40989,34 @@ snapshots: tabbable@6.2.0: {} - tailwindcss@3.4.13(ts-node@10.9.2(@types/node@20.16.10)(typescript@5.5.4)): + tailwindcss@3.4.13(ts-node@10.9.2(@swc/core@1.7.26(@swc/helpers@0.5.5))(@types/node@20.16.10)(typescript@5.5.4)): + dependencies: + '@alloc/quick-lru': 5.2.0 + arg: 5.0.2 + chokidar: 3.6.0 + didyoumean: 1.2.2 + dlv: 1.1.3 + fast-glob: 3.3.2 + glob-parent: 6.0.2 + is-glob: 4.0.3 + jiti: 1.21.6 + lilconfig: 2.1.0 + micromatch: 4.0.8 + normalize-path: 3.0.0 + object-hash: 3.0.0 + picocolors: 1.1.0 + postcss: 8.4.47 + postcss-import: 15.1.0(postcss@8.4.47) + postcss-js: 4.0.1(postcss@8.4.47) + postcss-load-config: 4.0.2(postcss@8.4.47)(ts-node@10.9.2(@swc/core@1.7.26(@swc/helpers@0.5.5))(@types/node@20.16.10)(typescript@5.5.4)) + postcss-nested: 6.2.0(postcss@8.4.47) + postcss-selector-parser: 6.1.2 + resolve: 1.22.8 + sucrase: 3.35.0 + transitivePeerDependencies: + - ts-node + + tailwindcss@3.4.13(ts-node@10.9.2(@swc/core@1.7.26(@swc/helpers@0.5.5))(@types/node@22.7.4)(typescript@5.5.4)): dependencies: '@alloc/quick-lru': 5.2.0 arg: 5.0.2 @@ -40998,13 +41035,14 @@ snapshots: postcss: 8.4.47 postcss-import: 15.1.0(postcss@8.4.47) postcss-js: 4.0.1(postcss@8.4.47) - postcss-load-config: 4.0.2(postcss@8.4.47)(ts-node@10.9.2(@types/node@20.16.10)(typescript@5.5.4)) + postcss-load-config: 4.0.2(postcss@8.4.47)(ts-node@10.9.2(@swc/core@1.7.26(@swc/helpers@0.5.5))(@types/node@22.7.4)(typescript@5.5.4)) postcss-nested: 6.2.0(postcss@8.4.47) postcss-selector-parser: 6.1.2 resolve: 1.22.8 sucrase: 3.35.0 transitivePeerDependencies: - ts-node + optional: true tamagui@1.79.6(@types/react@18.3.11)(immer@9.0.21)(react-dom@18.2.0(react@18.2.0))(react-native-web@0.19.12(encoding@0.1.13)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react-native@0.74.1(@babel/core@7.24.5)(@babel/preset-env@7.25.7(@babel/core@7.24.5))(@types/react@18.3.11)(encoding@0.1.13)(react@18.2.0))(react@18.2.0): dependencies: @@ -41171,49 +41209,28 @@ snapshots: optionalDependencies: '@swc/core': 1.6.13(@swc/helpers@0.5.5) - terser-webpack-plugin@5.3.10(@swc/core@1.7.26(@swc/helpers@0.5.5))(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5))): - dependencies: - '@jridgewell/trace-mapping': 0.3.25 - jest-worker: 27.5.1 - schema-utils: 3.3.0 - serialize-javascript: 6.0.2 - terser: 5.34.1 - webpack: 5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5)) - optionalDependencies: - '@swc/core': 1.7.26(@swc/helpers@0.5.5) - - terser-webpack-plugin@5.3.10(@swc/core@1.7.26)(esbuild@0.23.0)(webpack@5.94.0(@swc/core@1.7.26)(esbuild@0.23.0)): + terser-webpack-plugin@5.3.10(@swc/core@1.7.26(@swc/helpers@0.5.5))(esbuild@0.23.0)(webpack@5.94.0(@swc/core@1.7.26(@swc/helpers@0.5.5))): dependencies: '@jridgewell/trace-mapping': 0.3.25 jest-worker: 27.5.1 schema-utils: 3.3.0 serialize-javascript: 6.0.2 terser: 5.34.1 - webpack: 5.94.0(@swc/core@1.7.26)(esbuild@0.23.0) + webpack: 5.94.0(@swc/core@1.7.26(@swc/helpers@0.5.5))(esbuild@0.23.0) optionalDependencies: '@swc/core': 1.7.26(@swc/helpers@0.5.5) esbuild: 0.23.0 - terser-webpack-plugin@5.3.10(@swc/core@1.7.26)(webpack@5.94.0(@swc/core@1.7.26)): + terser-webpack-plugin@5.3.10(@swc/core@1.7.26(@swc/helpers@0.5.5))(webpack@5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5))): dependencies: '@jridgewell/trace-mapping': 0.3.25 jest-worker: 27.5.1 schema-utils: 3.3.0 serialize-javascript: 6.0.2 terser: 5.34.1 - webpack: 5.94.0(@swc/core@1.7.26) + webpack: 5.95.0(@swc/core@1.7.26(@swc/helpers@0.5.5)) optionalDependencies: '@swc/core': 1.7.26(@swc/helpers@0.5.5) - optional: true - - terser-webpack-plugin@5.3.10(webpack@5.95.0(webpack-cli@5.1.4)): - dependencies: - '@jridgewell/trace-mapping': 0.3.25 - jest-worker: 27.5.1 - schema-utils: 3.3.0 - serialize-javascript: 6.0.2 - terser: 5.34.1 - webpack: 5.95.0(webpack-cli@5.1.4) terser-webpack-plugin@5.3.10(webpack@5.95.0): dependencies: @@ -41222,7 +41239,7 @@ snapshots: schema-utils: 3.3.0 serialize-javascript: 6.0.2 terser: 5.34.1 - webpack: 5.95.0 + webpack: 5.95.0(webpack-cli@5.1.4) terser@5.31.6: dependencies: @@ -41427,7 +41444,7 @@ snapshots: optionalDependencies: '@swc/core': 1.7.26(@swc/helpers@0.5.5) - ts-node@10.9.2(@swc/core@1.7.26)(@types/node@22.7.4)(typescript@5.3.3): + ts-node@10.9.2(@swc/core@1.7.26(@swc/helpers@0.5.5))(@types/node@22.7.4)(typescript@5.3.3): dependencies: '@cspotcode/source-map-support': 0.8.1 '@tsconfig/node10': 1.0.11 @@ -41447,7 +41464,7 @@ snapshots: optionalDependencies: '@swc/core': 1.7.26(@swc/helpers@0.5.5) - ts-node@10.9.2(@swc/core@1.7.26)(@types/node@22.7.4)(typescript@5.5.4): + ts-node@10.9.2(@swc/core@1.7.26(@swc/helpers@0.5.5))(@types/node@22.7.4)(typescript@5.5.4): dependencies: '@cspotcode/source-map-support': 0.8.1 '@tsconfig/node10': 1.0.11 @@ -41871,7 +41888,7 @@ snapshots: loader-utils: 2.0.4 mime-types: 2.1.35 schema-utils: 3.3.0 - webpack: 5.95.0 + webpack: 5.95.0(webpack-cli@5.1.4) optionalDependencies: file-loader: 6.2.0(webpack@5.95.0) @@ -42099,7 +42116,7 @@ snapshots: vite-plugin-vuetify@2.0.4(vite@5.4.8(@types/node@22.7.4)(less@4.2.0)(sass@1.79.4)(terser@5.34.1))(vue@3.4.21(typescript@5.5.4))(vuetify@3.6.8): dependencies: - '@vuetify/loader-shared': 2.0.3(vue@3.4.21(typescript@5.5.4))(vuetify@3.6.8(typescript@5.5.4)(vite-plugin-vuetify@2.0.4)(vue@3.4.21(typescript@5.5.4))) + '@vuetify/loader-shared': 2.0.3(vue@3.4.21(typescript@5.5.4))(vuetify@3.6.8) debug: 4.3.7(supports-color@8.1.1) upath: 2.0.1 vite: 5.4.8(@types/node@22.7.4)(less@4.2.0)(sass@1.79.4)(terser@5.34.1) @@ -42212,7 +42229,7 @@ snapshots: why-is-node-running: 2.3.0 optionalDependencies: '@types/node': 22.7.4 - '@vitest/browser': 1.6.0(vitest@1.6.0) + '@vitest/browser': 1.6.0(vitest@1.6.0)(webdriverio@8.40.6) jsdom: 24.1.3 transitivePeerDependencies: - less @@ -42448,9 +42465,9 @@ snapshots: webpack-cli@5.1.4(webpack@5.95.0): dependencies: '@discoveryjs/json-ext': 0.5.7 - '@webpack-cli/configtest': 2.1.1(webpack-cli@5.1.4(webpack@5.95.0))(webpack@5.95.0(webpack-cli@5.1.4)) - '@webpack-cli/info': 2.0.2(webpack-cli@5.1.4(webpack@5.95.0))(webpack@5.95.0(webpack-cli@5.1.4)) - '@webpack-cli/serve': 2.0.5(webpack-cli@5.1.4(webpack@5.95.0))(webpack@5.95.0(webpack-cli@5.1.4)) + '@webpack-cli/configtest': 2.1.1(webpack-cli@5.1.4)(webpack@5.95.0) + '@webpack-cli/info': 2.0.2(webpack-cli@5.1.4)(webpack@5.95.0) + '@webpack-cli/serve': 2.0.5(webpack-cli@5.1.4)(webpack@5.95.0) colorette: 2.0.20 commander: 10.0.1 cross-spawn: 7.0.3 @@ -42469,9 +42486,9 @@ snapshots: mime-types: 2.1.35 range-parser: 1.2.1 schema-utils: 4.2.0 - webpack: 5.95.0 + webpack: 5.95.0(webpack-cli@5.1.4) - webpack-dev-middleware@7.4.2(webpack@5.94.0(@swc/core@1.7.26)(esbuild@0.23.0)): + webpack-dev-middleware@7.4.2(webpack@5.94.0(@swc/core@1.7.26(@swc/helpers@0.5.5))): dependencies: colorette: 2.0.20 memfs: 4.12.0 @@ -42480,7 +42497,7 @@ snapshots: range-parser: 1.2.1 schema-utils: 4.2.0 optionalDependencies: - webpack: 5.94.0(@swc/core@1.7.26)(esbuild@0.23.0) + webpack: 5.94.0(@swc/core@1.7.26(@swc/helpers@0.5.5))(esbuild@0.23.0) webpack-dev-server@4.15.2(webpack@5.95.0): dependencies: @@ -42515,14 +42532,14 @@ snapshots: webpack-dev-middleware: 5.3.4(webpack@5.95.0) ws: 8.18.0 optionalDependencies: - webpack: 5.95.0 + webpack: 5.95.0(webpack-cli@5.1.4) transitivePeerDependencies: - bufferutil - debug - supports-color - utf-8-validate - webpack-dev-server@5.0.4(webpack@5.94.0(@swc/core@1.7.26)(esbuild@0.23.0)): + webpack-dev-server@5.0.4(webpack@5.94.0(@swc/core@1.7.26(@swc/helpers@0.5.5))): dependencies: '@types/bonjour': 3.5.13 '@types/connect-history-api-fallback': 1.5.4 @@ -42552,10 +42569,10 @@ snapshots: serve-index: 1.9.1 sockjs: 0.3.24 spdy: 4.0.2 - webpack-dev-middleware: 7.4.2(webpack@5.94.0(@swc/core@1.7.26)(esbuild@0.23.0)) + webpack-dev-middleware: 7.4.2(webpack@5.94.0(@swc/core@1.7.26(@swc/helpers@0.5.5))) ws: 8.18.0 optionalDependencies: - webpack: 5.94.0(@swc/core@1.7.26)(esbuild@0.23.0) + webpack: 5.94.0(@swc/core@1.7.26(@swc/helpers@0.5.5))(esbuild@0.23.0) transitivePeerDependencies: - bufferutil - debug @@ -42578,47 +42595,16 @@ snapshots: webpack-sources@3.2.3: {} - webpack-subresource-integrity@5.1.0(html-webpack-plugin@5.6.0(webpack@5.94.0(@swc/core@1.7.26)))(webpack@5.94.0(@swc/core@1.7.26)(esbuild@0.23.0)): + webpack-subresource-integrity@5.1.0(html-webpack-plugin@5.6.0(webpack@5.94.0(@swc/core@1.7.26(@swc/helpers@0.5.5))))(webpack@5.94.0(@swc/core@1.7.26(@swc/helpers@0.5.5))): dependencies: typed-assert: 1.0.9 - webpack: 5.94.0(@swc/core@1.7.26)(esbuild@0.23.0) + webpack: 5.94.0(@swc/core@1.7.26(@swc/helpers@0.5.5))(esbuild@0.23.0) optionalDependencies: - html-webpack-plugin: 5.6.0(webpack@5.94.0(@swc/core@1.7.26)) + html-webpack-plugin: 5.6.0(webpack@5.94.0(@swc/core@1.7.26(@swc/helpers@0.5.5))) webpack-virtual-modules@0.6.2: {} - webpack@5.94.0(@swc/core@1.7.26): - dependencies: - '@types/estree': 1.0.6 - '@webassemblyjs/ast': 1.12.1 - '@webassemblyjs/wasm-edit': 1.12.1 - '@webassemblyjs/wasm-parser': 1.12.1 - acorn: 8.12.1 - acorn-import-attributes: 1.9.5(acorn@8.12.1) - browserslist: 4.24.0 - chrome-trace-event: 1.0.4 - enhanced-resolve: 5.17.1 - es-module-lexer: 1.5.4 - eslint-scope: 5.1.1 - events: 3.3.0 - glob-to-regexp: 0.4.1 - graceful-fs: 4.2.11 - json-parse-even-better-errors: 2.3.1 - loader-runner: 4.3.0 - mime-types: 2.1.35 - neo-async: 2.6.2 - schema-utils: 3.3.0 - tapable: 2.2.1 - terser-webpack-plugin: 5.3.10(@swc/core@1.7.26)(webpack@5.94.0(@swc/core@1.7.26)) - watchpack: 2.4.1 - webpack-sources: 3.2.3 - transitivePeerDependencies: - - '@swc/core' - - esbuild - - uglify-js - optional: true - - webpack@5.94.0(@swc/core@1.7.26)(esbuild@0.23.0): + webpack@5.94.0(@swc/core@1.7.26(@swc/helpers@0.5.5))(esbuild@0.23.0): dependencies: '@types/estree': 1.0.6 '@webassemblyjs/ast': 1.12.1 @@ -42640,7 +42626,7 @@ snapshots: neo-async: 2.6.2 schema-utils: 3.3.0 tapable: 2.2.1 - terser-webpack-plugin: 5.3.10(@swc/core@1.7.26)(esbuild@0.23.0)(webpack@5.94.0(@swc/core@1.7.26)(esbuild@0.23.0)) + terser-webpack-plugin: 5.3.10(@swc/core@1.7.26(@swc/helpers@0.5.5))(esbuild@0.23.0)(webpack@5.94.0(@swc/core@1.7.26(@swc/helpers@0.5.5))) watchpack: 2.4.1 webpack-sources: 3.2.3 transitivePeerDependencies: @@ -42648,36 +42634,6 @@ snapshots: - esbuild - uglify-js - webpack@5.95.0: - dependencies: - '@types/estree': 1.0.6 - '@webassemblyjs/ast': 1.12.1 - '@webassemblyjs/wasm-edit': 1.12.1 - '@webassemblyjs/wasm-parser': 1.12.1 - acorn: 8.12.1 - acorn-import-attributes: 1.9.5(acorn@8.12.1) - browserslist: 4.24.0 - chrome-trace-event: 1.0.4 - enhanced-resolve: 5.17.1 - es-module-lexer: 1.5.4 - eslint-scope: 5.1.1 - events: 3.3.0 - glob-to-regexp: 0.4.1 - graceful-fs: 4.2.11 - json-parse-even-better-errors: 2.3.1 - loader-runner: 4.3.0 - mime-types: 2.1.35 - neo-async: 2.6.2 - schema-utils: 3.3.0 - tapable: 2.2.1 - terser-webpack-plugin: 5.3.10(webpack@5.95.0) - watchpack: 2.4.2 - webpack-sources: 3.2.3 - transitivePeerDependencies: - - '@swc/core' - - esbuild - - uglify-js - webpack@5.95.0(@swc/core@1.6.13(@swc/helpers@0.5.5)): dependencies: '@types/estree': 1.0.6 @@ -42760,7 +42716,7 @@ snapshots: neo-async: 2.6.2 schema-utils: 3.3.0 tapable: 2.2.1 - terser-webpack-plugin: 5.3.10(webpack@5.95.0(webpack-cli@5.1.4)) + terser-webpack-plugin: 5.3.10(webpack@5.95.0) watchpack: 2.4.2 webpack-sources: 3.2.3 optionalDependencies: @@ -42776,7 +42732,7 @@ snapshots: consola: 2.15.3 pretty-time: 1.1.0 std-env: 3.7.0 - webpack: 5.95.0 + webpack: 5.95.0(webpack-cli@5.1.4) websocket-driver@0.7.4: dependencies: From 944bc839e437fb0ce7f3114ce1049c0b15f8d850 Mon Sep 17 00:00:00 2001 From: Christiaan Landman Date: Tue, 5 Nov 2024 09:46:27 +0200 Subject: [PATCH 16/17] Updated OPSqliteAdapter with incoming changes. --- packages/powersync-op-sqlite/src/db/OPSqliteAdapter.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/powersync-op-sqlite/src/db/OPSqliteAdapter.ts b/packages/powersync-op-sqlite/src/db/OPSqliteAdapter.ts index 146442777..8815f8e5d 100644 --- a/packages/powersync-op-sqlite/src/db/OPSqliteAdapter.ts +++ b/packages/powersync-op-sqlite/src/db/OPSqliteAdapter.ts @@ -275,8 +275,8 @@ export class OPSQLiteDBAdapter extends BaseObserver implement async refreshSchema(): Promise { await this.writeConnection?.refreshSchema(); - for (let connection of this.readConnections) { - await connection.refreshSchema(); + for (let readConnection of this.readConnections) { + await readConnection.connection.refreshSchema(); } } } From ac2839f9dac40c9fd798f5f52fa7b01596b66e19 Mon Sep 17 00:00:00 2001 From: Christiaan Landman Date: Tue, 5 Nov 2024 10:56:54 +0200 Subject: [PATCH 17/17] Minor comment and await on initialized in OPSQlite refreshSchema. --- packages/common/src/db/DBAdapter.ts | 3 +++ packages/powersync-op-sqlite/src/db/OPSqliteAdapter.ts | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/common/src/db/DBAdapter.ts b/packages/common/src/db/DBAdapter.ts index b35652a0f..56085284e 100644 --- a/packages/common/src/db/DBAdapter.ts +++ b/packages/common/src/db/DBAdapter.ts @@ -101,6 +101,9 @@ export interface DBAdapter extends BaseObserverInterface, DBG readTransaction: (fn: (tx: Transaction) => Promise, options?: DBLockOptions) => Promise; writeLock: (fn: (tx: LockContext) => Promise, options?: DBLockOptions) => Promise; writeTransaction: (fn: (tx: Transaction) => Promise, options?: DBLockOptions) => Promise; + /** + * This method refreshes the schema information across all connections. This is for advanced use cases, and should generally not be needed. + */ refreshSchema: () => Promise; } diff --git a/packages/powersync-op-sqlite/src/db/OPSqliteAdapter.ts b/packages/powersync-op-sqlite/src/db/OPSqliteAdapter.ts index 8815f8e5d..37a962ef1 100644 --- a/packages/powersync-op-sqlite/src/db/OPSqliteAdapter.ts +++ b/packages/powersync-op-sqlite/src/db/OPSqliteAdapter.ts @@ -273,7 +273,8 @@ export class OPSQLiteDBAdapter extends BaseObserver implement } async refreshSchema(): Promise { - await this.writeConnection?.refreshSchema(); + await this.initialized; + await this.writeConnection!.refreshSchema(); for (let readConnection of this.readConnections) { await readConnection.connection.refreshSchema();