@svgrid/enterprise 2.5.2 → 2.6.0

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 (620) 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/dist/SvExpressionEditor.svelte.d.ts +12 -0
  8. package/dist/SvFileInput.svelte.d.ts +20 -0
  9. package/dist/SvGridAlerts.svelte.d.ts +77 -0
  10. package/dist/SvGridBoard.svelte.d.ts +30 -0
  11. package/dist/SvGridEditPanel.svelte.d.ts +73 -0
  12. package/dist/SvGridMasterDetail.svelte.d.ts +49 -0
  13. package/dist/SvGridScheduler.svelte.d.ts +30 -0
  14. package/dist/SvImportDialog.svelte.d.ts +88 -0
  15. package/dist/SvLookupInput.svelte.d.ts +21 -0
  16. package/dist/SvPivotDesigner.svelte.d.ts +176 -0
  17. package/dist/SvRecordDetail.svelte.d.ts +58 -0
  18. package/dist/SvSchedule.svelte.d.ts +29 -0
  19. package/dist/SvSchemaChart.svelte.d.ts +61 -0
  20. package/dist/SvSchemaDashboard.svelte.d.ts +46 -0
  21. package/dist/alerts/alert-engine-attach.d.ts +79 -0
  22. package/dist/alerts/alert-engine-attach.js +106 -0
  23. package/dist/alerts/alert-engine.d.ts +42 -0
  24. package/dist/alerts/alert-engine.js +196 -0
  25. package/dist/alerts/alert-formats.d.ts +26 -0
  26. package/dist/alerts/alert-formats.js +58 -0
  27. package/dist/alerts/alert-observer.d.ts +54 -0
  28. package/dist/alerts/alert-observer.js +156 -0
  29. package/dist/alerts/alert-scheduler.d.ts +30 -0
  30. package/dist/alerts/alert-scheduler.js +54 -0
  31. package/dist/alerts/alert-storage.d.ts +31 -0
  32. package/dist/alerts/alert-storage.js +92 -0
  33. package/dist/alerts/alert-store.svelte.d.ts +24 -0
  34. package/dist/alerts/alert-store.svelte.js +69 -0
  35. package/dist/alerts/alert-types.d.ts +86 -0
  36. package/dist/alerts/alert-types.js +1 -0
  37. package/dist/alerts.d.ts +2 -0
  38. package/{src/alerts.ts → dist/alerts.js} +9 -9
  39. package/dist/board.d.ts +7 -0
  40. package/{src/board.ts → dist/board.js} +13 -14
  41. package/dist/cdn/svgrid-enterprise.svelte-external.js +2987 -2981
  42. package/dist/designer/assets/{index-CM5xvaOy.js → index-BF0UH638.js} +3 -3
  43. package/dist/designer/assets/{src-D-ET9Mmo.js → src-BPJruwB9.js} +184 -184
  44. package/dist/designer/index.html +2 -2
  45. package/dist/edit-panel.d.ts +105 -0
  46. package/dist/edit-panel.js +350 -0
  47. package/dist/export-conditional.d.ts +31 -0
  48. package/dist/export-conditional.js +65 -0
  49. package/dist/export-ooxml.d.ts +93 -0
  50. package/dist/export-ooxml.js +385 -0
  51. package/dist/export-pdf.d.ts +107 -0
  52. package/dist/export-pdf.js +144 -0
  53. package/dist/export-print.d.ts +55 -0
  54. package/dist/export-print.js +91 -0
  55. package/{src/export-serialize.ts → dist/export-serialize.d.ts} +11 -24
  56. package/dist/export-serialize.js +11 -0
  57. package/dist/export-xls.d.ts +26 -0
  58. package/dist/export-xls.js +157 -0
  59. package/dist/export.d.ts +323 -0
  60. package/dist/export.js +1021 -0
  61. package/dist/expressions/evaluate.d.ts +17 -0
  62. package/dist/expressions/evaluate.js +214 -0
  63. package/dist/expressions/expression-columns.d.ts +61 -0
  64. package/dist/expressions/expression-columns.js +72 -0
  65. package/dist/expressions/expression-types.d.ts +125 -0
  66. package/dist/expressions/expression-types.js +1 -0
  67. package/dist/expressions/parse.d.ts +25 -0
  68. package/dist/expressions/parse.js +537 -0
  69. package/dist/import.d.ts +232 -0
  70. package/dist/import.js +846 -0
  71. package/dist/index.d.ts +66 -0
  72. package/dist/index.js +91 -0
  73. package/dist/install.d.ts +70 -0
  74. package/dist/install.js +61 -0
  75. package/dist/license-core.d.ts +37 -0
  76. package/dist/license-core.js +81 -0
  77. package/dist/license.d.ts +30 -0
  78. package/dist/license.js +139 -0
  79. package/dist/master-detail.d.ts +23 -0
  80. package/dist/master-detail.js +35 -0
  81. package/dist/node/studio.js +1 -1
  82. package/dist/pivot-chart.d.ts +28 -0
  83. package/dist/pivot-chart.js +71 -0
  84. package/dist/pivot-designer.d.ts +69 -0
  85. package/dist/pivot-designer.js +38 -0
  86. package/dist/pivot-enable.d.ts +6 -0
  87. package/{src/pivot-enable.ts → dist/pivot-enable.js} +13 -18
  88. package/dist/pivot.d.ts +111 -0
  89. package/dist/pivot.js +353 -0
  90. package/dist/print.d.ts +33 -0
  91. package/dist/print.js +61 -0
  92. package/dist/revoked.d.ts +1 -0
  93. package/{src/revoked.ts → dist/revoked.js} +5 -6
  94. package/dist/scheduler-assignments.d.ts +64 -0
  95. package/dist/scheduler-assignments.js +92 -0
  96. package/dist/scheduler-axis.d.ts +81 -0
  97. package/dist/scheduler-axis.js +180 -0
  98. package/{src/scheduler-booking.ts → dist/scheduler-booking.d.ts} +10 -43
  99. package/dist/scheduler-booking.js +50 -0
  100. package/dist/scheduler-config.d.ts +177 -0
  101. package/dist/scheduler-config.js +1 -0
  102. package/dist/scheduler-dependencies.d.ts +89 -0
  103. package/dist/scheduler-dependencies.js +179 -0
  104. package/dist/scheduler-freebusy.d.ts +19 -0
  105. package/{src/scheduler-freebusy.ts → dist/scheduler-freebusy.js} +9 -19
  106. package/{src/scheduler-heatmap.ts → dist/scheduler-heatmap.d.ts} +12 -35
  107. package/dist/scheduler-heatmap.js +41 -0
  108. package/dist/scheduler-resource-tree.d.ts +48 -0
  109. package/dist/scheduler-resource-tree.js +78 -0
  110. package/dist/scheduler-slots.d.ts +37 -0
  111. package/dist/scheduler-slots.js +80 -0
  112. package/dist/scheduler-summary.d.ts +41 -0
  113. package/dist/scheduler-summary.js +54 -0
  114. package/dist/scheduler.d.ts +7 -0
  115. package/{src/scheduler.ts → dist/scheduler.js} +13 -14
  116. package/dist/scheduling.d.ts +132 -0
  117. package/dist/scheduling.js +228 -0
  118. package/dist/schema-designer.d.ts +42 -0
  119. package/dist/schema-designer.js +117 -0
  120. package/dist/schema.d.ts +369 -0
  121. package/dist/schema.js +216 -0
  122. package/dist/smart-shim.d.ts +62 -0
  123. package/dist/smart-shim.js +34 -0
  124. package/dist/sources/aggregate.d.ts +43 -0
  125. package/dist/sources/aggregate.js +60 -0
  126. package/dist/sources/auth-supabase.d.ts +69 -0
  127. package/dist/sources/auth-supabase.js +39 -0
  128. package/dist/sources/dashboard.d.ts +65 -0
  129. package/dist/sources/dashboard.js +95 -0
  130. package/dist/sources/field-inference.d.ts +23 -0
  131. package/dist/sources/field-inference.js +52 -0
  132. package/dist/sources/filters.d.ts +35 -0
  133. package/dist/sources/filters.js +52 -0
  134. package/dist/sources/index.d.ts +18 -0
  135. package/dist/sources/index.js +18 -0
  136. package/dist/sources/introspect-supabase.d.ts +30 -0
  137. package/dist/sources/introspect-supabase.js +134 -0
  138. package/dist/sources/realtime-supabase.d.ts +37 -0
  139. package/dist/sources/realtime-supabase.js +52 -0
  140. package/dist/sources/relation-lookup.d.ts +50 -0
  141. package/dist/sources/relation-lookup.js +77 -0
  142. package/dist/sources/rest-adapters.d.ts +48 -0
  143. package/dist/sources/rest-adapters.js +85 -0
  144. package/dist/sources/rest.d.ts +38 -0
  145. package/dist/sources/rest.js +86 -0
  146. package/dist/sources/schema-from-columns.d.ts +37 -0
  147. package/dist/sources/schema-from-columns.js +48 -0
  148. package/dist/sources/supabase.d.ts +33 -0
  149. package/dist/sources/supabase.js +74 -0
  150. package/dist/sources/with-entity-rules.d.ts +25 -0
  151. package/dist/sources/with-entity-rules.js +47 -0
  152. package/dist/sources/with-relation-labels.d.ts +26 -0
  153. package/dist/sources/with-relation-labels.js +38 -0
  154. package/dist/staged-editing.d.ts +85 -0
  155. package/dist/staged-editing.js +0 -0
  156. package/dist/studio/bug-report.d.ts +61 -0
  157. package/dist/studio/bug-report.js +126 -0
  158. package/dist/studio/cli.d.ts +56 -0
  159. package/dist/studio/cli.js +70 -0
  160. package/dist/studio/copilot-core.d.ts +22 -0
  161. package/{src/studio/copilot-core.ts → dist/studio/copilot-core.js} +34 -38
  162. package/dist/studio/csv.d.ts +36 -0
  163. package/dist/studio/csv.js +173 -0
  164. package/dist/studio/db-connect-string.d.ts +45 -0
  165. package/dist/studio/db-connect-string.js +113 -0
  166. package/dist/studio/deploy-cli.d.ts +35 -0
  167. package/dist/studio/deploy-cli.js +81 -0
  168. package/dist/studio/emit-project.d.ts +77 -0
  169. package/dist/studio/emit-project.js +5389 -0
  170. package/dist/studio/emit-schema.d.ts +110 -0
  171. package/dist/studio/emit-schema.js +1128 -0
  172. package/dist/studio/index.d.ts +35 -0
  173. package/dist/studio/index.js +38 -0
  174. package/dist/studio/init-flow.d.ts +58 -0
  175. package/dist/studio/init-flow.js +451 -0
  176. package/dist/studio/introspect-db.d.ts +47 -0
  177. package/dist/studio/introspect-db.js +255 -0
  178. package/dist/studio/introspect-openapi.d.ts +19 -0
  179. package/dist/studio/introspect-openapi.js +244 -0
  180. package/dist/studio/introspect-prisma.d.ts +25 -0
  181. package/dist/studio/introspect-prisma.js +164 -0
  182. package/dist/studio/introspect.d.ts +35 -0
  183. package/dist/studio/introspect.js +306 -0
  184. package/dist/studio/project.d.ts +1327 -0
  185. package/dist/studio/project.js +1798 -0
  186. package/dist/studio/sample-data.d.ts +19 -0
  187. package/dist/studio/sample-data.js +207 -0
  188. package/dist/studio/samples/ats.d.ts +2 -0
  189. package/dist/studio/samples/ats.js +194 -0
  190. package/dist/studio/samples/clinic.d.ts +2 -0
  191. package/dist/studio/samples/clinic.js +171 -0
  192. package/dist/studio/samples/crm.d.ts +2 -0
  193. package/dist/studio/samples/crm.js +280 -0
  194. package/dist/studio/samples/datasets.d.ts +38 -0
  195. package/dist/studio/samples/datasets.js +296 -0
  196. package/dist/studio/samples/ecommerce.d.ts +2 -0
  197. package/dist/studio/samples/ecommerce.js +178 -0
  198. package/dist/studio/samples/events.d.ts +2 -0
  199. package/dist/studio/samples/events.js +192 -0
  200. package/dist/studio/samples/fleet.d.ts +2 -0
  201. package/dist/studio/samples/fleet.js +203 -0
  202. package/dist/studio/samples/gym.d.ts +2 -0
  203. package/dist/studio/samples/gym.js +205 -0
  204. package/dist/studio/samples/hr.d.ts +2 -0
  205. package/dist/studio/samples/hr.js +186 -0
  206. package/dist/studio/samples/index.d.ts +13 -0
  207. package/dist/studio/samples/index.js +44 -0
  208. package/dist/studio/samples/insurance.d.ts +2 -0
  209. package/dist/studio/samples/insurance.js +220 -0
  210. package/dist/studio/samples/inventory.d.ts +2 -0
  211. package/dist/studio/samples/inventory.js +204 -0
  212. package/dist/studio/samples/invoicing.d.ts +2 -0
  213. package/dist/studio/samples/invoicing.js +154 -0
  214. package/dist/studio/samples/library.d.ts +2 -0
  215. package/dist/studio/samples/library.js +171 -0
  216. package/dist/studio/samples/live-data.d.ts +5 -0
  217. package/dist/studio/samples/live-data.js +261 -0
  218. package/dist/studio/samples/projects.d.ts +2 -0
  219. package/dist/studio/samples/projects.js +203 -0
  220. package/dist/studio/samples/realestate.d.ts +2 -0
  221. package/dist/studio/samples/realestate.js +187 -0
  222. package/dist/studio/samples/restaurant.d.ts +2 -0
  223. package/dist/studio/samples/restaurant.js +180 -0
  224. package/dist/studio/samples/school.d.ts +2 -0
  225. package/dist/studio/samples/school.js +188 -0
  226. package/dist/studio/samples/shared.d.ts +142 -0
  227. package/dist/studio/samples/shared.js +164 -0
  228. package/dist/studio/samples/starter.d.ts +4 -0
  229. package/dist/studio/samples/starter.js +237 -0
  230. package/dist/studio/samples/subscriptions.d.ts +2 -0
  231. package/dist/studio/samples/subscriptions.js +175 -0
  232. package/dist/studio/samples/support.d.ts +2 -0
  233. package/dist/studio/samples/support.js +209 -0
  234. package/dist/studio/scaffold-app.d.ts +22 -0
  235. package/{src/studio/scaffold-app.ts → dist/studio/scaffold-app.js} +45 -63
  236. package/dist/studio/scaffold.d.ts +63 -0
  237. package/dist/studio/scaffold.js +346 -0
  238. package/dist/studio/screen-suites.d.ts +193 -0
  239. package/dist/studio/screen-suites.js +297 -0
  240. package/dist/studio/themes.d.ts +34 -0
  241. package/dist/studio/themes.js +41 -0
  242. package/dist/studio/ui-components.d.ts +89 -0
  243. package/dist/studio/ui-components.generated.d.ts +29 -0
  244. package/dist/studio/ui-components.generated.js +7139 -0
  245. package/dist/studio/ui-components.js +673 -0
  246. package/dist/studio/user-error.d.ts +23 -0
  247. package/{src/studio/user-error.ts → dist/studio/user-error.js} +10 -13
  248. package/dist/studio/verify.d.ts +34 -0
  249. package/dist/studio/verify.js +47 -0
  250. package/dist/sveltekit/in-memory.d.ts +14 -0
  251. package/dist/sveltekit/in-memory.js +113 -0
  252. package/dist/sveltekit/index.d.ts +6 -0
  253. package/dist/sveltekit/index.js +5 -0
  254. package/dist/sveltekit/query-plan.d.ts +44 -0
  255. package/dist/sveltekit/query-plan.js +76 -0
  256. package/dist/sveltekit/sql-source.d.ts +47 -0
  257. package/dist/sveltekit/sql-source.js +106 -0
  258. package/dist/sveltekit/sql.d.ts +48 -0
  259. package/dist/sveltekit/sql.js +73 -0
  260. package/dist/sveltekit/transport.d.ts +209 -0
  261. package/dist/sveltekit/transport.js +219 -0
  262. package/{src/sveltekit/types.ts → dist/sveltekit/types.d.ts} +8 -11
  263. package/dist/sveltekit/types.js +1 -0
  264. package/dist/upgrade-prompt.d.ts +16 -0
  265. package/dist/upgrade-prompt.js +141 -0
  266. package/dist/version.d.ts +13 -0
  267. package/{src/version.ts → dist/version.js} +1 -1
  268. package/dist/watermark.d.ts +2 -0
  269. package/dist/watermark.js +146 -0
  270. package/package.json +26 -24
  271. package/src/SvBoard.dom.test.ts +0 -67
  272. package/src/SvGridAlerts.dom.test.ts +0 -113
  273. package/src/SvGridEditPanel.dom.test.ts +0 -320
  274. package/src/SvRecordDetail.dom.test.ts +0 -137
  275. package/src/SvSchedule.dom.test.ts +0 -57
  276. package/src/ai-export-pdf.dom.test.ts +0 -77
  277. package/src/ai-export-xlsx.dom.test.ts +0 -90
  278. package/src/ai-export.dom.test.ts +0 -114
  279. package/src/alerts/alert-engine-attach.ts +0 -165
  280. package/src/alerts/alert-engine.test.ts +0 -135
  281. package/src/alerts/alert-engine.ts +0 -260
  282. package/src/alerts/alert-formats.test.ts +0 -87
  283. package/src/alerts/alert-formats.ts +0 -77
  284. package/src/alerts/alert-observer.test.ts +0 -189
  285. package/src/alerts/alert-observer.ts +0 -208
  286. package/src/alerts/alert-scheduler.ts +0 -96
  287. package/src/alerts/alert-storage.test.ts +0 -54
  288. package/src/alerts/alert-storage.ts +0 -116
  289. package/src/alerts/alert-store.svelte.ts +0 -80
  290. package/src/alerts/alert-types.ts +0 -94
  291. package/src/board.dom.test.ts +0 -941
  292. package/src/edit-panel.test.ts +0 -322
  293. package/src/edit-panel.ts +0 -379
  294. package/src/export-conditional.test.ts +0 -60
  295. package/src/export-conditional.ts +0 -94
  296. package/src/export-ooxml.test.ts +0 -152
  297. package/src/export-ooxml.ts +0 -489
  298. package/src/export-pdf.test.ts +0 -138
  299. package/src/export-pdf.ts +0 -245
  300. package/src/export-print.test.ts +0 -66
  301. package/src/export-print.ts +0 -132
  302. package/src/export-serialize.test.ts +0 -56
  303. package/src/export-xls.ts +0 -199
  304. package/src/export-xlsx-roundtrip.test.ts +0 -120
  305. package/src/export-xlsx.test.ts +0 -150
  306. package/src/export.test.ts +0 -349
  307. package/src/export.ts +0 -1464
  308. package/src/expressions/evaluate.test.ts +0 -111
  309. package/src/expressions/evaluate.ts +0 -237
  310. package/src/expressions/expression-columns.ts +0 -133
  311. package/src/expressions/expression-types.ts +0 -84
  312. package/src/expressions/parse.test.ts +0 -106
  313. package/src/expressions/parse.ts +0 -610
  314. package/src/import-automap.test.ts +0 -131
  315. package/src/import-hardening.test.ts +0 -158
  316. package/src/import.test.ts +0 -415
  317. package/src/import.ts +0 -1044
  318. package/src/index.ts +0 -569
  319. package/src/install.ts +0 -154
  320. package/src/license-core.test.ts +0 -23
  321. package/src/license-core.ts +0 -107
  322. package/src/license-expiry.test.ts +0 -127
  323. package/src/license.ts +0 -137
  324. package/src/master-detail.test.ts +0 -61
  325. package/src/master-detail.ts +0 -42
  326. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/_metadata.json +0 -178
  327. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/attachments-ZrPsKxob.js +0 -3875
  328. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/attachments-ZrPsKxob.js.map +0 -1
  329. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/constants-ACqvWGE2.js +0 -21
  330. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/constants-ACqvWGE2.js.map +0 -1
  331. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/dev-D3w5jt92.js +0 -1938
  332. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/dev-D3w5jt92.js.map +0 -1
  333. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/events-CC2V3H0y.js +0 -205
  334. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/events-CC2V3H0y.js.map +0 -1
  335. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/flags-BXP37tAa.js +0 -18
  336. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/flags-BXP37tAa.js.map +0 -1
  337. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/hydration-DwubnU5b.js +0 -264
  338. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/hydration-DwubnU5b.js.map +0 -1
  339. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/legacy-client-hD7f6PUz.js +0 -697
  340. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/legacy-client-hD7f6PUz.js.map +0 -1
  341. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte.js +0 -134
  342. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte.js.map +0 -1
  343. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_animate.js +0 -55
  344. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_animate.js.map +0 -1
  345. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_attachments.js +0 -2
  346. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_compiler.js +0 -46843
  347. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_compiler.js.map +0 -1
  348. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_easing.js +0 -237
  349. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_easing.js.map +0 -1
  350. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_events.js +0 -2
  351. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal.js +0 -4
  352. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal.js.map +0 -1
  353. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_client.js +0 -7
  354. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_disclose-version.js +0 -4
  355. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_disclose-version.js.map +0 -1
  356. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_async.js +0 -5
  357. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_async.js.map +0 -1
  358. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_legacy.js +0 -5
  359. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_legacy.js.map +0 -1
  360. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_tracing.js +0 -5
  361. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_tracing.js.map +0 -1
  362. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_server.js +0 -6
  363. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_legacy.js +0 -83
  364. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_legacy.js.map +0 -1
  365. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_motion.js +0 -559
  366. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_motion.js.map +0 -1
  367. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_reactivity.js +0 -24
  368. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_reactivity.js.map +0 -1
  369. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_reactivity_window.js +0 -122
  370. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_reactivity_window.js.map +0 -1
  371. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_server.js +0 -2
  372. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_store.js +0 -89
  373. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_store.js.map +0 -1
  374. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_transition.js +0 -241
  375. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_transition.js.map +0 -1
  376. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/utils-DBx1SCN6.js +0 -4938
  377. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/utils-DBx1SCN6.js.map +0 -1
  378. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/utils-gjfpSTFS.js +0 -495
  379. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/utils-gjfpSTFS.js.map +0 -1
  380. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/validate-DKoOKg8S.js +0 -190
  381. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/validate-DKoOKg8S.js.map +0 -1
  382. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/version-C0MiR7eR.js +0 -8
  383. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/version-C0MiR7eR.js.map +0 -1
  384. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/warnings-B6Y7P0Q-.js +0 -138
  385. package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/warnings-B6Y7P0Q-.js.map +0 -1
  386. package/src/pivot-chart.test.ts +0 -86
  387. package/src/pivot-chart.ts +0 -112
  388. package/src/pivot-designer.ts +0 -101
  389. package/src/pivot.test.ts +0 -335
  390. package/src/pivot.ts +0 -578
  391. package/src/print.ts +0 -107
  392. package/src/scheduler-assignments.test.ts +0 -97
  393. package/src/scheduler-assignments.ts +0 -134
  394. package/src/scheduler-axis.test.ts +0 -108
  395. package/src/scheduler-axis.ts +0 -238
  396. package/src/scheduler-booking.test.ts +0 -57
  397. package/src/scheduler-config.ts +0 -179
  398. package/src/scheduler-dependencies.test.ts +0 -155
  399. package/src/scheduler-dependencies.ts +0 -223
  400. package/src/scheduler-freebusy.test.ts +0 -41
  401. package/src/scheduler-heatmap.test.ts +0 -39
  402. package/src/scheduler-resource-tree.test.ts +0 -84
  403. package/src/scheduler-resource-tree.ts +0 -107
  404. package/src/scheduler-slots.test.ts +0 -53
  405. package/src/scheduler-slots.ts +0 -94
  406. package/src/scheduler-summary.test.ts +0 -47
  407. package/src/scheduler-summary.ts +0 -81
  408. package/src/scheduling.test.ts +0 -194
  409. package/src/scheduling.ts +0 -293
  410. package/src/schema-designer.test.ts +0 -121
  411. package/src/schema-designer.ts +0 -142
  412. package/src/schema.test.ts +0 -268
  413. package/src/schema.ts +0 -562
  414. package/src/smart-shim.ts +0 -107
  415. package/src/sources/aggregate.test.ts +0 -79
  416. package/src/sources/aggregate.ts +0 -102
  417. package/src/sources/auth-supabase.test.ts +0 -80
  418. package/src/sources/auth-supabase.ts +0 -87
  419. package/src/sources/dashboard.kpi.test.ts +0 -50
  420. package/src/sources/dashboard.test.ts +0 -61
  421. package/src/sources/dashboard.ts +0 -136
  422. package/src/sources/field-inference.test.ts +0 -60
  423. package/src/sources/field-inference.ts +0 -63
  424. package/src/sources/filters.test.ts +0 -58
  425. package/src/sources/filters.ts +0 -70
  426. package/src/sources/index.ts +0 -67
  427. package/src/sources/introspect-supabase.test.ts +0 -112
  428. package/src/sources/introspect-supabase.ts +0 -139
  429. package/src/sources/realtime-supabase.test.ts +0 -93
  430. package/src/sources/realtime-supabase.ts +0 -99
  431. package/src/sources/relation-lookup.test.ts +0 -99
  432. package/src/sources/relation-lookup.ts +0 -128
  433. package/src/sources/rest-adapters.test.ts +0 -95
  434. package/src/sources/rest-adapters.ts +0 -120
  435. package/src/sources/rest.test.ts +0 -104
  436. package/src/sources/rest.ts +0 -129
  437. package/src/sources/schema-from-columns.test.ts +0 -106
  438. package/src/sources/schema-from-columns.ts +0 -88
  439. package/src/sources/supabase.test.ts +0 -110
  440. package/src/sources/supabase.ts +0 -99
  441. package/src/sources/with-entity-rules.test.ts +0 -104
  442. package/src/sources/with-entity-rules.ts +0 -78
  443. package/src/sources/with-relation-labels.test.ts +0 -75
  444. package/src/sources/with-relation-labels.ts +0 -73
  445. package/src/staged-editing.ts +0 -0
  446. package/src/studio/bug-report.test.ts +0 -101
  447. package/src/studio/bug-report.ts +0 -165
  448. package/src/studio/cli.test.ts +0 -187
  449. package/src/studio/cli.ts +0 -117
  450. package/src/studio/copilot-core.test.ts +0 -45
  451. package/src/studio/csv.test.ts +0 -90
  452. package/src/studio/csv.ts +0 -165
  453. package/src/studio/db-connect-string.test.ts +0 -94
  454. package/src/studio/db-connect-string.ts +0 -128
  455. package/src/studio/deploy-cli.test.ts +0 -56
  456. package/src/studio/deploy-cli.ts +0 -100
  457. package/src/studio/emit-project.test.ts +0 -3324
  458. package/src/studio/emit-project.ts +0 -5377
  459. package/src/studio/emit-schema.test.ts +0 -111
  460. package/src/studio/emit-schema.ts +0 -1181
  461. package/src/studio/index.ts +0 -380
  462. package/src/studio/init-flow.test.ts +0 -514
  463. package/src/studio/init-flow.ts +0 -556
  464. package/src/studio/introspect-db.test.ts +0 -186
  465. package/src/studio/introspect-db.ts +0 -312
  466. package/src/studio/introspect-openapi.test.ts +0 -84
  467. package/src/studio/introspect-openapi.ts +0 -252
  468. package/src/studio/introspect-prisma.test.ts +0 -99
  469. package/src/studio/introspect-prisma.ts +0 -175
  470. package/src/studio/introspect.test.ts +0 -172
  471. package/src/studio/introspect.ts +0 -310
  472. package/src/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/_svelte_metadata.json +0 -1
  473. package/src/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/package.json +0 -3
  474. package/src/studio/pipeline.test.ts +0 -42
  475. package/src/studio/project-robust.test.ts +0 -157
  476. package/src/studio/project.test.ts +0 -929
  477. package/src/studio/project.ts +0 -2394
  478. package/src/studio/sample-data.test.ts +0 -58
  479. package/src/studio/sample-data.ts +0 -203
  480. package/src/studio/samples/ats.ts +0 -202
  481. package/src/studio/samples/clinic.ts +0 -179
  482. package/src/studio/samples/crm.ts +0 -291
  483. package/src/studio/samples/datasets.test.ts +0 -84
  484. package/src/studio/samples/datasets.ts +0 -340
  485. package/src/studio/samples/ecommerce.ts +0 -187
  486. package/src/studio/samples/events.ts +0 -201
  487. package/src/studio/samples/fleet.ts +0 -213
  488. package/src/studio/samples/gym.ts +0 -215
  489. package/src/studio/samples/hr.ts +0 -195
  490. package/src/studio/samples/index.ts +0 -55
  491. package/src/studio/samples/insurance.ts +0 -229
  492. package/src/studio/samples/inventory.ts +0 -213
  493. package/src/studio/samples/invoicing.ts +0 -162
  494. package/src/studio/samples/library.ts +0 -180
  495. package/src/studio/samples/live-data.test.ts +0 -99
  496. package/src/studio/samples/live-data.ts +0 -306
  497. package/src/studio/samples/projects.ts +0 -212
  498. package/src/studio/samples/realestate.ts +0 -196
  499. package/src/studio/samples/restaurant.ts +0 -189
  500. package/src/studio/samples/samples.test.ts +0 -304
  501. package/src/studio/samples/school.ts +0 -197
  502. package/src/studio/samples/seed-floor.test.ts +0 -25
  503. package/src/studio/samples/shared.ts +0 -237
  504. package/src/studio/samples/starter.ts +0 -251
  505. package/src/studio/samples/subscriptions.ts +0 -183
  506. package/src/studio/samples/support.ts +0 -216
  507. package/src/studio/scaffold-app.test.ts +0 -91
  508. package/src/studio/scaffold.test.ts +0 -192
  509. package/src/studio/scaffold.ts +0 -390
  510. package/src/studio/screen-suites.test.ts +0 -269
  511. package/src/studio/screen-suites.ts +0 -448
  512. package/src/studio/themes.ts +0 -62
  513. package/src/studio/ui-components-surface.test.ts +0 -185
  514. package/src/studio/ui-components.generated.ts +0 -7154
  515. package/src/studio/ui-components.ts +0 -742
  516. package/src/studio/verify.test.ts +0 -47
  517. package/src/studio/verify.ts +0 -79
  518. package/src/sveltekit/in-memory.test.ts +0 -104
  519. package/src/sveltekit/in-memory.ts +0 -129
  520. package/src/sveltekit/index.ts +0 -24
  521. package/src/sveltekit/query-plan.test.ts +0 -109
  522. package/src/sveltekit/query-plan.ts +0 -125
  523. package/src/sveltekit/sql-source.test.ts +0 -198
  524. package/src/sveltekit/sql-source.ts +0 -171
  525. package/src/sveltekit/sql.test.ts +0 -80
  526. package/src/sveltekit/sql.ts +0 -131
  527. package/src/sveltekit/transport-scope.test.ts +0 -125
  528. package/src/sveltekit/transport.test.ts +0 -201
  529. package/src/sveltekit/transport.ts +0 -373
  530. package/src/upgrade-prompt.test.ts +0 -71
  531. package/src/upgrade-prompt.ts +0 -162
  532. package/src/version.test.ts +0 -17
  533. package/src/watermark.test.ts +0 -97
  534. package/src/watermark.ts +0 -156
  535. /package/{src → dist}/SvAlertRuleEditor.svelte +0 -0
  536. /package/{src → dist}/SvAlertsManager.svelte +0 -0
  537. /package/{src → dist}/SvAlertsPanel.svelte +0 -0
  538. /package/{src → dist}/SvAuthGate.svelte +0 -0
  539. /package/{src → dist}/SvBoard.svelte +0 -0
  540. /package/{src → dist}/SvExportMenu.svelte +0 -0
  541. /package/{src → dist}/SvExpressionEditor.svelte +0 -0
  542. /package/{src → dist}/SvFileInput.svelte +0 -0
  543. /package/{src → dist}/SvGridAlerts.svelte +0 -0
  544. /package/{src → dist}/SvGridBoard.svelte +0 -0
  545. /package/{src → dist}/SvGridEditPanel.svelte +0 -0
  546. /package/{src → dist}/SvGridMasterDetail.svelte +0 -0
  547. /package/{src → dist}/SvGridScheduler.svelte +0 -0
  548. /package/{src → dist}/SvImportDialog.svelte +0 -0
  549. /package/{src → dist}/SvLookupInput.svelte +0 -0
  550. /package/{src → dist}/SvPivotDesigner.svelte +0 -0
  551. /package/{src → dist}/SvRecordDetail.svelte +0 -0
  552. /package/{src → dist}/SvSchedule.svelte +0 -0
  553. /package/{src → dist}/SvSchemaChart.svelte +0 -0
  554. /package/{src → dist}/SvSchemaDashboard.svelte +0 -0
  555. /package/{src → dist}/pdfmake-shims.d.ts +0 -0
  556. /package/{src → dist}/smart.export.d.ts +0 -0
  557. /package/{src → dist}/smart.export.js +0 -0
  558. /package/{src → dist}/studio/HANDLERS-DESIGN.md +0 -0
  559. /package/{src → dist/studio}/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/_svelte_metadata.json +0 -0
  560. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/_metadata.json +0 -0
  561. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/attachments-BOv1rBKp.js +0 -0
  562. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/attachments-BOv1rBKp.js.map +0 -0
  563. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/constants-B9vgIdCd.js +0 -0
  564. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/constants-B9vgIdCd.js.map +0 -0
  565. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/dev-T1qbW_qD.js +0 -0
  566. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/dev-T1qbW_qD.js.map +0 -0
  567. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/events-Bo11SfVK.js +0 -0
  568. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/events-Bo11SfVK.js.map +0 -0
  569. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/flags-X7D4vfrZ.js +0 -0
  570. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/flags-X7D4vfrZ.js.map +0 -0
  571. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/hydration-oyUje5i1.js +0 -0
  572. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/hydration-oyUje5i1.js.map +0 -0
  573. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/legacy-client-DeSQgSFm.js +0 -0
  574. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/legacy-client-DeSQgSFm.js.map +0 -0
  575. /package/{src → dist/studio}/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/package.json +0 -0
  576. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte.js +0 -0
  577. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte.js.map +0 -0
  578. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_animate.js +0 -0
  579. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_animate.js.map +0 -0
  580. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_attachments.js +0 -0
  581. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_compiler.js +0 -0
  582. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_compiler.js.map +0 -0
  583. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_easing.js +0 -0
  584. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_easing.js.map +0 -0
  585. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_events.js +0 -0
  586. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal.js +0 -0
  587. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal.js.map +0 -0
  588. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_client.js +0 -0
  589. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_disclose-version.js +0 -0
  590. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_disclose-version.js.map +0 -0
  591. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_async.js +0 -0
  592. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_async.js.map +0 -0
  593. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_legacy.js +0 -0
  594. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_legacy.js.map +0 -0
  595. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_tracing.js +0 -0
  596. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_tracing.js.map +0 -0
  597. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_server.js +0 -0
  598. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_legacy.js +0 -0
  599. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_legacy.js.map +0 -0
  600. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_motion.js +0 -0
  601. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_motion.js.map +0 -0
  602. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_reactivity.js +0 -0
  603. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_reactivity.js.map +0 -0
  604. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_reactivity_window.js +0 -0
  605. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_reactivity_window.js.map +0 -0
  606. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_server.js +0 -0
  607. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_store.js +0 -0
  608. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_store.js.map +0 -0
  609. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_transition.js +0 -0
  610. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_transition.js.map +0 -0
  611. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/utils-BbWyXNk1.js +0 -0
  612. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/utils-BbWyXNk1.js.map +0 -0
  613. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/utils-DI_fC7vt.js +0 -0
  614. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/utils-DI_fC7vt.js.map +0 -0
  615. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/validate-Dyr3lQv9.js +0 -0
  616. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/validate-Dyr3lQv9.js.map +0 -0
  617. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/version-_9FHH-LF.js +0 -0
  618. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/version-_9FHH-LF.js.map +0 -0
  619. /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/warnings-CUbSPnyP.js +0 -0
  620. /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
- })