joist-core 2.3.0-next.97 → 2.3.0-next.98

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 (580) hide show
  1. package/build/EntityManager.cjs +45 -46
  2. package/build/EntityManager.cjs.map +1 -1
  3. package/build/EntityManager.d.cts +7 -7
  4. package/build/EntityManager.d.mts +7 -7
  5. package/build/EntityManager.js +27 -28
  6. package/build/EntityManager.js.map +1 -1
  7. package/build/EntityMetadata.cjs +0 -2
  8. package/build/EntityMetadata.cjs.map +1 -1
  9. package/build/EntityMetadata.d.cts +3 -3
  10. package/build/EntityMetadata.d.mts +3 -3
  11. package/build/EntityMetadata.js +0 -2
  12. package/build/EntityMetadata.js.map +1 -1
  13. package/build/IndexManager.cjs +1 -1
  14. package/build/IndexManager.js +1 -1
  15. package/build/PluginManager.cjs +0 -1
  16. package/build/PluginManager.cjs.map +1 -1
  17. package/build/PluginManager.d.cts +1 -1
  18. package/build/PluginManager.d.mts +1 -1
  19. package/build/PluginManager.js +0 -1
  20. package/build/PluginManager.js.map +1 -1
  21. package/build/batchloaders/enumCollectionBatchLoader.cjs +1 -1
  22. package/build/batchloaders/enumCollectionBatchLoader.d.cts +1 -1
  23. package/build/batchloaders/enumCollectionBatchLoader.d.mts +1 -1
  24. package/build/batchloaders/enumCollectionBatchLoader.js +1 -1
  25. package/build/batchloaders/loadBatchLoader.cjs +3 -4
  26. package/build/batchloaders/loadBatchLoader.cjs.map +1 -1
  27. package/build/batchloaders/loadBatchLoader.d.cts +1 -1
  28. package/build/batchloaders/loadBatchLoader.d.mts +1 -1
  29. package/build/batchloaders/loadBatchLoader.js +2 -3
  30. package/build/batchloaders/loadBatchLoader.js.map +1 -1
  31. package/build/batchloaders/manyToManyBatchLoader.cjs +1 -1
  32. package/build/batchloaders/manyToManyBatchLoader.d.cts +1 -1
  33. package/build/batchloaders/manyToManyBatchLoader.d.mts +1 -1
  34. package/build/batchloaders/manyToManyBatchLoader.js +1 -1
  35. package/build/batchloaders/oneToManyBatchLoader.cjs +1 -1
  36. package/build/batchloaders/oneToManyBatchLoader.js +1 -1
  37. package/build/batchloaders/oneToOneBatchLoader.cjs +1 -1
  38. package/build/batchloaders/oneToOneBatchLoader.js +1 -1
  39. package/build/batchloaders/populateBatchLoader.cjs +11 -12
  40. package/build/batchloaders/populateBatchLoader.cjs.map +1 -1
  41. package/build/batchloaders/populateBatchLoader.d.cts +1 -1
  42. package/build/batchloaders/populateBatchLoader.d.mts +1 -1
  43. package/build/batchloaders/populateBatchLoader.js +7 -8
  44. package/build/batchloaders/populateBatchLoader.js.map +1 -1
  45. package/build/batchloaders/recursiveChildrenBatchLoader.cjs +2 -2
  46. package/build/batchloaders/recursiveChildrenBatchLoader.js +2 -2
  47. package/build/batchloaders/recursiveM2mBatchLoader.cjs +2 -2
  48. package/build/batchloaders/recursiveM2mBatchLoader.js +2 -2
  49. package/build/batchloaders/recursiveParentsBatchLoader.cjs +2 -2
  50. package/build/batchloaders/recursiveParentsBatchLoader.js +2 -2
  51. package/build/changes.cjs +2 -3
  52. package/build/changes.cjs.map +1 -1
  53. package/build/changes.js +2 -3
  54. package/build/changes.js.map +1 -1
  55. package/build/config.cjs +3 -3
  56. package/build/config.cjs.map +1 -1
  57. package/build/config.d.cts +2 -2
  58. package/build/config.d.mts +2 -2
  59. package/build/config.js +1 -1
  60. package/build/config.js.map +1 -1
  61. package/build/configure.cjs +10 -10
  62. package/build/configure.cjs.map +1 -1
  63. package/build/configure.js +5 -5
  64. package/build/configure.js.map +1 -1
  65. package/build/dataloaders/fastWhereFilterHash.cjs +8 -8
  66. package/build/dataloaders/fastWhereFilterHash.cjs.map +1 -1
  67. package/build/dataloaders/fastWhereFilterHash.d.cts.map +1 -1
  68. package/build/dataloaders/fastWhereFilterHash.d.mts.map +1 -1
  69. package/build/dataloaders/fastWhereFilterHash.js +3 -3
  70. package/build/dataloaders/fastWhereFilterHash.js.map +1 -1
  71. package/build/dataloaders/findByUniqueDataLoader.cjs.map +1 -1
  72. package/build/dataloaders/findByUniqueDataLoader.js.map +1 -1
  73. package/build/dataloaders/findCountDataLoader.cjs +2 -2
  74. package/build/dataloaders/findCountDataLoader.cjs.map +1 -1
  75. package/build/dataloaders/findCountDataLoader.js +1 -1
  76. package/build/dataloaders/findCountDataLoader.js.map +1 -1
  77. package/build/dataloaders/findDataLoader.cjs +6 -6
  78. package/build/dataloaders/findDataLoader.cjs.map +1 -1
  79. package/build/dataloaders/findDataLoader.d.cts +1 -1
  80. package/build/dataloaders/findDataLoader.d.mts +1 -1
  81. package/build/dataloaders/findDataLoader.js +3 -3
  82. package/build/dataloaders/findDataLoader.js.map +1 -1
  83. package/build/dataloaders/findIdsDataLoader.cjs +3 -3
  84. package/build/dataloaders/findIdsDataLoader.cjs.map +1 -1
  85. package/build/dataloaders/findIdsDataLoader.js +2 -2
  86. package/build/dataloaders/findIdsDataLoader.js.map +1 -1
  87. package/build/dataloaders/findOrCreateDataLoader.cjs +1 -1
  88. package/build/dataloaders/findOrCreateDataLoader.js +1 -1
  89. package/build/dataloaders/findPaginatedDataLoader.cjs +6 -6
  90. package/build/dataloaders/findPaginatedDataLoader.cjs.map +1 -1
  91. package/build/dataloaders/findPaginatedDataLoader.d.cts +1 -1
  92. package/build/dataloaders/findPaginatedDataLoader.d.mts +1 -1
  93. package/build/dataloaders/findPaginatedDataLoader.js +3 -3
  94. package/build/dataloaders/findPaginatedDataLoader.js.map +1 -1
  95. package/build/dataloaders/lensDataLoader.cjs +3 -3
  96. package/build/dataloaders/lensDataLoader.cjs.map +1 -1
  97. package/build/dataloaders/lensDataLoader.js +2 -2
  98. package/build/dataloaders/lensDataLoader.js.map +1 -1
  99. package/build/dataloaders/manyToManyFindDataLoader.cjs +1 -1
  100. package/build/dataloaders/manyToManyFindDataLoader.js +1 -1
  101. package/build/dataloaders/oneToManyFindDataLoader.cjs +1 -1
  102. package/build/dataloaders/oneToManyFindDataLoader.js +1 -1
  103. package/build/defaults.cjs +5 -5
  104. package/build/defaults.cjs.map +1 -1
  105. package/build/defaults.d.cts +1 -1
  106. package/build/defaults.d.mts +1 -1
  107. package/build/defaults.js +4 -4
  108. package/build/defaults.js.map +1 -1
  109. package/build/drivers/Driver.cjs +0 -1
  110. package/build/drivers/Driver.d.cts +1 -1
  111. package/build/drivers/Driver.d.mts +1 -1
  112. package/build/drivers/Driver.js +0 -1
  113. package/build/drivers/EntityWriter.cjs +6 -7
  114. package/build/drivers/EntityWriter.cjs.map +1 -1
  115. package/build/drivers/EntityWriter.d.cts +1 -1
  116. package/build/drivers/EntityWriter.d.mts +1 -1
  117. package/build/drivers/EntityWriter.js +2 -3
  118. package/build/drivers/EntityWriter.js.map +1 -1
  119. package/build/drivers/IdAssigner.cjs +0 -1
  120. package/build/drivers/IdAssigner.cjs.map +1 -1
  121. package/build/drivers/IdAssigner.d.cts +1 -1
  122. package/build/drivers/IdAssigner.d.mts +1 -1
  123. package/build/drivers/IdAssigner.js +0 -1
  124. package/build/drivers/IdAssigner.js.map +1 -1
  125. package/build/drivers/driverApi.cjs +19 -0
  126. package/build/drivers/driverApi.cjs.map +1 -0
  127. package/build/drivers/driverApi.d.cts +22 -0
  128. package/build/drivers/driverApi.d.cts.map +1 -0
  129. package/build/drivers/driverApi.d.mts +22 -0
  130. package/build/drivers/driverApi.d.mts.map +1 -0
  131. package/build/drivers/driverApi.js +18 -0
  132. package/build/drivers/driverApi.js.map +1 -0
  133. package/build/fields.cjs +3 -3
  134. package/build/fields.cjs.map +1 -1
  135. package/build/fields.js +2 -2
  136. package/build/fields.js.map +1 -1
  137. package/build/{FlushLock.cjs → flush/FlushLock.cjs} +1 -1
  138. package/build/flush/FlushLock.cjs.map +1 -0
  139. package/build/{FlushLock.d.cts → flush/FlushLock.d.cts} +1 -1
  140. package/build/flush/FlushLock.d.cts.map +1 -0
  141. package/build/{FlushLock.d.mts → flush/FlushLock.d.mts} +1 -1
  142. package/build/flush/FlushLock.d.mts.map +1 -0
  143. package/build/{FlushLock.js → flush/FlushLock.js} +1 -1
  144. package/build/flush/FlushLock.js.map +1 -0
  145. package/build/{JoinRows.cjs → flush/JoinRows.cjs} +5 -8
  146. package/build/flush/JoinRows.cjs.map +1 -0
  147. package/build/{JoinRows.d.cts → flush/JoinRows.d.cts} +5 -5
  148. package/build/flush/JoinRows.d.cts.map +1 -0
  149. package/build/{JoinRows.d.mts → flush/JoinRows.d.mts} +5 -5
  150. package/build/flush/JoinRows.d.mts.map +1 -0
  151. package/build/{JoinRows.js → flush/JoinRows.js} +5 -8
  152. package/build/flush/JoinRows.js.map +1 -0
  153. package/build/{PendingChanges.cjs → flush/PendingChanges.cjs} +0 -1
  154. package/build/{PendingChanges.d.cts → flush/PendingChanges.d.cts} +2 -2
  155. package/build/flush/PendingChanges.d.cts.map +1 -0
  156. package/build/{PendingChanges.d.mts → flush/PendingChanges.d.mts} +2 -2
  157. package/build/flush/PendingChanges.d.mts.map +1 -0
  158. package/build/flush/PendingChanges.js +1 -0
  159. package/build/{Todo.cjs → flush/Todo.cjs} +4 -6
  160. package/build/flush/Todo.cjs.map +1 -0
  161. package/build/{Todo.d.cts → flush/Todo.d.cts} +3 -3
  162. package/build/flush/Todo.d.cts.map +1 -0
  163. package/build/{Todo.d.mts → flush/Todo.d.mts} +3 -3
  164. package/build/flush/Todo.d.mts.map +1 -0
  165. package/build/{Todo.js → flush/Todo.js} +4 -6
  166. package/build/flush/Todo.js.map +1 -0
  167. package/build/index.cjs +99 -99
  168. package/build/index.cjs.map +1 -1
  169. package/build/index.d.cts +15 -15
  170. package/build/index.d.mts +15 -15
  171. package/build/index.js +41 -41
  172. package/build/index.js.map +1 -1
  173. package/build/json.cjs +4 -4
  174. package/build/json.cjs.map +1 -1
  175. package/build/json.js +3 -3
  176. package/build/json.js.map +1 -1
  177. package/build/keys.cjs +1 -1
  178. package/build/keys.js +1 -1
  179. package/build/{HintTree.cjs → loading/HintTree.cjs} +2 -5
  180. package/build/loading/HintTree.cjs.map +1 -0
  181. package/build/{HintTree.d.cts → loading/HintTree.d.cts} +3 -3
  182. package/build/loading/HintTree.d.cts.map +1 -0
  183. package/build/{HintTree.d.mts → loading/HintTree.d.mts} +3 -3
  184. package/build/loading/HintTree.d.mts.map +1 -0
  185. package/build/{HintTree.js → loading/HintTree.js} +2 -5
  186. package/build/loading/HintTree.js.map +1 -0
  187. package/build/{IsLoadedCache.cjs → loading/IsLoadedCache.cjs} +2 -3
  188. package/build/loading/IsLoadedCache.cjs.map +1 -0
  189. package/build/{IsLoadedCache.d.cts → loading/IsLoadedCache.d.cts} +2 -2
  190. package/build/loading/IsLoadedCache.d.cts.map +1 -0
  191. package/build/{IsLoadedCache.d.mts → loading/IsLoadedCache.d.mts} +2 -2
  192. package/build/loading/IsLoadedCache.d.mts.map +1 -0
  193. package/build/{IsLoadedCache.js → loading/IsLoadedCache.js} +2 -3
  194. package/build/loading/IsLoadedCache.js.map +1 -0
  195. package/build/{loadHints.cjs → loading/loadHints.cjs} +6 -11
  196. package/build/loading/loadHints.cjs.map +1 -0
  197. package/build/{loadHints.d.cts → loading/loadHints.d.cts} +14 -14
  198. package/build/loading/loadHints.d.cts.map +1 -0
  199. package/build/{loadHints.d.mts → loading/loadHints.d.mts} +14 -14
  200. package/build/loading/loadHints.d.mts.map +1 -0
  201. package/build/{loadHints.js → loading/loadHints.js} +3 -8
  202. package/build/loading/loadHints.js.map +1 -0
  203. package/build/{loadLens.cjs → loading/loadLens.cjs} +8 -9
  204. package/build/loading/loadLens.cjs.map +1 -0
  205. package/build/{loadLens.d.cts → loading/loadLens.d.cts} +3 -3
  206. package/build/loading/loadLens.d.cts.map +1 -0
  207. package/build/{loadLens.d.mts → loading/loadLens.d.mts} +3 -3
  208. package/build/loading/loadLens.d.mts.map +1 -0
  209. package/build/{loadLens.js → loading/loadLens.js} +8 -9
  210. package/build/loading/loadLens.js.map +1 -0
  211. package/build/{withLoaded.cjs → loading/withLoaded.cjs} +12 -13
  212. package/build/loading/withLoaded.cjs.map +1 -0
  213. package/build/{withLoaded.d.cts → loading/withLoaded.d.cts} +9 -9
  214. package/build/loading/withLoaded.d.cts.map +1 -0
  215. package/build/{withLoaded.d.mts → loading/withLoaded.d.mts} +9 -9
  216. package/build/loading/withLoaded.d.mts.map +1 -0
  217. package/build/{withLoaded.js → loading/withLoaded.js} +10 -11
  218. package/build/loading/withLoaded.js.map +1 -0
  219. package/build/logging/ReactionLogger.cjs +0 -2
  220. package/build/logging/ReactionLogger.cjs.map +1 -1
  221. package/build/logging/ReactionLogger.d.cts +2 -2
  222. package/build/logging/ReactionLogger.d.mts +2 -2
  223. package/build/logging/ReactionLogger.js +0 -2
  224. package/build/logging/ReactionLogger.js.map +1 -1
  225. package/build/newTestInstance.cjs +3 -3
  226. package/build/newTestInstance.cjs.map +1 -1
  227. package/build/newTestInstance.d.cts +1 -1
  228. package/build/newTestInstance.d.mts +1 -1
  229. package/build/newTestInstance.js +2 -2
  230. package/build/newTestInstance.js.map +1 -1
  231. package/build/normalizeHints.cjs +0 -2
  232. package/build/normalizeHints.cjs.map +1 -1
  233. package/build/normalizeHints.d.cts +2 -2
  234. package/build/normalizeHints.d.mts +2 -2
  235. package/build/normalizeHints.js +0 -2
  236. package/build/normalizeHints.js.map +1 -1
  237. package/build/nowUTC.cjs +2 -2
  238. package/build/nowUTC.cjs.map +1 -1
  239. package/build/nowUTC.d.cts +1 -1
  240. package/build/nowUTC.d.mts +1 -1
  241. package/build/nowUTC.js +1 -1
  242. package/build/nowUTC.js.map +1 -1
  243. package/build/plugins/PreloadPlugin.cjs +0 -2
  244. package/build/plugins/PreloadPlugin.d.cts +2 -2
  245. package/build/plugins/PreloadPlugin.d.mts +2 -2
  246. package/build/plugins/PreloadPlugin.js +0 -2
  247. package/build/preloading/JsonAggregatePreloader.cjs +1 -4
  248. package/build/preloading/JsonAggregatePreloader.cjs.map +1 -1
  249. package/build/preloading/JsonAggregatePreloader.d.cts +2 -2
  250. package/build/preloading/JsonAggregatePreloader.d.mts +2 -2
  251. package/build/preloading/JsonAggregatePreloader.js +1 -4
  252. package/build/preloading/JsonAggregatePreloader.js.map +1 -1
  253. package/build/preloading/partitionHint.cjs +2 -3
  254. package/build/preloading/partitionHint.cjs.map +1 -1
  255. package/build/preloading/partitionHint.d.cts +1 -1
  256. package/build/preloading/partitionHint.d.mts +1 -1
  257. package/build/preloading/partitionHint.js +2 -3
  258. package/build/preloading/partitionHint.js.map +1 -1
  259. package/build/queries/ConditionBuilder.cjs.map +1 -1
  260. package/build/queries/ConditionBuilder.d.cts +1 -1
  261. package/build/queries/ConditionBuilder.d.mts +1 -1
  262. package/build/queries/ConditionBuilder.js.map +1 -1
  263. package/build/queries/find/Aliases.cjs +1 -1
  264. package/build/queries/find/Aliases.cjs.map +1 -1
  265. package/build/queries/find/Aliases.js +1 -1
  266. package/build/queries/find/Aliases.js.map +1 -1
  267. package/build/queries/find/QueryParser.cjs +1 -1
  268. package/build/queries/find/QueryParser.js +1 -1
  269. package/build/queries/find/scopes.cjs.map +1 -1
  270. package/build/queries/find/scopes.d.cts +1 -1
  271. package/build/queries/find/scopes.d.mts +1 -1
  272. package/build/queries/find/scopes.js.map +1 -1
  273. package/build/queries/sql/Expr.cjs +2 -2
  274. package/build/queries/sql/Expr.cjs.map +1 -1
  275. package/build/queries/sql/Expr.d.cts +1 -1
  276. package/build/queries/sql/Expr.d.mts +1 -1
  277. package/build/queries/sql/Expr.js +1 -1
  278. package/build/queries/sql/Expr.js.map +1 -1
  279. package/build/queries/sql/Tables.cjs +1 -1
  280. package/build/queries/sql/Tables.cjs.map +1 -1
  281. package/build/queries/sql/Tables.js +1 -1
  282. package/build/queries/sql/Tables.js.map +1 -1
  283. package/build/queries/sql/execute.cjs +1 -1
  284. package/build/queries/sql/execute.cjs.map +1 -1
  285. package/build/queries/sql/execute.js +1 -1
  286. package/build/queries/sql/execute.js.map +1 -1
  287. package/build/queries/sql/expressions/codecs.cjs +2 -2
  288. package/build/queries/sql/expressions/codecs.cjs.map +1 -1
  289. package/build/queries/sql/expressions/codecs.js +1 -1
  290. package/build/queries/sql/expressions/codecs.js.map +1 -1
  291. package/build/queries/sql/expressions/expression.cjs.map +1 -1
  292. package/build/queries/sql/expressions/expression.js.map +1 -1
  293. package/build/queries/sql/query.cjs.map +1 -1
  294. package/build/queries/sql/query.d.cts +1 -1
  295. package/build/queries/sql/query.d.mts +1 -1
  296. package/build/queries/sql/query.js.map +1 -1
  297. package/build/{unnest.cjs → queries/unnest.cjs} +1 -2
  298. package/build/queries/unnest.cjs.map +1 -0
  299. package/build/{unnest.d.cts → queries/unnest.d.cts} +3 -3
  300. package/build/queries/unnest.d.cts.map +1 -0
  301. package/build/{unnest.d.mts → queries/unnest.d.mts} +3 -3
  302. package/build/queries/unnest.d.mts.map +1 -0
  303. package/build/{unnest.js → queries/unnest.js} +1 -2
  304. package/build/queries/unnest.js.map +1 -0
  305. package/build/queries/valueFilters.cjs.map +1 -1
  306. package/build/queries/valueFilters.d.cts +1 -1
  307. package/build/queries/valueFilters.d.mts +1 -1
  308. package/build/queries/valueFilters.js.map +1 -1
  309. package/build/{ReactionsManager.cjs → reactivity/ReactionsManager.cjs} +8 -10
  310. package/build/reactivity/ReactionsManager.cjs.map +1 -0
  311. package/build/{ReactionsManager.d.cts → reactivity/ReactionsManager.d.cts} +5 -6
  312. package/build/reactivity/ReactionsManager.d.cts.map +1 -0
  313. package/build/{ReactionsManager.d.mts → reactivity/ReactionsManager.d.mts} +5 -6
  314. package/build/reactivity/ReactionsManager.d.mts.map +1 -0
  315. package/build/{ReactionsManager.js → reactivity/ReactionsManager.js} +6 -8
  316. package/build/reactivity/ReactionsManager.js.map +1 -0
  317. package/build/{reactiveHints.cjs → reactivity/reactiveHints.cjs} +12 -16
  318. package/build/reactivity/reactiveHints.cjs.map +1 -0
  319. package/build/{reactiveHints.d.cts → reactivity/reactiveHints.d.cts} +17 -17
  320. package/build/reactivity/reactiveHints.d.cts.map +1 -0
  321. package/build/{reactiveHints.d.mts → reactivity/reactiveHints.d.mts} +17 -17
  322. package/build/reactivity/reactiveHints.d.mts.map +1 -0
  323. package/build/{reactiveHints.js → reactivity/reactiveHints.js} +12 -16
  324. package/build/reactivity/reactiveHints.js.map +1 -0
  325. package/build/relations/AsyncReactiveField.cjs +6 -6
  326. package/build/relations/AsyncReactiveField.cjs.map +1 -1
  327. package/build/relations/AsyncReactiveField.d.cts +1 -1
  328. package/build/relations/AsyncReactiveField.d.mts +1 -1
  329. package/build/relations/AsyncReactiveField.js +4 -4
  330. package/build/relations/AsyncReactiveField.js.map +1 -1
  331. package/build/relations/Collection.cjs +1 -1
  332. package/build/relations/Collection.js +1 -1
  333. package/build/relations/CustomCollection.d.cts +1 -1
  334. package/build/relations/CustomCollection.d.mts +1 -1
  335. package/build/relations/CustomReference.cjs +1 -1
  336. package/build/relations/CustomReference.d.cts +1 -1
  337. package/build/relations/CustomReference.d.mts +1 -1
  338. package/build/relations/CustomReference.js +1 -1
  339. package/build/relations/EnumCollection.d.cts +1 -1
  340. package/build/relations/EnumCollection.d.mts +1 -1
  341. package/build/relations/LazyField.cjs +4 -4
  342. package/build/relations/LazyField.js +4 -4
  343. package/build/relations/ManyToManyCollection.cjs +3 -3
  344. package/build/relations/ManyToManyCollection.js +3 -3
  345. package/build/relations/ManyToManyLargeCollection.cjs +3 -3
  346. package/build/relations/ManyToManyLargeCollection.js +3 -3
  347. package/build/relations/ManyToOneReference.cjs +4 -4
  348. package/build/relations/ManyToOneReference.js +4 -4
  349. package/build/relations/OneToManyCollection.cjs +1 -2
  350. package/build/relations/OneToManyCollection.cjs.map +1 -1
  351. package/build/relations/OneToManyCollection.d.cts +1 -1
  352. package/build/relations/OneToManyCollection.d.mts +1 -1
  353. package/build/relations/OneToManyCollection.js +1 -2
  354. package/build/relations/OneToManyCollection.js.map +1 -1
  355. package/build/relations/OneToManyLargeCollection.cjs +1 -1
  356. package/build/relations/OneToManyLargeCollection.js +1 -1
  357. package/build/relations/OneToOneReference.cjs +5 -5
  358. package/build/relations/OneToOneReference.js +5 -5
  359. package/build/relations/PolymorphicReference.cjs +3 -3
  360. package/build/relations/PolymorphicReference.js +3 -3
  361. package/build/relations/ReactiveField.cjs +5 -6
  362. package/build/relations/ReactiveField.cjs.map +1 -1
  363. package/build/relations/ReactiveField.d.cts +2 -2
  364. package/build/relations/ReactiveField.d.mts +2 -2
  365. package/build/relations/ReactiveField.js +3 -4
  366. package/build/relations/ReactiveField.js.map +1 -1
  367. package/build/relations/ReactiveGetter.cjs +0 -1
  368. package/build/relations/ReactiveGetter.cjs.map +1 -1
  369. package/build/relations/ReactiveGetter.d.cts +1 -1
  370. package/build/relations/ReactiveGetter.d.mts +1 -1
  371. package/build/relations/ReactiveGetter.js +0 -1
  372. package/build/relations/ReactiveGetter.js.map +1 -1
  373. package/build/relations/ReactiveManyToMany.cjs +5 -6
  374. package/build/relations/ReactiveManyToMany.cjs.map +1 -1
  375. package/build/relations/ReactiveManyToMany.d.cts +2 -2
  376. package/build/relations/ReactiveManyToMany.d.cts.map +1 -1
  377. package/build/relations/ReactiveManyToMany.d.mts +2 -2
  378. package/build/relations/ReactiveManyToMany.d.mts.map +1 -1
  379. package/build/relations/ReactiveManyToMany.js +3 -4
  380. package/build/relations/ReactiveManyToMany.js.map +1 -1
  381. package/build/relations/ReactiveManyToManyOtherSide.cjs +1 -3
  382. package/build/relations/ReactiveManyToManyOtherSide.cjs.map +1 -1
  383. package/build/relations/ReactiveManyToManyOtherSide.d.cts +2 -2
  384. package/build/relations/ReactiveManyToManyOtherSide.d.mts +2 -2
  385. package/build/relations/ReactiveManyToManyOtherSide.js +1 -3
  386. package/build/relations/ReactiveManyToManyOtherSide.js.map +1 -1
  387. package/build/relations/ReactiveReference.cjs +8 -9
  388. package/build/relations/ReactiveReference.cjs.map +1 -1
  389. package/build/relations/ReactiveReference.d.cts +2 -2
  390. package/build/relations/ReactiveReference.d.cts.map +1 -1
  391. package/build/relations/ReactiveReference.d.mts +2 -2
  392. package/build/relations/ReactiveReference.d.mts.map +1 -1
  393. package/build/relations/ReactiveReference.js +6 -7
  394. package/build/relations/ReactiveReference.js.map +1 -1
  395. package/build/relations/RecursiveCollection.cjs +3 -4
  396. package/build/relations/RecursiveCollection.cjs.map +1 -1
  397. package/build/relations/RecursiveCollection.d.cts +1 -1
  398. package/build/relations/RecursiveCollection.d.mts +1 -1
  399. package/build/relations/RecursiveCollection.js +3 -4
  400. package/build/relations/RecursiveCollection.js.map +1 -1
  401. package/build/relations/Reference.cjs +1 -1
  402. package/build/relations/Reference.js +1 -1
  403. package/build/relations/hasAsyncMethod.cjs +2 -2
  404. package/build/relations/hasAsyncMethod.cjs.map +1 -1
  405. package/build/relations/hasAsyncMethod.d.cts +1 -1
  406. package/build/relations/hasAsyncMethod.d.mts +1 -1
  407. package/build/relations/hasAsyncMethod.js +1 -1
  408. package/build/relations/hasAsyncMethod.js.map +1 -1
  409. package/build/relations/hasManyDerived.cjs +3 -3
  410. package/build/relations/hasManyDerived.cjs.map +1 -1
  411. package/build/relations/hasManyDerived.d.cts +1 -1
  412. package/build/relations/hasManyDerived.d.mts +1 -1
  413. package/build/relations/hasManyDerived.js +2 -2
  414. package/build/relations/hasManyDerived.js.map +1 -1
  415. package/build/relations/hasManyThrough.cjs +6 -6
  416. package/build/relations/hasManyThrough.cjs.map +1 -1
  417. package/build/relations/hasManyThrough.d.cts +1 -1
  418. package/build/relations/hasManyThrough.d.mts +1 -1
  419. package/build/relations/hasManyThrough.js +2 -2
  420. package/build/relations/hasOneDerived.cjs +3 -3
  421. package/build/relations/hasOneDerived.cjs.map +1 -1
  422. package/build/relations/hasOneDerived.d.cts +1 -1
  423. package/build/relations/hasOneDerived.d.mts +1 -1
  424. package/build/relations/hasOneDerived.js +2 -2
  425. package/build/relations/hasOneDerived.js.map +1 -1
  426. package/build/relations/hasOneThrough.cjs +7 -7
  427. package/build/relations/hasOneThrough.cjs.map +1 -1
  428. package/build/relations/hasOneThrough.d.cts +1 -1
  429. package/build/relations/hasOneThrough.d.mts +1 -1
  430. package/build/relations/hasOneThrough.js +2 -2
  431. package/build/relations/hasProperty.cjs +4 -4
  432. package/build/relations/hasProperty.cjs.map +1 -1
  433. package/build/relations/hasProperty.d.cts +2 -2
  434. package/build/relations/hasProperty.d.mts +2 -2
  435. package/build/relations/hasProperty.js +2 -2
  436. package/build/relations/hasProperty.js.map +1 -1
  437. package/build/relations/index.cjs +10 -10
  438. package/build/relations/index.js +10 -10
  439. package/build/rules.cjs +3 -4
  440. package/build/rules.cjs.map +1 -1
  441. package/build/rules.d.cts +1 -1
  442. package/build/rules.d.mts +1 -1
  443. package/build/rules.js +3 -4
  444. package/build/rules.js.map +1 -1
  445. package/build/{TypeInfo.cjs → serde/TypeInfo.cjs} +1 -1
  446. package/build/serde/TypeInfo.cjs.map +1 -0
  447. package/build/{TypeInfo.d.cts → serde/TypeInfo.d.cts} +2 -2
  448. package/build/serde/TypeInfo.d.cts.map +1 -0
  449. package/build/{TypeInfo.d.mts → serde/TypeInfo.d.mts} +2 -2
  450. package/build/serde/TypeInfo.d.mts.map +1 -0
  451. package/build/{TypeInfo.js → serde/TypeInfo.js} +1 -1
  452. package/build/serde/TypeInfo.js.map +1 -0
  453. package/build/{columns.cjs → serde/columns.cjs} +1 -1
  454. package/build/serde/columns.cjs.map +1 -0
  455. package/build/{columns.d.cts → serde/columns.d.cts} +2 -2
  456. package/build/serde/columns.d.cts.map +1 -0
  457. package/build/{columns.d.mts → serde/columns.d.mts} +2 -2
  458. package/build/serde/columns.d.mts.map +1 -0
  459. package/build/{columns.js → serde/columns.js} +1 -1
  460. package/build/serde/columns.js.map +1 -0
  461. package/build/{fieldSerde.cjs → serde/fieldSerde.cjs} +6 -6
  462. package/build/serde/fieldSerde.cjs.map +1 -0
  463. package/build/{fieldSerde.d.cts → serde/fieldSerde.d.cts} +5 -5
  464. package/build/serde/fieldSerde.d.cts.map +1 -0
  465. package/build/{fieldSerde.d.mts → serde/fieldSerde.d.mts} +5 -5
  466. package/build/serde/fieldSerde.d.mts.map +1 -0
  467. package/build/{fieldSerde.js → serde/fieldSerde.js} +6 -6
  468. package/build/serde/fieldSerde.js.map +1 -0
  469. package/build/{serde.cjs → serde/serde.cjs} +25 -26
  470. package/build/serde/serde.cjs.map +1 -0
  471. package/build/{serde.d.cts → serde/serde.d.cts} +1 -1
  472. package/build/serde/serde.d.cts.map +1 -0
  473. package/build/{serde.d.mts → serde/serde.d.mts} +1 -1
  474. package/build/serde/serde.d.mts.map +1 -0
  475. package/build/{serde.js → serde/serde.js} +4 -5
  476. package/build/serde/serde.js.map +1 -0
  477. package/build/{temporal.cjs → serde/temporal.cjs} +1 -1
  478. package/build/serde/temporal.cjs.map +1 -0
  479. package/build/{temporal.d.cts → serde/temporal.d.cts} +1 -1
  480. package/build/serde/temporal.d.cts.map +1 -0
  481. package/build/{temporal.d.mts → serde/temporal.d.mts} +1 -1
  482. package/build/serde/temporal.d.mts.map +1 -0
  483. package/build/{temporal.js → serde/temporal.js} +1 -1
  484. package/build/serde/temporal.js.map +1 -0
  485. package/build/{temporalMappers.cjs → serde/temporalMappers.cjs} +4 -5
  486. package/build/serde/temporalMappers.cjs.map +1 -0
  487. package/build/{temporalMappers.d.cts → serde/temporalMappers.d.cts} +1 -1
  488. package/build/serde/temporalMappers.d.cts.map +1 -0
  489. package/build/{temporalMappers.d.mts → serde/temporalMappers.d.mts} +1 -1
  490. package/build/serde/temporalMappers.d.mts.map +1 -0
  491. package/build/{temporalMappers.js → serde/temporalMappers.js} +2 -3
  492. package/build/serde/temporalMappers.js.map +1 -0
  493. package/build/upsert.cjs +1 -1
  494. package/build/upsert.js +1 -1
  495. package/build/utils.cjs +0 -1
  496. package/build/utils.cjs.map +1 -1
  497. package/build/utils.d.cts +1 -1
  498. package/build/utils.d.mts +1 -1
  499. package/build/utils.js +0 -1
  500. package/build/utils.js.map +1 -1
  501. package/package.json +2 -2
  502. package/build/FlushLock.cjs.map +0 -1
  503. package/build/FlushLock.d.cts.map +0 -1
  504. package/build/FlushLock.d.mts.map +0 -1
  505. package/build/FlushLock.js.map +0 -1
  506. package/build/HintTree.cjs.map +0 -1
  507. package/build/HintTree.d.cts.map +0 -1
  508. package/build/HintTree.d.mts.map +0 -1
  509. package/build/HintTree.js.map +0 -1
  510. package/build/IsLoadedCache.cjs.map +0 -1
  511. package/build/IsLoadedCache.d.cts.map +0 -1
  512. package/build/IsLoadedCache.d.mts.map +0 -1
  513. package/build/IsLoadedCache.js.map +0 -1
  514. package/build/JoinRows.cjs.map +0 -1
  515. package/build/JoinRows.d.cts.map +0 -1
  516. package/build/JoinRows.d.mts.map +0 -1
  517. package/build/JoinRows.js.map +0 -1
  518. package/build/PendingChanges.d.cts.map +0 -1
  519. package/build/PendingChanges.d.mts.map +0 -1
  520. package/build/PendingChanges.js +0 -2
  521. package/build/ReactionsManager.cjs.map +0 -1
  522. package/build/ReactionsManager.d.cts.map +0 -1
  523. package/build/ReactionsManager.d.mts.map +0 -1
  524. package/build/ReactionsManager.js.map +0 -1
  525. package/build/Todo.cjs.map +0 -1
  526. package/build/Todo.d.cts.map +0 -1
  527. package/build/Todo.d.mts.map +0 -1
  528. package/build/Todo.js.map +0 -1
  529. package/build/TypeInfo.cjs.map +0 -1
  530. package/build/TypeInfo.d.cts.map +0 -1
  531. package/build/TypeInfo.d.mts.map +0 -1
  532. package/build/TypeInfo.js.map +0 -1
  533. package/build/columns.cjs.map +0 -1
  534. package/build/columns.d.cts.map +0 -1
  535. package/build/columns.d.mts.map +0 -1
  536. package/build/columns.js.map +0 -1
  537. package/build/driverApi.cjs +0 -18
  538. package/build/driverApi.cjs.map +0 -1
  539. package/build/driverApi.d.cts +0 -22
  540. package/build/driverApi.d.cts.map +0 -1
  541. package/build/driverApi.d.mts +0 -22
  542. package/build/driverApi.d.mts.map +0 -1
  543. package/build/driverApi.js +0 -18
  544. package/build/driverApi.js.map +0 -1
  545. package/build/fieldSerde.cjs.map +0 -1
  546. package/build/fieldSerde.d.cts.map +0 -1
  547. package/build/fieldSerde.d.mts.map +0 -1
  548. package/build/fieldSerde.js.map +0 -1
  549. package/build/loadHints.cjs.map +0 -1
  550. package/build/loadHints.d.cts.map +0 -1
  551. package/build/loadHints.d.mts.map +0 -1
  552. package/build/loadHints.js.map +0 -1
  553. package/build/loadLens.cjs.map +0 -1
  554. package/build/loadLens.d.cts.map +0 -1
  555. package/build/loadLens.d.mts.map +0 -1
  556. package/build/loadLens.js.map +0 -1
  557. package/build/reactiveHints.cjs.map +0 -1
  558. package/build/reactiveHints.d.cts.map +0 -1
  559. package/build/reactiveHints.d.mts.map +0 -1
  560. package/build/reactiveHints.js.map +0 -1
  561. package/build/serde.cjs.map +0 -1
  562. package/build/serde.d.cts.map +0 -1
  563. package/build/serde.d.mts.map +0 -1
  564. package/build/serde.js.map +0 -1
  565. package/build/temporal.cjs.map +0 -1
  566. package/build/temporal.d.cts.map +0 -1
  567. package/build/temporal.d.mts.map +0 -1
  568. package/build/temporal.js.map +0 -1
  569. package/build/temporalMappers.cjs.map +0 -1
  570. package/build/temporalMappers.d.cts.map +0 -1
  571. package/build/temporalMappers.d.mts.map +0 -1
  572. package/build/temporalMappers.js.map +0 -1
  573. package/build/unnest.cjs.map +0 -1
  574. package/build/unnest.d.cts.map +0 -1
  575. package/build/unnest.d.mts.map +0 -1
  576. package/build/unnest.js.map +0 -1
  577. package/build/withLoaded.cjs.map +0 -1
  578. package/build/withLoaded.d.cts.map +0 -1
  579. package/build/withLoaded.d.mts.map +0 -1
  580. package/build/withLoaded.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"loadLens.cjs","names":["isEntity","getMetadata","lensDataLoader","appendStack","AbstractRelationImpl","isProperty"],"sources":["../src/loadLens.ts"],"sourcesContent":["import { lensDataLoader } from \"./dataloaders/lensDataLoader.ts\";\nimport { type Entity, isEntity } from \"./Entity.ts\";\nimport { appendStack } from \"./EntityManager.ts\";\nimport {\n type EntityMetadata,\n type Field,\n type ManyToManyField,\n type ManyToOneField,\n type OneToManyField,\n type OneToOneField,\n type PrimitiveField,\n getMetadata,\n} from \"./EntityMetadata.ts\";\nimport { type LoadHint } from \"./loadHints.ts\";\nimport { AbstractRelationImpl } from \"./relations/AbstractRelationImpl.ts\";\nimport { isProperty } from \"./relations/index.ts\";\n\n/** Generically matches on a Reference/Collection's load method. */\ntype LoadLike<U> = { load(): Promise<U> };\n\n/** Generically matches a property or zero-arg method that returns a promise. */\ntype PromiseFnLike<U> = () => PromiseLike<U>;\n\n/**\n * Given a parent type `R` (that is our current lens \"return type\", i.e. `Author` or `Author | undefined` or `Author[]`),\n * and the type `V` of the \"next step\" of the traversal (i.e. itself `Book` or `Book | undefined` or `Book[]`, depending\n * on the relation being traversed), returns `V` mapped to \"the right format\" based on `R`.\n *\n * I.e.:\n *\n * - `Author | undefined` that navigates a `Book` will become `Book | undefined`\n * - `Author` that navigates a `Book | undefined` will also become `Book | undefined`\n * - `Author[]` that navigates a `Book | undefined` will become a `Book[]`\n * - `Author | undefined` that navigates a `Book[]` will become a `Book[]`\n */\n// The extra `[]` around `V` and `ReadonlyArray<any>` are to keep the type as `Array<Foo | undefined>`\n// instead of `Foo[] | undefined[]`.\n// When `P extends ReadonlyArray, i.e. we're in flatMap mode, we're also in filter undefined mode.\ntype MaybeArray<R, V> =\n R extends ReadonlyArray<any>\n ? [V] extends [ReadonlyArray<infer U>]\n ? DropUndefined<U>[]\n : DropUndefined<V>[]\n : V extends ReadonlyArray<any>\n ? V\n : [R] extends [undefined]\n ? V | undefined\n : V;\n\n// ([R] extends [undefined]) ? (V) : V;\n\n/** Given a type T that we come across in the path, de-array it to continue our flatMap-ish semantics. */\ntype MaybeDropArray<T> = T extends ReadonlyArray<infer U> ? U : T;\n\ntype DropUndefined<T> = Exclude<T, undefined>;\n\n/**\n * A type for declaratively walking the object graph.\n *\n * This is not technically a Lens that can `get/set`, but the idea is generally the same.\n *\n * `T` is the type we're on, i.e. when `T = Author` we can do `.firstName` or `.lastName.\n * `R` is either a `T` or `T[]` or `T | undefined` and just captures whether we've hit a\n * list at any point in the lens navigation path.\n */\nexport type Lens<T, R = T> = {\n [P in keyof T]: T[P] extends LoadLike<infer U>\n ? Lens<MaybeDropArray<DropUndefined<U>>, MaybeArray<R, U>>\n : T[P] extends PromiseFnLike<infer U>\n ? Lens<MaybeDropArray<DropUndefined<U>>, MaybeArray<R, U>>\n : Lens<MaybeDropArray<DropUndefined<T[P]>>, MaybeArray<R, T[P]>>;\n};\n\n/**\n * Allows declaratively loading/traversing several layers of references at once.\n *\n * I.e.:\n *\n * ```typescript\n * const publisher = await book.load(b => b.author.publisher);\n * ```\n */\n// For some reason accepting Lens<this, this> does not work when called from within the entity\n// subclass itself, so we use the codegen hammer in our subclass to force the right Lens type\n// in a .load stub that just calls us for the implementation.\nexport async function loadLens<T extends Entity, U, V>(\n start: T | readonly T[],\n fn: (lens: Lens<T>) => Lens<U, V>,\n opts: { forceReload?: boolean; sql?: boolean } = {},\n): Promise<V> {\n return loadLensPath(start, collectPaths(fn), opts);\n}\n\n/** Loads a precomputed lens path, avoiding repeated lambda/proxy evaluation for long-lived relation declarations. */\nexport function loadLensPath<T extends Entity, V>(\n start: T | readonly T[],\n paths: string[],\n opts: { forceReload?: boolean; sql?: boolean } = {},\n): Promise<V> {\n // Probe for the meta, so we can track when/if it needs to flip to a collection (even after hitting undefined)\n const meta = Array.isArray(start)\n ? isEntity(start[0]) && getMetadata(start[0])\n : isEntity(start) && getMetadata(start);\n // This should only happen for `start=[]`, which we know should return `[]`\n if (!meta) return [] as unknown as Promise<V>;\n\n // If we're already loaded, just return\n if (!opts.forceReload && isLensLoadedPath(start, paths)) {\n // Keep this synchronous to avoid adding a promise turn; this preserves nuanced hook timing in production code.\n return getLensPath(meta, start, paths) as Promise<V>;\n }\n\n return loadLensPathAsync(meta, start, paths, opts);\n}\n\n/**\n * Loads an unloaded lens path, keeping the already-loaded shortcut in `loadLensPath` synchronous.\n *\n * I.e. this avoids adding an extra promise turn for already-loaded paths during concurrent hooks.\n */\nasync function loadLensPathAsync<T extends Entity, V>(\n meta: EntityMetadata,\n start: T | readonly T[],\n paths: string[],\n opts: { forceReload?: boolean; sql?: boolean },\n): Promise<V> {\n // See if we can load this via SQL\n if (opts.sql) {\n // Are all paths SQL query-able?\n if (!isAllSqlPaths(meta, paths)) {\n throw new Error(\"Cannot use loadLens opts.sql with non-SQL paths\");\n }\n // If there is only 1 path, don't both with the fancy join\n if (paths.length > 1) {\n // TODO We can only do this is _none_ of the paths are loaded, otherwise we'll miss WIP mutations\n if (isReadOnlyArray(start)) {\n const em = start[0].em;\n return (await lensDataLoader(em, meta.cstr, true, paths)\n .loadMany(start.map((e) => e.idTagged))\n .catch(function loadLens(err) {\n throw appendStack(err, new Error());\n })) as V;\n } else {\n const em = start.em;\n return (await lensDataLoader(em, meta.cstr, false, paths)\n .load(start.idTagged)\n .catch(function loadLens(err) {\n throw appendStack(err, new Error());\n })) as V;\n }\n }\n }\n\n // This could be `Entity | Entity[] | undefined` as we keep walking\n let current: any = start;\n let currentMeta: EntityMetadata | undefined = meta;\n let seenSoftDeleted = false;\n // Now evaluate each step of the path\n for (const path of paths) {\n const field = currentMeta?.allFields[path] as\n | ManyToOneField\n | ManyToManyField\n | OneToManyField\n | OneToOneField\n | PrimitiveField\n | undefined;\n if (Array.isArray(current)) {\n current = (await Promise.all(current.map((c) => maybeLoad(c, path, opts)))).flat();\n current = [...new Set(current.filter((c: any) => c !== undefined && !c.isSoftDeletedEntity))];\n // As soon as we hit `current=[]`, we can early return (...`current=undefined` cannot b/c the next path might flip to a list)\n if (current.length === 0) return current!;\n } else if (current) {\n current = await maybeLoad(current, path, opts);\n seenSoftDeleted ||= (current as any)?.isSoftDeletedEntity;\n // If we had been traversing m2o -> m2o (i.e. book -> author) and just hit an o2m/m2m (i.e.\n // book -> author -> comments), and any of our prior m2os like `author` had been soft deleted,\n // just filter everything out.\n //\n // Otherwise, we keep `book -> author`, even if author is soft-deleted, b/c it changes the return\n // type from \"author\" to \"author | undefined\".\n if (Array.isArray(current) && seenSoftDeleted) {\n return [] as any;\n }\n } else {\n // current is undefined; see if we should flip to a list ... which means we can early return\n if (field?.kind === \"o2m\" || field?.kind === \"m2m\") return [] as any;\n }\n currentMeta = nextMeta(current, field);\n }\n return current!;\n}\n\nexport function isAllSqlPaths(meta: EntityMetadata, paths: string[]): boolean {\n for (let i = 0, current = meta; i < paths.length; i++) {\n const next = current.allFields[paths[i]];\n if (next && (next.kind === \"m2o\" || next.kind === \"m2m\" || next.kind === \"o2m\" || next.kind === \"o2o\")) {\n current = next.otherMetadata();\n } else {\n return false;\n }\n }\n return true;\n}\n\n// Given BookReview+[book, author] return [Author, books+bookReviews]\nexport function mapPathsToTarget(source: EntityMetadata, paths: string[]): [EntityMetadata, [EntityMetadata, Field][]] {\n let other = source;\n let fields: [EntityMetadata, Field][] = [];\n for (let i = 0; i < paths.length; i++) {\n const next = other.allFields[paths[i]];\n if (next && (next.kind === \"m2o\" || next.kind === \"m2m\" || next.kind === \"o2m\" || next.kind === \"o2o\")) {\n other = next.otherMetadata();\n fields.push([other, other.allFields[next.otherFieldName]]);\n } else {\n throw new Error(\"Either not an all-SQL path or not supported yet\");\n }\n }\n return [other, fields.reverse()];\n}\n\nfunction maybeLoad(object: any, path: string, opts: { forceReload?: boolean }): unknown {\n if (object === undefined || object === null) {\n return undefined;\n }\n const value = object[path];\n if (value && typeof value === \"object\" && \"load\" in value) {\n return value.load(opts);\n } else if (value && typeof value === \"function\") {\n return value.apply(object);\n } else {\n return value;\n }\n}\n\n/**\n * The synchronous version of `loadLens`.\n *\n * This assumes you've first evaluated the lens with `loadLens` and now can access it synchronously.\n */\nexport function getLens<T, U, V>(\n startMeta: EntityMetadata,\n start: T | readonly T[],\n fn: (lens: Lens<T>) => Lens<U, V>,\n): V {\n return getLensPath(startMeta, start, collectPaths(fn));\n}\n\n/** Synchronously traverses a precomputed lens path. */\nexport function getLensPath<T, V>(startMeta: EntityMetadata, start: T | readonly T[], paths: string[]): V {\n let currentMeta: EntityMetadata | undefined = startMeta;\n let current: any = start;\n let seenSoftDeleted = false;\n // Now evaluate each step of the path\n for (const path of paths) {\n // We might navigate into properties, at which point we won't know the currentMeta\n const field = currentMeta?.allFields[path] as\n | ManyToOneField\n | ManyToManyField\n | OneToManyField\n | OneToOneField\n | PrimitiveField\n | undefined;\n if (Array.isArray(current)) {\n // Use a set to dedup as we go\n const next = new Set();\n // This can be a hot path, so avoid `map` and `flat` and just loop\n for (const c of current) {\n const value = maybeGet(c, path);\n if (Array.isArray(value)) for (const v of value) maybeAdd(next, v);\n else maybeAdd(next, value);\n }\n current = [...next];\n } else if (current) {\n current = maybeGet(current, path);\n seenSoftDeleted ||= (current as any)?.isSoftDeletedEntity;\n // If we had been traversing m2o -> m2o and just hit an o2m/m2m, and any of our\n // prior m2os had been soft-deleted, just filter everything out.\n if (Array.isArray(current) && seenSoftDeleted) {\n return [] as any;\n }\n } else {\n // current is undefined; see if we should flip to a list ... which means we can early return\n if (field?.kind === \"o2m\" || field?.kind === \"m2m\") return [] as any;\n }\n currentMeta = nextMeta(current, field);\n }\n return current!;\n}\n\n/** Returns the next runtime metadata, preserving subtype-specific fields after base-typed traversals. */\nfunction nextMeta(current: unknown, field: Field | undefined): EntityMetadata | undefined {\n const entity = Array.isArray(current) ? current[0] : current;\n if (isEntity(entity)) return getMetadata(entity);\n return field && \"otherMetadata\" in field ? field.otherMetadata() : undefined;\n}\n\nfunction maybeAdd(set: Set<any>, value: any) {\n if (value !== undefined && !value.isSoftDeletedEntity) set.add(value);\n}\n\n/** Returns whether a lens is loaded; primarily for deeply loaded instances in tests. */\nexport function isLensLoaded<T, U, V>(start: T | readonly T[], fn: (lens: Lens<T>) => Lens<U, V>): boolean {\n return isLensLoadedPath(start, collectPaths(fn));\n}\n\n/** Returns whether a precomputed lens path is loaded; primarily for deeply loaded instances in tests. */\nexport function isLensLoadedPath<T>(start: T | readonly T[], paths: string[]): boolean {\n // This is a huge copy/paste of `getLens` but we check `isNotLoaded` and early return\n // as soon as we find any not-loaded relation\n let current: any = start;\n let seenSoftDeleted = false;\n // Now evaluate each step of the path\n for (const path of paths) {\n if (Array.isArray(current)) {\n // Use a set to dedup as we go\n const next = new Set();\n for (const c of current) {\n if (isNotLoaded(c, path)) return false;\n const value = maybeGet(c, path);\n if (Array.isArray(value)) for (const v of value) maybeAdd(next, v);\n else maybeAdd(next, value);\n }\n current = [...next];\n } else {\n if (isNotLoaded(current, path)) return false;\n current = maybeGet(current, path);\n seenSoftDeleted ||= (current as any)?.isSoftDeletedEntity;\n // If we had been traversing m2o -> m2o and just hit an o2m/m2m, and any of our\n // prior m2os had been soft deleted, just filter everything out.\n if (Array.isArray(current) && seenSoftDeleted) {\n return true;\n }\n }\n }\n return true;\n}\n\n/** Accepts a lens like `a => a.books.reviews` and returns a hint like `{ books: { reviews: {} } }`. */\nexport function lensToLoadHint<T extends Entity, U, V>(fn: (lens: Lens<T>) => Lens<U, V>): LoadHint<T> {\n return lensPathToLoadHint(collectPaths(fn));\n}\n\n/** Accepts lens paths like `[books, reviews]` and returns a hint like `{ books: { reviews: {} } }`. */\nexport function lensPathToLoadHint<T extends Entity>(paths: string[]): LoadHint<T> {\n let current = {};\n for (let i = paths.length - 1; i >= 0; i--) {\n const path = paths[i];\n current = { [path]: current };\n }\n return current as LoadHint<T>;\n}\n\n/** Accepts a lens like `a => a.books.reviews` and returns the paths like `[books, reviews]`. */\nexport function lensToPath<T extends Entity, U, V>(fn: (lens: Lens<T>) => Lens<U, V>): string[] {\n return [...collectPaths(fn)];\n}\n\nfunction isNotLoaded(object: any, path: string): boolean {\n const value = object && object[path];\n if (value instanceof AbstractRelationImpl || isProperty(value)) {\n return !value.isLoaded;\n }\n return false;\n}\n\nfunction maybeGet(object: any, path: string): unknown {\n if (object === undefined || object === null) {\n return undefined;\n }\n const value = object[path];\n if (typeof value === \"object\" && \"get\" in value) {\n return value.get;\n } else if (value && typeof value === \"function\") {\n return value.apply(object);\n } else {\n return value;\n }\n}\n\nfunction collectPaths(fn: Function): string[] {\n const paths: string[] = [];\n // The proxy collects the path navigations that the user's `fn` lambda invokes.\n const proxy = new Proxy(\n {},\n {\n get(_, property, receiver) {\n paths.push(String(property));\n return receiver;\n },\n },\n );\n // Invoke the lens function to record the navigation path on our proxy\n fn(proxy as any);\n return paths;\n}\n\n// Work around https://github.com/microsoft/TypeScript/issues/17002\nfunction isReadOnlyArray<T>(value: T | readonly T[]): value is readonly T[] {\n return Array.isArray(value);\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"loadLens.d.cts","names":[],"sources":["../src/loadLens.ts"],"mappings":";;;;;KAkBK,SAAS;EAAO,QAAQ,QAAQ;;;KAGhC,cAAc,WAAW,YAAY;;;;;;;;;;;;;KAiBrC,WAAW,GAAG,KACjB,UAAU,sBACL,YAAY,oBAAoB,MAC/B,cAAc,OACd,cAAc,OAChB,UAAU,qBACR,KACC,yBACC,gBACA;;KAKL,eAAe,KAAK,UAAU,oBAAoB,KAAK,IAAI;KAE3D,cAAc,KAAK,QAAQ;;;;;;;;;;KAWpB,KAAK,GAAG,IAAI,QACrB,WAAW,IAAI,EAAE,WAAW,eAAe,KACxC,KAAK,eAAe,cAAc,KAAK,WAAW,GAAG,MACrD,EAAE,WAAW,oBAAoB,KAC/B,KAAK,eAAe,cAAc,KAAK,WAAW,GAAG,MACrD,KAAK,eAAe,cAAc,EAAE,MAAM,WAAW,GAAG,EAAE;;;;;;;;;;iBAe5C,SAAS,UAAU,QAAQ,GAAG,GAClD,OAAO,aAAa,KACpB,KAAK,MAAM,KAAK,OAAO,KAAK,GAAG,IAC/B;EAAQ;EAAuB;IAC9B,QAAQ;;iBAKK,aAAa,UAAU,QAAQ,GAC7C,OAAO,aAAa,KACpB,iBACA;EAAQ;EAAuB;IAC9B,QAAQ;iBA8FK,cAAc,MAAM,gBAAgB;iBAapC,iBAAiB,QAAQ,gBAAgB,mBAAmB,iBAAiB,gBAAgB;;;;;;iBAkC7F,QAAQ,GAAG,GAAG,GAC5B,WAAW,gBACX,OAAO,aAAa,KACpB,KAAK,MAAM,KAAK,OAAO,KAAK,GAAG,KAC9B;;iBAKa,YAAY,GAAG,GAAG,WAAW,gBAAgB,OAAO,aAAa,KAAK,kBAAkB;;iBAqDxF,aAAa,GAAG,GAAG,GAAG,OAAO,aAAa,KAAK,KAAK,MAAM,KAAK,OAAO,KAAK,GAAG;;iBAK9E,iBAAiB,GAAG,OAAO,aAAa,KAAK;;iBAgC7C,eAAe,UAAU,QAAQ,GAAG,GAAG,KAAK,MAAM,KAAK,OAAO,KAAK,GAAG,KAAK,SAAS;;iBAKpF,mBAAmB,UAAU,QAAQ,kBAAkB,SAAS;;iBAUhE,WAAW,UAAU,QAAQ,GAAG,GAAG,KAAK,MAAM,KAAK,OAAO,KAAK,GAAG"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"loadLens.d.mts","names":[],"sources":["../src/loadLens.ts"],"mappings":";;;;;KAkBK,SAAS;EAAO,QAAQ,QAAQ;;;KAGhC,cAAc,WAAW,YAAY;;;;;;;;;;;;;KAiBrC,WAAW,GAAG,KACjB,UAAU,sBACL,YAAY,oBAAoB,MAC/B,cAAc,OACd,cAAc,OAChB,UAAU,qBACR,KACC,yBACC,gBACA;;KAKL,eAAe,KAAK,UAAU,oBAAoB,KAAK,IAAI;KAE3D,cAAc,KAAK,QAAQ;;;;;;;;;;KAWpB,KAAK,GAAG,IAAI,QACrB,WAAW,IAAI,EAAE,WAAW,eAAe,KACxC,KAAK,eAAe,cAAc,KAAK,WAAW,GAAG,MACrD,EAAE,WAAW,oBAAoB,KAC/B,KAAK,eAAe,cAAc,KAAK,WAAW,GAAG,MACrD,KAAK,eAAe,cAAc,EAAE,MAAM,WAAW,GAAG,EAAE;;;;;;;;;;iBAe5C,SAAS,UAAU,QAAQ,GAAG,GAClD,OAAO,aAAa,KACpB,KAAK,MAAM,KAAK,OAAO,KAAK,GAAG,IAC/B;EAAQ;EAAuB;IAC9B,QAAQ;;iBAKK,aAAa,UAAU,QAAQ,GAC7C,OAAO,aAAa,KACpB,iBACA;EAAQ;EAAuB;IAC9B,QAAQ;iBA8FK,cAAc,MAAM,gBAAgB;iBAapC,iBAAiB,QAAQ,gBAAgB,mBAAmB,iBAAiB,gBAAgB;;;;;;iBAkC7F,QAAQ,GAAG,GAAG,GAC5B,WAAW,gBACX,OAAO,aAAa,KACpB,KAAK,MAAM,KAAK,OAAO,KAAK,GAAG,KAC9B;;iBAKa,YAAY,GAAG,GAAG,WAAW,gBAAgB,OAAO,aAAa,KAAK,kBAAkB;;iBAqDxF,aAAa,GAAG,GAAG,GAAG,OAAO,aAAa,KAAK,KAAK,MAAM,KAAK,OAAO,KAAK,GAAG;;iBAK9E,iBAAiB,GAAG,OAAO,aAAa,KAAK;;iBAgC7C,eAAe,UAAU,QAAQ,GAAG,GAAG,KAAK,MAAM,KAAK,OAAO,KAAK,GAAG,KAAK,SAAS;;iBAKpF,mBAAmB,UAAU,QAAQ,kBAAkB,SAAS;;iBAUhE,WAAW,UAAU,QAAQ,GAAG,GAAG,KAAK,MAAM,KAAK,OAAO,KAAK,GAAG"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"loadLens.js","names":[],"sources":["../src/loadLens.ts"],"sourcesContent":["import { lensDataLoader } from \"./dataloaders/lensDataLoader.ts\";\nimport { type Entity, isEntity } from \"./Entity.ts\";\nimport { appendStack } from \"./EntityManager.ts\";\nimport {\n type EntityMetadata,\n type Field,\n type ManyToManyField,\n type ManyToOneField,\n type OneToManyField,\n type OneToOneField,\n type PrimitiveField,\n getMetadata,\n} from \"./EntityMetadata.ts\";\nimport { type LoadHint } from \"./loadHints.ts\";\nimport { AbstractRelationImpl } from \"./relations/AbstractRelationImpl.ts\";\nimport { isProperty } from \"./relations/index.ts\";\n\n/** Generically matches on a Reference/Collection's load method. */\ntype LoadLike<U> = { load(): Promise<U> };\n\n/** Generically matches a property or zero-arg method that returns a promise. */\ntype PromiseFnLike<U> = () => PromiseLike<U>;\n\n/**\n * Given a parent type `R` (that is our current lens \"return type\", i.e. `Author` or `Author | undefined` or `Author[]`),\n * and the type `V` of the \"next step\" of the traversal (i.e. itself `Book` or `Book | undefined` or `Book[]`, depending\n * on the relation being traversed), returns `V` mapped to \"the right format\" based on `R`.\n *\n * I.e.:\n *\n * - `Author | undefined` that navigates a `Book` will become `Book | undefined`\n * - `Author` that navigates a `Book | undefined` will also become `Book | undefined`\n * - `Author[]` that navigates a `Book | undefined` will become a `Book[]`\n * - `Author | undefined` that navigates a `Book[]` will become a `Book[]`\n */\n// The extra `[]` around `V` and `ReadonlyArray<any>` are to keep the type as `Array<Foo | undefined>`\n// instead of `Foo[] | undefined[]`.\n// When `P extends ReadonlyArray, i.e. we're in flatMap mode, we're also in filter undefined mode.\ntype MaybeArray<R, V> =\n R extends ReadonlyArray<any>\n ? [V] extends [ReadonlyArray<infer U>]\n ? DropUndefined<U>[]\n : DropUndefined<V>[]\n : V extends ReadonlyArray<any>\n ? V\n : [R] extends [undefined]\n ? V | undefined\n : V;\n\n// ([R] extends [undefined]) ? (V) : V;\n\n/** Given a type T that we come across in the path, de-array it to continue our flatMap-ish semantics. */\ntype MaybeDropArray<T> = T extends ReadonlyArray<infer U> ? U : T;\n\ntype DropUndefined<T> = Exclude<T, undefined>;\n\n/**\n * A type for declaratively walking the object graph.\n *\n * This is not technically a Lens that can `get/set`, but the idea is generally the same.\n *\n * `T` is the type we're on, i.e. when `T = Author` we can do `.firstName` or `.lastName.\n * `R` is either a `T` or `T[]` or `T | undefined` and just captures whether we've hit a\n * list at any point in the lens navigation path.\n */\nexport type Lens<T, R = T> = {\n [P in keyof T]: T[P] extends LoadLike<infer U>\n ? Lens<MaybeDropArray<DropUndefined<U>>, MaybeArray<R, U>>\n : T[P] extends PromiseFnLike<infer U>\n ? Lens<MaybeDropArray<DropUndefined<U>>, MaybeArray<R, U>>\n : Lens<MaybeDropArray<DropUndefined<T[P]>>, MaybeArray<R, T[P]>>;\n};\n\n/**\n * Allows declaratively loading/traversing several layers of references at once.\n *\n * I.e.:\n *\n * ```typescript\n * const publisher = await book.load(b => b.author.publisher);\n * ```\n */\n// For some reason accepting Lens<this, this> does not work when called from within the entity\n// subclass itself, so we use the codegen hammer in our subclass to force the right Lens type\n// in a .load stub that just calls us for the implementation.\nexport async function loadLens<T extends Entity, U, V>(\n start: T | readonly T[],\n fn: (lens: Lens<T>) => Lens<U, V>,\n opts: { forceReload?: boolean; sql?: boolean } = {},\n): Promise<V> {\n return loadLensPath(start, collectPaths(fn), opts);\n}\n\n/** Loads a precomputed lens path, avoiding repeated lambda/proxy evaluation for long-lived relation declarations. */\nexport function loadLensPath<T extends Entity, V>(\n start: T | readonly T[],\n paths: string[],\n opts: { forceReload?: boolean; sql?: boolean } = {},\n): Promise<V> {\n // Probe for the meta, so we can track when/if it needs to flip to a collection (even after hitting undefined)\n const meta = Array.isArray(start)\n ? isEntity(start[0]) && getMetadata(start[0])\n : isEntity(start) && getMetadata(start);\n // This should only happen for `start=[]`, which we know should return `[]`\n if (!meta) return [] as unknown as Promise<V>;\n\n // If we're already loaded, just return\n if (!opts.forceReload && isLensLoadedPath(start, paths)) {\n // Keep this synchronous to avoid adding a promise turn; this preserves nuanced hook timing in production code.\n return getLensPath(meta, start, paths) as Promise<V>;\n }\n\n return loadLensPathAsync(meta, start, paths, opts);\n}\n\n/**\n * Loads an unloaded lens path, keeping the already-loaded shortcut in `loadLensPath` synchronous.\n *\n * I.e. this avoids adding an extra promise turn for already-loaded paths during concurrent hooks.\n */\nasync function loadLensPathAsync<T extends Entity, V>(\n meta: EntityMetadata,\n start: T | readonly T[],\n paths: string[],\n opts: { forceReload?: boolean; sql?: boolean },\n): Promise<V> {\n // See if we can load this via SQL\n if (opts.sql) {\n // Are all paths SQL query-able?\n if (!isAllSqlPaths(meta, paths)) {\n throw new Error(\"Cannot use loadLens opts.sql with non-SQL paths\");\n }\n // If there is only 1 path, don't both with the fancy join\n if (paths.length > 1) {\n // TODO We can only do this is _none_ of the paths are loaded, otherwise we'll miss WIP mutations\n if (isReadOnlyArray(start)) {\n const em = start[0].em;\n return (await lensDataLoader(em, meta.cstr, true, paths)\n .loadMany(start.map((e) => e.idTagged))\n .catch(function loadLens(err) {\n throw appendStack(err, new Error());\n })) as V;\n } else {\n const em = start.em;\n return (await lensDataLoader(em, meta.cstr, false, paths)\n .load(start.idTagged)\n .catch(function loadLens(err) {\n throw appendStack(err, new Error());\n })) as V;\n }\n }\n }\n\n // This could be `Entity | Entity[] | undefined` as we keep walking\n let current: any = start;\n let currentMeta: EntityMetadata | undefined = meta;\n let seenSoftDeleted = false;\n // Now evaluate each step of the path\n for (const path of paths) {\n const field = currentMeta?.allFields[path] as\n | ManyToOneField\n | ManyToManyField\n | OneToManyField\n | OneToOneField\n | PrimitiveField\n | undefined;\n if (Array.isArray(current)) {\n current = (await Promise.all(current.map((c) => maybeLoad(c, path, opts)))).flat();\n current = [...new Set(current.filter((c: any) => c !== undefined && !c.isSoftDeletedEntity))];\n // As soon as we hit `current=[]`, we can early return (...`current=undefined` cannot b/c the next path might flip to a list)\n if (current.length === 0) return current!;\n } else if (current) {\n current = await maybeLoad(current, path, opts);\n seenSoftDeleted ||= (current as any)?.isSoftDeletedEntity;\n // If we had been traversing m2o -> m2o (i.e. book -> author) and just hit an o2m/m2m (i.e.\n // book -> author -> comments), and any of our prior m2os like `author` had been soft deleted,\n // just filter everything out.\n //\n // Otherwise, we keep `book -> author`, even if author is soft-deleted, b/c it changes the return\n // type from \"author\" to \"author | undefined\".\n if (Array.isArray(current) && seenSoftDeleted) {\n return [] as any;\n }\n } else {\n // current is undefined; see if we should flip to a list ... which means we can early return\n if (field?.kind === \"o2m\" || field?.kind === \"m2m\") return [] as any;\n }\n currentMeta = nextMeta(current, field);\n }\n return current!;\n}\n\nexport function isAllSqlPaths(meta: EntityMetadata, paths: string[]): boolean {\n for (let i = 0, current = meta; i < paths.length; i++) {\n const next = current.allFields[paths[i]];\n if (next && (next.kind === \"m2o\" || next.kind === \"m2m\" || next.kind === \"o2m\" || next.kind === \"o2o\")) {\n current = next.otherMetadata();\n } else {\n return false;\n }\n }\n return true;\n}\n\n// Given BookReview+[book, author] return [Author, books+bookReviews]\nexport function mapPathsToTarget(source: EntityMetadata, paths: string[]): [EntityMetadata, [EntityMetadata, Field][]] {\n let other = source;\n let fields: [EntityMetadata, Field][] = [];\n for (let i = 0; i < paths.length; i++) {\n const next = other.allFields[paths[i]];\n if (next && (next.kind === \"m2o\" || next.kind === \"m2m\" || next.kind === \"o2m\" || next.kind === \"o2o\")) {\n other = next.otherMetadata();\n fields.push([other, other.allFields[next.otherFieldName]]);\n } else {\n throw new Error(\"Either not an all-SQL path or not supported yet\");\n }\n }\n return [other, fields.reverse()];\n}\n\nfunction maybeLoad(object: any, path: string, opts: { forceReload?: boolean }): unknown {\n if (object === undefined || object === null) {\n return undefined;\n }\n const value = object[path];\n if (value && typeof value === \"object\" && \"load\" in value) {\n return value.load(opts);\n } else if (value && typeof value === \"function\") {\n return value.apply(object);\n } else {\n return value;\n }\n}\n\n/**\n * The synchronous version of `loadLens`.\n *\n * This assumes you've first evaluated the lens with `loadLens` and now can access it synchronously.\n */\nexport function getLens<T, U, V>(\n startMeta: EntityMetadata,\n start: T | readonly T[],\n fn: (lens: Lens<T>) => Lens<U, V>,\n): V {\n return getLensPath(startMeta, start, collectPaths(fn));\n}\n\n/** Synchronously traverses a precomputed lens path. */\nexport function getLensPath<T, V>(startMeta: EntityMetadata, start: T | readonly T[], paths: string[]): V {\n let currentMeta: EntityMetadata | undefined = startMeta;\n let current: any = start;\n let seenSoftDeleted = false;\n // Now evaluate each step of the path\n for (const path of paths) {\n // We might navigate into properties, at which point we won't know the currentMeta\n const field = currentMeta?.allFields[path] as\n | ManyToOneField\n | ManyToManyField\n | OneToManyField\n | OneToOneField\n | PrimitiveField\n | undefined;\n if (Array.isArray(current)) {\n // Use a set to dedup as we go\n const next = new Set();\n // This can be a hot path, so avoid `map` and `flat` and just loop\n for (const c of current) {\n const value = maybeGet(c, path);\n if (Array.isArray(value)) for (const v of value) maybeAdd(next, v);\n else maybeAdd(next, value);\n }\n current = [...next];\n } else if (current) {\n current = maybeGet(current, path);\n seenSoftDeleted ||= (current as any)?.isSoftDeletedEntity;\n // If we had been traversing m2o -> m2o and just hit an o2m/m2m, and any of our\n // prior m2os had been soft-deleted, just filter everything out.\n if (Array.isArray(current) && seenSoftDeleted) {\n return [] as any;\n }\n } else {\n // current is undefined; see if we should flip to a list ... which means we can early return\n if (field?.kind === \"o2m\" || field?.kind === \"m2m\") return [] as any;\n }\n currentMeta = nextMeta(current, field);\n }\n return current!;\n}\n\n/** Returns the next runtime metadata, preserving subtype-specific fields after base-typed traversals. */\nfunction nextMeta(current: unknown, field: Field | undefined): EntityMetadata | undefined {\n const entity = Array.isArray(current) ? current[0] : current;\n if (isEntity(entity)) return getMetadata(entity);\n return field && \"otherMetadata\" in field ? field.otherMetadata() : undefined;\n}\n\nfunction maybeAdd(set: Set<any>, value: any) {\n if (value !== undefined && !value.isSoftDeletedEntity) set.add(value);\n}\n\n/** Returns whether a lens is loaded; primarily for deeply loaded instances in tests. */\nexport function isLensLoaded<T, U, V>(start: T | readonly T[], fn: (lens: Lens<T>) => Lens<U, V>): boolean {\n return isLensLoadedPath(start, collectPaths(fn));\n}\n\n/** Returns whether a precomputed lens path is loaded; primarily for deeply loaded instances in tests. */\nexport function isLensLoadedPath<T>(start: T | readonly T[], paths: string[]): boolean {\n // This is a huge copy/paste of `getLens` but we check `isNotLoaded` and early return\n // as soon as we find any not-loaded relation\n let current: any = start;\n let seenSoftDeleted = false;\n // Now evaluate each step of the path\n for (const path of paths) {\n if (Array.isArray(current)) {\n // Use a set to dedup as we go\n const next = new Set();\n for (const c of current) {\n if (isNotLoaded(c, path)) return false;\n const value = maybeGet(c, path);\n if (Array.isArray(value)) for (const v of value) maybeAdd(next, v);\n else maybeAdd(next, value);\n }\n current = [...next];\n } else {\n if (isNotLoaded(current, path)) return false;\n current = maybeGet(current, path);\n seenSoftDeleted ||= (current as any)?.isSoftDeletedEntity;\n // If we had been traversing m2o -> m2o and just hit an o2m/m2m, and any of our\n // prior m2os had been soft deleted, just filter everything out.\n if (Array.isArray(current) && seenSoftDeleted) {\n return true;\n }\n }\n }\n return true;\n}\n\n/** Accepts a lens like `a => a.books.reviews` and returns a hint like `{ books: { reviews: {} } }`. */\nexport function lensToLoadHint<T extends Entity, U, V>(fn: (lens: Lens<T>) => Lens<U, V>): LoadHint<T> {\n return lensPathToLoadHint(collectPaths(fn));\n}\n\n/** Accepts lens paths like `[books, reviews]` and returns a hint like `{ books: { reviews: {} } }`. */\nexport function lensPathToLoadHint<T extends Entity>(paths: string[]): LoadHint<T> {\n let current = {};\n for (let i = paths.length - 1; i >= 0; i--) {\n const path = paths[i];\n current = { [path]: current };\n }\n return current as LoadHint<T>;\n}\n\n/** Accepts a lens like `a => a.books.reviews` and returns the paths like `[books, reviews]`. */\nexport function lensToPath<T extends Entity, U, V>(fn: (lens: Lens<T>) => Lens<U, V>): string[] {\n return [...collectPaths(fn)];\n}\n\nfunction isNotLoaded(object: any, path: string): boolean {\n const value = object && object[path];\n if (value instanceof AbstractRelationImpl || isProperty(value)) {\n return !value.isLoaded;\n }\n return false;\n}\n\nfunction maybeGet(object: any, path: string): unknown {\n if (object === undefined || object === null) {\n return undefined;\n }\n const value = object[path];\n if (typeof value === \"object\" && \"get\" in value) {\n return value.get;\n } else if (value && typeof value === \"function\") {\n return value.apply(object);\n } else {\n return value;\n }\n}\n\nfunction collectPaths(fn: Function): string[] {\n const paths: string[] = [];\n // The proxy collects the path navigations that the user's `fn` lambda invokes.\n const proxy = new Proxy(\n {},\n {\n get(_, property, receiver) {\n paths.push(String(property));\n return receiver;\n },\n },\n );\n // Invoke the lens function to record the navigation path on our proxy\n fn(proxy as any);\n return paths;\n}\n\n// Work around https://github.com/microsoft/TypeScript/issues/17002\nfunction isReadOnlyArray<T>(value: T | readonly T[]): value is readonly T[] {\n return Array.isArray(value);\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"reactiveHints.cjs","names":["getMetadata","normalizeHint","suffixRe","getProperties","PropertyImpl","ReactiveGetterImpl","RecursiveParentsCollectionImpl","RecursiveChildrenCollectionImpl","RecursiveM2mCollectionImpl","getInstanceData","getEmInternalApi","flatAndUnique","isEntity","isId","getBaseAndSelfMetas","getBaseMeta"],"sources":["../src/reactiveHints.ts"],"sourcesContent":["import { getInstanceData } from \"./BaseEntity.ts\";\nimport { type Changes } from \"./changes.ts\";\nimport { type Entity, isEntity } from \"./Entity.ts\";\nimport { type MaybeAbstractEntityConstructor, getEmInternalApi, isId } from \"./EntityManager.ts\";\nimport {\n type EntityMetadata,\n type ManyToManyField,\n type ManyToOneField,\n type OneToManyField,\n type OneToOneField,\n type PolymorphicFieldComponent,\n getBaseAndSelfMetas,\n getBaseMeta,\n getMetadata,\n} from \"./EntityMetadata.ts\";\nimport { getProperties } from \"./getProperties.ts\";\nimport { type LoadHint, type Loadable, type Loaded } from \"./loadHints.ts\";\nimport { type NormalizeHint, type SuffixSeperator, normalizeHint, suffixRe } from \"./normalizeHints.ts\";\nimport {\n type Collection,\n type EnumCollection,\n type LoadedCollection,\n type LoadedEnumCollection,\n type LoadedProperty,\n type LoadedReadOnlyCollection,\n type LoadedReference,\n type ManyToManyCollection,\n type OneToOneReference,\n type PolymorphicReference,\n type Property,\n PropertyImpl,\n type ReactiveGetter,\n type ReadOnlyCollection,\n type Reference,\n} from \"./relations/index.ts\";\nimport { type LoadedOneToOneReference } from \"./relations/OneToOneReference.ts\";\nimport { ReactiveGetterImpl } from \"./relations/ReactiveGetter.ts\";\nimport {\n RecursiveChildrenCollectionImpl,\n RecursiveM2mCollectionImpl,\n RecursiveParentsCollectionImpl,\n} from \"./relations/RecursiveCollection.ts\";\nimport { type FieldsOf, type RelationsOf } from \"./typeMap.ts\";\nimport { fail, flatAndUnique, mergeNormalizedHints } from \"./utils.ts\";\n\n/** The keys in `T` that rules & hooks can react to. */\nexport type Reactable<T extends Entity> =\n // This will be primitives + enums + m2os\n FieldsOf<T> &\n // We include `Loadable` so that we include hasReactiveProperties,\n // which are reversable but won't be in any of our codegen types.\n Loadable<T> &\n Gettable<T> &\n SuffixedFieldsOf<T> &\n SuffixedLoadable<T> &\n SuffixedGettable<T>;\n\n/** Finds `hasReactiveGetters` which are not \"loadable\" b/c they're always loaded. */\nexport type Gettable<T extends Entity> = {\n -readonly [K in keyof T as GettableValue<T[K]> extends never ? never : K]: GettableValue<T[K]>;\n};\n\ntype GettableValue<V> = V extends ReactiveGetter<any, infer P> ? P : never;\n\n/** The fields of `T` suffixed with `:ro` or `_ro`. */\ntype SuffixedFieldsOf<T extends Entity> = {\n [K in keyof FieldsOf<T> & string as `${K}${SuffixSeperator}ro`]: FieldsOf<T>[K];\n};\n\ntype SuffixedLoadable<T extends Entity> = {\n [K in keyof Loadable<T> & string as `${K}${SuffixSeperator}ro`]: Loadable<T>[K];\n};\n\ntype SuffixedGettable<T extends Entity> = {\n [K in keyof Gettable<T> & string as `${K}${SuffixSeperator}ro`]: Gettable<T>[K];\n};\n\n/**\n * A reactive hint of a single key, multiple keys, or nested keys and sub-hints.\n *\n * Reactive hints are different from load hints in that reactive hints include specific\n * fields to react against, while load hints contain only relations, collections, and async\n * properties to preload.\n */\nexport type ReactiveHint<T extends Entity> =\n | (keyof Reactable<T> & string)\n | ReadonlyArray<keyof Reactable<T> & string>\n | NestedReactiveHint<T>;\n\nexport type NestedReactiveHint<T extends Entity> = {\n [K in keyof Reactable<T>]?: Reactable<T>[K] extends infer U extends Entity ? ReactiveHint<U> : {};\n};\n\n/** Given an entity `T` that is being reacted with hint `H`, mark only the `H` attributes visible & populated. */\nexport type Reacted<T extends Entity, H> = Entity & {\n [K in keyof NormalizeHint<H> & keyof T]: T[K] extends OneToOneReference<any, infer U>\n ? LoadedOneToOneReference<T, Entity & Reacted<U, NormalizeHint<H>[K]>>\n : // Add an explicit check for PolymorphicReference because it can add `PolymorphicReference &` which gives access to `idIfSet`\n // ...although maybe LoadedReference should just have `idIfSet` in it as well? LoadedOneToOneReference does...\n T[K] extends PolymorphicReference<any, infer U, infer N>\n ? PolymorphicReference<T, U, N> & LoadedReference<T, Entity & Reacted<U, NormalizeHint<H>[K]>, N>\n : T[K] extends Reference<any, infer U, infer N>\n ? LoadedReference<T, Entity & Reacted<U, NormalizeHint<H>[K]>, N>\n : T[K] extends EnumCollection<any, infer E>\n ? LoadedEnumCollection<T, E>\n : T[K] extends Collection<any, infer U>\n ? LoadedCollection<T, Entity & Reacted<U, NormalizeHint<H>[K]>>\n : T[K] extends ReadOnlyCollection<any, infer U>\n ? LoadedReadOnlyCollection<T, Entity & Reacted<U, NormalizeHint<H>[K]>>\n : T[K] extends Property<any, infer V>\n ? LoadedProperty<any, V>\n : T[K];\n} & {\n /**\n * Gives reactive rules & fields a way to get the full entity if they really need it.\n *\n * This should be used carefully b/c it will side-step the reactive system, and instead\n * reactive rules & fields should explicitly declare access to the fields they need, which\n * will then allow accessing the field via the `Reacted<Author, ...>` type.\n */\n fullNonReactiveAccess: Loaded<T, H>;\n /** Allow detecting if a reactive change is due to nuances like `hasUpdated` or `hasChanged`. */\n changes: Changes<T, keyof (FieldsOf<T> & RelationsOf<T>), keyof NormalizeHint<H>>;\n} & MaybeTransientFields<T>;\n\n/** Allow returning reacted entities from `hasReactiveReference`. */\nexport type MaybeReactedEntity<V> = V extends Entity ? { fullNonReactiveAccess: V } : V;\n\n/**\n * Allow returning reacted entities from `hasReactiveProperty`.\n *\n * The `MaybeReactedEntity` is used by `hasReactiveReference` which already has `undefined | never`\n * broken out as a separate generic; `hasReactiveProperty` does not, and so this type conditionally\n * pulls `undefined` out first, and then defers to `MaybeReactedEntity`.\n */\nexport type MaybeReactedPropertyEntity<V> = V extends (infer V1 extends Entity) | undefined\n ? MaybeReactedEntity<V1> | undefined\n : MaybeReactedEntity<V>;\n\n/**\n * A reactive hint that only allows fields immediately on the entity, i.e. no nested hints.\n *\n * This is used by `ReactiveGetter`s to guarantee that their lambda functions will\n * always be `.get`-able and hence not need loading.\n */\nexport type ShallowReactiveHint<T extends Entity> =\n | (keyof FieldsOf<T> & string)\n | ReadonlyArray<keyof FieldsOf<T> & string>;\n\n/** If the domain model has transient fields, allow reactive behavior to see it, i.e. don't run validation rules for special operations. */\nexport type MaybeTransientFields<T> = \"transientFields\" extends keyof T\n ? { transientFields: T[\"transientFields\"] }\n : {};\n\n/**\n * Takes a reactive hint and returns the `ReactiveTarget`s that, should they change, need to\n * walk back to this watching reactable.\n *\n * @param rootType The original type that contained the reactive rule/field, used for helpful error messages\n * @param entityType The current entity of the step we're walking\n * @param hint The current hint we're walking\n * @param reactForOtherSide the name of our FK column, if the previous collection needs to react to our FK changing\n * @param isFirst\n */\nexport function reverseReactiveHint<T extends Entity>(\n rootType: MaybeAbstractEntityConstructor<T>,\n entityType: MaybeAbstractEntityConstructor<T>,\n hint: ReactiveHint<T>,\n reactForOtherSide?: string,\n reactForOtherSideIsReadOnly?: \"field-read-only\" | \"hint-read-only\" | false,\n isFirst: boolean = true,\n): ReactiveTarget[] {\n const meta = getMetadata(entityType);\n // This is the list of fields for this `entityType` that we will react to their changing values\n const fields: string[] = [];\n const readOnlyFields: string[] = [];\n const maybeRecursive: ReactiveTarget[] = [];\n\n // If the hint before us was a collection, i.e. { books: [\"title\"] }, besides just reacting\n // to our `title` changing, `reactForOtherSide` tells us to react to our `author` field as well.\n if (reactForOtherSide) {\n const _fields = reactForOtherSideIsReadOnly ? readOnlyFields : fields;\n _fields.push(reactForOtherSide);\n if (meta.timestampFields?.deletedAt) {\n _fields.push(meta.timestampFields.deletedAt);\n }\n }\n\n // Look through the hint for our own fields, i.e. `[\"firstName\", \"lastName]`, and nested hints like `{ books: \"title\" }`.\n const subHintTargets: ReactiveTarget[] = Object.entries(normalizeHint(hint)).flatMap(([keyMaybeSuffix, subHint]) => {\n return reverseSubHint(\n rootType,\n entityType,\n hint,\n meta,\n // Pass fields & readOnlyFields, so `reverseSubHint` can append any of our primitive fields it finds\n fields,\n readOnlyFields,\n maybeRecursive,\n keyMaybeSuffix, // maybeSuffix = might end with `_ro` like `name_ro`\n subHint,\n );\n });\n\n const myTargets: ReactiveTarget[] = [];\n // If any of our primitives (or m2o fields) change, establish a reactive path from \"here\" (entityType)\n // that is initially empty (path: []) but will have paths layered on by upstream callers\n if (fields.length > 0 || isFirst || reactForOtherSideIsReadOnly === \"field-read-only\") {\n myTargets.push({ kind: \"update\", entity: entityType, fields, path: [] });\n }\n // Normally read-only fields don't trigger true async reactivity, but IsLoadedCache\n // needs them for same-EM cache invalidation.\n if (readOnlyFields.length > 0) {\n myTargets.push({ kind: \"read-only\", entity: entityType, fields: readOnlyFields, path: [] });\n }\n\n return [...myTargets, ...maybeRecursive, ...subHintTargets];\n}\n\nfunction reverseSubHint(\n rootType: MaybeAbstractEntityConstructor<any>,\n entityType: MaybeAbstractEntityConstructor<any>,\n hint: any,\n meta: EntityMetadata,\n fields: string[],\n readOnlyFields: string[],\n maybeRecursive: ReactiveTarget[],\n keyMaybeSuffix: string,\n subHint: any,\n): ReactiveTarget[] {\n const key = keyMaybeSuffix.replace(suffixRe, \"\");\n const field = meta.allFields[key];\n const isReadOnly = !!keyMaybeSuffix.match(suffixRe) || (field && field.immutable);\n const _fields = isReadOnly ? readOnlyFields : fields;\n if (field) {\n switch (field.kind) {\n case \"m2o\": {\n // If this is a ReactiveReference, maybe we do something different?\n _fields.push(field.fieldName);\n const otherMeta = field.otherMetadata();\n // If this is a ReactiveReference, it won't have an \"other\" side, which is fine if:\n // - we're only reacting to the RR value itself (and have no sub-hints), or\n // - all of our sub-hints are read-only\n const otherField = otherMeta.allFields[field.otherFieldName];\n if (!otherField && !isAllReadOnly(subHint)) {\n throw new Error(\n `Invalid hint in ${rootType.name}.ts, we don't currently support reacting through ReactiveReferences, ${JSON.stringify(hint)}`,\n );\n }\n return reverseReactiveHint(rootType, otherMeta.cstr, subHint, undefined, false, false).map(\n appendPath(maybeAddTypeFilterSuffix(meta, field)),\n );\n }\n case \"poly\": {\n _fields.push(field.fieldName);\n // A poly is basically multiple m2os glued together, so copy/paste the `case m2o` code\n // above but do it for each component FK, and glue them together.\n return field.components.flatMap((comp) => {\n return reverseReactiveHint(rootType, comp.otherMetadata().cstr, subHint, undefined, false, false).map(\n appendPath(maybeAddTypeFilterSuffix(meta, comp)),\n );\n });\n }\n case \"m2m\": {\n // While o2m and o2o can watch for just FK changes by passing `reactForOtherSide` (the FK lives in the other\n // table), for m2m reactivity we push the collection name into the reactive hint, because it's effectively\n // \"the other/reverse side\", and JoinRows will trigger `queueDownstreamReactables` explicitly, instead of\n // `setField` which handles regular/non-m2m mutations.\n _fields.push(field.fieldName);\n const otherFieldName = maybeAddTypeFilterSuffix(meta, field);\n return reverseReactiveHint(\n rootType,\n field.otherMetadata().cstr,\n subHint,\n // For m2m, we can always pass undefined here, as otherwise having the opposite m2m collection\n // recalc all of its children will cause over-reactivity\n undefined,\n false,\n false,\n ).map(appendPath(otherFieldName));\n }\n case \"o2m\":\n case \"o2o\": {\n const isOtherReadOnly = field.otherMetadata().allFields[field.otherFieldName].immutable;\n const otherFieldName = maybeAddTypeFilterSuffix(meta, field);\n // This is not a field, but we want our reverse side to be reactive, so pass reactForOtherSide\n return reverseReactiveHint(\n rootType,\n field.otherMetadata().cstr,\n subHint,\n // IsLoadedCache invalidation always needs to know the otherField name, so we must\n // end up with either a kind=update or kind=read-only target with `otherFieldName` in it.\n field.otherFieldName,\n // We can have three outcomes:\n // - kind=update fields=[otherFieldName] (normal behavior)\n // - kind=update fields=[] + kind=read-only fields=[otherFieldName] (isOtherReadOnly)\n // - kind=read-only fields=[otherFieldName] (hint isReadOnly)\n isReadOnly ? \"hint-read-only\" : isOtherReadOnly ? \"field-read-only\" : false,\n false,\n ).map(appendPath(otherFieldName));\n }\n case \"primaryKey\":\n case \"primitive\":\n case \"enum\":\n _fields.push(key);\n return [];\n case \"m2mEnum\":\n // An enum m2m is a leaf of enum codes (no \"other side\" entity to recurse into); like a m2m,\n // `JoinRows` calls `queueDownstreamReactables` explicitly when its membership changes.\n _fields.push(key);\n return [];\n default:\n throw new Error(`Invalid hint in ${rootType.name}.ts hint ${JSON.stringify(hint)}`);\n }\n } else {\n // We only need to look for ReactiveProperties here, because ReactiveFields & ReactiveReferences\n // have underlying primitive fields that, when/if they change, will be handled in the ^ code.\n //\n // I.e. we specifically don't need to handle RFs & RRs ^, because the EntityManager.flush loop will\n // notice their primitive values changing, and kicking off any downstream reactive fields as necessary.\n const p = getProperties(meta)[key];\n if (p instanceof PropertyImpl) {\n // If the field is marked as readonly (i.e. using the `_ro` suffix), then we can assume that applies to its\n // entire hint as well and can simply omit it. This also allows us to use non-reactive async props as long as\n // they are readonly.\n if (isReadOnly) return [];\n if (!p.reactiveHint) {\n throw new Error(\n `Property ${key} cannot be used in reactive hints in ${rootType.name}.ts hint ${JSON.stringify(\n hint,\n )}, please use hasReactiveProperty instead`,\n );\n }\n return reverseReactiveHint(rootType, meta.cstr, p.reactiveHint, undefined, false, false);\n } else if (p instanceof ReactiveGetterImpl) {\n // If the field is marked as readonly, then we can assume that applies to its entire hint as well and can\n // simply omit it.\n if (isReadOnly) return [];\n return reverseReactiveHint(rootType, meta.cstr, p.reactiveHint, undefined, false, false);\n } else if (p instanceof RecursiveParentsCollectionImpl) {\n // I.e. if this is `Author.mentorsRecursive`:\n // - fieldName=mentorsRecursive (being watched by the caller)\n // - otherFieldName=menteesRecursive (our reversal for walking down)\n // - m2oFieldName = mentor\n //\n // Note that \"reversing parents\" is generally easier, b/c when the tree changes, any given node can\n // still \"walk down\" to find its children w/the \"current value\" childrenRecursive; and any just-now\n // orphaned parents will themselves trigger their own childrenRecursive changes (i.e. we do not need\n // any \"old reference value\" / \"new reference value\" handling).\n //\n // I.e. given a tree of `A is mentor of B is mentor of C`, when B changes mentors, and we need to\n // \"walk to all affected/children mentees, so they can observe their new mentorsRecursive\", merely\n // walking down from (b itself & it's mentees) will find all affected mentees.\n const { otherFieldName, m2oFieldName } = p;\n // When a mentor.firstName/etc field changes, walk to its transitive children (through otherFieldName)\n // via the `return reverseReactiveHint` line below.\n //\n // But if the `author.mentor` field itself changes, we ourselves are also \"a new mentee\" of the mentor, so\n // do `fields.push(m2oFieldName)` to notify our direct reactable (a new mentee), and then our transitive\n // children/mentees. This avoids going \"up to the mentor, and walking down all of his mentees\", which would go\n // through our siblings, which would not have changed/need reactivity.\n _fields.push(m2oFieldName);\n maybeRecursive.push({\n kind: isReadOnly ? \"read-only\" : \"update\",\n entity: entityType,\n fields: recursiveMembershipFields(meta, m2oFieldName),\n path: [otherFieldName],\n });\n // Any reactables who were watching `parentsRecursive`, we'll back down to by going through `childrenRecursive`\n return reverseReactiveHint(rootType, entityType, subHint, undefined, false).map(appendPath(otherFieldName));\n } else if (p instanceof RecursiveChildrenCollectionImpl) {\n const { otherFieldName, o2mFieldName } = p;\n // I.e. this is `Author.menteesRecursive`\n // - fieldName=menteesRecursive` (being watched by the caller)\n // - otherFieldName=mentorsRecursive` (our reversal for walking up)\n // - The o2m's otherFieldName gives us the FK field (e.g., \"mentor\") on the child entity.\n //\n // Note that \"reversing children\" is trickier than reversing parents, b/c when the tree changes,\n // we need to consider both \"old reference value\" and \"new reference value\" scenarios.\n const o2mField = meta.allFields[o2mFieldName] as OneToManyField | OneToOneField;\n const m2oFieldName = o2mField.otherFieldName;\n _fields.push(m2oFieldName);\n maybeRecursive.push({\n kind: isReadOnly ? \"read-only\" : \"update\",\n entity: entityType,\n fields: recursiveMembershipFields(meta, m2oFieldName), // i.e. parent\n path: [otherFieldName], // i.e. parentsRecursive to tell them \"observe your new childrenRecursive\"\n });\n // Any reactables who were watching `childrenRecursive`, we'll up to by going through `parentsRecursive`\n return reverseReactiveHint(rootType, entityType, subHint, undefined, false).map(appendPath(otherFieldName));\n } else if (p instanceof RecursiveM2mCollectionImpl) {\n // I.e. if this is `User.parentsRecursive`:\n // - fieldName=parentsRecursive (being watched by the caller)\n // - otherFieldName=childrenRecursive (our reversal for walking down)\n // - m2mFieldName=parents (the underlying m2m collection)\n //\n // For m2m recursive, the \"change signal\" is when join rows are added/removed, so we push\n // the m2m collection name into fields (like regular m2m handling). To find affected entities\n // that are watching `parentsRecursive`, we walk through `childrenRecursive` (the reverse direction).\n const { otherFieldName, m2mFieldName } = p;\n // When a join row changes (e.g. parents collection is mutated), notify both this entity\n // and its transitive children/parents via otherFieldName\n _fields.push(m2mFieldName);\n maybeRecursive.push({\n kind: isReadOnly ? \"read-only\" : \"update\",\n entity: entityType,\n fields: recursiveMembershipFields(meta, m2mFieldName),\n path: [otherFieldName],\n });\n // Any reactables who were watching this recursive collection, we'll reach via the other direction\n return reverseReactiveHint(rootType, entityType, subHint, undefined, false).map(appendPath(otherFieldName));\n } else {\n throw new Error(`Invalid hint in ${rootType.name}.ts ${JSON.stringify(hint)}`);\n }\n }\n}\n\nfunction maybeAddTypeFilterSuffix(\n meta: EntityMetadata,\n field: ManyToOneField | OneToManyField | ManyToManyField | OneToOneField | PolymorphicFieldComponent,\n): string {\n const otherField = field.otherMetadata().allFields[field.otherFieldName];\n if (!otherField) {\n // This is usually an error, unless if its ReactiveReference which we don't create o2m-s for\n const isReactiveReference = \"kind\" in field && field.kind === \"m2o\" && field.derived === \"async\";\n if (!isReactiveReference) fail(`No field ${field.otherMetadata().type}.${field.otherFieldName}`);\n return field.otherFieldName;\n }\n // If we're Foo, and the other field (which we'll traverse back from at runtime) is actually\n // a poly FK pointing back to multiple `owner=Foo | Bar | Zaz`, add a suffix of `@Foo` so\n // that any runtime traversal that hit `owner` and see a `Bar | Zaz` will stop.\n const nextFieldIsPoly = otherField.kind === \"poly\";\n // If we're a SubType, and the other field points to our base type, assume there might be\n // SubType-specific fields in the path so far, so tell the other side to only walk back through\n // us if its value is actually a SubType.\n const nextFieldPointsToBaseType =\n !!meta.baseType && otherField.kind !== \"poly\" && (otherField as any).otherMetadata().cstr !== meta.cstr;\n return nextFieldIsPoly || nextFieldPointsToBaseType ? `${field.otherFieldName}@${meta.type}` : field.otherFieldName;\n}\n\n/**\n * Walks `reverseHint` for every entity in `entities`.\n *\n * I.e. given `[book1, book2]` and `[\"author\", 'publisher\"]`, will return all the books' authors' publishers.\n *\n * Note that for references (and only references), we walk both through \"the current value\"\n * and prior values remembered in `referenceHistory`. This is fundamentally because references are the true \"owner\"\n * of the relation, while collections are derived.\n *\n * For example, with reversals walking through collections:\n *\n * - Given a hint `book: { author: firstName }`\n * - Which reverses to `author[firstName] -> books`\n * - When we walk through `a1.books`, we use only the current value, which might have only `[b2]` in it.\n * - We don't need to worry about \"the old a1.books\" value, which might have previously had `[b1]` in it,\n * because the `b1.author` changing authors (from `a1` to `a2`) will trigger its own reactivity.\n *\n * Contrast with reversals walking through references:\n *\n * - Given a hint `author: { books: \"title\" }`\n * - Which reverses to `book[title] -> author`\n * - When we traverse through `b1.author`, we use both the current value and remembered values, so that both\n * \"our prior authors\" and \"our new author\" see their latest `author.books` collection values.\n *\n * Delete cleanup runs before reverse hints are walked, so the current relation value may already be unset by the\n * time we get here. For persisted entities, `cleanupOnEntityDeleted` clears the owning FK via `setField`, which\n * remembers the prior FK in `referenceHistory`; this lets us still find the old owner. For collection reversals\n * this is enough because collections are derived from the owning FK: removing `b1` from `a1.books` is represented\n * by `b1.author` changing, not by an independent \"old books\" snapshot.\n *\n * References can also have transient values during a unit of work, i.e. a ReactiveField might observe `b1.author=a2`\n * before the final flush changes it to `a3`. `setField` remembers both original and transient reference values\n * separately from `originalData`, and we walk them in addition to the current value.\n */\nexport async function followReverseHint(\n reactionName: string,\n entities: Entity[],\n reverseHint: string[],\n): Promise<Entity[]> {\n // Start at the current (unique) entities\n let current = new Set(entities);\n const paths = [...reverseHint];\n // And \"walk backwards\" through the reverse hint\n while (paths.length) {\n const path = paths.shift()!;\n const [fieldName, viaType] = path.split(\"@\");\n const promises = new Array(current.size);\n // The path might touch either a reference or a collection\n for (const c of current as Set<any>) {\n const relation = c[fieldName];\n // If `!relation`, I'd really like to `fail`, but atm we're knowingly creating invalid reversals for when\n // a ReactiveField depends on a ReactiveReference; b/c RRs lack an \"other side\", we cannot walk them in\n // reverse, and so for awhile we \"supported\" the RF -> RR pattern by relying on a totally-read-only reactive\n // hint -> dropped during reversal.\n //\n // However, now IsLoadedCache means that even these \"totally read only\" RFs need to be reactive at least\n // during their initial EM creation, to avoid stale values being observed during first-flush mutations,\n // and so we're now stuck with these \"invalid RR reversals\" until we can figure out a better way to handle them.\n // (Now that IsLoadedCache doesn't technically walk paths, it just invalidates given entity+field pairs, so\n // it is not bothered by an invalid/missing RR reversal.)\n if (!relation) continue;\n // fail(`Attempting to react for ${reactionName} for ${c.toString()}, but there is no \"reverse walkable\" field ${c.constructor.name}.${fieldName}`,);\n const currentValuePromise = maybeApplyTypeFilter(relation.load(), viaType);\n // Always wait for the relation itself\n promises.push(currentValuePromise);\n // If we're going from Book.author back to Author to re-validate the Author.books collection,\n // see if Book.author has changed, so we can re-validate both the old author's books and the\n // new author's books.\n const fieldKind = getMetadata(c).allFields[fieldName]?.kind;\n const isReference = fieldKind === \"m2o\" || fieldKind === \"poly\";\n const isManyToMany = fieldKind === \"m2m\";\n // See jsdoc comment about why this is only necessary for references...\n if (isReference) {\n for (const value of getInstanceData(c).getReferenceHistory(fieldName)) {\n promises.push(maybeApplyTypeFilter(loadReferenceHistoryValue(c, value), viaType));\n }\n }\n if (isManyToMany) {\n const m2m = c[fieldName] as ManyToManyCollection<any, any>;\n const joinRows = getEmInternalApi(m2m.entity.em).joinRows(m2m);\n // Return a tuple of [currentRows, removedRows]\n promises.push(joinRows.removedFor(m2m, c));\n }\n // Walk up the old parents\n if (relation instanceof RecursiveParentsCollectionImpl) {\n const { m2oFieldName } = relation;\n for (const value of getInstanceData(c).getReferenceHistory(m2oFieldName)) {\n promises.push(\n // First load the old parent itself\n loadReferenceHistoryValue(c, value).then((oldParent) => {\n if (!oldParent) return undefined;\n // And then resolve its fieldName=parentsRecursive\n const oldParentRecursiveParents = (oldParent as any)[fieldName];\n return oldParentRecursiveParents.load().then((parents: any) => {\n return [oldParent, ...parents];\n });\n }),\n );\n }\n }\n }\n const nextLevel = await Promise.all(promises);\n // Make a new set so that we dedupe as we go\n current = flatAndUnique(nextLevel);\n }\n return [...current];\n}\n\n/** Converts a normalized reactive `hint` into a load hint. */\nexport function convertToLoadHint<T extends Entity>(\n meta: EntityMetadata,\n hint: ReactiveHint<T>,\n allowCustomKeys = false,\n): LoadHint<T> {\n const loadHint = {};\n // Process the hints individually instead of just calling Object.fromEntries so that\n // we can handle inlined reactive hints that overlap.\n for (const [keyMaybeSuffix, subHint] of Object.entries(normalizeHint(hint))) {\n let key = keyMaybeSuffix.replace(suffixRe, \"\");\n let field = meta.allFields[key];\n\n // If `allowCustomKeys` is enabled, we're probably doing `toJSON`,\n // so look for `companyId` & `companyIds` to turn into `company`\n if (!field && allowCustomKeys) {\n const realField = Object.values(meta.allFields).find((f) => f.fieldIdName === key);\n if (realField) {\n field = realField;\n key = realField.fieldName;\n }\n }\n\n if (field) {\n switch (field.kind) {\n case \"m2m\":\n case \"m2o\":\n case \"o2m\":\n case \"o2o\":\n mergeNormalizedHints(loadHint, { [key]: convertToLoadHint(field.otherMetadata(), subHint, allowCustomKeys) });\n break;\n case \"poly\":\n for (const comp of field.components) {\n // Write `{ parent: { child@Type: hint } }` into the load hint\n mergeNormalizedHints(loadHint, {\n [key]: Object.fromEntries(\n Object.entries(convertToLoadHint(comp.otherMetadata(), subHint, allowCustomKeys)).map(\n // Map the subHint keys to add in `@Type`\n ([subKey, subHint]) => [`${subKey}@${comp.otherMetadata().type}`, subHint],\n ),\n ),\n });\n }\n break;\n case \"primitive\":\n case \"enum\":\n if (field.derived === \"async\") {\n mergeNormalizedHints(loadHint, { [key]: {} });\n }\n continue;\n case \"m2mEnum\":\n // The enum codes are a leaf, but the collection itself must be loaded for the reaction to read it.\n mergeNormalizedHints(loadHint, { [key]: {} });\n break;\n case \"primaryKey\":\n continue;\n default:\n throw new Error(`Invalid reactive hint ${meta.tableName} ${JSON.stringify(hint)}`);\n }\n } else {\n const p = getProperties(meta)[key];\n if (p instanceof RecursiveParentsCollectionImpl) {\n mergeNormalizedHints(loadHint, { [p.fieldName]: convertToLoadHint(meta, subHint, allowCustomKeys) });\n } else if (p instanceof RecursiveChildrenCollectionImpl) {\n mergeNormalizedHints(loadHint, { [p.fieldName]: convertToLoadHint(meta, subHint, allowCustomKeys) });\n } else if (p instanceof RecursiveM2mCollectionImpl) {\n mergeNormalizedHints(loadHint, { [p.fieldName]: convertToLoadHint(meta, subHint, allowCustomKeys) });\n } else if (p && p.reactiveHint) {\n mergeNormalizedHints(loadHint, convertToLoadHint(meta, p.reactiveHint, allowCustomKeys));\n } else if (!allowCustomKeys) {\n fail(`Invalid reactive hint on ${meta.tableName} ${JSON.stringify(hint)}`);\n }\n }\n }\n return loadHint as any;\n}\n\n/** An entity that, when `fields` change, should trigger the reactive rule/field pointed to by `path`. */\nexport interface ReactiveTarget {\n kind: \"read-only\" | \"update\";\n /** The entity that contains a field our reactive rule/field accesses. */\n entity: MaybeAbstractEntityConstructor<any>;\n /** The field(s) that our reactive rule/field accesses, plus any implicit fields like FKs. */\n fields: string[];\n /** The path from this `entity` back to the source reactive rule/field. */\n path: string[];\n}\n\nfunction maybeApplyTypeFilter(loadPromise: Promise<Entity | Entity[] | undefined>, viaType: string | undefined) {\n if (viaType) {\n return loadPromise.then((loaded) => {\n if (Array.isArray(loaded)) {\n return loaded.filter((e) => isTypeOrSubType(e, viaType));\n } else if (loaded && isTypeOrSubType(loaded, viaType)) {\n return loaded;\n } else {\n return undefined;\n }\n });\n }\n return loadPromise;\n}\n\n/** Loads a remembered reference value so reverse-hint walking can revisit it. */\nfunction loadReferenceHistoryValue(entity: Entity, value: any): Promise<Entity | undefined> {\n if (isEntity(value)) return Promise.resolve(value);\n if (isId(value)) return entity.em.load(value) as Promise<Entity>;\n return Promise.resolve(undefined);\n}\n\n/** Returns true if `entity` is exactly `typeName` or a subtype of `typeName`.\n *\n * Used to honor poly/type filters like `@Publisher` during reverse-hint walks:\n * a `SmallPublisher` entity should pass an `@Publisher` filter because it is\n * a Publisher via inheritance.\n */\nexport function isTypeOrSubType(entity: Entity, typeName: string): boolean {\n const meta = getMetadata(entity);\n return meta.type === typeName || meta.baseTypes.some((b) => b.type === typeName);\n}\n\nexport function isPolyHint(key: string): boolean {\n return key.includes(\"@\");\n}\n\nexport function splitPolyHintToKeyAndType(key: string): [string, string] {\n const [k, type] = key.split(\"@\");\n return [k, type];\n}\n\n/** If this hint is a poly like `author@Book`, return the type, otherwise return undefined. */\nexport function getRelationFromMaybePolyKey(entity: Entity, key: string): any {\n if (isPolyHint(key)) {\n const [realKey, typeName] = splitPolyHintToKeyAndType(key);\n // Even though `entity[realKey]` might exist, if it's from a different poly type, we don't want it\n const isApplicable = getBaseAndSelfMetas(getMetadata(entity)).some((meta) => meta.type === typeName);\n if (!isApplicable) return undefined;\n return (entity as any)[realKey];\n } else {\n return (entity as any)[key];\n }\n}\n\n/**\n * For an `author -> books -> bookReviews` hint, appends `BookReview.book`, `Book.author`,\n * i.e. the \"other side\" relation, to the reversed path on the way \"out\" from a mutated BookReview\n * to the target `Author` RF/RR/rule.\n */\nfunction appendPath(reverseField: string): (rt: ReactiveTarget) => ReactiveTarget {\n return (rt) => {\n // We can mutate this array b/c it's only owned by a single/continually-updated `ReactiveTarget`\n rt.path = [...rt.path, reverseField];\n return rt;\n };\n}\n\n/** Recursive membership changes on soft deletion or resurrection, even when the underlying relation is unchanged. */\nfunction recursiveMembershipFields(meta: EntityMetadata, fieldName: string): string[] {\n const deletedAt = getBaseMeta(meta).timestampFields?.deletedAt;\n return deletedAt ? [fieldName, deletedAt] : [fieldName];\n}\n\nfunction isAllReadOnly(hint: any): boolean {\n for (const [key, subHint] of Object.entries(normalizeHint(hint))) {\n const okay = (key.endsWith(\"_ro\") || key.endsWith(\":ro\")) && isAllReadOnly(subHint);\n if (!okay) return false;\n }\n return true;\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"reactiveHints.d.cts","names":[],"sources":["../src/reactiveHints.ts"],"mappings":";;;;;;;;;;;;;;;;;;KA8CY,UAAU,UAAU,UAE9B,SAAS,KAGP,SAAS,KACT,SAAS,KACT,iBAAiB,KACjB,iBAAiB,KACjB,iBAAiB;;KAGT,SAAS,UAAU,uBAClB,WAAW,KAAK,cAAc,EAAE,4BAA4B,IAAI,cAAc,EAAE;KAGxF,cAAc,KAAK,UAAU,0BAA0B,KAAK;;KAG5D,iBAAiB,UAAU,aAC7B,WAAW,SAAS,kBAAkB,IAAI,sBAAsB,SAAS,GAAG;KAG1E,iBAAiB,UAAU,aAC7B,WAAW,SAAS,kBAAkB,IAAI,sBAAsB,SAAS,GAAG;KAG1E,iBAAiB,UAAU,aAC7B,WAAW,SAAS,kBAAkB,IAAI,sBAAsB,SAAS,GAAG;;;;;;;;KAUnE,aAAa,UAAU,iBACxB,UAAU,eACjB,oBAAoB,UAAU,eAC9B,mBAAmB;KAEX,mBAAmB,UAAU,aACtC,WAAW,UAAU,MAAM,UAAU,GAAG,kBAAiB,UAAU,UAAS,aAAa;;KAIhF,QAAQ,UAAU,QAAQ,KAAK,YACxC,WAAW,cAAc,WAAW,IAAI,EAAE,WAAW,6BAA6B,KAC/E,wBAAwB,GAAG,SAAS,QAAQ,GAAG,cAAc,GAAG,OAGhE,EAAE,WAAW,gCAAgC,SAAS,KACpD,qBAAqB,GAAG,GAAG,KAAK,gBAAgB,GAAG,SAAS,QAAQ,GAAG,cAAc,GAAG,KAAK,KAC7F,EAAE,WAAW,qBAAqB,SAAS,KACzC,gBAAgB,GAAG,SAAS,QAAQ,GAAG,cAAc,GAAG,KAAK,KAC7D,EAAE,WAAW,0BAA0B,KACrC,qBAAqB,GAAG,KACxB,EAAE,WAAW,sBAAsB,KACjC,iBAAiB,GAAG,SAAS,QAAQ,GAAG,cAAc,GAAG,OACzD,EAAE,WAAW,8BAA8B,KACzC,yBAAyB,GAAG,SAAS,QAAQ,GAAG,cAAc,GAAG,OACjE,EAAE,WAAW,oBAAoB,KAC/B,oBAAoB,KACpB,EAAE;;;;;;;;EASlB,uBAAuB,OAAO,GAAG;;EAEjC,SAAS,QAAQ,UAAU,SAAS,KAAK,YAAY,WAAW,cAAc;IAC5E,qBAAqB;;KAGb,mBAAmB,KAAK,UAAU;EAAW,uBAAuB;IAAM;;;;;;;;KAS1E,2BAA2B,KAAK,iBAAiB,WAAW,sBACpE,mBAAmB,kBACnB,mBAAmB;;;;;;;KAQX,oBAAoB,UAAU,iBAC/B,SAAS,eAChB,oBAAoB,SAAS;;KAGrB,qBAAqB,qCAAqC;EAChE,iBAAiB;;;;;;;;;;;;iBAaP,oBAAoB,UAAU,QAC5C,UAAU,+BAA+B,IACzC,YAAY,+BAA+B,IAC3C,MAAM,aAAa,IACnB,4BACA,4EACA,oBACC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA+SmB,kBACpB,sBACA,UAAU,UACV,wBACC,QAAQ;;iBAuEK,kBAAkB,UAAU,QAC1C,MAAM,gBACN,MAAM,aAAa,IACnB,4BACC,SAAS;;UAyEK;EACf;;EAEA,QAAQ;;EAER;;EAEA;;;;;;;;iBA+Bc,gBAAgB,QAAQ,QAAQ;iBAKhC,WAAW;iBAIX,0BAA0B;;iBAM1B,4BAA4B,QAAQ,QAAQ"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"reactiveHints.d.mts","names":[],"sources":["../src/reactiveHints.ts"],"mappings":";;;;;;;;;;;;;;;;;;KA8CY,UAAU,UAAU,UAE9B,SAAS,KAGP,SAAS,KACT,SAAS,KACT,iBAAiB,KACjB,iBAAiB,KACjB,iBAAiB;;KAGT,SAAS,UAAU,uBAClB,WAAW,KAAK,cAAc,EAAE,4BAA4B,IAAI,cAAc,EAAE;KAGxF,cAAc,KAAK,UAAU,0BAA0B,KAAK;;KAG5D,iBAAiB,UAAU,aAC7B,WAAW,SAAS,kBAAkB,IAAI,sBAAsB,SAAS,GAAG;KAG1E,iBAAiB,UAAU,aAC7B,WAAW,SAAS,kBAAkB,IAAI,sBAAsB,SAAS,GAAG;KAG1E,iBAAiB,UAAU,aAC7B,WAAW,SAAS,kBAAkB,IAAI,sBAAsB,SAAS,GAAG;;;;;;;;KAUnE,aAAa,UAAU,iBACxB,UAAU,eACjB,oBAAoB,UAAU,eAC9B,mBAAmB;KAEX,mBAAmB,UAAU,aACtC,WAAW,UAAU,MAAM,UAAU,GAAG,kBAAiB,UAAU,UAAS,aAAa;;KAIhF,QAAQ,UAAU,QAAQ,KAAK,YACxC,WAAW,cAAc,WAAW,IAAI,EAAE,WAAW,6BAA6B,KAC/E,wBAAwB,GAAG,SAAS,QAAQ,GAAG,cAAc,GAAG,OAGhE,EAAE,WAAW,gCAAgC,SAAS,KACpD,qBAAqB,GAAG,GAAG,KAAK,gBAAgB,GAAG,SAAS,QAAQ,GAAG,cAAc,GAAG,KAAK,KAC7F,EAAE,WAAW,qBAAqB,SAAS,KACzC,gBAAgB,GAAG,SAAS,QAAQ,GAAG,cAAc,GAAG,KAAK,KAC7D,EAAE,WAAW,0BAA0B,KACrC,qBAAqB,GAAG,KACxB,EAAE,WAAW,sBAAsB,KACjC,iBAAiB,GAAG,SAAS,QAAQ,GAAG,cAAc,GAAG,OACzD,EAAE,WAAW,8BAA8B,KACzC,yBAAyB,GAAG,SAAS,QAAQ,GAAG,cAAc,GAAG,OACjE,EAAE,WAAW,oBAAoB,KAC/B,oBAAoB,KACpB,EAAE;;;;;;;;EASlB,uBAAuB,OAAO,GAAG;;EAEjC,SAAS,QAAQ,UAAU,SAAS,KAAK,YAAY,WAAW,cAAc;IAC5E,qBAAqB;;KAGb,mBAAmB,KAAK,UAAU;EAAW,uBAAuB;IAAM;;;;;;;;KAS1E,2BAA2B,KAAK,iBAAiB,WAAW,sBACpE,mBAAmB,kBACnB,mBAAmB;;;;;;;KAQX,oBAAoB,UAAU,iBAC/B,SAAS,eAChB,oBAAoB,SAAS;;KAGrB,qBAAqB,qCAAqC;EAChE,iBAAiB;;;;;;;;;;;;iBAaP,oBAAoB,UAAU,QAC5C,UAAU,+BAA+B,IACzC,YAAY,+BAA+B,IAC3C,MAAM,aAAa,IACnB,4BACA,4EACA,oBACC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA+SmB,kBACpB,sBACA,UAAU,UACV,wBACC,QAAQ;;iBAuEK,kBAAkB,UAAU,QAC1C,MAAM,gBACN,MAAM,aAAa,IACnB,4BACC,SAAS;;UAyEK;EACf;;EAEA,QAAQ;;EAER;;EAEA;;;;;;;;iBA+Bc,gBAAgB,QAAQ,QAAQ;iBAKhC,WAAW;iBAIX,0BAA0B;;iBAM1B,4BAA4B,QAAQ,QAAQ"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"reactiveHints.js","names":[],"sources":["../src/reactiveHints.ts"],"sourcesContent":["import { getInstanceData } from \"./BaseEntity.ts\";\nimport { type Changes } from \"./changes.ts\";\nimport { type Entity, isEntity } from \"./Entity.ts\";\nimport { type MaybeAbstractEntityConstructor, getEmInternalApi, isId } from \"./EntityManager.ts\";\nimport {\n type EntityMetadata,\n type ManyToManyField,\n type ManyToOneField,\n type OneToManyField,\n type OneToOneField,\n type PolymorphicFieldComponent,\n getBaseAndSelfMetas,\n getBaseMeta,\n getMetadata,\n} from \"./EntityMetadata.ts\";\nimport { getProperties } from \"./getProperties.ts\";\nimport { type LoadHint, type Loadable, type Loaded } from \"./loadHints.ts\";\nimport { type NormalizeHint, type SuffixSeperator, normalizeHint, suffixRe } from \"./normalizeHints.ts\";\nimport {\n type Collection,\n type EnumCollection,\n type LoadedCollection,\n type LoadedEnumCollection,\n type LoadedProperty,\n type LoadedReadOnlyCollection,\n type LoadedReference,\n type ManyToManyCollection,\n type OneToOneReference,\n type PolymorphicReference,\n type Property,\n PropertyImpl,\n type ReactiveGetter,\n type ReadOnlyCollection,\n type Reference,\n} from \"./relations/index.ts\";\nimport { type LoadedOneToOneReference } from \"./relations/OneToOneReference.ts\";\nimport { ReactiveGetterImpl } from \"./relations/ReactiveGetter.ts\";\nimport {\n RecursiveChildrenCollectionImpl,\n RecursiveM2mCollectionImpl,\n RecursiveParentsCollectionImpl,\n} from \"./relations/RecursiveCollection.ts\";\nimport { type FieldsOf, type RelationsOf } from \"./typeMap.ts\";\nimport { fail, flatAndUnique, mergeNormalizedHints } from \"./utils.ts\";\n\n/** The keys in `T` that rules & hooks can react to. */\nexport type Reactable<T extends Entity> =\n // This will be primitives + enums + m2os\n FieldsOf<T> &\n // We include `Loadable` so that we include hasReactiveProperties,\n // which are reversable but won't be in any of our codegen types.\n Loadable<T> &\n Gettable<T> &\n SuffixedFieldsOf<T> &\n SuffixedLoadable<T> &\n SuffixedGettable<T>;\n\n/** Finds `hasReactiveGetters` which are not \"loadable\" b/c they're always loaded. */\nexport type Gettable<T extends Entity> = {\n -readonly [K in keyof T as GettableValue<T[K]> extends never ? never : K]: GettableValue<T[K]>;\n};\n\ntype GettableValue<V> = V extends ReactiveGetter<any, infer P> ? P : never;\n\n/** The fields of `T` suffixed with `:ro` or `_ro`. */\ntype SuffixedFieldsOf<T extends Entity> = {\n [K in keyof FieldsOf<T> & string as `${K}${SuffixSeperator}ro`]: FieldsOf<T>[K];\n};\n\ntype SuffixedLoadable<T extends Entity> = {\n [K in keyof Loadable<T> & string as `${K}${SuffixSeperator}ro`]: Loadable<T>[K];\n};\n\ntype SuffixedGettable<T extends Entity> = {\n [K in keyof Gettable<T> & string as `${K}${SuffixSeperator}ro`]: Gettable<T>[K];\n};\n\n/**\n * A reactive hint of a single key, multiple keys, or nested keys and sub-hints.\n *\n * Reactive hints are different from load hints in that reactive hints include specific\n * fields to react against, while load hints contain only relations, collections, and async\n * properties to preload.\n */\nexport type ReactiveHint<T extends Entity> =\n | (keyof Reactable<T> & string)\n | ReadonlyArray<keyof Reactable<T> & string>\n | NestedReactiveHint<T>;\n\nexport type NestedReactiveHint<T extends Entity> = {\n [K in keyof Reactable<T>]?: Reactable<T>[K] extends infer U extends Entity ? ReactiveHint<U> : {};\n};\n\n/** Given an entity `T` that is being reacted with hint `H`, mark only the `H` attributes visible & populated. */\nexport type Reacted<T extends Entity, H> = Entity & {\n [K in keyof NormalizeHint<H> & keyof T]: T[K] extends OneToOneReference<any, infer U>\n ? LoadedOneToOneReference<T, Entity & Reacted<U, NormalizeHint<H>[K]>>\n : // Add an explicit check for PolymorphicReference because it can add `PolymorphicReference &` which gives access to `idIfSet`\n // ...although maybe LoadedReference should just have `idIfSet` in it as well? LoadedOneToOneReference does...\n T[K] extends PolymorphicReference<any, infer U, infer N>\n ? PolymorphicReference<T, U, N> & LoadedReference<T, Entity & Reacted<U, NormalizeHint<H>[K]>, N>\n : T[K] extends Reference<any, infer U, infer N>\n ? LoadedReference<T, Entity & Reacted<U, NormalizeHint<H>[K]>, N>\n : T[K] extends EnumCollection<any, infer E>\n ? LoadedEnumCollection<T, E>\n : T[K] extends Collection<any, infer U>\n ? LoadedCollection<T, Entity & Reacted<U, NormalizeHint<H>[K]>>\n : T[K] extends ReadOnlyCollection<any, infer U>\n ? LoadedReadOnlyCollection<T, Entity & Reacted<U, NormalizeHint<H>[K]>>\n : T[K] extends Property<any, infer V>\n ? LoadedProperty<any, V>\n : T[K];\n} & {\n /**\n * Gives reactive rules & fields a way to get the full entity if they really need it.\n *\n * This should be used carefully b/c it will side-step the reactive system, and instead\n * reactive rules & fields should explicitly declare access to the fields they need, which\n * will then allow accessing the field via the `Reacted<Author, ...>` type.\n */\n fullNonReactiveAccess: Loaded<T, H>;\n /** Allow detecting if a reactive change is due to nuances like `hasUpdated` or `hasChanged`. */\n changes: Changes<T, keyof (FieldsOf<T> & RelationsOf<T>), keyof NormalizeHint<H>>;\n} & MaybeTransientFields<T>;\n\n/** Allow returning reacted entities from `hasReactiveReference`. */\nexport type MaybeReactedEntity<V> = V extends Entity ? { fullNonReactiveAccess: V } : V;\n\n/**\n * Allow returning reacted entities from `hasReactiveProperty`.\n *\n * The `MaybeReactedEntity` is used by `hasReactiveReference` which already has `undefined | never`\n * broken out as a separate generic; `hasReactiveProperty` does not, and so this type conditionally\n * pulls `undefined` out first, and then defers to `MaybeReactedEntity`.\n */\nexport type MaybeReactedPropertyEntity<V> = V extends (infer V1 extends Entity) | undefined\n ? MaybeReactedEntity<V1> | undefined\n : MaybeReactedEntity<V>;\n\n/**\n * A reactive hint that only allows fields immediately on the entity, i.e. no nested hints.\n *\n * This is used by `ReactiveGetter`s to guarantee that their lambda functions will\n * always be `.get`-able and hence not need loading.\n */\nexport type ShallowReactiveHint<T extends Entity> =\n | (keyof FieldsOf<T> & string)\n | ReadonlyArray<keyof FieldsOf<T> & string>;\n\n/** If the domain model has transient fields, allow reactive behavior to see it, i.e. don't run validation rules for special operations. */\nexport type MaybeTransientFields<T> = \"transientFields\" extends keyof T\n ? { transientFields: T[\"transientFields\"] }\n : {};\n\n/**\n * Takes a reactive hint and returns the `ReactiveTarget`s that, should they change, need to\n * walk back to this watching reactable.\n *\n * @param rootType The original type that contained the reactive rule/field, used for helpful error messages\n * @param entityType The current entity of the step we're walking\n * @param hint The current hint we're walking\n * @param reactForOtherSide the name of our FK column, if the previous collection needs to react to our FK changing\n * @param isFirst\n */\nexport function reverseReactiveHint<T extends Entity>(\n rootType: MaybeAbstractEntityConstructor<T>,\n entityType: MaybeAbstractEntityConstructor<T>,\n hint: ReactiveHint<T>,\n reactForOtherSide?: string,\n reactForOtherSideIsReadOnly?: \"field-read-only\" | \"hint-read-only\" | false,\n isFirst: boolean = true,\n): ReactiveTarget[] {\n const meta = getMetadata(entityType);\n // This is the list of fields for this `entityType` that we will react to their changing values\n const fields: string[] = [];\n const readOnlyFields: string[] = [];\n const maybeRecursive: ReactiveTarget[] = [];\n\n // If the hint before us was a collection, i.e. { books: [\"title\"] }, besides just reacting\n // to our `title` changing, `reactForOtherSide` tells us to react to our `author` field as well.\n if (reactForOtherSide) {\n const _fields = reactForOtherSideIsReadOnly ? readOnlyFields : fields;\n _fields.push(reactForOtherSide);\n if (meta.timestampFields?.deletedAt) {\n _fields.push(meta.timestampFields.deletedAt);\n }\n }\n\n // Look through the hint for our own fields, i.e. `[\"firstName\", \"lastName]`, and nested hints like `{ books: \"title\" }`.\n const subHintTargets: ReactiveTarget[] = Object.entries(normalizeHint(hint)).flatMap(([keyMaybeSuffix, subHint]) => {\n return reverseSubHint(\n rootType,\n entityType,\n hint,\n meta,\n // Pass fields & readOnlyFields, so `reverseSubHint` can append any of our primitive fields it finds\n fields,\n readOnlyFields,\n maybeRecursive,\n keyMaybeSuffix, // maybeSuffix = might end with `_ro` like `name_ro`\n subHint,\n );\n });\n\n const myTargets: ReactiveTarget[] = [];\n // If any of our primitives (or m2o fields) change, establish a reactive path from \"here\" (entityType)\n // that is initially empty (path: []) but will have paths layered on by upstream callers\n if (fields.length > 0 || isFirst || reactForOtherSideIsReadOnly === \"field-read-only\") {\n myTargets.push({ kind: \"update\", entity: entityType, fields, path: [] });\n }\n // Normally read-only fields don't trigger true async reactivity, but IsLoadedCache\n // needs them for same-EM cache invalidation.\n if (readOnlyFields.length > 0) {\n myTargets.push({ kind: \"read-only\", entity: entityType, fields: readOnlyFields, path: [] });\n }\n\n return [...myTargets, ...maybeRecursive, ...subHintTargets];\n}\n\nfunction reverseSubHint(\n rootType: MaybeAbstractEntityConstructor<any>,\n entityType: MaybeAbstractEntityConstructor<any>,\n hint: any,\n meta: EntityMetadata,\n fields: string[],\n readOnlyFields: string[],\n maybeRecursive: ReactiveTarget[],\n keyMaybeSuffix: string,\n subHint: any,\n): ReactiveTarget[] {\n const key = keyMaybeSuffix.replace(suffixRe, \"\");\n const field = meta.allFields[key];\n const isReadOnly = !!keyMaybeSuffix.match(suffixRe) || (field && field.immutable);\n const _fields = isReadOnly ? readOnlyFields : fields;\n if (field) {\n switch (field.kind) {\n case \"m2o\": {\n // If this is a ReactiveReference, maybe we do something different?\n _fields.push(field.fieldName);\n const otherMeta = field.otherMetadata();\n // If this is a ReactiveReference, it won't have an \"other\" side, which is fine if:\n // - we're only reacting to the RR value itself (and have no sub-hints), or\n // - all of our sub-hints are read-only\n const otherField = otherMeta.allFields[field.otherFieldName];\n if (!otherField && !isAllReadOnly(subHint)) {\n throw new Error(\n `Invalid hint in ${rootType.name}.ts, we don't currently support reacting through ReactiveReferences, ${JSON.stringify(hint)}`,\n );\n }\n return reverseReactiveHint(rootType, otherMeta.cstr, subHint, undefined, false, false).map(\n appendPath(maybeAddTypeFilterSuffix(meta, field)),\n );\n }\n case \"poly\": {\n _fields.push(field.fieldName);\n // A poly is basically multiple m2os glued together, so copy/paste the `case m2o` code\n // above but do it for each component FK, and glue them together.\n return field.components.flatMap((comp) => {\n return reverseReactiveHint(rootType, comp.otherMetadata().cstr, subHint, undefined, false, false).map(\n appendPath(maybeAddTypeFilterSuffix(meta, comp)),\n );\n });\n }\n case \"m2m\": {\n // While o2m and o2o can watch for just FK changes by passing `reactForOtherSide` (the FK lives in the other\n // table), for m2m reactivity we push the collection name into the reactive hint, because it's effectively\n // \"the other/reverse side\", and JoinRows will trigger `queueDownstreamReactables` explicitly, instead of\n // `setField` which handles regular/non-m2m mutations.\n _fields.push(field.fieldName);\n const otherFieldName = maybeAddTypeFilterSuffix(meta, field);\n return reverseReactiveHint(\n rootType,\n field.otherMetadata().cstr,\n subHint,\n // For m2m, we can always pass undefined here, as otherwise having the opposite m2m collection\n // recalc all of its children will cause over-reactivity\n undefined,\n false,\n false,\n ).map(appendPath(otherFieldName));\n }\n case \"o2m\":\n case \"o2o\": {\n const isOtherReadOnly = field.otherMetadata().allFields[field.otherFieldName].immutable;\n const otherFieldName = maybeAddTypeFilterSuffix(meta, field);\n // This is not a field, but we want our reverse side to be reactive, so pass reactForOtherSide\n return reverseReactiveHint(\n rootType,\n field.otherMetadata().cstr,\n subHint,\n // IsLoadedCache invalidation always needs to know the otherField name, so we must\n // end up with either a kind=update or kind=read-only target with `otherFieldName` in it.\n field.otherFieldName,\n // We can have three outcomes:\n // - kind=update fields=[otherFieldName] (normal behavior)\n // - kind=update fields=[] + kind=read-only fields=[otherFieldName] (isOtherReadOnly)\n // - kind=read-only fields=[otherFieldName] (hint isReadOnly)\n isReadOnly ? \"hint-read-only\" : isOtherReadOnly ? \"field-read-only\" : false,\n false,\n ).map(appendPath(otherFieldName));\n }\n case \"primaryKey\":\n case \"primitive\":\n case \"enum\":\n _fields.push(key);\n return [];\n case \"m2mEnum\":\n // An enum m2m is a leaf of enum codes (no \"other side\" entity to recurse into); like a m2m,\n // `JoinRows` calls `queueDownstreamReactables` explicitly when its membership changes.\n _fields.push(key);\n return [];\n default:\n throw new Error(`Invalid hint in ${rootType.name}.ts hint ${JSON.stringify(hint)}`);\n }\n } else {\n // We only need to look for ReactiveProperties here, because ReactiveFields & ReactiveReferences\n // have underlying primitive fields that, when/if they change, will be handled in the ^ code.\n //\n // I.e. we specifically don't need to handle RFs & RRs ^, because the EntityManager.flush loop will\n // notice their primitive values changing, and kicking off any downstream reactive fields as necessary.\n const p = getProperties(meta)[key];\n if (p instanceof PropertyImpl) {\n // If the field is marked as readonly (i.e. using the `_ro` suffix), then we can assume that applies to its\n // entire hint as well and can simply omit it. This also allows us to use non-reactive async props as long as\n // they are readonly.\n if (isReadOnly) return [];\n if (!p.reactiveHint) {\n throw new Error(\n `Property ${key} cannot be used in reactive hints in ${rootType.name}.ts hint ${JSON.stringify(\n hint,\n )}, please use hasReactiveProperty instead`,\n );\n }\n return reverseReactiveHint(rootType, meta.cstr, p.reactiveHint, undefined, false, false);\n } else if (p instanceof ReactiveGetterImpl) {\n // If the field is marked as readonly, then we can assume that applies to its entire hint as well and can\n // simply omit it.\n if (isReadOnly) return [];\n return reverseReactiveHint(rootType, meta.cstr, p.reactiveHint, undefined, false, false);\n } else if (p instanceof RecursiveParentsCollectionImpl) {\n // I.e. if this is `Author.mentorsRecursive`:\n // - fieldName=mentorsRecursive (being watched by the caller)\n // - otherFieldName=menteesRecursive (our reversal for walking down)\n // - m2oFieldName = mentor\n //\n // Note that \"reversing parents\" is generally easier, b/c when the tree changes, any given node can\n // still \"walk down\" to find its children w/the \"current value\" childrenRecursive; and any just-now\n // orphaned parents will themselves trigger their own childrenRecursive changes (i.e. we do not need\n // any \"old reference value\" / \"new reference value\" handling).\n //\n // I.e. given a tree of `A is mentor of B is mentor of C`, when B changes mentors, and we need to\n // \"walk to all affected/children mentees, so they can observe their new mentorsRecursive\", merely\n // walking down from (b itself & it's mentees) will find all affected mentees.\n const { otherFieldName, m2oFieldName } = p;\n // When a mentor.firstName/etc field changes, walk to its transitive children (through otherFieldName)\n // via the `return reverseReactiveHint` line below.\n //\n // But if the `author.mentor` field itself changes, we ourselves are also \"a new mentee\" of the mentor, so\n // do `fields.push(m2oFieldName)` to notify our direct reactable (a new mentee), and then our transitive\n // children/mentees. This avoids going \"up to the mentor, and walking down all of his mentees\", which would go\n // through our siblings, which would not have changed/need reactivity.\n _fields.push(m2oFieldName);\n maybeRecursive.push({\n kind: isReadOnly ? \"read-only\" : \"update\",\n entity: entityType,\n fields: recursiveMembershipFields(meta, m2oFieldName),\n path: [otherFieldName],\n });\n // Any reactables who were watching `parentsRecursive`, we'll back down to by going through `childrenRecursive`\n return reverseReactiveHint(rootType, entityType, subHint, undefined, false).map(appendPath(otherFieldName));\n } else if (p instanceof RecursiveChildrenCollectionImpl) {\n const { otherFieldName, o2mFieldName } = p;\n // I.e. this is `Author.menteesRecursive`\n // - fieldName=menteesRecursive` (being watched by the caller)\n // - otherFieldName=mentorsRecursive` (our reversal for walking up)\n // - The o2m's otherFieldName gives us the FK field (e.g., \"mentor\") on the child entity.\n //\n // Note that \"reversing children\" is trickier than reversing parents, b/c when the tree changes,\n // we need to consider both \"old reference value\" and \"new reference value\" scenarios.\n const o2mField = meta.allFields[o2mFieldName] as OneToManyField | OneToOneField;\n const m2oFieldName = o2mField.otherFieldName;\n _fields.push(m2oFieldName);\n maybeRecursive.push({\n kind: isReadOnly ? \"read-only\" : \"update\",\n entity: entityType,\n fields: recursiveMembershipFields(meta, m2oFieldName), // i.e. parent\n path: [otherFieldName], // i.e. parentsRecursive to tell them \"observe your new childrenRecursive\"\n });\n // Any reactables who were watching `childrenRecursive`, we'll up to by going through `parentsRecursive`\n return reverseReactiveHint(rootType, entityType, subHint, undefined, false).map(appendPath(otherFieldName));\n } else if (p instanceof RecursiveM2mCollectionImpl) {\n // I.e. if this is `User.parentsRecursive`:\n // - fieldName=parentsRecursive (being watched by the caller)\n // - otherFieldName=childrenRecursive (our reversal for walking down)\n // - m2mFieldName=parents (the underlying m2m collection)\n //\n // For m2m recursive, the \"change signal\" is when join rows are added/removed, so we push\n // the m2m collection name into fields (like regular m2m handling). To find affected entities\n // that are watching `parentsRecursive`, we walk through `childrenRecursive` (the reverse direction).\n const { otherFieldName, m2mFieldName } = p;\n // When a join row changes (e.g. parents collection is mutated), notify both this entity\n // and its transitive children/parents via otherFieldName\n _fields.push(m2mFieldName);\n maybeRecursive.push({\n kind: isReadOnly ? \"read-only\" : \"update\",\n entity: entityType,\n fields: recursiveMembershipFields(meta, m2mFieldName),\n path: [otherFieldName],\n });\n // Any reactables who were watching this recursive collection, we'll reach via the other direction\n return reverseReactiveHint(rootType, entityType, subHint, undefined, false).map(appendPath(otherFieldName));\n } else {\n throw new Error(`Invalid hint in ${rootType.name}.ts ${JSON.stringify(hint)}`);\n }\n }\n}\n\nfunction maybeAddTypeFilterSuffix(\n meta: EntityMetadata,\n field: ManyToOneField | OneToManyField | ManyToManyField | OneToOneField | PolymorphicFieldComponent,\n): string {\n const otherField = field.otherMetadata().allFields[field.otherFieldName];\n if (!otherField) {\n // This is usually an error, unless if its ReactiveReference which we don't create o2m-s for\n const isReactiveReference = \"kind\" in field && field.kind === \"m2o\" && field.derived === \"async\";\n if (!isReactiveReference) fail(`No field ${field.otherMetadata().type}.${field.otherFieldName}`);\n return field.otherFieldName;\n }\n // If we're Foo, and the other field (which we'll traverse back from at runtime) is actually\n // a poly FK pointing back to multiple `owner=Foo | Bar | Zaz`, add a suffix of `@Foo` so\n // that any runtime traversal that hit `owner` and see a `Bar | Zaz` will stop.\n const nextFieldIsPoly = otherField.kind === \"poly\";\n // If we're a SubType, and the other field points to our base type, assume there might be\n // SubType-specific fields in the path so far, so tell the other side to only walk back through\n // us if its value is actually a SubType.\n const nextFieldPointsToBaseType =\n !!meta.baseType && otherField.kind !== \"poly\" && (otherField as any).otherMetadata().cstr !== meta.cstr;\n return nextFieldIsPoly || nextFieldPointsToBaseType ? `${field.otherFieldName}@${meta.type}` : field.otherFieldName;\n}\n\n/**\n * Walks `reverseHint` for every entity in `entities`.\n *\n * I.e. given `[book1, book2]` and `[\"author\", 'publisher\"]`, will return all the books' authors' publishers.\n *\n * Note that for references (and only references), we walk both through \"the current value\"\n * and prior values remembered in `referenceHistory`. This is fundamentally because references are the true \"owner\"\n * of the relation, while collections are derived.\n *\n * For example, with reversals walking through collections:\n *\n * - Given a hint `book: { author: firstName }`\n * - Which reverses to `author[firstName] -> books`\n * - When we walk through `a1.books`, we use only the current value, which might have only `[b2]` in it.\n * - We don't need to worry about \"the old a1.books\" value, which might have previously had `[b1]` in it,\n * because the `b1.author` changing authors (from `a1` to `a2`) will trigger its own reactivity.\n *\n * Contrast with reversals walking through references:\n *\n * - Given a hint `author: { books: \"title\" }`\n * - Which reverses to `book[title] -> author`\n * - When we traverse through `b1.author`, we use both the current value and remembered values, so that both\n * \"our prior authors\" and \"our new author\" see their latest `author.books` collection values.\n *\n * Delete cleanup runs before reverse hints are walked, so the current relation value may already be unset by the\n * time we get here. For persisted entities, `cleanupOnEntityDeleted` clears the owning FK via `setField`, which\n * remembers the prior FK in `referenceHistory`; this lets us still find the old owner. For collection reversals\n * this is enough because collections are derived from the owning FK: removing `b1` from `a1.books` is represented\n * by `b1.author` changing, not by an independent \"old books\" snapshot.\n *\n * References can also have transient values during a unit of work, i.e. a ReactiveField might observe `b1.author=a2`\n * before the final flush changes it to `a3`. `setField` remembers both original and transient reference values\n * separately from `originalData`, and we walk them in addition to the current value.\n */\nexport async function followReverseHint(\n reactionName: string,\n entities: Entity[],\n reverseHint: string[],\n): Promise<Entity[]> {\n // Start at the current (unique) entities\n let current = new Set(entities);\n const paths = [...reverseHint];\n // And \"walk backwards\" through the reverse hint\n while (paths.length) {\n const path = paths.shift()!;\n const [fieldName, viaType] = path.split(\"@\");\n const promises = new Array(current.size);\n // The path might touch either a reference or a collection\n for (const c of current as Set<any>) {\n const relation = c[fieldName];\n // If `!relation`, I'd really like to `fail`, but atm we're knowingly creating invalid reversals for when\n // a ReactiveField depends on a ReactiveReference; b/c RRs lack an \"other side\", we cannot walk them in\n // reverse, and so for awhile we \"supported\" the RF -> RR pattern by relying on a totally-read-only reactive\n // hint -> dropped during reversal.\n //\n // However, now IsLoadedCache means that even these \"totally read only\" RFs need to be reactive at least\n // during their initial EM creation, to avoid stale values being observed during first-flush mutations,\n // and so we're now stuck with these \"invalid RR reversals\" until we can figure out a better way to handle them.\n // (Now that IsLoadedCache doesn't technically walk paths, it just invalidates given entity+field pairs, so\n // it is not bothered by an invalid/missing RR reversal.)\n if (!relation) continue;\n // fail(`Attempting to react for ${reactionName} for ${c.toString()}, but there is no \"reverse walkable\" field ${c.constructor.name}.${fieldName}`,);\n const currentValuePromise = maybeApplyTypeFilter(relation.load(), viaType);\n // Always wait for the relation itself\n promises.push(currentValuePromise);\n // If we're going from Book.author back to Author to re-validate the Author.books collection,\n // see if Book.author has changed, so we can re-validate both the old author's books and the\n // new author's books.\n const fieldKind = getMetadata(c).allFields[fieldName]?.kind;\n const isReference = fieldKind === \"m2o\" || fieldKind === \"poly\";\n const isManyToMany = fieldKind === \"m2m\";\n // See jsdoc comment about why this is only necessary for references...\n if (isReference) {\n for (const value of getInstanceData(c).getReferenceHistory(fieldName)) {\n promises.push(maybeApplyTypeFilter(loadReferenceHistoryValue(c, value), viaType));\n }\n }\n if (isManyToMany) {\n const m2m = c[fieldName] as ManyToManyCollection<any, any>;\n const joinRows = getEmInternalApi(m2m.entity.em).joinRows(m2m);\n // Return a tuple of [currentRows, removedRows]\n promises.push(joinRows.removedFor(m2m, c));\n }\n // Walk up the old parents\n if (relation instanceof RecursiveParentsCollectionImpl) {\n const { m2oFieldName } = relation;\n for (const value of getInstanceData(c).getReferenceHistory(m2oFieldName)) {\n promises.push(\n // First load the old parent itself\n loadReferenceHistoryValue(c, value).then((oldParent) => {\n if (!oldParent) return undefined;\n // And then resolve its fieldName=parentsRecursive\n const oldParentRecursiveParents = (oldParent as any)[fieldName];\n return oldParentRecursiveParents.load().then((parents: any) => {\n return [oldParent, ...parents];\n });\n }),\n );\n }\n }\n }\n const nextLevel = await Promise.all(promises);\n // Make a new set so that we dedupe as we go\n current = flatAndUnique(nextLevel);\n }\n return [...current];\n}\n\n/** Converts a normalized reactive `hint` into a load hint. */\nexport function convertToLoadHint<T extends Entity>(\n meta: EntityMetadata,\n hint: ReactiveHint<T>,\n allowCustomKeys = false,\n): LoadHint<T> {\n const loadHint = {};\n // Process the hints individually instead of just calling Object.fromEntries so that\n // we can handle inlined reactive hints that overlap.\n for (const [keyMaybeSuffix, subHint] of Object.entries(normalizeHint(hint))) {\n let key = keyMaybeSuffix.replace(suffixRe, \"\");\n let field = meta.allFields[key];\n\n // If `allowCustomKeys` is enabled, we're probably doing `toJSON`,\n // so look for `companyId` & `companyIds` to turn into `company`\n if (!field && allowCustomKeys) {\n const realField = Object.values(meta.allFields).find((f) => f.fieldIdName === key);\n if (realField) {\n field = realField;\n key = realField.fieldName;\n }\n }\n\n if (field) {\n switch (field.kind) {\n case \"m2m\":\n case \"m2o\":\n case \"o2m\":\n case \"o2o\":\n mergeNormalizedHints(loadHint, { [key]: convertToLoadHint(field.otherMetadata(), subHint, allowCustomKeys) });\n break;\n case \"poly\":\n for (const comp of field.components) {\n // Write `{ parent: { child@Type: hint } }` into the load hint\n mergeNormalizedHints(loadHint, {\n [key]: Object.fromEntries(\n Object.entries(convertToLoadHint(comp.otherMetadata(), subHint, allowCustomKeys)).map(\n // Map the subHint keys to add in `@Type`\n ([subKey, subHint]) => [`${subKey}@${comp.otherMetadata().type}`, subHint],\n ),\n ),\n });\n }\n break;\n case \"primitive\":\n case \"enum\":\n if (field.derived === \"async\") {\n mergeNormalizedHints(loadHint, { [key]: {} });\n }\n continue;\n case \"m2mEnum\":\n // The enum codes are a leaf, but the collection itself must be loaded for the reaction to read it.\n mergeNormalizedHints(loadHint, { [key]: {} });\n break;\n case \"primaryKey\":\n continue;\n default:\n throw new Error(`Invalid reactive hint ${meta.tableName} ${JSON.stringify(hint)}`);\n }\n } else {\n const p = getProperties(meta)[key];\n if (p instanceof RecursiveParentsCollectionImpl) {\n mergeNormalizedHints(loadHint, { [p.fieldName]: convertToLoadHint(meta, subHint, allowCustomKeys) });\n } else if (p instanceof RecursiveChildrenCollectionImpl) {\n mergeNormalizedHints(loadHint, { [p.fieldName]: convertToLoadHint(meta, subHint, allowCustomKeys) });\n } else if (p instanceof RecursiveM2mCollectionImpl) {\n mergeNormalizedHints(loadHint, { [p.fieldName]: convertToLoadHint(meta, subHint, allowCustomKeys) });\n } else if (p && p.reactiveHint) {\n mergeNormalizedHints(loadHint, convertToLoadHint(meta, p.reactiveHint, allowCustomKeys));\n } else if (!allowCustomKeys) {\n fail(`Invalid reactive hint on ${meta.tableName} ${JSON.stringify(hint)}`);\n }\n }\n }\n return loadHint as any;\n}\n\n/** An entity that, when `fields` change, should trigger the reactive rule/field pointed to by `path`. */\nexport interface ReactiveTarget {\n kind: \"read-only\" | \"update\";\n /** The entity that contains a field our reactive rule/field accesses. */\n entity: MaybeAbstractEntityConstructor<any>;\n /** The field(s) that our reactive rule/field accesses, plus any implicit fields like FKs. */\n fields: string[];\n /** The path from this `entity` back to the source reactive rule/field. */\n path: string[];\n}\n\nfunction maybeApplyTypeFilter(loadPromise: Promise<Entity | Entity[] | undefined>, viaType: string | undefined) {\n if (viaType) {\n return loadPromise.then((loaded) => {\n if (Array.isArray(loaded)) {\n return loaded.filter((e) => isTypeOrSubType(e, viaType));\n } else if (loaded && isTypeOrSubType(loaded, viaType)) {\n return loaded;\n } else {\n return undefined;\n }\n });\n }\n return loadPromise;\n}\n\n/** Loads a remembered reference value so reverse-hint walking can revisit it. */\nfunction loadReferenceHistoryValue(entity: Entity, value: any): Promise<Entity | undefined> {\n if (isEntity(value)) return Promise.resolve(value);\n if (isId(value)) return entity.em.load(value) as Promise<Entity>;\n return Promise.resolve(undefined);\n}\n\n/** Returns true if `entity` is exactly `typeName` or a subtype of `typeName`.\n *\n * Used to honor poly/type filters like `@Publisher` during reverse-hint walks:\n * a `SmallPublisher` entity should pass an `@Publisher` filter because it is\n * a Publisher via inheritance.\n */\nexport function isTypeOrSubType(entity: Entity, typeName: string): boolean {\n const meta = getMetadata(entity);\n return meta.type === typeName || meta.baseTypes.some((b) => b.type === typeName);\n}\n\nexport function isPolyHint(key: string): boolean {\n return key.includes(\"@\");\n}\n\nexport function splitPolyHintToKeyAndType(key: string): [string, string] {\n const [k, type] = key.split(\"@\");\n return [k, type];\n}\n\n/** If this hint is a poly like `author@Book`, return the type, otherwise return undefined. */\nexport function getRelationFromMaybePolyKey(entity: Entity, key: string): any {\n if (isPolyHint(key)) {\n const [realKey, typeName] = splitPolyHintToKeyAndType(key);\n // Even though `entity[realKey]` might exist, if it's from a different poly type, we don't want it\n const isApplicable = getBaseAndSelfMetas(getMetadata(entity)).some((meta) => meta.type === typeName);\n if (!isApplicable) return undefined;\n return (entity as any)[realKey];\n } else {\n return (entity as any)[key];\n }\n}\n\n/**\n * For an `author -> books -> bookReviews` hint, appends `BookReview.book`, `Book.author`,\n * i.e. the \"other side\" relation, to the reversed path on the way \"out\" from a mutated BookReview\n * to the target `Author` RF/RR/rule.\n */\nfunction appendPath(reverseField: string): (rt: ReactiveTarget) => ReactiveTarget {\n return (rt) => {\n // We can mutate this array b/c it's only owned by a single/continually-updated `ReactiveTarget`\n rt.path = [...rt.path, reverseField];\n return rt;\n };\n}\n\n/** Recursive membership changes on soft deletion or resurrection, even when the underlying relation is unchanged. */\nfunction recursiveMembershipFields(meta: EntityMetadata, fieldName: string): string[] {\n const deletedAt = getBaseMeta(meta).timestampFields?.deletedAt;\n return deletedAt ? [fieldName, deletedAt] : [fieldName];\n}\n\nfunction isAllReadOnly(hint: any): boolean {\n for (const [key, subHint] of Object.entries(normalizeHint(hint))) {\n const okay = (key.endsWith(\"_ro\") || key.endsWith(\":ro\")) && isAllReadOnly(subHint);\n if (!okay) return false;\n }\n return true;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAoKA,SAAgB,oBACd,UACA,YACA,MACA,mBACA,6BACA,UAAmB,MACD;CAClB,MAAM,OAAO,YAAY,UAAU;CAEnC,MAAM,SAAmB,CAAC;CAC1B,MAAM,iBAA2B,CAAC;CAClC,MAAM,iBAAmC,CAAC;CAI1C,IAAI,mBAAmB;EACrB,MAAM,UAAU,8BAA8B,iBAAiB;EAC/D,QAAQ,KAAK,iBAAiB;EAC9B,IAAI,KAAK,iBAAiB,WACxB,QAAQ,KAAK,KAAK,gBAAgB,SAAS;CAE/C;CAGA,MAAM,iBAAmC,OAAO,QAAQ,cAAc,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,gBAAgB,aAAa;EAClH,OAAO,eACL,UACA,YACA,MACA,MAEA,QACA,gBACA,gBACA,gBACA,OACF;CACF,CAAC;CAED,MAAM,YAA8B,CAAC;CAGrC,IAAI,OAAO,SAAS,KAAK,WAAW,gCAAgC,mBAClE,UAAU,KAAK;EAAE,MAAM;EAAU,QAAQ;EAAY;EAAQ,MAAM,CAAC;CAAE,CAAC;CAIzE,IAAI,eAAe,SAAS,GAC1B,UAAU,KAAK;EAAE,MAAM;EAAa,QAAQ;EAAY,QAAQ;EAAgB,MAAM,CAAC;CAAE,CAAC;CAG5F,OAAO;EAAC,GAAG;EAAW,GAAG;EAAgB,GAAG;CAAc;AAC5D;AAEA,SAAS,eACP,UACA,YACA,MACA,MACA,QACA,gBACA,gBACA,gBACA,SACkB;CAClB,MAAM,MAAM,eAAe,QAAQ,UAAU,EAAE;CAC/C,MAAM,QAAQ,KAAK,UAAU;CAC7B,MAAM,aAAa,CAAC,CAAC,eAAe,MAAM,QAAQ,KAAM,SAAS,MAAM;CACvE,MAAM,UAAU,aAAa,iBAAiB;CAC9C,IAAI,OACF,QAAQ,MAAM,MAAd;EACE,KAAK,OAAO;GAEV,QAAQ,KAAK,MAAM,SAAS;GAC5B,MAAM,YAAY,MAAM,cAAc;GAKtC,IAAI,CADe,UAAU,UAAU,MAAM,mBAC1B,CAAC,cAAc,OAAO,GACvC,MAAM,IAAI,MACR,mBAAmB,SAAS,KAAK,uEAAuE,KAAK,UAAU,IAAI,GAC7H;GAEF,OAAO,oBAAoB,UAAU,UAAU,MAAM,SAAS,KAAA,GAAW,OAAO,KAAK,CAAC,CAAC,IACrF,WAAW,yBAAyB,MAAM,KAAK,CAAC,CAClD;EACF;EACA,KAAK;GACH,QAAQ,KAAK,MAAM,SAAS;GAG5B,OAAO,MAAM,WAAW,SAAS,SAAS;IACxC,OAAO,oBAAoB,UAAU,KAAK,cAAc,CAAC,CAAC,MAAM,SAAS,KAAA,GAAW,OAAO,KAAK,CAAC,CAAC,IAChG,WAAW,yBAAyB,MAAM,IAAI,CAAC,CACjD;GACF,CAAC;EAEH,KAAK,OAAO;GAKV,QAAQ,KAAK,MAAM,SAAS;GAC5B,MAAM,iBAAiB,yBAAyB,MAAM,KAAK;GAC3D,OAAO,oBACL,UACA,MAAM,cAAc,CAAC,CAAC,MACtB,SAGA,KAAA,GACA,OACA,KACF,CAAC,CAAC,IAAI,WAAW,cAAc,CAAC;EAClC;EACA,KAAK;EACL,KAAK,OAAO;GACV,MAAM,kBAAkB,MAAM,cAAc,CAAC,CAAC,UAAU,MAAM,eAAe,CAAC;GAC9E,MAAM,iBAAiB,yBAAyB,MAAM,KAAK;GAE3D,OAAO,oBACL,UACA,MAAM,cAAc,CAAC,CAAC,MACtB,SAGA,MAAM,gBAKN,aAAa,mBAAmB,kBAAkB,oBAAoB,OACtE,KACF,CAAC,CAAC,IAAI,WAAW,cAAc,CAAC;EAClC;EACA,KAAK;EACL,KAAK;EACL,KAAK;GACH,QAAQ,KAAK,GAAG;GAChB,OAAO,CAAC;EACV,KAAK;GAGH,QAAQ,KAAK,GAAG;GAChB,OAAO,CAAC;EACV,SACE,MAAM,IAAI,MAAM,mBAAmB,SAAS,KAAK,WAAW,KAAK,UAAU,IAAI,GAAG;CACtF;MACK;EAML,MAAM,IAAI,cAAc,IAAI,CAAC,CAAC;EAC9B,IAAI,aAAa,cAAc;GAI7B,IAAI,YAAY,OAAO,CAAC;GACxB,IAAI,CAAC,EAAE,cACL,MAAM,IAAI,MACR,YAAY,IAAI,uCAAuC,SAAS,KAAK,WAAW,KAAK,UACnF,IACF,EAAE,yCACJ;GAEF,OAAO,oBAAoB,UAAU,KAAK,MAAM,EAAE,cAAc,KAAA,GAAW,OAAO,KAAK;EACzF,OAAO,IAAI,aAAa,oBAAoB;GAG1C,IAAI,YAAY,OAAO,CAAC;GACxB,OAAO,oBAAoB,UAAU,KAAK,MAAM,EAAE,cAAc,KAAA,GAAW,OAAO,KAAK;EACzF,OAAO,IAAI,aAAa,gCAAgC;GActD,MAAM,EAAE,gBAAgB,iBAAiB;GAQzC,QAAQ,KAAK,YAAY;GACzB,eAAe,KAAK;IAClB,MAAM,aAAa,cAAc;IACjC,QAAQ;IACR,QAAQ,0BAA0B,MAAM,YAAY;IACpD,MAAM,CAAC,cAAc;GACvB,CAAC;GAED,OAAO,oBAAoB,UAAU,YAAY,SAAS,KAAA,GAAW,KAAK,CAAC,CAAC,IAAI,WAAW,cAAc,CAAC;EAC5G,OAAO,IAAI,aAAa,iCAAiC;GACvD,MAAM,EAAE,gBAAgB,iBAAiB;GASzC,MAAM,eADW,KAAK,UAAU,aACH,CAAC;GAC9B,QAAQ,KAAK,YAAY;GACzB,eAAe,KAAK;IAClB,MAAM,aAAa,cAAc;IACjC,QAAQ;IACR,QAAQ,0BAA0B,MAAM,YAAY;IACpD,MAAM,CAAC,cAAc;GACvB,CAAC;GAED,OAAO,oBAAoB,UAAU,YAAY,SAAS,KAAA,GAAW,KAAK,CAAC,CAAC,IAAI,WAAW,cAAc,CAAC;EAC5G,OAAO,IAAI,aAAa,4BAA4B;GASlD,MAAM,EAAE,gBAAgB,iBAAiB;GAGzC,QAAQ,KAAK,YAAY;GACzB,eAAe,KAAK;IAClB,MAAM,aAAa,cAAc;IACjC,QAAQ;IACR,QAAQ,0BAA0B,MAAM,YAAY;IACpD,MAAM,CAAC,cAAc;GACvB,CAAC;GAED,OAAO,oBAAoB,UAAU,YAAY,SAAS,KAAA,GAAW,KAAK,CAAC,CAAC,IAAI,WAAW,cAAc,CAAC;EAC5G,OACE,MAAM,IAAI,MAAM,mBAAmB,SAAS,KAAK,MAAM,KAAK,UAAU,IAAI,GAAG;CAEjF;AACF;AAEA,SAAS,yBACP,MACA,OACQ;CACR,MAAM,aAAa,MAAM,cAAc,CAAC,CAAC,UAAU,MAAM;CACzD,IAAI,CAAC,YAAY;EAGf,IAAI,EADwB,UAAU,SAAS,MAAM,SAAS,SAAS,MAAM,YAAY,UAC/D,KAAK,YAAY,MAAM,cAAc,CAAC,CAAC,KAAK,GAAG,MAAM,gBAAgB;EAC/F,OAAO,MAAM;CACf;CAIA,MAAM,kBAAkB,WAAW,SAAS;CAI5C,MAAM,4BACJ,CAAC,CAAC,KAAK,YAAY,WAAW,SAAS,UAAW,WAAmB,cAAc,CAAC,CAAC,SAAS,KAAK;CACrG,OAAO,mBAAmB,4BAA4B,GAAG,MAAM,eAAe,GAAG,KAAK,SAAS,MAAM;AACvG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoCA,eAAsB,kBACpB,cACA,UACA,aACmB;CAEnB,IAAI,UAAU,IAAI,IAAI,QAAQ;CAC9B,MAAM,QAAQ,CAAC,GAAG,WAAW;CAE7B,OAAO,MAAM,QAAQ;EAEnB,MAAM,CAAC,WAAW,WADL,MAAM,MACa,CAAC,CAAC,MAAM,GAAG;EAC3C,MAAM,WAAW,IAAI,MAAM,QAAQ,IAAI;EAEvC,KAAK,MAAM,KAAK,SAAqB;GACnC,MAAM,WAAW,EAAE;GAWnB,IAAI,CAAC,UAAU;GAEf,MAAM,sBAAsB,qBAAqB,SAAS,KAAK,GAAG,OAAO;GAEzE,SAAS,KAAK,mBAAmB;GAIjC,MAAM,YAAY,YAAY,CAAC,CAAC,CAAC,UAAU,UAAU,EAAE;GACvD,MAAM,cAAc,cAAc,SAAS,cAAc;GACzD,MAAM,eAAe,cAAc;GAEnC,IAAI,aACF,KAAK,MAAM,SAAS,gBAAgB,CAAC,CAAC,CAAC,oBAAoB,SAAS,GAClE,SAAS,KAAK,qBAAqB,0BAA0B,GAAG,KAAK,GAAG,OAAO,CAAC;GAGpF,IAAI,cAAc;IAChB,MAAM,MAAM,EAAE;IACd,MAAM,WAAW,iBAAiB,IAAI,OAAO,EAAE,CAAC,CAAC,SAAS,GAAG;IAE7D,SAAS,KAAK,SAAS,WAAW,KAAK,CAAC,CAAC;GAC3C;GAEA,IAAI,oBAAoB,gCAAgC;IACtD,MAAM,EAAE,iBAAiB;IACzB,KAAK,MAAM,SAAS,gBAAgB,CAAC,CAAC,CAAC,oBAAoB,YAAY,GACrE,SAAS,KAEP,0BAA0B,GAAG,KAAK,CAAC,CAAC,MAAM,cAAc;KACtD,IAAI,CAAC,WAAW,OAAO,KAAA;KAGvB,OADmC,UAAkB,UACrB,CAAC,KAAK,CAAC,CAAC,MAAM,YAAiB;MAC7D,OAAO,CAAC,WAAW,GAAG,OAAO;KAC/B,CAAC;IACH,CAAC,CACH;GAEJ;EACF;EACA,MAAM,YAAY,MAAM,QAAQ,IAAI,QAAQ;EAE5C,UAAU,cAAc,SAAS;CACnC;CACA,OAAO,CAAC,GAAG,OAAO;AACpB;;AAGA,SAAgB,kBACd,MACA,MACA,kBAAkB,OACL;CACb,MAAM,WAAW,CAAC;CAGlB,KAAK,MAAM,CAAC,gBAAgB,YAAY,OAAO,QAAQ,cAAc,IAAI,CAAC,GAAG;EAC3E,IAAI,MAAM,eAAe,QAAQ,UAAU,EAAE;EAC7C,IAAI,QAAQ,KAAK,UAAU;EAI3B,IAAI,CAAC,SAAS,iBAAiB;GAC7B,MAAM,YAAY,OAAO,OAAO,KAAK,SAAS,CAAC,CAAC,MAAM,MAAM,EAAE,gBAAgB,GAAG;GACjF,IAAI,WAAW;IACb,QAAQ;IACR,MAAM,UAAU;GAClB;EACF;EAEA,IAAI,OACF,QAAQ,MAAM,MAAd;GACE,KAAK;GACL,KAAK;GACL,KAAK;GACL,KAAK;IACH,qBAAqB,UAAU,GAAG,MAAM,kBAAkB,MAAM,cAAc,GAAG,SAAS,eAAe,EAAE,CAAC;IAC5G;GACF,KAAK;IACH,KAAK,MAAM,QAAQ,MAAM,YAEvB,qBAAqB,UAAU,GAC5B,MAAM,OAAO,YACZ,OAAO,QAAQ,kBAAkB,KAAK,cAAc,GAAG,SAAS,eAAe,CAAC,CAAC,CAAC,KAE/E,CAAC,QAAQ,aAAa,CAAC,GAAG,OAAO,GAAG,KAAK,cAAc,CAAC,CAAC,QAAQ,OAAO,CAC3E,CACF,EACF,CAAC;IAEH;GACF,KAAK;GACL,KAAK;IACH,IAAI,MAAM,YAAY,SACpB,qBAAqB,UAAU,GAAG,MAAM,CAAC,EAAE,CAAC;IAE9C;GACF,KAAK;IAEH,qBAAqB,UAAU,GAAG,MAAM,CAAC,EAAE,CAAC;IAC5C;GACF,KAAK,cACH;GACF,SACE,MAAM,IAAI,MAAM,yBAAyB,KAAK,UAAU,GAAG,KAAK,UAAU,IAAI,GAAG;EACrF;OACK;GACL,MAAM,IAAI,cAAc,IAAI,CAAC,CAAC;GAC9B,IAAI,aAAa,gCACf,qBAAqB,UAAU,GAAG,EAAE,YAAY,kBAAkB,MAAM,SAAS,eAAe,EAAE,CAAC;QAC9F,IAAI,aAAa,iCACtB,qBAAqB,UAAU,GAAG,EAAE,YAAY,kBAAkB,MAAM,SAAS,eAAe,EAAE,CAAC;QAC9F,IAAI,aAAa,4BACtB,qBAAqB,UAAU,GAAG,EAAE,YAAY,kBAAkB,MAAM,SAAS,eAAe,EAAE,CAAC;QAC9F,IAAI,KAAK,EAAE,cAChB,qBAAqB,UAAU,kBAAkB,MAAM,EAAE,cAAc,eAAe,CAAC;QAClF,IAAI,CAAC,iBACV,KAAK,4BAA4B,KAAK,UAAU,GAAG,KAAK,UAAU,IAAI,GAAG;EAE7E;CACF;CACA,OAAO;AACT;AAaA,SAAS,qBAAqB,aAAqD,SAA6B;CAC9G,IAAI,SACF,OAAO,YAAY,MAAM,WAAW;EAClC,IAAI,MAAM,QAAQ,MAAM,GACtB,OAAO,OAAO,QAAQ,MAAM,gBAAgB,GAAG,OAAO,CAAC;OAClD,IAAI,UAAU,gBAAgB,QAAQ,OAAO,GAClD,OAAO;OAEP;CAEJ,CAAC;CAEH,OAAO;AACT;;AAGA,SAAS,0BAA0B,QAAgB,OAAyC;CAC1F,IAAI,SAAS,KAAK,GAAG,OAAO,QAAQ,QAAQ,KAAK;CACjD,IAAI,KAAK,KAAK,GAAG,OAAO,OAAO,GAAG,KAAK,KAAK;CAC5C,OAAO,QAAQ,QAAQ,KAAA,CAAS;AAClC;;;;;;;AAQA,SAAgB,gBAAgB,QAAgB,UAA2B;CACzE,MAAM,OAAO,YAAY,MAAM;CAC/B,OAAO,KAAK,SAAS,YAAY,KAAK,UAAU,MAAM,MAAM,EAAE,SAAS,QAAQ;AACjF;AAEA,SAAgB,WAAW,KAAsB;CAC/C,OAAO,IAAI,SAAS,GAAG;AACzB;AAEA,SAAgB,0BAA0B,KAA+B;CACvE,MAAM,CAAC,GAAG,QAAQ,IAAI,MAAM,GAAG;CAC/B,OAAO,CAAC,GAAG,IAAI;AACjB;;AAGA,SAAgB,4BAA4B,QAAgB,KAAkB;CAC5E,IAAI,WAAW,GAAG,GAAG;EACnB,MAAM,CAAC,SAAS,YAAY,0BAA0B,GAAG;EAGzD,IAAI,CADiB,oBAAoB,YAAY,MAAM,CAAC,CAAC,CAAC,MAAM,SAAS,KAAK,SAAS,QAC3E,GAAG,OAAO,KAAA;EAC1B,OAAQ,OAAe;CACzB,OACE,OAAQ,OAAe;AAE3B;;;;;;AAOA,SAAS,WAAW,cAA8D;CAChF,QAAQ,OAAO;EAEb,GAAG,OAAO,CAAC,GAAG,GAAG,MAAM,YAAY;EACnC,OAAO;CACT;AACF;;AAGA,SAAS,0BAA0B,MAAsB,WAA6B;CACpF,MAAM,YAAY,YAAY,IAAI,CAAC,CAAC,iBAAiB;CACrD,OAAO,YAAY,CAAC,WAAW,SAAS,IAAI,CAAC,SAAS;AACxD;AAEA,SAAS,cAAc,MAAoB;CACzC,KAAK,MAAM,CAAC,KAAK,YAAY,OAAO,QAAQ,cAAc,IAAI,CAAC,GAE7D,IAAI,GADU,IAAI,SAAS,KAAK,KAAK,IAAI,SAAS,KAAK,MAAM,cAAc,OAAO,IACvE,OAAO;CAEpB,OAAO;AACT"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"serde.cjs","names":["createRequire","canonicalDbType","arrayOutputType","plainDateMapper","plainTimeMapper","plainDateTimeMapper","getRuntimeConfig","requireTemporal","zonedDateTimeMapper","keyToNumber","maybeResolveReferenceToId","keyToTaggedId","isDefined"],"sources":["../src/serde.ts"],"sourcesContent":["import { createRequire } from \"node:module\";\n\nimport { isDefined, keyToNumber, keyToTaggedId, maybeResolveReferenceToId } from \"./index.ts\";\nimport { getRuntimeConfig } from \"./runtimeConfig.ts\";\nimport { type Temporal, requireTemporal } from \"./temporal.ts\";\nimport { plainDateMapper, plainDateTimeMapper, plainTimeMapper, zonedDateTimeMapper } from \"./temporalMappers.ts\";\nimport { type TypeInfo, arrayOutputType, canonicalDbType } from \"./TypeInfo.ts\";\n\nconst runtimeRequire = createRequire(import.meta.url);\n\n/** Scalar conversion only: no field names, entity hydration, or FK fixups. */\nexport interface ScalarCodec {\n dbType: string;\n isArray: boolean;\n /** Compatibility evidence for scalar conversion, absent for unknown codecs. */\n readonly outputType?: TypeInfo;\n /** Encodes a domain value for a filter, i.e. an em.find WHERE parameter. */\n mapToDb(value: any): any;\n /**\n * Encodes a domain value for an INSERT or UPDATE binding.\n *\n * Callers must handle omission, SQL NULL, and SQL expressions before encoding. JSON null and\n * codec defaults can differ from SQL NULL. Direct mutations must validate reference targets\n * and reject new or unflushed entities before encoding.\n */\n mapToDbValue?(value: unknown): unknown;\n /** Converts a driver value to its domain value, including the codec's null/default handling. */\n mapFromDb(value: unknown): unknown;\n /**\n * Converts a json_agg cell to a driver-row value, not a domain value.\n *\n * Lazy field hydration subsequently calls mapFromDb. I.e. Date codecs reconstruct a Date\n * from the JSON string, while Temporal codecs retain the driver's string representation.\n */\n mapFromJsonAgg(value: any): any;\n /** Reconstructs a driver value from a domain value, not a SQL binding. */\n mapToRow(value: any): any;\n}\n\n/** Converts the ORM clock to the timestamp's domain representation. */\nexport interface TimestampCodec<T> extends ScalarCodec {\n mapFromNow(now: Date): T;\n}\n\n/**\n * Provides a simplified, public API for mapping between db/domain values.\n *\n * Joist's internal `FieldSerde` API is admittedly a little crufty, and so this\n * API is intended to be a simpler, more user-friendly way to define custom types.\n */\nexport interface CustomSerde<DomainType, DbType> {\n toDb(value: DomainType): DbType;\n fromDb(value: DbType): DomainType;\n}\n\nexport class CustomSerdeAdapter implements ScalarCodec {\n isArray: boolean = false;\n\n constructor(\n public dbType: string,\n private mapper: CustomSerde<any, any>,\n isArray?: boolean,\n ) {\n if (isArray !== undefined) this.isArray = isArray;\n }\n\n /** Only known adapters share their mapper's identity and elementwise array conversion. */\n get outputType(): TypeInfo | undefined {\n if (\n this.isArray !== this.dbType.endsWith(\"[]\") ||\n (this.constructor !== CustomSerdeAdapter &&\n this.constructor !== PlainDateSerde &&\n this.constructor !== PlainTimeSerde &&\n this.constructor !== PlainDateTimeSerde &&\n this.constructor !== ZonedDateTimeSerde)\n ) {\n return undefined;\n }\n const dbType = canonicalDbType(this.dbType);\n // A numeric mapper may require scalar text; classic pg decodes numeric[] elements as numbers.\n const elementType = this.isArray ? dbType.slice(0, -2) : dbType;\n const outputType = { dbType: elementType, domain: this.mapper, arrayElementSafe: elementType !== \"numeric\" };\n if (!this.isArray) return outputType;\n // Physical arrays pass null elements to the mapper, unlike scalar arrayAgg; keep their domains distinct.\n return arrayOutputType(outputType) || [\"date\", \"time\", \"timestamp\", \"timestamptz\"].includes(elementType)\n ? { dbType, domain: this.mapper }\n : undefined;\n }\n\n /** Encodes each physical array element once. */\n mapToDbValue(value: unknown): unknown {\n return value !== undefined\n ? this.isArray\n ? (value as readonly unknown[]).map((element) => this.mapper.toDb(element))\n : this.mapper.toDb(value)\n : undefined;\n }\n\n mapToRow(value: any): any {\n return this.mapToDbValue(value);\n }\n\n mapToDb(value: any): any {\n return value === null\n ? value\n : this.isArray\n ? value.map((element: unknown) => this.mapper.toDb(element))\n : this.mapper.toDb(value);\n }\n\n /** Converts a driver value with the custom mapper, including array elements. */\n mapFromDb(value: unknown): unknown {\n const dbValue = maybeNullToUndefined(value);\n return dbValue !== undefined\n ? this.isArray\n ? dbValue.map((value: unknown) => this.mapper.fromDb(value))\n : this.mapper.fromDb(dbValue)\n : undefined;\n }\n\n mapFromJsonAgg(value: any): any {\n // Assume the database JSON value matches the ResultSet value\n return value;\n // return value === null\n // ? value\n // : this.isArray\n // ? value.map((value: any) => this.mapper.fromDb(value))\n // : this.mapper.fromDb(value);\n }\n}\n\n/**\n * Supports `string`, `int`, etc., as well as `string[]`, `int[]`, etc.\n *\n * This is not generally meant for subclassing, because it assumes things like\n * `string[]`s can be mapped 1:1. See `CustomSerdeAdapter` a good base class\n * that will handle converting individual elements.\n */\nexport class PrimitiveSerde implements ScalarCodec {\n constructor(\n public dbType: string,\n public isArray = false,\n ) {}\n\n /** Exact-class checks prevent an unknown subclass's overridden converters from sharing this codec. */\n get outputType(): TypeInfo | undefined {\n if (this.constructor !== PrimitiveSerde) return undefined;\n const dbType = canonicalDbType(this.dbType);\n const elementType = dbType.endsWith(\"[]\") ? dbType.slice(0, -2) : dbType;\n if (this.isArray !== dbType.endsWith(\"[]\")) return undefined;\n const outputType = {\n dbType: elementType,\n domain: primitiveOutputDomain(elementType),\n arrayElementSafe: elementType !== \"numeric\",\n };\n return this.isArray ? arrayOutputType(outputType) : outputType;\n }\n\n /** Primitive writes share their scalar/filter conversion, including subclass overrides. */\n mapToDbValue(value: unknown): unknown {\n return this.mapToDb(value);\n }\n\n mapToRow(value: any): any {\n return this.mapToDbValue(value);\n }\n\n mapToDb(value: any) {\n return value;\n }\n\n /** Keeps driver values as-is, with SQL NULL represented as an unset entity field. */\n mapFromDb(value: unknown): unknown {\n return maybeNullToUndefined(value);\n }\n\n mapFromJsonAgg(value: any): any {\n return value;\n }\n}\n\nexport class DateSerde extends PrimitiveSerde implements TimestampCodec<Date> {\n /** Date bindings use ISO strings; mapToDb does not support physical Date arrays. */\n get outputType(): TypeInfo | undefined {\n return this.constructor === DateSerde && !this.isArray && !this.dbType.endsWith(\"[]\")\n ? { dbType: canonicalDbType(this.dbType), domain: DateSerde }\n : undefined;\n }\n\n /** Accept the caller's date as-is. */\n mapFromNow(now: Date): Date {\n return now;\n }\n\n mapFromJsonAgg(value: any): any {\n if (value === null) return value;\n return new Date(value);\n }\n\n /**\n * Returns the `Date` a driver hands back on a read, and not `mapToDb`'s ISO string.\n *\n * Otherwise callers that round-trip a row through `rowValue` and back through `fromRow` (i.e.\n * `RunPlugin` mirroring writes into the test em) turn every date into a string, because our\n * `mapFromDb` returns the row value as-is.\n */\n mapToRow(value: any): any {\n return value;\n }\n\n mapToDb(value: Date) {\n // bun.sql needs this, node-pg does it out of the box\n return value?.toISOString();\n }\n}\n\n/** Converts `DATE`s `Temporal.PlainDate`s. */\nexport class PlainDateSerde extends CustomSerdeAdapter {\n constructor(dbType: string, isArray = false) {\n super(dbType, plainDateMapper, isArray);\n }\n}\n\n/** Converts `TIME`s to `Temporal.PlainTime`s. */\nexport class PlainTimeSerde extends CustomSerdeAdapter {\n constructor(dbType: string, isArray = false) {\n super(dbType, plainTimeMapper, isArray);\n }\n}\n\n/** Converts `TIMESTAMP`s to `Temporal.PlainDateTime`s. */\nexport class PlainDateTimeSerde extends CustomSerdeAdapter implements TimestampCodec<Temporal.PlainDateTime> {\n constructor(dbType: string, isArray = false) {\n super(dbType, plainDateTimeMapper, isArray);\n }\n\n mapFromNow(now: Date): Temporal.PlainDateTime {\n const { timeZone } = getRuntimeConfig().temporal as any;\n return requireTemporal().toTemporalInstant.call(now).toZonedDateTimeISO(timeZone).toPlainDateTime();\n }\n}\n\n/** Converts `TIMESTAMP WITH TIME ZONE`s to `Temporal.ZonedDateTime`s. */\nexport class ZonedDateTimeSerde extends CustomSerdeAdapter implements TimestampCodec<Temporal.ZonedDateTime> {\n constructor(dbType: string, isArray = false) {\n super(dbType, zonedDateTimeMapper, isArray);\n }\n\n mapFromNow(now: Date): Temporal.ZonedDateTime {\n const { timeZone } = getRuntimeConfig().temporal as any;\n return requireTemporal().toTemporalInstant.call(now).toZonedDateTimeISO(timeZone);\n }\n}\n\nexport class BigIntSerde implements ScalarCodec {\n dbType: string;\n\n constructor(public isArray = false) {\n this.dbType = isArray ? \"bigint[]\" : \"bigint\";\n }\n\n /** BigInt conversion is distinct from both the driver's int8 value and Number aggregates. */\n get outputType(): TypeInfo | undefined {\n if (this.constructor !== BigIntSerde) return undefined;\n const elementType = { dbType: \"int8\", domain: BigIntSerde, arrayElementSafe: true };\n return this.isArray ? arrayOutputType(elementType) : elementType;\n }\n\n /** Drivers accept native bigint values without conversion. */\n mapToDbValue(value: unknown): unknown {\n if (this.isArray) assertFlatNumericArray(value);\n return value;\n }\n\n mapToRow(value: any): any {\n return this.mapToDbValue(value);\n }\n\n mapToDb(value: any) {\n return value;\n }\n\n /** Converts the driver's bigint representation to the entity value. */\n mapFromDb(value: unknown): unknown {\n const dbValue = maybeNullToUndefined(value);\n if (this.isArray && dbValue !== undefined) {\n assertFlatNumericArray(dbValue);\n return dbValue.map((element: string | bigint | number | null) => (element === null ? null : BigInt(element)));\n }\n return dbValue ? BigInt(dbValue) : dbValue;\n }\n\n mapFromJsonAgg(value: any): any {\n return value === null ? value : this.isArray ? this.mapFromDb(value) : BigInt(value);\n }\n}\n\n/**\n * Maps `decimal(...)` database types to the JS `number`.\n *\n * Note that we assume the db values are within the range of the JS `number`;\n * we should eventually sanity check that.\n *\n * Also note that knex/pg accept `number`s as input, so we only need\n * to handle from-database -> to JS translation.\n */\nexport class DecimalToNumberSerde implements ScalarCodec {\n dbType: string;\n\n constructor(public isArray = false) {\n this.dbType = isArray ? \"numeric[]\" : \"decimal\";\n }\n\n /** Numeric aggregates use the same Number conversion and identity binding encoder. */\n get outputType(): TypeInfo | undefined {\n if (this.constructor !== DecimalToNumberSerde) return undefined;\n const elementType = { dbType: \"numeric\", domain: Number, arrayElementSafe: true };\n return this.isArray ? arrayOutputType(elementType) : elementType;\n }\n\n /** Drivers accept decimal numbers without conversion. */\n mapToDbValue(value: unknown): unknown {\n if (this.isArray) assertFlatNumericArray(value);\n return value;\n }\n\n mapToRow(value: any): any {\n return this.mapToDbValue(value);\n }\n\n mapToDb(value: any) {\n return value;\n }\n\n /** Converts a driver decimal value to a JavaScript number. */\n mapFromDb(value: unknown): unknown {\n const dbValue = maybeNullToUndefined(value);\n if (this.isArray && dbValue !== undefined) {\n assertFlatNumericArray(dbValue);\n return dbValue.map((element: string | number | null) => (element === null ? null : Number(element)));\n }\n return dbValue !== undefined ? Number(dbValue) : dbValue;\n }\n\n mapFromJsonAgg(value: any): any {\n return value === null ? value : this.isArray ? this.mapFromDb(value) : Number(value);\n }\n}\n\n/** Maps physical integer keys to logical string IDs \"because GraphQL\". */\nexport class KeySerde implements ScalarCodec {\n isArray = false;\n\n private meta: {\n tagName: string;\n idDbType: \"bigint\" | \"int\" | \"uuid\" | \"text\";\n };\n\n constructor(\n tagName: string,\n public dbType: \"bigint\" | \"int\" | \"uuid\" | \"text\",\n ) {\n this.meta = {\n tagName,\n idDbType: dbType,\n };\n }\n\n /** PKs and FKs share a tag and SQL representation; the alias supplies the exact target idMeta. */\n get outputType(): TypeInfo | undefined {\n return this.constructor === KeySerde && !this.isArray\n ? { dbType: canonicalDbType(this.dbType), domain: `key:${this.meta.tagName}`, arrayElementSafe: true }\n : undefined;\n }\n\n /** Resolves references and tagged, untagged, or numeric ids using the column's tag and storage type. */\n mapToDbValue(value: unknown): unknown {\n return keyToNumber(\n this.meta,\n typeof value === \"number\"\n ? value\n : maybeResolveReferenceToId(value as Parameters<typeof maybeResolveReferenceToId>[0]),\n );\n }\n\n mapToRow(value: any): any {\n // we don't have any fixups since we are trying to recreate what comes out of the db, so this is safe\n return this.mapToDbValue(value);\n }\n\n mapToDb(value: any) {\n // Sometimes the nilIdValue will pass -1 as already a number, but usually this should be a tagged id\n if (value === null || typeof value === \"number\") return value;\n // We go through `maybeResolveReferenceToId` because filters like `in: [a1, a2]` pass entities directly.\n return keyToNumber(this.meta, maybeResolveReferenceToId(value));\n }\n\n /** Converts a physical primary or foreign key to a tagged id. */\n mapFromDb(value: unknown): string | undefined {\n return keyToTaggedId(this.meta, value as string | number);\n }\n\n mapFromJsonAgg(value: any): any {\n return value === null ? value : value;\n }\n}\n\nexport class EnumFieldSerde implements ScalarCodec {\n isArray = false;\n\n constructor(\n public dbType: \"int\" | \"uuid\",\n private enumObject: any,\n ) {}\n\n /** Separate fields of the same generated enum share its code/id mapping. */\n get outputType(): TypeInfo | undefined {\n return this.constructor === EnumFieldSerde && !this.isArray\n ? { dbType: canonicalDbType(this.dbType), domain: this.enumObject, arrayElementSafe: true }\n : undefined;\n }\n\n /** Resolves the enum code to its stored id, leaving an unknown code unset. */\n mapToDbValue(value: unknown): unknown {\n return this.enumObject.findByCode(value)?.id;\n }\n\n mapToRow(value: any): any {\n return this.mapToDbValue(value);\n }\n\n mapToDb(value: any) {\n return this.enumObject.findByCode(value)?.id;\n }\n\n /** Converts a stored enum id to its enum code. */\n mapFromDb(value: unknown): unknown {\n return this.enumObject.findById(value)?.code;\n }\n\n mapFromJsonAgg(value: any): any {\n return value === null ? value : value;\n }\n}\n\nexport class EnumArrayFieldSerde implements ScalarCodec {\n isArray = true;\n\n constructor(\n public dbType: \"int[]\" | \"uuid[]\",\n private enumObject: any,\n ) {}\n\n /** Physical enum arrays reject null elements, unlike scalar enum arrayAgg; leave them unknown. */\n get outputType(): undefined {\n return undefined;\n }\n\n /** Resolves each enum code to its stored id, retaining the entity's empty-array default. */\n mapToDbValue(value: unknown): unknown {\n return (value as readonly unknown[] | null | undefined)?.map((code) => this.enumObject.getByCode(code).id) || [];\n }\n\n mapToRow(value: any): any {\n return this.mapToDbValue(value);\n }\n\n mapToDb(value: any) {\n return !value ? [] : value.map((code: any) => this.enumObject.getByCode(code).id);\n }\n\n /** Converts stored enum ids to codes, defaulting an unset entity field to an empty array. */\n mapFromDb(value: unknown): unknown[] {\n return (value as readonly unknown[] | null | undefined)?.map((id) => this.enumObject.findById(id).code) || [];\n }\n\n mapFromJsonAgg(value: any): any {\n return value === null ? value : value;\n }\n}\n\n/** Similar to SimpleSerde, but applies the superstruct `assert` function when reading values from the db. */\nexport class SuperstructSerde implements ScalarCodec {\n dbType = \"jsonb\";\n isArray = false;\n\n // Use a dynamic require so that downstream projects don't have to depend on superstruct\n // until they want to, i.e. we don't have superstruct in the joist-orm package.json.\n private assert = runtimeRequire(\"superstruct\").assert;\n\n constructor(private superstruct: any) {}\n\n /** JSON schemas describe a jsonb value, even when that value is a JSON array. */\n get outputType(): TypeInfo | undefined {\n return this.constructor === SuperstructSerde && !this.isArray\n ? { dbType: canonicalDbType(this.dbType), domain: this.superstruct, arrayElementSafe: true }\n : undefined;\n }\n\n /** Serializes the domain JSON value without running the read-time schema validation. */\n mapToDbValue(value: unknown): unknown {\n return JSON.stringify(value);\n }\n\n // JSON is returned by postgres already parsed, so we should just be able to return our data directly. Unlike with\n // JsonSerde, we can assume that superstruct would have parsed any complex types in the json correctly so we don't\n // need to do a round trip through JSON.stringify.\n mapToRow(value: any): any {\n return value;\n }\n\n mapToDb(value: any) {\n return JSON.stringify(value);\n }\n\n /** Validates a driver JSON value with the field's Superstruct schema. */\n mapFromDb(value: unknown): unknown {\n const dbValue = maybeNullToUndefined(value);\n if (dbValue) this.assert(dbValue, this.superstruct);\n return dbValue;\n }\n\n mapFromJsonAgg(value: any): any {\n return value === null ? value : value;\n }\n}\n\nexport class JsonSerde implements ScalarCodec {\n dbType = \"jsonb\";\n isArray = false;\n\n constructor() {}\n\n /** Unvalidated JSON uses its own encoder, not a primitive or schema-specific codec. */\n get outputType(): TypeInfo | undefined {\n return this.constructor === JsonSerde && !this.isArray\n ? { dbType: canonicalDbType(this.dbType), domain: JsonSerde, arrayElementSafe: true }\n : undefined;\n }\n\n /** Serializes the whole JSON value, including JSON arrays and custom toJSON methods. */\n mapToDbValue(value: unknown): unknown {\n return JSON.stringify(value);\n }\n\n // JSON is returned by postgres already parsed, so if we are trying to recreate then we need to stringify, then parse.\n // It's necessary to do this instead of just returning the object directly because any complex types in the json need\n // to be stringified to correctly reflect the db value.\n mapToRow(value: any): any {\n const json = JSON.stringify(value);\n return isDefined(json) ? JSON.parse(json) : undefined;\n }\n\n mapToDb(value: any) {\n return JSON.stringify(value);\n }\n\n /** Keeps the driver's parsed JSON value, normalizing SQL NULL for entity fields. */\n mapFromDb(value: unknown): unknown {\n return maybeNullToUndefined(value);\n }\n\n mapFromJsonAgg(value: any): any {\n return value === null ? value : value;\n }\n}\n\n/** Similar to SimpleSerde, but applies the zod's `parse` function when reading values from the db. */\nexport class ZodSerde implements ScalarCodec {\n dbType = \"jsonb\";\n isArray = false;\n\n constructor(private zodSchema: any) {}\n\n /** Parsing and transformations are compatible only for the same schema object. */\n get outputType(): TypeInfo | undefined {\n return this.constructor === ZodSerde && !this.isArray\n ? { dbType: canonicalDbType(this.dbType), domain: this.zodSchema, arrayElementSafe: true }\n : undefined;\n }\n\n /** Serializes the domain JSON value without running the read-time Zod parser or transforms. */\n mapToDbValue(value: unknown): unknown {\n return JSON.stringify(value);\n }\n\n // JSON is returned by postgres already parsed, so we should just be able to return our data directly. Unlike with\n // JsonSerde, we can assume that zod would have parsed any complex types in the json correctly so we don't need to\n // do a round trip through JSON.stringify.\n mapToRow(value: any): any {\n return value;\n }\n\n mapToDb(value: any) {\n return JSON.stringify(value);\n }\n\n /** Parses a driver JSON value with the field's Zod schema. */\n mapFromDb(value: unknown): unknown {\n const dbValue = maybeNullToUndefined(value);\n return dbValue ? this.zodSchema.parse(dbValue) : dbValue;\n }\n\n mapFromJsonAgg(value: any): any {\n return value === null ? value : value;\n }\n}\n\n/** PostgreSQL does not enforce declared array dimensions; reject nested values rather than coercing subarrays. */\nfunction assertFlatNumericArray(value: unknown): void {\n if (Array.isArray(value) && value.some(Array.isArray)) {\n throw new Error(\"Native numeric arrays must be one-dimensional\");\n }\n}\n\n/** Only driver-native numbers agree with Number aggregates; int8/numeric identity values do not. */\nfunction primitiveOutputDomain(dbType: string): unknown {\n switch (dbType) {\n case \"int2\":\n case \"int4\":\n case \"float4\":\n case \"float8\":\n return Number;\n case \"text\":\n case \"varchar\":\n case \"bpchar\":\n return String;\n default:\n return PrimitiveSerde;\n }\n}\n\n/** Normalizes SQL NULL to an unset entity field. */\nfunction maybeNullToUndefined(value: any): any {\n return value === null ? undefined : value;\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"serde.d.cts","names":[],"sources":["../src/serde.ts"],"mappings":";;;;UAWiB;EACf;EACA;;WAES,aAAa;;EAEtB,QAAQ;;;;;;;;EAQR,cAAc;;EAEd,UAAU;;;;;;;EAOV,eAAe;;EAEf,SAAS;;;UAIM,eAAe,WAAW;EACzC,WAAW,KAAK,OAAO;;;;;;;;UASR,YAAY,YAAY;EACvC,KAAK,OAAO,aAAa;EACzB,OAAO,OAAO,SAAS;;cAGZ,8BAA8B;EAIhC;UACC;EAJV;EAEA,YACS,gBACC,QAAQ,uBAChB;;MAME,cAAc;;EAuBlB,aAAa;EAQb,SAAS;EAIT,QAAQ;;EASR,UAAU;EASV,eAAe;;;;;;;;;cAkBJ,0BAA0B;EAE5B;EACA;EAFT,YACS,gBACA;;MAIL,cAAc;;EAclB,aAAa;EAIb,SAAS;EAIT,QAAQ;;EAKR,UAAU;EAIV,eAAe;;cAKJ,kBAAkB,0BAA0B,eAAe;;MAElE,cAAc;;EAOlB,WAAW,KAAK,OAAO;EAIvB,eAAe;;;;;;;;EAYf,SAAS;EAIT,QAAQ,OAAO;;;cAOJ,uBAAuB;EAClC,YAAY,gBAAgB;;;cAMjB,uBAAuB;EAClC,YAAY,gBAAgB;;;cAMjB,2BAA2B,8BAA8B,eAAe,SAAS;EAC5F,YAAY,gBAAgB;EAI5B,WAAW,KAAK,OAAO,SAAS;;;cAOrB,2BAA2B,8BAA8B,eAAe,SAAS;EAC5F,YAAY,gBAAgB;EAI5B,WAAW,KAAK,OAAO,SAAS;;cAMrB,uBAAuB;EAGf;EAFnB;EAEA,YAAmB;;MAKf,cAAc;;EAOlB,aAAa;EAKb,SAAS;EAIT,QAAQ;;EAKR,UAAU;EASV,eAAe;;;;;;;;;;;cAcJ,gCAAgC;EAGxB;EAFnB;EAEA,YAAmB;;MAKf,cAAc;;EAOlB,aAAa;EAKb,SAAS;EAIT,QAAQ;;EAKR,UAAU;EASV,eAAe;;;cAMJ,oBAAoB;EAUtB;EATT;UAEQ;EAKR,YACE,iBACO;;MASL,cAAc;;EAOlB,aAAa;EASb,SAAS;EAKT,QAAQ;;EAQR,UAAU;EAIV,eAAe;;cAKJ,0BAA0B;EAI5B;UACC;EAJV;EAEA,YACS,wBACC;;MAIN,cAAc;;EAOlB,aAAa;EAIb,SAAS;EAIT,QAAQ;;EAKR,UAAU;EAIV,eAAe;;cAKJ,+BAA+B;EAIjC;UACC;EAJV;EAEA,YACS,4BACC;;MAIN;;EAKJ,aAAa;EAIb,SAAS;EAIT,QAAQ;;EAKR,UAAU;EAIV,eAAe;;;cAMJ,4BAA4B;UAQnB;EAPpB;EACA;UAIQ;EAER,YAAoB;;MAGhB,cAAc;;EAOlB,aAAa;EAOb,SAAS;EAIT,QAAQ;;EAKR,UAAU;EAMV,eAAe;;cAKJ,qBAAqB;EAChC;EACA;EAEA;;MAGI,cAAc;;EAOlB,aAAa;EAOb,SAAS;EAKT,QAAQ;;EAKR,UAAU;EAIV,eAAe;;;cAMJ,oBAAoB;UAIX;EAHpB;EACA;EAEA,YAAoB;;MAGhB,cAAc;;EAOlB,aAAa;EAOb,SAAS;EAIT,QAAQ;;EAKR,UAAU;EAKV,eAAe"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"serde.d.mts","names":[],"sources":["../src/serde.ts"],"mappings":";;;;UAWiB;EACf;EACA;;WAES,aAAa;;EAEtB,QAAQ;;;;;;;;EAQR,cAAc;;EAEd,UAAU;;;;;;;EAOV,eAAe;;EAEf,SAAS;;;UAIM,eAAe,WAAW;EACzC,WAAW,KAAK,OAAO;;;;;;;;UASR,YAAY,YAAY;EACvC,KAAK,OAAO,aAAa;EACzB,OAAO,OAAO,SAAS;;cAGZ,8BAA8B;EAIhC;UACC;EAJV;EAEA,YACS,gBACC,QAAQ,uBAChB;;MAME,cAAc;;EAuBlB,aAAa;EAQb,SAAS;EAIT,QAAQ;;EASR,UAAU;EASV,eAAe;;;;;;;;;cAkBJ,0BAA0B;EAE5B;EACA;EAFT,YACS,gBACA;;MAIL,cAAc;;EAclB,aAAa;EAIb,SAAS;EAIT,QAAQ;;EAKR,UAAU;EAIV,eAAe;;cAKJ,kBAAkB,0BAA0B,eAAe;;MAElE,cAAc;;EAOlB,WAAW,KAAK,OAAO;EAIvB,eAAe;;;;;;;;EAYf,SAAS;EAIT,QAAQ,OAAO;;;cAOJ,uBAAuB;EAClC,YAAY,gBAAgB;;;cAMjB,uBAAuB;EAClC,YAAY,gBAAgB;;;cAMjB,2BAA2B,8BAA8B,eAAe,SAAS;EAC5F,YAAY,gBAAgB;EAI5B,WAAW,KAAK,OAAO,SAAS;;;cAOrB,2BAA2B,8BAA8B,eAAe,SAAS;EAC5F,YAAY,gBAAgB;EAI5B,WAAW,KAAK,OAAO,SAAS;;cAMrB,uBAAuB;EAGf;EAFnB;EAEA,YAAmB;;MAKf,cAAc;;EAOlB,aAAa;EAKb,SAAS;EAIT,QAAQ;;EAKR,UAAU;EASV,eAAe;;;;;;;;;;;cAcJ,gCAAgC;EAGxB;EAFnB;EAEA,YAAmB;;MAKf,cAAc;;EAOlB,aAAa;EAKb,SAAS;EAIT,QAAQ;;EAKR,UAAU;EASV,eAAe;;;cAMJ,oBAAoB;EAUtB;EATT;UAEQ;EAKR,YACE,iBACO;;MASL,cAAc;;EAOlB,aAAa;EASb,SAAS;EAKT,QAAQ;;EAQR,UAAU;EAIV,eAAe;;cAKJ,0BAA0B;EAI5B;UACC;EAJV;EAEA,YACS,wBACC;;MAIN,cAAc;;EAOlB,aAAa;EAIb,SAAS;EAIT,QAAQ;;EAKR,UAAU;EAIV,eAAe;;cAKJ,+BAA+B;EAIjC;UACC;EAJV;EAEA,YACS,4BACC;;MAIN;;EAKJ,aAAa;EAIb,SAAS;EAIT,QAAQ;;EAKR,UAAU;EAIV,eAAe;;;cAMJ,4BAA4B;UAQnB;EAPpB;EACA;UAIQ;EAER,YAAoB;;MAGhB,cAAc;;EAOlB,aAAa;EAOb,SAAS;EAIT,QAAQ;;EAKR,UAAU;EAMV,eAAe;;cAKJ,qBAAqB;EAChC;EACA;EAEA;;MAGI,cAAc;;EAOlB,aAAa;EAOb,SAAS;EAKT,QAAQ;;EAKR,UAAU;EAIV,eAAe;;;cAMJ,oBAAoB;UAIX;EAHpB;EACA;EAEA,YAAoB;;MAGhB,cAAc;;EAOlB,aAAa;EAOb,SAAS;EAIT,QAAQ;;EAKR,UAAU;EAKV,eAAe"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"serde.js","names":[],"sources":["../src/serde.ts"],"sourcesContent":["import { createRequire } from \"node:module\";\n\nimport { isDefined, keyToNumber, keyToTaggedId, maybeResolveReferenceToId } from \"./index.ts\";\nimport { getRuntimeConfig } from \"./runtimeConfig.ts\";\nimport { type Temporal, requireTemporal } from \"./temporal.ts\";\nimport { plainDateMapper, plainDateTimeMapper, plainTimeMapper, zonedDateTimeMapper } from \"./temporalMappers.ts\";\nimport { type TypeInfo, arrayOutputType, canonicalDbType } from \"./TypeInfo.ts\";\n\nconst runtimeRequire = createRequire(import.meta.url);\n\n/** Scalar conversion only: no field names, entity hydration, or FK fixups. */\nexport interface ScalarCodec {\n dbType: string;\n isArray: boolean;\n /** Compatibility evidence for scalar conversion, absent for unknown codecs. */\n readonly outputType?: TypeInfo;\n /** Encodes a domain value for a filter, i.e. an em.find WHERE parameter. */\n mapToDb(value: any): any;\n /**\n * Encodes a domain value for an INSERT or UPDATE binding.\n *\n * Callers must handle omission, SQL NULL, and SQL expressions before encoding. JSON null and\n * codec defaults can differ from SQL NULL. Direct mutations must validate reference targets\n * and reject new or unflushed entities before encoding.\n */\n mapToDbValue?(value: unknown): unknown;\n /** Converts a driver value to its domain value, including the codec's null/default handling. */\n mapFromDb(value: unknown): unknown;\n /**\n * Converts a json_agg cell to a driver-row value, not a domain value.\n *\n * Lazy field hydration subsequently calls mapFromDb. I.e. Date codecs reconstruct a Date\n * from the JSON string, while Temporal codecs retain the driver's string representation.\n */\n mapFromJsonAgg(value: any): any;\n /** Reconstructs a driver value from a domain value, not a SQL binding. */\n mapToRow(value: any): any;\n}\n\n/** Converts the ORM clock to the timestamp's domain representation. */\nexport interface TimestampCodec<T> extends ScalarCodec {\n mapFromNow(now: Date): T;\n}\n\n/**\n * Provides a simplified, public API for mapping between db/domain values.\n *\n * Joist's internal `FieldSerde` API is admittedly a little crufty, and so this\n * API is intended to be a simpler, more user-friendly way to define custom types.\n */\nexport interface CustomSerde<DomainType, DbType> {\n toDb(value: DomainType): DbType;\n fromDb(value: DbType): DomainType;\n}\n\nexport class CustomSerdeAdapter implements ScalarCodec {\n isArray: boolean = false;\n\n constructor(\n public dbType: string,\n private mapper: CustomSerde<any, any>,\n isArray?: boolean,\n ) {\n if (isArray !== undefined) this.isArray = isArray;\n }\n\n /** Only known adapters share their mapper's identity and elementwise array conversion. */\n get outputType(): TypeInfo | undefined {\n if (\n this.isArray !== this.dbType.endsWith(\"[]\") ||\n (this.constructor !== CustomSerdeAdapter &&\n this.constructor !== PlainDateSerde &&\n this.constructor !== PlainTimeSerde &&\n this.constructor !== PlainDateTimeSerde &&\n this.constructor !== ZonedDateTimeSerde)\n ) {\n return undefined;\n }\n const dbType = canonicalDbType(this.dbType);\n // A numeric mapper may require scalar text; classic pg decodes numeric[] elements as numbers.\n const elementType = this.isArray ? dbType.slice(0, -2) : dbType;\n const outputType = { dbType: elementType, domain: this.mapper, arrayElementSafe: elementType !== \"numeric\" };\n if (!this.isArray) return outputType;\n // Physical arrays pass null elements to the mapper, unlike scalar arrayAgg; keep their domains distinct.\n return arrayOutputType(outputType) || [\"date\", \"time\", \"timestamp\", \"timestamptz\"].includes(elementType)\n ? { dbType, domain: this.mapper }\n : undefined;\n }\n\n /** Encodes each physical array element once. */\n mapToDbValue(value: unknown): unknown {\n return value !== undefined\n ? this.isArray\n ? (value as readonly unknown[]).map((element) => this.mapper.toDb(element))\n : this.mapper.toDb(value)\n : undefined;\n }\n\n mapToRow(value: any): any {\n return this.mapToDbValue(value);\n }\n\n mapToDb(value: any): any {\n return value === null\n ? value\n : this.isArray\n ? value.map((element: unknown) => this.mapper.toDb(element))\n : this.mapper.toDb(value);\n }\n\n /** Converts a driver value with the custom mapper, including array elements. */\n mapFromDb(value: unknown): unknown {\n const dbValue = maybeNullToUndefined(value);\n return dbValue !== undefined\n ? this.isArray\n ? dbValue.map((value: unknown) => this.mapper.fromDb(value))\n : this.mapper.fromDb(dbValue)\n : undefined;\n }\n\n mapFromJsonAgg(value: any): any {\n // Assume the database JSON value matches the ResultSet value\n return value;\n // return value === null\n // ? value\n // : this.isArray\n // ? value.map((value: any) => this.mapper.fromDb(value))\n // : this.mapper.fromDb(value);\n }\n}\n\n/**\n * Supports `string`, `int`, etc., as well as `string[]`, `int[]`, etc.\n *\n * This is not generally meant for subclassing, because it assumes things like\n * `string[]`s can be mapped 1:1. See `CustomSerdeAdapter` a good base class\n * that will handle converting individual elements.\n */\nexport class PrimitiveSerde implements ScalarCodec {\n constructor(\n public dbType: string,\n public isArray = false,\n ) {}\n\n /** Exact-class checks prevent an unknown subclass's overridden converters from sharing this codec. */\n get outputType(): TypeInfo | undefined {\n if (this.constructor !== PrimitiveSerde) return undefined;\n const dbType = canonicalDbType(this.dbType);\n const elementType = dbType.endsWith(\"[]\") ? dbType.slice(0, -2) : dbType;\n if (this.isArray !== dbType.endsWith(\"[]\")) return undefined;\n const outputType = {\n dbType: elementType,\n domain: primitiveOutputDomain(elementType),\n arrayElementSafe: elementType !== \"numeric\",\n };\n return this.isArray ? arrayOutputType(outputType) : outputType;\n }\n\n /** Primitive writes share their scalar/filter conversion, including subclass overrides. */\n mapToDbValue(value: unknown): unknown {\n return this.mapToDb(value);\n }\n\n mapToRow(value: any): any {\n return this.mapToDbValue(value);\n }\n\n mapToDb(value: any) {\n return value;\n }\n\n /** Keeps driver values as-is, with SQL NULL represented as an unset entity field. */\n mapFromDb(value: unknown): unknown {\n return maybeNullToUndefined(value);\n }\n\n mapFromJsonAgg(value: any): any {\n return value;\n }\n}\n\nexport class DateSerde extends PrimitiveSerde implements TimestampCodec<Date> {\n /** Date bindings use ISO strings; mapToDb does not support physical Date arrays. */\n get outputType(): TypeInfo | undefined {\n return this.constructor === DateSerde && !this.isArray && !this.dbType.endsWith(\"[]\")\n ? { dbType: canonicalDbType(this.dbType), domain: DateSerde }\n : undefined;\n }\n\n /** Accept the caller's date as-is. */\n mapFromNow(now: Date): Date {\n return now;\n }\n\n mapFromJsonAgg(value: any): any {\n if (value === null) return value;\n return new Date(value);\n }\n\n /**\n * Returns the `Date` a driver hands back on a read, and not `mapToDb`'s ISO string.\n *\n * Otherwise callers that round-trip a row through `rowValue` and back through `fromRow` (i.e.\n * `RunPlugin` mirroring writes into the test em) turn every date into a string, because our\n * `mapFromDb` returns the row value as-is.\n */\n mapToRow(value: any): any {\n return value;\n }\n\n mapToDb(value: Date) {\n // bun.sql needs this, node-pg does it out of the box\n return value?.toISOString();\n }\n}\n\n/** Converts `DATE`s `Temporal.PlainDate`s. */\nexport class PlainDateSerde extends CustomSerdeAdapter {\n constructor(dbType: string, isArray = false) {\n super(dbType, plainDateMapper, isArray);\n }\n}\n\n/** Converts `TIME`s to `Temporal.PlainTime`s. */\nexport class PlainTimeSerde extends CustomSerdeAdapter {\n constructor(dbType: string, isArray = false) {\n super(dbType, plainTimeMapper, isArray);\n }\n}\n\n/** Converts `TIMESTAMP`s to `Temporal.PlainDateTime`s. */\nexport class PlainDateTimeSerde extends CustomSerdeAdapter implements TimestampCodec<Temporal.PlainDateTime> {\n constructor(dbType: string, isArray = false) {\n super(dbType, plainDateTimeMapper, isArray);\n }\n\n mapFromNow(now: Date): Temporal.PlainDateTime {\n const { timeZone } = getRuntimeConfig().temporal as any;\n return requireTemporal().toTemporalInstant.call(now).toZonedDateTimeISO(timeZone).toPlainDateTime();\n }\n}\n\n/** Converts `TIMESTAMP WITH TIME ZONE`s to `Temporal.ZonedDateTime`s. */\nexport class ZonedDateTimeSerde extends CustomSerdeAdapter implements TimestampCodec<Temporal.ZonedDateTime> {\n constructor(dbType: string, isArray = false) {\n super(dbType, zonedDateTimeMapper, isArray);\n }\n\n mapFromNow(now: Date): Temporal.ZonedDateTime {\n const { timeZone } = getRuntimeConfig().temporal as any;\n return requireTemporal().toTemporalInstant.call(now).toZonedDateTimeISO(timeZone);\n }\n}\n\nexport class BigIntSerde implements ScalarCodec {\n dbType: string;\n\n constructor(public isArray = false) {\n this.dbType = isArray ? \"bigint[]\" : \"bigint\";\n }\n\n /** BigInt conversion is distinct from both the driver's int8 value and Number aggregates. */\n get outputType(): TypeInfo | undefined {\n if (this.constructor !== BigIntSerde) return undefined;\n const elementType = { dbType: \"int8\", domain: BigIntSerde, arrayElementSafe: true };\n return this.isArray ? arrayOutputType(elementType) : elementType;\n }\n\n /** Drivers accept native bigint values without conversion. */\n mapToDbValue(value: unknown): unknown {\n if (this.isArray) assertFlatNumericArray(value);\n return value;\n }\n\n mapToRow(value: any): any {\n return this.mapToDbValue(value);\n }\n\n mapToDb(value: any) {\n return value;\n }\n\n /** Converts the driver's bigint representation to the entity value. */\n mapFromDb(value: unknown): unknown {\n const dbValue = maybeNullToUndefined(value);\n if (this.isArray && dbValue !== undefined) {\n assertFlatNumericArray(dbValue);\n return dbValue.map((element: string | bigint | number | null) => (element === null ? null : BigInt(element)));\n }\n return dbValue ? BigInt(dbValue) : dbValue;\n }\n\n mapFromJsonAgg(value: any): any {\n return value === null ? value : this.isArray ? this.mapFromDb(value) : BigInt(value);\n }\n}\n\n/**\n * Maps `decimal(...)` database types to the JS `number`.\n *\n * Note that we assume the db values are within the range of the JS `number`;\n * we should eventually sanity check that.\n *\n * Also note that knex/pg accept `number`s as input, so we only need\n * to handle from-database -> to JS translation.\n */\nexport class DecimalToNumberSerde implements ScalarCodec {\n dbType: string;\n\n constructor(public isArray = false) {\n this.dbType = isArray ? \"numeric[]\" : \"decimal\";\n }\n\n /** Numeric aggregates use the same Number conversion and identity binding encoder. */\n get outputType(): TypeInfo | undefined {\n if (this.constructor !== DecimalToNumberSerde) return undefined;\n const elementType = { dbType: \"numeric\", domain: Number, arrayElementSafe: true };\n return this.isArray ? arrayOutputType(elementType) : elementType;\n }\n\n /** Drivers accept decimal numbers without conversion. */\n mapToDbValue(value: unknown): unknown {\n if (this.isArray) assertFlatNumericArray(value);\n return value;\n }\n\n mapToRow(value: any): any {\n return this.mapToDbValue(value);\n }\n\n mapToDb(value: any) {\n return value;\n }\n\n /** Converts a driver decimal value to a JavaScript number. */\n mapFromDb(value: unknown): unknown {\n const dbValue = maybeNullToUndefined(value);\n if (this.isArray && dbValue !== undefined) {\n assertFlatNumericArray(dbValue);\n return dbValue.map((element: string | number | null) => (element === null ? null : Number(element)));\n }\n return dbValue !== undefined ? Number(dbValue) : dbValue;\n }\n\n mapFromJsonAgg(value: any): any {\n return value === null ? value : this.isArray ? this.mapFromDb(value) : Number(value);\n }\n}\n\n/** Maps physical integer keys to logical string IDs \"because GraphQL\". */\nexport class KeySerde implements ScalarCodec {\n isArray = false;\n\n private meta: {\n tagName: string;\n idDbType: \"bigint\" | \"int\" | \"uuid\" | \"text\";\n };\n\n constructor(\n tagName: string,\n public dbType: \"bigint\" | \"int\" | \"uuid\" | \"text\",\n ) {\n this.meta = {\n tagName,\n idDbType: dbType,\n };\n }\n\n /** PKs and FKs share a tag and SQL representation; the alias supplies the exact target idMeta. */\n get outputType(): TypeInfo | undefined {\n return this.constructor === KeySerde && !this.isArray\n ? { dbType: canonicalDbType(this.dbType), domain: `key:${this.meta.tagName}`, arrayElementSafe: true }\n : undefined;\n }\n\n /** Resolves references and tagged, untagged, or numeric ids using the column's tag and storage type. */\n mapToDbValue(value: unknown): unknown {\n return keyToNumber(\n this.meta,\n typeof value === \"number\"\n ? value\n : maybeResolveReferenceToId(value as Parameters<typeof maybeResolveReferenceToId>[0]),\n );\n }\n\n mapToRow(value: any): any {\n // we don't have any fixups since we are trying to recreate what comes out of the db, so this is safe\n return this.mapToDbValue(value);\n }\n\n mapToDb(value: any) {\n // Sometimes the nilIdValue will pass -1 as already a number, but usually this should be a tagged id\n if (value === null || typeof value === \"number\") return value;\n // We go through `maybeResolveReferenceToId` because filters like `in: [a1, a2]` pass entities directly.\n return keyToNumber(this.meta, maybeResolveReferenceToId(value));\n }\n\n /** Converts a physical primary or foreign key to a tagged id. */\n mapFromDb(value: unknown): string | undefined {\n return keyToTaggedId(this.meta, value as string | number);\n }\n\n mapFromJsonAgg(value: any): any {\n return value === null ? value : value;\n }\n}\n\nexport class EnumFieldSerde implements ScalarCodec {\n isArray = false;\n\n constructor(\n public dbType: \"int\" | \"uuid\",\n private enumObject: any,\n ) {}\n\n /** Separate fields of the same generated enum share its code/id mapping. */\n get outputType(): TypeInfo | undefined {\n return this.constructor === EnumFieldSerde && !this.isArray\n ? { dbType: canonicalDbType(this.dbType), domain: this.enumObject, arrayElementSafe: true }\n : undefined;\n }\n\n /** Resolves the enum code to its stored id, leaving an unknown code unset. */\n mapToDbValue(value: unknown): unknown {\n return this.enumObject.findByCode(value)?.id;\n }\n\n mapToRow(value: any): any {\n return this.mapToDbValue(value);\n }\n\n mapToDb(value: any) {\n return this.enumObject.findByCode(value)?.id;\n }\n\n /** Converts a stored enum id to its enum code. */\n mapFromDb(value: unknown): unknown {\n return this.enumObject.findById(value)?.code;\n }\n\n mapFromJsonAgg(value: any): any {\n return value === null ? value : value;\n }\n}\n\nexport class EnumArrayFieldSerde implements ScalarCodec {\n isArray = true;\n\n constructor(\n public dbType: \"int[]\" | \"uuid[]\",\n private enumObject: any,\n ) {}\n\n /** Physical enum arrays reject null elements, unlike scalar enum arrayAgg; leave them unknown. */\n get outputType(): undefined {\n return undefined;\n }\n\n /** Resolves each enum code to its stored id, retaining the entity's empty-array default. */\n mapToDbValue(value: unknown): unknown {\n return (value as readonly unknown[] | null | undefined)?.map((code) => this.enumObject.getByCode(code).id) || [];\n }\n\n mapToRow(value: any): any {\n return this.mapToDbValue(value);\n }\n\n mapToDb(value: any) {\n return !value ? [] : value.map((code: any) => this.enumObject.getByCode(code).id);\n }\n\n /** Converts stored enum ids to codes, defaulting an unset entity field to an empty array. */\n mapFromDb(value: unknown): unknown[] {\n return (value as readonly unknown[] | null | undefined)?.map((id) => this.enumObject.findById(id).code) || [];\n }\n\n mapFromJsonAgg(value: any): any {\n return value === null ? value : value;\n }\n}\n\n/** Similar to SimpleSerde, but applies the superstruct `assert` function when reading values from the db. */\nexport class SuperstructSerde implements ScalarCodec {\n dbType = \"jsonb\";\n isArray = false;\n\n // Use a dynamic require so that downstream projects don't have to depend on superstruct\n // until they want to, i.e. we don't have superstruct in the joist-orm package.json.\n private assert = runtimeRequire(\"superstruct\").assert;\n\n constructor(private superstruct: any) {}\n\n /** JSON schemas describe a jsonb value, even when that value is a JSON array. */\n get outputType(): TypeInfo | undefined {\n return this.constructor === SuperstructSerde && !this.isArray\n ? { dbType: canonicalDbType(this.dbType), domain: this.superstruct, arrayElementSafe: true }\n : undefined;\n }\n\n /** Serializes the domain JSON value without running the read-time schema validation. */\n mapToDbValue(value: unknown): unknown {\n return JSON.stringify(value);\n }\n\n // JSON is returned by postgres already parsed, so we should just be able to return our data directly. Unlike with\n // JsonSerde, we can assume that superstruct would have parsed any complex types in the json correctly so we don't\n // need to do a round trip through JSON.stringify.\n mapToRow(value: any): any {\n return value;\n }\n\n mapToDb(value: any) {\n return JSON.stringify(value);\n }\n\n /** Validates a driver JSON value with the field's Superstruct schema. */\n mapFromDb(value: unknown): unknown {\n const dbValue = maybeNullToUndefined(value);\n if (dbValue) this.assert(dbValue, this.superstruct);\n return dbValue;\n }\n\n mapFromJsonAgg(value: any): any {\n return value === null ? value : value;\n }\n}\n\nexport class JsonSerde implements ScalarCodec {\n dbType = \"jsonb\";\n isArray = false;\n\n constructor() {}\n\n /** Unvalidated JSON uses its own encoder, not a primitive or schema-specific codec. */\n get outputType(): TypeInfo | undefined {\n return this.constructor === JsonSerde && !this.isArray\n ? { dbType: canonicalDbType(this.dbType), domain: JsonSerde, arrayElementSafe: true }\n : undefined;\n }\n\n /** Serializes the whole JSON value, including JSON arrays and custom toJSON methods. */\n mapToDbValue(value: unknown): unknown {\n return JSON.stringify(value);\n }\n\n // JSON is returned by postgres already parsed, so if we are trying to recreate then we need to stringify, then parse.\n // It's necessary to do this instead of just returning the object directly because any complex types in the json need\n // to be stringified to correctly reflect the db value.\n mapToRow(value: any): any {\n const json = JSON.stringify(value);\n return isDefined(json) ? JSON.parse(json) : undefined;\n }\n\n mapToDb(value: any) {\n return JSON.stringify(value);\n }\n\n /** Keeps the driver's parsed JSON value, normalizing SQL NULL for entity fields. */\n mapFromDb(value: unknown): unknown {\n return maybeNullToUndefined(value);\n }\n\n mapFromJsonAgg(value: any): any {\n return value === null ? value : value;\n }\n}\n\n/** Similar to SimpleSerde, but applies the zod's `parse` function when reading values from the db. */\nexport class ZodSerde implements ScalarCodec {\n dbType = \"jsonb\";\n isArray = false;\n\n constructor(private zodSchema: any) {}\n\n /** Parsing and transformations are compatible only for the same schema object. */\n get outputType(): TypeInfo | undefined {\n return this.constructor === ZodSerde && !this.isArray\n ? { dbType: canonicalDbType(this.dbType), domain: this.zodSchema, arrayElementSafe: true }\n : undefined;\n }\n\n /** Serializes the domain JSON value without running the read-time Zod parser or transforms. */\n mapToDbValue(value: unknown): unknown {\n return JSON.stringify(value);\n }\n\n // JSON is returned by postgres already parsed, so we should just be able to return our data directly. Unlike with\n // JsonSerde, we can assume that zod would have parsed any complex types in the json correctly so we don't need to\n // do a round trip through JSON.stringify.\n mapToRow(value: any): any {\n return value;\n }\n\n mapToDb(value: any) {\n return JSON.stringify(value);\n }\n\n /** Parses a driver JSON value with the field's Zod schema. */\n mapFromDb(value: unknown): unknown {\n const dbValue = maybeNullToUndefined(value);\n return dbValue ? this.zodSchema.parse(dbValue) : dbValue;\n }\n\n mapFromJsonAgg(value: any): any {\n return value === null ? value : value;\n }\n}\n\n/** PostgreSQL does not enforce declared array dimensions; reject nested values rather than coercing subarrays. */\nfunction assertFlatNumericArray(value: unknown): void {\n if (Array.isArray(value) && value.some(Array.isArray)) {\n throw new Error(\"Native numeric arrays must be one-dimensional\");\n }\n}\n\n/** Only driver-native numbers agree with Number aggregates; int8/numeric identity values do not. */\nfunction primitiveOutputDomain(dbType: string): unknown {\n switch (dbType) {\n case \"int2\":\n case \"int4\":\n case \"float4\":\n case \"float8\":\n return Number;\n case \"text\":\n case \"varchar\":\n case \"bpchar\":\n return String;\n default:\n return PrimitiveSerde;\n }\n}\n\n/** Normalizes SQL NULL to an unset entity field. */\nfunction maybeNullToUndefined(value: any): any {\n return value === null ? undefined : value;\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"temporal.cjs","names":["createRequire"],"sources":["../src/temporal.ts"],"sourcesContent":["/// <reference types=\"temporal-spec/global\" preserve=\"true\" />\n\nimport { createRequire } from \"node:module\";\n\nconst runtimeRequire = createRequire(import.meta.url);\n\n// Native Temporal and both supported polyfills expose this shape; use the shared spec types instead of duplicating it.\ntype TemporalModule = typeof import(\"temporal-spec\");\nlet temporal: TemporalModule | undefined | false;\n\n/**\n * Lazily exposes Joist's native-first / polyfill-fallback Temporal detection.\n *\n * This is useful while the joist-orm repo itself has both pre-Node 26, and post-Node 26\n * test coverage, b/c our CI test suite needs the same a) codegen output and b) test suites\n * to \"just work\" with either Node 24/25 or Node 26, which means they can't have an explicit\n * import to either `temporal-polyfill` or the `Temporal` global.\n *\n * This is exactly what Joist's internal temporal resolution was already working around, so\n * this just exposes an `import { Temporal } from joist-orm` that lets the codegen & tests\n * reuse the same abstraction.\n */\nexport const Temporal = new Proxy(\n {},\n {\n get(_target, property, receiver) {\n return Reflect.get(requireTemporal().Temporal, property, receiver);\n },\n },\n) as typeof globalThis.Temporal;\n\n/**\n * A type-only `Temporal` namespace that merges with the `const Temporal` above.\n *\n * The `const` is only a value, so using `Temporal.PlainDate` / `Temporal.ZonedDateTime` as a\n * type needs a namespace to resolve against. Node 26 has that as a global, but older Node\n * versions don't, so `temporal-spec/global` supplies the same global namespace as a fallback.\n */\nexport declare namespace Temporal {\n export type Instant = globalThis.Temporal.Instant;\n export type ZonedDateTime = globalThis.Temporal.ZonedDateTime;\n export type PlainDate = globalThis.Temporal.PlainDate;\n export type PlainTime = globalThis.Temporal.PlainTime;\n export type PlainDateTime = globalThis.Temporal.PlainDateTime;\n export type PlainYearMonth = globalThis.Temporal.PlainYearMonth;\n export type PlainMonthDay = globalThis.Temporal.PlainMonthDay;\n export type Duration = globalThis.Temporal.Duration;\n}\n\n/**\n * Conditionally/dynamically requires `temporal-polyfill`.\n *\n * We want to avoid directly importing/requiring `temporal-polyfill` because\n * it will introduce the dependency to all users of Joist.\n */\nexport function maybeRequireTemporal(): TemporalModule | undefined {\n // if we've already failed to find a temporal implementation before, early exit\n if (temporal === false) return undefined;\n // if we already required temporal, just return that\n if (temporal) return temporal;\n // use built in temporal if present\n if (\"Temporal\" in global && \"Intl\" in global) {\n temporal = {\n Temporal: global.Temporal as typeof globalThis.Temporal,\n toTemporalInstant: Date.prototype.toTemporalInstant,\n Intl: global.Intl,\n };\n return temporal;\n }\n // preferentially try to use temporal-polyfill\n try {\n temporal = runtimeRequire(\"temporal-polyfill\");\n return temporal as TemporalModule;\n } catch (e) {}\n // last resort, try to use @js-temporal/polyfill\n try {\n temporal = runtimeRequire(\"@js-temporal/polyfill\");\n return temporal as TemporalModule;\n } catch (e) {}\n // don't try to load temporal again\n temporal = false;\n return undefined;\n}\n\nexport function requireTemporal(): TemporalModule {\n const temporal = maybeRequireTemporal();\n if (!temporal) throw new Error(\"Unable to find a Temporal implementation\");\n return temporal;\n}\n"],"mappings":";;AAIA,MAAM,kBAAA,wBAAiBA,CAAAA,CAAAA,cAAAA,CAAAA,QAAAA,KAAAA,CAAAA,CAAAA,cAAAA,UAAAA,CAAAA,CAAAA,IAA6B;AAIpD,IAAI;;;;;;;;;;;;;AAcJ,MAAa,WAAW,IAAI,MAC1B,CAAC,GACD,EACE,IAAI,SAAS,UAAU,UAAU;CAC/B,OAAO,QAAQ,IAAI,gBAAgB,CAAC,CAAC,UAAU,UAAU,QAAQ;AACnE,EACF,CACF;;;;;;;AA0BA,SAAgB,uBAAmD;CAEjE,IAAI,aAAa,OAAO,OAAO,KAAA;CAE/B,IAAI,UAAU,OAAO;CAErB,IAAI,cAAc,UAAU,UAAU,QAAQ;EAC5C,WAAW;GACT,UAAU,OAAO;GACjB,mBAAmB,KAAK,UAAU;GAClC,MAAM,OAAO;EACf;EACA,OAAO;CACT;CAEA,IAAI;EACF,WAAW,eAAe,mBAAmB;EAC7C,OAAO;CACT,SAAS,GAAG,CAAC;CAEb,IAAI;EACF,WAAW,eAAe,uBAAuB;EACjD,OAAO;CACT,SAAS,GAAG,CAAC;CAEb,WAAW;AAEb;AAEA,SAAgB,kBAAkC;CAChD,MAAM,WAAW,qBAAqB;CACtC,IAAI,CAAC,UAAU,MAAM,IAAI,MAAM,0CAA0C;CACzE,OAAO;AACT"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"temporal.d.cts","names":[],"sources":["../src/temporal.ts"],"mappings":";;KAOK;;;;;;;;;;;;;cAeQ,iBAOD,WAAW;;;;;;;;kBASE;OACX,UAAU,WAAW,SAAS;OAC9B,gBAAgB,WAAW,SAAS;OACpC,YAAY,WAAW,SAAS;OAChC,YAAY,WAAW,SAAS;OAChC,gBAAgB,WAAW,SAAS;OACpC,iBAAiB,WAAW,SAAS;OACrC,gBAAgB,WAAW,SAAS;OACpC,WAAW,WAAW,SAAS;;;;;;;;iBAS7B,wBAAwB;iBA6BxB,mBAAmB"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"temporal.d.mts","names":[],"sources":["../src/temporal.ts"],"mappings":";;KAOK;;;;;;;;;;;;;cAeQ,iBAOD,WAAW;;;;;;;;kBASE;OACX,UAAU,WAAW,SAAS;OAC9B,gBAAgB,WAAW,SAAS;OACpC,YAAY,WAAW,SAAS;OAChC,YAAY,WAAW,SAAS;OAChC,gBAAgB,WAAW,SAAS;OACpC,iBAAiB,WAAW,SAAS;OACrC,gBAAgB,WAAW,SAAS;OACpC,WAAW,WAAW,SAAS;;;;;;;;iBAS7B,wBAAwB;iBA6BxB,mBAAmB"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"temporal.js","names":[],"sources":["../src/temporal.ts"],"sourcesContent":["/// <reference types=\"temporal-spec/global\" preserve=\"true\" />\n\nimport { createRequire } from \"node:module\";\n\nconst runtimeRequire = createRequire(import.meta.url);\n\n// Native Temporal and both supported polyfills expose this shape; use the shared spec types instead of duplicating it.\ntype TemporalModule = typeof import(\"temporal-spec\");\nlet temporal: TemporalModule | undefined | false;\n\n/**\n * Lazily exposes Joist's native-first / polyfill-fallback Temporal detection.\n *\n * This is useful while the joist-orm repo itself has both pre-Node 26, and post-Node 26\n * test coverage, b/c our CI test suite needs the same a) codegen output and b) test suites\n * to \"just work\" with either Node 24/25 or Node 26, which means they can't have an explicit\n * import to either `temporal-polyfill` or the `Temporal` global.\n *\n * This is exactly what Joist's internal temporal resolution was already working around, so\n * this just exposes an `import { Temporal } from joist-orm` that lets the codegen & tests\n * reuse the same abstraction.\n */\nexport const Temporal = new Proxy(\n {},\n {\n get(_target, property, receiver) {\n return Reflect.get(requireTemporal().Temporal, property, receiver);\n },\n },\n) as typeof globalThis.Temporal;\n\n/**\n * A type-only `Temporal` namespace that merges with the `const Temporal` above.\n *\n * The `const` is only a value, so using `Temporal.PlainDate` / `Temporal.ZonedDateTime` as a\n * type needs a namespace to resolve against. Node 26 has that as a global, but older Node\n * versions don't, so `temporal-spec/global` supplies the same global namespace as a fallback.\n */\nexport declare namespace Temporal {\n export type Instant = globalThis.Temporal.Instant;\n export type ZonedDateTime = globalThis.Temporal.ZonedDateTime;\n export type PlainDate = globalThis.Temporal.PlainDate;\n export type PlainTime = globalThis.Temporal.PlainTime;\n export type PlainDateTime = globalThis.Temporal.PlainDateTime;\n export type PlainYearMonth = globalThis.Temporal.PlainYearMonth;\n export type PlainMonthDay = globalThis.Temporal.PlainMonthDay;\n export type Duration = globalThis.Temporal.Duration;\n}\n\n/**\n * Conditionally/dynamically requires `temporal-polyfill`.\n *\n * We want to avoid directly importing/requiring `temporal-polyfill` because\n * it will introduce the dependency to all users of Joist.\n */\nexport function maybeRequireTemporal(): TemporalModule | undefined {\n // if we've already failed to find a temporal implementation before, early exit\n if (temporal === false) return undefined;\n // if we already required temporal, just return that\n if (temporal) return temporal;\n // use built in temporal if present\n if (\"Temporal\" in global && \"Intl\" in global) {\n temporal = {\n Temporal: global.Temporal as typeof globalThis.Temporal,\n toTemporalInstant: Date.prototype.toTemporalInstant,\n Intl: global.Intl,\n };\n return temporal;\n }\n // preferentially try to use temporal-polyfill\n try {\n temporal = runtimeRequire(\"temporal-polyfill\");\n return temporal as TemporalModule;\n } catch (e) {}\n // last resort, try to use @js-temporal/polyfill\n try {\n temporal = runtimeRequire(\"@js-temporal/polyfill\");\n return temporal as TemporalModule;\n } catch (e) {}\n // don't try to load temporal again\n temporal = false;\n return undefined;\n}\n\nexport function requireTemporal(): TemporalModule {\n const temporal = maybeRequireTemporal();\n if (!temporal) throw new Error(\"Unable to find a Temporal implementation\");\n return temporal;\n}\n"],"mappings":";;AAIA,MAAM,iBAAiB,cAAc,YAAY,GAAG;AAIpD,IAAI;;;;;;;;;;;;;AAcJ,MAAa,WAAW,IAAI,MAC1B,CAAC,GACD,EACE,IAAI,SAAS,UAAU,UAAU;CAC/B,OAAO,QAAQ,IAAI,gBAAgB,CAAC,CAAC,UAAU,UAAU,QAAQ;AACnE,EACF,CACF;;;;;;;AA0BA,SAAgB,uBAAmD;CAEjE,IAAI,aAAa,OAAO,OAAO,KAAA;CAE/B,IAAI,UAAU,OAAO;CAErB,IAAI,cAAc,UAAU,UAAU,QAAQ;EAC5C,WAAW;GACT,UAAU,OAAO;GACjB,mBAAmB,KAAK,UAAU;GAClC,MAAM,OAAO;EACf;EACA,OAAO;CACT;CAEA,IAAI;EACF,WAAW,eAAe,mBAAmB;EAC7C,OAAO;CACT,SAAS,GAAG,CAAC;CAEb,IAAI;EACF,WAAW,eAAe,uBAAuB;EACjD,OAAO;CACT,SAAS,GAAG,CAAC;CAEb,WAAW;AAEb;AAEA,SAAgB,kBAAkC;CAChD,MAAM,WAAW,qBAAqB;CACtC,IAAI,CAAC,UAAU,MAAM,IAAI,MAAM,0CAA0C;CACzE,OAAO;AACT"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"temporalMappers.cjs","names":["maybeRequireTemporal","fail"],"sources":["../src/temporalMappers.ts"],"sourcesContent":["import { type CustomSerde } from \"./serde.ts\";\nimport { type Temporal, maybeRequireTemporal } from \"./temporal.ts\";\nimport { fail } from \"./utils.ts\";\n\nconst { Temporal: t } = maybeRequireTemporal() ?? {};\nconst temporalNotAvailable = {\n fromDb: () => fail(\"Temporal not available\"),\n toDb: () => fail(\"Temporal not available\"),\n};\n\n/**\n * Converts Postgres `DATE` to/from Temporal.PlainDate.\n *\n * `fromDb` accepts either pg's text form (classic/knex text queries, json_agg preloads) or an\n * already-constructed `PlainDate` (lazy binary queries decode wire bytes -> Temporal directly).\n */\nexport const plainDateMapper: CustomSerde<Temporal.PlainDate, string> = t\n ? {\n fromDb: (value: string | Temporal.PlainDate) => (value instanceof t.PlainDate ? value : t.PlainDate.from(value)),\n toDb: (p) => p.toString(),\n }\n : temporalNotAvailable;\n\n/** Converts Postgres `TIME` to/from Temporal.PlainTime; `fromDb` also passes binary-decoded instances through. */\nexport const plainTimeMapper: CustomSerde<Temporal.PlainTime, string> = t\n ? {\n fromDb: (value: string | Temporal.PlainTime) => (value instanceof t.PlainTime ? value : t.PlainTime.from(value)),\n toDb: (pt) => pt.toString(),\n }\n : temporalNotAvailable;\n\n/**\n * Converts Postgres `TIMESTAMP` / `TIMESTAMP WITHOUT TIME ZONE` to/from Temporal.PlainDateTime;\n * `fromDb` also passes binary-decoded instances through.\n */\nexport const plainDateTimeMapper: CustomSerde<Temporal.PlainDateTime, string> = t\n ? {\n // Text values look like `2018-01-01 10:00:00`\n fromDb: (value: string | Temporal.PlainDateTime) =>\n value instanceof t.PlainDateTime ? value : t.PlainDateTime.from(value),\n toDb: (p) => p.toString(),\n }\n : temporalNotAvailable;\n\n/**\n * Converts Postgres `TIMESTAMPTZ`, `TIMESTAMPTZ WITH TIME ZONE` to/from Temporal.ZonedDateTime.\n *\n * Specifically, Postgres uses ISO 8601, which Temporal supports as well, except that PG ouputs a space instead of `T`\n * between the date/time for output.\n *\n * Additionally, `Temporal.ZonedDateTime.from` expects a time zone literal name to be supplied as part of the string,\n * but this is not stored by postgres.\n *\n * As such, we parse the offset and append it to string passed to `from` as the time zone. This means that if we did a\n * round trip of generating a db value then parsing it, then it may not strictly equal the original zdt.\n *\n * Finally, PG stores dates as UTC and converts them to its local time zone for output, so we could get any offset\n * theoretically. If, somehow, we don't get an offset, then we assume UTC.\n */\nexport const zonedDateTimeMapper: CustomSerde<Temporal.ZonedDateTime, string> = t\n ? {\n // Produce a ZDT from a PG output like \"2021-01-01 12:00:00-05:00\"; binary-decoded\n // instances (lazy queries construct ZonedDateTimes directly) pass through\n fromDb: (value: string | Temporal.ZonedDateTime) => {\n if (typeof value !== \"string\") return value;\n const [offset] = value.match(/([+-]\\d{2}(?::?\\d{2})?)$/) ?? [];\n return t.ZonedDateTime.from(`${value}[${!offset || /^\\+00(:?00)?$/.test(offset) ? \"UTC\" : offset}]`);\n },\n // Match a PG `TIMESTAMPTZ` input format, i.e. \"2021-01-01T12:00:00-05:00\"\n toDb: (zdt) => zdt.toString({ timeZoneName: \"never\" }),\n }\n : temporalNotAvailable;\n"],"mappings":";;;;;AAIA,MAAM,EAAE,UAAU,MAAMA,iBAAAA,qBAAqB,KAAK,CAAC;AACnD,MAAM,uBAAuB;CAC3B,cAAcC,cAAAA,KAAK,wBAAwB;CAC3C,YAAYA,cAAAA,KAAK,wBAAwB;AAC3C;;;;;;;AAQA,MAAa,kBAA2D,IACpE;CACE,SAAS,UAAwC,iBAAiB,EAAE,YAAY,QAAQ,EAAE,UAAU,KAAK,KAAK;CAC9G,OAAO,MAAM,EAAE,SAAS;AAC1B,IACA;;AAGJ,MAAa,kBAA2D,IACpE;CACE,SAAS,UAAwC,iBAAiB,EAAE,YAAY,QAAQ,EAAE,UAAU,KAAK,KAAK;CAC9G,OAAO,OAAO,GAAG,SAAS;AAC5B,IACA;;;;;AAMJ,MAAa,sBAAmE,IAC5E;CAEE,SAAS,UACP,iBAAiB,EAAE,gBAAgB,QAAQ,EAAE,cAAc,KAAK,KAAK;CACvE,OAAO,MAAM,EAAE,SAAS;AAC1B,IACA;;;;;;;;;;;;;;;;AAiBJ,MAAa,sBAAmE,IAC5E;CAGE,SAAS,UAA2C;EAClD,IAAI,OAAO,UAAU,UAAU,OAAO;EACtC,MAAM,CAAC,UAAU,MAAM,MAAM,0BAA0B,KAAK,CAAC;EAC7D,OAAO,EAAE,cAAc,KAAK,GAAG,MAAM,GAAG,CAAC,UAAU,gBAAgB,KAAK,MAAM,IAAI,QAAQ,OAAO,EAAE;CACrG;CAEA,OAAO,QAAQ,IAAI,SAAS,EAAE,cAAc,QAAQ,CAAC;AACvD,IACA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"temporalMappers.d.cts","names":[],"sources":["../src/temporalMappers.ts"],"mappings":";;;;;;;;;cAgBa,iBAAiB,YAAY,SAAS;;cAQtC,iBAAiB,YAAY,SAAS;;;;;cAWtC,qBAAqB,YAAY,SAAS;;;;;;;;;;;;;;;;cAwB1C,qBAAqB,YAAY,SAAS"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"temporalMappers.d.mts","names":[],"sources":["../src/temporalMappers.ts"],"mappings":";;;;;;;;;cAgBa,iBAAiB,YAAY,SAAS;;cAQtC,iBAAiB,YAAY,SAAS;;;;;cAWtC,qBAAqB,YAAY,SAAS;;;;;;;;;;;;;;;;cAwB1C,qBAAqB,YAAY,SAAS"}