s3db.js 13.2.2 → 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 +180 -182
- package/dist/s3db.cjs.js.map +1 -1
- package/dist/s3db.es.js +180 -182
- package/dist/s3db.es.js.map +1 -1
- package/package.json +1 -1
- package/src/clients/memory-client.class.js +5 -3
- package/src/database.class.js +6 -3
- package/src/plugins/audit.plugin.js +3 -3
- package/src/plugins/cache/cache.class.js +2 -2
- package/src/plugins/costs.plugin.js +3 -2
- package/src/plugins/replicator.plugin.js +10 -10
- package/src/plugins/replicators/base-replicator.class.js +1 -1
- package/src/plugins/replicators/bigquery-replicator.class.js +3 -3
- package/src/plugins/replicators/planetscale-replicator.class.js +1 -1
- package/src/plugins/replicators/postgres-replicator.class.js +3 -3
- package/src/plugins/replicators/sqs-replicator.class.js +3 -3
- package/src/plugins/replicators/turso-replicator.class.js +1 -1
- package/src/plugins/replicators/webhook-replicator.class.js +3 -3
- package/src/plugins/s3-queue.plugin.js +1 -1
- package/src/resource.class.js +149 -155
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("
|
|
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("
|
|
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("
|
|
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("
|
|
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("
|
|
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("
|
|
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("
|
|
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("
|
|
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._emitStandardized("
|
|
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._emitStandardized("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._emitStandardized("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._emitStandardized("
|
|
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._emitStandardized("
|
|
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._emitStandardized("
|
|
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._emitStandardized("
|
|
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._emitStandardized("
|
|
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._emitStandardized("list",
|
|
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._emitStandardized("list",
|
|
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._emitStandardized("list",
|
|
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._emitStandardized("list",
|
|
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._emitStandardized("list",
|
|
25074
|
+
this._emitStandardized("list", { partition, partitionValues, count: 0, errors: 1 });
|
|
25077
25075
|
return [];
|
|
25078
25076
|
}
|
|
25079
|
-
this._emitStandardized("list",
|
|
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._emitStandardized("
|
|
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._emitStandardized("
|
|
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._emitStandardized("
|
|
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._emitStandardized("content
|
|
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._emitStandardized("
|
|
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._emitStandardized("
|
|
25639
|
+
this._emitStandardized("partition-fetched", data, data.id);
|
|
25642
25640
|
return data;
|
|
25643
25641
|
}
|
|
25644
25642
|
/**
|
|
@@ -25891,109 +25889,106 @@ ${errorDetails}`,
|
|
|
25891
25889
|
// STATE MACHINE METHODS
|
|
25892
25890
|
// ============================================================================
|
|
25893
25891
|
/**
|
|
25894
|
-
*
|
|
25895
|
-
*
|
|
25896
|
-
* @
|
|
25897
|
-
* @
|
|
25898
|
-
* @
|
|
25899
|
-
* @
|
|
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
|
|
25900
25901
|
* @example
|
|
25901
|
-
* await orders.state('order-123', 'CONFIRM'
|
|
25902
|
-
|
|
25903
|
-
|
|
25904
|
-
|
|
25905
|
-
|
|
25906
|
-
|
|
25907
|
-
|
|
25908
|
-
|
|
25909
|
-
|
|
25910
|
-
|
|
25911
|
-
|
|
25912
|
-
|
|
25913
|
-
|
|
25914
|
-
|
|
25915
|
-
|
|
25916
|
-
|
|
25917
|
-
|
|
25918
|
-
|
|
25919
|
-
|
|
25920
|
-
|
|
25921
|
-
|
|
25922
|
-
|
|
25923
|
-
|
|
25924
|
-
|
|
25925
|
-
|
|
25926
|
-
|
|
25927
|
-
|
|
25928
|
-
|
|
25929
|
-
|
|
25930
|
-
|
|
25931
|
-
|
|
25932
|
-
|
|
25933
|
-
|
|
25934
|
-
|
|
25935
|
-
|
|
25936
|
-
|
|
25937
|
-
|
|
25938
|
-
|
|
25939
|
-
|
|
25940
|
-
|
|
25941
|
-
|
|
25942
|
-
|
|
25943
|
-
|
|
25944
|
-
|
|
25945
|
-
|
|
25946
|
-
|
|
25947
|
-
|
|
25948
|
-
|
|
25949
|
-
|
|
25950
|
-
|
|
25951
|
-
|
|
25952
|
-
|
|
25953
|
-
|
|
25954
|
-
|
|
25955
|
-
|
|
25956
|
-
|
|
25957
|
-
|
|
25958
|
-
|
|
25959
|
-
|
|
25960
|
-
|
|
25961
|
-
|
|
25962
|
-
|
|
25963
|
-
|
|
25964
|
-
|
|
25965
|
-
|
|
25966
|
-
|
|
25967
|
-
|
|
25968
|
-
|
|
25969
|
-
|
|
25970
|
-
|
|
25971
|
-
|
|
25972
|
-
|
|
25973
|
-
|
|
25974
|
-
|
|
25975
|
-
|
|
25976
|
-
|
|
25977
|
-
|
|
25978
|
-
|
|
25979
|
-
|
|
25980
|
-
|
|
25981
|
-
|
|
25982
|
-
|
|
25983
|
-
|
|
25984
|
-
|
|
25985
|
-
|
|
25986
|
-
|
|
25987
|
-
|
|
25988
|
-
|
|
25989
|
-
|
|
25990
|
-
|
|
25991
|
-
if (!this._stateMachine) {
|
|
25992
|
-
throw new Error(
|
|
25993
|
-
`No state machine configured for resource '${this.name}'. Ensure StateMachinePlugin is installed and configured for this resource.`
|
|
25994
|
-
);
|
|
25995
|
-
}
|
|
25996
|
-
return this._stateMachine.getTransitionHistory(id, options);
|
|
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
|
+
};
|
|
25997
25992
|
}
|
|
25998
25993
|
/**
|
|
25999
25994
|
* Internal method to attach state machine instance
|
|
@@ -26164,7 +26159,7 @@ class Database extends EventEmitter {
|
|
|
26164
26159
|
})();
|
|
26165
26160
|
this.version = "1";
|
|
26166
26161
|
this.s3dbVersion = (() => {
|
|
26167
|
-
const [ok, err, version] = tryFn(() => true ? "13.
|
|
26162
|
+
const [ok, err, version] = tryFn(() => true ? "13.3.0" : "latest");
|
|
26168
26163
|
return ok ? version : "latest";
|
|
26169
26164
|
})();
|
|
26170
26165
|
this._resourcesMap = {};
|
|
@@ -27009,7 +27004,7 @@ class Database extends EventEmitter {
|
|
|
27009
27004
|
if (!existingVersionData || existingVersionData.hash !== newHash) {
|
|
27010
27005
|
await this.uploadMetadataFile();
|
|
27011
27006
|
}
|
|
27012
|
-
this.emit("
|
|
27007
|
+
this.emit("s3db.resourceUpdated", name);
|
|
27013
27008
|
return existingResource;
|
|
27014
27009
|
}
|
|
27015
27010
|
const existingMetadata = this.savedMetadata?.resources?.[name];
|
|
@@ -27046,7 +27041,7 @@ class Database extends EventEmitter {
|
|
|
27046
27041
|
this._applyMiddlewares(resource, middlewares);
|
|
27047
27042
|
}
|
|
27048
27043
|
await this.uploadMetadataFile();
|
|
27049
|
-
this.emit("
|
|
27044
|
+
this.emit("s3db.resourceCreated", name);
|
|
27050
27045
|
return resource;
|
|
27051
27046
|
}
|
|
27052
27047
|
/**
|
|
@@ -27172,6 +27167,7 @@ class Database extends EventEmitter {
|
|
|
27172
27167
|
return !!this.savedMetadata;
|
|
27173
27168
|
}
|
|
27174
27169
|
async disconnect() {
|
|
27170
|
+
await this.emit("disconnected", /* @__PURE__ */ new Date());
|
|
27175
27171
|
await tryFn(async () => {
|
|
27176
27172
|
if (this.pluginList && this.pluginList.length > 0) {
|
|
27177
27173
|
for (const plugin of this.pluginList) {
|
|
@@ -27322,7 +27318,7 @@ class Database extends EventEmitter {
|
|
|
27322
27318
|
for (const hook of hooks) {
|
|
27323
27319
|
const [ok, error] = await tryFn(() => hook({ database: this, ...context }));
|
|
27324
27320
|
if (!ok) {
|
|
27325
|
-
this.emit("
|
|
27321
|
+
this.emit("hookError", { event, error, context });
|
|
27326
27322
|
if (this.strictHooks) {
|
|
27327
27323
|
throw new DatabaseError(`Hook execution failed for event '${event}': ${error.message}`, {
|
|
27328
27324
|
event,
|
|
@@ -27881,7 +27877,7 @@ class SqsReplicator extends BaseReplicator {
|
|
|
27881
27877
|
region: this.region,
|
|
27882
27878
|
credentials: this.config.credentials
|
|
27883
27879
|
});
|
|
27884
|
-
this.emit("initialized", {
|
|
27880
|
+
this.emit("db:plugin:initialized", {
|
|
27885
27881
|
replicator: this.name,
|
|
27886
27882
|
queueUrl: this.queueUrl,
|
|
27887
27883
|
queues: this.queues,
|
|
@@ -27911,7 +27907,7 @@ class SqsReplicator extends BaseReplicator {
|
|
|
27911
27907
|
});
|
|
27912
27908
|
const result2 = await this.sqsClient.send(command);
|
|
27913
27909
|
results.push({ queueUrl, messageId: result2.MessageId });
|
|
27914
|
-
this.emit("replicated", {
|
|
27910
|
+
this.emit("plg:replicator:replicated", {
|
|
27915
27911
|
replicator: this.name,
|
|
27916
27912
|
resource,
|
|
27917
27913
|
operation,
|
|
@@ -27927,7 +27923,7 @@ class SqsReplicator extends BaseReplicator {
|
|
|
27927
27923
|
if (this.config.verbose) {
|
|
27928
27924
|
console.warn(`[SqsReplicator] Replication failed for ${resource}: ${err.message}`);
|
|
27929
27925
|
}
|
|
27930
|
-
this.emit("
|
|
27926
|
+
this.emit("plg:replicator:error", {
|
|
27931
27927
|
replicator: this.name,
|
|
27932
27928
|
resource,
|
|
27933
27929
|
operation,
|
|
@@ -28324,7 +28320,7 @@ ${createSQL}`);
|
|
|
28324
28320
|
}
|
|
28325
28321
|
}
|
|
28326
28322
|
const success = errors.length === 0;
|
|
28327
|
-
this.emit("replicated", {
|
|
28323
|
+
this.emit("plg:replicator:replicated", {
|
|
28328
28324
|
replicator: this.name,
|
|
28329
28325
|
resourceName,
|
|
28330
28326
|
operation,
|
|
@@ -28610,7 +28606,7 @@ class WebhookReplicator extends BaseReplicator {
|
|
|
28610
28606
|
});
|
|
28611
28607
|
throw error;
|
|
28612
28608
|
}
|
|
28613
|
-
this.emit("initialized", {
|
|
28609
|
+
this.emit("db:plugin:initialized", {
|
|
28614
28610
|
replicator: this.name,
|
|
28615
28611
|
url: this.url,
|
|
28616
28612
|
method: this.method,
|
|
@@ -28630,7 +28626,7 @@ class WebhookReplicator extends BaseReplicator {
|
|
|
28630
28626
|
const payload = this.createPayload(resource, operation, transformedData, id, beforeData);
|
|
28631
28627
|
const response = await this._makeRequest(payload);
|
|
28632
28628
|
if (response.success) {
|
|
28633
|
-
this.emit("replicated", {
|
|
28629
|
+
this.emit("plg:replicator:replicated", {
|
|
28634
28630
|
replicator: this.name,
|
|
28635
28631
|
resource,
|
|
28636
28632
|
operation,
|
|
@@ -28647,7 +28643,7 @@ class WebhookReplicator extends BaseReplicator {
|
|
|
28647
28643
|
if (this.config.verbose) {
|
|
28648
28644
|
console.warn(`[WebhookReplicator] Replication failed for ${resource}: ${err.message}`);
|
|
28649
28645
|
}
|
|
28650
|
-
this.emit("
|
|
28646
|
+
this.emit("plg:replicator:error", {
|
|
28651
28647
|
replicator: this.name,
|
|
28652
28648
|
resource,
|
|
28653
28649
|
operation,
|
|
@@ -28926,13 +28922,13 @@ class ReplicatorPlugin extends Plugin {
|
|
|
28926
28922
|
}
|
|
28927
28923
|
};
|
|
28928
28924
|
this.eventHandlers.set(resource.name, {
|
|
28929
|
-
|
|
28930
|
-
|
|
28931
|
-
|
|
28925
|
+
inserted: insertHandler,
|
|
28926
|
+
updated: updateHandler,
|
|
28927
|
+
deleted: deleteHandler
|
|
28932
28928
|
});
|
|
28933
|
-
resource.on("
|
|
28934
|
-
resource.on("
|
|
28935
|
-
resource.on("
|
|
28929
|
+
resource.on("inserted", insertHandler);
|
|
28930
|
+
resource.on("updated", updateHandler);
|
|
28931
|
+
resource.on("deleted", deleteHandler);
|
|
28936
28932
|
this.eventListenersInstalled.add(resource.name);
|
|
28937
28933
|
}
|
|
28938
28934
|
async onInstall() {
|
|
@@ -29322,9 +29318,9 @@ class ReplicatorPlugin extends Plugin {
|
|
|
29322
29318
|
const resource = this.database.resources[resourceName];
|
|
29323
29319
|
const handlers = this.eventHandlers.get(resourceName);
|
|
29324
29320
|
if (resource && handlers) {
|
|
29325
|
-
resource.off("
|
|
29326
|
-
resource.off("
|
|
29327
|
-
resource.off("
|
|
29321
|
+
resource.off("inserted", handlers.inserted);
|
|
29322
|
+
resource.off("updated", handlers.updated);
|
|
29323
|
+
resource.off("deleted", handlers.deleted);
|
|
29328
29324
|
}
|
|
29329
29325
|
}
|
|
29330
29326
|
}
|
|
@@ -29453,7 +29449,7 @@ class S3QueuePlugin extends Plugin {
|
|
|
29453
29449
|
createdAt: (/* @__PURE__ */ new Date()).toISOString().slice(0, 10)
|
|
29454
29450
|
};
|
|
29455
29451
|
await plugin.queueResource.insert(queueEntry);
|
|
29456
|
-
plugin.emit("message
|
|
29452
|
+
plugin.emit("plg:s3-queue:message-enqueued", { id: record.id, queueId: queueEntry.id });
|
|
29457
29453
|
return record;
|
|
29458
29454
|
};
|
|
29459
29455
|
resource.queueStats = async function() {
|
|
@@ -43872,6 +43868,7 @@ class MemoryClient extends EventEmitter {
|
|
|
43872
43868
|
const commandName = command.constructor.name;
|
|
43873
43869
|
const input = command.input || {};
|
|
43874
43870
|
this.emit("cl:request", commandName, input);
|
|
43871
|
+
this.emit("command.request", commandName, input);
|
|
43875
43872
|
let response;
|
|
43876
43873
|
try {
|
|
43877
43874
|
switch (commandName) {
|
|
@@ -43900,6 +43897,7 @@ class MemoryClient extends EventEmitter {
|
|
|
43900
43897
|
throw new Error(`Unsupported command: ${commandName}`);
|
|
43901
43898
|
}
|
|
43902
43899
|
this.emit("cl:response", commandName, response, input);
|
|
43900
|
+
this.emit("command.response", commandName, response, input);
|
|
43903
43901
|
return response;
|
|
43904
43902
|
} catch (error) {
|
|
43905
43903
|
const mappedError = mapAwsError(error, {
|
|
@@ -44195,13 +44193,13 @@ class MemoryClient extends EventEmitter {
|
|
|
44195
44193
|
if (keys.length > 0) {
|
|
44196
44194
|
const result = await this.deleteObjects(keys);
|
|
44197
44195
|
totalDeleted = result.Deleted.length;
|
|
44198
|
-
this.emit("
|
|
44196
|
+
this.emit("deleteAll", {
|
|
44199
44197
|
prefix,
|
|
44200
44198
|
batch: totalDeleted,
|
|
44201
44199
|
total: totalDeleted
|
|
44202
44200
|
});
|
|
44203
44201
|
}
|
|
44204
|
-
this.emit("
|
|
44202
|
+
this.emit("deleteAllComplete", {
|
|
44205
44203
|
prefix,
|
|
44206
44204
|
totalDeleted
|
|
44207
44205
|
});
|
|
@@ -44248,7 +44246,7 @@ class MemoryClient extends EventEmitter {
|
|
|
44248
44246
|
});
|
|
44249
44247
|
}
|
|
44250
44248
|
}
|
|
44251
|
-
this.emit("
|
|
44249
|
+
this.emit("moveAllObjects", { results, errors });
|
|
44252
44250
|
if (errors.length > 0) {
|
|
44253
44251
|
const error = new Error("Some objects could not be moved");
|
|
44254
44252
|
error.context = {
|