@gaganref/confect-server 0.0.0-stage → 10.3.1-fork.2

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.
Files changed (367) hide show
  1. package/CHANGELOG.md +2119 -0
  2. package/LICENSE +7 -0
  3. package/README.md +16 -2
  4. package/dist/ActionCtx.d.ts +10 -0
  5. package/dist/ActionCtx.d.ts.map +1 -0
  6. package/dist/ActionCtx.js +18 -0
  7. package/dist/ActionCtx.js.map +1 -0
  8. package/dist/ActionRunner.d.ts +16 -0
  9. package/dist/ActionRunner.d.ts.map +1 -0
  10. package/dist/ActionRunner.js +18 -0
  11. package/dist/ActionRunner.js.map +1 -0
  12. package/dist/AiGatewayDecisionClient.d.ts +20 -0
  13. package/dist/AiGatewayDecisionClient.d.ts.map +1 -0
  14. package/dist/AiGatewayDecisionClient.js +31 -0
  15. package/dist/AiGatewayDecisionClient.js.map +1 -0
  16. package/dist/AiGatewayDecisionModel.d.ts +24 -0
  17. package/dist/AiGatewayDecisionModel.d.ts.map +1 -0
  18. package/dist/AiGatewayDecisionModel.js +27 -0
  19. package/dist/AiGatewayDecisionModel.js.map +1 -0
  20. package/dist/AiGatewayLanguageClient.d.ts +21 -0
  21. package/dist/AiGatewayLanguageClient.d.ts.map +1 -0
  22. package/dist/AiGatewayLanguageClient.js +32 -0
  23. package/dist/AiGatewayLanguageClient.js.map +1 -0
  24. package/dist/AiGatewayLanguageModel.d.ts +95 -0
  25. package/dist/AiGatewayLanguageModel.d.ts.map +1 -0
  26. package/dist/AiGatewayLanguageModel.js +42 -0
  27. package/dist/AiGatewayLanguageModel.js.map +1 -0
  28. package/dist/Auth.d.ts +20 -0
  29. package/dist/Auth.d.ts.map +1 -0
  30. package/dist/Auth.js +31 -0
  31. package/dist/Auth.js.map +1 -0
  32. package/dist/BlobNotFoundError.d.ts +9 -0
  33. package/dist/BlobNotFoundError.d.ts.map +1 -0
  34. package/dist/BlobNotFoundError.js +13 -0
  35. package/dist/BlobNotFoundError.js.map +1 -0
  36. package/dist/Callback.d.ts +31 -0
  37. package/dist/Callback.d.ts.map +1 -0
  38. package/dist/Callback.js +182 -0
  39. package/dist/Callback.js.map +1 -0
  40. package/dist/ComponentCtx.d.ts +71 -0
  41. package/dist/ComponentCtx.d.ts.map +1 -0
  42. package/dist/ComponentCtx.js +0 -0
  43. package/dist/ConvexConfigProvider.d.ts +21 -0
  44. package/dist/ConvexConfigProvider.d.ts.map +1 -0
  45. package/dist/ConvexConfigProvider.js +36 -0
  46. package/dist/ConvexConfigProvider.js.map +1 -0
  47. package/dist/ConvexFunctionDefinitions.d.ts +25 -0
  48. package/dist/ConvexFunctionDefinitions.d.ts.map +1 -0
  49. package/dist/ConvexFunctionDefinitions.js +25 -0
  50. package/dist/ConvexFunctionDefinitions.js.map +1 -0
  51. package/dist/ConvexLogger.d.ts +17 -0
  52. package/dist/ConvexLogger.d.ts.map +1 -0
  53. package/dist/ConvexLogger.js +33 -0
  54. package/dist/ConvexLogger.js.map +1 -0
  55. package/dist/CronJob.d.ts +14 -0
  56. package/dist/CronJob.d.ts.map +1 -0
  57. package/dist/CronJob.js +22 -0
  58. package/dist/CronJob.js.map +1 -0
  59. package/dist/CronJobs.d.ts +22 -0
  60. package/dist/CronJobs.d.ts.map +1 -0
  61. package/dist/CronJobs.js +83 -0
  62. package/dist/CronJobs.js.map +1 -0
  63. package/dist/DataModel.d.ts +28 -0
  64. package/dist/DataModel.d.ts.map +1 -0
  65. package/dist/DataModel.js +7 -0
  66. package/dist/DataModel.js.map +1 -0
  67. package/dist/DatabaseReader.d.ts +26 -0
  68. package/dist/DatabaseReader.d.ts.map +1 -0
  69. package/dist/DatabaseReader.js +33 -0
  70. package/dist/DatabaseReader.js.map +1 -0
  71. package/dist/DatabaseSchema.d.ts +67 -0
  72. package/dist/DatabaseSchema.d.ts.map +1 -0
  73. package/dist/DatabaseSchema.js +61 -0
  74. package/dist/DatabaseSchema.js.map +1 -0
  75. package/dist/DatabaseWriter.d.ts +44 -0
  76. package/dist/DatabaseWriter.d.ts.map +1 -0
  77. package/dist/DatabaseWriter.js +47 -0
  78. package/dist/DatabaseWriter.js.map +1 -0
  79. package/dist/Document.d.ts +37 -0
  80. package/dist/Document.d.ts.map +1 -0
  81. package/dist/Document.js +54 -0
  82. package/dist/Document.js.map +1 -0
  83. package/dist/ExecutionMetadata.d.ts +13 -0
  84. package/dist/ExecutionMetadata.d.ts.map +1 -0
  85. package/dist/ExecutionMetadata.js +19 -0
  86. package/dist/ExecutionMetadata.js.map +1 -0
  87. package/dist/FunctionImpl.d.ts +39 -0
  88. package/dist/FunctionImpl.d.ts.map +1 -0
  89. package/dist/FunctionImpl.js +46 -0
  90. package/dist/FunctionImpl.js.map +1 -0
  91. package/dist/FunctionRegistryItem.d.ts +36 -0
  92. package/dist/FunctionRegistryItem.d.ts.map +1 -0
  93. package/dist/FunctionRegistryItem.js +34 -0
  94. package/dist/FunctionRegistryItem.js.map +1 -0
  95. package/dist/GroupImpl.d.ts +77 -0
  96. package/dist/GroupImpl.d.ts.map +1 -0
  97. package/dist/GroupImpl.js +81 -0
  98. package/dist/GroupImpl.js.map +1 -0
  99. package/dist/GroupRegistry.d.ts +8 -0
  100. package/dist/GroupRegistry.d.ts.map +1 -0
  101. package/dist/GroupRegistry.js +26 -0
  102. package/dist/GroupRegistry.js.map +1 -0
  103. package/dist/Handler.d.ts +47 -0
  104. package/dist/Handler.d.ts.map +1 -0
  105. package/dist/Handler.js +7 -0
  106. package/dist/Handler.js.map +1 -0
  107. package/dist/HttpRouter.d.ts +80 -0
  108. package/dist/HttpRouter.d.ts.map +1 -0
  109. package/dist/HttpRouter.js +195 -0
  110. package/dist/HttpRouter.js.map +1 -0
  111. package/dist/MiddlewareImpl.d.ts +79 -0
  112. package/dist/MiddlewareImpl.d.ts.map +1 -0
  113. package/dist/MiddlewareImpl.js +58 -0
  114. package/dist/MiddlewareImpl.js.map +1 -0
  115. package/dist/MiddlewareRegistryItem.d.ts +12 -0
  116. package/dist/MiddlewareRegistryItem.d.ts.map +1 -0
  117. package/dist/MiddlewareRegistryItem.js +15 -0
  118. package/dist/MiddlewareRegistryItem.js.map +1 -0
  119. package/dist/MutationCtx.d.ts +10 -0
  120. package/dist/MutationCtx.d.ts.map +1 -0
  121. package/dist/MutationCtx.js +18 -0
  122. package/dist/MutationCtx.js.map +1 -0
  123. package/dist/MutationRunner.d.ts +27 -0
  124. package/dist/MutationRunner.d.ts.map +1 -0
  125. package/dist/MutationRunner.js +28 -0
  126. package/dist/MutationRunner.js.map +1 -0
  127. package/dist/MutationTransactionContext.d.ts +17 -0
  128. package/dist/MutationTransactionContext.d.ts.map +1 -0
  129. package/dist/MutationTransactionContext.js +20 -0
  130. package/dist/MutationTransactionContext.js.map +1 -0
  131. package/dist/OrderedQuery.d.ts +32 -0
  132. package/dist/OrderedQuery.d.ts.map +1 -0
  133. package/dist/OrderedQuery.js +36 -0
  134. package/dist/OrderedQuery.js.map +1 -0
  135. package/dist/QueryCtx.d.ts +10 -0
  136. package/dist/QueryCtx.d.ts.map +1 -0
  137. package/dist/QueryCtx.js +18 -0
  138. package/dist/QueryCtx.js.map +1 -0
  139. package/dist/QueryInitializer.d.ts +75 -0
  140. package/dist/QueryInitializer.d.ts.map +1 -0
  141. package/dist/QueryInitializer.js +105 -0
  142. package/dist/QueryInitializer.js.map +1 -0
  143. package/dist/QueryRunner.d.ts +46 -0
  144. package/dist/QueryRunner.d.ts.map +1 -0
  145. package/dist/QueryRunner.js +30 -0
  146. package/dist/QueryRunner.js.map +1 -0
  147. package/dist/QueryStream.d.ts +678 -0
  148. package/dist/QueryStream.d.ts.map +1 -0
  149. package/dist/QueryStream.js +943 -0
  150. package/dist/QueryStream.js.map +1 -0
  151. package/dist/QueryStreamCursor.d.ts +39 -0
  152. package/dist/QueryStreamCursor.d.ts.map +1 -0
  153. package/dist/QueryStreamCursor.js +52 -0
  154. package/dist/QueryStreamCursor.js.map +1 -0
  155. package/dist/QueryStreamIndexPrefix.d.ts +48 -0
  156. package/dist/QueryStreamIndexPrefix.d.ts.map +1 -0
  157. package/dist/QueryStreamIndexPrefix.js +38 -0
  158. package/dist/QueryStreamIndexPrefix.js.map +1 -0
  159. package/dist/QueryStreamIndexRange.d.ts +193 -0
  160. package/dist/QueryStreamIndexRange.d.ts.map +1 -0
  161. package/dist/QueryStreamIndexRange.js +241 -0
  162. package/dist/QueryStreamIndexRange.js.map +1 -0
  163. package/dist/QueryStreamKey.d.ts +64 -0
  164. package/dist/QueryStreamKey.d.ts.map +1 -0
  165. package/dist/QueryStreamKey.js +69 -0
  166. package/dist/QueryStreamKey.js.map +1 -0
  167. package/dist/QueryStreamKeyBounds.d.ts +136 -0
  168. package/dist/QueryStreamKeyBounds.d.ts.map +1 -0
  169. package/dist/QueryStreamKeyBounds.js +208 -0
  170. package/dist/QueryStreamKeyBounds.js.map +1 -0
  171. package/dist/QueryStreamKeyLabels.d.ts +27 -0
  172. package/dist/QueryStreamKeyLabels.d.ts.map +1 -0
  173. package/dist/QueryStreamKeyLabels.js +22 -0
  174. package/dist/QueryStreamKeyLabels.js.map +1 -0
  175. package/dist/QueryStreamKeyLayout.d.ts +179 -0
  176. package/dist/QueryStreamKeyLayout.d.ts.map +1 -0
  177. package/dist/QueryStreamKeyLayout.js +167 -0
  178. package/dist/QueryStreamKeyLayout.js.map +1 -0
  179. package/dist/QueryStreamKeyValues.d.ts +40 -0
  180. package/dist/QueryStreamKeyValues.d.ts.map +1 -0
  181. package/dist/QueryStreamKeyValues.js +57 -0
  182. package/dist/QueryStreamKeyValues.js.map +1 -0
  183. package/dist/QueryStreamOrderDirection.d.ts +24 -0
  184. package/dist/QueryStreamOrderDirection.d.ts.map +1 -0
  185. package/dist/QueryStreamOrderDirection.js +11 -0
  186. package/dist/QueryStreamOrderDirection.js.map +1 -0
  187. package/dist/QueryStreamPagination.d.ts +264 -0
  188. package/dist/QueryStreamPagination.d.ts.map +1 -0
  189. package/dist/QueryStreamPagination.js +172 -0
  190. package/dist/QueryStreamPagination.js.map +1 -0
  191. package/dist/QueryStreamReadBudget.d.ts +63 -0
  192. package/dist/QueryStreamReadBudget.d.ts.map +1 -0
  193. package/dist/QueryStreamReadBudget.js +81 -0
  194. package/dist/QueryStreamReadBudget.js.map +1 -0
  195. package/dist/QueryTransactionContext.d.ts +16 -0
  196. package/dist/QueryTransactionContext.d.ts.map +1 -0
  197. package/dist/QueryTransactionContext.js +17 -0
  198. package/dist/QueryTransactionContext.js.map +1 -0
  199. package/dist/RegisteredConvexFunction.d.ts +359 -0
  200. package/dist/RegisteredConvexFunction.d.ts.map +1 -0
  201. package/dist/RegisteredConvexFunction.js +154 -0
  202. package/dist/RegisteredConvexFunction.js.map +1 -0
  203. package/dist/RegisteredFunction.d.ts +143 -0
  204. package/dist/RegisteredFunction.d.ts.map +1 -0
  205. package/dist/RegisteredFunction.js +125 -0
  206. package/dist/RegisteredFunction.js.map +1 -0
  207. package/dist/RegisteredFunctions.d.ts +57 -0
  208. package/dist/RegisteredFunctions.d.ts.map +1 -0
  209. package/dist/RegisteredFunctions.js +32 -0
  210. package/dist/RegisteredFunctions.js.map +1 -0
  211. package/dist/RegisteredNodeFunction.d.ts +11 -0
  212. package/dist/RegisteredNodeFunction.d.ts.map +1 -0
  213. package/dist/RegisteredNodeFunction.js +45 -0
  214. package/dist/RegisteredNodeFunction.js.map +1 -0
  215. package/dist/Registry.d.ts +12 -0
  216. package/dist/Registry.d.ts.map +1 -0
  217. package/dist/Registry.js +17 -0
  218. package/dist/Registry.js.map +1 -0
  219. package/dist/RegistryItems.d.ts +21 -0
  220. package/dist/RegistryItems.d.ts.map +1 -0
  221. package/dist/RegistryItems.js +27 -0
  222. package/dist/RegistryItems.js.map +1 -0
  223. package/dist/RequestMetadata.d.ts +12 -0
  224. package/dist/RequestMetadata.d.ts.map +1 -0
  225. package/dist/RequestMetadata.js +16 -0
  226. package/dist/RequestMetadata.js.map +1 -0
  227. package/dist/ResolvedMiddleware.d.ts +24 -0
  228. package/dist/ResolvedMiddleware.d.ts.map +1 -0
  229. package/dist/ResolvedMiddleware.js +34 -0
  230. package/dist/ResolvedMiddleware.js.map +1 -0
  231. package/dist/Scheduler.d.ts +31 -0
  232. package/dist/Scheduler.d.ts.map +1 -0
  233. package/dist/Scheduler.js +35 -0
  234. package/dist/Scheduler.js.map +1 -0
  235. package/dist/Storage.d.ts +22 -0
  236. package/dist/Storage.d.ts.map +1 -0
  237. package/dist/Storage.js +27 -0
  238. package/dist/Storage.js.map +1 -0
  239. package/dist/StorageActionWriter.d.ts +35 -0
  240. package/dist/StorageActionWriter.d.ts.map +1 -0
  241. package/dist/StorageActionWriter.js +24 -0
  242. package/dist/StorageActionWriter.js.map +1 -0
  243. package/dist/StorageReader.d.ts +26 -0
  244. package/dist/StorageReader.d.ts.map +1 -0
  245. package/dist/StorageReader.js +22 -0
  246. package/dist/StorageReader.js.map +1 -0
  247. package/dist/StorageWriter.d.ts +29 -0
  248. package/dist/StorageWriter.d.ts.map +1 -0
  249. package/dist/StorageWriter.js +24 -0
  250. package/dist/StorageWriter.js.map +1 -0
  251. package/dist/Table.d.ts +274 -0
  252. package/dist/Table.d.ts.map +1 -0
  253. package/dist/Table.js +70 -0
  254. package/dist/Table.js.map +1 -0
  255. package/dist/TableInfo.d.ts +44 -0
  256. package/dist/TableInfo.d.ts.map +1 -0
  257. package/dist/TableInfo.js +7 -0
  258. package/dist/TableInfo.js.map +1 -0
  259. package/dist/TransactionMetadata.d.ts +12 -0
  260. package/dist/TransactionMetadata.d.ts.map +1 -0
  261. package/dist/TransactionMetadata.js +16 -0
  262. package/dist/TransactionMetadata.js.map +1 -0
  263. package/dist/VectorSearch.d.ts +23 -0
  264. package/dist/VectorSearch.d.ts.map +1 -0
  265. package/dist/VectorSearch.js +17 -0
  266. package/dist/VectorSearch.js.map +1 -0
  267. package/dist/_virtual/_rolldown/runtime.js +13 -0
  268. package/dist/index.d.ts +88 -0
  269. package/dist/index.d.ts.map +1 -0
  270. package/dist/index.js +61 -0
  271. package/dist/internal/AiGatewayDecisionClient.d.ts +7 -0
  272. package/dist/internal/AiGatewayDecisionClient.d.ts.map +1 -0
  273. package/dist/internal/AiGatewayDecisionClient.js +19 -0
  274. package/dist/internal/AiGatewayDecisionClient.js.map +1 -0
  275. package/dist/internal/AiGatewayLanguageClient.d.ts +7 -0
  276. package/dist/internal/AiGatewayLanguageClient.d.ts.map +1 -0
  277. package/dist/internal/AiGatewayLanguageClient.js +19 -0
  278. package/dist/internal/AiGatewayLanguageClient.js.map +1 -0
  279. package/dist/internal/AiGatewayServiceToken.d.ts +46 -0
  280. package/dist/internal/AiGatewayServiceToken.d.ts.map +1 -0
  281. package/dist/internal/AiGatewayServiceToken.js +62 -0
  282. package/dist/internal/AiGatewayServiceToken.js.map +1 -0
  283. package/dist/internal/constants.d.ts +2 -0
  284. package/dist/internal/constants.d.ts.map +1 -0
  285. package/dist/internal/constants.js +6 -0
  286. package/dist/internal/constants.js.map +1 -0
  287. package/dist/internal/utils.d.ts +13 -0
  288. package/dist/internal/utils.d.ts.map +1 -0
  289. package/dist/internal/utils.js +50 -0
  290. package/dist/internal/utils.js.map +1 -0
  291. package/dist/node.d.ts +2 -0
  292. package/dist/node.d.ts.map +1 -0
  293. package/dist/node.js +1 -0
  294. package/package.json +68 -3
  295. package/src/ActionCtx.ts +45 -0
  296. package/src/ActionRunner.ts +36 -0
  297. package/src/AiGatewayDecisionClient.ts +40 -0
  298. package/src/AiGatewayDecisionModel.ts +46 -0
  299. package/src/AiGatewayLanguageClient.ts +41 -0
  300. package/src/AiGatewayLanguageModel.ts +61 -0
  301. package/src/Auth.ts +51 -0
  302. package/src/BlobNotFoundError.ts +12 -0
  303. package/src/Callback.ts +313 -0
  304. package/src/ComponentCtx.ts +192 -0
  305. package/src/ConvexConfigProvider.ts +39 -0
  306. package/src/ConvexFunctionDefinitions.ts +91 -0
  307. package/src/ConvexLogger.ts +43 -0
  308. package/src/CronJob.ts +42 -0
  309. package/src/CronJobs.ts +165 -0
  310. package/src/DataModel.ts +81 -0
  311. package/src/DatabaseReader.ts +118 -0
  312. package/src/DatabaseSchema.ts +139 -0
  313. package/src/DatabaseWriter.ts +232 -0
  314. package/src/Document.ts +146 -0
  315. package/src/ExecutionMetadata.ts +26 -0
  316. package/src/FunctionImpl.ts +96 -0
  317. package/src/FunctionRegistryItem.ts +85 -0
  318. package/src/GroupImpl.ts +167 -0
  319. package/src/GroupRegistry.ts +41 -0
  320. package/src/Handler.ts +191 -0
  321. package/src/HttpRouter.ts +388 -0
  322. package/src/MiddlewareImpl.ts +247 -0
  323. package/src/MiddlewareRegistryItem.ts +21 -0
  324. package/src/MutationCtx.ts +45 -0
  325. package/src/MutationRunner.ts +66 -0
  326. package/src/MutationTransactionContext.ts +48 -0
  327. package/src/OrderedQuery.ts +136 -0
  328. package/src/QueryCtx.ts +45 -0
  329. package/src/QueryInitializer.ts +537 -0
  330. package/src/QueryRunner.ts +91 -0
  331. package/src/QueryStream.ts +2476 -0
  332. package/src/QueryStreamCursor.ts +99 -0
  333. package/src/QueryStreamIndexPrefix.ts +79 -0
  334. package/src/QueryStreamIndexRange.ts +489 -0
  335. package/src/QueryStreamKey.ts +118 -0
  336. package/src/QueryStreamKeyBounds.ts +395 -0
  337. package/src/QueryStreamKeyLabels.ts +56 -0
  338. package/src/QueryStreamKeyLayout.ts +382 -0
  339. package/src/QueryStreamKeyValues.ts +112 -0
  340. package/src/QueryStreamOrderDirection.ts +29 -0
  341. package/src/QueryStreamPagination.ts +357 -0
  342. package/src/QueryStreamReadBudget.ts +167 -0
  343. package/src/QueryTransactionContext.ts +37 -0
  344. package/src/RegisteredConvexFunction.ts +415 -0
  345. package/src/RegisteredFunction.ts +391 -0
  346. package/src/RegisteredFunctions.ts +88 -0
  347. package/src/RegisteredNodeFunction.ts +120 -0
  348. package/src/Registry.ts +17 -0
  349. package/src/RegistryItems.ts +40 -0
  350. package/src/RequestMetadata.ts +20 -0
  351. package/src/ResolvedMiddleware.ts +70 -0
  352. package/src/Scheduler.ts +85 -0
  353. package/src/Storage.ts +37 -0
  354. package/src/StorageActionWriter.ts +59 -0
  355. package/src/StorageReader.ts +59 -0
  356. package/src/StorageWriter.ts +58 -0
  357. package/src/Table.ts +156 -0
  358. package/src/TableInfo.ts +106 -0
  359. package/src/TransactionMetadata.ts +20 -0
  360. package/src/VectorSearch.ts +75 -0
  361. package/src/index.ts +87 -0
  362. package/src/internal/AiGatewayDecisionClient.ts +16 -0
  363. package/src/internal/AiGatewayLanguageClient.ts +16 -0
  364. package/src/internal/AiGatewayServiceToken.ts +129 -0
  365. package/src/internal/constants.ts +1 -0
  366. package/src/internal/utils.ts +89 -0
  367. package/src/node.ts +1 -0
