@svgrid/enterprise 3.0.0 → 3.0.2

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 (390) hide show
  1. package/README.md +95 -95
  2. package/dist/ExpressionEditorHarness.svelte.d.ts +2 -2
  3. package/dist/SvAdvancedFilter.svelte.d.ts +2 -2
  4. package/dist/SvAlertRuleEditor.svelte.d.ts +2 -2
  5. package/dist/SvAlertsManager.svelte.d.ts +3 -3
  6. package/dist/SvAlertsPanel.svelte.d.ts +1 -1
  7. package/dist/SvAuthGate.svelte +115 -115
  8. package/dist/SvAuthGate.svelte.d.ts +1 -1
  9. package/dist/SvBoard.svelte.d.ts +1 -1
  10. package/dist/SvExportMenu.svelte +553 -553
  11. package/dist/SvExportMenu.svelte.d.ts +2 -2
  12. package/dist/SvExpressionEditor.svelte.d.ts +2 -2
  13. package/dist/SvFileInput.svelte +113 -113
  14. package/dist/SvFormulaBar.svelte +606 -0
  15. package/dist/SvFormulaBar.svelte.d.ts +62 -0
  16. package/dist/SvGridAlerts.svelte.d.ts +2 -2
  17. package/dist/SvGridBoard.svelte +2358 -2358
  18. package/dist/SvGridBulkEditDrawer.svelte.d.ts +1 -1
  19. package/dist/SvGridEditPanel.svelte +1157 -1157
  20. package/dist/SvGridEditPanel.svelte.d.ts +3 -3
  21. package/dist/SvGridMasterDetail.svelte +116 -116
  22. package/dist/SvGridMasterDetail.svelte.d.ts +1 -1
  23. package/dist/SvGridScheduler.svelte +5358 -5358
  24. package/dist/SvImportDialog.svelte +1020 -1020
  25. package/dist/SvImportDialog.svelte.d.ts +2 -2
  26. package/dist/SvLookupInput.svelte +180 -180
  27. package/dist/SvLookupInput.svelte.d.ts +1 -1
  28. package/dist/SvPivotDesigner.svelte +2041 -1990
  29. package/dist/SvPivotDesigner.svelte.d.ts +2 -2
  30. package/dist/SvRecordDetail.svelte.d.ts +1 -1
  31. package/dist/SvRibbonIcon.svelte +46 -0
  32. package/dist/SvRibbonIcon.svelte.d.ts +17 -0
  33. package/dist/SvSchedule.svelte.d.ts +1 -1
  34. package/dist/SvSchemaChart.svelte +236 -234
  35. package/dist/SvSchemaChart.svelte.d.ts +2 -2
  36. package/dist/SvSchemaDashboard.svelte +130 -130
  37. package/dist/SvSchemaDashboard.svelte.d.ts +3 -3
  38. package/dist/SvSheet.svelte +4114 -0
  39. package/dist/SvSheet.svelte.d.ts +142 -0
  40. package/dist/SvSheetComment.svelte +98 -0
  41. package/dist/SvSheetComment.svelte.d.ts +22 -0
  42. package/dist/SvSheetConditionalFormat.svelte +162 -0
  43. package/dist/SvSheetConditionalFormat.svelte.d.ts +14 -0
  44. package/dist/SvSheetDataValidation.svelte +249 -0
  45. package/dist/SvSheetDataValidation.svelte.d.ts +14 -0
  46. package/dist/SvSheetFilterMenu.svelte +217 -0
  47. package/dist/SvSheetFilterMenu.svelte.d.ts +17 -0
  48. package/dist/SvSheetFindReplace.svelte +132 -0
  49. package/dist/SvSheetFindReplace.svelte.d.ts +10 -0
  50. package/dist/SvSheetFormatCells.svelte +421 -0
  51. package/dist/SvSheetFormatCells.svelte.d.ts +17 -0
  52. package/dist/SvSheetGoalSeek.svelte +144 -0
  53. package/dist/SvSheetGoalSeek.svelte.d.ts +12 -0
  54. package/dist/SvSheetInsertFunction.svelte +147 -0
  55. package/dist/SvSheetInsertFunction.svelte.d.ts +8 -0
  56. package/dist/SvSheetListPicker.svelte +89 -0
  57. package/dist/SvSheetListPicker.svelte.d.ts +16 -0
  58. package/dist/SvSheetManageRules.svelte +185 -0
  59. package/dist/SvSheetManageRules.svelte.d.ts +16 -0
  60. package/dist/SvSheetNameManager.svelte +225 -0
  61. package/dist/SvSheetNameManager.svelte.d.ts +11 -0
  62. package/dist/SvSheetPasteSpecial.svelte +105 -0
  63. package/dist/SvSheetPasteSpecial.svelte.d.ts +12 -0
  64. package/dist/SvSheetRemoveDuplicates.svelte +149 -0
  65. package/dist/SvSheetRemoveDuplicates.svelte.d.ts +12 -0
  66. package/dist/SvSheetRibbon.svelte +1201 -0
  67. package/dist/SvSheetRibbon.svelte.d.ts +34 -0
  68. package/dist/SvSheetSizeDialog.svelte +58 -0
  69. package/dist/SvSheetSizeDialog.svelte.d.ts +11 -0
  70. package/dist/SvSheetTabs.svelte +441 -0
  71. package/dist/SvSheetTabs.svelte.d.ts +36 -0
  72. package/dist/SvSheetTabs.test-harness.svelte.d.ts +17 -0
  73. package/dist/SvSheetTabs.test-harness.svelte.js +22 -0
  74. package/dist/SvSheetTextToColumns.svelte +172 -0
  75. package/dist/SvSheetTextToColumns.svelte.d.ts +13 -0
  76. package/dist/SvSheetValidationAlert.svelte +83 -0
  77. package/dist/SvSheetValidationAlert.svelte.d.ts +15 -0
  78. package/dist/advanced-filter/expr-columns-from-grid.d.ts +1 -1
  79. package/dist/advanced-filter-enable.js +3 -3
  80. package/dist/alerts/alert-engine-attach.d.ts +2 -2
  81. package/dist/alerts/alert-engine-attach.js +3 -3
  82. package/dist/alerts/alert-engine.d.ts +1 -1
  83. package/dist/alerts/alert-engine.js +2 -2
  84. package/dist/alerts/alert-formats.d.ts +1 -1
  85. package/dist/alerts/alert-formats.js +1 -1
  86. package/dist/alerts/alert-observer.d.ts +3 -3
  87. package/dist/alerts/alert-observer.js +1 -1
  88. package/dist/alerts/alert-storage.d.ts +1 -1
  89. package/dist/alerts/alert-store.svelte.d.ts +1 -1
  90. package/dist/alerts/alert-types.d.ts +2 -2
  91. package/dist/alerts.js +2 -2
  92. package/dist/board.js +2 -2
  93. package/dist/cdn/svgrid-enterprise.svelte-external.js +19046 -5428
  94. package/dist/designer/assets/GridMenus-BlsvL_aU.js +8 -0
  95. package/dist/designer/assets/SvChartMenu-BYO9cYdy.css +1 -0
  96. package/dist/designer/assets/SvChartMenu-D9hEeHar.js +1 -0
  97. package/dist/designer/assets/SvDateRangeInput-BBRzrQeg.js +1 -0
  98. package/dist/designer/assets/SvDateRangeInput-C0iCCZ8o.css +1 -0
  99. package/dist/designer/assets/SvDateTimePicker-DARvKUL2.js +1 -0
  100. package/dist/designer/assets/SvDateTimePicker-DPv09DIT.css +1 -0
  101. package/dist/designer/assets/{preload-helper-CG0n22O7.js → SvGrid.helpers-BgT-gnCo.js} +1 -1
  102. package/dist/designer/assets/SvGridCellEditor-C7uQXYds.js +4 -0
  103. package/dist/designer/assets/SvGridChart-B8j1SSy3.js +3 -0
  104. package/dist/designer/assets/SvGridChart-BgLuPO7I.css +1 -0
  105. package/dist/designer/assets/SvGridChartBuilder-08YWWeqY.css +1 -0
  106. package/dist/designer/assets/SvGridChartBuilder-kvyIU_Rl.js +1 -0
  107. package/dist/designer/assets/SvGridChartPanel-4Pc8y5yO.css +1 -0
  108. package/dist/designer/assets/SvGridChartPanel-pT6ITc2P.js +4 -0
  109. package/dist/designer/assets/SvGridChartView-7msfnWZT.css +1 -0
  110. package/dist/designer/assets/SvGridChartView-bg281UA1.js +1 -0
  111. package/dist/designer/assets/SvGridDropdown-Bb3HH2Aj.js +1 -0
  112. package/dist/designer/assets/SvGridDropdown-CcidB3rm.css +1 -0
  113. package/dist/designer/assets/SvListBox-BDS66lmZ.js +110 -0
  114. package/dist/designer/assets/SvListBox-BXfyqy4a.css +1 -0
  115. package/dist/designer/assets/SvMenuList-DJ47ba1h.css +1 -0
  116. package/dist/designer/assets/SvMenuList-Dgq2D5VN.js +1 -0
  117. package/dist/designer/assets/SvTabs-DKmwb5p1.css +1 -0
  118. package/dist/designer/assets/SvTabs-UFCMTHXS.js +1 -0
  119. package/dist/designer/assets/cell-formatting-wr5wm7US.js +1 -0
  120. package/dist/designer/assets/chart-cIPUsbM5.js +1 -0
  121. package/dist/designer/assets/chart-export-B6bkQ3X8.js +11 -0
  122. package/dist/designer/assets/chart-export-pdf-BbA28-gt.js +11 -0
  123. package/dist/designer/assets/chart-panel-messages-DtTxpBUU.js +1 -0
  124. package/dist/designer/assets/chart-summary-Czu_5epb.js +1 -0
  125. package/dist/designer/assets/chart-trend-D5I5VEe8.js +1 -0
  126. package/dist/designer/assets/chart-validate-BMqM-qkF.js +1 -0
  127. package/dist/designer/assets/column-resize-BYDzR1Ve.js +1 -0
  128. package/dist/designer/assets/date-format-B8JbEtIG.js +1 -0
  129. package/dist/designer/assets/date-format-DKS-z0xS.css +1 -0
  130. package/dist/designer/assets/editor-contract-Bpoa7A5g.js +1 -0
  131. package/dist/designer/assets/export-format-D-eP4b2l.js +6 -0
  132. package/dist/designer/assets/focus-trap-CAreAhlU.js +1 -0
  133. package/dist/designer/assets/index-CMFgAoVV.css +1 -0
  134. package/dist/designer/assets/{index-zUBix-JQ.js → index-DwU7CAMm.js} +2985 -141
  135. package/dist/designer/assets/list-option-BP_dWS66.js +1 -0
  136. package/dist/designer/assets/preload-helper-HclGiUj8.js +1 -0
  137. package/dist/designer/assets/row-resize-DLktcqUK.js +1 -0
  138. package/dist/designer/assets/src-CITpcm6b.js +1 -0
  139. package/dist/designer/assets/src-EdI3Xqds.js +58 -0
  140. package/dist/designer/index.html +32 -23
  141. package/dist/export-conditional.d.ts +1 -1
  142. package/dist/export-pdf.d.ts +89 -0
  143. package/dist/export-pdf.js +130 -0
  144. package/dist/export-print.js +19 -19
  145. package/dist/export-xls.d.ts +2 -2
  146. package/dist/export.d.ts +2 -2
  147. package/dist/export.js +23 -16
  148. package/dist/expressions/builder-tree.d.ts +2 -2
  149. package/dist/expressions/builder-tree.js +1 -1
  150. package/dist/expressions/compile.d.ts +1 -1
  151. package/dist/import.js +1 -1
  152. package/dist/index.d.ts +116 -53
  153. package/dist/index.js +117 -50
  154. package/dist/install.d.ts +4 -4
  155. package/dist/install.js +16 -11
  156. package/dist/license.d.ts +3 -2
  157. package/dist/license.js +9 -4
  158. package/dist/node/studio.js +187 -116
  159. package/dist/pivot-chart.d.ts +26 -2
  160. package/dist/pivot-chart.js +25 -69
  161. package/dist/pivot-designer.d.ts +1 -1
  162. package/dist/pivot-enable.js +3 -3
  163. package/dist/print.d.ts +1 -1
  164. package/dist/print.js +4 -4
  165. package/dist/scheduler-config.d.ts +5 -5
  166. package/dist/scheduler-freebusy.d.ts +1 -1
  167. package/dist/scheduler-freebusy.js +1 -1
  168. package/dist/scheduler.js +2 -2
  169. package/dist/schema-designer.d.ts +1 -1
  170. package/dist/schema-designer.js +2 -2
  171. package/dist/selection-bar.js +2 -2
  172. package/dist/sheet/address.d.ts +43 -0
  173. package/dist/sheet/address.js +81 -0
  174. package/dist/sheet/ast.d.ts +94 -0
  175. package/dist/sheet/ast.js +56 -0
  176. package/dist/sheet/auto-filter.d.ts +66 -0
  177. package/dist/sheet/auto-filter.js +147 -0
  178. package/dist/sheet/autocomplete.d.ts +42 -0
  179. package/dist/sheet/autocomplete.js +162 -0
  180. package/dist/sheet/coerce.d.ts +31 -0
  181. package/dist/sheet/coerce.js +122 -0
  182. package/dist/sheet/commands.d.ts +89 -0
  183. package/dist/sheet/commands.js +230 -0
  184. package/dist/sheet/comments.d.ts +29 -0
  185. package/dist/sheet/comments.js +73 -0
  186. package/dist/sheet/conditional-formats.d.ts +144 -0
  187. package/dist/sheet/conditional-formats.js +316 -0
  188. package/dist/sheet/deps.d.ts +60 -0
  189. package/dist/sheet/deps.js +199 -0
  190. package/dist/sheet/document.d.ts +150 -0
  191. package/dist/sheet/document.js +264 -0
  192. package/dist/sheet/edit-keys.d.ts +14 -0
  193. package/dist/sheet/edit-keys.js +40 -0
  194. package/dist/sheet/entry.d.ts +31 -0
  195. package/dist/sheet/entry.js +76 -0
  196. package/dist/sheet/evaluate.d.ts +61 -0
  197. package/dist/sheet/evaluate.js +337 -0
  198. package/dist/sheet/find-replace.d.ts +62 -0
  199. package/dist/sheet/find-replace.js +152 -0
  200. package/dist/sheet/format-store.d.ts +99 -0
  201. package/dist/sheet/format-store.js +233 -0
  202. package/dist/sheet/freeze.d.ts +54 -0
  203. package/dist/sheet/freeze.js +58 -0
  204. package/dist/sheet/function-catalog.d.ts +10 -0
  205. package/dist/sheet/function-catalog.js +94 -0
  206. package/dist/sheet/functions.d.ts +28 -0
  207. package/dist/sheet/functions.js +362 -0
  208. package/dist/sheet/goal-seek.d.ts +73 -0
  209. package/dist/sheet/goal-seek.js +153 -0
  210. package/dist/sheet/index.d.ts +53 -0
  211. package/dist/sheet/index.js +53 -0
  212. package/dist/sheet/merges.d.ts +71 -0
  213. package/dist/sheet/merges.js +137 -0
  214. package/dist/sheet/names.d.ts +31 -0
  215. package/dist/sheet/names.js +87 -0
  216. package/dist/sheet/navigate.d.ts +52 -0
  217. package/dist/sheet/navigate.js +135 -0
  218. package/dist/sheet/number-format.d.ts +63 -0
  219. package/dist/sheet/number-format.js +508 -0
  220. package/dist/sheet/palette.d.ts +19 -0
  221. package/dist/sheet/palette.js +84 -0
  222. package/dist/sheet/parse.d.ts +13 -0
  223. package/dist/sheet/parse.js +108 -0
  224. package/dist/sheet/paste-special.d.ts +164 -0
  225. package/dist/sheet/paste-special.js +592 -0
  226. package/dist/sheet/protection.d.ts +21 -0
  227. package/dist/sheet/protection.js +48 -0
  228. package/dist/sheet/rects.d.ts +45 -0
  229. package/dist/sheet/rects.js +112 -0
  230. package/dist/sheet/refs.d.ts +82 -0
  231. package/dist/sheet/refs.js +266 -0
  232. package/dist/sheet/ribbon-icons.d.ts +31 -0
  233. package/dist/sheet/ribbon-icons.js +350 -0
  234. package/dist/sheet/ribbon.d.ts +173 -0
  235. package/dist/sheet/ribbon.js +753 -0
  236. package/dist/sheet/shortcuts.d.ts +164 -0
  237. package/dist/sheet/shortcuts.js +623 -0
  238. package/dist/sheet/structure.d.ts +87 -0
  239. package/dist/sheet/structure.js +166 -0
  240. package/dist/sheet/tables.d.ts +70 -0
  241. package/dist/sheet/tables.js +147 -0
  242. package/dist/sheet/tokenize.d.ts +54 -0
  243. package/dist/sheet/tokenize.js +304 -0
  244. package/dist/sheet/transforms.d.ts +76 -0
  245. package/dist/sheet/transforms.js +154 -0
  246. package/dist/sheet/validation.d.ts +92 -0
  247. package/dist/sheet/validation.js +241 -0
  248. package/dist/sheet/workbook.d.ts +72 -0
  249. package/dist/sheet/workbook.js +409 -0
  250. package/dist/sheet-enable.d.ts +6 -0
  251. package/dist/sheet-enable.js +46 -0
  252. package/dist/sources/aggregate.d.ts +1 -1
  253. package/dist/sources/auth-supabase.js +1 -1
  254. package/dist/sources/dashboard.d.ts +2 -2
  255. package/dist/sources/dashboard.js +1 -1
  256. package/dist/sources/index.d.ts +13 -13
  257. package/dist/sources/index.js +13 -13
  258. package/dist/sources/realtime-supabase.js +1 -1
  259. package/dist/sources/relation-lookup.d.ts +1 -1
  260. package/dist/sources/relation-lookup.js +1 -1
  261. package/dist/sources/rest-adapters.d.ts +1 -1
  262. package/dist/sources/rest-adapters.js +1 -1
  263. package/dist/sources/rest.d.ts +2 -2
  264. package/dist/sources/rest.js +3 -3
  265. package/dist/sources/supabase.d.ts +2 -2
  266. package/dist/sources/supabase.js +3 -3
  267. package/dist/sources/with-entity-rules.d.ts +1 -1
  268. package/dist/sources/with-entity-rules.js +1 -1
  269. package/dist/sources/with-relation-labels.d.ts +1 -1
  270. package/dist/studio/emit-project.js +2161 -2127
  271. package/dist/studio/emit-schema.js +369 -369
  272. package/dist/studio/index.d.ts +1 -1
  273. package/dist/studio/index.js +1 -1
  274. package/dist/studio/introspect-db.js +45 -45
  275. package/dist/studio/project.d.ts +10 -0
  276. package/dist/studio/samples/crm.js +6 -6
  277. package/dist/studio/samples/fleet.js +7 -7
  278. package/dist/studio/samples/insurance.js +9 -9
  279. package/dist/studio/samples/inventory.js +12 -12
  280. package/dist/studio/samples/projects.js +5 -5
  281. package/dist/studio/samples/support.js +8 -8
  282. package/dist/studio/scaffold-app.js +104 -104
  283. package/dist/studio/scaffold.js +151 -151
  284. package/dist/studio/ui-components.d.ts +7 -0
  285. package/dist/studio/ui-components.generated.js +63 -1
  286. package/dist/studio/ui-components.js +35 -0
  287. package/dist/sveltekit/in-memory.d.ts +3 -3
  288. package/dist/sveltekit/in-memory.js +4 -4
  289. package/dist/sveltekit/index.d.ts +6 -6
  290. package/dist/sveltekit/index.js +5 -5
  291. package/dist/sveltekit/query-plan.d.ts +1 -1
  292. package/dist/sveltekit/sql-source.d.ts +4 -4
  293. package/dist/sveltekit/sql-source.js +4 -4
  294. package/dist/sveltekit/sql.d.ts +1 -1
  295. package/dist/sveltekit/transport.d.ts +2 -2
  296. package/dist/sveltekit/transport.js +1 -1
  297. package/dist/upgrade-prompt.js +25 -25
  298. package/dist/version.d.ts +1 -1
  299. package/dist/version.js +1 -1
  300. package/package.json +12 -4
  301. package/dist/designer/assets/GridMenus-Cgilexpk.js +0 -8
  302. package/dist/designer/assets/SvDateRangeInput-BV5OXYQ2.css +0 -1
  303. package/dist/designer/assets/SvDateRangeInput-CVn-yqrQ.js +0 -1
  304. package/dist/designer/assets/SvDateTimePicker-BdioTrJQ.js +0 -1
  305. package/dist/designer/assets/SvDateTimePicker-CY8TK4BT.css +0 -1
  306. package/dist/designer/assets/SvField-BF-9TJSd.css +0 -1
  307. package/dist/designer/assets/SvField-BsqiA5me.js +0 -1
  308. package/dist/designer/assets/SvGridCellEditor-dLY7_kk9.js +0 -2
  309. package/dist/designer/assets/SvGridChart-BEDNTdc5.js +0 -2
  310. package/dist/designer/assets/SvGridChart-Vu4Nvjiv.css +0 -1
  311. package/dist/designer/assets/SvGridChartPanel-x3lzSxuf.js +0 -10
  312. package/dist/designer/assets/SvGridChartView-CAKhPELi.js +0 -1
  313. package/dist/designer/assets/SvGridChartView-DX9HfkBR.css +0 -1
  314. package/dist/designer/assets/SvGridDropdown-CAYG7Y-O.js +0 -1
  315. package/dist/designer/assets/SvGridDropdown-Crwb2P3Q.css +0 -1
  316. package/dist/designer/assets/SvListBox-CVYQcLX9.js +0 -1
  317. package/dist/designer/assets/SvListBox-DgN8kvjt.css +0 -1
  318. package/dist/designer/assets/chart-DHEgt4lN.js +0 -1
  319. package/dist/designer/assets/column-resize-C_inr5zT.js +0 -1
  320. package/dist/designer/assets/date-format-4DJvNtG2.js +0 -1
  321. package/dist/designer/assets/date-format-Dzy4mTGh.css +0 -1
  322. package/dist/designer/assets/easing-zaypKrr0.js +0 -3
  323. package/dist/designer/assets/export-format-DwjuTfrQ.js +0 -6
  324. package/dist/designer/assets/index-Cp7fDJ3b.css +0 -1
  325. package/dist/designer/assets/js-scroller.svelte-Bhxqb3-c.js +0 -110
  326. package/dist/designer/assets/row-resize-B0FWHcNr.js +0 -1
  327. package/dist/designer/assets/src-B7DNcoQK.css +0 -1
  328. package/dist/designer/assets/src-BoYyigAC.js +0 -2896
  329. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/_svelte_metadata.json +0 -1
  330. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/_metadata.json +0 -178
  331. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/attachments-BOv1rBKp.js +0 -3875
  332. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/attachments-BOv1rBKp.js.map +0 -1
  333. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/constants-B9vgIdCd.js +0 -21
  334. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/constants-B9vgIdCd.js.map +0 -1
  335. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/dev-T1qbW_qD.js +0 -1938
  336. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/dev-T1qbW_qD.js.map +0 -1
  337. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/events-Bo11SfVK.js +0 -205
  338. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/events-Bo11SfVK.js.map +0 -1
  339. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/flags-X7D4vfrZ.js +0 -18
  340. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/flags-X7D4vfrZ.js.map +0 -1
  341. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/hydration-oyUje5i1.js +0 -264
  342. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/hydration-oyUje5i1.js.map +0 -1
  343. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/legacy-client-DeSQgSFm.js +0 -697
  344. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/legacy-client-DeSQgSFm.js.map +0 -1
  345. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/package.json +0 -3
  346. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte.js +0 -134
  347. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte.js.map +0 -1
  348. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_animate.js +0 -55
  349. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_animate.js.map +0 -1
  350. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_attachments.js +0 -2
  351. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_compiler.js +0 -46843
  352. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_compiler.js.map +0 -1
  353. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_easing.js +0 -237
  354. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_easing.js.map +0 -1
  355. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_events.js +0 -2
  356. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal.js +0 -4
  357. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal.js.map +0 -1
  358. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_client.js +0 -7
  359. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_disclose-version.js +0 -4
  360. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_disclose-version.js.map +0 -1
  361. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_async.js +0 -5
  362. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_async.js.map +0 -1
  363. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_legacy.js +0 -5
  364. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_legacy.js.map +0 -1
  365. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_tracing.js +0 -5
  366. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_tracing.js.map +0 -1
  367. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_server.js +0 -6
  368. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_legacy.js +0 -83
  369. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_legacy.js.map +0 -1
  370. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_motion.js +0 -559
  371. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_motion.js.map +0 -1
  372. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_reactivity.js +0 -24
  373. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_reactivity.js.map +0 -1
  374. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_reactivity_window.js +0 -122
  375. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_reactivity_window.js.map +0 -1
  376. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_server.js +0 -2
  377. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_store.js +0 -89
  378. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_store.js.map +0 -1
  379. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_transition.js +0 -241
  380. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_transition.js.map +0 -1
  381. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/utils-BbWyXNk1.js +0 -4938
  382. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/utils-BbWyXNk1.js.map +0 -1
  383. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/utils-DI_fC7vt.js +0 -495
  384. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/utils-DI_fC7vt.js.map +0 -1
  385. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/validate-Dyr3lQv9.js +0 -190
  386. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/validate-Dyr3lQv9.js.map +0 -1
  387. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/version-_9FHH-LF.js +0 -8
  388. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/version-_9FHH-LF.js.map +0 -1
  389. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/warnings-CUbSPnyP.js +0 -138
  390. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/warnings-CUbSPnyP.js.map +0 -1
