typeferry 0.6.0
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 +88 -0
- package/dist/auth/client/cross-tab-sync.d.ts +21 -0
- package/dist/auth/client/cross-tab-sync.js +56 -0
- package/dist/auth/client/cross-tab-sync.js.map +1 -0
- package/dist/auth/client/index.d.ts +2 -0
- package/dist/auth/client/index.js +3 -0
- package/dist/auth/client/index.js.map +1 -0
- package/dist/auth/client/oauth/google-provider.d.ts +11 -0
- package/dist/auth/client/oauth/google-provider.js +11 -0
- package/dist/auth/client/oauth/google-provider.js.map +1 -0
- package/dist/auth/client/oauth/index.d.ts +4 -0
- package/dist/auth/client/oauth/index.js +3 -0
- package/dist/auth/client/oauth/index.js.map +1 -0
- package/dist/auth/client/oauth/use-google-login.d.ts +39 -0
- package/dist/auth/client/oauth/use-google-login.js +55 -0
- package/dist/auth/client/oauth/use-google-login.js.map +1 -0
- package/dist/auth/client/token-refresh.d.ts +21 -0
- package/dist/auth/client/token-refresh.js +212 -0
- package/dist/auth/client/token-refresh.js.map +1 -0
- package/dist/auth/index.d.ts +7 -0
- package/dist/auth/index.js +9 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/server/cookie-utils.d.ts +42 -0
- package/dist/auth/server/cookie-utils.js +91 -0
- package/dist/auth/server/cookie-utils.js.map +1 -0
- package/dist/auth/server/device-info.d.ts +23 -0
- package/dist/auth/server/device-info.js +52 -0
- package/dist/auth/server/device-info.js.map +1 -0
- package/dist/auth/server/index.d.ts +4 -0
- package/dist/auth/server/index.js +5 -0
- package/dist/auth/server/index.js.map +1 -0
- package/dist/auth/server/jwt-utils.d.ts +29 -0
- package/dist/auth/server/jwt-utils.js +53 -0
- package/dist/auth/server/jwt-utils.js.map +1 -0
- package/dist/auth/server/oauth/google.d.ts +31 -0
- package/dist/auth/server/oauth/google.js +40 -0
- package/dist/auth/server/oauth/google.js.map +1 -0
- package/dist/auth/server/oauth/index.d.ts +3 -0
- package/dist/auth/server/oauth/index.js +2 -0
- package/dist/auth/server/oauth/index.js.map +1 -0
- package/dist/auth/server/oauth/types.d.ts +37 -0
- package/dist/auth/server/oauth/types.js +2 -0
- package/dist/auth/server/oauth/types.js.map +1 -0
- package/dist/auth/server/session-manager.d.ts +46 -0
- package/dist/auth/server/session-manager.js +167 -0
- package/dist/auth/server/session-manager.js.map +1 -0
- package/dist/auth/types.d.ts +197 -0
- package/dist/auth/types.js +2 -0
- package/dist/auth/types.js.map +1 -0
- package/dist/client/call-method-proxy.d.ts +2 -0
- package/dist/client/call-method-proxy.js +22 -0
- package/dist/client/call-method-proxy.js.map +1 -0
- package/dist/client/client-channel.d.ts +43 -0
- package/dist/client/client-channel.js +148 -0
- package/dist/client/client-channel.js.map +1 -0
- package/dist/client/client-http.d.ts +27 -0
- package/dist/client/client-http.js +106 -0
- package/dist/client/client-http.js.map +1 -0
- package/dist/client/client-socket.d.ts +85 -0
- package/dist/client/client-socket.js +317 -0
- package/dist/client/client-socket.js.map +1 -0
- package/dist/client/client.d.ts +149 -0
- package/dist/client/client.js +401 -0
- package/dist/client/client.js.map +1 -0
- package/dist/client/context-manager.d.ts +54 -0
- package/dist/client/context-manager.js +89 -0
- package/dist/client/context-manager.js.map +1 -0
- package/dist/client/idle-timer.d.ts +35 -0
- package/dist/client/idle-timer.js +101 -0
- package/dist/client/idle-timer.js.map +1 -0
- package/dist/client/index.d.ts +6 -0
- package/dist/client/index.js +7 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/logger.d.ts +76 -0
- package/dist/client/logger.js +129 -0
- package/dist/client/logger.js.map +1 -0
- package/dist/client/visibility-manager.d.ts +62 -0
- package/dist/client/visibility-manager.js +177 -0
- package/dist/client/visibility-manager.js.map +1 -0
- package/dist/ejson/adjust-types-from-json-value.d.ts +1 -0
- package/dist/ejson/adjust-types-from-json-value.js +35 -0
- package/dist/ejson/adjust-types-from-json-value.js.map +1 -0
- package/dist/ejson/base64.d.ts +11 -0
- package/dist/ejson/base64.js +87 -0
- package/dist/ejson/base64.js.map +1 -0
- package/dist/ejson/built-in-converters.d.ts +1 -0
- package/dist/ejson/built-in-converters.js +137 -0
- package/dist/ejson/built-in-converters.js.map +1 -0
- package/dist/ejson/clone.d.ts +1 -0
- package/dist/ejson/clone.js +80 -0
- package/dist/ejson/clone.js.map +1 -0
- package/dist/ejson/custom-models.d.ts +38 -0
- package/dist/ejson/custom-models.js +76 -0
- package/dist/ejson/custom-models.js.map +1 -0
- package/dist/ejson/custom-types.d.ts +1 -0
- package/dist/ejson/custom-types.js +2 -0
- package/dist/ejson/custom-types.js.map +1 -0
- package/dist/ejson/equals.d.ts +1 -0
- package/dist/ejson/equals.js +117 -0
- package/dist/ejson/equals.js.map +1 -0
- package/dist/ejson/from-json-value.d.ts +1 -0
- package/dist/ejson/from-json-value.js +13 -0
- package/dist/ejson/from-json-value.js.map +1 -0
- package/dist/ejson/helpers/adjust-types-to-json-value.d.ts +1 -0
- package/dist/ejson/helpers/adjust-types-to-json-value.js +36 -0
- package/dist/ejson/helpers/adjust-types-to-json-value.js.map +1 -0
- package/dist/ejson/helpers/from-json-value-helper.d.ts +1 -0
- package/dist/ejson/helpers/from-json-value-helper.js +24 -0
- package/dist/ejson/helpers/from-json-value-helper.js.map +1 -0
- package/dist/ejson/helpers/to-json-value-helper.d.ts +1 -0
- package/dist/ejson/helpers/to-json-value-helper.js +15 -0
- package/dist/ejson/helpers/to-json-value-helper.js.map +1 -0
- package/dist/ejson/index.d.ts +27 -0
- package/dist/ejson/index.js +54 -0
- package/dist/ejson/index.js.map +1 -0
- package/dist/ejson/is-binary.d.ts +2 -0
- package/dist/ejson/is-binary.js +5 -0
- package/dist/ejson/is-binary.js.map +1 -0
- package/dist/ejson/parse.d.ts +6 -0
- package/dist/ejson/parse.js +12 -0
- package/dist/ejson/parse.js.map +1 -0
- package/dist/ejson/stable-stringify.d.ts +10 -0
- package/dist/ejson/stable-stringify.js +25 -0
- package/dist/ejson/stable-stringify.js.map +1 -0
- package/dist/ejson/stringify.d.ts +5 -0
- package/dist/ejson/stringify.js +15 -0
- package/dist/ejson/stringify.js.map +1 -0
- package/dist/ejson/to-json-value.d.ts +1 -0
- package/dist/ejson/to-json-value.js +17 -0
- package/dist/ejson/to-json-value.js.map +1 -0
- package/dist/ejson/utils.d.ts +18 -0
- package/dist/ejson/utils.js +43 -0
- package/dist/ejson/utils.js.map +1 -0
- package/dist/mongodb/change-streams.d.ts +31 -0
- package/dist/mongodb/change-streams.js +142 -0
- package/dist/mongodb/change-streams.js.map +1 -0
- package/dist/mongodb/client.d.ts +13 -0
- package/dist/mongodb/client.js +30 -0
- package/dist/mongodb/client.js.map +1 -0
- package/dist/mongodb/decorators/collection.d.ts +9 -0
- package/dist/mongodb/decorators/collection.js +26 -0
- package/dist/mongodb/decorators/collection.js.map +1 -0
- package/dist/mongodb/decorators/index.d.ts +4 -0
- package/dist/mongodb/decorators/index.js +5 -0
- package/dist/mongodb/decorators/index.js.map +1 -0
- package/dist/mongodb/decorators/metadata.d.ts +21 -0
- package/dist/mongodb/decorators/metadata.js +29 -0
- package/dist/mongodb/decorators/metadata.js.map +1 -0
- package/dist/mongodb/decorators/register.d.ts +3 -0
- package/dist/mongodb/decorators/register.js +10 -0
- package/dist/mongodb/decorators/register.js.map +1 -0
- package/dist/mongodb/decorators/watch.d.ts +4 -0
- package/dist/mongodb/decorators/watch.js +10 -0
- package/dist/mongodb/decorators/watch.js.map +1 -0
- package/dist/mongodb/filters.d.ts +20 -0
- package/dist/mongodb/filters.js +40 -0
- package/dist/mongodb/filters.js.map +1 -0
- package/dist/mongodb/find-one-or-create.d.ts +4 -0
- package/dist/mongodb/find-one-or-create.js +16 -0
- package/dist/mongodb/find-one-or-create.js.map +1 -0
- package/dist/mongodb/index.d.ts +10 -0
- package/dist/mongodb/index.js +11 -0
- package/dist/mongodb/index.js.map +1 -0
- package/dist/mongodb/live/client.d.ts +52 -0
- package/dist/mongodb/live/client.js +266 -0
- package/dist/mongodb/live/client.js.map +1 -0
- package/dist/mongodb/live/engine.d.ts +55 -0
- package/dist/mongodb/live/engine.js +440 -0
- package/dist/mongodb/live/engine.js.map +1 -0
- package/dist/mongodb/live/index.d.ts +5 -0
- package/dist/mongodb/live/index.js +6 -0
- package/dist/mongodb/live/index.js.map +1 -0
- package/dist/mongodb/live/observer.d.ts +58 -0
- package/dist/mongodb/live/observer.js +246 -0
- package/dist/mongodb/live/observer.js.map +1 -0
- package/dist/mongodb/live/publication.d.ts +4 -0
- package/dist/mongodb/live/publication.js +30 -0
- package/dist/mongodb/live/publication.js.map +1 -0
- package/dist/mongodb/live/source.d.ts +55 -0
- package/dist/mongodb/live/source.js +197 -0
- package/dist/mongodb/live/source.js.map +1 -0
- package/dist/mongodb/live/types.d.ts +266 -0
- package/dist/mongodb/live/types.js +29 -0
- package/dist/mongodb/live/types.js.map +1 -0
- package/dist/mongodb/live/window.d.ts +7 -0
- package/dist/mongodb/live/window.js +93 -0
- package/dist/mongodb/live/window.js.map +1 -0
- package/dist/mongodb/registry.d.ts +35 -0
- package/dist/mongodb/registry.js +129 -0
- package/dist/mongodb/registry.js.map +1 -0
- package/dist/mongodb/schema.d.ts +16 -0
- package/dist/mongodb/schema.js +43 -0
- package/dist/mongodb/schema.js.map +1 -0
- package/dist/mongodb/timestamps.d.ts +17 -0
- package/dist/mongodb/timestamps.js +27 -0
- package/dist/mongodb/timestamps.js.map +1 -0
- package/dist/mongodb/types.d.ts +120 -0
- package/dist/mongodb/types.js +10 -0
- package/dist/mongodb/types.js.map +1 -0
- package/dist/react/components/client-provider.d.ts +8 -0
- package/dist/react/components/client-provider.js +23 -0
- package/dist/react/components/client-provider.js.map +1 -0
- package/dist/react/components/index.d.ts +1 -0
- package/dist/react/components/index.js +2 -0
- package/dist/react/components/index.js.map +1 -0
- package/dist/react/hooks/index.d.ts +13 -0
- package/dist/react/hooks/index.js +14 -0
- package/dist/react/hooks/index.js.map +1 -0
- package/dist/react/hooks/use-auth.d.ts +4 -0
- package/dist/react/hooks/use-auth.js +35 -0
- package/dist/react/hooks/use-auth.js.map +1 -0
- package/dist/react/hooks/use-caller.d.ts +5 -0
- package/dist/react/hooks/use-caller.js +13 -0
- package/dist/react/hooks/use-caller.js.map +1 -0
- package/dist/react/hooks/use-channel.d.ts +1 -0
- package/dist/react/hooks/use-channel.js +7 -0
- package/dist/react/hooks/use-channel.js.map +1 -0
- package/dist/react/hooks/use-circuit-breaker.d.ts +6 -0
- package/dist/react/hooks/use-circuit-breaker.js +16 -0
- package/dist/react/hooks/use-circuit-breaker.js.map +1 -0
- package/dist/react/hooks/use-client.d.ts +3 -0
- package/dist/react/hooks/use-client.js +13 -0
- package/dist/react/hooks/use-client.js.map +1 -0
- package/dist/react/hooks/use-connection-state.d.ts +13 -0
- package/dist/react/hooks/use-connection-state.js +55 -0
- package/dist/react/hooks/use-connection-state.js.map +1 -0
- package/dist/react/hooks/use-creation.d.ts +5 -0
- package/dist/react/hooks/use-creation.js +17 -0
- package/dist/react/hooks/use-creation.js.map +1 -0
- package/dist/react/hooks/use-deps-change.d.ts +1 -0
- package/dist/react/hooks/use-deps-change.js +11 -0
- package/dist/react/hooks/use-deps-change.js.map +1 -0
- package/dist/react/hooks/use-local-event.d.ts +13 -0
- package/dist/react/hooks/use-local-event.js +32 -0
- package/dist/react/hooks/use-local-event.js.map +1 -0
- package/dist/react/hooks/use-method-refresh.d.ts +15 -0
- package/dist/react/hooks/use-method-refresh.js +48 -0
- package/dist/react/hooks/use-method-refresh.js.map +1 -0
- package/dist/react/hooks/use-method.d.ts +26 -0
- package/dist/react/hooks/use-method.js +161 -0
- package/dist/react/hooks/use-method.js.map +1 -0
- package/dist/react/hooks/use-mongodb-live-publication.d.ts +13 -0
- package/dist/react/hooks/use-mongodb-live-publication.js +26 -0
- package/dist/react/hooks/use-mongodb-live-publication.js.map +1 -0
- package/dist/react/hooks/use-object.d.ts +2 -0
- package/dist/react/hooks/use-object.js +22 -0
- package/dist/react/hooks/use-object.js.map +1 -0
- package/dist/react/hooks/use-subscribe.d.ts +8 -0
- package/dist/react/hooks/use-subscribe.js +49 -0
- package/dist/react/hooks/use-subscribe.js.map +1 -0
- package/dist/react/hooks/use-throttled-events.d.ts +7 -0
- package/dist/react/hooks/use-throttled-events.js +11 -0
- package/dist/react/hooks/use-throttled-events.js.map +1 -0
- package/dist/react/hooks/use-token-refresh.d.ts +13 -0
- package/dist/react/hooks/use-token-refresh.js +40 -0
- package/dist/react/hooks/use-token-refresh.js.map +1 -0
- package/dist/react/index.d.ts +2 -0
- package/dist/react/index.js +3 -0
- package/dist/react/index.js.map +1 -0
- package/dist/server/client-node.d.ts +76 -0
- package/dist/server/client-node.js +159 -0
- package/dist/server/client-node.js.map +1 -0
- package/dist/server/create-method-proxy.d.ts +2 -0
- package/dist/server/create-method-proxy.js +16 -0
- package/dist/server/create-method-proxy.js.map +1 -0
- package/dist/server/decorators/cached.d.ts +37 -0
- package/dist/server/decorators/cached.js +65 -0
- package/dist/server/decorators/cached.js.map +1 -0
- package/dist/server/decorators/index.d.ts +14 -0
- package/dist/server/decorators/index.js +13 -0
- package/dist/server/decorators/index.js.map +1 -0
- package/dist/server/decorators/infer.d.ts +78 -0
- package/dist/server/decorators/infer.js +11 -0
- package/dist/server/decorators/infer.js.map +1 -0
- package/dist/server/decorators/metadata.d.ts +60 -0
- package/dist/server/decorators/metadata.js +77 -0
- package/dist/server/decorators/metadata.js.map +1 -0
- package/dist/server/decorators/method.d.ts +14 -0
- package/dist/server/decorators/method.js +25 -0
- package/dist/server/decorators/method.js.map +1 -0
- package/dist/server/decorators/namespace.d.ts +25 -0
- package/dist/server/decorators/namespace.js +34 -0
- package/dist/server/decorators/namespace.js.map +1 -0
- package/dist/server/decorators/protected.d.ts +36 -0
- package/dist/server/decorators/protected.js +61 -0
- package/dist/server/decorators/protected.js.map +1 -0
- package/dist/server/decorators/register.d.ts +25 -0
- package/dist/server/decorators/register.js +72 -0
- package/dist/server/decorators/register.js.map +1 -0
- package/dist/server/decorators/schema.d.ts +17 -0
- package/dist/server/decorators/schema.js +27 -0
- package/dist/server/decorators/schema.js.map +1 -0
- package/dist/server/decorators/use.d.ts +22 -0
- package/dist/server/decorators/use.js +32 -0
- package/dist/server/decorators/use.js.map +1 -0
- package/dist/server/default-methods.d.ts +8 -0
- package/dist/server/default-methods.js +8 -0
- package/dist/server/default-methods.js.map +1 -0
- package/dist/server/event.d.ts +42 -0
- package/dist/server/event.js +53 -0
- package/dist/server/event.js.map +1 -0
- package/dist/server/index.d.ts +10 -0
- package/dist/server/index.js +11 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/method.d.ts +95 -0
- package/dist/server/method.js +113 -0
- package/dist/server/method.js.map +1 -0
- package/dist/server/methods.d.ts +11 -0
- package/dist/server/methods.js +74 -0
- package/dist/server/methods.js.map +1 -0
- package/dist/server/request-types.d.ts +20 -0
- package/dist/server/request-types.js +8 -0
- package/dist/server/request-types.js.map +1 -0
- package/dist/server/room-registry.d.ts +28 -0
- package/dist/server/room-registry.js +83 -0
- package/dist/server/room-registry.js.map +1 -0
- package/dist/server/server-channel.d.ts +32 -0
- package/dist/server/server-channel.js +104 -0
- package/dist/server/server-channel.js.map +1 -0
- package/dist/server/server.d.ts +124 -0
- package/dist/server/server.js +243 -0
- package/dist/server/server.js.map +1 -0
- package/dist/server/transports/hono-rate-limit.d.ts +15 -0
- package/dist/server/transports/hono-rate-limit.js +36 -0
- package/dist/server/transports/hono-rate-limit.js.map +1 -0
- package/dist/server/transports/index.d.ts +4 -0
- package/dist/server/transports/index.js +5 -0
- package/dist/server/transports/index.js.map +1 -0
- package/dist/server/transports/node-hono-transport-contract.d.ts +16 -0
- package/dist/server/transports/node-hono-transport-contract.js +18 -0
- package/dist/server/transports/node-hono-transport-contract.js.map +1 -0
- package/dist/server/transports/node-hono-transport.d.ts +47 -0
- package/dist/server/transports/node-hono-transport.js +327 -0
- package/dist/server/transports/node-hono-transport.js.map +1 -0
- package/dist/server/transports/redis-transport.d.ts +34 -0
- package/dist/server/transports/redis-transport.js +84 -0
- package/dist/server/transports/redis-transport.js.map +1 -0
- package/dist/server/transports/websocket-transport.d.ts +42 -0
- package/dist/server/transports/websocket-transport.js +174 -0
- package/dist/server/transports/websocket-transport.js.map +1 -0
- package/dist/server/transports/ws-shared.d.ts +37 -0
- package/dist/server/transports/ws-shared.js +188 -0
- package/dist/server/transports/ws-shared.js.map +1 -0
- package/dist/server/typeferry-async-local-storage.d.ts +5 -0
- package/dist/server/typeferry-async-local-storage.js +6 -0
- package/dist/server/typeferry-async-local-storage.js.map +1 -0
- package/dist/server/types.d.ts +27 -0
- package/dist/server/types.js +11 -0
- package/dist/server/types.js.map +1 -0
- package/dist/utils/constants.d.ts +72 -0
- package/dist/utils/constants.js +79 -0
- package/dist/utils/constants.js.map +1 -0
- package/dist/utils/environment.d.ts +8 -0
- package/dist/utils/environment.js +17 -0
- package/dist/utils/environment.js.map +1 -0
- package/dist/utils/errors.d.ts +26 -0
- package/dist/utils/errors.js +35 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/event-emitter.d.ts +37 -0
- package/dist/utils/event-emitter.js +104 -0
- package/dist/utils/event-emitter.js.map +1 -0
- package/dist/utils/events.d.ts +7 -0
- package/dist/utils/events.js +23 -0
- package/dist/utils/events.js.map +1 -0
- package/dist/utils/helpers.d.ts +14 -0
- package/dist/utils/helpers.js +40 -0
- package/dist/utils/helpers.js.map +1 -0
- package/dist/utils/index.d.ts +11 -0
- package/dist/utils/index.js +12 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/intercept.d.ts +7 -0
- package/dist/utils/intercept.js +21 -0
- package/dist/utils/intercept.js.map +1 -0
- package/dist/utils/iterator.d.ts +9 -0
- package/dist/utils/iterator.js +28 -0
- package/dist/utils/iterator.js.map +1 -0
- package/dist/utils/lodash.d.ts +33 -0
- package/dist/utils/lodash.js +123 -0
- package/dist/utils/lodash.js.map +1 -0
- package/dist/utils/presentation.d.ts +19 -0
- package/dist/utils/presentation.js +25 -0
- package/dist/utils/presentation.js.map +1 -0
- package/dist/utils/promise.d.ts +6 -0
- package/dist/utils/promise.js +17 -0
- package/dist/utils/promise.js.map +1 -0
- package/dist/utils/protocol.d.ts +110 -0
- package/dist/utils/protocol.js +59 -0
- package/dist/utils/protocol.js.map +1 -0
- package/dist/utils/types.d.ts +23 -0
- package/dist/utils/types.js +2 -0
- package/dist/utils/types.js.map +1 -0
- package/package.json +187 -0
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
import type { Document, Filter, ObjectId } from 'mongodb';
|
|
2
|
+
import type { z } from 'zod';
|
|
3
|
+
import type { ClientNode } from '../../server/index.js';
|
|
4
|
+
import type { MongoCollectionToken } from '../types.js';
|
|
5
|
+
/** Reserved RPC used to create a connection-owned live subscription. */
|
|
6
|
+
export declare const MONGO_LIVE_SUBSCRIBE_METHOD: "mongo:live:subscribe";
|
|
7
|
+
/** Reserved RPC used to replace a stale live subscription snapshot. */
|
|
8
|
+
export declare const MONGO_LIVE_RESYNC_METHOD: "mongo:live:resync";
|
|
9
|
+
/** Reserved RPC used to stop a live subscription. */
|
|
10
|
+
export declare const MONGO_LIVE_UNSUBSCRIBE_METHOD: "mongo:live:unsubscribe";
|
|
11
|
+
/** Reserved event carrying live deltas and resynchronization controls. */
|
|
12
|
+
export declare const MONGO_LIVE_EVENT: "mongo:live:delta";
|
|
13
|
+
/** Client capability required before an ordered splice can be delivered. */
|
|
14
|
+
export declare const MONGO_LIVE_ORDERED_WINDOW_CAPABILITY: "ordered-window-splice-v1";
|
|
15
|
+
/** Client capability for collision-proof ObjectId materialization. */
|
|
16
|
+
export declare const MONGO_LIVE_TYPED_OBJECT_ID_CAPABILITY: "typed-object-id-v1";
|
|
17
|
+
/** Default maximum live subscriptions owned by one WebSocket connection. */
|
|
18
|
+
export declare const MONGO_LIVE_MAX_SUBSCRIPTIONS_PER_CONNECTION = 32;
|
|
19
|
+
/** Default maximum documents accepted in one initial snapshot. */
|
|
20
|
+
export declare const MONGO_LIVE_MAX_SNAPSHOT_DOCUMENTS = 10000;
|
|
21
|
+
/** Default native WebSocket queue size before a subscription becomes stale. */
|
|
22
|
+
export declare const MONGO_LIVE_MAX_BUFFERED_BYTES: number;
|
|
23
|
+
/** Time allowed for a slow consumer to recover before its socket is closed. */
|
|
24
|
+
export declare const MONGO_LIVE_SLOW_CONSUMER_GRACE_MS = 30000;
|
|
25
|
+
/** Delay between change-stream reconnect attempts. */
|
|
26
|
+
export declare const MONGO_LIVE_SOURCE_RETRY_MS = 250;
|
|
27
|
+
/** Default maximum number of documents skipped by an ordered window. */
|
|
28
|
+
export declare const MONGO_LIVE_MAX_WINDOW_SKIP = 100000;
|
|
29
|
+
/** MongoDB identifiers accepted by the server-side source. */
|
|
30
|
+
export type MongoLiveSourceId = ObjectId | string | number;
|
|
31
|
+
/** Collision-proof ObjectId representation produced on the client wire. */
|
|
32
|
+
export interface MongoLiveObjectId {
|
|
33
|
+
/** Canonical MongoDB ObjectId hexadecimal value. */
|
|
34
|
+
readonly $objectId: string;
|
|
35
|
+
}
|
|
36
|
+
/** Identifiers produced by TypeFerry EJSON on the client wire. */
|
|
37
|
+
export type MongoLiveId = MongoLiveObjectId | string | number;
|
|
38
|
+
/** Removes source identity from fields returned by a publication projector. */
|
|
39
|
+
export type MongoLiveProjectedFields<TFields extends object = object> = Readonly<Omit<TFields, '_id'>> & {
|
|
40
|
+
readonly _id?: never;
|
|
41
|
+
};
|
|
42
|
+
/** Client-visible live document with a source-owned stable identity. */
|
|
43
|
+
export type MongoLiveClientDocument<TFields extends object = object> = Readonly<{
|
|
44
|
+
_id: MongoLiveId;
|
|
45
|
+
} & Omit<TFields, '_id'>>;
|
|
46
|
+
declare const MONGO_LIVE_ARGS: unique symbol;
|
|
47
|
+
declare const MONGO_LIVE_DOCUMENT: unique symbol;
|
|
48
|
+
/** Serializable client contract for one named live publication. */
|
|
49
|
+
export interface MongoLivePublicationDescriptor<TName extends string, TArgs, TDocument extends {
|
|
50
|
+
readonly _id: MongoLiveId;
|
|
51
|
+
}> {
|
|
52
|
+
/** Server-registered publication name. */
|
|
53
|
+
readonly name: TName;
|
|
54
|
+
/** Phantom argument type used by client inference. */
|
|
55
|
+
readonly [MONGO_LIVE_ARGS]?: TArgs;
|
|
56
|
+
/** Phantom result type used by client inference. */
|
|
57
|
+
readonly [MONGO_LIVE_DOCUMENT]?: TDocument;
|
|
58
|
+
}
|
|
59
|
+
/** Extracts the argument type carried by a publication descriptor. */
|
|
60
|
+
export type MongoLiveArgsOf<TDescriptor> = TDescriptor extends MongoLivePublicationDescriptor<string, infer TArgs, {
|
|
61
|
+
readonly _id: MongoLiveId;
|
|
62
|
+
}> ? TArgs : never;
|
|
63
|
+
/** Extracts the client document type carried by a publication descriptor. */
|
|
64
|
+
export type MongoLiveDocumentOf<TDescriptor> = TDescriptor extends MongoLivePublicationDescriptor<string, unknown, infer TDocument> ? TDocument : never;
|
|
65
|
+
/** Creates a client-safe publication descriptor factory with inferred name. */
|
|
66
|
+
export declare function mongoLivePublication<TArgs, TDocument extends {
|
|
67
|
+
readonly _id: MongoLiveId;
|
|
68
|
+
}>(): <const TName extends string>(name: TName) => MongoLivePublicationDescriptor<TName, TArgs, TDocument>;
|
|
69
|
+
/** Connection context available only while authorizing a subscription. */
|
|
70
|
+
export interface MongoLiveAuthorizationContext {
|
|
71
|
+
/** Calling TypeFerry WebSocket node. */
|
|
72
|
+
readonly client: ClientNode;
|
|
73
|
+
/** Aborts when authorization or the owning connection is cancelled. */
|
|
74
|
+
readonly signal: AbortSignal;
|
|
75
|
+
}
|
|
76
|
+
/** Typed server implementation of a live publication. */
|
|
77
|
+
export interface MongoLivePublicationConfig<TArgs, TScope, TStoredDocument extends Document, TFields extends object> {
|
|
78
|
+
/** Decorated collection token queried by the publication. */
|
|
79
|
+
readonly collection: MongoCollectionToken<TStoredDocument>;
|
|
80
|
+
/** Runtime argument validator. */
|
|
81
|
+
readonly args: z.ZodType<TArgs>;
|
|
82
|
+
/** Authentication is required unless explicitly disabled. */
|
|
83
|
+
readonly protected?: boolean;
|
|
84
|
+
/** Authorizes the caller and returns detached immutable query scope. */
|
|
85
|
+
readonly authorize: (context: MongoLiveAuthorizationContext, args: TArgs) => TScope | Promise<TScope>;
|
|
86
|
+
/** Builds the authoritative MongoDB selector. */
|
|
87
|
+
readonly filter: (scope: TScope, args: TArgs) => Filter<TStoredDocument>;
|
|
88
|
+
/**
|
|
89
|
+
* Builds one bounded ordered window. Omit for unordered set semantics.
|
|
90
|
+
*
|
|
91
|
+
* The runtime appends `_id`; application code must not declare it.
|
|
92
|
+
*/
|
|
93
|
+
readonly window?: (scope: NoInfer<TScope>, args: NoInfer<TArgs>) => MongoLiveWindow<TStoredDocument>;
|
|
94
|
+
/** Projects stored data into client-visible fields without `_id`. */
|
|
95
|
+
readonly project: (document: TStoredDocument, scope: TScope) => MongoLiveProjectedFields<TFields> | Promise<MongoLiveProjectedFields<TFields>>;
|
|
96
|
+
}
|
|
97
|
+
/** Runtime-erased publication consumed by the live engine. */
|
|
98
|
+
export interface MongoLiveRuntimePublication {
|
|
99
|
+
/** Public publication name. */
|
|
100
|
+
readonly name: string;
|
|
101
|
+
/** Decorated collection token. */
|
|
102
|
+
readonly collection: MongoCollectionToken<Document>;
|
|
103
|
+
/** Whether the caller must be authenticated. */
|
|
104
|
+
readonly protected: boolean;
|
|
105
|
+
/** Parses untrusted RPC arguments. */
|
|
106
|
+
parseArgs(value: unknown): unknown;
|
|
107
|
+
/** Authorizes a caller and returns detached query scope. */
|
|
108
|
+
authorize(context: MongoLiveAuthorizationContext, args: unknown): Promise<unknown>;
|
|
109
|
+
/** Builds the MongoDB selector from validated state. */
|
|
110
|
+
filter(scope: unknown, args: unknown): Filter<Document>;
|
|
111
|
+
/** Builds the optional server-owned ordered window. */
|
|
112
|
+
window?(scope: unknown, args: unknown): MongoLiveWindowInput | null;
|
|
113
|
+
/** Projects one stored document and injects no identity. */
|
|
114
|
+
project(document: Document, scope: unknown): Promise<MongoLiveProjectedFields<object>>;
|
|
115
|
+
}
|
|
116
|
+
/** Server registration retaining its typed client descriptor. */
|
|
117
|
+
export interface MongoLivePublicationDefinition<TDescriptor extends MongoLivePublicationDescriptor<string, unknown, MongoLiveClientDocument>> extends MongoLiveRuntimePublication {
|
|
118
|
+
/** Client-safe descriptor corresponding to the server implementation. */
|
|
119
|
+
readonly descriptor: TDescriptor;
|
|
120
|
+
}
|
|
121
|
+
/** Untrusted request to start a live subscription. */
|
|
122
|
+
export interface MongoLiveSubscribeRequest {
|
|
123
|
+
/** Stable client-generated subscription identifier. */
|
|
124
|
+
readonly subscriptionId: string;
|
|
125
|
+
/** Registered publication name. */
|
|
126
|
+
readonly publication: string;
|
|
127
|
+
/** Publication-specific arguments validated by the server. */
|
|
128
|
+
readonly args: unknown;
|
|
129
|
+
/** Optional wire extensions understood by the subscribing client. */
|
|
130
|
+
readonly capabilities?: readonly string[];
|
|
131
|
+
}
|
|
132
|
+
/** Request to replace a stale subscription generation. */
|
|
133
|
+
export interface MongoLiveResyncRequest {
|
|
134
|
+
/** Existing connection-owned subscription identifier. */
|
|
135
|
+
readonly subscriptionId: string;
|
|
136
|
+
/** Generation observed by the requesting client. */
|
|
137
|
+
readonly staleGeneration: string;
|
|
138
|
+
}
|
|
139
|
+
/** Request to stop a connection-owned subscription. */
|
|
140
|
+
export interface MongoLiveUnsubscribeRequest {
|
|
141
|
+
/** Existing connection-owned subscription identifier. */
|
|
142
|
+
readonly subscriptionId: string;
|
|
143
|
+
}
|
|
144
|
+
/** Complete authoritative state returned by subscribe and resync RPCs. */
|
|
145
|
+
export interface MongoLiveSnapshot<TDocument extends MongoLiveClientDocument = MongoLiveClientDocument> {
|
|
146
|
+
/** Stable connection-owned subscription identifier. */
|
|
147
|
+
readonly subscriptionId: string;
|
|
148
|
+
/** Incarnation identifier replaced by every resnapshot. */
|
|
149
|
+
readonly generation: string;
|
|
150
|
+
/** Last sequence represented by the snapshot. */
|
|
151
|
+
readonly sequence: number;
|
|
152
|
+
/** Whether document order is part of the authoritative contract. */
|
|
153
|
+
readonly ordered?: boolean;
|
|
154
|
+
/** Complete authoritative result set or ordered window. */
|
|
155
|
+
readonly documents: readonly TDocument[];
|
|
156
|
+
}
|
|
157
|
+
/** Direction accepted for one ordered publication sort field. */
|
|
158
|
+
export type MongoLiveSortDirection = 1 | -1;
|
|
159
|
+
/** Top-level stored-document field accepted by an ordered publication. */
|
|
160
|
+
type MongoLiveDeclaredDocumentKeys<TDocument extends Document> = keyof {
|
|
161
|
+
[TKey in keyof TDocument as string extends TKey ? never : number extends TKey ? never : TKey]: TDocument[TKey];
|
|
162
|
+
};
|
|
163
|
+
/** Top-level stored-document field accepted by an ordered publication. */
|
|
164
|
+
export type MongoLiveSortField<TDocument extends Document> = Exclude<Extract<MongoLiveDeclaredDocumentKeys<TDocument>, string>, '_id'>;
|
|
165
|
+
/** Stable application sort owned by an ordered publication. */
|
|
166
|
+
export type MongoLiveSort<TDocument extends Document> = Readonly<Partial<Record<MongoLiveSortField<TDocument>, MongoLiveSortDirection>>> & {
|
|
167
|
+
readonly _id?: never;
|
|
168
|
+
};
|
|
169
|
+
/** Stable, bounded server-owned ordered MongoDB query window. */
|
|
170
|
+
export interface MongoLiveWindow<TDocument extends Document = Document> {
|
|
171
|
+
/** Non-empty top-level sort fields; the runtime appends `_id: 1`. */
|
|
172
|
+
readonly sort: MongoLiveSort<TDocument>;
|
|
173
|
+
/** Number of matching documents omitted before the visible window. */
|
|
174
|
+
readonly skip?: number;
|
|
175
|
+
/** Maximum number of visible documents. */
|
|
176
|
+
readonly limit: number;
|
|
177
|
+
}
|
|
178
|
+
/** Runtime-erased ordered-window input awaiting capacity validation. */
|
|
179
|
+
export interface MongoLiveWindowInput {
|
|
180
|
+
/** Application fields before the runtime identity tie-breaker. */
|
|
181
|
+
readonly sort: Readonly<Record<string, MongoLiveSortDirection>>;
|
|
182
|
+
/** Requested offset. */
|
|
183
|
+
readonly skip?: number;
|
|
184
|
+
/** Requested visible bound. */
|
|
185
|
+
readonly limit: number;
|
|
186
|
+
}
|
|
187
|
+
/** Runtime-erased and validated ordered window. */
|
|
188
|
+
export interface MongoLiveRuntimeWindow {
|
|
189
|
+
/** Unique application fields followed by the runtime `_id` tie-breaker. */
|
|
190
|
+
readonly sort: readonly (readonly [string, MongoLiveSortDirection])[];
|
|
191
|
+
/** Validated non-negative offset. */
|
|
192
|
+
readonly skip: number;
|
|
193
|
+
/** Validated positive bound. */
|
|
194
|
+
readonly limit: number;
|
|
195
|
+
}
|
|
196
|
+
/** Atomic ordered-window replacement operation. */
|
|
197
|
+
export interface MongoLiveWindowSpliceOperation<TDocument extends MongoLiveClientDocument = MongoLiveClientDocument> {
|
|
198
|
+
/** Positional operation discriminator. */
|
|
199
|
+
readonly type: 'window-splice';
|
|
200
|
+
/** Zero-based index in the current ordered array. */
|
|
201
|
+
readonly index: number;
|
|
202
|
+
/** Number of current documents removed at `index`. */
|
|
203
|
+
readonly deleteCount: number;
|
|
204
|
+
/** Authoritative replacement documents inserted at `index`. */
|
|
205
|
+
readonly documents: readonly TDocument[];
|
|
206
|
+
}
|
|
207
|
+
/** Semantic document operation following a snapshot. */
|
|
208
|
+
export type MongoLiveOperation<TDocument extends MongoLiveClientDocument = MongoLiveClientDocument> = {
|
|
209
|
+
readonly type: 'added';
|
|
210
|
+
readonly document: TDocument;
|
|
211
|
+
} | {
|
|
212
|
+
readonly type: 'changed';
|
|
213
|
+
readonly document: TDocument;
|
|
214
|
+
} | {
|
|
215
|
+
readonly type: 'removed';
|
|
216
|
+
readonly id: MongoLiveId;
|
|
217
|
+
} | MongoLiveWindowSpliceOperation<TDocument>;
|
|
218
|
+
/** Ordered operation batch for one subscription generation. */
|
|
219
|
+
export interface MongoLiveDelta<TDocument extends MongoLiveClientDocument = MongoLiveClientDocument> {
|
|
220
|
+
/** Discriminator for data messages. */
|
|
221
|
+
readonly type: 'delta';
|
|
222
|
+
/** Target subscription. */
|
|
223
|
+
readonly subscriptionId: string;
|
|
224
|
+
/** Target generation. */
|
|
225
|
+
readonly generation: string;
|
|
226
|
+
/** Monotonically increasing connection-local sequence. */
|
|
227
|
+
readonly sequence: number;
|
|
228
|
+
/** Semantic operations applied atomically by the client. */
|
|
229
|
+
readonly operations: readonly MongoLiveOperation<TDocument>[];
|
|
230
|
+
}
|
|
231
|
+
/** Control message requiring a complete authoritative replacement. */
|
|
232
|
+
export interface MongoLiveResyncRequired {
|
|
233
|
+
/** Discriminator for control messages. */
|
|
234
|
+
readonly type: 'resync-required';
|
|
235
|
+
/** Target subscription. */
|
|
236
|
+
readonly subscriptionId: string;
|
|
237
|
+
/** Generation that must no longer be treated as ready. */
|
|
238
|
+
readonly staleGeneration: string;
|
|
239
|
+
}
|
|
240
|
+
/** Payload carried by the reserved live event. */
|
|
241
|
+
export type MongoLiveEvent<TDocument extends MongoLiveClientDocument = MongoLiveClientDocument> = MongoLiveDelta<TDocument> | MongoLiveResyncRequired;
|
|
242
|
+
/** Runtime capacity and slow-consumer controls. */
|
|
243
|
+
export interface MongoLiveOptions {
|
|
244
|
+
/** Named server publications exposed by this registry. */
|
|
245
|
+
readonly publications: readonly MongoLiveRuntimePublication[];
|
|
246
|
+
/** Maximum subscriptions owned by one connection. */
|
|
247
|
+
readonly maxSubscriptionsPerConnection?: number;
|
|
248
|
+
/** Maximum documents accepted in one snapshot. */
|
|
249
|
+
readonly maxSnapshotDocuments?: number;
|
|
250
|
+
/** Maximum `skip` accepted from a server-owned ordered publication. */
|
|
251
|
+
readonly maxWindowSkip?: number;
|
|
252
|
+
/** Native WebSocket queue threshold before resync is required. */
|
|
253
|
+
readonly maxBufferedBytes?: number;
|
|
254
|
+
/** Slow-consumer recovery grace period. */
|
|
255
|
+
readonly slowConsumerGraceMs?: number;
|
|
256
|
+
}
|
|
257
|
+
/** Public client state for one live view. */
|
|
258
|
+
export interface MongoLiveViewSnapshot<TDocument extends MongoLiveClientDocument> {
|
|
259
|
+
/** Current lifecycle state. */
|
|
260
|
+
readonly status: 'connecting' | 'ready' | 'resyncing' | 'stopped' | 'error';
|
|
261
|
+
/** Complete immutable result set in authoritative order when configured. */
|
|
262
|
+
readonly documents: readonly TDocument[];
|
|
263
|
+
/** Current failure, when status is `error`. */
|
|
264
|
+
readonly error: Error | null;
|
|
265
|
+
}
|
|
266
|
+
export {};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/** Reserved RPC used to create a connection-owned live subscription. */
|
|
2
|
+
export const MONGO_LIVE_SUBSCRIBE_METHOD = 'mongo:live:subscribe';
|
|
3
|
+
/** Reserved RPC used to replace a stale live subscription snapshot. */
|
|
4
|
+
export const MONGO_LIVE_RESYNC_METHOD = 'mongo:live:resync';
|
|
5
|
+
/** Reserved RPC used to stop a live subscription. */
|
|
6
|
+
export const MONGO_LIVE_UNSUBSCRIBE_METHOD = 'mongo:live:unsubscribe';
|
|
7
|
+
/** Reserved event carrying live deltas and resynchronization controls. */
|
|
8
|
+
export const MONGO_LIVE_EVENT = 'mongo:live:delta';
|
|
9
|
+
/** Client capability required before an ordered splice can be delivered. */
|
|
10
|
+
export const MONGO_LIVE_ORDERED_WINDOW_CAPABILITY = 'ordered-window-splice-v1';
|
|
11
|
+
/** Client capability for collision-proof ObjectId materialization. */
|
|
12
|
+
export const MONGO_LIVE_TYPED_OBJECT_ID_CAPABILITY = 'typed-object-id-v1';
|
|
13
|
+
/** Default maximum live subscriptions owned by one WebSocket connection. */
|
|
14
|
+
export const MONGO_LIVE_MAX_SUBSCRIPTIONS_PER_CONNECTION = 32;
|
|
15
|
+
/** Default maximum documents accepted in one initial snapshot. */
|
|
16
|
+
export const MONGO_LIVE_MAX_SNAPSHOT_DOCUMENTS = 10_000;
|
|
17
|
+
/** Default native WebSocket queue size before a subscription becomes stale. */
|
|
18
|
+
export const MONGO_LIVE_MAX_BUFFERED_BYTES = 2 * 1024 * 1024;
|
|
19
|
+
/** Time allowed for a slow consumer to recover before its socket is closed. */
|
|
20
|
+
export const MONGO_LIVE_SLOW_CONSUMER_GRACE_MS = 30_000;
|
|
21
|
+
/** Delay between change-stream reconnect attempts. */
|
|
22
|
+
export const MONGO_LIVE_SOURCE_RETRY_MS = 250;
|
|
23
|
+
/** Default maximum number of documents skipped by an ordered window. */
|
|
24
|
+
export const MONGO_LIVE_MAX_WINDOW_SKIP = 100_000;
|
|
25
|
+
/** Creates a client-safe publication descriptor factory with inferred name. */
|
|
26
|
+
export function mongoLivePublication() {
|
|
27
|
+
return (name) => ({ name });
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/mongodb/live/types.ts"],"names":[],"mappings":"AAUA,wEAAwE;AACxE,MAAM,CAAC,MAAM,2BAA2B,GAAG,sBAA+B,CAAA;AAE1E,uEAAuE;AACvE,MAAM,CAAC,MAAM,wBAAwB,GAAG,mBAA4B,CAAA;AAEpE,qDAAqD;AACrD,MAAM,CAAC,MAAM,6BAA6B,GAAG,wBAAiC,CAAA;AAE9E,0EAA0E;AAC1E,MAAM,CAAC,MAAM,gBAAgB,GAAG,kBAA2B,CAAA;AAE3D,4EAA4E;AAC5E,MAAM,CAAC,MAAM,oCAAoC,GAC/C,0BAAmC,CAAA;AAErC,sEAAsE;AACtE,MAAM,CAAC,MAAM,qCAAqC,GAChD,oBAA6B,CAAA;AAE/B,4EAA4E;AAC5E,MAAM,CAAC,MAAM,2CAA2C,GAAG,EAAE,CAAA;AAE7D,kEAAkE;AAClE,MAAM,CAAC,MAAM,iCAAiC,GAAG,MAAM,CAAA;AAEvD,+EAA+E;AAC/E,MAAM,CAAC,MAAM,6BAA6B,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,CAAA;AAE5D,+EAA+E;AAC/E,MAAM,CAAC,MAAM,iCAAiC,GAAG,MAAM,CAAA;AAEvD,sDAAsD;AACtD,MAAM,CAAC,MAAM,0BAA0B,GAAG,GAAG,CAAA;AAE7C,wEAAwE;AACxE,MAAM,CAAC,MAAM,0BAA0B,GAAG,OAAO,CAAA;AAoDjD,+EAA+E;AAC/E,MAAM,UAAU,oBAAoB;IAMlC,OAAO,CACL,IAAW,EAC8C,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAA;AAC1E,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type MongoLiveClientDocument, type MongoLiveRuntimeWindow, type MongoLiveWindowInput, type MongoLiveWindowSpliceOperation } from './types.js';
|
|
2
|
+
/** Validates and normalizes one server-owned ordered window. */
|
|
3
|
+
export declare function normalizeMongoLiveWindow(window: MongoLiveWindowInput, maxDocuments: number, maxSkip: number): MongoLiveRuntimeWindow;
|
|
4
|
+
/** Derives one atomic splice between two authoritative ordered windows. */
|
|
5
|
+
export declare function createMongoLiveWindowSplice<TDocument extends MongoLiveClientDocument>(previous: readonly TDocument[], current: readonly TDocument[]): MongoLiveWindowSpliceOperation<TDocument> | null;
|
|
6
|
+
/** Applies one splice after validating indices and unique materialized identity. */
|
|
7
|
+
export declare function applyMongoLiveWindowSplice<TDocument extends MongoLiveClientDocument>(previous: readonly TDocument[], operation: MongoLiveWindowSpliceOperation<TDocument>): readonly TDocument[] | null;
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { EJSON } from '../../ejson/index.js';
|
|
2
|
+
import {} from './types.js';
|
|
3
|
+
/** Validates and normalizes one server-owned ordered window. */
|
|
4
|
+
export function normalizeMongoLiveWindow(window, maxDocuments, maxSkip) {
|
|
5
|
+
const entries = Object.entries(window.sort);
|
|
6
|
+
if (entries.length === 0) {
|
|
7
|
+
throw new Error('MongoDB live ordered windows require at least one sort field.');
|
|
8
|
+
}
|
|
9
|
+
if (!Number.isSafeInteger(window.limit) || window.limit < 1) {
|
|
10
|
+
throw new Error('MongoDB live ordered window "limit" must be a positive integer.');
|
|
11
|
+
}
|
|
12
|
+
if (window.limit > maxDocuments) {
|
|
13
|
+
throw new Error(`MongoDB live ordered window "limit" exceeds ${maxDocuments} documents.`);
|
|
14
|
+
}
|
|
15
|
+
const skip = window.skip ?? 0;
|
|
16
|
+
if (!Number.isSafeInteger(skip) || skip < 0) {
|
|
17
|
+
throw new Error('MongoDB live ordered window "skip" must be a non-negative integer.');
|
|
18
|
+
}
|
|
19
|
+
if (skip > maxSkip) {
|
|
20
|
+
throw new Error(`MongoDB live ordered window "skip" exceeds ${maxSkip} documents.`);
|
|
21
|
+
}
|
|
22
|
+
const fields = new Set();
|
|
23
|
+
const sort = [];
|
|
24
|
+
for (const [field, direction] of entries) {
|
|
25
|
+
if (typeof field !== 'string' ||
|
|
26
|
+
field.length === 0 ||
|
|
27
|
+
field === '_id' ||
|
|
28
|
+
field.startsWith('$') ||
|
|
29
|
+
field.includes('.')) {
|
|
30
|
+
throw new Error('MongoDB live ordered window sort fields must be unique top-level fields other than "_id".');
|
|
31
|
+
}
|
|
32
|
+
if (fields.has(field)) {
|
|
33
|
+
throw new Error(`MongoDB live ordered window sort field "${field}" is duplicated.`);
|
|
34
|
+
}
|
|
35
|
+
if (direction !== 1 && direction !== -1) {
|
|
36
|
+
throw new Error(`MongoDB live ordered window sort direction for "${field}" must be 1 or -1.`);
|
|
37
|
+
}
|
|
38
|
+
fields.add(field);
|
|
39
|
+
sort.push([field, direction]);
|
|
40
|
+
}
|
|
41
|
+
sort.push(['_id', 1]);
|
|
42
|
+
return { sort, skip, limit: window.limit };
|
|
43
|
+
}
|
|
44
|
+
/** Derives one atomic splice between two authoritative ordered windows. */
|
|
45
|
+
export function createMongoLiveWindowSplice(previous, current) {
|
|
46
|
+
let prefix = 0;
|
|
47
|
+
while (prefix < previous.length &&
|
|
48
|
+
prefix < current.length &&
|
|
49
|
+
EJSON.equals(previous[prefix], current[prefix])) {
|
|
50
|
+
prefix += 1;
|
|
51
|
+
}
|
|
52
|
+
if (prefix === previous.length && prefix === current.length)
|
|
53
|
+
return null;
|
|
54
|
+
let suffix = 0;
|
|
55
|
+
while (suffix < previous.length - prefix &&
|
|
56
|
+
suffix < current.length - prefix &&
|
|
57
|
+
EJSON.equals(previous[previous.length - 1 - suffix], current[current.length - 1 - suffix])) {
|
|
58
|
+
suffix += 1;
|
|
59
|
+
}
|
|
60
|
+
const operation = {
|
|
61
|
+
type: 'window-splice',
|
|
62
|
+
index: prefix,
|
|
63
|
+
deleteCount: previous.length - prefix - suffix,
|
|
64
|
+
documents: current.slice(prefix, current.length - suffix),
|
|
65
|
+
};
|
|
66
|
+
const applied = applyMongoLiveWindowSplice(previous, operation);
|
|
67
|
+
if (!applied || !EJSON.equals(applied, current)) {
|
|
68
|
+
throw new Error('MongoDB live ordered window splice invariant failed.');
|
|
69
|
+
}
|
|
70
|
+
return operation;
|
|
71
|
+
}
|
|
72
|
+
/** Applies one splice after validating indices and unique materialized identity. */
|
|
73
|
+
export function applyMongoLiveWindowSplice(previous, operation) {
|
|
74
|
+
if (!Number.isSafeInteger(operation.index) ||
|
|
75
|
+
!Number.isSafeInteger(operation.deleteCount) ||
|
|
76
|
+
operation.index < 0 ||
|
|
77
|
+
operation.deleteCount < 0 ||
|
|
78
|
+
operation.index > previous.length ||
|
|
79
|
+
operation.index + operation.deleteCount > previous.length) {
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
const current = [...previous];
|
|
83
|
+
current.splice(operation.index, operation.deleteCount, ...operation.documents);
|
|
84
|
+
const identities = new Set();
|
|
85
|
+
for (const document of current) {
|
|
86
|
+
const identity = EJSON.stringify(document._id, { canonical: true });
|
|
87
|
+
if (identities.has(identity))
|
|
88
|
+
return null;
|
|
89
|
+
identities.add(identity);
|
|
90
|
+
}
|
|
91
|
+
return current;
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=window.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"window.js","sourceRoot":"","sources":["../../../src/mongodb/live/window.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { Collection, Db, Document, MongoClient } from 'mongodb';
|
|
2
|
+
import type { TypeFerryMongo, TypeFerryMongoOptions, MongoCollectionClass, MongoCollectionDefinition, MongoCollectionTarget, MongoCollectionToken, MongoDocumentOf } from './types.js';
|
|
3
|
+
/** Extracts a decorated collection class from a raw class or typed token. */
|
|
4
|
+
export declare function mongoCollectionClass(target: MongoCollectionTarget): MongoCollectionClass;
|
|
5
|
+
/** Runtime registry for decorated MongoDB collections and native driver handles. */
|
|
6
|
+
export declare class TypeFerryMongoRegistry implements TypeFerryMongo {
|
|
7
|
+
/** Native database handle used by registered collections. */
|
|
8
|
+
readonly db: Db;
|
|
9
|
+
/** Native client when one is known; `null` when constructed from an external `Db`. */
|
|
10
|
+
readonly client: MongoClient | null;
|
|
11
|
+
private readonly closeClient;
|
|
12
|
+
private readonly definitions;
|
|
13
|
+
private readonly collections;
|
|
14
|
+
private readonly watchHandles;
|
|
15
|
+
private readonly liveEngine;
|
|
16
|
+
/** Creates a registry from resolved MongoDB handles. */
|
|
17
|
+
constructor(options: TypeFerryMongoOptions, connection: {
|
|
18
|
+
readonly db: Db;
|
|
19
|
+
readonly client: MongoClient | null;
|
|
20
|
+
readonly ownsClient: boolean;
|
|
21
|
+
});
|
|
22
|
+
/** Returns a native driver collection inferred from a typed collection token. */
|
|
23
|
+
collection<TToken extends MongoCollectionToken<Document>>(token: TToken): Collection<MongoDocumentOf<TToken>>;
|
|
24
|
+
/** Returns a native driver collection by name when no typed token is available. */
|
|
25
|
+
collectionByName<TDocument extends Document = Document>(name: string): Collection<TDocument>;
|
|
26
|
+
/** Returns decorator metadata for a registered collection. */
|
|
27
|
+
meta(target: MongoCollectionTarget): MongoCollectionDefinition;
|
|
28
|
+
/** Creates all declared indexes without dropping or reconciling existing indexes. */
|
|
29
|
+
ensureIndexes(): Promise<void>;
|
|
30
|
+
/** Closes change streams and the owned MongoDB client when applicable. */
|
|
31
|
+
close(): Promise<void>;
|
|
32
|
+
private startWatches;
|
|
33
|
+
}
|
|
34
|
+
/** Creates a TypeFerry MongoDB registry around native MongoDB driver handles. */
|
|
35
|
+
export declare function createTypeFerryMongo(options: TypeFerryMongoOptions): Promise<TypeFerryMongo>;
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { startMongoWatch } from './change-streams.js';
|
|
2
|
+
import { resolveMongoConnection } from './client.js';
|
|
3
|
+
import { getMongoCollectionDefinition } from './decorators/index.js';
|
|
4
|
+
import { MongoLiveEngine } from './live/engine.js';
|
|
5
|
+
/** Extracts a decorated collection class from a raw class or typed token. */
|
|
6
|
+
export function mongoCollectionClass(target) {
|
|
7
|
+
return 'Class' in target ? target.Class : target;
|
|
8
|
+
}
|
|
9
|
+
/** Runtime registry for decorated MongoDB collections and native driver handles. */
|
|
10
|
+
export class TypeFerryMongoRegistry {
|
|
11
|
+
/** Native database handle used by registered collections. */
|
|
12
|
+
db;
|
|
13
|
+
/** Native client when one is known; `null` when constructed from an external `Db`. */
|
|
14
|
+
client;
|
|
15
|
+
closeClient;
|
|
16
|
+
definitions = new Map();
|
|
17
|
+
collections = new Map();
|
|
18
|
+
watchHandles = [];
|
|
19
|
+
liveEngine;
|
|
20
|
+
/** Creates a registry from resolved MongoDB handles. */
|
|
21
|
+
constructor(options, connection) {
|
|
22
|
+
this.db = connection.db;
|
|
23
|
+
this.client = connection.client;
|
|
24
|
+
this.closeClient = connection.ownsClient || Boolean(options.closeExternalClient);
|
|
25
|
+
for (const target of options.collections) {
|
|
26
|
+
const Class = mongoCollectionClass(target);
|
|
27
|
+
const definition = getMongoCollectionDefinition(Class);
|
|
28
|
+
this.definitions.set(Class, definition);
|
|
29
|
+
this.collections.set(definition.name, this.db.collection(definition.name));
|
|
30
|
+
}
|
|
31
|
+
if (options.live && !options.server) {
|
|
32
|
+
throw new Error('MongoDB live publications require a TypeFerry server.');
|
|
33
|
+
}
|
|
34
|
+
if (options.live) {
|
|
35
|
+
for (const publication of options.live.publications) {
|
|
36
|
+
this.meta(publication.collection);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
this.liveEngine =
|
|
40
|
+
options.server && options.live
|
|
41
|
+
? new MongoLiveEngine({
|
|
42
|
+
server: options.server,
|
|
43
|
+
options: options.live,
|
|
44
|
+
resolveCollection: publication => this.collection(publication.collection),
|
|
45
|
+
collectionName: publication => this.meta(publication.collection).name,
|
|
46
|
+
})
|
|
47
|
+
: null;
|
|
48
|
+
if (options.server) {
|
|
49
|
+
this.startWatches(options);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
/** Returns a native driver collection inferred from a typed collection token. */
|
|
53
|
+
collection(token) {
|
|
54
|
+
const definition = this.meta(token);
|
|
55
|
+
return this.collectionByName(definition.name);
|
|
56
|
+
}
|
|
57
|
+
/** Returns a native driver collection by name when no typed token is available. */
|
|
58
|
+
collectionByName(name) {
|
|
59
|
+
const registered = this.collections.get(name);
|
|
60
|
+
if (registered)
|
|
61
|
+
return registered;
|
|
62
|
+
return this.db.collection(name);
|
|
63
|
+
}
|
|
64
|
+
/** Returns decorator metadata for a registered collection. */
|
|
65
|
+
meta(target) {
|
|
66
|
+
const Class = mongoCollectionClass(target);
|
|
67
|
+
const definition = this.definitions.get(Class);
|
|
68
|
+
if (!definition) {
|
|
69
|
+
throw new Error(`MongoDB collection "${Class.name}" is not registered.`);
|
|
70
|
+
}
|
|
71
|
+
return definition;
|
|
72
|
+
}
|
|
73
|
+
/** Creates all declared indexes without dropping or reconciling existing indexes. */
|
|
74
|
+
async ensureIndexes() {
|
|
75
|
+
for (const definition of this.definitions.values()) {
|
|
76
|
+
const collection = this.collectionByName(definition.name);
|
|
77
|
+
for (const index of definition.indexes) {
|
|
78
|
+
await collection.createIndex(index.spec, index.options);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/** Closes change streams and the owned MongoDB client when applicable. */
|
|
83
|
+
async close() {
|
|
84
|
+
await this.liveEngine?.close();
|
|
85
|
+
await Promise.all(this.watchHandles.map(handle => handle.close()));
|
|
86
|
+
this.watchHandles.length = 0;
|
|
87
|
+
if (this.closeClient) {
|
|
88
|
+
await this.client?.close();
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
startWatches(options) {
|
|
92
|
+
const server = options.server;
|
|
93
|
+
if (!server)
|
|
94
|
+
return;
|
|
95
|
+
for (const definition of this.definitions.values()) {
|
|
96
|
+
const collection = this.collectionByName(definition.name);
|
|
97
|
+
for (const watch of definition.watches) {
|
|
98
|
+
this.watchHandles.push(startMongoWatch({
|
|
99
|
+
collection,
|
|
100
|
+
definition,
|
|
101
|
+
watch,
|
|
102
|
+
server,
|
|
103
|
+
}));
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
/** Creates a TypeFerry MongoDB registry around native MongoDB driver handles. */
|
|
109
|
+
export async function createTypeFerryMongo(options) {
|
|
110
|
+
const connection = await resolveMongoConnection(options);
|
|
111
|
+
let registry = null;
|
|
112
|
+
try {
|
|
113
|
+
registry = new TypeFerryMongoRegistry(options, connection);
|
|
114
|
+
if (options.ensureIndexes) {
|
|
115
|
+
await registry.ensureIndexes();
|
|
116
|
+
}
|
|
117
|
+
return registry;
|
|
118
|
+
}
|
|
119
|
+
catch (error) {
|
|
120
|
+
if (registry) {
|
|
121
|
+
await registry.close();
|
|
122
|
+
}
|
|
123
|
+
else if (connection.ownsClient) {
|
|
124
|
+
await connection.client?.close();
|
|
125
|
+
}
|
|
126
|
+
throw error;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/mongodb/registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { ObjectId, type Document } from 'mongodb';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
/** Zod schema that accepts only native MongoDB `ObjectId` values. */
|
|
4
|
+
export declare function objectId(): z.ZodType<ObjectId>;
|
|
5
|
+
/** Zod schema that coerces valid hex strings into native MongoDB `ObjectId`s. */
|
|
6
|
+
export declare function coerceObjectId(): z.ZodType<ObjectId>;
|
|
7
|
+
/** Converts a hex string or native `ObjectId` into a native `ObjectId`. */
|
|
8
|
+
export declare function toObjectId(value: string | ObjectId): ObjectId;
|
|
9
|
+
/** Converts a hex string or native `ObjectId` into a stable lowercase hex id. */
|
|
10
|
+
export declare function objectIdHex(value: string | ObjectId): string;
|
|
11
|
+
/** Parses an insert document through an explicit Zod schema. */
|
|
12
|
+
export declare function parseInsert<TDocument extends Document>(schema: z.ZodType<TDocument>, value: unknown): TDocument;
|
|
13
|
+
/** Parses a replacement document through an explicit Zod schema. */
|
|
14
|
+
export declare function parseReplacement<TDocument extends Document>(schema: z.ZodType<TDocument>, value: unknown): TDocument;
|
|
15
|
+
/** Parses a `$set` payload through an explicit Zod schema for that payload. */
|
|
16
|
+
export declare function parseSet<TSet extends Document>(schema: z.ZodType<TSet>, value: unknown): TSet;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { ObjectId } from 'mongodb';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
/** Zod schema that accepts only native MongoDB `ObjectId` values. */
|
|
4
|
+
export function objectId() {
|
|
5
|
+
return z.custom((value) => value instanceof ObjectId, 'Expected MongoDB ObjectId');
|
|
6
|
+
}
|
|
7
|
+
/** Zod schema that coerces valid hex strings into native MongoDB `ObjectId`s. */
|
|
8
|
+
export function coerceObjectId() {
|
|
9
|
+
return z.preprocess(value => {
|
|
10
|
+
if (value instanceof ObjectId)
|
|
11
|
+
return value;
|
|
12
|
+
if (typeof value === 'string' && ObjectId.isValid(value)) {
|
|
13
|
+
return new ObjectId(value);
|
|
14
|
+
}
|
|
15
|
+
return value;
|
|
16
|
+
}, objectId());
|
|
17
|
+
}
|
|
18
|
+
/** Converts a hex string or native `ObjectId` into a native `ObjectId`. */
|
|
19
|
+
export function toObjectId(value) {
|
|
20
|
+
if (value instanceof ObjectId)
|
|
21
|
+
return value;
|
|
22
|
+
if (!ObjectId.isValid(value)) {
|
|
23
|
+
throw new Error(`Invalid MongoDB ObjectId "${value}".`);
|
|
24
|
+
}
|
|
25
|
+
return new ObjectId(value);
|
|
26
|
+
}
|
|
27
|
+
/** Converts a hex string or native `ObjectId` into a stable lowercase hex id. */
|
|
28
|
+
export function objectIdHex(value) {
|
|
29
|
+
return toObjectId(value).toHexString();
|
|
30
|
+
}
|
|
31
|
+
/** Parses an insert document through an explicit Zod schema. */
|
|
32
|
+
export function parseInsert(schema, value) {
|
|
33
|
+
return schema.parse(value);
|
|
34
|
+
}
|
|
35
|
+
/** Parses a replacement document through an explicit Zod schema. */
|
|
36
|
+
export function parseReplacement(schema, value) {
|
|
37
|
+
return schema.parse(value);
|
|
38
|
+
}
|
|
39
|
+
/** Parses a `$set` payload through an explicit Zod schema for that payload. */
|
|
40
|
+
export function parseSet(schema, value) {
|
|
41
|
+
return schema.parse(value);
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/mongodb/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAiB,MAAM,SAAS,CAAA;AACjD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,qEAAqE;AACrE,MAAM,UAAU,QAAQ;IACtB,OAAO,CAAC,CAAC,MAAM,CACb,CAAC,KAAK,EAAqB,EAAE,CAAC,KAAK,YAAY,QAAQ,EACvD,2BAA2B,CAC5B,CAAA;AACH,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,cAAc;IAC5B,OAAO,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE;QAC1B,IAAI,KAAK,YAAY,QAAQ;YAAE,OAAO,KAAK,CAAA;QAC3C,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACzD,OAAO,IAAI,QAAQ,CAAC,KAAK,CAAC,CAAA;QAC5B,CAAC;QACD,OAAO,KAAK,CAAA;IACd,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAA;AAChB,CAAC;AAED,2EAA2E;AAC3E,MAAM,UAAU,UAAU,CAAC,KAAwB;IACjD,IAAI,KAAK,YAAY,QAAQ;QAAE,OAAO,KAAK,CAAA;IAC3C,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,6BAA6B,KAAK,IAAI,CAAC,CAAA;IACzD,CAAC;IACD,OAAO,IAAI,QAAQ,CAAC,KAAK,CAAC,CAAA;AAC5B,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,WAAW,CAAC,KAAwB;IAClD,OAAO,UAAU,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,CAAA;AACxC,CAAC;AAED,gEAAgE;AAChE,MAAM,UAAU,WAAW,CACzB,MAA4B,EAC5B,KAAc;IAEd,OAAO,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;AAC5B,CAAC;AAED,oEAAoE;AACpE,MAAM,UAAU,gBAAgB,CAC9B,MAA4B,EAC5B,KAAc;IAEd,OAAO,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;AAC5B,CAAC;AAED,+EAA+E;AAC/E,MAAM,UAAU,QAAQ,CACtB,MAAuB,EACvB,KAAc;IAEd,OAAO,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;AAC5B,CAAC"}
|