s3db.js 7.3.6 → 7.3.9

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/s3db.es.js CHANGED
@@ -8992,11 +8992,21 @@ class BigqueryReplicator extends base_replicator_class_default {
8992
8992
  }));
8993
8993
  }
8994
8994
  applyTransform(data, transformFn) {
8995
- if (!transformFn) return data;
8996
- let transformedData = JSON.parse(JSON.stringify(data));
8997
- if (transformedData._length) delete transformedData._length;
8995
+ let cleanData = this._cleanInternalFields(data);
8996
+ if (!transformFn) return cleanData;
8997
+ let transformedData = JSON.parse(JSON.stringify(cleanData));
8998
8998
  return transformFn(transformedData);
8999
8999
  }
9000
+ _cleanInternalFields(data) {
9001
+ if (!data || typeof data !== "object") return data;
9002
+ const cleanData = { ...data };
9003
+ Object.keys(cleanData).forEach((key) => {
9004
+ if (key.startsWith("$") || key.startsWith("_")) {
9005
+ delete cleanData[key];
9006
+ }
9007
+ });
9008
+ return cleanData;
9009
+ }
9000
9010
  async replicate(resourceName, operation, data, id, beforeData = null) {
9001
9011
  if (!this.enabled || !this.shouldReplicateResource(resourceName)) {
9002
9012
  return { skipped: true, reason: "resource_not_included" };
@@ -9018,7 +9028,17 @@ class BigqueryReplicator extends base_replicator_class_default {
9018
9028
  let job;
9019
9029
  if (operation === "insert") {
9020
9030
  const transformedData = this.applyTransform(data, tableConfig.transform);
9021
- job = await table.insert([transformedData]);
9031
+ try {
9032
+ job = await table.insert([transformedData]);
9033
+ } catch (error) {
9034
+ const { errors: errors2, response } = error;
9035
+ if (this.config.verbose) {
9036
+ console.error("[BigqueryReplicator] BigQuery insert error details:");
9037
+ if (errors2) console.error("Errors:", JSON.stringify(errors2, null, 2));
9038
+ if (response) console.error("Response:", JSON.stringify(response, null, 2));
9039
+ }
9040
+ throw error;
9041
+ }
9022
9042
  } else if (operation === "update") {
9023
9043
  const transformedData = this.applyTransform(data, tableConfig.transform);
9024
9044
  const keys = Object.keys(transformedData).filter((k) => k !== "id");
@@ -9044,6 +9064,10 @@ class BigqueryReplicator extends base_replicator_class_default {
9044
9064
  lastError = error;
9045
9065
  if (this.config.verbose) {
9046
9066
  console.warn(`[BigqueryReplicator] Update attempt ${attempt} failed: ${error.message}`);
9067
+ if (error.errors) {
9068
+ console.error("[BigqueryReplicator] BigQuery update error details:");
9069
+ console.error("Errors:", JSON.stringify(error.errors, null, 2));
9070
+ }
9047
9071
  }
9048
9072
  if (error?.message?.includes("streaming buffer") && attempt < maxRetries) {
9049
9073
  const delaySeconds = 30;
@@ -9059,13 +9083,23 @@ class BigqueryReplicator extends base_replicator_class_default {
9059
9083
  if (!job) throw lastError;
9060
9084
  } else if (operation === "delete") {
9061
9085
  const query = `DELETE FROM \`${this.projectId}.${this.datasetId}.${tableConfig.table}\` WHERE id = @id`;
9062
- const [deleteJob] = await this.bigqueryClient.createQueryJob({
9063
- query,
9064
- params: { id },
9065
- location: this.location
9066
- });
9067
- await deleteJob.getQueryResults();
9068
- job = [deleteJob];
9086
+ try {
9087
+ const [deleteJob] = await this.bigqueryClient.createQueryJob({
9088
+ query,
9089
+ params: { id },
9090
+ location: this.location
9091
+ });
9092
+ await deleteJob.getQueryResults();
9093
+ job = [deleteJob];
9094
+ } catch (error) {
9095
+ if (this.config.verbose) {
9096
+ console.error("[BigqueryReplicator] BigQuery delete error details:");
9097
+ console.error("Query:", query);
9098
+ if (error.errors) console.error("Errors:", JSON.stringify(error.errors, null, 2));
9099
+ if (error.response) console.error("Response:", JSON.stringify(error.response, null, 2));
9100
+ }
9101
+ throw error;
9102
+ }
9069
9103
  } else {
9070
9104
  throw new Error(`Unsupported operation: ${operation}`);
9071
9105
  }
@@ -9098,6 +9132,9 @@ class BigqueryReplicator extends base_replicator_class_default {
9098
9132
  }
9099
9133
  }
9100
9134
  const success = errors.length === 0;
9135
+ if (errors.length > 0) {
9136
+ console.warn(`[BigqueryReplicator] Replication completed with errors for ${resourceName}:`, errors);
9137
+ }
9101
9138
  this.emit("replicated", {
9102
9139
  replicator: this.name,
9103
9140
  resourceName,
@@ -9148,6 +9185,9 @@ class BigqueryReplicator extends base_replicator_class_default {
9148
9185
  errors.push({ id: record.id, error: err.message });
9149
9186
  }
9150
9187
  }
9188
+ if (errors.length > 0) {
9189
+ console.warn(`[BigqueryReplicator] Batch replication completed with ${errors.length} error(s) for ${resourceName}:`, errors);
9190
+ }
9151
9191
  return {
9152
9192
  success: errors.length === 0,
9153
9193
  results,
@@ -9334,16 +9374,18 @@ class PostgresReplicator extends base_replicator_class_default {
9334
9374
  const [okTable, errTable] = await try_fn_default(async () => {
9335
9375
  let result2;
9336
9376
  if (operation === "insert") {
9337
- const keys = Object.keys(data);
9338
- const values = keys.map((k) => data[k]);
9377
+ const cleanData = this._cleanInternalFields(data);
9378
+ const keys = Object.keys(cleanData);
9379
+ const values = keys.map((k) => cleanData[k]);
9339
9380
  const columns = keys.map((k) => `"${k}"`).join(", ");
9340
9381
  const params = keys.map((_, i) => `$${i + 1}`).join(", ");
9341
9382
  const sql = `INSERT INTO ${table} (${columns}) VALUES (${params}) ON CONFLICT (id) DO NOTHING RETURNING *`;
9342
9383
  result2 = await this.client.query(sql, values);
9343
9384
  } else if (operation === "update") {
9344
- const keys = Object.keys(data).filter((k) => k !== "id");
9385
+ const cleanData = this._cleanInternalFields(data);
9386
+ const keys = Object.keys(cleanData).filter((k) => k !== "id");
9345
9387
  const setClause = keys.map((k, i) => `"${k}"=$${i + 1}`).join(", ");
9346
- const values = keys.map((k) => data[k]);
9388
+ const values = keys.map((k) => cleanData[k]);
9347
9389
  values.push(id);
9348
9390
  const sql = `UPDATE ${table} SET ${setClause} WHERE id=$${keys.length + 1} RETURNING *`;
9349
9391
  result2 = await this.client.query(sql, values);
@@ -9378,6 +9420,9 @@ class PostgresReplicator extends base_replicator_class_default {
9378
9420
  }
9379
9421
  }
9380
9422
  const success = errors.length === 0;
9423
+ if (errors.length > 0) {
9424
+ console.warn(`[PostgresReplicator] Replication completed with errors for ${resourceName}:`, errors);
9425
+ }
9381
9426
  this.emit("replicated", {
9382
9427
  replicator: this.name,
9383
9428
  resourceName,
@@ -9428,6 +9473,9 @@ class PostgresReplicator extends base_replicator_class_default {
9428
9473
  errors.push({ id: record.id, error: err.message });
9429
9474
  }
9430
9475
  }
9476
+ if (errors.length > 0) {
9477
+ console.warn(`[PostgresReplicator] Batch replication completed with ${errors.length} error(s) for ${resourceName}:`, errors);
9478
+ }
9431
9479
  return {
9432
9480
  success: errors.length === 0,
9433
9481
  results,
@@ -9447,6 +9495,16 @@ class PostgresReplicator extends base_replicator_class_default {
9447
9495
  this.emit("connection_error", { replicator: this.name, error: err.message });
9448
9496
  return false;
9449
9497
  }
9498
+ _cleanInternalFields(data) {
9499
+ if (!data || typeof data !== "object") return data;
9500
+ const cleanData = { ...data };
9501
+ Object.keys(cleanData).forEach((key) => {
9502
+ if (key.startsWith("$") || key.startsWith("_")) {
9503
+ delete cleanData[key];
9504
+ }
9505
+ });
9506
+ return cleanData;
9507
+ }
9450
9508
  async cleanup() {
9451
9509
  if (this.client) await this.client.end();
9452
9510
  }
@@ -13178,7 +13236,7 @@ class Database extends EventEmitter {
13178
13236
  super();
13179
13237
  this.version = "1";
13180
13238
  this.s3dbVersion = (() => {
13181
- const [ok, err, version] = try_fn_default(() => true ? "7.3.6" : "latest");
13239
+ const [ok, err, version] = try_fn_default(() => true ? "7.3.8" : "latest");
13182
13240
  return ok ? version : "latest";
13183
13241
  })();
13184
13242
  this.resources = {};
@@ -13842,36 +13900,47 @@ class S3dbReplicator extends base_replicator_class_default {
13842
13900
  return result;
13843
13901
  }
13844
13902
  _applyTransformer(resource, data) {
13903
+ let cleanData = this._cleanInternalFields(data);
13845
13904
  const normResource = normalizeResourceName$1(resource);
13846
13905
  const entry = this.resourcesMap[normResource];
13847
13906
  let result;
13848
- if (!entry) return data;
13907
+ if (!entry) return cleanData;
13849
13908
  if (Array.isArray(entry)) {
13850
13909
  for (const item of entry) {
13851
13910
  if (typeof item === "object" && item.transform && typeof item.transform === "function") {
13852
- result = item.transform(data);
13911
+ result = item.transform(cleanData);
13853
13912
  break;
13854
13913
  } else if (typeof item === "object" && item.transformer && typeof item.transformer === "function") {
13855
- result = item.transformer(data);
13914
+ result = item.transformer(cleanData);
13856
13915
  break;
13857
13916
  }
13858
13917
  }
13859
- if (!result) result = data;
13918
+ if (!result) result = cleanData;
13860
13919
  } else if (typeof entry === "object") {
13861
13920
  if (typeof entry.transform === "function") {
13862
- result = entry.transform(data);
13921
+ result = entry.transform(cleanData);
13863
13922
  } else if (typeof entry.transformer === "function") {
13864
- result = entry.transformer(data);
13923
+ result = entry.transformer(cleanData);
13865
13924
  }
13866
13925
  } else if (typeof entry === "function") {
13867
- result = entry(data);
13926
+ result = entry(cleanData);
13868
13927
  } else {
13869
- result = data;
13928
+ result = cleanData;
13870
13929
  }
13871
- if (result && data && data.id && !result.id) result.id = data.id;
13872
- if (!result && data) result = data;
13930
+ if (result && cleanData && cleanData.id && !result.id) result.id = cleanData.id;
13931
+ if (!result && cleanData) result = cleanData;
13873
13932
  return result;
13874
13933
  }
13934
+ _cleanInternalFields(data) {
13935
+ if (!data || typeof data !== "object") return data;
13936
+ const cleanData = { ...data };
13937
+ Object.keys(cleanData).forEach((key) => {
13938
+ if (key.startsWith("$") || key.startsWith("_")) {
13939
+ delete cleanData[key];
13940
+ }
13941
+ });
13942
+ return cleanData;
13943
+ }
13875
13944
  _resolveDestResource(resource, data) {
13876
13945
  const normResource = normalizeResourceName$1(resource);
13877
13946
  const entry = this.resourcesMap[normResource];
@@ -13920,6 +13989,9 @@ class S3dbReplicator extends base_replicator_class_default {
13920
13989
  errors.push({ id: record.id, error: err.message });
13921
13990
  }
13922
13991
  }
13992
+ if (errors.length > 0) {
13993
+ console.warn(`[S3dbReplicator] Batch replication completed with ${errors.length} error(s) for ${resourceName}:`, errors);
13994
+ }
13923
13995
  this.emit("batch_replicated", {
13924
13996
  replicator: this.name,
13925
13997
  resourceName,
@@ -14058,15 +14130,26 @@ class SqsReplicator extends base_replicator_class_default {
14058
14130
  throw new Error(`No queue URL found for resource '${resource}'`);
14059
14131
  }
14060
14132
  _applyTransformer(resource, data) {
14133
+ let cleanData = this._cleanInternalFields(data);
14061
14134
  const entry = this.resources[resource];
14062
- let result = data;
14063
- if (!entry) return data;
14135
+ let result = cleanData;
14136
+ if (!entry) return cleanData;
14064
14137
  if (typeof entry.transform === "function") {
14065
- result = entry.transform(data);
14138
+ result = entry.transform(cleanData);
14066
14139
  } else if (typeof entry.transformer === "function") {
14067
- result = entry.transformer(data);
14140
+ result = entry.transformer(cleanData);
14068
14141
  }
14069
- return result || data;
14142
+ return result || cleanData;
14143
+ }
14144
+ _cleanInternalFields(data) {
14145
+ if (!data || typeof data !== "object") return data;
14146
+ const cleanData = { ...data };
14147
+ Object.keys(cleanData).forEach((key) => {
14148
+ if (key.startsWith("$") || key.startsWith("_")) {
14149
+ delete cleanData[key];
14150
+ }
14151
+ });
14152
+ return cleanData;
14070
14153
  }
14071
14154
  /**
14072
14155
  * Create standardized message structure
@@ -14217,6 +14300,9 @@ class SqsReplicator extends base_replicator_class_default {
14217
14300
  }
14218
14301
  }
14219
14302
  }
14303
+ if (errors.length > 0) {
14304
+ console.warn(`[SqsReplicator] Batch replication completed with ${errors.length} error(s) for ${resource}:`, errors);
14305
+ }
14220
14306
  this.emit("batch_replicated", {
14221
14307
  replicator: this.name,
14222
14308
  resource,