@@ -0,0 +1,943 @@
1
+ import { __exportAll } from "./_virtual/_rolldown/runtime.js";
2
+ import { decode } from "./Document.js";
3
+ import { make } from "./QueryStreamKeyLabels.js";
4
+ import { Equivalence, concat, format, fromIndex, rename, resolvePrefix, runtimeWidth } from "./QueryStreamKeyLayout.js";
5
+ import { complete, toPrefix, values } from "./QueryStreamKey.js";
6
+ import { Order as Order$1, extract } from "./QueryStreamKeyValues.js";
7
+ import { fromKeyLayout } from "./QueryStreamCursor.js";
8
+ import { flip } from "./QueryStreamOrderDirection.js";
9
+ import { fromStreamKey, keyValues } from "./QueryStreamIndexPrefix.js";
10
+ import { admittedByLower, admittedByUpper, forLayout, fromParsed, intersect, intersectIndexBounds, parse, parseBound, tightestLower, tightestParsedLower, tightestParsedUpper, tightestUpper, toBounds, unbounded } from "./QueryStreamKeyBounds.js";
11
+ import { apply, equalityPrefixLength, fromBounds, toBounds as toBounds$1 } from "./QueryStreamIndexRange.js";
12
+ import { EmptyInitialPageError, InvalidPageSizeError, Range, Start, finish, initial, parseRequest, record } from "./QueryStreamPagination.js";
13
+ import { InvalidReadLimitError, Limits, QueryStreamReadBudget, make as make$1 } from "./QueryStreamReadBudget.js";
14
+ import * as Effect from "effect/Effect";
15
+ import * as Schema from "effect/Schema";
16
+ import { dual, identity, pipe } from "effect/Function";
17
+ import * as Match from "effect/Match";
18
+ import * as Option from "effect/Option";
19
+ import { ConvexError } from "convex/values";
20
+ import * as Array from "effect/Array";
21
+ import * as Order from "effect/Order";
22
+ import * as Predicate from "effect/Predicate";
23
+ import * as Result from "effect/Result";
24
+ import * as Data from "effect/Data";
25
+ import * as Stream from "effect/Stream";
26
+ import { pipeArguments } from "effect/Pipeable";
27
+ import * as Chunk from "effect/Chunk";
28
+ import * as Filter from "effect/Filter";
29
+ import * as Pull from "effect/Pull";
30
+ import * as Sink from "effect/Sink";
31
+ import * as String from "effect/String";
32
+ import * as Tuple from "effect/Tuple";
33
+ //#region src/QueryStream.ts
34
+ var QueryStream_exports = /* @__PURE__ */ __exportAll({
35
+ Element: () => Element,
36
+ EmptyInitialPageError: () => EmptyInitialPageError,
37
+ IncompatibleStreamsError: () => IncompatibleStreamsError,
38
+ InnerStreamLayoutMismatchError: () => InnerStreamLayoutMismatchError,
39
+ InnerStreamOrderMismatchError: () => InnerStreamOrderMismatchError,
40
+ InvalidPageSizeError: () => InvalidPageSizeError,
41
+ InvalidReadLimitError: () => InvalidReadLimitError,
42
+ MissingReversalRecipeError: () => MissingReversalRecipeError,
43
+ NotUniqueError: () => NotUniqueError,
44
+ QueryStream: () => QueryStream,
45
+ ReadBudgetExceededError: () => ReadBudgetExceededError,
46
+ TypeId: () => TypeId,
47
+ distinct: () => distinct,
48
+ empty: () => empty,
49
+ filter: () => filter,
50
+ filterEffect: () => filterEffect,
51
+ flatMap: () => flatMap,
52
+ fromReflection: () => fromReflection,
53
+ isQueryStream: () => isQueryStream,
54
+ map: () => map,
55
+ mapEffect: () => mapEffect,
56
+ merge: () => merge,
57
+ narrow: () => narrow,
58
+ paginate: () => paginate,
59
+ renameKey: () => renameKey,
60
+ reverse: () => reverse,
61
+ unique: () => unique
62
+ });
63
+ /**
64
+ * A page exhausted its read budget without a safe logical continuation.
65
+ *
66
+ * @experimental
67
+ */
68
+ var ReadBudgetExceededError = class extends Schema.TaggedError()("ReadBudgetExceededError", {
69
+ rowsRead: Schema.Natural,
70
+ bytesRead: Schema.Natural
71
+ }) {
72
+ get message() {
73
+ return "The read budget was exhausted before a safe page boundary; increase the budget or simplify the query";
74
+ }
75
+ };
76
+ /**
77
+ * Thrown by `merge` when inputs have different directions, visible ordering
78
+ * labels, or implicit-ID positions. The payload identifies the expected and
79
+ * actual direction and layout; map and relabel compatible inputs before
80
+ * merging.
81
+ *
82
+ * @experimental
83
+ */
84
+ var IncompatibleStreamsError = class extends Data.TaggedError("IncompatibleStreamsError") {
85
+ get message() {
86
+ return `QueryStream.merge: all streams must share an order and key layout (got ${this.expectedOrderDirection} ${format(this.expectedKeyLayout)} and ${this.actualOrderDirection} ${format(this.actualKeyLayout)})`;
87
+ }
88
+ };
89
+ /**
90
+ * A `flatMap` inner stream runs in a different direction from its outer stream.
91
+ * The join dies with this error when it runs; `expectedOrderDirection` is the
92
+ * outer direction and `actualOrderDirection` is the inner direction.
93
+ *
94
+ * @experimental
95
+ */
96
+ var InnerStreamOrderMismatchError = class extends Data.TaggedError("InnerStreamOrderMismatchError") {
97
+ get message() {
98
+ return `QueryStream.flatMap: inner stream order (${this.actualOrderDirection}) differs from the outer stream's (${this.expectedOrderDirection})`;
99
+ }
100
+ };
101
+ /**
102
+ * A `flatMap` inner stream does not match the supplied `innerKeyLayout`,
103
+ * including visible labels and implicit-ID positions. The join dies with this
104
+ * error when it runs; the payload contains the expected and actual layouts.
105
+ *
106
+ * @experimental
107
+ */
108
+ var InnerStreamLayoutMismatchError = class extends Data.TaggedError("InnerStreamLayoutMismatchError") {
109
+ get message() {
110
+ return `QueryStream.flatMap: inner stream key layout (${format(this.actualKeyLayout)}) differs from innerKeyLayout (${format(this.expectedKeyLayout)})`;
111
+ }
112
+ };
113
+ /**
114
+ * Thrown by `reverse` when a manually constructed stream has no `reverseWith`
115
+ * recipe. Streams created through the table reader and `QueryStream`
116
+ * combinators support reversal.
117
+ *
118
+ * @experimental
119
+ */
120
+ var MissingReversalRecipeError = class extends Data.TaggedError("MissingReversalRecipeError") {
121
+ get message() {
122
+ return "QueryStream.reverse: this stream cannot be reversed without a reversal recipe";
123
+ }
124
+ };
125
+ /**
126
+ * Runtime identifier used to distinguish query streams from plain streams.
127
+ *
128
+ * @experimental
129
+ */
130
+ const TypeId = "~@confect/server/QueryStream";
131
+ /**
132
+ * A decoded value and its stored key. `doc: None` marks an element that was
133
+ * read but filtered out: it emits no value, but still advances cursors. Mapping
134
+ * a value does not recompute its key.
135
+ *
136
+ * @experimental
137
+ */
138
+ var Element = class extends Data.Class {};
139
+ /**
140
+ * An Effect `Stream` whose stored keys determine its order and pagination
141
+ * boundaries independently of its emitted values.
142
+ *
143
+ * TypeScript normally infers all five parameters from the table's `stream`
144
+ * method and subsequent composition:
145
+ *
146
+ * - `Doc` is the emitted value: a decoded document or a mapped or joined result.
147
+ * - `KeyLabels` is the branded readonly tuple of visible ordering names,
148
+ * initially the index fields not pinned by `eq`. `flatMap` appends labels and
149
+ * `renameKey` replaces them. Implicit ID tiebreakers are omitted from labels
150
+ * but retained in `keyLayout`.
151
+ * - `OrderDirection` is `"asc"` or `"desc"`; the type defaults to their union.
152
+ * - `E` contains typed failures while reading or transforming values. `never`
153
+ * means no typed failures, not no defects.
154
+ * - `R` contains Effect services required to run the stream. The stream retains
155
+ * the database access supplied at creation, so it doesn't require providing
156
+ * `DatabaseReader` again; effectful callbacks can add requirements.
157
+ *
158
+ * Known label or direction mismatches prevent merging at compile time. Runtime
159
+ * checks also compare implicit-ID positions. Reuse a compatible stream's
160
+ * `keyLayout` for `empty` or `flatMap`'s `innerKeyLayout`.
161
+ *
162
+ * Consume with Effect's `Stream.runCollect` or `Stream.runHead`, or use
163
+ * `unique` or `paginate`. A plain `Stream` transform such as `Stream.take`
164
+ * returns an ordinary stream that can be consumed but no longer merged or
165
+ * paginated with this module.
166
+ *
167
+ * @experimental
168
+ */
169
+ var QueryStream = class {
170
+ orderDirection;
171
+ keyLayout;
172
+ annotated;
173
+ reflection;
174
+ narrowWith;
175
+ reverseWith;
176
+ constructor(orderDirection, keyLayout, annotated, reflection, narrowWith, reverseWith) {
177
+ this.orderDirection = orderDirection;
178
+ this.keyLayout = keyLayout;
179
+ this.annotated = annotated;
180
+ this.reflection = reflection;
181
+ this.narrowWith = narrowWith;
182
+ this.reverseWith = reverseWith;
183
+ if (narrowWith !== void 0) this.narrowWith = (parsedBounds) => narrowWith(Result.getOrThrowWith(forLayout(keyLayout, parsedBounds), identity));
184
+ }
185
+ toStream() {
186
+ return Stream.unwrap(Effect.gen({ self: this }, function* () {
187
+ const readBudget = yield* Effect.serviceOption(QueryStreamReadBudget).pipe(Effect.flatMap(Option.match({
188
+ onNone: () => make$1({
189
+ maximumRowsRead: Option.none(),
190
+ maximumBytesRead: Option.none()
191
+ }),
192
+ onSome: Effect.succeed
193
+ })));
194
+ return Stream.filterMap(this.annotated, Filter.fromPredicateOption(({ doc }) => doc)).pipe(Stream.provideService(QueryStreamReadBudget, readBudget));
195
+ }));
196
+ }
197
+ };
198
+ const streamVariance = {
199
+ _R: identity,
200
+ _E: identity,
201
+ _A: identity
202
+ };
203
+ const queryStreamPrototype = QueryStream.prototype;
204
+ Object.defineProperties(queryStreamPrototype, {
205
+ [TypeId]: { value: TypeId },
206
+ [Stream.TypeId]: { value: streamVariance },
207
+ pipe: { value: function() {
208
+ return pipeArguments(this, arguments);
209
+ } },
210
+ channel: { get() {
211
+ return Stream.toChannel(this.toStream());
212
+ } }
213
+ });
214
+ /**
215
+ * Check whether a value retains query-stream ordering and pagination support.
216
+ * Plain `Stream` transforms return ordinary streams, for which this is false.
217
+ *
218
+ * @experimental
219
+ */
220
+ const isQueryStream = (u) => Predicate.hasProperty(u, TypeId);
221
+ /**
222
+ * Create a stream with no documents but a known key layout and direction. Use
223
+ * it when a dynamic list of streams is empty, since `merge` requires at least
224
+ * one input. The direction defaults to `"asc"`.
225
+ *
226
+ * Supply the document type in the first call, then reuse a compatible stream's
227
+ * layout: `QueryStream.empty<NotesDoc>()(source.keyLayout, "desc")`. Creating
228
+ * the source solely to obtain its layout does not read documents.
229
+ *
230
+ * @experimental
231
+ */
232
+ const empty = () => (keyLayout, orderDirection = "asc") => {
233
+ const make = (currentOrderDirection) => new QueryStream(currentOrderDirection, keyLayout, Stream.empty, void 0, () => make(currentOrderDirection), () => make(flip(currentOrderDirection)));
234
+ return make(orderDirection);
235
+ };
236
+ /**
237
+ * Create a reusable query stream from an index-query description. Prefer
238
+ * `reader.table(...).stream(...)` for inferred document and ordering types.
239
+ *
240
+ * Construction does not read documents. Each consuming run rebuilds the index
241
+ * queries within the supplied range and decodes their documents, failing with
242
+ * `DocumentDecodeError` if decoding fails. Key values come from encoded index
243
+ * values before decoding, with equality-pinned fields removed.
244
+ *
245
+ * @experimental
246
+ */
247
+ const fromReflection = (reflection) => makeLeaf(reflection, reflection.indexBounds === void 0 ? toBounds$1(reflection.indexRange) : intersectIndexBounds(toBounds$1(reflection.indexRange), reflection.indexBounds));
248
+ /**
249
+ * Complete the source index paths with Convex's implicit ID tiebreaker. These
250
+ * paths address the encoded document and are never ordering aliases.
251
+ */
252
+ const completeFieldPaths = (fieldPaths) => Option.exists(Array.last(fieldPaths), (fieldPath) => fieldPath === "_id") ? fieldPaths : Array.append(fieldPaths, "_id");
253
+ const makeLeaf = (reflection, indexBounds) => {
254
+ const fullFieldPaths = completeFieldPaths(reflection.indexFieldPaths);
255
+ const equalityPrefixLength$1 = equalityPrefixLength(reflection.indexRange);
256
+ const keyLayout = Result.getOrThrowWith(fromIndex(reflection.indexFieldPaths, equalityPrefixLength$1), identity);
257
+ const keyPaths = Array.map(Array.drop(fullFieldPaths, equalityPrefixLength$1), (fieldPath) => String.split(fieldPath, "."));
258
+ const equalityKeyValues = Array.take(indexBounds.lower.keyValues, equalityPrefixLength$1);
259
+ const indexRanges = Result.getOrThrowWith(fromBounds(fullFieldPaths, reflection.orderDirection, indexBounds), identity);
260
+ const encodedDocuments = Stream.fromIterable(indexRanges).pipe(Stream.flatMap((indexRange) => Stream.suspend(() => Stream.fromAsyncIterable(reflection.reader.query(reflection.table.tableName).withIndex(reflection.indexName, (q) => apply(indexRange, q)).order(reflection.orderDirection), identity).pipe(Stream.orDie))));
261
+ const annotated = Stream.unwrap(Effect.map(QueryStreamReadBudget, (readBudget) => readBudget.accountFor(encodedDocuments))).pipe(Stream.mapEffect((encoded) => Effect.map(decode(reflection.table)(encoded), (doc) => new Element({
262
+ doc: Option.some(doc),
263
+ keyValues: extract(encoded, keyPaths)
264
+ }))));
265
+ const toFullKeySpace = (bound) => ({
266
+ keyValues: keyValues(Result.getOrThrowWith(fromStreamKey(fullFieldPaths, equalityKeyValues, bound.key), identity)),
267
+ inclusive: bound.inclusive
268
+ });
269
+ return new QueryStream(reflection.orderDirection, keyLayout, annotated, {
270
+ ...reflection,
271
+ indexBounds
272
+ }, (parsedBounds) => makeLeaf(reflection, {
273
+ lower: Option.match(parsedBounds.lower, {
274
+ onNone: () => indexBounds.lower,
275
+ onSome: (bound) => tightestLower(indexBounds.lower, toFullKeySpace(bound))
276
+ }),
277
+ upper: Option.match(parsedBounds.upper, {
278
+ onNone: () => indexBounds.upper,
279
+ onSome: (bound) => tightestUpper(indexBounds.upper, toFullKeySpace(bound))
280
+ })
281
+ }), () => makeLeaf({
282
+ ...reflection,
283
+ orderDirection: flip(reflection.orderDirection)
284
+ }, indexBounds));
285
+ };
286
+ const MergeSource = Data.taggedEnum();
287
+ var MergeCandidate = class extends Data.Class {};
288
+ const fillMergeSource = (source) => MergeSource.$match(source, {
289
+ NeedsPull: ({ pull }) => pull.pipe(Effect.map((elements) => MergeSource.Buffered({
290
+ pull,
291
+ head: Array.headNonEmpty(elements),
292
+ tail: Chunk.fromIterable(Array.tailNonEmpty(elements))
293
+ })), Pull.catchDone(() => Effect.gen(function* () {
294
+ return (yield* (yield* QueryStreamReadBudget).isStopped) ? MergeSource.BudgetLimited() : MergeSource.Exhausted();
295
+ }))),
296
+ Buffered: () => Effect.succeed(source),
297
+ Exhausted: () => Effect.succeed(source),
298
+ BudgetLimited: () => Effect.succeed(source)
299
+ });
300
+ /**
301
+ * One step of the k-way merge as a pure unfold: fill every source, emit the
302
+ * earliest head (ties go to the earliest source, keeping the merge stable), and
303
+ * return the sources with that head consumed. `undefined` when every source is
304
+ * exhausted or an input stopped before its next key was known.
305
+ */
306
+ const mergeStep = (keyOrder) => (sources) => Effect.gen(function* () {
307
+ const readBudget = yield* QueryStreamReadBudget;
308
+ const filled = yield* Effect.forEach(sources, fillMergeSource, { concurrency: (yield* readBudget.isUnlimited) ? "unbounded" : 1 });
309
+ if (filled.some((source) => MergeSource.$is("BudgetLimited")(source))) return void 0;
310
+ const isEarlier = Order.isLessThan(keyOrder);
311
+ const earliest = Array.reduce(filled, Option.none(), (best, source, index) => Option.match(source._tag === "Buffered" ? Option.some(source.head) : Option.none(), {
312
+ onNone: () => best,
313
+ onSome: (head) => Option.match(best, {
314
+ onNone: () => Option.some(new MergeCandidate({
315
+ index,
316
+ element: head
317
+ })),
318
+ onSome: ({ element: bestElement }) => isEarlier(head.keyValues, bestElement.keyValues) ? Option.some(new MergeCandidate({
319
+ index,
320
+ element: head
321
+ })) : best
322
+ })
323
+ }));
324
+ return Option.getOrUndefined(Option.map(earliest, ({ index, element }) => Tuple.make(element, Array.map(filled, (source, sourceIndex) => sourceIndex === index && source._tag === "Buffered" ? Option.match(Chunk.head(source.tail), {
325
+ onNone: () => MergeSource.NeedsPull({ pull: source.pull }),
326
+ onSome: (head) => MergeSource.Buffered({
327
+ pull: source.pull,
328
+ head,
329
+ tail: Chunk.drop(source.tail, 1)
330
+ })
331
+ }) : source))));
332
+ });
333
+ /**
334
+ * Combine streams sharing a key layout into one stream in key order. Use this
335
+ * to query several index ranges at once, such as notes by multiple roles.
336
+ *
337
+ * The merge emits the smallest next key when ascending and the largest when
338
+ * descending. Unlike `Stream.merge`, it does not interleave by arrival time.
339
+ * Overlapping inputs are not deduplicated: a document matched twice appears
340
+ * twice. Supply at least one input; use `empty` for an empty dynamic list.
341
+ *
342
+ * Inputs need compatible document types and identical key layouts and
343
+ * directions. TypeScript rejects known mismatches; runtime mismatches throw
344
+ * `IncompatibleStreamsError` when combined. Map to a common value shape and use
345
+ * `renameKey` when compatible indexes have different field names.
346
+ *
347
+ * @experimental
348
+ */
349
+ const merge = (streams) => {
350
+ const head = Array.headNonEmpty(streams);
351
+ const incompatible = Array.findFirst(Array.tailNonEmpty(streams), (stream) => stream.orderDirection !== head.orderDirection || !Equivalence(stream.keyLayout, head.keyLayout));
352
+ if (Option.isSome(incompatible)) throw new IncompatibleStreamsError({
353
+ expectedOrderDirection: head.orderDirection,
354
+ actualOrderDirection: incompatible.value.orderDirection,
355
+ expectedKeyLayout: head.keyLayout,
356
+ actualKeyLayout: incompatible.value.keyLayout
357
+ });
358
+ return mergeUnchecked(streams);
359
+ };
360
+ /**
361
+ * `merge` without the compatibility check—for re-merging branches that were
362
+ * validated when the merge was built (narrowing never changes a branch's order
363
+ * or key layout).
364
+ */
365
+ const mergeUnchecked = (streams) => {
366
+ const head = Array.headNonEmpty(streams);
367
+ const annotated = Stream.unwrap(Effect.map(Effect.forEach(streams, (stream) => Stream.toPull(stream.annotated)), (pulls) => Stream.unfold(Array.map(pulls, (pull) => MergeSource.NeedsPull({ pull })), mergeStep(Order$1(head.orderDirection)))));
368
+ return new QueryStream(head.orderDirection, head.keyLayout, annotated, void 0, (parsedBounds) => mergeUnchecked([narrowByParsedBounds(head, parsedBounds), ...Array.map(Array.tailNonEmpty(streams), (stream) => narrowByParsedBounds(stream, parsedBounds))]), () => mergeUnchecked([reverse(head), ...Array.map(Array.tailNonEmpty(streams), (stream) => reverse(stream))]));
369
+ };
370
+ /**
371
+ * Derive a stream by transforming each present document into `Some` (keep,
372
+ * possibly changed) or `None` (drop). Key values are preserved and dropped
373
+ * elements stay in cursor accounting as read-but-filtered, so the result
374
+ * remains mergeable and paginable; narrowing narrows the input and re-applies
375
+ * the transform, so cursor bounds keep pushing down to leaves.
376
+ */
377
+ const transform = (self, f) => new QueryStream(self.orderDirection, self.keyLayout, Stream.map(self.annotated, ({ doc, keyValues }) => new Element({
378
+ doc: Option.flatMap(doc, f),
379
+ keyValues
380
+ })), void 0, (parsedBounds) => transform(narrowByParsedBounds(self, parsedBounds), f), () => transform(reverse(self), f));
381
+ /**
382
+ * The effectful {@link transform}.
383
+ */
384
+ const transformEffect = (self, f, options) => new QueryStream(self.orderDirection, self.keyLayout, Stream.mapEffect(self.annotated, ({ doc, keyValues }) => Option.match(doc, {
385
+ onNone: () => Effect.succeed(new Element({
386
+ doc: Option.none(),
387
+ keyValues
388
+ })),
389
+ onSome: (value) => Effect.map(f(value), (mapped) => new Element({
390
+ doc: mapped,
391
+ keyValues
392
+ }))
393
+ }), { concurrency: options?.concurrency }), void 0, (parsedBounds) => transformEffect(narrowByParsedBounds(self, parsedBounds), f, options), () => transformEffect(reverse(self), f, options));
394
+ /**
395
+ * Keep values that satisfy a pure predicate without changing their stored keys.
396
+ * Like `Stream.filter`, this removes emitted values, but it retains the
397
+ * ordering information needed to merge and paginate the result.
398
+ *
399
+ * Rejected documents still count as reads and advance cursors. Filtering before
400
+ * `distinct` selects each group's first matching document; filtering after it
401
+ * tests only the chosen representative. Use `filterEffect` for predicates that
402
+ * read another table, use a service, or fail with a typed error.
403
+ *
404
+ * @experimental
405
+ */
406
+ const filter = dual(2, (self, predicate) => transform(self, (doc) => predicate(doc) ? Option.some(doc) : Option.none()));
407
+ /**
408
+ * Keep values that satisfy an effectful predicate, preserving stored keys and
409
+ * cursor progress just like `filter`. The predicate can read other tables or
410
+ * use services; its errors and requirements become part of the stream's types.
411
+ *
412
+ * Effects run one document at a time by default. Pass `{ concurrency }` to run
413
+ * several at once while retaining stream order. Keep the predicate
414
+ * deterministic and read-only, since seeks and pagination can run it again.
415
+ * Separate lookups inside the predicate are not counted by pagination's read
416
+ * budgets.
417
+ *
418
+ * @experimental
419
+ */
420
+ const filterEffect = dual((args) => isQueryStream(args[0]), (self, predicate, options) => transformEffect(self, (doc) => Effect.map(predicate(doc), (keep) => keep ? Option.some(doc) : Option.none()), options));
421
+ /**
422
+ * Transform emitted values with a pure function while keeping their stored key
423
+ * values. The result retains merge and pagination support, unlike the plain
424
+ * stream returned by `Stream.map`.
425
+ *
426
+ * The mapper may replace any fields, including indexed fields, or return a
427
+ * different shape entirely. It does not recompute keys or sort by the new
428
+ * values: mapping note text to its length still orders by the original text,
429
+ * creation time, and ID, not by length. Preserve the input value rather than
430
+ * mutating it. Use `mapEffect` when the mapper needs an effect.
431
+ *
432
+ * @experimental
433
+ */
434
+ const map = dual(2, (self, f) => transform(self, (doc) => Option.some(f(doc))));
435
+ /**
436
+ * Transform emitted values with an effect, preserving the original stored keys
437
+ * just like `map`. The mapper may read another table or use services; its
438
+ * errors and requirements become part of the stream's types.
439
+ *
440
+ * Effects run one document at a time by default. Pass `{ concurrency }` for
441
+ * concurrent reads without changing output order. Keep the mapper deterministic
442
+ * and read-only: seeks, reversal, and pagination can reevaluate it. Separate
443
+ * lookups inside the mapper are not counted by pagination's read budgets.
444
+ *
445
+ * @experimental
446
+ */
447
+ const mapEffect = dual((args) => isQueryStream(args[0]), (self, f, options) => transformEffect(self, (doc) => Effect.asSome(f(doc)), options));
448
+ /**
449
+ * Run an inner query stream for each outer document and concatenate the
450
+ * results. Like sequential `Stream.flatMap`, each inner stream finishes before
451
+ * the next begins. The joined key is the outer key followed by the inner key,
452
+ * retaining both document IDs so equal timestamps remain distinguishable.
453
+ *
454
+ * Supply `options.innerKeyLayout` from a compatible stream's `keyLayout`. For
455
+ * example, comments indexed by `noteId` and pinned to a note have the same
456
+ * layout as comments ordered by creation time: one visible creation-time
457
+ * position followed by an implicit ID. Creating the template reads no
458
+ * documents. For nested joins or renamed streams, apply the same composition or
459
+ * renaming to the template before reusing its layout.
460
+ *
461
+ * The layout is required when constructing the joined stream, before any outer
462
+ * document is available to pass to `f`, including when the outer stream is
463
+ * empty. It determines the joined key positions and the width of empty-inner
464
+ * markers. It contains no query results or direction.
465
+ *
466
+ * Every inner stream must match that layout and the outer direction. TypeScript
467
+ * rejects known mismatches; others die with `InnerStreamOrderMismatchError` or
468
+ * `InnerStreamLayoutMismatchError` when the join runs.
469
+ *
470
+ * An empty inner stream emits no value by default, but leaves a filtered marker
471
+ * that advances cursors past its outer document. Pass `options.onEmpty` to emit
472
+ * `onEmpty(outer)` instead. The element type widens to include the placeholder,
473
+ * so map inner values to a common shape when needed. Its key is the outer key
474
+ * followed by null inner components, and pagination steps past it like any
475
+ * element. Outer documents filtered out before the join remain absent.
476
+ *
477
+ * Keep `f` and `onEmpty` deterministic and read-only. Pagination, narrowing,
478
+ * and reversal can reevaluate them; both outer and inner index reads count
479
+ * toward pagination's budgets.
480
+ *
481
+ * @experimental
482
+ */
483
+ const flatMap = dual(3, (self, f, options) => {
484
+ return makeFlatMap(self, f, options.innerKeyLayout, Option.fromUndefinedOr(options.onEmpty), {
485
+ lower: Option.none(),
486
+ upper: Option.none()
487
+ });
488
+ });
489
+ const FlatMapBound = Data.taggedEnum();
490
+ const combineLowerRefinements = (existing, incoming) => Option.orElse(Option.zipWith(existing, incoming, (left, right) => {
491
+ const ordering = Order$1("asc")(left.outerKeyValues, right.outerKeyValues);
492
+ return ordering > 0 ? left : ordering < 0 ? right : {
493
+ outerKeyValues: left.outerKeyValues,
494
+ innerParsedBound: Result.getOrThrowWith(tightestParsedLower(left.innerParsedBound, right.innerParsedBound), identity)
495
+ };
496
+ }), () => Option.orElse(existing, () => incoming));
497
+ const combineUpperRefinements = (existing, incoming) => Option.orElse(Option.zipWith(existing, incoming, (left, right) => {
498
+ const ordering = Order$1("asc")(left.outerKeyValues, right.outerKeyValues);
499
+ return ordering < 0 ? left : ordering > 0 ? right : {
500
+ outerKeyValues: left.outerKeyValues,
501
+ innerParsedBound: Result.getOrThrowWith(tightestParsedUpper(left.innerParsedBound, right.innerParsedBound), identity)
502
+ };
503
+ }), () => Option.orElse(existing, () => incoming));
504
+ const makeFlatMap = (self, f, innerKeyLayout, onEmpty, refinements) => {
505
+ const outerLength = runtimeWidth(self.keyLayout);
506
+ const keyLayout = concat(self.keyLayout, innerKeyLayout);
507
+ const emptyInnerKeyValues = Array.makeBy(runtimeWidth(innerKeyLayout), () => null);
508
+ const validated = (inner) => {
509
+ if (inner.orderDirection !== self.orderDirection) throw new InnerStreamOrderMismatchError({
510
+ expectedOrderDirection: self.orderDirection,
511
+ actualOrderDirection: inner.orderDirection
512
+ });
513
+ if (!Equivalence(inner.keyLayout, innerKeyLayout)) throw new InnerStreamLayoutMismatchError({
514
+ expectedKeyLayout: innerKeyLayout,
515
+ actualKeyLayout: inner.keyLayout
516
+ });
517
+ return inner;
518
+ };
519
+ const innerParsedBoundsFor = (outerKeyValues) => Result.getOrThrowWith(fromParsed(innerKeyLayout, {
520
+ lower: Option.map(Option.filter(refinements.lower, (refinement) => Order$1("asc")(outerKeyValues, refinement.outerKeyValues) === 0), (refinement) => refinement.innerParsedBound),
521
+ upper: Option.map(Option.filter(refinements.upper, (refinement) => Order$1("asc")(outerKeyValues, refinement.outerKeyValues) === 0), (refinement) => refinement.innerParsedBound)
522
+ }), identity);
523
+ const markerStream = (outerKeyValues, innerParsedBounds, doc) => {
524
+ const { aboveLower, belowUpper } = keyPredicates(innerParsedBounds);
525
+ return aboveLower(emptyInnerKeyValues) && belowUpper(emptyInnerKeyValues) ? Stream.succeed(new Element({
526
+ doc,
527
+ keyValues: Array.appendAll(outerKeyValues, emptyInnerKeyValues)
528
+ })) : Stream.empty;
529
+ };
530
+ const annotated = self.annotated.pipe(Stream.flatMap(({ doc: outerDoc, keyValues: outerKeyValues }) => {
531
+ const innerParsedBounds = innerParsedBoundsFor(outerKeyValues);
532
+ return Option.match(outerDoc, {
533
+ onNone: () => markerStream(outerKeyValues, innerParsedBounds, Option.none()),
534
+ onSome: (doc) => {
535
+ const inner = validated(f(doc));
536
+ return narrowByParsedBounds(inner, innerParsedBounds).annotated.pipe(Stream.map(({ doc: innerDoc, keyValues: innerKeyValues }) => new Element({
537
+ doc: innerDoc,
538
+ keyValues: Array.appendAll(outerKeyValues, innerKeyValues)
539
+ })), Stream.orElseIfEmpty(() => Stream.unwrap(Effect.gen(function* () {
540
+ const readBudget = yield* QueryStreamReadBudget;
541
+ if (yield* readBudget.isStopped) return Stream.empty;
542
+ const original = yield* Option.match(Option.gen(function* () {
543
+ yield* onEmpty;
544
+ return yield* Option.orElse(innerParsedBounds.lower, () => innerParsedBounds.upper);
545
+ }), {
546
+ onNone: () => Effect.succeed(Option.none()),
547
+ onSome: () => Stream.runHead(inner.annotated)
548
+ });
549
+ const isStopped = yield* readBudget.isStopped;
550
+ return Option.match(original, {
551
+ onSome: () => Stream.empty,
552
+ onNone: () => isStopped ? Stream.empty : markerStream(outerKeyValues, innerParsedBounds, Option.map(onEmpty, (makeEmpty) => makeEmpty(doc)))
553
+ });
554
+ }))));
555
+ }
556
+ });
557
+ }));
558
+ const split = (bound) => {
559
+ const keyValues = values(bound.key);
560
+ const { inclusive } = bound;
561
+ return keyValues.length <= outerLength ? FlatMapBound.Outer({
562
+ keyValues,
563
+ inclusive
564
+ }) : FlatMapBound.Inner({
565
+ outerKeyValues: Array.take(keyValues, outerLength),
566
+ innerParsedBound: Result.getOrThrowWith(parseBound(innerKeyLayout, {
567
+ keyValues: Array.drop(keyValues, outerLength),
568
+ inclusive
569
+ }), identity)
570
+ });
571
+ };
572
+ const outerBound = (bound) => FlatMapBound.$match(bound, {
573
+ Outer: ({ keyValues, inclusive }) => ({
574
+ keyValues,
575
+ inclusive
576
+ }),
577
+ Inner: ({ outerKeyValues }) => ({
578
+ keyValues: outerKeyValues,
579
+ inclusive: true
580
+ })
581
+ });
582
+ return new QueryStream(self.orderDirection, keyLayout, annotated, void 0, (parsedBounds) => {
583
+ const lower = Option.map(parsedBounds.lower, split);
584
+ const upper = Option.map(parsedBounds.upper, split);
585
+ return makeFlatMap(narrowByKeyBounds(self, {
586
+ lower: Option.map(lower, outerBound),
587
+ upper: Option.map(upper, outerBound)
588
+ }), f, innerKeyLayout, onEmpty, {
589
+ lower: combineLowerRefinements(refinements.lower, Option.filter(lower, FlatMapBound.$is("Inner"))),
590
+ upper: combineUpperRefinements(refinements.upper, Option.filter(upper, FlatMapBound.$is("Inner")))
591
+ });
592
+ }, () => makeFlatMap(reverse(self), (doc) => reverse(f(doc)), innerKeyLayout, onEmpty, refinements));
593
+ };
594
+ /**
595
+ * Keep the first document for each distinct value of a key prefix. Similar to
596
+ * `Stream.changes` on that prefix, this groups consecutive equal keys, but
597
+ * seeks past the rest of each group instead of scanning it.
598
+ *
599
+ * Pass a prefix of the visible ordering labels, such as `["text"]` for notes
600
+ * ordered by text and creation time. Prefix validity is checked by TypeScript
601
+ * and at runtime. On a `flatMap` result, a prefix reaching into the inner key
602
+ * also groups by the outer document, including its ID.
603
+ *
604
+ * Operation order controls representative selection. Filter before `distinct`
605
+ * to choose the first matching document, or after it to test only the selected
606
+ * representative. `reverse(distinct(q))` keeps those representatives and flips
607
+ * their output order; `distinct(reverse(q))` selects from the other direction.
608
+ *
609
+ * Narrowing after `distinct` filters the original representatives without
610
+ * selecting replacements. Narrowing before it constrains the input and can
611
+ * change the representatives. Preserving representatives may require extra
612
+ * reads outside output bounds and repeated callback evaluation.
613
+ *
614
+ * @experimental
615
+ */
616
+ const distinct = dual(2, (self, prefixNames) => {
617
+ return makeDistinct(self, Result.getOrThrowWith(resolvePrefix(self.keyLayout, make(prefixNames)), identity), self.orderDirection, unbounded(self.keyLayout));
618
+ });
619
+ /**
620
+ * Relabel visible key positions without changing values or their order. This
621
+ * does not sort or transform emitted documents.
622
+ *
623
+ * Use it to merge indexes or tables ordered by comparable values under
624
+ * different field names. For example, relabel comments ordered by `["body",
625
+ * "_creationTime"]` as `["text", "_creationTime"]` to merge with notes ordered
626
+ * by text. Map both streams to a common value shape first.
627
+ *
628
+ * Supply exactly as many replacement labels as the original visible labels. The
629
+ * values at corresponding positions must be comparable; relabeling does not
630
+ * establish that semantic compatibility for you. Implicit ID tiebreakers keep
631
+ * their positions. For joined streams, replacement labels cover the combined
632
+ * key, outer labels first.
633
+ *
634
+ * @experimental
635
+ */
636
+ const renameKey = dual(2, (self, replacementNames) => renameKeyImpl(self, make(replacementNames)));
637
+ const renameKeyImpl = (self, replacementKeyLabels) => {
638
+ const keyLayout = Result.getOrThrowWith(rename(self.keyLayout, replacementKeyLabels), identity);
639
+ return new QueryStream(self.orderDirection, keyLayout, self.annotated, void 0, (parsedBounds) => renameKeyImpl(narrowByKeyBounds(self, toBounds(parsedBounds)), replacementKeyLabels), () => renameKeyImpl(reverse(self), replacementKeyLabels));
640
+ };
641
+ const makeDistinct = (self, distinctLength, orderDirection, parsedBounds) => {
642
+ const afterKeyValues = (keyValues) => {
643
+ const pastGroup = {
644
+ keyValues,
645
+ inclusive: false
646
+ };
647
+ return orderDirection === "asc" ? {
648
+ lower: Option.some(pastGroup),
649
+ upper: Option.none()
650
+ } : {
651
+ lower: Option.none(),
652
+ upper: Option.some(pastGroup)
653
+ };
654
+ };
655
+ const groupBound = (bound) => Option.map(bound, ({ inclusive, key }) => ({
656
+ keyValues: Array.take(values(key), distinctLength),
657
+ inclusive: values(key).length > distinctLength || inclusive
658
+ }));
659
+ const { aboveLower, belowUpper } = keyPredicates(parsedBounds);
660
+ const isAdmitted = (keyValues) => aboveLower(keyValues) && belowUpper(keyValues);
661
+ const annotated = Stream.unwrap(Effect.map(QueryStreamReadBudget, (readBudget) => Stream.paginate(narrowByKeyBounds(orderDirection === self.orderDirection ? self : reverse(self), {
662
+ lower: groupBound(parsedBounds.lower),
663
+ upper: groupBound(parsedBounds.upper)
664
+ }), (current) => Effect.gen(function* () {
665
+ if (yield* readBudget.isStopped) return Tuple.make([], Option.none());
666
+ const discovered = yield* Stream.runHead(current.annotated);
667
+ if (Option.isNone(discovered)) return Tuple.make([], Option.none());
668
+ const element = discovered.value;
669
+ const { doc, keyValues } = element;
670
+ const prefixKeyValues = Array.take(keyValues, distinctLength);
671
+ if (orderDirection === self.orderDirection) {
672
+ const nextKeyValues = Option.match(doc, {
673
+ onNone: () => keyValues,
674
+ onSome: () => prefixKeyValues
675
+ });
676
+ return Tuple.make(isAdmitted(keyValues) ? [element] : [], Option.some(narrowByKeyBounds(current, afterKeyValues(nextKeyValues))));
677
+ }
678
+ const next = Option.some(narrowByKeyBounds(current, afterKeyValues(prefixKeyValues)));
679
+ const { firstKeyValues, selected } = yield* narrowByKeyBounds(self, {
680
+ lower: Option.some({
681
+ keyValues: prefixKeyValues,
682
+ inclusive: true
683
+ }),
684
+ upper: Option.some({
685
+ keyValues: prefixKeyValues,
686
+ inclusive: true
687
+ })
688
+ }).annotated.pipe(Stream.run(Sink.fold(() => ({
689
+ firstKeyValues: Option.none(),
690
+ selected: Option.none()
691
+ }), (probe) => Option.isNone(probe.selected), (probe, candidate) => Effect.succeed({
692
+ firstKeyValues: Option.orElse(probe.firstKeyValues, () => Option.some(candidate.keyValues)),
693
+ selected: Option.as(candidate.doc, candidate)
694
+ }))));
695
+ if (Option.isSome(selected)) {
696
+ const representative = selected.value;
697
+ return Tuple.make(isAdmitted(representative.keyValues) ? [representative] : [], next);
698
+ }
699
+ if (yield* readBudget.isStopped) return Tuple.make([], Option.none());
700
+ const checkpointKeyValues = Option.getOrElse(firstKeyValues, () => keyValues);
701
+ return Tuple.make(isAdmitted(checkpointKeyValues) ? [new Element({
702
+ doc: Option.none(),
703
+ keyValues: checkpointKeyValues
704
+ })] : [], next);
705
+ }))));
706
+ return new QueryStream(orderDirection, self.keyLayout, annotated, void 0, (incomingParsedBounds) => makeDistinct(self, distinctLength, orderDirection, Result.getOrThrowWith(intersect(parsedBounds, incomingParsedBounds), identity)), () => makeDistinct(self, distinctLength, flip(orderDirection), parsedBounds));
707
+ };
708
+ /**
709
+ * Run a composed query stream in the opposite direction without changing its
710
+ * key layout. Use this for bidirectional pagination: a reversed feed can load
711
+ * its earlier pages.
712
+ *
713
+ * Reversal uses index scans and seeks rather than collecting and reversing
714
+ * values. Merges, filters, maps, flat-maps (including their inner streams),
715
+ * distinct streams, renamed streams, and empty streams all support it.
716
+ *
717
+ * `reverse(distinct(q))` retains each group's original first representative and
718
+ * reverses their output order. `distinct(reverse(q))` instead chooses the first
719
+ * document from the other direction. Preserving representatives can require
720
+ * extra reads to discover groups and seek their original first documents.
721
+ *
722
+ * A manually constructed stream without `reverseWith` throws
723
+ * `MissingReversalRecipeError`.
724
+ *
725
+ * @experimental
726
+ */
727
+ const reverse = (self) => {
728
+ if (self.reverseWith === void 0) throw new MissingReversalRecipeError();
729
+ return self.reverseWith();
730
+ };
731
+ /**
732
+ * Restrict a stream to keys between `start` and `end`. Provide at least one
733
+ * endpoint, each with `keyValues` and a required `inclusive` flag; omit the
734
+ * other endpoint to leave that side unbounded.
735
+ *
736
+ * Endpoints follow stream order: `start` is the lower key when ascending and
737
+ * the upper key when descending. Repeated narrowing intersects existing bounds
738
+ * and can only restrict the range further.
739
+ *
740
+ * A key may be a prefix of the full key. An inclusive prefix includes every key
741
+ * extending it; an exclusive prefix excludes the whole group. For example,
742
+ * creation-time bounds can use `[startTime]` and `[endTime]` without trailing
743
+ * IDs. Equal endpoints produce an empty range unless both are inclusive, in
744
+ * which case they select that key or prefix group.
745
+ *
746
+ * Bounds are pushed into index ranges where that preserves the composition's
747
+ * results. On a distinct stream, full-key bounds filter original
748
+ * representatives without choosing replacements; prefix bounds include or
749
+ * exclude whole groups. This can require reads outside the output bounds. Apply
750
+ * bounds before `distinct` instead to constrain which documents can represent a
751
+ * group. Manually constructed streams without `narrowWith` are filtered in
752
+ * memory.
753
+ *
754
+ * For pagination, pass the previous `continueCursor` unchanged to `paginate`;
755
+ * do not decode a cursor into explicit bounds.
756
+ *
757
+ * @experimental
758
+ */
759
+ const narrow = dual(2, (self, narrowBounds) => {
760
+ const start = Option.fromUndefinedOr(narrowBounds.start);
761
+ const end = Option.fromUndefinedOr(narrowBounds.end);
762
+ const keyBounds = self.orderDirection === "asc" ? {
763
+ lower: start,
764
+ upper: end
765
+ } : {
766
+ lower: end,
767
+ upper: start
768
+ };
769
+ return narrowByKeyBounds(self, keyBounds);
770
+ });
771
+ const narrowByKeyBounds = (self, keyBounds) => {
772
+ const parsedBounds = Result.getOrThrowWith(parse(self.keyLayout, keyBounds), identity);
773
+ return narrowByParsedBounds(self, parsedBounds);
774
+ };
775
+ const narrowByParsedBounds = (self, parsedBounds) => {
776
+ const unbounded = Option.isNone(parsedBounds.lower) && Option.isNone(parsedBounds.upper);
777
+ if (!unbounded && self.narrowWith !== void 0) return self.narrowWith(parsedBounds);
778
+ Result.getOrThrowWith(forLayout(self.keyLayout, parsedBounds), identity);
779
+ return unbounded ? self : narrowInMemory(self, parsedBounds);
780
+ };
781
+ /**
782
+ * The fallback for streams that don't know how to rebuild themselves.
783
+ */
784
+ const keyPredicates = (parsedBounds) => {
785
+ const complete$1 = (keyValues) => Result.getOrThrowWith(complete(parsedBounds.keyLayout, keyValues), identity);
786
+ return {
787
+ aboveLower: (keyValues) => Result.getOrThrowWith(admittedByLower(parsedBounds)(complete$1(keyValues)), identity),
788
+ belowUpper: (keyValues) => Result.getOrThrowWith(admittedByUpper(parsedBounds)(complete$1(keyValues)), identity)
789
+ };
790
+ };
791
+ const narrowInMemory = (self, parsedBounds) => {
792
+ const { aboveLower, belowUpper } = keyPredicates(parsedBounds);
793
+ const dropOutOfRange = self.orderDirection === "asc" ? Stream.dropWhile(({ keyValues }) => !aboveLower(keyValues)) : Stream.dropWhile(({ keyValues }) => !belowUpper(keyValues));
794
+ const takeInRange = self.orderDirection === "asc" ? Stream.takeWhile(({ keyValues }) => belowUpper(keyValues)) : Stream.takeWhile(({ keyValues }) => aboveLower(keyValues));
795
+ return new QueryStream(self.orderDirection, self.keyLayout, pipe(self.annotated, dropOutOfRange, takeInRange), void 0, void 0, self.reverseWith === void 0 ? void 0 : () => narrowInMemory(reverse(self), parsedBounds));
796
+ };
797
+ /**
798
+ * `unique` found at least two emitted values. Narrow the query if at most one
799
+ * value was expected, or use another consumer to handle multiple results.
800
+ *
801
+ * @experimental
802
+ */
803
+ var NotUniqueError = class extends Schema.TaggedError()("NotUniqueError", {}) {
804
+ get message() {
805
+ return "Expected the query stream to contain at most one document";
806
+ }
807
+ };
808
+ /**
809
+ * Consume a stream expected to emit at most one value. The effect returns
810
+ * `None` for no values and `Some(value)` for one, or fails with
811
+ * `NotUniqueError` for two or more. Like `Stream.runHead` with a uniqueness
812
+ * check, it inspects at most two emitted values; finding them may read
813
+ * additional filtered documents.
814
+ *
815
+ * @experimental
816
+ */
817
+ const unique = Effect.fn("QueryStream.unique")((self) => self.pipe(Stream.take(2), Stream.runCollect, Effect.flatMap((docs) => docs.length >= 2 ? Effect.fail(new NotUniqueError()) : Effect.succeed(Array.head(docs)))));
818
+ /**
819
+ * Return an effect producing one page of a composed query stream. Start with
820
+ * `cursor: null`, then pass each returned `continueCursor` back unchanged until
821
+ * `isDone`. Cursors record key boundaries, not offsets or the last visible
822
+ * document: filtered elements can advance the cursor without entering `page`.
823
+ *
824
+ * `cursor` is exclusive and `endCursor` is inclusive, in stream order. Without
825
+ * an end boundary, `numItems` limits emitted values. With `endCursor`, the page
826
+ * covers the pinned range regardless of its item count, keeping adjacent
827
+ * reactive pages gap-free as data changes. See `PaginateOptions` for read
828
+ * limits and the special case of a zero-sized request.
829
+ *
830
+ * Bounds are pushed into underlying index queries where possible, but composed
831
+ * streams may read more documents than they return, including documents read on
832
+ * earlier pages. Budgets count filtered documents, distinct-group discovery,
833
+ * repeated seeks, merge prefetch, and both outer and inner query-stream reads
834
+ * in joins. Arbitrary I/O inside callbacks, such as a separate lookup in
835
+ * `mapEffect`, is not tracked.
836
+ *
837
+ * A budget-limited page returns `SplitRequired` at a safe logical boundary. If
838
+ * the budget prevents safe progress or an interior split of a pinned page, the
839
+ * effect fails with `ReadBudgetExceededError` rather than returning a
840
+ * non-advancing cursor. Increase the budget or reduce the reads needed for
841
+ * progress. See `PaginationResult` for split and completion handling.
842
+ *
843
+ * Malformed or incompatible cursors die with a `ConvexError` whose data is `{
844
+ * paginationError: "InvalidCursor" }`; Confect's pagination clients restart
845
+ * from the first page. Restart pagination whenever filters, ordering, or other
846
+ * query semantics change, even if an old cursor is still accepted.
847
+ *
848
+ * Cursors expose boundary field names and key values, including document IDs.
849
+ * They are neither opaque nor signed: clients can read or craft them. Do not
850
+ * publicly paginate over sensitive indexed fields unless pinned with `eq`.
851
+ * Never construct cursors from documents or decode them into `narrow` bounds.
852
+ *
853
+ * Return the whole result to reactive clients. React's
854
+ * `useStreamPaginatedQuery` handles pinning, splitting, and invalid-cursor
855
+ * resets; `usePaginatedQuery` does not support stream pages. Foldkit's
856
+ * `PaginatedQuery` also supports them.
857
+ *
858
+ * @experimental
859
+ */
860
+ const paginate = dual(2, Effect.fn("QueryStream.paginate")(function* (self, options) {
861
+ const cursorSchema = fromKeyLayout(self.keyLayout);
862
+ const encodeCursor = Schema.encodeEffect(cursorSchema);
863
+ const decodeCursor = Schema.decodeEffect(cursorSchema);
864
+ const complete$2 = (keyValues) => Result.getOrThrowWith(complete(self.keyLayout, keyValues), identity);
865
+ const decoded = yield* Effect.all({
866
+ start: Option.match(Option.fromNullOr(options.cursor), {
867
+ onNone: () => Effect.succeed(Start.Beginning()),
868
+ onSome: (cursor) => Effect.map(decodeCursor(cursor), (key) => Start.After({
869
+ cursor,
870
+ key
871
+ }))
872
+ }),
873
+ range: Option.match(Option.fromNullishOr(options.endCursor), {
874
+ onNone: () => Effect.succeed(Range.Unpinned()),
875
+ onSome: (cursor) => cursor === "[]" ? Effect.succeed(Range.ThroughEnd()) : Effect.map(decodeCursor(cursor), (key) => Range.ThroughKey({ key }))
876
+ })
877
+ }).pipe(Effect.catchTag("SchemaError", () => Effect.die(new ConvexError({ paginationError: "InvalidCursor" }))));
878
+ const request = yield* parseRequest(options.numItems, decoded.start, decoded.range).pipe(Effect.fromResult, Effect.catchTags({
879
+ InvalidPageSizeError: Effect.die,
880
+ EmptyInitialPageError: Effect.die
881
+ }));
882
+ if (request._tag === "Unchanged") return {
883
+ page: [],
884
+ isDone: false,
885
+ continueCursor: request.cursor
886
+ };
887
+ const start = Option.map(request.after, (key) => ({
888
+ key: toPrefix(key),
889
+ inclusive: false
890
+ }));
891
+ const end = Range.$match(request.range, {
892
+ Unpinned: () => Option.none(),
893
+ ThroughEnd: () => Option.none(),
894
+ ThroughKey: ({ key }) => Option.some({
895
+ key: toPrefix(key),
896
+ inclusive: true
897
+ })
898
+ });
899
+ const narrowed = narrowByParsedBounds(self, Result.getOrThrowWith(fromParsed(self.keyLayout, self.orderDirection === "asc" ? {
900
+ lower: start,
901
+ upper: end
902
+ } : {
903
+ lower: end,
904
+ upper: start
905
+ }), identity));
906
+ const readBudget = yield* QueryStreamReadBudget;
907
+ const collected = yield* Stream.run(narrowed.annotated, Sink.fold(() => initial(), (state) => state._tag === "Reading", (state, { doc, keyValues }) => Effect.map(readBudget.isExhausted, (hitLimit) => record(request, state, doc, complete$2(keyValues), hitLimit))));
908
+ const stopped = yield* readBudget.isStopped;
909
+ const outcome = finish(request, collected, stopped);
910
+ if (Result.isFailure(outcome)) return yield* new ReadBudgetExceededError(yield* readBudget.getReadCounts);
911
+ const encode = (key) => encodeCursor(key).pipe(Effect.catchTag("SchemaError", Effect.die));
912
+ const encodeSplit = (result) => Effect.gen(function* () {
913
+ const continueCursor = yield* Match.value(result.continuation).pipe(Match.tagsExhaustive({
914
+ End: () => Effect.succeed("[]"),
915
+ Key: ({ key }) => encode(key)
916
+ }));
917
+ return {
918
+ page: Array.fromIterable(result.page),
919
+ isDone: false,
920
+ continueCursor,
921
+ pageStatus: result._tag,
922
+ splitCursor: yield* encode(result.splitKey)
923
+ };
924
+ });
925
+ return yield* Match.value(outcome.success).pipe(Match.tagsExhaustive({
926
+ Done: ({ page }) => Effect.succeed({
927
+ page: Array.fromIterable(page),
928
+ isDone: true,
929
+ continueCursor: "[]"
930
+ }),
931
+ Continue: ({ page, key }) => Effect.map(encode(key), (continueCursor) => ({
932
+ page: Array.fromIterable(page),
933
+ isDone: false,
934
+ continueCursor
935
+ })),
936
+ SplitRequired: encodeSplit,
937
+ SplitRecommended: encodeSplit
938
+ }));
939
+ }, (effect, _self, options) => Effect.provideServiceEffect(effect, QueryStreamReadBudget, Schema.decodeEffect(Limits)(options).pipe(Effect.catchTag("SchemaError", (cause) => Effect.die(new InvalidReadLimitError({ cause }))), Effect.flatMap(make$1)))));
940
+ //#endregion
941
+ export { Element, EmptyInitialPageError, IncompatibleStreamsError, InnerStreamLayoutMismatchError, InnerStreamOrderMismatchError, InvalidPageSizeError, InvalidReadLimitError, MissingReversalRecipeError, NotUniqueError, QueryStream, QueryStream_exports, ReadBudgetExceededError, TypeId, distinct, empty, filter, filterEffect, flatMap, fromReflection, isQueryStream, map, mapEffect, merge, narrow, paginate, renameKey, reverse, unique };
942
+
943
+ //# sourceMappingURL=QueryStream.js.map