@gaganref/confect-server 0.0.0-stage → 10.3.1-fork.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 +2119 -0
- package/LICENSE +7 -0
- package/README.md +16 -2
- package/dist/ActionCtx.d.ts +10 -0
- package/dist/ActionCtx.d.ts.map +1 -0
- package/dist/ActionCtx.js +18 -0
- package/dist/ActionCtx.js.map +1 -0
- package/dist/ActionRunner.d.ts +16 -0
- package/dist/ActionRunner.d.ts.map +1 -0
- package/dist/ActionRunner.js +18 -0
- package/dist/ActionRunner.js.map +1 -0
- package/dist/AiGatewayDecisionClient.d.ts +20 -0
- package/dist/AiGatewayDecisionClient.d.ts.map +1 -0
- package/dist/AiGatewayDecisionClient.js +31 -0
- package/dist/AiGatewayDecisionClient.js.map +1 -0
- package/dist/AiGatewayDecisionModel.d.ts +24 -0
- package/dist/AiGatewayDecisionModel.d.ts.map +1 -0
- package/dist/AiGatewayDecisionModel.js +27 -0
- package/dist/AiGatewayDecisionModel.js.map +1 -0
- package/dist/AiGatewayLanguageClient.d.ts +21 -0
- package/dist/AiGatewayLanguageClient.d.ts.map +1 -0
- package/dist/AiGatewayLanguageClient.js +32 -0
- package/dist/AiGatewayLanguageClient.js.map +1 -0
- package/dist/AiGatewayLanguageModel.d.ts +95 -0
- package/dist/AiGatewayLanguageModel.d.ts.map +1 -0
- package/dist/AiGatewayLanguageModel.js +42 -0
- package/dist/AiGatewayLanguageModel.js.map +1 -0
- package/dist/Auth.d.ts +20 -0
- package/dist/Auth.d.ts.map +1 -0
- package/dist/Auth.js +31 -0
- package/dist/Auth.js.map +1 -0
- package/dist/BlobNotFoundError.d.ts +9 -0
- package/dist/BlobNotFoundError.d.ts.map +1 -0
- package/dist/BlobNotFoundError.js +13 -0
- package/dist/BlobNotFoundError.js.map +1 -0
- package/dist/Callback.d.ts +31 -0
- package/dist/Callback.d.ts.map +1 -0
- package/dist/Callback.js +182 -0
- package/dist/Callback.js.map +1 -0
- package/dist/ComponentCtx.d.ts +71 -0
- package/dist/ComponentCtx.d.ts.map +1 -0
- package/dist/ComponentCtx.js +0 -0
- package/dist/ConvexConfigProvider.d.ts +21 -0
- package/dist/ConvexConfigProvider.d.ts.map +1 -0
- package/dist/ConvexConfigProvider.js +36 -0
- package/dist/ConvexConfigProvider.js.map +1 -0
- package/dist/ConvexFunctionDefinitions.d.ts +25 -0
- package/dist/ConvexFunctionDefinitions.d.ts.map +1 -0
- package/dist/ConvexFunctionDefinitions.js +25 -0
- package/dist/ConvexFunctionDefinitions.js.map +1 -0
- package/dist/ConvexLogger.d.ts +17 -0
- package/dist/ConvexLogger.d.ts.map +1 -0
- package/dist/ConvexLogger.js +33 -0
- package/dist/ConvexLogger.js.map +1 -0
- package/dist/CronJob.d.ts +14 -0
- package/dist/CronJob.d.ts.map +1 -0
- package/dist/CronJob.js +22 -0
- package/dist/CronJob.js.map +1 -0
- package/dist/CronJobs.d.ts +22 -0
- package/dist/CronJobs.d.ts.map +1 -0
- package/dist/CronJobs.js +83 -0
- package/dist/CronJobs.js.map +1 -0
- package/dist/DataModel.d.ts +28 -0
- package/dist/DataModel.d.ts.map +1 -0
- package/dist/DataModel.js +7 -0
- package/dist/DataModel.js.map +1 -0
- package/dist/DatabaseReader.d.ts +26 -0
- package/dist/DatabaseReader.d.ts.map +1 -0
- package/dist/DatabaseReader.js +33 -0
- package/dist/DatabaseReader.js.map +1 -0
- package/dist/DatabaseSchema.d.ts +67 -0
- package/dist/DatabaseSchema.d.ts.map +1 -0
- package/dist/DatabaseSchema.js +61 -0
- package/dist/DatabaseSchema.js.map +1 -0
- package/dist/DatabaseWriter.d.ts +44 -0
- package/dist/DatabaseWriter.d.ts.map +1 -0
- package/dist/DatabaseWriter.js +47 -0
- package/dist/DatabaseWriter.js.map +1 -0
- package/dist/Document.d.ts +37 -0
- package/dist/Document.d.ts.map +1 -0
- package/dist/Document.js +54 -0
- package/dist/Document.js.map +1 -0
- package/dist/ExecutionMetadata.d.ts +13 -0
- package/dist/ExecutionMetadata.d.ts.map +1 -0
- package/dist/ExecutionMetadata.js +19 -0
- package/dist/ExecutionMetadata.js.map +1 -0
- package/dist/FunctionImpl.d.ts +39 -0
- package/dist/FunctionImpl.d.ts.map +1 -0
- package/dist/FunctionImpl.js +46 -0
- package/dist/FunctionImpl.js.map +1 -0
- package/dist/FunctionRegistryItem.d.ts +36 -0
- package/dist/FunctionRegistryItem.d.ts.map +1 -0
- package/dist/FunctionRegistryItem.js +34 -0
- package/dist/FunctionRegistryItem.js.map +1 -0
- package/dist/GroupImpl.d.ts +77 -0
- package/dist/GroupImpl.d.ts.map +1 -0
- package/dist/GroupImpl.js +81 -0
- package/dist/GroupImpl.js.map +1 -0
- package/dist/GroupRegistry.d.ts +8 -0
- package/dist/GroupRegistry.d.ts.map +1 -0
- package/dist/GroupRegistry.js +26 -0
- package/dist/GroupRegistry.js.map +1 -0
- package/dist/Handler.d.ts +47 -0
- package/dist/Handler.d.ts.map +1 -0
- package/dist/Handler.js +7 -0
- package/dist/Handler.js.map +1 -0
- package/dist/HttpRouter.d.ts +80 -0
- package/dist/HttpRouter.d.ts.map +1 -0
- package/dist/HttpRouter.js +195 -0
- package/dist/HttpRouter.js.map +1 -0
- package/dist/MiddlewareImpl.d.ts +79 -0
- package/dist/MiddlewareImpl.d.ts.map +1 -0
- package/dist/MiddlewareImpl.js +58 -0
- package/dist/MiddlewareImpl.js.map +1 -0
- package/dist/MiddlewareRegistryItem.d.ts +12 -0
- package/dist/MiddlewareRegistryItem.d.ts.map +1 -0
- package/dist/MiddlewareRegistryItem.js +15 -0
- package/dist/MiddlewareRegistryItem.js.map +1 -0
- package/dist/MutationCtx.d.ts +10 -0
- package/dist/MutationCtx.d.ts.map +1 -0
- package/dist/MutationCtx.js +18 -0
- package/dist/MutationCtx.js.map +1 -0
- package/dist/MutationRunner.d.ts +27 -0
- package/dist/MutationRunner.d.ts.map +1 -0
- package/dist/MutationRunner.js +28 -0
- package/dist/MutationRunner.js.map +1 -0
- package/dist/MutationTransactionContext.d.ts +17 -0
- package/dist/MutationTransactionContext.d.ts.map +1 -0
- package/dist/MutationTransactionContext.js +20 -0
- package/dist/MutationTransactionContext.js.map +1 -0
- package/dist/OrderedQuery.d.ts +32 -0
- package/dist/OrderedQuery.d.ts.map +1 -0
- package/dist/OrderedQuery.js +36 -0
- package/dist/OrderedQuery.js.map +1 -0
- package/dist/QueryCtx.d.ts +10 -0
- package/dist/QueryCtx.d.ts.map +1 -0
- package/dist/QueryCtx.js +18 -0
- package/dist/QueryCtx.js.map +1 -0
- package/dist/QueryInitializer.d.ts +75 -0
- package/dist/QueryInitializer.d.ts.map +1 -0
- package/dist/QueryInitializer.js +105 -0
- package/dist/QueryInitializer.js.map +1 -0
- package/dist/QueryRunner.d.ts +46 -0
- package/dist/QueryRunner.d.ts.map +1 -0
- package/dist/QueryRunner.js +30 -0
- package/dist/QueryRunner.js.map +1 -0
- package/dist/QueryStream.d.ts +678 -0
- package/dist/QueryStream.d.ts.map +1 -0
- package/dist/QueryStream.js +943 -0
- package/dist/QueryStream.js.map +1 -0
- package/dist/QueryStreamCursor.d.ts +39 -0
- package/dist/QueryStreamCursor.d.ts.map +1 -0
- package/dist/QueryStreamCursor.js +52 -0
- package/dist/QueryStreamCursor.js.map +1 -0
- package/dist/QueryStreamIndexPrefix.d.ts +48 -0
- package/dist/QueryStreamIndexPrefix.d.ts.map +1 -0
- package/dist/QueryStreamIndexPrefix.js +38 -0
- package/dist/QueryStreamIndexPrefix.js.map +1 -0
- package/dist/QueryStreamIndexRange.d.ts +193 -0
- package/dist/QueryStreamIndexRange.d.ts.map +1 -0
- package/dist/QueryStreamIndexRange.js +241 -0
- package/dist/QueryStreamIndexRange.js.map +1 -0
- package/dist/QueryStreamKey.d.ts +64 -0
- package/dist/QueryStreamKey.d.ts.map +1 -0
- package/dist/QueryStreamKey.js +69 -0
- package/dist/QueryStreamKey.js.map +1 -0
- package/dist/QueryStreamKeyBounds.d.ts +136 -0
- package/dist/QueryStreamKeyBounds.d.ts.map +1 -0
- package/dist/QueryStreamKeyBounds.js +208 -0
- package/dist/QueryStreamKeyBounds.js.map +1 -0
- package/dist/QueryStreamKeyLabels.d.ts +27 -0
- package/dist/QueryStreamKeyLabels.d.ts.map +1 -0
- package/dist/QueryStreamKeyLabels.js +22 -0
- package/dist/QueryStreamKeyLabels.js.map +1 -0
- package/dist/QueryStreamKeyLayout.d.ts +179 -0
- package/dist/QueryStreamKeyLayout.d.ts.map +1 -0
- package/dist/QueryStreamKeyLayout.js +167 -0
- package/dist/QueryStreamKeyLayout.js.map +1 -0
- package/dist/QueryStreamKeyValues.d.ts +40 -0
- package/dist/QueryStreamKeyValues.d.ts.map +1 -0
- package/dist/QueryStreamKeyValues.js +57 -0
- package/dist/QueryStreamKeyValues.js.map +1 -0
- package/dist/QueryStreamOrderDirection.d.ts +24 -0
- package/dist/QueryStreamOrderDirection.d.ts.map +1 -0
- package/dist/QueryStreamOrderDirection.js +11 -0
- package/dist/QueryStreamOrderDirection.js.map +1 -0
- package/dist/QueryStreamPagination.d.ts +264 -0
- package/dist/QueryStreamPagination.d.ts.map +1 -0
- package/dist/QueryStreamPagination.js +172 -0
- package/dist/QueryStreamPagination.js.map +1 -0
- package/dist/QueryStreamReadBudget.d.ts +63 -0
- package/dist/QueryStreamReadBudget.d.ts.map +1 -0
- package/dist/QueryStreamReadBudget.js +81 -0
- package/dist/QueryStreamReadBudget.js.map +1 -0
- package/dist/QueryTransactionContext.d.ts +16 -0
- package/dist/QueryTransactionContext.d.ts.map +1 -0
- package/dist/QueryTransactionContext.js +17 -0
- package/dist/QueryTransactionContext.js.map +1 -0
- package/dist/RegisteredConvexFunction.d.ts +359 -0
- package/dist/RegisteredConvexFunction.d.ts.map +1 -0
- package/dist/RegisteredConvexFunction.js +154 -0
- package/dist/RegisteredConvexFunction.js.map +1 -0
- package/dist/RegisteredFunction.d.ts +143 -0
- package/dist/RegisteredFunction.d.ts.map +1 -0
- package/dist/RegisteredFunction.js +125 -0
- package/dist/RegisteredFunction.js.map +1 -0
- package/dist/RegisteredFunctions.d.ts +57 -0
- package/dist/RegisteredFunctions.d.ts.map +1 -0
- package/dist/RegisteredFunctions.js +32 -0
- package/dist/RegisteredFunctions.js.map +1 -0
- package/dist/RegisteredNodeFunction.d.ts +11 -0
- package/dist/RegisteredNodeFunction.d.ts.map +1 -0
- package/dist/RegisteredNodeFunction.js +45 -0
- package/dist/RegisteredNodeFunction.js.map +1 -0
- package/dist/Registry.d.ts +12 -0
- package/dist/Registry.d.ts.map +1 -0
- package/dist/Registry.js +17 -0
- package/dist/Registry.js.map +1 -0
- package/dist/RegistryItems.d.ts +21 -0
- package/dist/RegistryItems.d.ts.map +1 -0
- package/dist/RegistryItems.js +27 -0
- package/dist/RegistryItems.js.map +1 -0
- package/dist/RequestMetadata.d.ts +12 -0
- package/dist/RequestMetadata.d.ts.map +1 -0
- package/dist/RequestMetadata.js +16 -0
- package/dist/RequestMetadata.js.map +1 -0
- package/dist/ResolvedMiddleware.d.ts +24 -0
- package/dist/ResolvedMiddleware.d.ts.map +1 -0
- package/dist/ResolvedMiddleware.js +34 -0
- package/dist/ResolvedMiddleware.js.map +1 -0
- package/dist/Scheduler.d.ts +31 -0
- package/dist/Scheduler.d.ts.map +1 -0
- package/dist/Scheduler.js +35 -0
- package/dist/Scheduler.js.map +1 -0
- package/dist/Storage.d.ts +22 -0
- package/dist/Storage.d.ts.map +1 -0
- package/dist/Storage.js +27 -0
- package/dist/Storage.js.map +1 -0
- package/dist/StorageActionWriter.d.ts +35 -0
- package/dist/StorageActionWriter.d.ts.map +1 -0
- package/dist/StorageActionWriter.js +24 -0
- package/dist/StorageActionWriter.js.map +1 -0
- package/dist/StorageReader.d.ts +26 -0
- package/dist/StorageReader.d.ts.map +1 -0
- package/dist/StorageReader.js +22 -0
- package/dist/StorageReader.js.map +1 -0
- package/dist/StorageWriter.d.ts +29 -0
- package/dist/StorageWriter.d.ts.map +1 -0
- package/dist/StorageWriter.js +24 -0
- package/dist/StorageWriter.js.map +1 -0
- package/dist/Table.d.ts +274 -0
- package/dist/Table.d.ts.map +1 -0
- package/dist/Table.js +70 -0
- package/dist/Table.js.map +1 -0
- package/dist/TableInfo.d.ts +44 -0
- package/dist/TableInfo.d.ts.map +1 -0
- package/dist/TableInfo.js +7 -0
- package/dist/TableInfo.js.map +1 -0
- package/dist/TransactionMetadata.d.ts +12 -0
- package/dist/TransactionMetadata.d.ts.map +1 -0
- package/dist/TransactionMetadata.js +16 -0
- package/dist/TransactionMetadata.js.map +1 -0
- package/dist/VectorSearch.d.ts +23 -0
- package/dist/VectorSearch.d.ts.map +1 -0
- package/dist/VectorSearch.js +17 -0
- package/dist/VectorSearch.js.map +1 -0
- package/dist/_virtual/_rolldown/runtime.js +13 -0
- package/dist/index.d.ts +88 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +61 -0
- package/dist/internal/AiGatewayDecisionClient.d.ts +7 -0
- package/dist/internal/AiGatewayDecisionClient.d.ts.map +1 -0
- package/dist/internal/AiGatewayDecisionClient.js +19 -0
- package/dist/internal/AiGatewayDecisionClient.js.map +1 -0
- package/dist/internal/AiGatewayLanguageClient.d.ts +7 -0
- package/dist/internal/AiGatewayLanguageClient.d.ts.map +1 -0
- package/dist/internal/AiGatewayLanguageClient.js +19 -0
- package/dist/internal/AiGatewayLanguageClient.js.map +1 -0
- package/dist/internal/AiGatewayServiceToken.d.ts +46 -0
- package/dist/internal/AiGatewayServiceToken.d.ts.map +1 -0
- package/dist/internal/AiGatewayServiceToken.js +62 -0
- package/dist/internal/AiGatewayServiceToken.js.map +1 -0
- package/dist/internal/constants.d.ts +2 -0
- package/dist/internal/constants.d.ts.map +1 -0
- package/dist/internal/constants.js +6 -0
- package/dist/internal/constants.js.map +1 -0
- package/dist/internal/utils.d.ts +13 -0
- package/dist/internal/utils.d.ts.map +1 -0
- package/dist/internal/utils.js +50 -0
- package/dist/internal/utils.js.map +1 -0
- package/dist/node.d.ts +2 -0
- package/dist/node.d.ts.map +1 -0
- package/dist/node.js +1 -0
- package/package.json +68 -3
- package/src/ActionCtx.ts +45 -0
- package/src/ActionRunner.ts +36 -0
- package/src/AiGatewayDecisionClient.ts +40 -0
- package/src/AiGatewayDecisionModel.ts +46 -0
- package/src/AiGatewayLanguageClient.ts +41 -0
- package/src/AiGatewayLanguageModel.ts +61 -0
- package/src/Auth.ts +51 -0
- package/src/BlobNotFoundError.ts +12 -0
- package/src/Callback.ts +313 -0
- package/src/ComponentCtx.ts +192 -0
- package/src/ConvexConfigProvider.ts +39 -0
- package/src/ConvexFunctionDefinitions.ts +91 -0
- package/src/ConvexLogger.ts +43 -0
- package/src/CronJob.ts +42 -0
- package/src/CronJobs.ts +165 -0
- package/src/DataModel.ts +81 -0
- package/src/DatabaseReader.ts +118 -0
- package/src/DatabaseSchema.ts +139 -0
- package/src/DatabaseWriter.ts +232 -0
- package/src/Document.ts +146 -0
- package/src/ExecutionMetadata.ts +26 -0
- package/src/FunctionImpl.ts +96 -0
- package/src/FunctionRegistryItem.ts +85 -0
- package/src/GroupImpl.ts +167 -0
- package/src/GroupRegistry.ts +41 -0
- package/src/Handler.ts +191 -0
- package/src/HttpRouter.ts +388 -0
- package/src/MiddlewareImpl.ts +247 -0
- package/src/MiddlewareRegistryItem.ts +21 -0
- package/src/MutationCtx.ts +45 -0
- package/src/MutationRunner.ts +66 -0
- package/src/MutationTransactionContext.ts +48 -0
- package/src/OrderedQuery.ts +136 -0
- package/src/QueryCtx.ts +45 -0
- package/src/QueryInitializer.ts +537 -0
- package/src/QueryRunner.ts +91 -0
- package/src/QueryStream.ts +2476 -0
- package/src/QueryStreamCursor.ts +99 -0
- package/src/QueryStreamIndexPrefix.ts +79 -0
- package/src/QueryStreamIndexRange.ts +489 -0
- package/src/QueryStreamKey.ts +118 -0
- package/src/QueryStreamKeyBounds.ts +395 -0
- package/src/QueryStreamKeyLabels.ts +56 -0
- package/src/QueryStreamKeyLayout.ts +382 -0
- package/src/QueryStreamKeyValues.ts +112 -0
- package/src/QueryStreamOrderDirection.ts +29 -0
- package/src/QueryStreamPagination.ts +357 -0
- package/src/QueryStreamReadBudget.ts +167 -0
- package/src/QueryTransactionContext.ts +37 -0
- package/src/RegisteredConvexFunction.ts +415 -0
- package/src/RegisteredFunction.ts +391 -0
- package/src/RegisteredFunctions.ts +88 -0
- package/src/RegisteredNodeFunction.ts +120 -0
- package/src/Registry.ts +17 -0
- package/src/RegistryItems.ts +40 -0
- package/src/RequestMetadata.ts +20 -0
- package/src/ResolvedMiddleware.ts +70 -0
- package/src/Scheduler.ts +85 -0
- package/src/Storage.ts +37 -0
- package/src/StorageActionWriter.ts +59 -0
- package/src/StorageReader.ts +59 -0
- package/src/StorageWriter.ts +58 -0
- package/src/Table.ts +156 -0
- package/src/TableInfo.ts +106 -0
- package/src/TransactionMetadata.ts +20 -0
- package/src/VectorSearch.ts +75 -0
- package/src/index.ts +87 -0
- package/src/internal/AiGatewayDecisionClient.ts +16 -0
- package/src/internal/AiGatewayLanguageClient.ts +16 -0
- package/src/internal/AiGatewayServiceToken.ts +129 -0
- package/src/internal/constants.ts +1 -0
- package/src/internal/utils.ts +89 -0
- package/src/node.ts +1 -0
|
@@ -0,0 +1,382 @@
|
|
|
1
|
+
import * as Array from "effect/Array";
|
|
2
|
+
import * as Data from "effect/Data";
|
|
3
|
+
import * as Equivalence_ from "effect/Equivalence";
|
|
4
|
+
import { identity } from "effect/Function";
|
|
5
|
+
import * as Option from "effect/Option";
|
|
6
|
+
import * as Result from "effect/Result";
|
|
7
|
+
import type * as Types from "effect/Types";
|
|
8
|
+
|
|
9
|
+
import * as QueryStreamKeyLabels from "./QueryStreamKeyLabels";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* One runtime position of a stream key. Explicit IDs and their aliases are
|
|
13
|
+
* visible; implicit ID tiebreakers have no label. Empty keys have no
|
|
14
|
+
* positions.
|
|
15
|
+
*
|
|
16
|
+
* @experimental
|
|
17
|
+
*/
|
|
18
|
+
export type Position = Data.TaggedEnum<{
|
|
19
|
+
Visible: { readonly label: string };
|
|
20
|
+
ImplicitId: {};
|
|
21
|
+
}>;
|
|
22
|
+
|
|
23
|
+
const Position = Data.taggedEnum<Position>();
|
|
24
|
+
const TypeId = "@confect/server/QueryStreamKeyLayout";
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Describes the positions in a stream's keys: their sequence, their labels, and
|
|
28
|
+
* where implicit document-ID tiebreakers occur. Every element has its own key
|
|
29
|
+
* values; the stream has one shared layout.
|
|
30
|
+
*
|
|
31
|
+
* For example, labels `["text", "_creationTime"]` describe the labeled
|
|
32
|
+
* positions in a key such as `["apple", 1, "n1"]`. Its layout also records the
|
|
33
|
+
* final implicit ID position. Joined layouts retain each component's ID, so
|
|
34
|
+
* their labels alone do not describe every key position.
|
|
35
|
+
*
|
|
36
|
+
* Layouts are compatible when they have the same total width, labels in the
|
|
37
|
+
* same positions, and implicit-ID positions. Direction is separate. Layouts
|
|
38
|
+
* contain no key values, value-type schemas, table identity, or equality-pinned
|
|
39
|
+
* values. Labels start as index field paths but may be renamed. An explicit ID,
|
|
40
|
+
* such as in `by_id`, has a label.
|
|
41
|
+
*
|
|
42
|
+
* Reuse a stream's `keyLayout` with `empty` or `flatMap`'s `innerKeyLayout`.
|
|
43
|
+
* Creating a stream to obtain its layout does not read documents. The
|
|
44
|
+
* `KeyLabels` parameter tracks only labels; implicit-ID positions are checked
|
|
45
|
+
* at runtime. Normally this type is inferred from the source stream.
|
|
46
|
+
*
|
|
47
|
+
* @experimental
|
|
48
|
+
*/
|
|
49
|
+
export interface QueryStreamKeyLayout<
|
|
50
|
+
out KeyLabels extends QueryStreamKeyLabels.QueryStreamKeyLabels =
|
|
51
|
+
QueryStreamKeyLabels.QueryStreamKeyLabels,
|
|
52
|
+
> {
|
|
53
|
+
readonly [TypeId]: {
|
|
54
|
+
readonly _Labels: Types.Covariant<KeyLabels>;
|
|
55
|
+
readonly positions: ReadonlyArray<Position>;
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Private construction keeps the visible label witness with the operations
|
|
60
|
+
// that derive it from index fields, concatenation, or renaming.
|
|
61
|
+
const make = <KeyLabels extends QueryStreamKeyLabels.QueryStreamKeyLabels>(
|
|
62
|
+
positions: ReadonlyArray<Position>,
|
|
63
|
+
): QueryStreamKeyLayout<KeyLabels> => ({
|
|
64
|
+
[TypeId]: { _Labels: identity, positions },
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* The runtime positions, including implicit ID tiebreakers.
|
|
69
|
+
*
|
|
70
|
+
* @experimental
|
|
71
|
+
*/
|
|
72
|
+
export const positions = (
|
|
73
|
+
self: QueryStreamKeyLayout,
|
|
74
|
+
): ReadonlyArray<Position> => self[TypeId].positions;
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* The source field paths remaining after an equality prefix.
|
|
78
|
+
*
|
|
79
|
+
* @experimental
|
|
80
|
+
*/
|
|
81
|
+
export type RemainingFieldPaths<
|
|
82
|
+
FieldPaths extends ReadonlyArray<string>,
|
|
83
|
+
Count extends number,
|
|
84
|
+
> = Count extends unknown ? DropPrefix<FieldPaths, Count> : never;
|
|
85
|
+
|
|
86
|
+
type DropPrefix<
|
|
87
|
+
FieldPaths extends ReadonlyArray<string>,
|
|
88
|
+
Count extends number,
|
|
89
|
+
Prefix extends ReadonlyArray<unknown> = [],
|
|
90
|
+
> = number extends Count
|
|
91
|
+
? ReadonlyArray<string>
|
|
92
|
+
: Prefix["length"] extends Count
|
|
93
|
+
? Types.Mutable<FieldPaths>
|
|
94
|
+
: FieldPaths extends readonly [
|
|
95
|
+
string,
|
|
96
|
+
...infer TailFieldPaths extends ReadonlyArray<string>,
|
|
97
|
+
]
|
|
98
|
+
? DropPrefix<TailFieldPaths, Count, readonly [...Prefix, unknown]>
|
|
99
|
+
: FieldPaths extends readonly []
|
|
100
|
+
? []
|
|
101
|
+
: ReadonlyArray<string>;
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* The equality prefix cannot select a whole number of source field paths.
|
|
105
|
+
*
|
|
106
|
+
* @experimental
|
|
107
|
+
*/
|
|
108
|
+
export class InvalidEqualityPrefixError extends Data.TaggedError(
|
|
109
|
+
"InvalidEqualityPrefixError",
|
|
110
|
+
)<{
|
|
111
|
+
readonly fieldPaths: ReadonlyArray<string>;
|
|
112
|
+
readonly eqCount: number;
|
|
113
|
+
}> {
|
|
114
|
+
override get message(): string {
|
|
115
|
+
return `QueryStreamKeyLayout.fromIndex: invalid equality prefix length (${this.eqCount}) for ${this.fieldPaths.length} field paths`;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* The requested labels do not form a prefix of the layout's visible labels.
|
|
121
|
+
*
|
|
122
|
+
* @experimental
|
|
123
|
+
*/
|
|
124
|
+
export class InvalidLabelPrefixError extends Data.TaggedError(
|
|
125
|
+
"InvalidLabelPrefixError",
|
|
126
|
+
)<{
|
|
127
|
+
readonly keyLabels: QueryStreamKeyLabels.QueryStreamKeyLabels;
|
|
128
|
+
readonly prefixKeyLabels: QueryStreamKeyLabels.QueryStreamKeyLabels;
|
|
129
|
+
}> {
|
|
130
|
+
override get message(): string {
|
|
131
|
+
return `Labels ([${Array.join(this.prefixKeyLabels, ", ")}]) must be a prefix of the ordering labels ([${Array.join(this.keyLabels, ", ")}])`;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* The replacement labels cannot fill exactly the layout's visible positions.
|
|
137
|
+
*
|
|
138
|
+
* @experimental
|
|
139
|
+
*/
|
|
140
|
+
export class LabelCountMismatchError extends Data.TaggedError(
|
|
141
|
+
"LabelCountMismatchError",
|
|
142
|
+
)<{
|
|
143
|
+
readonly keyLabels: QueryStreamKeyLabels.QueryStreamKeyLabels;
|
|
144
|
+
readonly replacementKeyLabels: QueryStreamKeyLabels.QueryStreamKeyLabels;
|
|
145
|
+
}> {
|
|
146
|
+
override get message(): string {
|
|
147
|
+
return `Replacement labels ([${Array.join(this.replacementKeyLabels, ", ")}]) must have as many labels as the ordering labels ([${Array.join(this.keyLabels, ", ")}])`;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Construct a scan layout from the original index field paths, before equality
|
|
153
|
+
* pinning. Only an ID absent from the end of that original key is implicit.
|
|
154
|
+
* Pinning every field of `by_id` produces a zero-width layout; pinning every
|
|
155
|
+
* visible field of another index leaves its implicit ID. Invalid equality
|
|
156
|
+
* prefix lengths return `InvalidEqualityPrefixError`.
|
|
157
|
+
*
|
|
158
|
+
* @experimental
|
|
159
|
+
*/
|
|
160
|
+
export function fromIndex<const FieldPaths extends ReadonlyArray<string>>(
|
|
161
|
+
fieldPaths: FieldPaths,
|
|
162
|
+
): Result.Result<
|
|
163
|
+
QueryStreamKeyLayout<QueryStreamKeyLabels.QueryStreamKeyLabels<FieldPaths>>,
|
|
164
|
+
InvalidEqualityPrefixError
|
|
165
|
+
>;
|
|
166
|
+
/**
|
|
167
|
+
* @experimental
|
|
168
|
+
*/
|
|
169
|
+
export function fromIndex<
|
|
170
|
+
const FieldPaths extends ReadonlyArray<string>,
|
|
171
|
+
const Count extends number,
|
|
172
|
+
>(
|
|
173
|
+
fieldPaths: FieldPaths,
|
|
174
|
+
eqCount: Count,
|
|
175
|
+
): Result.Result<
|
|
176
|
+
QueryStreamKeyLayout<
|
|
177
|
+
QueryStreamKeyLabels.QueryStreamKeyLabels<
|
|
178
|
+
RemainingFieldPaths<FieldPaths, Count>
|
|
179
|
+
>
|
|
180
|
+
>,
|
|
181
|
+
InvalidEqualityPrefixError
|
|
182
|
+
>;
|
|
183
|
+
export function fromIndex(
|
|
184
|
+
fieldPaths: ReadonlyArray<string>,
|
|
185
|
+
eqCount = 0,
|
|
186
|
+
): Result.Result<QueryStreamKeyLayout, InvalidEqualityPrefixError> {
|
|
187
|
+
if (
|
|
188
|
+
!Number.isInteger(eqCount) ||
|
|
189
|
+
eqCount < 0 ||
|
|
190
|
+
eqCount > fieldPaths.length
|
|
191
|
+
) {
|
|
192
|
+
return Result.fail(new InvalidEqualityPrefixError({ fieldPaths, eqCount }));
|
|
193
|
+
}
|
|
194
|
+
const visible = Array.map(Array.drop(fieldPaths, eqCount), (label) =>
|
|
195
|
+
Position.Visible({ label }),
|
|
196
|
+
);
|
|
197
|
+
const keyPositions = Option.exists(
|
|
198
|
+
Array.last(fieldPaths),
|
|
199
|
+
(fieldPath) => fieldPath === "_id",
|
|
200
|
+
)
|
|
201
|
+
? visible
|
|
202
|
+
: Array.append(visible, Position.ImplicitId());
|
|
203
|
+
return Result.succeed(make(keyPositions));
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Concatenate layouts without losing component tiebreakers.
|
|
208
|
+
*
|
|
209
|
+
* @experimental
|
|
210
|
+
*/
|
|
211
|
+
export const concat = <
|
|
212
|
+
LeftKeyLabels extends QueryStreamKeyLabels.QueryStreamKeyLabels,
|
|
213
|
+
RightKeyLabels extends QueryStreamKeyLabels.QueryStreamKeyLabels,
|
|
214
|
+
>(
|
|
215
|
+
self: QueryStreamKeyLayout<LeftKeyLabels>,
|
|
216
|
+
that: QueryStreamKeyLayout<RightKeyLabels>,
|
|
217
|
+
): QueryStreamKeyLayout<
|
|
218
|
+
QueryStreamKeyLabels.Concat<LeftKeyLabels, RightKeyLabels>
|
|
219
|
+
> => make(Array.appendAll(positions(self), positions(that)));
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Format visible labels and implicit IDs for diagnostics.
|
|
223
|
+
*
|
|
224
|
+
* @experimental
|
|
225
|
+
*/
|
|
226
|
+
export const format = (self: QueryStreamKeyLayout): string => {
|
|
227
|
+
const tokens = Array.map(
|
|
228
|
+
positions(self),
|
|
229
|
+
Position.$match({
|
|
230
|
+
Visible: ({ label }) => JSON.stringify(label),
|
|
231
|
+
ImplicitId: () => "<implicit _id>",
|
|
232
|
+
}),
|
|
233
|
+
);
|
|
234
|
+
return `[${Array.join(tokens, ", ")}]`;
|
|
235
|
+
};
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* The labels available to `distinct` and `renameKey`.
|
|
239
|
+
*
|
|
240
|
+
* @experimental
|
|
241
|
+
*/
|
|
242
|
+
export function visibleLabels<
|
|
243
|
+
KeyLabels extends QueryStreamKeyLabels.QueryStreamKeyLabels,
|
|
244
|
+
>(self: QueryStreamKeyLayout<KeyLabels>): KeyLabels;
|
|
245
|
+
export function visibleLabels(
|
|
246
|
+
self: QueryStreamKeyLayout,
|
|
247
|
+
): QueryStreamKeyLabels.QueryStreamKeyLabels {
|
|
248
|
+
return QueryStreamKeyLabels.make(
|
|
249
|
+
Array.filterMap(
|
|
250
|
+
positions(self),
|
|
251
|
+
Position.$match({
|
|
252
|
+
Visible: ({ label }) => Result.succeed(label),
|
|
253
|
+
ImplicitId: () => Result.failVoid,
|
|
254
|
+
}),
|
|
255
|
+
),
|
|
256
|
+
);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Number of positions in an element's runtime key.
|
|
261
|
+
*
|
|
262
|
+
* @experimental
|
|
263
|
+
*/
|
|
264
|
+
export const runtimeWidth = (self: QueryStreamKeyLayout): number =>
|
|
265
|
+
positions(self).length;
|
|
266
|
+
|
|
267
|
+
// Runtime offsets of visible labels, used to resolve label prefixes.
|
|
268
|
+
const visiblePositions = (self: QueryStreamKeyLayout): ReadonlyArray<number> =>
|
|
269
|
+
Array.filterMap(positions(self), (position, index) =>
|
|
270
|
+
Position.$is("Visible")(position) ? Result.succeed(index) : Result.failVoid,
|
|
271
|
+
);
|
|
272
|
+
|
|
273
|
+
const PositionsEquivalence = Equivalence_.Array<Position>((self, that) =>
|
|
274
|
+
Position.$match(self, {
|
|
275
|
+
Visible: ({ label }) =>
|
|
276
|
+
Position.$is("Visible")(that) && label === that.label,
|
|
277
|
+
ImplicitId: () => Position.$is("ImplicitId")(that),
|
|
278
|
+
}),
|
|
279
|
+
);
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* @experimental
|
|
283
|
+
*/
|
|
284
|
+
export const Equivalence: Equivalence_.Equivalence<QueryStreamKeyLayout> =
|
|
285
|
+
Equivalence_.mapInput(PositionsEquivalence, positions);
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* @experimental
|
|
289
|
+
*/
|
|
290
|
+
export class KeyLayoutMismatchError extends Data.TaggedError(
|
|
291
|
+
"KeyLayoutMismatchError",
|
|
292
|
+
)<{
|
|
293
|
+
readonly expectedKeyLayout: QueryStreamKeyLayout;
|
|
294
|
+
readonly actualKeyLayout: QueryStreamKeyLayout;
|
|
295
|
+
}> {
|
|
296
|
+
override get message(): string {
|
|
297
|
+
return `Key layout (${format(this.actualKeyLayout)}) does not match the expected layout (${format(this.expectedKeyLayout)})`;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* @experimental
|
|
303
|
+
*/
|
|
304
|
+
export const validateEquivalence = (
|
|
305
|
+
expectedKeyLayout: QueryStreamKeyLayout,
|
|
306
|
+
actualKeyLayout: QueryStreamKeyLayout,
|
|
307
|
+
): Result.Result<void, KeyLayoutMismatchError> =>
|
|
308
|
+
Equivalence(expectedKeyLayout, actualKeyLayout)
|
|
309
|
+
? Result.succeed(undefined)
|
|
310
|
+
: Result.fail(
|
|
311
|
+
new KeyLayoutMismatchError({ expectedKeyLayout, actualKeyLayout }),
|
|
312
|
+
);
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* Parse a visible label prefix and resolve its runtime width. Implicit IDs
|
|
316
|
+
* before the last selected label are included; implicit IDs after it are not.
|
|
317
|
+
*
|
|
318
|
+
* @experimental
|
|
319
|
+
*/
|
|
320
|
+
export const resolvePrefix = (
|
|
321
|
+
self: QueryStreamKeyLayout,
|
|
322
|
+
prefixKeyLabels: QueryStreamKeyLabels.QueryStreamKeyLabels,
|
|
323
|
+
): Result.Result<number, InvalidLabelPrefixError> => {
|
|
324
|
+
const keyLabels = visibleLabels(self);
|
|
325
|
+
if (!QueryStreamKeyLabels.hasPrefix(keyLabels, prefixKeyLabels)) {
|
|
326
|
+
return Result.fail(
|
|
327
|
+
new InvalidLabelPrefixError({ keyLabels, prefixKeyLabels }),
|
|
328
|
+
);
|
|
329
|
+
}
|
|
330
|
+
return Result.succeed(
|
|
331
|
+
Option.match(
|
|
332
|
+
Array.get(visiblePositions(self), prefixKeyLabels.length - 1),
|
|
333
|
+
{
|
|
334
|
+
onNone: () => 0,
|
|
335
|
+
onSome: (position) => position + 1,
|
|
336
|
+
},
|
|
337
|
+
),
|
|
338
|
+
);
|
|
339
|
+
};
|
|
340
|
+
|
|
341
|
+
/**
|
|
342
|
+
* Relabel visible positions, preserving every implicit ID.
|
|
343
|
+
*
|
|
344
|
+
* @experimental
|
|
345
|
+
*/
|
|
346
|
+
export const rename = <
|
|
347
|
+
ReplacementKeyLabels extends QueryStreamKeyLabels.QueryStreamKeyLabels,
|
|
348
|
+
>(
|
|
349
|
+
self: QueryStreamKeyLayout,
|
|
350
|
+
replacementKeyLabels: ReplacementKeyLabels,
|
|
351
|
+
): Result.Result<
|
|
352
|
+
QueryStreamKeyLayout<ReplacementKeyLabels>,
|
|
353
|
+
LabelCountMismatchError
|
|
354
|
+
> => {
|
|
355
|
+
const [consumed, renamed] = Array.mapAccum(
|
|
356
|
+
positions(self),
|
|
357
|
+
0,
|
|
358
|
+
(index, position): readonly [number, Option.Option<Position>] =>
|
|
359
|
+
Position.$match(position, {
|
|
360
|
+
ImplicitId: () => [index, Option.some(position)] as const,
|
|
361
|
+
Visible: () =>
|
|
362
|
+
[
|
|
363
|
+
index + 1,
|
|
364
|
+
Option.map(Array.get(replacementKeyLabels, index), (label) =>
|
|
365
|
+
Position.Visible({ label }),
|
|
366
|
+
),
|
|
367
|
+
] as const,
|
|
368
|
+
}),
|
|
369
|
+
);
|
|
370
|
+
const parsed =
|
|
371
|
+
consumed === replacementKeyLabels.length
|
|
372
|
+
? Option.all(renamed)
|
|
373
|
+
: Option.none();
|
|
374
|
+
return Result.fromOption(
|
|
375
|
+
Option.map(parsed, make<ReplacementKeyLabels>),
|
|
376
|
+
() =>
|
|
377
|
+
new LabelCountMismatchError({
|
|
378
|
+
keyLabels: visibleLabels(self),
|
|
379
|
+
replacementKeyLabels,
|
|
380
|
+
}),
|
|
381
|
+
);
|
|
382
|
+
};
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import {
|
|
2
|
+
convexToJson,
|
|
3
|
+
jsonToConvex,
|
|
4
|
+
compareValues,
|
|
5
|
+
type Value,
|
|
6
|
+
} from "convex/values";
|
|
7
|
+
import * as Array from "effect/Array";
|
|
8
|
+
import * as Effect from "effect/Effect";
|
|
9
|
+
import * as Order_ from "effect/Order";
|
|
10
|
+
import type * as Record from "effect/Record";
|
|
11
|
+
import * as Result from "effect/Result";
|
|
12
|
+
import * as Schema from "effect/Schema";
|
|
13
|
+
import * as SchemaGetter from "effect/SchemaGetter";
|
|
14
|
+
import * as SchemaIssue from "effect/SchemaIssue";
|
|
15
|
+
import type * as QueryStreamOrderDirection from "./QueryStreamOrderDirection";
|
|
16
|
+
|
|
17
|
+
const UNDEFINED_SENTINEL = { $undefined: true } as const;
|
|
18
|
+
const KeyValue = Schema.Json.pipe(
|
|
19
|
+
Schema.decodeTo(
|
|
20
|
+
Schema.declare<Value | undefined>(
|
|
21
|
+
(value): value is Value | undefined =>
|
|
22
|
+
value === undefined ||
|
|
23
|
+
Result.isSuccess(Result.try(() => convexToJson(value as Value))),
|
|
24
|
+
),
|
|
25
|
+
{
|
|
26
|
+
decode: SchemaGetter.transformEffect((value, options) =>
|
|
27
|
+
Effect.try({
|
|
28
|
+
try: () =>
|
|
29
|
+
Result.match(
|
|
30
|
+
Schema.decodeUnknownResult(
|
|
31
|
+
Schema.Struct({ $undefined: Schema.Literal(true) }),
|
|
32
|
+
{ onExcessProperty: "error" },
|
|
33
|
+
)(value),
|
|
34
|
+
{
|
|
35
|
+
onSuccess: () => undefined,
|
|
36
|
+
onFailure: () =>
|
|
37
|
+
jsonToConvex(value as Parameters<typeof jsonToConvex>[0]),
|
|
38
|
+
},
|
|
39
|
+
),
|
|
40
|
+
catch: () =>
|
|
41
|
+
new SchemaIssue.InvalidValue(
|
|
42
|
+
{ message: "Invalid Convex key value" },
|
|
43
|
+
value,
|
|
44
|
+
options,
|
|
45
|
+
),
|
|
46
|
+
}),
|
|
47
|
+
),
|
|
48
|
+
encode: SchemaGetter.transform((value) =>
|
|
49
|
+
value === undefined ? UNDEFINED_SENTINEL : convexToJson(value),
|
|
50
|
+
),
|
|
51
|
+
},
|
|
52
|
+
),
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* @experimental
|
|
57
|
+
*/
|
|
58
|
+
export type KeyValue = typeof KeyValue.Type;
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* @experimental
|
|
62
|
+
*/
|
|
63
|
+
export const QueryStreamKeyValues = Schema.Array(KeyValue);
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* @experimental
|
|
67
|
+
*/
|
|
68
|
+
export type QueryStreamKeyValues = typeof QueryStreamKeyValues.Type;
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* `Order` over Convex values, matching Convex's index ordering—a wrapper around
|
|
72
|
+
* the canonical `compareValues` from `convex/values` (type rank first, then
|
|
73
|
+
* within the type, including UTF-8 string order and NaN bit-level ordering).
|
|
74
|
+
*
|
|
75
|
+
* @experimental
|
|
76
|
+
*/
|
|
77
|
+
export const ValueOrder: Order_.Order<KeyValue> = Order_.make(
|
|
78
|
+
(self, that) => Math.sign(compareValues(self, that)) as -1 | 0 | 1,
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
const AscendingOrder = Order_.Array(ValueOrder);
|
|
82
|
+
const DescendingOrder = Order_.flip(AscendingOrder);
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Compare key values in the requested direction. Ascending order is
|
|
86
|
+
* lexicographic by `ValueOrder`, then by length, matching Convex array values;
|
|
87
|
+
* descending order reverses it.
|
|
88
|
+
*
|
|
89
|
+
* @experimental
|
|
90
|
+
*/
|
|
91
|
+
export const Order = (
|
|
92
|
+
orderDirection: QueryStreamOrderDirection.QueryStreamOrderDirection,
|
|
93
|
+
): Order_.Order<QueryStreamKeyValues> =>
|
|
94
|
+
orderDirection === "asc" ? AscendingOrder : DescendingOrder;
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* @experimental
|
|
98
|
+
*/
|
|
99
|
+
export const extract = (
|
|
100
|
+
encoded: Record.ReadonlyRecord<string, unknown>,
|
|
101
|
+
keyPaths: ReadonlyArray<ReadonlyArray<string>>,
|
|
102
|
+
): QueryStreamKeyValues =>
|
|
103
|
+
Array.map(keyPaths, (path) =>
|
|
104
|
+
Array.reduce(
|
|
105
|
+
path,
|
|
106
|
+
encoded as unknown,
|
|
107
|
+
(value, segment) =>
|
|
108
|
+
(value as Record.ReadonlyRecord<string, unknown> | undefined)?.[
|
|
109
|
+
segment
|
|
110
|
+
],
|
|
111
|
+
),
|
|
112
|
+
) as QueryStreamKeyValues;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The direction a stream is ordered in. Tracked covariantly in the type: a
|
|
3
|
+
* stream of a known direction is also a stream of `"asc" | "desc"`, the class
|
|
4
|
+
* default, so annotations that omit the direction accept every stream.
|
|
5
|
+
* Combining streams of different known directions—`merge`, or a `flatMap` whose
|
|
6
|
+
* inner streams run the other way—is a type error; a direction chosen at
|
|
7
|
+
* runtime types as the union, and the runtime check catches what the types
|
|
8
|
+
* can't see (`merge` throws when the streams are combined, `flatMap` fails when
|
|
9
|
+
* the join runs).
|
|
10
|
+
*
|
|
11
|
+
* @experimental
|
|
12
|
+
*/
|
|
13
|
+
export type QueryStreamOrderDirection = "asc" | "desc";
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* The opposite of a direction; a runtime-chosen direction stays the union.
|
|
17
|
+
*
|
|
18
|
+
* @experimental
|
|
19
|
+
*/
|
|
20
|
+
export type Flip<OrderDirection extends QueryStreamOrderDirection> =
|
|
21
|
+
OrderDirection extends "asc" ? "desc" : "asc";
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* @experimental
|
|
25
|
+
*/
|
|
26
|
+
export const flip = <OrderDirection extends QueryStreamOrderDirection>(
|
|
27
|
+
orderDirection: OrderDirection,
|
|
28
|
+
): Flip<OrderDirection> =>
|
|
29
|
+
(orderDirection === "asc" ? "desc" : "asc") as Flip<OrderDirection>;
|