@@ -0,0 +1,199 @@
1
+ /**
2
+ * Dependency graph, so a recalc costs what the edit actually affects.
3
+ *
4
+ * The demo engines call `computeSheet`, which resolves every cell on every
5
+ * keystroke. On a small budget sheet nobody notices; on demo 211's 360-row
6
+ * amortisation schedule, typing one digit in an input cell walks every cell in
7
+ * the sheet and re-parses every formula among them.
8
+ *
9
+ * This tracks which cells each formula reads, inverts that into "who reads
10
+ * me", and walks forward from an edit in topological order.
11
+ *
12
+ * Cycles are reported rather than thrown. A cycle is a normal thing to type on
13
+ * the way to something correct, and every cell in one shows #CYCLE! while the
14
+ * rest of the sheet keeps working.
15
+ */
16
+ import { visit } from './ast.js';
17
+ /**
18
+ * Cells are keyed "row col sheet", in that order deliberately.
19
+ *
20
+ * Row and column are numbers and contain no separator, so the first two fields
21
+ * are unambiguous and EVERYTHING after the second space is the sheet name.
22
+ * Putting the sheet first would let a name like `Price list` collide with a
23
+ * different cell, and a ':' or '!' separator has the same problem the moment
24
+ * someone names a sheet after a range.
25
+ */
26
+ export function cellKey(sheet, row, col) {
27
+ return `${row} ${col} ${sheet ?? ''}`;
28
+ }
29
+ export function parseCellKey(key) {
30
+ const firstGap = key.indexOf(' ');
31
+ const secondGap = key.indexOf(' ', firstGap + 1);
32
+ const sheet = key.slice(secondGap + 1);
33
+ return {
34
+ sheet: sheet === '' ? null : sheet,
35
+ row: Number(key.slice(0, firstGap)),
36
+ col: Number(key.slice(firstGap + 1, secondGap)),
37
+ };
38
+ }
39
+ /**
40
+ * Every cell a formula reads. A range contributes each cell inside it, which
41
+ * is why `lastRow` is needed: a whole-column reference has no upper bound of
42
+ * its own.
43
+ */
44
+ export function precedentsOf(ast, self, lastRow,
45
+ /**
46
+ * The reference behind a defined name. Without it a formula that reads
47
+ * `=Subtotal*Tax` records no precedents at all, so editing the cell behind
48
+ * `Tax` leaves the formula showing its old value until something else
49
+ * forces a recalculation.
50
+ */
51
+ resolveName, depth = 0) {
52
+ const out = [];
53
+ visit(ast, (n) => {
54
+ if (n.k === 'name') {
55
+ // A name defined as another name is followed; a circular chain is cut
56
+ // after a few hops rather than recursing forever.
57
+ const target = depth < 8 ? resolveName?.(n.name) : null;
58
+ if (target)
59
+ out.push(...precedentsOf(target, self, lastRow, resolveName, depth + 1));
60
+ return;
61
+ }
62
+ if (n.k === 'ref' && n.ref.row !== null) {
63
+ out.push(cellKey(n.ref.sheet ?? self.sheet, n.ref.row, n.ref.col));
64
+ return;
65
+ }
66
+ if (n.k === 'range') {
67
+ const sheet = n.from.sheet ?? n.to.sheet ?? self.sheet;
68
+ const r1 = Math.min(n.from.row ?? 0, n.to.row ?? n.from.row ?? 0);
69
+ const r2 = n.to.row === null || n.from.row === null
70
+ ? lastRow(sheet)
71
+ : Math.max(n.from.row, n.to.row);
72
+ const c1 = Math.min(n.from.col, n.to.col);
73
+ const c2 = Math.max(n.from.col, n.to.col);
74
+ for (let r = r1; r <= r2; r += 1) {
75
+ for (let c = c1; c <= c2; c += 1)
76
+ out.push(cellKey(sheet, r, c));
77
+ }
78
+ }
79
+ });
80
+ return out;
81
+ }
82
+ export function createDependencyGraph() {
83
+ /** cell -> what it reads. */
84
+ const precedents = new Map();
85
+ /** cell -> who reads it. The index that makes dirtyFrom cheap. */
86
+ const dependents = new Map();
87
+ function unlink(cell) {
88
+ const old = precedents.get(cell);
89
+ if (!old)
90
+ return;
91
+ for (const p of old) {
92
+ const set = dependents.get(p);
93
+ if (!set)
94
+ continue;
95
+ set.delete(cell);
96
+ if (set.size === 0)
97
+ dependents.delete(p);
98
+ }
99
+ precedents.delete(cell);
100
+ }
101
+ return {
102
+ setPrecedents(cell, next) {
103
+ unlink(cell);
104
+ if (!next || next.length === 0)
105
+ return;
106
+ // A self-reference is a cycle of one; it is kept so `cycles()` sees it.
107
+ const set = new Set(next);
108
+ precedents.set(cell, set);
109
+ for (const p of set) {
110
+ let back = dependents.get(p);
111
+ if (!back) {
112
+ back = new Set();
113
+ dependents.set(p, back);
114
+ }
115
+ back.add(cell);
116
+ }
117
+ },
118
+ dirtyFrom(changed) {
119
+ // Collect everything reachable downstream, then order it so a cell only
120
+ // recomputes once its own inputs have. Kahn's algorithm over that
121
+ // subgraph, not over the whole sheet.
122
+ const affected = new Set();
123
+ const stack = [...changed];
124
+ while (stack.length) {
125
+ const cur = stack.pop();
126
+ for (const d of dependents.get(cur) ?? []) {
127
+ if (affected.has(d))
128
+ continue;
129
+ affected.add(d);
130
+ stack.push(d);
131
+ }
132
+ }
133
+ if (affected.size === 0)
134
+ return [];
135
+ const indegree = new Map();
136
+ for (const cell of affected) {
137
+ let n = 0;
138
+ for (const p of precedents.get(cell) ?? [])
139
+ if (affected.has(p))
140
+ n += 1;
141
+ indegree.set(cell, n);
142
+ }
143
+ const ready = [...affected].filter((c) => (indegree.get(c) ?? 0) === 0);
144
+ const order = [];
145
+ const placed = new Set();
146
+ while (ready.length) {
147
+ const cur = ready.shift();
148
+ order.push(cur);
149
+ placed.add(cur);
150
+ for (const d of dependents.get(cur) ?? []) {
151
+ if (!affected.has(d))
152
+ continue;
153
+ const n = (indegree.get(d) ?? 0) - 1;
154
+ indegree.set(d, n);
155
+ if (n === 0)
156
+ ready.push(d);
157
+ }
158
+ }
159
+ // Anything left never reached indegree zero, so it sits in a cycle.
160
+ // Append it rather than dropping it: those cells still need evaluating
161
+ // so they can report #CYCLE! instead of keeping a stale value.
162
+ for (const cell of affected)
163
+ if (!placed.has(cell))
164
+ order.push(cell);
165
+ return order;
166
+ },
167
+ cycles() {
168
+ // A cell is in a cycle when it can reach itself through its precedents.
169
+ const out = [];
170
+ for (const start of precedents.keys()) {
171
+ const seen = new Set();
172
+ const stack = [...(precedents.get(start) ?? [])];
173
+ let found = false;
174
+ while (stack.length) {
175
+ const cur = stack.pop();
176
+ if (cur === start) {
177
+ found = true;
178
+ break;
179
+ }
180
+ if (seen.has(cur))
181
+ continue;
182
+ seen.add(cur);
183
+ for (const p of precedents.get(cur) ?? [])
184
+ stack.push(p);
185
+ }
186
+ if (found)
187
+ out.push(start);
188
+ }
189
+ return out;
190
+ },
191
+ dependentsOf(cell) {
192
+ return [...(dependents.get(cell) ?? [])];
193
+ },
194
+ clear() {
195
+ precedents.clear();
196
+ dependents.clear();
197
+ },
198
+ };
199
+ }
@@ -0,0 +1,150 @@
1
+ /**
2
+ * The sheet document: the workbook plus everything a sheet keeps beside its
3
+ * cells, per sheet, in one model.
4
+ *
5
+ * The shell used to keep five Maps (format stores, column widths, row
6
+ * heights, hidden lines, frozen panes), each keyed by sheet name, each
7
+ * swapped on a sheet switch and each moved by hand on an insert or delete.
8
+ * Comments, validation rules, conditional formats, protection and merges
9
+ * would have made it ten. The document holds all of it, moves all of it in
10
+ * one `shift()` when rows or columns are inserted or deleted, saves and
11
+ * restores all of it through one `getState()` / `setState()` pair, and tells
12
+ * a listener once per tick what changed. `SvSheet` is a view over it: it
13
+ * puts the active sheet's sizes and hidden lines on the grid and writes
14
+ * them back here whenever they change, so the document is always the
15
+ * truth and the grid a rendering of it.
16
+ *
17
+ * Nothing in here touches the DOM, so a document can be built, edited,
18
+ * saved and restored in Node, in a test, or on a server.
19
+ */
20
+ import { type Workbook, type SheetData } from './workbook.js';
21
+ import { type SheetFormatStore, type CellFormatEntry } from './format-store.js';
22
+ import type { FreezeState } from './freeze.js';
23
+ import type { StructuralEdit } from './refs.js';
24
+ import { type NotesMap, type Rect } from './rects.js';
25
+ import { type ValidationRule } from './validation.js';
26
+ import { type CfRule } from './conditional-formats.js';
27
+ import { type AutoFilterState } from './auto-filter.js';
28
+ /** Why the document changed. A listener gets every reason since its last call. */
29
+ export type SheetChangeReason = {
30
+ kind: 'cells';
31
+ } | {
32
+ kind: 'formats';
33
+ } | {
34
+ kind: 'sizes';
35
+ } | {
36
+ kind: 'hidden';
37
+ } | {
38
+ kind: 'freeze';
39
+ } | {
40
+ kind: 'sheets';
41
+ } | {
42
+ kind: 'comments';
43
+ } | {
44
+ kind: 'validation';
45
+ } | {
46
+ kind: 'conditional-formats';
47
+ } | {
48
+ kind: 'protection';
49
+ } | {
50
+ kind: 'merges';
51
+ } | {
52
+ kind: 'filter';
53
+ } | {
54
+ kind: 'structure';
55
+ sheet: string;
56
+ edit: StructuralEdit;
57
+ } | {
58
+ kind: 'restore';
59
+ };
60
+ /** What one sheet keeps beside its cells. Live objects, not a snapshot. */
61
+ export type PerSheetState = {
62
+ formats: SheetFormatStore;
63
+ /** Column widths in px by letter; a letter absent here reads the default. */
64
+ widths: Record<string, number>;
65
+ /** Row heights in px by row index; a row absent here reads the default. */
66
+ heights: Map<number, number>;
67
+ hidden: {
68
+ rows: Set<number>;
69
+ cols: Set<number>;
70
+ };
71
+ freeze: FreezeState;
72
+ /** Cell comments in the grid's `notes` shape: `r4` -> `B` -> text. */
73
+ notes: NotesMap;
74
+ protected: boolean;
75
+ merges: Rect[];
76
+ /** Data validation rules, in order; the last one covering a cell applies. */
77
+ validation: ValidationRule[];
78
+ /** Conditional formatting rules, in priority order: the first one decides. */
79
+ conditionalFormats: CfRule[];
80
+ /** Excel's AutoFilter over a region, or null when the arrows are off. */
81
+ autoFilter: AutoFilterState | null;
82
+ /** The rows the AutoFilter hides right now; worked out, never saved. */
83
+ filterHidden: Set<number>;
84
+ };
85
+ /** One sheet's part of a saved document. JSON-safe. */
86
+ export type SheetStateEntry = {
87
+ formats: Record<string, CellFormatEntry>;
88
+ columnWidths: Record<string, number>;
89
+ rowHeights: Array<[row: number, px: number]>;
90
+ hidden: {
91
+ rows: number[];
92
+ cols: number[];
93
+ };
94
+ freeze: FreezeState;
95
+ comments: NotesMap;
96
+ protected: boolean;
97
+ merges: Array<[number, number, number, number]>;
98
+ validation: ValidationRule[];
99
+ conditionalFormats: CfRule[];
100
+ autoFilter: AutoFilterState | null;
101
+ };
102
+ /**
103
+ * A saved document. `workbook` is the raw text of every cell (formulas as
104
+ * typed), the sheet order, the active sheet and the defined names; `sheets`
105
+ * is keyed by the sheet's spelled name.
106
+ */
107
+ export type SheetState = {
108
+ version: 1;
109
+ workbook: ReturnType<Workbook['serialize']>;
110
+ sheets: Record<string, SheetStateEntry>;
111
+ };
112
+ export type SheetDocument = {
113
+ readonly workbook: Workbook;
114
+ /** The sheet's state, created on first use. Names compare case-insensitively. */
115
+ get(name: string): PerSheetState;
116
+ has(name: string): boolean;
117
+ rename(from: string, to: string): void;
118
+ remove(name: string): void;
119
+ /** The sheets that have state, in no particular order. */
120
+ names(): string[];
121
+ /**
122
+ * Move every position-keyed part of a sheet for an insert or delete:
123
+ * formats, heights, hidden lines, comments, merges. The workbook's own
124
+ * cells and formulas move through `workbook.applyStructuralEdit`; the
125
+ * shell calls both.
126
+ */
127
+ shift(name: string, edit: StructuralEdit): void;
128
+ getState(): SheetState;
129
+ /**
130
+ * Put a saved document back. The workbook is edited in place (sheets
131
+ * added, removed and reordered to match, cells written where they differ,
132
+ * names and the active sheet set), so the workbook a consumer holds stays
133
+ * the same object.
134
+ */
135
+ setState(state: SheetState): void;
136
+ /** Hear about changes, once per tick with every reason since the last call. */
137
+ subscribe(listener: (reasons: ReadonlyArray<SheetChangeReason>) => void): () => void;
138
+ /** Record a change. Coalesced per microtask; silent while muted. */
139
+ changed(reason: SheetChangeReason): void;
140
+ /** Run `fn` without reporting changes: restores and mount-time seeding. */
141
+ mute<T>(fn: () => T): T;
142
+ };
143
+ export type SheetDocumentInit = {
144
+ /** An existing workbook to wrap. Created from `sheets` or `state` when absent. */
145
+ workbook?: Workbook;
146
+ sheets?: ReadonlyArray<SheetData>;
147
+ /** A saved document to start from; wins over `sheets`. */
148
+ state?: SheetState;
149
+ };
150
+ export declare function createSheetDocument(init?: SheetDocumentInit): SheetDocument;
@@ -0,0 +1,264 @@
1
+ /**
2
+ * The sheet document: the workbook plus everything a sheet keeps beside its
3
+ * cells, per sheet, in one model.
4
+ *
5
+ * The shell used to keep five Maps (format stores, column widths, row
6
+ * heights, hidden lines, frozen panes), each keyed by sheet name, each
7
+ * swapped on a sheet switch and each moved by hand on an insert or delete.
8
+ * Comments, validation rules, conditional formats, protection and merges
9
+ * would have made it ten. The document holds all of it, moves all of it in
10
+ * one `shift()` when rows or columns are inserted or deleted, saves and
11
+ * restores all of it through one `getState()` / `setState()` pair, and tells
12
+ * a listener once per tick what changed. `SvSheet` is a view over it: it
13
+ * puts the active sheet's sizes and hidden lines on the grid and writes
14
+ * them back here whenever they change, so the document is always the
15
+ * truth and the grid a rendering of it.
16
+ *
17
+ * Nothing in here touches the DOM, so a document can be built, edited,
18
+ * saved and restored in Node, in a test, or on a server.
19
+ */
20
+ import { createWorkbook } from './workbook.js';
21
+ import { createFormatStore } from './format-store.js';
22
+ import { lineShift, remapNotes, shiftRect } from './rects.js';
23
+ import { colToLetters, lettersToCol } from './address.js';
24
+ import { shiftValidation } from './validation.js';
25
+ import { shiftCf } from './conditional-formats.js';
26
+ import { shiftAutoFilter } from './auto-filter.js';
27
+ function emptySheetState() {
28
+ return {
29
+ formats: createFormatStore(),
30
+ widths: {},
31
+ heights: new Map(),
32
+ hidden: { rows: new Set(), cols: new Set() },
33
+ freeze: { rows: 0, cols: 0 },
34
+ notes: {},
35
+ protected: false,
36
+ merges: [],
37
+ validation: [],
38
+ conditionalFormats: [],
39
+ autoFilter: null,
40
+ filterHidden: new Set(),
41
+ };
42
+ }
43
+ export function createSheetDocument(init = {}) {
44
+ const workbook = init.workbook ??
45
+ createWorkbook(init.state ? init.state.workbook.sheets.map((s) => ({ name: s.name, cells: s.cells })) : (init.sheets ? [...init.sheets] : [{ name: 'Sheet1', cells: [] }]));
46
+ const entries = new Map();
47
+ const listeners = new Set();
48
+ let pending = [];
49
+ let scheduled = false;
50
+ let muted = 0;
51
+ const key = (name) => name.toLowerCase();
52
+ function get(name) {
53
+ let found = entries.get(key(name));
54
+ if (!found) {
55
+ found = emptySheetState();
56
+ entries.set(key(name), found);
57
+ }
58
+ return found;
59
+ }
60
+ function flush() {
61
+ scheduled = false;
62
+ const batch = pending;
63
+ pending = [];
64
+ for (const listener of listeners)
65
+ listener(batch);
66
+ }
67
+ function changed(reason) {
68
+ if (muted > 0)
69
+ return;
70
+ // The same plain reason twice in a tick says nothing new; a structural
71
+ // edit is worth hearing about each time.
72
+ if (reason.kind !== 'structure' && pending.some((r) => r.kind === reason.kind))
73
+ return;
74
+ pending.push(reason);
75
+ if (scheduled)
76
+ return;
77
+ scheduled = true;
78
+ queueMicrotask(flush);
79
+ }
80
+ function serializeEntry(state) {
81
+ return {
82
+ formats: state.formats.serialize(),
83
+ columnWidths: { ...state.widths },
84
+ rowHeights: [...state.heights].map(([r, h]) => [r, h]),
85
+ hidden: { rows: [...state.hidden.rows], cols: [...state.hidden.cols] },
86
+ freeze: { ...state.freeze },
87
+ comments: Object.fromEntries(Object.entries(state.notes).map(([r, line]) => [r, { ...line }])),
88
+ protected: state.protected,
89
+ merges: state.merges.map(([r1, c1, r2, c2]) => [r1, c1, r2, c2]),
90
+ validation: state.validation.map((rule) => ({ ...rule, rects: rule.rects.map((r) => [...r]), alert: { ...rule.alert } })),
91
+ conditionalFormats: state.conditionalFormats.map((rule) => ({ ...rule, rects: rule.rects.map((r) => [...r]) })),
92
+ autoFilter: state.autoFilter ? { range: [...state.autoFilter.range], filters: { ...state.autoFilter.filters } } : null,
93
+ };
94
+ }
95
+ function hydrateEntry(state, entry) {
96
+ state.formats.hydrate(entry.formats ?? {});
97
+ state.widths = { ...(entry.columnWidths ?? {}) };
98
+ state.heights = new Map(entry.rowHeights ?? []);
99
+ state.hidden = { rows: new Set(entry.hidden?.rows ?? []), cols: new Set(entry.hidden?.cols ?? []) };
100
+ state.freeze = { rows: entry.freeze?.rows ?? 0, cols: entry.freeze?.cols ?? 0 };
101
+ state.notes = Object.fromEntries(Object.entries(entry.comments ?? {}).map(([r, line]) => [r, { ...line }]));
102
+ state.protected = entry.protected ?? false;
103
+ state.merges = (entry.merges ?? []).map(([r1, c1, r2, c2]) => [r1, c1, r2, c2]);
104
+ state.validation = (entry.validation ?? []).map((rule) => ({
105
+ ...rule,
106
+ rects: rule.rects.map(([r1, c1, r2, c2]) => [r1, c1, r2, c2]),
107
+ alert: { ...rule.alert },
108
+ }));
109
+ state.conditionalFormats = (entry.conditionalFormats ?? []).map((rule) => ({
110
+ ...rule,
111
+ rects: rule.rects.map(([r1, c1, r2, c2]) => [r1, c1, r2, c2]),
112
+ }));
113
+ const af = entry.autoFilter;
114
+ state.autoFilter = af ? { range: [af.range[0], af.range[1], af.range[2], af.range[3]], filters: { ...af.filters } } : null;
115
+ state.filterHidden = new Set();
116
+ }
117
+ const document = {
118
+ workbook,
119
+ get,
120
+ has: (name) => entries.has(key(name)),
121
+ rename(from, to) {
122
+ const moved = entries.get(key(from));
123
+ entries.delete(key(from));
124
+ if (moved)
125
+ entries.set(key(to), moved);
126
+ },
127
+ remove(name) {
128
+ entries.delete(key(name));
129
+ },
130
+ names: () => [...entries.keys()],
131
+ shift(name, edit) {
132
+ const state = get(name);
133
+ const shift = lineShift(edit);
134
+ const rows = edit.kind === 'insertRows' || edit.kind === 'deleteRows';
135
+ if (rows) {
136
+ state.formats.remapRows((id) => {
137
+ const i = Number(id.slice(1));
138
+ const next = Number.isInteger(i) ? shift(i) : i;
139
+ return next === null ? null : `r${next}`;
140
+ });
141
+ const heights = new Map();
142
+ for (const [r, h] of state.heights) {
143
+ const next = shift(r);
144
+ if (next !== null)
145
+ heights.set(next, h);
146
+ }
147
+ state.heights = heights;
148
+ const hiddenRows = new Set();
149
+ for (const r of state.hidden.rows) {
150
+ const next = shift(r);
151
+ if (next !== null)
152
+ hiddenRows.add(next);
153
+ }
154
+ state.hidden = { rows: hiddenRows, cols: state.hidden.cols };
155
+ state.notes = remapNotes(state.notes, 'rows', shift);
156
+ }
157
+ else {
158
+ state.formats.remapColumns((id) => {
159
+ const i = lettersToCol(id);
160
+ const next = i < 0 ? i : shift(i);
161
+ return next === null ? null : colToLetters(next);
162
+ });
163
+ const widths = {};
164
+ for (const [letter, w] of Object.entries(state.widths)) {
165
+ const i = lettersToCol(letter);
166
+ const next = i < 0 ? i : shift(i);
167
+ if (next !== null)
168
+ widths[i < 0 ? letter : colToLetters(next)] = w;
169
+ }
170
+ state.widths = widths;
171
+ const hiddenCols = new Set();
172
+ for (const c of state.hidden.cols) {
173
+ const next = shift(c);
174
+ if (next !== null)
175
+ hiddenCols.add(next);
176
+ }
177
+ state.hidden = { rows: state.hidden.rows, cols: hiddenCols };
178
+ state.notes = remapNotes(state.notes, 'cols', shift);
179
+ }
180
+ state.merges = state.merges.map((m) => shiftRect(m, edit)).filter((m) => m !== null);
181
+ state.validation = shiftValidation(state.validation, edit);
182
+ state.conditionalFormats = shiftCf(state.conditionalFormats, edit);
183
+ state.autoFilter = shiftAutoFilter(state.autoFilter, edit);
184
+ },
185
+ getState() {
186
+ const sheets = {};
187
+ for (const name of workbook.sheets)
188
+ sheets[name] = serializeEntry(get(name));
189
+ return { version: 1, workbook: workbook.serialize(), sheets };
190
+ },
191
+ setState(state) {
192
+ document.mute(() => {
193
+ const wanted = state.workbook.sheets.map((s) => s.name);
194
+ const wantedKeys = new Set(wanted.map(key));
195
+ // Sheets to add, then the ones to drop (never the last one standing),
196
+ // then the order, then the cells.
197
+ for (const name of wanted) {
198
+ if (!workbook.sheets.some((s) => key(s) === key(name)))
199
+ workbook.addSheet(name);
200
+ }
201
+ for (const name of [...workbook.sheets]) {
202
+ if (!wantedKeys.has(key(name)) && workbook.sheets.length > 1) {
203
+ workbook.removeSheet(name);
204
+ entries.delete(key(name));
205
+ }
206
+ }
207
+ wanted.forEach((name, index) => {
208
+ if (workbook.sheets[index]?.toLowerCase() !== key(name))
209
+ workbook.moveSheet(name, index);
210
+ });
211
+ for (const sheet of state.workbook.sheets) {
212
+ const rows = Math.max(workbook.rowCount(sheet.name), sheet.cells.length);
213
+ for (let r = 0; r < rows; r += 1) {
214
+ const cols = Math.max(workbook.colCount(sheet.name), sheet.cells[r]?.length ?? 0);
215
+ for (let c = 0; c < cols; c += 1) {
216
+ const text = sheet.cells[r]?.[c] ?? '';
217
+ if (workbook.getRaw(sheet.name, r, c) !== text)
218
+ workbook.setRaw(sheet.name, r, c, text);
219
+ }
220
+ }
221
+ }
222
+ workbook.names.hydrate(state.workbook.names ?? {});
223
+ if (workbook.sheets.some((s) => key(s) === key(state.workbook.active)))
224
+ workbook.setActive(state.workbook.active);
225
+ // Entries are hydrated in place, never replaced: a format store the
226
+ // shell has registered as its target must stay the store in use, or
227
+ // every format written after a restore would land in an orphan.
228
+ const kept = new Set(Object.keys(state.sheets ?? {}).map(key));
229
+ for (const name of [...entries.keys()])
230
+ if (!kept.has(name) && !wantedKeys.has(name))
231
+ entries.delete(name);
232
+ for (const name of workbook.sheets)
233
+ hydrateEntry(get(name), state.sheets?.[name] ?? {});
234
+ });
235
+ changed({ kind: 'restore' });
236
+ },
237
+ subscribe(listener) {
238
+ listeners.add(listener);
239
+ return () => {
240
+ listeners.delete(listener);
241
+ };
242
+ },
243
+ changed,
244
+ mute(fn) {
245
+ muted += 1;
246
+ try {
247
+ return fn();
248
+ }
249
+ finally {
250
+ muted -= 1;
251
+ }
252
+ },
253
+ };
254
+ if (init.state) {
255
+ document.mute(() => {
256
+ workbook.names.hydrate(init.state.workbook.names ?? {});
257
+ if (workbook.sheets.some((s) => key(s) === key(init.state.workbook.active)))
258
+ workbook.setActive(init.state.workbook.active);
259
+ for (const [name, entry] of Object.entries(init.state.sheets ?? {}))
260
+ hydrateEntry(get(name), entry);
261
+ });
262
+ }
263
+ return document;
264
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Keys that act on the text of a formula while it is being written.
3
+ *
4
+ * F4 in Excel cycles the reference at the caret through its four anchorings:
5
+ * `A1` -> `$A$1` -> `A$1` -> `$A1` -> `A1`, both ends of a range together.
6
+ * The caret counts as "at" a reference when it sits inside it or right after
7
+ * it, which is where it is after typing one. A sheet prefix (`Orders!A1`)
8
+ * is left as it is; only the cell part turns.
9
+ */
10
+ export type TextEdit = {
11
+ text: string;
12
+ caret: number;
13
+ };
14
+ export declare function cycleReference(text: string, caret: number): TextEdit | null;
@@ -0,0 +1,40 @@
1
+ const CELL = String.raw `\$?[A-Za-z]{1,3}\$?\d+`;
2
+ const REFERENCE = new RegExp(String.raw `(${CELL})(?::(${CELL}))?`, 'g');
3
+ /** The next anchoring in Excel's F4 order. */
4
+ function turn(cell) {
5
+ const m = /^(\$?)([A-Za-z]+)(\$?)(\d+)$/.exec(cell);
6
+ if (!m)
7
+ return cell;
8
+ const [, colAbs, col, rowAbs, row] = m;
9
+ const state = (colAbs ? 2 : 0) + (rowAbs ? 1 : 0);
10
+ // relative -> both -> row only -> column only -> relative
11
+ const next = { 0: 3, 3: 1, 1: 2, 2: 0 }[state];
12
+ return `${next & 2 ? '$' : ''}${col}${next & 1 ? '$' : ''}${row}`;
13
+ }
14
+ export function cycleReference(text, caret) {
15
+ if (!text.startsWith('='))
16
+ return null;
17
+ REFERENCE.lastIndex = 0;
18
+ let m;
19
+ while ((m = REFERENCE.exec(text)) !== null) {
20
+ const start = m.index;
21
+ const end = start + m[0].length;
22
+ if (caret < start || caret > end)
23
+ continue;
24
+ // A word character before the match means this is part of a name or a
25
+ // function (SUM1 is not a cell), not a reference.
26
+ const before = text[start - 1];
27
+ if (before && /[A-Za-z0-9_.]/.test(before))
28
+ continue;
29
+ // And a parenthesis after it makes it a function call: SUM1 is a cell in
30
+ // Excel's grid, SUM1( is not.
31
+ if (text[end] === '(')
32
+ continue;
33
+ const replaced = m[2] ? `${turn(m[1])}:${turn(m[2])}` : turn(m[1]);
34
+ return {
35
+ text: text.slice(0, start) + replaced + text.slice(end),
36
+ caret: start + replaced.length,
37
+ };
38
+ }
39
+ return null;
40
+ }