@statezero/core 0.2.38 → 0.2.39

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 (294) hide show
  1. package/dist/actions/backend1/django_app/calculate-hash.d.ts +57 -0
  2. package/dist/actions/backend1/django_app/calculate-hash.js +80 -0
  3. package/dist/actions/backend1/django_app/calculate-hash.schema.json +148 -0
  4. package/dist/actions/backend1/django_app/get-current-username.d.ts +29 -0
  5. package/dist/actions/backend1/django_app/get-current-username.js +65 -0
  6. package/dist/actions/backend1/django_app/get-current-username.schema.json +47 -0
  7. package/dist/actions/backend1/django_app/get-server-status.d.ts +38 -0
  8. package/dist/actions/backend1/django_app/get-server-status.js +68 -0
  9. package/dist/actions/backend1/django_app/get-server-status.schema.json +93 -0
  10. package/dist/actions/backend1/django_app/get-user-info.d.ts +44 -0
  11. package/dist/actions/backend1/django_app/get-user-info.js +70 -0
  12. package/dist/actions/backend1/django_app/get-user-info.schema.json +127 -0
  13. package/dist/actions/backend1/django_app/index.d.ts +1 -0
  14. package/dist/actions/backend1/django_app/index.js +6 -0
  15. package/dist/actions/backend1/django_app/process-data.d.ts +51 -0
  16. package/dist/actions/backend1/django_app/process-data.js +78 -0
  17. package/dist/actions/backend1/django_app/process-data.schema.json +117 -0
  18. package/dist/actions/backend1/django_app/send-notification.d.ts +55 -0
  19. package/dist/actions/backend1/django_app/send-notification.js +81 -0
  20. package/dist/actions/backend1/django_app/send-notification.schema.json +175 -0
  21. package/dist/actions/backend1/index.d.ts +1 -0
  22. package/dist/actions/backend1/index.js +1 -0
  23. package/dist/actions/default/django_app/calculate-hash.d.ts +57 -0
  24. package/dist/actions/default/django_app/calculate-hash.js +80 -0
  25. package/dist/actions/default/django_app/calculate-hash.schema.json +148 -0
  26. package/dist/actions/default/django_app/get-current-username.d.ts +29 -0
  27. package/dist/actions/default/django_app/get-current-username.js +65 -0
  28. package/dist/actions/default/django_app/get-current-username.schema.json +47 -0
  29. package/dist/actions/default/django_app/get-server-status.d.ts +38 -0
  30. package/dist/actions/default/django_app/get-server-status.js +68 -0
  31. package/dist/actions/default/django_app/get-server-status.schema.json +93 -0
  32. package/dist/actions/default/django_app/get-user-info.d.ts +44 -0
  33. package/dist/actions/default/django_app/get-user-info.js +70 -0
  34. package/dist/actions/default/django_app/get-user-info.schema.json +127 -0
  35. package/dist/actions/default/django_app/index.d.ts +1 -0
  36. package/dist/actions/default/django_app/index.js +6 -0
  37. package/dist/actions/default/django_app/process-data.d.ts +51 -0
  38. package/dist/actions/default/django_app/process-data.js +78 -0
  39. package/dist/actions/default/django_app/process-data.schema.json +117 -0
  40. package/dist/actions/default/django_app/send-notification.d.ts +55 -0
  41. package/dist/actions/default/django_app/send-notification.js +81 -0
  42. package/dist/actions/default/django_app/send-notification.schema.json +175 -0
  43. package/dist/actions/default/index.d.ts +1 -0
  44. package/dist/actions/default/index.js +1 -0
  45. package/dist/actions/index.d.ts +1 -0
  46. package/dist/actions/index.js +5 -0
  47. package/dist/adaptors/react/composables.d.ts +1 -0
  48. package/dist/adaptors/react/composables.js +4 -0
  49. package/dist/adaptors/react/index.d.ts +1 -0
  50. package/dist/adaptors/react/index.js +1 -0
  51. package/dist/adaptors/vue/components/LayoutRenderer.js +46 -49
  52. package/dist/adaptors/vue/components/defaults/index.d.ts +7 -0
  53. package/dist/adaptors/vue/components/defaults/index.js +31 -0
  54. package/dist/adaptors/vue/components/index.d.ts +1 -0
  55. package/dist/adaptors/vue/components/index.js +7 -0
  56. package/dist/adaptors/vue/composables.d.ts +2 -0
  57. package/dist/adaptors/vue/composables.js +44 -0
  58. package/dist/adaptors/vue/index.d.ts +3 -0
  59. package/dist/adaptors/vue/index.js +4 -0
  60. package/dist/adaptors/vue/reactivity.d.ts +18 -0
  61. package/dist/adaptors/vue/reactivity.js +132 -0
  62. package/dist/cli/commands/sync.d.ts +6 -0
  63. package/dist/cli/commands/sync.js +30 -0
  64. package/dist/cli/commands/syncActions.d.ts +46 -0
  65. package/dist/cli/commands/syncActions.js +717 -0
  66. package/dist/cli/commands/syncModels.d.ts +132 -0
  67. package/dist/cli/commands/syncModels.js +1120 -0
  68. package/dist/cli/configFileLoader.d.ts +10 -0
  69. package/dist/cli/configFileLoader.js +85 -0
  70. package/dist/cli/index.d.ts +2 -0
  71. package/dist/cli/index.js +22 -0
  72. package/dist/config.d.ts +57 -0
  73. package/dist/config.js +273 -0
  74. package/dist/core/eventReceivers.d.ts +185 -0
  75. package/dist/core/eventReceivers.js +266 -0
  76. package/dist/core/utils.d.ts +8 -0
  77. package/dist/core/utils.js +62 -0
  78. package/dist/errorHandler.d.ts +21 -0
  79. package/dist/errorHandler.js +27 -0
  80. package/dist/filtering/localFiltering.d.ts +110 -0
  81. package/dist/filtering/localFiltering.js +1080 -0
  82. package/dist/flavours/django/dates.d.ts +34 -0
  83. package/dist/flavours/django/dates.js +113 -0
  84. package/dist/flavours/django/errors.d.ts +138 -0
  85. package/dist/flavours/django/errors.js +195 -0
  86. package/dist/flavours/django/f.d.ts +6 -0
  87. package/dist/flavours/django/f.js +91 -0
  88. package/dist/flavours/django/files.d.ts +62 -0
  89. package/dist/flavours/django/files.js +355 -0
  90. package/dist/flavours/django/makeApiCall.d.ts +36 -0
  91. package/dist/flavours/django/makeApiCall.js +169 -0
  92. package/dist/flavours/django/manager.d.ts +204 -0
  93. package/dist/flavours/django/manager.js +222 -0
  94. package/dist/flavours/django/model.d.ts +137 -0
  95. package/dist/flavours/django/model.js +366 -0
  96. package/dist/flavours/django/operationFactory.d.ts +73 -0
  97. package/dist/flavours/django/operationFactory.js +248 -0
  98. package/dist/flavours/django/q.d.ts +70 -0
  99. package/dist/flavours/django/q.js +43 -0
  100. package/dist/flavours/django/queryExecutor.d.ts +149 -0
  101. package/dist/flavours/django/queryExecutor.js +590 -0
  102. package/dist/flavours/django/querySet.d.ts +301 -0
  103. package/dist/flavours/django/querySet.js +736 -0
  104. package/dist/flavours/django/serializers.d.ts +39 -0
  105. package/dist/flavours/django/serializers.js +296 -0
  106. package/dist/flavours/django/tempPk.d.ts +31 -0
  107. package/dist/flavours/django/tempPk.js +92 -0
  108. package/dist/flavours/django/utils.d.ts +19 -0
  109. package/dist/flavours/django/utils.js +29 -0
  110. package/dist/index.d.ts +46 -0
  111. package/dist/index.js +48 -0
  112. package/dist/models/backend1/django_app/comprehensivemodel.d.ts +894 -0
  113. package/dist/models/backend1/django_app/comprehensivemodel.js +71 -0
  114. package/dist/models/backend1/django_app/comprehensivemodel.schema.json +870 -0
  115. package/dist/models/backend1/django_app/custompkmodel.d.ts +92 -0
  116. package/dist/models/backend1/django_app/custompkmodel.js +69 -0
  117. package/dist/models/backend1/django_app/custompkmodel.schema.json +71 -0
  118. package/dist/models/backend1/django_app/dailyrate.d.ts +230 -0
  119. package/dist/models/backend1/django_app/dailyrate.js +71 -0
  120. package/dist/models/backend1/django_app/dailyrate.schema.json +212 -0
  121. package/dist/models/backend1/django_app/deepmodellevel1.d.ts +140 -0
  122. package/dist/models/backend1/django_app/deepmodellevel1.js +72 -0
  123. package/dist/models/backend1/django_app/deepmodellevel1.schema.json +114 -0
  124. package/dist/models/backend1/django_app/deepmodellevel2.d.ts +118 -0
  125. package/dist/models/backend1/django_app/deepmodellevel2.js +71 -0
  126. package/dist/models/backend1/django_app/deepmodellevel2.schema.json +92 -0
  127. package/dist/models/backend1/django_app/deepmodellevel3.d.ts +92 -0
  128. package/dist/models/backend1/django_app/deepmodellevel3.js +69 -0
  129. package/dist/models/backend1/django_app/deepmodellevel3.schema.json +69 -0
  130. package/dist/models/backend1/django_app/dummymodel.d.ts +134 -0
  131. package/dist/models/backend1/django_app/dummymodel.js +71 -0
  132. package/dist/models/backend1/django_app/dummymodel.schema.json +109 -0
  133. package/dist/models/backend1/django_app/dummyrelatedmodel.d.ts +92 -0
  134. package/dist/models/backend1/django_app/dummyrelatedmodel.js +69 -0
  135. package/dist/models/backend1/django_app/dummyrelatedmodel.schema.json +69 -0
  136. package/dist/models/backend1/django_app/filetest.d.ts +140 -0
  137. package/dist/models/backend1/django_app/filetest.js +69 -0
  138. package/dist/models/backend1/django_app/filetest.schema.json +111 -0
  139. package/dist/models/backend1/django_app/index.d.ts +1 -0
  140. package/dist/models/backend1/django_app/index.js +21 -0
  141. package/dist/models/backend1/django_app/m2mdepthtestlevel1.d.ts +118 -0
  142. package/dist/models/backend1/django_app/m2mdepthtestlevel1.js +71 -0
  143. package/dist/models/backend1/django_app/m2mdepthtestlevel1.schema.json +94 -0
  144. package/dist/models/backend1/django_app/m2mdepthtestlevel2.d.ts +118 -0
  145. package/dist/models/backend1/django_app/m2mdepthtestlevel2.js +71 -0
  146. package/dist/models/backend1/django_app/m2mdepthtestlevel2.schema.json +94 -0
  147. package/dist/models/backend1/django_app/m2mdepthtestlevel3.d.ts +134 -0
  148. package/dist/models/backend1/django_app/m2mdepthtestlevel3.js +71 -0
  149. package/dist/models/backend1/django_app/m2mdepthtestlevel3.schema.json +112 -0
  150. package/dist/models/backend1/django_app/modelwithcustompkrelation.d.ts +118 -0
  151. package/dist/models/backend1/django_app/modelwithcustompkrelation.js +71 -0
  152. package/dist/models/backend1/django_app/modelwithcustompkrelation.schema.json +93 -0
  153. package/dist/models/backend1/django_app/modelwithrestrictedfields.d.ts +134 -0
  154. package/dist/models/backend1/django_app/modelwithrestrictedfields.js +71 -0
  155. package/dist/models/backend1/django_app/modelwithrestrictedfields.schema.json +111 -0
  156. package/dist/models/backend1/django_app/namefiltercustompkmodel.d.ts +92 -0
  157. package/dist/models/backend1/django_app/namefiltercustompkmodel.js +69 -0
  158. package/dist/models/backend1/django_app/namefiltercustompkmodel.schema.json +71 -0
  159. package/dist/models/backend1/django_app/order.d.ts +220 -0
  160. package/dist/models/backend1/django_app/order.js +71 -0
  161. package/dist/models/backend1/django_app/order.schema.json +203 -0
  162. package/dist/models/backend1/django_app/orderitem.d.ts +172 -0
  163. package/dist/models/backend1/django_app/orderitem.js +72 -0
  164. package/dist/models/backend1/django_app/orderitem.schema.json +149 -0
  165. package/dist/models/backend1/django_app/product.d.ts +254 -0
  166. package/dist/models/backend1/django_app/product.js +71 -0
  167. package/dist/models/backend1/django_app/product.schema.json +277 -0
  168. package/dist/models/backend1/django_app/productcategory.d.ts +92 -0
  169. package/dist/models/backend1/django_app/productcategory.js +69 -0
  170. package/dist/models/backend1/django_app/productcategory.schema.json +70 -0
  171. package/dist/models/backend1/django_app/rateplan.d.ts +92 -0
  172. package/dist/models/backend1/django_app/rateplan.js +69 -0
  173. package/dist/models/backend1/django_app/rateplan.schema.json +70 -0
  174. package/dist/models/backend1/django_app/restrictedfieldrelatedmodel.d.ts +108 -0
  175. package/dist/models/backend1/django_app/restrictedfieldrelatedmodel.js +69 -0
  176. package/dist/models/backend1/django_app/restrictedfieldrelatedmodel.schema.json +87 -0
  177. package/dist/models/backend1/fileobject.d.ts +4 -0
  178. package/dist/models/backend1/fileobject.js +9 -0
  179. package/dist/models/backend1/index.d.ts +2 -0
  180. package/dist/models/backend1/index.js +2 -0
  181. package/dist/models/default/django_app/comprehensivemodel.d.ts +894 -0
  182. package/dist/models/default/django_app/comprehensivemodel.js +71 -0
  183. package/dist/models/default/django_app/comprehensivemodel.schema.json +870 -0
  184. package/dist/models/default/django_app/custompkmodel.d.ts +92 -0
  185. package/dist/models/default/django_app/custompkmodel.js +69 -0
  186. package/dist/models/default/django_app/custompkmodel.schema.json +71 -0
  187. package/dist/models/default/django_app/dailyrate.d.ts +230 -0
  188. package/dist/models/default/django_app/dailyrate.js +71 -0
  189. package/dist/models/default/django_app/dailyrate.schema.json +212 -0
  190. package/dist/models/default/django_app/deepmodellevel1.d.ts +128 -0
  191. package/dist/models/default/django_app/deepmodellevel1.js +72 -0
  192. package/dist/models/default/django_app/deepmodellevel1.schema.json +102 -0
  193. package/dist/models/default/django_app/deepmodellevel2.d.ts +106 -0
  194. package/dist/models/default/django_app/deepmodellevel2.js +71 -0
  195. package/dist/models/default/django_app/deepmodellevel2.schema.json +80 -0
  196. package/dist/models/default/django_app/deepmodellevel3.d.ts +80 -0
  197. package/dist/models/default/django_app/deepmodellevel3.js +69 -0
  198. package/dist/models/default/django_app/deepmodellevel3.schema.json +57 -0
  199. package/dist/models/default/django_app/dummymodel.d.ts +122 -0
  200. package/dist/models/default/django_app/dummymodel.js +71 -0
  201. package/dist/models/default/django_app/dummymodel.schema.json +97 -0
  202. package/dist/models/default/django_app/dummyrelatedmodel.d.ts +80 -0
  203. package/dist/models/default/django_app/dummyrelatedmodel.js +69 -0
  204. package/dist/models/default/django_app/dummyrelatedmodel.schema.json +57 -0
  205. package/dist/models/default/django_app/filetest.d.ts +128 -0
  206. package/dist/models/default/django_app/filetest.js +69 -0
  207. package/dist/models/default/django_app/filetest.schema.json +99 -0
  208. package/dist/models/default/django_app/index.d.ts +1 -0
  209. package/dist/models/default/django_app/index.js +21 -0
  210. package/dist/models/default/django_app/m2mdepthtestlevel1.d.ts +118 -0
  211. package/dist/models/default/django_app/m2mdepthtestlevel1.js +71 -0
  212. package/dist/models/default/django_app/m2mdepthtestlevel1.schema.json +94 -0
  213. package/dist/models/default/django_app/m2mdepthtestlevel2.d.ts +118 -0
  214. package/dist/models/default/django_app/m2mdepthtestlevel2.js +71 -0
  215. package/dist/models/default/django_app/m2mdepthtestlevel2.schema.json +94 -0
  216. package/dist/models/default/django_app/m2mdepthtestlevel3.d.ts +134 -0
  217. package/dist/models/default/django_app/m2mdepthtestlevel3.js +71 -0
  218. package/dist/models/default/django_app/m2mdepthtestlevel3.schema.json +112 -0
  219. package/dist/models/default/django_app/modelwithcustompkrelation.d.ts +118 -0
  220. package/dist/models/default/django_app/modelwithcustompkrelation.js +71 -0
  221. package/dist/models/default/django_app/modelwithcustompkrelation.schema.json +93 -0
  222. package/dist/models/default/django_app/modelwithrestrictedfields.d.ts +134 -0
  223. package/dist/models/default/django_app/modelwithrestrictedfields.js +71 -0
  224. package/dist/models/default/django_app/modelwithrestrictedfields.schema.json +111 -0
  225. package/dist/models/default/django_app/namefiltercustompkmodel.d.ts +92 -0
  226. package/dist/models/default/django_app/namefiltercustompkmodel.js +69 -0
  227. package/dist/models/default/django_app/namefiltercustompkmodel.schema.json +71 -0
  228. package/dist/models/default/django_app/order.d.ts +220 -0
  229. package/dist/models/default/django_app/order.js +71 -0
  230. package/dist/models/default/django_app/order.schema.json +203 -0
  231. package/dist/models/default/django_app/orderitem.d.ts +172 -0
  232. package/dist/models/default/django_app/orderitem.js +72 -0
  233. package/dist/models/default/django_app/orderitem.schema.json +149 -0
  234. package/dist/models/default/django_app/product.d.ts +254 -0
  235. package/dist/models/default/django_app/product.js +71 -0
  236. package/dist/models/default/django_app/product.schema.json +277 -0
  237. package/dist/models/default/django_app/productcategory.d.ts +92 -0
  238. package/dist/models/default/django_app/productcategory.js +69 -0
  239. package/dist/models/default/django_app/productcategory.schema.json +70 -0
  240. package/dist/models/default/django_app/rateplan.d.ts +92 -0
  241. package/dist/models/default/django_app/rateplan.js +69 -0
  242. package/dist/models/default/django_app/rateplan.schema.json +70 -0
  243. package/dist/models/default/django_app/restrictedfieldrelatedmodel.d.ts +108 -0
  244. package/dist/models/default/django_app/restrictedfieldrelatedmodel.js +69 -0
  245. package/dist/models/default/django_app/restrictedfieldrelatedmodel.schema.json +87 -0
  246. package/dist/models/default/fileobject.d.ts +4 -0
  247. package/dist/models/default/fileobject.js +9 -0
  248. package/dist/models/default/index.d.ts +2 -0
  249. package/dist/models/default/index.js +2 -0
  250. package/dist/models/index.d.ts +1 -0
  251. package/dist/models/index.js +5 -0
  252. package/dist/react-entry.d.ts +2 -0
  253. package/dist/react-entry.js +2 -0
  254. package/dist/reactiveAdaptor.d.ts +24 -0
  255. package/dist/reactiveAdaptor.js +38 -0
  256. package/dist/reset.d.ts +15 -0
  257. package/dist/reset.js +97 -0
  258. package/dist/setup.d.ts +15 -0
  259. package/dist/setup.js +33 -0
  260. package/dist/syncEngine/cache/cache.d.ts +75 -0
  261. package/dist/syncEngine/cache/cache.js +355 -0
  262. package/dist/syncEngine/metrics/metricOptCalcs.d.ts +79 -0
  263. package/dist/syncEngine/metrics/metricOptCalcs.js +284 -0
  264. package/dist/syncEngine/registries/metricRegistry.d.ts +58 -0
  265. package/dist/syncEngine/registries/metricRegistry.js +171 -0
  266. package/dist/syncEngine/registries/modelStoreRegistry.d.ts +11 -0
  267. package/dist/syncEngine/registries/modelStoreRegistry.js +63 -0
  268. package/dist/syncEngine/registries/querysetStoreGraph.d.ts +41 -0
  269. package/dist/syncEngine/registries/querysetStoreGraph.js +174 -0
  270. package/dist/syncEngine/registries/querysetStoreRegistry.d.ts +72 -0
  271. package/dist/syncEngine/registries/querysetStoreRegistry.js +335 -0
  272. package/dist/syncEngine/stores/metricStore.d.ts +55 -0
  273. package/dist/syncEngine/stores/metricStore.js +222 -0
  274. package/dist/syncEngine/stores/modelStore.d.ts +53 -0
  275. package/dist/syncEngine/stores/modelStore.js +565 -0
  276. package/dist/syncEngine/stores/operation.d.ts +139 -0
  277. package/dist/syncEngine/stores/operation.js +291 -0
  278. package/dist/syncEngine/stores/operationEventHandlers.d.ts +8 -0
  279. package/dist/syncEngine/stores/operationEventHandlers.js +322 -0
  280. package/dist/syncEngine/stores/querysetStore.d.ts +60 -0
  281. package/dist/syncEngine/stores/querysetStore.js +294 -0
  282. package/dist/syncEngine/stores/reactivity.d.ts +3 -0
  283. package/dist/syncEngine/stores/reactivity.js +4 -0
  284. package/dist/syncEngine/stores/utils.d.ts +14 -0
  285. package/dist/syncEngine/stores/utils.js +32 -0
  286. package/dist/syncEngine/sync.d.ts +46 -0
  287. package/dist/syncEngine/sync.js +389 -0
  288. package/dist/testing.d.ts +63 -0
  289. package/dist/testing.js +175 -0
  290. package/dist/vue-entry.d.ts +15 -0
  291. package/dist/vue-entry.js +7 -0
  292. package/package.json +6 -7
  293. package/dist/adaptors/vue/components/layout.tailwind.css +0 -51
  294. /package/{dist → src}/adaptors/vue/components/layout.css +0 -0
