velocious 1.0.562 → 1.0.563
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 +3 -1
- package/build/configuration-types.js +1 -0
- package/build/configuration.js +44 -3
- package/build/http-server/client/websocket-session.js +3 -3
- package/build/http-server/client-delivery-queue.js +168 -0
- package/build/http-server/server-client.js +9 -0
- package/build/http-server/websocket-events-host.js +42 -12
- package/build/http-server/worker-handler/in-process.js +53 -14
- package/build/http-server/worker-handler/index.js +88 -18
- package/build/http-server/worker-handler/worker-thread.js +2 -2
- package/build/src/configuration-types.d.ts +8 -0
- package/build/src/configuration-types.d.ts.map +1 -1
- package/build/src/configuration-types.js +2 -1
- package/build/src/configuration.d.ts +34 -1
- package/build/src/configuration.d.ts.map +1 -1
- package/build/src/configuration.js +40 -4
- package/build/src/http-server/client/websocket-session.js +4 -4
- package/build/src/http-server/client-delivery-queue.d.ts +121 -0
- package/build/src/http-server/client-delivery-queue.d.ts.map +1 -0
- package/build/src/http-server/client-delivery-queue.js +152 -0
- package/build/src/http-server/server-client.d.ts +6 -0
- package/build/src/http-server/server-client.d.ts.map +1 -1
- package/build/src/http-server/server-client.js +10 -1
- package/build/src/http-server/websocket-events-host.d.ts +15 -4
- package/build/src/http-server/websocket-events-host.d.ts.map +1 -1
- package/build/src/http-server/websocket-events-host.js +39 -13
- package/build/src/http-server/worker-handler/in-process.d.ts +19 -1
- package/build/src/http-server/worker-handler/in-process.d.ts.map +1 -1
- package/build/src/http-server/worker-handler/in-process.js +50 -14
- package/build/src/http-server/worker-handler/index.d.ts +36 -4
- package/build/src/http-server/worker-handler/index.d.ts.map +1 -1
- package/build/src/http-server/worker-handler/index.js +82 -18
- package/build/src/http-server/worker-handler/worker-thread.js +3 -3
- package/build/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -1
- package/src/configuration-types.js +1 -0
- package/src/configuration.js +44 -3
- package/src/http-server/client/websocket-session.js +3 -3
- package/src/http-server/client-delivery-queue.js +168 -0
- package/src/http-server/server-client.js +9 -0
- package/src/http-server/websocket-events-host.js +42 -12
- package/src/http-server/worker-handler/in-process.js +53 -14
- package/src/http-server/worker-handler/index.js +88 -18
- package/src/http-server/worker-handler/worker-thread.js +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"root":["../index.js","../bin/velocious.js","../src/application.js","../src/configuration-resolver.js","../src/configuration-types.js","../src/configuration.js","../src/controller.js","../src/current-configuration.js","../src/current.js","../src/error-logger.js","../src/frontend-model-controller.js","../src/initializer.js","../src/logger.js","../src/mailer.js","../src/record-payload-values.js","../src/time-zone.js","../src/velocious-error.js","../src/authorization/ability.js","../src/authorization/base-resource.js","../src/background-jobs/client.js","../src/background-jobs/cron-expression.js","../src/background-jobs/forked-runner-child.js","../src/background-jobs/job-record.js","../src/background-jobs/job-registry.js","../src/background-jobs/job-runner.js","../src/background-jobs/job.js","../src/background-jobs/json-socket.js","../src/background-jobs/main.js","../src/background-jobs/normalize-error.js","../src/background-jobs/pooled-runner-child.js","../src/background-jobs/runner-graceful-shutdown.js","../src/background-jobs/runner-process-title.js","../src/background-jobs/scheduler.js","../src/background-jobs/socket-request.js","../src/background-jobs/status-reporter.js","../src/background-jobs/store.js","../src/background-jobs/types.js","../src/background-jobs/worker.js","../src/background-jobs/web/authorization.js","../src/background-jobs/web/controller.js","../src/background-jobs/web/counts-channel.js","../src/background-jobs/web/index.js","../src/background-jobs/web/path-matcher.js","../src/background-jobs/web/registry.js","../src/beacon/client.js","../src/beacon/in-process-broker.js","../src/beacon/in-process-client.js","../src/beacon/server.js","../src/beacon/types.js","../src/cli/base-command.js","../src/cli/browser-cli.js","../src/cli/index.js","../src/cli/tenant-database-command-helper.js","../src/cli/use-browser-cli.js","../src/cli/commands/background-jobs-main.js","../src/cli/commands/background-jobs-runner.js","../src/cli/commands/background-jobs-worker.js","../src/cli/commands/beacon.js","../src/cli/commands/console.js","../src/cli/commands/init.js","../src/cli/commands/routes.js","../src/cli/commands/run-script.js","../src/cli/commands/runner.js","../src/cli/commands/server.js","../src/cli/commands/test.js","../src/cli/commands/db/base-command.js","../src/cli/commands/db/create.js","../src/cli/commands/db/drop.js","../src/cli/commands/db/migrate.js","../src/cli/commands/db/reset.js","../src/cli/commands/db/rollback.js","../src/cli/commands/db/seed.js","../src/cli/commands/db/schema/dump.js","../src/cli/commands/db/schema/load.js","../src/cli/commands/db/tenants/check.js","../src/cli/commands/db/tenants/create.js","../src/cli/commands/db/tenants/drop.js","../src/cli/commands/db/tenants/migrate.js","../src/cli/commands/destroy/migration.js","../src/cli/commands/generate/base-models.js","../src/cli/commands/generate/frontend-models.js","../src/cli/commands/generate/migration.js","../src/cli/commands/generate/model.js","../src/cli/commands/lint/relationships.js","../src/database/advisory-lock-runner.js","../src/database/annotations-async-hooks.js","../src/database/annotations.js","../src/database/column-types.js","../src/database/datetime-storage.js","../src/database/handler.js","../src/database/initializer-from-require-context.js","../src/database/live-query.js","../src/database/migrations-ledger.js","../src/database/migrator.js","../src/database/query-aborted-error.js","../src/database/record-changes.js","../src/database/structure-sql-loader.js","../src/database/use-database.js","../src/database/use-live-query.js","../src/database/drivers/base-column.js","../src/database/drivers/base-columns-index.js","../src/database/drivers/base-foreign-key.js","../src/database/drivers/base-table.js","../src/database/drivers/base.js","../src/database/drivers/mssql/column.js","../src/database/drivers/mssql/columns-index.js","../src/database/drivers/mssql/connect-connection.js","../src/database/drivers/mssql/foreign-key.js","../src/database/drivers/mssql/index.js","../src/database/drivers/mssql/options.js","../src/database/drivers/mssql/query-parser.js","../src/database/drivers/mssql/structure-sql.js","../src/database/drivers/mssql/table.js","../src/database/drivers/mssql/sql/alter-table.js","../src/database/drivers/mssql/sql/create-database.js","../src/database/drivers/mssql/sql/create-index.js","../src/database/drivers/mssql/sql/create-table.js","../src/database/drivers/mssql/sql/delete.js","../src/database/drivers/mssql/sql/drop-database.js","../src/database/drivers/mssql/sql/drop-table.js","../src/database/drivers/mssql/sql/insert.js","../src/database/drivers/mssql/sql/remove-index.js","../src/database/drivers/mssql/sql/update.js","../src/database/drivers/mssql/sql/upsert.js","../src/database/drivers/mysql/column.js","../src/database/drivers/mysql/columns-index.js","../src/database/drivers/mysql/foreign-key.js","../src/database/drivers/mysql/index.js","../src/database/drivers/mysql/options.js","../src/database/drivers/mysql/query-parser.js","../src/database/drivers/mysql/query-stream.js","../src/database/drivers/mysql/query.js","../src/database/drivers/mysql/structure-sql.js","../src/database/drivers/mysql/table.js","../src/database/drivers/mysql/sql/alter-table.js","../src/database/drivers/mysql/sql/create-database.js","../src/database/drivers/mysql/sql/create-index.js","../src/database/drivers/mysql/sql/create-table.js","../src/database/drivers/mysql/sql/delete.js","../src/database/drivers/mysql/sql/drop-database.js","../src/database/drivers/mysql/sql/drop-table.js","../src/database/drivers/mysql/sql/insert.js","../src/database/drivers/mysql/sql/remove-index.js","../src/database/drivers/mysql/sql/update.js","../src/database/drivers/mysql/sql/upsert.js","../src/database/drivers/pgsql/column.js","../src/database/drivers/pgsql/columns-index.js","../src/database/drivers/pgsql/foreign-key.js","../src/database/drivers/pgsql/index.js","../src/database/drivers/pgsql/options.js","../src/database/drivers/pgsql/query-parser.js","../src/database/drivers/pgsql/structure-sql.js","../src/database/drivers/pgsql/table.js","../src/database/drivers/pgsql/sql/alter-table.js","../src/database/drivers/pgsql/sql/create-database.js","../src/database/drivers/pgsql/sql/create-index.js","../src/database/drivers/pgsql/sql/create-table.js","../src/database/drivers/pgsql/sql/delete.js","../src/database/drivers/pgsql/sql/drop-database.js","../src/database/drivers/pgsql/sql/drop-table.js","../src/database/drivers/pgsql/sql/insert.js","../src/database/drivers/pgsql/sql/remove-index.js","../src/database/drivers/pgsql/sql/update.js","../src/database/drivers/pgsql/sql/upsert.js","../src/database/drivers/sqlite/base.js","../src/database/drivers/sqlite/column.js","../src/database/drivers/sqlite/columns-index.js","../src/database/drivers/sqlite/connection-sql-js.js","../src/database/drivers/sqlite/foreign-key.js","../src/database/drivers/sqlite/index.js","../src/database/drivers/sqlite/index.native.js","../src/database/drivers/sqlite/index.web.js","../src/database/drivers/sqlite/options.js","../src/database/drivers/sqlite/query-parser.js","../src/database/drivers/sqlite/query.js","../src/database/drivers/sqlite/query.native.js","../src/database/drivers/sqlite/query.web.js","../src/database/drivers/sqlite/structure-sql.js","../src/database/drivers/sqlite/table-rebuilder.js","../src/database/drivers/sqlite/table.js","../src/database/drivers/sqlite/web-persistence.js","../src/database/drivers/sqlite/sql/alter-table.js","../src/database/drivers/sqlite/sql/create-index.js","../src/database/drivers/sqlite/sql/create-table.js","../src/database/drivers/sqlite/sql/delete.js","../src/database/drivers/sqlite/sql/drop-table.js","../src/database/drivers/sqlite/sql/insert.js","../src/database/drivers/sqlite/sql/remove-index.js","../src/database/drivers/sqlite/sql/update.js","../src/database/drivers/sqlite/sql/upsert.js","../src/database/drivers/structure-sql/utils.js","../src/database/migration/index.js","../src/database/migrator/files-finder.js","../src/database/migrator/types.js","../src/database/pool/async-tracked-multi-connection.js","../src/database/pool/base-methods-forward.js","../src/database/pool/base.js","../src/database/pool/single-multi-use.js","../src/database/query/alter-table-base.js","../src/database/query/base.js","../src/database/query/create-database-base.js","../src/database/query/create-index-base.js","../src/database/query/create-table-base.js","../src/database/query/delete-base.js","../src/database/query/drop-database-base.js","../src/database/query/drop-table-base.js","../src/database/query/from-base.js","../src/database/query/from-plain.js","../src/database/query/from-table.js","../src/database/query/index.js","../src/database/query/insert-base.js","../src/database/query/join-base.js","../src/database/query/join-object.js","../src/database/query/join-plain.js","../src/database/query/join-tracker.js","../src/database/query/model-class-query.js","../src/database/query/order-base.js","../src/database/query/order-column.js","../src/database/query/order-plain.js","../src/database/query/preloader.js","../src/database/query/query-data.js","../src/database/query/remove-index-base.js","../src/database/query/select-base.js","../src/database/query/select-plain.js","../src/database/query/select-table-and-column.js","../src/database/query/update-base.js","../src/database/query/upsert-base.js","../src/database/query/where-base.js","../src/database/query/where-combinator.js","../src/database/query/where-hash.js","../src/database/query/where-model-class-hash.js","../src/database/query/where-not.js","../src/database/query/where-plain.js","../src/database/query/with-count.js","../src/database/query/preloader/belongs-to.js","../src/database/query/preloader/ensure-model-class-initialized.js","../src/database/query/preloader/has-many.js","../src/database/query/preloader/has-one.js","../src/database/query/preloader/selection.js","../src/database/query-parser/base-query-parser.js","../src/database/query-parser/from-parser.js","../src/database/query-parser/group-parser.js","../src/database/query-parser/joins-parser.js","../src/database/query-parser/limit-parser.js","../src/database/query-parser/options.js","../src/database/query-parser/order-parser.js","../src/database/query-parser/select-parser.js","../src/database/query-parser/where-parser.js","../src/database/record/acts-as-list.js","../src/database/record/auditing.js","../src/database/record/counter-cache-magnitude.js","../src/database/record/index.js","../src/database/record/record-not-found-error.js","../src/database/record/state-machine.js","../src/database/record/user-module.js","../src/database/record/validation-messages.js","../src/database/record/attachments/attachment-record.js","../src/database/record/attachments/download.js","../src/database/record/attachments/handle.js","../src/database/record/attachments/normalize-input.js","../src/database/record/attachments/store.js","../src/database/record/attachments/storage-drivers/filesystem.js","../src/database/record/attachments/storage-drivers/native.js","../src/database/record/attachments/storage-drivers/s3.js","../src/database/record/instance-relationships/base.js","../src/database/record/instance-relationships/belongs-to.js","../src/database/record/instance-relationships/has-many.js","../src/database/record/instance-relationships/has-one.js","../src/database/record/relationships/base.js","../src/database/record/relationships/belongs-to.js","../src/database/record/relationships/has-many.js","../src/database/record/relationships/has-one.js","../src/database/record/validators/base.js","../src/database/record/validators/format.js","../src/database/record/validators/length.js","../src/database/record/validators/presence.js","../src/database/record/validators/uniqueness.js","../src/database/table-data/index.js","../src/database/table-data/table-column.js","../src/database/table-data/table-foreign-key.js","../src/database/table-data/table-index.js","../src/database/table-data/table-reference.js","../src/database/tenants/data-copier.js","../src/database/tenants/schema-cloner.js","../src/database/tenants/tenant-table-plan.js","../src/environment-handlers/base.js","../src/environment-handlers/browser.js","../src/environment-handlers/node.js","../src/environment-handlers/node/cli/commands/background-jobs-main.js","../src/environment-handlers/node/cli/commands/background-jobs-runner.js","../src/environment-handlers/node/cli/commands/background-jobs-worker.js","../src/environment-handlers/node/cli/commands/beacon.js","../src/environment-handlers/node/cli/commands/cli-command-context.js","../src/environment-handlers/node/cli/commands/console.js","../src/environment-handlers/node/cli/commands/init.js","../src/environment-handlers/node/cli/commands/routes.js","../src/environment-handlers/node/cli/commands/run-script.js","../src/environment-handlers/node/cli/commands/runner.js","../src/environment-handlers/node/cli/commands/server.js","../src/environment-handlers/node/cli/commands/test.js","../src/environment-handlers/node/cli/commands/db/seed.js","../src/environment-handlers/node/cli/commands/db/schema/dump.js","../src/environment-handlers/node/cli/commands/db/schema/load.js","../src/environment-handlers/node/cli/commands/destroy/migration.js","../src/environment-handlers/node/cli/commands/generate/base-models.js","../src/environment-handlers/node/cli/commands/generate/frontend-models.js","../src/environment-handlers/node/cli/commands/generate/generated-file-banner.js","../src/environment-handlers/node/cli/commands/generate/migration.js","../src/environment-handlers/node/cli/commands/generate/model.js","../src/environment-handlers/node/cli/commands/lint/relationships.js","../src/error-reporting/request-details.js","../src/frontend-model-resource/base-resource.js","../src/frontend-model-resource/velocious-attachment-resource.js","../src/frontend-models/base.js","../src/frontend-models/built-in-resources.js","../src/frontend-models/clear-pending-debounced-callback.js","../src/frontend-models/event-hook-models.js","../src/frontend-models/model-registry.js","../src/frontend-models/outgoing-event-buffer.js","../src/frontend-models/preloader.js","../src/frontend-models/query.js","../src/frontend-models/resource-config-validation.js","../src/frontend-models/resource-definition.js","../src/frontend-models/transport-deadline.js","../src/frontend-models/transport-serialization.js","../src/frontend-models/use-created-event.js","../src/frontend-models/use-destroyed-event.js","../src/frontend-models/use-model-class-event.js","../src/frontend-models/use-updated-event.js","../src/frontend-models/websocket-channel.js","../src/frontend-models/websocket-publishers.js","../src/http-client/header.js","../src/http-client/index.js","../src/http-client/request.js","../src/http-client/response.js","../src/http-client/websocket-client.js","../src/http-server/cookie.js","../src/http-server/development-reloader.js","../src/http-server/index.js","../src/http-server/remote-address.js","../src/http-server/server-client.js","../src/http-server/server-lock.js","../src/http-server/websocket-channel-subscribers.js","../src/http-server/websocket-channel.js","../src/http-server/websocket-connection.js","../src/http-server/websocket-event-log-store.js","../src/http-server/websocket-events-host.js","../src/http-server/websocket-events.js","../src/http-server/client/index.js","../src/http-server/client/params-to-object.js","../src/http-server/client/request-parser.js","../src/http-server/client/request-runner.js","../src/http-server/client/request-timing.js","../src/http-server/client/request.js","../src/http-server/client/response.js","../src/http-server/client/websocket-request.js","../src/http-server/client/websocket-session.js","../src/http-server/client/request-buffer/form-data-part.js","../src/http-server/client/request-buffer/header.js","../src/http-server/client/request-buffer/index.js","../src/http-server/client/uploaded-file/memory-uploaded-file.js","../src/http-server/client/uploaded-file/temporary-uploaded-file.js","../src/http-server/client/uploaded-file/uploaded-file.js","../src/http-server/worker-handler/channel-subscriber-dispatch.js","../src/http-server/worker-handler/in-process.js","../src/http-server/worker-handler/index.js","../src/http-server/worker-handler/worker-script.js","../src/http-server/worker-handler/worker-thread.js","../src/jobs/mail-delivery.js","../src/jobs/prune-terminal-background-jobs.js","../src/logger/base-logger.js","../src/logger/console-logger.js","../src/logger/file-logger.js","../src/logger/outputs/array-output.js","../src/logger/outputs/console-output.js","../src/logger/outputs/file-output.js","../src/logger/outputs/stdout-output.js","../src/mailer/base.js","../src/mailer/delivery.js","../src/mailer/index.js","../src/mailer/backends/smtp.js","../src/packages/velocious-package.js","../src/plugins/sqljs-wasm-route-controller.js","../src/plugins/sqljs-wasm-route.js","../src/routes/app-routes.js","../src/routes/base-route.js","../src/routes/basic-route.js","../src/routes/get-route.js","../src/routes/index.js","../src/routes/namespace-route.js","../src/routes/plugin-routes.js","../src/routes/post-route.js","../src/routes/resolver.js","../src/routes/resource-route.js","../src/routes/root-route.js","../src/routes/built-in/api-manifest/controller.js","../src/routes/built-in/debug/controller.js","../src/routes/built-in/errors/controller.js","../src/routes/hooks/frontend-model-command-route-hook.js","../src/sync/conflict-strategy.js","../src/sync/device-identity.js","../src/sync/local-mutation-log.js","../src/sync/offline-grant.js","../src/sync/peer-mutation-bundle.js","../src/sync/query-scope.js","../src/sync/server-change-feed.js","../src/sync/server-sequence-allocator.js","../src/sync/stable-json.js","../src/sync/sync-api-client-types.js","../src/sync/sync-api-client.js","../src/sync/sync-api-controller.js","../src/sync/sync-change-fanout.js","../src/sync/sync-channel-name.js","../src/sync/sync-client-registry.js","../src/sync/sync-client-types.js","../src/sync/sync-client.js","../src/sync/sync-envelope-replay-service.js","../src/sync/sync-model-change-feed-service.js","../src/sync/sync-publish-suppression.js","../src/sync/sync-publisher-types.js","../src/sync/sync-publisher.js","../src/sync/sync-realtime-bridge.js","../src/sync/sync-replay-upsert-applier.js","../src/sync/sync-resource-base.js","../src/sync/sync-scope-attributes.js","../src/sync/sync-scope-store.js","../src/sync/sync-websocket-channel.js","../src/tenants/default-tenant-database-provisioning.js","../src/tenants/tenant-aggregator.js","../src/tenants/tenant-iterator.js","../src/tenants/tenant.js","../src/testing/base-expect.js","../src/testing/browser-frontend-model-event-hook-scenarios.js","../src/testing/browser-test-app.js","../src/testing/expect-to-change.js","../src/testing/expect-utils.js","../src/testing/expect.js","../src/testing/request-client.js","../src/testing/test-files-finder.js","../src/testing/test-filter-parser.js","../src/testing/test-runner.js","../src/testing/test-suite-splitter.js","../src/testing/test.js","../src/testing/wait-for-event.js","../src/testing/factory/association-declaration.js","../src/testing/factory/declarations.js","../src/testing/factory/definition-builder.js","../src/testing/factory/errors.js","../src/testing/factory/evaluation-context.js","../src/testing/factory/events.js","../src/testing/factory/factory-definition.js","../src/testing/factory/factory-registry.js","../src/testing/factory/factory-runner.js","../src/testing/factory/index.js","../src/testing/factory/linter.js","../src/testing/factory/model-contract.js","../src/testing/factory/sequence.js","../src/testing/factory/trait-definition.js","../src/testing/factory/node/load-definitions.js","../src/testing/factory/strategies/attributes-for.js","../src/testing/factory/strategies/base.js","../src/testing/factory/strategies/build.js","../src/testing/factory/strategies/create.js","../src/types/external-modules.d.ts","../src/utils/backtrace-cleaner-node.js","../src/utils/backtrace-cleaner.js","../src/utils/deburr-column-name.js","../src/utils/event-emitter.js","../src/utils/file-exists.js","../src/utils/format-value.js","../src/utils/is-date.js","../src/utils/model-scope.js","../src/utils/nest-callbacks.js","../src/utils/plain-object.js","../src/utils/ransack.js","../src/utils/rest-args-error.js","../src/utils/shutdown-lifecycle.js","../src/utils/singularize-model-name.js","../src/utils/split-sql-statements.js","../src/utils/to-import-specifier.js","../src/utils/with-tracked-stack-async-hooks.js","../src/utils/with-tracked-stack.js"],"version":"6.0.3"}
|
|
1
|
+
{"root":["../index.js","../bin/velocious.js","../src/application.js","../src/configuration-resolver.js","../src/configuration-types.js","../src/configuration.js","../src/controller.js","../src/current-configuration.js","../src/current.js","../src/error-logger.js","../src/frontend-model-controller.js","../src/initializer.js","../src/logger.js","../src/mailer.js","../src/record-payload-values.js","../src/time-zone.js","../src/velocious-error.js","../src/authorization/ability.js","../src/authorization/base-resource.js","../src/background-jobs/client.js","../src/background-jobs/cron-expression.js","../src/background-jobs/forked-runner-child.js","../src/background-jobs/job-record.js","../src/background-jobs/job-registry.js","../src/background-jobs/job-runner.js","../src/background-jobs/job.js","../src/background-jobs/json-socket.js","../src/background-jobs/main.js","../src/background-jobs/normalize-error.js","../src/background-jobs/pooled-runner-child.js","../src/background-jobs/runner-graceful-shutdown.js","../src/background-jobs/runner-process-title.js","../src/background-jobs/scheduler.js","../src/background-jobs/socket-request.js","../src/background-jobs/status-reporter.js","../src/background-jobs/store.js","../src/background-jobs/types.js","../src/background-jobs/worker.js","../src/background-jobs/web/authorization.js","../src/background-jobs/web/controller.js","../src/background-jobs/web/counts-channel.js","../src/background-jobs/web/index.js","../src/background-jobs/web/path-matcher.js","../src/background-jobs/web/registry.js","../src/beacon/client.js","../src/beacon/in-process-broker.js","../src/beacon/in-process-client.js","../src/beacon/server.js","../src/beacon/types.js","../src/cli/base-command.js","../src/cli/browser-cli.js","../src/cli/index.js","../src/cli/tenant-database-command-helper.js","../src/cli/use-browser-cli.js","../src/cli/commands/background-jobs-main.js","../src/cli/commands/background-jobs-runner.js","../src/cli/commands/background-jobs-worker.js","../src/cli/commands/beacon.js","../src/cli/commands/console.js","../src/cli/commands/init.js","../src/cli/commands/routes.js","../src/cli/commands/run-script.js","../src/cli/commands/runner.js","../src/cli/commands/server.js","../src/cli/commands/test.js","../src/cli/commands/db/base-command.js","../src/cli/commands/db/create.js","../src/cli/commands/db/drop.js","../src/cli/commands/db/migrate.js","../src/cli/commands/db/reset.js","../src/cli/commands/db/rollback.js","../src/cli/commands/db/seed.js","../src/cli/commands/db/schema/dump.js","../src/cli/commands/db/schema/load.js","../src/cli/commands/db/tenants/check.js","../src/cli/commands/db/tenants/create.js","../src/cli/commands/db/tenants/drop.js","../src/cli/commands/db/tenants/migrate.js","../src/cli/commands/destroy/migration.js","../src/cli/commands/generate/base-models.js","../src/cli/commands/generate/frontend-models.js","../src/cli/commands/generate/migration.js","../src/cli/commands/generate/model.js","../src/cli/commands/lint/relationships.js","../src/database/advisory-lock-runner.js","../src/database/annotations-async-hooks.js","../src/database/annotations.js","../src/database/column-types.js","../src/database/datetime-storage.js","../src/database/handler.js","../src/database/initializer-from-require-context.js","../src/database/live-query.js","../src/database/migrations-ledger.js","../src/database/migrator.js","../src/database/query-aborted-error.js","../src/database/record-changes.js","../src/database/structure-sql-loader.js","../src/database/use-database.js","../src/database/use-live-query.js","../src/database/drivers/base-column.js","../src/database/drivers/base-columns-index.js","../src/database/drivers/base-foreign-key.js","../src/database/drivers/base-table.js","../src/database/drivers/base.js","../src/database/drivers/mssql/column.js","../src/database/drivers/mssql/columns-index.js","../src/database/drivers/mssql/connect-connection.js","../src/database/drivers/mssql/foreign-key.js","../src/database/drivers/mssql/index.js","../src/database/drivers/mssql/options.js","../src/database/drivers/mssql/query-parser.js","../src/database/drivers/mssql/structure-sql.js","../src/database/drivers/mssql/table.js","../src/database/drivers/mssql/sql/alter-table.js","../src/database/drivers/mssql/sql/create-database.js","../src/database/drivers/mssql/sql/create-index.js","../src/database/drivers/mssql/sql/create-table.js","../src/database/drivers/mssql/sql/delete.js","../src/database/drivers/mssql/sql/drop-database.js","../src/database/drivers/mssql/sql/drop-table.js","../src/database/drivers/mssql/sql/insert.js","../src/database/drivers/mssql/sql/remove-index.js","../src/database/drivers/mssql/sql/update.js","../src/database/drivers/mssql/sql/upsert.js","../src/database/drivers/mysql/column.js","../src/database/drivers/mysql/columns-index.js","../src/database/drivers/mysql/foreign-key.js","../src/database/drivers/mysql/index.js","../src/database/drivers/mysql/options.js","../src/database/drivers/mysql/query-parser.js","../src/database/drivers/mysql/query-stream.js","../src/database/drivers/mysql/query.js","../src/database/drivers/mysql/structure-sql.js","../src/database/drivers/mysql/table.js","../src/database/drivers/mysql/sql/alter-table.js","../src/database/drivers/mysql/sql/create-database.js","../src/database/drivers/mysql/sql/create-index.js","../src/database/drivers/mysql/sql/create-table.js","../src/database/drivers/mysql/sql/delete.js","../src/database/drivers/mysql/sql/drop-database.js","../src/database/drivers/mysql/sql/drop-table.js","../src/database/drivers/mysql/sql/insert.js","../src/database/drivers/mysql/sql/remove-index.js","../src/database/drivers/mysql/sql/update.js","../src/database/drivers/mysql/sql/upsert.js","../src/database/drivers/pgsql/column.js","../src/database/drivers/pgsql/columns-index.js","../src/database/drivers/pgsql/foreign-key.js","../src/database/drivers/pgsql/index.js","../src/database/drivers/pgsql/options.js","../src/database/drivers/pgsql/query-parser.js","../src/database/drivers/pgsql/structure-sql.js","../src/database/drivers/pgsql/table.js","../src/database/drivers/pgsql/sql/alter-table.js","../src/database/drivers/pgsql/sql/create-database.js","../src/database/drivers/pgsql/sql/create-index.js","../src/database/drivers/pgsql/sql/create-table.js","../src/database/drivers/pgsql/sql/delete.js","../src/database/drivers/pgsql/sql/drop-database.js","../src/database/drivers/pgsql/sql/drop-table.js","../src/database/drivers/pgsql/sql/insert.js","../src/database/drivers/pgsql/sql/remove-index.js","../src/database/drivers/pgsql/sql/update.js","../src/database/drivers/pgsql/sql/upsert.js","../src/database/drivers/sqlite/base.js","../src/database/drivers/sqlite/column.js","../src/database/drivers/sqlite/columns-index.js","../src/database/drivers/sqlite/connection-sql-js.js","../src/database/drivers/sqlite/foreign-key.js","../src/database/drivers/sqlite/index.js","../src/database/drivers/sqlite/index.native.js","../src/database/drivers/sqlite/index.web.js","../src/database/drivers/sqlite/options.js","../src/database/drivers/sqlite/query-parser.js","../src/database/drivers/sqlite/query.js","../src/database/drivers/sqlite/query.native.js","../src/database/drivers/sqlite/query.web.js","../src/database/drivers/sqlite/structure-sql.js","../src/database/drivers/sqlite/table-rebuilder.js","../src/database/drivers/sqlite/table.js","../src/database/drivers/sqlite/web-persistence.js","../src/database/drivers/sqlite/sql/alter-table.js","../src/database/drivers/sqlite/sql/create-index.js","../src/database/drivers/sqlite/sql/create-table.js","../src/database/drivers/sqlite/sql/delete.js","../src/database/drivers/sqlite/sql/drop-table.js","../src/database/drivers/sqlite/sql/insert.js","../src/database/drivers/sqlite/sql/remove-index.js","../src/database/drivers/sqlite/sql/update.js","../src/database/drivers/sqlite/sql/upsert.js","../src/database/drivers/structure-sql/utils.js","../src/database/migration/index.js","../src/database/migrator/files-finder.js","../src/database/migrator/types.js","../src/database/pool/async-tracked-multi-connection.js","../src/database/pool/base-methods-forward.js","../src/database/pool/base.js","../src/database/pool/single-multi-use.js","../src/database/query/alter-table-base.js","../src/database/query/base.js","../src/database/query/create-database-base.js","../src/database/query/create-index-base.js","../src/database/query/create-table-base.js","../src/database/query/delete-base.js","../src/database/query/drop-database-base.js","../src/database/query/drop-table-base.js","../src/database/query/from-base.js","../src/database/query/from-plain.js","../src/database/query/from-table.js","../src/database/query/index.js","../src/database/query/insert-base.js","../src/database/query/join-base.js","../src/database/query/join-object.js","../src/database/query/join-plain.js","../src/database/query/join-tracker.js","../src/database/query/model-class-query.js","../src/database/query/order-base.js","../src/database/query/order-column.js","../src/database/query/order-plain.js","../src/database/query/preloader.js","../src/database/query/query-data.js","../src/database/query/remove-index-base.js","../src/database/query/select-base.js","../src/database/query/select-plain.js","../src/database/query/select-table-and-column.js","../src/database/query/update-base.js","../src/database/query/upsert-base.js","../src/database/query/where-base.js","../src/database/query/where-combinator.js","../src/database/query/where-hash.js","../src/database/query/where-model-class-hash.js","../src/database/query/where-not.js","../src/database/query/where-plain.js","../src/database/query/with-count.js","../src/database/query/preloader/belongs-to.js","../src/database/query/preloader/ensure-model-class-initialized.js","../src/database/query/preloader/has-many.js","../src/database/query/preloader/has-one.js","../src/database/query/preloader/selection.js","../src/database/query-parser/base-query-parser.js","../src/database/query-parser/from-parser.js","../src/database/query-parser/group-parser.js","../src/database/query-parser/joins-parser.js","../src/database/query-parser/limit-parser.js","../src/database/query-parser/options.js","../src/database/query-parser/order-parser.js","../src/database/query-parser/select-parser.js","../src/database/query-parser/where-parser.js","../src/database/record/acts-as-list.js","../src/database/record/auditing.js","../src/database/record/counter-cache-magnitude.js","../src/database/record/index.js","../src/database/record/record-not-found-error.js","../src/database/record/state-machine.js","../src/database/record/user-module.js","../src/database/record/validation-messages.js","../src/database/record/attachments/attachment-record.js","../src/database/record/attachments/download.js","../src/database/record/attachments/handle.js","../src/database/record/attachments/normalize-input.js","../src/database/record/attachments/store.js","../src/database/record/attachments/storage-drivers/filesystem.js","../src/database/record/attachments/storage-drivers/native.js","../src/database/record/attachments/storage-drivers/s3.js","../src/database/record/instance-relationships/base.js","../src/database/record/instance-relationships/belongs-to.js","../src/database/record/instance-relationships/has-many.js","../src/database/record/instance-relationships/has-one.js","../src/database/record/relationships/base.js","../src/database/record/relationships/belongs-to.js","../src/database/record/relationships/has-many.js","../src/database/record/relationships/has-one.js","../src/database/record/validators/base.js","../src/database/record/validators/format.js","../src/database/record/validators/length.js","../src/database/record/validators/presence.js","../src/database/record/validators/uniqueness.js","../src/database/table-data/index.js","../src/database/table-data/table-column.js","../src/database/table-data/table-foreign-key.js","../src/database/table-data/table-index.js","../src/database/table-data/table-reference.js","../src/database/tenants/data-copier.js","../src/database/tenants/schema-cloner.js","../src/database/tenants/tenant-table-plan.js","../src/environment-handlers/base.js","../src/environment-handlers/browser.js","../src/environment-handlers/node.js","../src/environment-handlers/node/cli/commands/background-jobs-main.js","../src/environment-handlers/node/cli/commands/background-jobs-runner.js","../src/environment-handlers/node/cli/commands/background-jobs-worker.js","../src/environment-handlers/node/cli/commands/beacon.js","../src/environment-handlers/node/cli/commands/cli-command-context.js","../src/environment-handlers/node/cli/commands/console.js","../src/environment-handlers/node/cli/commands/init.js","../src/environment-handlers/node/cli/commands/routes.js","../src/environment-handlers/node/cli/commands/run-script.js","../src/environment-handlers/node/cli/commands/runner.js","../src/environment-handlers/node/cli/commands/server.js","../src/environment-handlers/node/cli/commands/test.js","../src/environment-handlers/node/cli/commands/db/seed.js","../src/environment-handlers/node/cli/commands/db/schema/dump.js","../src/environment-handlers/node/cli/commands/db/schema/load.js","../src/environment-handlers/node/cli/commands/destroy/migration.js","../src/environment-handlers/node/cli/commands/generate/base-models.js","../src/environment-handlers/node/cli/commands/generate/frontend-models.js","../src/environment-handlers/node/cli/commands/generate/generated-file-banner.js","../src/environment-handlers/node/cli/commands/generate/migration.js","../src/environment-handlers/node/cli/commands/generate/model.js","../src/environment-handlers/node/cli/commands/lint/relationships.js","../src/error-reporting/request-details.js","../src/frontend-model-resource/base-resource.js","../src/frontend-model-resource/velocious-attachment-resource.js","../src/frontend-models/base.js","../src/frontend-models/built-in-resources.js","../src/frontend-models/clear-pending-debounced-callback.js","../src/frontend-models/event-hook-models.js","../src/frontend-models/model-registry.js","../src/frontend-models/outgoing-event-buffer.js","../src/frontend-models/preloader.js","../src/frontend-models/query.js","../src/frontend-models/resource-config-validation.js","../src/frontend-models/resource-definition.js","../src/frontend-models/transport-deadline.js","../src/frontend-models/transport-serialization.js","../src/frontend-models/use-created-event.js","../src/frontend-models/use-destroyed-event.js","../src/frontend-models/use-model-class-event.js","../src/frontend-models/use-updated-event.js","../src/frontend-models/websocket-channel.js","../src/frontend-models/websocket-publishers.js","../src/http-client/header.js","../src/http-client/index.js","../src/http-client/request.js","../src/http-client/response.js","../src/http-client/websocket-client.js","../src/http-server/client-delivery-queue.js","../src/http-server/cookie.js","../src/http-server/development-reloader.js","../src/http-server/index.js","../src/http-server/remote-address.js","../src/http-server/server-client.js","../src/http-server/server-lock.js","../src/http-server/websocket-channel-subscribers.js","../src/http-server/websocket-channel.js","../src/http-server/websocket-connection.js","../src/http-server/websocket-event-log-store.js","../src/http-server/websocket-events-host.js","../src/http-server/websocket-events.js","../src/http-server/client/index.js","../src/http-server/client/params-to-object.js","../src/http-server/client/request-parser.js","../src/http-server/client/request-runner.js","../src/http-server/client/request-timing.js","../src/http-server/client/request.js","../src/http-server/client/response.js","../src/http-server/client/websocket-request.js","../src/http-server/client/websocket-session.js","../src/http-server/client/request-buffer/form-data-part.js","../src/http-server/client/request-buffer/header.js","../src/http-server/client/request-buffer/index.js","../src/http-server/client/uploaded-file/memory-uploaded-file.js","../src/http-server/client/uploaded-file/temporary-uploaded-file.js","../src/http-server/client/uploaded-file/uploaded-file.js","../src/http-server/worker-handler/channel-subscriber-dispatch.js","../src/http-server/worker-handler/in-process.js","../src/http-server/worker-handler/index.js","../src/http-server/worker-handler/worker-script.js","../src/http-server/worker-handler/worker-thread.js","../src/jobs/mail-delivery.js","../src/jobs/prune-terminal-background-jobs.js","../src/logger/base-logger.js","../src/logger/console-logger.js","../src/logger/file-logger.js","../src/logger/outputs/array-output.js","../src/logger/outputs/console-output.js","../src/logger/outputs/file-output.js","../src/logger/outputs/stdout-output.js","../src/mailer/base.js","../src/mailer/delivery.js","../src/mailer/index.js","../src/mailer/backends/smtp.js","../src/packages/velocious-package.js","../src/plugins/sqljs-wasm-route-controller.js","../src/plugins/sqljs-wasm-route.js","../src/routes/app-routes.js","../src/routes/base-route.js","../src/routes/basic-route.js","../src/routes/get-route.js","../src/routes/index.js","../src/routes/namespace-route.js","../src/routes/plugin-routes.js","../src/routes/post-route.js","../src/routes/resolver.js","../src/routes/resource-route.js","../src/routes/root-route.js","../src/routes/built-in/api-manifest/controller.js","../src/routes/built-in/debug/controller.js","../src/routes/built-in/errors/controller.js","../src/routes/hooks/frontend-model-command-route-hook.js","../src/sync/conflict-strategy.js","../src/sync/device-identity.js","../src/sync/local-mutation-log.js","../src/sync/offline-grant.js","../src/sync/peer-mutation-bundle.js","../src/sync/query-scope.js","../src/sync/server-change-feed.js","../src/sync/server-sequence-allocator.js","../src/sync/stable-json.js","../src/sync/sync-api-client-types.js","../src/sync/sync-api-client.js","../src/sync/sync-api-controller.js","../src/sync/sync-change-fanout.js","../src/sync/sync-channel-name.js","../src/sync/sync-client-registry.js","../src/sync/sync-client-types.js","../src/sync/sync-client.js","../src/sync/sync-envelope-replay-service.js","../src/sync/sync-model-change-feed-service.js","../src/sync/sync-publish-suppression.js","../src/sync/sync-publisher-types.js","../src/sync/sync-publisher.js","../src/sync/sync-realtime-bridge.js","../src/sync/sync-replay-upsert-applier.js","../src/sync/sync-resource-base.js","../src/sync/sync-scope-attributes.js","../src/sync/sync-scope-store.js","../src/sync/sync-websocket-channel.js","../src/tenants/default-tenant-database-provisioning.js","../src/tenants/tenant-aggregator.js","../src/tenants/tenant-iterator.js","../src/tenants/tenant.js","../src/testing/base-expect.js","../src/testing/browser-frontend-model-event-hook-scenarios.js","../src/testing/browser-test-app.js","../src/testing/expect-to-change.js","../src/testing/expect-utils.js","../src/testing/expect.js","../src/testing/request-client.js","../src/testing/test-files-finder.js","../src/testing/test-filter-parser.js","../src/testing/test-runner.js","../src/testing/test-suite-splitter.js","../src/testing/test.js","../src/testing/wait-for-event.js","../src/testing/factory/association-declaration.js","../src/testing/factory/declarations.js","../src/testing/factory/definition-builder.js","../src/testing/factory/errors.js","../src/testing/factory/evaluation-context.js","../src/testing/factory/events.js","../src/testing/factory/factory-definition.js","../src/testing/factory/factory-registry.js","../src/testing/factory/factory-runner.js","../src/testing/factory/index.js","../src/testing/factory/linter.js","../src/testing/factory/model-contract.js","../src/testing/factory/sequence.js","../src/testing/factory/trait-definition.js","../src/testing/factory/node/load-definitions.js","../src/testing/factory/strategies/attributes-for.js","../src/testing/factory/strategies/base.js","../src/testing/factory/strategies/build.js","../src/testing/factory/strategies/create.js","../src/types/external-modules.d.ts","../src/utils/backtrace-cleaner-node.js","../src/utils/backtrace-cleaner.js","../src/utils/deburr-column-name.js","../src/utils/event-emitter.js","../src/utils/file-exists.js","../src/utils/format-value.js","../src/utils/is-date.js","../src/utils/model-scope.js","../src/utils/nest-callbacks.js","../src/utils/plain-object.js","../src/utils/ransack.js","../src/utils/rest-args-error.js","../src/utils/shutdown-lifecycle.js","../src/utils/singularize-model-name.js","../src/utils/split-sql-statements.js","../src/utils/to-import-specifier.js","../src/utils/with-tracked-stack-async-hooks.js","../src/utils/with-tracked-stack.js"],"version":"6.0.3"}
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"velocious": "build/bin/velocious.js"
|
|
4
4
|
},
|
|
5
5
|
"name": "velocious",
|
|
6
|
-
"version": "1.0.
|
|
6
|
+
"version": "1.0.563",
|
|
7
7
|
"main": "build/index.js",
|
|
8
8
|
"types": "build/index.d.ts",
|
|
9
9
|
"files": [
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
"benchmark:preloader-id-dedup": "node benchmark/preloader-id-dedup.js",
|
|
21
21
|
"benchmark:mysql-result-row-materialization": "node benchmark/mysql-result-row-materialization.js",
|
|
22
22
|
"benchmark:query-roundtrip-batching": "node benchmark/query-roundtrip-batching.js",
|
|
23
|
+
"benchmark:websocket-outbound-queue": "node benchmark/websocket-outbound-queue.js",
|
|
23
24
|
"benchmark:websocket-frame-buffering": "node benchmark/websocket-frame-buffering.js",
|
|
24
25
|
"build": "node scripts/clean-build.js && npm run compile",
|
|
25
26
|
"compile": "tsc -b && npm run copy:js && npm run copy:ejs && npm run copy:templates && node scripts/ensure-bin-executable.js",
|
|
@@ -255,6 +255,7 @@
|
|
|
255
255
|
* @property {boolean} [inProcess] - Run HTTP handlers in the main thread instead of worker threads.
|
|
256
256
|
* @property {number} [maxWorkers] - Backward-compatible alias for workers.
|
|
257
257
|
* @property {number} [port] - Port to bind the HTTP server to.
|
|
258
|
+
* @property {{maxPendingBytes?: number, maxPendingFrames?: number}} [websocketOutboundQueue] - Per-client retained outbound WebSocket frame limits.
|
|
258
259
|
* @property {number} [workers] - Worker handlers to start for the HTTP server.
|
|
259
260
|
*/
|
|
260
261
|
|
package/src/configuration.js
CHANGED
|
@@ -114,6 +114,25 @@ function resolveBeaconUnreachableReportMs(value) {
|
|
|
114
114
|
return 30_000
|
|
115
115
|
}
|
|
116
116
|
|
|
117
|
+
const DEFAULT_WEBSOCKET_OUTBOUND_MAX_PENDING_BYTES = 16 * 1024 * 1024
|
|
118
|
+
const DEFAULT_WEBSOCKET_OUTBOUND_MAX_PENDING_FRAMES = 256
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Validates a positive safe integer configuration value.
|
|
122
|
+
* @param {?} value - Configured positive safe integer.
|
|
123
|
+
* @param {string} name - Configuration key.
|
|
124
|
+
* @param {number} defaultValue - Default value.
|
|
125
|
+
* @returns {number} - Validated configured or default value.
|
|
126
|
+
*/
|
|
127
|
+
function positiveSafeInteger(value, name, defaultValue) {
|
|
128
|
+
if (value === undefined) return defaultValue
|
|
129
|
+
if (typeof value !== "number" || !Number.isSafeInteger(value) || value <= 0) {
|
|
130
|
+
throw new TypeError(`${name} must be a positive safe integer`)
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
return value
|
|
134
|
+
}
|
|
135
|
+
|
|
117
136
|
export default class VelociousConfiguration {
|
|
118
137
|
/**
|
|
119
138
|
* Close database connections promise.
|
|
@@ -209,7 +228,15 @@ export default class VelociousConfiguration {
|
|
|
209
228
|
* @type {Promise<void> | undefined}
|
|
210
229
|
*/
|
|
211
230
|
this._initializePromise = undefined
|
|
212
|
-
|
|
231
|
+
const websocketOutboundQueue = httpServer?.websocketOutboundQueue
|
|
232
|
+
|
|
233
|
+
this.httpServer = {
|
|
234
|
+
...(httpServer || {}),
|
|
235
|
+
websocketOutboundQueue: {
|
|
236
|
+
maxPendingBytes: positiveSafeInteger(websocketOutboundQueue?.maxPendingBytes, "httpServer.websocketOutboundQueue.maxPendingBytes", DEFAULT_WEBSOCKET_OUTBOUND_MAX_PENDING_BYTES),
|
|
237
|
+
maxPendingFrames: positiveSafeInteger(websocketOutboundQueue?.maxPendingFrames, "httpServer.websocketOutboundQueue.maxPendingFrames", DEFAULT_WEBSOCKET_OUTBOUND_MAX_PENDING_FRAMES)
|
|
238
|
+
}
|
|
239
|
+
}
|
|
213
240
|
/**
|
|
214
241
|
* Stores the http server instance value.
|
|
215
242
|
* @type {{getDebugSnapshot: () => Promise<Record<string, ?>>} | undefined} */
|
|
@@ -1693,7 +1720,8 @@ export default class VelociousConfiguration {
|
|
|
1693
1720
|
websocketEvents.broadcastV2({
|
|
1694
1721
|
channel: message.channel,
|
|
1695
1722
|
broadcastParams: message.broadcastParams,
|
|
1696
|
-
body: message.body
|
|
1723
|
+
body: message.body,
|
|
1724
|
+
configuration: this
|
|
1697
1725
|
})
|
|
1698
1726
|
return
|
|
1699
1727
|
}
|
|
@@ -2342,6 +2370,19 @@ export default class VelociousConfiguration {
|
|
|
2342
2370
|
*/
|
|
2343
2371
|
getWebsocketSessionHeartbeatSeconds() { return this._websocketSessionHeartbeatSeconds }
|
|
2344
2372
|
|
|
2373
|
+
/**
|
|
2374
|
+
* Gets per-client WebSocket outbound queue limits.
|
|
2375
|
+
* @returns {{maxBytes: number, maxFrames: number}} - Per-client outbound queue high-water marks.
|
|
2376
|
+
*/
|
|
2377
|
+
getWebsocketOutboundQueueLimits() {
|
|
2378
|
+
const queue = this.httpServer.websocketOutboundQueue
|
|
2379
|
+
|
|
2380
|
+
return {
|
|
2381
|
+
maxBytes: queue.maxPendingBytes,
|
|
2382
|
+
maxFrames: queue.maxPendingFrames
|
|
2383
|
+
}
|
|
2384
|
+
}
|
|
2385
|
+
|
|
2345
2386
|
/**
|
|
2346
2387
|
* Registers a wrapper invoked around every WS-borne request /
|
|
2347
2388
|
* connection message / channel dispatch. The wrapper receives the
|
|
@@ -2537,7 +2578,7 @@ export default class VelociousConfiguration {
|
|
|
2537
2578
|
const websocketEvents = this._websocketEvents
|
|
2538
2579
|
|
|
2539
2580
|
if (websocketEvents && typeof websocketEvents.broadcastV2 === "function") {
|
|
2540
|
-
websocketEvents.broadcastV2({channel: name, broadcastParams, body})
|
|
2581
|
+
websocketEvents.broadcastV2({channel: name, broadcastParams, body, configuration: this})
|
|
2541
2582
|
return
|
|
2542
2583
|
}
|
|
2543
2584
|
|
|
@@ -423,7 +423,7 @@ export default class VelociousHttpServerClientWebsocketSession {
|
|
|
423
423
|
sendGoodbye(client) {
|
|
424
424
|
const frame = Buffer.from([WEBSOCKET_FINAL_FRAME | WEBSOCKET_OPCODE_CLOSE, 0x00])
|
|
425
425
|
|
|
426
|
-
client.events.emit("output", frame)
|
|
426
|
+
client.events.emit("output", frame, {websocketFrame: true})
|
|
427
427
|
}
|
|
428
428
|
|
|
429
429
|
/**
|
|
@@ -967,7 +967,7 @@ export default class VelociousHttpServerClientWebsocketSession {
|
|
|
967
967
|
header[0] = WEBSOCKET_FINAL_FRAME | opcode
|
|
968
968
|
header[1] = payload.length
|
|
969
969
|
|
|
970
|
-
this.client.events.emit("output", Buffer.concat([header, payload]))
|
|
970
|
+
this.client.events.emit("output", Buffer.concat([header, payload]), {websocketFrame: true})
|
|
971
971
|
}
|
|
972
972
|
|
|
973
973
|
/**
|
|
@@ -1012,7 +1012,7 @@ export default class VelociousHttpServerClientWebsocketSession {
|
|
|
1012
1012
|
|
|
1013
1013
|
header[0] = WEBSOCKET_FINAL_FRAME | WEBSOCKET_OPCODE_TEXT
|
|
1014
1014
|
|
|
1015
|
-
this.client.events.emit("output", Buffer.concat([header, payload]))
|
|
1015
|
+
this.client.events.emit("output", Buffer.concat([header, payload]), {websocketFrame: true})
|
|
1016
1016
|
}
|
|
1017
1017
|
|
|
1018
1018
|
/**
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
export class ClientDeliveryQueueOverflowError extends Error {
|
|
4
|
+
/**
|
|
5
|
+
* Builds an outbound queue overflow error.
|
|
6
|
+
* @param {object} args - Overflow details.
|
|
7
|
+
* @param {number} args.clientCount - Client identifier.
|
|
8
|
+
* @param {number} args.maxBytes - Configured byte high-water mark.
|
|
9
|
+
* @param {number} args.maxFrames - Configured frame high-water mark.
|
|
10
|
+
* @param {number} args.pendingBytes - Bytes retained before rejecting the frame.
|
|
11
|
+
* @param {number} args.pendingFrames - Frames retained before rejecting the frame.
|
|
12
|
+
* @param {number} args.rejectedBytes - Rejected frame size.
|
|
13
|
+
*/
|
|
14
|
+
constructor({clientCount, maxBytes, maxFrames, pendingBytes, pendingFrames, rejectedBytes}) {
|
|
15
|
+
super(`WebSocket client ${clientCount} exceeded its outbound queue limit (${pendingFrames}/${maxFrames} frames, ${pendingBytes}/${maxBytes} bytes; rejected ${rejectedBytes} bytes)`)
|
|
16
|
+
this.name = "ClientDeliveryQueueOverflowError"
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @typedef {object} DeliveryTask
|
|
22
|
+
* @property {number} byteLength - Retained complete-buffer bytes.
|
|
23
|
+
* @property {boolean} countedFrame - Whether this task is an outbound frame.
|
|
24
|
+
* @property {() => Promise<void>} delivery - Delivery operation.
|
|
25
|
+
* @property {(error?: Error) => void} settle - Settles the enqueue promise.
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
export default class ClientDeliveryQueue {
|
|
29
|
+
/**
|
|
30
|
+
* Builds a per-client delivery queue.
|
|
31
|
+
* @param {object} args - Queue options.
|
|
32
|
+
* @param {number} args.clientCount - Client identifier.
|
|
33
|
+
* @param {number} args.maxBytes - Byte high-water mark.
|
|
34
|
+
* @param {number} args.maxFrames - Frame high-water mark.
|
|
35
|
+
* @param {(error: ClientDeliveryQueueOverflowError) => void} args.onOverflow - Overflow handler.
|
|
36
|
+
*/
|
|
37
|
+
constructor({clientCount, maxBytes, maxFrames, onOverflow}) {
|
|
38
|
+
this.clientCount = clientCount
|
|
39
|
+
this.maxBytes = maxBytes
|
|
40
|
+
this.maxFrames = maxFrames
|
|
41
|
+
this.onOverflow = onOverflow
|
|
42
|
+
/** @type {DeliveryTask[]} */
|
|
43
|
+
this.tasks = []
|
|
44
|
+
/** @type {DeliveryTask | undefined} */
|
|
45
|
+
this.activeTask = undefined
|
|
46
|
+
this.pendingBytes = 0
|
|
47
|
+
this.pendingFrames = 0
|
|
48
|
+
this.destroyed = false
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Enqueues one complete output buffer.
|
|
53
|
+
* @param {object} args - Delivery details.
|
|
54
|
+
* @param {number} args.byteLength - Exact buffer byte length.
|
|
55
|
+
* @param {() => Promise<void>} args.delivery - Delivery operation.
|
|
56
|
+
* @returns {Promise<void>} - Settles after delivery or teardown.
|
|
57
|
+
*/
|
|
58
|
+
enqueueFrame({byteLength, delivery}) {
|
|
59
|
+
if (this.destroyed) return Promise.resolve()
|
|
60
|
+
|
|
61
|
+
if (this.pendingFrames + 1 > this.maxFrames || this.pendingBytes + byteLength > this.maxBytes) {
|
|
62
|
+
const error = new ClientDeliveryQueueOverflowError({
|
|
63
|
+
clientCount: this.clientCount,
|
|
64
|
+
maxBytes: this.maxBytes,
|
|
65
|
+
maxFrames: this.maxFrames,
|
|
66
|
+
pendingBytes: this.pendingBytes,
|
|
67
|
+
pendingFrames: this.pendingFrames,
|
|
68
|
+
rejectedBytes: byteLength
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
this.onOverflow(error)
|
|
72
|
+
return Promise.reject(error)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
this.pendingFrames += 1
|
|
76
|
+
this.pendingBytes += byteLength
|
|
77
|
+
return this._enqueue({byteLength, countedFrame: true, delivery})
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Enqueues an ordering-only operation that retains no complete output frame.
|
|
82
|
+
* @param {() => Promise<void>} delivery - Delivery operation.
|
|
83
|
+
* @returns {Promise<void>} - Settles after delivery or teardown.
|
|
84
|
+
*/
|
|
85
|
+
enqueueControl(delivery) {
|
|
86
|
+
if (this.destroyed) return Promise.resolve()
|
|
87
|
+
|
|
88
|
+
return this._enqueue({byteLength: 0, countedFrame: false, delivery})
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Releases queued and active accounting during explicit client teardown.
|
|
93
|
+
* @returns {void}
|
|
94
|
+
*/
|
|
95
|
+
destroy() {
|
|
96
|
+
if (this.destroyed) return
|
|
97
|
+
|
|
98
|
+
this.destroyed = true
|
|
99
|
+
const tasks = this.activeTask ? [this.activeTask, ...this.tasks] : this.tasks
|
|
100
|
+
|
|
101
|
+
this.activeTask = undefined
|
|
102
|
+
this.tasks = []
|
|
103
|
+
this.pendingBytes = 0
|
|
104
|
+
this.pendingFrames = 0
|
|
105
|
+
|
|
106
|
+
for (const task of tasks) task.settle()
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Gets current retained-buffer accounting.
|
|
111
|
+
* @returns {{pendingBytes: number, pendingFrames: number}} - Current retained-buffer accounting.
|
|
112
|
+
*/
|
|
113
|
+
snapshot() {
|
|
114
|
+
return {pendingBytes: this.pendingBytes, pendingFrames: this.pendingFrames}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Enqueues a delivery task.
|
|
119
|
+
* @param {Omit<DeliveryTask, "settle">} task - Task to enqueue.
|
|
120
|
+
* @returns {Promise<void>} - Task completion.
|
|
121
|
+
*/
|
|
122
|
+
_enqueue(task) {
|
|
123
|
+
const promise = new Promise((resolve, reject) => {
|
|
124
|
+
this.tasks.push({
|
|
125
|
+
...task,
|
|
126
|
+
settle: (error) => error ? reject(error) : resolve(undefined)
|
|
127
|
+
})
|
|
128
|
+
})
|
|
129
|
+
|
|
130
|
+
this._drain()
|
|
131
|
+
return promise
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Starts the next task when idle.
|
|
136
|
+
* @returns {void} - No return value.
|
|
137
|
+
*/
|
|
138
|
+
_drain() {
|
|
139
|
+
if (this.destroyed || this.activeTask) return
|
|
140
|
+
|
|
141
|
+
const task = this.tasks.shift()
|
|
142
|
+
if (!task) return
|
|
143
|
+
|
|
144
|
+
this.activeTask = task
|
|
145
|
+
void task.delivery().then(
|
|
146
|
+
() => this._finish(task),
|
|
147
|
+
(error) => this._finish(task, error)
|
|
148
|
+
)
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Finishes the active delivery task.
|
|
153
|
+
* @param {DeliveryTask} task - Completed task.
|
|
154
|
+
* @param {Error} [error] - Delivery error.
|
|
155
|
+
* @returns {void}
|
|
156
|
+
*/
|
|
157
|
+
_finish(task, error) {
|
|
158
|
+
if (this.destroyed || this.activeTask !== task) return
|
|
159
|
+
|
|
160
|
+
this.activeTask = undefined
|
|
161
|
+
if (task.countedFrame) {
|
|
162
|
+
this.pendingBytes -= task.byteLength
|
|
163
|
+
this.pendingFrames -= 1
|
|
164
|
+
}
|
|
165
|
+
task.settle(error)
|
|
166
|
+
this._drain()
|
|
167
|
+
}
|
|
168
|
+
}
|
|
@@ -76,6 +76,15 @@ export default class ServerClient {
|
|
|
76
76
|
})
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
+
/**
|
|
80
|
+
* Immediately destroys the socket and all transport-owned write buffers.
|
|
81
|
+
* @param {Error} error - Destruction reason.
|
|
82
|
+
* @returns {void}
|
|
83
|
+
*/
|
|
84
|
+
destroy(error) {
|
|
85
|
+
if (!this.socket.destroyed) this.socket.destroy(error)
|
|
86
|
+
}
|
|
87
|
+
|
|
79
88
|
/**
|
|
80
89
|
* On socket data.
|
|
81
90
|
* @param {Buffer} chunk - Chunk.
|
|
@@ -8,6 +8,10 @@ export class VelociousHttpServerWebsocketEventsHost {
|
|
|
8
8
|
* Narrows the runtime value to the documented type.
|
|
9
9
|
* @type {Set<import("./worker-handler/index.js").default>} */
|
|
10
10
|
this.handlers = new Set()
|
|
11
|
+
/**
|
|
12
|
+
* Broadcast handlers grouped by the configuration that owns them.
|
|
13
|
+
* @type {Map<import("../configuration.js").default, Set<import("./worker-handler/index.js").default>>} */
|
|
14
|
+
this.broadcastHandlersByConfiguration = new Map()
|
|
11
15
|
this.publishQueue = Promise.resolve()
|
|
12
16
|
}
|
|
13
17
|
|
|
@@ -30,8 +34,23 @@ export class VelociousHttpServerWebsocketEventsHost {
|
|
|
30
34
|
*/
|
|
31
35
|
register(handler) {
|
|
32
36
|
this.handlers.add(handler)
|
|
37
|
+
let configurationHandlers = this.broadcastHandlersByConfiguration.get(handler.configuration)
|
|
38
|
+
|
|
39
|
+
if (!configurationHandlers) {
|
|
40
|
+
configurationHandlers = new Set()
|
|
41
|
+
this.broadcastHandlersByConfiguration.set(handler.configuration, configurationHandlers)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
configurationHandlers.add(handler)
|
|
45
|
+
|
|
46
|
+
return () => {
|
|
47
|
+
this.handlers.delete(handler)
|
|
48
|
+
configurationHandlers.delete(handler)
|
|
33
49
|
|
|
34
|
-
|
|
50
|
+
if (configurationHandlers.size === 0) {
|
|
51
|
+
this.broadcastHandlersByConfiguration.delete(handler.configuration)
|
|
52
|
+
}
|
|
53
|
+
}
|
|
35
54
|
}
|
|
36
55
|
|
|
37
56
|
/**
|
|
@@ -69,17 +88,24 @@ export class VelociousHttpServerWebsocketEventsHost {
|
|
|
69
88
|
* @param {string} args.channel - Channel name.
|
|
70
89
|
* @param {Record<string, ?>} args.broadcastParams - Routing filter params.
|
|
71
90
|
* @param {?} args.body - Message body.
|
|
91
|
+
* @param {import("../configuration.js").default} args.configuration - Originating configuration.
|
|
72
92
|
* @returns {void}
|
|
73
93
|
*/
|
|
74
|
-
broadcastV2({body, broadcastParams, channel}) {
|
|
94
|
+
broadcastV2({body, broadcastParams, channel, configuration}) {
|
|
75
95
|
// Chain onto publishQueue so persistence completes before
|
|
76
96
|
// the next broadcast — without this, a subscriber that connects
|
|
77
97
|
// immediately after a broadcast could miss the just-persisted
|
|
78
98
|
// event when replaying from lastEventId on a slow DB.
|
|
79
99
|
this._queuePublish(async () => {
|
|
80
|
-
const persistedEvent = await this._persistV2EventIfNeeded({body, channel})
|
|
100
|
+
const persistedEvent = await this._persistV2EventIfNeeded({body, channel, configuration})
|
|
101
|
+
const dispatchedTargets = new Set()
|
|
81
102
|
|
|
82
|
-
for (const handler of this.
|
|
103
|
+
for (const handler of this.broadcastHandlersByConfiguration.get(configuration) || []) {
|
|
104
|
+
const dispatchKey = handler.websocketV2BroadcastDispatchKey()
|
|
105
|
+
|
|
106
|
+
if (dispatchedTargets.has(dispatchKey)) continue
|
|
107
|
+
|
|
108
|
+
dispatchedTargets.add(dispatchKey)
|
|
83
109
|
handler.dispatchWebsocketV2Broadcast({
|
|
84
110
|
body,
|
|
85
111
|
broadcastParams,
|
|
@@ -88,18 +114,19 @@ export class VelociousHttpServerWebsocketEventsHost {
|
|
|
88
114
|
createdAt: persistedEvent?.createdAt
|
|
89
115
|
})
|
|
90
116
|
}
|
|
91
|
-
}, "Failed to persist/broadcast V2 event")
|
|
117
|
+
}, "Failed to persist/broadcast V2 event", configuration)
|
|
92
118
|
}
|
|
93
119
|
|
|
94
120
|
/**
|
|
95
121
|
* Runs queue publish.
|
|
96
122
|
* @param {() => Promise<void>} callback - Publish work to run in order.
|
|
97
123
|
* @param {string} errorMessage - Message logged when publish work fails.
|
|
124
|
+
* @param {import("../configuration.js").default} [originatingConfiguration] - Configuration whose context owns the work.
|
|
98
125
|
* @returns {void}
|
|
99
126
|
*/
|
|
100
|
-
_queuePublish(callback, errorMessage) {
|
|
127
|
+
_queuePublish(callback, errorMessage, originatingConfiguration) {
|
|
101
128
|
const handler = this.handlers.values().next().value
|
|
102
|
-
const configuration = handler?.configuration
|
|
129
|
+
const configuration = originatingConfiguration || handler?.configuration
|
|
103
130
|
|
|
104
131
|
this.publishQueue = this.publishQueue
|
|
105
132
|
.then(async () => {
|
|
@@ -120,10 +147,11 @@ export class VelociousHttpServerWebsocketEventsHost {
|
|
|
120
147
|
* @param {object} args - Options.
|
|
121
148
|
* @param {?} args.body - Event body.
|
|
122
149
|
* @param {string} args.channel - Channel name.
|
|
150
|
+
* @param {import("../configuration.js").default} args.configuration - Originating configuration.
|
|
123
151
|
* @returns {Promise<{createdAt: string, id: string} | null>} - Persisted event metadata when storage is enabled.
|
|
124
152
|
*/
|
|
125
|
-
async _persistV2EventIfNeeded({body, channel}) {
|
|
126
|
-
return await this._persistChannelEventIfNeeded({channel, payload: body})
|
|
153
|
+
async _persistV2EventIfNeeded({body, channel, configuration}) {
|
|
154
|
+
return await this._persistChannelEventIfNeeded({channel, payload: body, configuration})
|
|
127
155
|
}
|
|
128
156
|
|
|
129
157
|
/**
|
|
@@ -142,14 +170,16 @@ export class VelociousHttpServerWebsocketEventsHost {
|
|
|
142
170
|
* @param {object} args - Options object.
|
|
143
171
|
* @param {string} args.channel - Channel name.
|
|
144
172
|
* @param {?} args.payload - Payload data.
|
|
173
|
+
* @param {import("../configuration.js").default} [args.configuration] - Configuration owning the event store.
|
|
145
174
|
* @returns {Promise<{createdAt: string, id: string} | null>} - Persisted event metadata.
|
|
146
175
|
*/
|
|
147
|
-
async _persistChannelEventIfNeeded({channel, payload}) {
|
|
176
|
+
async _persistChannelEventIfNeeded({channel, payload, configuration}) {
|
|
148
177
|
const handler = this.handlers.values().next().value
|
|
178
|
+
const eventConfiguration = configuration || handler?.configuration
|
|
149
179
|
|
|
150
|
-
if (!
|
|
180
|
+
if (!eventConfiguration) return null
|
|
151
181
|
|
|
152
|
-
const websocketEventLogStore = websocketEventLogStoreForConfiguration(
|
|
182
|
+
const websocketEventLogStore = websocketEventLogStoreForConfiguration(eventConfiguration)
|
|
153
183
|
const shouldPersist = await websocketEventLogStore.shouldPersistChannel(channel)
|
|
154
184
|
|
|
155
185
|
if (!shouldPersist) return null
|