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.cjs.js CHANGED
@@ -5186,7 +5186,7 @@ class AuditPlugin extends Plugin {
5186
5186
  async onStop() {
5187
5187
  }
5188
5188
  setupResourceAuditing(resource) {
5189
- resource.on("insert", async (data) => {
5189
+ resource.on("inserted", async (data) => {
5190
5190
  const partitionValues = this.config.includePartitions ? this.getPartitionValues(data, resource) : null;
5191
5191
  await this.logAudit({
5192
5192
  resourceName: resource.name,
@@ -5198,7 +5198,7 @@ class AuditPlugin extends Plugin {
5198
5198
  partitionValues: partitionValues ? JSON.stringify(partitionValues) : null
5199
5199
  });
5200
5200
  });
5201
- resource.on("update", async (data) => {
5201
+ resource.on("updated", async (data) => {
5202
5202
  let oldData = data.$before;
5203
5203
  if (this.config.includeData && !oldData) {
5204
5204
  const [ok, err, fetched] = await tryFn(() => resource.get(data.id));
@@ -5215,7 +5215,7 @@ class AuditPlugin extends Plugin {
5215
5215
  partitionValues: partitionValues ? JSON.stringify(partitionValues) : null
5216
5216
  });
5217
5217
  });
5218
- resource.on("delete", async (data) => {
5218
+ resource.on("deleted", async (data) => {
5219
5219
  let oldData = data;
5220
5220
  if (this.config.includeData && !oldData) {
5221
5221
  const [ok, err, fetched] = await tryFn(() => resource.get(data.id));
@@ -7320,13 +7320,13 @@ class Cache extends EventEmitter {
7320
7320
  async get(key) {
7321
7321
  this.validateKey(key);
7322
7322
  const data = await this._get(key);
7323
- this.emit("get", data);
7323
+ this.emit("fetched", data);
7324
7324
  return data;
7325
7325
  }
7326
7326
  async del(key) {
7327
7327
  this.validateKey(key);
7328
7328
  const data = await this._del(key);
7329
- this.emit("delete", data);
7329
+ this.emit("deleted", data);
7330
7330
  return data;
7331
7331
  }
7332
7332
  async delete(key) {
@@ -9141,8 +9141,7 @@ class CostsPlugin extends Plugin {
9141
9141
  }
9142
9142
  async onStart() {
9143
9143
  if (this.client) {
9144
- this.client.on("command.response", (name, response, input) => this.addRequest(name, this.map[name], response, input));
9145
- this.client.on("command.error", (name, response, input) => this.addRequest(name, this.map[name], response, input));
9144
+ this.client.on("cl:response", (name, response, input) => this.addRequest(name, this.map[name], response, input));
9146
9145
  }
9147
9146
  }
9148
9147
  addRequest(name, method, response = {}, input = {}) {
@@ -17724,7 +17723,7 @@ class BaseReplicator extends EventEmitter {
17724
17723
  */
17725
17724
  async initialize(database) {
17726
17725
  this.database = database;
17727
- this.emit("initialized", { replicator: this.name });
17726
+ this.emit("db:plugin:initialized", { replicator: this.name });
17728
17727
  }
17729
17728
  /**
17730
17729
  * Replicate data to the target
@@ -18295,7 +18294,7 @@ class BigqueryReplicator extends BaseReplicator {
18295
18294
  if (this.schemaSync.enabled) {
18296
18295
  await this.syncSchemas(database);
18297
18296
  }
18298
- this.emit("initialized", {
18297
+ this.emit("db:plugin:initialized", {
18299
18298
  replicator: this.name,
18300
18299
  projectId: this.projectId,
18301
18300
  datasetId: this.datasetId,
@@ -18602,7 +18601,7 @@ class BigqueryReplicator extends BaseReplicator {
18602
18601
  if (errors.length > 0) {
18603
18602
  console.warn(`[BigqueryReplicator] Replication completed with errors for ${resourceName}:`, errors);
18604
18603
  }
18605
- this.emit("replicated", {
18604
+ this.emit("plg:replicator:replicated", {
18606
18605
  replicator: this.name,
18607
18606
  resourceName,
18608
18607
  operation,
@@ -18623,7 +18622,7 @@ class BigqueryReplicator extends BaseReplicator {
18623
18622
  if (this.config.verbose) {
18624
18623
  console.warn(`[BigqueryReplicator] Replication failed for ${resourceName}: ${err.message}`);
18625
18624
  }
18626
- this.emit("replicator_error", {
18625
+ this.emit("plg:replicator:error", {
18627
18626
  replicator: this.name,
18628
18627
  resourceName,
18629
18628
  operation,
@@ -19898,7 +19897,7 @@ ${createSQL}`);
19898
19897
  }
19899
19898
  }
19900
19899
  const success = errors.length === 0;
19901
- this.emit("replicated", {
19900
+ this.emit("plg:replicator:replicated", {
19902
19901
  replicator: this.name,
19903
19902
  resourceName,
19904
19903
  operation,
@@ -20043,7 +20042,7 @@ class PostgresReplicator extends BaseReplicator {
20043
20042
  if (this.schemaSync.enabled) {
20044
20043
  await this.syncSchemas(database);
20045
20044
  }
20046
- this.emit("initialized", {
20045
+ this.emit("db:plugin:initialized", {
20047
20046
  replicator: this.name,
20048
20047
  database: this.database || "postgres",
20049
20048
  resources: Object.keys(this.resources)
@@ -20249,7 +20248,7 @@ ${createSQL}`);
20249
20248
  if (errors.length > 0) {
20250
20249
  console.warn(`[PostgresReplicator] Replication completed with errors for ${resourceName}:`, errors);
20251
20250
  }
20252
- this.emit("replicated", {
20251
+ this.emit("plg:replicator:replicated", {
20253
20252
  replicator: this.name,
20254
20253
  resourceName,
20255
20254
  operation,
@@ -20270,7 +20269,7 @@ ${createSQL}`);
20270
20269
  if (this.config.verbose) {
20271
20270
  console.warn(`[PostgresReplicator] Replication failed for ${resourceName}: ${err.message}`);
20272
20271
  }
20273
- this.emit("replicator_error", {
20272
+ this.emit("plg:replicator:error", {
20274
20273
  replicator: this.name,
20275
20274
  resourceName,
20276
20275
  operation,
@@ -23939,7 +23938,7 @@ ${errorDetails}`,
23939
23938
  data = await this.applyVersionMapping(data, objectVersion, this.version);
23940
23939
  }
23941
23940
  data = await this.executeHooks("afterGet", data);
23942
- this._emitWithDeprecation("get", "fetched", data, data.id);
23941
+ this._emitStandardized("fetched", data, data.id);
23943
23942
  const value = data;
23944
23943
  return value;
23945
23944
  }
@@ -24649,26 +24648,6 @@ ${errorDetails}`,
24649
24648
  await this.executeHooks("beforeDelete", objectData);
24650
24649
  const key = this.getResourceKey(id);
24651
24650
  const [ok2, err2, response] = await tryFn(() => this.client.deleteObject(key));
24652
- this._emitWithDeprecation("delete", "deleted", {
24653
- ...objectData,
24654
- $before: { ...objectData },
24655
- $after: null
24656
- }, id);
24657
- if (deleteError) {
24658
- throw mapAwsError(deleteError, {
24659
- bucket: this.client.config.bucket,
24660
- key,
24661
- resourceName: this.name,
24662
- operation: "delete",
24663
- id
24664
- });
24665
- }
24666
- if (!ok2) throw mapAwsError(err2, {
24667
- key,
24668
- resourceName: this.name,
24669
- operation: "delete",
24670
- id
24671
- });
24672
24651
  if (this.config.partitions && Object.keys(this.config.partitions).length > 0 && objectData) {
24673
24652
  if (this.config.strictPartitions) {
24674
24653
  await this.deletePartitionReferences(objectData);
@@ -24701,11 +24680,30 @@ ${errorDetails}`,
24701
24680
  for (const hook of nonPartitionHooks) {
24702
24681
  afterDeleteData = await hook(afterDeleteData);
24703
24682
  }
24704
- return response;
24705
24683
  } else {
24706
24684
  await this.executeHooks("afterDelete", objectData);
24707
- return response;
24708
24685
  }
24686
+ this._emitStandardized("deleted", {
24687
+ ...objectData,
24688
+ $before: { ...objectData },
24689
+ $after: null
24690
+ }, id);
24691
+ if (deleteError) {
24692
+ throw mapAwsError(deleteError, {
24693
+ bucket: this.client.config.bucket,
24694
+ key,
24695
+ resourceName: this.name,
24696
+ operation: "delete",
24697
+ id
24698
+ });
24699
+ }
24700
+ if (!ok2) throw mapAwsError(err2, {
24701
+ key,
24702
+ resourceName: this.name,
24703
+ operation: "delete",
24704
+ id
24705
+ });
24706
+ return response;
24709
24707
  }
24710
24708
  /**
24711
24709
  * Insert or update a resource object (upsert operation)
@@ -24777,7 +24775,7 @@ ${errorDetails}`,
24777
24775
  }
24778
24776
  const count = await this.client.count({ prefix });
24779
24777
  await this.executeHooks("afterCount", { count, partition, partitionValues });
24780
- this._emitWithDeprecation("count", "counted", count);
24778
+ this._emitStandardized("count", count);
24781
24779
  return count;
24782
24780
  }
24783
24781
  /**
@@ -24800,7 +24798,7 @@ ${errorDetails}`,
24800
24798
  const result = await this.insert(attributes);
24801
24799
  return result;
24802
24800
  });
24803
- this._emitWithDeprecation("insertMany", "inserted-many", objects.length);
24801
+ this._emitStandardized("inserted-many", objects.length);
24804
24802
  return results;
24805
24803
  }
24806
24804
  /**
@@ -24835,7 +24833,7 @@ ${errorDetails}`,
24835
24833
  return response;
24836
24834
  });
24837
24835
  await this.executeHooks("afterDeleteMany", { ids, results });
24838
- this._emitWithDeprecation("deleteMany", "deleted-many", ids.length);
24836
+ this._emitStandardized("deleted-many", ids.length);
24839
24837
  return results;
24840
24838
  }
24841
24839
  async deleteAll() {
@@ -24844,7 +24842,7 @@ ${errorDetails}`,
24844
24842
  }
24845
24843
  const prefix = `resource=${this.name}/data`;
24846
24844
  const deletedCount = await this.client.deleteAll({ prefix });
24847
- this._emitWithDeprecation("deleteAll", "deleted-all", {
24845
+ this._emitStandardized("deleted-all", {
24848
24846
  version: this.version,
24849
24847
  prefix,
24850
24848
  deletedCount
@@ -24861,7 +24859,7 @@ ${errorDetails}`,
24861
24859
  }
24862
24860
  const prefix = `resource=${this.name}`;
24863
24861
  const deletedCount = await this.client.deleteAll({ prefix });
24864
- this._emitWithDeprecation("deleteAllData", "deleted-all-data", {
24862
+ this._emitStandardized("deleted-all-data", {
24865
24863
  resource: this.name,
24866
24864
  prefix,
24867
24865
  deletedCount
@@ -24931,7 +24929,7 @@ ${errorDetails}`,
24931
24929
  const idPart = parts.find((part) => part.startsWith("id="));
24932
24930
  return idPart ? idPart.replace("id=", "") : null;
24933
24931
  }).filter(Boolean);
24934
- this._emitWithDeprecation("listIds", "listed-ids", ids.length);
24932
+ this._emitStandardized("listed-ids", ids.length);
24935
24933
  return ids;
24936
24934
  }
24937
24935
  /**
@@ -24973,12 +24971,12 @@ ${errorDetails}`,
24973
24971
  const [ok, err, ids] = await tryFn(() => this.listIds({ limit, offset }));
24974
24972
  if (!ok) throw err;
24975
24973
  const results = await this.processListResults(ids, "main");
24976
- this._emitWithDeprecation("list", "listed", { count: results.length, errors: 0 });
24974
+ this._emitStandardized("list", { count: results.length, errors: 0 });
24977
24975
  return results;
24978
24976
  }
24979
24977
  async listPartition({ partition, partitionValues, limit, offset = 0 }) {
24980
24978
  if (!this.config.partitions?.[partition]) {
24981
- this._emitWithDeprecation("list", "listed", { partition, partitionValues, count: 0, errors: 0 });
24979
+ this._emitStandardized("list", { partition, partitionValues, count: 0, errors: 0 });
24982
24980
  return [];
24983
24981
  }
24984
24982
  const partitionDef = this.config.partitions[partition];
@@ -24988,7 +24986,7 @@ ${errorDetails}`,
24988
24986
  const ids = this.extractIdsFromKeys(keys).slice(offset);
24989
24987
  const filteredIds = limit ? ids.slice(0, limit) : ids;
24990
24988
  const results = await this.processPartitionResults(filteredIds, partition, partitionDef, keys);
24991
- this._emitWithDeprecation("list", "listed", { partition, partitionValues, count: results.length, errors: 0 });
24989
+ this._emitStandardized("list", { partition, partitionValues, count: results.length, errors: 0 });
24992
24990
  return results;
24993
24991
  }
24994
24992
  /**
@@ -25033,7 +25031,7 @@ ${errorDetails}`,
25033
25031
  }
25034
25032
  return this.handleResourceError(err, id, context);
25035
25033
  });
25036
- this._emitWithDeprecation("list", "listed", { count: results.length, errors: 0 });
25034
+ this._emitStandardized("list", { count: results.length, errors: 0 });
25037
25035
  return results;
25038
25036
  }
25039
25037
  /**
@@ -25096,10 +25094,10 @@ ${errorDetails}`,
25096
25094
  */
25097
25095
  handleListError(error, { partition, partitionValues }) {
25098
25096
  if (error.message.includes("Partition '") && error.message.includes("' not found")) {
25099
- this._emitWithDeprecation("list", "listed", { partition, partitionValues, count: 0, errors: 1 });
25097
+ this._emitStandardized("list", { partition, partitionValues, count: 0, errors: 1 });
25100
25098
  return [];
25101
25099
  }
25102
- this._emitWithDeprecation("list", "listed", { partition, partitionValues, count: 0, errors: 1 });
25100
+ this._emitStandardized("list", { partition, partitionValues, count: 0, errors: 1 });
25103
25101
  return [];
25104
25102
  }
25105
25103
  /**
@@ -25132,7 +25130,7 @@ ${errorDetails}`,
25132
25130
  throw err;
25133
25131
  });
25134
25132
  const finalResults = await this.executeHooks("afterGetMany", results);
25135
- this._emitWithDeprecation("getMany", "fetched-many", ids.length);
25133
+ this._emitStandardized("fetched-many", ids.length);
25136
25134
  return finalResults;
25137
25135
  }
25138
25136
  /**
@@ -25218,7 +25216,7 @@ ${errorDetails}`,
25218
25216
  hasTotalItems: totalItems !== null
25219
25217
  }
25220
25218
  };
25221
- this._emitWithDeprecation("page", "paginated", result2);
25219
+ this._emitStandardized("paginated", result2);
25222
25220
  return result2;
25223
25221
  });
25224
25222
  if (ok) return result;
@@ -25288,7 +25286,7 @@ ${errorDetails}`,
25288
25286
  contentType
25289
25287
  }));
25290
25288
  if (!ok2) throw err2;
25291
- this._emitWithDeprecation("setContent", "content-set", { id, contentType, contentLength: buffer.length }, id);
25289
+ this._emitStandardized("content-set", { id, contentType, contentLength: buffer.length }, id);
25292
25290
  return updatedData;
25293
25291
  }
25294
25292
  /**
@@ -25317,7 +25315,7 @@ ${errorDetails}`,
25317
25315
  }
25318
25316
  const buffer = Buffer.from(await response.Body.transformToByteArray());
25319
25317
  const contentType = response.ContentType || null;
25320
- this._emitWithDeprecation("content", "content-fetched", { id, contentLength: buffer.length, contentType }, id);
25318
+ this._emitStandardized("content-fetched", { id, contentLength: buffer.length, contentType }, id);
25321
25319
  return {
25322
25320
  buffer,
25323
25321
  contentType
@@ -25349,7 +25347,7 @@ ${errorDetails}`,
25349
25347
  metadata: existingMetadata
25350
25348
  }));
25351
25349
  if (!ok2) throw err2;
25352
- this._emitWithDeprecation("deleteContent", "content-deleted", id, id);
25350
+ this._emitStandardized("content-deleted", id, id);
25353
25351
  return response;
25354
25352
  }
25355
25353
  /**
@@ -25661,7 +25659,7 @@ ${errorDetails}`,
25661
25659
  const data = await this.get(id);
25662
25660
  data._partition = partitionName;
25663
25661
  data._partitionValues = partitionValues;
25664
- this._emitWithDeprecation("getFromPartition", "partition-fetched", data, data.id);
25662
+ this._emitStandardized("partition-fetched", data, data.id);
25665
25663
  return data;
25666
25664
  }
25667
25665
  /**
@@ -25910,6 +25908,120 @@ ${errorDetails}`,
25910
25908
  }
25911
25909
  return out;
25912
25910
  }
25911
+ // ============================================================================
25912
+ // STATE MACHINE METHODS
25913
+ // ============================================================================
25914
+ /**
25915
+ * State machine accessor object
25916
+ * Provides namespaced access to state machine operations
25917
+ * @type {Object}
25918
+ * @property {Function} send - Trigger state transition
25919
+ * @property {Function} get - Get current state
25920
+ * @property {Function} canTransition - Check if transition is valid
25921
+ * @property {Function} getValidEvents - Get valid events for current state
25922
+ * @property {Function} initialize - Initialize entity with initial state
25923
+ * @property {Function} history - Get transition history
25924
+ * @example
25925
+ * await orders.state.send('order-123', 'CONFIRM');
25926
+ * const state = await orders.state.get('order-123');
25927
+ * const canShip = await orders.state.canTransition('order-123', 'SHIP');
25928
+ */
25929
+ get state() {
25930
+ const resource = this;
25931
+ const throwIfNoStateMachine = () => {
25932
+ if (!resource._stateMachine) {
25933
+ throw new Error(
25934
+ `No state machine configured for resource '${resource.name}'. Ensure StateMachinePlugin is installed and configured for this resource.`
25935
+ );
25936
+ }
25937
+ };
25938
+ return {
25939
+ /**
25940
+ * Trigger a state transition
25941
+ * @param {string} id - Entity ID
25942
+ * @param {string} event - Event name
25943
+ * @param {Object} [eventData] - Event data
25944
+ * @returns {Promise<Object>} Transition result
25945
+ * @example
25946
+ * await orders.state.send('order-123', 'CONFIRM', { confirmedBy: 'user-456' });
25947
+ */
25948
+ send: async (id, event, eventData) => {
25949
+ throwIfNoStateMachine();
25950
+ return resource._stateMachine.send(id, event, eventData);
25951
+ },
25952
+ /**
25953
+ * Get current state of an entity
25954
+ * @param {string} id - Entity ID
25955
+ * @returns {Promise<string>} Current state
25956
+ * @example
25957
+ * const currentState = await orders.state.get('order-123');
25958
+ */
25959
+ get: async (id) => {
25960
+ throwIfNoStateMachine();
25961
+ return resource._stateMachine.getState(id);
25962
+ },
25963
+ /**
25964
+ * Check if a transition is valid
25965
+ * @param {string} id - Entity ID
25966
+ * @param {string} event - Event name
25967
+ * @returns {Promise<boolean>} True if transition is valid
25968
+ * @example
25969
+ * const canConfirm = await orders.state.canTransition('order-123', 'CONFIRM');
25970
+ */
25971
+ canTransition: async (id, event) => {
25972
+ throwIfNoStateMachine();
25973
+ return resource._stateMachine.canTransition(id, event);
25974
+ },
25975
+ /**
25976
+ * Get all valid events for the current state
25977
+ * @param {string} id - Entity ID
25978
+ * @returns {Promise<Array<string>>} Array of valid event names
25979
+ * @example
25980
+ * const events = await orders.state.getValidEvents('order-123');
25981
+ * // Returns: ['SHIP', 'CANCEL']
25982
+ */
25983
+ getValidEvents: async (id) => {
25984
+ throwIfNoStateMachine();
25985
+ return resource._stateMachine.getValidEvents(id);
25986
+ },
25987
+ /**
25988
+ * Initialize entity with initial state
25989
+ * @param {string} id - Entity ID
25990
+ * @param {Object} [context] - Initial context data
25991
+ * @returns {Promise<void>}
25992
+ * @example
25993
+ * await orders.state.initialize('order-456', { customerId: 'user-123' });
25994
+ */
25995
+ initialize: async (id, context) => {
25996
+ throwIfNoStateMachine();
25997
+ return resource._stateMachine.initializeEntity(id, context);
25998
+ },
25999
+ /**
26000
+ * Get transition history for an entity
26001
+ * @param {string} id - Entity ID
26002
+ * @param {Object} [options] - Query options
26003
+ * @param {number} [options.limit=100] - Maximum number of transitions
26004
+ * @param {Date} [options.fromDate] - Filter from date
26005
+ * @param {Date} [options.toDate] - Filter to date
26006
+ * @returns {Promise<Array<Object>>} Transition history
26007
+ * @example
26008
+ * const history = await orders.state.history('order-123', { limit: 50 });
26009
+ */
26010
+ history: async (id, options) => {
26011
+ throwIfNoStateMachine();
26012
+ return resource._stateMachine.getTransitionHistory(id, options);
26013
+ }
26014
+ };
26015
+ }
26016
+ /**
26017
+ * Internal method to attach state machine instance
26018
+ * This is called by StateMachinePlugin during initialization
26019
+ * @private
26020
+ * @param {Object} stateMachine - State machine instance
26021
+ */
26022
+ _attachStateMachine(stateMachine) {
26023
+ this._stateMachine = stateMachine;
26024
+ }
25913
26025
  }
25914
26026
  function validateResourceConfig(config) {
25915
26027
  const errors = [];
@@ -26070,7 +26182,7 @@ class Database extends EventEmitter {
26070
26182
  })();
26071
26183
  this.version = "1";
26072
26184
  this.s3dbVersion = (() => {
26073
- const [ok, err, version] = tryFn(() => true ? "13.2.1" : "latest");
26185
+ const [ok, err, version] = tryFn(() => true ? "13.3.0" : "latest");
26074
26186
  return ok ? version : "latest";
26075
26187
  })();
26076
26188
  this._resourcesMap = {};
@@ -26915,7 +27027,7 @@ class Database extends EventEmitter {
26915
27027
  if (!existingVersionData || existingVersionData.hash !== newHash) {
26916
27028
  await this.uploadMetadataFile();
26917
27029
  }
26918
- this.emit("db:resource:updated", name);
27030
+ this.emit("s3db.resourceUpdated", name);
26919
27031
  return existingResource;
26920
27032
  }
26921
27033
  const existingMetadata = this.savedMetadata?.resources?.[name];
@@ -26952,7 +27064,7 @@ class Database extends EventEmitter {
26952
27064
  this._applyMiddlewares(resource, middlewares);
26953
27065
  }
26954
27066
  await this.uploadMetadataFile();
26955
- this.emit("db:resource:created", name);
27067
+ this.emit("s3db.resourceCreated", name);
26956
27068
  return resource;
26957
27069
  }
26958
27070
  /**
@@ -27078,6 +27190,7 @@ class Database extends EventEmitter {
27078
27190
  return !!this.savedMetadata;
27079
27191
  }
27080
27192
  async disconnect() {
27193
+ await this.emit("disconnected", /* @__PURE__ */ new Date());
27081
27194
  await tryFn(async () => {
27082
27195
  if (this.pluginList && this.pluginList.length > 0) {
27083
27196
  for (const plugin of this.pluginList) {
@@ -27228,7 +27341,7 @@ class Database extends EventEmitter {
27228
27341
  for (const hook of hooks) {
27229
27342
  const [ok, error] = await tryFn(() => hook({ database: this, ...context }));
27230
27343
  if (!ok) {
27231
- this.emit("db:hook-error", { event, error, context });
27344
+ this.emit("hookError", { event, error, context });
27232
27345
  if (this.strictHooks) {
27233
27346
  throw new DatabaseError(`Hook execution failed for event '${event}': ${error.message}`, {
27234
27347
  event,
@@ -27787,7 +27900,7 @@ class SqsReplicator extends BaseReplicator {
27787
27900
  region: this.region,
27788
27901
  credentials: this.config.credentials
27789
27902
  });
27790
- this.emit("initialized", {
27903
+ this.emit("db:plugin:initialized", {
27791
27904
  replicator: this.name,
27792
27905
  queueUrl: this.queueUrl,
27793
27906
  queues: this.queues,
@@ -27817,7 +27930,7 @@ class SqsReplicator extends BaseReplicator {
27817
27930
  });
27818
27931
  const result2 = await this.sqsClient.send(command);
27819
27932
  results.push({ queueUrl, messageId: result2.MessageId });
27820
- this.emit("replicated", {
27933
+ this.emit("plg:replicator:replicated", {
27821
27934
  replicator: this.name,
27822
27935
  resource,
27823
27936
  operation,
@@ -27833,7 +27946,7 @@ class SqsReplicator extends BaseReplicator {
27833
27946
  if (this.config.verbose) {
27834
27947
  console.warn(`[SqsReplicator] Replication failed for ${resource}: ${err.message}`);
27835
27948
  }
27836
- this.emit("replicator_error", {
27949
+ this.emit("plg:replicator:error", {
27837
27950
  replicator: this.name,
27838
27951
  resource,
27839
27952
  operation,
@@ -28230,7 +28343,7 @@ ${createSQL}`);
28230
28343
  }
28231
28344
  }
28232
28345
  const success = errors.length === 0;
28233
- this.emit("replicated", {
28346
+ this.emit("plg:replicator:replicated", {
28234
28347
  replicator: this.name,
28235
28348
  resourceName,
28236
28349
  operation,
@@ -28516,7 +28629,7 @@ class WebhookReplicator extends BaseReplicator {
28516
28629
  });
28517
28630
  throw error;
28518
28631
  }
28519
- this.emit("initialized", {
28632
+ this.emit("db:plugin:initialized", {
28520
28633
  replicator: this.name,
28521
28634
  url: this.url,
28522
28635
  method: this.method,
@@ -28536,7 +28649,7 @@ class WebhookReplicator extends BaseReplicator {
28536
28649
  const payload = this.createPayload(resource, operation, transformedData, id, beforeData);
28537
28650
  const response = await this._makeRequest(payload);
28538
28651
  if (response.success) {
28539
- this.emit("replicated", {
28652
+ this.emit("plg:replicator:replicated", {
28540
28653
  replicator: this.name,
28541
28654
  resource,
28542
28655
  operation,
@@ -28553,7 +28666,7 @@ class WebhookReplicator extends BaseReplicator {
28553
28666
  if (this.config.verbose) {
28554
28667
  console.warn(`[WebhookReplicator] Replication failed for ${resource}: ${err.message}`);
28555
28668
  }
28556
- this.emit("replicator_error", {
28669
+ this.emit("plg:replicator:error", {
28557
28670
  replicator: this.name,
28558
28671
  resource,
28559
28672
  operation,
@@ -28832,13 +28945,13 @@ class ReplicatorPlugin extends Plugin {
28832
28945
  }
28833
28946
  };
28834
28947
  this.eventHandlers.set(resource.name, {
28835
- insert: insertHandler,
28836
- update: updateHandler,
28837
- delete: deleteHandler
28948
+ inserted: insertHandler,
28949
+ updated: updateHandler,
28950
+ deleted: deleteHandler
28838
28951
  });
28839
- resource.on("insert", insertHandler);
28840
- resource.on("update", updateHandler);
28841
- resource.on("delete", deleteHandler);
28952
+ resource.on("inserted", insertHandler);
28953
+ resource.on("updated", updateHandler);
28954
+ resource.on("deleted", deleteHandler);
28842
28955
  this.eventListenersInstalled.add(resource.name);
28843
28956
  }
28844
28957
  async onInstall() {
@@ -29228,9 +29341,9 @@ class ReplicatorPlugin extends Plugin {
29228
29341
  const resource = this.database.resources[resourceName];
29229
29342
  const handlers = this.eventHandlers.get(resourceName);
29230
29343
  if (resource && handlers) {
29231
- resource.off("insert", handlers.insert);
29232
- resource.off("update", handlers.update);
29233
- resource.off("delete", handlers.delete);
29344
+ resource.off("inserted", handlers.inserted);
29345
+ resource.off("updated", handlers.updated);
29346
+ resource.off("deleted", handlers.deleted);
29234
29347
  }
29235
29348
  }
29236
29349
  }
@@ -29359,7 +29472,7 @@ class S3QueuePlugin extends Plugin {
29359
29472
  createdAt: (/* @__PURE__ */ new Date()).toISOString().slice(0, 10)
29360
29473
  };
29361
29474
  await plugin.queueResource.insert(queueEntry);
29362
- plugin.emit("message.enqueued", { id: record.id, queueId: queueEntry.id });
29475
+ plugin.emit("plg:s3-queue:message-enqueued", { id: record.id, queueId: queueEntry.id });
29363
29476
  return record;
29364
29477
  };
29365
29478
  resource.queueStats = async function() {
@@ -30620,6 +30733,7 @@ class StateMachinePlugin extends Plugin {
30620
30733
  // entityId -> currentState
30621
30734
  });
30622
30735
  }
30736
+ await this._attachStateMachinesToResources();
30623
30737
  await this._setupTriggers();
30624
30738
  this.emit("db:plugin:initialized", { machines: Array.from(this.machines.keys()) });
30625
30739
  }
@@ -31461,6 +31575,58 @@ class StateMachinePlugin extends Plugin {
31461
31575
  }
31462
31576
  }
31463
31577
  }
31578
+ /**
31579
+ * Attach state machine instances to their associated resources
31580
+ * This enables the resource API: resource.state(id, event)
31581
+ * @private
31582
+ */
31583
+ async _attachStateMachinesToResources() {
31584
+ for (const [machineName, machineConfig] of Object.entries(this.config.stateMachines)) {
31585
+ const resourceConfig = machineConfig.config || machineConfig;
31586
+ if (!resourceConfig.resource) {
31587
+ if (this.config.verbose) {
31588
+ console.log(`[StateMachinePlugin] Machine '${machineName}' has no resource configured, skipping attachment`);
31589
+ }
31590
+ continue;
31591
+ }
31592
+ let resource;
31593
+ if (typeof resourceConfig.resource === "string") {
31594
+ resource = this.database.resources[resourceConfig.resource];
31595
+ if (!resource) {
31596
+ console.warn(
31597
+ `[StateMachinePlugin] Resource '${resourceConfig.resource}' not found for machine '${machineName}'. Resource API will not be available.`
31598
+ );
31599
+ continue;
31600
+ }
31601
+ } else {
31602
+ resource = resourceConfig.resource;
31603
+ }
31604
+ const machineProxy = {
31605
+ send: async (id, event, eventData) => {
31606
+ return this.send(machineName, id, event, eventData);
31607
+ },
31608
+ getState: async (id) => {
31609
+ return this.getState(machineName, id);
31610
+ },
31611
+ canTransition: async (id, event) => {
31612
+ return this.canTransition(machineName, id, event);
31613
+ },
31614
+ getValidEvents: async (id) => {
31615
+ return this.getValidEvents(machineName, id);
31616
+ },
31617
+ initializeEntity: async (id, context) => {
31618
+ return this.initializeEntity(machineName, id, context);
31619
+ },
31620
+ getTransitionHistory: async (id, options) => {
31621
+ return this.getTransitionHistory(machineName, id, options);
31622
+ }
31623
+ };
31624
+ resource._attachStateMachine(machineProxy);
31625
+ if (this.config.verbose) {
31626
+ console.log(`[StateMachinePlugin] Attached machine '${machineName}' to resource '${resource.name}'`);
31627
+ }
31628
+ }
31629
+ }
31464
31630
  async start() {
31465
31631
  if (this.config.verbose) {
31466
31632
  console.log(`[StateMachinePlugin] Started with ${this.machines.size} state machines`);
@@ -43725,6 +43891,7 @@ class MemoryClient extends EventEmitter {
43725
43891
  const commandName = command.constructor.name;
43726
43892
  const input = command.input || {};
43727
43893
  this.emit("cl:request", commandName, input);
43894
+ this.emit("command.request", commandName, input);
43728
43895
  let response;
43729
43896
  try {
43730
43897
  switch (commandName) {
@@ -43753,6 +43920,7 @@ class MemoryClient extends EventEmitter {
43753
43920
  throw new Error(`Unsupported command: ${commandName}`);
43754
43921
  }
43755
43922
  this.emit("cl:response", commandName, response, input);
43923
+ this.emit("command.response", commandName, response, input);
43756
43924
  return response;
43757
43925
  } catch (error) {
43758
43926
  const mappedError = mapAwsError(error, {
@@ -44048,13 +44216,13 @@ class MemoryClient extends EventEmitter {
44048
44216
  if (keys.length > 0) {
44049
44217
  const result = await this.deleteObjects(keys);
44050
44218
  totalDeleted = result.Deleted.length;
44051
- this.emit("cl:DeleteAll", {
44219
+ this.emit("deleteAll", {
44052
44220
  prefix,
44053
44221
  batch: totalDeleted,
44054
44222
  total: totalDeleted
44055
44223
  });
44056
44224
  }
44057
- this.emit("cl:DeleteAllComplete", {
44225
+ this.emit("deleteAllComplete", {
44058
44226
  prefix,
44059
44227
  totalDeleted
44060
44228
  });
@@ -44101,7 +44269,7 @@ class MemoryClient extends EventEmitter {
44101
44269
  });
44102
44270
  }
44103
44271
  }
44104
- this.emit("cl:MoveAllObjects", { results, errors }, { prefixFrom, prefixTo });
44272
+ this.emit("moveAllObjects", { results, errors });
44105
44273
  if (errors.length > 0) {
44106
44274
  const error = new Error("Some objects could not be moved");
44107
44275
  error.context = {