@statezero/core 0.2.37 → 0.2.38

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 (307) hide show
  1. package/dist/adaptors/vue/components/LayoutRenderer.js +166 -0
  2. package/dist/adaptors/vue/components/defaults/AlertElement.js +31 -0
  3. package/dist/adaptors/vue/components/defaults/DisplayElement.js +44 -0
  4. package/dist/adaptors/vue/components/defaults/DividerElement.js +10 -0
  5. package/dist/adaptors/vue/components/defaults/ErrorBlock.js +24 -0
  6. package/dist/adaptors/vue/components/defaults/GroupElement.js +41 -0
  7. package/dist/adaptors/vue/components/defaults/LabelElement.js +21 -0
  8. package/dist/adaptors/vue/components/defaults/TabsElement.js +38 -0
  9. package/package.json +6 -4
  10. package/dist/actions/backend1/django_app/calculate-hash.d.ts +0 -57
  11. package/dist/actions/backend1/django_app/calculate-hash.js +0 -80
  12. package/dist/actions/backend1/django_app/calculate-hash.schema.json +0 -148
  13. package/dist/actions/backend1/django_app/get-current-username.d.ts +0 -29
  14. package/dist/actions/backend1/django_app/get-current-username.js +0 -65
  15. package/dist/actions/backend1/django_app/get-current-username.schema.json +0 -47
  16. package/dist/actions/backend1/django_app/get-server-status.d.ts +0 -38
  17. package/dist/actions/backend1/django_app/get-server-status.js +0 -68
  18. package/dist/actions/backend1/django_app/get-server-status.schema.json +0 -93
  19. package/dist/actions/backend1/django_app/get-user-info.d.ts +0 -44
  20. package/dist/actions/backend1/django_app/get-user-info.js +0 -70
  21. package/dist/actions/backend1/django_app/get-user-info.schema.json +0 -127
  22. package/dist/actions/backend1/django_app/index.d.ts +0 -1
  23. package/dist/actions/backend1/django_app/index.js +0 -6
  24. package/dist/actions/backend1/django_app/process-data.d.ts +0 -51
  25. package/dist/actions/backend1/django_app/process-data.js +0 -78
  26. package/dist/actions/backend1/django_app/process-data.schema.json +0 -117
  27. package/dist/actions/backend1/django_app/send-notification.d.ts +0 -55
  28. package/dist/actions/backend1/django_app/send-notification.js +0 -81
  29. package/dist/actions/backend1/django_app/send-notification.schema.json +0 -175
  30. package/dist/actions/backend1/index.d.ts +0 -1
  31. package/dist/actions/backend1/index.js +0 -1
  32. package/dist/actions/default/django_app/calculate-hash.d.ts +0 -57
  33. package/dist/actions/default/django_app/calculate-hash.js +0 -80
  34. package/dist/actions/default/django_app/calculate-hash.schema.json +0 -148
  35. package/dist/actions/default/django_app/get-current-username.d.ts +0 -29
  36. package/dist/actions/default/django_app/get-current-username.js +0 -65
  37. package/dist/actions/default/django_app/get-current-username.schema.json +0 -47
  38. package/dist/actions/default/django_app/get-server-status.d.ts +0 -38
  39. package/dist/actions/default/django_app/get-server-status.js +0 -68
  40. package/dist/actions/default/django_app/get-server-status.schema.json +0 -93
  41. package/dist/actions/default/django_app/get-user-info.d.ts +0 -44
  42. package/dist/actions/default/django_app/get-user-info.js +0 -70
  43. package/dist/actions/default/django_app/get-user-info.schema.json +0 -127
  44. package/dist/actions/default/django_app/index.d.ts +0 -1
  45. package/dist/actions/default/django_app/index.js +0 -6
  46. package/dist/actions/default/django_app/process-data.d.ts +0 -51
  47. package/dist/actions/default/django_app/process-data.js +0 -78
  48. package/dist/actions/default/django_app/process-data.schema.json +0 -117
  49. package/dist/actions/default/django_app/send-notification.d.ts +0 -55
  50. package/dist/actions/default/django_app/send-notification.js +0 -81
  51. package/dist/actions/default/django_app/send-notification.schema.json +0 -175
  52. package/dist/actions/default/index.d.ts +0 -1
  53. package/dist/actions/default/index.js +0 -1
  54. package/dist/actions/index.d.ts +0 -1
  55. package/dist/actions/index.js +0 -5
  56. package/dist/adaptors/react/composables.d.ts +0 -1
  57. package/dist/adaptors/react/composables.js +0 -4
  58. package/dist/adaptors/react/index.d.ts +0 -1
  59. package/dist/adaptors/react/index.js +0 -1
  60. package/dist/adaptors/vue/components/LayoutRenderer.vue +0 -361
  61. package/dist/adaptors/vue/components/defaults/AlertElement.vue +0 -38
  62. package/dist/adaptors/vue/components/defaults/DisplayElement.vue +0 -57
  63. package/dist/adaptors/vue/components/defaults/DividerElement.vue +0 -13
  64. package/dist/adaptors/vue/components/defaults/ErrorBlock.vue +0 -28
  65. package/dist/adaptors/vue/components/defaults/GroupElement.vue +0 -53
  66. package/dist/adaptors/vue/components/defaults/LabelElement.vue +0 -25
  67. package/dist/adaptors/vue/components/defaults/TabsElement.vue +0 -54
  68. package/dist/adaptors/vue/components/defaults/index.d.ts +0 -7
  69. package/dist/adaptors/vue/components/defaults/index.js +0 -31
  70. package/dist/adaptors/vue/components/index.d.ts +0 -1
  71. package/dist/adaptors/vue/components/index.js +0 -7
  72. package/dist/adaptors/vue/composables.d.ts +0 -2
  73. package/dist/adaptors/vue/composables.js +0 -44
  74. package/dist/adaptors/vue/index.d.ts +0 -3
  75. package/dist/adaptors/vue/index.js +0 -4
  76. package/dist/adaptors/vue/reactivity.d.ts +0 -18
  77. package/dist/adaptors/vue/reactivity.js +0 -132
  78. package/dist/cli/commands/sync.d.ts +0 -6
  79. package/dist/cli/commands/sync.js +0 -30
  80. package/dist/cli/commands/syncActions.d.ts +0 -46
  81. package/dist/cli/commands/syncActions.js +0 -717
  82. package/dist/cli/commands/syncModels.d.ts +0 -132
  83. package/dist/cli/commands/syncModels.js +0 -1120
  84. package/dist/cli/configFileLoader.d.ts +0 -10
  85. package/dist/cli/configFileLoader.js +0 -85
  86. package/dist/cli/index.d.ts +0 -2
  87. package/dist/cli/index.js +0 -22
  88. package/dist/config.d.ts +0 -57
  89. package/dist/config.js +0 -273
  90. package/dist/core/eventReceivers.d.ts +0 -185
  91. package/dist/core/eventReceivers.js +0 -266
  92. package/dist/core/utils.d.ts +0 -8
  93. package/dist/core/utils.js +0 -62
  94. package/dist/errorHandler.d.ts +0 -21
  95. package/dist/errorHandler.js +0 -27
  96. package/dist/filtering/localFiltering.d.ts +0 -110
  97. package/dist/filtering/localFiltering.js +0 -1080
  98. package/dist/flavours/django/dates.d.ts +0 -34
  99. package/dist/flavours/django/dates.js +0 -113
  100. package/dist/flavours/django/errors.d.ts +0 -138
  101. package/dist/flavours/django/errors.js +0 -195
  102. package/dist/flavours/django/f.d.ts +0 -6
  103. package/dist/flavours/django/f.js +0 -91
  104. package/dist/flavours/django/files.d.ts +0 -62
  105. package/dist/flavours/django/files.js +0 -355
  106. package/dist/flavours/django/makeApiCall.d.ts +0 -36
  107. package/dist/flavours/django/makeApiCall.js +0 -169
  108. package/dist/flavours/django/manager.d.ts +0 -204
  109. package/dist/flavours/django/manager.js +0 -222
  110. package/dist/flavours/django/model.d.ts +0 -137
  111. package/dist/flavours/django/model.js +0 -366
  112. package/dist/flavours/django/operationFactory.d.ts +0 -73
  113. package/dist/flavours/django/operationFactory.js +0 -248
  114. package/dist/flavours/django/q.d.ts +0 -70
  115. package/dist/flavours/django/q.js +0 -43
  116. package/dist/flavours/django/queryExecutor.d.ts +0 -149
  117. package/dist/flavours/django/queryExecutor.js +0 -590
  118. package/dist/flavours/django/querySet.d.ts +0 -301
  119. package/dist/flavours/django/querySet.js +0 -736
  120. package/dist/flavours/django/serializers.d.ts +0 -39
  121. package/dist/flavours/django/serializers.js +0 -296
  122. package/dist/flavours/django/tempPk.d.ts +0 -31
  123. package/dist/flavours/django/tempPk.js +0 -92
  124. package/dist/flavours/django/utils.d.ts +0 -19
  125. package/dist/flavours/django/utils.js +0 -29
  126. package/dist/index.d.ts +0 -46
  127. package/dist/index.js +0 -48
  128. package/dist/models/backend1/django_app/comprehensivemodel.d.ts +0 -894
  129. package/dist/models/backend1/django_app/comprehensivemodel.js +0 -71
  130. package/dist/models/backend1/django_app/comprehensivemodel.schema.json +0 -870
  131. package/dist/models/backend1/django_app/custompkmodel.d.ts +0 -92
  132. package/dist/models/backend1/django_app/custompkmodel.js +0 -69
  133. package/dist/models/backend1/django_app/custompkmodel.schema.json +0 -71
  134. package/dist/models/backend1/django_app/dailyrate.d.ts +0 -230
  135. package/dist/models/backend1/django_app/dailyrate.js +0 -71
  136. package/dist/models/backend1/django_app/dailyrate.schema.json +0 -212
  137. package/dist/models/backend1/django_app/deepmodellevel1.d.ts +0 -140
  138. package/dist/models/backend1/django_app/deepmodellevel1.js +0 -72
  139. package/dist/models/backend1/django_app/deepmodellevel1.schema.json +0 -114
  140. package/dist/models/backend1/django_app/deepmodellevel2.d.ts +0 -118
  141. package/dist/models/backend1/django_app/deepmodellevel2.js +0 -71
  142. package/dist/models/backend1/django_app/deepmodellevel2.schema.json +0 -92
  143. package/dist/models/backend1/django_app/deepmodellevel3.d.ts +0 -92
  144. package/dist/models/backend1/django_app/deepmodellevel3.js +0 -69
  145. package/dist/models/backend1/django_app/deepmodellevel3.schema.json +0 -69
  146. package/dist/models/backend1/django_app/dummymodel.d.ts +0 -134
  147. package/dist/models/backend1/django_app/dummymodel.js +0 -71
  148. package/dist/models/backend1/django_app/dummymodel.schema.json +0 -109
  149. package/dist/models/backend1/django_app/dummyrelatedmodel.d.ts +0 -92
  150. package/dist/models/backend1/django_app/dummyrelatedmodel.js +0 -69
  151. package/dist/models/backend1/django_app/dummyrelatedmodel.schema.json +0 -69
  152. package/dist/models/backend1/django_app/filetest.d.ts +0 -140
  153. package/dist/models/backend1/django_app/filetest.js +0 -69
  154. package/dist/models/backend1/django_app/filetest.schema.json +0 -111
  155. package/dist/models/backend1/django_app/index.d.ts +0 -1
  156. package/dist/models/backend1/django_app/index.js +0 -21
  157. package/dist/models/backend1/django_app/m2mdepthtestlevel1.d.ts +0 -118
  158. package/dist/models/backend1/django_app/m2mdepthtestlevel1.js +0 -71
  159. package/dist/models/backend1/django_app/m2mdepthtestlevel1.schema.json +0 -94
  160. package/dist/models/backend1/django_app/m2mdepthtestlevel2.d.ts +0 -118
  161. package/dist/models/backend1/django_app/m2mdepthtestlevel2.js +0 -71
  162. package/dist/models/backend1/django_app/m2mdepthtestlevel2.schema.json +0 -94
  163. package/dist/models/backend1/django_app/m2mdepthtestlevel3.d.ts +0 -134
  164. package/dist/models/backend1/django_app/m2mdepthtestlevel3.js +0 -71
  165. package/dist/models/backend1/django_app/m2mdepthtestlevel3.schema.json +0 -112
  166. package/dist/models/backend1/django_app/modelwithcustompkrelation.d.ts +0 -118
  167. package/dist/models/backend1/django_app/modelwithcustompkrelation.js +0 -71
  168. package/dist/models/backend1/django_app/modelwithcustompkrelation.schema.json +0 -93
  169. package/dist/models/backend1/django_app/modelwithrestrictedfields.d.ts +0 -134
  170. package/dist/models/backend1/django_app/modelwithrestrictedfields.js +0 -71
  171. package/dist/models/backend1/django_app/modelwithrestrictedfields.schema.json +0 -111
  172. package/dist/models/backend1/django_app/namefiltercustompkmodel.d.ts +0 -92
  173. package/dist/models/backend1/django_app/namefiltercustompkmodel.js +0 -69
  174. package/dist/models/backend1/django_app/namefiltercustompkmodel.schema.json +0 -71
  175. package/dist/models/backend1/django_app/order.d.ts +0 -220
  176. package/dist/models/backend1/django_app/order.js +0 -71
  177. package/dist/models/backend1/django_app/order.schema.json +0 -203
  178. package/dist/models/backend1/django_app/orderitem.d.ts +0 -172
  179. package/dist/models/backend1/django_app/orderitem.js +0 -72
  180. package/dist/models/backend1/django_app/orderitem.schema.json +0 -149
  181. package/dist/models/backend1/django_app/product.d.ts +0 -254
  182. package/dist/models/backend1/django_app/product.js +0 -71
  183. package/dist/models/backend1/django_app/product.schema.json +0 -277
  184. package/dist/models/backend1/django_app/productcategory.d.ts +0 -92
  185. package/dist/models/backend1/django_app/productcategory.js +0 -69
  186. package/dist/models/backend1/django_app/productcategory.schema.json +0 -70
  187. package/dist/models/backend1/django_app/rateplan.d.ts +0 -92
  188. package/dist/models/backend1/django_app/rateplan.js +0 -69
  189. package/dist/models/backend1/django_app/rateplan.schema.json +0 -70
  190. package/dist/models/backend1/django_app/restrictedfieldrelatedmodel.d.ts +0 -108
  191. package/dist/models/backend1/django_app/restrictedfieldrelatedmodel.js +0 -69
  192. package/dist/models/backend1/django_app/restrictedfieldrelatedmodel.schema.json +0 -87
  193. package/dist/models/backend1/fileobject.d.ts +0 -4
  194. package/dist/models/backend1/fileobject.js +0 -9
  195. package/dist/models/backend1/index.d.ts +0 -2
  196. package/dist/models/backend1/index.js +0 -2
  197. package/dist/models/default/django_app/comprehensivemodel.d.ts +0 -894
  198. package/dist/models/default/django_app/comprehensivemodel.js +0 -71
  199. package/dist/models/default/django_app/comprehensivemodel.schema.json +0 -870
  200. package/dist/models/default/django_app/custompkmodel.d.ts +0 -92
  201. package/dist/models/default/django_app/custompkmodel.js +0 -69
  202. package/dist/models/default/django_app/custompkmodel.schema.json +0 -71
  203. package/dist/models/default/django_app/dailyrate.d.ts +0 -230
  204. package/dist/models/default/django_app/dailyrate.js +0 -71
  205. package/dist/models/default/django_app/dailyrate.schema.json +0 -212
  206. package/dist/models/default/django_app/deepmodellevel1.d.ts +0 -128
  207. package/dist/models/default/django_app/deepmodellevel1.js +0 -72
  208. package/dist/models/default/django_app/deepmodellevel1.schema.json +0 -102
  209. package/dist/models/default/django_app/deepmodellevel2.d.ts +0 -106
  210. package/dist/models/default/django_app/deepmodellevel2.js +0 -71
  211. package/dist/models/default/django_app/deepmodellevel2.schema.json +0 -80
  212. package/dist/models/default/django_app/deepmodellevel3.d.ts +0 -80
  213. package/dist/models/default/django_app/deepmodellevel3.js +0 -69
  214. package/dist/models/default/django_app/deepmodellevel3.schema.json +0 -57
  215. package/dist/models/default/django_app/dummymodel.d.ts +0 -122
  216. package/dist/models/default/django_app/dummymodel.js +0 -71
  217. package/dist/models/default/django_app/dummymodel.schema.json +0 -97
  218. package/dist/models/default/django_app/dummyrelatedmodel.d.ts +0 -80
  219. package/dist/models/default/django_app/dummyrelatedmodel.js +0 -69
  220. package/dist/models/default/django_app/dummyrelatedmodel.schema.json +0 -57
  221. package/dist/models/default/django_app/filetest.d.ts +0 -128
  222. package/dist/models/default/django_app/filetest.js +0 -69
  223. package/dist/models/default/django_app/filetest.schema.json +0 -99
  224. package/dist/models/default/django_app/index.d.ts +0 -1
  225. package/dist/models/default/django_app/index.js +0 -21
  226. package/dist/models/default/django_app/m2mdepthtestlevel1.d.ts +0 -118
  227. package/dist/models/default/django_app/m2mdepthtestlevel1.js +0 -71
  228. package/dist/models/default/django_app/m2mdepthtestlevel1.schema.json +0 -94
  229. package/dist/models/default/django_app/m2mdepthtestlevel2.d.ts +0 -118
  230. package/dist/models/default/django_app/m2mdepthtestlevel2.js +0 -71
  231. package/dist/models/default/django_app/m2mdepthtestlevel2.schema.json +0 -94
  232. package/dist/models/default/django_app/m2mdepthtestlevel3.d.ts +0 -134
  233. package/dist/models/default/django_app/m2mdepthtestlevel3.js +0 -71
  234. package/dist/models/default/django_app/m2mdepthtestlevel3.schema.json +0 -112
  235. package/dist/models/default/django_app/modelwithcustompkrelation.d.ts +0 -118
  236. package/dist/models/default/django_app/modelwithcustompkrelation.js +0 -71
  237. package/dist/models/default/django_app/modelwithcustompkrelation.schema.json +0 -93
  238. package/dist/models/default/django_app/modelwithrestrictedfields.d.ts +0 -134
  239. package/dist/models/default/django_app/modelwithrestrictedfields.js +0 -71
  240. package/dist/models/default/django_app/modelwithrestrictedfields.schema.json +0 -111
  241. package/dist/models/default/django_app/namefiltercustompkmodel.d.ts +0 -92
  242. package/dist/models/default/django_app/namefiltercustompkmodel.js +0 -69
  243. package/dist/models/default/django_app/namefiltercustompkmodel.schema.json +0 -71
  244. package/dist/models/default/django_app/order.d.ts +0 -220
  245. package/dist/models/default/django_app/order.js +0 -71
  246. package/dist/models/default/django_app/order.schema.json +0 -203
  247. package/dist/models/default/django_app/orderitem.d.ts +0 -172
  248. package/dist/models/default/django_app/orderitem.js +0 -72
  249. package/dist/models/default/django_app/orderitem.schema.json +0 -149
  250. package/dist/models/default/django_app/product.d.ts +0 -254
  251. package/dist/models/default/django_app/product.js +0 -71
  252. package/dist/models/default/django_app/product.schema.json +0 -277
  253. package/dist/models/default/django_app/productcategory.d.ts +0 -92
  254. package/dist/models/default/django_app/productcategory.js +0 -69
  255. package/dist/models/default/django_app/productcategory.schema.json +0 -70
  256. package/dist/models/default/django_app/rateplan.d.ts +0 -92
  257. package/dist/models/default/django_app/rateplan.js +0 -69
  258. package/dist/models/default/django_app/rateplan.schema.json +0 -70
  259. package/dist/models/default/django_app/restrictedfieldrelatedmodel.d.ts +0 -108
  260. package/dist/models/default/django_app/restrictedfieldrelatedmodel.js +0 -69
  261. package/dist/models/default/django_app/restrictedfieldrelatedmodel.schema.json +0 -87
  262. package/dist/models/default/fileobject.d.ts +0 -4
  263. package/dist/models/default/fileobject.js +0 -9
  264. package/dist/models/default/index.d.ts +0 -2
  265. package/dist/models/default/index.js +0 -2
  266. package/dist/models/index.d.ts +0 -1
  267. package/dist/models/index.js +0 -5
  268. package/dist/react-entry.d.ts +0 -2
  269. package/dist/react-entry.js +0 -2
  270. package/dist/reactiveAdaptor.d.ts +0 -24
  271. package/dist/reactiveAdaptor.js +0 -38
  272. package/dist/reset.d.ts +0 -15
  273. package/dist/reset.js +0 -97
  274. package/dist/setup.d.ts +0 -15
  275. package/dist/setup.js +0 -33
  276. package/dist/syncEngine/cache/cache.d.ts +0 -75
  277. package/dist/syncEngine/cache/cache.js +0 -355
  278. package/dist/syncEngine/metrics/metricOptCalcs.d.ts +0 -79
  279. package/dist/syncEngine/metrics/metricOptCalcs.js +0 -284
  280. package/dist/syncEngine/registries/metricRegistry.d.ts +0 -58
  281. package/dist/syncEngine/registries/metricRegistry.js +0 -171
  282. package/dist/syncEngine/registries/modelStoreRegistry.d.ts +0 -11
  283. package/dist/syncEngine/registries/modelStoreRegistry.js +0 -63
  284. package/dist/syncEngine/registries/querysetStoreGraph.d.ts +0 -41
  285. package/dist/syncEngine/registries/querysetStoreGraph.js +0 -174
  286. package/dist/syncEngine/registries/querysetStoreRegistry.d.ts +0 -72
  287. package/dist/syncEngine/registries/querysetStoreRegistry.js +0 -335
  288. package/dist/syncEngine/stores/metricStore.d.ts +0 -55
  289. package/dist/syncEngine/stores/metricStore.js +0 -222
  290. package/dist/syncEngine/stores/modelStore.d.ts +0 -53
  291. package/dist/syncEngine/stores/modelStore.js +0 -565
  292. package/dist/syncEngine/stores/operation.d.ts +0 -139
  293. package/dist/syncEngine/stores/operation.js +0 -291
  294. package/dist/syncEngine/stores/operationEventHandlers.d.ts +0 -8
  295. package/dist/syncEngine/stores/operationEventHandlers.js +0 -322
  296. package/dist/syncEngine/stores/querysetStore.d.ts +0 -60
  297. package/dist/syncEngine/stores/querysetStore.js +0 -294
  298. package/dist/syncEngine/stores/reactivity.d.ts +0 -3
  299. package/dist/syncEngine/stores/reactivity.js +0 -4
  300. package/dist/syncEngine/stores/utils.d.ts +0 -14
  301. package/dist/syncEngine/stores/utils.js +0 -32
  302. package/dist/syncEngine/sync.d.ts +0 -46
  303. package/dist/syncEngine/sync.js +0 -389
  304. package/dist/testing.d.ts +0 -63
  305. package/dist/testing.js +0 -175
  306. package/dist/vue-entry.d.ts +0 -15
  307. package/dist/vue-entry.js +0 -7
