@velajs/vela 1.18.0 → 1.19.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +78 -14
- package/dist/configurable-module.builder-5FGMaXG6.js +91 -0
- package/dist/configurable-module.builder-5FGMaXG6.js.map +1 -0
- package/dist/container-BqUHID4l.js +645 -0
- package/dist/container-BqUHID4l.js.map +1 -0
- package/dist/cron-matcher-C9qv5OUA.js +113 -0
- package/dist/cron-matcher-C9qv5OUA.js.map +1 -0
- package/dist/decorate-GcSMAbKn.js +528 -0
- package/dist/decorate-GcSMAbKn.js.map +1 -0
- package/dist/decorators-C8YBFCIk.js +53 -0
- package/dist/decorators-C8YBFCIk.js.map +1 -0
- package/dist/define-module-NOyOZNXD.js +235 -0
- package/dist/define-module-NOyOZNXD.js.map +1 -0
- package/dist/discovery.service-BYm95SSD.js +368 -0
- package/dist/discovery.service-BYm95SSD.js.map +1 -0
- package/dist/discovery.service-Cpf1QcZ5.d.ts +648 -0
- package/dist/i18n/index.d.ts +138 -10
- package/dist/i18n/index.js +270 -8
- package/dist/i18n/index.js.map +1 -0
- package/dist/index-D72EQfcC.d.ts +430 -0
- package/dist/index-DhShDLCM.d.ts +2310 -0
- package/dist/index.d.ts +6 -66
- package/dist/index.js +14 -71
- package/dist/internal.d.ts +13 -17
- package/dist/internal.js +6 -19
- package/dist/live/index.d.ts +2 -12
- package/dist/live/index.js +826 -16
- package/dist/live/index.js.map +1 -0
- package/dist/metadata.registry-D1od8ZBt.d.ts +842 -0
- package/dist/plugin-ByBlVOve.js +1387 -0
- package/dist/plugin-ByBlVOve.js.map +1 -0
- package/dist/queue/index.d.ts +247 -10
- package/dist/queue/index.js +384 -12
- package/dist/queue/index.js.map +1 -0
- package/dist/request-context-C3nCGJNd.js +26 -0
- package/dist/request-context-C3nCGJNd.js.map +1 -0
- package/dist/route.manager-DRAZ5X04.js +991 -0
- package/dist/route.manager-DRAZ5X04.js.map +1 -0
- package/dist/schedule-node/index.d.ts +32 -3
- package/dist/schedule-node/index.js +97 -3
- package/dist/schedule-node/index.js.map +1 -0
- package/dist/schedule.registry-DVm7Jp5w.d.ts +55 -0
- package/dist/seeder/index.d.ts +75 -5
- package/dist/seeder/index.js +105 -4
- package/dist/seeder/index.js.map +1 -0
- package/dist/signed-url-CMmi0SIb.js +56 -0
- package/dist/signed-url-CMmi0SIb.js.map +1 -0
- package/dist/signed-url-DKhgja4U.d.ts +16 -0
- package/dist/src-eb5CI6Xn.js +2151 -0
- package/dist/src-eb5CI6Xn.js.map +1 -0
- package/dist/storage/index.d.ts +57 -4
- package/dist/storage/index.js +22 -5
- package/dist/storage/index.js.map +1 -0
- package/dist/streaming/index.d.ts +2 -2
- package/dist/streaming/index.js +2 -1
- package/dist/websocket/index.d.ts +3 -12
- package/dist/websocket/index.js +2 -16
- package/dist/websocket-DXmB-MWJ.js +697 -0
- package/dist/websocket-DXmB-MWJ.js.map +1 -0
- package/dist/websocket-node/index.d.ts +108 -6
- package/dist/websocket-node/index.js +228 -6
- package/dist/websocket-node/index.js.map +1 -0
- package/package.json +67 -53
- package/dist/__tests__/workers/entry.d.ts +0 -9
- package/dist/__tests__/workers-als/entry-als.d.ts +0 -9
- package/dist/application.d.ts +0 -91
- package/dist/application.js +0 -308
- package/dist/cache/cache.decorators.d.ts +0 -2
- package/dist/cache/cache.decorators.js +0 -4
- package/dist/cache/cache.interceptor.d.ts +0 -9
- package/dist/cache/cache.interceptor.js +0 -60
- package/dist/cache/cache.module.d.ts +0 -7
- package/dist/cache/cache.module.js +0 -58
- package/dist/cache/cache.service.d.ts +0 -9
- package/dist/cache/cache.service.js +0 -42
- package/dist/cache/cache.store.d.ts +0 -12
- package/dist/cache/cache.store.js +0 -51
- package/dist/cache/cache.tokens.d.ts +0 -6
- package/dist/cache/cache.tokens.js +0 -5
- package/dist/cache/cache.types.d.ts +0 -41
- package/dist/cache/cache.types.js +0 -1
- package/dist/cache/index.d.ts +0 -8
- package/dist/cache/index.js +0 -7
- package/dist/cache/tiered-cache.store.d.ts +0 -19
- package/dist/cache/tiered-cache.store.js +0 -40
- package/dist/config/config.module.d.ts +0 -19
- package/dist/config/config.module.js +0 -98
- package/dist/config/config.service.d.ts +0 -20
- package/dist/config/config.service.js +0 -43
- package/dist/config/config.store.d.ts +0 -46
- package/dist/config/config.store.js +0 -119
- package/dist/config/config.tokens.d.ts +0 -13
- package/dist/config/config.tokens.js +0 -14
- package/dist/config/config.types.d.ts +0 -41
- package/dist/config/config.types.js +0 -4
- package/dist/config/index.d.ts +0 -7
- package/dist/config/index.js +0 -5
- package/dist/config/register-as.d.ts +0 -52
- package/dist/config/register-as.js +0 -39
- package/dist/constants.d.ts +0 -44
- package/dist/constants.js +0 -46
- package/dist/container/container.d.ts +0 -154
- package/dist/container/container.js +0 -849
- package/dist/container/decorators.d.ts +0 -17
- package/dist/container/decorators.js +0 -57
- package/dist/container/disposable.d.ts +0 -5
- package/dist/container/disposable.js +0 -33
- package/dist/container/index.d.ts +0 -6
- package/dist/container/index.js +0 -5
- package/dist/container/mixin.d.ts +0 -24
- package/dist/container/mixin.js +0 -26
- package/dist/container/module-ref.d.ts +0 -21
- package/dist/container/module-ref.js +0 -48
- package/dist/container/types.d.ts +0 -154
- package/dist/container/types.js +0 -49
- package/dist/cors/cors.module.d.ts +0 -7
- package/dist/cors/cors.module.js +0 -37
- package/dist/cors/cors.tokens.d.ts +0 -3
- package/dist/cors/cors.tokens.js +0 -2
- package/dist/cors/cors.types.d.ts +0 -8
- package/dist/cors/cors.types.js +0 -1
- package/dist/cors/index.d.ts +0 -3
- package/dist/cors/index.js +0 -2
- package/dist/crypto/signed-url.d.ts +0 -12
- package/dist/crypto/signed-url.js +0 -60
- package/dist/discovery/discoverable.decorator.d.ts +0 -38
- package/dist/discovery/discoverable.decorator.js +0 -42
- package/dist/discovery/discovery.service.d.ts +0 -102
- package/dist/discovery/discovery.service.js +0 -177
- package/dist/discovery/index.d.ts +0 -2
- package/dist/discovery/index.js +0 -2
- package/dist/entrypoint/entrypoint.registry.d.ts +0 -42
- package/dist/entrypoint/entrypoint.registry.js +0 -112
- package/dist/entrypoint/entrypoint.types.d.ts +0 -41
- package/dist/entrypoint/entrypoint.types.js +0 -3
- package/dist/entrypoint/execution-context.d.ts +0 -15
- package/dist/entrypoint/execution-context.js +0 -21
- package/dist/entrypoint/execution-scope.d.ts +0 -21
- package/dist/entrypoint/execution-scope.js +0 -28
- package/dist/entrypoint/index.d.ts +0 -4
- package/dist/entrypoint/index.js +0 -4
- package/dist/errors/http-exception.d.ts +0 -62
- package/dist/errors/http-exception.js +0 -134
- package/dist/errors/index.d.ts +0 -1
- package/dist/errors/index.js +0 -1
- package/dist/event-emitter/event-emitter.decorators.d.ts +0 -1
- package/dist/event-emitter/event-emitter.decorators.js +0 -10
- package/dist/event-emitter/event-emitter.module.d.ts +0 -2
- package/dist/event-emitter/event-emitter.module.js +0 -23
- package/dist/event-emitter/event-emitter.service.d.ts +0 -13
- package/dist/event-emitter/event-emitter.service.js +0 -127
- package/dist/event-emitter/event-emitter.subscriber.d.ts +0 -9
- package/dist/event-emitter/event-emitter.subscriber.js +0 -45
- package/dist/event-emitter/event-emitter.tokens.d.ts +0 -1
- package/dist/event-emitter/event-emitter.tokens.js +0 -1
- package/dist/event-emitter/event-emitter.types.d.ts +0 -5
- package/dist/event-emitter/event-emitter.types.js +0 -1
- package/dist/event-emitter/index.d.ts +0 -6
- package/dist/event-emitter/index.js +0 -5
- package/dist/factory/adapter.d.ts +0 -36
- package/dist/factory/adapter.js +0 -18
- package/dist/factory/bootstrap.d.ts +0 -23
- package/dist/factory/bootstrap.js +0 -108
- package/dist/factory.d.ts +0 -16
- package/dist/factory.js +0 -36
- package/dist/fetch/fetch.module.d.ts +0 -7
- package/dist/fetch/fetch.module.js +0 -31
- package/dist/fetch/fetch.service.d.ts +0 -24
- package/dist/fetch/fetch.service.js +0 -145
- package/dist/fetch/fetch.types.d.ts +0 -24
- package/dist/fetch/fetch.types.js +0 -1
- package/dist/fetch/index.d.ts +0 -3
- package/dist/fetch/index.js +0 -2
- package/dist/health/health.http.d.ts +0 -14
- package/dist/health/health.http.js +0 -75
- package/dist/health/health.indicator.d.ts +0 -9
- package/dist/health/health.indicator.js +0 -32
- package/dist/health/health.module.d.ts +0 -2
- package/dist/health/health.module.js +0 -26
- package/dist/health/health.service.d.ts +0 -7
- package/dist/health/health.service.js +0 -69
- package/dist/health/health.types.d.ts +0 -15
- package/dist/health/health.types.js +0 -1
- package/dist/health/index.d.ts +0 -6
- package/dist/health/index.js +0 -4
- package/dist/http/ambient.d.ts +0 -17
- package/dist/http/ambient.js +0 -44
- package/dist/http/argument-resolver.d.ts +0 -10
- package/dist/http/argument-resolver.js +0 -89
- package/dist/http/decorators.d.ts +0 -198
- package/dist/http/decorators.js +0 -321
- package/dist/http/execution-context.d.ts +0 -8
- package/dist/http/execution-context.js +0 -35
- package/dist/http/handler-executor.d.ts +0 -20
- package/dist/http/handler-executor.js +0 -111
- package/dist/http/index.d.ts +0 -12
- package/dist/http/index.js +0 -7
- package/dist/http/instantiate.d.ts +0 -4
- package/dist/http/instantiate.js +0 -45
- package/dist/http/lazy-param.decorator.d.ts +0 -37
- package/dist/http/lazy-param.decorator.js +0 -117
- package/dist/http/request-container.d.ts +0 -16
- package/dist/http/request-container.js +0 -19
- package/dist/http/request-context.d.ts +0 -13
- package/dist/http/request-context.js +0 -22
- package/dist/http/response-mapper.d.ts +0 -8
- package/dist/http/response-mapper.js +0 -42
- package/dist/http/route-contributor.d.ts +0 -68
- package/dist/http/route-contributor.js +0 -22
- package/dist/http/route-map.d.ts +0 -30
- package/dist/http/route-map.js +0 -27
- package/dist/http/route.manager.d.ts +0 -92
- package/dist/http/route.manager.js +0 -481
- package/dist/http/types.d.ts +0 -37
- package/dist/http/types.js +0 -1
- package/dist/http/url/index.d.ts +0 -4
- package/dist/http/url/index.js +0 -3
- package/dist/http/url/signed-url.guard.d.ts +0 -27
- package/dist/http/url/signed-url.guard.js +0 -62
- package/dist/http/url/signing-secret.d.ts +0 -20
- package/dist/http/url/signing-secret.js +0 -24
- package/dist/http/url/url-generator.service.d.ts +0 -52
- package/dist/http/url/url-generator.service.js +0 -104
- package/dist/i18n/deep-merge.d.ts +0 -2
- package/dist/i18n/deep-merge.js +0 -15
- package/dist/i18n/i18n.middleware.d.ts +0 -15
- package/dist/i18n/i18n.middleware.js +0 -94
- package/dist/i18n/i18n.module.d.ts +0 -13
- package/dist/i18n/i18n.module.js +0 -69
- package/dist/i18n/i18n.options.d.ts +0 -30
- package/dist/i18n/i18n.options.js +0 -16
- package/dist/i18n/i18n.service.d.ts +0 -20
- package/dist/i18n/i18n.service.js +0 -49
- package/dist/i18n/i18n.tokens.d.ts +0 -6
- package/dist/i18n/i18n.tokens.js +0 -3
- package/dist/i18n/i18n.types.d.ts +0 -6
- package/dist/i18n/i18n.types.js +0 -1
- package/dist/i18n/message-loader.service.d.ts +0 -21
- package/dist/i18n/message-loader.service.js +0 -90
- package/dist/i18n/message-registry.d.ts +0 -16
- package/dist/i18n/message-registry.js +0 -49
- package/dist/lifecycle/index.d.ts +0 -20
- package/dist/lifecycle/index.js +0 -15
- package/dist/live/live.cursor.d.ts +0 -22
- package/dist/live/live.cursor.js +0 -56
- package/dist/live/live.decorators.d.ts +0 -32
- package/dist/live/live.decorators.js +0 -46
- package/dist/live/live.delta.d.ts +0 -15
- package/dist/live/live.delta.js +0 -51
- package/dist/live/live.engine.d.ts +0 -81
- package/dist/live/live.engine.js +0 -448
- package/dist/live/live.invalidation.d.ts +0 -45
- package/dist/live/live.invalidation.js +0 -99
- package/dist/live/live.module.d.ts +0 -28
- package/dist/live/live.module.js +0 -87
- package/dist/live/live.tokens.d.ts +0 -9
- package/dist/live/live.tokens.js +0 -8
- package/dist/live/live.types.d.ts +0 -138
- package/dist/live/live.types.js +0 -1
- package/dist/live/presence.d.ts +0 -44
- package/dist/live/presence.js +0 -130
- package/dist/metadata.d.ts +0 -10
- package/dist/metadata.js +0 -20
- package/dist/module/configurable-module.builder.d.ts +0 -56
- package/dist/module/configurable-module.builder.js +0 -84
- package/dist/module/configurable-module.types.d.ts +0 -93
- package/dist/module/configurable-module.types.js +0 -5
- package/dist/module/decorators.d.ts +0 -10
- package/dist/module/decorators.js +0 -47
- package/dist/module/define-module.d.ts +0 -112
- package/dist/module/define-module.js +0 -232
- package/dist/module/graph.d.ts +0 -10
- package/dist/module/graph.js +0 -35
- package/dist/module/index.d.ts +0 -10
- package/dist/module/index.js +0 -7
- package/dist/module/lazy-modules.d.ts +0 -82
- package/dist/module/lazy-modules.js +0 -231
- package/dist/module/lazy-provider.d.ts +0 -65
- package/dist/module/lazy-provider.js +0 -111
- package/dist/module/middleware.d.ts +0 -30
- package/dist/module/middleware.js +0 -67
- package/dist/module/module-loader.d.ts +0 -58
- package/dist/module/module-loader.js +0 -484
- package/dist/module/stable-hash.d.ts +0 -15
- package/dist/module/stable-hash.js +0 -52
- package/dist/module/types.d.ts +0 -1
- package/dist/module/types.js +0 -1
- package/dist/openapi/decorators.d.ts +0 -34
- package/dist/openapi/decorators.js +0 -66
- package/dist/openapi/document.d.ts +0 -3
- package/dist/openapi/document.js +0 -316
- package/dist/openapi/index.d.ts +0 -7
- package/dist/openapi/index.js +0 -6
- package/dist/openapi/redoc-ui.d.ts +0 -1
- package/dist/openapi/redoc-ui.js +0 -19
- package/dist/openapi/scalar-ui.d.ts +0 -1
- package/dist/openapi/scalar-ui.js +0 -19
- package/dist/openapi/swagger-ui.d.ts +0 -1
- package/dist/openapi/swagger-ui.js +0 -23
- package/dist/openapi/types.d.ts +0 -182
- package/dist/openapi/types.js +0 -4
- package/dist/openapi/zod-to-json-schema.d.ts +0 -4
- package/dist/openapi/zod-to-json-schema.js +0 -57
- package/dist/pipeline/app-providers.d.ts +0 -10
- package/dist/pipeline/app-providers.js +0 -43
- package/dist/pipeline/component.manager.d.ts +0 -25
- package/dist/pipeline/component.manager.js +0 -66
- package/dist/pipeline/decorators.d.ts +0 -10
- package/dist/pipeline/decorators.js +0 -42
- package/dist/pipeline/index.d.ts +0 -12
- package/dist/pipeline/index.js +0 -7
- package/dist/pipeline/pipeline-runner.d.ts +0 -31
- package/dist/pipeline/pipeline-runner.js +0 -40
- package/dist/pipeline/pipes.d.ts +0 -48
- package/dist/pipeline/pipes.js +0 -104
- package/dist/pipeline/reflector.d.ts +0 -86
- package/dist/pipeline/reflector.js +0 -121
- package/dist/pipeline/scoped-components.d.ts +0 -26
- package/dist/pipeline/scoped-components.js +0 -27
- package/dist/pipeline/tokens.d.ts +0 -33
- package/dist/pipeline/tokens.js +0 -27
- package/dist/pipeline/types.d.ts +0 -64
- package/dist/pipeline/types.js +0 -1
- package/dist/plugin/plugin.d.ts +0 -31
- package/dist/plugin/plugin.js +0 -111
- package/dist/queue/inline.driver.d.ts +0 -30
- package/dist/queue/inline.driver.js +0 -58
- package/dist/queue/queue.binding.d.ts +0 -23
- package/dist/queue/queue.binding.js +0 -53
- package/dist/queue/queue.client.d.ts +0 -20
- package/dist/queue/queue.client.js +0 -33
- package/dist/queue/queue.decorators.d.ts +0 -23
- package/dist/queue/queue.decorators.js +0 -46
- package/dist/queue/queue.dispatch.d.ts +0 -36
- package/dist/queue/queue.dispatch.js +0 -102
- package/dist/queue/queue.module.d.ts +0 -32
- package/dist/queue/queue.module.js +0 -80
- package/dist/queue/queue.tokens.d.ts +0 -21
- package/dist/queue/queue.tokens.js +0 -34
- package/dist/queue/queue.types.d.ts +0 -61
- package/dist/queue/queue.types.js +0 -4
- package/dist/registry/index.d.ts +0 -2
- package/dist/registry/index.js +0 -1
- package/dist/registry/metadata.registry.d.ts +0 -73
- package/dist/registry/metadata.registry.js +0 -357
- package/dist/registry/paths.d.ts +0 -3
- package/dist/registry/paths.js +0 -15
- package/dist/registry/types.d.ts +0 -116
- package/dist/registry/types.js +0 -1
- package/dist/registry/util.d.ts +0 -3
- package/dist/registry/util.js +0 -8
- package/dist/schedule/cron-matcher.d.ts +0 -2
- package/dist/schedule/cron-matcher.js +0 -62
- package/dist/schedule/index.d.ts +0 -8
- package/dist/schedule/index.js +0 -5
- package/dist/schedule/schedule.decorators.d.ts +0 -2
- package/dist/schedule/schedule.decorators.js +0 -18
- package/dist/schedule/schedule.module.d.ts +0 -9
- package/dist/schedule/schedule.module.js +0 -28
- package/dist/schedule/schedule.registry.d.ts +0 -23
- package/dist/schedule/schedule.registry.js +0 -63
- package/dist/schedule/schedule.tokens.d.ts +0 -2
- package/dist/schedule/schedule.tokens.js +0 -2
- package/dist/schedule/schedule.types.d.ts +0 -8
- package/dist/schedule/schedule.types.js +0 -1
- package/dist/schedule-node/schedule-node.module.d.ts +0 -9
- package/dist/schedule-node/schedule-node.module.js +0 -28
- package/dist/schedule-node/schedule.executor.d.ts +0 -19
- package/dist/schedule-node/schedule.executor.js +0 -107
- package/dist/seeder/seeder.decorator.d.ts +0 -7
- package/dist/seeder/seeder.decorator.js +0 -15
- package/dist/seeder/seeder.module.d.ts +0 -16
- package/dist/seeder/seeder.module.js +0 -44
- package/dist/seeder/seeder.registry.d.ts +0 -23
- package/dist/seeder/seeder.registry.js +0 -83
- package/dist/seeder/seeder.tokens.d.ts +0 -2
- package/dist/seeder/seeder.tokens.js +0 -1
- package/dist/seeder/seeder.types.d.ts +0 -20
- package/dist/seeder/seeder.types.js +0 -1
- package/dist/serialization/index.d.ts +0 -2
- package/dist/serialization/index.js +0 -2
- package/dist/serialization/serialize.decorator.d.ts +0 -6
- package/dist/serialization/serialize.decorator.js +0 -7
- package/dist/serialization/serializer.interceptor.d.ts +0 -4
- package/dist/serialization/serializer.interceptor.js +0 -16
- package/dist/services/index.d.ts +0 -2
- package/dist/services/index.js +0 -1
- package/dist/services/logger.d.ts +0 -59
- package/dist/services/logger.js +0 -159
- package/dist/storage/path-template.d.ts +0 -9
- package/dist/storage/path-template.js +0 -20
- package/dist/storage/storage.types.d.ts +0 -41
- package/dist/storage/storage.types.js +0 -5
- package/dist/throttler/index.d.ts +0 -6
- package/dist/throttler/index.js +0 -5
- package/dist/throttler/throttler.decorators.d.ts +0 -3
- package/dist/throttler/throttler.decorators.js +0 -4
- package/dist/throttler/throttler.guard.d.ts +0 -9
- package/dist/throttler/throttler.guard.js +0 -72
- package/dist/throttler/throttler.module.d.ts +0 -7
- package/dist/throttler/throttler.module.js +0 -41
- package/dist/throttler/throttler.storage.d.ts +0 -10
- package/dist/throttler/throttler.storage.js +0 -44
- package/dist/throttler/throttler.tokens.d.ts +0 -6
- package/dist/throttler/throttler.tokens.js +0 -5
- package/dist/throttler/throttler.types.d.ts +0 -25
- package/dist/throttler/throttler.types.js +0 -1
- package/dist/validation/create-zod-dto.d.ts +0 -13
- package/dist/validation/create-zod-dto.js +0 -18
- package/dist/validation/index.d.ts +0 -3
- package/dist/validation/index.js +0 -2
- package/dist/validation/validation.pipe.d.ts +0 -4
- package/dist/validation/validation.pipe.js +0 -19
- package/dist/websocket/websocket.decorators.d.ts +0 -47
- package/dist/websocket/websocket.decorators.js +0 -80
- package/dist/websocket/websocket.module.d.ts +0 -35
- package/dist/websocket/websocket.module.js +0 -63
- package/dist/websocket/websocket.tokens.d.ts +0 -30
- package/dist/websocket/websocket.tokens.js +0 -27
- package/dist/websocket/websocket.types.d.ts +0 -102
- package/dist/websocket/websocket.types.js +0 -4
- package/dist/websocket/ws-argument-resolver.d.ts +0 -13
- package/dist/websocket/ws-argument-resolver.js +0 -40
- package/dist/websocket/ws-dispatcher.d.ts +0 -54
- package/dist/websocket/ws-dispatcher.js +0 -322
- package/dist/websocket/ws-exception.d.ts +0 -16
- package/dist/websocket/ws-exception.js +0 -32
- package/dist/websocket/ws-execution-context.d.ts +0 -9
- package/dist/websocket/ws-execution-context.js +0 -24
- package/dist/websocket/ws-server.d.ts +0 -31
- package/dist/websocket/ws-server.js +0 -74
- package/dist/websocket/ws-sync.d.ts +0 -47
- package/dist/websocket/ws-sync.js +0 -74
- package/dist/websocket-node/node-ws-client.d.ts +0 -24
- package/dist/websocket-node/node-ws-client.js +0 -49
- package/dist/websocket-node/redis-live.d.ts +0 -24
- package/dist/websocket-node/redis-live.js +0 -57
- package/dist/websocket-node/redis-sync.d.ts +0 -33
- package/dist/websocket-node/redis-sync.js +0 -56
- package/dist/websocket-node/register-gateways.d.ts +0 -20
- package/dist/websocket-node/register-gateways.js +0 -61
package/dist/live/index.js
CHANGED
|
@@ -1,16 +1,826 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
1
|
+
import { C as InjectionToken, a as Injectable, i as Inject, n as __decorateParam, o as Optional, r as __decorateMetadata, t as __decorate } from "../decorate-GcSMAbKn.js";
|
|
2
|
+
import { G as getMetadata, L as PipelineRunner, W as defineMetadata } from "../route.manager-DRAZ5X04.js";
|
|
3
|
+
import { n as resolveErrorReporter, t as DiscoveryService } from "../discovery.service-BYm95SSD.js";
|
|
4
|
+
import { t as Container } from "../container-BqUHID4l.js";
|
|
5
|
+
import { E as runInEntrypointScope, T as buildEntrypointExecutionContext, c as toErrorBody, s as isVelaError, w as resolveScopedComponents } from "../src-eb5CI6Xn.js";
|
|
6
|
+
import { n as defineModule } from "../define-module-NOyOZNXD.js";
|
|
7
|
+
import { E as createDiscoverableDecorator, p as ReservedWsEvent } from "../websocket-DXmB-MWJ.js";
|
|
8
|
+
import { getContext } from "hono/context-storage";
|
|
9
|
+
import { COMMIT_CURSOR_HEADER, COMMIT_CURSOR_HEADER as COMMIT_CURSOR_HEADER$1, COMMIT_EPOCH_HEADER, COMMIT_EPOCH_HEADER as COMMIT_EPOCH_HEADER$1, DEFAULT_KEY_FIELD, DEFAULT_KEY_FIELD as DEFAULT_KEY_FIELD$1, LIVE_ERROR_CODES, LIVE_ERROR_CODES as LIVE_ERROR_CODES$1, LIVE_EVENT, LIVE_PROTOCOL, LIVE_PROTOCOL as LIVE_PROTOCOL$1, applyListDelta, encodeListDelta, encodeListDelta as encodeListDelta$1, encodeLiveEnvelope, encodeLiveEnvelope as encodeLiveEnvelope$1, encodeLiveFrame, isClientLiveFrame, isClientLiveFrame as isClientLiveFrame$1, isServerLiveFrame, readLiveEnvelope } from "@velajs/live-protocol";
|
|
10
|
+
//#region src/live/live.cursor.ts
|
|
11
|
+
const intersects = (a, b) => a.some((tag) => b.has(tag));
|
|
12
|
+
/**
|
|
13
|
+
* The in-core `CursorLog`: a bounded in-memory ring, epoch minted per process
|
|
14
|
+
* (Web Crypto). A restart rolls the epoch, so every reconnecting client falls
|
|
15
|
+
* back to snapshot — exactly the documented node/dev semantics. Within one
|
|
16
|
+
* process lifetime resume works for gaps the ring still covers; a trimmed gap
|
|
17
|
+
* degrades to snapshot (mirrors lunora's CDC retention rule,
|
|
18
|
+
* `ctx-db-cdc.ts` — retention gap → snapshot).
|
|
19
|
+
*
|
|
20
|
+
* The Cloudflare transport replaces this with a Durable-Object SQLite log so
|
|
21
|
+
* resume survives hibernation and eviction.
|
|
22
|
+
*/
|
|
23
|
+
var InMemoryCursorLog = class {
|
|
24
|
+
maxEntries;
|
|
25
|
+
epoch = crypto.randomUUID();
|
|
26
|
+
entries = [];
|
|
27
|
+
seq = 0;
|
|
28
|
+
constructor(maxEntries = 1024) {
|
|
29
|
+
this.maxEntries = maxEntries;
|
|
30
|
+
}
|
|
31
|
+
append(tags) {
|
|
32
|
+
this.seq += 1;
|
|
33
|
+
this.entries.push({
|
|
34
|
+
seq: this.seq,
|
|
35
|
+
tags
|
|
36
|
+
});
|
|
37
|
+
if (this.entries.length > this.maxEntries) this.entries.splice(0, this.entries.length - this.maxEntries);
|
|
38
|
+
return {
|
|
39
|
+
cursor: this.seq,
|
|
40
|
+
epoch: this.epoch
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
current() {
|
|
44
|
+
return {
|
|
45
|
+
cursor: this.seq,
|
|
46
|
+
epoch: this.epoch
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
evaluateResume(sinceCursor, sinceEpoch, subscriptionTags) {
|
|
50
|
+
if (sinceEpoch !== this.epoch) return "snapshot";
|
|
51
|
+
if (sinceCursor > this.seq) return "snapshot";
|
|
52
|
+
if (sinceCursor === this.seq) return "resume";
|
|
53
|
+
const oldest = this.entries[0];
|
|
54
|
+
if (oldest === void 0 || oldest.seq > sinceCursor + 1) return "snapshot";
|
|
55
|
+
const subTags = new Set(subscriptionTags);
|
|
56
|
+
for (const entry of this.entries) {
|
|
57
|
+
if (entry.seq <= sinceCursor) continue;
|
|
58
|
+
if (intersects(entry.tags, subTags)) return "rerun";
|
|
59
|
+
}
|
|
60
|
+
return "resume";
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
//#endregion
|
|
64
|
+
//#region src/live/live.tokens.ts
|
|
65
|
+
const LIVE_RESOLVER_METADATA = "vela:live:resolver";
|
|
66
|
+
const LIVE_QUERY_METADATA = "vela:live:query";
|
|
67
|
+
/** The invalidation driver in effect for a `LiveModule` instance (`localLive()` by default). */
|
|
68
|
+
const LIVE_DRIVER = new InjectionToken("vela:live:driver");
|
|
69
|
+
/** The ordered tag-invalidation log backing cursors/epochs for this log scope. */
|
|
70
|
+
const LIVE_CURSOR_LOG = new InjectionToken("vela:live:cursor-log");
|
|
71
|
+
const LIVE_MODULE_OPTIONS = new InjectionToken("LIVE_MODULE_OPTIONS");
|
|
72
|
+
//#endregion
|
|
73
|
+
//#region src/live/live.decorators.ts
|
|
74
|
+
const LiveResolverMeta = createDiscoverableDecorator(LIVE_RESOLVER_METADATA);
|
|
75
|
+
/**
|
|
76
|
+
* Marks a provider class as a live-query resolver:
|
|
77
|
+
*
|
|
78
|
+
* ```ts
|
|
79
|
+
* @LiveResolver()
|
|
80
|
+
* @Injectable()
|
|
81
|
+
* class TodoLive {
|
|
82
|
+
* constructor(private readonly todos: TodoService) {}
|
|
83
|
+
*
|
|
84
|
+
* @LiveQuery('todos.list', { tags: (a: { listId: string }) => [`todos:${a.listId}`] })
|
|
85
|
+
* list(args: { listId: string }, ctx: LiveQueryContext) {
|
|
86
|
+
* return this.todos.byList(args.listId, ctx.identity?.userId);
|
|
87
|
+
* }
|
|
88
|
+
* }
|
|
89
|
+
* ```
|
|
90
|
+
*
|
|
91
|
+
* Clients subscribe by query name over the `$live` reserved event; the engine
|
|
92
|
+
* re-runs a handler whenever one of its tags is invalidated and pushes the
|
|
93
|
+
* result (as a keyed delta when possible). Stack with `@Injectable()`, exactly
|
|
94
|
+
* like `@Processor`.
|
|
95
|
+
*/
|
|
96
|
+
function LiveResolver() {
|
|
97
|
+
return LiveResolverMeta({});
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Declares a live query on a resolver method. The handler receives
|
|
101
|
+
* `(args, ctx: LiveQueryContext)` positionally — args are validated once at
|
|
102
|
+
* subscribe (via `options.parse`), then replayed verbatim into every re-run
|
|
103
|
+
* under the subscriber's captured identity.
|
|
104
|
+
*/
|
|
105
|
+
function LiveQuery(name, options) {
|
|
106
|
+
return (target, propertyKey) => {
|
|
107
|
+
const ctor = target.constructor;
|
|
108
|
+
const existing = getMetadata("vela:live:query", ctor) ?? [];
|
|
109
|
+
existing.push({
|
|
110
|
+
name,
|
|
111
|
+
methodName: propertyKey,
|
|
112
|
+
options
|
|
113
|
+
});
|
|
114
|
+
defineMetadata(LIVE_QUERY_METADATA, existing, ctor);
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
/** `@LiveQuery` entries declared on a resolver class (declaration order). */
|
|
118
|
+
function getLiveQueries(resolverClass) {
|
|
119
|
+
return getMetadata("vela:live:query", resolverClass) ?? [];
|
|
120
|
+
}
|
|
121
|
+
//#endregion
|
|
122
|
+
//#region src/live/live.delta.ts
|
|
123
|
+
/**
|
|
124
|
+
* Decide what one re-run puts on the wire — pure, so the contract is
|
|
125
|
+
* unit-testable without sockets:
|
|
126
|
+
*
|
|
127
|
+
* - byte-identical to the baseline → `settled` (cursor still advances; this
|
|
128
|
+
* is what drops client optimistic layers for writes that didn't change the
|
|
129
|
+
* result);
|
|
130
|
+
* - baseline exists and the shared codec can diff → `delta` (batched keyed
|
|
131
|
+
* row ops);
|
|
132
|
+
* - otherwise (first send after subscribe/resume, codec bailed, unparseable
|
|
133
|
+
* baseline) → full `data` snapshot.
|
|
134
|
+
*/
|
|
135
|
+
function encodeSubscriptionUpdate(record, json, result, stamp, initial) {
|
|
136
|
+
const settled = {
|
|
137
|
+
t: "settled",
|
|
138
|
+
sub: record.sub,
|
|
139
|
+
cursor: stamp.cursor,
|
|
140
|
+
epoch: stamp.epoch
|
|
141
|
+
};
|
|
142
|
+
if (!initial && record.lastJson !== void 0) {
|
|
143
|
+
if (record.lastJson === json) return settled;
|
|
144
|
+
let previous;
|
|
145
|
+
let parsed = false;
|
|
146
|
+
try {
|
|
147
|
+
previous = JSON.parse(record.lastJson);
|
|
148
|
+
parsed = true;
|
|
149
|
+
} catch {}
|
|
150
|
+
if (parsed) {
|
|
151
|
+
const ops = encodeListDelta$1(previous, result, record.key ?? DEFAULT_KEY_FIELD$1);
|
|
152
|
+
if (ops !== void 0 && ops.length > 0) return {
|
|
153
|
+
t: "delta",
|
|
154
|
+
sub: record.sub,
|
|
155
|
+
ops,
|
|
156
|
+
cursor: stamp.cursor,
|
|
157
|
+
epoch: stamp.epoch
|
|
158
|
+
};
|
|
159
|
+
if (ops !== void 0) return settled;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
return {
|
|
163
|
+
t: "data",
|
|
164
|
+
sub: record.sub,
|
|
165
|
+
snapshot: result,
|
|
166
|
+
cursor: stamp.cursor,
|
|
167
|
+
epoch: stamp.epoch
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
//#endregion
|
|
171
|
+
//#region src/live/presence.ts
|
|
172
|
+
/** The invalidation tag for one room's roster. `$`-prefixed: never collides with app tags. */
|
|
173
|
+
const presenceTag = (room) => `$presence:${room}`;
|
|
174
|
+
/** The built-in roster query name (`useLiveQuery`-able like any app query). */
|
|
175
|
+
const PRESENCE_ROSTER_QUERY = "$presence.roster";
|
|
176
|
+
/**
|
|
177
|
+
* The presence preset's server half. Heartbeats arrive as `{ t: 'presence' }`
|
|
178
|
+
* frames on the live socket (routed here by the engine); the roster is a
|
|
179
|
+
* built-in live query invalidated per room. Departure is immediate: the WS
|
|
180
|
+
* close hook reaps the member without waiting out the TTL. Staleness (an
|
|
181
|
+
* ungraceful drop the transport never noticed) is filtered AT READ TIME —
|
|
182
|
+
* no timers, per the edge rules (`setInterval` is forbidden).
|
|
183
|
+
*
|
|
184
|
+
* Scope note: the roster lives in this log scope (one process on node, one
|
|
185
|
+
* room-DO on Cloudflare — where it is exactly the room's roster).
|
|
186
|
+
*/
|
|
187
|
+
var PresenceService = class {
|
|
188
|
+
ttlMs;
|
|
189
|
+
enabled;
|
|
190
|
+
rooms = /* @__PURE__ */ new Map();
|
|
191
|
+
roomsByClient = /* @__PURE__ */ new Map();
|
|
192
|
+
invalidator;
|
|
193
|
+
constructor(ttlMs = 3e4, enabled = true) {
|
|
194
|
+
this.ttlMs = ttlMs;
|
|
195
|
+
this.enabled = enabled;
|
|
196
|
+
}
|
|
197
|
+
/** Wired by the engine so beats/reaps invalidate through the live driver. */
|
|
198
|
+
bindInvalidator(invalidator) {
|
|
199
|
+
this.invalidator = invalidator;
|
|
200
|
+
}
|
|
201
|
+
beat(room, clientId, meta) {
|
|
202
|
+
if (!this.enabled) return;
|
|
203
|
+
let state = this.rooms.get(room);
|
|
204
|
+
if (!state) {
|
|
205
|
+
state = { members: /* @__PURE__ */ new Map() };
|
|
206
|
+
this.rooms.set(room, state);
|
|
207
|
+
}
|
|
208
|
+
state.members.set(clientId, {
|
|
209
|
+
meta,
|
|
210
|
+
lastSeen: Date.now()
|
|
211
|
+
});
|
|
212
|
+
let joined = this.roomsByClient.get(clientId);
|
|
213
|
+
if (!joined) {
|
|
214
|
+
joined = /* @__PURE__ */ new Set();
|
|
215
|
+
this.roomsByClient.set(clientId, joined);
|
|
216
|
+
}
|
|
217
|
+
joined.add(room);
|
|
218
|
+
this.invalidator?.([presenceTag(room)]);
|
|
219
|
+
}
|
|
220
|
+
/** Immediate departure on socket close — peers see it without a TTL wait. */
|
|
221
|
+
reap(clientId) {
|
|
222
|
+
const joined = this.roomsByClient.get(clientId);
|
|
223
|
+
if (!joined) return;
|
|
224
|
+
this.roomsByClient.delete(clientId);
|
|
225
|
+
for (const room of joined) {
|
|
226
|
+
const state = this.rooms.get(room);
|
|
227
|
+
if (!state) continue;
|
|
228
|
+
state.members.delete(clientId);
|
|
229
|
+
if (state.members.size === 0) this.rooms.delete(room);
|
|
230
|
+
this.invalidator?.([presenceTag(room)]);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
roster(room) {
|
|
234
|
+
const state = this.rooms.get(room);
|
|
235
|
+
if (!state) return [];
|
|
236
|
+
const oldestAlive = Date.now() - this.ttlMs;
|
|
237
|
+
return [...state.members.entries()].filter(([, member]) => member.lastSeen >= oldestAlive).map(([id, member]) => ({
|
|
238
|
+
id,
|
|
239
|
+
meta: member.meta,
|
|
240
|
+
lastSeen: member.lastSeen
|
|
241
|
+
}));
|
|
242
|
+
}
|
|
243
|
+
};
|
|
244
|
+
let PresenceResolver = class PresenceResolver {
|
|
245
|
+
presence;
|
|
246
|
+
constructor(presence) {
|
|
247
|
+
this.presence = presence;
|
|
248
|
+
}
|
|
249
|
+
roster(args) {
|
|
250
|
+
return this.presence.roster(args.room);
|
|
251
|
+
}
|
|
252
|
+
};
|
|
253
|
+
__decorate([
|
|
254
|
+
LiveQuery(PRESENCE_ROSTER_QUERY, {
|
|
255
|
+
tags: (args) => [presenceTag(args.room)],
|
|
256
|
+
parse: (args) => {
|
|
257
|
+
const room = args?.room;
|
|
258
|
+
if (typeof room !== "string" || room.length === 0) throw new Error("presence roster args require a non-empty 'room' string");
|
|
259
|
+
return { room };
|
|
260
|
+
}
|
|
261
|
+
}),
|
|
262
|
+
__decorateMetadata("design:type", Function),
|
|
263
|
+
__decorateMetadata("design:paramtypes", [Object]),
|
|
264
|
+
__decorateMetadata("design:returntype", Array)
|
|
265
|
+
], PresenceResolver.prototype, "roster", null);
|
|
266
|
+
PresenceResolver = __decorate([
|
|
267
|
+
LiveResolver(),
|
|
268
|
+
Injectable(),
|
|
269
|
+
__decorateParam(0, Inject(PresenceService)),
|
|
270
|
+
__decorateMetadata("design:paramtypes", [typeof PresenceService === "undefined" ? Object : PresenceService])
|
|
271
|
+
], PresenceResolver);
|
|
272
|
+
//#endregion
|
|
273
|
+
//#region src/live/live.engine.ts
|
|
274
|
+
var _LiveEngine;
|
|
275
|
+
/** How many subscriptions refresh concurrently per flush (lunora's socket-pool default). */
|
|
276
|
+
const REFRESH_POOL_SIZE = 8;
|
|
277
|
+
/**
|
|
278
|
+
* Where the engine persists a connection's subscription records inside
|
|
279
|
+
* `client.data` (committed through `WsClient.commit()`). On Cloudflare that
|
|
280
|
+
* lands in the hibernation attachment, so subscriptions survive DO eviction;
|
|
281
|
+
* the transport replays them via `restoreSubscription` on wake. On node,
|
|
282
|
+
* `commit()` is a no-op and this is just in-memory bookkeeping.
|
|
283
|
+
*/
|
|
284
|
+
const LIVE_SUBS_DATA_KEY = "__velaLiveSubs";
|
|
285
|
+
/** Read the subscription records a transport persisted for a connection (wake/restore path). */
|
|
286
|
+
function readPersistedLiveSubscriptions(client) {
|
|
287
|
+
const raw = client.data?.[LIVE_SUBS_DATA_KEY];
|
|
288
|
+
if (!Array.isArray(raw)) return [];
|
|
289
|
+
return raw.filter((record) => typeof record === "object" && record !== null && typeof record.sub === "string" && typeof record.query === "string" && Array.isArray(record.tags));
|
|
290
|
+
}
|
|
291
|
+
const defaultIdentity = (client) => {
|
|
292
|
+
const data = client.data;
|
|
293
|
+
if (!data || Object.keys(data).length === 0) return void 0;
|
|
294
|
+
return { ...data };
|
|
295
|
+
};
|
|
296
|
+
async function runPool(items, size, run) {
|
|
297
|
+
const queue = [...items];
|
|
298
|
+
const workers = Array.from({ length: Math.min(size, queue.length) }, async () => {
|
|
299
|
+
for (let item = queue.shift(); item !== void 0; item = queue.shift()) await run(item);
|
|
300
|
+
});
|
|
301
|
+
await Promise.all(workers);
|
|
302
|
+
}
|
|
303
|
+
let LiveEngine = _LiveEngine = class LiveEngine {
|
|
304
|
+
container;
|
|
305
|
+
discovery;
|
|
306
|
+
log;
|
|
307
|
+
options;
|
|
308
|
+
presence;
|
|
309
|
+
queries = /* @__PURE__ */ new Map();
|
|
310
|
+
connections = /* @__PURE__ */ new Map();
|
|
311
|
+
pendingTags = /* @__PURE__ */ new Set();
|
|
312
|
+
drainChain = Promise.resolve();
|
|
313
|
+
draining = false;
|
|
314
|
+
constructor(container, discovery, log, driver, options, presence) {
|
|
315
|
+
this.container = container;
|
|
316
|
+
this.discovery = discovery;
|
|
317
|
+
this.log = log;
|
|
318
|
+
this.options = options;
|
|
319
|
+
this.presence = presence;
|
|
320
|
+
driver.bind(this);
|
|
321
|
+
this.presence?.bindInvalidator((tags) => {
|
|
322
|
+
driver.dispatch({ tags });
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
async onApplicationBootstrap() {
|
|
326
|
+
for (const found of this.discovery.providersWithMeta(LIVE_RESOLVER_METADATA)) {
|
|
327
|
+
if (!found.instance) continue;
|
|
328
|
+
for (const declared of getLiveQueries(found.metatype)) {
|
|
329
|
+
if (this.queries.has(declared.name)) {
|
|
330
|
+
const msg = `[vela] duplicate @LiveQuery('${declared.name}') (${found.metatype.name}); keeping the first.`;
|
|
331
|
+
if (this.container.getDiagnostics() === "throw") throw new Error(msg);
|
|
332
|
+
console.warn(msg);
|
|
333
|
+
continue;
|
|
334
|
+
}
|
|
335
|
+
this.queries.set(declared.name, {
|
|
336
|
+
token: found.metatype,
|
|
337
|
+
methodName: declared.methodName,
|
|
338
|
+
options: declared.options
|
|
339
|
+
});
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
/** The `'live'` entrypoint — how transports (node registrar, CF DO bootstrap) find the engine. */
|
|
344
|
+
collectEntrypoints() {
|
|
345
|
+
return [{
|
|
346
|
+
kind: "live",
|
|
347
|
+
token: _LiveEngine,
|
|
348
|
+
instance: this,
|
|
349
|
+
meta: { engine: this }
|
|
350
|
+
}];
|
|
351
|
+
}
|
|
352
|
+
async handleReservedEvent(path, client, message) {
|
|
353
|
+
const frame = message.data;
|
|
354
|
+
if (!isClientLiveFrame$1(frame)) return;
|
|
355
|
+
switch (frame.t) {
|
|
356
|
+
case "sub":
|
|
357
|
+
await this.onSubscribe(path, client, frame);
|
|
358
|
+
return;
|
|
359
|
+
case "unsub": {
|
|
360
|
+
const conn = this.connections.get(client.id);
|
|
361
|
+
if (!conn) return;
|
|
362
|
+
conn.subs.delete(frame.sub);
|
|
363
|
+
if (conn.subs.size === 0) this.connections.delete(client.id);
|
|
364
|
+
await this.persistSubscriptions(conn);
|
|
365
|
+
return;
|
|
366
|
+
}
|
|
367
|
+
case "presence":
|
|
368
|
+
if (this.presence?.enabled) this.presence.beat(frame.room, client.id, frame.meta);
|
|
369
|
+
return;
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
async handleSocketClose(_path, client) {
|
|
373
|
+
this.connections.delete(client.id);
|
|
374
|
+
this.presence?.reap(client.id);
|
|
375
|
+
}
|
|
376
|
+
async applyInvalidation(cmd) {
|
|
377
|
+
const stamp = await this.log.append(cmd.tags);
|
|
378
|
+
for (const tag of cmd.tags) this.pendingTags.add(tag);
|
|
379
|
+
this.scheduleDrain();
|
|
380
|
+
return stamp;
|
|
381
|
+
}
|
|
382
|
+
/** Settles when every pending invalidation has been flushed (tests, graceful transports). */
|
|
383
|
+
async whenIdle() {
|
|
384
|
+
do
|
|
385
|
+
await this.drainChain;
|
|
386
|
+
while (this.draining || this.pendingTags.size > 0);
|
|
387
|
+
}
|
|
388
|
+
/**
|
|
389
|
+
* Re-attach a persisted subscription without the subscribe handshake — the
|
|
390
|
+
* Cloudflare transport replays hibernation-attachment records through this
|
|
391
|
+
* on wake. No frames are sent; the next relevant invalidation pushes.
|
|
392
|
+
*/
|
|
393
|
+
restoreSubscription(path, client, record) {
|
|
394
|
+
this.ensureConnection(path, client).subs.set(record.sub, record);
|
|
395
|
+
}
|
|
396
|
+
async onSubscribe(path, client, frame) {
|
|
397
|
+
if (frame.v !== void 0 && frame.v > LIVE_PROTOCOL$1) {
|
|
398
|
+
this.sendFrame(client, {
|
|
399
|
+
t: "error",
|
|
400
|
+
sub: frame.sub,
|
|
401
|
+
code: LIVE_ERROR_CODES$1.UNSUPPORTED_PROTOCOL,
|
|
402
|
+
message: `server speaks live protocol v${LIVE_PROTOCOL$1}, client asked for v${frame.v}`,
|
|
403
|
+
fatal: true
|
|
404
|
+
});
|
|
405
|
+
return;
|
|
406
|
+
}
|
|
407
|
+
const conn = this.ensureConnection(path, client);
|
|
408
|
+
if (conn.subs.has(frame.sub)) {
|
|
409
|
+
this.sendFrame(client, {
|
|
410
|
+
t: "error",
|
|
411
|
+
sub: frame.sub,
|
|
412
|
+
code: LIVE_ERROR_CODES$1.DUPLICATE_SUB,
|
|
413
|
+
message: `subscription id '${frame.sub}' is already active on this socket`,
|
|
414
|
+
fatal: false
|
|
415
|
+
});
|
|
416
|
+
return;
|
|
417
|
+
}
|
|
418
|
+
const registered = this.queries.get(frame.query);
|
|
419
|
+
if (!registered) {
|
|
420
|
+
this.sendFrame(client, {
|
|
421
|
+
t: "error",
|
|
422
|
+
sub: frame.sub,
|
|
423
|
+
code: LIVE_ERROR_CODES$1.UNKNOWN_QUERY,
|
|
424
|
+
message: `no @LiveQuery('${frame.query}') is registered`,
|
|
425
|
+
fatal: true
|
|
426
|
+
});
|
|
427
|
+
return;
|
|
428
|
+
}
|
|
429
|
+
let args = frame.args;
|
|
430
|
+
if (registered.options.parse) try {
|
|
431
|
+
args = registered.options.parse(frame.args);
|
|
432
|
+
} catch (err) {
|
|
433
|
+
this.sendFrame(client, {
|
|
434
|
+
t: "error",
|
|
435
|
+
sub: frame.sub,
|
|
436
|
+
code: LIVE_ERROR_CODES$1.BAD_ARGS,
|
|
437
|
+
message: err instanceof Error ? err.message : "invalid subscription args",
|
|
438
|
+
fatal: true
|
|
439
|
+
});
|
|
440
|
+
return;
|
|
441
|
+
}
|
|
442
|
+
if (!await this.runSubscribeGuards(registered, client, frame.query, args)) {
|
|
443
|
+
this.sendFrame(client, {
|
|
444
|
+
t: "error",
|
|
445
|
+
sub: frame.sub,
|
|
446
|
+
code: LIVE_ERROR_CODES$1.FORBIDDEN,
|
|
447
|
+
message: `subscription to '${frame.query}' was rejected`,
|
|
448
|
+
fatal: true
|
|
449
|
+
});
|
|
450
|
+
return;
|
|
451
|
+
}
|
|
452
|
+
const identity = (this.options.identity ?? defaultIdentity)(client);
|
|
453
|
+
const tags = typeof registered.options.tags === "function" ? registered.options.tags(args) : registered.options.tags;
|
|
454
|
+
const record = {
|
|
455
|
+
sub: frame.sub,
|
|
456
|
+
query: frame.query,
|
|
457
|
+
args,
|
|
458
|
+
tags,
|
|
459
|
+
key: frame.key ?? registered.options.key,
|
|
460
|
+
identity
|
|
461
|
+
};
|
|
462
|
+
conn.subs.set(frame.sub, record);
|
|
463
|
+
await this.persistSubscriptions(conn);
|
|
464
|
+
this.sendFrame(client, {
|
|
465
|
+
t: "ack",
|
|
466
|
+
sub: frame.sub
|
|
467
|
+
});
|
|
468
|
+
if (frame.sinceCursor !== void 0 && frame.sinceEpoch !== void 0) {
|
|
469
|
+
if (await this.log.evaluateResume(frame.sinceCursor, frame.sinceEpoch, tags) === "resume") {
|
|
470
|
+
const stamp = await this.log.current();
|
|
471
|
+
if (this.sendFrame(client, {
|
|
472
|
+
t: "resume",
|
|
473
|
+
sub: frame.sub,
|
|
474
|
+
cursor: stamp.cursor,
|
|
475
|
+
epoch: stamp.epoch
|
|
476
|
+
})) record.lastCursor = stamp.cursor;
|
|
477
|
+
return;
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
await this.push(conn, record, await this.log.current(), { initial: true });
|
|
481
|
+
}
|
|
482
|
+
async runSubscribeGuards(registered, client, query, args) {
|
|
483
|
+
const guards = resolveScopedComponents("guard", registered.token, registered.methodName, this.container);
|
|
484
|
+
if (guards.length === 0) return true;
|
|
485
|
+
const context = buildEntrypointExecutionContext("live", registered.token, registered.methodName, {
|
|
486
|
+
query,
|
|
487
|
+
args,
|
|
488
|
+
client
|
|
489
|
+
});
|
|
490
|
+
try {
|
|
491
|
+
for (const guard of guards) if (!await guard.canActivate(context)) return false;
|
|
492
|
+
return true;
|
|
493
|
+
} catch {
|
|
494
|
+
return false;
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
scheduleDrain() {
|
|
498
|
+
if (this.draining) return;
|
|
499
|
+
this.draining = true;
|
|
500
|
+
this.drainChain = this.drainChain.then(() => this.drainLoop()).catch((err) => {
|
|
501
|
+
if (this.container.getDiagnostics() !== "silent") console.warn("[vela] live refresh flush failed:", err);
|
|
502
|
+
}).finally(() => {
|
|
503
|
+
this.draining = false;
|
|
504
|
+
if (this.pendingTags.size > 0) this.scheduleDrain();
|
|
505
|
+
});
|
|
506
|
+
}
|
|
507
|
+
async drainLoop() {
|
|
508
|
+
while (this.pendingTags.size > 0) {
|
|
509
|
+
const changed = new Set(this.pendingTags);
|
|
510
|
+
this.pendingTags.clear();
|
|
511
|
+
const stamp = await this.log.current();
|
|
512
|
+
const work = [];
|
|
513
|
+
for (const conn of this.connections.values()) for (const record of conn.subs.values()) if (record.tags.some((tag) => changed.has(tag))) work.push({
|
|
514
|
+
conn,
|
|
515
|
+
record
|
|
516
|
+
});
|
|
517
|
+
await runPool(work, REFRESH_POOL_SIZE, async ({ conn, record }) => {
|
|
518
|
+
await this.push(conn, record, stamp, { initial: false });
|
|
519
|
+
});
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
/**
|
|
523
|
+
* Map a resolver failure to its live error-frame code. A branded
|
|
524
|
+
* {@link VelaError} carries an HTTP-ish status that projects onto the live
|
|
525
|
+
* vocabulary (403 → forbidden, 400/422 → bad_args); everything else — and
|
|
526
|
+
* every unbranded error — is `internal` (the client sees a redacted message).
|
|
527
|
+
*/
|
|
528
|
+
static liveFrameCode(err) {
|
|
529
|
+
if (!isVelaError(err)) return LIVE_ERROR_CODES$1.INTERNAL;
|
|
530
|
+
if (err.status === 403) return LIVE_ERROR_CODES$1.FORBIDDEN;
|
|
531
|
+
if (err.status === 400 || err.status === 422) return LIVE_ERROR_CODES$1.BAD_ARGS;
|
|
532
|
+
return LIVE_ERROR_CODES$1.INTERNAL;
|
|
533
|
+
}
|
|
534
|
+
async push(conn, record, stamp, { initial }) {
|
|
535
|
+
const expiresAt = record.identity?.expiresAt;
|
|
536
|
+
if (typeof expiresAt === "number" && expiresAt <= Date.now()) {
|
|
537
|
+
this.connections.delete(conn.client.id);
|
|
538
|
+
try {
|
|
539
|
+
conn.client.close(1008, "identity expired");
|
|
540
|
+
} catch {}
|
|
541
|
+
return;
|
|
542
|
+
}
|
|
543
|
+
let json;
|
|
544
|
+
let result;
|
|
545
|
+
try {
|
|
546
|
+
result = await this.runQuery(record, conn.client);
|
|
547
|
+
if (result === void 0) result = null;
|
|
548
|
+
json = JSON.stringify(result);
|
|
549
|
+
} catch (err) {
|
|
550
|
+
if (initial) {
|
|
551
|
+
conn.subs.delete(record.sub);
|
|
552
|
+
const reporter = resolveErrorReporter(this.container);
|
|
553
|
+
reporter.report(err, {
|
|
554
|
+
edge: "live",
|
|
555
|
+
source: record.query
|
|
556
|
+
});
|
|
557
|
+
const safe = toErrorBody(err, { catalog: reporter.catalog });
|
|
558
|
+
this.sendFrame(conn.client, {
|
|
559
|
+
t: "error",
|
|
560
|
+
sub: record.sub,
|
|
561
|
+
code: _LiveEngine.liveFrameCode(err),
|
|
562
|
+
message: safe.body.error.message,
|
|
563
|
+
fatal: true
|
|
564
|
+
});
|
|
565
|
+
} else if (this.container.getDiagnostics() !== "silent") console.warn(`[vela] live query '${record.query}' re-run failed (will retry):`, err);
|
|
566
|
+
return;
|
|
567
|
+
}
|
|
568
|
+
const frame = encodeSubscriptionUpdate(record, json, result, stamp, initial);
|
|
569
|
+
if (this.sendFrame(conn.client, frame)) {
|
|
570
|
+
record.lastJson = json;
|
|
571
|
+
record.lastCursor = stamp.cursor;
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
async runQuery(record, client) {
|
|
575
|
+
const registered = this.queries.get(record.query);
|
|
576
|
+
if (!registered) throw new Error(`live query '${record.query}' disappeared from the registry`);
|
|
577
|
+
return runInEntrypointScope(this.container, async (scope) => {
|
|
578
|
+
const instance = await scope.resolveAsync(registered.token);
|
|
579
|
+
const liveContext = {
|
|
580
|
+
identity: record.identity,
|
|
581
|
+
clientId: client.id,
|
|
582
|
+
rooms: [...client.rooms]
|
|
583
|
+
};
|
|
584
|
+
const context = buildEntrypointExecutionContext("live", registered.token, registered.methodName, {
|
|
585
|
+
query: record.query,
|
|
586
|
+
args: record.args,
|
|
587
|
+
client
|
|
588
|
+
});
|
|
589
|
+
const interceptors = resolveScopedComponents("interceptor", registered.token, registered.methodName, scope);
|
|
590
|
+
return PipelineRunner.run({
|
|
591
|
+
context,
|
|
592
|
+
guards: [],
|
|
593
|
+
interceptors,
|
|
594
|
+
resolveArgs: async () => [record.args, liveContext],
|
|
595
|
+
invoke: async (args) => {
|
|
596
|
+
return instance[registered.methodName].apply(instance, args);
|
|
597
|
+
}
|
|
598
|
+
});
|
|
599
|
+
});
|
|
600
|
+
}
|
|
601
|
+
/**
|
|
602
|
+
* Mirror the connection's records into `client.data` + `commit()` so
|
|
603
|
+
* hibernating transports can replay them on wake. The volatile diff
|
|
604
|
+
* baseline (`lastJson`/`lastCursor`) is deliberately stripped: it can be
|
|
605
|
+
* large (the whole last result vs the 16 KiB attachment cap) and a lost
|
|
606
|
+
* baseline just means the next relevant change sends a full snapshot.
|
|
607
|
+
*/
|
|
608
|
+
async persistSubscriptions(conn) {
|
|
609
|
+
const records = [...conn.subs.values()].map(({ lastJson: _lastJson, lastCursor: _lastCursor, ...persisted }) => persisted);
|
|
610
|
+
try {
|
|
611
|
+
conn.client.data[LIVE_SUBS_DATA_KEY] = records;
|
|
612
|
+
await conn.client.commit();
|
|
613
|
+
} catch (err) {
|
|
614
|
+
if (this.container.getDiagnostics() !== "silent") console.warn("[vela] live subscription persistence failed (resume across eviction disabled):", err);
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
ensureConnection(path, client) {
|
|
618
|
+
let conn = this.connections.get(client.id);
|
|
619
|
+
if (!conn) {
|
|
620
|
+
conn = {
|
|
621
|
+
client,
|
|
622
|
+
path,
|
|
623
|
+
subs: /* @__PURE__ */ new Map()
|
|
624
|
+
};
|
|
625
|
+
this.connections.set(client.id, conn);
|
|
626
|
+
}
|
|
627
|
+
return conn;
|
|
628
|
+
}
|
|
629
|
+
sendFrame(client, frame) {
|
|
630
|
+
try {
|
|
631
|
+
client.sendRaw(encodeLiveEnvelope$1(frame));
|
|
632
|
+
return true;
|
|
633
|
+
} catch {
|
|
634
|
+
return false;
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
};
|
|
638
|
+
LiveEngine = _LiveEngine = __decorate([
|
|
639
|
+
ReservedWsEvent("$live"),
|
|
640
|
+
Injectable(),
|
|
641
|
+
__decorateParam(0, Inject(Container)),
|
|
642
|
+
__decorateParam(1, Inject(DiscoveryService)),
|
|
643
|
+
__decorateParam(2, Inject(LIVE_CURSOR_LOG)),
|
|
644
|
+
__decorateParam(3, Inject(LIVE_DRIVER)),
|
|
645
|
+
__decorateParam(4, Inject(LIVE_MODULE_OPTIONS)),
|
|
646
|
+
__decorateParam(5, Optional()),
|
|
647
|
+
__decorateParam(5, Inject(PresenceService)),
|
|
648
|
+
__decorateMetadata("design:paramtypes", [
|
|
649
|
+
typeof Container === "undefined" ? Object : Container,
|
|
650
|
+
typeof DiscoveryService === "undefined" ? Object : DiscoveryService,
|
|
651
|
+
Object,
|
|
652
|
+
Object,
|
|
653
|
+
Object,
|
|
654
|
+
typeof PresenceService === "undefined" ? Object : PresenceService
|
|
655
|
+
])
|
|
656
|
+
], LiveEngine);
|
|
657
|
+
//#endregion
|
|
658
|
+
//#region src/live/live.invalidation.ts
|
|
659
|
+
/** Single-scope default driver: deliver straight to this process's engine. */
|
|
660
|
+
function localLive() {
|
|
661
|
+
let sink;
|
|
662
|
+
return {
|
|
663
|
+
kind: "local",
|
|
664
|
+
bind(s) {
|
|
665
|
+
sink = s;
|
|
666
|
+
},
|
|
667
|
+
dispatch(cmd) {
|
|
668
|
+
return sink?.applyInvalidation(cmd);
|
|
669
|
+
}
|
|
670
|
+
};
|
|
671
|
+
}
|
|
672
|
+
/**
|
|
673
|
+
* Per-app wrapper around a (possibly SHARED) driver instance.
|
|
674
|
+
*
|
|
675
|
+
* A driver passed to `LiveModule.forRoot({ driver })` is a plain config object
|
|
676
|
+
* — and on Cloudflare the SAME app module (thus the same driver object)
|
|
677
|
+
* bootstraps in the Worker isolate AND inside each Durable Object, often
|
|
678
|
+
* within one isolate. Mutable per-app state must therefore never live on the
|
|
679
|
+
* driver itself: the DO flipping a shared `durableObjectLive()` into local
|
|
680
|
+
* mode would otherwise poison the Worker's engine, which then executes the
|
|
681
|
+
* DO's storage handle in the wrong request context ("Cannot perform I/O on
|
|
682
|
+
* behalf of a different request").
|
|
683
|
+
*
|
|
684
|
+
* The wrapper owns the per-app sink and the per-app local-mode flag; isolate-
|
|
685
|
+
* wide concerns (env capture) forward to the underlying driver. Platform init
|
|
686
|
+
* hooks (`_setLocalMode`, `_initializeEnv`) are exposed pass-through so
|
|
687
|
+
* platform packages can keep type-guarding on their presence.
|
|
688
|
+
*/
|
|
689
|
+
function perAppLiveDriver(underlying) {
|
|
690
|
+
let ownSink;
|
|
691
|
+
let localMode = false;
|
|
692
|
+
const cfHooks = underlying;
|
|
693
|
+
return {
|
|
694
|
+
get kind() {
|
|
695
|
+
return underlying.kind;
|
|
696
|
+
},
|
|
697
|
+
bind(sink) {
|
|
698
|
+
ownSink = sink;
|
|
699
|
+
underlying.bind(sink);
|
|
700
|
+
},
|
|
701
|
+
dispatch(cmd) {
|
|
702
|
+
if (localMode && ownSink) return ownSink.applyInvalidation(cmd);
|
|
703
|
+
return underlying.dispatch(cmd);
|
|
704
|
+
},
|
|
705
|
+
start: underlying.start ? () => underlying.start?.() : void 0,
|
|
706
|
+
stop: underlying.stop ? () => underlying.stop?.() : void 0,
|
|
707
|
+
_setLocalMode() {
|
|
708
|
+
localMode = true;
|
|
709
|
+
},
|
|
710
|
+
_initializeEnv(env) {
|
|
711
|
+
cfHooks._initializeEnv?.(env);
|
|
712
|
+
}
|
|
713
|
+
};
|
|
714
|
+
}
|
|
715
|
+
/**
|
|
716
|
+
* The injectable invalidation surface for custom (non-CRUD) write paths:
|
|
717
|
+
*
|
|
718
|
+
* ```ts
|
|
719
|
+
* await this.live.invalidate({ tags: ['todos:' + listId] });
|
|
720
|
+
* ```
|
|
721
|
+
*
|
|
722
|
+
* Every affected live query re-runs and pushes. Returns the commit stamp of
|
|
723
|
+
* the targeted log scope so mutation endpoints can expose it to the client
|
|
724
|
+
* (`Vela-Commit-Cursor` / `Vela-Commit-Epoch`) — the cursor optimistic
|
|
725
|
+
* updates gate on. When ambient request access is enabled
|
|
726
|
+
* (`VelaFactory.create(m, { ambientContainer: true })`) the headers are
|
|
727
|
+
* stamped onto the current HTTP response automatically; otherwise stamp them
|
|
728
|
+
* yourself via {@link stampCommitHeaders}.
|
|
729
|
+
*/
|
|
730
|
+
var LiveInvalidation = class {
|
|
731
|
+
driver;
|
|
732
|
+
constructor(driver) {
|
|
733
|
+
this.driver = driver;
|
|
734
|
+
}
|
|
735
|
+
async invalidate(cmd) {
|
|
736
|
+
const stamp = await this.driver.dispatch(cmd);
|
|
737
|
+
if (stamp) stampAmbientCommitHeaders(stamp);
|
|
738
|
+
return stamp;
|
|
739
|
+
}
|
|
740
|
+
};
|
|
741
|
+
/** Write the commit headers onto a Hono context (a mutation route's response). */
|
|
742
|
+
function stampCommitHeaders(c, stamp) {
|
|
743
|
+
c.header(COMMIT_CURSOR_HEADER$1, String(stamp.cursor));
|
|
744
|
+
c.header(COMMIT_EPOCH_HEADER$1, stamp.epoch);
|
|
745
|
+
}
|
|
746
|
+
/**
|
|
747
|
+
* Best-effort automatic header stamping through Hono's ambient context
|
|
748
|
+
* storage. A no-op outside a request or when `contextStorage()` isn't
|
|
749
|
+
* registered — ALS keeps this per-request-correct under concurrency (a
|
|
750
|
+
* mutable singleton slot would race interleaved awaits).
|
|
751
|
+
*/
|
|
752
|
+
function stampAmbientCommitHeaders(stamp) {
|
|
753
|
+
try {
|
|
754
|
+
stampCommitHeaders(getContext(), stamp);
|
|
755
|
+
} catch {}
|
|
756
|
+
}
|
|
757
|
+
//#endregion
|
|
758
|
+
//#region src/live/live.module.ts
|
|
759
|
+
/**
|
|
760
|
+
* First-party live-query module (tag-based realtime reactivity) — authored,
|
|
761
|
+
* like the queue module, entirely on vela's public API (`live-openness.test.ts`
|
|
762
|
+
* machine-verifies it; the only extra dependency is the shared wire package
|
|
763
|
+
* `@velajs/live-protocol`).
|
|
764
|
+
*
|
|
765
|
+
* ```ts
|
|
766
|
+
* imports: [WebSocketModule.forRoot({}), LiveModule.forRoot({})]
|
|
767
|
+
* ```
|
|
768
|
+
*
|
|
769
|
+
* App code declares `@LiveResolver` classes with `@LiveQuery(name, { tags })`
|
|
770
|
+
* methods; clients subscribe over the `$live` reserved WebSocket event; writes
|
|
771
|
+
* invalidate tags via `LiveInvalidation` (the `@velajs/crud` bridge does it
|
|
772
|
+
* automatically per table). See `LIVE.md` for the wire protocol, delivery
|
|
773
|
+
* guarantees, and the resume story.
|
|
774
|
+
*
|
|
775
|
+
* Deliberately EAGER (like WebSocketModule): the engine self-drives — it
|
|
776
|
+
* claims the `$live` event at bootstrap and receives invalidations from
|
|
777
|
+
* writes that never touch a live token — so the lazy-module contract
|
|
778
|
+
* ("nothing self-drives") rules laziness out.
|
|
779
|
+
*/
|
|
780
|
+
const { ConfigurableModuleClass } = defineModule({
|
|
781
|
+
name: "Live",
|
|
782
|
+
optionsToken: LIVE_MODULE_OPTIONS,
|
|
783
|
+
key: (options) => `live#${options?.driver?.kind ?? "local"}`,
|
|
784
|
+
setup: ({ OPTIONS, options }) => ({
|
|
785
|
+
providers: [
|
|
786
|
+
{
|
|
787
|
+
provide: LIVE_CURSOR_LOG,
|
|
788
|
+
useFactory: (o) => o.log ?? new InMemoryCursorLog(),
|
|
789
|
+
inject: [OPTIONS]
|
|
790
|
+
},
|
|
791
|
+
{
|
|
792
|
+
provide: LIVE_DRIVER,
|
|
793
|
+
useFactory: (o) => perAppLiveDriver(o.driver ?? localLive()),
|
|
794
|
+
inject: [OPTIONS]
|
|
795
|
+
},
|
|
796
|
+
{
|
|
797
|
+
provide: PresenceService,
|
|
798
|
+
useFactory: (o) => {
|
|
799
|
+
const presence = o.presence;
|
|
800
|
+
if (presence === false) return new PresenceService(void 0, false);
|
|
801
|
+
return new PresenceService(presence?.ttlMs, true);
|
|
802
|
+
},
|
|
803
|
+
inject: [OPTIONS]
|
|
804
|
+
},
|
|
805
|
+
{
|
|
806
|
+
provide: LiveInvalidation,
|
|
807
|
+
useFactory: (driver) => new LiveInvalidation(driver),
|
|
808
|
+
inject: [LIVE_DRIVER]
|
|
809
|
+
},
|
|
810
|
+
LiveEngine,
|
|
811
|
+
...options?.presence === false ? [] : [PresenceResolver]
|
|
812
|
+
],
|
|
813
|
+
exports: [
|
|
814
|
+
LiveEngine,
|
|
815
|
+
LiveInvalidation,
|
|
816
|
+
LIVE_DRIVER,
|
|
817
|
+
LIVE_CURSOR_LOG,
|
|
818
|
+
PresenceService
|
|
819
|
+
]
|
|
820
|
+
})
|
|
821
|
+
});
|
|
822
|
+
var LiveModule = class extends ConfigurableModuleClass {};
|
|
823
|
+
//#endregion
|
|
824
|
+
export { COMMIT_CURSOR_HEADER, COMMIT_EPOCH_HEADER, DEFAULT_KEY_FIELD, InMemoryCursorLog, LIVE_CURSOR_LOG, LIVE_DRIVER, LIVE_ERROR_CODES, LIVE_EVENT, LIVE_MODULE_OPTIONS, LIVE_PROTOCOL, LIVE_QUERY_METADATA, LIVE_RESOLVER_METADATA, LIVE_SUBS_DATA_KEY, LiveEngine, LiveInvalidation, LiveModule, LiveQuery, LiveResolver, PRESENCE_ROSTER_QUERY, PresenceResolver, PresenceService, applyListDelta, encodeListDelta, encodeLiveEnvelope, encodeLiveFrame, encodeSubscriptionUpdate, getLiveQueries, isClientLiveFrame, isServerLiveFrame, localLive, perAppLiveDriver, presenceTag, readLiveEnvelope, readPersistedLiveSubscriptions, stampCommitHeaders };
|
|
825
|
+
|
|
826
|
+
//# sourceMappingURL=index.js.map
|