@@ -0,0 +1,174 @@
1
+ import { Graph } from "graphlib";
2
+ /**
3
+ * Simple graph for tracking queryset store ancestry
4
+ */
5
+ export class QuerysetStoreGraph {
6
+ constructor() {
7
+ this.graph = new Graph({ directed: true });
8
+ this.processedQuerysets = new Set(); // Track UUIDs of processed querysets
9
+ }
10
+ /**
11
+ * Add a queryset and its parent relationship to the graph
12
+ */
13
+ addQueryset(queryset) {
14
+ if (!queryset)
15
+ return;
16
+ if (this.processedQuerysets.has(queryset.key)) {
17
+ return; // Already processed, skip
18
+ }
19
+ let current = queryset;
20
+ while (current && !this.processedQuerysets.has(current.key)) {
21
+ const currentKey = current.semanticKey;
22
+ const currentUuid = current.key;
23
+ this.processedQuerysets.add(currentUuid);
24
+ this.graph.setNode(currentKey);
25
+ if (current.__parent) {
26
+ const parentKey = current.__parent.semanticKey;
27
+ this.graph.setNode(parentKey);
28
+ // Determine if we can create an edge to parent
29
+ // Parent must be a valid data source (superset of child's data needs)
30
+ const canLinkToParent = currentKey !== parentKey &&
31
+ this._isValidParentForEdge(current.__parent._serializerOptions, current._serializerOptions, current.__parent._orderBy, current._orderBy);
32
+ if (canLinkToParent) {
33
+ this.graph.setEdge(currentKey, parentKey);
34
+ }
35
+ current = current.__parent;
36
+ }
37
+ else {
38
+ break;
39
+ }
40
+ }
41
+ }
42
+ /**
43
+ * Find the root (topmost ancestor) of a queryset chain within a subset.
44
+ * Traverses up the graph but only considers nodes that are in the subset.
45
+ * Uses the graph to "jump" through nodes not in subset to find connections.
46
+ *
47
+ * @param {Object} queryset - The queryset to analyze
48
+ * @param {Set|null} subset - Set of semanticKeys to consider. If null, considers all nodes in graph.
49
+ * @returns {Object} { isRoot: boolean, root: semanticKey|null }
50
+ */
51
+ findRoot(queryset, subset = null) {
52
+ // Validate input - null/undefined is a programming error
53
+ if (!queryset) {
54
+ throw new Error("findRoot was called with a null object, instead of a queryset");
55
+ }
56
+ // Handle queryset without semanticKey
57
+ if (!queryset.semanticKey) {
58
+ throw new Error("findRoot was called on an object without a semanticKey, which means its not a queryset. findRoot only works on querysets");
59
+ }
60
+ const semanticKey = queryset.semanticKey;
61
+ if (!this.graph.hasNode(semanticKey)) {
62
+ this.addQueryset(queryset);
63
+ }
64
+ // If no subset provided, consider all nodes in the graph
65
+ subset = subset || new Set(this.graph.nodes());
66
+ // Traverse ALL the way up to find the HIGHEST ancestor in the subset
67
+ const visited = new Set();
68
+ let current = semanticKey;
69
+ let highestInSubset = null;
70
+ while (current && !visited.has(current)) {
71
+ visited.add(current);
72
+ // Check if current node is in subset
73
+ if (subset.has(current)) {
74
+ highestInSubset = current;
75
+ }
76
+ // Move to parent (continue jumping even if current not in subset)
77
+ const parents = this.graph.successors(current) || [];
78
+ if (parents.length > 0) {
79
+ current = parents[0];
80
+ }
81
+ else {
82
+ break;
83
+ }
84
+ }
85
+ if (highestInSubset) {
86
+ if (highestInSubset === semanticKey) {
87
+ // This queryset itself is the highest in subset
88
+ return { isRoot: true, root: semanticKey };
89
+ }
90
+ else {
91
+ // Found a higher ancestor in subset
92
+ return { isRoot: false, root: highestInSubset };
93
+ }
94
+ }
95
+ // No nodes found in subset
96
+ return { isRoot: true, root: null };
97
+ }
98
+ /**
99
+ * Check if parent queryset is a valid data source for creating an edge.
100
+ * Parent must have data that is a superset of what child needs.
101
+ * Child with offset must sync independently (can't derive window from parent).
102
+ *
103
+ * @param {Object} parentOpts - Parent's serializerOptions
104
+ * @param {Object} childOpts - Child's serializerOptions
105
+ * @param {Array|undefined} parentOrderBy - Parent's ordering
106
+ * @param {Array|undefined} childOrderBy - Child's ordering
107
+ * @returns {boolean} - True if parent is valid for edge creation
108
+ */
109
+ _isValidParentForEdge(parentOpts = {}, childOpts = {}, parentOrderBy, childOrderBy) {
110
+ // Cannot link if parent has offset > 0 (paginated parent has subset of data)
111
+ // Note: offset: 0 is treated as no offset (start from beginning)
112
+ if (parentOpts.offset != null && parentOpts.offset > 0) {
113
+ return false;
114
+ }
115
+ // Cannot link if parent has limit - child may need items beyond parent's limit window
116
+ // (filtered items matching child could exist beyond parent's limit cutoff)
117
+ // If child has same filter + same limit, they'd have same semanticKey (no edge needed)
118
+ if (parentOpts.limit != null) {
119
+ return false;
120
+ }
121
+ // Cannot link if child has offset > 0 - must sync independently
122
+ // We can't derive which items are at positions N-M from the parent's full data
123
+ // because that requires the server's ordering logic
124
+ // Note: offset: 0 is treated as no offset (start from beginning)
125
+ if (childOpts.offset != null && childOpts.offset > 0) {
126
+ return false;
127
+ }
128
+ // Note: ordering doesn't matter for linking since parent has no limit (checked above)
129
+ // Parent has all items, so child can re-sort locally regardless of ordering
130
+ // Cannot link if parent has different depth
131
+ // Different depth means different nested data structure
132
+ if (parentOpts.depth != null && parentOpts.depth !== childOpts.depth) {
133
+ return false;
134
+ }
135
+ // Cannot link if parent has fields that are not a superset of child's fields
136
+ // Parent must have all fields that child needs
137
+ if (parentOpts.fields != null) {
138
+ // If child needs all fields (null) but parent restricts fields, cannot link
139
+ if (childOpts.fields == null) {
140
+ return false;
141
+ }
142
+ // Check if parent's fields contain all of child's fields
143
+ const parentFields = new Set(parentOpts.fields);
144
+ const childHasFieldsNotInParent = childOpts.fields.some(f => !parentFields.has(f));
145
+ if (childHasFieldsNotInParent) {
146
+ return false;
147
+ }
148
+ }
149
+ return true;
150
+ }
151
+ /**
152
+ * Check if two orderings are equivalent.
153
+ * @param {Array|undefined} orderBy1
154
+ * @param {Array|undefined} orderBy2
155
+ * @returns {boolean}
156
+ */
157
+ _orderingsMatch(orderBy1, orderBy2) {
158
+ // Both undefined/null = match
159
+ if (!orderBy1 && !orderBy2)
160
+ return true;
161
+ // One defined, one not = no match
162
+ if (!orderBy1 || !orderBy2)
163
+ return false;
164
+ // Different lengths = no match
165
+ if (orderBy1.length !== orderBy2.length)
166
+ return false;
167
+ // Compare each field
168
+ return orderBy1.every((field, i) => field === orderBy2[i]);
169
+ }
170
+ clear() {
171
+ this.graph = new Graph({ directed: true });
172
+ this.processedQuerysets = new Set();
173
+ }
174
+ }
@@ -0,0 +1,72 @@
1
+ /**
2
+ * A dynamic wrapper that always returns the latest queryset results
3
+ * This class proxies array operations to always reflect the current state
4
+ * of the underlying QuerysetStore.
5
+ */
6
+ export class LiveQueryset {
7
+ constructor(queryset: any);
8
+ /**
9
+ * Serializes the lqs as a simple array of objects, for freezing e.g in the metric stores
10
+ */
11
+ serialize(): any;
12
+ /**
13
+ * Refresh the queryset data from the database
14
+ * Delegates to the underlying store's sync method
15
+ */
16
+ refreshFromDb(): any;
17
+ /**
18
+ * Get the current items from the store
19
+ * @private
20
+ * @returns {Array} The current items in the queryset
21
+ */
22
+ private getCurrentItems;
23
+ #private;
24
+ }
25
+ export class QuerysetStoreRegistry {
26
+ _stores: Map<any, any>;
27
+ _tempStores: WeakMap<object, any>;
28
+ followingQuerysets: Map<any, any>;
29
+ syncManager: () => void;
30
+ querysetStoreGraph: QuerysetStoreGraph;
31
+ _groupSyncCache: Map<any, any>;
32
+ clear(): void;
33
+ setSyncManager(syncManager: any): void;
34
+ /**
35
+ * Add a queryset to the following set for a semantic key
36
+ */
37
+ addFollowingQueryset(semanticKey: any, queryset: any): void;
38
+ getStore(queryset: any): any;
39
+ /**
40
+ * Get the current state of the queryset, wrapped in a LiveQueryset
41
+ * @param {Object} queryset - The queryset
42
+ * @param {Boolean} sync - Schedule a sync of the queryset with the backend
43
+ * @returns {LiveQueryset} - A live view of the queryset
44
+ */
45
+ getEntity(queryset: Object, sync?: boolean): LiveQueryset;
46
+ /**
47
+ * Set ground truth for a queryset
48
+ * @param {Object} queryset - The queryset
49
+ * @param {Array} instances - Array of instances to set as ground truth
50
+ * @returns {Array} - The set instances
51
+ */
52
+ setEntity(queryset: Object, instances: any[]): any[];
53
+ /**
54
+ * Get all queryset stores for a specific model class
55
+ * @param {ModelClass} ModelClass - The model class to get stores for
56
+ * @returns {Array} - Array of queryset stores for this model
57
+ */
58
+ getAllStoresForModel(ModelClass: any): any[];
59
+ /**
60
+ * Sync a queryset, coordinating with its chain to minimize DB calls.
61
+ * The root fetches from DB, children filter from cached results.
62
+ * Uses operationId to coordinate - whoever arrives first creates the promise,
63
+ * the root takes over and resolves it.
64
+ *
65
+ * @param {Object} queryset - The queryset to sync
66
+ * @param {string} operationId - Unique ID for this sync operation (for coordination)
67
+ * @param {Set} dbSyncedKeys - Set of semanticKeys that are dbSynced (followedQuerysets)
68
+ */
69
+ groupSync(queryset: Object, operationId: string, dbSyncedKeys: Set<any>): Promise<void>;
70
+ }
71
+ export const querysetStoreRegistry: QuerysetStoreRegistry;
72
+ import { QuerysetStoreGraph } from './querysetStoreGraph.js';
@@ -0,0 +1,335 @@
1
+ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
2
+ if (kind === "m") throw new TypeError("Private method is not writable");
3
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
4
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
5
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
6
+ };
7
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
8
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
9
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
10
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
11
+ };
12
+ var _LiveQueryset_queryset, _LiveQueryset_ModelClass, _LiveQueryset_proxy, _LiveQueryset_array;
13
+ import { QuerysetStore } from '../stores/querysetStore.js';
14
+ import { modelStoreRegistry } from '../registries/modelStoreRegistry.js';
15
+ import { wrapReactiveQuerySet } from '../../reactiveAdaptor.js';
16
+ import { processQuery, getRequiredFields, pickRequiredFields } from '../../filtering/localFiltering.js';
17
+ import { filter } from '../../filtering/localFiltering.js';
18
+ import { makeApiCall } from '../../flavours/django/makeApiCall.js';
19
+ import { QuerysetStoreGraph } from './querysetStoreGraph.js';
20
+ import { isNil, pick } from 'lodash-es';
21
+ import hash from 'object-hash';
22
+ import { Operation } from '../stores/operation.js';
23
+ import { Cache } from '../cache/cache.js';
24
+ /**
25
+ * A dynamic wrapper that always returns the latest queryset results
26
+ * This class proxies array operations to always reflect the current state
27
+ * of the underlying QuerysetStore.
28
+ */
29
+ export class LiveQueryset {
30
+ constructor(queryset) {
31
+ _LiveQueryset_queryset.set(this, void 0);
32
+ _LiveQueryset_ModelClass.set(this, void 0);
33
+ _LiveQueryset_proxy.set(this, void 0);
34
+ _LiveQueryset_array.set(this, []);
35
+ // used internally
36
+ __classPrivateFieldSet(this, _LiveQueryset_queryset, queryset, "f");
37
+ __classPrivateFieldSet(this, _LiveQueryset_ModelClass, queryset.ModelClass, "f");
38
+ __classPrivateFieldGet(this, _LiveQueryset_array, "f").queryset = queryset;
39
+ __classPrivateFieldGet(this, _LiveQueryset_array, "f").ModelClass = queryset.ModelClass;
40
+ // Create a proxy that intercepts all array access
41
+ __classPrivateFieldSet(this, _LiveQueryset_proxy, new Proxy(__classPrivateFieldGet(this, _LiveQueryset_array, "f"), {
42
+ get: (target, prop, receiver) => {
43
+ // Expose the touch method through the proxy
44
+ if (prop === "touch") {
45
+ return () => this.touch();
46
+ }
47
+ if (prop === "serialize") {
48
+ return () => this.serialize();
49
+ }
50
+ // Special handling for iterators and common array methods
51
+ if (prop === Symbol.iterator) {
52
+ return () => this.getCurrentItems()[Symbol.iterator]();
53
+ }
54
+ else if (typeof prop === "string" &&
55
+ [
56
+ "forEach",
57
+ "map",
58
+ "filter",
59
+ "reduce",
60
+ "some",
61
+ "every",
62
+ "find",
63
+ ].includes(prop)) {
64
+ return (...args) => this.getCurrentItems()[prop](...args);
65
+ }
66
+ else if (prop === "length") {
67
+ return this.getCurrentItems().length;
68
+ }
69
+ else if (typeof prop === "string" && !isNaN(parseInt(prop))) {
70
+ // Handle numeric indices
71
+ return this.getCurrentItems()[prop];
72
+ }
73
+ return target[prop];
74
+ },
75
+ }), "f");
76
+ return __classPrivateFieldGet(this, _LiveQueryset_proxy, "f");
77
+ }
78
+ /**
79
+ * Serializes the lqs as a simple array of objects, for freezing e.g in the metric stores
80
+ */
81
+ serialize() {
82
+ const store = querysetStoreRegistry.getStore(__classPrivateFieldGet(this, _LiveQueryset_queryset, "f"));
83
+ // Get the current primary keys from the store
84
+ const pks = store.render();
85
+ // Map primary keys to full model objects
86
+ return pks.map((pk) => {
87
+ // Get the full model instance from the model store
88
+ const pkField = __classPrivateFieldGet(this, _LiveQueryset_ModelClass, "f").primaryKeyField;
89
+ return __classPrivateFieldGet(this, _LiveQueryset_ModelClass, "f").fromPk(pk, __classPrivateFieldGet(this, _LiveQueryset_queryset, "f")).serialize();
90
+ });
91
+ }
92
+ /**
93
+ * Refresh the queryset data from the database
94
+ * Delegates to the underlying store's sync method
95
+ */
96
+ refreshFromDb() {
97
+ const store = querysetStoreRegistry.getStore(__classPrivateFieldGet(this, _LiveQueryset_queryset, "f"));
98
+ return store.sync(true);
99
+ }
100
+ /**
101
+ * Get the current items from the store
102
+ * @private
103
+ * @returns {Array} The current items in the queryset
104
+ */
105
+ getCurrentItems() {
106
+ const store = querysetStoreRegistry.getStore(__classPrivateFieldGet(this, _LiveQueryset_queryset, "f"));
107
+ // Get the current primary keys from the store
108
+ const pks = store.render();
109
+ // Map primary keys to full model objects
110
+ const instances = pks
111
+ .map((pk) => {
112
+ // Get the full model instance from the model store
113
+ const pkField = __classPrivateFieldGet(this, _LiveQueryset_ModelClass, "f").primaryKeyField;
114
+ return __classPrivateFieldGet(this, _LiveQueryset_ModelClass, "f").fromPk(pk, __classPrivateFieldGet(this, _LiveQueryset_queryset, "f"));
115
+ });
116
+ return instances;
117
+ }
118
+ }
119
+ _LiveQueryset_queryset = new WeakMap(), _LiveQueryset_ModelClass = new WeakMap(), _LiveQueryset_proxy = new WeakMap(), _LiveQueryset_array = new WeakMap();
120
+ export class QuerysetStoreRegistry {
121
+ constructor() {
122
+ this._stores = new Map(); // Map<semanticKey, Store>
123
+ this._tempStores = new WeakMap(); // WeakMap<Queryset, Store>
124
+ this.followingQuerysets = new Map(); // Map<semanticKey, Set<queryset>>
125
+ this.syncManager = () => { console.warn("SyncManager not set for QuerysetStoreRegistry"); };
126
+ this.querysetStoreGraph = new QuerysetStoreGraph();
127
+ // Cache for groupSync coordination
128
+ // Map<operationId, { promise, resolve, rootKey, pks, ModelClass }>
129
+ this._groupSyncCache = new Map();
130
+ }
131
+ clear() {
132
+ this._stores.forEach((store) => {
133
+ this.syncManager.unfollowModel(this, store.modelClass);
134
+ });
135
+ this._stores = new Map();
136
+ this.followingQuerysets = new Map();
137
+ this.querysetStoreGraph.clear();
138
+ }
139
+ setSyncManager(syncManager) {
140
+ this.syncManager = syncManager;
141
+ }
142
+ /**
143
+ * Add a queryset to the following set for a semantic key
144
+ */
145
+ addFollowingQueryset(semanticKey, queryset) {
146
+ if (!this.followingQuerysets.has(semanticKey)) {
147
+ this.followingQuerysets.set(semanticKey, new Set());
148
+ }
149
+ this.followingQuerysets.get(semanticKey).add(queryset);
150
+ }
151
+ getStore(queryset) {
152
+ if (isNil(queryset) || isNil(queryset.ModelClass)) {
153
+ throw new Error("QuerysetStoreRegistry.getStore requires a valid queryset");
154
+ }
155
+ this.querysetStoreGraph.addQueryset(queryset);
156
+ // Check if we already have a temporary store for this exact QuerySet instance
157
+ if (this._tempStores.has(queryset)) {
158
+ return this._tempStores.get(queryset);
159
+ }
160
+ // Get the semanticKey
161
+ const semanticKey = queryset.semanticKey;
162
+ // Check if we have a permanent store with this semanticKey
163
+ if (this._stores.has(semanticKey)) {
164
+ this.addFollowingQueryset(semanticKey, queryset);
165
+ return this._stores.get(semanticKey);
166
+ }
167
+ // Check if any parent in the chain has a temp store with the same semantic key
168
+ // This ensures that materialized querysets (created via fetch/create/etc) share
169
+ // the same store as their parent queryset when they have the same semantic key
170
+ let current = queryset.__parent;
171
+ while (current) {
172
+ if (this._tempStores.has(current) && current.semanticKey === semanticKey) {
173
+ return this._tempStores.get(current);
174
+ }
175
+ current = current.__parent;
176
+ }
177
+ // Create a new temporary store
178
+ const fetchQueryset = async ({ ast, modelClass, canonical_id }) => {
179
+ // Directly assemble the request and call the API to avoid recursive logic from the
180
+ // queryset back to the registry / store
181
+ const payload = {
182
+ ...ast,
183
+ type: 'list'
184
+ };
185
+ const response = await makeApiCall(queryset, 'list', payload, null, // operationId
186
+ null, // beforeExit
187
+ canonical_id, // canonical_id for caching
188
+ { namespace: 'sync', timeout: 30000 } // Sync ops on separate queue
189
+ );
190
+ return response.data;
191
+ };
192
+ const store = new QuerysetStore(queryset.ModelClass, fetchQueryset, queryset, null, // No initial ground truth - will render from model store if needed
193
+ null, // Initial operations
194
+ { isTemp: true });
195
+ // Store it in the temp store map
196
+ this._tempStores.set(queryset, store);
197
+ return store;
198
+ }
199
+ /**
200
+ * Get the current state of the queryset, wrapped in a LiveQueryset
201
+ * @param {Object} queryset - The queryset
202
+ * @param {Boolean} sync - Schedule a sync of the queryset with the backend
203
+ * @returns {LiveQueryset} - A live view of the queryset
204
+ */
205
+ getEntity(queryset, sync = false) {
206
+ if (isNil(queryset))
207
+ throw new Error(`qsStoreRegistry: getEntity cannot be called without a queryset`);
208
+ const semanticKey = queryset.semanticKey;
209
+ this.addFollowingQueryset(semanticKey, queryset);
210
+ let store;
211
+ // If we have a temporary store, promote it
212
+ if (this._tempStores.has(queryset)) {
213
+ store = this._tempStores.get(queryset);
214
+ store.isTemp = false; // Promote to permanent store
215
+ store.registerWithModelStore(); // Register for model store changes now that it's permanent
216
+ this._stores.set(semanticKey, store);
217
+ this.syncManager.followModel(this, queryset.ModelClass);
218
+ }
219
+ // Otherwise, ensure we have a permanent store
220
+ else if (!this._stores.has(semanticKey)) {
221
+ store = this.getStore(queryset);
222
+ store.isTemp = false;
223
+ store.registerWithModelStore(); // Register for model store changes now that it's permanent
224
+ this._stores.set(semanticKey, store);
225
+ this.syncManager.followModel(this, queryset.ModelClass);
226
+ }
227
+ else {
228
+ store = this._stores.get(semanticKey);
229
+ }
230
+ const liveQueryset = new LiveQueryset(queryset);
231
+ if (sync)
232
+ store.sync();
233
+ return wrapReactiveQuerySet(liveQueryset);
234
+ }
235
+ /**
236
+ * Set ground truth for a queryset
237
+ * @param {Object} queryset - The queryset
238
+ * @param {Array} instances - Array of instances to set as ground truth
239
+ * @returns {Array} - The set instances
240
+ */
241
+ setEntity(queryset, instances) {
242
+ if (isNil(queryset) || isNil(instances))
243
+ return [];
244
+ const semanticKey = queryset.semanticKey;
245
+ this.addFollowingQueryset(semanticKey, queryset);
246
+ let store;
247
+ if (this._stores.has(semanticKey)) {
248
+ store = this._stores.get(semanticKey);
249
+ }
250
+ else {
251
+ // If we have a temp store, promote it
252
+ if (this._tempStores.has(queryset)) {
253
+ store = this._tempStores.get(queryset);
254
+ store.isTemp = false; // Promote to permanent store
255
+ store.registerWithModelStore(); // Register for model store changes now that it's permanent
256
+ this._stores.set(semanticKey, store);
257
+ }
258
+ else {
259
+ // Create a new permanent store
260
+ store = this.getStore(queryset);
261
+ store.isTemp = false;
262
+ store.registerWithModelStore(); // Register for model store changes now that it's permanent
263
+ this._stores.set(semanticKey, store);
264
+ }
265
+ }
266
+ store.setGroundTruth(instances.map(instance => instance[queryset.ModelClass.primaryKeyField] || instance));
267
+ return instances;
268
+ }
269
+ /**
270
+ * Get all queryset stores for a specific model class
271
+ * @param {ModelClass} ModelClass - The model class to get stores for
272
+ * @returns {Array} - Array of queryset stores for this model
273
+ */
274
+ getAllStoresForModel(ModelClass) {
275
+ if (!ModelClass)
276
+ return [];
277
+ return Array.from(this._stores.values()).filter(store => store.modelClass === ModelClass);
278
+ }
279
+ /**
280
+ * Sync a queryset, coordinating with its chain to minimize DB calls.
281
+ * The root fetches from DB, children filter from cached results.
282
+ * Uses operationId to coordinate - whoever arrives first creates the promise,
283
+ * the root takes over and resolves it.
284
+ *
285
+ * @param {Object} queryset - The queryset to sync
286
+ * @param {string} operationId - Unique ID for this sync operation (for coordination)
287
+ * @param {Set} dbSyncedKeys - Set of semanticKeys that are dbSynced (followedQuerysets)
288
+ */
289
+ async groupSync(queryset, operationId, dbSyncedKeys) {
290
+ if (isNil(queryset))
291
+ return;
292
+ const semanticKey = queryset.semanticKey;
293
+ const ModelClass = queryset.ModelClass;
294
+ // Convert dbSyncedKeys to semanticKeys if needed
295
+ const subset = new Set();
296
+ for (const item of dbSyncedKeys) {
297
+ subset.add(typeof item === 'string' ? item : item?.semanticKey);
298
+ }
299
+ // Find the dbSynced root
300
+ const { isRoot, root: rootKey } = this.querysetStoreGraph.findRoot(queryset, subset);
301
+ const iAmRoot = isRoot || rootKey === semanticKey;
302
+ // Get or create cache entry - whoever arrives first creates it
303
+ if (!this._groupSyncCache.has(operationId)) {
304
+ let resolve;
305
+ const promise = new Promise(r => { resolve = r; });
306
+ this._groupSyncCache.set(operationId, { promise, resolve, pks: null, ModelClass });
307
+ setTimeout(() => this._groupSyncCache.delete(operationId), 5000);
308
+ }
309
+ const cached = this._groupSyncCache.get(operationId);
310
+ const store = this._stores.get(semanticKey);
311
+ if (!store) {
312
+ console.warn(`[groupSync] No store found for queryset: ${semanticKey}`);
313
+ return;
314
+ }
315
+ if (iAmRoot) {
316
+ // I'm the root - sync from DB (store handles everything)
317
+ await store.sync();
318
+ cached.pks = store.groundTruthPks;
319
+ cached.resolve();
320
+ }
321
+ else {
322
+ // Wait for root to finish
323
+ await cached.promise;
324
+ // Filter from cached root data
325
+ const rootInstances = cached.pks.map(pk => ModelClass.fromPk(pk, queryset));
326
+ const ast = queryset.build();
327
+ const filteredPks = filter(rootInstances, ast, ModelClass, false);
328
+ // Set ground truth and clean up inflight ops (like sync does)
329
+ store.setGroundTruth(filteredPks);
330
+ store.setOperations(store.getInflightOperations());
331
+ store.lastSync = Date.now();
332
+ }
333
+ }
334
+ }
335
+ export const querysetStoreRegistry = new QuerysetStoreRegistry();
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Store for managing a single metric with optimistic updates
3
+ */
4
+ export class MetricStore {
5
+ constructor(metricType: any, modelClass: any, queryset: any, field: null | undefined, ast: null | undefined, fetchFn: any);
6
+ metricType: any;
7
+ modelClass: any;
8
+ queryset: any;
9
+ field: any;
10
+ ast: any;
11
+ fetchFn: any;
12
+ groundTruthValue: any;
13
+ isSyncing: boolean;
14
+ strategy: import("../metrics/metricOptCalcs.js").MetricCalculationStrategy;
15
+ operations: any[];
16
+ confirmedOps: Set<any>;
17
+ metricCache: Cache;
18
+ _lastCalculatedValue: any;
19
+ reset(): void;
20
+ get cacheKey(): string;
21
+ /**
22
+ * Add an operation to this metric store
23
+ * @param {Operation} operation - The operation to add
24
+ */
25
+ addOperation(operation: Operation): void;
26
+ /**
27
+ * Update an operation in this metric store
28
+ * @param {Operation} operation - The operation to update
29
+ */
30
+ updateOperation(operation: Operation): void;
31
+ /**
32
+ * Confirm an operation in this metric store
33
+ * @param {Operation} operation - The operation to confirm
34
+ */
35
+ confirm(operation: Operation): void;
36
+ /**
37
+ * Reject an operation in this metric store
38
+ * @param {Operation} operation - The operation to reject
39
+ */
40
+ reject(operation: Operation): void;
41
+ onHydrated(): void;
42
+ setCache(): void;
43
+ clearCache(): void;
44
+ setGroundTruth(value: any): void;
45
+ /**
46
+ * Render the metric with current operations
47
+ * @returns {any} Calculated metric value
48
+ */
49
+ render(): any;
50
+ /**
51
+ * Sync metric with server
52
+ */
53
+ sync(): Promise<any>;
54
+ }
55
+ import { Cache } from '../cache/cache.js';