s3db.js 13.0.0 → 13.2.1
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 +3637 -191
- package/dist/s3db.cjs.js.map +1 -1
- package/dist/s3db.es.js +3637 -191
- 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/api/index.js +1 -7
- package/src/plugins/api/routes/resource-routes.js +3 -3
- package/src/plugins/api/server.js +29 -9
- package/src/plugins/audit.plugin.js +2 -4
- package/src/plugins/backup.plugin.js +10 -12
- package/src/plugins/cache.plugin.js +4 -6
- package/src/plugins/concerns/plugin-dependencies.js +12 -0
- package/src/plugins/costs.plugin.js +0 -2
- package/src/plugins/eventual-consistency/index.js +1 -3
- package/src/plugins/fulltext.plugin.js +2 -4
- package/src/plugins/geo.plugin.js +3 -5
- package/src/plugins/importer/index.js +0 -2
- package/src/plugins/index.js +0 -1
- package/src/plugins/metrics.plugin.js +2 -4
- package/src/plugins/ml.plugin.js +1004 -42
- package/src/plugins/plugin.class.js +1 -3
- package/src/plugins/queue-consumer.plugin.js +1 -3
- package/src/plugins/relation.plugin.js +2 -4
- package/src/plugins/replicator.plugin.js +18 -20
- package/src/plugins/s3-queue.plugin.js +6 -8
- package/src/plugins/scheduler.plugin.js +9 -11
- package/src/plugins/state-machine.errors.js +9 -1
- package/src/plugins/state-machine.plugin.js +605 -20
- package/src/plugins/tfstate/index.js +0 -2
- package/src/plugins/ttl.plugin.js +40 -25
- package/src/plugins/vector.plugin.js +10 -12
- package/src/resource.class.js +58 -40
|
@@ -4,9 +4,6 @@
|
|
|
4
4
|
* Manages HTTP server lifecycle and routing
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import { Hono } from 'hono';
|
|
8
|
-
import { serve } from '@hono/node-server';
|
|
9
|
-
import { swaggerUI } from '@hono/swagger-ui';
|
|
10
7
|
import { createResourceRoutes, createRelationalRoutes } from './routes/resource-routes.js';
|
|
11
8
|
import { errorHandler } from './utils/error-handler.js';
|
|
12
9
|
import * as formatter from './utils/response-formatter.js';
|
|
@@ -46,17 +43,18 @@ export class ApiServer {
|
|
|
46
43
|
}
|
|
47
44
|
};
|
|
48
45
|
|
|
49
|
-
this.app =
|
|
46
|
+
this.app = null; // Will be initialized in start() with dynamic import
|
|
50
47
|
this.server = null;
|
|
51
48
|
this.isRunning = false;
|
|
52
49
|
this.openAPISpec = null;
|
|
50
|
+
this.initialized = false;
|
|
53
51
|
|
|
54
52
|
// Detect if RelationPlugin is installed
|
|
55
53
|
this.relationsPlugin = this.options.database?.plugins?.relation ||
|
|
56
54
|
this.options.database?.plugins?.RelationPlugin ||
|
|
57
55
|
null;
|
|
58
56
|
|
|
59
|
-
|
|
57
|
+
// Routes will be setup in start() after dynamic import
|
|
60
58
|
}
|
|
61
59
|
|
|
62
60
|
/**
|
|
@@ -170,7 +168,7 @@ export class ApiServer {
|
|
|
170
168
|
|
|
171
169
|
// API Documentation UI endpoint
|
|
172
170
|
if (this.options.docsUI === 'swagger') {
|
|
173
|
-
this.app.get('/docs', swaggerUI({
|
|
171
|
+
this.app.get('/docs', this.swaggerUI({
|
|
174
172
|
url: '/openapi.json'
|
|
175
173
|
}));
|
|
176
174
|
} else {
|
|
@@ -254,7 +252,7 @@ export class ApiServer {
|
|
|
254
252
|
methods: config.methods,
|
|
255
253
|
customMiddleware: config.customMiddleware || [],
|
|
256
254
|
enableValidation: config.validation !== false
|
|
257
|
-
});
|
|
255
|
+
}, this.Hono);
|
|
258
256
|
|
|
259
257
|
// Mount resource routes
|
|
260
258
|
this.app.route(`/${version}/${name}`, resourceApp);
|
|
@@ -317,7 +315,8 @@ export class ApiServer {
|
|
|
317
315
|
resource,
|
|
318
316
|
relationName,
|
|
319
317
|
relationConfig,
|
|
320
|
-
version
|
|
318
|
+
version,
|
|
319
|
+
this.Hono
|
|
321
320
|
);
|
|
322
321
|
|
|
323
322
|
// Mount relational routes at /{version}/{resource}/:id/{relation}
|
|
@@ -343,11 +342,32 @@ export class ApiServer {
|
|
|
343
342
|
return;
|
|
344
343
|
}
|
|
345
344
|
|
|
345
|
+
// Dynamic import of Hono dependencies (peer dependencies)
|
|
346
|
+
// This ensures hono is only loaded when server actually starts
|
|
347
|
+
if (!this.initialized) {
|
|
348
|
+
const { Hono } = await import('hono');
|
|
349
|
+
const { serve } = await import('@hono/node-server');
|
|
350
|
+
const { swaggerUI } = await import('@hono/swagger-ui');
|
|
351
|
+
|
|
352
|
+
// Store for use in _setupRoutes
|
|
353
|
+
this.Hono = Hono;
|
|
354
|
+
this.serve = serve;
|
|
355
|
+
this.swaggerUI = swaggerUI;
|
|
356
|
+
|
|
357
|
+
// Initialize app
|
|
358
|
+
this.app = new Hono();
|
|
359
|
+
|
|
360
|
+
// Setup all routes
|
|
361
|
+
this._setupRoutes();
|
|
362
|
+
|
|
363
|
+
this.initialized = true;
|
|
364
|
+
}
|
|
365
|
+
|
|
346
366
|
const { port, host } = this.options;
|
|
347
367
|
|
|
348
368
|
return new Promise((resolve, reject) => {
|
|
349
369
|
try {
|
|
350
|
-
this.server = serve({
|
|
370
|
+
this.server = this.serve({
|
|
351
371
|
fetch: this.app.fetch,
|
|
352
372
|
port,
|
|
353
373
|
hostname: host
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import Plugin from "./plugin.class.js";
|
|
1
|
+
import { Plugin } from "./plugin.class.js";
|
|
2
2
|
import tryFn from "../concerns/try-fn.js";
|
|
3
3
|
|
|
4
4
|
export class AuditPlugin extends Plugin {
|
|
@@ -420,6 +420,4 @@ export class AuditPlugin extends Plugin {
|
|
|
420
420
|
|
|
421
421
|
return deletedCount;
|
|
422
422
|
}
|
|
423
|
-
}
|
|
424
|
-
|
|
425
|
-
export default AuditPlugin;
|
|
423
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import Plugin from "./plugin.class.js";
|
|
1
|
+
import { Plugin } from "./plugin.class.js";
|
|
2
2
|
import tryFn from "../concerns/try-fn.js";
|
|
3
3
|
import { createBackupDriver, validateBackupConfig } from "./backup/index.js";
|
|
4
4
|
import { StreamingExporter } from "./backup/streaming-exporter.js";
|
|
@@ -149,7 +149,7 @@ export class BackupPlugin extends Plugin {
|
|
|
149
149
|
console.log(`[BackupPlugin] Initialized with driver: ${storageInfo.type}`);
|
|
150
150
|
}
|
|
151
151
|
|
|
152
|
-
this.emit('initialized', {
|
|
152
|
+
this.emit('db:plugin:initialized', {
|
|
153
153
|
driver: this.driver.getType(),
|
|
154
154
|
config: this.driver.getStorageInfo()
|
|
155
155
|
});
|
|
@@ -205,7 +205,7 @@ export class BackupPlugin extends Plugin {
|
|
|
205
205
|
await this._executeHook(this.config.onBackupStart, type, { backupId });
|
|
206
206
|
}
|
|
207
207
|
|
|
208
|
-
this.emit('
|
|
208
|
+
this.emit('plg:backup:start', { id: backupId, type });
|
|
209
209
|
|
|
210
210
|
// Create backup metadata
|
|
211
211
|
const metadata = await this._createBackupMetadata(backupId, type);
|
|
@@ -262,7 +262,7 @@ export class BackupPlugin extends Plugin {
|
|
|
262
262
|
await this._executeHook(this.config.onBackupComplete, type, stats);
|
|
263
263
|
}
|
|
264
264
|
|
|
265
|
-
this.emit('
|
|
265
|
+
this.emit('plg:backup:complete', {
|
|
266
266
|
id: backupId,
|
|
267
267
|
type,
|
|
268
268
|
size: totalSize,
|
|
@@ -300,7 +300,7 @@ export class BackupPlugin extends Plugin {
|
|
|
300
300
|
duration: Date.now() - startTime
|
|
301
301
|
});
|
|
302
302
|
|
|
303
|
-
this.emit('
|
|
303
|
+
this.emit('plg:backup:error', { id: backupId, type, error: error.message });
|
|
304
304
|
throw error;
|
|
305
305
|
|
|
306
306
|
} finally {
|
|
@@ -579,7 +579,7 @@ export class BackupPlugin extends Plugin {
|
|
|
579
579
|
await this._executeHook(this.config.onRestoreStart, backupId, options);
|
|
580
580
|
}
|
|
581
581
|
|
|
582
|
-
this.emit('
|
|
582
|
+
this.emit('plg:backup:restore-start', { id: backupId, options });
|
|
583
583
|
|
|
584
584
|
// Get backup metadata
|
|
585
585
|
const backup = await this.getBackupStatus(backupId);
|
|
@@ -616,7 +616,7 @@ export class BackupPlugin extends Plugin {
|
|
|
616
616
|
await this._executeHook(this.config.onRestoreComplete, backupId, { restored: restoredResources });
|
|
617
617
|
}
|
|
618
618
|
|
|
619
|
-
this.emit('
|
|
619
|
+
this.emit('plg:backup:restore-complete', {
|
|
620
620
|
id: backupId,
|
|
621
621
|
restored: restoredResources
|
|
622
622
|
});
|
|
@@ -637,7 +637,7 @@ export class BackupPlugin extends Plugin {
|
|
|
637
637
|
await this._executeHook(this.config.onRestoreError, backupId, { error });
|
|
638
638
|
}
|
|
639
639
|
|
|
640
|
-
this.emit('
|
|
640
|
+
this.emit('plg:backup:restore-error', { id: backupId, error: error.message });
|
|
641
641
|
throw error;
|
|
642
642
|
}
|
|
643
643
|
}
|
|
@@ -973,7 +973,7 @@ export class BackupPlugin extends Plugin {
|
|
|
973
973
|
async stop() {
|
|
974
974
|
// Cancel any active backups
|
|
975
975
|
for (const backupId of this.activeBackups) {
|
|
976
|
-
this.emit('
|
|
976
|
+
this.emit('plg:backup:cancelled', { id: backupId });
|
|
977
977
|
}
|
|
978
978
|
this.activeBackups.clear();
|
|
979
979
|
|
|
@@ -982,6 +982,4 @@ export class BackupPlugin extends Plugin {
|
|
|
982
982
|
await this.driver.cleanup();
|
|
983
983
|
}
|
|
984
984
|
}
|
|
985
|
-
}
|
|
986
|
-
|
|
987
|
-
export default BackupPlugin;
|
|
985
|
+
}
|
|
@@ -2,7 +2,7 @@ import { join } from "path";
|
|
|
2
2
|
import jsonStableStringify from "json-stable-stringify";
|
|
3
3
|
import crypto from 'crypto';
|
|
4
4
|
|
|
5
|
-
import Plugin from "./plugin.class.js";
|
|
5
|
+
import { Plugin } from "./plugin.class.js";
|
|
6
6
|
import S3Cache from "./cache/s3-cache.class.js";
|
|
7
7
|
import MemoryCache from "./cache/memory-cache.class.js";
|
|
8
8
|
import { FilesystemCache } from "./cache/filesystem-cache.class.js";
|
|
@@ -434,7 +434,7 @@ export class CachePlugin extends Plugin {
|
|
|
434
434
|
const [ok, err] = await this.clearCacheWithRetry(resource.cache, specificKey);
|
|
435
435
|
|
|
436
436
|
if (!ok) {
|
|
437
|
-
this.emit('
|
|
437
|
+
this.emit('plg:cache:clear-error', {
|
|
438
438
|
resource: resource.name,
|
|
439
439
|
method,
|
|
440
440
|
id: data.id,
|
|
@@ -456,7 +456,7 @@ export class CachePlugin extends Plugin {
|
|
|
456
456
|
const [ok, err] = await this.clearCacheWithRetry(resource.cache, partitionKeyPrefix);
|
|
457
457
|
|
|
458
458
|
if (!ok) {
|
|
459
|
-
this.emit('
|
|
459
|
+
this.emit('plg:cache:clear-error', {
|
|
460
460
|
resource: resource.name,
|
|
461
461
|
partition: partitionName,
|
|
462
462
|
error: err.message
|
|
@@ -475,7 +475,7 @@ export class CachePlugin extends Plugin {
|
|
|
475
475
|
const [ok, err] = await this.clearCacheWithRetry(resource.cache, keyPrefix);
|
|
476
476
|
|
|
477
477
|
if (!ok) {
|
|
478
|
-
this.emit('
|
|
478
|
+
this.emit('plg:cache:clear-error', {
|
|
479
479
|
resource: resource.name,
|
|
480
480
|
type: 'broad',
|
|
481
481
|
error: err.message
|
|
@@ -781,5 +781,3 @@ export class CachePlugin extends Plugin {
|
|
|
781
781
|
return parts.join(' ');
|
|
782
782
|
}
|
|
783
783
|
}
|
|
784
|
-
|
|
785
|
-
export default CachePlugin;
|
|
@@ -109,6 +109,18 @@ export const PLUGIN_DEPENDENCIES = {
|
|
|
109
109
|
npmUrl: 'https://www.npmjs.com/package/@hono/swagger-ui'
|
|
110
110
|
}
|
|
111
111
|
}
|
|
112
|
+
},
|
|
113
|
+
'ml-plugin': {
|
|
114
|
+
name: 'ML Plugin',
|
|
115
|
+
docsUrl: 'https://github.com/forattini-dev/s3db.js/blob/main/docs/plugins/ml-plugin.md',
|
|
116
|
+
dependencies: {
|
|
117
|
+
'@tensorflow/tfjs-node': {
|
|
118
|
+
version: '^4.0.0',
|
|
119
|
+
description: 'TensorFlow.js for Node.js with native bindings',
|
|
120
|
+
installCommand: 'pnpm add @tensorflow/tfjs-node',
|
|
121
|
+
npmUrl: 'https://www.npmjs.com/package/@tensorflow/tfjs-node'
|
|
122
|
+
}
|
|
123
|
+
}
|
|
112
124
|
}
|
|
113
125
|
};
|
|
114
126
|
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* @module eventual-consistency
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import Plugin from "../plugin.class.js";
|
|
7
|
+
import { Plugin } from "../plugin.class.js";
|
|
8
8
|
import { createConfig, validateResourcesConfig, logConfigWarnings, logInitialization } from "./config.js";
|
|
9
9
|
import { detectTimezone, getCohortInfo, createFieldHandler } from "./utils.js";
|
|
10
10
|
import { createPartitionConfig } from "./partitions.js";
|
|
@@ -733,5 +733,3 @@ export class EventualConsistencyPlugin extends Plugin {
|
|
|
733
733
|
return diagnostics;
|
|
734
734
|
}
|
|
735
735
|
}
|
|
736
|
-
|
|
737
|
-
export default EventualConsistencyPlugin;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import Plugin from "./plugin.class.js";
|
|
1
|
+
import { Plugin } from "./plugin.class.js";
|
|
2
2
|
import tryFn from "../concerns/try-fn.js";
|
|
3
3
|
import { FulltextError } from "./fulltext.errors.js";
|
|
4
4
|
|
|
@@ -554,6 +554,4 @@ export class FullTextPlugin extends Plugin {
|
|
|
554
554
|
// Save changes
|
|
555
555
|
await this.saveIndexes();
|
|
556
556
|
}
|
|
557
|
-
}
|
|
558
|
-
|
|
559
|
-
export default FullTextPlugin;
|
|
557
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import Plugin from "./plugin.class.js";
|
|
1
|
+
import { Plugin } from "./plugin.class.js";
|
|
2
2
|
import tryFn from "../concerns/try-fn.js";
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -109,7 +109,7 @@ export class GeoPlugin extends Plugin {
|
|
|
109
109
|
console.log(`[GeoPlugin] Installed with ${Object.keys(this.resources).length} resources`);
|
|
110
110
|
}
|
|
111
111
|
|
|
112
|
-
this.emit('installed', {
|
|
112
|
+
this.emit('db:plugin:installed', {
|
|
113
113
|
plugin: 'GeoPlugin',
|
|
114
114
|
resources: Object.keys(this.resources)
|
|
115
115
|
});
|
|
@@ -861,12 +861,10 @@ export class GeoPlugin extends Plugin {
|
|
|
861
861
|
console.log('[GeoPlugin] Uninstalled');
|
|
862
862
|
}
|
|
863
863
|
|
|
864
|
-
this.emit('uninstalled', {
|
|
864
|
+
this.emit('db:plugin:uninstalled', {
|
|
865
865
|
plugin: 'GeoPlugin'
|
|
866
866
|
});
|
|
867
867
|
|
|
868
868
|
await super.uninstall();
|
|
869
869
|
}
|
|
870
870
|
}
|
|
871
|
-
|
|
872
|
-
export default GeoPlugin;
|
package/src/plugins/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import Plugin from "./plugin.class.js";
|
|
1
|
+
import { Plugin } from "./plugin.class.js";
|
|
2
2
|
import tryFn from "../concerns/try-fn.js";
|
|
3
3
|
|
|
4
4
|
export class MetricsPlugin extends Plugin {
|
|
@@ -831,6 +831,4 @@ export class MetricsPlugin extends Plugin {
|
|
|
831
831
|
console.error('[Metrics Plugin] Standalone metrics server error:', err);
|
|
832
832
|
});
|
|
833
833
|
}
|
|
834
|
-
}
|
|
835
|
-
|
|
836
|
-
export default MetricsPlugin;
|
|
834
|
+
}
|