s3db.js 13.1.0 → 13.2.2
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/README.md +9 -9
- package/dist/s3db.cjs.js +1249 -271
- package/dist/s3db.cjs.js.map +1 -1
- package/dist/s3db.es.js +1249 -271
- package/dist/s3db.es.js.map +1 -1
- package/package.json +2 -1
- package/src/clients/memory-client.class.js +16 -16
- package/src/clients/s3-client.class.js +17 -17
- package/src/concerns/error-classifier.js +204 -0
- package/src/database.class.js +9 -9
- package/src/plugins/backup.plugin.js +8 -8
- package/src/plugins/cache.plugin.js +3 -3
- package/src/plugins/concerns/plugin-dependencies.js +12 -0
- package/src/plugins/geo.plugin.js +2 -2
- package/src/plugins/ml.plugin.js +337 -137
- package/src/plugins/relation.plugin.js +1 -1
- package/src/plugins/replicator.plugin.js +16 -16
- package/src/plugins/s3-queue.plugin.js +5 -5
- package/src/plugins/scheduler.plugin.js +7 -7
- package/src/plugins/state-machine.errors.js +9 -1
- package/src/plugins/state-machine.plugin.js +671 -16
- package/src/plugins/ttl.plugin.js +4 -4
- package/src/plugins/vector.plugin.js +10 -10
- package/src/resource.class.js +189 -40
|
@@ -350,7 +350,7 @@ export class RelationPlugin extends Plugin {
|
|
|
350
350
|
console.log(`[RelationPlugin] Installed with ${Object.keys(this.relations).length} resources`);
|
|
351
351
|
}
|
|
352
352
|
|
|
353
|
-
this.emit('installed', {
|
|
353
|
+
this.emit('db:plugin:installed', {
|
|
354
354
|
plugin: 'RelationPlugin',
|
|
355
355
|
resources: Object.keys(this.relations)
|
|
356
356
|
});
|
|
@@ -217,7 +217,7 @@ export class ReplicatorPlugin extends Plugin {
|
|
|
217
217
|
if (this.config.verbose) {
|
|
218
218
|
console.warn(`[ReplicatorPlugin] Insert event failed for resource ${resource.name}: ${error.message}`);
|
|
219
219
|
}
|
|
220
|
-
this.emit('error', { operation: 'insert', error: error.message, resource: resource.name });
|
|
220
|
+
this.emit('plg:replicator:error', { operation: 'insert', error: error.message, resource: resource.name });
|
|
221
221
|
}
|
|
222
222
|
};
|
|
223
223
|
|
|
@@ -233,7 +233,7 @@ export class ReplicatorPlugin extends Plugin {
|
|
|
233
233
|
if (this.config.verbose) {
|
|
234
234
|
console.warn(`[ReplicatorPlugin] Update event failed for resource ${resource.name}: ${error.message}`);
|
|
235
235
|
}
|
|
236
|
-
this.emit('error', { operation: 'update', error: error.message, resource: resource.name });
|
|
236
|
+
this.emit('plg:replicator:error', { operation: 'update', error: error.message, resource: resource.name });
|
|
237
237
|
}
|
|
238
238
|
};
|
|
239
239
|
|
|
@@ -246,7 +246,7 @@ export class ReplicatorPlugin extends Plugin {
|
|
|
246
246
|
if (this.config.verbose) {
|
|
247
247
|
console.warn(`[ReplicatorPlugin] Delete event failed for resource ${resource.name}: ${error.message}`);
|
|
248
248
|
}
|
|
249
|
-
this.emit('error', { operation: 'delete', error: error.message, resource: resource.name });
|
|
249
|
+
this.emit('plg:replicator:error', { operation: 'delete', error: error.message, resource: resource.name });
|
|
250
250
|
}
|
|
251
251
|
};
|
|
252
252
|
|
|
@@ -403,7 +403,7 @@ export class ReplicatorPlugin extends Plugin {
|
|
|
403
403
|
if (this.config.verbose) {
|
|
404
404
|
console.warn(`[ReplicatorPlugin] Failed to log error for ${resourceName}: ${logError.message}`);
|
|
405
405
|
}
|
|
406
|
-
this.emit('
|
|
406
|
+
this.emit('plg:replicator:log-error', {
|
|
407
407
|
replicator: replicator.name || replicator.id,
|
|
408
408
|
resourceName,
|
|
409
409
|
operation,
|
|
@@ -433,7 +433,7 @@ export class ReplicatorPlugin extends Plugin {
|
|
|
433
433
|
this.config.maxRetries
|
|
434
434
|
);
|
|
435
435
|
|
|
436
|
-
this.emit('replicated', {
|
|
436
|
+
this.emit('plg:replicator:replicated', {
|
|
437
437
|
replicator: replicator.name || replicator.id,
|
|
438
438
|
resourceName,
|
|
439
439
|
operation,
|
|
@@ -452,7 +452,7 @@ export class ReplicatorPlugin extends Plugin {
|
|
|
452
452
|
console.warn(`[ReplicatorPlugin] Replication failed for ${replicator.name || replicator.id} on ${resourceName}: ${error.message}`);
|
|
453
453
|
}
|
|
454
454
|
|
|
455
|
-
this.emit('
|
|
455
|
+
this.emit('plg:replicator:error', {
|
|
456
456
|
replicator: replicator.name || replicator.id,
|
|
457
457
|
resourceName,
|
|
458
458
|
operation,
|
|
@@ -492,7 +492,7 @@ export class ReplicatorPlugin extends Plugin {
|
|
|
492
492
|
console.warn(`[ReplicatorPlugin] Replicator item processing failed for ${replicator.name || replicator.id} on ${item.resourceName}: ${err.message}`);
|
|
493
493
|
}
|
|
494
494
|
|
|
495
|
-
this.emit('
|
|
495
|
+
this.emit('plg:replicator:error', {
|
|
496
496
|
replicator: replicator.name || replicator.id,
|
|
497
497
|
resourceName: item.resourceName,
|
|
498
498
|
operation: item.operation,
|
|
@@ -507,7 +507,7 @@ export class ReplicatorPlugin extends Plugin {
|
|
|
507
507
|
return { success: false, error: err.message };
|
|
508
508
|
}
|
|
509
509
|
|
|
510
|
-
this.emit('replicated', {
|
|
510
|
+
this.emit('plg:replicator:replicated', {
|
|
511
511
|
replicator: replicator.name || replicator.id,
|
|
512
512
|
resourceName: item.resourceName,
|
|
513
513
|
operation: item.operation,
|
|
@@ -526,7 +526,7 @@ export class ReplicatorPlugin extends Plugin {
|
|
|
526
526
|
console.warn(`[ReplicatorPlugin] Wrapper processing failed for ${replicator.name || replicator.id} on ${item.resourceName}: ${wrapperError.message}`);
|
|
527
527
|
}
|
|
528
528
|
|
|
529
|
-
this.emit('
|
|
529
|
+
this.emit('plg:replicator:error', {
|
|
530
530
|
replicator: replicator.name || replicator.id,
|
|
531
531
|
resourceName: item.resourceName,
|
|
532
532
|
operation: item.operation,
|
|
@@ -549,7 +549,7 @@ export class ReplicatorPlugin extends Plugin {
|
|
|
549
549
|
// Always use the saved reference
|
|
550
550
|
const logRes = this.replicatorLog || this.database.resources[normalizeResourceName(this.config.replicatorLogResource)];
|
|
551
551
|
if (!logRes) {
|
|
552
|
-
this.emit('replicator
|
|
552
|
+
this.emit('plg:replicator:log-failed', { error: 'replicator log resource not found', item });
|
|
553
553
|
return;
|
|
554
554
|
}
|
|
555
555
|
// Fix required fields of log resource
|
|
@@ -569,7 +569,7 @@ export class ReplicatorPlugin extends Plugin {
|
|
|
569
569
|
if (this.config.verbose) {
|
|
570
570
|
console.warn(`[ReplicatorPlugin] Failed to log replicator item: ${err.message}`);
|
|
571
571
|
}
|
|
572
|
-
this.emit('replicator
|
|
572
|
+
this.emit('plg:replicator:log-failed', { error: err, item });
|
|
573
573
|
}
|
|
574
574
|
}
|
|
575
575
|
|
|
@@ -584,7 +584,7 @@ export class ReplicatorPlugin extends Plugin {
|
|
|
584
584
|
});
|
|
585
585
|
});
|
|
586
586
|
if (!ok) {
|
|
587
|
-
this.emit('replicator
|
|
587
|
+
this.emit('plg:replicator:update-log-failed', { error: err.message, logId, updates });
|
|
588
588
|
}
|
|
589
589
|
}
|
|
590
590
|
|
|
@@ -690,7 +690,7 @@ export class ReplicatorPlugin extends Plugin {
|
|
|
690
690
|
if (normalizeResourceName(resourceName) === normalizeResourceName('plg_replicator_logs')) continue;
|
|
691
691
|
|
|
692
692
|
if (replicator.shouldReplicateResource(resourceName)) {
|
|
693
|
-
this.emit('replicator
|
|
693
|
+
this.emit('plg:replicator:sync-resource', { resourceName, replicatorId });
|
|
694
694
|
|
|
695
695
|
const resource = this.database.resources[resourceName];
|
|
696
696
|
|
|
@@ -715,7 +715,7 @@ export class ReplicatorPlugin extends Plugin {
|
|
|
715
715
|
}
|
|
716
716
|
}
|
|
717
717
|
|
|
718
|
-
this.emit('replicator
|
|
718
|
+
this.emit('plg:replicator:sync-completed', { replicatorId, stats: this.stats });
|
|
719
719
|
}
|
|
720
720
|
|
|
721
721
|
async stop() {
|
|
@@ -732,7 +732,7 @@ export class ReplicatorPlugin extends Plugin {
|
|
|
732
732
|
if (this.config.verbose) {
|
|
733
733
|
console.warn(`[ReplicatorPlugin] Failed to stop replicator ${replicator.name || replicator.id}: ${replicatorError.message}`);
|
|
734
734
|
}
|
|
735
|
-
this.emit('
|
|
735
|
+
this.emit('plg:replicator:stop-error', {
|
|
736
736
|
replicator: replicator.name || replicator.id || 'unknown',
|
|
737
737
|
driver: replicator.driver || 'unknown',
|
|
738
738
|
error: replicatorError.message
|
|
@@ -772,7 +772,7 @@ export class ReplicatorPlugin extends Plugin {
|
|
|
772
772
|
if (this.config.verbose) {
|
|
773
773
|
console.warn(`[ReplicatorPlugin] Failed to stop plugin: ${error.message}`);
|
|
774
774
|
}
|
|
775
|
-
this.emit('
|
|
775
|
+
this.emit('plg:replicator:plugin-stop-error', {
|
|
776
776
|
error: error.message
|
|
777
777
|
});
|
|
778
778
|
}
|
|
@@ -262,7 +262,7 @@ export class S3QueuePlugin extends Plugin {
|
|
|
262
262
|
console.log(`[S3QueuePlugin] Started ${concurrency} workers`);
|
|
263
263
|
}
|
|
264
264
|
|
|
265
|
-
this.emit('workers
|
|
265
|
+
this.emit('plg:s3-queue:workers-started', { concurrency, workerId: this.workerId });
|
|
266
266
|
}
|
|
267
267
|
|
|
268
268
|
async stopProcessing() {
|
|
@@ -289,7 +289,7 @@ export class S3QueuePlugin extends Plugin {
|
|
|
289
289
|
console.log('[S3QueuePlugin] Stopped all workers');
|
|
290
290
|
}
|
|
291
291
|
|
|
292
|
-
this.emit('workers
|
|
292
|
+
this.emit('plg:s3-queue:workers-stopped', { workerId: this.workerId });
|
|
293
293
|
}
|
|
294
294
|
|
|
295
295
|
createWorker(handler, workerIndex) {
|
|
@@ -518,7 +518,7 @@ export class S3QueuePlugin extends Plugin {
|
|
|
518
518
|
|
|
519
519
|
const duration = Date.now() - startTime;
|
|
520
520
|
|
|
521
|
-
this.emit('message
|
|
521
|
+
this.emit('plg:s3-queue:message-completed', {
|
|
522
522
|
queueId: message.queueId,
|
|
523
523
|
originalId: message.record.id,
|
|
524
524
|
duration,
|
|
@@ -537,7 +537,7 @@ export class S3QueuePlugin extends Plugin {
|
|
|
537
537
|
// Retry with backoff
|
|
538
538
|
await this.retryMessage(message.queueId, message.attempts, error.message);
|
|
539
539
|
|
|
540
|
-
this.emit('message
|
|
540
|
+
this.emit('plg:s3-queue:message-retry', {
|
|
541
541
|
queueId: message.queueId,
|
|
542
542
|
originalId: message.record.id,
|
|
543
543
|
attempts: message.attempts,
|
|
@@ -547,7 +547,7 @@ export class S3QueuePlugin extends Plugin {
|
|
|
547
547
|
// Max attempts reached - move to dead letter queue
|
|
548
548
|
await this.moveToDeadLetter(message.queueId, message.record, error.message);
|
|
549
549
|
|
|
550
|
-
this.emit('message
|
|
550
|
+
this.emit('plg:s3-queue:message-dead', {
|
|
551
551
|
queueId: message.queueId,
|
|
552
552
|
originalId: message.record.id,
|
|
553
553
|
error: error.message
|
|
@@ -272,7 +272,7 @@ export class SchedulerPlugin extends Plugin {
|
|
|
272
272
|
// Start scheduling
|
|
273
273
|
await this._startScheduling();
|
|
274
274
|
|
|
275
|
-
this.emit('initialized', { jobs: this.jobs.size });
|
|
275
|
+
this.emit('db:plugin:initialized', { jobs: this.jobs.size });
|
|
276
276
|
}
|
|
277
277
|
|
|
278
278
|
|
|
@@ -450,7 +450,7 @@ export class SchedulerPlugin extends Plugin {
|
|
|
450
450
|
await this._executeHook(this.config.onJobStart, jobName, context);
|
|
451
451
|
}
|
|
452
452
|
|
|
453
|
-
this.emit('
|
|
453
|
+
this.emit('plg:scheduler:job-start', { jobName, executionId, startTime });
|
|
454
454
|
|
|
455
455
|
let attempt = 0;
|
|
456
456
|
let lastError = null;
|
|
@@ -547,7 +547,7 @@ export class SchedulerPlugin extends Plugin {
|
|
|
547
547
|
await this._executeHook(this.config.onJobError, jobName, lastError, attempt);
|
|
548
548
|
}
|
|
549
549
|
|
|
550
|
-
this.emit('
|
|
550
|
+
this.emit('plg:scheduler:job-complete', {
|
|
551
551
|
jobName,
|
|
552
552
|
executionId,
|
|
553
553
|
status,
|
|
@@ -649,7 +649,7 @@ export class SchedulerPlugin extends Plugin {
|
|
|
649
649
|
job.enabled = true;
|
|
650
650
|
this._scheduleNextExecution(jobName);
|
|
651
651
|
|
|
652
|
-
this.emit('
|
|
652
|
+
this.emit('plg:scheduler:job-enabled', { jobName });
|
|
653
653
|
}
|
|
654
654
|
|
|
655
655
|
/**
|
|
@@ -675,7 +675,7 @@ export class SchedulerPlugin extends Plugin {
|
|
|
675
675
|
this.timers.delete(jobName);
|
|
676
676
|
}
|
|
677
677
|
|
|
678
|
-
this.emit('
|
|
678
|
+
this.emit('plg:scheduler:job-disabled', { jobName });
|
|
679
679
|
}
|
|
680
680
|
|
|
681
681
|
/**
|
|
@@ -837,7 +837,7 @@ export class SchedulerPlugin extends Plugin {
|
|
|
837
837
|
this._scheduleNextExecution(jobName);
|
|
838
838
|
}
|
|
839
839
|
|
|
840
|
-
this.emit('
|
|
840
|
+
this.emit('plg:scheduler:job-added', { jobName });
|
|
841
841
|
}
|
|
842
842
|
|
|
843
843
|
/**
|
|
@@ -866,7 +866,7 @@ export class SchedulerPlugin extends Plugin {
|
|
|
866
866
|
this.statistics.delete(jobName);
|
|
867
867
|
this.activeJobs.delete(jobName);
|
|
868
868
|
|
|
869
|
-
this.emit('
|
|
869
|
+
this.emit('plg:scheduler:job-removed', { jobName });
|
|
870
870
|
}
|
|
871
871
|
|
|
872
872
|
/**
|
|
@@ -14,7 +14,7 @@ import { S3dbError } from '../errors.js';
|
|
|
14
14
|
*/
|
|
15
15
|
export class StateMachineError extends S3dbError {
|
|
16
16
|
constructor(message, details = {}) {
|
|
17
|
-
const { currentState, targetState, resourceName, operation = 'unknown', ...rest } = details;
|
|
17
|
+
const { currentState, targetState, resourceName, operation = 'unknown', retriable, ...rest } = details;
|
|
18
18
|
|
|
19
19
|
let description = details.description;
|
|
20
20
|
if (!description) {
|
|
@@ -41,6 +41,14 @@ Docs: https://github.com/forattini-dev/s3db.js/blob/main/docs/plugins/state-mach
|
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
super(message, { ...rest, currentState, targetState, resourceName, operation, description });
|
|
44
|
+
|
|
45
|
+
// Support retriable property for error classification
|
|
46
|
+
// retriable: true = will be retried
|
|
47
|
+
// retriable: false = will not be retried
|
|
48
|
+
// retriable: undefined = classified by ErrorClassifier
|
|
49
|
+
if (retriable !== undefined) {
|
|
50
|
+
this.retriable = retriable;
|
|
51
|
+
}
|
|
44
52
|
}
|
|
45
53
|
}
|
|
46
54
|
|