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,14 +1,14 @@
1
- import { setField } from "../fields.js";
2
1
  import { AbstractRelationImpl } from "./AbstractRelationImpl.js";
3
2
  import { RelationT, RelationU } from "./RelationSymbols.js";
4
- import { oneToOneBatchLoader } from "../batchloaders/oneToOneBatchLoader.js";
5
- import { isCascadeDelete } from "./isCascadeDelete.js";
6
3
  import { ReferenceN } from "./ReferenceSymbols.js";
7
- import { failIfNewEntity, failNoId } from "./ManyToOneReference.js";
4
+ import { setField } from "../fields.js";
5
+ import { deTagId } from "../keys.js";
8
6
  import "./Reference.js";
7
+ import { isCascadeDelete } from "./isCascadeDelete.js";
8
+ import { failIfNewEntity, failNoId } from "./ManyToOneReference.js";
9
+ import { oneToOneBatchLoader } from "../batchloaders/oneToOneBatchLoader.js";
9
10
  import { isReactiveReference } from "./ReactiveReference.js";
10
11
  import { lazyField } from "../newEntity.js";
11
- import { deTagId } from "../keys.js";
12
12
  import { getMetadata } from "../EntityMetadata.js";
13
13
  import { ensureNotDeleted } from "../index.js";
14
14
  import { appendStack, getEmInternalApi } from "../EntityManager.js";
@@ -1,14 +1,14 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_fields = require("../fields.cjs");
3
2
  const require_relations_AbstractRelationImpl = require("./AbstractRelationImpl.cjs");
4
3
  const require_relations_RelationSymbols = require("./RelationSymbols.cjs");
4
+ const require_relations_ReferenceSymbols = require("./ReferenceSymbols.cjs");
5
+ const require_fields = require("../fields.cjs");
6
+ const require_keys = require("../keys.cjs");
5
7
  const require_relations_isCascadeDelete = require("./isCascadeDelete.cjs");
6
8
  const require_relations_OneToManyCollection = require("./OneToManyCollection.cjs");
7
- const require_relations_ReferenceSymbols = require("./ReferenceSymbols.cjs");
8
9
  const require_relations_ManyToOneReference = require("./ManyToOneReference.cjs");
9
10
  const require_utils = require("../utils.cjs");
10
11
  const require_newEntity = require("../newEntity.cjs");
11
- const require_keys = require("../keys.cjs");
12
12
  const require_configure = require("../configure.cjs");
13
13
  const require_EntityMetadata = require("../EntityMetadata.cjs");
14
14
  const require_index = require("../index.cjs");
@@ -1,13 +1,13 @@
1
- import { getField, setField } from "../fields.js";
2
1
  import { AbstractRelationImpl } from "./AbstractRelationImpl.js";
3
2
  import { RelationT, RelationU } from "./RelationSymbols.js";
3
+ import { ReferenceN } from "./ReferenceSymbols.js";
4
+ import { getField, setField } from "../fields.js";
5
+ import { maybeResolveReferenceToId } from "../keys.js";
4
6
  import { isCascadeDelete } from "./isCascadeDelete.js";
5
7
  import { OneToManyCollection } from "./OneToManyCollection.js";
6
- import { ReferenceN } from "./ReferenceSymbols.js";
7
8
  import { failIfNewEntity, failNoId } from "./ManyToOneReference.js";
8
9
  import { fail } from "../utils.js";
9
10
  import { lazyField } from "../newEntity.js";
10
- import { maybeResolveReferenceToId } from "../keys.js";
11
11
  import { getConstructorFromTaggedId, maybeGetConstructorFromReference } from "../configure.js";
12
12
  import { getMetadata } from "../EntityMetadata.js";
13
13
  import { ensureNotDeleted } from "../index.js";
@@ -1,10 +1,9 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_fields = require("../fields.cjs");
3
2
  const require_relations_AbstractPropertyImpl = require("./AbstractPropertyImpl.cjs");
4
3
  const require_relations_PropertySymbols = require("./PropertySymbols.cjs");
5
- require("../IsLoadedCache.cjs");
6
- const require_reactiveHints = require("../reactiveHints.cjs");
7
- const require_loadHints = require("../loadHints.cjs");
4
+ const require_reactivity_reactiveHints = require("../reactivity/reactiveHints.cjs");
5
+ const require_loading_loadHints = require("../loading/loadHints.cjs");
6
+ const require_fields = require("../fields.cjs");
8
7
  const require_newEntity = require("../newEntity.cjs");
9
8
  const require_EntityMetadata = require("../EntityMetadata.cjs");
10
9
  require("../index.cjs");
@@ -81,7 +80,7 @@ var ReactiveFieldImpl = class extends require_relations_AbstractPropertyImpl.Abs
81
80
  }
82
81
  get isLoaded() {
83
82
  if (this.#isLoaded !== void 0) return this.#isLoaded;
84
- this.#isLoaded = require_loadHints.isLoaded(this.entity, this.loadHint);
83
+ this.#isLoaded = require_loading_loadHints.isLoaded(this.entity, this.loadHint);
85
84
  require_EntityManager.getEmInternalApi(this.entity.em).isLoadedCache.add(this);
86
85
  return this.#isLoaded;
87
86
  }
@@ -91,7 +90,7 @@ var ReactiveFieldImpl = class extends require_relations_AbstractPropertyImpl.Abs
91
90
  }
92
91
  get loadHint() {
93
92
  const meta = require_EntityMetadata.getMetadata(this.entity);
94
- return meta.config.__data.cachedReactiveLoadHints[this.fieldName] ??= require_reactiveHints.convertToLoadHint(meta, this.reactiveHint);
93
+ return meta.config.__data.cachedReactiveLoadHints[this.fieldName] ??= require_reactivity_reactiveHints.convertToLoadHint(meta, this.reactiveHint);
95
94
  }
