@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/index.ts
CHANGED
|
@@ -1,6 +1,17 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { ActivityLog, AdminApi, AdminStore } from './admin/index.js';
|
|
2
|
+
export type {
|
|
3
|
+
AdminActivityEvent,
|
|
4
|
+
AdminConnectionSnapshot,
|
|
5
|
+
AdminHealthCheck,
|
|
6
|
+
AdminServerStats,
|
|
7
|
+
AdminTenantDetail,
|
|
8
|
+
AdminTenantSummary,
|
|
9
|
+
} from './admin/index.js';
|
|
10
|
+
export { config as defaultDwnServerConfig, DwnServerConfig } from './config.js';
|
|
11
|
+
export { DeliveryService } from './delivery-service.js';
|
|
2
12
|
export { DwnServer, DwnServerOptions } from './dwn-server.js';
|
|
3
13
|
export { HttpApi } from './http-api.js';
|
|
4
14
|
export { jsonRpcRouter } from './json-rpc-api.js';
|
|
5
|
-
export {
|
|
15
|
+
export type { MessageProcessedContext, MessageProcessedHook } from './message-processed-hook.js';
|
|
16
|
+
export { getDwnConfig, StoreType, BackendTypes, DwnStore } from './storage.js';
|
|
6
17
|
export { WsApi } from './ws-api.js';
|
package/src/json-rpc-api.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { JsonRpcRouter } from './lib/json-rpc-router.js';
|
|
2
2
|
|
|
3
3
|
import { handleDwnProcessMessage } from './json-rpc-handlers/dwn/index.js';
|
|
4
|
-
import { handleSubscriptionsClose } from './json-rpc-handlers/subscription/index.js';
|
|
4
|
+
import { handleSubscriptionAck, handleSubscriptionsClose } from './json-rpc-handlers/subscription/index.js';
|
|
5
5
|
|
|
6
6
|
export const jsonRpcRouter = new JsonRpcRouter();
|
|
7
7
|
|
|
8
8
|
jsonRpcRouter.on('dwn.processMessage', handleDwnProcessMessage);
|
|
9
9
|
jsonRpcRouter.on('rpc.subscribe.dwn.processMessage', handleDwnProcessMessage);
|
|
10
10
|
|
|
11
|
+
jsonRpcRouter.on('rpc.ack', handleSubscriptionAck);
|
|
11
12
|
jsonRpcRouter.on('rpc.subscribe.close', handleSubscriptionsClose);
|
|
@@ -1,21 +1,22 @@
|
|
|
1
1
|
import type { GenericMessage } from '@enbox/dwn-sdk-js';
|
|
2
2
|
import { DwnInterfaceName, DwnMethodName } from '@enbox/dwn-sdk-js';
|
|
3
3
|
|
|
4
|
-
import type { Readable as IsomorphicReadable } from 'readable-stream';
|
|
5
4
|
import log from 'loglevel';
|
|
6
5
|
import { v4 as uuidv4 } from 'uuid';
|
|
7
6
|
|
|
8
|
-
import type { JsonRpcSubscription } from '
|
|
7
|
+
import type { JsonRpcSubscription } from '@enbox/dwn-clients';
|
|
9
8
|
import type {
|
|
10
9
|
HandlerResponse,
|
|
11
10
|
JsonRpcHandler,
|
|
12
11
|
} from '../../lib/json-rpc-router.js';
|
|
13
12
|
|
|
13
|
+
import { DwnServerErrorCode } from '../../dwn-error.js';
|
|
14
|
+
import { requestDataBytesTotal } from '../../metrics.js';
|
|
14
15
|
import {
|
|
15
16
|
createJsonRpcErrorResponse,
|
|
16
17
|
createJsonRpcSuccessResponse,
|
|
17
18
|
JsonRpcErrorCodes,
|
|
18
|
-
} from '
|
|
19
|
+
} from '@enbox/dwn-clients';
|
|
19
20
|
|
|
20
21
|
|
|
21
22
|
export const handleDwnProcessMessage: JsonRpcHandler = async (
|
|
@@ -28,7 +29,7 @@ export const handleDwnProcessMessage: JsonRpcHandler = async (
|
|
|
28
29
|
|
|
29
30
|
try {
|
|
30
31
|
// RecordsWrite is only supported on 'http' to support data stream for large data
|
|
31
|
-
// TODO: https://github.com/
|
|
32
|
+
// TODO: https://github.com/enboxorg/enbox/issues/108
|
|
32
33
|
if (
|
|
33
34
|
transport !== 'http' &&
|
|
34
35
|
message.descriptor.interface === DwnInterfaceName.Records &&
|
|
@@ -38,11 +39,11 @@ export const handleDwnProcessMessage: JsonRpcHandler = async (
|
|
|
38
39
|
requestId,
|
|
39
40
|
JsonRpcErrorCodes.InvalidParams,
|
|
40
41
|
`RecordsWrite is not supported via ${context.transport}`
|
|
41
|
-
)
|
|
42
|
+
);
|
|
42
43
|
return { jsonRpcResponse };
|
|
43
44
|
}
|
|
44
45
|
|
|
45
|
-
// subscribe methods must come with a subscriptionRequest context
|
|
46
|
+
// subscribe methods must come with a subscriptionRequest context
|
|
46
47
|
if (message.descriptor.method === DwnMethodName.Subscribe && subscriptionRequest === undefined) {
|
|
47
48
|
const jsonRpcResponse = createJsonRpcErrorResponse(
|
|
48
49
|
requestId,
|
|
@@ -58,7 +59,7 @@ export const handleDwnProcessMessage: JsonRpcHandler = async (
|
|
|
58
59
|
requestId,
|
|
59
60
|
JsonRpcErrorCodes.InvalidParams,
|
|
60
61
|
`subscriptions are not supported via ${context.transport}`
|
|
61
|
-
)
|
|
62
|
+
);
|
|
62
63
|
return { jsonRpcResponse };
|
|
63
64
|
}
|
|
64
65
|
|
|
@@ -70,12 +71,40 @@ export const handleDwnProcessMessage: JsonRpcHandler = async (
|
|
|
70
71
|
requestId,
|
|
71
72
|
JsonRpcErrorCodes.InvalidParams,
|
|
72
73
|
`the subscribe id: ${subscriptionRequest.id} is in use by an active subscription`
|
|
73
|
-
)
|
|
74
|
+
);
|
|
74
75
|
return { jsonRpcResponse };
|
|
75
76
|
}
|
|
76
77
|
|
|
78
|
+
// --- Per-tenant rate limiting (before any DWN processing) ---
|
|
79
|
+
if (context.tenantRateLimiter) {
|
|
80
|
+
const result = context.tenantRateLimiter.consume(target);
|
|
81
|
+
if (result.allowed === false) {
|
|
82
|
+
const retryAfterSec = Math.ceil(result.retryAfterMs / 1000);
|
|
83
|
+
const jsonRpcResponse = createJsonRpcErrorResponse(
|
|
84
|
+
requestId,
|
|
85
|
+
JsonRpcErrorCodes.TooManyRequests,
|
|
86
|
+
`${DwnServerErrorCode.RateLimitExceeded}: tenant rate limit exceeded, retry after ${retryAfterSec}s`,
|
|
87
|
+
{ retryAfterSec },
|
|
88
|
+
);
|
|
89
|
+
return { jsonRpcResponse };
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// --- Per-tenant storage quota enforcement (RecordsWrite only) ---
|
|
94
|
+
if (
|
|
95
|
+
context.config &&
|
|
96
|
+
context.adminStore &&
|
|
97
|
+
message.descriptor.interface === DwnInterfaceName.Records &&
|
|
98
|
+
message.descriptor.method === DwnMethodName.Write
|
|
99
|
+
) {
|
|
100
|
+
const quotaResult = await enforceQuota(target, message, context);
|
|
101
|
+
if (quotaResult !== undefined) {
|
|
102
|
+
return quotaResult;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
77
106
|
const reply = await dwn.processMessage(target, message, {
|
|
78
|
-
dataStream
|
|
107
|
+
dataStream,
|
|
79
108
|
subscriptionHandler: subscriptionRequest?.subscriptionHandler,
|
|
80
109
|
});
|
|
81
110
|
|
|
@@ -83,7 +112,7 @@ export const handleDwnProcessMessage: JsonRpcHandler = async (
|
|
|
83
112
|
const { entry } = reply;
|
|
84
113
|
// RecordsRead or MessagesRead messages optionally return data as a stream to accommodate large amounts of data
|
|
85
114
|
// we remove the data stream from the reply that will be serialized and return it as a separate property in the response payload.
|
|
86
|
-
let recordDataStream:
|
|
115
|
+
let recordDataStream: ReadableStream<Uint8Array>;
|
|
87
116
|
if (entry !== undefined && entry.data !== undefined) {
|
|
88
117
|
recordDataStream = entry.data;
|
|
89
118
|
delete reply.entry.data; // not serializable via JSON
|
|
@@ -97,9 +126,9 @@ export const handleDwnProcessMessage: JsonRpcHandler = async (
|
|
|
97
126
|
const subscriptionReply: JsonRpcSubscription = {
|
|
98
127
|
id: subscriptionRequest.id,
|
|
99
128
|
close,
|
|
100
|
-
}
|
|
129
|
+
};
|
|
101
130
|
await socketConnection.addSubscription(subscriptionReply);
|
|
102
|
-
delete reply.subscription.close // delete the close method from the reply as it's not JSON serializable and has a held reference.
|
|
131
|
+
delete reply.subscription.close; // delete the close method from the reply as it's not JSON serializable and has a held reference.
|
|
103
132
|
}
|
|
104
133
|
|
|
105
134
|
const jsonRpcResponse = createJsonRpcSuccessResponse(requestId, { reply });
|
|
@@ -108,16 +137,121 @@ export const handleDwnProcessMessage: JsonRpcHandler = async (
|
|
|
108
137
|
responsePayload.dataStream = recordDataStream;
|
|
109
138
|
}
|
|
110
139
|
|
|
140
|
+
// --- Fire-and-forget: post-processing hooks ---
|
|
141
|
+
const statusCode = reply.status?.code ?? 0;
|
|
142
|
+
if (context.messageProcessedHooks) {
|
|
143
|
+
const hookContext = { tenant: target, message, status: reply.status, transport };
|
|
144
|
+
for (const hook of context.messageProcessedHooks) {
|
|
145
|
+
try {
|
|
146
|
+
const result = hook.onMessageProcessed(hookContext);
|
|
147
|
+
if (result instanceof Promise) {
|
|
148
|
+
result.catch((err: unknown): void => {
|
|
149
|
+
log.error('MessageProcessedHook error', err);
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
} catch (err) {
|
|
153
|
+
log.error('MessageProcessedHook error', err);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// Capture activity event and per-request metrics.
|
|
159
|
+
const dwnInterface = message.descriptor.interface as string;
|
|
160
|
+
const dwnMethod = message.descriptor.method as string;
|
|
161
|
+
const dataSizeBytes = (message.descriptor as { dataSize?: number }).dataSize;
|
|
162
|
+
|
|
163
|
+
if (dataSizeBytes !== undefined && dataSizeBytes > 0) {
|
|
164
|
+
requestDataBytesTotal.inc({ interface: dwnInterface, method: dwnMethod }, dataSizeBytes);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
if (context.activityLog) {
|
|
168
|
+
context.activityLog.record({
|
|
169
|
+
tenant : target,
|
|
170
|
+
interface : dwnInterface,
|
|
171
|
+
method : dwnMethod,
|
|
172
|
+
statusCode,
|
|
173
|
+
transport,
|
|
174
|
+
dataSizeBytes,
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
|
|
111
178
|
return responsePayload;
|
|
112
179
|
} catch (error) {
|
|
180
|
+
// Log the full error internally but return a generic message to the client
|
|
181
|
+
// to avoid leaking implementation details (SQL errors, file paths, etc.).
|
|
182
|
+
log.error('handleDwnProcessMessage error', error);
|
|
183
|
+
|
|
113
184
|
const jsonRpcResponse = createJsonRpcErrorResponse(
|
|
114
185
|
requestId,
|
|
115
186
|
JsonRpcErrorCodes.InternalError,
|
|
116
|
-
error
|
|
187
|
+
'an unexpected error occurred while processing the message',
|
|
117
188
|
);
|
|
118
189
|
|
|
119
|
-
// log the unhandled error response
|
|
120
|
-
log.error('handleDwnProcessMessage error', jsonRpcResponse, dwnRequest, error);
|
|
121
190
|
return { jsonRpcResponse } as HandlerResponse;
|
|
122
191
|
}
|
|
123
192
|
};
|
|
193
|
+
|
|
194
|
+
// ---------------------------------------------------------------------------
|
|
195
|
+
// Quota enforcement helper
|
|
196
|
+
// ---------------------------------------------------------------------------
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Checks whether the tenant has exceeded their message count or storage quota.
|
|
200
|
+
* Returns a JSON-RPC error response if the quota is exceeded, or `undefined` to proceed.
|
|
201
|
+
*/
|
|
202
|
+
async function enforceQuota(
|
|
203
|
+
target: string,
|
|
204
|
+
message: GenericMessage,
|
|
205
|
+
context: Parameters<JsonRpcHandler>[1],
|
|
206
|
+
): Promise<HandlerResponse | undefined> {
|
|
207
|
+
const { config, adminStore, registrationStore } = context;
|
|
208
|
+
const requestId = (message as any).recordId ?? uuidv4();
|
|
209
|
+
|
|
210
|
+
// Resolve effective quota: per-tenant override > global config > unlimited.
|
|
211
|
+
let maxMessages = config!.quotaMaxMessages ?? 0;
|
|
212
|
+
let maxStorageBytes = config!.quotaMaxStorageBytes ?? 0;
|
|
213
|
+
|
|
214
|
+
if (registrationStore) {
|
|
215
|
+
const tenantQuota = await registrationStore.getQuota(target);
|
|
216
|
+
if (tenantQuota !== undefined) {
|
|
217
|
+
maxMessages = tenantQuota.maxMessages ?? maxMessages;
|
|
218
|
+
maxStorageBytes = tenantQuota.maxStorageBytes ?? maxStorageBytes;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// 0 means unlimited — skip enforcement.
|
|
223
|
+
if (maxMessages === 0 && maxStorageBytes === 0) {
|
|
224
|
+
return undefined;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// Check message count quota.
|
|
228
|
+
if (maxMessages > 0) {
|
|
229
|
+
const currentMessages = await adminStore!.getTenantMessageCount(target);
|
|
230
|
+
if (currentMessages >= maxMessages) {
|
|
231
|
+
return {
|
|
232
|
+
jsonRpcResponse: createJsonRpcErrorResponse(
|
|
233
|
+
requestId,
|
|
234
|
+
JsonRpcErrorCodes.InvalidRequest,
|
|
235
|
+
`${DwnServerErrorCode.TenantMessageQuotaExceeded}: tenant has reached the message limit of ${maxMessages}`,
|
|
236
|
+
),
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// Check storage size quota.
|
|
242
|
+
if (maxStorageBytes > 0) {
|
|
243
|
+
const dataSize = (message.descriptor as { dataSize?: number }).dataSize ?? 0;
|
|
244
|
+
const currentStorage = await adminStore!.getTenantStorageSize(target);
|
|
245
|
+
if (currentStorage + dataSize > maxStorageBytes) {
|
|
246
|
+
return {
|
|
247
|
+
jsonRpcResponse: createJsonRpcErrorResponse(
|
|
248
|
+
requestId,
|
|
249
|
+
JsonRpcErrorCodes.InvalidRequest,
|
|
250
|
+
`${DwnServerErrorCode.TenantStorageQuotaExceeded}: tenant would exceed storage limit of ${maxStorageBytes} bytes`,
|
|
251
|
+
),
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
return undefined;
|
|
257
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
2
|
+
|
|
3
|
+
import type { JsonRpcId } from '@enbox/dwn-clients';
|
|
4
|
+
import type {
|
|
5
|
+
HandlerResponse,
|
|
6
|
+
JsonRpcHandler,
|
|
7
|
+
} from '../../lib/json-rpc-router.js';
|
|
8
|
+
|
|
9
|
+
import { createJsonRpcErrorResponse, createJsonRpcSuccessResponse, JsonRpcErrorCodes } from '@enbox/dwn-clients';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Handles `rpc.ack` — acknowledges receipt of subscription events up to the
|
|
13
|
+
* given cursor, advancing the per-subscription flow-control window.
|
|
14
|
+
*
|
|
15
|
+
* Request shape:
|
|
16
|
+
* ```json
|
|
17
|
+
* {
|
|
18
|
+
* "jsonrpc": "2.0",
|
|
19
|
+
* "method": "rpc.ack",
|
|
20
|
+
* "params": { "cursor": "<opaque-cursor>" },
|
|
21
|
+
* "subscription": { "id": "<subscription-id>" }
|
|
22
|
+
* }
|
|
23
|
+
* ```
|
|
24
|
+
*
|
|
25
|
+
* This is a notification (no `id` required), but the server sends a response
|
|
26
|
+
* if validation fails (missing params, unknown subscription, etc.).
|
|
27
|
+
*/
|
|
28
|
+
export const handleSubscriptionAck: JsonRpcHandler = async (
|
|
29
|
+
jsonRpcRequest,
|
|
30
|
+
context,
|
|
31
|
+
) => {
|
|
32
|
+
const requestId = jsonRpcRequest.id ?? uuidv4();
|
|
33
|
+
|
|
34
|
+
if (context.socketConnection === undefined) {
|
|
35
|
+
const jsonRpcResponse = createJsonRpcErrorResponse(
|
|
36
|
+
requestId, JsonRpcErrorCodes.InvalidRequest, 'socket connection does not exist'
|
|
37
|
+
);
|
|
38
|
+
return { jsonRpcResponse };
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (jsonRpcRequest.subscription === undefined) {
|
|
42
|
+
const jsonRpcResponse = createJsonRpcErrorResponse(
|
|
43
|
+
requestId, JsonRpcErrorCodes.InvalidParams, 'subscription options are required'
|
|
44
|
+
);
|
|
45
|
+
return { jsonRpcResponse };
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const { id: subscriptionId } = jsonRpcRequest.subscription as { id: JsonRpcId };
|
|
49
|
+
const { cursor } = (jsonRpcRequest.params ?? {}) as { cursor?: string };
|
|
50
|
+
|
|
51
|
+
if (cursor === undefined || typeof cursor !== 'string' || cursor === '') {
|
|
52
|
+
const jsonRpcResponse = createJsonRpcErrorResponse(
|
|
53
|
+
requestId, JsonRpcErrorCodes.InvalidParams, 'params.cursor is required and must be a non-empty string'
|
|
54
|
+
);
|
|
55
|
+
return { jsonRpcResponse };
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const { socketConnection } = context;
|
|
59
|
+
socketConnection.ackSubscription(subscriptionId, cursor);
|
|
60
|
+
|
|
61
|
+
const jsonRpcResponse = createJsonRpcSuccessResponse(requestId, { reply: { status: 200, detail: 'OK' } });
|
|
62
|
+
return { jsonRpcResponse } as HandlerResponse;
|
|
63
|
+
};
|
|
@@ -1,17 +1,13 @@
|
|
|
1
1
|
import { v4 as uuidv4 } from 'uuid';
|
|
2
2
|
|
|
3
|
-
import { DwnServerErrorCode } from '../../dwn-error.js';
|
|
4
3
|
import type {
|
|
5
4
|
HandlerResponse,
|
|
6
5
|
JsonRpcHandler,
|
|
7
6
|
} from '../../lib/json-rpc-router.js';
|
|
7
|
+
import type { JsonRpcId, JsonRpcResponse } from '@enbox/dwn-clients';
|
|
8
8
|
|
|
9
|
-
import
|
|
10
|
-
import {
|
|
11
|
-
createJsonRpcErrorResponse,
|
|
12
|
-
createJsonRpcSuccessResponse,
|
|
13
|
-
JsonRpcErrorCodes,
|
|
14
|
-
} from '../../lib/json-rpc.js';
|
|
9
|
+
import { DwnServerErrorCode } from '../../dwn-error.js';
|
|
10
|
+
import { createJsonRpcErrorResponse, createJsonRpcSuccessResponse, JsonRpcErrorCodes } from '@enbox/dwn-clients';
|
|
15
11
|
|
|
16
12
|
/**
|
|
17
13
|
* Closes a subscription tied to a specific `SocketConnection`.
|
|
@@ -43,7 +39,7 @@ export const handleSubscriptionsClose: JsonRpcHandler = async (
|
|
|
43
39
|
// closing the subscription and cleaning up the reference within the given connection.
|
|
44
40
|
await socketConnection.closeSubscription(id);
|
|
45
41
|
jsonRpcResponse = createJsonRpcSuccessResponse(requestId, { reply: { status: 200, detail: 'Accepted' } });
|
|
46
|
-
} catch(error) {
|
|
42
|
+
} catch (error) {
|
|
47
43
|
if (error.code === DwnServerErrorCode.ConnectionSubscriptionJsonRpcIdNotFound) {
|
|
48
44
|
jsonRpcResponse = createJsonRpcErrorResponse(requestId, JsonRpcErrorCodes.InvalidParams, `subscription ${id} does not exist.`);
|
|
49
45
|
} else {
|
|
@@ -56,4 +52,4 @@ export const handleSubscriptionsClose: JsonRpcHandler = async (
|
|
|
56
52
|
}
|
|
57
53
|
|
|
58
54
|
return { jsonRpcResponse } as HandlerResponse;
|
|
59
|
-
}
|
|
55
|
+
};
|
|
@@ -1,9 +1,12 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
3
|
-
import type {
|
|
4
|
-
|
|
5
|
-
import type {
|
|
1
|
+
import type { ActivityLog } from '../admin/activity-log.js';
|
|
2
|
+
import type { AdminStore } from '../admin/admin-store.js';
|
|
3
|
+
import type { DwnServerConfig } from '../config.js';
|
|
4
|
+
import type { MessageProcessedHook } from '../message-processed-hook.js';
|
|
5
|
+
import type { RateLimiter } from '../rate-limiter.js';
|
|
6
|
+
import type { RegistrationStore } from '../registration/registration-store.js';
|
|
6
7
|
import type { SocketConnection } from '../connection/socket-connection.js';
|
|
8
|
+
import type { Dwn, SubscriptionListener } from '@enbox/dwn-sdk-js';
|
|
9
|
+
import type { JsonRpcId, JsonRpcRequest, JsonRpcResponse } from '@enbox/dwn-clients';
|
|
7
10
|
|
|
8
11
|
export type RequestContext = {
|
|
9
12
|
transport: 'http' | 'ws';
|
|
@@ -12,17 +15,29 @@ export type RequestContext = {
|
|
|
12
15
|
socketConnection?: SocketConnection;
|
|
13
16
|
subscriptionRequest?: {
|
|
14
17
|
/** The JsonRpcId of the subscription handler */
|
|
15
|
-
id: JsonRpcId;
|
|
16
|
-
/** The `
|
|
17
|
-
subscriptionHandler:
|
|
18
|
+
id: JsonRpcId;
|
|
19
|
+
/** The `SubscriptionMessage` handler associated with a subscription request, only used in `ws` requests */
|
|
20
|
+
subscriptionHandler: SubscriptionListener;
|
|
18
21
|
}
|
|
19
|
-
/** The `
|
|
20
|
-
dataStream?:
|
|
22
|
+
/** The `ReadableStream` associated with a `RecordsWrite` request only used in `http` requests */
|
|
23
|
+
dataStream?: ReadableStream<Uint8Array>;
|
|
24
|
+
/** The admin activity log for capturing DWN request events (optional). */
|
|
25
|
+
activityLog?: ActivityLog;
|
|
26
|
+
/** The admin store for quota usage queries (optional). */
|
|
27
|
+
adminStore?: AdminStore;
|
|
28
|
+
/** The registration store for per-tenant quota lookups (optional). */
|
|
29
|
+
registrationStore?: RegistrationStore;
|
|
30
|
+
/** Server configuration for global quota/rate-limit defaults (optional). */
|
|
31
|
+
config?: DwnServerConfig;
|
|
32
|
+
/** Per-tenant rate limiter (optional). */
|
|
33
|
+
tenantRateLimiter?: RateLimiter;
|
|
34
|
+
/** Hooks invoked after every `dwn.processMessage()` call (fire-and-forget). */
|
|
35
|
+
messageProcessedHooks?: MessageProcessedHook[];
|
|
21
36
|
};
|
|
22
37
|
|
|
23
38
|
export type HandlerResponse = {
|
|
24
39
|
jsonRpcResponse: JsonRpcResponse;
|
|
25
|
-
dataStream?:
|
|
40
|
+
dataStream?: ReadableStream<Uint8Array>;
|
|
26
41
|
};
|
|
27
42
|
|
|
28
43
|
export type JsonRpcHandler = (
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Escapes SQL LIKE wildcard characters (`%`, `_`, `\`) in user-supplied input
|
|
3
|
+
* so that they are treated as literal characters rather than pattern operators.
|
|
4
|
+
*/
|
|
5
|
+
export function escapeLikeWildcards(input: string): string {
|
|
6
|
+
return input.replace(/[%_\\]/g, '\\$&');
|
|
7
|
+
}
|
package/src/main.ts
CHANGED
|
@@ -1,14 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
// node.js 18 and earlier, needs globalThis.crypto polyfill. needed for dwn-sdk-js
|
|
3
|
-
import { webcrypto } from 'node:crypto';
|
|
4
|
-
|
|
5
2
|
import { DwnServer } from './dwn-server.js';
|
|
6
3
|
|
|
7
|
-
if (!globalThis.crypto) {
|
|
8
|
-
// @ts-ignore
|
|
9
|
-
globalThis.crypto = webcrypto;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
4
|
const dwnServer = new DwnServer();
|
|
13
5
|
|
|
14
6
|
await dwnServer.start();
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { GenericMessage } from '@enbox/dwn-sdk-js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Context provided to hooks after `dwn.processMessage()` returns.
|
|
5
|
+
*/
|
|
6
|
+
export type MessageProcessedContext = {
|
|
7
|
+
/** The tenant DID that owns the DWN. */
|
|
8
|
+
tenant: string;
|
|
9
|
+
/** The original signed DWN message. */
|
|
10
|
+
message: GenericMessage;
|
|
11
|
+
/** The reply status from the DWN engine. */
|
|
12
|
+
status: { code: number; detail: string };
|
|
13
|
+
/** The transport over which the message was received. */
|
|
14
|
+
transport: 'http' | 'ws';
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Hook that is invoked after every successful `dwn.processMessage()` call.
|
|
19
|
+
*
|
|
20
|
+
* Hooks are fire-and-forget: they run asynchronously and their return values
|
|
21
|
+
* are ignored. Errors thrown by hooks are logged but never propagate to the
|
|
22
|
+
* request handler or the client.
|
|
23
|
+
*
|
|
24
|
+
* Implementations should return quickly and schedule any expensive work
|
|
25
|
+
* (network I/O, retries) internally.
|
|
26
|
+
*/
|
|
27
|
+
export interface MessageProcessedHook {
|
|
28
|
+
/**
|
|
29
|
+
* Called after a DWN message has been processed.
|
|
30
|
+
* May return void or a Promise — both are handled gracefully.
|
|
31
|
+
*/
|
|
32
|
+
onMessageProcessed(context: MessageProcessedContext): void | Promise<void>;
|
|
33
|
+
}
|
package/src/metrics.ts
CHANGED
|
@@ -1,14 +1,63 @@
|
|
|
1
|
-
import { Counter, Histogram } from 'prom-client';
|
|
1
|
+
import { Counter, Gauge, Histogram } from 'prom-client';
|
|
2
|
+
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
// Existing metrics
|
|
5
|
+
// ---------------------------------------------------------------------------
|
|
2
6
|
|
|
3
7
|
export const requestCounter = new Counter({
|
|
4
|
-
name: 'dwn_requests_total',
|
|
5
|
-
help: 'all dwn requests processed',
|
|
6
|
-
labelNames: ['method', 'status', 'error'],
|
|
8
|
+
name : 'dwn_requests_total',
|
|
9
|
+
help : 'all dwn requests processed',
|
|
10
|
+
labelNames : ['method', 'status', 'error'],
|
|
7
11
|
});
|
|
8
12
|
|
|
9
13
|
export const responseHistogram = new Histogram({
|
|
10
|
-
name: 'http_response',
|
|
11
|
-
help: 'response histogram',
|
|
12
|
-
buckets: [0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10],
|
|
13
|
-
labelNames: ['route', 'code'],
|
|
14
|
+
name : 'http_response',
|
|
15
|
+
help : 'response histogram',
|
|
16
|
+
buckets : [0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10],
|
|
17
|
+
labelNames : ['route', 'code'],
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
// ---------------------------------------------------------------------------
|
|
21
|
+
// Enhanced gauges — updated periodically by AdminApi.startMetricsUpdater()
|
|
22
|
+
// ---------------------------------------------------------------------------
|
|
23
|
+
|
|
24
|
+
/** Number of active (registered) tenants. */
|
|
25
|
+
export const activeTenants = new Gauge({
|
|
26
|
+
name : 'dwn_active_tenants',
|
|
27
|
+
help : 'number of active registered tenants',
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
/** Total messages stored across all tenants. */
|
|
31
|
+
export const totalMessages = new Gauge({
|
|
32
|
+
name : 'dwn_total_messages',
|
|
33
|
+
help : 'total messages stored across all tenants',
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
/** Total data storage in bytes across all tenants. */
|
|
37
|
+
export const totalDataBytes = new Gauge({
|
|
38
|
+
name : 'dwn_total_data_bytes',
|
|
39
|
+
help : 'total data storage bytes across all tenants',
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
/** Number of active WebSocket connections. */
|
|
43
|
+
export const websocketConnections = new Gauge({
|
|
44
|
+
name : 'dwn_websocket_connections',
|
|
45
|
+
help : 'number of active websocket connections',
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
/** Number of active WebSocket subscriptions. */
|
|
49
|
+
export const websocketSubscriptions = new Gauge({
|
|
50
|
+
name : 'dwn_websocket_subscriptions',
|
|
51
|
+
help : 'number of active websocket subscriptions',
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
// ---------------------------------------------------------------------------
|
|
55
|
+
// Enhanced counters — incremented per-request
|
|
56
|
+
// ---------------------------------------------------------------------------
|
|
57
|
+
|
|
58
|
+
/** Total data bytes written via RecordsWrite, labeled by interface + method. */
|
|
59
|
+
export const requestDataBytesTotal = new Counter({
|
|
60
|
+
name : 'dwn_request_data_bytes_total',
|
|
61
|
+
help : 'total data bytes processed in DWN requests',
|
|
62
|
+
labelNames : ['interface', 'method'],
|
|
14
63
|
});
|