@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,437 @@
1
+ "use strict";
2
+ /**
3
+ * Dependency Graph for Formula Calculation
4
+ *
5
+ * Builds a dependency graph from compiled formulas' static dependencies,
6
+ * then produces a topological evaluation order with circular reference
7
+ * detection.
8
+ *
9
+ * Key exports:
10
+ * - `buildDependencyGraphFromDeps()` — build graph from CompiledFormula static deps
11
+ * - `topologicalSort()` — produce evaluation order, detecting circular refs
12
+ */
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ exports.buildDependencyGraphFromDeps = buildDependencyGraphFromDeps;
15
+ exports.mergeDynamicDeps = mergeDynamicDeps;
16
+ exports.topologicalSort = topologicalSort;
17
+ // ============================================================================
18
+ // Cell Key Helpers
19
+ // ============================================================================
20
+ function makeKey(sheet, row, col) {
21
+ return `${sheet}!${row}:${col}`;
22
+ }
23
+ // ============================================================================
24
+ // Dependency Reference → Cell Key Expansion
25
+ // ============================================================================
26
+ /**
27
+ * Type guard: is this a range reference (has `top` property)?
28
+ */
29
+ function isRange(ref) {
30
+ return "top" in ref;
31
+ }
32
+ /**
33
+ * Expand a set of DepRefs into concrete cell keys.
34
+ * For single-cell refs, the key is produced directly.
35
+ * For range refs, we check which formula cells fall within the range rather
36
+ * than enumerating every cell (which would be prohibitively expensive for
37
+ * whole-column ranges like A:A).
38
+ */
39
+ function expandRefsToKeys(refs, formulaKeySet, formulaCellCoordsBySheet) {
40
+ const keys = new Set();
41
+ for (const ref of refs) {
42
+ if (isRange(ref)) {
43
+ const rangeSize = (ref.bottom - ref.top + 1) * (ref.right - ref.left + 1);
44
+ if (rangeSize <= 10000) {
45
+ // Small-to-medium range: enumerate every cell
46
+ for (let r = ref.top; r <= ref.bottom; r++) {
47
+ for (let c = ref.left; c <= ref.right; c++) {
48
+ keys.add(makeKey(ref.sheet, r, c));
49
+ }
50
+ }
51
+ }
52
+ else {
53
+ // Large range (e.g. whole column A:A): scan formula cells in the
54
+ // referenced sheet only and check containment.
55
+ const sheetCoords = formulaCellCoordsBySheet.get(ref.sheet);
56
+ if (sheetCoords) {
57
+ for (const [fKey, coord] of sheetCoords) {
58
+ if (coord.row >= ref.top &&
59
+ coord.row <= ref.bottom &&
60
+ coord.col >= ref.left &&
61
+ coord.col <= ref.right) {
62
+ keys.add(fKey);
63
+ }
64
+ }
65
+ }
66
+ }
67
+ }
68
+ else {
69
+ // Single cell — always add
70
+ keys.add(makeKey(ref.sheet, ref.row, ref.col));
71
+ }
72
+ }
73
+ return keys;
74
+ }
75
+ // ============================================================================
76
+ // Build Dependency Graph from CompiledFormula StaticDeps
77
+ // ============================================================================
78
+ /**
79
+ * Build a dependency graph from compiled formulas' static dependencies.
80
+ *
81
+ * Operates on the already-resolved `StaticDependencySet` from each compiled
82
+ * formula. Since names and structured references are already resolved by
83
+ * the binder, the dependency edges are complete.
84
+ *
85
+ * @param compiled - Map from formula cell key to compiled formula with static deps
86
+ * @param producerMap - Optional map from cell key → formula key that produces
87
+ * that cell's value (via CSE distribution or dynamic-array spill). Allows
88
+ * dependency edges to be added to the producer even when the target cell
89
+ * isn't itself a formula.
90
+ * @returns The complete dependency graph
91
+ */
92
+ function buildDependencyGraphFromDeps(compiled, producerMap) {
93
+ // Build a lookup of all formula cell coordinates for range intersection.
94
+ // We group by sheet so that large-range containment scans only visit the
95
+ // relevant sheet's formula cells instead of the entire workbook.
96
+ const formulaKeySet = new Set();
97
+ const formulaCellCoordsBySheet = new Map();
98
+ const formulaKeys = [];
99
+ for (const [key, cf] of compiled) {
100
+ formulaKeySet.add(key);
101
+ // Use the instance's already-known coordinates instead of reverse-parsing
102
+ // the key string — saves two lastIndexOf calls and two parseInt calls
103
+ // per formula on cold-start.
104
+ const inst = cf.instance;
105
+ const coord = { sheet: inst.sheetName, row: inst.row, col: inst.col };
106
+ let list = formulaCellCoordsBySheet.get(inst.sheetName);
107
+ if (!list) {
108
+ list = [];
109
+ formulaCellCoordsBySheet.set(inst.sheetName, list);
110
+ }
111
+ list.push([key, coord]);
112
+ formulaKeys.push(key);
113
+ }
114
+ // Forward edges: formula key → set of keys it depends on
115
+ const dependsOn = new Map();
116
+ // Reverse edges: cell key → set of formula keys that depend on it
117
+ const dependedBy = new Map();
118
+ for (const [key, cf] of compiled) {
119
+ const deps = cf.staticDeps;
120
+ // Convert StaticDependencySet to DepRef[]
121
+ const refs = [];
122
+ // Direct cell deps always pass through verbatim.
123
+ for (const cell of deps.cells) {
124
+ refs.push({ sheet: cell.sheet, row: cell.row, col: cell.col });
125
+ }
126
+ // Area deps normally expand into every cell in the range. For areas
127
+ // that start at a dynamic-array master (e.g. the `A1:A5` in
128
+ // `SUM(A1:A5)` where A1 is a live `=SEQUENCE(5)`), we replace the
129
+ // expansion with a single dependency on the master. Evaluator-time
130
+ // `getCellValue` then reads the master's cached array result for
131
+ // the ghost positions, so downstream formulas see the full spill
132
+ // in the same calc pass. Without this, A2..A5 aren't yet in the
133
+ // snapshot on the first run and the SUM only picks up A1.
134
+ const dynMasterDeps = [];
135
+ for (const area of deps.areas) {
136
+ const topLeftKey = makeKey(area.sheet, area.top, area.left);
137
+ const masterCf = compiled.get(topLeftKey);
138
+ const isDynMaster = masterCf !== undefined &&
139
+ (masterCf.instance.isDynamicArray || masterCf.isDynamicArrayFunction);
140
+ if (isDynMaster) {
141
+ dynMasterDeps.push(topLeftKey);
142
+ continue;
143
+ }
144
+ refs.push({
145
+ sheet: area.sheet,
146
+ top: area.top,
147
+ left: area.left,
148
+ bottom: area.bottom,
149
+ right: area.right
150
+ });
151
+ }
152
+ // Expand to concrete cell keys
153
+ const depKeys = expandRefsToKeys(refs, formulaKeySet, formulaCellCoordsBySheet);
154
+ for (const mk of dynMasterDeps) {
155
+ depKeys.add(mk);
156
+ }
157
+ // Remap producer keys: if a dep points to a cell that's not a formula
158
+ // but IS produced by another formula (CSE target or spill target),
159
+ // depend on the producer instead.
160
+ if (producerMap && producerMap.size > 0) {
161
+ const remapped = new Set();
162
+ for (const depKey of depKeys) {
163
+ if (!formulaKeySet.has(depKey)) {
164
+ const producer = producerMap.get(depKey);
165
+ if (producer) {
166
+ remapped.add(producer);
167
+ continue;
168
+ }
169
+ }
170
+ remapped.add(depKey);
171
+ }
172
+ dependsOn.set(key, remapped);
173
+ for (const depKey of remapped) {
174
+ let set = dependedBy.get(depKey);
175
+ if (!set) {
176
+ set = new Set();
177
+ dependedBy.set(depKey, set);
178
+ }
179
+ set.add(key);
180
+ }
181
+ continue;
182
+ }
183
+ dependsOn.set(key, depKeys);
184
+ // Build reverse index
185
+ for (const depKey of depKeys) {
186
+ let set = dependedBy.get(depKey);
187
+ if (!set) {
188
+ set = new Set();
189
+ dependedBy.set(depKey, set);
190
+ }
191
+ set.add(key);
192
+ }
193
+ }
194
+ // Detect circular references
195
+ const { circularKeys } = detectCircularRefs(formulaKeys, dependsOn);
196
+ return {
197
+ dependsOn,
198
+ dependedBy,
199
+ formulaKeys,
200
+ circularKeys
201
+ };
202
+ }
203
+ // ============================================================================
204
+ // Merge Runtime Dynamic Dependencies
205
+ // ============================================================================
206
+ /**
207
+ * Merge runtime-discovered dynamic dependencies into a dependency graph.
208
+ *
209
+ * After evaluating formulas that contain INDIRECT/OFFSET, the runtime
210
+ * dependency recorder has collected the actual cell accesses. This function
211
+ * incorporates those dynamic edges into the graph and re-detects cycles.
212
+ *
213
+ * Returns a new graph if edges were added, or the original graph if no
214
+ * dynamic deps were recorded.
215
+ */
216
+ function mergeDynamicDeps(graph, dynamicDeps) {
217
+ if (dynamicDeps.size === 0) {
218
+ return { graph, changed: false };
219
+ }
220
+ // First pass: detect whether any new edges would actually be added.
221
+ // Cloning the full dependsOn/dependedBy maps is expensive for large
222
+ // workbooks; skip it entirely when there's no real work to do.
223
+ let needsClone = false;
224
+ for (const [formulaKey, accessedKeys] of dynamicDeps) {
225
+ const existing = graph.dependsOn.get(formulaKey);
226
+ for (const k of accessedKeys) {
227
+ if (!existing || !existing.has(k)) {
228
+ needsClone = true;
229
+ break;
230
+ }
231
+ }
232
+ if (needsClone) {
233
+ break;
234
+ }
235
+ }
236
+ if (!needsClone) {
237
+ return { graph, changed: false };
238
+ }
239
+ // Clone forward and reverse edges
240
+ const newDependsOn = new Map();
241
+ for (const [k, v] of graph.dependsOn) {
242
+ newDependsOn.set(k, new Set(v));
243
+ }
244
+ const newDependedBy = new Map();
245
+ for (const [k, v] of graph.dependedBy) {
246
+ newDependedBy.set(k, new Set(v));
247
+ }
248
+ // Add dynamic edges
249
+ for (const [formulaKey, accessedKeys] of dynamicDeps) {
250
+ let deps = newDependsOn.get(formulaKey);
251
+ if (!deps) {
252
+ deps = new Set();
253
+ newDependsOn.set(formulaKey, deps);
254
+ }
255
+ for (const accessedKey of accessedKeys) {
256
+ if (!deps.has(accessedKey)) {
257
+ deps.add(accessedKey);
258
+ // Update reverse edge
259
+ let rev = newDependedBy.get(accessedKey);
260
+ if (!rev) {
261
+ rev = new Set();
262
+ newDependedBy.set(accessedKey, rev);
263
+ }
264
+ rev.add(formulaKey);
265
+ }
266
+ }
267
+ }
268
+ // Re-detect cycles with the augmented graph
269
+ const { circularKeys } = detectCircularRefs(graph.formulaKeys, newDependsOn);
270
+ return {
271
+ graph: {
272
+ dependsOn: newDependsOn,
273
+ dependedBy: newDependedBy,
274
+ formulaKeys: graph.formulaKeys,
275
+ circularKeys
276
+ },
277
+ changed: true
278
+ };
279
+ }
280
+ // ============================================================================
281
+ // Circular Reference Detection
282
+ // ============================================================================
283
+ /**
284
+ * Detect circular references using Tarjan's SCC algorithm.
285
+ *
286
+ * A formula is "circular" if it belongs to a strongly connected component
287
+ * of size > 1, or if it has a direct self-loop (A = f(A)).
288
+ *
289
+ * This correctly identifies ALL nodes in cycles, including nodes reachable
290
+ * only through cross-edges to already-visited SCC members — a case that
291
+ * a simple 3-color DFS misses (e.g. diamond cycles like A→B→C→A plus A→D→C).
292
+ */
293
+ function detectCircularRefs(formulaKeys, dependsOn) {
294
+ const circularKeys = new Set();
295
+ // Tarjan's iterative SCC
296
+ const index = new Map();
297
+ const lowlink = new Map();
298
+ const onStack = new Set();
299
+ const sccStack = [];
300
+ let nextIndex = 0;
301
+ for (const startKey of formulaKeys) {
302
+ if (index.has(startKey)) {
303
+ continue;
304
+ }
305
+ const dfsStack = [];
306
+ index.set(startKey, nextIndex);
307
+ lowlink.set(startKey, nextIndex);
308
+ nextIndex++;
309
+ sccStack.push(startKey);
310
+ onStack.add(startKey);
311
+ dfsStack.push({
312
+ key: startKey,
313
+ iter: (dependsOn.get(startKey) ?? new Set())[Symbol.iterator](),
314
+ pendingChild: null
315
+ });
316
+ while (dfsStack.length > 0) {
317
+ const frame = dfsStack[dfsStack.length - 1];
318
+ // If we just returned from a child, update our lowlink
319
+ if (frame.pendingChild !== null) {
320
+ const childLow = lowlink.get(frame.pendingChild);
321
+ lowlink.set(frame.key, Math.min(lowlink.get(frame.key), childLow));
322
+ frame.pendingChild = null;
323
+ }
324
+ const next = frame.iter.next();
325
+ if (next.done) {
326
+ // Finished processing all children — check if this is an SCC root
327
+ if (lowlink.get(frame.key) === index.get(frame.key)) {
328
+ const scc = [];
329
+ let node;
330
+ do {
331
+ node = sccStack.pop();
332
+ onStack.delete(node);
333
+ scc.push(node);
334
+ } while (node !== frame.key);
335
+ // Mark as circular if SCC has > 1 node, OR if it's a self-loop
336
+ const hasSelfLoop = scc.length === 1 && dependsOn.get(scc[0])?.has(scc[0]);
337
+ if (scc.length > 1 || hasSelfLoop) {
338
+ for (const k of scc) {
339
+ circularKeys.add(k);
340
+ }
341
+ }
342
+ }
343
+ dfsStack.pop();
344
+ // Record returning to parent so it can update its lowlink
345
+ if (dfsStack.length > 0) {
346
+ dfsStack[dfsStack.length - 1].pendingChild = frame.key;
347
+ }
348
+ continue;
349
+ }
350
+ const depKey = next.value;
351
+ if (!index.has(depKey)) {
352
+ // Unvisited — push new frame
353
+ index.set(depKey, nextIndex);
354
+ lowlink.set(depKey, nextIndex);
355
+ nextIndex++;
356
+ sccStack.push(depKey);
357
+ onStack.add(depKey);
358
+ dfsStack.push({
359
+ key: depKey,
360
+ iter: (dependsOn.get(depKey) ?? new Set())[Symbol.iterator](),
361
+ pendingChild: null
362
+ });
363
+ }
364
+ else if (onStack.has(depKey)) {
365
+ // Back edge — update lowlink with dep's index
366
+ lowlink.set(frame.key, Math.min(lowlink.get(frame.key), index.get(depKey)));
367
+ }
368
+ // Cross edge to fully-processed SCC: skip (correct Tarjan behavior)
369
+ }
370
+ }
371
+ return { circularKeys };
372
+ }
373
+ // ============================================================================
374
+ // Topological Sort (Kahn's Algorithm)
375
+ // ============================================================================
376
+ /**
377
+ * Produce a topological evaluation order for formula cells using Kahn's algorithm.
378
+ * Cells with no dependencies are evaluated first. Circular references are
379
+ * appended at the end in their original order.
380
+ */
381
+ function topologicalSort(graph) {
382
+ const { formulaKeys, dependsOn, circularKeys } = graph;
383
+ const formulaKeySet = new Set(formulaKeys);
384
+ const inDegree = new Map();
385
+ for (const key of formulaKeys) {
386
+ if (circularKeys.has(key)) {
387
+ continue;
388
+ }
389
+ const deps = dependsOn.get(key);
390
+ if (!deps) {
391
+ inDegree.set(key, 0);
392
+ continue;
393
+ }
394
+ let count = 0;
395
+ for (const depKey of deps) {
396
+ if (formulaKeySet.has(depKey) && !circularKeys.has(depKey)) {
397
+ count++;
398
+ }
399
+ }
400
+ inDegree.set(key, count);
401
+ }
402
+ const queue = [];
403
+ for (const key of formulaKeys) {
404
+ if (circularKeys.has(key)) {
405
+ continue;
406
+ }
407
+ if ((inDegree.get(key) ?? 0) === 0) {
408
+ queue.push(key);
409
+ }
410
+ }
411
+ const sorted = [];
412
+ let head = 0;
413
+ while (head < queue.length) {
414
+ const key = queue[head++];
415
+ sorted.push(key);
416
+ const dependents = graph.dependedBy.get(key);
417
+ if (dependents) {
418
+ for (const depKey of dependents) {
419
+ if (circularKeys.has(depKey) || !formulaKeySet.has(depKey)) {
420
+ continue;
421
+ }
422
+ const deg = (inDegree.get(depKey) ?? 1) - 1;
423
+ inDegree.set(depKey, deg);
424
+ if (deg === 0) {
425
+ queue.push(depKey);
426
+ }
427
+ }
428
+ }
429
+ }
430
+ // Append circular reference cells at the end in original order
431
+ for (const key of formulaKeys) {
432
+ if (circularKeys.has(key)) {
433
+ sorted.push(key);
434
+ }
435
+ }
436
+ return sorted;
437
+ }
@@ -0,0 +1,141 @@
1
+ "use strict";
2
+ /**
3
+ * Shared utilities for structured reference (table) row-range resolution.
4
+ *
5
+ * The row-range logic for structured references is needed in three places:
6
+ * - binder (compile-time range resolution)
7
+ * - compiled-formula (static dependency extraction)
8
+ * - evaluator (runtime evaluation)
9
+ *
10
+ * This module provides the canonical implementation to avoid triplication.
11
+ */
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.buildTableGeometry = buildTableGeometry;
14
+ exports.resolveStructuredRefColumns = resolveStructuredRefColumns;
15
+ exports.resolveStructuredRefRows = resolveStructuredRefRows;
16
+ /**
17
+ * Derive `TableGeometry` from a table's snapshot fields.
18
+ *
19
+ * The data row range excludes the header (if any) but also excludes the
20
+ * totals row — totals, when present, occupy `dataRowEnd + 1`.
21
+ */
22
+ function buildTableGeometry(table) {
23
+ const topLeftRow = table.topLeft.row;
24
+ const dataRowStart = topLeftRow + (table.hasHeaderRow ? 1 : 0);
25
+ const dataRowEnd = dataRowStart + table.dataRowCount - 1;
26
+ return {
27
+ topLeftRow,
28
+ dataRowStart,
29
+ dataRowEnd,
30
+ hasHeaderRow: table.hasHeaderRow,
31
+ hasTotalsRow: table.hasTotalsRow
32
+ };
33
+ }
34
+ /**
35
+ * Resolve a list of structured-reference column names to a contiguous
36
+ * column range `[colLeft, colRight]` in absolute sheet coordinates.
37
+ *
38
+ * @param columns - Requested column names (case-insensitive match).
39
+ * @param table - Table whose columns are searched.
40
+ * @param mode -
41
+ * - `"strict"` — return `"error"` if any name is missing (used by
42
+ * binder and evaluator — unknown columns are `#REF!` errors).
43
+ * - `"permissive"` — ignore missing names; if ALL names are missing,
44
+ * falls back to the full table width (used by static-deps extraction,
45
+ * where a conservative over-estimate is acceptable).
46
+ * @returns `{ colLeft, colRight }`, or `"error"` in strict mode when a
47
+ * column name is not found. If `columns` is empty, returns the full
48
+ * table width.
49
+ */
50
+ function resolveStructuredRefColumns(columns, table, mode) {
51
+ const tl = table.topLeft;
52
+ const width = table.columns.length;
53
+ if (columns.length === 0) {
54
+ return { colLeft: tl.col, colRight: tl.col + width - 1 };
55
+ }
56
+ const indices = [];
57
+ for (const colName of columns) {
58
+ const idx = table.columns.findIndex(c => c.name.toLowerCase() === colName.toLowerCase());
59
+ if (idx === -1) {
60
+ if (mode === "strict") {
61
+ return "error";
62
+ }
63
+ continue;
64
+ }
65
+ indices.push(idx);
66
+ }
67
+ if (indices.length === 0) {
68
+ // permissive + all names missing → conservative full-width fallback
69
+ return { colLeft: tl.col, colRight: tl.col + width - 1 };
70
+ }
71
+ return {
72
+ colLeft: tl.col + Math.min(...indices),
73
+ colRight: tl.col + Math.max(...indices)
74
+ };
75
+ }
76
+ /**
77
+ * Resolve structured reference specials to a row range.
78
+ *
79
+ * This is the single source of truth for the mapping from
80
+ * `#All`, `#Headers`, `#Data`, `#Totals`, `#This Row` (and their
81
+ * combinations) to concrete row numbers.
82
+ */
83
+ function resolveStructuredRefRows(specials, geo) {
84
+ // Tokenizer stashes unknown `[#Something]` tokens with a sentinel
85
+ // prefix. Surface them as errors rather than let them alias to the
86
+ // default-data-range path below.
87
+ for (const s of specials) {
88
+ if (s.startsWith("#__INVALID__")) {
89
+ return "error";
90
+ }
91
+ }
92
+ const hasAll = specials.includes("#All");
93
+ const hasHeaders = specials.includes("#Headers");
94
+ const hasTotals = specials.includes("#Totals");
95
+ const hasData = specials.includes("#Data");
96
+ const hasThisRow = specials.includes("#This Row");
97
+ if (hasAll) {
98
+ return {
99
+ rowTop: geo.topLeftRow,
100
+ rowBottom: geo.hasTotalsRow ? geo.dataRowEnd + 1 : geo.dataRowEnd
101
+ };
102
+ }
103
+ if (hasThisRow) {
104
+ return "thisRow";
105
+ }
106
+ if (hasHeaders && hasTotals) {
107
+ return {
108
+ rowTop: geo.topLeftRow,
109
+ rowBottom: geo.hasTotalsRow ? geo.dataRowEnd + 1 : geo.dataRowEnd
110
+ };
111
+ }
112
+ if (hasHeaders && hasData) {
113
+ return {
114
+ rowTop: geo.hasHeaderRow ? geo.topLeftRow : geo.dataRowStart,
115
+ rowBottom: geo.dataRowEnd
116
+ };
117
+ }
118
+ if (hasData && hasTotals) {
119
+ return {
120
+ rowTop: geo.dataRowStart,
121
+ rowBottom: geo.hasTotalsRow ? geo.dataRowEnd + 1 : geo.dataRowEnd
122
+ };
123
+ }
124
+ if (hasHeaders) {
125
+ if (geo.hasHeaderRow) {
126
+ return { rowTop: geo.topLeftRow, rowBottom: geo.topLeftRow };
127
+ }
128
+ // Table without a header row: Excel reports #REF! rather than silently
129
+ // aliasing to the first data row. Returning the data row here would
130
+ // route `Table1[#Headers]` to real data values, masking user mistakes.
131
+ return "error";
132
+ }
133
+ if (hasTotals) {
134
+ if (geo.hasTotalsRow) {
135
+ return { rowTop: geo.dataRowEnd + 1, rowBottom: geo.dataRowEnd + 1 };
136
+ }
137
+ return "error";
138
+ }
139
+ // #Data or no specials → data range
140
+ return { rowTop: geo.dataRowStart, rowBottom: geo.dataRowEnd };
141
+ }
@@ -0,0 +1,87 @@
1
+ "use strict";
2
+ /**
3
+ * Formula-syntax probe slot.
4
+ *
5
+ * ## What this is
6
+ *
7
+ * `DefinedNames` (in the excel module) needs a way to tell whether a raw
8
+ * defined-name text like `OFFSET(Sheet1!$A$1,0,0,3,1)` is a parseable
9
+ * formula or opaque content to preserve verbatim. The only authoritative
10
+ * answer comes from the formula tokenizer + parser, which ship in the
11
+ * `@cj-tech-master/excelts/formula` subpath and are an opt-in
12
+ * dependency.
13
+ *
14
+ * This file is a tiny passive registration slot — a single `let` with
15
+ * a getter/setter pair — carrying **no** formula-engine code. Importing
16
+ * `DefinedNames` pulls in this slot (~0.5 KB minified) but never drags
17
+ * in the tokenizer, parser, or evaluator.
18
+ *
19
+ * ## Classification semantics
20
+ *
21
+ * - **No probe installed** (default): `DefinedNames` classifies any
22
+ * non-range, non-wrapper text as **opaque**. The `rawText` is
23
+ * preserved so XLSX round-trip bytes are stable; the entry simply
24
+ * cannot be evaluated — which is correct, because no formula engine
25
+ * is available anyway.
26
+ *
27
+ * - **Probe installed** (after `installFormulaEngine()`): `DefinedNames`
28
+ * classifies strictly. Parseable text becomes `formula`, unparseable
29
+ * text becomes `opaque`.
30
+ *
31
+ * ## Why the slot lives in the formula module
32
+ *
33
+ * Module dependency direction: `excel` may import from `formula`
34
+ * (layer 4 → layer 3), but `formula` must not import from `excel`. The
35
+ * probe slot is a *formula-module concept* (it wraps a formula
36
+ * tokenizer+parser) that excel consults; keeping it here preserves the
37
+ * one-way dependency.
38
+ *
39
+ * ## Construction-time injection is also supported
40
+ *
41
+ * `Workbook` and `DefinedNames` each accept an explicit
42
+ * `formulaSyntaxProbe` option. That is the preferred API for callers
43
+ * who want deterministic, per-instance behaviour (e.g. a test that
44
+ * needs a specific probe without touching process-global state). The
45
+ * default-probe slot here is the convenience layer for
46
+ * `installFormulaEngine()` — call it once at startup and every
47
+ * subsequent `new Workbook()` picks up strict classification
48
+ * automatically.
49
+ *
50
+ * ## Lookup timing
51
+ *
52
+ * `DefinedNames` reads the default probe lazily, at the moment `model`
53
+ * is assigned (i.e. during XLSX parsing). This means the common
54
+ * sequence
55
+ *
56
+ * ```ts
57
+ * const wb = new Workbook();
58
+ * installFormulaEngine(); // later
59
+ * await wb.xlsx.load(buffer); // sees the installed probe
60
+ * ```
61
+ *
62
+ * works correctly — the probe installed before `load()` is the one
63
+ * used, regardless of when `Workbook` itself was constructed.
64
+ */
65
+ Object.defineProperty(exports, "__esModule", { value: true });
66
+ exports.setDefaultSyntaxProbe = setDefaultSyntaxProbe;
67
+ exports.getDefaultSyntaxProbe = getDefaultSyntaxProbe;
68
+ let defaultProbe = null;
69
+ /**
70
+ * Install (or clear) the process-wide default syntax probe.
71
+ *
72
+ * Called from `installFormulaEngine()` in `./install`. Passing `null`
73
+ * uninstalls the probe — symmetric with the formula-engine registry and
74
+ * useful for tests that exercise the "no probe" classification path.
75
+ */
76
+ function setDefaultSyntaxProbe(probe) {
77
+ defaultProbe = probe;
78
+ }
79
+ /**
80
+ * Retrieve the currently-installed default probe, or `null` if none is
81
+ * installed. Consumers (chiefly `DefinedNames`) should treat `null` as
82
+ * a signal to use conservative (opaque) classification rather than
83
+ * guessing.
84
+ */
85
+ function getDefaultSyntaxProbe() {
86
+ return defaultProbe;
87
+ }
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.setDate1904 = setDate1904;
4
+ exports.isDate1904 = isDate1904;
5
+ /**
6
+ * Date context shared between formula functions and the evaluator.
7
+ *
8
+ * Native function signatures (`NativeFn = (args: RuntimeValue[]) => RuntimeValue`)
9
+ * have no access to the evaluation context, so date/time functions cannot
10
+ * receive the workbook's `date1904` flag through a parameter. Rather than
11
+ * plumb a new argument through 200+ function signatures, we store the flag
12
+ * in a module-local variable. The evaluator sets it before evaluating any
13
+ * formula in a calculation session.
14
+ *
15
+ * ## Thread safety
16
+ *
17
+ * JavaScript runtimes are single-threaded and a single calculation session
18
+ * operates on exactly one workbook at a time, so a module-level variable is
19
+ * safe in practice. If the engine is ever extended to support concurrent
20
+ * calculations across different workbooks (e.g. via worker threads), each
21
+ * worker will have its own module instance and remain correctly isolated.
22
+ * Nested synchronous calls within the same session all share the same
23
+ * workbook, so the flag remains correct throughout.
24
+ */
25
+ let currentDate1904 = false;
26
+ /** Set the workbook-wide `date1904` mode for the current calculation session. */
27
+ function setDate1904(v) {
28
+ currentDate1904 = v;
29
+ }
30
+ /** Read the workbook-wide `date1904` mode. */
31
+ function isDate1904() {
32
+ return currentDate1904;
33
+ }