@@ -1,322 +0,0 @@
1
- import { operationEvents, Status, Type, operationRegistry, OperationMembership } from './operation.js';
2
- import { modelStoreRegistry } from '../registries/modelStoreRegistry.js';
3
- import { querysetStoreRegistry } from '../registries/querysetStoreRegistry.js';
4
- import { metricRegistry } from '../registries/metricRegistry.js';
5
- import { getFingerprint } from './utils.js';
6
- import { QuerySet } from '../../flavours/django/querySet.js';
7
- import { isEqual, isNil } from 'lodash-es';
8
- import hash from 'object-hash';
9
- import { filter } from '../../filtering/localFiltering.js';
10
- /**
11
- * Evaluates and routes a CREATE operation to querysets, tracking membership state.
12
- *
13
- * For each queryset:
14
- * - If offset > 0: mark as MAYBE (can't determine position based on slicing)
15
- * - If item doesn't match filter: mark DEFINITELY_NO
16
- * - If item matches filter AND (no limit OR count < limit): mark DEFINITELY_YES
17
- * - If item matches filter AND count >= limit: mark MAYBE (ordering determines inclusion)
18
- *
19
- * @param {Operation} operation - The CREATE operation to route
20
- * @param {Function} applyAction - Function to apply the operation to a store
21
- */
22
- function routeCreateOperation(operation, applyAction) {
23
- const modelClass = operation.queryset.ModelClass;
24
- const instances = operation.instances;
25
- Array.from(querysetStoreRegistry._stores.entries()).forEach(([semanticKey, store]) => {
26
- if (store.modelClass !== modelClass)
27
- return;
28
- const serializerOptions = store.queryset?._serializerOptions || {};
29
- const { offset, limit } = serializerOptions;
30
- // Offset > 0: can't determine position based on slicing
31
- if (offset != null && offset > 0) {
32
- operationRegistry.setQuerysetState(operation.operationId, semanticKey, OperationMembership.MAYBE);
33
- return;
34
- }
35
- // Evaluate if instances match this queryset's filter
36
- const ast = store.queryset.build();
37
- const matchingInstances = filter(instances, ast, modelClass, false);
38
- if (matchingInstances.length === 0) {
39
- // No instances match - mark DEFINITELY_NO (no need to sync this queryset)
40
- operationRegistry.setQuerysetState(operation.operationId, semanticKey, OperationMembership.DEFINITELY_NO);
41
- return;
42
- }
43
- // Item matches filter - check limit
44
- if (limit != null) {
45
- const currentCount = store.groundTruthPks?.length || 0;
46
- // At capacity: check if ordering could affect position
47
- if (currentCount >= limit) {
48
- // Check explicit ordering on queryset OR implicit ordering from Django Meta
49
- const hasExplicitOrdering = store.queryset._orderBy && store.queryset._orderBy.length > 0;
50
- const hasImplicitOrdering = (modelClass.schema?.default_ordering?.length || 0) > 0;
51
- if (hasExplicitOrdering || hasImplicitOrdering) {
52
- // With ordering, new item could displace existing items - can't know without server
53
- operationRegistry.setQuerysetState(operation.operationId, semanticKey, OperationMembership.MAYBE);
54
- }
55
- else {
56
- // No ordering - new items go at end, won't be in first N
57
- operationRegistry.setQuerysetState(operation.operationId, semanticKey, OperationMembership.DEFINITELY_NO);
58
- }
59
- return;
60
- }
61
- // Room for some or all items - continue to DEFINITELY_YES below
62
- }
63
- // Matches filter, has room or no limit - DEFINITELY_YES
64
- applyAction(store);
65
- operationRegistry.setQuerysetState(operation.operationId, semanticKey, OperationMembership.DEFINITELY_YES);
66
- });
67
- }
68
- /**
69
- * Evaluates and tracks membership state for UPDATE operations.
70
- *
71
- * For UPDATE, we check filter FIRST (optimization), then offset:
72
- * - If item didn't match before AND doesn't match after: DEFINITELY_NO (regardless of offset)
73
- * - If item matched before OR matches after AND offset > 0: MAYBE (can't determine position)
74
- * - If item matched before OR matches after AND offset = 0: DEFINITELY_YES
75
- *
76
- * @param {Operation} operation - The UPDATE operation
77
- */
78
- function routeUpdateOperation(operation) {
79
- const modelClass = operation.queryset.ModelClass;
80
- const beforeInstances = operation.frozenInstances;
81
- const afterInstances = operation.instances;
82
- Array.from(querysetStoreRegistry._stores.entries()).forEach(([semanticKey, store]) => {
83
- if (store.modelClass !== modelClass)
84
- return;
85
- // Check filter match FIRST (optimization: skip offset check if no match)
86
- const ast = store.queryset.build();
87
- const matchedBefore = filter(beforeInstances, ast, modelClass, false).length > 0;
88
- const matchesAfter = filter(afterInstances, ast, modelClass, false).length > 0;
89
- // If item never matched filter, definitely not affected (regardless of offset)
90
- if (!matchedBefore && !matchesAfter) {
91
- operationRegistry.setQuerysetState(operation.operationId, semanticKey, OperationMembership.DEFINITELY_NO);
92
- return;
93
- }
94
- // Item matches filter - now check offset
95
- const serializerOptions = store.queryset?._serializerOptions || {};
96
- const { offset } = serializerOptions;
97
- if (offset != null && offset > 0) {
98
- // Can't determine position in paginated window
99
- operationRegistry.setQuerysetState(operation.operationId, semanticKey, OperationMembership.MAYBE);
100
- return;
101
- }
102
- // Item matched before OR matches after, no offset - definitely affected
103
- operationRegistry.setQuerysetState(operation.operationId, semanticKey, OperationMembership.DEFINITELY_YES);
104
- });
105
- }
106
- /**
107
- * Evaluates and tracks membership state for DELETE operations.
108
- *
109
- * For DELETE, we check filter FIRST (optimization), then offset:
110
- * - If item didn't match before: DEFINITELY_NO (regardless of offset)
111
- * - If item matched before AND offset > 0: MAYBE (can't determine position)
112
- * - If item matched before AND offset = 0: DEFINITELY_YES
113
- *
114
- * @param {Operation} operation - The DELETE operation
115
- */
116
- function routeDeleteOperation(operation) {
117
- const modelClass = operation.queryset.ModelClass;
118
- const beforeInstances = operation.frozenInstances;
119
- Array.from(querysetStoreRegistry._stores.entries()).forEach(([semanticKey, store]) => {
120
- if (store.modelClass !== modelClass)
121
- return;
122
- // Check filter match FIRST (optimization: skip offset check if no match)
123
- const ast = store.queryset.build();
124
- const matchedBefore = filter(beforeInstances, ast, modelClass, false).length > 0;
125
- // If item never matched filter, definitely not affected (regardless of offset)
126
- if (!matchedBefore) {
127
- operationRegistry.setQuerysetState(operation.operationId, semanticKey, OperationMembership.DEFINITELY_NO);
128
- return;
129
- }
130
- // Item matched filter - now check offset
131
- const serializerOptions = store.queryset?._serializerOptions || {};
132
- const { offset } = serializerOptions;
133
- if (offset != null && offset > 0) {
134
- // Can't determine position in paginated window
135
- operationRegistry.setQuerysetState(operation.operationId, semanticKey, OperationMembership.MAYBE);
136
- return;
137
- }
138
- // Item matched before, no offset - definitely affected
139
- operationRegistry.setQuerysetState(operation.operationId, semanticKey, OperationMembership.DEFINITELY_YES);
140
- });
141
- }
142
- /**
143
- * Process an operation in the model store
144
- *
145
- * @param {Operation} operation - The operation to process
146
- * @param {string} actionType - The action to perform ('add', 'update', 'confirm', 'reject')
147
- */
148
- function processModelStore(operation, actionType) {
149
- const ModelClass = operation.queryset.ModelClass;
150
- const modelStore = modelStoreRegistry.getStore(ModelClass);
151
- if (!modelStore)
152
- return;
153
- switch (actionType) {
154
- case 'add':
155
- modelStore.addOperation(operation);
156
- break;
157
- case 'update':
158
- modelStore.updateOperation(operation);
159
- break;
160
- case 'confirm':
161
- modelStore.confirm(operation);
162
- break;
163
- case 'reject':
164
- modelStore.reject(operation);
165
- break;
166
- }
167
- }
168
- /**
169
- * Process an operation in the queryset stores based on operation type
170
- * Uses different routing strategies based on the operation type
171
- *
172
- * @param {Operation} operation - The operation to process
173
- * @param {string} actionType - The action to perform ('add', 'update', 'confirm', 'reject')
174
- */
175
- function processQuerysetStores(operation, actionType) {
176
- const ModelClass = operation.queryset.ModelClass;
177
- const queryset = operation.queryset;
178
- // Apply the appropriate action to a single queryset store
179
- const applyAction = (store) => {
180
- switch (actionType) {
181
- case 'add':
182
- store.addOperation(operation);
183
- break;
184
- case 'update':
185
- store.updateOperation(operation);
186
- break;
187
- case 'confirm':
188
- store.confirm(operation);
189
- break;
190
- case 'reject':
191
- store.reject(operation);
192
- break;
193
- }
194
- };
195
- let querysetStoreMap;
196
- // Route to querysets based on operation type
197
- // All operation types track membership state for sync optimization
198
- // CREATE: adds operation to store + tracks membership
199
- // UPDATE/DELETE: only tracks membership (model store + reactivity handles rendering)
200
- switch (operation.type) {
201
- case Type.CREATE:
202
- case Type.BULK_CREATE:
203
- case Type.GET_OR_CREATE:
204
- case Type.UPDATE_OR_CREATE:
205
- // For creates, evaluate each queryset and track membership state
206
- // This allows us to skip syncing querysets that we know don't contain the item
207
- routeCreateOperation(operation, applyAction);
208
- return;
209
- case Type.UPDATE:
210
- case Type.UPDATE_INSTANCE:
211
- // Track membership for sync optimization
212
- // Check both before (frozenInstances) and after (instances) state
213
- routeUpdateOperation(operation);
214
- return;
215
- case Type.DELETE:
216
- case Type.DELETE_INSTANCE:
217
- // Track membership for sync optimization
218
- // Check before state only (item being deleted)
219
- routeDeleteOperation(operation);
220
- return;
221
- case Type.CHECKPOINT:
222
- // Model store handles the change, querysets re-render via local filtering
223
- // No membership tracking needed for checkpoints
224
- return;
225
- default:
226
- // For other operation types, route like creates
227
- routeCreateOperation(operation, applyAction);
228
- return;
229
- }
230
- }
231
- /**
232
- * Process an operation in the metric stores
233
- *
234
- * For metrics, we route operations UP the family tree - any metric on an ancestor
235
- * queryset should receive the operation so it can check if it affects the metric.
236
- *
237
- * @param {Operation} operation - The operation to process
238
- * @param {string} actionType - The action to perform ('add', 'update', 'confirm', 'reject')
239
- */
240
- function processMetricStores(operation, actionType) {
241
- const queryset = operation.queryset;
242
- const allMetricStores = new Set();
243
- // Walk up the queryset family tree and collect all metrics
244
- let current = queryset;
245
- while (current) {
246
- const stores = metricRegistry.getAllStoresForQueryset(current);
247
- if (stores && stores.length > 0) {
248
- stores.forEach(store => allMetricStores.add(store));
249
- }
250
- current = current.__parent;
251
- }
252
- if (allMetricStores.size === 0) {
253
- return;
254
- }
255
- // Apply the action to each matching metric store
256
- allMetricStores.forEach(store => {
257
- switch (actionType) {
258
- case 'add':
259
- store.addOperation(operation);
260
- break;
261
- case 'update':
262
- store.updateOperation(operation);
263
- break;
264
- case 'confirm':
265
- store.confirm(operation);
266
- break;
267
- case 'reject':
268
- store.reject(operation);
269
- break;
270
- }
271
- });
272
- }
273
- /**
274
- * Common processing logic for operations, handling validation and routing
275
- * to the appropriate store processors
276
- *
277
- * @param {Operation} operation - The operation to process
278
- * @param {string} actionType - The action to perform ('add', 'update', 'confirm', 'reject')
279
- */
280
- function processOperation(operation, actionType) {
281
- if (!operation || !operation.queryset || !operation.queryset.ModelClass) {
282
- console.warn(`Received invalid operation in processOperation (${actionType})`, operation);
283
- return;
284
- }
285
- if (operation.doNotPropagate) {
286
- return;
287
- }
288
- // Process model store first
289
- processModelStore(operation, actionType);
290
- // Then process queryset stores with improved routing
291
- processQuerysetStores(operation, actionType);
292
- // Finally process metric stores
293
- processMetricStores(operation, actionType);
294
- }
295
- // Define handlers as named arrow functions at the top level
296
- const handleOperationCreated = operation => processOperation(operation, 'add');
297
- const handleOperationUpdated = operation => processOperation(operation, 'update');
298
- const handleOperationMutated = operation => processOperation(operation, 'update');
299
- const handleOperationConfirmed = operation => processOperation(operation, 'confirm');
300
- const handleOperationRejected = operation => processOperation(operation, 'reject');
301
- /**
302
- * Initialize the operation event handler system by setting up event listeners
303
- */
304
- export function initEventHandler() {
305
- operationEvents.on(Status.CREATED, handleOperationCreated);
306
- operationEvents.on(Status.UPDATED, handleOperationUpdated);
307
- operationEvents.on(Status.CONFIRMED, handleOperationConfirmed);
308
- operationEvents.on(Status.REJECTED, handleOperationRejected);
309
- operationEvents.on(Status.MUTATED, handleOperationMutated);
310
- console.log('Operation event handler initialized');
311
- }
312
- /**
313
- * Clean up by removing all event listeners
314
- */
315
- export function cleanupEventHandler() {
316
- operationEvents.off(Status.CREATED, handleOperationCreated);
317
- operationEvents.off(Status.UPDATED, handleOperationUpdated);
318
- operationEvents.off(Status.CONFIRMED, handleOperationConfirmed);
319
- operationEvents.off(Status.REJECTED, handleOperationRejected);
320
- operationEvents.off(Status.MUTATED, handleOperationMutated);
321
- console.log('Operation event handler cleaned up');
322
- }
@@ -1,60 +0,0 @@
1
- export class QuerysetStore {
2
- constructor(modelClass: any, fetchFn: any, queryset: any, initialGroundTruthPks?: null, initialOperations?: null, options?: {});
3
- modelClass: any;
4
- fetchFn: any;
5
- queryset: any;
6
- operationsMap: Map<any, any>;
7
- groundTruthPks: never[];
8
- isSyncing: boolean;
9
- lastSync: number | null;
10
- isTemp: any;
11
- pruneThreshold: any;
12
- includedPks: Map<any, any>;
13
- qsCache: Cache;
14
- _lastRenderedPks: any[] | null;
15
- renderCallbacks: Set<any>;
16
- _modelStoreUnregister: any;
17
- get cacheKey(): any;
18
- onHydrated(hydratedData: any): void;
19
- setCache(result: any): void;
20
- clearCache(): void;
21
- get operations(): any[];
22
- get pkField(): any;
23
- get groundTruthSet(): Set<never>;
24
- _emitRenderEvent(): void;
25
- addOperation(operation: any): Promise<void>;
26
- updateOperation(operation: any): Promise<true | undefined>;
27
- confirm(operation: any): Promise<void>;
28
- reject(operation: any): Promise<void>;
29
- setGroundTruth(groundTruthPks: any): Promise<void>;
30
- setOperations(operations: any): Promise<void>;
31
- getTrimmedOperations(): any[];
32
- getInflightOperations(): any[];
33
- prune(): void;
34
- registerRenderCallback(callback: any): () => boolean;
35
- /**
36
- * Register this store with the model store for change notifications.
37
- * Called when a temp store is promoted to permanent.
38
- */
39
- registerWithModelStore(): void;
40
- /**
41
- * Helper to validate PKs against the model store and apply local filtering/sorting.
42
- * This is the core of the rendering logic.
43
- * @private
44
- */
45
- private _getValidatedAndFilteredPks;
46
- render(optimistic?: boolean, fromCache?: boolean): any[];
47
- renderFromData(optimistic?: boolean): any[];
48
- /**
49
- * Render by getting all instances from the model store and filtering locally.
50
- * Used when a queryset has no ground truth (temp stores, newly created stores, etc.)
51
- */
52
- renderFromModelStore(): any[];
53
- applyOperation(operation: any, currentPks: any): any;
54
- /**
55
- * Sync this queryset with the database.
56
- * Fetches from DB and sets ground truth.
57
- */
58
- sync(): Promise<void>;
59
- }
60
- import { Cache } from '../cache/cache.js';
@@ -1,294 +0,0 @@
1
- import { Operation, Status, Type, operationRegistry } from './operation.js';
2
- import { querysetEventEmitter } from './reactivity.js';
3
- import { isNil, isEmpty, trim, isEqual } from 'lodash-es';
4
- import { replaceTempPks, containsTempPk } from '../../flavours/django/tempPk.js';
5
- import { modelStoreRegistry } from '../registries/modelStoreRegistry.js';
6
- import { processIncludedEntities } from '../../flavours/django/makeApiCall.js';
7
- import { Cache } from '../cache/cache.js';
8
- import { filter } from "../../filtering/localFiltering.js";
9
- export class QuerysetStore {
10
- constructor(modelClass, fetchFn, queryset, initialGroundTruthPks = null, initialOperations = null, options = {}) {
11
- this.modelClass = modelClass;
12
- this.fetchFn = fetchFn;
13
- this.queryset = queryset;
14
- this.isSyncing = false;
15
- this.lastSync = null;
16
- this.isTemp = options.isTemp || false;
17
- this.pruneThreshold = options.pruneThreshold || 10;
18
- this.groundTruthPks = initialGroundTruthPks || [];
19
- this.operationsMap = new Map();
20
- // Track which model PKs are in this queryset's included data
21
- // Map<modelName, Set<pk>>
22
- this.includedPks = new Map();
23
- if (Array.isArray(initialOperations)) {
24
- for (const opData of initialOperations) {
25
- const existing = operationRegistry.get(opData.operationId);
26
- const op = existing || new Operation(opData, true);
27
- this.operationsMap.set(op.operationId, op);
28
- }
29
- }
30
- this.qsCache = new Cache("queryset-cache", {}, this.onHydrated.bind(this));
31
- this._lastRenderedPks = null;
32
- this.renderCallbacks = new Set();
33
- // Register for model store changes to re-render when model data changes
34
- // Only register permanent stores - temp stores are transient and should not
35
- // accumulate callbacks (causes reactivity cascade when Vue creates new querysets)
36
- if (!this.isTemp) {
37
- const modelStore = modelStoreRegistry.getStore(this.modelClass);
38
- this._modelStoreUnregister = modelStore.registerRenderCallback(() => {
39
- this._emitRenderEvent();
40
- });
41
- }
42
- }
43
- // Caching
44
- get cacheKey() {
45
- return this.queryset.semanticKey;
46
- }
47
- onHydrated(hydratedData) {
48
- if (this.groundTruthPks.length === 0 && this.operationsMap.size === 0) {
49
- const cached = this.qsCache.get(this.cacheKey);
50
- if (!isNil(cached) && !isEmpty(cached)) {
51
- console.log(`[QuerysetStore] Hydrated ${this.modelClass.modelName} queryset with ${cached.length} items from cache`);
52
- this.setGroundTruth(cached);
53
- }
54
- }
55
- }
56
- setCache(result) {
57
- let nonTempPks = [];
58
- result.forEach((pk) => {
59
- if (typeof pk === "string" && containsTempPk(pk)) {
60
- pk = replaceTempPks(pk);
61
- if (isNil(pk) || isEmpty(trim(pk))) {
62
- return;
63
- }
64
- }
65
- nonTempPks.push(pk);
66
- });
67
- this.qsCache.set(this.cacheKey, nonTempPks);
68
- }
69
- clearCache() {
70
- this.qsCache.delete(this.cacheKey);
71
- }
72
- // -- Core methods --
73
- get operations() {
74
- return Array.from(this.operationsMap.values());
75
- }
76
- get pkField() {
77
- return this.modelClass.primaryKeyField;
78
- }
79
- get groundTruthSet() {
80
- return new Set(this.groundTruthPks);
81
- }
82
- _emitRenderEvent() {
83
- const newPks = this.render(true, false);
84
- // 1. Always notify direct child stores to trigger their own re-evaluation.
85
- // They will perform their own check to see if their own results have changed.
86
- this.renderCallbacks.forEach((callback) => {
87
- try {
88
- callback();
89
- }
90
- catch (error) {
91
- console.warn("Error in render callback:", error);
92
- }
93
- });
94
- // 2. Only emit the global event for UI components if the final list of PKs has actually changed.
95
- if (!isEqual(newPks, this._lastRenderedPks)) {
96
- this._lastRenderedPks = newPks; // Update the cache with the new state
97
- querysetEventEmitter.emit(`${this.modelClass.configKey}::${this.modelClass.modelName}::queryset::render`, { ast: this.queryset.build(), ModelClass: this.modelClass });
98
- }
99
- }
100
- async addOperation(operation) {
101
- this.operationsMap.set(operation.operationId, operation);
102
- if (this.operationsMap.size > this.pruneThreshold) {
103
- this.prune();
104
- }
105
- this._emitRenderEvent();
106
- }
107
- async updateOperation(operation) {
108
- if (!this.operationsMap.has(operation.operationId))
109
- return;
110
- this.operationsMap.set(operation.operationId, operation);
111
- this._emitRenderEvent();
112
- return true;
113
- }
114
- async confirm(operation) {
115
- if (!this.operationsMap.has(operation.operationId))
116
- return;
117
- this.operationsMap.set(operation.operationId, operation);
118
- this._emitRenderEvent();
119
- }
120
- async reject(operation) {
121
- if (!this.operationsMap.has(operation.operationId))
122
- return;
123
- this.operationsMap.set(operation.operationId, operation);
124
- this._emitRenderEvent();
125
- }
126
- async setGroundTruth(groundTruthPks) {
127
- this.groundTruthPks = Array.isArray(groundTruthPks) ? groundTruthPks : [];
128
- this.lastSync = Date.now();
129
- this._emitRenderEvent();
130
- }
131
- async setOperations(operations) {
132
- this.operationsMap.clear();
133
- if (Array.isArray(operations)) {
134
- for (const op of operations) {
135
- this.operationsMap.set(op.operationId, op);
136
- }
137
- }
138
- this._emitRenderEvent();
139
- }
140
- getTrimmedOperations() {
141
- const cutoff = Date.now() - 1000 * 60 * 2;
142
- return this.operations.filter((op) => op.timestamp > cutoff);
143
- }
144
- getInflightOperations() {
145
- return this.operations.filter((operation) => operation.status != Status.CONFIRMED &&
146
- operation.status != Status.REJECTED);
147
- }
148
- prune() {
149
- const renderedPks = this.render(false);
150
- this.setGroundTruth(renderedPks);
151
- this.setOperations(this.getInflightOperations());
152
- }
153
- registerRenderCallback(callback) {
154
- this.renderCallbacks.add(callback);
155
- return () => this.renderCallbacks.delete(callback);
156
- }
157
- /**
158
- * Register this store with the model store for change notifications.
159
- * Called when a temp store is promoted to permanent.
160
- */
161
- registerWithModelStore() {
162
- if (this._modelStoreUnregister)
163
- return; // Already registered
164
- const modelStore = modelStoreRegistry.getStore(this.modelClass);
165
- this._modelStoreUnregister = modelStore.registerRenderCallback(() => {
166
- this._emitRenderEvent();
167
- });
168
- }
169
- /**
170
- * Helper to validate PKs against the model store and apply local filtering/sorting.
171
- * This is the core of the rendering logic.
172
- * @private
173
- */
174
- _getValidatedAndFilteredPks(pks) {
175
- // 1. Convert PKs to instances, filtering out any that are null (deleted).
176
- const instances = Array.from(pks)
177
- .map((pk) => this.modelClass.fromPk(pk, this.queryset))
178
- .filter((instance) => modelStoreRegistry.getEntity(this.modelClass, instance.pk) !== null);
179
- // 2. Apply the queryset's AST (filters, ordering) to the validated instances.
180
- const ast = this.queryset.build();
181
- const finalPks = filter(instances, ast, this.modelClass, false); // false = return PKs
182
- return finalPks;
183
- }
184
- render(optimistic = true, fromCache = false) {
185
- // Check cache first if requested
186
- if (fromCache) {
187
- const cachedResult = this.qsCache.get(this.cacheKey);
188
- if (Array.isArray(cachedResult)) {
189
- return cachedResult;
190
- }
191
- }
192
- // If no ground truth AND hasn't been synced, render from model store
193
- // This handles chained optimistic filters, newly created stores, etc.
194
- // (If synced with empty results, that's valid ground truth)
195
- const pks = this.groundTruthPks.length === 0 && this.lastSync === null
196
- ? this.renderFromModelStore()
197
- : this.renderFromData(optimistic);
198
- // Validate against model store and apply local filtering/sorting
199
- let result = this._getValidatedAndFilteredPks(pks);
200
- // Apply pagination limit
201
- const limit = this.queryset.build().serializerOptions?.limit;
202
- if (limit) {
203
- result = result.slice(0, limit);
204
- }
205
- this.setCache(result);
206
- return result;
207
- }
208
- renderFromData(optimistic = true) {
209
- const renderedPks = this.groundTruthSet;
210
- for (const op of this.operations) {
211
- if (op.status !== Status.REJECTED &&
212
- (optimistic || op.status === Status.CONFIRMED)) {
213
- this.applyOperation(op, renderedPks);
214
- }
215
- }
216
- let result = Array.from(renderedPks);
217
- return result;
218
- }
219
- /**
220
- * Render by getting all instances from the model store and filtering locally.
221
- * Used when a queryset has no ground truth (temp stores, newly created stores, etc.)
222
- */
223
- renderFromModelStore() {
224
- const modelStore = modelStoreRegistry.getStore(this.modelClass);
225
- const allPks = modelStore.groundTruthPks;
226
- const allInstances = allPks.map((pk) => this.modelClass.fromPk(pk, this.queryset));
227
- const ast = this.queryset.build();
228
- return filter(allInstances, ast, this.modelClass, false);
229
- }
230
- applyOperation(operation, currentPks) {
231
- const pkField = this.pkField;
232
- for (const instance of operation.instances) {
233
- if (!instance || typeof instance !== "object" || !(pkField in instance)) {
234
- console.warn(`[QuerysetStore ${this.modelClass.modelName}] Skipping instance in operation ${operation.operationId} due to missing PK '${String(pkField)}' or invalid format.`);
235
- continue;
236
- }
237
- let pk = instance[pkField];
238
- switch (operation.type) {
239
- case Type.CREATE:
240
- case Type.BULK_CREATE:
241
- currentPks.add(pk);
242
- break;
243
- case Type.CHECKPOINT:
244
- case Type.UPDATE:
245
- case Type.UPDATE_INSTANCE:
246
- break;
247
- case Type.DELETE:
248
- case Type.DELETE_INSTANCE:
249
- currentPks.delete(pk);
250
- break;
251
- default:
252
- console.error(`[QuerysetStore ${this.modelClass.modelName}] Unknown operation type: ${operation.type}`);
253
- }
254
- }
255
- return currentPks;
256
- }
257
- /**
258
- * Sync this queryset with the database.
259
- * Fetches from DB and sets ground truth.
260
- */
261
- async sync() {
262
- const id = this.modelClass.modelName;
263
- if (this.isSyncing) {
264
- console.warn(`[QuerysetStore ${id}] Already syncing, request ignored.`);
265
- return;
266
- }
267
- this.isSyncing = true;
268
- console.log(`[${id}] Starting sync...`);
269
- try {
270
- const response = await this.fetchFn({
271
- ast: this.queryset.build(),
272
- modelClass: this.modelClass,
273
- });
274
- const { data, included } = response;
275
- if (!isNil(data)) {
276
- console.log(`[${id}] Sync fetch completed. Received: ${JSON.stringify(data)}.`);
277
- // Clear previous included PKs tracking before processing new data
278
- this.includedPks.clear();
279
- // Persist all instances (including nested) to the model store
280
- processIncludedEntities(modelStoreRegistry, included, this.modelClass, this.queryset);
281
- this.setGroundTruth(data);
282
- }
283
- this.setOperations(this.getInflightOperations());
284
- this.lastSync = Date.now();
285
- console.log(`[${id}] Sync completed.`);
286
- }
287
- catch (e) {
288
- console.error(`[${id}] Failed to sync ground truth:`, e);
289
- }
290
- finally {
291
- this.isSyncing = false;
292
- }
293
- }
294
- }
@@ -1,3 +0,0 @@
1
- export const modelEventEmitter: any;
2
- export const querysetEventEmitter: any;
3
- export const metricEventEmitter: any;
@@ -1,4 +0,0 @@
1
- import mitt from 'mitt';
2
- export const modelEventEmitter = mitt();
3
- export const querysetEventEmitter = mitt();
4
- export const metricEventEmitter = mitt();