@svgrid/enterprise 2.5.3 → 2.6.1

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 (624) hide show
  1. package/dist/SvAlertRuleEditor.svelte.d.ts +13 -0
  2. package/dist/SvAlertsManager.svelte.d.ts +14 -0
  3. package/dist/SvAlertsPanel.svelte.d.ts +9 -0
  4. package/dist/SvAuthGate.svelte.d.ts +22 -0
  5. package/dist/SvBoard.svelte.d.ts +35 -0
  6. package/dist/SvExportMenu.svelte.d.ts +61 -0
  7. package/{src → dist}/SvExpressionEditor.svelte +4 -1
  8. package/dist/SvExpressionEditor.svelte.d.ts +12 -0
  9. package/dist/SvFileInput.svelte.d.ts +20 -0
  10. package/dist/SvGridAlerts.svelte.d.ts +77 -0
  11. package/dist/SvGridBoard.svelte.d.ts +30 -0
  12. package/{src → dist}/SvGridEditPanel.svelte +173 -28
  13. package/dist/SvGridEditPanel.svelte.d.ts +75 -0
  14. package/dist/SvGridMasterDetail.svelte.d.ts +49 -0
  15. package/dist/SvGridScheduler.svelte.d.ts +30 -0
  16. package/dist/SvImportDialog.svelte.d.ts +88 -0
  17. package/dist/SvLookupInput.svelte.d.ts +21 -0
  18. package/dist/SvPivotDesigner.svelte.d.ts +176 -0
  19. package/dist/SvRecordDetail.svelte.d.ts +58 -0
  20. package/dist/SvSchedule.svelte.d.ts +29 -0
  21. package/dist/SvSchemaChart.svelte.d.ts +61 -0
  22. package/dist/SvSchemaDashboard.svelte.d.ts +46 -0
  23. package/dist/alerts/alert-engine-attach.d.ts +79 -0
  24. package/dist/alerts/alert-engine-attach.js +106 -0
  25. package/dist/alerts/alert-engine.d.ts +42 -0
  26. package/dist/alerts/alert-engine.js +196 -0
  27. package/dist/alerts/alert-formats.d.ts +26 -0
  28. package/dist/alerts/alert-formats.js +58 -0
  29. package/dist/alerts/alert-observer.d.ts +54 -0
  30. package/dist/alerts/alert-observer.js +156 -0
  31. package/dist/alerts/alert-scheduler.d.ts +30 -0
  32. package/dist/alerts/alert-scheduler.js +54 -0
  33. package/dist/alerts/alert-storage.d.ts +31 -0
  34. package/dist/alerts/alert-storage.js +92 -0
  35. package/dist/alerts/alert-store.svelte.d.ts +24 -0
  36. package/dist/alerts/alert-store.svelte.js +69 -0
  37. package/dist/alerts/alert-types.d.ts +86 -0
  38. package/dist/alerts/alert-types.js +1 -0
  39. package/dist/alerts.d.ts +2 -0
  40. package/{src/alerts.ts → dist/alerts.js} +9 -9
  41. package/dist/board.d.ts +7 -0
  42. package/{src/board.ts → dist/board.js} +13 -14
  43. package/dist/cdn/svgrid-enterprise.svelte-external.js +3220 -2607
  44. package/dist/designer/assets/index-BfzoL904.css +1 -0
  45. package/dist/designer/assets/{index-CBYU-KNn.js → index-CKdwDseq.js} +139 -139
  46. package/dist/designer/assets/src-DCKhP5Xy.css +1 -0
  47. package/dist/designer/assets/{src-i309BeJb.js → src-DLsSdh3J.js} +213 -193
  48. package/dist/designer/index.html +4 -4
  49. package/dist/edit-panel.d.ts +105 -0
  50. package/dist/edit-panel.js +350 -0
  51. package/dist/export-conditional.d.ts +31 -0
  52. package/dist/export-conditional.js +65 -0
  53. package/dist/export-ooxml.d.ts +93 -0
  54. package/dist/export-ooxml.js +385 -0
  55. package/dist/export-pdf.d.ts +107 -0
  56. package/dist/export-pdf.js +144 -0
  57. package/dist/export-print.d.ts +55 -0
  58. package/dist/export-print.js +91 -0
  59. package/{src/export-serialize.ts → dist/export-serialize.d.ts} +11 -24
  60. package/dist/export-serialize.js +11 -0
  61. package/dist/export-xls.d.ts +26 -0
  62. package/dist/export-xls.js +157 -0
  63. package/dist/export.d.ts +323 -0
  64. package/dist/export.js +1021 -0
  65. package/dist/expressions/evaluate.d.ts +17 -0
  66. package/dist/expressions/evaluate.js +214 -0
  67. package/dist/expressions/expression-columns.d.ts +61 -0
  68. package/dist/expressions/expression-columns.js +72 -0
  69. package/dist/expressions/expression-types.d.ts +125 -0
  70. package/dist/expressions/expression-types.js +1 -0
  71. package/dist/expressions/parse.d.ts +25 -0
  72. package/dist/expressions/parse.js +537 -0
  73. package/dist/import.d.ts +232 -0
  74. package/dist/import.js +846 -0
  75. package/dist/index.d.ts +66 -0
  76. package/dist/index.js +91 -0
  77. package/dist/install.d.ts +70 -0
  78. package/dist/install.js +61 -0
  79. package/dist/license-core.d.ts +37 -0
  80. package/dist/license-core.js +81 -0
  81. package/dist/license.d.ts +30 -0
  82. package/dist/license.js +139 -0
  83. package/dist/master-detail.d.ts +23 -0
  84. package/dist/master-detail.js +35 -0
  85. package/dist/node/studio.js +683 -13
  86. package/dist/pivot-chart.d.ts +28 -0
  87. package/dist/pivot-chart.js +71 -0
  88. package/dist/pivot-designer.d.ts +69 -0
  89. package/dist/pivot-designer.js +38 -0
  90. package/dist/pivot-enable.d.ts +6 -0
  91. package/{src/pivot-enable.ts → dist/pivot-enable.js} +13 -18
  92. package/dist/pivot.d.ts +111 -0
  93. package/dist/pivot.js +353 -0
  94. package/dist/print.d.ts +33 -0
  95. package/dist/print.js +61 -0
  96. package/dist/revoked.d.ts +1 -0
  97. package/{src/revoked.ts → dist/revoked.js} +5 -6
  98. package/dist/scheduler-assignments.d.ts +64 -0
  99. package/dist/scheduler-assignments.js +92 -0
  100. package/dist/scheduler-axis.d.ts +81 -0
  101. package/dist/scheduler-axis.js +180 -0
  102. package/{src/scheduler-booking.ts → dist/scheduler-booking.d.ts} +10 -43
  103. package/dist/scheduler-booking.js +50 -0
  104. package/dist/scheduler-config.d.ts +177 -0
  105. package/dist/scheduler-config.js +1 -0
  106. package/dist/scheduler-dependencies.d.ts +89 -0
  107. package/dist/scheduler-dependencies.js +179 -0
  108. package/dist/scheduler-freebusy.d.ts +19 -0
  109. package/{src/scheduler-freebusy.ts → dist/scheduler-freebusy.js} +9 -19
  110. package/{src/scheduler-heatmap.ts → dist/scheduler-heatmap.d.ts} +12 -35
  111. package/dist/scheduler-heatmap.js +41 -0
  112. package/dist/scheduler-resource-tree.d.ts +48 -0
  113. package/dist/scheduler-resource-tree.js +78 -0
  114. package/dist/scheduler-slots.d.ts +37 -0
  115. package/dist/scheduler-slots.js +80 -0
  116. package/dist/scheduler-summary.d.ts +41 -0
  117. package/dist/scheduler-summary.js +54 -0
  118. package/dist/scheduler.d.ts +7 -0
  119. package/{src/scheduler.ts → dist/scheduler.js} +13 -14
  120. package/dist/scheduling.d.ts +132 -0
  121. package/dist/scheduling.js +228 -0
  122. package/dist/schema-designer.d.ts +42 -0
  123. package/dist/schema-designer.js +117 -0
  124. package/dist/schema.d.ts +408 -0
  125. package/dist/schema.js +225 -0
  126. package/dist/smart-shim.d.ts +62 -0
  127. package/dist/smart-shim.js +34 -0
  128. package/dist/sources/aggregate.d.ts +43 -0
  129. package/dist/sources/aggregate.js +60 -0
  130. package/dist/sources/auth-supabase.d.ts +69 -0
  131. package/dist/sources/auth-supabase.js +39 -0
  132. package/dist/sources/dashboard.d.ts +65 -0
  133. package/dist/sources/dashboard.js +95 -0
  134. package/dist/sources/field-inference.d.ts +23 -0
  135. package/dist/sources/field-inference.js +52 -0
  136. package/dist/sources/filters.d.ts +35 -0
  137. package/dist/sources/filters.js +52 -0
  138. package/dist/sources/index.d.ts +18 -0
  139. package/dist/sources/index.js +18 -0
  140. package/dist/sources/introspect-supabase.d.ts +30 -0
  141. package/dist/sources/introspect-supabase.js +134 -0
  142. package/dist/sources/realtime-supabase.d.ts +37 -0
  143. package/dist/sources/realtime-supabase.js +52 -0
  144. package/dist/sources/relation-lookup.d.ts +50 -0
  145. package/dist/sources/relation-lookup.js +77 -0
  146. package/dist/sources/rest-adapters.d.ts +48 -0
  147. package/dist/sources/rest-adapters.js +85 -0
  148. package/dist/sources/rest.d.ts +38 -0
  149. package/dist/sources/rest.js +86 -0
  150. package/dist/sources/schema-from-columns.d.ts +37 -0
  151. package/dist/sources/schema-from-columns.js +48 -0
  152. package/dist/sources/supabase.d.ts +33 -0
  153. package/dist/sources/supabase.js +74 -0
  154. package/dist/sources/with-entity-rules.d.ts +25 -0
  155. package/dist/sources/with-entity-rules.js +47 -0
  156. package/dist/sources/with-relation-labels.d.ts +26 -0
  157. package/dist/sources/with-relation-labels.js +38 -0
  158. package/dist/staged-editing.d.ts +85 -0
  159. package/dist/staged-editing.js +0 -0
  160. package/dist/studio/bug-report.d.ts +61 -0
  161. package/dist/studio/bug-report.js +126 -0
  162. package/dist/studio/cli.d.ts +56 -0
  163. package/dist/studio/cli.js +70 -0
  164. package/dist/studio/copilot-core.d.ts +22 -0
  165. package/{src/studio/copilot-core.ts → dist/studio/copilot-core.js} +34 -38
  166. package/dist/studio/csv.d.ts +36 -0
  167. package/dist/studio/csv.js +173 -0
  168. package/dist/studio/db-connect-string.d.ts +45 -0
  169. package/dist/studio/db-connect-string.js +113 -0
  170. package/dist/studio/deploy-cli.d.ts +35 -0
  171. package/dist/studio/deploy-cli.js +81 -0
  172. package/dist/studio/emit-project.d.ts +77 -0
  173. package/dist/studio/emit-project.js +5463 -0
  174. package/dist/studio/emit-schema.d.ts +110 -0
  175. package/dist/studio/emit-schema.js +1128 -0
  176. package/dist/studio/index.d.ts +35 -0
  177. package/dist/studio/index.js +41 -0
  178. package/dist/studio/init-flow.d.ts +58 -0
  179. package/dist/studio/init-flow.js +451 -0
  180. package/dist/studio/introspect-db.d.ts +47 -0
  181. package/dist/studio/introspect-db.js +255 -0
  182. package/dist/studio/introspect-openapi.d.ts +19 -0
  183. package/dist/studio/introspect-openapi.js +244 -0
  184. package/dist/studio/introspect-prisma.d.ts +25 -0
  185. package/dist/studio/introspect-prisma.js +164 -0
  186. package/dist/studio/introspect.d.ts +35 -0
  187. package/dist/studio/introspect.js +306 -0
  188. package/dist/studio/project.d.ts +1448 -0
  189. package/dist/studio/project.js +2187 -0
  190. package/dist/studio/sample-data.d.ts +19 -0
  191. package/dist/studio/sample-data.js +207 -0
  192. package/dist/studio/samples/ats.d.ts +2 -0
  193. package/dist/studio/samples/ats.js +194 -0
  194. package/dist/studio/samples/clinic.d.ts +2 -0
  195. package/dist/studio/samples/clinic.js +171 -0
  196. package/dist/studio/samples/crm.d.ts +2 -0
  197. package/dist/studio/samples/crm.js +280 -0
  198. package/dist/studio/samples/datasets.d.ts +38 -0
  199. package/dist/studio/samples/datasets.js +296 -0
  200. package/dist/studio/samples/ecommerce.d.ts +2 -0
  201. package/dist/studio/samples/ecommerce.js +178 -0
  202. package/dist/studio/samples/events.d.ts +2 -0
  203. package/dist/studio/samples/events.js +192 -0
  204. package/dist/studio/samples/fleet.d.ts +2 -0
  205. package/dist/studio/samples/fleet.js +203 -0
  206. package/dist/studio/samples/gym.d.ts +2 -0
  207. package/dist/studio/samples/gym.js +205 -0
  208. package/dist/studio/samples/hr.d.ts +2 -0
  209. package/dist/studio/samples/hr.js +186 -0
  210. package/dist/studio/samples/index.d.ts +13 -0
  211. package/dist/studio/samples/index.js +44 -0
  212. package/dist/studio/samples/insurance.d.ts +2 -0
  213. package/dist/studio/samples/insurance.js +220 -0
  214. package/dist/studio/samples/inventory.d.ts +2 -0
  215. package/dist/studio/samples/inventory.js +204 -0
  216. package/dist/studio/samples/invoicing.d.ts +2 -0
  217. package/dist/studio/samples/invoicing.js +154 -0
  218. package/dist/studio/samples/library.d.ts +2 -0
  219. package/dist/studio/samples/library.js +171 -0
  220. package/dist/studio/samples/live-data.d.ts +5 -0
  221. package/dist/studio/samples/live-data.js +261 -0
  222. package/dist/studio/samples/projects.d.ts +2 -0
  223. package/dist/studio/samples/projects.js +203 -0
  224. package/dist/studio/samples/realestate.d.ts +2 -0
  225. package/dist/studio/samples/realestate.js +187 -0
  226. package/dist/studio/samples/restaurant.d.ts +2 -0
  227. package/dist/studio/samples/restaurant.js +180 -0
  228. package/dist/studio/samples/school.d.ts +2 -0
  229. package/dist/studio/samples/school.js +188 -0
  230. package/dist/studio/samples/shared.d.ts +142 -0
  231. package/dist/studio/samples/shared.js +164 -0
  232. package/dist/studio/samples/starter.d.ts +4 -0
  233. package/dist/studio/samples/starter.js +237 -0
  234. package/dist/studio/samples/subscriptions.d.ts +2 -0
  235. package/dist/studio/samples/subscriptions.js +175 -0
  236. package/dist/studio/samples/support.d.ts +2 -0
  237. package/dist/studio/samples/support.js +209 -0
  238. package/dist/studio/scaffold-app.d.ts +22 -0
  239. package/{src/studio/scaffold-app.ts → dist/studio/scaffold-app.js} +45 -63
  240. package/dist/studio/scaffold.d.ts +63 -0
  241. package/dist/studio/scaffold.js +346 -0
  242. package/dist/studio/screen-suites.d.ts +193 -0
  243. package/dist/studio/screen-suites.js +297 -0
  244. package/dist/studio/themes.d.ts +34 -0
  245. package/dist/studio/themes.js +41 -0
  246. package/dist/studio/ui-components.d.ts +89 -0
  247. package/dist/studio/ui-components.generated.d.ts +29 -0
  248. package/dist/studio/ui-components.generated.js +7319 -0
  249. package/dist/studio/ui-components.js +673 -0
  250. package/dist/studio/user-error.d.ts +23 -0
  251. package/{src/studio/user-error.ts → dist/studio/user-error.js} +10 -13
  252. package/dist/studio/verify.d.ts +34 -0
  253. package/dist/studio/verify.js +47 -0
  254. package/dist/sveltekit/in-memory.d.ts +14 -0
  255. package/dist/sveltekit/in-memory.js +113 -0
  256. package/dist/sveltekit/index.d.ts +6 -0
  257. package/dist/sveltekit/index.js +5 -0
  258. package/dist/sveltekit/query-plan.d.ts +44 -0
  259. package/dist/sveltekit/query-plan.js +76 -0
  260. package/dist/sveltekit/sql-source.d.ts +47 -0
  261. package/dist/sveltekit/sql-source.js +106 -0
  262. package/dist/sveltekit/sql.d.ts +48 -0
  263. package/dist/sveltekit/sql.js +73 -0
  264. package/dist/sveltekit/transport.d.ts +209 -0
  265. package/dist/sveltekit/transport.js +219 -0
  266. package/{src/sveltekit/types.ts → dist/sveltekit/types.d.ts} +8 -11
  267. package/dist/sveltekit/types.js +1 -0
  268. package/dist/upgrade-prompt.d.ts +16 -0
  269. package/dist/upgrade-prompt.js +141 -0
  270. package/dist/version.d.ts +13 -0
  271. package/{src/version.ts → dist/version.js} +1 -1
  272. package/dist/watermark.d.ts +2 -0
  273. package/dist/watermark.js +146 -0
  274. package/package.json +28 -26
  275. package/dist/designer/assets/index-oYok52zd.css +0 -1
  276. package/dist/designer/assets/src-D-O2F805.css +0 -1
  277. package/src/SvBoard.dom.test.ts +0 -67
  278. package/src/SvGridAlerts.dom.test.ts +0 -113
  279. package/src/SvGridEditPanel.dom.test.ts +0 -320
  280. package/src/SvRecordDetail.dom.test.ts +0 -137
  281. package/src/SvSchedule.dom.test.ts +0 -57
  282. package/src/ai-export-pdf.dom.test.ts +0 -77
  283. package/src/ai-export-xlsx.dom.test.ts +0 -90
  284. package/src/ai-export.dom.test.ts +0 -114
  285. package/src/alerts/alert-engine-attach.ts +0 -165
  286. package/src/alerts/alert-engine.test.ts +0 -135
  287. package/src/alerts/alert-engine.ts +0 -260
  288. package/src/alerts/alert-formats.test.ts +0 -87
  289. package/src/alerts/alert-formats.ts +0 -77
  290. package/src/alerts/alert-observer.test.ts +0 -189
  291. package/src/alerts/alert-observer.ts +0 -208
  292. package/src/alerts/alert-scheduler.ts +0 -96
  293. package/src/alerts/alert-storage.test.ts +0 -54
  294. package/src/alerts/alert-storage.ts +0 -116
  295. package/src/alerts/alert-store.svelte.ts +0 -80
  296. package/src/alerts/alert-types.ts +0 -94
  297. package/src/board.dom.test.ts +0 -941
  298. package/src/edit-panel.test.ts +0 -322
  299. package/src/edit-panel.ts +0 -379
  300. package/src/export-conditional.test.ts +0 -60
  301. package/src/export-conditional.ts +0 -94
  302. package/src/export-ooxml.test.ts +0 -152
  303. package/src/export-ooxml.ts +0 -489
  304. package/src/export-pdf.test.ts +0 -138
  305. package/src/export-pdf.ts +0 -245
  306. package/src/export-print.test.ts +0 -66
  307. package/src/export-print.ts +0 -132
  308. package/src/export-serialize.test.ts +0 -56
  309. package/src/export-xls.ts +0 -199
  310. package/src/export-xlsx-roundtrip.test.ts +0 -120
  311. package/src/export-xlsx.test.ts +0 -150
  312. package/src/export.test.ts +0 -349
  313. package/src/export.ts +0 -1464
  314. package/src/expressions/evaluate.test.ts +0 -111
  315. package/src/expressions/evaluate.ts +0 -237
  316. package/src/expressions/expression-columns.ts +0 -133
  317. package/src/expressions/expression-types.ts +0 -84
  318. package/src/expressions/parse.test.ts +0 -106
  319. package/src/expressions/parse.ts +0 -610
  320. package/src/import-automap.test.ts +0 -131
  321. package/src/import-hardening.test.ts +0 -158
  322. package/src/import.test.ts +0 -415
  323. package/src/import.ts +0 -1044
  324. package/src/index.ts +0 -569
  325. package/src/install.ts +0 -154
  326. package/src/license-core.test.ts +0 -23
  327. package/src/license-core.ts +0 -107
  328. package/src/license-expiry.test.ts +0 -144
  329. package/src/license.ts +0 -157
  330. package/src/master-detail.test.ts +0 -61
  331. package/src/master-detail.ts +0 -42
  332. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/_metadata.json +0 -178
  333. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/attachments-ZrPsKxob.js +0 -3875
  334. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/attachments-ZrPsKxob.js.map +0 -1
  335. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/constants-ACqvWGE2.js +0 -21
  336. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/constants-ACqvWGE2.js.map +0 -1
  337. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/dev-D3w5jt92.js +0 -1938
  338. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/dev-D3w5jt92.js.map +0 -1
  339. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/events-CC2V3H0y.js +0 -205
  340. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/events-CC2V3H0y.js.map +0 -1
  341. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/flags-BXP37tAa.js +0 -18
  342. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/flags-BXP37tAa.js.map +0 -1
  343. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/hydration-DwubnU5b.js +0 -264
  344. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/hydration-DwubnU5b.js.map +0 -1
  345. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/legacy-client-hD7f6PUz.js +0 -697
  346. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/legacy-client-hD7f6PUz.js.map +0 -1
  347. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte.js +0 -134
  348. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte.js.map +0 -1
  349. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_animate.js +0 -55
  350. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_animate.js.map +0 -1
  351. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_attachments.js +0 -2
  352. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_compiler.js +0 -46843
  353. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_compiler.js.map +0 -1
  354. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_easing.js +0 -237
  355. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_easing.js.map +0 -1
  356. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_events.js +0 -2
  357. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal.js +0 -4
  358. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal.js.map +0 -1
  359. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_client.js +0 -7
  360. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_disclose-version.js +0 -4
  361. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_disclose-version.js.map +0 -1
  362. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_async.js +0 -5
  363. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_async.js.map +0 -1
  364. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_legacy.js +0 -5
  365. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_legacy.js.map +0 -1
  366. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_tracing.js +0 -5
  367. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_tracing.js.map +0 -1
  368. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_server.js +0 -6
  369. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_legacy.js +0 -83
  370. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_legacy.js.map +0 -1
  371. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_motion.js +0 -559
  372. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_motion.js.map +0 -1
  373. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_reactivity.js +0 -24
  374. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_reactivity.js.map +0 -1
  375. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_reactivity_window.js +0 -122
  376. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_reactivity_window.js.map +0 -1
  377. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_server.js +0 -2
  378. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_store.js +0 -89
  379. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_store.js.map +0 -1
  380. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_transition.js +0 -241
  381. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_transition.js.map +0 -1
  382. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/utils-DBx1SCN6.js +0 -4938
  383. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/utils-DBx1SCN6.js.map +0 -1
  384. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/utils-gjfpSTFS.js +0 -495
  385. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/utils-gjfpSTFS.js.map +0 -1
  386. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/validate-DKoOKg8S.js +0 -190
  387. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/validate-DKoOKg8S.js.map +0 -1
  388. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/version-C0MiR7eR.js +0 -8
  389. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/version-C0MiR7eR.js.map +0 -1
  390. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/warnings-B6Y7P0Q-.js +0 -138
  391. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/warnings-B6Y7P0Q-.js.map +0 -1
  392. package/src/pivot-chart.test.ts +0 -86
  393. package/src/pivot-chart.ts +0 -112
  394. package/src/pivot-designer.ts +0 -101
  395. package/src/pivot.test.ts +0 -335
  396. package/src/pivot.ts +0 -578
  397. package/src/print.ts +0 -107
  398. package/src/scheduler-assignments.test.ts +0 -97
  399. package/src/scheduler-assignments.ts +0 -134
  400. package/src/scheduler-axis.test.ts +0 -108
  401. package/src/scheduler-axis.ts +0 -238
  402. package/src/scheduler-booking.test.ts +0 -57
  403. package/src/scheduler-config.ts +0 -179
  404. package/src/scheduler-dependencies.test.ts +0 -155
  405. package/src/scheduler-dependencies.ts +0 -223
  406. package/src/scheduler-freebusy.test.ts +0 -41
  407. package/src/scheduler-heatmap.test.ts +0 -39
  408. package/src/scheduler-resource-tree.test.ts +0 -84
  409. package/src/scheduler-resource-tree.ts +0 -107
  410. package/src/scheduler-slots.test.ts +0 -53
  411. package/src/scheduler-slots.ts +0 -94
  412. package/src/scheduler-summary.test.ts +0 -47
  413. package/src/scheduler-summary.ts +0 -81
  414. package/src/scheduling.test.ts +0 -194
  415. package/src/scheduling.ts +0 -293
  416. package/src/schema-designer.test.ts +0 -121
  417. package/src/schema-designer.ts +0 -142
  418. package/src/schema.test.ts +0 -268
  419. package/src/schema.ts +0 -562
  420. package/src/smart-shim.ts +0 -107
  421. package/src/sources/aggregate.test.ts +0 -79
  422. package/src/sources/aggregate.ts +0 -102
  423. package/src/sources/auth-supabase.test.ts +0 -80
  424. package/src/sources/auth-supabase.ts +0 -87
  425. package/src/sources/dashboard.kpi.test.ts +0 -50
  426. package/src/sources/dashboard.test.ts +0 -61
  427. package/src/sources/dashboard.ts +0 -136
  428. package/src/sources/field-inference.test.ts +0 -60
  429. package/src/sources/field-inference.ts +0 -63
  430. package/src/sources/filters.test.ts +0 -58
  431. package/src/sources/filters.ts +0 -70
  432. package/src/sources/index.ts +0 -67
  433. package/src/sources/introspect-supabase.test.ts +0 -112
  434. package/src/sources/introspect-supabase.ts +0 -139
  435. package/src/sources/realtime-supabase.test.ts +0 -93
  436. package/src/sources/realtime-supabase.ts +0 -99
  437. package/src/sources/relation-lookup.test.ts +0 -99
  438. package/src/sources/relation-lookup.ts +0 -128
  439. package/src/sources/rest-adapters.test.ts +0 -95
  440. package/src/sources/rest-adapters.ts +0 -120
  441. package/src/sources/rest.test.ts +0 -104
  442. package/src/sources/rest.ts +0 -129
  443. package/src/sources/schema-from-columns.test.ts +0 -106
  444. package/src/sources/schema-from-columns.ts +0 -88
  445. package/src/sources/supabase.test.ts +0 -110
  446. package/src/sources/supabase.ts +0 -99
  447. package/src/sources/with-entity-rules.test.ts +0 -104
  448. package/src/sources/with-entity-rules.ts +0 -78
  449. package/src/sources/with-relation-labels.test.ts +0 -75
  450. package/src/sources/with-relation-labels.ts +0 -73
  451. package/src/staged-editing.ts +0 -0
  452. package/src/studio/bug-report.test.ts +0 -101
  453. package/src/studio/bug-report.ts +0 -165
  454. package/src/studio/cli.test.ts +0 -187
  455. package/src/studio/cli.ts +0 -117
  456. package/src/studio/copilot-core.test.ts +0 -45
  457. package/src/studio/csv.test.ts +0 -90
  458. package/src/studio/csv.ts +0 -165
  459. package/src/studio/db-connect-string.test.ts +0 -94
  460. package/src/studio/db-connect-string.ts +0 -128
  461. package/src/studio/deploy-cli.test.ts +0 -56
  462. package/src/studio/deploy-cli.ts +0 -100
  463. package/src/studio/emit-project.test.ts +0 -3324
  464. package/src/studio/emit-project.ts +0 -5377
  465. package/src/studio/emit-schema.test.ts +0 -111
  466. package/src/studio/emit-schema.ts +0 -1181
  467. package/src/studio/index.ts +0 -380
  468. package/src/studio/init-flow.test.ts +0 -514
  469. package/src/studio/init-flow.ts +0 -556
  470. package/src/studio/introspect-db.test.ts +0 -186
  471. package/src/studio/introspect-db.ts +0 -312
  472. package/src/studio/introspect-openapi.test.ts +0 -84
  473. package/src/studio/introspect-openapi.ts +0 -252
  474. package/src/studio/introspect-prisma.test.ts +0 -99
  475. package/src/studio/introspect-prisma.ts +0 -175
  476. package/src/studio/introspect.test.ts +0 -172
  477. package/src/studio/introspect.ts +0 -310
  478. package/src/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/_svelte_metadata.json +0 -1
  479. package/src/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/package.json +0 -3
  480. package/src/studio/pipeline.test.ts +0 -42
  481. package/src/studio/project-robust.test.ts +0 -157
  482. package/src/studio/project.test.ts +0 -929
  483. package/src/studio/project.ts +0 -2394
  484. package/src/studio/sample-data.test.ts +0 -58
  485. package/src/studio/sample-data.ts +0 -203
  486. package/src/studio/samples/ats.ts +0 -202
  487. package/src/studio/samples/clinic.ts +0 -179
  488. package/src/studio/samples/crm.ts +0 -291
  489. package/src/studio/samples/datasets.test.ts +0 -84
  490. package/src/studio/samples/datasets.ts +0 -340
  491. package/src/studio/samples/ecommerce.ts +0 -187
  492. package/src/studio/samples/events.ts +0 -201
  493. package/src/studio/samples/fleet.ts +0 -213
  494. package/src/studio/samples/gym.ts +0 -215
  495. package/src/studio/samples/hr.ts +0 -195
  496. package/src/studio/samples/index.ts +0 -55
  497. package/src/studio/samples/insurance.ts +0 -229
  498. package/src/studio/samples/inventory.ts +0 -213
  499. package/src/studio/samples/invoicing.ts +0 -162
  500. package/src/studio/samples/library.ts +0 -180
  501. package/src/studio/samples/live-data.test.ts +0 -99
  502. package/src/studio/samples/live-data.ts +0 -306
  503. package/src/studio/samples/projects.ts +0 -212
  504. package/src/studio/samples/realestate.ts +0 -196
  505. package/src/studio/samples/restaurant.ts +0 -189
  506. package/src/studio/samples/samples.test.ts +0 -304
  507. package/src/studio/samples/school.ts +0 -197
  508. package/src/studio/samples/seed-floor.test.ts +0 -25
  509. package/src/studio/samples/shared.ts +0 -237
  510. package/src/studio/samples/starter.ts +0 -251
  511. package/src/studio/samples/subscriptions.ts +0 -183
  512. package/src/studio/samples/support.ts +0 -216
  513. package/src/studio/scaffold-app.test.ts +0 -91
  514. package/src/studio/scaffold.test.ts +0 -192
  515. package/src/studio/scaffold.ts +0 -390
  516. package/src/studio/screen-suites.test.ts +0 -269
  517. package/src/studio/screen-suites.ts +0 -448
  518. package/src/studio/themes.ts +0 -62
  519. package/src/studio/ui-components-surface.test.ts +0 -185
  520. package/src/studio/ui-components.generated.ts +0 -7154
  521. package/src/studio/ui-components.ts +0 -742
  522. package/src/studio/verify.test.ts +0 -47
  523. package/src/studio/verify.ts +0 -79
  524. package/src/sveltekit/in-memory.test.ts +0 -104
  525. package/src/sveltekit/in-memory.ts +0 -129
  526. package/src/sveltekit/index.ts +0 -24
  527. package/src/sveltekit/query-plan.test.ts +0 -109
  528. package/src/sveltekit/query-plan.ts +0 -125
  529. package/src/sveltekit/sql-source.test.ts +0 -198
  530. package/src/sveltekit/sql-source.ts +0 -171
  531. package/src/sveltekit/sql.test.ts +0 -80
  532. package/src/sveltekit/sql.ts +0 -131
  533. package/src/sveltekit/transport-scope.test.ts +0 -125
  534. package/src/sveltekit/transport.test.ts +0 -201
  535. package/src/sveltekit/transport.ts +0 -373
  536. package/src/upgrade-prompt.test.ts +0 -71
  537. package/src/upgrade-prompt.ts +0 -162
  538. package/src/version.test.ts +0 -17
  539. package/src/watermark.test.ts +0 -97
  540. package/src/watermark.ts +0 -156
  541. /package/{src → dist}/SvAlertRuleEditor.svelte +0 -0
  542. /package/{src → dist}/SvAlertsManager.svelte +0 -0
  543. /package/{src → dist}/SvAlertsPanel.svelte +0 -0
  544. /package/{src → dist}/SvAuthGate.svelte +0 -0
  545. /package/{src → dist}/SvBoard.svelte +0 -0
  546. /package/{src → dist}/SvExportMenu.svelte +0 -0
  547. /package/{src → dist}/SvFileInput.svelte +0 -0
  548. /package/{src → dist}/SvGridAlerts.svelte +0 -0
  549. /package/{src → dist}/SvGridBoard.svelte +0 -0
  550. /package/{src → dist}/SvGridMasterDetail.svelte +0 -0
  551. /package/{src → dist}/SvGridScheduler.svelte +0 -0
  552. /package/{src → dist}/SvImportDialog.svelte +0 -0
  553. /package/{src → dist}/SvLookupInput.svelte +0 -0
  554. /package/{src → dist}/SvPivotDesigner.svelte +0 -0
  555. /package/{src → dist}/SvRecordDetail.svelte +0 -0
  556. /package/{src → dist}/SvSchedule.svelte +0 -0
  557. /package/{src → dist}/SvSchemaChart.svelte +0 -0
  558. /package/{src → dist}/SvSchemaDashboard.svelte +0 -0
  559. /package/{src → dist}/pdfmake-shims.d.ts +0 -0
  560. /package/{src → dist}/smart.export.d.ts +0 -0
  561. /package/{src → dist}/smart.export.js +0 -0
  562. /package/{src → dist}/studio/HANDLERS-DESIGN.md +0 -0
  563. /package/{src → dist/studio}/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/_svelte_metadata.json +0 -0
  564. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/_metadata.json +0 -0
  565. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/attachments-BOv1rBKp.js +0 -0
  566. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/attachments-BOv1rBKp.js.map +0 -0
  567. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/constants-B9vgIdCd.js +0 -0
  568. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/constants-B9vgIdCd.js.map +0 -0
  569. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/dev-T1qbW_qD.js +0 -0
  570. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/dev-T1qbW_qD.js.map +0 -0
  571. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/events-Bo11SfVK.js +0 -0
  572. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/events-Bo11SfVK.js.map +0 -0
  573. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/flags-X7D4vfrZ.js +0 -0
  574. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/flags-X7D4vfrZ.js.map +0 -0
  575. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/hydration-oyUje5i1.js +0 -0
  576. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/hydration-oyUje5i1.js.map +0 -0
  577. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/legacy-client-DeSQgSFm.js +0 -0
  578. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/legacy-client-DeSQgSFm.js.map +0 -0
  579. /package/{src → dist/studio}/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/package.json +0 -0
  580. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte.js +0 -0
  581. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte.js.map +0 -0
  582. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_animate.js +0 -0
  583. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_animate.js.map +0 -0
  584. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_attachments.js +0 -0
  585. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_compiler.js +0 -0
  586. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_compiler.js.map +0 -0
  587. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_easing.js +0 -0
  588. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_easing.js.map +0 -0
  589. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_events.js +0 -0
  590. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal.js +0 -0
  591. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal.js.map +0 -0
  592. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_client.js +0 -0
  593. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_disclose-version.js +0 -0
  594. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_disclose-version.js.map +0 -0
  595. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_async.js +0 -0
  596. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_async.js.map +0 -0
  597. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_legacy.js +0 -0
  598. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_legacy.js.map +0 -0
  599. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_tracing.js +0 -0
  600. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_tracing.js.map +0 -0
  601. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_server.js +0 -0
  602. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_legacy.js +0 -0
  603. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_legacy.js.map +0 -0
  604. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_motion.js +0 -0
  605. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_motion.js.map +0 -0
  606. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_reactivity.js +0 -0
  607. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_reactivity.js.map +0 -0
  608. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_reactivity_window.js +0 -0
  609. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_reactivity_window.js.map +0 -0
  610. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_server.js +0 -0
  611. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_store.js +0 -0
  612. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_store.js.map +0 -0
  613. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_transition.js +0 -0
  614. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_transition.js.map +0 -0
  615. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/utils-BbWyXNk1.js +0 -0
  616. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/utils-BbWyXNk1.js.map +0 -0
  617. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/utils-DI_fC7vt.js +0 -0
  618. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/utils-DI_fC7vt.js.map +0 -0
  619. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/validate-Dyr3lQv9.js +0 -0
  620. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/validate-Dyr3lQv9.js.map +0 -0
  621. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/version-_9FHH-LF.js +0 -0
  622. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/version-_9FHH-LF.js.map +0 -0
  623. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/warnings-CUbSPnyP.js +0 -0
  624. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/warnings-CUbSPnyP.js.map +0 -0
