@powersync/common 0.0.0-dev-20260226160529 → 0.0.0-dev-20260305092446

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/dist/bundle.cjs +48 -53
  2. package/dist/bundle.cjs.map +1 -1
  3. package/dist/bundle.mjs +49 -53
  4. package/dist/bundle.mjs.map +1 -1
  5. package/dist/bundle.node.cjs +48 -53
  6. package/dist/bundle.node.cjs.map +1 -1
  7. package/dist/bundle.node.mjs +49 -53
  8. package/dist/bundle.node.mjs.map +1 -1
  9. package/dist/index.d.cts +130 -80
  10. package/lib/client/AbstractPowerSyncDatabase.js +1 -5
  11. package/lib/client/AbstractPowerSyncDatabase.js.map +1 -1
  12. package/lib/client/triggers/TriggerManager.d.ts +5 -0
  13. package/lib/client/triggers/TriggerManagerImpl.d.ts +1 -1
  14. package/lib/client/triggers/TriggerManagerImpl.js +6 -4
  15. package/lib/client/triggers/TriggerManagerImpl.js.map +1 -1
  16. package/lib/db/schema/RawTable.d.ts +61 -26
  17. package/lib/db/schema/RawTable.js +1 -32
  18. package/lib/db/schema/RawTable.js.map +1 -1
  19. package/lib/db/schema/Schema.d.ts +14 -7
  20. package/lib/db/schema/Schema.js +25 -3
  21. package/lib/db/schema/Schema.js.map +1 -1
  22. package/lib/db/schema/Table.d.ts +13 -8
  23. package/lib/db/schema/Table.js +3 -8
  24. package/lib/db/schema/Table.js.map +1 -1
  25. package/lib/db/schema/internal.d.ts +12 -0
  26. package/lib/db/schema/internal.js +15 -0
  27. package/lib/db/schema/internal.js.map +1 -0
  28. package/lib/index.d.ts +1 -1
  29. package/lib/index.js +0 -1
  30. package/lib/index.js.map +1 -1
  31. package/package.json +1 -1
  32. package/src/client/AbstractPowerSyncDatabase.ts +1 -6
  33. package/src/client/triggers/TriggerManager.ts +6 -0
  34. package/src/client/triggers/TriggerManagerImpl.ts +6 -3
  35. package/src/db/schema/RawTable.ts +66 -31
  36. package/src/db/schema/Schema.ts +27 -2
  37. package/src/db/schema/Table.ts +11 -11
  38. package/src/db/schema/internal.ts +17 -0
  39. package/src/index.ts +1 -1
@@ -105,6 +105,21 @@ class Index {
105
105
  }
106
106
  }
107
107
 
108
+ /**
109
+ * @internal Not exported from `index.ts`.
110
+ */
111
+ function encodeTableOptions(options) {
112
+ const trackPrevious = options.trackPrevious;
113
+ return {
114
+ local_only: options.localOnly,
115
+ insert_only: options.insertOnly,
116
+ include_old: trackPrevious && (trackPrevious.columns ?? true),
117
+ include_old_only_when_changed: typeof trackPrevious == 'object' && trackPrevious.onlyWhenChanged == true,
118
+ include_metadata: options.trackMetadata,
119
+ ignore_empty_update: options.ignoreEmptyUpdates
120
+ };
121
+ }
122
+
108
123
  const DEFAULT_TABLE_OPTIONS = {
109
124
  indexes: [],
110
125
  insertOnly: false,
@@ -294,18 +309,12 @@ class Table {
294
309
  }
295
310
  }
296
311
  toJSON() {
297
- const trackPrevious = this.trackPrevious;
298
312
  return {
299
313
  name: this.name,
300
314
  view_name: this.viewName,
301
- local_only: this.localOnly,
302
- insert_only: this.insertOnly,
303
- include_old: trackPrevious && (trackPrevious.columns ?? true),
304
- include_old_only_when_changed: typeof trackPrevious == 'object' && trackPrevious.onlyWhenChanged == true,
305
- include_metadata: this.trackMetadata,
306
- ignore_empty_update: this.ignoreEmptyUpdates,
307
315
  columns: this.columns.map((c) => c.toJSON()),
308
- indexes: this.indexes.map((e) => e.toJSON(this))
316
+ indexes: this.indexes.map((e) => e.toJSON(this)),
317
+ ...encodeTableOptions(this)
309
318
  };
310
319
  }
311
320
  }
@@ -9959,7 +9968,7 @@ class TriggerManagerImpl {
9959
9968
  }