96
95
  setFactoryValue(newValue) {
97
96
  require_fields.setField(this.entity, this.fieldName, newValue);
@@ -1 +1 @@
1
- {"version":3,"file":"ReactiveField.cjs","names":["lazyField","getMetadata","AbstractPropertyImpl","#field","#reactiveHint","#loadPromise","#isLoaded","#isCached","getEmInternalApi","getField","isFieldSet","isLoaded","convertToLoadHint","PropertyT"],"sources":["../../src/relations/ReactiveField.ts"],"sourcesContent":["import { type Entity } from \"../Entity.ts\";\nimport { getEmInternalApi } from \"../EntityManager.ts\";\nimport { type PrimitiveField, getMetadata } from \"../EntityMetadata.ts\";\nimport { getField, isFieldSet, setField } from \"../fields.ts\";\nimport { isLoaded } from \"../index.ts\";\nimport { type IsLoadedCachable } from \"../IsLoadedCache.ts\";\nimport { lazyField } from \"../newEntity.ts\";\nimport { type Reacted, type ReactiveHint, convertToLoadHint } from \"../reactiveHints.ts\";\nimport { AbstractPropertyImpl } from \"./AbstractPropertyImpl.ts\";\nimport { PropertyT } from \"./PropertySymbols.ts\";\n\n/**\n * A `ReactiveField` is a value that is derived from other entities/values,\n * similar to a `Property`, but it is also persisted in the database.\n *\n * This allows callers (or SQL queries) to access the value without first calling\n * `await load()` on the property.\n *\n * So, unlike `Property`, `.get` is always available; if the property is unloaded,\n * then `.get` will return the last-calculated value, but if the property is loaded,\n * then it will go ahead and invoke function to calculate the latest value (i.e. so\n * that you can observe the latest & greatest value w/o waiting for `em.flush` to\n * re-calc the value while persisting to the database.\n */\nexport interface ReactiveField<T extends Entity, V> {\n [PropertyT]: T;\n isLoaded: boolean;\n isSet: boolean;\n\n /**\n * Calculates the latest derived value.\n *\n * Users are not required to call this method explicitly, as Joist will keep the\n * persisted value automatically in-sync, but if for some reason (code changes,\n * bug fixes, etc.) you need to trigger an explicit recalc, you can call `.load()`,\n * any dependent data will be loaded from the database, and the latest value\n * returned, and then later stored to the database on `em.flush`.\n *\n * Note that persisted properties used in load hints, i.e. `em.populate`s that\n * accidentally list reactive fields (instead of just relations) will not have\n * `.load()` invoked, and will instead use the previously-calculated value.\n * The rationale is that one persisted property should be able to declare its\n * dependency on another persisted property (for its reactive field-level hint)\n * without causing that dependent property's populate hint to itself be loaded.\n */\n load(opts?: { forceReload?: boolean }): Promise<V>;\n\n /** If loaded, returns the latest derived value, or if unload returns the previously-calculated value. */\n get: V;\n\n /**\n * Returns the as-of-last-flush previously-calculated value.\n *\n * This is useful if you have to purposefully avoid using the lambda to calc the latest value,\n * i.e. if you're in a test and want to watch a calculated value change from some dummy value\n * to the new derived value.\n * */\n fieldValue: V;\n}\n\n/**\n * Creates a calculated derived value from a load hint + lambda.\n *\n * The property can be accessed by default as a promise, with `someProperty.load()`.\n *\n * But if `someProperty` is used as a populate hint, then it can be accessed synchronously,\n * with `someProperty.get`.\n */\nexport function hasReactiveField<T extends Entity, const H extends ReactiveHint<T>, V>(\n hint: H,\n fn: (entity: Reacted<T, H>) => V,\n): ReactiveField<T, V> {\n return lazyField((entity: T, fieldName) => {\n const field = getMetadata(entity).allFields[fieldName] as PrimitiveField;\n return new ReactiveFieldImpl(entity, field, hint, fn);\n });\n}\n\nexport class ReactiveFieldImpl<T extends Entity, H extends ReactiveHint<T>, V>\n extends AbstractPropertyImpl<T>\n implements ReactiveField<T, V>, IsLoadedCachable\n{\n readonly #field: PrimitiveField;\n readonly #reactiveHint: H;\n #loadPromise: any;\n // Initially undefined, then cached as true/false\n #isLoaded: boolean | undefined;\n #isCached: boolean | \"factory-value\" = false;\n\n constructor(\n entity: T,\n field: PrimitiveField,\n reactiveHint: H,\n private fn: (entity: Reacted<T, H>) => V,\n ) {\n super(entity);\n this.#field = field;\n this.#reactiveHint = reactiveHint;\n }\n\n async load(opts?: { forceReload?: boolean }): Promise<V> {\n // Even without `forceReload=true`, any explicit calls to `.load()` ==> ensure a fresh value,\n // because `.get` may have cached the stale/previously-calculated value.\n //\n // (Currently `em.populate` / `populateDataLoader` has a hack/escape hatch that ignores calling\n // RF.load(), to avoid pulling in the RF subgraph over using the materialized value, which ideally would be\n // replaced with us learning to do the maybeDirty approach.)\n if (!this.isLoaded || opts?.forceReload) {\n return (this.#loadPromise ??= this.entity.em.populate(this.entity, { hint: this.loadHint } as any).then(() => {\n this.#loadPromise = undefined;\n this.#isLoaded = true;\n getEmInternalApi(this.entity.em).isLoadedCache.add(this);\n // Wait and reset `#isCached` until inside this `then`, so that we don't have a race condition where:\n // - two relations (us and someone else) are both passed to `em.calc`\n // - their load hint is simpler, so their promises resolves first, and their `.get` calls our `.get`\n // - our `.get` sees we're not loaded, but calls `fieldValue` for the existing value, and dutifully sets `#isCached=true`\n // - finally our promise runs, and if we didn't immediately set `#isCached=false` here, our `.get` would again\n // early return and keep using the stale fieldValue.\n this.resetCacheUnlessFactoryPinned();\n // Go through `this.get` so that `setField` is called to set our latest value\n return this.get;\n }));\n }\n this.resetCacheUnlessFactoryPinned();\n return this.get;\n }\n\n /** Returns either the latest calculated value (if loaded) or the previously-calculated value (if not loaded). */\n get get(): V {\n const { fn } = this;\n // Some ReactiveFields can have surprisingly expensive calculations, especially in loops\n // or those that invoke loops, so cache the value.\n if (this.#isCached) return this.fieldValue;\n // isLoaded will watch for our previously-loaded subgraph being mutated (isLoaded is locally cached but hooked into\n // our IsLoadedCache cache that is immediately invalidated on write-path), and if we've drifted to not-loaded, it's\n // better to fail and tell the user.\n if (this.isLoaded) {\n const newValue = fn(this.entity as Reacted<T, H>);\n if (!getEmInternalApi(this.entity.em).isValidating) {\n // setField will immediately invalidate downstream #isLoaded/#isCached values\n setField(this.entity, this.fieldName, newValue);\n this.#isCached = true;\n getEmInternalApi(this.entity.em).isLoadedCache.add(this);\n }\n return newValue;\n } else if (this.isSet) {\n this.#isCached = true;\n getEmInternalApi(this.entity.em).isLoadedCache.add(this);\n return this.fieldValue;\n } else {\n throw new Error(`${this.fieldName} has not been derived yet`);\n }\n }\n\n get fieldName(): keyof T & string {\n return this.#field.fieldName as keyof T & string;\n }\n\n get reactiveHint(): H {\n return this.#reactiveHint;\n }\n\n get fieldValue(): V {\n return getField(this.entity, this.fieldName);\n }\n\n get isSet() {\n return isFieldSet(this.entity, this.fieldName);\n }\n\n get isLoaded() {\n // Skip an expensive isLoaded(subgraph) call if no mutations have happened\n if (this.#isLoaded !== undefined) return this.#isLoaded;\n this.#isLoaded = isLoaded(this.entity, this.loadHint);\n getEmInternalApi(this.entity.em).isLoadedCache.add(this);\n return this.#isLoaded;\n }\n\n resetIsLoaded(): void {\n // Even though we reset this on every mutation, `isLoaded` will still realize when the subgraph\n // is still loaded (as it did before we added caching), so users won't see false positive.\n this.#isLoaded = undefined;\n this.resetCacheUnlessFactoryPinned();\n }\n\n get loadHint(): any {\n const meta = getMetadata(this.entity);\n return (meta.config.__data.cachedReactiveLoadHints[this.fieldName] ??= convertToLoadHint(meta, this.reactiveHint));\n }\n\n setFactoryValue(newValue: any): void {\n setField(this.entity, this.fieldName, newValue);\n this.#isCached = \"factory-value\";\n }\n\n [PropertyT] = undefined as any as T;\n\n private resetCacheUnlessFactoryPinned(): void {\n // If factories asked for a hard-coded value, don't reset the cached flag\n if (this.#isCached === \"factory-value\") return;\n this.#isCached = false;\n }\n}\n\n/** Type guard utility for determining if an entity field is a ReactiveField. */\nexport function isReactiveField(maybeReactiveField: any): maybeReactiveField is ReactiveField<any, any> {\n return maybeReactiveField instanceof ReactiveFieldImpl;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAoEA,SAAgB,iBACd,MACA,IACqB;CACrB,OAAOA,kBAAAA,WAAW,QAAW,cAAc;EACzC,MAAM,QAAQC,uBAAAA,YAAY,MAAM,CAAC,CAAC,UAAU;EAC5C,OAAO,IAAI,kBAAkB,QAAQ,OAAO,MAAM,EAAE;CACtD,CAAC;AACH;AAEA,IAAa,oBAAb,cACUC,uCAAAA,qBAEV;CAYY;CAXV;CACA;CACA;CAEA;CACA,YAAuC;CAEvC,YACE,QACA,OACA,cACA,IACA;EACA,MAAM,MAAM;EAFJ,KAAA,KAAA;EAGR,KAAKC,SAAS;EACd,KAAKC,gBAAgB;CACvB;CAEA,MAAM,KAAK,MAA8C;EAOvD,IAAI,CAAC,KAAK,YAAY,MAAM,aAC1B,OAAQ,KAAKC,iBAAiB,KAAK,OAAO,GAAG,SAAS,KAAK,QAAQ,EAAE,MAAM,KAAK,SAAS,CAAQ,CAAC,CAAC,WAAW;GAC5G,KAAKA,eAAe,KAAA;GACpB,KAAKC,YAAY;GACjB,sBAAA,iBAAiB,KAAK,OAAO,EAAE,CAAC,CAAC,cAAc,IAAI,IAAI;GAOvD,KAAK,8BAA8B;GAEnC,OAAO,KAAK;EACd,CAAC;EAEH,KAAK,8BAA8B;EACnC,OAAO,KAAK;CACd;;CAGA,IAAI,MAAS;EACX,MAAM,EAAE,OAAO;EAGf,IAAI,KAAKC,WAAW,OAAO,KAAK;EAIhC,IAAI,KAAK,UAAU;GACjB,MAAM,WAAW,GAAG,KAAK,MAAuB;GAChD,IAAI,CAACC,sBAAAA,iBAAiB,KAAK,OAAO,EAAE,CAAC,CAAC,cAAc;IAElD,eAAA,SAAS,KAAK,QAAQ,KAAK,WAAW,QAAQ;IAC9C,KAAKD,YAAY;IACjB,sBAAA,iBAAiB,KAAK,OAAO,EAAE,CAAC,CAAC,cAAc,IAAI,IAAI;GACzD;GACA,OAAO;EACT,OAAO,IAAI,KAAK,OAAO;GACrB,KAAKA,YAAY;GACjB,sBAAA,iBAAiB,KAAK,OAAO,EAAE,CAAC,CAAC,cAAc,IAAI,IAAI;GACvD,OAAO,KAAK;EACd,OACE,MAAM,IAAI,MAAM,GAAG,KAAK,UAAU,0BAA0B;CAEhE;CAEA,IAAI,YAA8B;EAChC,OAAO,KAAKJ,OAAO;CACrB;CAEA,IAAI,eAAkB;EACpB,OAAO,KAAKC;CACd;CAEA,IAAI,aAAgB;EAClB,OAAOK,eAAAA,SAAS,KAAK,QAAQ,KAAK,SAAS;CAC7C;CAEA,IAAI,QAAQ;EACV,OAAOC,eAAAA,WAAW,KAAK,QAAQ,KAAK,SAAS;CAC/C;CAEA,IAAI,WAAW;EAEb,IAAI,KAAKJ,cAAc,KAAA,GAAW,OAAO,KAAKA;EAC9C,KAAKA,YAAYK,kBAAAA,SAAS,KAAK,QAAQ,KAAK,QAAQ;EACpD,sBAAA,iBAAiB,KAAK,OAAO,EAAE,CAAC,CAAC,cAAc,IAAI,IAAI;EACvD,OAAO,KAAKL;CACd;CAEA,gBAAsB;EAGpB,KAAKA,YAAY,KAAA;EACjB,KAAK,8BAA8B;CACrC;CAEA,IAAI,WAAgB;EAClB,MAAM,OAAOL,uBAAAA,YAAY,KAAK,MAAM;EACpC,OAAQ,KAAK,OAAO,OAAO,wBAAwB,KAAK,eAAeW,sBAAAA,kBAAkB,MAAM,KAAK,YAAY;CAClH;CAEA,gBAAgB,UAAqB;EACnC,eAAA,SAAS,KAAK,QAAQ,KAAK,WAAW,QAAQ;EAC9C,KAAKL,YAAY;CACnB;CAEA,CAACM,kCAAAA,aAAa,KAAA;CAEd,gCAA8C;EAE5C,IAAI,KAAKN,cAAc,iBAAiB;EACxC,KAAKA,YAAY;CACnB;AACF;;AAGA,SAAgB,gBAAgB,oBAAwE;CACtG,OAAO,8BAA8B;AACvC"}
1
+ {"version":3,"file":"ReactiveField.cjs","names":["lazyField","getMetadata","AbstractPropertyImpl","#field","#reactiveHint","#loadPromise","#isLoaded","#isCached","getEmInternalApi","getField","isFieldSet","isLoaded","convertToLoadHint","PropertyT"],"sources":["../../src/relations/ReactiveField.ts"],"sourcesContent":["import { type Entity } from \"../Entity.ts\";\nimport { getEmInternalApi } from \"../EntityManager.ts\";\nimport { type PrimitiveField, getMetadata } from \"../EntityMetadata.ts\";\nimport { getField, isFieldSet, setField } from \"../fields.ts\";\nimport { isLoaded } from \"../index.ts\";\nimport type { IsLoadedCachable } from \"../loading/IsLoadedCache.ts\";\nimport { lazyField } from \"../newEntity.ts\";\nimport { type Reacted, type ReactiveHint, convertToLoadHint } from \"../reactivity/reactiveHints.ts\";\nimport { AbstractPropertyImpl } from \"./AbstractPropertyImpl.ts\";\nimport { PropertyT } from \"./PropertySymbols.ts\";\n\n/**\n * A `ReactiveField` is a value that is derived from other entities/values,\n * similar to a `Property`, but it is also persisted in the database.\n *\n * This allows callers (or SQL queries) to access the value without first calling\n * `await load()` on the property.\n *\n * So, unlike `Property`, `.get` is always available; if the property is unloaded,\n * then `.get` will return the last-calculated value, but if the property is loaded,\n * then it will go ahead and invoke function to calculate the latest value (i.e. so\n * that you can observe the latest & greatest value w/o waiting for `em.flush` to\n * re-calc the value while persisting to the database.\n */\nexport interface ReactiveField<T extends Entity, V> {\n [PropertyT]: T;\n isLoaded: boolean;\n isSet: boolean;\n\n /**\n * Calculates the latest derived value.\n *\n * Users are not required to call this method explicitly, as Joist will keep the\n * persisted value automatically in-sync, but if for some reason (code changes,\n * bug fixes, etc.) you need to trigger an explicit recalc, you can call `.load()`,\n * any dependent data will be loaded from the database, and the latest value\n * returned, and then later stored to the database on `em.flush`.\n *\n * Note that persisted properties used in load hints, i.e. `em.populate`s that\n * accidentally list reactive fields (instead of just relations) will not have\n * `.load()` invoked, and will instead use the previously-calculated value.\n * The rationale is that one persisted property should be able to declare its\n * dependency on another persisted property (for its reactive field-level hint)\n * without causing that dependent property's populate hint to itself be loaded.\n */\n load(opts?: { forceReload?: boolean }): Promise<V>;\n\n /** If loaded, returns the latest derived value, or if unload returns the previously-calculated value. */\n get: V;\n\n /**\n * Returns the as-of-last-flush previously-calculated value.\n *\n * This is useful if you have to purposefully avoid using the lambda to calc the latest value,\n * i.e. if you're in a test and want to watch a calculated value change from some dummy value\n * to the new derived value.\n * */\n fieldValue: V;\n}\n\n/**\n * Creates a calculated derived value from a load hint + lambda.\n *\n * The property can be accessed by default as a promise, with `someProperty.load()`.\n *\n * But if `someProperty` is used as a populate hint, then it can be accessed synchronously,\n * with `someProperty.get`.\n */\nexport function hasReactiveField<T extends Entity, const H extends ReactiveHint<T>, V>(\n hint: H,\n fn: (entity: Reacted<T, H>) => V,\n): ReactiveField<T, V> {\n return lazyField((entity: T, fieldName) => {\n const field = getMetadata(entity).allFields[fieldName] as PrimitiveField;\n return new ReactiveFieldImpl(entity, field, hint, fn);\n });\n}\n\nexport class ReactiveFieldImpl<T extends Entity, H extends ReactiveHint<T>, V>\n extends AbstractPropertyImpl<T>\n implements ReactiveField<T, V>, IsLoadedCachable\n{\n readonly #field: PrimitiveField;\n readonly #reactiveHint: H;\n #loadPromise: any;\n // Initially undefined, then cached as true/false\n #isLoaded: boolean | undefined;\n #isCached: boolean | \"factory-value\" = false;\n\n constructor(\n entity: T,\n field: PrimitiveField,\n reactiveHint: H,\n private fn: (entity: Reacted<T, H>) => V,\n ) {\n super(entity);\n this.#field = field;\n this.#reactiveHint = reactiveHint;\n }\n\n async load(opts?: { forceReload?: boolean }): Promise<V> {\n // Even without `forceReload=true`, any explicit calls to `.load()` ==> ensure a fresh value,\n // because `.get` may have cached the stale/previously-calculated value.\n //\n // (Currently `em.populate` / `populateDataLoader` has a hack/escape hatch that ignores calling\n // RF.load(), to avoid pulling in the RF subgraph over using the materialized value, which ideally would be\n // replaced with us learning to do the maybeDirty approach.)\n if (!this.isLoaded || opts?.forceReload) {\n return (this.#loadPromise ??= this.entity.em.populate(this.entity, { hint: this.loadHint } as any).then(() => {\n this.#loadPromise = undefined;\n this.#isLoaded = true;\n getEmInternalApi(this.entity.em).isLoadedCache.add(this);\n // Wait and reset `#isCached` until inside this `then`, so that we don't have a race condition where:\n // - two relations (us and someone else) are both passed to `em.calc`\n // - their load hint is simpler, so their promises resolves first, and their `.get` calls our `.get`\n // - our `.get` sees we're not loaded, but calls `fieldValue` for the existing value, and dutifully sets `#isCached=true`\n // - finally our promise runs, and if we didn't immediately set `#isCached=false` here, our `.get` would again\n // early return and keep using the stale fieldValue.\n this.resetCacheUnlessFactoryPinned();\n // Go through `this.get` so that `setField` is called to set our latest value\n return this.get;\n }));\n }\n this.resetCacheUnlessFactoryPinned();\n return this.get;\n }\n\n /** Returns either the latest calculated value (if loaded) or the previously-calculated value (if not loaded). */\n get get(): V {\n const { fn } = this;\n // Some ReactiveFields can have surprisingly expensive calculations, especially in loops\n // or those that invoke loops, so cache the value.\n if (this.#isCached) return this.fieldValue;\n // isLoaded will watch for our previously-loaded subgraph being mutated (isLoaded is locally cached but hooked into\n // our IsLoadedCache cache that is immediately invalidated on write-path), and if we've drifted to not-loaded, it's\n // better to fail and tell the user.\n if (this.isLoaded) {\n const newValue = fn(this.entity as Reacted<T, H>);\n if (!getEmInternalApi(this.entity.em).isValidating) {\n // setField will immediately invalidate downstream #isLoaded/#isCached values\n setField(this.entity, this.fieldName, newValue);\n this.#isCached = true;\n getEmInternalApi(this.entity.em).isLoadedCache.add(this);\n }\n return newValue;\n } else if (this.isSet) {\n this.#isCached = true;\n getEmInternalApi(this.entity.em).isLoadedCache.add(this);\n return this.fieldValue;\n } else {\n throw new Error(`${this.fieldName} has not been derived yet`);\n }\n }\n\n get fieldName(): keyof T & string {\n return this.#field.fieldName as keyof T & string;\n }\n\n get reactiveHint(): H {\n return this.#reactiveHint;\n }\n\n get fieldValue(): V {\n return getField(this.entity, this.fieldName);\n }\n\n get isSet() {\n return isFieldSet(this.entity, this.fieldName);\n }\n\n get isLoaded() {\n // Skip an expensive isLoaded(subgraph) call if no mutations have happened\n if (this.#isLoaded !== undefined) return this.#isLoaded;\n this.#isLoaded = isLoaded(this.entity, this.loadHint);\n getEmInternalApi(this.entity.em).isLoadedCache.add(this);\n return this.#isLoaded;\n }\n\n resetIsLoaded(): void {\n // Even though we reset this on every mutation, `isLoaded` will still realize when the subgraph\n // is still loaded (as it did before we added caching), so users won't see false positive.\n this.#isLoaded = undefined;\n this.resetCacheUnlessFactoryPinned();\n }\n\n get loadHint(): any {\n const meta = getMetadata(this.entity);\n return (meta.config.__data.cachedReactiveLoadHints[this.fieldName] ??= convertToLoadHint(meta, this.reactiveHint));\n }\n\n setFactoryValue(newValue: any): void {\n setField(this.entity, this.fieldName, newValue);\n this.#isCached = \"factory-value\";\n }\n\n [PropertyT] = undefined as any as T;\n\n private resetCacheUnlessFactoryPinned(): void {\n // If factories asked for a hard-coded value, don't reset the cached flag\n if (this.#isCached === \"factory-value\") return;\n this.#isCached = false;\n }\n}\n\n/** Type guard utility for determining if an entity field is a ReactiveField. */\nexport function isReactiveField(maybeReactiveField: any): maybeReactiveField is ReactiveField<any, any> {\n return maybeReactiveField instanceof ReactiveFieldImpl;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAoEA,SAAgB,iBACd,MACA,IACqB;CACrB,OAAOA,kBAAAA,WAAW,QAAW,cAAc;EACzC,MAAM,QAAQC,uBAAAA,YAAY,MAAM,CAAC,CAAC,UAAU;EAC5C,OAAO,IAAI,kBAAkB,QAAQ,OAAO,MAAM,EAAE;CACtD,CAAC;AACH;AAEA,IAAa,oBAAb,cACUC,uCAAAA,qBAEV;CAYY;CAXV;CACA;CACA;CAEA;CACA,YAAuC;CAEvC,YACE,QACA,OACA,cACA,IACA;EACA,MAAM,MAAM;EAFJ,KAAA,KAAA;EAGR,KAAKC,SAAS;EACd,KAAKC,gBAAgB;CACvB;CAEA,MAAM,KAAK,MAA8C;EAOvD,IAAI,CAAC,KAAK,YAAY,MAAM,aAC1B,OAAQ,KAAKC,iBAAiB,KAAK,OAAO,GAAG,SAAS,KAAK,QAAQ,EAAE,MAAM,KAAK,SAAS,CAAQ,CAAC,CAAC,WAAW;GAC5G,KAAKA,eAAe,KAAA;GACpB,KAAKC,YAAY;GACjB,sBAAA,iBAAiB,KAAK,OAAO,EAAE,CAAC,CAAC,cAAc,IAAI,IAAI;GAOvD,KAAK,8BAA8B;GAEnC,OAAO,KAAK;EACd,CAAC;EAEH,KAAK,8BAA8B;EACnC,OAAO,KAAK;CACd;;CAGA,IAAI,MAAS;EACX,MAAM,EAAE,OAAO;EAGf,IAAI,KAAKC,WAAW,OAAO,KAAK;EAIhC,IAAI,KAAK,UAAU;GACjB,MAAM,WAAW,GAAG,KAAK,MAAuB;GAChD,IAAI,CAACC,sBAAAA,iBAAiB,KAAK,OAAO,EAAE,CAAC,CAAC,cAAc;IAElD,eAAA,SAAS,KAAK,QAAQ,KAAK,WAAW,QAAQ;IAC9C,KAAKD,YAAY;IACjB,sBAAA,iBAAiB,KAAK,OAAO,EAAE,CAAC,CAAC,cAAc,IAAI,IAAI;GACzD;GACA,OAAO;EACT,OAAO,IAAI,KAAK,OAAO;GACrB,KAAKA,YAAY;GACjB,sBAAA,iBAAiB,KAAK,OAAO,EAAE,CAAC,CAAC,cAAc,IAAI,IAAI;GACvD,OAAO,KAAK;EACd,OACE,MAAM,IAAI,MAAM,GAAG,KAAK,UAAU,0BAA0B;CAEhE;CAEA,IAAI,YAA8B;EAChC,OAAO,KAAKJ,OAAO;CACrB;CAEA,IAAI,eAAkB;EACpB,OAAO,KAAKC;CACd;CAEA,IAAI,aAAgB;EAClB,OAAOK,eAAAA,SAAS,KAAK,QAAQ,KAAK,SAAS;CAC7C;CAEA,IAAI,QAAQ;EACV,OAAOC,eAAAA,WAAW,KAAK,QAAQ,KAAK,SAAS;CAC/C;CAEA,IAAI,WAAW;EAEb,IAAI,KAAKJ,cAAc,KAAA,GAAW,OAAO,KAAKA;EAC9C,KAAKA,YAAYK,0BAAAA,SAAS,KAAK,QAAQ,KAAK,QAAQ;EACpD,sBAAA,iBAAiB,KAAK,OAAO,EAAE,CAAC,CAAC,cAAc,IAAI,IAAI;EACvD,OAAO,KAAKL;CACd;CAEA,gBAAsB;EAGpB,KAAKA,YAAY,KAAA;EACjB,KAAK,8BAA8B;CACrC;CAEA,IAAI,WAAgB;EAClB,MAAM,OAAOL,uBAAAA,YAAY,KAAK,MAAM;EACpC,OAAQ,KAAK,OAAO,OAAO,wBAAwB,KAAK,eAAeW,iCAAAA,kBAAkB,MAAM,KAAK,YAAY;CAClH;CAEA,gBAAgB,UAAqB;EACnC,eAAA,SAAS,KAAK,QAAQ,KAAK,WAAW,QAAQ;EAC9C,KAAKL,YAAY;CACnB;CAEA,CAACM,kCAAAA,aAAa,KAAA;CAEd,gCAA8C;EAE5C,IAAI,KAAKN,cAAc,iBAAiB;EACxC,KAAKA,YAAY;CACnB;AACF;;AAGA,SAAgB,gBAAgB,oBAAwE;CACtG,OAAO,8BAA8B;AACvC"}
@@ -1,7 +1,7 @@
1
1
  import { AbstractPropertyImpl } from "./AbstractPropertyImpl.cjs";
2
2
  import { PropertyT } from "./PropertySymbols.cjs";
3
- import { IsLoadedCachable } from "../IsLoadedCache.cjs";
4
- import { Reacted, ReactiveHint } from "../reactiveHints.cjs";
3
+ import { IsLoadedCachable } from "../loading/IsLoadedCache.cjs";
4
+ import { Reacted, ReactiveHint } from "../reactivity/reactiveHints.cjs";
5
5
  import { PrimitiveField } from "../EntityMetadata.cjs";
6
6
  import { Entity } from "../Entity.cjs";
7
7
  //#region src/relations/ReactiveField.d.ts
@@ -1,7 +1,7 @@
1
1
  import { AbstractPropertyImpl } from "./AbstractPropertyImpl.mjs";
2
2
  import { PropertyT } from "./PropertySymbols.mjs";
3
- import { IsLoadedCachable } from "../IsLoadedCache.mjs";
4
- import { Reacted, ReactiveHint } from "../reactiveHints.mjs";
3
+ import { IsLoadedCachable } from "../loading/IsLoadedCache.mjs";
4
+ import { Reacted, ReactiveHint } from "../reactivity/reactiveHints.mjs";
5
5
  import { PrimitiveField } from "../EntityMetadata.mjs";
6
6
  import { Entity } from "../Entity.mjs";
7
7
  //#region src/relations/ReactiveField.d.ts
@@ -1,9 +1,8 @@
1
- import { getField, isFieldSet, setField } from "../fields.js";
2
1
  import { AbstractPropertyImpl } from "./AbstractPropertyImpl.js";
3
2
  import { PropertyT } from "./PropertySymbols.js";
4
- import "../IsLoadedCache.js";
5
- import { convertToLoadHint } from "../reactiveHints.js";
6
- import { isLoaded } from "../loadHints.js";
3
+ import { convertToLoadHint } from "../reactivity/reactiveHints.js";
4
+ import { isLoaded } from "../loading/loadHints.js";
5
+ import { getField, isFieldSet, setField } from "../fields.js";
7
6
  import { lazyField } from "../newEntity.js";
8
7
  import { getMetadata } from "../EntityMetadata.js";
9
8
  import "../index.js";
@@ -1 +1 @@
1
- {"version":3,"file":"ReactiveField.js","names":["#field","#reactiveHint","#loadPromise","#isLoaded","#isCached"],"sources":["../../src/relations/ReactiveField.ts"],"sourcesContent":["import { type Entity } from \"../Entity.ts\";\nimport { getEmInternalApi } from \"../EntityManager.ts\";\nimport { type PrimitiveField, getMetadata } from \"../EntityMetadata.ts\";\nimport { getField, isFieldSet, setField } from \"../fields.ts\";\nimport { isLoaded } from \"../index.ts\";\nimport { type IsLoadedCachable } from \"../IsLoadedCache.ts\";\nimport { lazyField } from \"../newEntity.ts\";\nimport { type Reacted, type ReactiveHint, convertToLoadHint } from \"../reactiveHints.ts\";\nimport { AbstractPropertyImpl } from \"./AbstractPropertyImpl.ts\";\nimport { PropertyT } from \"./PropertySymbols.ts\";\n\n/**\n * A `ReactiveField` is a value that is derived from other entities/values,\n * similar to a `Property`, but it is also persisted in the database.\n *\n * This allows callers (or SQL queries) to access the value without first calling\n * `await load()` on the property.\n *\n * So, unlike `Property`, `.get` is always available; if the property is unloaded,\n * then `.get` will return the last-calculated value, but if the property is loaded,\n * then it will go ahead and invoke function to calculate the latest value (i.e. so\n * that you can observe the latest & greatest value w/o waiting for `em.flush` to\n * re-calc the value while persisting to the database.\n */\nexport interface ReactiveField<T extends Entity, V> {\n [PropertyT]: T;\n isLoaded: boolean;\n isSet: boolean;\n\n /**\n * Calculates the latest derived value.\n *\n * Users are not required to call this method explicitly, as Joist will keep the\n * persisted value automatically in-sync, but if for some reason (code changes,\n * bug fixes, etc.) you need to trigger an explicit recalc, you can call `.load()`,\n * any dependent data will be loaded from the database, and the latest value\n * returned, and then later stored to the database on `em.flush`.\n *\n * Note that persisted properties used in load hints, i.e. `em.populate`s that\n * accidentally list reactive fields (instead of just relations) will not have\n * `.load()` invoked, and will instead use the previously-calculated value.\n * The rationale is that one persisted property should be able to declare its\n * dependency on another persisted property (for its reactive field-level hint)\n * without causing that dependent property's populate hint to itself be loaded.\n */\n load(opts?: { forceReload?: boolean }): Promise<V>;\n\n /** If loaded, returns the latest derived value, or if unload returns the previously-calculated value. */\n get: V;\n\n /**\n * Returns the as-of-last-flush previously-calculated value.\n *\n * This is useful if you have to purposefully avoid using the lambda to calc the latest value,\n * i.e. if you're in a test and want to watch a calculated value change from some dummy value\n * to the new derived value.\n * */\n fieldValue: V;\n}\n\n/**\n * Creates a calculated derived value from a load hint + lambda.\n *\n * The property can be accessed by default as a promise, with `someProperty.load()`.\n *\n * But if `someProperty` is used as a populate hint, then it can be accessed synchronously,\n * with `someProperty.get`.\n */\nexport function hasReactiveField<T extends Entity, const H extends ReactiveHint<T>, V>(\n hint: H,\n fn: (entity: Reacted<T, H>) => V,\n): ReactiveField<T, V> {\n return lazyField((entity: T, fieldName) => {\n const field = getMetadata(entity).allFields[fieldName] as PrimitiveField;\n return new ReactiveFieldImpl(entity, field, hint, fn);\n });\n}\n\nexport class ReactiveFieldImpl<T extends Entity, H extends ReactiveHint<T>, V>\n extends AbstractPropertyImpl<T>\n implements ReactiveField<T, V>, IsLoadedCachable\n{\n readonly #field: PrimitiveField;\n readonly #reactiveHint: H;\n #loadPromise: any;\n // Initially undefined, then cached as true/false\n #isLoaded: boolean | undefined;\n #isCached: boolean | \"factory-value\" = false;\n\n constructor(\n entity: T,\n field: PrimitiveField,\n reactiveHint: H,\n private fn: (entity: Reacted<T, H>) => V,\n ) {\n super(entity);\n this.#field = field;\n this.#reactiveHint = reactiveHint;\n }\n\n async load(opts?: { forceReload?: boolean }): Promise<V> {\n // Even without `forceReload=true`, any explicit calls to `.load()` ==> ensure a fresh value,\n // because `.get` may have cached the stale/previously-calculated value.\n //\n // (Currently `em.populate` / `populateDataLoader` has a hack/escape hatch that ignores calling\n // RF.load(), to avoid pulling in the RF subgraph over using the materialized value, which ideally would be\n // replaced with us learning to do the maybeDirty approach.)\n if (!this.isLoaded || opts?.forceReload) {\n return (this.#loadPromise ??= this.entity.em.populate(this.entity, { hint: this.loadHint } as any).then(() => {\n this.#loadPromise = undefined;\n this.#isLoaded = true;\n getEmInternalApi(this.entity.em).isLoadedCache.add(this);\n // Wait and reset `#isCached` until inside this `then`, so that we don't have a race condition where:\n // - two relations (us and someone else) are both passed to `em.calc`\n // - their load hint is simpler, so their promises resolves first, and their `.get` calls our `.get`\n // - our `.get` sees we're not loaded, but calls `fieldValue` for the existing value, and dutifully sets `#isCached=true`\n // - finally our promise runs, and if we didn't immediately set `#isCached=false` here, our `.get` would again\n // early return and keep using the stale fieldValue.\n this.resetCacheUnlessFactoryPinned();\n // Go through `this.get` so that `setField` is called to set our latest value\n return this.get;\n }));\n }\n this.resetCacheUnlessFactoryPinned();\n return this.get;\n }\n\n /** Returns either the latest calculated value (if loaded) or the previously-calculated value (if not loaded). */\n get get(): V {\n const { fn } = this;\n // Some ReactiveFields can have surprisingly expensive calculations, especially in loops\n // or those that invoke loops, so cache the value.\n if (this.#isCached) return this.fieldValue;\n // isLoaded will watch for our previously-loaded subgraph being mutated (isLoaded is locally cached but hooked into\n // our IsLoadedCache cache that is immediately invalidated on write-path), and if we've drifted to not-loaded, it's\n // better to fail and tell the user.\n if (this.isLoaded) {\n const newValue = fn(this.entity as Reacted<T, H>);\n if (!getEmInternalApi(this.entity.em).isValidating) {\n // setField will immediately invalidate downstream #isLoaded/#isCached values\n setField(this.entity, this.fieldName, newValue);\n this.#isCached = true;\n getEmInternalApi(this.entity.em).isLoadedCache.add(this);\n }\n return newValue;\n } else if (this.isSet) {\n this.#isCached = true;\n getEmInternalApi(this.entity.em).isLoadedCache.add(this);\n return this.fieldValue;\n } else {\n throw new Error(`${this.fieldName} has not been derived yet`);\n }\n }\n\n get fieldName(): keyof T & string {\n return this.#field.fieldName as keyof T & string;\n }\n\n get reactiveHint(): H {\n return this.#reactiveHint;\n }\n\n get fieldValue(): V {\n return getField(this.entity, this.fieldName);\n }\n\n get isSet() {\n return isFieldSet(this.entity, this.fieldName);\n }\n\n get isLoaded() {\n // Skip an expensive isLoaded(subgraph) call if no mutations have happened\n if (this.#isLoaded !== undefined) return this.#isLoaded;\n this.#isLoaded = isLoaded(this.entity, this.loadHint);\n getEmInternalApi(this.entity.em).isLoadedCache.add(this);\n return this.#isLoaded;\n }\n\n resetIsLoaded(): void {\n // Even though we reset this on every mutation, `isLoaded` will still realize when the subgraph\n // is still loaded (as it did before we added caching), so users won't see false positive.\n this.#isLoaded = undefined;\n this.resetCacheUnlessFactoryPinned();\n }\n\n get loadHint(): any {\n const meta = getMetadata(this.entity);\n return (meta.config.__data.cachedReactiveLoadHints[this.fieldName] ??= convertToLoadHint(meta, this.reactiveHint));\n }\n\n setFactoryValue(newValue: any): void {\n setField(this.entity, this.fieldName, newValue);\n this.#isCached = \"factory-value\";\n }\n\n [PropertyT] = undefined as any as T;\n\n private resetCacheUnlessFactoryPinned(): void {\n // If factories asked for a hard-coded value, don't reset the cached flag\n if (this.#isCached === \"factory-value\") return;\n this.#isCached = false;\n }\n}\n\n/** Type guard utility for determining if an entity field is a ReactiveField. */\nexport function isReactiveField(maybeReactiveField: any): maybeReactiveField is ReactiveField<any, any> {\n return maybeReactiveField instanceof ReactiveFieldImpl;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAoEA,SAAgB,iBACd,MACA,IACqB;CACrB,OAAO,WAAW,QAAW,cAAc;EACzC,MAAM,QAAQ,YAAY,MAAM,CAAC,CAAC,UAAU;EAC5C,OAAO,IAAI,kBAAkB,QAAQ,OAAO,MAAM,EAAE;CACtD,CAAC;AACH;AAEA,IAAa,oBAAb,cACU,qBAEV;CAYY;CAXV;CACA;CACA;CAEA;CACA,YAAuC;CAEvC,YACE,QACA,OACA,cACA,IACA;EACA,MAAM,MAAM;EAFJ,KAAA,KAAA;EAGR,KAAKA,SAAS;EACd,KAAKC,gBAAgB;CACvB;CAEA,MAAM,KAAK,MAA8C;EAOvD,IAAI,CAAC,KAAK,YAAY,MAAM,aAC1B,OAAQ,KAAKC,iBAAiB,KAAK,OAAO,GAAG,SAAS,KAAK,QAAQ,EAAE,MAAM,KAAK,SAAS,CAAQ,CAAC,CAAC,WAAW;GAC5G,KAAKA,eAAe,KAAA;GACpB,KAAKC,YAAY;GACjB,iBAAiB,KAAK,OAAO,EAAE,CAAC,CAAC,cAAc,IAAI,IAAI;GAOvD,KAAK,8BAA8B;GAEnC,OAAO,KAAK;EACd,CAAC;EAEH,KAAK,8BAA8B;EACnC,OAAO,KAAK;CACd;;CAGA,IAAI,MAAS;EACX,MAAM,EAAE,OAAO;EAGf,IAAI,KAAKC,WAAW,OAAO,KAAK;EAIhC,IAAI,KAAK,UAAU;GACjB,MAAM,WAAW,GAAG,KAAK,MAAuB;GAChD,IAAI,CAAC,iBAAiB,KAAK,OAAO,EAAE,CAAC,CAAC,cAAc;IAElD,SAAS,KAAK,QAAQ,KAAK,WAAW,QAAQ;IAC9C,KAAKA,YAAY;IACjB,iBAAiB,KAAK,OAAO,EAAE,CAAC,CAAC,cAAc,IAAI,IAAI;GACzD;GACA,OAAO;EACT,OAAO,IAAI,KAAK,OAAO;GACrB,KAAKA,YAAY;GACjB,iBAAiB,KAAK,OAAO,EAAE,CAAC,CAAC,cAAc,IAAI,IAAI;GACvD,OAAO,KAAK;EACd,OACE,MAAM,IAAI,MAAM,GAAG,KAAK,UAAU,0BAA0B;CAEhE;CAEA,IAAI,YAA8B;EAChC,OAAO,KAAKJ,OAAO;CACrB;CAEA,IAAI,eAAkB;EACpB,OAAO,KAAKC;CACd;CAEA,IAAI,aAAgB;EAClB,OAAO,SAAS,KAAK,QAAQ,KAAK,SAAS;CAC7C;CAEA,IAAI,QAAQ;EACV,OAAO,WAAW,KAAK,QAAQ,KAAK,SAAS;CAC/C;CAEA,IAAI,WAAW;EAEb,IAAI,KAAKE,cAAc,KAAA,GAAW,OAAO,KAAKA;EAC9C,KAAKA,YAAY,SAAS,KAAK,QAAQ,KAAK,QAAQ;EACpD,iBAAiB,KAAK,OAAO,EAAE,CAAC,CAAC,cAAc,IAAI,IAAI;EACvD,OAAO,KAAKA;CACd;CAEA,gBAAsB;EAGpB,KAAKA,YAAY,KAAA;EACjB,KAAK,8BAA8B;CACrC;CAEA,IAAI,WAAgB;EAClB,MAAM,OAAO,YAAY,KAAK,MAAM;EACpC,OAAQ,KAAK,OAAO,OAAO,wBAAwB,KAAK,eAAe,kBAAkB,MAAM,KAAK,YAAY;CAClH;CAEA,gBAAgB,UAAqB;EACnC,SAAS,KAAK,QAAQ,KAAK,WAAW,QAAQ;EAC9C,KAAKC,YAAY;CACnB;CAEA,CAAC,aAAa,KAAA;CAEd,gCAA8C;EAE5C,IAAI,KAAKA,cAAc,iBAAiB;EACxC,KAAKA,YAAY;CACnB;AACF;;AAGA,SAAgB,gBAAgB,oBAAwE;CACtG,OAAO,8BAA8B;AACvC"}
1
+ {"version":3,"file":"ReactiveField.js","names":["#field","#reactiveHint","#loadPromise","#isLoaded","#isCached"],"sources":["../../src/relations/ReactiveField.ts"],"sourcesContent":["import { type Entity } from \"../Entity.ts\";\nimport { getEmInternalApi } from \"../EntityManager.ts\";\nimport { type PrimitiveField, getMetadata } from \"../EntityMetadata.ts\";\nimport { getField, isFieldSet, setField } from \"../fields.ts\";\nimport { isLoaded } from \"../index.ts\";\nimport type { IsLoadedCachable } from \"../loading/IsLoadedCache.ts\";\nimport { lazyField } from \"../newEntity.ts\";\nimport { type Reacted, type ReactiveHint, convertToLoadHint } from \"../reactivity/reactiveHints.ts\";\nimport { AbstractPropertyImpl } from \"./AbstractPropertyImpl.ts\";\nimport { PropertyT } from \"./PropertySymbols.ts\";\n\n/**\n * A `ReactiveField` is a value that is derived from other entities/values,\n * similar to a `Property`, but it is also persisted in the database.\n *\n * This allows callers (or SQL queries) to access the value without first calling\n * `await load()` on the property.\n *\n * So, unlike `Property`, `.get` is always available; if the property is unloaded,\n * then `.get` will return the last-calculated value, but if the property is loaded,\n * then it will go ahead and invoke function to calculate the latest value (i.e. so\n * that you can observe the latest & greatest value w/o waiting for `em.flush` to\n * re-calc the value while persisting to the database.\n */\nexport interface ReactiveField<T extends Entity, V> {\n [PropertyT]: T;\n isLoaded: boolean;\n isSet: boolean;\n\n /**\n * Calculates the latest derived value.\n *\n * Users are not required to call this method explicitly, as Joist will keep the\n * persisted value automatically in-sync, but if for some reason (code changes,\n * bug fixes, etc.) you need to trigger an explicit recalc, you can call `.load()`,\n * any dependent data will be loaded from the database, and the latest value\n * returned, and then later stored to the database on `em.flush`.\n *\n * Note that persisted properties used in load hints, i.e. `em.populate`s that\n * accidentally list reactive fields (instead of just relations) will not have\n * `.load()` invoked, and will instead use the previously-calculated value.\n * The rationale is that one persisted property should be able to declare its\n * dependency on another persisted property (for its reactive field-level hint)\n * without causing that dependent property's populate hint to itself be loaded.\n */\n load(opts?: { forceReload?: boolean }): Promise<V>;\n\n /** If loaded, returns the latest derived value, or if unload returns the previously-calculated value. */\n get: V;\n\n /**\n * Returns the as-of-last-flush previously-calculated value.\n *\n * This is useful if you have to purposefully avoid using the lambda to calc the latest value,\n * i.e. if you're in a test and want to watch a calculated value change from some dummy value\n * to the new derived value.\n * */\n fieldValue: V;\n}\n\n/**\n * Creates a calculated derived value from a load hint + lambda.\n *\n * The property can be accessed by default as a promise, with `someProperty.load()`.\n *\n * But if `someProperty` is used as a populate hint, then it can be accessed synchronously,\n * with `someProperty.get`.\n */\nexport function hasReactiveField<T extends Entity, const H extends ReactiveHint<T>, V>(\n hint: H,\n fn: (entity: Reacted<T, H>) => V,\n): ReactiveField<T, V> {\n return lazyField((entity: T, fieldName) => {\n const field = getMetadata(entity).allFields[fieldName] as PrimitiveField;\n return new ReactiveFieldImpl(entity, field, hint, fn);\n });\n}\n\nexport class ReactiveFieldImpl<T extends Entity, H extends ReactiveHint<T>, V>\n extends AbstractPropertyImpl<T>\n implements ReactiveField<T, V>, IsLoadedCachable\n{\n readonly #field: PrimitiveField;\n readonly #reactiveHint: H;\n #loadPromise: any;\n // Initially undefined, then cached as true/false\n #isLoaded: boolean | undefined;\n #isCached: boolean | \"factory-value\" = false;\n\n constructor(\n entity: T,\n field: PrimitiveField,\n reactiveHint: H,\n private fn: (entity: Reacted<T, H>) => V,\n ) {\n super(entity);\n this.#field = field;\n this.#reactiveHint = reactiveHint;\n }\n\n async load(opts?: { forceReload?: boolean }): Promise<V> {\n // Even without `forceReload=true`, any explicit calls to `.load()` ==> ensure a fresh value,\n // because `.get` may have cached the stale/previously-calculated value.\n //\n // (Currently `em.populate` / `populateDataLoader` has a hack/escape hatch that ignores calling\n // RF.load(), to avoid pulling in the RF subgraph over using the materialized value, which ideally would be\n // replaced with us learning to do the maybeDirty approach.)\n if (!this.isLoaded || opts?.forceReload) {\n return (this.#loadPromise ??= this.entity.em.populate(this.entity, { hint: this.loadHint } as any).then(() => {\n this.#loadPromise = undefined;\n this.#isLoaded = true;\n getEmInternalApi(this.entity.em).isLoadedCache.add(this);\n // Wait and reset `#isCached` until inside this `then`, so that we don't have a race condition where:\n // - two relations (us and someone else) are both passed to `em.calc`\n // - their load hint is simpler, so their promises resolves first, and their `.get` calls our `.get`\n // - our `.get` sees we're not loaded, but calls `fieldValue` for the existing value, and dutifully sets `#isCached=true`\n // - finally our promise runs, and if we didn't immediately set `#isCached=false` here, our `.get` would again\n // early return and keep using the stale fieldValue.\n this.resetCacheUnlessFactoryPinned();\n // Go through `this.get` so that `setField` is called to set our latest value\n return this.get;\n }));\n }\n this.resetCacheUnlessFactoryPinned();\n return this.get;\n }\n\n /** Returns either the latest calculated value (if loaded) or the previously-calculated value (if not loaded). */\n get get(): V {\n const { fn } = this;\n // Some ReactiveFields can have surprisingly expensive calculations, especially in loops\n // or those that invoke loops, so cache the value.\n if (this.#isCached) return this.fieldValue;\n // isLoaded will watch for our previously-loaded subgraph being mutated (isLoaded is locally cached but hooked into\n // our IsLoadedCache cache that is immediately invalidated on write-path), and if we've drifted to not-loaded, it's\n // better to fail and tell the user.\n if (this.isLoaded) {\n const newValue = fn(this.entity as Reacted<T, H>);\n if (!getEmInternalApi(this.entity.em).isValidating) {\n // setField will immediately invalidate downstream #isLoaded/#isCached values\n setField(this.entity, this.fieldName, newValue);\n this.#isCached = true;\n getEmInternalApi(this.entity.em).isLoadedCache.add(this);\n }\n return newValue;\n } else if (this.isSet) {\n this.#isCached = true;\n getEmInternalApi(this.entity.em).isLoadedCache.add(this);\n return this.fieldValue;\n } else {\n throw new Error(`${this.fieldName} has not been derived yet`);\n }\n }\n\n get fieldName(): keyof T & string {\n return this.#field.fieldName as keyof T & string;\n }\n\n get reactiveHint(): H {\n return this.#reactiveHint;\n }\n\n get fieldValue(): V {\n return getField(this.entity, this.fieldName);\n }\n\n get isSet() {\n return isFieldSet(this.entity, this.fieldName);\n }\n\n get isLoaded() {\n // Skip an expensive isLoaded(subgraph) call if no mutations have happened\n if (this.#isLoaded !== undefined) return this.#isLoaded;\n this.#isLoaded = isLoaded(this.entity, this.loadHint);\n getEmInternalApi(this.entity.em).isLoadedCache.add(this);\n return this.#isLoaded;\n }\n\n resetIsLoaded(): void {\n // Even though we reset this on every mutation, `isLoaded` will still realize when the subgraph\n // is still loaded (as it did before we added caching), so users won't see false positive.\n this.#isLoaded = undefined;\n this.resetCacheUnlessFactoryPinned();\n }\n\n get loadHint(): any {\n const meta = getMetadata(this.entity);\n return (meta.config.__data.cachedReactiveLoadHints[this.fieldName] ??= convertToLoadHint(meta, this.reactiveHint));\n }\n\n setFactoryValue(newValue: any): void {\n setField(this.entity, this.fieldName, newValue);\n this.#isCached = \"factory-value\";\n }\n\n [PropertyT] = undefined as any as T;\n\n private resetCacheUnlessFactoryPinned(): void {\n // If factories asked for a hard-coded value, don't reset the cached flag\n if (this.#isCached === \"factory-value\") return;\n this.#isCached = false;\n }\n}\n\n/** Type guard utility for determining if an entity field is a ReactiveField. */\nexport function isReactiveField(maybeReactiveField: any): maybeReactiveField is ReactiveField<any, any> {\n return maybeReactiveField instanceof ReactiveFieldImpl;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAoEA,SAAgB,iBACd,MACA,IACqB;CACrB,OAAO,WAAW,QAAW,cAAc;EACzC,MAAM,QAAQ,YAAY,MAAM,CAAC,CAAC,UAAU;EAC5C,OAAO,IAAI,kBAAkB,QAAQ,OAAO,MAAM,EAAE;CACtD,CAAC;AACH;AAEA,IAAa,oBAAb,cACU,qBAEV;CAYY;CAXV;CACA;CACA;CAEA;CACA,YAAuC;CAEvC,YACE,QACA,OACA,cACA,IACA;EACA,MAAM,MAAM;EAFJ,KAAA,KAAA;EAGR,KAAKA,SAAS;EACd,KAAKC,gBAAgB;CACvB;CAEA,MAAM,KAAK,MAA8C;EAOvD,IAAI,CAAC,KAAK,YAAY,MAAM,aAC1B,OAAQ,KAAKC,iBAAiB,KAAK,OAAO,GAAG,SAAS,KAAK,QAAQ,EAAE,MAAM,KAAK,SAAS,CAAQ,CAAC,CAAC,WAAW;GAC5G,KAAKA,eAAe,KAAA;GACpB,KAAKC,YAAY;GACjB,iBAAiB,KAAK,OAAO,EAAE,CAAC,CAAC,cAAc,IAAI,IAAI;GAOvD,KAAK,8BAA8B;GAEnC,OAAO,KAAK;EACd,CAAC;EAEH,KAAK,8BAA8B;EACnC,OAAO,KAAK;CACd;;CAGA,IAAI,MAAS;EACX,MAAM,EAAE,OAAO;EAGf,IAAI,KAAKC,WAAW,OAAO,KAAK;EAIhC,IAAI,KAAK,UAAU;GACjB,MAAM,WAAW,GAAG,KAAK,MAAuB;GAChD,IAAI,CAAC,iBAAiB,KAAK,OAAO,EAAE,CAAC,CAAC,cAAc;IAElD,SAAS,KAAK,QAAQ,KAAK,WAAW,QAAQ;IAC9C,KAAKA,YAAY;IACjB,iBAAiB,KAAK,OAAO,EAAE,CAAC,CAAC,cAAc,IAAI,IAAI;GACzD;GACA,OAAO;EACT,OAAO,IAAI,KAAK,OAAO;GACrB,KAAKA,YAAY;GACjB,iBAAiB,KAAK,OAAO,EAAE,CAAC,CAAC,cAAc,IAAI,IAAI;GACvD,OAAO,KAAK;EACd,OACE,MAAM,IAAI,MAAM,GAAG,KAAK,UAAU,0BAA0B;CAEhE;CAEA,IAAI,YAA8B;EAChC,OAAO,KAAKJ,OAAO;CACrB;CAEA,IAAI,eAAkB;EACpB,OAAO,KAAKC;CACd;CAEA,IAAI,aAAgB;EAClB,OAAO,SAAS,KAAK,QAAQ,KAAK,SAAS;CAC7C;CAEA,IAAI,QAAQ;EACV,OAAO,WAAW,KAAK,QAAQ,KAAK,SAAS;CAC/C;CAEA,IAAI,WAAW;EAEb,IAAI,KAAKE,cAAc,KAAA,GAAW,OAAO,KAAKA;EAC9C,KAAKA,YAAY,SAAS,KAAK,QAAQ,KAAK,QAAQ;EACpD,iBAAiB,KAAK,OAAO,EAAE,CAAC,CAAC,cAAc,IAAI,IAAI;EACvD,OAAO,KAAKA;CACd;CAEA,gBAAsB;EAGpB,KAAKA,YAAY,KAAA;EACjB,KAAK,8BAA8B;CACrC;CAEA,IAAI,WAAgB;EAClB,MAAM,OAAO,YAAY,KAAK,MAAM;EACpC,OAAQ,KAAK,OAAO,OAAO,wBAAwB,KAAK,eAAe,kBAAkB,MAAM,KAAK,YAAY;CAClH;CAEA,gBAAgB,UAAqB;EACnC,SAAS,KAAK,QAAQ,KAAK,WAAW,QAAQ;EAC9C,KAAKC,YAAY;CACnB;CAEA,CAAC,aAAa,KAAA;CAEd,gCAA8C;EAE5C,IAAI,KAAKA,cAAc,iBAAiB;EACxC,KAAKA,YAAY;CACnB;AACF;;AAGA,SAAgB,gBAAgB,oBAAwE;CACtG,OAAO,8BAA8B;AACvC"}
@@ -1,6 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_relations_PropertySymbols = require("./PropertySymbols.cjs");
3
- require("../reactiveHints.cjs");
4
3
  const require_newEntity = require("../newEntity.cjs");
5
4
  require("../Entity.cjs");
6
5
  //#region src/relations/ReactiveGetter.ts
@@ -1 +1 @@
1
- {"version":3,"file":"ReactiveGetter.cjs","names":["lazyField","#entity","#fieldName","#hint","#fn","PropertyT"],"sources":["../../src/relations/ReactiveGetter.ts"],"sourcesContent":["import { type Entity } from \"../Entity.ts\";\nimport { lazyField } from \"../newEntity.ts\";\nimport { type Reacted, type ShallowReactiveHint } from \"../reactiveHints.ts\";\nimport { PropertyT } from \"./PropertySymbols.ts\";\n\n/**\n * A `ReactiveGetter` is a getter that declares what primitive fields it depends on.\n *\n * This is very similar to a `ReactiveProperty`, except because it's limited to\n * only immediate fields on the entity, it can always have `.get` called, and doesn't\n * need to be loaded.\n *\n * The benefit over a pure getter is that `ReactiveGetter` can be used in reactive\n * rules and reactive fields, which would otherwise need to use `fullNonReactiveAccess`\n * to access getter, and risk missing reactivity.\n */\nexport interface ReactiveGetter<T extends Entity, V> {\n [PropertyT]: T;\n get: V;\n}\n\n/** Creates a `ReactiveGetter`, for simple \"getters\" that still trackable for reactivity. */\nexport function hasReactiveGetter<T extends Entity, const H extends ShallowReactiveHint<T>, V>(\n fieldName: keyof T & string,\n hint: H,\n fn: (entity: Reacted<T, H>) => V,\n): ReactiveGetter<T, V> {\n return lazyField((entity: T, fieldName) => {\n return new ReactiveGetterImpl(entity, fieldName as keyof T & string, hint, fn);\n });\n}\n\nexport class ReactiveGetterImpl<T extends Entity, const H extends ShallowReactiveHint<T>, V> implements ReactiveGetter<\n T,\n V\n> {\n readonly #entity: T;\n readonly #fieldName: keyof T & string;\n readonly #hint: H;\n readonly #fn: (entity: Reacted<T, H>) => V;\n\n constructor(entity: T, fieldName: keyof T & string, hint: H, fn: (entity: Reacted<T, H>) => V) {\n this.#entity = entity;\n this.#fieldName = fieldName;\n this.#hint = hint;\n this.#fn = fn;\n }\n\n get get(): V {\n return this.#fn(this.#entity as any);\n }\n\n get reactiveHint(): H {\n return this.#hint;\n }\n\n [PropertyT] = undefined as any as T;\n}\n\n/** Type guard utility for determining if an entity field is a ReactiveGetter. */\nexport function isReactiveGetter(maybeReactiveGetter: any): maybeReactiveGetter is ReactiveGetter<any, any> {\n return maybeReactiveGetter instanceof ReactiveGetterImpl;\n}\n"],"mappings":";;;;;;;AAsBA,SAAgB,kBACd,WACA,MACA,IACsB;CACtB,OAAOA,kBAAAA,WAAW,QAAW,cAAc;EACzC,OAAO,IAAI,mBAAmB,QAAQ,WAA+B,MAAM,EAAE;CAC/E,CAAC;AACH;AAEA,IAAa,qBAAb,MAGE;CACA;CACA;CACA;CACA;CAEA,YAAY,QAAW,WAA6B,MAAS,IAAkC;EAC7F,KAAKC,UAAU;EACf,KAAKC,aAAa;EAClB,KAAKC,QAAQ;EACb,KAAKC,MAAM;CACb;CAEA,IAAI,MAAS;EACX,OAAO,KAAKA,IAAI,KAAKH,OAAc;CACrC;CAEA,IAAI,eAAkB;EACpB,OAAO,KAAKE;CACd;CAEA,CAACE,kCAAAA,aAAa,KAAA;AAChB;;AAGA,SAAgB,iBAAiB,qBAA2E;CAC1G,OAAO,+BAA+B;AACxC"}
1
+ {"version":3,"file":"ReactiveGetter.cjs","names":["lazyField","#entity","#fieldName","#hint","#fn","PropertyT"],"sources":["../../src/relations/ReactiveGetter.ts"],"sourcesContent":["import { type Entity } from \"../Entity.ts\";\nimport { lazyField } from \"../newEntity.ts\";\nimport type { Reacted, ShallowReactiveHint } from \"../reactivity/reactiveHints.ts\";\nimport { PropertyT } from \"./PropertySymbols.ts\";\n\n/**\n * A `ReactiveGetter` is a getter that declares what primitive fields it depends on.\n *\n * This is very similar to a `ReactiveProperty`, except because it's limited to\n * only immediate fields on the entity, it can always have `.get` called, and doesn't\n * need to be loaded.\n *\n * The benefit over a pure getter is that `ReactiveGetter` can be used in reactive\n * rules and reactive fields, which would otherwise need to use `fullNonReactiveAccess`\n * to access getter, and risk missing reactivity.\n */\nexport interface ReactiveGetter<T extends Entity, V> {\n [PropertyT]: T;\n get: V;\n}\n\n/** Creates a `ReactiveGetter`, for simple \"getters\" that still trackable for reactivity. */\nexport function hasReactiveGetter<T extends Entity, const H extends ShallowReactiveHint<T>, V>(\n fieldName: keyof T & string,\n hint: H,\n fn: (entity: Reacted<T, H>) => V,\n): ReactiveGetter<T, V> {\n return lazyField((entity: T, fieldName) => {\n return new ReactiveGetterImpl(entity, fieldName as keyof T & string, hint, fn);\n });\n}\n\nexport class ReactiveGetterImpl<T extends Entity, const H extends ShallowReactiveHint<T>, V> implements ReactiveGetter<\n T,\n V\n> {\n readonly #entity: T;\n readonly #fieldName: keyof T & string;\n readonly #hint: H;\n readonly #fn: (entity: Reacted<T, H>) => V;\n\n constructor(entity: T, fieldName: keyof T & string, hint: H, fn: (entity: Reacted<T, H>) => V) {\n this.#entity = entity;\n this.#fieldName = fieldName;\n this.#hint = hint;\n this.#fn = fn;\n }\n\n get get(): V {\n return this.#fn(this.#entity as any);\n }\n\n get reactiveHint(): H {\n return this.#hint;\n }\n\n [PropertyT] = undefined as any as T;\n}\n\n/** Type guard utility for determining if an entity field is a ReactiveGetter. */\nexport function isReactiveGetter(maybeReactiveGetter: any): maybeReactiveGetter is ReactiveGetter<any, any> {\n return maybeReactiveGetter instanceof ReactiveGetterImpl;\n}\n"],"mappings":";;;;;;AAsBA,SAAgB,kBACd,WACA,MACA,IACsB;CACtB,OAAOA,kBAAAA,WAAW,QAAW,cAAc;EACzC,OAAO,IAAI,mBAAmB,QAAQ,WAA+B,MAAM,EAAE;CAC/E,CAAC;AACH;AAEA,IAAa,qBAAb,MAGE;CACA;CACA;CACA;CACA;CAEA,YAAY,QAAW,WAA6B,MAAS,IAAkC;EAC7F,KAAKC,UAAU;EACf,KAAKC,aAAa;EAClB,KAAKC,QAAQ;EACb,KAAKC,MAAM;CACb;CAEA,IAAI,MAAS;EACX,OAAO,KAAKA,IAAI,KAAKH,OAAc;CACrC;CAEA,IAAI,eAAkB;EACpB,OAAO,KAAKE;CACd;CAEA,CAACE,kCAAAA,aAAa,KAAA;AAChB;;AAGA,SAAgB,iBAAiB,qBAA2E;CAC1G,OAAO,+BAA+B;AACxC"}
@@ -1,5 +1,5 @@
1
1
  import { PropertyT } from "./PropertySymbols.cjs";
2
- import { Reacted, ShallowReactiveHint } from "../reactiveHints.cjs";
2
+ import { Reacted, ShallowReactiveHint } from "../reactivity/reactiveHints.cjs";
3
3
  import { Entity } from "../Entity.cjs";
4
4
  //#region src/relations/ReactiveGetter.d.ts
5
5
  /**
@@ -1,5 +1,5 @@
1
1
  import { PropertyT } from "./PropertySymbols.mjs";
2
- import { Reacted, ShallowReactiveHint } from "../reactiveHints.mjs";
2
+ import { Reacted, ShallowReactiveHint } from "../reactivity/reactiveHints.mjs";
3
3
  import { Entity } from "../Entity.mjs";
4
4
  //#region src/relations/ReactiveGetter.d.ts
5
5
  /**
@@ -1,5 +1,4 @@
1
1
  import { PropertyT } from "./PropertySymbols.js";
2
- import "../reactiveHints.js";
3
2
  import { lazyField } from "../newEntity.js";
4
3
  import "../Entity.js";
5
4
  //#region src/relations/ReactiveGetter.ts
@@ -1 +1 @@
1
- {"version":3,"file":"ReactiveGetter.js","names":["#entity","#fieldName","#hint","#fn"],"sources":["../../src/relations/ReactiveGetter.ts"],"sourcesContent":["import { type Entity } from \"../Entity.ts\";\nimport { lazyField } from \"../newEntity.ts\";\nimport { type Reacted, type ShallowReactiveHint } from \"../reactiveHints.ts\";\nimport { PropertyT } from \"./PropertySymbols.ts\";\n\n/**\n * A `ReactiveGetter` is a getter that declares what primitive fields it depends on.\n *\n * This is very similar to a `ReactiveProperty`, except because it's limited to\n * only immediate fields on the entity, it can always have `.get` called, and doesn't\n * need to be loaded.\n *\n * The benefit over a pure getter is that `ReactiveGetter` can be used in reactive\n * rules and reactive fields, which would otherwise need to use `fullNonReactiveAccess`\n * to access getter, and risk missing reactivity.\n */\nexport interface ReactiveGetter<T extends Entity, V> {\n [PropertyT]: T;\n get: V;\n}\n\n/** Creates a `ReactiveGetter`, for simple \"getters\" that still trackable for reactivity. */\nexport function hasReactiveGetter<T extends Entity, const H extends ShallowReactiveHint<T>, V>(\n fieldName: keyof T & string,\n hint: H,\n fn: (entity: Reacted<T, H>) => V,\n): ReactiveGetter<T, V> {\n return lazyField((entity: T, fieldName) => {\n return new ReactiveGetterImpl(entity, fieldName as keyof T & string, hint, fn);\n });\n}\n\nexport class ReactiveGetterImpl<T extends Entity, const H extends ShallowReactiveHint<T>, V> implements ReactiveGetter<\n T,\n V\n> {\n readonly #entity: T;\n readonly #fieldName: keyof T & string;\n readonly #hint: H;\n readonly #fn: (entity: Reacted<T, H>) => V;\n\n constructor(entity: T, fieldName: keyof T & string, hint: H, fn: (entity: Reacted<T, H>) => V) {\n this.#entity = entity;\n this.#fieldName = fieldName;\n this.#hint = hint;\n this.#fn = fn;\n }\n\n get get(): V {\n return this.#fn(this.#entity as any);\n }\n\n get reactiveHint(): H {\n return this.#hint;\n }\n\n [PropertyT] = undefined as any as T;\n}\n\n/** Type guard utility for determining if an entity field is a ReactiveGetter. */\nexport function isReactiveGetter(maybeReactiveGetter: any): maybeReactiveGetter is ReactiveGetter<any, any> {\n return maybeReactiveGetter instanceof ReactiveGetterImpl;\n}\n"],"mappings":";;;;;;AAsBA,SAAgB,kBACd,WACA,MACA,IACsB;CACtB,OAAO,WAAW,QAAW,cAAc;EACzC,OAAO,IAAI,mBAAmB,QAAQ,WAA+B,MAAM,EAAE;CAC/E,CAAC;AACH;AAEA,IAAa,qBAAb,MAGE;CACA;CACA;CACA;CACA;CAEA,YAAY,QAAW,WAA6B,MAAS,IAAkC;EAC7F,KAAKA,UAAU;EACf,KAAKC,aAAa;EAClB,KAAKC,QAAQ;EACb,KAAKC,MAAM;CACb;CAEA,IAAI,MAAS;EACX,OAAO,KAAKA,IAAI,KAAKH,OAAc;CACrC;CAEA,IAAI,eAAkB;EACpB,OAAO,KAAKE;CACd;CAEA,CAAC,aAAa,KAAA;AAChB;;AAGA,SAAgB,iBAAiB,qBAA2E;CAC1G,OAAO,+BAA+B;AACxC"}
1
+ {"version":3,"file":"ReactiveGetter.js","names":["#entity","#fieldName","#hint","#fn"],"sources":["../../src/relations/ReactiveGetter.ts"],"sourcesContent":["import { type Entity } from \"../Entity.ts\";\nimport { lazyField } from \"../newEntity.ts\";\nimport type { Reacted, ShallowReactiveHint } from \"../reactivity/reactiveHints.ts\";\nimport { PropertyT } from \"./PropertySymbols.ts\";\n\n/**\n * A `ReactiveGetter` is a getter that declares what primitive fields it depends on.\n *\n * This is very similar to a `ReactiveProperty`, except because it's limited to\n * only immediate fields on the entity, it can always have `.get` called, and doesn't\n * need to be loaded.\n *\n * The benefit over a pure getter is that `ReactiveGetter` can be used in reactive\n * rules and reactive fields, which would otherwise need to use `fullNonReactiveAccess`\n * to access getter, and risk missing reactivity.\n */\nexport interface ReactiveGetter<T extends Entity, V> {\n [PropertyT]: T;\n get: V;\n}\n\n/** Creates a `ReactiveGetter`, for simple \"getters\" that still trackable for reactivity. */\nexport function hasReactiveGetter<T extends Entity, const H extends ShallowReactiveHint<T>, V>(\n fieldName: keyof T & string,\n hint: H,\n fn: (entity: Reacted<T, H>) => V,\n): ReactiveGetter<T, V> {\n return lazyField((entity: T, fieldName) => {\n return new ReactiveGetterImpl(entity, fieldName as keyof T & string, hint, fn);\n });\n}\n\nexport class ReactiveGetterImpl<T extends Entity, const H extends ShallowReactiveHint<T>, V> implements ReactiveGetter<\n T,\n V\n> {\n readonly #entity: T;\n readonly #fieldName: keyof T & string;\n readonly #hint: H;\n readonly #fn: (entity: Reacted<T, H>) => V;\n\n constructor(entity: T, fieldName: keyof T & string, hint: H, fn: (entity: Reacted<T, H>) => V) {\n this.#entity = entity;\n this.#fieldName = fieldName;\n this.#hint = hint;\n this.#fn = fn;\n }\n\n get get(): V {\n return this.#fn(this.#entity as any);\n }\n\n get reactiveHint(): H {\n return this.#hint;\n }\n\n [PropertyT] = undefined as any as T;\n}\n\n/** Type guard utility for determining if an entity field is a ReactiveGetter. */\nexport function isReactiveGetter(maybeReactiveGetter: any): maybeReactiveGetter is ReactiveGetter<any, any> {\n return maybeReactiveGetter instanceof ReactiveGetterImpl;\n}\n"],"mappings":";;;;;AAsBA,SAAgB,kBACd,WACA,MACA,IACsB;CACtB,OAAO,WAAW,QAAW,cAAc;EACzC,OAAO,IAAI,mBAAmB,QAAQ,WAA+B,MAAM,EAAE;CAC/E,CAAC;AACH;AAEA,IAAa,qBAAb,MAGE;CACA;CACA;CACA;CACA;CAEA,YAAY,QAAW,WAA6B,MAAS,IAAkC;EAC7F,KAAKA,UAAU;EACf,KAAKC,aAAa;EAClB,KAAKC,QAAQ;EACb,KAAKC,MAAM;CACb;CAEA,IAAI,MAAS;EACX,OAAO,KAAKA,IAAI,KAAKH,OAAc;CACrC;CAEA,IAAI,eAAkB;EACpB,OAAO,KAAKE;CACd;CAEA,CAAC,aAAa,KAAA;AAChB;;AAGA,SAAgB,iBAAiB,qBAA2E;CAC1G,OAAO,+BAA+B;AACxC"}
@@ -1,13 +1,12 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_relations_AbstractRelationImpl = require("./AbstractRelationImpl.cjs");
3
3
  const require_relations_RelationSymbols = require("./RelationSymbols.cjs");
4
+ const require_reactivity_reactiveHints = require("../reactivity/reactiveHints.cjs");
5
+ const require_loading_loadHints = require("../loading/loadHints.cjs");
6
+ const require_batchloaders_manyToManyBatchLoader = require("../batchloaders/manyToManyBatchLoader.cjs");
4
7
  const require_relations_isCascadeDelete = require("./isCascadeDelete.cjs");
5
- require("../IsLoadedCache.cjs");
6
- const require_reactiveHints = require("../reactiveHints.cjs");
7
- const require_loadHints = require("../loadHints.cjs");
8
8
  const require_utils = require("../utils.cjs");
9
9
  const require_newEntity = require("../newEntity.cjs");
10
- const require_batchloaders_manyToManyBatchLoader = require("../batchloaders/manyToManyBatchLoader.cjs");
11
10
  const require_EntityMetadata = require("../EntityMetadata.cjs");
12
11
  const require_index = require("../index.cjs");
13
12
  const require_EntityManager = require("../EntityManager.cjs");
@@ -70,7 +69,7 @@ var ReactiveManyToManyImpl = class extends require_relations_AbstractRelationImp
70
69
  require_EntityManager.getEmInternalApi(this.entity.em).isLoadedCache.add(this);
71
70
  if (require_EntityManager.getEmInternalApi(this.entity.em).rm.isMaybePendingRecalc(this.entity, this.fieldName)) {
72
71
  this.#loadedMode = "full";
73
- this.#isLoaded = require_loadHints.isLoaded(this.entity, this.loadHint);
72
+ this.#isLoaded = require_loading_loadHints.isLoaded(this.entity, this.loadHint);
74
73
  this.#isCached = false;
75
74
  } else this.#isLoaded = !!this.#loadedMode;
76
75
  return this.#isLoaded;
@@ -111,7 +110,7 @@ var ReactiveManyToManyImpl = class extends require_relations_AbstractRelationImp
111
110
  }
112
111
  get loadHint() {
113
112
  const meta = require_EntityMetadata.getMetadata(this.entity);
114
- return meta.config.__data.cachedReactiveLoadHints[this.fieldName] ??= require_reactiveHints.convertToLoadHint(meta, this.reactiveHint);
113
+ return meta.config.__data.cachedReactiveLoadHints[this.fieldName] ??= require_reactivity_reactiveHints.convertToLoadHint(meta, this.reactiveHint);
115
114
  }
116
115
  setFromOpts(_others) {
117
116
  throw new Error(`ReactiveManyToMany ${this.entity}.${this.fieldName} cannot be set via opts`);
@@ -1 +1 @@
1
- {"version":3,"file":"ReactiveManyToMany.cjs","names":["lazyField","getMetadata","AbstractRelationImpl","#field","getEmInternalApi","#isCached","#loadPromise","#loadedMode","#isLoaded","#doGet","#loadFromJoinTable","#loaded","#filterDeleted","isLoaded","#syncJoinTableRows","convertToLoadHint","#isCascadeDelete","getMetadataForField","isCascadeDelete","manyToManyBatchLoader","RelationT","RelationU"],"sources":["../../src/relations/ReactiveManyToMany.ts"],"sourcesContent":["import { manyToManyBatchLoader } from \"../batchloaders/manyToManyBatchLoader.ts\";\nimport {\n type Entity,\n type EntityMetadata,\n type ManyToManyField,\n type ReadOnlyCollection,\n ensureNotDeleted,\n fail,\n getEmInternalApi,\n getInstanceData,\n getMetadata,\n getMetadataForField,\n isLoaded,\n} from \"../index.ts\";\nimport { type IsLoadedCachable } from \"../IsLoadedCache.ts\";\nimport { lazyField } from \"../newEntity.ts\";\nimport { type MaybeReactedEntity, type Reacted, type ReactiveHint, convertToLoadHint } from \"../reactiveHints.ts\";\nimport { AbstractRelationImpl } from \"./AbstractRelationImpl.ts\";\nimport { isCascadeDelete } from \"./isCascadeDelete.ts\";\nimport { RelationT, RelationU } from \"./RelationSymbols.ts\";\n\n/**\n * A reactive, derived many-to-many collection.\n *\n * Similar to `ReactiveReference` but for collections--membership is calculated from a reactive\n * function and persisted to the underlying join table.\n */\nexport interface ReactiveManyToMany<T extends Entity, U extends Entity> extends ReadOnlyCollection<T, U> {\n load(opts?: { withDeleted?: boolean; forceReload?: boolean }): Promise<readonly U[]>;\n}\n\n/** Creates a `ReactiveManyToMany`. */\nexport function hasReactiveManyToMany<T extends Entity, U extends Entity, const H extends ReactiveHint<T>>(\n hint: H,\n fn: (entity: Reacted<T, H>) => readonly MaybeReactedEntity<U>[],\n): ReactiveManyToMany<T, U> {\n return lazyField((entity: T, fieldName) => {\n const m2m = getMetadata(entity).allFields[fieldName] as ManyToManyField;\n return new ReactiveManyToManyImpl<T, U, H>(entity, m2m, hint, fn);\n });\n}\n\n/** Implements ReactiveManyToMany, initially a copy/paste of ReactiveReference but for m2m. */\nexport class ReactiveManyToManyImpl<T extends Entity, U extends Entity, H extends ReactiveHint<T>>\n extends AbstractRelationImpl<T, U[]>\n implements ReactiveManyToMany<T, U>, IsLoadedCachable\n{\n readonly #field: ManyToManyField;\n\n // Could be either the ref-loaded stored array, or full-loaded calculated array\n #loaded: U[] | undefined;\n // In ref-mode, we use our materialized FK value (which might be undefined)\n // If full-mode, we calculate the FK value from the subgraph\n #loadedMode: \"ref\" | \"full\" | undefined = undefined;\n // #isLoaded doesn't necessary care if we're ref-mode or full-mode, it's just\n // whether a caller can call `.get` and not have it blow up.\n #isLoaded: boolean | undefined = undefined;\n #isCached: boolean = false;\n #loadPromise: Promise<ReadonlyArray<U>> | undefined;\n\n constructor(\n entity: T,\n field: ManyToManyField,\n public reactiveHint: H,\n private fn: (entity: Reacted<T, H>) => readonly MaybeReactedEntity<U>[],\n ) {\n super(entity);\n this.#field = field;\n (getInstanceData(entity).relations ??= {})[this.fieldName] = this;\n }\n\n async load(opts?: { withDeleted?: boolean; forceReload?: boolean }): Promise<ReadonlyArray<U>> {\n ensureNotDeleted(this.entity, \"pending\");\n const { loadHint } = this;\n\n if (!this.isLoaded || opts?.forceReload) {\n const { em } = this.entity;\n const maybeDirty = opts?.forceReload || getEmInternalApi(em).rm.isMaybePendingRecalc(this.entity, this.fieldName);\n\n if (maybeDirty) {\n this.#isCached = false;\n return (this.#loadPromise ??= em.populate(this.entity, { hint: loadHint, ...opts }).then(() => {\n this.#loadPromise = undefined;\n this.#loadedMode = \"full\";\n this.#isLoaded = true;\n getEmInternalApi(this.entity.em).isLoadedCache.add(this);\n return this.#doGet(opts);\n }));\n } else {\n // Load from join table (existing materialized state)\n return (this.#loadPromise ??= this.#loadFromJoinTable().then((loaded) => {\n this.#loadPromise = undefined;\n this.#loadedMode = \"ref\";\n this.#isLoaded = true;\n this.#loaded = loaded;\n getEmInternalApi(this.entity.em).isLoadedCache.add(this);\n return this.#filterDeleted(loaded, opts);\n }));\n }\n }\n return this.#doGet(opts);\n }\n\n get isLoaded(): boolean {\n if (this.#isLoaded !== undefined) return this.#isLoaded;\n getEmInternalApi(this.entity.em).isLoadedCache.add(this);\n // If a WIP mutation has marked our field as potentially dirty, we need to be \"full\" loaded\n const maybeDirty = getEmInternalApi(this.entity.em).rm.isMaybePendingRecalc(this.entity, this.fieldName);\n if (maybeDirty) {\n // If we're dirty, only being \"full\" loaded is good enough to recalc\n this.#loadedMode = \"full\";\n this.#isLoaded = isLoaded(this.entity, this.loadHint);\n this.#isCached = false;\n } else {\n // If we've had `.load` called before, assume we're still loaded\n this.#isLoaded = !!this.#loadedMode;\n }\n return this.#isLoaded;\n }\n\n resetIsLoaded(): void {\n this.#isLoaded = undefined;\n this.#isCached = false;\n }\n\n #doGet(opts?: { withDeleted?: boolean }): U[] {\n const { fn } = this;\n ensureNotDeleted(this.entity, \"pending\");\n // Fast pass if we've already calculated this (cache invalidation will happen on\n // any mutation via #resetIsLoaded)..\n if (this.#isCached) {\n return this.#filterDeleted(this.#loaded ?? [], opts) as U[];\n }\n // Call isLoaded to probe the load hint, and get `#isLoaded` set, but still have\n // our `if` check the raw `#isLoaded` to know if we should eval-latest or return `loaded`.\n if (this.isLoaded && this.#loadedMode === \"full\") {\n const newValue = fn(this.entity as any) as unknown as U[];\n // Preserve deleted entities that were in the previous loaded value\n const previousDeleted = (this.#loaded ?? []).filter((e) => e.isDeletedEntity);\n for (const entity of previousDeleted) {\n if (!newValue.includes(entity)) newValue.push(entity);\n }\n if (!getEmInternalApi(this.entity.em).isValidating) {\n this.#syncJoinTableRows(newValue);\n }\n this.#loaded = newValue;\n this.#isCached = true;\n getEmInternalApi(this.entity.em).isLoadedCache.add(this);\n } else if (!!this.#loadedMode) {\n // We're either loadedMode=ref, or loadedMode=full (but not actually fully loaded),\n // but in theory loadedMode only gets set in `.load()`, so we should have #loaded\n // set to some value, even if it's not fully up-to-date.\n this.#isCached = true;\n getEmInternalApi(this.entity.em).isLoadedCache.add(this);\n } else {\n const noun = this.entity.isNewEntity ? \"derived\" : \"loaded\";\n throw new Error(`${this.entity}.${this.fieldName} has not been ${noun} yet`);\n }\n return this.#filterDeleted(this.#loaded ?? [], opts) as U[];\n }\n\n get getWithDeleted(): U[] {\n return this.#doGet({ withDeleted: true });\n }\n\n get get(): U[] {\n return this.#doGet({ withDeleted: false });\n }\n\n set(): void {\n fail(`Cannot set ${this.entity}.${this.fieldName} ReactiveManyToMany directly.`);\n }\n\n get loadHint(): any {\n const meta = getMetadata(this.entity);\n return (meta.config.__data.cachedReactiveLoadHints[this.fieldName] ??= convertToLoadHint(meta, this.reactiveHint));\n }\n\n setFromOpts(_others: U[]): void {\n throw new Error(`ReactiveManyToMany ${this.entity}.${this.fieldName} cannot be set via opts`);\n }\n\n maybeCascadeDelete(): void {\n if (this.#isCascadeDelete) {\n const jr = getEmInternalApi(this.entity.em).joinRows(this);\n (jr.getOthers(this.columnName, this.entity) as U[]).forEach((e) => this.entity.em.delete(e));\n }\n }\n\n async cleanupOnEntityDeleted(): Promise<void> {\n const existing = await this.load({ withDeleted: true });\n const jr = getEmInternalApi(this.entity.em).joinRows(this);\n for (const entity of existing) jr.addRemove(this, this.entity, entity);\n this.#loaded = [];\n this.#isLoaded = false;\n }\n\n // Properties needed for JoinRows/ManyToManyCollection compatibility\n get meta(): EntityMetadata {\n return getMetadataForField(getMetadata(this.entity), this.fieldName);\n }\n\n get fieldName(): string {\n return this.#field.fieldName;\n }\n\n get otherMeta(): EntityMetadata {\n return this.#field.otherMetadata();\n }\n\n get joinTableName(): string {\n return this.#field.joinTableName;\n }\n\n get columnName(): string {\n return this.#field.columnNames[0];\n }\n\n get otherColumnName(): string {\n return this.#field.columnNames[1];\n }\n\n get hasJoinTableId(): boolean {\n return this.#field.hasJoinTableId;\n }\n\n get otherFieldName(): string {\n return this.#field.otherFieldName;\n }\n\n get hasBeenSet(): boolean {\n return true;\n }\n\n get isPreloaded(): boolean {\n return false;\n }\n\n preload(): void {\n // No-op for now - could implement if needed\n }\n\n import(\n other: ReactiveManyToManyImpl<T, U, H>,\n _: unknown,\n mapEntities: (e: U[] | undefined) => U[] | undefined,\n ): void {\n this.#loaded = mapEntities(other.#loaded);\n this.#loadedMode = other.#loadedMode;\n this.#isLoaded = other.#isLoaded ?? false;\n // Don't set `#isCached b/c we're not registering ourselves with `isLoadedCache` yet; let\n // the first caller to `#doGet` do that if needed.\n }\n\n public toString(): string {\n return `ReactiveManyToMany(entity: ${this.entity}, fieldName: ${this.fieldName}, otherMeta: ${this.otherMeta.type})`;\n }\n\n get #isCascadeDelete(): boolean {\n return isCascadeDelete(this, this.#field.fieldName);\n }\n\n async #loadFromJoinTable(): Promise<U[]> {\n const { em } = this.entity;\n const key = `${this.columnName}=${this.entity.id}`;\n // Use the existing m2m loader by creating a compatible collection-like object\n await manyToManyBatchLoader(em, this).load(key);\n return getEmInternalApi(em).joinRows(this).getOthers(this.columnName, this.entity) as U[];\n }\n\n // This is like calling `setField` but for a m2m relation...\n #syncJoinTableRows(newValue: U[]): void {\n const jr = getEmInternalApi(this.entity.em).joinRows(this);\n const newSet = new Set(newValue);\n const oldSet = new Set(jr.getOthers(this.columnName, this.entity) as U[]);\n // Find entities to add (in new but not in old)\n for (const entity of newValue) {\n if (!oldSet.has(entity)) {\n jr.addNew(this, this.entity, entity);\n }\n }\n // Find entities to remove (in old but not in new)\n for (const entity of oldSet) {\n if (!newSet.has(entity)) {\n jr.addRemove(this, this.entity, entity);\n }\n }\n }\n\n #filterDeleted(entities: U[], opts?: { withDeleted?: boolean }): U[] {\n return opts?.withDeleted === true\n ? [...entities]\n : entities.filter((e) => !e.isDeletedEntity && !(e as any).isSoftDeletedEntity);\n }\n\n [RelationT]: T = null!;\n [RelationU]: U = null!;\n}\n\n/** Type guard utility for determining if an entity field is a ReactiveManyToMany. */\nexport function isReactiveManyToMany(\n maybeReactiveManyToMany: any,\n): maybeReactiveManyToMany is ReactiveManyToMany<any, any> {\n return maybeReactiveManyToMany instanceof ReactiveManyToManyImpl;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"ReactiveManyToMany.cjs","names":["lazyField","getMetadata","AbstractRelationImpl","#field","getEmInternalApi","#isCached","#loadPromise","#loadedMode","#isLoaded","#doGet","#loadFromJoinTable","#loaded","#filterDeleted","isLoaded","#syncJoinTableRows","convertToLoadHint","#isCascadeDelete","getMetadataForField","isCascadeDelete","manyToManyBatchLoader","RelationT","RelationU"],"sources":["../../src/relations/ReactiveManyToMany.ts"],"sourcesContent":["import { manyToManyBatchLoader } from \"../batchloaders/manyToManyBatchLoader.ts\";\nimport {\n type Entity,\n type EntityMetadata,\n type ManyToManyField,\n type ReadOnlyCollection,\n ensureNotDeleted,\n fail,\n getEmInternalApi,\n getInstanceData,\n getMetadata,\n getMetadataForField,\n isLoaded,\n} from \"../index.ts\";\nimport type { IsLoadedCachable } from \"../loading/IsLoadedCache.ts\";\nimport { lazyField } from \"../newEntity.ts\";\nimport {\n type MaybeReactedEntity,\n type Reacted,\n type ReactiveHint,\n convertToLoadHint,\n} from \"../reactivity/reactiveHints.ts\";\nimport { AbstractRelationImpl } from \"./AbstractRelationImpl.ts\";\nimport { isCascadeDelete } from \"./isCascadeDelete.ts\";\nimport { RelationT, RelationU } from \"./RelationSymbols.ts\";\n\n/**\n * A reactive, derived many-to-many collection.\n *\n * Similar to `ReactiveReference` but for collections--membership is calculated from a reactive\n * function and persisted to the underlying join table.\n */\nexport interface ReactiveManyToMany<T extends Entity, U extends Entity> extends ReadOnlyCollection<T, U> {\n load(opts?: { withDeleted?: boolean; forceReload?: boolean }): Promise<readonly U[]>;\n}\n\n/** Creates a `ReactiveManyToMany`. */\nexport function hasReactiveManyToMany<T extends Entity, U extends Entity, const H extends ReactiveHint<T>>(\n hint: H,\n fn: (entity: Reacted<T, H>) => readonly MaybeReactedEntity<U>[],\n): ReactiveManyToMany<T, U> {\n return lazyField((entity: T, fieldName) => {\n const m2m = getMetadata(entity).allFields[fieldName] as ManyToManyField;\n return new ReactiveManyToManyImpl<T, U, H>(entity, m2m, hint, fn);\n });\n}\n\n/** Implements ReactiveManyToMany, initially a copy/paste of ReactiveReference but for m2m. */\nexport class ReactiveManyToManyImpl<T extends Entity, U extends Entity, H extends ReactiveHint<T>>\n extends AbstractRelationImpl<T, U[]>\n implements ReactiveManyToMany<T, U>, IsLoadedCachable\n{\n readonly #field: ManyToManyField;\n\n // Could be either the ref-loaded stored array, or full-loaded calculated array\n #loaded: U[] | undefined;\n // In ref-mode, we use our materialized FK value (which might be undefined)\n // If full-mode, we calculate the FK value from the subgraph\n #loadedMode: \"ref\" | \"full\" | undefined = undefined;\n // #isLoaded doesn't necessary care if we're ref-mode or full-mode, it's just\n // whether a caller can call `.get` and not have it blow up.\n #isLoaded: boolean | undefined = undefined;\n #isCached: boolean = false;\n #loadPromise: Promise<ReadonlyArray<U>> | undefined;\n\n constructor(\n entity: T,\n field: ManyToManyField,\n public reactiveHint: H,\n private fn: (entity: Reacted<T, H>) => readonly MaybeReactedEntity<U>[],\n ) {\n super(entity);\n this.#field = field;\n (getInstanceData(entity).relations ??= {})[this.fieldName] = this;\n }\n\n async load(opts?: { withDeleted?: boolean; forceReload?: boolean }): Promise<ReadonlyArray<U>> {\n ensureNotDeleted(this.entity, \"pending\");\n const { loadHint } = this;\n\n if (!this.isLoaded || opts?.forceReload) {\n const { em } = this.entity;\n const maybeDirty = opts?.forceReload || getEmInternalApi(em).rm.isMaybePendingRecalc(this.entity, this.fieldName);\n\n if (maybeDirty) {\n this.#isCached = false;\n return (this.#loadPromise ??= em.populate(this.entity, { hint: loadHint, ...opts }).then(() => {\n this.#loadPromise = undefined;\n this.#loadedMode = \"full\";\n this.#isLoaded = true;\n getEmInternalApi(this.entity.em).isLoadedCache.add(this);\n return this.#doGet(opts);\n }));\n } else {\n // Load from join table (existing materialized state)\n return (this.#loadPromise ??= this.#loadFromJoinTable().then((loaded) => {\n this.#loadPromise = undefined;\n this.#loadedMode = \"ref\";\n this.#isLoaded = true;\n this.#loaded = loaded;\n getEmInternalApi(this.entity.em).isLoadedCache.add(this);\n return this.#filterDeleted(loaded, opts);\n }));\n }\n }\n return this.#doGet(opts);\n }\n\n get isLoaded(): boolean {\n if (this.#isLoaded !== undefined) return this.#isLoaded;\n getEmInternalApi(this.entity.em).isLoadedCache.add(this);\n // If a WIP mutation has marked our field as potentially dirty, we need to be \"full\" loaded\n const maybeDirty = getEmInternalApi(this.entity.em).rm.isMaybePendingRecalc(this.entity, this.fieldName);\n if (maybeDirty) {\n // If we're dirty, only being \"full\" loaded is good enough to recalc\n this.#loadedMode = \"full\";\n this.#isLoaded = isLoaded(this.entity, this.loadHint);\n this.#isCached = false;\n } else {\n // If we've had `.load` called before, assume we're still loaded\n this.#isLoaded = !!this.#loadedMode;\n }\n return this.#isLoaded;\n }\n\n resetIsLoaded(): void {\n this.#isLoaded = undefined;\n this.#isCached = false;\n }\n\n #doGet(opts?: { withDeleted?: boolean }): U[] {\n const { fn } = this;\n ensureNotDeleted(this.entity, \"pending\");\n // Fast pass if we've already calculated this (cache invalidation will happen on\n // any mutation via #resetIsLoaded)..\n if (this.#isCached) {\n return this.#filterDeleted(this.#loaded ?? [], opts) as U[];\n }\n // Call isLoaded to probe the load hint, and get `#isLoaded` set, but still have\n // our `if` check the raw `#isLoaded` to know if we should eval-latest or return `loaded`.\n if (this.isLoaded && this.#loadedMode === \"full\") {\n const newValue = fn(this.entity as any) as unknown as U[];\n // Preserve deleted entities that were in the previous loaded value\n const previousDeleted = (this.#loaded ?? []).filter((e) => e.isDeletedEntity);\n for (const entity of previousDeleted) {\n if (!newValue.includes(entity)) newValue.push(entity);\n }\n if (!getEmInternalApi(this.entity.em).isValidating) {\n this.#syncJoinTableRows(newValue);\n }\n this.#loaded = newValue;\n this.#isCached = true;\n getEmInternalApi(this.entity.em).isLoadedCache.add(this);\n } else if (!!this.#loadedMode) {\n // We're either loadedMode=ref, or loadedMode=full (but not actually fully loaded),\n // but in theory loadedMode only gets set in `.load()`, so we should have #loaded\n // set to some value, even if it's not fully up-to-date.\n this.#isCached = true;\n getEmInternalApi(this.entity.em).isLoadedCache.add(this);\n } else {\n const noun = this.entity.isNewEntity ? \"derived\" : \"loaded\";\n throw new Error(`${this.entity}.${this.fieldName} has not been ${noun} yet`);\n }\n return this.#filterDeleted(this.#loaded ?? [], opts) as U[];\n }\n\n get getWithDeleted(): U[] {\n return this.#doGet({ withDeleted: true });\n }\n\n get get(): U[] {\n return this.#doGet({ withDeleted: false });\n }\n\n set(): void {\n fail(`Cannot set ${this.entity}.${this.fieldName} ReactiveManyToMany directly.`);\n }\n\n get loadHint(): any {\n const meta = getMetadata(this.entity);\n return (meta.config.__data.cachedReactiveLoadHints[this.fieldName] ??= convertToLoadHint(meta, this.reactiveHint));\n }\n\n setFromOpts(_others: U[]): void {\n throw new Error(`ReactiveManyToMany ${this.entity}.${this.fieldName} cannot be set via opts`);\n }\n\n maybeCascadeDelete(): void {\n if (this.#isCascadeDelete) {\n const jr = getEmInternalApi(this.entity.em).joinRows(this);\n (jr.getOthers(this.columnName, this.entity) as U[]).forEach((e) => this.entity.em.delete(e));\n }\n }\n\n async cleanupOnEntityDeleted(): Promise<void> {\n const existing = await this.load({ withDeleted: true });\n const jr = getEmInternalApi(this.entity.em).joinRows(this);\n for (const entity of existing) jr.addRemove(this, this.entity, entity);\n this.#loaded = [];\n this.#isLoaded = false;\n }\n\n // Properties needed for JoinRows/ManyToManyCollection compatibility\n get meta(): EntityMetadata {\n return getMetadataForField(getMetadata(this.entity), this.fieldName);\n }\n\n get fieldName(): string {\n return this.#field.fieldName;\n }\n\n get otherMeta(): EntityMetadata {\n return this.#field.otherMetadata();\n }\n\n get joinTableName(): string {\n return this.#field.joinTableName;\n }\n\n get columnName(): string {\n return this.#field.columnNames[0];\n }\n\n get otherColumnName(): string {\n return this.#field.columnNames[1];\n }\n\n get hasJoinTableId(): boolean {\n return this.#field.hasJoinTableId;\n }\n\n get otherFieldName(): string {\n return this.#field.otherFieldName;\n }\n\n get hasBeenSet(): boolean {\n return true;\n }\n\n get isPreloaded(): boolean {\n return false;\n }\n\n preload(): void {\n // No-op for now - could implement if needed\n }\n\n import(\n other: ReactiveManyToManyImpl<T, U, H>,\n _: unknown,\n mapEntities: (e: U[] | undefined) => U[] | undefined,\n ): void {\n this.#loaded = mapEntities(other.#loaded);\n this.#loadedMode = other.#loadedMode;\n this.#isLoaded = other.#isLoaded ?? false;\n // Don't set `#isCached b/c we're not registering ourselves with `isLoadedCache` yet; let\n // the first caller to `#doGet` do that if needed.\n }\n\n public toString(): string {\n return `ReactiveManyToMany(entity: ${this.entity}, fieldName: ${this.fieldName}, otherMeta: ${this.otherMeta.type})`;\n }\n\n get #isCascadeDelete(): boolean {\n return isCascadeDelete(this, this.#field.fieldName);\n }\n\n async #loadFromJoinTable(): Promise<U[]> {\n const { em } = this.entity;\n const key = `${this.columnName}=${this.entity.id}`;\n // Use the existing m2m loader by creating a compatible collection-like object\n await manyToManyBatchLoader(em, this).load(key);\n return getEmInternalApi(em).joinRows(this).getOthers(this.columnName, this.entity) as U[];\n }\n\n // This is like calling `setField` but for a m2m relation...\n #syncJoinTableRows(newValue: U[]): void {\n const jr = getEmInternalApi(this.entity.em).joinRows(this);\n const newSet = new Set(newValue);\n const oldSet = new Set(jr.getOthers(this.columnName, this.entity) as U[]);\n // Find entities to add (in new but not in old)\n for (const entity of newValue) {\n if (!oldSet.has(entity)) {\n jr.addNew(this, this.entity, entity);\n }\n }\n // Find entities to remove (in old but not in new)\n for (const entity of oldSet) {\n if (!newSet.has(entity)) {\n jr.addRemove(this, this.entity, entity);\n }\n }\n }\n\n #filterDeleted(entities: U[], opts?: { withDeleted?: boolean }): U[] {\n return opts?.withDeleted === true\n ? [...entities]\n : entities.filter((e) => !e.isDeletedEntity && !(e as any).isSoftDeletedEntity);\n }\n\n [RelationT]: T = null!;\n [RelationU]: U = null!;\n}\n\n/** Type guard utility for determining if an entity field is a ReactiveManyToMany. */\nexport function isReactiveManyToMany(\n maybeReactiveManyToMany: any,\n): maybeReactiveManyToMany is ReactiveManyToMany<any, any> {\n return maybeReactiveManyToMany instanceof ReactiveManyToManyImpl;\n}\n"],"mappings":"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"}
@@ -1,8 +1,8 @@
1
1
  import { AbstractRelationImpl } from "./AbstractRelationImpl.cjs";
2
2
  import { RelationT, RelationU } from "./RelationSymbols.cjs";
3
- import { IsLoadedCachable } from "../IsLoadedCache.cjs";
3
+ import { IsLoadedCachable } from "../loading/IsLoadedCache.cjs";
4
4
  import { ReadOnlyCollection } from "./ReadOnlyCollection.cjs";
5
- import { MaybeReactedEntity, Reacted, ReactiveHint } from "../reactiveHints.cjs";
5
+ import { MaybeReactedEntity, Reacted, ReactiveHint } from "../reactivity/reactiveHints.cjs";
6
6
  import { EntityMetadata, ManyToManyField } from "../EntityMetadata.cjs";
7
7
  import "../index.cjs";
8
8
  import { Entity } from "../Entity.cjs";
@@ -1 +1 @@
1
- {"version":3,"file":"ReactiveManyToMany.d.cts","names":[],"sources":["../../src/relations/ReactiveManyToMany.ts"],"mappings":";;;;;;;;;;;;;;;UA2BiB,mBAAmB,UAAU,QAAQ,UAAU,gBAAgB,mBAAmB,GAAG;EACpG,KAAK;IAAS;IAAuB;MAA0B,iBAAiB;;;iBAIlE,sBAAsB,UAAU,QAAQ,UAAU,cAAc,UAAU,aAAa,IACrG,MAAM,GACN,KAAK,QAAQ,QAAQ,GAAG,gBAAgB,mBAAmB,OAC1D,mBAAmB,GAAG;;cAQZ,uBAAuB,UAAU,QAAQ,UAAU,QAAQ,UAAU,aAAa,YACrF,qBAAqB,GAAG,gBACrB,mBAAmB,GAAG,IAAI;;EAkB5B,cAAc;UACb;EAJV,YACE,QAAQ,GACR,OAAO,iBACA,cAAc,GACb,KAAK,QAAQ,QAAQ,GAAG,gBAAgB,mBAAmB;EAO/D,KAAK;IAAS;IAAuB;MAA0B,QAAQ,cAAc;MAgCvF;EAiBJ;MAyCI,kBAAkB;MAIlB,OAAO;EAIX;MAII;EAKJ,YAAY,SAAS;EAIrB;EAOM,0BAA0B;MAS5B,QAAQ;MAIR;MAIA,aAAa;MAIb;MAIA;MAIA;MAIA;MAIA;MAIA;MAIA;EAIJ;EAIA,OACE,OAAO,uBAAuB,GAAG,GAAG,IACpC,YACA,cAAc,GAAG,oBAAoB;EAShC;GAyCN,YAAY;GACZ,YAAY;;;iBAIC,qBACd,+BACC,2BAA2B"}
1
+ {"version":3,"file":"ReactiveManyToMany.d.cts","names":[],"sources":["../../src/relations/ReactiveManyToMany.ts"],"mappings":";;;;;;;;;;;;;;;UAgCiB,mBAAmB,UAAU,QAAQ,UAAU,gBAAgB,mBAAmB,GAAG;EACpG,KAAK;IAAS;IAAuB;MAA0B,iBAAiB;;;iBAIlE,sBAAsB,UAAU,QAAQ,UAAU,cAAc,UAAU,aAAa,IACrG,MAAM,GACN,KAAK,QAAQ,QAAQ,GAAG,gBAAgB,mBAAmB,OAC1D,mBAAmB,GAAG;;cAQZ,uBAAuB,UAAU,QAAQ,UAAU,QAAQ,UAAU,aAAa,YACrF,qBAAqB,GAAG,gBACrB,mBAAmB,GAAG,IAAI;;EAkB5B,cAAc;UACb;EAJV,YACE,QAAQ,GACR,OAAO,iBACA,cAAc,GACb,KAAK,QAAQ,QAAQ,GAAG,gBAAgB,mBAAmB;EAO/D,KAAK;IAAS;IAAuB;MAA0B,QAAQ,cAAc;MAgCvF;EAiBJ;MAyCI,kBAAkB;MAIlB,OAAO;EAIX;MAII;EAKJ,YAAY,SAAS;EAIrB;EAOM,0BAA0B;MAS5B,QAAQ;MAIR;MAIA,aAAa;MAIb;MAIA;MAIA;MAIA;MAIA;MAIA;MAIA;EAIJ;EAIA,OACE,OAAO,uBAAuB,GAAG,GAAG,IACpC,YACA,cAAc,GAAG,oBAAoB;EAShC;GAyCN,YAAY;GACZ,YAAY;;;iBAIC,qBACd,+BACC,2BAA2B"}
@@ -1,8 +1,8 @@
1
1
  import { AbstractRelationImpl } from "./AbstractRelationImpl.mjs";
2
2
  import { RelationT, RelationU } from "./RelationSymbols.mjs";
3
- import { IsLoadedCachable } from "../IsLoadedCache.mjs";
3
+ import { IsLoadedCachable } from "../loading/IsLoadedCache.mjs";
4
4
  import { ReadOnlyCollection } from "./ReadOnlyCollection.mjs";
5
- import { MaybeReactedEntity, Reacted, ReactiveHint } from "../reactiveHints.mjs";
5
+ import { MaybeReactedEntity, Reacted, ReactiveHint } from "../reactivity/reactiveHints.mjs";
6
6
  import { EntityMetadata, ManyToManyField } from "../EntityMetadata.mjs";
7
7
  import "../index.mjs";
8
8
  import { Entity } from "../Entity.mjs";
@@ -1 +1 @@
1
- {"version":3,"file":"ReactiveManyToMany.d.mts","names":[],"sources":["../../src/relations/ReactiveManyToMany.ts"],"mappings":";;;;;;;;;;;;;;;UA2BiB,mBAAmB,UAAU,QAAQ,UAAU,gBAAgB,mBAAmB,GAAG;EACpG,KAAK;IAAS;IAAuB;MAA0B,iBAAiB;;;iBAIlE,sBAAsB,UAAU,QAAQ,UAAU,cAAc,UAAU,aAAa,IACrG,MAAM,GACN,KAAK,QAAQ,QAAQ,GAAG,gBAAgB,mBAAmB,OAC1D,mBAAmB,GAAG;;cAQZ,uBAAuB,UAAU,QAAQ,UAAU,QAAQ,UAAU,aAAa,YACrF,qBAAqB,GAAG,gBACrB,mBAAmB,GAAG,IAAI;;EAkB5B,cAAc;UACb;EAJV,YACE,QAAQ,GACR,OAAO,iBACA,cAAc,GACb,KAAK,QAAQ,QAAQ,GAAG,gBAAgB,mBAAmB;EAO/D,KAAK;IAAS;IAAuB;MAA0B,QAAQ,cAAc;MAgCvF;EAiBJ;MAyCI,kBAAkB;MAIlB,OAAO;EAIX;MAII;EAKJ,YAAY,SAAS;EAIrB;EAOM,0BAA0B;MAS5B,QAAQ;MAIR;MAIA,aAAa;MAIb;MAIA;MAIA;MAIA;MAIA;MAIA;MAIA;EAIJ;EAIA,OACE,OAAO,uBAAuB,GAAG,GAAG,IACpC,YACA,cAAc,GAAG,oBAAoB;EAShC;GAyCN,YAAY;GACZ,YAAY;;;iBAIC,qBACd,+BACC,2BAA2B"}
1
+ {"version":3,"file":"ReactiveManyToMany.d.mts","names":[],"sources":["../../src/relations/ReactiveManyToMany.ts"],"mappings":";;;;;;;;;;;;;;;UAgCiB,mBAAmB,UAAU,QAAQ,UAAU,gBAAgB,mBAAmB,GAAG;EACpG,KAAK;IAAS;IAAuB;MAA0B,iBAAiB;;;iBAIlE,sBAAsB,UAAU,QAAQ,UAAU,cAAc,UAAU,aAAa,IACrG,MAAM,GACN,KAAK,QAAQ,QAAQ,GAAG,gBAAgB,mBAAmB,OAC1D,mBAAmB,GAAG;;cAQZ,uBAAuB,UAAU,QAAQ,UAAU,QAAQ,UAAU,aAAa,YACrF,qBAAqB,GAAG,gBACrB,mBAAmB,GAAG,IAAI;;EAkB5B,cAAc;UACb;EAJV,YACE,QAAQ,GACR,OAAO,iBACA,cAAc,GACb,KAAK,QAAQ,QAAQ,GAAG,gBAAgB,mBAAmB;EAO/D,KAAK;IAAS;IAAuB;MAA0B,QAAQ,cAAc;MAgCvF;EAiBJ;MAyCI,kBAAkB;MAIlB,OAAO;EAIX;MAII;EAKJ,YAAY,SAAS;EAIrB;EAOM,0BAA0B;MAS5B,QAAQ;MAIR;MAIA,aAAa;MAIb;MAIA;MAIA;MAIA;MAIA;MAIA;MAIA;EAIJ;EAIA,OACE,OAAO,uBAAuB,GAAG,GAAG,IACpC,YACA,cAAc,GAAG,oBAAoB;EAShC;GAyCN,YAAY;GACZ,YAAY;;;iBAIC,qBACd,+BACC,2BAA2B"}
@@ -1,12 +1,11 @@
1
1
  import { AbstractRelationImpl } from "./AbstractRelationImpl.js";
2
2
  import { RelationT, RelationU } from "./RelationSymbols.js";
3
+ import { convertToLoadHint } from "../reactivity/reactiveHints.js";
4
+ import { isLoaded } from "../loading/loadHints.js";
5
+ import { manyToManyBatchLoader } from "../batchloaders/manyToManyBatchLoader.js";
3
6
  import { isCascadeDelete } from "./isCascadeDelete.js";
4
- import "../IsLoadedCache.js";
5
- import { convertToLoadHint } from "../reactiveHints.js";
6
- import { isLoaded } from "../loadHints.js";
7
7
  import { fail } from "../utils.js";
8
8
  import { lazyField } from "../newEntity.js";
9
- import { manyToManyBatchLoader } from "../batchloaders/manyToManyBatchLoader.js";
10
9
  import { getMetadata, getMetadataForField } from "../EntityMetadata.js";
11
10
  import { ensureNotDeleted } from "../index.js";
12
11
  import { getEmInternalApi } from "../EntityManager.js";
@@ -1 +1 @@
1
- {"version":3,"file":"ReactiveManyToMany.js","names":["#field","#isCached","#loadPromise","#loadedMode","#isLoaded","#doGet","#loadFromJoinTable","#loaded","#filterDeleted","#syncJoinTableRows","#isCascadeDelete"],"sources":["../../src/relations/ReactiveManyToMany.ts"],"sourcesContent":["import { manyToManyBatchLoader } from \"../batchloaders/manyToManyBatchLoader.ts\";\nimport {\n type Entity,\n type EntityMetadata,\n type ManyToManyField,\n type ReadOnlyCollection,\n ensureNotDeleted,\n fail,\n getEmInternalApi,\n getInstanceData,\n getMetadata,\n getMetadataForField,\n isLoaded,\n} from \"../index.ts\";\nimport { type IsLoadedCachable } from \"../IsLoadedCache.ts\";\nimport { lazyField } from \"../newEntity.ts\";\nimport { type MaybeReactedEntity, type Reacted, type ReactiveHint, convertToLoadHint } from \"../reactiveHints.ts\";\nimport { AbstractRelationImpl } from \"./AbstractRelationImpl.ts\";\nimport { isCascadeDelete } from \"./isCascadeDelete.ts\";\nimport { RelationT, RelationU } from \"./RelationSymbols.ts\";\n\n/**\n * A reactive, derived many-to-many collection.\n *\n * Similar to `ReactiveReference` but for collections--membership is calculated from a reactive\n * function and persisted to the underlying join table.\n */\nexport interface ReactiveManyToMany<T extends Entity, U extends Entity> extends ReadOnlyCollection<T, U> {\n load(opts?: { withDeleted?: boolean; forceReload?: boolean }): Promise<readonly U[]>;\n}\n\n/** Creates a `ReactiveManyToMany`. */\nexport function hasReactiveManyToMany<T extends Entity, U extends Entity, const H extends ReactiveHint<T>>(\n hint: H,\n fn: (entity: Reacted<T, H>) => readonly MaybeReactedEntity<U>[],\n): ReactiveManyToMany<T, U> {\n return lazyField((entity: T, fieldName) => {\n const m2m = getMetadata(entity).allFields[fieldName] as ManyToManyField;\n return new ReactiveManyToManyImpl<T, U, H>(entity, m2m, hint, fn);\n });\n}\n\n/** Implements ReactiveManyToMany, initially a copy/paste of ReactiveReference but for m2m. */\nexport class ReactiveManyToManyImpl<T extends Entity, U extends Entity, H extends ReactiveHint<T>>\n extends AbstractRelationImpl<T, U[]>\n implements ReactiveManyToMany<T, U>, IsLoadedCachable\n{\n readonly #field: ManyToManyField;\n\n // Could be either the ref-loaded stored array, or full-loaded calculated array\n #loaded: U[] | undefined;\n // In ref-mode, we use our materialized FK value (which might be undefined)\n // If full-mode, we calculate the FK value from the subgraph\n #loadedMode: \"ref\" | \"full\" | undefined = undefined;\n // #isLoaded doesn't necessary care if we're ref-mode or full-mode, it's just\n // whether a caller can call `.get` and not have it blow up.\n #isLoaded: boolean | undefined = undefined;\n #isCached: boolean = false;\n #loadPromise: Promise<ReadonlyArray<U>> | undefined;\n\n constructor(\n entity: T,\n field: ManyToManyField,\n public reactiveHint: H,\n private fn: (entity: Reacted<T, H>) => readonly MaybeReactedEntity<U>[],\n ) {\n super(entity);\n this.#field = field;\n (getInstanceData(entity).relations ??= {})[this.fieldName] = this;\n }\n\n async load(opts?: { withDeleted?: boolean; forceReload?: boolean }): Promise<ReadonlyArray<U>> {\n ensureNotDeleted(this.entity, \"pending\");\n const { loadHint } = this;\n\n if (!this.isLoaded || opts?.forceReload) {\n const { em } = this.entity;\n const maybeDirty = opts?.forceReload || getEmInternalApi(em).rm.isMaybePendingRecalc(this.entity, this.fieldName);\n\n if (maybeDirty) {\n this.#isCached = false;\n return (this.#loadPromise ??= em.populate(this.entity, { hint: loadHint, ...opts }).then(() => {\n this.#loadPromise = undefined;\n this.#loadedMode = \"full\";\n this.#isLoaded = true;\n getEmInternalApi(this.entity.em).isLoadedCache.add(this);\n return this.#doGet(opts);\n }));\n } else {\n // Load from join table (existing materialized state)\n return (this.#loadPromise ??= this.#loadFromJoinTable().then((loaded) => {\n this.#loadPromise = undefined;\n this.#loadedMode = \"ref\";\n this.#isLoaded = true;\n this.#loaded = loaded;\n getEmInternalApi(this.entity.em).isLoadedCache.add(this);\n return this.#filterDeleted(loaded, opts);\n }));\n }\n }\n return this.#doGet(opts);\n }\n\n get isLoaded(): boolean {\n if (this.#isLoaded !== undefined) return this.#isLoaded;\n getEmInternalApi(this.entity.em).isLoadedCache.add(this);\n // If a WIP mutation has marked our field as potentially dirty, we need to be \"full\" loaded\n const maybeDirty = getEmInternalApi(this.entity.em).rm.isMaybePendingRecalc(this.entity, this.fieldName);\n if (maybeDirty) {\n // If we're dirty, only being \"full\" loaded is good enough to recalc\n this.#loadedMode = \"full\";\n this.#isLoaded = isLoaded(this.entity, this.loadHint);\n this.#isCached = false;\n } else {\n // If we've had `.load` called before, assume we're still loaded\n this.#isLoaded = !!this.#loadedMode;\n }\n return this.#isLoaded;\n }\n\n resetIsLoaded(): void {\n this.#isLoaded = undefined;\n this.#isCached = false;\n }\n\n #doGet(opts?: { withDeleted?: boolean }): U[] {\n const { fn } = this;\n ensureNotDeleted(this.entity, \"pending\");\n // Fast pass if we've already calculated this (cache invalidation will happen on\n // any mutation via #resetIsLoaded)..\n if (this.#isCached) {\n return this.#filterDeleted(this.#loaded ?? [], opts) as U[];\n }\n // Call isLoaded to probe the load hint, and get `#isLoaded` set, but still have\n // our `if` check the raw `#isLoaded` to know if we should eval-latest or return `loaded`.\n if (this.isLoaded && this.#loadedMode === \"full\") {\n const newValue = fn(this.entity as any) as unknown as U[];\n // Preserve deleted entities that were in the previous loaded value\n const previousDeleted = (this.#loaded ?? []).filter((e) => e.isDeletedEntity);\n for (const entity of previousDeleted) {\n if (!newValue.includes(entity)) newValue.push(entity);\n }\n if (!getEmInternalApi(this.entity.em).isValidating) {\n this.#syncJoinTableRows(newValue);\n }\n this.#loaded = newValue;\n this.#isCached = true;\n getEmInternalApi(this.entity.em).isLoadedCache.add(this);\n } else if (!!this.#loadedMode) {\n // We're either loadedMode=ref, or loadedMode=full (but not actually fully loaded),\n // but in theory loadedMode only gets set in `.load()`, so we should have #loaded\n // set to some value, even if it's not fully up-to-date.\n this.#isCached = true;\n getEmInternalApi(this.entity.em).isLoadedCache.add(this);\n } else {\n const noun = this.entity.isNewEntity ? \"derived\" : \"loaded\";\n throw new Error(`${this.entity}.${this.fieldName} has not been ${noun} yet`);\n }\n return this.#filterDeleted(this.#loaded ?? [], opts) as U[];\n }\n\n get getWithDeleted(): U[] {\n return this.#doGet({ withDeleted: true });\n }\n\n get get(): U[] {\n return this.#doGet({ withDeleted: false });\n }\n\n set(): void {\n fail(`Cannot set ${this.entity}.${this.fieldName} ReactiveManyToMany directly.`);\n }\n\n get loadHint(): any {\n const meta = getMetadata(this.entity);\n return (meta.config.__data.cachedReactiveLoadHints[this.fieldName] ??= convertToLoadHint(meta, this.reactiveHint));\n }\n\n setFromOpts(_others: U[]): void {\n throw new Error(`ReactiveManyToMany ${this.entity}.${this.fieldName} cannot be set via opts`);\n }\n\n maybeCascadeDelete(): void {\n if (this.#isCascadeDelete) {\n const jr = getEmInternalApi(this.entity.em).joinRows(this);\n (jr.getOthers(this.columnName, this.entity) as U[]).forEach((e) => this.entity.em.delete(e));\n }\n }\n\n async cleanupOnEntityDeleted(): Promise<void> {\n const existing = await this.load({ withDeleted: true });\n const jr = getEmInternalApi(this.entity.em).joinRows(this);\n for (const entity of existing) jr.addRemove(this, this.entity, entity);\n this.#loaded = [];\n this.#isLoaded = false;\n }\n\n // Properties needed for JoinRows/ManyToManyCollection compatibility\n get meta(): EntityMetadata {\n return getMetadataForField(getMetadata(this.entity), this.fieldName);\n }\n\n get fieldName(): string {\n return this.#field.fieldName;\n }\n\n get otherMeta(): EntityMetadata {\n return this.#field.otherMetadata();\n }\n\n get joinTableName(): string {\n return this.#field.joinTableName;\n }\n\n get columnName(): string {\n return this.#field.columnNames[0];\n }\n\n get otherColumnName(): string {\n return this.#field.columnNames[1];\n }\n\n get hasJoinTableId(): boolean {\n return this.#field.hasJoinTableId;\n }\n\n get otherFieldName(): string {\n return this.#field.otherFieldName;\n }\n\n get hasBeenSet(): boolean {\n return true;\n }\n\n get isPreloaded(): boolean {\n return false;\n }\n\n preload(): void {\n // No-op for now - could implement if needed\n }\n\n import(\n other: ReactiveManyToManyImpl<T, U, H>,\n _: unknown,\n mapEntities: (e: U[] | undefined) => U[] | undefined,\n ): void {\n this.#loaded = mapEntities(other.#loaded);\n this.#loadedMode = other.#loadedMode;\n this.#isLoaded = other.#isLoaded ?? false;\n // Don't set `#isCached b/c we're not registering ourselves with `isLoadedCache` yet; let\n // the first caller to `#doGet` do that if needed.\n }\n\n public toString(): string {\n return `ReactiveManyToMany(entity: ${this.entity}, fieldName: ${this.fieldName}, otherMeta: ${this.otherMeta.type})`;\n }\n\n get #isCascadeDelete(): boolean {\n return isCascadeDelete(this, this.#field.fieldName);\n }\n\n async #loadFromJoinTable(): Promise<U[]> {\n const { em } = this.entity;\n const key = `${this.columnName}=${this.entity.id}`;\n // Use the existing m2m loader by creating a compatible collection-like object\n await manyToManyBatchLoader(em, this).load(key);\n return getEmInternalApi(em).joinRows(this).getOthers(this.columnName, this.entity) as U[];\n }\n\n // This is like calling `setField` but for a m2m relation...\n #syncJoinTableRows(newValue: U[]): void {\n const jr = getEmInternalApi(this.entity.em).joinRows(this);\n const newSet = new Set(newValue);\n const oldSet = new Set(jr.getOthers(this.columnName, this.entity) as U[]);\n // Find entities to add (in new but not in old)\n for (const entity of newValue) {\n if (!oldSet.has(entity)) {\n jr.addNew(this, this.entity, entity);\n }\n }\n // Find entities to remove (in old but not in new)\n for (const entity of oldSet) {\n if (!newSet.has(entity)) {\n jr.addRemove(this, this.entity, entity);\n }\n }\n }\n\n #filterDeleted(entities: U[], opts?: { withDeleted?: boolean }): U[] {\n return opts?.withDeleted === true\n ? [...entities]\n : entities.filter((e) => !e.isDeletedEntity && !(e as any).isSoftDeletedEntity);\n }\n\n [RelationT]: T = null!;\n [RelationU]: U = null!;\n}\n\n/** Type guard utility for determining if an entity field is a ReactiveManyToMany. */\nexport function isReactiveManyToMany(\n maybeReactiveManyToMany: any,\n): maybeReactiveManyToMany is ReactiveManyToMany<any, any> {\n return maybeReactiveManyToMany instanceof ReactiveManyToManyImpl;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"ReactiveManyToMany.js","names":["#field","#isCached","#loadPromise","#loadedMode","#isLoaded","#doGet","#loadFromJoinTable","#loaded","#filterDeleted","#syncJoinTableRows","#isCascadeDelete"],"sources":["../../src/relations/ReactiveManyToMany.ts"],"sourcesContent":["import { manyToManyBatchLoader } from \"../batchloaders/manyToManyBatchLoader.ts\";\nimport {\n type Entity,\n type EntityMetadata,\n type ManyToManyField,\n type ReadOnlyCollection,\n ensureNotDeleted,\n fail,\n getEmInternalApi,\n getInstanceData,\n getMetadata,\n getMetadataForField,\n isLoaded,\n} from \"../index.ts\";\nimport type { IsLoadedCachable } from \"../loading/IsLoadedCache.ts\";\nimport { lazyField } from \"../newEntity.ts\";\nimport {\n type MaybeReactedEntity,\n type Reacted,\n type ReactiveHint,\n convertToLoadHint,\n} from \"../reactivity/reactiveHints.ts\";\nimport { AbstractRelationImpl } from \"./AbstractRelationImpl.ts\";\nimport { isCascadeDelete } from \"./isCascadeDelete.ts\";\nimport { RelationT, RelationU } from \"./RelationSymbols.ts\";\n\n/**\n * A reactive, derived many-to-many collection.\n *\n * Similar to `ReactiveReference` but for collections--membership is calculated from a reactive\n * function and persisted to the underlying join table.\n */\nexport interface ReactiveManyToMany<T extends Entity, U extends Entity> extends ReadOnlyCollection<T, U> {\n load(opts?: { withDeleted?: boolean; forceReload?: boolean }): Promise<readonly U[]>;\n}\n\n/** Creates a `ReactiveManyToMany`. */\nexport function hasReactiveManyToMany<T extends Entity, U extends Entity, const H extends ReactiveHint<T>>(\n hint: H,\n fn: (entity: Reacted<T, H>) => readonly MaybeReactedEntity<U>[],\n): ReactiveManyToMany<T, U> {\n return lazyField((entity: T, fieldName) => {\n const m2m = getMetadata(entity).allFields[fieldName] as ManyToManyField;\n return new ReactiveManyToManyImpl<T, U, H>(entity, m2m, hint, fn);\n });\n}\n\n/** Implements ReactiveManyToMany, initially a copy/paste of ReactiveReference but for m2m. */\nexport class ReactiveManyToManyImpl<T extends Entity, U extends Entity, H extends ReactiveHint<T>>\n extends AbstractRelationImpl<T, U[]>\n implements ReactiveManyToMany<T, U>, IsLoadedCachable\n{\n readonly #field: ManyToManyField;\n\n // Could be either the ref-loaded stored array, or full-loaded calculated array\n #loaded: U[] | undefined;\n // In ref-mode, we use our materialized FK value (which might be undefined)\n // If full-mode, we calculate the FK value from the subgraph\n #loadedMode: \"ref\" | \"full\" | undefined = undefined;\n // #isLoaded doesn't necessary care if we're ref-mode or full-mode, it's just\n // whether a caller can call `.get` and not have it blow up.\n #isLoaded: boolean | undefined = undefined;\n #isCached: boolean = false;\n #loadPromise: Promise<ReadonlyArray<U>> | undefined;\n\n constructor(\n entity: T,\n field: ManyToManyField,\n public reactiveHint: H,\n private fn: (entity: Reacted<T, H>) => readonly MaybeReactedEntity<U>[],\n ) {\n super(entity);\n this.#field = field;\n (getInstanceData(entity).relations ??= {})[this.fieldName] = this;\n }\n\n async load(opts?: { withDeleted?: boolean; forceReload?: boolean }): Promise<ReadonlyArray<U>> {\n ensureNotDeleted(this.entity, \"pending\");\n const { loadHint } = this;\n\n if (!this.isLoaded || opts?.forceReload) {\n const { em } = this.entity;\n const maybeDirty = opts?.forceReload || getEmInternalApi(em).rm.isMaybePendingRecalc(this.entity, this.fieldName);\n\n if (maybeDirty) {\n this.#isCached = false;\n return (this.#loadPromise ??= em.populate(this.entity, { hint: loadHint, ...opts }).then(() => {\n this.#loadPromise = undefined;\n this.#loadedMode = \"full\";\n this.#isLoaded = true;\n getEmInternalApi(this.entity.em).isLoadedCache.add(this);\n return this.#doGet(opts);\n }));\n } else {\n // Load from join table (existing materialized state)\n return (this.#loadPromise ??= this.#loadFromJoinTable().then((loaded) => {\n this.#loadPromise = undefined;\n this.#loadedMode = \"ref\";\n this.#isLoaded = true;\n this.#loaded = loaded;\n getEmInternalApi(this.entity.em).isLoadedCache.add(this);\n return this.#filterDeleted(loaded, opts);\n }));\n }\n }\n return this.#doGet(opts);\n }\n\n get isLoaded(): boolean {\n if (this.#isLoaded !== undefined) return this.#isLoaded;\n getEmInternalApi(this.entity.em).isLoadedCache.add(this);\n // If a WIP mutation has marked our field as potentially dirty, we need to be \"full\" loaded\n const maybeDirty = getEmInternalApi(this.entity.em).rm.isMaybePendingRecalc(this.entity, this.fieldName);\n if (maybeDirty) {\n // If we're dirty, only being \"full\" loaded is good enough to recalc\n this.#loadedMode = \"full\";\n this.#isLoaded = isLoaded(this.entity, this.loadHint);\n this.#isCached = false;\n } else {\n // If we've had `.load` called before, assume we're still loaded\n this.#isLoaded = !!this.#loadedMode;\n }\n return this.#isLoaded;\n }\n\n resetIsLoaded(): void {\n this.#isLoaded = undefined;\n this.#isCached = false;\n }\n\n #doGet(opts?: { withDeleted?: boolean }): U[] {\n const { fn } = this;\n ensureNotDeleted(this.entity, \"pending\");\n // Fast pass if we've already calculated this (cache invalidation will happen on\n // any mutation via #resetIsLoaded)..\n if (this.#isCached) {\n return this.#filterDeleted(this.#loaded ?? [], opts) as U[];\n }\n // Call isLoaded to probe the load hint, and get `#isLoaded` set, but still have\n // our `if` check the raw `#isLoaded` to know if we should eval-latest or return `loaded`.\n if (this.isLoaded && this.#loadedMode === \"full\") {\n const newValue = fn(this.entity as any) as unknown as U[];\n // Preserve deleted entities that were in the previous loaded value\n const previousDeleted = (this.#loaded ?? []).filter((e) => e.isDeletedEntity);\n for (const entity of previousDeleted) {\n if (!newValue.includes(entity)) newValue.push(entity);\n }\n if (!getEmInternalApi(this.entity.em).isValidating) {\n this.#syncJoinTableRows(newValue);\n }\n this.#loaded = newValue;\n this.#isCached = true;\n getEmInternalApi(this.entity.em).isLoadedCache.add(this);\n } else if (!!this.#loadedMode) {\n // We're either loadedMode=ref, or loadedMode=full (but not actually fully loaded),\n // but in theory loadedMode only gets set in `.load()`, so we should have #loaded\n // set to some value, even if it's not fully up-to-date.\n this.#isCached = true;\n getEmInternalApi(this.entity.em).isLoadedCache.add(this);\n } else {\n const noun = this.entity.isNewEntity ? \"derived\" : \"loaded\";\n throw new Error(`${this.entity}.${this.fieldName} has not been ${noun} yet`);\n }\n return this.#filterDeleted(this.#loaded ?? [], opts) as U[];\n }\n\n get getWithDeleted(): U[] {\n return this.#doGet({ withDeleted: true });\n }\n\n get get(): U[] {\n return this.#doGet({ withDeleted: false });\n }\n\n set(): void {\n fail(`Cannot set ${this.entity}.${this.fieldName} ReactiveManyToMany directly.`);\n }\n\n get loadHint(): any {\n const meta = getMetadata(this.entity);\n return (meta.config.__data.cachedReactiveLoadHints[this.fieldName] ??= convertToLoadHint(meta, this.reactiveHint));\n }\n\n setFromOpts(_others: U[]): void {\n throw new Error(`ReactiveManyToMany ${this.entity}.${this.fieldName} cannot be set via opts`);\n }\n\n maybeCascadeDelete(): void {\n if (this.#isCascadeDelete) {\n const jr = getEmInternalApi(this.entity.em).joinRows(this);\n (jr.getOthers(this.columnName, this.entity) as U[]).forEach((e) => this.entity.em.delete(e));\n }\n }\n\n async cleanupOnEntityDeleted(): Promise<void> {\n const existing = await this.load({ withDeleted: true });\n const jr = getEmInternalApi(this.entity.em).joinRows(this);\n for (const entity of existing) jr.addRemove(this, this.entity, entity);\n this.#loaded = [];\n this.#isLoaded = false;\n }\n\n // Properties needed for JoinRows/ManyToManyCollection compatibility\n get meta(): EntityMetadata {\n return getMetadataForField(getMetadata(this.entity), this.fieldName);\n }\n\n get fieldName(): string {\n return this.#field.fieldName;\n }\n\n get otherMeta(): EntityMetadata {\n return this.#field.otherMetadata();\n }\n\n get joinTableName(): string {\n return this.#field.joinTableName;\n }\n\n get columnName(): string {\n return this.#field.columnNames[0];\n }\n\n get otherColumnName(): string {\n return this.#field.columnNames[1];\n }\n\n get hasJoinTableId(): boolean {\n return this.#field.hasJoinTableId;\n }\n\n get otherFieldName(): string {\n return this.#field.otherFieldName;\n }\n\n get hasBeenSet(): boolean {\n return true;\n }\n\n get isPreloaded(): boolean {\n return false;\n }\n\n preload(): void {\n // No-op for now - could implement if needed\n }\n\n import(\n other: ReactiveManyToManyImpl<T, U, H>,\n _: unknown,\n mapEntities: (e: U[] | undefined) => U[] | undefined,\n ): void {\n this.#loaded = mapEntities(other.#loaded);\n this.#loadedMode = other.#loadedMode;\n this.#isLoaded = other.#isLoaded ?? false;\n // Don't set `#isCached b/c we're not registering ourselves with `isLoadedCache` yet; let\n // the first caller to `#doGet` do that if needed.\n }\n\n public toString(): string {\n return `ReactiveManyToMany(entity: ${this.entity}, fieldName: ${this.fieldName}, otherMeta: ${this.otherMeta.type})`;\n }\n\n get #isCascadeDelete(): boolean {\n return isCascadeDelete(this, this.#field.fieldName);\n }\n\n async #loadFromJoinTable(): Promise<U[]> {\n const { em } = this.entity;\n const key = `${this.columnName}=${this.entity.id}`;\n // Use the existing m2m loader by creating a compatible collection-like object\n await manyToManyBatchLoader(em, this).load(key);\n return getEmInternalApi(em).joinRows(this).getOthers(this.columnName, this.entity) as U[];\n }\n\n // This is like calling `setField` but for a m2m relation...\n #syncJoinTableRows(newValue: U[]): void {\n const jr = getEmInternalApi(this.entity.em).joinRows(this);\n const newSet = new Set(newValue);\n const oldSet = new Set(jr.getOthers(this.columnName, this.entity) as U[]);\n // Find entities to add (in new but not in old)\n for (const entity of newValue) {\n if (!oldSet.has(entity)) {\n jr.addNew(this, this.entity, entity);\n }\n }\n // Find entities to remove (in old but not in new)\n for (const entity of oldSet) {\n if (!newSet.has(entity)) {\n jr.addRemove(this, this.entity, entity);\n }\n }\n }\n\n #filterDeleted(entities: U[], opts?: { withDeleted?: boolean }): U[] {\n return opts?.withDeleted === true\n ? [...entities]\n : entities.filter((e) => !e.isDeletedEntity && !(e as any).isSoftDeletedEntity);\n }\n\n [RelationT]: T = null!;\n [RelationU]: U = null!;\n}\n\n/** Type guard utility for determining if an entity field is a ReactiveManyToMany. */\nexport function isReactiveManyToMany(\n maybeReactiveManyToMany: any,\n): maybeReactiveManyToMany is ReactiveManyToMany<any, any> {\n return maybeReactiveManyToMany instanceof ReactiveManyToManyImpl;\n}\n"],"mappings":"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"}
@@ -1,10 +1,8 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- require("../JoinRows.cjs");
3
2
  const require_relations_AbstractRelationImpl = require("./AbstractRelationImpl.cjs");
4
3
  const require_relations_RelationSymbols = require("./RelationSymbols.cjs");
5
- require("../IsLoadedCache.cjs");
6
- const require_newEntity = require("../newEntity.cjs");
7
4
  const require_batchloaders_manyToManyBatchLoader = require("../batchloaders/manyToManyBatchLoader.cjs");
5
+ const require_newEntity = require("../newEntity.cjs");
8
6
  const require_EntityMetadata = require("../EntityMetadata.cjs");
9
7
  const require_index = require("../index.cjs");
10
8
  const require_EntityManager = require("../EntityManager.cjs");