@@ -1,260 +0,0 @@
1
- /**
2
- * The pure alert engine - no DOM, no timers. It turns rules + data snapshots
3
- * into `AlertEvent`s, with true-edge de-duplication so a `dataChange` rule fires
4
- * once when a row starts matching (not on every re-evaluation while it keeps
5
- * matching). The reactive/observing wrapper lives in `alert-engine-attach.ts`.
6
- */
7
- import { evaluateChange, evaluatePredicate } from '../expressions/evaluate'
8
- import { collectColumnRefs } from '../expressions/parse'
9
- import type { EvalContext } from '../expressions/expression-types'
10
- import type { AlertEvent, AlertRule } from './alert-types'
11
-
12
- export type AlertEngineOptions<TData> = {
13
- rules: AlertRule[]
14
- getRowId: (row: TData) => string
15
- /** Resolve a column id to a value (defaults to `row[id]`). */
16
- getValue?: (row: TData, columnId: string) => unknown
17
- locale?: string | ReadonlyArray<string>
18
- /** Clock for `firedAt` (injectable for deterministic tests). */
19
- now?: () => number
20
- }
21
-
22
- export type ValidateEditResult = {
23
- vetoed: boolean
24
- events: AlertEvent[]
25
- }
26
-
27
- export type AlertEngine<TData> = {
28
- setRules(rules: AlertRule[]): void
29
- getRules(): AlertRule[]
30
- /** Full-snapshot pass: fires `dataChange`/`scheduled`/aggregate edges. */
31
- evaluate(rows: ReadonlyArray<TData>): AlertEvent[]
32
- /** Prev -> next pass: fires `relativeChange` plus `dataChange` edges. */
33
- evaluateTransition(prev: ReadonlyArray<TData>, next: ReadonlyArray<TData>): AlertEvent[]
34
- /** Would editing `(row, columnId) -> nextValue` trip a validation rule? */
35
- validateEdit(row: TData, columnId: string, nextValue: unknown): ValidateEditResult
36
- /**
37
- * True iff some enabled rule reads a row's PREVIOUS value (a `relativeChange`
38
- * trigger). When false, the observer can skip cloning prev-snapshots entirely
39
- * - the hot-path saver for `dataChange`/aggregate-only rule sets over big feeds.
40
- */
41
- needsPrev(): boolean
42
- /** True iff some enabled rule is aggregate-scope (needs the full row set). */
43
- needsFullSet(): boolean
44
- /** Forget edge memory so matching rows can fire again. */
45
- reset(): void
46
- }
47
-
48
- const AGG_ROW_KEY = '*'
49
-
50
- /** Fill message-template tokens from the firing context. */
51
- export function renderTemplate(
52
- template: string,
53
- ctx: { rule: AlertRule; row?: Record<string, unknown>; columnId?: string; value?: unknown },
54
- ): string {
55
- const { rule, row, columnId, value } = ctx
56
- return template
57
- .replace(/\{rule\}/g, rule.name)
58
- .replace(/\{severity\}/g, rule.severity)
59
- .replace(/\{column\}/g, columnId ?? '')
60
- .replace(/\{value\}/g, value == null ? '' : String(value))
61
- .replace(/\{row\.([\w$]+)\}/g, (_m, key: string) => fmt(row?.[key]))
62
- .replace(/\{([\w$]+)\}/g, (m, key: string) => (row && key in row ? fmt(row[key]) : m))
63
- }
64
-
65
- function fmt(v: unknown): string {
66
- return v == null ? '' : String(v)
67
- }
68
-
69
- function defaultMessage(rule: AlertRule): string {
70
- return rule.name
71
- }
72
-
73
- export function createAlertEngine<TData = Record<string, unknown>>(
74
- options: AlertEngineOptions<TData>,
75
- ): AlertEngine<TData> {
76
- let rules = options.rules
77
- const getValue = options.getValue
78
- const now = options.now ?? (() => Date.now())
79
- // Edge memory: keys currently satisfying a `dataChange`/aggregate predicate.
80
- const active = new Set<string>()
81
-
82
- const ctxFor = (row: TData, rows?: ReadonlyArray<TData>, prev?: TData): EvalContext<TData> => ({
83
- row,
84
- prev,
85
- rows,
86
- getValue,
87
- locale: options.locale,
88
- })
89
-
90
- const val = (row: TData, columnId?: string): unknown =>
91
- columnId == null
92
- ? undefined
93
- : getValue
94
- ? getValue(row, columnId)
95
- : (row as Record<string, unknown>)?.[columnId]
96
-
97
- // A representative column for the message `{value}`/`{column}` tokens: the
98
- // rule's explicit target, else the first column its predicate references.
99
- const primaryColumn = (rule: AlertRule): string | undefined =>
100
- rule.columns?.[0] ?? collectColumnRefs(rule.predicate)[0]
101
-
102
- function buildEvent(
103
- rule: AlertRule,
104
- opts: { row?: TData; rowId?: string; columnId?: string; value?: unknown },
105
- ): AlertEvent {
106
- const msgAction = rule.actions.find((a) => a.message)
107
- const template = msgAction?.message ?? defaultMessage(rule)
108
- const message = renderTemplate(template, {
109
- rule,
110
- row: opts.row as Record<string, unknown> | undefined,
111
- columnId: opts.columnId,
112
- value: opts.value,
113
- })
114
- return {
115
- ruleId: rule.id,
116
- ruleName: rule.name,
117
- severity: rule.severity,
118
- scope: rule.scope,
119
- triggerType: rule.trigger.type,
120
- rowId: opts.rowId,
121
- columnId: opts.columnId,
122
- value: opts.value,
123
- message,
124
- actions: rule.actions,
125
- firedAt: now(),
126
- }
127
- }
128
-
129
- /** Aggregate-scope: one edge event when the predicate over all rows flips true. */
130
- function evaluateAggregate(rule: AlertRule, rows: ReadonlyArray<TData>): AlertEvent[] {
131
- const key = `${rule.id}::${AGG_ROW_KEY}`
132
- const first = rows[0]
133
- const matches = first != null && evaluatePredicate(rule.predicate, ctxFor(first, rows))
134
- if (matches && !active.has(key)) {
135
- active.add(key)
136
- return [buildEvent(rule, {})]
137
- }
138
- if (!matches) active.delete(key)
139
- return []
140
- }
141
-
142
- /** Row/cell dataChange: edge event when a row newly satisfies the predicate. */
143
- function evaluateDataChangeRow(
144
- rule: AlertRule,
145
- row: TData,
146
- rows: ReadonlyArray<TData>,
147
- ): AlertEvent[] {
148
- const id = options.getRowId(row)
149
- const key = `${rule.id}::${id}`
150
- const matches = evaluatePredicate(rule.predicate, ctxFor(row, rows))
151
- if (matches && !active.has(key)) {
152
- active.add(key)
153
- const source = primaryColumn(rule)
154
- // Expose the column on the event only for cell scope; still surface its
155
- // value for the message tokens regardless of scope.
156
- const columnId = rule.scope === 'cell' ? source : undefined
157
- return [buildEvent(rule, { row, rowId: id, columnId, value: val(row, source) })]
158
- }
159
- if (!matches) active.delete(key)
160
- return []
161
- }
162
-
163
- /** relativeChange: fires whenever the change test holds for a prev->next row. */
164
- function evaluateRelative(
165
- rule: AlertRule,
166
- row: TData,
167
- prev: TData | undefined,
168
- rows: ReadonlyArray<TData>,
169
- ): AlertEvent[] {
170
- if (rule.trigger.type !== 'relativeChange' || prev == null) return []
171
- const changed = evaluateChange(rule.trigger.expr, ctxFor(row, rows, prev))
172
- if (!changed) return []
173
- // Gate on the predicate too, so "price jumped AND price > 100" is expressible.
174
- if (!evaluatePredicate(rule.predicate, ctxFor(row, rows, prev))) return []
175
- const columnId = rule.trigger.expr.column
176
- return [
177
- buildEvent(rule, {
178
- row,
179
- rowId: options.getRowId(row),
180
- columnId,
181
- value: val(row, columnId),
182
- }),
183
- ]
184
- }
185
-
186
- function activeRules(): AlertRule[] {
187
- return rules.filter((r) => r.enabled)
188
- }
189
-
190
- return {
191
- setRules(next) {
192
- rules = next
193
- },
194
- getRules() {
195
- return rules
196
- },
197
- needsPrev() {
198
- return rules.some((r) => r.enabled && r.trigger.type === 'relativeChange')
199
- },
200
- needsFullSet() {
201
- return rules.some((r) => r.enabled && r.scope === 'aggregate')
202
- },
203
- reset() {
204
- active.clear()
205
- },
206
-
207
- evaluate(rows) {
208
- const events: AlertEvent[] = []
209
- for (const rule of activeRules()) {
210
- if (rule.scope === 'aggregate') {
211
- events.push(...evaluateAggregate(rule, rows))
212
- } else if (rule.trigger.type === 'dataChange' || rule.trigger.type === 'scheduled') {
213
- for (const row of rows) events.push(...evaluateDataChangeRow(rule, row, rows))
214
- }
215
- }
216
- return events
217
- },
218
-
219
- evaluateTransition(prev, next) {
220
- const prevById = new Map<string, TData>()
221
- for (const row of prev) prevById.set(options.getRowId(row), row)
222
- const events: AlertEvent[] = []
223
- for (const rule of activeRules()) {
224
- if (rule.scope === 'aggregate') {
225
- events.push(...evaluateAggregate(rule, next))
226
- continue
227
- }
228
- for (const row of next) {
229
- const before = prevById.get(options.getRowId(row))
230
- if (rule.trigger.type === 'relativeChange') {
231
- events.push(...evaluateRelative(rule, row, before, next))
232
- } else if (rule.trigger.type === 'dataChange') {
233
- events.push(...evaluateDataChangeRow(rule, row, next))
234
- }
235
- }
236
- }
237
- return events
238
- },
239
-
240
- validateEdit(row, columnId, nextValue) {
241
- const candidate = { ...(row as Record<string, unknown>), [columnId]: nextValue } as TData
242
- const events: AlertEvent[] = []
243
- let vetoed = false
244
- for (const rule of activeRules()) {
245
- if (rule.trigger.type !== 'validation') continue
246
- if (!evaluatePredicate(rule.predicate, ctxFor(candidate))) continue
247
- events.push(
248
- buildEvent(rule, {
249
- row: candidate,
250
- rowId: options.getRowId(candidate),
251
- columnId,
252
- value: nextValue,
253
- }),
254
- )
255
- if (rule.actions.some((a) => a.kind === 'preventEdit')) vetoed = true
256
- }
257
- return { vetoed, events }
258
- },
259
- }
260
- }
@@ -1,87 +0,0 @@
1
- import { describe, expect, it } from 'vitest'
2
- import { rulesToConditionalFormats, toConditionalFormats } from './alert-formats'
3
- import type { AlertEvent, AlertRule } from './alert-types'
4
-
5
- type Row = { id: string; price: number }
6
- const getRowId = (r: Row) => r.id
7
-
8
- const event = (over: Partial<AlertEvent> = {}): AlertEvent => ({
9
- ruleId: 'r1',
10
- ruleName: 'High',
11
- severity: 'warning',
12
- scope: 'row',
13
- triggerType: 'dataChange',
14
- rowId: 'a',
15
- message: 'hi',
16
- actions: [{ kind: 'highlight', style: { background: '#fee2e2', color: '#991b1b' } }],
17
- firedAt: 0,
18
- ...over,
19
- })
20
-
21
- describe('toConditionalFormats', () => {
22
- it('turns a highlight action into a row-matching RuleFormat', () => {
23
- const formats = toConditionalFormats([event()], getRowId)
24
- expect(formats).toHaveLength(1)
25
- const f = formats[0]!
26
- expect(f.type).toBe('rule')
27
- if (f.type === 'rule') {
28
- expect(f.background).toBe('#fee2e2')
29
- expect(f.color).toBe('#991b1b')
30
- expect(f.when({ value: 120, row: { id: 'a', price: 120 } })).toBe(true)
31
- expect(f.when({ value: 80, row: { id: 'b', price: 80 } })).toBe(false)
32
- }
33
- })
34
-
35
- it('scopes to the event column when no explicit columns', () => {
36
- const formats = toConditionalFormats([event({ columnId: 'price' })], getRowId)
37
- const f = formats[0]!
38
- if (f.type === 'rule') expect(f.columns).toEqual(['price'])
39
- })
40
-
41
- it('honours explicit action columns', () => {
42
- const formats = toConditionalFormats(
43
- [event({ actions: [{ kind: 'badge', columns: ['price', 'id'], style: { background: '#fff' } }] })],
44
- getRowId,
45
- )
46
- const f = formats[0]!
47
- if (f.type === 'rule') expect(f.columns).toEqual(['price', 'id'])
48
- })
49
-
50
- it('ignores toast/log/flash-only events (no styling)', () => {
51
- expect(toConditionalFormats([event({ actions: [{ kind: 'toast' }, { kind: 'log' }] })], getRowId)).toHaveLength(0)
52
- })
53
-
54
- it('skips events without a row id', () => {
55
- expect(toConditionalFormats([event({ rowId: undefined })], getRowId)).toHaveLength(0)
56
- })
57
- })
58
-
59
- describe('rulesToConditionalFormats', () => {
60
- const rule = (over: Partial<AlertRule> = {}): AlertRule => ({
61
- id: 'r1',
62
- name: 'High',
63
- enabled: true,
64
- severity: 'warning',
65
- scope: 'row',
66
- predicate: { kind: 'cmp', column: 'price', op: 'greaterThan', value: 100 },
67
- trigger: { type: 'dataChange' },
68
- actions: [{ kind: 'highlight', style: { background: '#fee2e2' } }],
69
- createdAt: 0,
70
- ...over,
71
- })
72
-
73
- it('emits one live predicate-driven format per styling rule', () => {
74
- const formats = rulesToConditionalFormats<Row>([rule()])
75
- expect(formats).toHaveLength(1)
76
- const f = formats[0]!
77
- if (f.type === 'rule') {
78
- expect(f.when({ value: 0, row: { id: 'a', price: 120 } })).toBe(true)
79
- expect(f.when({ value: 0, row: { id: 'b', price: 80 } })).toBe(false)
80
- }
81
- })
82
-
83
- it('ignores disabled rules and non-styling rules', () => {
84
- expect(rulesToConditionalFormats<Row>([rule({ enabled: false })])).toHaveLength(0)
85
- expect(rulesToConditionalFormats<Row>([rule({ actions: [{ kind: 'toast' }] })])).toHaveLength(0)
86
- })
87
- })
@@ -1,77 +0,0 @@
1
- /**
2
- * Bridge fired alert events to the grid's conditional-formatting engine. A
3
- * `badge` / `highlight` action becomes a `RuleFormat` whose `when` matches the
4
- * row that fired, so `resolveCellFormat` paints it - the same painter the grid
5
- * already uses for color scales and data bars. No new rendering path.
6
- */
7
- import type { ConditionalFormat } from '@svgrid/grid/format'
8
- import { evaluatePredicate } from '../expressions/evaluate'
9
- import type { AlertEvent, AlertRule } from './alert-types'
10
-
11
- /** Which action kinds paint onto cells. */
12
- const STYLING_KINDS = new Set(['badge', 'highlight'])
13
-
14
- export type StylingContext<TData> = {
15
- getValue?: (row: TData, columnId: string) => unknown
16
- locale?: string | ReadonlyArray<string>
17
- }
18
-
19
- /**
20
- * Persistent styling: one self-contained `RuleFormat` per enabled rule that has
21
- * a `badge`/`highlight` action. The format's `when` runs the rule predicate
22
- * directly, so the styling stays live as data changes (rows light up while they
23
- * match and clear when they stop) without any row-id bookkeeping. One format
24
- * per rule keeps the array tiny regardless of row count.
25
- */
26
- export function rulesToConditionalFormats<TData = Record<string, unknown>>(
27
- rules: ReadonlyArray<AlertRule>,
28
- ctx: StylingContext<TData> = {},
29
- ): ConditionalFormat<TData>[] {
30
- const formats: ConditionalFormat<TData>[] = []
31
- for (const rule of rules) {
32
- if (!rule.enabled) continue
33
- for (const action of rule.actions) {
34
- if (!STYLING_KINDS.has(action.kind)) continue
35
- const columns = action.columns ?? rule.columns
36
- const style = action.style ?? {}
37
- formats.push({
38
- type: 'rule',
39
- ...(columns ? { columns } : {}),
40
- when: ({ row }: { value: unknown; row: TData }) =>
41
- evaluatePredicate(rule.predicate, { row, getValue: ctx.getValue, locale: ctx.locale }),
42
- ...(style.background ? { background: style.background } : {}),
43
- ...(style.color ? { color: style.color } : {}),
44
- })
45
- }
46
- }
47
- return formats
48
- }
49
-
50
- /**
51
- * Turn active alert events into conditional formats. Events whose actions only
52
- * toast/log/flash contribute nothing here. Matching is by row id, so the format
53
- * follows the row through sort/filter rather than a fixed index.
54
- */
55
- export function toConditionalFormats<TData = Record<string, unknown>>(
56
- events: ReadonlyArray<AlertEvent>,
57
- getRowId: (row: TData) => string,
58
- ): ConditionalFormat<TData>[] {
59
- const formats: ConditionalFormat<TData>[] = []
60
- for (const event of events) {
61
- if (event.rowId == null) continue
62
- const rowId = event.rowId
63
- for (const action of event.actions) {
64
- if (!STYLING_KINDS.has(action.kind)) continue
65
- const columns = action.columns ?? (event.columnId ? [event.columnId] : undefined)
66
- const style = action.style ?? {}
67
- formats.push({
68
- type: 'rule',
69
- ...(columns ? { columns } : {}),
70
- when: ({ row }: { value: unknown; row: TData }) => getRowId(row) === rowId,
71
- ...(style.background ? { background: style.background } : {}),
72
- ...(style.color ? { color: style.color } : {}),
73
- })
74
- }
75
- }
76
- return formats
77
- }
@@ -1,189 +0,0 @@
1
- import { describe, expect, it, vi } from 'vitest'
2
- import { createAlertEngine } from './alert-engine'
3
- import { createAlertObserver } from './alert-observer'
4
- import { createAlertScheduler } from './alert-scheduler'
5
- import type { AlertEvent, AlertRule } from './alert-types'
6
-
7
- type Row = { id: string; price: number; region: string; status: string }
8
-
9
- const seedRows = (over: Partial<Row>[] = []): Row[] =>
10
- [
11
- { id: 'a', price: 120, region: 'EU', status: 'open' },
12
- { id: 'b', price: 80, region: 'US', status: 'open' },
13
- ].map((r, i) => ({ ...r, ...(over[i] ?? {}) }))
14
-
15
- const getRowId = (r: Row) => r.id
16
-
17
- const dataChangeRule: AlertRule = {
18
- id: 'r1',
19
- name: 'High price',
20
- enabled: true,
21
- severity: 'warning',
22
- scope: 'row',
23
- predicate: { kind: 'cmp', column: 'price', op: 'greaterThan', value: 100 },
24
- trigger: { type: 'dataChange' },
25
- actions: [{ kind: 'toast', message: '{region} at {value}' }],
26
- createdAt: 0,
27
- }
28
-
29
- const relativeRule: AlertRule = {
30
- id: 'r2',
31
- name: 'Jumped',
32
- enabled: true,
33
- severity: 'info',
34
- scope: 'row',
35
- predicate: { kind: 'const', value: true },
36
- trigger: { type: 'relativeChange', expr: { kind: 'percentChange', column: 'price', op: '>', value: 5, abs: true } },
37
- actions: [{ kind: 'toast', message: 'moved' }],
38
- createdAt: 0,
39
- }
40
-
41
- function harness(rules: AlertRule[]) {
42
- const engine = createAlertEngine<Row>({ rules, getRowId, now: () => 1000 })
43
- const events: AlertEvent[] = []
44
- const observer = createAlertObserver<Row>({
45
- engine,
46
- getRowId,
47
- schedule: 'sync', // deterministic: runs inline
48
- onEvents: (batch) => events.push(...batch),
49
- })
50
- return { engine, observer, events }
51
- }
52
-
53
- describe('engine.needsPrev / needsFullSet', () => {
54
- it('needsPrev is true only when a relativeChange rule is enabled', () => {
55
- expect(createAlertEngine<Row>({ rules: [dataChangeRule], getRowId }).needsPrev()).toBe(false)
56
- expect(createAlertEngine<Row>({ rules: [relativeRule], getRowId }).needsPrev()).toBe(true)
57
- expect(
58
- createAlertEngine<Row>({ rules: [{ ...relativeRule, enabled: false }], getRowId }).needsPrev(),
59
- ).toBe(false)
60
- })
61
-
62
- it('needsFullSet is true only when an aggregate-scope rule is enabled', () => {
63
- expect(createAlertEngine<Row>({ rules: [dataChangeRule], getRowId }).needsFullSet()).toBe(false)
64
- const agg: AlertRule = { ...dataChangeRule, id: 'agg', scope: 'aggregate' }
65
- expect(createAlertEngine<Row>({ rules: [agg], getRowId }).needsFullSet()).toBe(true)
66
- })
67
- })
68
-
69
- describe('createAlertObserver push mode', () => {
70
- it('seed is silent - pre-existing matches do not fire', () => {
71
- const { observer, events } = harness([dataChangeRule])
72
- observer.seed(seedRows()) // 'a' already > 100
73
- expect(events).toHaveLength(0)
74
- })
75
-
76
- it('pushChanged fires only for the rows it is given, once on crossing', () => {
77
- const { observer, events } = harness([dataChangeRule])
78
- observer.seed(seedRows([{ price: 90 }])) // 'a' starts below threshold
79
- // 'b' unchanged and below threshold; push 'a' now crossing.
80
- observer.pushChanged([{ id: 'a', price: 130, region: 'EU', status: 'open' }])
81
- expect(events).toHaveLength(1)
82
- expect(events[0]!.rowId).toBe('a')
83
- // Pushing it again while it stays above must not re-fire (edge memory).
84
- observer.pushChanged([{ id: 'a', price: 131, region: 'EU', status: 'open' }])
85
- expect(events).toHaveLength(1)
86
- })
87
-
88
- it('does not evaluate rows that were never pushed', () => {
89
- const { observer, events } = harness([dataChangeRule])
90
- observer.seed(seedRows([{ price: 90 }, { price: 95 }])) // both below
91
- // Only 'b' is pushed, crossing the line; 'a' is untouched.
92
- observer.pushChanged([{ id: 'b', price: 150, region: 'US', status: 'open' }])
93
- expect(events).toHaveLength(1)
94
- expect(events[0]!.rowId).toBe('b')
95
- })
96
-
97
- it('relativeChange push sees prev via the maintained snapshot', () => {
98
- const { observer, events } = harness([relativeRule])
99
- const start = seedRows()
100
- observer.seed(start)
101
- // 'a' 120 -> 140 is +16% -> fires.
102
- observer.pushChanged([{ id: 'a', price: 140, region: 'EU', status: 'open' }])
103
- expect(events).toHaveLength(1)
104
- expect(events[0]!.columnId).toBe('price')
105
- })
106
- })
107
-
108
- describe('createAlertObserver scales O(changed), not O(total)', () => {
109
- it('a push over a 100k seed touches only the changed rows', () => {
110
- // Seed 100k rows, then push a handful. The evaluation must not re-scan the
111
- // whole set - we assert by counting getRowId calls after the seed.
112
- let calls = 0
113
- const countingId = (r: Row) => {
114
- calls++
115
- return r.id
116
- }
117
- const engine = createAlertEngine<Row>({ rules: [dataChangeRule], getRowId: countingId, now: () => 1000 })
118
- const events: AlertEvent[] = []
119
- const observer = createAlertObserver<Row>({
120
- engine,
121
- getRowId: countingId,
122
- schedule: 'sync',
123
- onEvents: (b) => events.push(...b),
124
- })
125
-
126
- const big: Row[] = Array.from({ length: 100_000 }, (_, i) => ({
127
- id: `r${i}`,
128
- price: 10, // all below the >100 threshold
129
- region: 'EU',
130
- status: 'open',
131
- }))
132
- observer.seed(big)
133
- calls = 0 // ignore the one-time seed cost; measure only the push
134
-
135
- observer.pushChanged([{ id: 'r5', price: 130, region: 'EU', status: 'open' }])
136
- expect(events).toHaveLength(1)
137
- expect(events[0]!.rowId).toBe('r5')
138
- // O(changed): a single changed row costs a bounded handful of id lookups,
139
- // nowhere near the 100k total.
140
- expect(calls).toBeLessThan(50)
141
- })
142
- })
143
-
144
- describe('createAlertObserver scan (watch) mode', () => {
145
- it('index-diffs the array and evaluates only changed rows', () => {
146
- const { observer, events } = harness([dataChangeRule])
147
- let data: Row[] = seedRows([{ price: 90 }]) // 'a' below
148
- observer.scan(() => data) // first scan seeds silently
149
- expect(events).toHaveLength(0)
150
- // Immutable replace of 'a' only (Svelte-5 style).
151
- data = [{ ...data[0]!, price: 130 }, data[1]!]
152
- observer.scan(() => data)
153
- expect(events).toHaveLength(1)
154
- expect(events[0]!.rowId).toBe('a')
155
- })
156
- })
157
-
158
- describe('createScheduler', () => {
159
- it('sync mode runs immediately', () => {
160
- const s = createAlertScheduler('sync')
161
- const fn = vi.fn()
162
- s.schedule(fn)
163
- expect(fn).toHaveBeenCalledTimes(1)
164
- expect(s.pending).toBe(false)
165
- })
166
-
167
- it('coalesces multiple schedules and flush runs the latest once', () => {
168
- const s = createAlertScheduler('raf') // no rAF in node -> setTimeout fallback, but flush is sync
169
- const a = vi.fn()
170
- const b = vi.fn()
171
- s.schedule(a)
172
- s.schedule(b)
173
- expect(s.pending).toBe(true)
174
- s.flush()
175
- // Latest wins - only the most recent callback runs, exactly once.
176
- expect(a).not.toHaveBeenCalled()
177
- expect(b).toHaveBeenCalledTimes(1)
178
- expect(s.pending).toBe(false)
179
- })
180
-
181
- it('cancel drops the pending callback', () => {
182
- const s = createAlertScheduler('raf')
183
- const fn = vi.fn()
184
- s.schedule(fn)
185
- s.cancel()
186
- s.flush()
187
- expect(fn).not.toHaveBeenCalled()
188
- })
189
- })