9960
9969
  async createDiffTrigger(options) {
9961
9970
  await this.db.waitForReady();
9962
- const { source, destination, columns, when, hooks,
9971
+ const { source, destination, columns, when, hooks, persistDestination = false,
9963
9972
  // Fall back to the provided default if not given on this level
9964
9973
  useStorage = this.defaultConfig.useStorageByDefault } = options;
9965
9974
  const operations = Object.keys(when);
@@ -10014,11 +10023,13 @@ class TriggerManagerImpl {
10014
10023
  * we need to ensure we can cleanup the created resources.
10015
10024
  * We unfortunately cannot rely on transaction rollback.
10016
10025
  */
10017
- const cleanup = async () => {
10026
+ const cleanup = async (force) => {
10018
10027
  disposeWarningListener();
10019
10028
  return this.db.writeLock(async (tx) => {
10020
10029
  await this.removeTriggers(tx, triggerIds);
10021
- await tx.execute(/* sql */ `DROP TABLE IF EXISTS ${destination};`);
10030
+ if (!persistDestination || force) {
10031
+ await tx.execute(/* sql */ `DROP TABLE IF EXISTS ${destination};`);
10032
+ }
10022
10033
  await releaseStorageClaim?.();
10023
10034
  });
10024
10035
  };
@@ -10026,7 +10037,7 @@ class TriggerManagerImpl {
10026
10037
  // Allow user code to execute in this lock context before the trigger is created.
10027
10038
  await hooks?.beforeCreate?.(tx);
10028
10039
  await tx.execute(/* sql */ `
10029
- CREATE ${tableTriggerTypeClause} TABLE ${destination} (
10040
+ CREATE ${tableTriggerTypeClause} TABLE ${persistDestination ? 'IF NOT EXISTS ' : ''}${destination} (
10030
10041
  operation_id INTEGER PRIMARY KEY AUTOINCREMENT,
10031
10042
  id TEXT,
10032
10043
  operation TEXT,
@@ -10502,11 +10513,7 @@ class AbstractPowerSyncDatabase extends BaseObserver {
10502
10513
  this.logger.warn('Schema validation failed. Unexpected behaviour could occur', ex);
10503
10514
  }
10504
10515
  this._schema = schema;
10505
- // powersync_replace_schema starts a transaction internally, but we can be more efficient by using BEGIN EXCLUSIVE
10506
- // on some DB adapters.
10507
- this.database.writeTransaction((tx) => {
10508
- return tx.execute('SELECT powersync_replace_schema(?)', [JSON.stringify(this.schema.toJSON())]);
10509
- });
10516
+ await this.database.execute('SELECT powersync_replace_schema(?)', [JSON.stringify(this.schema.toJSON())]);
10510
10517
  await this.database.refreshSchema();
10511
10518
  this.iterateListeners(async (cb) => cb.schemaChanged?.(schema));
10512
10519
  }
@@ -11611,39 +11618,6 @@ class ConnectionClosedError extends Error {
11611
11618
  }
11612
11619
  }
11613
11620
 
11614
- /**
11615
- * Instructs PowerSync to sync data into a "raw" table.
11616
- *
11617
- * Since raw tables are not backed by JSON, running complex queries on them may be more efficient. Further, they allow
11618
- * using client-side table and column constraints.
11619
- *
11620
- * To collect local writes to raw tables with PowerSync, custom triggers are required. See
11621
- * {@link https://docs.powersync.com/usage/use-case-examples/raw-tables the documentation} for details and an example on
11622
- * using raw tables.
11623
- *
11624
- * Note that raw tables are only supported when using the new `SyncClientImplementation.rust` sync client.
11625
- *
11626
- * @experimental Please note that this feature is experimental at the moment, and not covered by PowerSync semver or
11627
- * stability guarantees.
11628
- */
11629
- class RawTable {
11630
- /**
11631
- * The name of the table.
11632
- *
11633
- * This does not have to match the actual table name in the schema - {@link put} and {@link delete} are free to use
11634
- * another table. Instead, this name is used by the sync client to recognize that operations on this table (as it
11635
- * appears in the source / backend database) are to be handled specially.
11636
- */
11637
- name;
11638
- put;
11639
- delete;
11640
- constructor(name, type) {
11641
- this.name = name;
11642
- this.put = type.put;
11643
- this.delete = type.delete;
11644
- }
11645
- }
11646
-
11647
11621
  /**
11648
11622
  * A schema is a collection of tables. It is used to define the structure of a database.
11649
11623
  */
@@ -11688,7 +11662,7 @@ class Schema {
11688
11662
  */
11689
11663
  withRawTables(tables) {
11690
11664
  for (const [name, rawTableDefinition] of Object.entries(tables)) {
11691
- this.rawTables.push(new RawTable(name, rawTableDefinition));
11665
+ this.rawTables.push({ name, ...rawTableDefinition });
11692
11666
  }
11693
11667
  }
11694
11668
  validate() {
@@ -11699,8 +11673,30 @@ class Schema {
11699
11673
  toJSON() {
11700
11674
  return {
11701
11675
  tables: this.tables.map((t) => t.toJSON()),
11702
- raw_tables: this.rawTables
11676
+ raw_tables: this.rawTables.map(Schema.rawTableToJson)
11677
+ };
11678
+ }
11679
+ /**
11680
+ * Returns a representation of the raw table that is understood by the PowerSync SQLite core extension.
11681
+ *
11682
+ * The output of this can be passed through `JSON.serialize` and then used in `powersync_create_raw_table_crud_trigger`
11683
+ * to define triggers for this table.
11684
+ */
11685
+ static rawTableToJson(table) {
11686
+ const serialized = {
11687
+ name: table.name,
11688
+ put: table.put,
11689
+ delete: table.delete,
11690
+ clear: table.clear
11703
11691
  };
11692
+ if ('schema' in table) {
11693
+ // We have schema options, those are flattened into the outer JSON object for the core extension.
11694
+ const schema = table.schema;
11695
+ serialized.table_name = schema.tableName ?? table.name;
11696
+ serialized.synced_columns = schema.syncedColumns;
11697
+ Object.assign(serialized, encodeTableOptions(table.schema));
11698
+ }
11699
+ return serialized;
11704
11700
  }
11705
11701
  }
11706
11702
 
@@ -11913,7 +11909,6 @@ exports.MEMORY_TRIGGER_CLAIM_MANAGER = MEMORY_TRIGGER_CLAIM_MANAGER;
11913
11909
  exports.OnChangeQueryProcessor = OnChangeQueryProcessor;
11914
11910
  exports.OpType = OpType;
11915
11911
  exports.OplogEntry = OplogEntry;
11916
- exports.RawTable = RawTable;
11917
11912
  exports.Schema = Schema;
11918
11913
  exports.SqliteBucketStorage = SqliteBucketStorage;
11919
11914
  exports.SyncDataBatch = SyncDataBatch;