s3db.js 13.2.1 → 13.3.0

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
@@ -5163,7 +5163,7 @@ class AuditPlugin extends Plugin {
5163
5163
  async onStop() {
5164
5164
  }
5165
5165
  setupResourceAuditing(resource) {
5166
- resource.on("insert", async (data) => {
5166
+ resource.on("inserted", async (data) => {
5167
5167
  const partitionValues = this.config.includePartitions ? this.getPartitionValues(data, resource) : null;
5168
5168
  await this.logAudit({
5169
5169
  resourceName: resource.name,
@@ -5175,7 +5175,7 @@ class AuditPlugin extends Plugin {
5175
5175
  partitionValues: partitionValues ? JSON.stringify(partitionValues) : null
5176
5176
  });
5177
5177
  });
5178
- resource.on("update", async (data) => {
5178
+ resource.on("updated", async (data) => {
5179
5179
  let oldData = data.$before;
5180
5180
  if (this.config.includeData && !oldData) {
5181
5181
  const [ok, err, fetched] = await tryFn(() => resource.get(data.id));
@@ -5192,7 +5192,7 @@ class AuditPlugin extends Plugin {
5192
5192
  partitionValues: partitionValues ? JSON.stringify(partitionValues) : null
5193
5193
  });
5194
5194
  });
5195
- resource.on("delete", async (data) => {
5195
+ resource.on("deleted", async (data) => {
5196
5196
  let oldData = data;
5197
5197
  if (this.config.includeData && !oldData) {
5198
5198
  const [ok, err, fetched] = await tryFn(() => resource.get(data.id));
@@ -7297,13 +7297,13 @@ class Cache extends EventEmitter {
7297
7297
  async get(key) {
7298
7298
  this.validateKey(key);
7299
7299
  const data = await this._get(key);
7300
- this.emit("get", data);
7300
+ this.emit("fetched", data);
7301
7301
  return data;
7302
7302
  }
7303
7303
  async del(key) {
7304
7304
  this.validateKey(key);
7305
7305
  const data = await this._del(key);
7306
- this.emit("delete", data);
7306
+ this.emit("deleted", data);
7307
7307
  return data;
7308
7308
  }
7309
7309
  async delete(key) {
@@ -9118,8 +9118,7 @@ class CostsPlugin extends Plugin {
9118
9118
  }
9119
9119
  async onStart() {
9120
9120
  if (this.client) {
9121
- this.client.on("command.response", (name, response, input) => this.addRequest(name, this.map[name], response, input));
9122
- this.client.on("command.error", (name, response, input) => this.addRequest(name, this.map[name], response, input));
9121
+ this.client.on("cl:response", (name, response, input) => this.addRequest(name, this.map[name], response, input));
9123
9122
  }
9124
9123
  }
9125
9124
  addRequest(name, method, response = {}, input = {}) {
@@ -17701,7 +17700,7 @@ class BaseReplicator extends EventEmitter {
17701
17700
  */
17702
17701
  async initialize(database) {
17703
17702
  this.database = database;
17704
- this.emit("initialized", { replicator: this.name });
17703
+ this.emit("db:plugin:initialized", { replicator: this.name });
17705
17704
  }
17706
17705
  /**
17707
17706
  * Replicate data to the target
@@ -18272,7 +18271,7 @@ class BigqueryReplicator extends BaseReplicator {
18272
18271
  if (this.schemaSync.enabled) {
18273
18272
  await this.syncSchemas(database);
18274
18273
  }
18275
- this.emit("initialized", {
18274
+ this.emit("db:plugin:initialized", {
18276
18275
  replicator: this.name,
18277
18276
  projectId: this.projectId,
18278
18277
  datasetId: this.datasetId,
@@ -18579,7 +18578,7 @@ class BigqueryReplicator extends BaseReplicator {
18579
18578
  if (errors.length > 0) {
18580
18579
  console.warn(`[BigqueryReplicator] Replication completed with errors for ${resourceName}:`, errors);
18581
18580
  }
18582
- this.emit("replicated", {
18581
+ this.emit("plg:replicator:replicated", {
18583
18582
  replicator: this.name,
18584
18583
  resourceName,
18585
18584
  operation,
@@ -18600,7 +18599,7 @@ class BigqueryReplicator extends BaseReplicator {
18600
18599
  if (this.config.verbose) {
18601
18600
  console.warn(`[BigqueryReplicator] Replication failed for ${resourceName}: ${err.message}`);
18602
18601
  }
18603
- this.emit("replicator_error", {
18602
+ this.emit("plg:replicator:error", {
18604
18603
  replicator: this.name,
18605
18604
  resourceName,
18606
18605
  operation,
@@ -19875,7 +19874,7 @@ ${createSQL}`);
19875
19874
  }
19876
19875
  }
19877
19876
  const success = errors.length === 0;
19878
- this.emit("replicated", {
19877
+ this.emit("plg:replicator:replicated", {
19879
19878
  replicator: this.name,
19880
19879
  resourceName,
19881
19880
  operation,
@@ -20020,7 +20019,7 @@ class PostgresReplicator extends BaseReplicator {
20020
20019
  if (this.schemaSync.enabled) {
20021
20020
  await this.syncSchemas(database);
20022
20021
  }
20023
- this.emit("initialized", {
20022
+ this.emit("db:plugin:initialized", {
20024
20023
  replicator: this.name,
20025
20024
  database: this.database || "postgres",
20026
20025
  resources: Object.keys(this.resources)
@@ -20226,7 +20225,7 @@ ${createSQL}`);
20226
20225
  if (errors.length > 0) {
20227
20226
  console.warn(`[PostgresReplicator] Replication completed with errors for ${resourceName}:`, errors);
20228
20227
  }
20229
- this.emit("replicated", {
20228
+ this.emit("plg:replicator:replicated", {
20230
20229
  replicator: this.name,
20231
20230
  resourceName,
20232
20231
  operation,
@@ -20247,7 +20246,7 @@ ${createSQL}`);
20247
20246
  if (this.config.verbose) {
20248
20247
  console.warn(`[PostgresReplicator] Replication failed for ${resourceName}: ${err.message}`);
20249
20248
  }
20250
- this.emit("replicator_error", {
20249
+ this.emit("plg:replicator:error", {
20251
20250
  replicator: this.name,
20252
20251
  resourceName,
20253
20252
  operation,
@@ -23916,7 +23915,7 @@ ${errorDetails}`,
23916
23915
  data = await this.applyVersionMapping(data, objectVersion, this.version);
23917
23916
  }
23918
23917
  data = await this.executeHooks("afterGet", data);
23919
- this._emitWithDeprecation("get", "fetched", data, data.id);
23918
+ this._emitStandardized("fetched", data, data.id);
23920
23919
  const value = data;
23921
23920
  return value;
23922
23921
  }
@@ -24626,26 +24625,6 @@ ${errorDetails}`,
24626
24625
  await this.executeHooks("beforeDelete", objectData);
24627
24626
  const key = this.getResourceKey(id);
24628
24627
  const [ok2, err2, response] = await tryFn(() => this.client.deleteObject(key));
24629
- this._emitWithDeprecation("delete", "deleted", {
24630
- ...objectData,
24631
- $before: { ...objectData },
24632
- $after: null
24633
- }, id);
24634
- if (deleteError) {
24635
- throw mapAwsError(deleteError, {
24636
- bucket: this.client.config.bucket,
24637
- key,
24638
- resourceName: this.name,
24639
- operation: "delete",
24640
- id
24641
- });
24642
- }
24643
- if (!ok2) throw mapAwsError(err2, {
24644
- key,
24645
- resourceName: this.name,
24646
- operation: "delete",
24647
- id
24648
- });
24649
24628
  if (this.config.partitions && Object.keys(this.config.partitions).length > 0 && objectData) {
24650
24629
  if (this.config.strictPartitions) {
24651
24630
  await this.deletePartitionReferences(objectData);
@@ -24678,11 +24657,30 @@ ${errorDetails}`,
24678
24657
  for (const hook of nonPartitionHooks) {
24679
24658
  afterDeleteData = await hook(afterDeleteData);
24680
24659
  }
24681
- return response;
24682
24660
  } else {
24683
24661
  await this.executeHooks("afterDelete", objectData);
24684
- return response;
24685
24662
  }
24663
+ this._emitStandardized("deleted", {
24664
+ ...objectData,
24665
+ $before: { ...objectData },
24666
+ $after: null
24667
+ }, id);
24668
+ if (deleteError) {
24669
+ throw mapAwsError(deleteError, {
24670
+ bucket: this.client.config.bucket,
24671
+ key,
24672
+ resourceName: this.name,
24673
+ operation: "delete",
24674
+ id
24675
+ });
24676
+ }
24677
+ if (!ok2) throw mapAwsError(err2, {
24678
+ key,
24679
+ resourceName: this.name,
24680
+ operation: "delete",
24681
+ id
24682
+ });
24683
+ return response;
24686
24684
  }
24687
24685
  /**
24688
24686
  * Insert or update a resource object (upsert operation)
@@ -24754,7 +24752,7 @@ ${errorDetails}`,
24754
24752
  }
24755
24753
  const count = await this.client.count({ prefix });
24756
24754
  await this.executeHooks("afterCount", { count, partition, partitionValues });
24757
- this._emitWithDeprecation("count", "counted", count);
24755
+ this._emitStandardized("count", count);
24758
24756
  return count;
24759
24757
  }
24760
24758
  /**
@@ -24777,7 +24775,7 @@ ${errorDetails}`,
24777
24775
  const result = await this.insert(attributes);
24778
24776
  return result;
24779
24777
  });
24780
- this._emitWithDeprecation("insertMany", "inserted-many", objects.length);
24778
+ this._emitStandardized("inserted-many", objects.length);
24781
24779
  return results;
24782
24780
  }
24783
24781
  /**
@@ -24812,7 +24810,7 @@ ${errorDetails}`,
24812
24810
  return response;
24813
24811
  });
24814
24812
  await this.executeHooks("afterDeleteMany", { ids, results });
24815
- this._emitWithDeprecation("deleteMany", "deleted-many", ids.length);
24813
+ this._emitStandardized("deleted-many", ids.length);
24816
24814
  return results;
24817
24815
  }
24818
24816
  async deleteAll() {
@@ -24821,7 +24819,7 @@ ${errorDetails}`,
24821
24819
  }
24822
24820
  const prefix = `resource=${this.name}/data`;
24823
24821
  const deletedCount = await this.client.deleteAll({ prefix });
24824
- this._emitWithDeprecation("deleteAll", "deleted-all", {
24822
+ this._emitStandardized("deleted-all", {
24825
24823
  version: this.version,
24826
24824
  prefix,
24827
24825
  deletedCount
@@ -24838,7 +24836,7 @@ ${errorDetails}`,
24838
24836
  }
24839
24837
  const prefix = `resource=${this.name}`;
24840
24838
  const deletedCount = await this.client.deleteAll({ prefix });
24841
- this._emitWithDeprecation("deleteAllData", "deleted-all-data", {
24839
+ this._emitStandardized("deleted-all-data", {
24842
24840
  resource: this.name,
24843
24841
  prefix,
24844
24842
  deletedCount
@@ -24908,7 +24906,7 @@ ${errorDetails}`,
24908
24906
  const idPart = parts.find((part) => part.startsWith("id="));
24909
24907
  return idPart ? idPart.replace("id=", "") : null;
24910
24908
  }).filter(Boolean);
24911
- this._emitWithDeprecation("listIds", "listed-ids", ids.length);
24909
+ this._emitStandardized("listed-ids", ids.length);
24912
24910
  return ids;
24913
24911
  }
24914
24912
  /**
@@ -24950,12 +24948,12 @@ ${errorDetails}`,
24950
24948
  const [ok, err, ids] = await tryFn(() => this.listIds({ limit, offset }));
24951
24949
  if (!ok) throw err;
24952
24950
  const results = await this.processListResults(ids, "main");
24953
- this._emitWithDeprecation("list", "listed", { count: results.length, errors: 0 });
24951
+ this._emitStandardized("list", { count: results.length, errors: 0 });
24954
24952
  return results;
24955
24953
  }
24956
24954
  async listPartition({ partition, partitionValues, limit, offset = 0 }) {
24957
24955
  if (!this.config.partitions?.[partition]) {
24958
- this._emitWithDeprecation("list", "listed", { partition, partitionValues, count: 0, errors: 0 });
24956
+ this._emitStandardized("list", { partition, partitionValues, count: 0, errors: 0 });
24959
24957
  return [];
24960
24958
  }
24961
24959
  const partitionDef = this.config.partitions[partition];
@@ -24965,7 +24963,7 @@ ${errorDetails}`,
24965
24963
  const ids = this.extractIdsFromKeys(keys).slice(offset);
24966
24964
  const filteredIds = limit ? ids.slice(0, limit) : ids;
24967
24965
  const results = await this.processPartitionResults(filteredIds, partition, partitionDef, keys);
24968
- this._emitWithDeprecation("list", "listed", { partition, partitionValues, count: results.length, errors: 0 });
24966
+ this._emitStandardized("list", { partition, partitionValues, count: results.length, errors: 0 });
24969
24967
  return results;
24970
24968
  }
24971
24969
  /**
@@ -25010,7 +25008,7 @@ ${errorDetails}`,
25010
25008
  }
25011
25009
  return this.handleResourceError(err, id, context);
25012
25010
  });
25013
- this._emitWithDeprecation("list", "listed", { count: results.length, errors: 0 });
25011
+ this._emitStandardized("list", { count: results.length, errors: 0 });
25014
25012
  return results;
25015
25013
  }
25016
25014
  /**
@@ -25073,10 +25071,10 @@ ${errorDetails}`,
25073
25071
  */
25074
25072
  handleListError(error, { partition, partitionValues }) {
25075
25073
  if (error.message.includes("Partition '") && error.message.includes("' not found")) {
25076
- this._emitWithDeprecation("list", "listed", { partition, partitionValues, count: 0, errors: 1 });
25074
+ this._emitStandardized("list", { partition, partitionValues, count: 0, errors: 1 });
25077
25075
  return [];
25078
25076
  }
25079
- this._emitWithDeprecation("list", "listed", { partition, partitionValues, count: 0, errors: 1 });
25077
+ this._emitStandardized("list", { partition, partitionValues, count: 0, errors: 1 });
25080
25078
  return [];
25081
25079
  }
25082
25080
  /**
@@ -25109,7 +25107,7 @@ ${errorDetails}`,
25109
25107
  throw err;
25110
25108
  });
25111
25109
  const finalResults = await this.executeHooks("afterGetMany", results);
25112
- this._emitWithDeprecation("getMany", "fetched-many", ids.length);
25110
+ this._emitStandardized("fetched-many", ids.length);
25113
25111
  return finalResults;
25114
25112
  }
25115
25113
  /**
@@ -25195,7 +25193,7 @@ ${errorDetails}`,
25195
25193
  hasTotalItems: totalItems !== null
25196
25194
  }
25197
25195
  };
25198
- this._emitWithDeprecation("page", "paginated", result2);
25196
+ this._emitStandardized("paginated", result2);
25199
25197
  return result2;
25200
25198
  });
25201
25199
  if (ok) return result;
@@ -25265,7 +25263,7 @@ ${errorDetails}`,
25265
25263
  contentType
25266
25264
  }));
25267
25265
  if (!ok2) throw err2;
25268
- this._emitWithDeprecation("setContent", "content-set", { id, contentType, contentLength: buffer.length }, id);
25266
+ this._emitStandardized("content-set", { id, contentType, contentLength: buffer.length }, id);
25269
25267
  return updatedData;
25270
25268
  }
25271
25269
  /**
@@ -25294,7 +25292,7 @@ ${errorDetails}`,
25294
25292
  }
25295
25293
  const buffer = Buffer.from(await response.Body.transformToByteArray());
25296
25294
  const contentType = response.ContentType || null;
25297
- this._emitWithDeprecation("content", "content-fetched", { id, contentLength: buffer.length, contentType }, id);
25295
+ this._emitStandardized("content-fetched", { id, contentLength: buffer.length, contentType }, id);
25298
25296
  return {
25299
25297
  buffer,
25300
25298
  contentType
@@ -25326,7 +25324,7 @@ ${errorDetails}`,
25326
25324
  metadata: existingMetadata
25327
25325
  }));
25328
25326
  if (!ok2) throw err2;
25329
- this._emitWithDeprecation("deleteContent", "content-deleted", id, id);
25327
+ this._emitStandardized("content-deleted", id, id);
25330
25328
  return response;
25331
25329
  }
25332
25330
  /**
@@ -25638,7 +25636,7 @@ ${errorDetails}`,
25638
25636
  const data = await this.get(id);
25639
25637
  data._partition = partitionName;
25640
25638
  data._partitionValues = partitionValues;
25641
- this._emitWithDeprecation("getFromPartition", "partition-fetched", data, data.id);
25639
+ this._emitStandardized("partition-fetched", data, data.id);
25642
25640
  return data;
25643
25641
  }
25644
25642
  /**
@@ -25887,6 +25885,120 @@ ${errorDetails}`,
25887
25885
  }
25888
25886
  return out;
25889
25887
  }
25888
+ // ============================================================================
25889
+ // STATE MACHINE METHODS
25890
+ // ============================================================================
25891
+ /**
25892
+ * State machine accessor object
25893
+ * Provides namespaced access to state machine operations
25894
+ * @type {Object}
25895
+ * @property {Function} send - Trigger state transition
25896
+ * @property {Function} get - Get current state
25897
+ * @property {Function} canTransition - Check if transition is valid
25898
+ * @property {Function} getValidEvents - Get valid events for current state
25899
+ * @property {Function} initialize - Initialize entity with initial state
25900
+ * @property {Function} history - Get transition history
25901
+ * @example
25902
+ * await orders.state.send('order-123', 'CONFIRM');
25903
+ * const state = await orders.state.get('order-123');
25904
+ * const canShip = await orders.state.canTransition('order-123', 'SHIP');
25905
+ */
25906
+ get state() {
25907
+ const resource = this;
25908
+ const throwIfNoStateMachine = () => {
25909
+ if (!resource._stateMachine) {
25910
+ throw new Error(
25911
+ `No state machine configured for resource '${resource.name}'. Ensure StateMachinePlugin is installed and configured for this resource.`
25912
+ );
25913
+ }
25914
+ };
25915
+ return {
25916
+ /**
25917
+ * Trigger a state transition
25918
+ * @param {string} id - Entity ID
25919
+ * @param {string} event - Event name
25920
+ * @param {Object} [eventData] - Event data
25921
+ * @returns {Promise<Object>} Transition result
25922
+ * @example
25923
+ * await orders.state.send('order-123', 'CONFIRM', { confirmedBy: 'user-456' });
25924
+ */
25925
+ send: async (id, event, eventData) => {
25926
+ throwIfNoStateMachine();
25927
+ return resource._stateMachine.send(id, event, eventData);
25928
+ },
25929
+ /**
25930
+ * Get current state of an entity
25931
+ * @param {string} id - Entity ID
25932
+ * @returns {Promise<string>} Current state
25933
+ * @example
25934
+ * const currentState = await orders.state.get('order-123');
25935
+ */
25936
+ get: async (id) => {
25937
+ throwIfNoStateMachine();
25938
+ return resource._stateMachine.getState(id);
25939
+ },
25940
+ /**
25941
+ * Check if a transition is valid
25942
+ * @param {string} id - Entity ID
25943
+ * @param {string} event - Event name
25944
+ * @returns {Promise<boolean>} True if transition is valid
25945
+ * @example
25946
+ * const canConfirm = await orders.state.canTransition('order-123', 'CONFIRM');
25947
+ */
25948
+ canTransition: async (id, event) => {
25949
+ throwIfNoStateMachine();
25950
+ return resource._stateMachine.canTransition(id, event);
25951
+ },
25952
+ /**
25953
+ * Get all valid events for the current state
25954
+ * @param {string} id - Entity ID
25955
+ * @returns {Promise<Array<string>>} Array of valid event names
25956
+ * @example
25957
+ * const events = await orders.state.getValidEvents('order-123');
25958
+ * // Returns: ['SHIP', 'CANCEL']
25959
+ */
25960
+ getValidEvents: async (id) => {
25961
+ throwIfNoStateMachine();
25962
+ return resource._stateMachine.getValidEvents(id);
25963
+ },
25964
+ /**
25965
+ * Initialize entity with initial state
25966
+ * @param {string} id - Entity ID
25967
+ * @param {Object} [context] - Initial context data
25968
+ * @returns {Promise<void>}
25969
+ * @example
25970
+ * await orders.state.initialize('order-456', { customerId: 'user-123' });
25971
+ */
25972
+ initialize: async (id, context) => {
25973
+ throwIfNoStateMachine();
25974
+ return resource._stateMachine.initializeEntity(id, context);
25975
+ },
25976
+ /**
25977
+ * Get transition history for an entity
25978
+ * @param {string} id - Entity ID
25979
+ * @param {Object} [options] - Query options
25980
+ * @param {number} [options.limit=100] - Maximum number of transitions
25981
+ * @param {Date} [options.fromDate] - Filter from date
25982
+ * @param {Date} [options.toDate] - Filter to date
25983
+ * @returns {Promise<Array<Object>>} Transition history
25984
+ * @example
25985
+ * const history = await orders.state.history('order-123', { limit: 50 });
25986
+ */
25987
+ history: async (id, options) => {
25988
+ throwIfNoStateMachine();
25989
+ return resource._stateMachine.getTransitionHistory(id, options);
25990
+ }
25991
+ };
25992
+ }
25993
+ /**
25994
+ * Internal method to attach state machine instance
25995
+ * This is called by StateMachinePlugin during initialization
25996
+ * @private
25997
+ * @param {Object} stateMachine - State machine instance
25998
+ */
25999
+ _attachStateMachine(stateMachine) {
26000
+ this._stateMachine = stateMachine;
26001
+ }
25890
26002
  }
25891
26003
  function validateResourceConfig(config) {
25892
26004
  const errors = [];
@@ -26047,7 +26159,7 @@ class Database extends EventEmitter {
26047
26159
  })();
26048
26160
  this.version = "1";
26049
26161
  this.s3dbVersion = (() => {
26050
- const [ok, err, version] = tryFn(() => true ? "13.2.1" : "latest");
26162
+ const [ok, err, version] = tryFn(() => true ? "13.3.0" : "latest");
26051
26163
  return ok ? version : "latest";
26052
26164
  })();
26053
26165
  this._resourcesMap = {};
@@ -26892,7 +27004,7 @@ class Database extends EventEmitter {
26892
27004
  if (!existingVersionData || existingVersionData.hash !== newHash) {
26893
27005
  await this.uploadMetadataFile();
26894
27006
  }
26895
- this.emit("db:resource:updated", name);
27007
+ this.emit("s3db.resourceUpdated", name);
26896
27008
  return existingResource;
26897
27009
  }
26898
27010
  const existingMetadata = this.savedMetadata?.resources?.[name];
@@ -26929,7 +27041,7 @@ class Database extends EventEmitter {
26929
27041
  this._applyMiddlewares(resource, middlewares);
26930
27042
  }
26931
27043
  await this.uploadMetadataFile();
26932
- this.emit("db:resource:created", name);
27044
+ this.emit("s3db.resourceCreated", name);
26933
27045
  return resource;
26934
27046
  }
26935
27047
  /**
@@ -27055,6 +27167,7 @@ class Database extends EventEmitter {
27055
27167
  return !!this.savedMetadata;
27056
27168
  }
27057
27169
  async disconnect() {
27170
+ await this.emit("disconnected", /* @__PURE__ */ new Date());
27058
27171
  await tryFn(async () => {
27059
27172
  if (this.pluginList && this.pluginList.length > 0) {
27060
27173
  for (const plugin of this.pluginList) {
@@ -27205,7 +27318,7 @@ class Database extends EventEmitter {
27205
27318
  for (const hook of hooks) {
27206
27319
  const [ok, error] = await tryFn(() => hook({ database: this, ...context }));
27207
27320
  if (!ok) {
27208
- this.emit("db:hook-error", { event, error, context });
27321
+ this.emit("hookError", { event, error, context });
27209
27322
  if (this.strictHooks) {
27210
27323
  throw new DatabaseError(`Hook execution failed for event '${event}': ${error.message}`, {
27211
27324
  event,
@@ -27764,7 +27877,7 @@ class SqsReplicator extends BaseReplicator {
27764
27877
  region: this.region,
27765
27878
  credentials: this.config.credentials
27766
27879
  });
27767
- this.emit("initialized", {
27880
+ this.emit("db:plugin:initialized", {
27768
27881
  replicator: this.name,
27769
27882
  queueUrl: this.queueUrl,
27770
27883
  queues: this.queues,
@@ -27794,7 +27907,7 @@ class SqsReplicator extends BaseReplicator {
27794
27907
  });
27795
27908
  const result2 = await this.sqsClient.send(command);
27796
27909
  results.push({ queueUrl, messageId: result2.MessageId });
27797
- this.emit("replicated", {
27910
+ this.emit("plg:replicator:replicated", {
27798
27911
  replicator: this.name,
27799
27912
  resource,
27800
27913
  operation,
@@ -27810,7 +27923,7 @@ class SqsReplicator extends BaseReplicator {
27810
27923
  if (this.config.verbose) {
27811
27924
  console.warn(`[SqsReplicator] Replication failed for ${resource}: ${err.message}`);
27812
27925
  }
27813
- this.emit("replicator_error", {
27926
+ this.emit("plg:replicator:error", {
27814
27927
  replicator: this.name,
27815
27928
  resource,
27816
27929
  operation,
@@ -28207,7 +28320,7 @@ ${createSQL}`);
28207
28320
  }
28208
28321
  }
28209
28322
  const success = errors.length === 0;
28210
- this.emit("replicated", {
28323
+ this.emit("plg:replicator:replicated", {
28211
28324
  replicator: this.name,
28212
28325
  resourceName,
28213
28326
  operation,
@@ -28493,7 +28606,7 @@ class WebhookReplicator extends BaseReplicator {
28493
28606
  });
28494
28607
  throw error;
28495
28608
  }
28496
- this.emit("initialized", {
28609
+ this.emit("db:plugin:initialized", {
28497
28610
  replicator: this.name,
28498
28611
  url: this.url,
28499
28612
  method: this.method,
@@ -28513,7 +28626,7 @@ class WebhookReplicator extends BaseReplicator {
28513
28626
  const payload = this.createPayload(resource, operation, transformedData, id, beforeData);
28514
28627
  const response = await this._makeRequest(payload);
28515
28628
  if (response.success) {
28516
- this.emit("replicated", {
28629
+ this.emit("plg:replicator:replicated", {
28517
28630
  replicator: this.name,
28518
28631
  resource,
28519
28632
  operation,
@@ -28530,7 +28643,7 @@ class WebhookReplicator extends BaseReplicator {
28530
28643
  if (this.config.verbose) {
28531
28644
  console.warn(`[WebhookReplicator] Replication failed for ${resource}: ${err.message}`);
28532
28645
  }
28533
- this.emit("replicator_error", {
28646
+ this.emit("plg:replicator:error", {
28534
28647
  replicator: this.name,
28535
28648
  resource,
28536
28649
  operation,
@@ -28809,13 +28922,13 @@ class ReplicatorPlugin extends Plugin {
28809
28922
  }
28810
28923
  };
28811
28924
  this.eventHandlers.set(resource.name, {
28812
- insert: insertHandler,
28813
- update: updateHandler,
28814
- delete: deleteHandler
28925
+ inserted: insertHandler,
28926
+ updated: updateHandler,
28927
+ deleted: deleteHandler
28815
28928
  });
28816
- resource.on("insert", insertHandler);
28817
- resource.on("update", updateHandler);
28818
- resource.on("delete", deleteHandler);
28929
+ resource.on("inserted", insertHandler);
28930
+ resource.on("updated", updateHandler);
28931
+ resource.on("deleted", deleteHandler);
28819
28932
  this.eventListenersInstalled.add(resource.name);
28820
28933
  }
28821
28934
  async onInstall() {
@@ -29205,9 +29318,9 @@ class ReplicatorPlugin extends Plugin {
29205
29318
  const resource = this.database.resources[resourceName];
29206
29319
  const handlers = this.eventHandlers.get(resourceName);
29207
29320
  if (resource && handlers) {
29208
- resource.off("insert", handlers.insert);
29209
- resource.off("update", handlers.update);
29210
- resource.off("delete", handlers.delete);
29321
+ resource.off("inserted", handlers.inserted);
29322
+ resource.off("updated", handlers.updated);
29323
+ resource.off("deleted", handlers.deleted);
29211
29324
  }
29212
29325
  }
29213
29326
  }
@@ -29336,7 +29449,7 @@ class S3QueuePlugin extends Plugin {
29336
29449
  createdAt: (/* @__PURE__ */ new Date()).toISOString().slice(0, 10)
29337
29450
  };
29338
29451
  await plugin.queueResource.insert(queueEntry);
29339
- plugin.emit("message.enqueued", { id: record.id, queueId: queueEntry.id });
29452
+ plugin.emit("plg:s3-queue:message-enqueued", { id: record.id, queueId: queueEntry.id });
29340
29453
  return record;
29341
29454
  };
29342
29455
  resource.queueStats = async function() {
@@ -30597,6 +30710,7 @@ class StateMachinePlugin extends Plugin {
30597
30710
  // entityId -> currentState
30598
30711
  });
30599
30712
  }
30713
+ await this._attachStateMachinesToResources();
30600
30714
  await this._setupTriggers();
30601
30715
  this.emit("db:plugin:initialized", { machines: Array.from(this.machines.keys()) });
30602
30716
  }
@@ -31438,6 +31552,58 @@ class StateMachinePlugin extends Plugin {
31438
31552
  }
31439
31553
  }
31440
31554
  }
31555
+ /**
31556
+ * Attach state machine instances to their associated resources
31557
+ * This enables the resource API: resource.state(id, event)
31558
+ * @private
31559
+ */
31560
+ async _attachStateMachinesToResources() {
31561
+ for (const [machineName, machineConfig] of Object.entries(this.config.stateMachines)) {
31562
+ const resourceConfig = machineConfig.config || machineConfig;
31563
+ if (!resourceConfig.resource) {
31564
+ if (this.config.verbose) {
31565
+ console.log(`[StateMachinePlugin] Machine '${machineName}' has no resource configured, skipping attachment`);
31566
+ }
31567
+ continue;
31568
+ }
31569
+ let resource;
31570
+ if (typeof resourceConfig.resource === "string") {
31571
+ resource = this.database.resources[resourceConfig.resource];
31572
+ if (!resource) {
31573
+ console.warn(
31574
+ `[StateMachinePlugin] Resource '${resourceConfig.resource}' not found for machine '${machineName}'. Resource API will not be available.`
31575
+ );
31576
+ continue;
31577
+ }
31578
+ } else {
31579
+ resource = resourceConfig.resource;
31580
+ }
31581
+ const machineProxy = {
31582
+ send: async (id, event, eventData) => {
31583
+ return this.send(machineName, id, event, eventData);
31584
+ },
31585
+ getState: async (id) => {
31586
+ return this.getState(machineName, id);
31587
+ },
31588
+ canTransition: async (id, event) => {
31589
+ return this.canTransition(machineName, id, event);
31590
+ },
31591
+ getValidEvents: async (id) => {
31592
+ return this.getValidEvents(machineName, id);
31593
+ },
31594
+ initializeEntity: async (id, context) => {
31595
+ return this.initializeEntity(machineName, id, context);
31596
+ },
31597
+ getTransitionHistory: async (id, options) => {
31598
+ return this.getTransitionHistory(machineName, id, options);
31599
+ }
31600
+ };
31601
+ resource._attachStateMachine(machineProxy);
31602
+ if (this.config.verbose) {
31603
+ console.log(`[StateMachinePlugin] Attached machine '${machineName}' to resource '${resource.name}'`);
31604
+ }
31605
+ }
31606
+ }
31441
31607
  async start() {
31442
31608
  if (this.config.verbose) {
31443
31609
  console.log(`[StateMachinePlugin] Started with ${this.machines.size} state machines`);
@@ -43702,6 +43868,7 @@ class MemoryClient extends EventEmitter {
43702
43868
  const commandName = command.constructor.name;
43703
43869
  const input = command.input || {};
43704
43870
  this.emit("cl:request", commandName, input);
43871
+ this.emit("command.request", commandName, input);
43705
43872
  let response;
43706
43873
  try {
43707
43874
  switch (commandName) {
@@ -43730,6 +43897,7 @@ class MemoryClient extends EventEmitter {
43730
43897
  throw new Error(`Unsupported command: ${commandName}`);
43731
43898
  }
43732
43899
  this.emit("cl:response", commandName, response, input);
43900
+ this.emit("command.response", commandName, response, input);
43733
43901
  return response;
43734
43902
  } catch (error) {
43735
43903
  const mappedError = mapAwsError(error, {
@@ -44025,13 +44193,13 @@ class MemoryClient extends EventEmitter {
44025
44193
  if (keys.length > 0) {
44026
44194
  const result = await this.deleteObjects(keys);
44027
44195
  totalDeleted = result.Deleted.length;
44028
- this.emit("cl:DeleteAll", {
44196
+ this.emit("deleteAll", {
44029
44197
  prefix,
44030
44198
  batch: totalDeleted,
44031
44199
  total: totalDeleted
44032
44200
  });
44033
44201
  }
44034
- this.emit("cl:DeleteAllComplete", {
44202
+ this.emit("deleteAllComplete", {
44035
44203
  prefix,
44036
44204
  totalDeleted
44037
44205
  });
@@ -44078,7 +44246,7 @@ class MemoryClient extends EventEmitter {
44078
44246
  });
44079
44247
  }
44080
44248
  }
44081
- this.emit("cl:MoveAllObjects", { results, errors }, { prefixFrom, prefixTo });
44249
+ this.emit("moveAllObjects", { results, errors });
44082
44250
  if (errors.length > 0) {
44083
44251
  const error = new Error("Some objects could not be moved");
44084
44252
  error.context = {