s3db.js 7.3.4 → 7.3.6

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.cjs.js CHANGED
@@ -7,8 +7,8 @@ var zlib = require('node:zlib');
7
7
  var promisePool = require('@supercharge/promise-pool');
8
8
  var web = require('node:stream/web');
9
9
  var promises = require('fs/promises');
10
- var lodashEs = require('lodash-es');
11
10
  var crypto = require('crypto');
11
+ var lodashEs = require('lodash-es');
12
12
  var jsonStableStringify = require('json-stable-stringify');
13
13
  var clientS3 = require('@aws-sdk/client-s3');
14
14
  var flat = require('flat');
@@ -7083,6 +7083,12 @@ class FilesystemCache extends Cache {
7083
7083
  }
7084
7084
  async _clear(prefix) {
7085
7085
  try {
7086
+ if (!await this._fileExists(this.directory)) {
7087
+ if (this.enableStats) {
7088
+ this.stats.clears++;
7089
+ }
7090
+ return true;
7091
+ }
7086
7092
  const files = await promises.readdir(this.directory);
7087
7093
  const cacheFiles = files.filter((file) => {
7088
7094
  if (!file.startsWith(this.prefix)) return false;
@@ -8353,7 +8359,7 @@ class MetricsPlugin extends plugin_class_default {
8353
8359
  }
8354
8360
  async setup(database) {
8355
8361
  this.database = database;
8356
- if (process.env.NODE_ENV === "test") return;
8362
+ if (typeof process !== "undefined" && process.env.NODE_ENV === "test") return;
8357
8363
  const [ok, err] = await try_fn_default(async () => {
8358
8364
  const [ok1, err1, metricsResource] = await try_fn_default(() => database.createResource({
8359
8365
  name: "metrics",
@@ -8403,7 +8409,7 @@ class MetricsPlugin extends plugin_class_default {
8403
8409
  this.performanceResource = database.resources.performance_logs;
8404
8410
  }
8405
8411
  this.installMetricsHooks();
8406
- if (process.env.NODE_ENV !== "test") {
8412
+ if (typeof process !== "undefined" && process.env.NODE_ENV !== "test") {
8407
8413
  this.startFlushTimer();
8408
8414
  }
8409
8415
  }
@@ -8414,7 +8420,7 @@ class MetricsPlugin extends plugin_class_default {
8414
8420
  clearInterval(this.flushTimer);
8415
8421
  this.flushTimer = null;
8416
8422
  }
8417
- if (process.env.NODE_ENV !== "test") {
8423
+ if (typeof process !== "undefined" && process.env.NODE_ENV !== "test") {
8418
8424
  await this.flushMetrics();
8419
8425
  }
8420
8426
  }
@@ -8593,10 +8599,18 @@ class MetricsPlugin extends plugin_class_default {
8593
8599
  async flushMetrics() {
8594
8600
  if (!this.metricsResource) return;
8595
8601
  const [ok, err] = await try_fn_default(async () => {
8596
- const metadata = process.env.NODE_ENV === "test" ? {} : { global: "true" };
8597
- const perfMetadata = process.env.NODE_ENV === "test" ? {} : { perf: "true" };
8598
- const errorMetadata = process.env.NODE_ENV === "test" ? {} : { error: "true" };
8599
- const resourceMetadata = process.env.NODE_ENV === "test" ? {} : { resource: "true" };
8602
+ let metadata, perfMetadata, errorMetadata, resourceMetadata;
8603
+ if (typeof process !== "undefined" && process.env.NODE_ENV === "test") {
8604
+ metadata = {};
8605
+ perfMetadata = {};
8606
+ errorMetadata = {};
8607
+ resourceMetadata = {};
8608
+ } else {
8609
+ metadata = { global: "true" };
8610
+ perfMetadata = { perf: "true" };
8611
+ errorMetadata = { error: "true" };
8612
+ resourceMetadata = { resource: "true" };
8613
+ }
8600
8614
  for (const [operation, data] of Object.entries(this.metrics.operations)) {
8601
8615
  if (data.count > 0) {
8602
8616
  await this.metricsResource.insert({
@@ -8946,6 +8960,9 @@ class BigqueryReplicator extends base_replicator_class_default {
8946
8960
  await super.initialize(database);
8947
8961
  const [ok, err, sdk] = await try_fn_default(() => import('@google-cloud/bigquery'));
8948
8962
  if (!ok) {
8963
+ if (this.config.verbose) {
8964
+ console.warn(`[BigqueryReplicator] Failed to import BigQuery SDK: ${err.message}`);
8965
+ }
8949
8966
  this.emit("initialization_error", { replicator: this.name, error: err.message });
8950
8967
  throw err;
8951
8968
  }
@@ -9015,19 +9032,28 @@ class BigqueryReplicator extends base_replicator_class_default {
9015
9032
  const maxRetries = 2;
9016
9033
  let lastError = null;
9017
9034
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
9018
- try {
9035
+ const [ok2, error] = await try_fn_default(async () => {
9019
9036
  const [updateJob] = await this.bigqueryClient.createQueryJob({
9020
9037
  query,
9021
9038
  params,
9022
9039
  location: this.location
9023
9040
  });
9024
9041
  await updateJob.getQueryResults();
9025
- job = [updateJob];
9042
+ return [updateJob];
9043
+ });
9044
+ if (ok2) {
9045
+ job = ok2;
9026
9046
  break;
9027
- } catch (error) {
9047
+ } else {
9028
9048
  lastError = error;
9049
+ if (this.config.verbose) {
9050
+ console.warn(`[BigqueryReplicator] Update attempt ${attempt} failed: ${error.message}`);
9051
+ }
9029
9052
  if (error?.message?.includes("streaming buffer") && attempt < maxRetries) {
9030
9053
  const delaySeconds = 30;
9054
+ if (this.config.verbose) {
9055
+ console.warn(`[BigqueryReplicator] Retrying in ${delaySeconds} seconds due to streaming buffer issue`);
9056
+ }
9031
9057
  await new Promise((resolve) => setTimeout(resolve, delaySeconds * 1e3));
9032
9058
  continue;
9033
9059
  }
@@ -9094,6 +9120,9 @@ class BigqueryReplicator extends base_replicator_class_default {
9094
9120
  };
9095
9121
  });
9096
9122
  if (ok) return result;
9123
+ if (this.config.verbose) {
9124
+ console.warn(`[BigqueryReplicator] Replication failed for ${resourceName}: ${err.message}`);
9125
+ }
9097
9126
  this.emit("replicator_error", {
9098
9127
  replicator: this.name,
9099
9128
  resourceName,
@@ -9114,8 +9143,14 @@ class BigqueryReplicator extends base_replicator_class_default {
9114
9143
  record.id,
9115
9144
  record.beforeData
9116
9145
  ));
9117
- if (ok) results.push(res);
9118
- else errors.push({ id: record.id, error: err.message });
9146
+ if (ok) {
9147
+ results.push(res);
9148
+ } else {
9149
+ if (this.config.verbose) {
9150
+ console.warn(`[BigqueryReplicator] Batch replication failed for record ${record.id}: ${err.message}`);
9151
+ }
9152
+ errors.push({ id: record.id, error: err.message });
9153
+ }
9119
9154
  }
9120
9155
  return {
9121
9156
  success: errors.length === 0,
@@ -9131,6 +9166,9 @@ class BigqueryReplicator extends base_replicator_class_default {
9131
9166
  return true;
9132
9167
  });
9133
9168
  if (ok) return true;
9169
+ if (this.config.verbose) {
9170
+ console.warn(`[BigqueryReplicator] Connection test failed: ${err.message}`);
9171
+ }
9134
9172
  this.emit("connection_error", { replicator: this.name, error: err.message });
9135
9173
  return false;
9136
9174
  }
@@ -9218,6 +9256,9 @@ class PostgresReplicator extends base_replicator_class_default {
9218
9256
  await super.initialize(database);
9219
9257
  const [ok, err, sdk] = await try_fn_default(() => import('pg'));
9220
9258
  if (!ok) {
9259
+ if (this.config.verbose) {
9260
+ console.warn(`[PostgresReplicator] Failed to import pg SDK: ${err.message}`);
9261
+ }
9221
9262
  this.emit("initialization_error", {
9222
9263
  replicator: this.name,
9223
9264
  error: err.message
@@ -9359,6 +9400,9 @@ class PostgresReplicator extends base_replicator_class_default {
9359
9400
  };
9360
9401
  });
9361
9402
  if (ok) return result;
9403
+ if (this.config.verbose) {
9404
+ console.warn(`[PostgresReplicator] Replication failed for ${resourceName}: ${err.message}`);
9405
+ }
9362
9406
  this.emit("replicator_error", {
9363
9407
  replicator: this.name,
9364
9408
  resourceName,
@@ -9379,8 +9423,14 @@ class PostgresReplicator extends base_replicator_class_default {
9379
9423
  record.id,
9380
9424
  record.beforeData
9381
9425
  ));
9382
- if (ok) results.push(res);
9383
- else errors.push({ id: record.id, error: err.message });
9426
+ if (ok) {
9427
+ results.push(res);
9428
+ } else {
9429
+ if (this.config.verbose) {
9430
+ console.warn(`[PostgresReplicator] Batch replication failed for record ${record.id}: ${err.message}`);
9431
+ }
9432
+ errors.push({ id: record.id, error: err.message });
9433
+ }
9384
9434
  }
9385
9435
  return {
9386
9436
  success: errors.length === 0,
@@ -9395,6 +9445,9 @@ class PostgresReplicator extends base_replicator_class_default {
9395
9445
  return true;
9396
9446
  });
9397
9447
  if (ok) return true;
9448
+ if (this.config.verbose) {
9449
+ console.warn(`[PostgresReplicator] Connection test failed: ${err.message}`);
9450
+ }
9398
9451
  this.emit("connection_error", { replicator: this.name, error: err.message });
9399
9452
  return false;
9400
9453
  }
@@ -13129,7 +13182,7 @@ class Database extends EventEmitter {
13129
13182
  super();
13130
13183
  this.version = "1";
13131
13184
  this.s3dbVersion = (() => {
13132
- const [ok, err, version] = try_fn_default(() => true ? "7.3.4" : "latest");
13185
+ const [ok, err, version] = try_fn_default(() => true ? "7.3.6" : "latest");
13133
13186
  return ok ? version : "latest";
13134
13187
  })();
13135
13188
  this.resources = {};
@@ -13172,14 +13225,16 @@ class Database extends EventEmitter {
13172
13225
  this.keyPrefix = this.client.keyPrefix;
13173
13226
  if (!this._exitListenerRegistered) {
13174
13227
  this._exitListenerRegistered = true;
13175
- process.on("exit", async () => {
13176
- if (this.isConnected()) {
13177
- try {
13178
- await this.disconnect();
13179
- } catch (err) {
13228
+ if (typeof process !== "undefined") {
13229
+ process.on("exit", async () => {
13230
+ if (this.isConnected()) {
13231
+ try {
13232
+ await this.disconnect();
13233
+ } catch (err) {
13234
+ }
13180
13235
  }
13181
- }
13182
- });
13236
+ });
13237
+ }
13183
13238
  }
13184
13239
  }
13185
13240
  async connect() {
@@ -13631,9 +13686,8 @@ class S3dbReplicator extends base_replicator_class_default {
13631
13686
  const map = {};
13632
13687
  for (const res of resources) {
13633
13688
  if (typeof res === "string") map[normalizeResourceName$1(res)] = res;
13634
- else if (Array.isArray(res) && typeof res[0] === "string") map[normalizeResourceName$1(res[0])] = res;
13635
13689
  else if (typeof res === "object" && res.resource) {
13636
- map[normalizeResourceName$1(res.resource)] = { ...res };
13690
+ map[normalizeResourceName$1(res.resource)] = res;
13637
13691
  }
13638
13692
  }
13639
13693
  return map;
@@ -13646,15 +13700,14 @@ class S3dbReplicator extends base_replicator_class_default {
13646
13700
  else if (Array.isArray(dest)) {
13647
13701
  map[normSrc] = dest.map((item) => {
13648
13702
  if (typeof item === "string") return item;
13649
- if (typeof item === "function") return item;
13650
13703
  if (typeof item === "object" && item.resource) {
13651
- return { ...item };
13704
+ return item;
13652
13705
  }
13653
13706
  return item;
13654
13707
  });
13655
13708
  } else if (typeof dest === "function") map[normSrc] = dest;
13656
13709
  else if (typeof dest === "object" && dest.resource) {
13657
- map[normSrc] = { ...dest };
13710
+ map[normSrc] = dest;
13658
13711
  }
13659
13712
  }
13660
13713
  return map;
@@ -13662,10 +13715,6 @@ class S3dbReplicator extends base_replicator_class_default {
13662
13715
  if (typeof resources === "function") {
13663
13716
  return resources;
13664
13717
  }
13665
- if (typeof resources === "string") {
13666
- const map = { [normalizeResourceName$1(resources)]: resources };
13667
- return map;
13668
- }
13669
13718
  return {};
13670
13719
  }
13671
13720
  validateConfig() {
@@ -13679,8 +13728,8 @@ class S3dbReplicator extends base_replicator_class_default {
13679
13728
  return { isValid: errors.length === 0, errors };
13680
13729
  }
13681
13730
  async initialize(database) {
13682
- try {
13683
- await super.initialize(database);
13731
+ await super.initialize(database);
13732
+ const [ok, err] = await try_fn_default(async () => {
13684
13733
  if (this.client) {
13685
13734
  this.targetDatabase = this.client;
13686
13735
  } else if (this.connectionString) {
@@ -13699,7 +13748,11 @@ class S3dbReplicator extends base_replicator_class_default {
13699
13748
  replicator: this.name,
13700
13749
  target: this.connectionString || "client-provided"
13701
13750
  });
13702
- } catch (err) {
13751
+ });
13752
+ if (!ok) {
13753
+ if (this.config.verbose) {
13754
+ console.warn(`[S3dbReplicator] Initialization failed: ${err.message}`);
13755
+ }
13703
13756
  throw err;
13704
13757
  }
13705
13758
  }
@@ -13718,18 +13771,77 @@ class S3dbReplicator extends base_replicator_class_default {
13718
13771
  id = recordId;
13719
13772
  }
13720
13773
  const normResource = normalizeResourceName$1(resource);
13721
- const destResource = this._resolveDestResource(normResource, payload);
13722
- const destResourceObj = this._getDestResourceObj(destResource);
13723
- const transformedData = this._applyTransformer(normResource, payload);
13774
+ const entry = this.resourcesMap[normResource];
13775
+ if (!entry) {
13776
+ throw new Error(`[S3dbReplicator] Resource not configured: ${resource}`);
13777
+ }
13778
+ if (Array.isArray(entry)) {
13779
+ const results = [];
13780
+ for (const destConfig of entry) {
13781
+ const [ok, error, result] = await try_fn_default(async () => {
13782
+ return await this._replicateToSingleDestination(destConfig, normResource, op, payload, id);
13783
+ });
13784
+ if (!ok) {
13785
+ if (this.config && this.config.verbose) {
13786
+ console.warn(`[S3dbReplicator] Failed to replicate to destination ${JSON.stringify(destConfig)}: ${error.message}`);
13787
+ }
13788
+ throw error;
13789
+ }
13790
+ results.push(result);
13791
+ }
13792
+ return results;
13793
+ } else {
13794
+ const [ok, error, result] = await try_fn_default(async () => {
13795
+ return await this._replicateToSingleDestination(entry, normResource, op, payload, id);
13796
+ });
13797
+ if (!ok) {
13798
+ if (this.config && this.config.verbose) {
13799
+ console.warn(`[S3dbReplicator] Failed to replicate to destination ${JSON.stringify(entry)}: ${error.message}`);
13800
+ }
13801
+ throw error;
13802
+ }
13803
+ return result;
13804
+ }
13805
+ }
13806
+ async _replicateToSingleDestination(destConfig, sourceResource, operation, data, recordId) {
13807
+ let destResourceName;
13808
+ if (typeof destConfig === "string") {
13809
+ destResourceName = destConfig;
13810
+ } else if (typeof destConfig === "object" && destConfig.resource) {
13811
+ destResourceName = destConfig.resource;
13812
+ } else {
13813
+ destResourceName = sourceResource;
13814
+ }
13815
+ if (typeof destConfig === "object" && destConfig.actions && Array.isArray(destConfig.actions)) {
13816
+ if (!destConfig.actions.includes(operation)) {
13817
+ return { skipped: true, reason: "action_not_supported", action: operation, destination: destResourceName };
13818
+ }
13819
+ }
13820
+ const destResourceObj = this._getDestResourceObj(destResourceName);
13821
+ let transformedData;
13822
+ if (typeof destConfig === "object" && destConfig.transform && typeof destConfig.transform === "function") {
13823
+ transformedData = destConfig.transform(data);
13824
+ if (transformedData && data && data.id && !transformedData.id) {
13825
+ transformedData.id = data.id;
13826
+ }
13827
+ } else if (typeof destConfig === "object" && destConfig.transformer && typeof destConfig.transformer === "function") {
13828
+ transformedData = destConfig.transformer(data);
13829
+ if (transformedData && data && data.id && !transformedData.id) {
13830
+ transformedData.id = data.id;
13831
+ }
13832
+ } else {
13833
+ transformedData = data;
13834
+ }
13835
+ if (!transformedData && data) transformedData = data;
13724
13836
  let result;
13725
- if (op === "insert") {
13837
+ if (operation === "insert") {
13726
13838
  result = await destResourceObj.insert(transformedData);
13727
- } else if (op === "update") {
13728
- result = await destResourceObj.update(id, transformedData);
13729
- } else if (op === "delete") {
13730
- result = await destResourceObj.delete(id);
13839
+ } else if (operation === "update") {
13840
+ result = await destResourceObj.update(recordId, transformedData);
13841
+ } else if (operation === "delete") {
13842
+ result = await destResourceObj.delete(recordId);
13731
13843
  } else {
13732
- throw new Error(`Invalid operation: ${op}. Supported operations are: insert, update, delete`);
13844
+ throw new Error(`Invalid operation: ${operation}. Supported operations are: insert, update, delete`);
13733
13845
  }
13734
13846
  return result;
13735
13847
  }
@@ -13738,13 +13850,25 @@ class S3dbReplicator extends base_replicator_class_default {
13738
13850
  const entry = this.resourcesMap[normResource];
13739
13851
  let result;
13740
13852
  if (!entry) return data;
13741
- if (Array.isArray(entry) && typeof entry[1] === "function") {
13742
- result = entry[1](data);
13853
+ if (Array.isArray(entry)) {
13854
+ for (const item of entry) {
13855
+ if (typeof item === "object" && item.transform && typeof item.transform === "function") {
13856
+ result = item.transform(data);
13857
+ break;
13858
+ } else if (typeof item === "object" && item.transformer && typeof item.transformer === "function") {
13859
+ result = item.transformer(data);
13860
+ break;
13861
+ }
13862
+ }
13863
+ if (!result) result = data;
13864
+ } else if (typeof entry === "object") {
13865
+ if (typeof entry.transform === "function") {
13866
+ result = entry.transform(data);
13867
+ } else if (typeof entry.transformer === "function") {
13868
+ result = entry.transformer(data);
13869
+ }
13743
13870
  } else if (typeof entry === "function") {
13744
13871
  result = entry(data);
13745
- } else if (typeof entry === "object") {
13746
- if (typeof entry.transform === "function") result = entry.transform(data);
13747
- else if (typeof entry.transformer === "function") result = entry.transformer(data);
13748
13872
  } else {
13749
13873
  result = data;
13750
13874
  }
@@ -13757,18 +13881,19 @@ class S3dbReplicator extends base_replicator_class_default {
13757
13881
  const entry = this.resourcesMap[normResource];
13758
13882
  if (!entry) return resource;
13759
13883
  if (Array.isArray(entry)) {
13760
- if (typeof entry[0] === "string") return entry[0];
13761
- if (typeof entry[0] === "object" && entry[0].resource) return entry[0].resource;
13762
- if (typeof entry[0] === "function") return resource;
13884
+ for (const item of entry) {
13885
+ if (typeof item === "string") return item;
13886
+ if (typeof item === "object" && item.resource) return item.resource;
13887
+ }
13888
+ return resource;
13763
13889
  }
13764
13890
  if (typeof entry === "string") return entry;
13765
- if (resource && !targetResourceName) targetResourceName = resource;
13891
+ if (typeof entry === "function") return resource;
13766
13892
  if (typeof entry === "object" && entry.resource) return entry.resource;
13767
13893
  return resource;
13768
13894
  }
13769
13895
  _getDestResourceObj(resource) {
13770
- if (!this.client || !this.client.resources) return null;
13771
- const available = Object.keys(this.client.resources);
13896
+ const available = Object.keys(this.client.resources || {});
13772
13897
  const norm = normalizeResourceName$1(resource);
13773
13898
  const found = available.find((r) => normalizeResourceName$1(r) === norm);
13774
13899
  if (!found) {
@@ -13790,8 +13915,14 @@ class S3dbReplicator extends base_replicator_class_default {
13790
13915
  data: record.data,
13791
13916
  beforeData: record.beforeData
13792
13917
  }));
13793
- if (ok) results.push(result);
13794
- else errors.push({ id: record.id, error: err.message });
13918
+ if (ok) {
13919
+ results.push(result);
13920
+ } else {
13921
+ if (this.config.verbose) {
13922
+ console.warn(`[S3dbReplicator] Batch replication failed for record ${record.id}: ${err.message}`);
13923
+ }
13924
+ errors.push({ id: record.id, error: err.message });
13925
+ }
13795
13926
  }
13796
13927
  this.emit("batch_replicated", {
13797
13928
  replicator: this.name,
@@ -13809,18 +13940,20 @@ class S3dbReplicator extends base_replicator_class_default {
13809
13940
  }
13810
13941
  async testConnection() {
13811
13942
  const [ok, err] = await try_fn_default(async () => {
13812
- if (!this.targetDatabase) {
13813
- await this.initialize(this.database);
13943
+ if (!this.targetDatabase) throw new Error("No target database configured");
13944
+ if (typeof this.targetDatabase.connect === "function") {
13945
+ await this.targetDatabase.connect();
13814
13946
  }
13815
- await this.targetDatabase.listResources();
13816
13947
  return true;
13817
13948
  });
13818
- if (ok) return true;
13819
- this.emit("connection_error", {
13820
- replicator: this.name,
13821
- error: err.message
13822
- });
13823
- return false;
13949
+ if (!ok) {
13950
+ if (this.config.verbose) {
13951
+ console.warn(`[S3dbReplicator] Connection test failed: ${err.message}`);
13952
+ }
13953
+ this.emit("connection_error", { replicator: this.name, error: err.message });
13954
+ return false;
13955
+ }
13956
+ return true;
13824
13957
  }
13825
13958
  async getStatus() {
13826
13959
  const baseStatus = await super.getStatus();
@@ -13852,7 +13985,7 @@ class S3dbReplicator extends base_replicator_class_default {
13852
13985
  } else {
13853
13986
  return true;
13854
13987
  }
13855
- } else if (typeof item === "string" || typeof item === "function") {
13988
+ } else if (typeof item === "string") {
13856
13989
  return true;
13857
13990
  }
13858
13991
  }
@@ -13979,6 +14112,9 @@ class SqsReplicator extends base_replicator_class_default {
13979
14112
  if (!this.sqsClient) {
13980
14113
  const [ok, err, sdk] = await try_fn_default(() => import('@aws-sdk/client-sqs'));
13981
14114
  if (!ok) {
14115
+ if (this.config.verbose) {
14116
+ console.warn(`[SqsReplicator] Failed to import SQS SDK: ${err.message}`);
14117
+ }
13982
14118
  this.emit("initialization_error", {
13983
14119
  replicator: this.name,
13984
14120
  error: err.message
@@ -14030,6 +14166,9 @@ class SqsReplicator extends base_replicator_class_default {
14030
14166
  return { success: true, results };
14031
14167
  });
14032
14168
  if (ok) return result;
14169
+ if (this.config.verbose) {
14170
+ console.warn(`[SqsReplicator] Replication failed for ${resource}: ${err.message}`);
14171
+ }
14033
14172
  this.emit("replicator_error", {
14034
14173
  replicator: this.name,
14035
14174
  resource,
@@ -14102,6 +14241,9 @@ class SqsReplicator extends base_replicator_class_default {
14102
14241
  });
14103
14242
  if (ok) return result;
14104
14243
  const errorMessage = err?.message || err || "Unknown error";
14244
+ if (this.config.verbose) {
14245
+ console.warn(`[SqsReplicator] Batch replication failed for ${resource}: ${errorMessage}`);
14246
+ }
14105
14247
  this.emit("batch_replicator_error", {
14106
14248
  replicator: this.name,
14107
14249
  resource,
@@ -14123,6 +14265,9 @@ class SqsReplicator extends base_replicator_class_default {
14123
14265
  return true;
14124
14266
  });
14125
14267
  if (ok) return true;
14268
+ if (this.config.verbose) {
14269
+ console.warn(`[SqsReplicator] Connection test failed: ${err.message}`);
14270
+ }
14126
14271
  this.emit("connection_error", {
14127
14272
  replicator: this.name,
14128
14273
  error: err.message
@@ -14219,25 +14364,37 @@ class ReplicatorPlugin extends plugin_class_default {
14219
14364
  return;
14220
14365
  }
14221
14366
  resource.on("insert", async (data) => {
14222
- try {
14367
+ const [ok, error] = await try_fn_default(async () => {
14223
14368
  const completeData = { ...data, createdAt: (/* @__PURE__ */ new Date()).toISOString() };
14224
14369
  await plugin.processReplicatorEvent("insert", resource.name, completeData.id, completeData);
14225
- } catch (error) {
14370
+ });
14371
+ if (!ok) {
14372
+ if (this.config.verbose) {
14373
+ console.warn(`[ReplicatorPlugin] Insert event failed for resource ${resource.name}: ${error.message}`);
14374
+ }
14226
14375
  this.emit("error", { operation: "insert", error: error.message, resource: resource.name });
14227
14376
  }
14228
14377
  });
14229
14378
  resource.on("update", async (data, beforeData) => {
14230
- try {
14379
+ const [ok, error] = await try_fn_default(async () => {
14231
14380
  const completeData = { ...data, updatedAt: (/* @__PURE__ */ new Date()).toISOString() };
14232
14381
  await plugin.processReplicatorEvent("update", resource.name, completeData.id, completeData, beforeData);
14233
- } catch (error) {
14382
+ });
14383
+ if (!ok) {
14384
+ if (this.config.verbose) {
14385
+ console.warn(`[ReplicatorPlugin] Update event failed for resource ${resource.name}: ${error.message}`);
14386
+ }
14234
14387
  this.emit("error", { operation: "update", error: error.message, resource: resource.name });
14235
14388
  }
14236
14389
  });
14237
14390
  resource.on("delete", async (data) => {
14238
- try {
14391
+ const [ok, error] = await try_fn_default(async () => {
14239
14392
  await plugin.processReplicatorEvent("delete", resource.name, data.id, data);
14240
- } catch (error) {
14393
+ });
14394
+ if (!ok) {
14395
+ if (this.config.verbose) {
14396
+ console.warn(`[ReplicatorPlugin] Delete event failed for resource ${resource.name}: ${error.message}`);
14397
+ }
14241
14398
  this.emit("error", { operation: "delete", error: error.message, resource: resource.name });
14242
14399
  }
14243
14400
  });
@@ -14253,13 +14410,17 @@ class ReplicatorPlugin extends plugin_class_default {
14253
14410
  }
14254
14411
  async setup(database) {
14255
14412
  this.database = database;
14256
- try {
14413
+ const [initOk, initError] = await try_fn_default(async () => {
14257
14414
  await this.initializeReplicators(database);
14258
- } catch (error) {
14259
- this.emit("error", { operation: "setup", error: error.message });
14260
- throw error;
14415
+ });
14416
+ if (!initOk) {
14417
+ if (this.config.verbose) {
14418
+ console.warn(`[ReplicatorPlugin] Replicator initialization failed: ${initError.message}`);
14419
+ }
14420
+ this.emit("error", { operation: "setup", error: initError.message });
14421
+ throw initError;
14261
14422
  }
14262
- try {
14423
+ const [logOk, logError] = await try_fn_default(async () => {
14263
14424
  if (this.config.replicatorLogResource) {
14264
14425
  const logRes = await database.createResource({
14265
14426
  name: this.config.replicatorLogResource,
@@ -14276,7 +14437,15 @@ class ReplicatorPlugin extends plugin_class_default {
14276
14437
  }
14277
14438
  });
14278
14439
  }
14279
- } catch (error) {
14440
+ });
14441
+ if (!logOk) {
14442
+ if (this.config.verbose) {
14443
+ console.warn(`[ReplicatorPlugin] Failed to create log resource ${this.config.replicatorLogResource}: ${logError.message}`);
14444
+ }
14445
+ this.emit("replicator_log_resource_creation_error", {
14446
+ resourceName: this.config.replicatorLogResource,
14447
+ error: logError.message
14448
+ });
14280
14449
  }
14281
14450
  await this.uploadMetadataFile(database);
14282
14451
  const originalCreateResource = database.createResource.bind(database);
@@ -14311,49 +14480,36 @@ class ReplicatorPlugin extends plugin_class_default {
14311
14480
  }
14312
14481
  async stop() {
14313
14482
  }
14314
- filterInternalFields(data) {
14315
- if (!data || typeof data !== "object") return data;
14316
- const filtered = {};
14317
- for (const [key, value] of Object.entries(data)) {
14318
- if (!key.startsWith("_") && !key.startsWith("$")) {
14319
- filtered[key] = value;
14320
- }
14321
- }
14322
- return filtered;
14323
- }
14324
14483
  async uploadMetadataFile(database) {
14325
14484
  if (typeof database.uploadMetadataFile === "function") {
14326
14485
  await database.uploadMetadataFile();
14327
14486
  }
14328
14487
  }
14329
- async getCompleteData(resource, data) {
14330
- try {
14331
- const [ok, err, record] = await try_fn_default(() => resource.get(data.id));
14332
- if (ok && record) {
14333
- return record;
14334
- }
14335
- } catch (error) {
14336
- }
14337
- return data;
14338
- }
14339
14488
  async retryWithBackoff(operation, maxRetries = 3) {
14340
14489
  let lastError;
14341
14490
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
14342
- try {
14343
- return await operation();
14344
- } catch (error) {
14491
+ const [ok, error] = await try_fn_default(operation);
14492
+ if (ok) {
14493
+ return ok;
14494
+ } else {
14345
14495
  lastError = error;
14496
+ if (this.config.verbose) {
14497
+ console.warn(`[ReplicatorPlugin] Retry attempt ${attempt}/${maxRetries} failed: ${error.message}`);
14498
+ }
14346
14499
  if (attempt === maxRetries) {
14347
14500
  throw error;
14348
14501
  }
14349
14502
  const delay = Math.pow(2, attempt - 1) * 1e3;
14503
+ if (this.config.verbose) {
14504
+ console.warn(`[ReplicatorPlugin] Waiting ${delay}ms before retry...`);
14505
+ }
14350
14506
  await new Promise((resolve) => setTimeout(resolve, delay));
14351
14507
  }
14352
14508
  }
14353
14509
  throw lastError;
14354
14510
  }
14355
14511
  async logError(replicator, resourceName, operation, recordId, data, error) {
14356
- try {
14512
+ const [ok, logError] = await try_fn_default(async () => {
14357
14513
  const logResourceName = this.config.replicatorLogResource;
14358
14514
  if (this.database && this.database.resources && this.database.resources[logResourceName]) {
14359
14515
  const logResource = this.database.resources[logResourceName];
@@ -14368,7 +14524,19 @@ class ReplicatorPlugin extends plugin_class_default {
14368
14524
  status: "error"
14369
14525
  });
14370
14526
  }
14371
- } catch (logError) {
14527
+ });
14528
+ if (!ok) {
14529
+ if (this.config.verbose) {
14530
+ console.warn(`[ReplicatorPlugin] Failed to log error for ${resourceName}: ${logError.message}`);
14531
+ }
14532
+ this.emit("replicator_log_error", {
14533
+ replicator: replicator.name || replicator.id,
14534
+ resourceName,
14535
+ operation,
14536
+ recordId,
14537
+ originalError: error.message,
14538
+ logError: logError.message
14539
+ });
14372
14540
  }
14373
14541
  }
14374
14542
  async processReplicatorEvent(operation, resourceName, recordId, data, beforeData = null) {
@@ -14381,8 +14549,8 @@ class ReplicatorPlugin extends plugin_class_default {
14381
14549
  return;
14382
14550
  }
14383
14551
  const promises = applicableReplicators.map(async (replicator) => {
14384
- try {
14385
- const result = await this.retryWithBackoff(
14552
+ const [ok, error, result] = await try_fn_default(async () => {
14553
+ const result2 = await this.retryWithBackoff(
14386
14554
  () => replicator.replicate(resourceName, operation, data, recordId, beforeData),
14387
14555
  this.config.maxRetries
14388
14556
  );
@@ -14391,11 +14559,17 @@ class ReplicatorPlugin extends plugin_class_default {
14391
14559
  resourceName,
14392
14560
  operation,
14393
14561
  recordId,
14394
- result,
14562
+ result: result2,
14395
14563
  success: true
14396
14564
  });
14565
+ return result2;
14566
+ });
14567
+ if (ok) {
14397
14568
  return result;
14398
- } catch (error) {
14569
+ } else {
14570
+ if (this.config.verbose) {
14571
+ console.warn(`[ReplicatorPlugin] Replication failed for ${replicator.name || replicator.id} on ${resourceName}: ${error.message}`);
14572
+ }
14399
14573
  this.emit("replicator_error", {
14400
14574
  replicator: replicator.name || replicator.id,
14401
14575
  resourceName,
@@ -14420,11 +14594,14 @@ class ReplicatorPlugin extends plugin_class_default {
14420
14594
  return;
14421
14595
  }
14422
14596
  const promises = applicableReplicators.map(async (replicator) => {
14423
- try {
14597
+ const [wrapperOk, wrapperError] = await try_fn_default(async () => {
14424
14598
  const [ok, err, result] = await try_fn_default(
14425
14599
  () => replicator.replicate(item.resourceName, item.operation, item.data, item.recordId, item.beforeData)
14426
14600
  );
14427
14601
  if (!ok) {
14602
+ if (this.config.verbose) {
14603
+ console.warn(`[ReplicatorPlugin] Replicator item processing failed for ${replicator.name || replicator.id} on ${item.resourceName}: ${err.message}`);
14604
+ }
14428
14605
  this.emit("replicator_error", {
14429
14606
  replicator: replicator.name || replicator.id,
14430
14607
  resourceName: item.resourceName,
@@ -14446,18 +14623,24 @@ class ReplicatorPlugin extends plugin_class_default {
14446
14623
  success: true
14447
14624
  });
14448
14625
  return { success: true, result };
14449
- } catch (error) {
14626
+ });
14627
+ if (wrapperOk) {
14628
+ return wrapperOk;
14629
+ } else {
14630
+ if (this.config.verbose) {
14631
+ console.warn(`[ReplicatorPlugin] Wrapper processing failed for ${replicator.name || replicator.id} on ${item.resourceName}: ${wrapperError.message}`);
14632
+ }
14450
14633
  this.emit("replicator_error", {
14451
14634
  replicator: replicator.name || replicator.id,
14452
14635
  resourceName: item.resourceName,
14453
14636
  operation: item.operation,
14454
14637
  recordId: item.recordId,
14455
- error: error.message
14638
+ error: wrapperError.message
14456
14639
  });
14457
14640
  if (this.config.logErrors && this.database) {
14458
- await this.logError(replicator, item.resourceName, item.operation, item.recordId, item.data, error);
14641
+ await this.logError(replicator, item.resourceName, item.operation, item.recordId, item.data, wrapperError);
14459
14642
  }
14460
- return { success: false, error: error.message };
14643
+ return { success: false, error: wrapperError.message };
14461
14644
  }
14462
14645
  });
14463
14646
  return Promise.allSettled(promises);
@@ -14479,9 +14662,13 @@ class ReplicatorPlugin extends plugin_class_default {
14479
14662
  timestamp: typeof item.timestamp === "number" ? item.timestamp : Date.now(),
14480
14663
  createdAt: item.createdAt || (/* @__PURE__ */ new Date()).toISOString().slice(0, 10)
14481
14664
  };
14482
- try {
14665
+ const [ok, err] = await try_fn_default(async () => {
14483
14666
  await logRes.insert(logItem);
14484
- } catch (err) {
14667
+ });
14668
+ if (!ok) {
14669
+ if (this.config.verbose) {
14670
+ console.warn(`[ReplicatorPlugin] Failed to log replicator item: ${err.message}`);
14671
+ }
14485
14672
  this.emit("replicator.log.failed", { error: err, item });
14486
14673
  }
14487
14674
  }
@@ -14587,14 +14774,23 @@ class ReplicatorPlugin extends plugin_class_default {
14587
14774
  this.emit("replicator.sync.completed", { replicatorId, stats: this.stats });
14588
14775
  }
14589
14776
  async cleanup() {
14590
- try {
14777
+ const [ok, error] = await try_fn_default(async () => {
14591
14778
  if (this.replicators && this.replicators.length > 0) {
14592
14779
  const cleanupPromises = this.replicators.map(async (replicator) => {
14593
- try {
14780
+ const [replicatorOk, replicatorError] = await try_fn_default(async () => {
14594
14781
  if (replicator && typeof replicator.cleanup === "function") {
14595
14782
  await replicator.cleanup();
14596
14783
  }
14597
- } catch (error) {
14784
+ });
14785
+ if (!replicatorOk) {
14786
+ if (this.config.verbose) {
14787
+ console.warn(`[ReplicatorPlugin] Failed to cleanup replicator ${replicator.name || replicator.id}: ${replicatorError.message}`);
14788
+ }
14789
+ this.emit("replicator_cleanup_error", {
14790
+ replicator: replicator.name || replicator.id || "unknown",
14791
+ driver: replicator.driver || "unknown",
14792
+ error: replicatorError.message
14793
+ });
14598
14794
  }
14599
14795
  });
14600
14796
  await Promise.allSettled(cleanupPromises);
@@ -14603,7 +14799,14 @@ class ReplicatorPlugin extends plugin_class_default {
14603
14799
  this.database = null;
14604
14800
  this.eventListenersInstalled.clear();
14605
14801
  this.removeAllListeners();
14606
- } catch (error) {
14802
+ });
14803
+ if (!ok) {
14804
+ if (this.config.verbose) {
14805
+ console.warn(`[ReplicatorPlugin] Failed to cleanup plugin: ${error.message}`);
14806
+ }
14807
+ this.emit("replicator_plugin_cleanup_error", {
14808
+ error: error.message
14809
+ });
14607
14810
  }
14608
14811
  }
14609
14812
  }