@objectstack/objectql 3.3.0 → 3.3.1

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.
package/dist/index.mjs CHANGED
@@ -2730,9 +2730,13 @@ var ObjectQLPlugin = class {
2730
2730
  /**
2731
2731
  * Synchronize all registered object schemas to the database.
2732
2732
  *
2733
- * Iterates every object in the SchemaRegistry and calls the
2734
- * responsible driver's `syncSchema()` for each one. This is
2735
- * idempotent drivers must tolerate repeated calls without
2733
+ * Groups objects by their responsible driver, then:
2734
+ * - If the driver advertises `supports.batchSchemaSync` and implements
2735
+ * `syncSchemasBatch()`, submits all schemas in a single call (reducing
2736
+ * network round-trips for remote drivers like Turso).
2737
+ * - Otherwise falls back to sequential `syncSchema()` per object.
2738
+ *
2739
+ * This is idempotent — drivers must tolerate repeated calls without
2736
2740
  * duplicating tables or erroring out.
2737
2741
  *
2738
2742
  * Drivers that do not implement `syncSchema` are silently skipped.
@@ -2743,6 +2747,7 @@ var ObjectQLPlugin = class {
2743
2747
  if (allObjects.length === 0) return;
2744
2748
  let synced = 0;
2745
2749
  let skipped = 0;
2750
+ const driverGroups = /* @__PURE__ */ new Map();
2746
2751
  for (const obj of allObjects) {
2747
2752
  const driver = this.ql.getDriverForObject(obj.name);
2748
2753
  if (!driver) {
@@ -2761,16 +2766,59 @@ var ObjectQLPlugin = class {
2761
2766
  continue;
2762
2767
  }
2763
2768
  const tableName = obj.tableName || obj.name;
2764
- try {
2765
- await driver.syncSchema(tableName, obj);
2766
- synced++;
2767
- } catch (e) {
2768
- ctx.logger.warn("Failed to sync schema for object", {
2769
- object: obj.name,
2770
- tableName,
2771
- driver: driver.name,
2772
- error: e instanceof Error ? e.message : String(e)
2773
- });
2769
+ let group = driverGroups.get(driver);
2770
+ if (!group) {
2771
+ group = [];
2772
+ driverGroups.set(driver, group);
2773
+ }
2774
+ group.push({ obj, tableName });
2775
+ }
2776
+ for (const [driver, entries] of driverGroups) {
2777
+ if (driver.supports?.batchSchemaSync && typeof driver.syncSchemasBatch === "function") {
2778
+ const batchPayload = entries.map((e) => ({
2779
+ object: e.tableName,
2780
+ schema: e.obj
2781
+ }));
2782
+ try {
2783
+ await driver.syncSchemasBatch(batchPayload);
2784
+ synced += entries.length;
2785
+ ctx.logger.debug("Batch schema sync succeeded", {
2786
+ driver: driver.name,
2787
+ count: entries.length
2788
+ });
2789
+ } catch (e) {
2790
+ ctx.logger.warn("Batch schema sync failed, falling back to sequential", {
2791
+ driver: driver.name,
2792
+ error: e instanceof Error ? e.message : String(e)
2793
+ });
2794
+ for (const { obj, tableName } of entries) {
2795
+ try {
2796
+ await driver.syncSchema(tableName, obj);
2797
+ synced++;
2798
+ } catch (seqErr) {
2799
+ ctx.logger.warn("Failed to sync schema for object", {
2800
+ object: obj.name,
2801
+ tableName,
2802
+ driver: driver.name,
2803
+ error: seqErr instanceof Error ? seqErr.message : String(seqErr)
2804
+ });
2805
+ }
2806
+ }
2807
+ }
2808
+ } else {
2809
+ for (const { obj, tableName } of entries) {
2810
+ try {
2811
+ await driver.syncSchema(tableName, obj);
2812
+ synced++;
2813
+ } catch (e) {
2814
+ ctx.logger.warn("Failed to sync schema for object", {
2815
+ object: obj.name,
2816
+ tableName,
2817
+ driver: driver.name,
2818
+ error: e instanceof Error ? e.message : String(e)
2819
+ });
2820
+ }
2821
+ }
2774
2822
  }
2775
2823
  }
2776
2824
  if (synced > 0 || skipped > 0) {