@cj-tech-master/excelts 9.2.1 → 9.3.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 (383) hide show
  1. package/README.md +25 -2
  2. package/README_zh.md +29 -6
  3. package/dist/browser/index.browser.d.ts +1 -1
  4. package/dist/browser/index.browser.js +4 -0
  5. package/dist/browser/index.d.ts +1 -1
  6. package/dist/browser/index.js +4 -0
  7. package/dist/browser/modules/excel/cell.d.ts +17 -3
  8. package/dist/browser/modules/excel/cell.js +170 -22
  9. package/dist/browser/modules/excel/defined-names.d.ts +96 -1
  10. package/dist/browser/modules/excel/defined-names.js +411 -21
  11. package/dist/browser/modules/excel/image.d.ts +11 -0
  12. package/dist/browser/modules/excel/image.js +24 -1
  13. package/dist/browser/modules/excel/stream/workbook-reader.browser.d.ts +9 -3
  14. package/dist/browser/modules/excel/stream/workbook-reader.browser.js +14 -0
  15. package/dist/browser/modules/excel/stream/workbook-reader.d.ts +2 -1
  16. package/dist/browser/modules/excel/stream/workbook-writer.browser.d.ts +39 -5
  17. package/dist/browser/modules/excel/stream/workbook-writer.browser.js +48 -1
  18. package/dist/browser/modules/excel/stream/workbook-writer.d.ts +3 -2
  19. package/dist/browser/modules/excel/stream/worksheet-reader.js +17 -1
  20. package/dist/browser/modules/excel/stream/worksheet-writer.d.ts +39 -6
  21. package/dist/browser/modules/excel/stream/worksheet-writer.js +45 -5
  22. package/dist/browser/modules/excel/table.js +15 -2
  23. package/dist/browser/modules/excel/types.d.ts +133 -2
  24. package/dist/browser/modules/excel/utils/col-cache.d.ts +1 -0
  25. package/dist/browser/modules/excel/utils/col-cache.js +15 -0
  26. package/dist/browser/modules/excel/utils/drawing-utils.d.ts +3 -3
  27. package/dist/browser/modules/excel/utils/drawing-utils.js +4 -0
  28. package/dist/browser/modules/excel/utils/external-link-formula.d.ts +76 -0
  29. package/dist/browser/modules/excel/utils/external-link-formula.js +208 -0
  30. package/dist/browser/modules/excel/utils/iterate-stream.d.ts +9 -3
  31. package/dist/browser/modules/excel/utils/iterate-stream.js +3 -1
  32. package/dist/browser/modules/excel/utils/ooxml-paths.d.ts +19 -0
  33. package/dist/browser/modules/excel/utils/ooxml-paths.js +37 -2
  34. package/dist/browser/modules/excel/utils/shared-strings.d.ts +8 -3
  35. package/dist/browser/modules/excel/utils/shared-strings.js +21 -2
  36. package/dist/browser/modules/excel/utils/workbook-protection.d.ts +30 -0
  37. package/dist/browser/modules/excel/utils/workbook-protection.js +30 -0
  38. package/dist/browser/modules/excel/workbook.browser.d.ts +257 -6
  39. package/dist/browser/modules/excel/workbook.browser.js +318 -34
  40. package/dist/browser/modules/excel/workbook.d.ts +1 -1
  41. package/dist/browser/modules/excel/worksheet.d.ts +3 -1
  42. package/dist/browser/modules/excel/worksheet.js +21 -2
  43. package/dist/browser/modules/excel/xlsx/rel-type.d.ts +15 -0
  44. package/dist/browser/modules/excel/xlsx/rel-type.js +16 -1
  45. package/dist/browser/modules/excel/xlsx/xform/book/defined-name-xform.d.ts +6 -5
  46. package/dist/browser/modules/excel/xlsx/xform/book/defined-name-xform.js +21 -86
  47. package/dist/browser/modules/excel/xlsx/xform/book/external-link-xform.d.ts +84 -0
  48. package/dist/browser/modules/excel/xlsx/xform/book/external-link-xform.js +330 -0
  49. package/dist/browser/modules/excel/xlsx/xform/book/external-reference-xform.d.ts +17 -0
  50. package/dist/browser/modules/excel/xlsx/xform/book/external-reference-xform.js +24 -0
  51. package/dist/browser/modules/excel/xlsx/xform/book/workbook-calc-properties-xform.d.ts +3 -0
  52. package/dist/browser/modules/excel/xlsx/xform/book/workbook-calc-properties-xform.js +11 -2
  53. package/dist/browser/modules/excel/xlsx/xform/book/workbook-protection-xform.d.ts +20 -0
  54. package/dist/browser/modules/excel/xlsx/xform/book/workbook-protection-xform.js +66 -0
  55. package/dist/browser/modules/excel/xlsx/xform/book/workbook-xform.js +38 -5
  56. package/dist/browser/modules/excel/xlsx/xform/core/content-types-xform.js +19 -1
  57. package/dist/browser/modules/excel/xlsx/xform/core/metadata-xform.d.ts +56 -0
  58. package/dist/browser/modules/excel/xlsx/xform/core/metadata-xform.js +158 -0
  59. package/dist/browser/modules/excel/xlsx/xform/drawing/absolute-anchor-xform.d.ts +26 -0
  60. package/dist/browser/modules/excel/xlsx/xform/drawing/absolute-anchor-xform.js +105 -0
  61. package/dist/browser/modules/excel/xlsx/xform/drawing/base-cell-anchor-xform.js +3 -0
  62. package/dist/browser/modules/excel/xlsx/xform/drawing/drawing-xform.js +10 -2
  63. package/dist/browser/modules/excel/xlsx/xform/sheet/cell-xform.d.ts +1 -1
  64. package/dist/browser/modules/excel/xlsx/xform/sheet/cell-xform.js +166 -8
  65. package/dist/browser/modules/excel/xlsx/xform/sheet/data-validations-xform.js +1 -1
  66. package/dist/browser/modules/excel/xlsx/xform/sheet/ignored-errors-xform.d.ts +21 -0
  67. package/dist/browser/modules/excel/xlsx/xform/sheet/ignored-errors-xform.js +80 -0
  68. package/dist/browser/modules/excel/xlsx/xform/sheet/worksheet-xform.js +9 -4
  69. package/dist/browser/modules/excel/xlsx/xform/style/border-xform.js +4 -1
  70. package/dist/browser/modules/excel/xlsx/xlsx.browser.d.ts +172 -13
  71. package/dist/browser/modules/excel/xlsx/xlsx.browser.js +410 -20
  72. package/dist/browser/modules/excel/xlsx/xlsx.d.ts +7 -4
  73. package/dist/browser/modules/excel/xlsx/xlsx.js +4 -5
  74. package/dist/browser/modules/formula/compile/address-utils.d.ts +62 -0
  75. package/dist/browser/modules/formula/compile/address-utils.js +83 -0
  76. package/dist/browser/modules/formula/compile/binder.d.ts +42 -0
  77. package/dist/browser/modules/formula/compile/binder.js +487 -0
  78. package/dist/browser/modules/formula/compile/bound-ast.d.ts +230 -0
  79. package/dist/browser/modules/formula/compile/bound-ast.js +80 -0
  80. package/dist/browser/modules/formula/compile/compiled-formula.d.ts +137 -0
  81. package/dist/browser/modules/formula/compile/compiled-formula.js +383 -0
  82. package/dist/browser/modules/formula/compile/dependency-analysis.d.ts +93 -0
  83. package/dist/browser/modules/formula/compile/dependency-analysis.js +432 -0
  84. package/dist/browser/modules/formula/compile/structured-ref-utils.d.ts +93 -0
  85. package/dist/browser/modules/formula/compile/structured-ref-utils.js +136 -0
  86. package/dist/browser/modules/formula/default-syntax-probe.d.ts +79 -0
  87. package/dist/browser/modules/formula/default-syntax-probe.js +83 -0
  88. package/dist/browser/modules/formula/functions/_date-context.d.ts +4 -0
  89. package/dist/browser/modules/formula/functions/_date-context.js +29 -0
  90. package/dist/browser/modules/formula/functions/_shared.d.ts +121 -0
  91. package/dist/browser/modules/formula/functions/_shared.js +381 -0
  92. package/dist/browser/modules/formula/functions/conditional.d.ts +27 -0
  93. package/dist/browser/modules/formula/functions/conditional.js +343 -0
  94. package/dist/browser/modules/formula/functions/database.d.ts +37 -0
  95. package/dist/browser/modules/formula/functions/database.js +274 -0
  96. package/dist/browser/modules/formula/functions/date.d.ts +61 -0
  97. package/dist/browser/modules/formula/functions/date.js +855 -0
  98. package/dist/browser/modules/formula/functions/dynamic-array.d.ts +23 -0
  99. package/dist/browser/modules/formula/functions/dynamic-array.js +860 -0
  100. package/dist/browser/modules/formula/functions/engineering.d.ts +57 -0
  101. package/dist/browser/modules/formula/functions/engineering.js +1128 -0
  102. package/dist/browser/modules/formula/functions/financial.d.ts +202 -0
  103. package/dist/browser/modules/formula/functions/financial.js +2296 -0
  104. package/dist/browser/modules/formula/functions/lookup.d.ts +18 -0
  105. package/dist/browser/modules/formula/functions/lookup.js +886 -0
  106. package/dist/browser/modules/formula/functions/math.d.ts +114 -0
  107. package/dist/browser/modules/formula/functions/math.js +1406 -0
  108. package/dist/browser/modules/formula/functions/statistical.d.ts +193 -0
  109. package/dist/browser/modules/formula/functions/statistical.js +3390 -0
  110. package/dist/browser/modules/formula/functions/text.d.ts +86 -0
  111. package/dist/browser/modules/formula/functions/text.js +1845 -0
  112. package/dist/browser/modules/formula/host-registry.d.ts +53 -0
  113. package/dist/browser/modules/formula/host-registry.js +69 -0
  114. package/dist/browser/modules/formula/index.d.ts +39 -0
  115. package/dist/browser/modules/formula/index.js +49 -0
  116. package/dist/browser/modules/formula/install.d.ts +62 -0
  117. package/dist/browser/modules/formula/install.js +88 -0
  118. package/dist/browser/modules/formula/integration/apply-writeback-plan.d.ts +26 -0
  119. package/dist/browser/modules/formula/integration/apply-writeback-plan.js +210 -0
  120. package/dist/browser/modules/formula/integration/calculate-formulas-impl.d.ts +30 -0
  121. package/dist/browser/modules/formula/integration/calculate-formulas-impl.js +616 -0
  122. package/dist/browser/modules/formula/integration/calculate-formulas.d.ts +67 -0
  123. package/dist/browser/modules/formula/integration/calculate-formulas.js +68 -0
  124. package/dist/browser/modules/formula/integration/formula-instance.d.ts +64 -0
  125. package/dist/browser/modules/formula/integration/formula-instance.js +79 -0
  126. package/dist/browser/modules/formula/integration/workbook-adapter.d.ts +26 -0
  127. package/dist/browser/modules/formula/integration/workbook-adapter.js +324 -0
  128. package/dist/browser/modules/formula/integration/workbook-snapshot.d.ts +267 -0
  129. package/dist/browser/modules/formula/integration/workbook-snapshot.js +77 -0
  130. package/dist/browser/modules/formula/materialize/build-writeback-plan.d.ts +34 -0
  131. package/dist/browser/modules/formula/materialize/build-writeback-plan.js +473 -0
  132. package/dist/browser/modules/formula/materialize/spill-engine.d.ts +9 -0
  133. package/dist/browser/modules/formula/materialize/spill-engine.js +38 -0
  134. package/dist/browser/modules/formula/materialize/types.d.ts +179 -0
  135. package/dist/browser/modules/formula/materialize/types.js +29 -0
  136. package/dist/browser/modules/formula/materialize/writeback-plan.d.ts +167 -0
  137. package/dist/browser/modules/formula/materialize/writeback-plan.js +27 -0
  138. package/dist/browser/modules/formula/runtime/evaluator.d.ts +151 -0
  139. package/dist/browser/modules/formula/runtime/evaluator.js +2291 -0
  140. package/dist/browser/modules/formula/runtime/function-registry.d.ts +47 -0
  141. package/dist/browser/modules/formula/runtime/function-registry.js +840 -0
  142. package/dist/browser/modules/formula/runtime/values.d.ts +211 -0
  143. package/dist/browser/modules/formula/runtime/values.js +385 -0
  144. package/dist/browser/modules/formula/syntax/ast.d.ts +129 -0
  145. package/dist/browser/modules/formula/syntax/ast.js +28 -0
  146. package/dist/browser/modules/formula/syntax/parser.d.ts +18 -0
  147. package/dist/browser/modules/formula/syntax/parser.js +439 -0
  148. package/dist/browser/modules/formula/syntax/token-types.d.ts +153 -0
  149. package/dist/browser/modules/formula/syntax/token-types.js +59 -0
  150. package/dist/browser/modules/formula/syntax/tokenizer.d.ts +10 -0
  151. package/dist/browser/modules/formula/syntax/tokenizer.js +1074 -0
  152. package/dist/browser/modules/pdf/excel-bridge.js +9 -0
  153. package/dist/cjs/index.js +4 -0
  154. package/dist/cjs/modules/excel/cell.js +170 -22
  155. package/dist/cjs/modules/excel/defined-names.js +411 -21
  156. package/dist/cjs/modules/excel/image.js +24 -1
  157. package/dist/cjs/modules/excel/stream/workbook-reader.browser.js +14 -0
  158. package/dist/cjs/modules/excel/stream/workbook-writer.browser.js +48 -1
  159. package/dist/cjs/modules/excel/stream/worksheet-reader.js +17 -1
  160. package/dist/cjs/modules/excel/stream/worksheet-writer.js +45 -5
  161. package/dist/cjs/modules/excel/table.js +15 -2
  162. package/dist/cjs/modules/excel/utils/col-cache.js +15 -0
  163. package/dist/cjs/modules/excel/utils/drawing-utils.js +4 -0
  164. package/dist/cjs/modules/excel/utils/external-link-formula.js +212 -0
  165. package/dist/cjs/modules/excel/utils/iterate-stream.js +3 -1
  166. package/dist/cjs/modules/excel/utils/ooxml-paths.js +42 -2
  167. package/dist/cjs/modules/excel/utils/shared-strings.js +21 -2
  168. package/dist/cjs/modules/excel/utils/workbook-protection.js +33 -0
  169. package/dist/cjs/modules/excel/workbook.browser.js +318 -34
  170. package/dist/cjs/modules/excel/worksheet.js +20 -1
  171. package/dist/cjs/modules/excel/xlsx/rel-type.js +16 -1
  172. package/dist/cjs/modules/excel/xlsx/xform/book/defined-name-xform.js +21 -86
  173. package/dist/cjs/modules/excel/xlsx/xform/book/external-link-xform.js +333 -0
  174. package/dist/cjs/modules/excel/xlsx/xform/book/external-reference-xform.js +27 -0
  175. package/dist/cjs/modules/excel/xlsx/xform/book/workbook-calc-properties-xform.js +11 -2
  176. package/dist/cjs/modules/excel/xlsx/xform/book/workbook-protection-xform.js +69 -0
  177. package/dist/cjs/modules/excel/xlsx/xform/book/workbook-xform.js +38 -5
  178. package/dist/cjs/modules/excel/xlsx/xform/core/content-types-xform.js +18 -0
  179. package/dist/cjs/modules/excel/xlsx/xform/core/metadata-xform.js +161 -0
  180. package/dist/cjs/modules/excel/xlsx/xform/drawing/absolute-anchor-xform.js +108 -0
  181. package/dist/cjs/modules/excel/xlsx/xform/drawing/base-cell-anchor-xform.js +3 -0
  182. package/dist/cjs/modules/excel/xlsx/xform/drawing/drawing-xform.js +10 -2
  183. package/dist/cjs/modules/excel/xlsx/xform/sheet/cell-xform.js +166 -8
  184. package/dist/cjs/modules/excel/xlsx/xform/sheet/data-validations-xform.js +1 -1
  185. package/dist/cjs/modules/excel/xlsx/xform/sheet/ignored-errors-xform.js +83 -0
  186. package/dist/cjs/modules/excel/xlsx/xform/sheet/worksheet-xform.js +9 -4
  187. package/dist/cjs/modules/excel/xlsx/xform/style/border-xform.js +4 -1
  188. package/dist/cjs/modules/excel/xlsx/xlsx.browser.js +408 -18
  189. package/dist/cjs/modules/excel/xlsx/xlsx.js +4 -5
  190. package/dist/cjs/modules/formula/compile/address-utils.js +89 -0
  191. package/dist/cjs/modules/formula/compile/binder.js +489 -0
  192. package/dist/cjs/modules/formula/compile/bound-ast.js +68 -0
  193. package/dist/cjs/modules/formula/compile/compiled-formula.js +387 -0
  194. package/dist/cjs/modules/formula/compile/dependency-analysis.js +437 -0
  195. package/dist/cjs/modules/formula/compile/structured-ref-utils.js +141 -0
  196. package/dist/cjs/modules/formula/default-syntax-probe.js +87 -0
  197. package/dist/cjs/modules/formula/functions/_date-context.js +33 -0
  198. package/dist/cjs/modules/formula/functions/_shared.js +396 -0
  199. package/dist/cjs/modules/formula/functions/conditional.js +354 -0
  200. package/dist/cjs/modules/formula/functions/database.js +288 -0
  201. package/dist/cjs/modules/formula/functions/date.js +883 -0
  202. package/dist/cjs/modules/formula/functions/dynamic-array.js +881 -0
  203. package/dist/cjs/modules/formula/functions/engineering.js +1183 -0
  204. package/dist/cjs/modules/formula/functions/financial.js +2348 -0
  205. package/dist/cjs/modules/formula/functions/lookup.js +902 -0
  206. package/dist/cjs/modules/formula/functions/math.js +1487 -0
  207. package/dist/cjs/modules/formula/functions/statistical.js +3488 -0
  208. package/dist/cjs/modules/formula/functions/text.js +1889 -0
  209. package/dist/cjs/modules/formula/host-registry.js +75 -0
  210. package/dist/cjs/modules/formula/index.js +58 -0
  211. package/dist/cjs/modules/formula/install.js +93 -0
  212. package/dist/cjs/modules/formula/integration/apply-writeback-plan.js +213 -0
  213. package/dist/cjs/modules/formula/integration/calculate-formulas-impl.js +619 -0
  214. package/dist/cjs/modules/formula/integration/calculate-formulas.js +71 -0
  215. package/dist/cjs/modules/formula/integration/formula-instance.js +82 -0
  216. package/dist/cjs/modules/formula/integration/workbook-adapter.js +327 -0
  217. package/dist/cjs/modules/formula/integration/workbook-snapshot.js +84 -0
  218. package/dist/cjs/modules/formula/materialize/build-writeback-plan.js +475 -0
  219. package/dist/cjs/modules/formula/materialize/spill-engine.js +42 -0
  220. package/dist/cjs/modules/formula/materialize/types.js +32 -0
  221. package/dist/cjs/modules/formula/materialize/writeback-plan.js +28 -0
  222. package/dist/cjs/modules/formula/runtime/evaluator.js +2298 -0
  223. package/dist/cjs/modules/formula/runtime/function-registry.js +846 -0
  224. package/dist/cjs/modules/formula/runtime/values.js +385 -0
  225. package/dist/cjs/modules/formula/syntax/ast.js +8 -0
  226. package/dist/cjs/modules/formula/syntax/parser.js +440 -0
  227. package/dist/cjs/modules/formula/syntax/token-types.js +32 -0
  228. package/dist/cjs/modules/formula/syntax/tokenizer.js +1076 -0
  229. package/dist/cjs/modules/pdf/excel-bridge.js +9 -0
  230. package/dist/esm/index.browser.js +4 -0
  231. package/dist/esm/index.js +4 -0
  232. package/dist/esm/modules/excel/cell.js +170 -22
  233. package/dist/esm/modules/excel/defined-names.js +411 -21
  234. package/dist/esm/modules/excel/image.js +24 -1
  235. package/dist/esm/modules/excel/stream/workbook-reader.browser.js +14 -0
  236. package/dist/esm/modules/excel/stream/workbook-writer.browser.js +48 -1
  237. package/dist/esm/modules/excel/stream/worksheet-reader.js +17 -1
  238. package/dist/esm/modules/excel/stream/worksheet-writer.js +45 -5
  239. package/dist/esm/modules/excel/table.js +15 -2
  240. package/dist/esm/modules/excel/utils/col-cache.js +15 -0
  241. package/dist/esm/modules/excel/utils/drawing-utils.js +4 -0
  242. package/dist/esm/modules/excel/utils/external-link-formula.js +208 -0
  243. package/dist/esm/modules/excel/utils/iterate-stream.js +3 -1
  244. package/dist/esm/modules/excel/utils/ooxml-paths.js +37 -2
  245. package/dist/esm/modules/excel/utils/shared-strings.js +21 -2
  246. package/dist/esm/modules/excel/utils/workbook-protection.js +30 -0
  247. package/dist/esm/modules/excel/workbook.browser.js +318 -34
  248. package/dist/esm/modules/excel/worksheet.js +21 -2
  249. package/dist/esm/modules/excel/xlsx/rel-type.js +16 -1
  250. package/dist/esm/modules/excel/xlsx/xform/book/defined-name-xform.js +21 -86
  251. package/dist/esm/modules/excel/xlsx/xform/book/external-link-xform.js +330 -0
  252. package/dist/esm/modules/excel/xlsx/xform/book/external-reference-xform.js +24 -0
  253. package/dist/esm/modules/excel/xlsx/xform/book/workbook-calc-properties-xform.js +11 -2
  254. package/dist/esm/modules/excel/xlsx/xform/book/workbook-protection-xform.js +66 -0
  255. package/dist/esm/modules/excel/xlsx/xform/book/workbook-xform.js +38 -5
  256. package/dist/esm/modules/excel/xlsx/xform/core/content-types-xform.js +19 -1
  257. package/dist/esm/modules/excel/xlsx/xform/core/metadata-xform.js +158 -0
  258. package/dist/esm/modules/excel/xlsx/xform/drawing/absolute-anchor-xform.js +105 -0
  259. package/dist/esm/modules/excel/xlsx/xform/drawing/base-cell-anchor-xform.js +3 -0
  260. package/dist/esm/modules/excel/xlsx/xform/drawing/drawing-xform.js +10 -2
  261. package/dist/esm/modules/excel/xlsx/xform/sheet/cell-xform.js +166 -8
  262. package/dist/esm/modules/excel/xlsx/xform/sheet/data-validations-xform.js +1 -1
  263. package/dist/esm/modules/excel/xlsx/xform/sheet/ignored-errors-xform.js +80 -0
  264. package/dist/esm/modules/excel/xlsx/xform/sheet/worksheet-xform.js +9 -4
  265. package/dist/esm/modules/excel/xlsx/xform/style/border-xform.js +4 -1
  266. package/dist/esm/modules/excel/xlsx/xlsx.browser.js +410 -20
  267. package/dist/esm/modules/excel/xlsx/xlsx.js +4 -5
  268. package/dist/esm/modules/formula/compile/address-utils.js +83 -0
  269. package/dist/esm/modules/formula/compile/binder.js +487 -0
  270. package/dist/esm/modules/formula/compile/bound-ast.js +80 -0
  271. package/dist/esm/modules/formula/compile/compiled-formula.js +383 -0
  272. package/dist/esm/modules/formula/compile/dependency-analysis.js +432 -0
  273. package/dist/esm/modules/formula/compile/structured-ref-utils.js +136 -0
  274. package/dist/esm/modules/formula/default-syntax-probe.js +83 -0
  275. package/dist/esm/modules/formula/functions/_date-context.js +29 -0
  276. package/dist/esm/modules/formula/functions/_shared.js +381 -0
  277. package/dist/esm/modules/formula/functions/conditional.js +343 -0
  278. package/dist/esm/modules/formula/functions/database.js +274 -0
  279. package/dist/esm/modules/formula/functions/date.js +855 -0
  280. package/dist/esm/modules/formula/functions/dynamic-array.js +860 -0
  281. package/dist/esm/modules/formula/functions/engineering.js +1128 -0
  282. package/dist/esm/modules/formula/functions/financial.js +2296 -0
  283. package/dist/esm/modules/formula/functions/lookup.js +886 -0
  284. package/dist/esm/modules/formula/functions/math.js +1406 -0
  285. package/dist/esm/modules/formula/functions/statistical.js +3390 -0
  286. package/dist/esm/modules/formula/functions/text.js +1845 -0
  287. package/dist/esm/modules/formula/host-registry.js +69 -0
  288. package/dist/esm/modules/formula/index.js +49 -0
  289. package/dist/esm/modules/formula/install.js +88 -0
  290. package/dist/esm/modules/formula/integration/apply-writeback-plan.js +210 -0
  291. package/dist/esm/modules/formula/integration/calculate-formulas-impl.js +616 -0
  292. package/dist/esm/modules/formula/integration/calculate-formulas.js +68 -0
  293. package/dist/esm/modules/formula/integration/formula-instance.js +79 -0
  294. package/dist/esm/modules/formula/integration/workbook-adapter.js +324 -0
  295. package/dist/esm/modules/formula/integration/workbook-snapshot.js +77 -0
  296. package/dist/esm/modules/formula/materialize/build-writeback-plan.js +473 -0
  297. package/dist/esm/modules/formula/materialize/spill-engine.js +38 -0
  298. package/dist/esm/modules/formula/materialize/types.js +29 -0
  299. package/dist/esm/modules/formula/materialize/writeback-plan.js +27 -0
  300. package/dist/esm/modules/formula/runtime/evaluator.js +2291 -0
  301. package/dist/esm/modules/formula/runtime/function-registry.js +840 -0
  302. package/dist/esm/modules/formula/runtime/values.js +385 -0
  303. package/dist/esm/modules/formula/syntax/ast.js +28 -0
  304. package/dist/esm/modules/formula/syntax/parser.js +439 -0
  305. package/dist/esm/modules/formula/syntax/token-types.js +59 -0
  306. package/dist/esm/modules/formula/syntax/tokenizer.js +1074 -0
  307. package/dist/esm/modules/pdf/excel-bridge.js +9 -0
  308. package/dist/iife/excelts.iife.js +2302 -373
  309. package/dist/iife/excelts.iife.js.map +1 -1
  310. package/dist/iife/excelts.iife.min.js +34 -34
  311. package/dist/types/index.browser.d.ts +1 -1
  312. package/dist/types/index.d.ts +1 -1
  313. package/dist/types/modules/excel/cell.d.ts +17 -3
  314. package/dist/types/modules/excel/defined-names.d.ts +96 -1
  315. package/dist/types/modules/excel/image.d.ts +11 -0
  316. package/dist/types/modules/excel/stream/workbook-reader.browser.d.ts +9 -3
  317. package/dist/types/modules/excel/stream/workbook-reader.d.ts +2 -1
  318. package/dist/types/modules/excel/stream/workbook-writer.browser.d.ts +39 -5
  319. package/dist/types/modules/excel/stream/workbook-writer.d.ts +3 -2
  320. package/dist/types/modules/excel/stream/worksheet-writer.d.ts +39 -6
  321. package/dist/types/modules/excel/types.d.ts +133 -2
  322. package/dist/types/modules/excel/utils/col-cache.d.ts +1 -0
  323. package/dist/types/modules/excel/utils/drawing-utils.d.ts +3 -3
  324. package/dist/types/modules/excel/utils/external-link-formula.d.ts +76 -0
  325. package/dist/types/modules/excel/utils/iterate-stream.d.ts +9 -3
  326. package/dist/types/modules/excel/utils/ooxml-paths.d.ts +19 -0
  327. package/dist/types/modules/excel/utils/shared-strings.d.ts +8 -3
  328. package/dist/types/modules/excel/utils/workbook-protection.d.ts +30 -0
  329. package/dist/types/modules/excel/workbook.browser.d.ts +257 -6
  330. package/dist/types/modules/excel/workbook.d.ts +1 -1
  331. package/dist/types/modules/excel/worksheet.d.ts +3 -1
  332. package/dist/types/modules/excel/xlsx/rel-type.d.ts +15 -0
  333. package/dist/types/modules/excel/xlsx/xform/book/defined-name-xform.d.ts +6 -5
  334. package/dist/types/modules/excel/xlsx/xform/book/external-link-xform.d.ts +84 -0
  335. package/dist/types/modules/excel/xlsx/xform/book/external-reference-xform.d.ts +17 -0
  336. package/dist/types/modules/excel/xlsx/xform/book/workbook-calc-properties-xform.d.ts +3 -0
  337. package/dist/types/modules/excel/xlsx/xform/book/workbook-protection-xform.d.ts +20 -0
  338. package/dist/types/modules/excel/xlsx/xform/core/metadata-xform.d.ts +56 -0
  339. package/dist/types/modules/excel/xlsx/xform/drawing/absolute-anchor-xform.d.ts +26 -0
  340. package/dist/types/modules/excel/xlsx/xform/sheet/cell-xform.d.ts +1 -1
  341. package/dist/types/modules/excel/xlsx/xform/sheet/ignored-errors-xform.d.ts +21 -0
  342. package/dist/types/modules/excel/xlsx/xlsx.browser.d.ts +172 -13
  343. package/dist/types/modules/excel/xlsx/xlsx.d.ts +7 -4
  344. package/dist/types/modules/formula/compile/address-utils.d.ts +62 -0
  345. package/dist/types/modules/formula/compile/binder.d.ts +42 -0
  346. package/dist/types/modules/formula/compile/bound-ast.d.ts +230 -0
  347. package/dist/types/modules/formula/compile/compiled-formula.d.ts +137 -0
  348. package/dist/types/modules/formula/compile/dependency-analysis.d.ts +93 -0
  349. package/dist/types/modules/formula/compile/structured-ref-utils.d.ts +93 -0
  350. package/dist/types/modules/formula/default-syntax-probe.d.ts +79 -0
  351. package/dist/types/modules/formula/functions/_date-context.d.ts +4 -0
  352. package/dist/types/modules/formula/functions/_shared.d.ts +121 -0
  353. package/dist/types/modules/formula/functions/conditional.d.ts +27 -0
  354. package/dist/types/modules/formula/functions/database.d.ts +37 -0
  355. package/dist/types/modules/formula/functions/date.d.ts +61 -0
  356. package/dist/types/modules/formula/functions/dynamic-array.d.ts +23 -0
  357. package/dist/types/modules/formula/functions/engineering.d.ts +57 -0
  358. package/dist/types/modules/formula/functions/financial.d.ts +202 -0
  359. package/dist/types/modules/formula/functions/lookup.d.ts +18 -0
  360. package/dist/types/modules/formula/functions/math.d.ts +114 -0
  361. package/dist/types/modules/formula/functions/statistical.d.ts +193 -0
  362. package/dist/types/modules/formula/functions/text.d.ts +86 -0
  363. package/dist/types/modules/formula/host-registry.d.ts +53 -0
  364. package/dist/types/modules/formula/index.d.ts +39 -0
  365. package/dist/types/modules/formula/install.d.ts +62 -0
  366. package/dist/types/modules/formula/integration/apply-writeback-plan.d.ts +26 -0
  367. package/dist/types/modules/formula/integration/calculate-formulas-impl.d.ts +30 -0
  368. package/dist/types/modules/formula/integration/calculate-formulas.d.ts +67 -0
  369. package/dist/types/modules/formula/integration/formula-instance.d.ts +64 -0
  370. package/dist/types/modules/formula/integration/workbook-adapter.d.ts +26 -0
  371. package/dist/types/modules/formula/integration/workbook-snapshot.d.ts +267 -0
  372. package/dist/types/modules/formula/materialize/build-writeback-plan.d.ts +34 -0
  373. package/dist/types/modules/formula/materialize/spill-engine.d.ts +9 -0
  374. package/dist/types/modules/formula/materialize/types.d.ts +179 -0
  375. package/dist/types/modules/formula/materialize/writeback-plan.d.ts +167 -0
  376. package/dist/types/modules/formula/runtime/evaluator.d.ts +151 -0
  377. package/dist/types/modules/formula/runtime/function-registry.d.ts +47 -0
  378. package/dist/types/modules/formula/runtime/values.d.ts +211 -0
  379. package/dist/types/modules/formula/syntax/ast.d.ts +129 -0
  380. package/dist/types/modules/formula/syntax/parser.d.ts +18 -0
  381. package/dist/types/modules/formula/syntax/token-types.d.ts +153 -0
  382. package/dist/types/modules/formula/syntax/tokenizer.d.ts +10 -0
  383. package/package.json +28 -28
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Formula Calculation Engine
3
+ *
4
+ * Provides `calculateFormulas()` as the primary function-style entry
5
+ * point. The same work runs when a host calls
6
+ * `Workbook.calculateFormulas()` — both paths dispatch through the
7
+ * engine registered via `installFormulaEngine()`.
8
+ *
9
+ * ## Architecture
10
+ *
11
+ * 1. **Snapshot** — immutable capture of all workbook state
12
+ * 2. **Normalize** — uniform FormulaInstance objects
13
+ * 3. **Parse** — tokenize → AST
14
+ * 4. **Compile** — bind AST → BoundExpr (resolve names, structured refs, sheets)
15
+ * 5. **Dependency Analysis** — topological sort
16
+ * 6. **Evaluate** — execute BoundExpr with RuntimeValue system
17
+ * 7. **Materialize** — build declarative WritebackPlan
18
+ * 8. **Apply** — write plan to live workbook
19
+ */
20
+ import { calculateFormulasImpl } from "./calculate-formulas-impl.js";
21
+ /**
22
+ * Recalculate all formula cells in a workbook.
23
+ *
24
+ * Evaluates every formula cell using the built-in calculation engine
25
+ * and updates each cell's `result` value. Formulas are evaluated lazily
26
+ * with recursive dependency resolution, memoization, and circular
27
+ * reference detection.
28
+ *
29
+ * All evaluation state is scoped to this invocation — concurrent calls
30
+ * for different workbooks are safe.
31
+ *
32
+ * **Supported formula features:**
33
+ * - Cell references: `A1`, `$B$2`, `Sheet1!A1`, `'Sheet Name'!A1:B10`
34
+ * - Operators: `+ - * / ^`, `& (concat)`, `= <> < > <= >=`, `%`
35
+ * - 433 built-in functions across math, text, logical, date, lookup,
36
+ * statistical, financial, dynamic-array, database and engineering
37
+ * categories.
38
+ * - Shared formulas, array constants, nested expressions
39
+ * - Dynamic array spill: FILTER, SORT, UNIQUE, SORTBY results are
40
+ * written to adjacent cells. #SPILL! error if target cells are occupied.
41
+ * - CSE array formulas: `{=formula}` with a ref range distribute results
42
+ * across the designated range.
43
+ * - Array arithmetic broadcasting: `{1,2,3} + {4;5;6}` produces a 3x3 matrix.
44
+ * - Implicit intersection: range references in scalar context pick the
45
+ * value from the formula cell's row or column.
46
+ *
47
+ * **Unsupported formula behavior:**
48
+ * - If a formula uses a function the engine does not implement, the engine
49
+ * returns `#NAME?`. However, if the cell already has a cached result
50
+ * (e.g., pre-computed by Excel when the XLSX was saved), that cached
51
+ * result is **preserved** — the engine will not overwrite usable data.
52
+ * - If no cached result exists, the cell's result becomes `#NAME?`.
53
+ *
54
+ * **Volatile functions:**
55
+ * - `RAND`, `RANDBETWEEN`, `NOW`, `TODAY` are re-evaluated on every call.
56
+ * This is intentional — these functions are expected to produce fresh values.
57
+ *
58
+ * **Side effects:**
59
+ * - This function **mutates** the workbook by updating formula cells' `result`
60
+ * property in-place. For dynamic array formulas, adjacent cells are also
61
+ * written with spill results. If you need the original cached results
62
+ * preserved, clone the workbook before calling this function.
63
+ *
64
+ * @param workbook - The workbook whose formulas should be recalculated
65
+ */
66
+ export function calculateFormulas(workbook) {
67
+ calculateFormulasImpl(workbook);
68
+ }
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Formula Instance — Unified model for all formula cell variants.
3
+ *
4
+ * The normalizer converts the heterogeneous formula representations found
5
+ * in the snapshot (normal, shared-master, shared-slave, CSE, dynamic-array)
6
+ * into a uniform `FormulaInstance` structure. After normalization, the
7
+ * compile and runtime layers do not need to know how a formula originated.
8
+ *
9
+ * ## Invariants
10
+ *
11
+ * - Every `FormulaInstance` has a non-empty `sourceText` (the formula to parse).
12
+ * - Shared-slave formulas have already been translated (offset applied) by
13
+ * the snapshot builder, so `sourceText` is the final formula text.
14
+ * - `kind` is preserved so the materialize layer can determine the correct
15
+ * writeback strategy (scalar vs. CSE vs. spill).
16
+ */
17
+ import type { FormulaCellKind, WorkbookSnapshot } from "./workbook-snapshot.js";
18
+ /**
19
+ * A normalized, engine-internal representation of a formula cell.
20
+ * This is the unit of work that enters the compile → evaluate pipeline.
21
+ */
22
+ export interface FormulaInstance {
23
+ /** The worksheet name this formula belongs to. */
24
+ readonly sheetName: string;
25
+ /** The worksheet id (stable across renames). */
26
+ readonly sheetId: number;
27
+ /** 1-based row number. */
28
+ readonly row: number;
29
+ /** 1-based column number. */
30
+ readonly col: number;
31
+ /** The final formula text to parse and evaluate. */
32
+ readonly sourceText: string;
33
+ /**
34
+ * The formula classification.
35
+ * - `"normal"` — standard scalar formula
36
+ * - `"shared-master"` — master of a shared formula group (treated as normal for eval)
37
+ * - `"shared-slave"` — slave with translated formula (treated as normal for eval)
38
+ * - `"cse"` — legacy CSE array formula; result distributed across `targetRef`
39
+ * - `"dynamic-array"` — dynamic array formula; result spills to adjacent cells
40
+ */
41
+ readonly kind: FormulaCellKind;
42
+ /**
43
+ * For CSE formulas: the target range in "A1:B2" format.
44
+ * For dynamic-array formulas: `undefined` (spill range is computed at runtime).
45
+ * For all other kinds: `undefined`.
46
+ */
47
+ readonly targetRef?: string;
48
+ /**
49
+ * Whether this formula was explicitly flagged as a dynamic array formula
50
+ * (from the XLSX `isDynamicArray` attribute).
51
+ */
52
+ readonly isDynamicArray: boolean;
53
+ }
54
+ /**
55
+ * Collect all formula instances from a workbook snapshot.
56
+ *
57
+ * Iterates every cell in every worksheet, selects cells with formulas,
58
+ * and normalizes them into `FormulaInstance` objects. The result is a
59
+ * flat list ordered by worksheet order then cell position.
60
+ *
61
+ * This replaces the old `collectFormulaCells()` function but operates
62
+ * entirely on snapshot data — no live workbook objects are touched.
63
+ */
64
+ export declare function collectFormulaInstances(snapshot: WorkbookSnapshot): FormulaInstance[];
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Formula Instance — Unified model for all formula cell variants.
3
+ *
4
+ * The normalizer converts the heterogeneous formula representations found
5
+ * in the snapshot (normal, shared-master, shared-slave, CSE, dynamic-array)
6
+ * into a uniform `FormulaInstance` structure. After normalization, the
7
+ * compile and runtime layers do not need to know how a formula originated.
8
+ *
9
+ * ## Invariants
10
+ *
11
+ * - Every `FormulaInstance` has a non-empty `sourceText` (the formula to parse).
12
+ * - Shared-slave formulas have already been translated (offset applied) by
13
+ * the snapshot builder, so `sourceText` is the final formula text.
14
+ * - `kind` is preserved so the materialize layer can determine the correct
15
+ * writeback strategy (scalar vs. CSE vs. spill).
16
+ */
17
+ // ============================================================================
18
+ // Normalizer
19
+ // ============================================================================
20
+ /**
21
+ * Collect all formula instances from a workbook snapshot.
22
+ *
23
+ * Iterates every cell in every worksheet, selects cells with formulas,
24
+ * and normalizes them into `FormulaInstance` objects. The result is a
25
+ * flat list ordered by worksheet order then cell position.
26
+ *
27
+ * This replaces the old `collectFormulaCells()` function but operates
28
+ * entirely on snapshot data — no live workbook objects are touched.
29
+ */
30
+ export function collectFormulaInstances(snapshot) {
31
+ const instances = [];
32
+ for (const ws of snapshot.worksheets) {
33
+ collectFromWorksheet(ws, instances);
34
+ }
35
+ return instances;
36
+ }
37
+ /**
38
+ * Collect formula instances from a single worksheet snapshot.
39
+ */
40
+ function collectFromWorksheet(ws, out) {
41
+ for (const cell of ws.cells.values()) {
42
+ if (cell.formulaKind === "none") {
43
+ continue;
44
+ }
45
+ if (!cell.formula) {
46
+ continue;
47
+ }
48
+ const instance = normalizeCell(ws, cell);
49
+ if (instance) {
50
+ out.push(instance);
51
+ }
52
+ }
53
+ }
54
+ /**
55
+ * Normalize a single cell snapshot into a FormulaInstance.
56
+ *
57
+ * This is where the different formula types are unified:
58
+ * - Normal formulas pass through directly.
59
+ * - Shared-master and shared-slave formulas are both treated as normal
60
+ * for evaluation purposes (the slave's formula text is already translated).
61
+ * - CSE formulas carry their target ref for the materialize layer.
62
+ * - Dynamic-array formulas are flagged for spill handling.
63
+ */
64
+ function normalizeCell(ws, cell) {
65
+ const formula = cell.formula;
66
+ if (!formula) {
67
+ return null;
68
+ }
69
+ return {
70
+ sheetName: ws.name,
71
+ sheetId: ws.id,
72
+ row: cell.row,
73
+ col: cell.col,
74
+ sourceText: formula,
75
+ kind: cell.formulaKind,
76
+ targetRef: cell.ref,
77
+ isDynamicArray: cell.isDynamicArray ?? false
78
+ };
79
+ }
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Workbook Adapter — Bridge between a host workbook (implementing the
3
+ * `WorkbookLike` / `WorksheetLike` / `CellLike` interfaces) and the
4
+ * engine's snapshot representation.
5
+ *
6
+ * This is the only file in the engine pipeline that walks a live host
7
+ * workbook; the rest of the pipeline consumes the immutable
8
+ * `WorkbookSnapshot` this file produces.
9
+ *
10
+ * ## Responsibilities
11
+ *
12
+ * 1. `buildWorkbookSnapshot()` — walk the host workbook and produce an
13
+ * immutable `WorkbookSnapshot`.
14
+ * 2. Cell value conversion — Date → serial number, rich text → string,
15
+ * shared formula translation, etc.
16
+ */
17
+ import type { WorkbookLike } from "../materialize/types.js";
18
+ import type { WorkbookSnapshot } from "./workbook-snapshot.js";
19
+ /**
20
+ * Build a complete `WorkbookSnapshot` from a live workbook.
21
+ *
22
+ * This traverses all worksheets and cells once, converting everything to
23
+ * engine-internal snapshot types. The result is a fully self-contained,
24
+ * read-only data structure.
25
+ */
26
+ export declare function buildWorkbookSnapshot(workbook: WorkbookLike): WorkbookSnapshot;
@@ -0,0 +1,324 @@
1
+ /**
2
+ * Workbook Adapter — Bridge between a host workbook (implementing the
3
+ * `WorkbookLike` / `WorksheetLike` / `CellLike` interfaces) and the
4
+ * engine's snapshot representation.
5
+ *
6
+ * This is the only file in the engine pipeline that walks a live host
7
+ * workbook; the rest of the pipeline consumes the immutable
8
+ * `WorkbookSnapshot` this file produces.
9
+ *
10
+ * ## Responsibilities
11
+ *
12
+ * 1. `buildWorkbookSnapshot()` — walk the host workbook and produce an
13
+ * immutable `WorkbookSnapshot`.
14
+ * 2. Cell value conversion — Date → serial number, rich text → string,
15
+ * shared formula translation, etc.
16
+ */
17
+ import { dateToExcel } from "../../../utils/utils.base.js";
18
+ import { CellValueTypeLike } from "../materialize/types.js";
19
+ import { snapshotCellKey, scopedNameKey } from "./workbook-snapshot.js";
20
+ // ============================================================================
21
+ // Build Workbook Snapshot
22
+ // ============================================================================
23
+ /**
24
+ * Build a complete `WorkbookSnapshot` from a live workbook.
25
+ *
26
+ * This traverses all worksheets and cells once, converting everything to
27
+ * engine-internal snapshot types. The result is a fully self-contained,
28
+ * read-only data structure.
29
+ */
30
+ export function buildWorkbookSnapshot(workbook) {
31
+ const worksheets = [];
32
+ const worksheetsByName = new Map();
33
+ const worksheetsById = new Map();
34
+ const date1904 = workbook.properties?.date1904 ?? false;
35
+ for (const ws of workbook.worksheets) {
36
+ const wsSnapshot = buildWorksheetSnapshot(ws, date1904);
37
+ worksheets.push(wsSnapshot);
38
+ worksheetsByName.set(ws.name.toLowerCase(), wsSnapshot);
39
+ worksheetsById.set(ws.id, wsSnapshot);
40
+ }
41
+ const definedNames = buildDefinedNames(workbook);
42
+ // Build table-by-name index for O(1) lookup
43
+ const tablesByName = new Map();
44
+ for (const wsSnapshot of worksheets) {
45
+ for (const table of wsSnapshot.tables) {
46
+ if (table.name) {
47
+ tablesByName.set(table.name.toLowerCase(), {
48
+ table,
49
+ sheetName: wsSnapshot.name
50
+ });
51
+ }
52
+ }
53
+ }
54
+ const calcProperties = {
55
+ fullCalcOnLoad: workbook.calcProperties?.fullCalcOnLoad,
56
+ iterate: workbook.calcProperties?.iterate,
57
+ iterateCount: workbook.calcProperties?.iterateCount,
58
+ iterateDelta: workbook.calcProperties?.iterateDelta
59
+ };
60
+ const properties = {
61
+ date1904
62
+ };
63
+ return {
64
+ worksheets,
65
+ worksheetsByName,
66
+ worksheetsById,
67
+ definedNames,
68
+ tablesByName,
69
+ calcProperties,
70
+ properties
71
+ };
72
+ }
73
+ // ============================================================================
74
+ // Build Worksheet Snapshot
75
+ // ============================================================================
76
+ function buildWorksheetSnapshot(ws, date1904) {
77
+ const cells = new Map();
78
+ const hiddenRows = new Set();
79
+ // Use includeEmpty so we observe the `hidden` flag on rows that have
80
+ // no populated cells — a user may hide an empty row (e.g. filter UI)
81
+ // and SUBTOTAL(1xx,…) still needs to treat that row as hidden.
82
+ ws.eachRow({ includeEmpty: true }, (row, rowNumber) => {
83
+ if (row.hidden) {
84
+ hiddenRows.add(rowNumber);
85
+ }
86
+ row.eachCell((cell, colNumber) => {
87
+ const cellSnapshot = buildCellSnapshot(cell, rowNumber, colNumber, date1904);
88
+ if (cellSnapshot) {
89
+ cells.set(snapshotCellKey(rowNumber, colNumber), cellSnapshot);
90
+ }
91
+ });
92
+ });
93
+ const dims = ws.dimensions;
94
+ const dimensions = dims
95
+ ? { top: dims.top, left: dims.left, bottom: dims.bottom, right: dims.right }
96
+ : null;
97
+ const tables = buildTables(ws);
98
+ return {
99
+ id: ws.id,
100
+ name: ws.name,
101
+ dimensions,
102
+ cells,
103
+ hiddenRows,
104
+ tables
105
+ };
106
+ }
107
+ // ============================================================================
108
+ // Build Cell Snapshot
109
+ // ============================================================================
110
+ function buildCellSnapshot(cell, row, col, date1904) {
111
+ const cellType = cell.type;
112
+ // Skip truly empty cells
113
+ if (cellType === CellValueTypeLike.Null) {
114
+ return null;
115
+ }
116
+ // ── Formula cells ──
117
+ if (cellType === CellValueTypeLike.Formula) {
118
+ return buildFormulaCellSnapshot(cell, row, col, date1904);
119
+ }
120
+ // ── Non-formula cells ──
121
+ const value = convertCellValue(cell.value, date1904);
122
+ return {
123
+ row,
124
+ col,
125
+ value,
126
+ formulaKind: "none"
127
+ };
128
+ }
129
+ function buildFormulaCellSnapshot(cell, row, col, date1904) {
130
+ const model = cell.model;
131
+ const formula = cell.formula; // triggers shared formula translation for slaves
132
+ if (formula == null) {
133
+ // Formula cell with no parseable formula — capture the cached result
134
+ const cachedResult = convertFormulaResult(cell.result, date1904);
135
+ return {
136
+ row,
137
+ col,
138
+ value: cachedResult,
139
+ formulaKind: "none",
140
+ cachedResult
141
+ };
142
+ }
143
+ // Determine formula kind
144
+ const kind = classifyFormulaKind(model);
145
+ // Capture the cached result from the XLSX
146
+ const cachedResult = convertFormulaResult(cell.result, date1904);
147
+ return {
148
+ row,
149
+ col,
150
+ value: cachedResult,
151
+ formulaKind: kind,
152
+ formula,
153
+ ref: model.ref,
154
+ isDynamicArray: model.isDynamicArray ?? undefined,
155
+ cachedResult
156
+ };
157
+ }
158
+ /**
159
+ * Classify a formula cell's kind based on its model properties.
160
+ */
161
+ function classifyFormulaKind(model) {
162
+ if (model.isDynamicArray) {
163
+ return "dynamic-array";
164
+ }
165
+ if (model.shareType === "array" && model.ref) {
166
+ return "cse";
167
+ }
168
+ if (model.shareType === "shared") {
169
+ // shared-master has formula + ref, shared-slave has sharedFormula
170
+ if (model.formula && model.ref) {
171
+ return "shared-master";
172
+ }
173
+ if (model.sharedFormula) {
174
+ return "shared-slave";
175
+ }
176
+ }
177
+ return "normal";
178
+ }
179
+ // ============================================================================
180
+ // Value Conversion
181
+ // ============================================================================
182
+ /**
183
+ * Convert a live cell value to a snapshot value.
184
+ * - Dates → Excel serial number
185
+ * - Rich text → plain string
186
+ * - Errors → SnapshotErrorValue
187
+ * - All other types pass through
188
+ */
189
+ function convertCellValue(value, date1904) {
190
+ if (value === null || value === undefined) {
191
+ return null;
192
+ }
193
+ if (typeof value === "number") {
194
+ return value;
195
+ }
196
+ if (typeof value === "string") {
197
+ return value;
198
+ }
199
+ if (typeof value === "boolean") {
200
+ return value;
201
+ }
202
+ if (value instanceof Date) {
203
+ return dateToExcel(value, date1904);
204
+ }
205
+ if (typeof value === "object" && "error" in value) {
206
+ // Gate the error code through the known set so user-supplied values
207
+ // like `{ error: "anything" }` can't pollute the snapshot. Unknown
208
+ // strings fall back to #VALUE! — matches Excel's default diagnostic
209
+ // when it reads an unrecognised error value from a persisted file.
210
+ const raw = value.error;
211
+ const KNOWN_ERRORS = new Set([
212
+ "#N/A",
213
+ "#NULL!",
214
+ "#DIV/0!",
215
+ "#VALUE!",
216
+ "#REF!",
217
+ "#NAME?",
218
+ "#NUM!",
219
+ "#GETTING_DATA",
220
+ "#CALC!",
221
+ "#SPILL!",
222
+ "#CONNECT!",
223
+ "#BLOCKED!",
224
+ "#UNKNOWN!",
225
+ "#FIELD!",
226
+ "#BUSY!"
227
+ ]);
228
+ const code = KNOWN_ERRORS.has(raw) ? raw : "#VALUE!";
229
+ return { error: code };
230
+ }
231
+ // Rich text → plain string
232
+ if (typeof value === "object" && "richText" in value) {
233
+ return (value.richText || []).map(r => r.text).join("");
234
+ }
235
+ // Hyperlink / other objects with text
236
+ if (typeof value === "object" && "text" in value) {
237
+ return value.text;
238
+ }
239
+ return null;
240
+ }
241
+ /**
242
+ * Convert a formula result to a snapshot value.
243
+ */
244
+ function convertFormulaResult(result, date1904) {
245
+ if (result === undefined || result === null) {
246
+ return null;
247
+ }
248
+ return convertCellValue(result, date1904);
249
+ }
250
+ // ============================================================================
251
+ // Build Tables
252
+ // ============================================================================
253
+ function buildTables(ws) {
254
+ if (!ws.getTables) {
255
+ return [];
256
+ }
257
+ const tables = [];
258
+ for (const t of ws.getTables()) {
259
+ const model = t.table;
260
+ if (!model || !model.tl) {
261
+ continue;
262
+ }
263
+ const columns = (model.columns || []).map(c => ({
264
+ name: c.name
265
+ }));
266
+ tables.push({
267
+ name: model.name || model.displayName || "",
268
+ columns,
269
+ topLeft: { row: model.tl.row, col: model.tl.col },
270
+ dataRowCount: (model.rows || []).length,
271
+ hasHeaderRow: model.headerRow !== false,
272
+ hasTotalsRow: model.totalsRow === true
273
+ });
274
+ }
275
+ return tables;
276
+ }
277
+ // ============================================================================
278
+ // Build Defined Names
279
+ // ============================================================================
280
+ function buildDefinedNames(workbook) {
281
+ const map = new Map();
282
+ if (!workbook.definedNames) {
283
+ return map;
284
+ }
285
+ // Build a sheet-id-to-name lookup for resolving localSheetId → sheet name.
286
+ //
287
+ // `localSheetId` stores the 0-based position in the XLSX-model sheet list,
288
+ // which in this library corresponds to the index in `workbook.worksheets`
289
+ // (the filtered+ordered view, see `workbook.xlsx/xform/book/workbook-xform.ts`
290
+ // line 50-94 where `index` is incremented per rendered sheet).
291
+ //
292
+ // Iterate the array exactly once and capture the position directly — avoids
293
+ // an O(n²) `indexOf` over a fresh array each call. Any caller that has
294
+ // deleted sheets after creating scoped names is responsible for updating
295
+ // `localSheetId` to match the new positions; this layer just reflects the
296
+ // workbook's current state.
297
+ const sheetIdToName = new Map();
298
+ const liveSheets = workbook.worksheets;
299
+ for (let idx = 0; idx < liveSheets.length; idx++) {
300
+ sheetIdToName.set(idx, liveSheets[idx].name);
301
+ }
302
+ // getAllEntries() returns self-contained entries — no second lookup needed.
303
+ const entries = workbook.definedNames.getAllEntries();
304
+ for (const entry of entries) {
305
+ if (!entry.ranges || entry.ranges.length === 0) {
306
+ continue;
307
+ }
308
+ // Convert numeric localSheetId → sheet name string for the snapshot
309
+ let scope;
310
+ if (entry.localSheetId !== undefined) {
311
+ scope = sheetIdToName.get(entry.localSheetId);
312
+ }
313
+ const snapshot = {
314
+ name: entry.name,
315
+ ranges: [...entry.ranges],
316
+ ...(scope ? { scope } : {})
317
+ };
318
+ const key = scope ? scopedNameKey(scope, entry.name) : entry.name.toUpperCase();
319
+ if (!map.has(key)) {
320
+ map.set(key, snapshot);
321
+ }
322
+ }
323
+ return map;
324
+ }