@enbox/dwn-server 0.0.2 → 0.0.4
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/LICENSE +3 -2
- package/README.md +115 -215
- package/dist/esm/src/admin/activity-log.d.ts +44 -0
- package/dist/esm/src/admin/activity-log.d.ts.map +1 -0
- package/dist/esm/src/admin/activity-log.js +85 -0
- package/dist/esm/src/admin/activity-log.js.map +1 -0
- package/dist/esm/src/admin/admin-api.d.ts +61 -0
- package/dist/esm/src/admin/admin-api.d.ts.map +1 -0
- package/dist/esm/src/admin/admin-api.js +1047 -0
- package/dist/esm/src/admin/admin-api.js.map +1 -0
- package/dist/esm/src/admin/admin-auth.d.ts +9 -0
- package/dist/esm/src/admin/admin-auth.d.ts.map +1 -0
- package/dist/esm/src/admin/admin-auth.js +45 -0
- package/dist/esm/src/admin/admin-auth.js.map +1 -0
- package/dist/esm/src/admin/admin-store.d.ts +111 -0
- package/dist/esm/src/admin/admin-store.d.ts.map +1 -0
- package/dist/esm/src/admin/admin-store.js +376 -0
- package/dist/esm/src/admin/admin-store.js.map +1 -0
- package/dist/esm/src/admin/audit-log.d.ts +94 -0
- package/dist/esm/src/admin/audit-log.d.ts.map +1 -0
- package/dist/esm/src/admin/audit-log.js +220 -0
- package/dist/esm/src/admin/audit-log.js.map +1 -0
- package/dist/esm/src/admin/index.d.ts +10 -0
- package/dist/esm/src/admin/index.d.ts.map +1 -0
- package/dist/esm/src/admin/index.js +7 -0
- package/dist/esm/src/admin/index.js.map +1 -0
- package/dist/esm/src/admin/types.d.ts +306 -0
- package/dist/esm/src/admin/types.d.ts.map +1 -0
- package/dist/esm/src/admin/types.js +2 -0
- package/dist/esm/src/admin/types.js.map +1 -0
- package/dist/esm/src/admin/webhook-manager.d.ts +55 -0
- package/dist/esm/src/admin/webhook-manager.d.ts.map +1 -0
- package/dist/esm/src/admin/webhook-manager.js +184 -0
- package/dist/esm/src/admin/webhook-manager.js.map +1 -0
- package/dist/esm/src/config.d.ts +124 -9
- package/dist/esm/src/config.d.ts.map +1 -1
- package/dist/esm/src/config.js +155 -13
- package/dist/esm/src/config.js.map +1 -1
- package/dist/esm/src/connection/connection-manager.d.ts +32 -9
- package/dist/esm/src/connection/connection-manager.d.ts.map +1 -1
- package/dist/esm/src/connection/connection-manager.js +38 -5
- package/dist/esm/src/connection/connection-manager.js.map +1 -1
- package/dist/esm/src/connection/flow-controller.d.ts +53 -0
- package/dist/esm/src/connection/flow-controller.d.ts.map +1 -0
- package/dist/esm/src/connection/flow-controller.js +101 -0
- package/dist/esm/src/connection/flow-controller.js.map +1 -0
- package/dist/esm/src/connection/socket-connection.d.ts +54 -18
- package/dist/esm/src/connection/socket-connection.d.ts.map +1 -1
- package/dist/esm/src/connection/socket-connection.js +102 -40
- package/dist/esm/src/connection/socket-connection.js.map +1 -1
- package/dist/esm/src/delivery-service.d.ts +43 -0
- package/dist/esm/src/delivery-service.d.ts.map +1 -0
- package/dist/esm/src/delivery-service.js +574 -0
- package/dist/esm/src/delivery-service.js.map +1 -0
- package/dist/esm/src/dwn-error.d.ts +10 -1
- package/dist/esm/src/dwn-error.d.ts.map +1 -1
- package/dist/esm/src/dwn-error.js +9 -0
- package/dist/esm/src/dwn-error.js.map +1 -1
- package/dist/esm/src/dwn-server.d.ts +13 -6
- package/dist/esm/src/dwn-server.d.ts.map +1 -1
- package/dist/esm/src/dwn-server.js +199 -24
- package/dist/esm/src/dwn-server.js.map +1 -1
- package/dist/esm/src/http-api.d.ts +28 -13
- package/dist/esm/src/http-api.d.ts.map +1 -1
- package/dist/esm/src/http-api.js +649 -374
- package/dist/esm/src/http-api.js.map +1 -1
- package/dist/esm/src/index.d.ts +6 -2
- package/dist/esm/src/index.d.ts.map +1 -1
- package/dist/esm/src/index.js +4 -1
- package/dist/esm/src/index.js.map +1 -1
- package/dist/esm/src/json-rpc-api.js +2 -1
- package/dist/esm/src/json-rpc-api.js.map +1 -1
- package/dist/esm/src/json-rpc-handlers/dwn/process-message.d.ts.map +1 -1
- package/dist/esm/src/json-rpc-handlers/dwn/process-message.js +109 -7
- package/dist/esm/src/json-rpc-handlers/dwn/process-message.js.map +1 -1
- package/dist/esm/src/json-rpc-handlers/subscription/ack.d.ts +20 -0
- package/dist/esm/src/json-rpc-handlers/subscription/ack.d.ts.map +1 -0
- package/dist/esm/src/json-rpc-handlers/subscription/ack.js +41 -0
- package/dist/esm/src/json-rpc-handlers/subscription/ack.js.map +1 -0
- package/dist/esm/src/json-rpc-handlers/subscription/close.d.ts.map +1 -1
- package/dist/esm/src/json-rpc-handlers/subscription/close.js +1 -1
- package/dist/esm/src/json-rpc-handlers/subscription/close.js.map +1 -1
- package/dist/esm/src/json-rpc-handlers/subscription/index.d.ts +1 -0
- package/dist/esm/src/json-rpc-handlers/subscription/index.d.ts.map +1 -1
- package/dist/esm/src/json-rpc-handlers/subscription/index.js +1 -0
- package/dist/esm/src/json-rpc-handlers/subscription/index.js.map +1 -1
- package/dist/esm/src/lib/json-rpc-router.d.ts +25 -8
- package/dist/esm/src/lib/json-rpc-router.d.ts.map +1 -1
- package/dist/esm/src/lib/json-rpc-router.js.map +1 -1
- package/dist/esm/src/lib/sql-utils.d.ts +6 -0
- package/dist/esm/src/lib/sql-utils.d.ts.map +1 -0
- package/dist/esm/src/lib/sql-utils.js +8 -0
- package/dist/esm/src/lib/sql-utils.js.map +1 -0
- package/dist/esm/src/main.js +0 -6
- package/dist/esm/src/main.js.map +1 -1
- package/dist/esm/src/message-processed-hook.d.ts +35 -0
- package/dist/esm/src/message-processed-hook.d.ts.map +1 -0
- package/dist/esm/src/message-processed-hook.js +2 -0
- package/dist/esm/src/message-processed-hook.js.map +1 -0
- package/dist/esm/src/metrics.d.ts +14 -2
- package/dist/esm/src/metrics.d.ts.map +1 -1
- package/dist/esm/src/metrics.js +41 -1
- package/dist/esm/src/metrics.js.map +1 -1
- package/dist/esm/src/plugins/event-log-nats.d.ts +25 -0
- package/dist/esm/src/plugins/event-log-nats.d.ts.map +1 -0
- package/dist/esm/src/plugins/event-log-nats.js +379 -0
- package/dist/esm/src/plugins/event-log-nats.js.map +1 -0
- package/dist/esm/src/rate-limiter.d.ts +60 -0
- package/dist/esm/src/rate-limiter.d.ts.map +1 -0
- package/dist/esm/src/rate-limiter.js +116 -0
- package/dist/esm/src/rate-limiter.js.map +1 -0
- package/dist/esm/src/registration/jwt-provider-auth-plugin.d.ts +53 -0
- package/dist/esm/src/registration/jwt-provider-auth-plugin.d.ts.map +1 -0
- package/dist/esm/src/registration/jwt-provider-auth-plugin.js +90 -0
- package/dist/esm/src/registration/jwt-provider-auth-plugin.js.map +1 -0
- package/dist/esm/src/registration/open-auth-handler.d.ts +37 -0
- package/dist/esm/src/registration/open-auth-handler.d.ts.map +1 -0
- package/dist/esm/src/registration/open-auth-handler.js +214 -0
- package/dist/esm/src/registration/open-auth-handler.js.map +1 -0
- package/dist/esm/src/registration/proof-of-work-manager.d.ts +1 -1
- package/dist/esm/src/registration/proof-of-work-manager.d.ts.map +1 -1
- package/dist/esm/src/registration/proof-of-work-manager.js +3 -3
- package/dist/esm/src/registration/proof-of-work-manager.js.map +1 -1
- package/dist/esm/src/registration/provider-auth-plugin.d.ts +46 -0
- package/dist/esm/src/registration/provider-auth-plugin.d.ts.map +1 -0
- package/dist/esm/src/registration/provider-auth-plugin.js +29 -0
- package/dist/esm/src/registration/provider-auth-plugin.js.map +1 -0
- package/dist/esm/src/registration/registration-manager.d.ts +28 -5
- package/dist/esm/src/registration/registration-manager.d.ts.map +1 -1
- package/dist/esm/src/registration/registration-manager.js +83 -12
- package/dist/esm/src/registration/registration-manager.js.map +1 -1
- package/dist/esm/src/registration/registration-store.d.ts +83 -3
- package/dist/esm/src/registration/registration-store.d.ts.map +1 -1
- package/dist/esm/src/registration/registration-store.js +248 -11
- package/dist/esm/src/registration/registration-store.js.map +1 -1
- package/dist/esm/src/storage.d.ts +5 -5
- package/dist/esm/src/storage.d.ts.map +1 -1
- package/dist/esm/src/storage.js +105 -24
- package/dist/esm/src/storage.js.map +1 -1
- package/dist/esm/src/web5-connect/sql-ttl-cache.d.ts.map +1 -1
- package/dist/esm/src/web5-connect/sql-ttl-cache.js +11 -3
- package/dist/esm/src/web5-connect/sql-ttl-cache.js.map +1 -1
- package/dist/esm/src/web5-connect/web5-connect-server.d.ts.map +1 -1
- package/dist/esm/src/web5-connect/web5-connect-server.js +2 -2
- package/dist/esm/src/web5-connect/web5-connect-server.js.map +1 -1
- package/dist/esm/src/ws-api.d.ts +18 -4
- package/dist/esm/src/ws-api.d.ts.map +1 -1
- package/dist/esm/src/ws-api.js +12 -16
- package/dist/esm/src/ws-api.js.map +1 -1
- package/package.json +34 -53
- package/src/admin/activity-log.ts +100 -0
- package/src/admin/admin-api.ts +1308 -0
- package/src/admin/admin-auth.ts +56 -0
- package/src/admin/admin-store.ts +515 -0
- package/src/admin/audit-log.ts +327 -0
- package/src/admin/index.ts +34 -0
- package/src/admin/types.ts +352 -0
- package/src/admin/webhook-manager.ts +245 -0
- package/src/config.ts +190 -22
- package/src/connection/connection-manager.ts +67 -17
- package/src/connection/flow-controller.ts +117 -0
- package/src/connection/socket-connection.ts +144 -67
- package/src/delivery-service.ts +740 -0
- package/src/dwn-error.ts +11 -2
- package/src/dwn-server.ts +254 -39
- package/src/http-api.ts +736 -392
- package/src/index.ts +13 -2
- package/src/json-rpc-api.ts +2 -1
- package/src/json-rpc-handlers/dwn/process-message.ts +149 -15
- package/src/json-rpc-handlers/subscription/ack.ts +63 -0
- package/src/json-rpc-handlers/subscription/close.ts +5 -9
- package/src/json-rpc-handlers/subscription/index.ts +1 -0
- package/src/lib/json-rpc-router.ts +26 -11
- package/src/lib/sql-utils.ts +7 -0
- package/src/main.ts +0 -8
- package/src/message-processed-hook.ts +33 -0
- package/src/metrics.ts +57 -8
- package/src/plugins/event-log-nats.ts +466 -0
- package/src/process-handlers.ts +5 -5
- package/src/rate-limiter.ts +143 -0
- package/src/registration/jwt-provider-auth-plugin.ts +119 -0
- package/src/registration/open-auth-handler.ts +263 -0
- package/src/registration/proof-of-work-manager.ts +11 -10
- package/src/registration/provider-auth-plugin.ts +84 -0
- package/src/registration/registration-manager.ts +129 -31
- package/src/registration/registration-store.ts +332 -22
- package/src/storage.ts +136 -40
- package/src/web5-connect/sql-ttl-cache.ts +12 -5
- package/src/web5-connect/web5-connect-server.ts +9 -8
- package/src/ws-api.ts +39 -26
- package/dist/cjs/index.js +0 -6811
- package/dist/cjs/package.json +0 -1
- package/dist/esm/src/json-rpc-socket.d.ts +0 -39
- package/dist/esm/src/json-rpc-socket.d.ts.map +0 -1
- package/dist/esm/src/json-rpc-socket.js +0 -125
- package/dist/esm/src/json-rpc-socket.js.map +0 -1
- package/dist/esm/src/lib/http-server-shutdown-handler.d.ts +0 -10
- package/dist/esm/src/lib/http-server-shutdown-handler.d.ts.map +0 -1
- package/dist/esm/src/lib/http-server-shutdown-handler.js +0 -65
- package/dist/esm/src/lib/http-server-shutdown-handler.js.map +0 -1
- package/dist/esm/src/lib/json-rpc.d.ts +0 -54
- package/dist/esm/src/lib/json-rpc.d.ts.map +0 -1
- package/dist/esm/src/lib/json-rpc.js +0 -60
- package/dist/esm/src/lib/json-rpc.js.map +0 -1
- package/dist/esm/src/registration/proof-of-work-types.d.ts +0 -8
- package/dist/esm/src/registration/proof-of-work-types.d.ts.map +0 -1
- package/dist/esm/src/registration/proof-of-work-types.js +0 -2
- package/dist/esm/src/registration/proof-of-work-types.js.map +0 -1
- package/dist/esm/src/registration/registration-types.d.ts +0 -18
- package/dist/esm/src/registration/registration-types.d.ts.map +0 -1
- package/dist/esm/src/registration/registration-types.js +0 -2
- package/dist/esm/src/registration/registration-types.js.map +0 -1
- package/dist/esm/tests/common-scenario-validator.d.ts +0 -11
- package/dist/esm/tests/common-scenario-validator.d.ts.map +0 -1
- package/dist/esm/tests/common-scenario-validator.js +0 -114
- package/dist/esm/tests/common-scenario-validator.js.map +0 -1
- package/dist/esm/tests/connection/connection-manager.spec.d.ts +0 -2
- package/dist/esm/tests/connection/connection-manager.spec.d.ts.map +0 -1
- package/dist/esm/tests/connection/connection-manager.spec.js +0 -47
- package/dist/esm/tests/connection/connection-manager.spec.js.map +0 -1
- package/dist/esm/tests/connection/socket-connection.spec.d.ts +0 -2
- package/dist/esm/tests/connection/socket-connection.spec.d.ts.map +0 -1
- package/dist/esm/tests/connection/socket-connection.spec.js +0 -125
- package/dist/esm/tests/connection/socket-connection.spec.js.map +0 -1
- package/dist/esm/tests/cors/http-api.browser.d.ts +0 -2
- package/dist/esm/tests/cors/http-api.browser.d.ts.map +0 -1
- package/dist/esm/tests/cors/http-api.browser.js +0 -60
- package/dist/esm/tests/cors/http-api.browser.js.map +0 -1
- package/dist/esm/tests/cors/ping.browser.d.ts +0 -2
- package/dist/esm/tests/cors/ping.browser.d.ts.map +0 -1
- package/dist/esm/tests/cors/ping.browser.js +0 -7
- package/dist/esm/tests/cors/ping.browser.js.map +0 -1
- package/dist/esm/tests/dwn-process-message.spec.d.ts +0 -2
- package/dist/esm/tests/dwn-process-message.spec.d.ts.map +0 -1
- package/dist/esm/tests/dwn-process-message.spec.js +0 -172
- package/dist/esm/tests/dwn-process-message.spec.js.map +0 -1
- package/dist/esm/tests/dwn-server.spec.d.ts +0 -2
- package/dist/esm/tests/dwn-server.spec.d.ts.map +0 -1
- package/dist/esm/tests/dwn-server.spec.js +0 -49
- package/dist/esm/tests/dwn-server.spec.js.map +0 -1
- package/dist/esm/tests/http-api.spec.d.ts +0 -2
- package/dist/esm/tests/http-api.spec.d.ts.map +0 -1
- package/dist/esm/tests/http-api.spec.js +0 -775
- package/dist/esm/tests/http-api.spec.js.map +0 -1
- package/dist/esm/tests/json-rpc-socket.spec.d.ts +0 -2
- package/dist/esm/tests/json-rpc-socket.spec.d.ts.map +0 -1
- package/dist/esm/tests/json-rpc-socket.spec.js +0 -225
- package/dist/esm/tests/json-rpc-socket.spec.js.map +0 -1
- package/dist/esm/tests/plugins/data-store-sqlite.d.ts +0 -17
- package/dist/esm/tests/plugins/data-store-sqlite.d.ts.map +0 -1
- package/dist/esm/tests/plugins/data-store-sqlite.js +0 -23
- package/dist/esm/tests/plugins/data-store-sqlite.js.map +0 -1
- package/dist/esm/tests/plugins/event-log-sqlite.d.ts +0 -17
- package/dist/esm/tests/plugins/event-log-sqlite.d.ts.map +0 -1
- package/dist/esm/tests/plugins/event-log-sqlite.js +0 -23
- package/dist/esm/tests/plugins/event-log-sqlite.js.map +0 -1
- package/dist/esm/tests/plugins/event-stream-in-memory.d.ts +0 -17
- package/dist/esm/tests/plugins/event-stream-in-memory.d.ts.map +0 -1
- package/dist/esm/tests/plugins/event-stream-in-memory.js +0 -21
- package/dist/esm/tests/plugins/event-stream-in-memory.js.map +0 -1
- package/dist/esm/tests/plugins/message-store-sqlite.d.ts +0 -17
- package/dist/esm/tests/plugins/message-store-sqlite.d.ts.map +0 -1
- package/dist/esm/tests/plugins/message-store-sqlite.js +0 -23
- package/dist/esm/tests/plugins/message-store-sqlite.js.map +0 -1
- package/dist/esm/tests/plugins/resumable-task-store-sqlite.d.ts +0 -17
- package/dist/esm/tests/plugins/resumable-task-store-sqlite.d.ts.map +0 -1
- package/dist/esm/tests/plugins/resumable-task-store-sqlite.js +0 -23
- package/dist/esm/tests/plugins/resumable-task-store-sqlite.js.map +0 -1
- package/dist/esm/tests/process-handler.spec.d.ts +0 -2
- package/dist/esm/tests/process-handler.spec.d.ts.map +0 -1
- package/dist/esm/tests/process-handler.spec.js +0 -60
- package/dist/esm/tests/process-handler.spec.js.map +0 -1
- package/dist/esm/tests/registration/proof-of-work-manager.spec.d.ts +0 -2
- package/dist/esm/tests/registration/proof-of-work-manager.spec.d.ts.map +0 -1
- package/dist/esm/tests/registration/proof-of-work-manager.spec.js +0 -157
- package/dist/esm/tests/registration/proof-of-work-manager.spec.js.map +0 -1
- package/dist/esm/tests/rpc-subscribe-close.spec.d.ts +0 -2
- package/dist/esm/tests/rpc-subscribe-close.spec.d.ts.map +0 -1
- package/dist/esm/tests/rpc-subscribe-close.spec.js +0 -81
- package/dist/esm/tests/rpc-subscribe-close.spec.js.map +0 -1
- package/dist/esm/tests/scenarios/dynamic-plugin-loading.spec.d.ts +0 -2
- package/dist/esm/tests/scenarios/dynamic-plugin-loading.spec.d.ts.map +0 -1
- package/dist/esm/tests/scenarios/dynamic-plugin-loading.spec.js +0 -73
- package/dist/esm/tests/scenarios/dynamic-plugin-loading.spec.js.map +0 -1
- package/dist/esm/tests/scenarios/registration.spec.d.ts +0 -2
- package/dist/esm/tests/scenarios/registration.spec.d.ts.map +0 -1
- package/dist/esm/tests/scenarios/registration.spec.js +0 -507
- package/dist/esm/tests/scenarios/registration.spec.js.map +0 -1
- package/dist/esm/tests/scenarios/web5-connect.spec.d.ts +0 -2
- package/dist/esm/tests/scenarios/web5-connect.spec.d.ts.map +0 -1
- package/dist/esm/tests/scenarios/web5-connect.spec.js +0 -137
- package/dist/esm/tests/scenarios/web5-connect.spec.js.map +0 -1
- package/dist/esm/tests/test-dwn.d.ts +0 -7
- package/dist/esm/tests/test-dwn.d.ts.map +0 -1
- package/dist/esm/tests/test-dwn.js +0 -34
- package/dist/esm/tests/test-dwn.js.map +0 -1
- package/dist/esm/tests/utils.d.ts +0 -46
- package/dist/esm/tests/utils.d.ts.map +0 -1
- package/dist/esm/tests/utils.js +0 -116
- package/dist/esm/tests/utils.js.map +0 -1
- package/dist/esm/tests/ws-api.spec.d.ts +0 -2
- package/dist/esm/tests/ws-api.spec.d.ts.map +0 -1
- package/dist/esm/tests/ws-api.spec.js +0 -327
- package/dist/esm/tests/ws-api.spec.js.map +0 -1
- package/src/json-rpc-socket.ts +0 -155
- package/src/lib/http-server-shutdown-handler.ts +0 -79
- package/src/lib/json-rpc.ts +0 -126
- package/src/registration/proof-of-work-types.ts +0 -7
- package/src/registration/registration-types.ts +0 -18
package/src/storage.ts
CHANGED
|
@@ -1,43 +1,47 @@
|
|
|
1
|
+
import type { Dialect } from '@enbox/dwn-sql-store';
|
|
1
2
|
import type { DidResolver } from '@enbox/dids';
|
|
3
|
+
import type { DwnServerConfig } from './config.js';
|
|
2
4
|
import type {
|
|
3
5
|
DataStore,
|
|
4
6
|
DwnConfig,
|
|
5
7
|
EventLog,
|
|
6
|
-
EventStream,
|
|
7
8
|
MessageStore,
|
|
8
9
|
ResumableTaskStore,
|
|
10
|
+
StateIndex,
|
|
9
11
|
TenantGate,
|
|
10
12
|
} from '@enbox/dwn-sdk-js';
|
|
11
|
-
import type { Dialect } from '@enbox/dwn-sql-store';
|
|
12
|
-
import type { DwnServerConfig } from './config.js';
|
|
13
13
|
|
|
14
14
|
import * as fs from 'fs';
|
|
15
15
|
import Cursor from 'pg-cursor';
|
|
16
|
-
import Database from 'better-sqlite3';
|
|
17
|
-
import pg from 'pg';
|
|
18
16
|
import { createPool as MySQLCreatePool } from 'mysql2';
|
|
17
|
+
import pg from 'pg';
|
|
18
|
+
|
|
19
|
+
import { Kysely } from 'kysely';
|
|
20
|
+
|
|
21
|
+
import { createBunSqliteDatabase } from '@enbox/dwn-sql-store';
|
|
19
22
|
import { PluginLoader } from './plugin-loader.js';
|
|
20
23
|
|
|
21
24
|
import {
|
|
22
25
|
DataStoreLevel,
|
|
23
|
-
EventLogLevel,
|
|
24
26
|
MessageStoreLevel,
|
|
25
27
|
ResumableTaskStoreLevel,
|
|
28
|
+
StateIndexLevel,
|
|
26
29
|
} from '@enbox/dwn-sdk-js';
|
|
27
30
|
import {
|
|
28
31
|
DataStoreSql,
|
|
29
|
-
EventLogSql,
|
|
30
32
|
MessageStoreSql,
|
|
31
33
|
MysqlDialect,
|
|
32
34
|
PostgresDialect,
|
|
33
35
|
ResumableTaskStoreSql,
|
|
36
|
+
runDwnStoreMigrations,
|
|
34
37
|
SqliteDialect,
|
|
38
|
+
StateIndexSql,
|
|
35
39
|
} from '@enbox/dwn-sql-store';
|
|
36
40
|
|
|
37
41
|
export enum StoreType {
|
|
38
42
|
DataStore,
|
|
39
43
|
MessageStore,
|
|
40
|
-
|
|
44
|
+
StateIndex,
|
|
41
45
|
ResumableTaskStore,
|
|
42
46
|
}
|
|
43
47
|
|
|
@@ -48,23 +52,113 @@ export enum BackendTypes {
|
|
|
48
52
|
POSTGRES = 'postgres',
|
|
49
53
|
}
|
|
50
54
|
|
|
51
|
-
export type DwnStore = DataStore |
|
|
55
|
+
export type DwnStore = DataStore | StateIndex | MessageStore | ResumableTaskStore;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Cache of shared PostgreSQL dialects keyed by connection URL. When multiple
|
|
59
|
+
* DWN stores share the same Postgres URL, they reuse a single dialect (and
|
|
60
|
+
* thus a single `pg.Pool`) instead of each creating their own. This reduces
|
|
61
|
+
* connection count from 4 × pool_max to 1 × pool_max per DWN process.
|
|
62
|
+
*/
|
|
63
|
+
const sharedDialectCache: Map<string, Dialect> = new Map();
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Returns a (potentially cached) dialect for the given Postgres connection URL.
|
|
67
|
+
* Non-Postgres URLs always return a fresh dialect (no caching).
|
|
68
|
+
*/
|
|
69
|
+
function getOrCreateDialect(connectionUrl: URL, config: DwnServerConfig): Dialect {
|
|
70
|
+
const protocol = connectionUrl.protocol.slice(0, -1);
|
|
71
|
+
|
|
72
|
+
if (protocol !== BackendTypes.POSTGRES) {
|
|
73
|
+
return getDialectFromUrl(connectionUrl);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const key = connectionUrl.toString();
|
|
77
|
+
const cached = sharedDialectCache.get(key);
|
|
78
|
+
if (cached !== undefined) {
|
|
79
|
+
return cached;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Create a single pg.Pool instance with configurable sizing.
|
|
83
|
+
const pool = new pg.Pool({
|
|
84
|
+
connectionString : connectionUrl.toString(),
|
|
85
|
+
min : config.pgPoolMin,
|
|
86
|
+
max : config.pgPoolMax,
|
|
87
|
+
idleTimeoutMillis : config.pgPoolIdleTimeout,
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
const dialect = new PostgresDialect({
|
|
91
|
+
pool : async (): Promise<pg.Pool> => pool,
|
|
92
|
+
cursor : Cursor,
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
sharedDialectCache.set(key, dialect);
|
|
96
|
+
return dialect;
|
|
97
|
+
}
|
|
52
98
|
|
|
53
99
|
export async function getDwnConfig(
|
|
54
|
-
config
|
|
100
|
+
config : DwnServerConfig,
|
|
55
101
|
options : {
|
|
56
102
|
didResolver? : DidResolver,
|
|
57
|
-
tenantGate?
|
|
58
|
-
|
|
103
|
+
tenantGate? : TenantGate,
|
|
104
|
+
eventLog? : EventLog,
|
|
59
105
|
}
|
|
60
106
|
): Promise<DwnConfig> {
|
|
61
|
-
const { tenantGate,
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
107
|
+
const { tenantGate, eventLog, didResolver } = options;
|
|
108
|
+
|
|
109
|
+
// Run SQL schema migrations before creating stores. Uses the data store
|
|
110
|
+
// connection to determine the dialect — all SQL stores typically share the
|
|
111
|
+
// same database. Non-SQL backends (level://) are skipped.
|
|
112
|
+
await runSqlMigrationsIfNeeded(config);
|
|
66
113
|
|
|
67
|
-
|
|
114
|
+
const dataStore: DataStore = await getStore(config, config.dataStore, StoreType.DataStore);
|
|
115
|
+
const stateIndex: StateIndex = await getStore(config, config.stateIndex, StoreType.StateIndex);
|
|
116
|
+
const messageStore: MessageStore = await getStore(config, config.messageStore, StoreType.MessageStore);
|
|
117
|
+
const resumableTaskStore: ResumableTaskStore = await getStore(config, config.resumableTaskStore, StoreType.ResumableTaskStore);
|
|
118
|
+
|
|
119
|
+
return { didResolver, eventLog, stateIndex, dataStore, messageStore, resumableTaskStore, tenantGate };
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Runs DWN SQL schema migrations if the data store is configured with a SQL
|
|
124
|
+
* backend. Creates a temporary Kysely instance, runs all pending migrations,
|
|
125
|
+
* then destroys it. The subsequent store `open()` calls will reuse the shared
|
|
126
|
+
* dialect/pool and find the schema already in place.
|
|
127
|
+
*/
|
|
128
|
+
async function runSqlMigrationsIfNeeded(config: DwnServerConfig): Promise<void> {
|
|
129
|
+
// Skip if the data store config is a file path (plugin) or non-SQL backend
|
|
130
|
+
if (isFilePath(config.dataStore)) {
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
let storeUrl: URL;
|
|
135
|
+
try {
|
|
136
|
+
storeUrl = new URL(config.dataStore);
|
|
137
|
+
} catch {
|
|
138
|
+
return; // Not a valid URL — skip
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const protocol = storeUrl.protocol.slice(0, -1);
|
|
142
|
+
const sqlBackends: string[] = [BackendTypes.SQLITE, BackendTypes.MYSQL, BackendTypes.POSTGRES];
|
|
143
|
+
if (!sqlBackends.includes(protocol)) {
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const dialect = getOrCreateDialect(storeUrl, config);
|
|
148
|
+
const db = new Kysely<Record<string, unknown>>({ dialect });
|
|
149
|
+
try {
|
|
150
|
+
const applied = await runDwnStoreMigrations(db, dialect);
|
|
151
|
+
if (applied.length > 0) {
|
|
152
|
+
console.log(`DWN migrations applied: ${applied.join(', ')}`);
|
|
153
|
+
}
|
|
154
|
+
} finally {
|
|
155
|
+
// Don't destroy the Kysely instance if using a shared Postgres pool —
|
|
156
|
+
// the pool is cached in sharedDialectCache and will be reused by stores.
|
|
157
|
+
// Only destroy for non-cached dialects (SQLite, MySQL).
|
|
158
|
+
if (protocol !== BackendTypes.POSTGRES) {
|
|
159
|
+
await db.destroy();
|
|
160
|
+
}
|
|
161
|
+
}
|
|
68
162
|
}
|
|
69
163
|
|
|
70
164
|
function getLevelStore(
|
|
@@ -78,12 +172,12 @@ function getLevelStore(
|
|
|
78
172
|
});
|
|
79
173
|
case StoreType.MessageStore:
|
|
80
174
|
return new MessageStoreLevel({
|
|
81
|
-
blockstoreLocation: storeURI.host + storeURI.pathname + '/MESSAGESTORE',
|
|
82
|
-
indexLocation: storeURI.host + storeURI.pathname + '/INDEX',
|
|
175
|
+
blockstoreLocation : storeURI.host + storeURI.pathname + '/MESSAGESTORE',
|
|
176
|
+
indexLocation : storeURI.host + storeURI.pathname + '/INDEX',
|
|
83
177
|
});
|
|
84
|
-
case StoreType.
|
|
85
|
-
return new
|
|
86
|
-
location: storeURI.host + storeURI.pathname + '/
|
|
178
|
+
case StoreType.StateIndex:
|
|
179
|
+
return new StateIndexLevel({
|
|
180
|
+
location: storeURI.host + storeURI.pathname + '/STATEINDEX',
|
|
87
181
|
});
|
|
88
182
|
case StoreType.ResumableTaskStore:
|
|
89
183
|
return new ResumableTaskStoreLevel({
|
|
@@ -95,18 +189,19 @@ function getLevelStore(
|
|
|
95
189
|
}
|
|
96
190
|
|
|
97
191
|
function getSqlStore(
|
|
192
|
+
config: DwnServerConfig,
|
|
98
193
|
connectionUrl: URL,
|
|
99
194
|
storeType: StoreType,
|
|
100
195
|
): DwnStore {
|
|
101
|
-
const dialect =
|
|
196
|
+
const dialect = getOrCreateDialect(connectionUrl, config);
|
|
102
197
|
|
|
103
198
|
switch (storeType) {
|
|
104
199
|
case StoreType.DataStore:
|
|
105
200
|
return new DataStoreSql(dialect);
|
|
106
201
|
case StoreType.MessageStore:
|
|
107
202
|
return new MessageStoreSql(dialect);
|
|
108
|
-
case StoreType.
|
|
109
|
-
return new
|
|
203
|
+
case StoreType.StateIndex:
|
|
204
|
+
return new StateIndexSql(dialect);
|
|
110
205
|
case StoreType.ResumableTaskStore:
|
|
111
206
|
return new ResumableTaskStoreSql(dialect);
|
|
112
207
|
default:
|
|
@@ -122,16 +217,16 @@ function isFilePath(configString: string): boolean {
|
|
|
122
217
|
return filePathPrefixes.some(prefix => configString.startsWith(prefix));
|
|
123
218
|
}
|
|
124
219
|
|
|
125
|
-
async function getStore(storeString: string, storeType: StoreType.DataStore): Promise<DataStore>;
|
|
126
|
-
async function getStore(storeString: string, storeType: StoreType.
|
|
127
|
-
async function getStore(storeString: string, storeType: StoreType.MessageStore): Promise<MessageStore>;
|
|
128
|
-
async function getStore(storeString: string, storeType: StoreType.ResumableTaskStore): Promise<ResumableTaskStore>;
|
|
129
|
-
async function getStore(storeConfigString: string, storeType: StoreType): Promise<DwnStore> {
|
|
220
|
+
async function getStore(config: DwnServerConfig, storeString: string, storeType: StoreType.DataStore): Promise<DataStore>;
|
|
221
|
+
async function getStore(config: DwnServerConfig, storeString: string, storeType: StoreType.StateIndex): Promise<StateIndex>;
|
|
222
|
+
async function getStore(config: DwnServerConfig, storeString: string, storeType: StoreType.MessageStore): Promise<MessageStore>;
|
|
223
|
+
async function getStore(config: DwnServerConfig, storeString: string, storeType: StoreType.ResumableTaskStore): Promise<ResumableTaskStore>;
|
|
224
|
+
async function getStore(config: DwnServerConfig, storeConfigString: string, storeType: StoreType): Promise<DwnStore> {
|
|
130
225
|
if (isFilePath(storeConfigString)) {
|
|
131
226
|
return await loadStoreFromFilePath(storeConfigString, storeType);
|
|
132
227
|
}
|
|
133
228
|
// else treat the `storeConfigString` as a connection string
|
|
134
|
-
|
|
229
|
+
|
|
135
230
|
const storeURI = new URL(storeConfigString);
|
|
136
231
|
|
|
137
232
|
switch (storeURI.protocol.slice(0, -1)) {
|
|
@@ -141,7 +236,7 @@ async function getStore(storeConfigString: string, storeType: StoreType): Promis
|
|
|
141
236
|
case BackendTypes.SQLITE:
|
|
142
237
|
case BackendTypes.MYSQL:
|
|
143
238
|
case BackendTypes.POSTGRES:
|
|
144
|
-
return getSqlStore(storeURI, storeType);
|
|
239
|
+
return getSqlStore(config, storeURI, storeType);
|
|
145
240
|
|
|
146
241
|
default:
|
|
147
242
|
throw invalidStorageSchemeMessage(storeURI.protocol);
|
|
@@ -158,8 +253,8 @@ async function loadStoreFromFilePath(
|
|
|
158
253
|
switch (storeType) {
|
|
159
254
|
case StoreType.DataStore:
|
|
160
255
|
return await PluginLoader.loadPlugin<DataStore>(filePath);
|
|
161
|
-
case StoreType.
|
|
162
|
-
return await PluginLoader.loadPlugin<
|
|
256
|
+
case StoreType.StateIndex:
|
|
257
|
+
return await PluginLoader.loadPlugin<StateIndex>(filePath);
|
|
163
258
|
case StoreType.MessageStore:
|
|
164
259
|
return await PluginLoader.loadPlugin<MessageStore>(filePath);
|
|
165
260
|
case StoreType.ResumableTaskStore:
|
|
@@ -171,7 +266,7 @@ async function loadStoreFromFilePath(
|
|
|
171
266
|
|
|
172
267
|
export function getDialectFromUrl(connectionUrl: URL): Dialect {
|
|
173
268
|
switch (connectionUrl.protocol.slice(0, -1)) {
|
|
174
|
-
case BackendTypes.SQLITE:
|
|
269
|
+
case BackendTypes.SQLITE: {
|
|
175
270
|
const path = connectionUrl.host + connectionUrl.pathname;
|
|
176
271
|
console.log('SQL-lite relative path:', path ? path : undefined); // NOTE, using ? for lose equality comparison
|
|
177
272
|
|
|
@@ -184,16 +279,17 @@ export function getDialectFromUrl(connectionUrl: URL): Dialect {
|
|
|
184
279
|
const dbPath = path || ':memory:';
|
|
185
280
|
|
|
186
281
|
return new SqliteDialect({
|
|
187
|
-
database: async () =>
|
|
282
|
+
database: async () => createBunSqliteDatabase(dbPath),
|
|
188
283
|
});
|
|
284
|
+
}
|
|
189
285
|
case BackendTypes.MYSQL:
|
|
190
286
|
return new MysqlDialect({
|
|
191
287
|
pool: async () => MySQLCreatePool(connectionUrl.toString()),
|
|
192
288
|
});
|
|
193
289
|
case BackendTypes.POSTGRES:
|
|
194
290
|
return new PostgresDialect({
|
|
195
|
-
pool: async () => new pg.Pool({ connectionString: connectionUrl.toString() }),
|
|
196
|
-
cursor: Cursor,
|
|
291
|
+
pool : async () => new pg.Pool({ connectionString: connectionUrl.toString() }),
|
|
292
|
+
cursor : Cursor,
|
|
197
293
|
});
|
|
198
294
|
}
|
|
199
295
|
}
|
|
@@ -205,7 +301,7 @@ function invalidStorageSchemeMessage(protocol: string): string {
|
|
|
205
301
|
}
|
|
206
302
|
return (
|
|
207
303
|
'Unknown storage protocol ' +
|
|
208
|
-
protocol.slice(0, 1) +
|
|
304
|
+
protocol.slice(0, -1) +
|
|
209
305
|
'! Please use one of: ' +
|
|
210
306
|
schemes.join(', ') +
|
|
211
307
|
'. For details, see README'
|
|
@@ -39,9 +39,9 @@ export class SqlTtlCache {
|
|
|
39
39
|
// 512 chars to accommodate potentially large `state` in Web5 Connect flow
|
|
40
40
|
.addColumn('key', 'varchar(512)', (column) => column.primaryKey())
|
|
41
41
|
.addColumn('value', 'text', (column) => column.notNull())
|
|
42
|
-
.addColumn('expiry', '
|
|
42
|
+
.addColumn('expiry', 'bigint', (column) => column.notNull())
|
|
43
43
|
.execute();
|
|
44
|
-
|
|
44
|
+
|
|
45
45
|
await this.db.schema
|
|
46
46
|
.createIndex('index_expiry')
|
|
47
47
|
// .ifNotExists() // intentionally kept commented out code to show that it is not supported by all dialects (ie. MySQL)
|
|
@@ -97,12 +97,19 @@ export class SqlTtlCache {
|
|
|
97
97
|
const entry = result[0];
|
|
98
98
|
|
|
99
99
|
// if the entry is expired, don't return it and delete it
|
|
100
|
-
|
|
100
|
+
const expiry = typeof entry.expiry === 'string' ? parseInt(entry.expiry, 10) : entry.expiry;
|
|
101
|
+
if (Date.now() >= expiry) {
|
|
101
102
|
this.delete(key); // no need to await
|
|
102
103
|
return undefined;
|
|
103
104
|
}
|
|
104
105
|
|
|
105
|
-
|
|
106
|
+
try {
|
|
107
|
+
return JSON.parse(entry.value);
|
|
108
|
+
} catch {
|
|
109
|
+
// Corrupt entry — remove it and return undefined.
|
|
110
|
+
this.delete(key); // no need to await
|
|
111
|
+
return undefined;
|
|
112
|
+
}
|
|
106
113
|
}
|
|
107
114
|
|
|
108
115
|
/**
|
|
@@ -129,7 +136,7 @@ export class SqlTtlCache {
|
|
|
129
136
|
interface CacheEntry {
|
|
130
137
|
key: string;
|
|
131
138
|
value: string;
|
|
132
|
-
expiry: number;
|
|
139
|
+
expiry: number | string; // bigint is returned as string by PostgreSQL driver
|
|
133
140
|
}
|
|
134
141
|
|
|
135
142
|
interface CacheDatabase {
|
|
@@ -1,16 +1,17 @@
|
|
|
1
|
-
import { getDialectFromUrl } from "../storage.js";
|
|
2
1
|
import { CryptoUtils } from '@enbox/crypto';
|
|
3
|
-
|
|
2
|
+
|
|
3
|
+
import { getDialectFromUrl } from '../storage.js';
|
|
4
|
+
import { SqlTtlCache } from './sql-ttl-cache.js';
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* The Web5 Connect Request object.
|
|
7
8
|
*/
|
|
8
|
-
export type Web5ConnectRequest = any; // TODO: define type in common repo for reuse (https://github.com/
|
|
9
|
+
export type Web5ConnectRequest = any; // TODO: define type in common repo for reuse (https://github.com/enboxorg/enbox/issues/138)
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* The Web5 Connect Response object, which is also an OIDC ID token
|
|
12
13
|
*/
|
|
13
|
-
export type Web5ConnectResponse = any; // TODO: define type in common repo for reuse (https://github.com/
|
|
14
|
+
export type Web5ConnectResponse = any; // TODO: define type in common repo for reuse (https://github.com/enboxorg/enbox/issues/138)
|
|
14
15
|
|
|
15
16
|
/**
|
|
16
17
|
* The result of the setWeb5ConnectRequest() method.
|
|
@@ -25,7 +26,7 @@ export type SetWeb5ConnectRequestResult = {
|
|
|
25
26
|
* The time in seconds that the Request URI is valid for.
|
|
26
27
|
*/
|
|
27
28
|
expires_in: number;
|
|
28
|
-
}
|
|
29
|
+
};
|
|
29
30
|
|
|
30
31
|
/**
|
|
31
32
|
* The Web5 Connect Server is responsible for handling the Web5 Connect flow.
|
|
@@ -69,13 +70,13 @@ export class Web5ConnectServer {
|
|
|
69
70
|
// Generate a request URI
|
|
70
71
|
const requestId = CryptoUtils.randomUuid();
|
|
71
72
|
const request_uri = `${this.baseUrl}/connect/authorize/${requestId}.jwt`;
|
|
72
|
-
|
|
73
|
+
|
|
73
74
|
// Store the Request Object.
|
|
74
75
|
this.cache.insert(`request:${requestId}`, request, Web5ConnectServer.ttlInSeconds);
|
|
75
|
-
|
|
76
|
+
|
|
76
77
|
return {
|
|
77
78
|
request_uri,
|
|
78
|
-
expires_in
|
|
79
|
+
expires_in: Web5ConnectServer.ttlInSeconds,
|
|
79
80
|
};
|
|
80
81
|
}
|
|
81
82
|
|
package/src/ws-api.ts
CHANGED
|
@@ -1,45 +1,58 @@
|
|
|
1
|
+
import type { Dwn } from '@enbox/dwn-sdk-js';
|
|
2
|
+
import type { ServerWebSocket } from 'bun';
|
|
1
3
|
|
|
2
|
-
import type {
|
|
3
|
-
|
|
4
|
-
} from '@enbox/dwn-sdk-js';
|
|
5
|
-
|
|
6
|
-
import type { Server } from 'http';
|
|
7
|
-
|
|
8
|
-
import { WebSocketServer } from 'ws';
|
|
9
|
-
|
|
4
|
+
import type { ActivityLog } from './admin/activity-log.js';
|
|
5
|
+
import type { AdminStore } from './admin/admin-store.js';
|
|
10
6
|
import type { ConnectionManager } from './connection/connection-manager.js';
|
|
7
|
+
import type { DwnServerConfig } from './config.js';
|
|
8
|
+
import type { MessageProcessedHook } from './message-processed-hook.js';
|
|
9
|
+
import type { RateLimiter } from './rate-limiter.js';
|
|
10
|
+
import type { RegistrationStore } from './registration/registration-store.js';
|
|
11
|
+
import type { HttpApi, WsData } from './http-api.js';
|
|
12
|
+
|
|
11
13
|
import { InMemoryConnectionManager } from './connection/connection-manager.js';
|
|
12
14
|
|
|
13
15
|
export class WsApi {
|
|
14
|
-
#wsServer: WebSocketServer;
|
|
15
16
|
dwn: Dwn;
|
|
16
|
-
#connectionManager: ConnectionManager
|
|
17
|
-
|
|
18
|
-
constructor(
|
|
17
|
+
#connectionManager: ConnectionManager;
|
|
18
|
+
|
|
19
|
+
constructor(
|
|
20
|
+
httpApi: HttpApi, dwn: Dwn, connectionManager?: ConnectionManager,
|
|
21
|
+
maxInFlight?: number, activityLog?: ActivityLog,
|
|
22
|
+
options?: {
|
|
23
|
+
adminStore? : AdminStore;
|
|
24
|
+
registrationStore? : RegistrationStore;
|
|
25
|
+
config? : DwnServerConfig;
|
|
26
|
+
tenantRateLimiter? : RateLimiter;
|
|
27
|
+
messageProcessedHooks? : MessageProcessedHook[];
|
|
28
|
+
},
|
|
29
|
+
) {
|
|
19
30
|
this.dwn = dwn;
|
|
20
|
-
this.#connectionManager = connectionManager ||
|
|
21
|
-
|
|
31
|
+
this.#connectionManager = connectionManager ||
|
|
32
|
+
new InMemoryConnectionManager(
|
|
33
|
+
dwn, new Map(), maxInFlight, activityLog,
|
|
34
|
+
options?.adminStore, options?.registrationStore, options?.config, options?.tenantRateLimiter,
|
|
35
|
+
options?.messageProcessedHooks,
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
// Wire up the WebSocket open event from Bun.serve() to the connection manager.
|
|
39
|
+
httpApi.onWebSocketConnection = (ws: ServerWebSocket<WsData>): void => {
|
|
40
|
+
this.#connectionManager.connect(ws);
|
|
41
|
+
};
|
|
22
42
|
}
|
|
23
43
|
|
|
24
|
-
|
|
25
|
-
|
|
44
|
+
start(): void {
|
|
45
|
+
// No additional setup needed — Bun.serve() handles WebSocket lifecycle.
|
|
26
46
|
}
|
|
27
47
|
|
|
28
48
|
/**
|
|
29
|
-
*
|
|
30
|
-
* Sets listeners for `connection`, `close` events.
|
|
49
|
+
* Returns the connection manager. Used by the admin API for connection introspection.
|
|
31
50
|
*/
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
this.#wsServer.on('close', () => this.#connectionManager.closeAll());
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
start(): void {
|
|
38
|
-
this.#setupWebSocket();
|
|
51
|
+
get connectionManager(): ConnectionManager {
|
|
52
|
+
return this.#connectionManager;
|
|
39
53
|
}
|
|
40
54
|
|
|
41
55
|
async close(): Promise<void> {
|
|
42
|
-
this.#wsServer.close();
|
|
43
56
|
await this.#connectionManager.closeAll();
|
|
44
57
|
}
|
|
45
58
|
}
|