@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.
- package/README.md +25 -2
- package/README_zh.md +29 -6
- package/dist/browser/index.browser.d.ts +1 -1
- package/dist/browser/index.browser.js +4 -0
- package/dist/browser/index.d.ts +1 -1
- package/dist/browser/index.js +4 -0
- package/dist/browser/modules/excel/cell.d.ts +17 -3
- package/dist/browser/modules/excel/cell.js +170 -22
- package/dist/browser/modules/excel/defined-names.d.ts +96 -1
- package/dist/browser/modules/excel/defined-names.js +411 -21
- package/dist/browser/modules/excel/image.d.ts +11 -0
- package/dist/browser/modules/excel/image.js +24 -1
- package/dist/browser/modules/excel/stream/workbook-reader.browser.d.ts +9 -3
- package/dist/browser/modules/excel/stream/workbook-reader.browser.js +14 -0
- package/dist/browser/modules/excel/stream/workbook-reader.d.ts +2 -1
- package/dist/browser/modules/excel/stream/workbook-writer.browser.d.ts +39 -5
- package/dist/browser/modules/excel/stream/workbook-writer.browser.js +48 -1
- package/dist/browser/modules/excel/stream/workbook-writer.d.ts +3 -2
- package/dist/browser/modules/excel/stream/worksheet-reader.js +17 -1
- package/dist/browser/modules/excel/stream/worksheet-writer.d.ts +39 -6
- package/dist/browser/modules/excel/stream/worksheet-writer.js +45 -5
- package/dist/browser/modules/excel/table.js +15 -2
- package/dist/browser/modules/excel/types.d.ts +133 -2
- package/dist/browser/modules/excel/utils/col-cache.d.ts +1 -0
- package/dist/browser/modules/excel/utils/col-cache.js +15 -0
- package/dist/browser/modules/excel/utils/drawing-utils.d.ts +3 -3
- package/dist/browser/modules/excel/utils/drawing-utils.js +4 -0
- package/dist/browser/modules/excel/utils/external-link-formula.d.ts +76 -0
- package/dist/browser/modules/excel/utils/external-link-formula.js +208 -0
- package/dist/browser/modules/excel/utils/iterate-stream.d.ts +9 -3
- package/dist/browser/modules/excel/utils/iterate-stream.js +3 -1
- package/dist/browser/modules/excel/utils/ooxml-paths.d.ts +19 -0
- package/dist/browser/modules/excel/utils/ooxml-paths.js +37 -2
- package/dist/browser/modules/excel/utils/shared-strings.d.ts +8 -3
- package/dist/browser/modules/excel/utils/shared-strings.js +21 -2
- package/dist/browser/modules/excel/utils/workbook-protection.d.ts +30 -0
- package/dist/browser/modules/excel/utils/workbook-protection.js +30 -0
- package/dist/browser/modules/excel/workbook.browser.d.ts +257 -6
- package/dist/browser/modules/excel/workbook.browser.js +318 -34
- package/dist/browser/modules/excel/workbook.d.ts +1 -1
- package/dist/browser/modules/excel/worksheet.d.ts +3 -1
- package/dist/browser/modules/excel/worksheet.js +21 -2
- package/dist/browser/modules/excel/xlsx/rel-type.d.ts +15 -0
- package/dist/browser/modules/excel/xlsx/rel-type.js +16 -1
- package/dist/browser/modules/excel/xlsx/xform/book/defined-name-xform.d.ts +6 -5
- package/dist/browser/modules/excel/xlsx/xform/book/defined-name-xform.js +21 -86
- package/dist/browser/modules/excel/xlsx/xform/book/external-link-xform.d.ts +84 -0
- package/dist/browser/modules/excel/xlsx/xform/book/external-link-xform.js +330 -0
- package/dist/browser/modules/excel/xlsx/xform/book/external-reference-xform.d.ts +17 -0
- package/dist/browser/modules/excel/xlsx/xform/book/external-reference-xform.js +24 -0
- package/dist/browser/modules/excel/xlsx/xform/book/workbook-calc-properties-xform.d.ts +3 -0
- package/dist/browser/modules/excel/xlsx/xform/book/workbook-calc-properties-xform.js +11 -2
- package/dist/browser/modules/excel/xlsx/xform/book/workbook-protection-xform.d.ts +20 -0
- package/dist/browser/modules/excel/xlsx/xform/book/workbook-protection-xform.js +66 -0
- package/dist/browser/modules/excel/xlsx/xform/book/workbook-xform.js +38 -5
- package/dist/browser/modules/excel/xlsx/xform/core/content-types-xform.js +19 -1
- package/dist/browser/modules/excel/xlsx/xform/core/metadata-xform.d.ts +56 -0
- package/dist/browser/modules/excel/xlsx/xform/core/metadata-xform.js +158 -0
- package/dist/browser/modules/excel/xlsx/xform/drawing/absolute-anchor-xform.d.ts +26 -0
- package/dist/browser/modules/excel/xlsx/xform/drawing/absolute-anchor-xform.js +105 -0
- package/dist/browser/modules/excel/xlsx/xform/drawing/base-cell-anchor-xform.js +3 -0
- package/dist/browser/modules/excel/xlsx/xform/drawing/drawing-xform.js +10 -2
- package/dist/browser/modules/excel/xlsx/xform/sheet/cell-xform.d.ts +1 -1
- package/dist/browser/modules/excel/xlsx/xform/sheet/cell-xform.js +166 -8
- package/dist/browser/modules/excel/xlsx/xform/sheet/data-validations-xform.js +1 -1
- package/dist/browser/modules/excel/xlsx/xform/sheet/ignored-errors-xform.d.ts +21 -0
- package/dist/browser/modules/excel/xlsx/xform/sheet/ignored-errors-xform.js +80 -0
- package/dist/browser/modules/excel/xlsx/xform/sheet/worksheet-xform.js +9 -4
- package/dist/browser/modules/excel/xlsx/xform/style/border-xform.js +4 -1
- package/dist/browser/modules/excel/xlsx/xlsx.browser.d.ts +172 -13
- package/dist/browser/modules/excel/xlsx/xlsx.browser.js +410 -20
- package/dist/browser/modules/excel/xlsx/xlsx.d.ts +7 -4
- package/dist/browser/modules/excel/xlsx/xlsx.js +4 -5
- package/dist/browser/modules/formula/compile/address-utils.d.ts +62 -0
- package/dist/browser/modules/formula/compile/address-utils.js +83 -0
- package/dist/browser/modules/formula/compile/binder.d.ts +42 -0
- package/dist/browser/modules/formula/compile/binder.js +487 -0
- package/dist/browser/modules/formula/compile/bound-ast.d.ts +230 -0
- package/dist/browser/modules/formula/compile/bound-ast.js +80 -0
- package/dist/browser/modules/formula/compile/compiled-formula.d.ts +137 -0
- package/dist/browser/modules/formula/compile/compiled-formula.js +383 -0
- package/dist/browser/modules/formula/compile/dependency-analysis.d.ts +93 -0
- package/dist/browser/modules/formula/compile/dependency-analysis.js +432 -0
- package/dist/browser/modules/formula/compile/structured-ref-utils.d.ts +93 -0
- package/dist/browser/modules/formula/compile/structured-ref-utils.js +136 -0
- package/dist/browser/modules/formula/default-syntax-probe.d.ts +79 -0
- package/dist/browser/modules/formula/default-syntax-probe.js +83 -0
- package/dist/browser/modules/formula/functions/_date-context.d.ts +4 -0
- package/dist/browser/modules/formula/functions/_date-context.js +29 -0
- package/dist/browser/modules/formula/functions/_shared.d.ts +121 -0
- package/dist/browser/modules/formula/functions/_shared.js +381 -0
- package/dist/browser/modules/formula/functions/conditional.d.ts +27 -0
- package/dist/browser/modules/formula/functions/conditional.js +343 -0
- package/dist/browser/modules/formula/functions/database.d.ts +37 -0
- package/dist/browser/modules/formula/functions/database.js +274 -0
- package/dist/browser/modules/formula/functions/date.d.ts +61 -0
- package/dist/browser/modules/formula/functions/date.js +855 -0
- package/dist/browser/modules/formula/functions/dynamic-array.d.ts +23 -0
- package/dist/browser/modules/formula/functions/dynamic-array.js +860 -0
- package/dist/browser/modules/formula/functions/engineering.d.ts +57 -0
- package/dist/browser/modules/formula/functions/engineering.js +1128 -0
- package/dist/browser/modules/formula/functions/financial.d.ts +202 -0
- package/dist/browser/modules/formula/functions/financial.js +2296 -0
- package/dist/browser/modules/formula/functions/lookup.d.ts +18 -0
- package/dist/browser/modules/formula/functions/lookup.js +886 -0
- package/dist/browser/modules/formula/functions/math.d.ts +114 -0
- package/dist/browser/modules/formula/functions/math.js +1406 -0
- package/dist/browser/modules/formula/functions/statistical.d.ts +193 -0
- package/dist/browser/modules/formula/functions/statistical.js +3390 -0
- package/dist/browser/modules/formula/functions/text.d.ts +86 -0
- package/dist/browser/modules/formula/functions/text.js +1845 -0
- package/dist/browser/modules/formula/host-registry.d.ts +53 -0
- package/dist/browser/modules/formula/host-registry.js +69 -0
- package/dist/browser/modules/formula/index.d.ts +39 -0
- package/dist/browser/modules/formula/index.js +49 -0
- package/dist/browser/modules/formula/install.d.ts +62 -0
- package/dist/browser/modules/formula/install.js +88 -0
- package/dist/browser/modules/formula/integration/apply-writeback-plan.d.ts +26 -0
- package/dist/browser/modules/formula/integration/apply-writeback-plan.js +210 -0
- package/dist/browser/modules/formula/integration/calculate-formulas-impl.d.ts +30 -0
- package/dist/browser/modules/formula/integration/calculate-formulas-impl.js +616 -0
- package/dist/browser/modules/formula/integration/calculate-formulas.d.ts +67 -0
- package/dist/browser/modules/formula/integration/calculate-formulas.js +68 -0
- package/dist/browser/modules/formula/integration/formula-instance.d.ts +64 -0
- package/dist/browser/modules/formula/integration/formula-instance.js +79 -0
- package/dist/browser/modules/formula/integration/workbook-adapter.d.ts +26 -0
- package/dist/browser/modules/formula/integration/workbook-adapter.js +324 -0
- package/dist/browser/modules/formula/integration/workbook-snapshot.d.ts +267 -0
- package/dist/browser/modules/formula/integration/workbook-snapshot.js +77 -0
- package/dist/browser/modules/formula/materialize/build-writeback-plan.d.ts +34 -0
- package/dist/browser/modules/formula/materialize/build-writeback-plan.js +473 -0
- package/dist/browser/modules/formula/materialize/spill-engine.d.ts +9 -0
- package/dist/browser/modules/formula/materialize/spill-engine.js +38 -0
- package/dist/browser/modules/formula/materialize/types.d.ts +179 -0
- package/dist/browser/modules/formula/materialize/types.js +29 -0
- package/dist/browser/modules/formula/materialize/writeback-plan.d.ts +167 -0
- package/dist/browser/modules/formula/materialize/writeback-plan.js +27 -0
- package/dist/browser/modules/formula/runtime/evaluator.d.ts +151 -0
- package/dist/browser/modules/formula/runtime/evaluator.js +2291 -0
- package/dist/browser/modules/formula/runtime/function-registry.d.ts +47 -0
- package/dist/browser/modules/formula/runtime/function-registry.js +840 -0
- package/dist/browser/modules/formula/runtime/values.d.ts +211 -0
- package/dist/browser/modules/formula/runtime/values.js +385 -0
- package/dist/browser/modules/formula/syntax/ast.d.ts +129 -0
- package/dist/browser/modules/formula/syntax/ast.js +28 -0
- package/dist/browser/modules/formula/syntax/parser.d.ts +18 -0
- package/dist/browser/modules/formula/syntax/parser.js +439 -0
- package/dist/browser/modules/formula/syntax/token-types.d.ts +153 -0
- package/dist/browser/modules/formula/syntax/token-types.js +59 -0
- package/dist/browser/modules/formula/syntax/tokenizer.d.ts +10 -0
- package/dist/browser/modules/formula/syntax/tokenizer.js +1074 -0
- package/dist/browser/modules/pdf/excel-bridge.js +9 -0
- package/dist/cjs/index.js +4 -0
- package/dist/cjs/modules/excel/cell.js +170 -22
- package/dist/cjs/modules/excel/defined-names.js +411 -21
- package/dist/cjs/modules/excel/image.js +24 -1
- package/dist/cjs/modules/excel/stream/workbook-reader.browser.js +14 -0
- package/dist/cjs/modules/excel/stream/workbook-writer.browser.js +48 -1
- package/dist/cjs/modules/excel/stream/worksheet-reader.js +17 -1
- package/dist/cjs/modules/excel/stream/worksheet-writer.js +45 -5
- package/dist/cjs/modules/excel/table.js +15 -2
- package/dist/cjs/modules/excel/utils/col-cache.js +15 -0
- package/dist/cjs/modules/excel/utils/drawing-utils.js +4 -0
- package/dist/cjs/modules/excel/utils/external-link-formula.js +212 -0
- package/dist/cjs/modules/excel/utils/iterate-stream.js +3 -1
- package/dist/cjs/modules/excel/utils/ooxml-paths.js +42 -2
- package/dist/cjs/modules/excel/utils/shared-strings.js +21 -2
- package/dist/cjs/modules/excel/utils/workbook-protection.js +33 -0
- package/dist/cjs/modules/excel/workbook.browser.js +318 -34
- package/dist/cjs/modules/excel/worksheet.js +20 -1
- package/dist/cjs/modules/excel/xlsx/rel-type.js +16 -1
- package/dist/cjs/modules/excel/xlsx/xform/book/defined-name-xform.js +21 -86
- package/dist/cjs/modules/excel/xlsx/xform/book/external-link-xform.js +333 -0
- package/dist/cjs/modules/excel/xlsx/xform/book/external-reference-xform.js +27 -0
- package/dist/cjs/modules/excel/xlsx/xform/book/workbook-calc-properties-xform.js +11 -2
- package/dist/cjs/modules/excel/xlsx/xform/book/workbook-protection-xform.js +69 -0
- package/dist/cjs/modules/excel/xlsx/xform/book/workbook-xform.js +38 -5
- package/dist/cjs/modules/excel/xlsx/xform/core/content-types-xform.js +18 -0
- package/dist/cjs/modules/excel/xlsx/xform/core/metadata-xform.js +161 -0
- package/dist/cjs/modules/excel/xlsx/xform/drawing/absolute-anchor-xform.js +108 -0
- package/dist/cjs/modules/excel/xlsx/xform/drawing/base-cell-anchor-xform.js +3 -0
- package/dist/cjs/modules/excel/xlsx/xform/drawing/drawing-xform.js +10 -2
- package/dist/cjs/modules/excel/xlsx/xform/sheet/cell-xform.js +166 -8
- package/dist/cjs/modules/excel/xlsx/xform/sheet/data-validations-xform.js +1 -1
- package/dist/cjs/modules/excel/xlsx/xform/sheet/ignored-errors-xform.js +83 -0
- package/dist/cjs/modules/excel/xlsx/xform/sheet/worksheet-xform.js +9 -4
- package/dist/cjs/modules/excel/xlsx/xform/style/border-xform.js +4 -1
- package/dist/cjs/modules/excel/xlsx/xlsx.browser.js +408 -18
- package/dist/cjs/modules/excel/xlsx/xlsx.js +4 -5
- package/dist/cjs/modules/formula/compile/address-utils.js +89 -0
- package/dist/cjs/modules/formula/compile/binder.js +489 -0
- package/dist/cjs/modules/formula/compile/bound-ast.js +68 -0
- package/dist/cjs/modules/formula/compile/compiled-formula.js +387 -0
- package/dist/cjs/modules/formula/compile/dependency-analysis.js +437 -0
- package/dist/cjs/modules/formula/compile/structured-ref-utils.js +141 -0
- package/dist/cjs/modules/formula/default-syntax-probe.js +87 -0
- package/dist/cjs/modules/formula/functions/_date-context.js +33 -0
- package/dist/cjs/modules/formula/functions/_shared.js +396 -0
- package/dist/cjs/modules/formula/functions/conditional.js +354 -0
- package/dist/cjs/modules/formula/functions/database.js +288 -0
- package/dist/cjs/modules/formula/functions/date.js +883 -0
- package/dist/cjs/modules/formula/functions/dynamic-array.js +881 -0
- package/dist/cjs/modules/formula/functions/engineering.js +1183 -0
- package/dist/cjs/modules/formula/functions/financial.js +2348 -0
- package/dist/cjs/modules/formula/functions/lookup.js +902 -0
- package/dist/cjs/modules/formula/functions/math.js +1487 -0
- package/dist/cjs/modules/formula/functions/statistical.js +3488 -0
- package/dist/cjs/modules/formula/functions/text.js +1889 -0
- package/dist/cjs/modules/formula/host-registry.js +75 -0
- package/dist/cjs/modules/formula/index.js +58 -0
- package/dist/cjs/modules/formula/install.js +93 -0
- package/dist/cjs/modules/formula/integration/apply-writeback-plan.js +213 -0
- package/dist/cjs/modules/formula/integration/calculate-formulas-impl.js +619 -0
- package/dist/cjs/modules/formula/integration/calculate-formulas.js +71 -0
- package/dist/cjs/modules/formula/integration/formula-instance.js +82 -0
- package/dist/cjs/modules/formula/integration/workbook-adapter.js +327 -0
- package/dist/cjs/modules/formula/integration/workbook-snapshot.js +84 -0
- package/dist/cjs/modules/formula/materialize/build-writeback-plan.js +475 -0
- package/dist/cjs/modules/formula/materialize/spill-engine.js +42 -0
- package/dist/cjs/modules/formula/materialize/types.js +32 -0
- package/dist/cjs/modules/formula/materialize/writeback-plan.js +28 -0
- package/dist/cjs/modules/formula/runtime/evaluator.js +2298 -0
- package/dist/cjs/modules/formula/runtime/function-registry.js +846 -0
- package/dist/cjs/modules/formula/runtime/values.js +385 -0
- package/dist/cjs/modules/formula/syntax/ast.js +8 -0
- package/dist/cjs/modules/formula/syntax/parser.js +440 -0
- package/dist/cjs/modules/formula/syntax/token-types.js +32 -0
- package/dist/cjs/modules/formula/syntax/tokenizer.js +1076 -0
- package/dist/cjs/modules/pdf/excel-bridge.js +9 -0
- package/dist/esm/index.browser.js +4 -0
- package/dist/esm/index.js +4 -0
- package/dist/esm/modules/excel/cell.js +170 -22
- package/dist/esm/modules/excel/defined-names.js +411 -21
- package/dist/esm/modules/excel/image.js +24 -1
- package/dist/esm/modules/excel/stream/workbook-reader.browser.js +14 -0
- package/dist/esm/modules/excel/stream/workbook-writer.browser.js +48 -1
- package/dist/esm/modules/excel/stream/worksheet-reader.js +17 -1
- package/dist/esm/modules/excel/stream/worksheet-writer.js +45 -5
- package/dist/esm/modules/excel/table.js +15 -2
- package/dist/esm/modules/excel/utils/col-cache.js +15 -0
- package/dist/esm/modules/excel/utils/drawing-utils.js +4 -0
- package/dist/esm/modules/excel/utils/external-link-formula.js +208 -0
- package/dist/esm/modules/excel/utils/iterate-stream.js +3 -1
- package/dist/esm/modules/excel/utils/ooxml-paths.js +37 -2
- package/dist/esm/modules/excel/utils/shared-strings.js +21 -2
- package/dist/esm/modules/excel/utils/workbook-protection.js +30 -0
- package/dist/esm/modules/excel/workbook.browser.js +318 -34
- package/dist/esm/modules/excel/worksheet.js +21 -2
- package/dist/esm/modules/excel/xlsx/rel-type.js +16 -1
- package/dist/esm/modules/excel/xlsx/xform/book/defined-name-xform.js +21 -86
- package/dist/esm/modules/excel/xlsx/xform/book/external-link-xform.js +330 -0
- package/dist/esm/modules/excel/xlsx/xform/book/external-reference-xform.js +24 -0
- package/dist/esm/modules/excel/xlsx/xform/book/workbook-calc-properties-xform.js +11 -2
- package/dist/esm/modules/excel/xlsx/xform/book/workbook-protection-xform.js +66 -0
- package/dist/esm/modules/excel/xlsx/xform/book/workbook-xform.js +38 -5
- package/dist/esm/modules/excel/xlsx/xform/core/content-types-xform.js +19 -1
- package/dist/esm/modules/excel/xlsx/xform/core/metadata-xform.js +158 -0
- package/dist/esm/modules/excel/xlsx/xform/drawing/absolute-anchor-xform.js +105 -0
- package/dist/esm/modules/excel/xlsx/xform/drawing/base-cell-anchor-xform.js +3 -0
- package/dist/esm/modules/excel/xlsx/xform/drawing/drawing-xform.js +10 -2
- package/dist/esm/modules/excel/xlsx/xform/sheet/cell-xform.js +166 -8
- package/dist/esm/modules/excel/xlsx/xform/sheet/data-validations-xform.js +1 -1
- package/dist/esm/modules/excel/xlsx/xform/sheet/ignored-errors-xform.js +80 -0
- package/dist/esm/modules/excel/xlsx/xform/sheet/worksheet-xform.js +9 -4
- package/dist/esm/modules/excel/xlsx/xform/style/border-xform.js +4 -1
- package/dist/esm/modules/excel/xlsx/xlsx.browser.js +410 -20
- package/dist/esm/modules/excel/xlsx/xlsx.js +4 -5
- package/dist/esm/modules/formula/compile/address-utils.js +83 -0
- package/dist/esm/modules/formula/compile/binder.js +487 -0
- package/dist/esm/modules/formula/compile/bound-ast.js +80 -0
- package/dist/esm/modules/formula/compile/compiled-formula.js +383 -0
- package/dist/esm/modules/formula/compile/dependency-analysis.js +432 -0
- package/dist/esm/modules/formula/compile/structured-ref-utils.js +136 -0
- package/dist/esm/modules/formula/default-syntax-probe.js +83 -0
- package/dist/esm/modules/formula/functions/_date-context.js +29 -0
- package/dist/esm/modules/formula/functions/_shared.js +381 -0
- package/dist/esm/modules/formula/functions/conditional.js +343 -0
- package/dist/esm/modules/formula/functions/database.js +274 -0
- package/dist/esm/modules/formula/functions/date.js +855 -0
- package/dist/esm/modules/formula/functions/dynamic-array.js +860 -0
- package/dist/esm/modules/formula/functions/engineering.js +1128 -0
- package/dist/esm/modules/formula/functions/financial.js +2296 -0
- package/dist/esm/modules/formula/functions/lookup.js +886 -0
- package/dist/esm/modules/formula/functions/math.js +1406 -0
- package/dist/esm/modules/formula/functions/statistical.js +3390 -0
- package/dist/esm/modules/formula/functions/text.js +1845 -0
- package/dist/esm/modules/formula/host-registry.js +69 -0
- package/dist/esm/modules/formula/index.js +49 -0
- package/dist/esm/modules/formula/install.js +88 -0
- package/dist/esm/modules/formula/integration/apply-writeback-plan.js +210 -0
- package/dist/esm/modules/formula/integration/calculate-formulas-impl.js +616 -0
- package/dist/esm/modules/formula/integration/calculate-formulas.js +68 -0
- package/dist/esm/modules/formula/integration/formula-instance.js +79 -0
- package/dist/esm/modules/formula/integration/workbook-adapter.js +324 -0
- package/dist/esm/modules/formula/integration/workbook-snapshot.js +77 -0
- package/dist/esm/modules/formula/materialize/build-writeback-plan.js +473 -0
- package/dist/esm/modules/formula/materialize/spill-engine.js +38 -0
- package/dist/esm/modules/formula/materialize/types.js +29 -0
- package/dist/esm/modules/formula/materialize/writeback-plan.js +27 -0
- package/dist/esm/modules/formula/runtime/evaluator.js +2291 -0
- package/dist/esm/modules/formula/runtime/function-registry.js +840 -0
- package/dist/esm/modules/formula/runtime/values.js +385 -0
- package/dist/esm/modules/formula/syntax/ast.js +28 -0
- package/dist/esm/modules/formula/syntax/parser.js +439 -0
- package/dist/esm/modules/formula/syntax/token-types.js +59 -0
- package/dist/esm/modules/formula/syntax/tokenizer.js +1074 -0
- package/dist/esm/modules/pdf/excel-bridge.js +9 -0
- package/dist/iife/excelts.iife.js +2302 -373
- package/dist/iife/excelts.iife.js.map +1 -1
- package/dist/iife/excelts.iife.min.js +34 -34
- package/dist/types/index.browser.d.ts +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/modules/excel/cell.d.ts +17 -3
- package/dist/types/modules/excel/defined-names.d.ts +96 -1
- package/dist/types/modules/excel/image.d.ts +11 -0
- package/dist/types/modules/excel/stream/workbook-reader.browser.d.ts +9 -3
- package/dist/types/modules/excel/stream/workbook-reader.d.ts +2 -1
- package/dist/types/modules/excel/stream/workbook-writer.browser.d.ts +39 -5
- package/dist/types/modules/excel/stream/workbook-writer.d.ts +3 -2
- package/dist/types/modules/excel/stream/worksheet-writer.d.ts +39 -6
- package/dist/types/modules/excel/types.d.ts +133 -2
- package/dist/types/modules/excel/utils/col-cache.d.ts +1 -0
- package/dist/types/modules/excel/utils/drawing-utils.d.ts +3 -3
- package/dist/types/modules/excel/utils/external-link-formula.d.ts +76 -0
- package/dist/types/modules/excel/utils/iterate-stream.d.ts +9 -3
- package/dist/types/modules/excel/utils/ooxml-paths.d.ts +19 -0
- package/dist/types/modules/excel/utils/shared-strings.d.ts +8 -3
- package/dist/types/modules/excel/utils/workbook-protection.d.ts +30 -0
- package/dist/types/modules/excel/workbook.browser.d.ts +257 -6
- package/dist/types/modules/excel/workbook.d.ts +1 -1
- package/dist/types/modules/excel/worksheet.d.ts +3 -1
- package/dist/types/modules/excel/xlsx/rel-type.d.ts +15 -0
- package/dist/types/modules/excel/xlsx/xform/book/defined-name-xform.d.ts +6 -5
- package/dist/types/modules/excel/xlsx/xform/book/external-link-xform.d.ts +84 -0
- package/dist/types/modules/excel/xlsx/xform/book/external-reference-xform.d.ts +17 -0
- package/dist/types/modules/excel/xlsx/xform/book/workbook-calc-properties-xform.d.ts +3 -0
- package/dist/types/modules/excel/xlsx/xform/book/workbook-protection-xform.d.ts +20 -0
- package/dist/types/modules/excel/xlsx/xform/core/metadata-xform.d.ts +56 -0
- package/dist/types/modules/excel/xlsx/xform/drawing/absolute-anchor-xform.d.ts +26 -0
- package/dist/types/modules/excel/xlsx/xform/sheet/cell-xform.d.ts +1 -1
- package/dist/types/modules/excel/xlsx/xform/sheet/ignored-errors-xform.d.ts +21 -0
- package/dist/types/modules/excel/xlsx/xlsx.browser.d.ts +172 -13
- package/dist/types/modules/excel/xlsx/xlsx.d.ts +7 -4
- package/dist/types/modules/formula/compile/address-utils.d.ts +62 -0
- package/dist/types/modules/formula/compile/binder.d.ts +42 -0
- package/dist/types/modules/formula/compile/bound-ast.d.ts +230 -0
- package/dist/types/modules/formula/compile/compiled-formula.d.ts +137 -0
- package/dist/types/modules/formula/compile/dependency-analysis.d.ts +93 -0
- package/dist/types/modules/formula/compile/structured-ref-utils.d.ts +93 -0
- package/dist/types/modules/formula/default-syntax-probe.d.ts +79 -0
- package/dist/types/modules/formula/functions/_date-context.d.ts +4 -0
- package/dist/types/modules/formula/functions/_shared.d.ts +121 -0
- package/dist/types/modules/formula/functions/conditional.d.ts +27 -0
- package/dist/types/modules/formula/functions/database.d.ts +37 -0
- package/dist/types/modules/formula/functions/date.d.ts +61 -0
- package/dist/types/modules/formula/functions/dynamic-array.d.ts +23 -0
- package/dist/types/modules/formula/functions/engineering.d.ts +57 -0
- package/dist/types/modules/formula/functions/financial.d.ts +202 -0
- package/dist/types/modules/formula/functions/lookup.d.ts +18 -0
- package/dist/types/modules/formula/functions/math.d.ts +114 -0
- package/dist/types/modules/formula/functions/statistical.d.ts +193 -0
- package/dist/types/modules/formula/functions/text.d.ts +86 -0
- package/dist/types/modules/formula/host-registry.d.ts +53 -0
- package/dist/types/modules/formula/index.d.ts +39 -0
- package/dist/types/modules/formula/install.d.ts +62 -0
- package/dist/types/modules/formula/integration/apply-writeback-plan.d.ts +26 -0
- package/dist/types/modules/formula/integration/calculate-formulas-impl.d.ts +30 -0
- package/dist/types/modules/formula/integration/calculate-formulas.d.ts +67 -0
- package/dist/types/modules/formula/integration/formula-instance.d.ts +64 -0
- package/dist/types/modules/formula/integration/workbook-adapter.d.ts +26 -0
- package/dist/types/modules/formula/integration/workbook-snapshot.d.ts +267 -0
- package/dist/types/modules/formula/materialize/build-writeback-plan.d.ts +34 -0
- package/dist/types/modules/formula/materialize/spill-engine.d.ts +9 -0
- package/dist/types/modules/formula/materialize/types.d.ts +179 -0
- package/dist/types/modules/formula/materialize/writeback-plan.d.ts +167 -0
- package/dist/types/modules/formula/runtime/evaluator.d.ts +151 -0
- package/dist/types/modules/formula/runtime/function-registry.d.ts +47 -0
- package/dist/types/modules/formula/runtime/values.d.ts +211 -0
- package/dist/types/modules/formula/syntax/ast.d.ts +129 -0
- package/dist/types/modules/formula/syntax/parser.d.ts +18 -0
- package/dist/types/modules/formula/syntax/token-types.d.ts +153 -0
- package/dist/types/modules/formula/syntax/tokenizer.d.ts +10 -0
- package/package.json +28 -28
|
@@ -0,0 +1,475 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Build Writeback Plan — Convert evaluation results into a WritebackPlan.
|
|
4
|
+
*
|
|
5
|
+
* This module takes the evaluation results from the evaluator and
|
|
6
|
+
* produces a declarative `WritebackPlan` that describes all cell mutations.
|
|
7
|
+
* The plan is then applied by `apply-writeback-plan.ts`.
|
|
8
|
+
*
|
|
9
|
+
* ## Responsibilities
|
|
10
|
+
*
|
|
11
|
+
* 1. Classify each formula's result as scalar, CSE, or dynamic-array.
|
|
12
|
+
* 2. Check spill availability and detect #SPILL! conflicts.
|
|
13
|
+
* 3. Generate cleanup operations for stale ghost cells.
|
|
14
|
+
* 4. Track spill regions and ghost snapshots for persistence.
|
|
15
|
+
*
|
|
16
|
+
* ## Key Principle
|
|
17
|
+
*
|
|
18
|
+
* This module does NOT touch any live workbook objects. It reads only
|
|
19
|
+
* from the `WorkbookSnapshot` and the evaluation results.
|
|
20
|
+
*/
|
|
21
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
+
exports.buildWritebackPlan = buildWritebackPlan;
|
|
23
|
+
const address_utils_1 = require("../compile/address-utils");
|
|
24
|
+
const workbook_snapshot_1 = require("../integration/workbook-snapshot");
|
|
25
|
+
// ============================================================================
|
|
26
|
+
// Build Writeback Plan
|
|
27
|
+
// ============================================================================
|
|
28
|
+
/**
|
|
29
|
+
* Build a complete `WritebackPlan` from evaluation results.
|
|
30
|
+
*
|
|
31
|
+
* @param snapshot - The workbook snapshot
|
|
32
|
+
* @param compiled - All compiled formulas in evaluation order
|
|
33
|
+
* @param results - Raw evaluation results, keyed by formula cell key
|
|
34
|
+
* @param previousSpills - Persistent spill regions from previous calculation
|
|
35
|
+
* @param previousGhosts - Persistent ghost snapshots from previous calculation
|
|
36
|
+
*/
|
|
37
|
+
function buildWritebackPlan(snapshot, compiled, results, previousSpills, previousGhosts) {
|
|
38
|
+
const operations = [];
|
|
39
|
+
const spillRegions = new Map();
|
|
40
|
+
const ghostSnapshots = new Map();
|
|
41
|
+
const removedSpillKeys = [];
|
|
42
|
+
// Target cells already claimed by a spill produced EARLIER in this
|
|
43
|
+
// calc pass. Without this set, two dynamic-array formulas whose spill
|
|
44
|
+
// regions overlap would each pass the availability check against the
|
|
45
|
+
// immutable snapshot and then silently clobber each other during
|
|
46
|
+
// apply. See R5-P0-6.
|
|
47
|
+
const activeSpillTargets = new Set();
|
|
48
|
+
// Build a set of current formula cell keys (using worksheet-id-based keys)
|
|
49
|
+
const formulaKeys = new Set();
|
|
50
|
+
for (const cf of compiled) {
|
|
51
|
+
formulaKeys.add((0, workbook_snapshot_1.spillCellKeyFromId)(cf.instance.sheetId, cf.instance.row, cf.instance.col));
|
|
52
|
+
}
|
|
53
|
+
// Build ghost map from previous spills (validated against snapshot)
|
|
54
|
+
const ghostMap = new Map();
|
|
55
|
+
for (const [srcKey, region] of previousSpills) {
|
|
56
|
+
for (let r = 0; r < region.rows; r++) {
|
|
57
|
+
for (let c = 0; c < region.cols; c++) {
|
|
58
|
+
if (r === 0 && c === 0) {
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
const targetRow = region.sourceRow + r;
|
|
62
|
+
const targetCol = region.sourceCol + c;
|
|
63
|
+
const targetKey = (0, workbook_snapshot_1.spillCellKeyFromId)(region.worksheetId, targetRow, targetCol);
|
|
64
|
+
// Validate ghost cell is still unmodified
|
|
65
|
+
const ws = snapshot.worksheetsById.get(region.worksheetId);
|
|
66
|
+
if (ws) {
|
|
67
|
+
const cell = ws.cells.get((0, workbook_snapshot_1.snapshotCellKey)(targetRow, targetCol));
|
|
68
|
+
if (isGhostUnmodified(cell, targetKey, previousGhosts)) {
|
|
69
|
+
ghostMap.set(targetKey, srcKey);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
// Clean up stale spill regions (source formula no longer exists)
|
|
76
|
+
for (const [srcKey, region] of previousSpills) {
|
|
77
|
+
if (!formulaKeys.has(srcKey)) {
|
|
78
|
+
const ws = snapshot.worksheetsById.get(region.worksheetId);
|
|
79
|
+
if (ws) {
|
|
80
|
+
emitPreviousSpillCleanup(region, previousGhosts, snapshot, operations, ws.name, region.worksheetId);
|
|
81
|
+
}
|
|
82
|
+
removedSpillKeys.push(srcKey);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
// Process each compiled formula's result
|
|
86
|
+
for (const cf of compiled) {
|
|
87
|
+
const inst = cf.instance;
|
|
88
|
+
const fKey = (0, workbook_snapshot_1.formulaCellKey)(inst.sheetName, inst.row, inst.col);
|
|
89
|
+
const result = results.get(fKey);
|
|
90
|
+
if (result === undefined) {
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
const isCSE = inst.kind === "cse" && inst.targetRef;
|
|
94
|
+
const isDynamic = inst.isDynamicArray || cf.isDynamicArrayFunction;
|
|
95
|
+
if (isCSE) {
|
|
96
|
+
// CSE array formula
|
|
97
|
+
const op = buildCSEWrite(inst, result);
|
|
98
|
+
if (op) {
|
|
99
|
+
operations.push(op);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
else if (isDynamic &&
|
|
103
|
+
result.kind === 5 /* RVKind.Array */ &&
|
|
104
|
+
(result.height > 1 || result.width > 1)) {
|
|
105
|
+
// Dynamic array formula with array result
|
|
106
|
+
const srcKey = (0, workbook_snapshot_1.spillCellKeyFromId)(inst.sheetId, inst.row, inst.col);
|
|
107
|
+
// Check spill availability
|
|
108
|
+
const spillResult = buildSpillWrite(inst, result, srcKey, ghostMap, previousSpills.get(srcKey), previousGhosts, snapshot, spillRegions, ghostSnapshots, operations, activeSpillTargets);
|
|
109
|
+
if (spillResult === "error") {
|
|
110
|
+
operations.push({
|
|
111
|
+
type: "spill-error",
|
|
112
|
+
sheetName: inst.sheetName,
|
|
113
|
+
sheetId: inst.sheetId,
|
|
114
|
+
row: inst.row,
|
|
115
|
+
col: inst.col
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
// Scalar result (or 1x1 array)
|
|
121
|
+
const scalar = scalarFromResult(result);
|
|
122
|
+
// If this formula previously had a spill region, clean it up
|
|
123
|
+
const srcKey = (0, workbook_snapshot_1.spillCellKeyFromId)(inst.sheetId, inst.row, inst.col);
|
|
124
|
+
const prevRegion = previousSpills.get(srcKey);
|
|
125
|
+
if (prevRegion) {
|
|
126
|
+
emitPreviousSpillCleanup(prevRegion, previousGhosts, snapshot, operations, inst.sheetName, inst.sheetId);
|
|
127
|
+
removedSpillKeys.push(srcKey);
|
|
128
|
+
}
|
|
129
|
+
if (shouldPreserve(scalar, inst, snapshot)) {
|
|
130
|
+
operations.push({
|
|
131
|
+
type: "preserve",
|
|
132
|
+
sheetName: inst.sheetName,
|
|
133
|
+
row: inst.row,
|
|
134
|
+
col: inst.col
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
operations.push({
|
|
139
|
+
type: "scalar",
|
|
140
|
+
sheetName: inst.sheetName,
|
|
141
|
+
row: inst.row,
|
|
142
|
+
col: inst.col,
|
|
143
|
+
value: runtimeToSnapshotValue(scalar)
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return {
|
|
149
|
+
operations,
|
|
150
|
+
spillState: {
|
|
151
|
+
spillRegions,
|
|
152
|
+
ghostSnapshots,
|
|
153
|
+
removedSpillKeys
|
|
154
|
+
}
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
// ============================================================================
|
|
158
|
+
// CSE Write
|
|
159
|
+
// ============================================================================
|
|
160
|
+
function buildCSEWrite(inst, result) {
|
|
161
|
+
const ref = inst.targetRef;
|
|
162
|
+
if (!ref) {
|
|
163
|
+
return null;
|
|
164
|
+
}
|
|
165
|
+
const range = (0, address_utils_1.parseRefRange)(ref);
|
|
166
|
+
if (!range) {
|
|
167
|
+
return null;
|
|
168
|
+
}
|
|
169
|
+
if (result.kind === 5 /* RVKind.Array */) {
|
|
170
|
+
const results = [];
|
|
171
|
+
const numRows = range.bottom - range.top + 1;
|
|
172
|
+
const numCols = range.right - range.left + 1;
|
|
173
|
+
for (let r = 0; r < numRows; r++) {
|
|
174
|
+
const row = [];
|
|
175
|
+
for (let c = 0; c < numCols; c++) {
|
|
176
|
+
// When the array result is smaller than the CSE target range,
|
|
177
|
+
// positions outside the array get #N/A (Excel behaviour) — not
|
|
178
|
+
// BLANK, which is what the previous `?? { kind: Blank }` gave
|
|
179
|
+
// us. R6-P1-3.
|
|
180
|
+
const inBounds = r < result.height && c < result.width;
|
|
181
|
+
const val = inBounds
|
|
182
|
+
? result.rows[r][c]
|
|
183
|
+
: { kind: 4 /* RVKind.Error */, code: "#N/A" };
|
|
184
|
+
row.push(runtimeToSnapshotValue(val));
|
|
185
|
+
}
|
|
186
|
+
results.push(row);
|
|
187
|
+
}
|
|
188
|
+
return {
|
|
189
|
+
type: "cse",
|
|
190
|
+
sheetName: inst.sheetName,
|
|
191
|
+
top: range.top,
|
|
192
|
+
left: range.left,
|
|
193
|
+
bottom: range.bottom,
|
|
194
|
+
right: range.right,
|
|
195
|
+
results
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
// Scalar fill
|
|
199
|
+
const scalarVal = runtimeToSnapshotValue(scalarFromResult(result));
|
|
200
|
+
return {
|
|
201
|
+
type: "cse",
|
|
202
|
+
sheetName: inst.sheetName,
|
|
203
|
+
top: range.top,
|
|
204
|
+
left: range.left,
|
|
205
|
+
bottom: range.bottom,
|
|
206
|
+
right: range.right,
|
|
207
|
+
results: [],
|
|
208
|
+
scalarFill: scalarVal
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
// ============================================================================
|
|
212
|
+
// Spill Write
|
|
213
|
+
// ============================================================================
|
|
214
|
+
function buildSpillWrite(inst, arr, srcKey, ghostMap, previousRegion, previousGhosts, snapshot, spillRegions, ghostSnapshotsOut, operations,
|
|
215
|
+
/**
|
|
216
|
+
* Target cell keys claimed by spill regions produced EARLIER in this
|
|
217
|
+
* same calc pass. The snapshot is immutable during a pass, so without
|
|
218
|
+
* an explicit set the availability check wouldn't see the A1→A1:A5
|
|
219
|
+
* spill that the previous iteration just committed, and a subsequent
|
|
220
|
+
* formula spilling over A3:A7 would silently overwrite half of it.
|
|
221
|
+
*/
|
|
222
|
+
activeSpillTargets) {
|
|
223
|
+
const ws = snapshot.worksheetsByName.get(inst.sheetName.toLowerCase());
|
|
224
|
+
if (!ws) {
|
|
225
|
+
return "error";
|
|
226
|
+
}
|
|
227
|
+
// 1x1 result: just write scalar, no spilling
|
|
228
|
+
if (arr.height <= 1 && arr.width <= 1) {
|
|
229
|
+
const val = arr.height > 0 && arr.width > 0 ? arr.rows[0][0] : { kind: 0 /* RVKind.Blank */ };
|
|
230
|
+
operations.push({
|
|
231
|
+
type: "scalar",
|
|
232
|
+
sheetName: inst.sheetName,
|
|
233
|
+
row: inst.row,
|
|
234
|
+
col: inst.col,
|
|
235
|
+
value: runtimeToSnapshotValue(val)
|
|
236
|
+
});
|
|
237
|
+
// Clean up previous spill if any
|
|
238
|
+
if (previousRegion) {
|
|
239
|
+
emitPreviousSpillCleanup(previousRegion, previousGhosts, snapshot, operations, inst.sheetName, inst.sheetId);
|
|
240
|
+
}
|
|
241
|
+
return "ok";
|
|
242
|
+
}
|
|
243
|
+
// Reject if the spill region would extend past the sheet's maximum
|
|
244
|
+
// dimensions (1048576 rows x 16384 columns) — Excel reports #SPILL! here.
|
|
245
|
+
if (inst.row + arr.height - 1 > 1048576 || inst.col + arr.width - 1 > 16384) {
|
|
246
|
+
return "error";
|
|
247
|
+
}
|
|
248
|
+
// Check spill availability: verify all target ghost cells are unoccupied
|
|
249
|
+
for (let r = 0; r < arr.height; r++) {
|
|
250
|
+
for (let c = 0; c < arr.width; c++) {
|
|
251
|
+
if (r === 0 && c === 0) {
|
|
252
|
+
continue; // Source cell is always available
|
|
253
|
+
}
|
|
254
|
+
const targetRow = inst.row + r;
|
|
255
|
+
const targetCol = inst.col + c;
|
|
256
|
+
const targetKey = (0, workbook_snapshot_1.spillCellKeyFromId)(inst.sheetId, targetRow, targetCol);
|
|
257
|
+
// Another spill in this calc pass already claimed this cell —
|
|
258
|
+
// report #SPILL! rather than silently overwrite.
|
|
259
|
+
if (activeSpillTargets.has(targetKey)) {
|
|
260
|
+
return "error";
|
|
261
|
+
}
|
|
262
|
+
// Check if the cell is a ghost from ANY previous spill.
|
|
263
|
+
// If the user hasn't modified it, it's safe to overwrite — the
|
|
264
|
+
// originating formula will clean it up (or we'll overwrite it).
|
|
265
|
+
if (ghostMap.has(targetKey)) {
|
|
266
|
+
const cell = ws.cells.get((0, workbook_snapshot_1.snapshotCellKey)(targetRow, targetCol));
|
|
267
|
+
if (!isGhostUnmodified(cell, targetKey, previousGhosts)) {
|
|
268
|
+
return "error"; // User wrote into a ghost → #SPILL!
|
|
269
|
+
}
|
|
270
|
+
continue;
|
|
271
|
+
}
|
|
272
|
+
// Check if the cell is occupied by another formula or has a value
|
|
273
|
+
const cell = ws.cells.get((0, workbook_snapshot_1.snapshotCellKey)(targetRow, targetCol));
|
|
274
|
+
if (cell && cell.value !== null && cell.formulaKind === "none") {
|
|
275
|
+
// Non-empty, non-formula cell → blocked
|
|
276
|
+
return "error";
|
|
277
|
+
}
|
|
278
|
+
if (cell && cell.formulaKind !== "none") {
|
|
279
|
+
// Formula cell → blocked (not our ghost)
|
|
280
|
+
return "error";
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
// Now that availability is confirmed, claim the target cells so the
|
|
285
|
+
// next spill in this pass sees them as occupied.
|
|
286
|
+
for (let r = 0; r < arr.height; r++) {
|
|
287
|
+
for (let c = 0; c < arr.width; c++) {
|
|
288
|
+
if (r === 0 && c === 0) {
|
|
289
|
+
continue;
|
|
290
|
+
}
|
|
291
|
+
const targetRow = inst.row + r;
|
|
292
|
+
const targetCol = inst.col + c;
|
|
293
|
+
activeSpillTargets.add((0, workbook_snapshot_1.spillCellKeyFromId)(inst.sheetId, targetRow, targetCol));
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
// Clean up previous spill region if size changed
|
|
297
|
+
if (previousRegion) {
|
|
298
|
+
emitPreviousSpillCleanup(previousRegion, previousGhosts, snapshot, operations, inst.sheetName, inst.sheetId);
|
|
299
|
+
}
|
|
300
|
+
// Build spill write operation
|
|
301
|
+
const results = [];
|
|
302
|
+
for (let r = 0; r < arr.height; r++) {
|
|
303
|
+
const row = [];
|
|
304
|
+
for (let c = 0; c < arr.width; c++) {
|
|
305
|
+
const val = arr.rows[r]?.[c] ?? { kind: 0 /* RVKind.Blank */ };
|
|
306
|
+
const sv = runtimeToSnapshotValue(val);
|
|
307
|
+
row.push(sv);
|
|
308
|
+
// Record ghost snapshot
|
|
309
|
+
if (r !== 0 || c !== 0) {
|
|
310
|
+
const targetKey = (0, workbook_snapshot_1.spillCellKeyFromId)(inst.sheetId, inst.row + r, inst.col + c);
|
|
311
|
+
ghostSnapshotsOut.set(targetKey, sv);
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
results.push(row);
|
|
315
|
+
}
|
|
316
|
+
operations.push({
|
|
317
|
+
type: "spill",
|
|
318
|
+
sheetName: inst.sheetName,
|
|
319
|
+
sheetId: inst.sheetId,
|
|
320
|
+
row: inst.row,
|
|
321
|
+
col: inst.col,
|
|
322
|
+
results
|
|
323
|
+
});
|
|
324
|
+
// Record spill region
|
|
325
|
+
spillRegions.set(srcKey, {
|
|
326
|
+
worksheetId: inst.sheetId,
|
|
327
|
+
sourceRow: inst.row,
|
|
328
|
+
sourceCol: inst.col,
|
|
329
|
+
rows: arr.height,
|
|
330
|
+
cols: arr.width
|
|
331
|
+
});
|
|
332
|
+
return "ok";
|
|
333
|
+
}
|
|
334
|
+
// ============================================================================
|
|
335
|
+
// Helpers
|
|
336
|
+
// ============================================================================
|
|
337
|
+
function collectStaleGhosts(region, previousGhosts, snapshot) {
|
|
338
|
+
const cells = [];
|
|
339
|
+
const ws = snapshot.worksheetsById.get(region.worksheetId);
|
|
340
|
+
if (!ws) {
|
|
341
|
+
return cells;
|
|
342
|
+
}
|
|
343
|
+
for (let r = 0; r < region.rows; r++) {
|
|
344
|
+
for (let c = 0; c < region.cols; c++) {
|
|
345
|
+
if (r === 0 && c === 0) {
|
|
346
|
+
continue;
|
|
347
|
+
}
|
|
348
|
+
const targetRow = region.sourceRow + r;
|
|
349
|
+
const targetCol = region.sourceCol + c;
|
|
350
|
+
const targetKey = (0, workbook_snapshot_1.spillCellKeyFromId)(region.worksheetId, targetRow, targetCol);
|
|
351
|
+
const cell = ws.cells.get((0, workbook_snapshot_1.snapshotCellKey)(targetRow, targetCol));
|
|
352
|
+
if (isGhostUnmodified(cell, targetKey, previousGhosts)) {
|
|
353
|
+
cells.push({ row: targetRow, col: targetCol });
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
return cells;
|
|
358
|
+
}
|
|
359
|
+
/**
|
|
360
|
+
* Emit a cleanup operation for a previous spill region whose ghosts are
|
|
361
|
+
* still unmodified.
|
|
362
|
+
*
|
|
363
|
+
* Collects the stale ghost cells and, if any remain, pushes a single
|
|
364
|
+
* `CleanupWrite` onto `operations`. The caller is responsible for
|
|
365
|
+
* updating `removedSpillKeys` / `spillRegions` as appropriate for its
|
|
366
|
+
* situation (this helper deliberately does not touch them since the
|
|
367
|
+
* three callsites have slightly different follow-up actions).
|
|
368
|
+
*/
|
|
369
|
+
function emitPreviousSpillCleanup(previousRegion, previousGhosts, snapshot, operations, sheetName, sheetId) {
|
|
370
|
+
const cleanupCells = collectStaleGhosts(previousRegion, previousGhosts, snapshot);
|
|
371
|
+
if (cleanupCells.length === 0) {
|
|
372
|
+
return;
|
|
373
|
+
}
|
|
374
|
+
operations.push({
|
|
375
|
+
type: "cleanup",
|
|
376
|
+
sheetName,
|
|
377
|
+
sheetId,
|
|
378
|
+
cells: cleanupCells
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
function isGhostUnmodified(cell, ghostKey, previousGhosts) {
|
|
382
|
+
if (!cell) {
|
|
383
|
+
return true;
|
|
384
|
+
}
|
|
385
|
+
if (cell.value === null) {
|
|
386
|
+
return true;
|
|
387
|
+
}
|
|
388
|
+
if (cell.formulaKind !== "none") {
|
|
389
|
+
return false;
|
|
390
|
+
}
|
|
391
|
+
const snapshot = previousGhosts.get(ghostKey);
|
|
392
|
+
if (snapshot === undefined) {
|
|
393
|
+
return true; // No snapshot — assume unmodified (conservative)
|
|
394
|
+
}
|
|
395
|
+
return snapshotValuesEqual(cell.value, snapshot);
|
|
396
|
+
}
|
|
397
|
+
/**
|
|
398
|
+
* Structural comparison for snapshot values.
|
|
399
|
+
* Handles error objects (which are reference types and fail `===` comparison)
|
|
400
|
+
* as well as primitives.
|
|
401
|
+
*/
|
|
402
|
+
function snapshotValuesEqual(a, b) {
|
|
403
|
+
if (a === b) {
|
|
404
|
+
return true;
|
|
405
|
+
}
|
|
406
|
+
// Both are error objects — compare by error code
|
|
407
|
+
if (a !== null &&
|
|
408
|
+
typeof a === "object" &&
|
|
409
|
+
"error" in a &&
|
|
410
|
+
b !== null &&
|
|
411
|
+
typeof b === "object" &&
|
|
412
|
+
"error" in b) {
|
|
413
|
+
return a.error === b.error;
|
|
414
|
+
}
|
|
415
|
+
return false;
|
|
416
|
+
}
|
|
417
|
+
function scalarFromResult(v) {
|
|
418
|
+
if (v.kind === 5 /* RVKind.Array */) {
|
|
419
|
+
if (v.height > 0 && v.width > 0) {
|
|
420
|
+
return v.rows[0][0];
|
|
421
|
+
}
|
|
422
|
+
return { kind: 0 /* RVKind.Blank */ };
|
|
423
|
+
}
|
|
424
|
+
if (v.kind === 0 /* RVKind.Blank */ ||
|
|
425
|
+
v.kind === 1 /* RVKind.Number */ ||
|
|
426
|
+
v.kind === 2 /* RVKind.String */ ||
|
|
427
|
+
v.kind === 3 /* RVKind.Boolean */ ||
|
|
428
|
+
v.kind === 4 /* RVKind.Error */) {
|
|
429
|
+
return v;
|
|
430
|
+
}
|
|
431
|
+
return { kind: 0 /* RVKind.Blank */ };
|
|
432
|
+
}
|
|
433
|
+
function runtimeToSnapshotValue(v) {
|
|
434
|
+
switch (v.kind) {
|
|
435
|
+
case 0 /* RVKind.Blank */:
|
|
436
|
+
return null;
|
|
437
|
+
case 1 /* RVKind.Number */:
|
|
438
|
+
// Boundary guard: never let NaN or ±Infinity leak into the
|
|
439
|
+
// persisted workbook. Either comes from arithmetic the per-
|
|
440
|
+
// function guards missed (for example extreme ROUND digit
|
|
441
|
+
// counts before the R6-P1-2 clamp). Convert to #NUM! here so
|
|
442
|
+
// downstream readers see a clean error instead of a stringified
|
|
443
|
+
// "NaN" / "Infinity" value. See R6 architectural note.
|
|
444
|
+
if (!Number.isFinite(v.value)) {
|
|
445
|
+
return { error: "#NUM!" };
|
|
446
|
+
}
|
|
447
|
+
return v.value;
|
|
448
|
+
case 2 /* RVKind.String */:
|
|
449
|
+
return v.value;
|
|
450
|
+
case 3 /* RVKind.Boolean */:
|
|
451
|
+
return v.value;
|
|
452
|
+
case 4 /* RVKind.Error */:
|
|
453
|
+
return { error: v.code };
|
|
454
|
+
case 5 /* RVKind.Array */:
|
|
455
|
+
// Take top-left
|
|
456
|
+
if (v.height > 0 && v.width > 0) {
|
|
457
|
+
return runtimeToSnapshotValue(v.rows[0][0]);
|
|
458
|
+
}
|
|
459
|
+
return null;
|
|
460
|
+
default:
|
|
461
|
+
return null;
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
function shouldPreserve(computed, inst, snapshot) {
|
|
465
|
+
if (computed.kind !== 4 /* RVKind.Error */ || computed.code !== "#NAME?") {
|
|
466
|
+
return false;
|
|
467
|
+
}
|
|
468
|
+
// Check if cell has a cached result in the snapshot
|
|
469
|
+
const ws = snapshot.worksheetsByName.get(inst.sheetName.toLowerCase());
|
|
470
|
+
if (!ws) {
|
|
471
|
+
return false;
|
|
472
|
+
}
|
|
473
|
+
const cell = ws.cells.get((0, workbook_snapshot_1.snapshotCellKey)(inst.row, inst.col));
|
|
474
|
+
return cell?.cachedResult !== undefined && cell.cachedResult !== null;
|
|
475
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Spill Engine — Persistent state management for dynamic array formulas.
|
|
4
|
+
*
|
|
5
|
+
* Manages persistent spill metadata that survives across
|
|
6
|
+
* `calculateFormulas()` invocations.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.getPersistentSpillMap = getPersistentSpillMap;
|
|
10
|
+
exports.getGhostSnapshots = getGhostSnapshots;
|
|
11
|
+
// ============================================================================
|
|
12
|
+
// Persistent State (WeakMap keyed by workbook — survives across invocations)
|
|
13
|
+
// ============================================================================
|
|
14
|
+
/**
|
|
15
|
+
* Persistent spill metadata: survives across calculateFormulas invocations.
|
|
16
|
+
* Key: "ws:<id>!row:col" of the source cell → SpillRegion.
|
|
17
|
+
* Stored in a WeakMap keyed by the workbook object to allow GC.
|
|
18
|
+
*/
|
|
19
|
+
const persistentSpillRegions = new WeakMap();
|
|
20
|
+
function getPersistentSpillMap(workbook) {
|
|
21
|
+
let map = persistentSpillRegions.get(workbook);
|
|
22
|
+
if (!map) {
|
|
23
|
+
map = new Map();
|
|
24
|
+
persistentSpillRegions.set(workbook, map);
|
|
25
|
+
}
|
|
26
|
+
return map;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Persistent snapshot of values written to ghost (spill target) cells.
|
|
30
|
+
* Key: ghost cell key "ws:<id>!row:col" → raw value written by spill.
|
|
31
|
+
* Used to detect whether a ghost cell has been modified by the user since
|
|
32
|
+
* the last calculation.
|
|
33
|
+
*/
|
|
34
|
+
const persistentGhostSnapshots = new WeakMap();
|
|
35
|
+
function getGhostSnapshots(workbook) {
|
|
36
|
+
let map = persistentGhostSnapshots.get(workbook);
|
|
37
|
+
if (!map) {
|
|
38
|
+
map = new Map();
|
|
39
|
+
persistentGhostSnapshots.set(workbook, map);
|
|
40
|
+
}
|
|
41
|
+
return map;
|
|
42
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Structural interfaces the formula engine consumes.
|
|
4
|
+
*
|
|
5
|
+
* The engine talks to these interfaces only — never to the concrete
|
|
6
|
+
* `Workbook` / `Worksheet` / `Cell` classes from the `excel` module. Any
|
|
7
|
+
* host that wants to drive the engine (including the Node/browser
|
|
8
|
+
* Workbook in `@excel/*`) must implement these shapes.
|
|
9
|
+
*
|
|
10
|
+
* This is what keeps the Layer 3 ↔ Layer 4 dependency one-way: the
|
|
11
|
+
* `excel` module imports from `formula`, never the reverse.
|
|
12
|
+
*/
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.CellValueTypeLike = void 0;
|
|
15
|
+
// ============================================================================
|
|
16
|
+
// ValueType — numeric mirror of `@excel/enums` ValueType
|
|
17
|
+
// ============================================================================
|
|
18
|
+
/**
|
|
19
|
+
* Numeric cell-type tag exposed by host cells. The engine only compares
|
|
20
|
+
* against `Null` and `Formula`; any other value is treated as a scalar
|
|
21
|
+
* literal.
|
|
22
|
+
*
|
|
23
|
+
* Kept as inline numeric literals (not an enum) so this file stays free
|
|
24
|
+
* of runtime dependencies. The `const` object and `type` alias share a
|
|
25
|
+
* name via TypeScript's declaration merging — the value form
|
|
26
|
+
* (`CellValueTypeLike.Null`, `CellValueTypeLike.Formula`) is used at
|
|
27
|
+
* comparison sites, the type form annotates `CellLike.type`.
|
|
28
|
+
*/
|
|
29
|
+
exports.CellValueTypeLike = {
|
|
30
|
+
Null: 0,
|
|
31
|
+
Formula: 6
|
|
32
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Writeback Plan — Declarative description of formula calculation results.
|
|
4
|
+
*
|
|
5
|
+
* The engine never directly mutates workbook cells. Instead, it produces a
|
|
6
|
+
* `WritebackPlan` — a list of write operations that describe what values
|
|
7
|
+
* should be written where. A thin adapter layer then applies the plan to
|
|
8
|
+
* the live workbook.
|
|
9
|
+
*
|
|
10
|
+
* ## Design Principles
|
|
11
|
+
*
|
|
12
|
+
* 1. **Declarative** — the plan describes *what* to write, not *how*.
|
|
13
|
+
* 2. **Deterministic** — #SPILL! conflicts are detected during plan
|
|
14
|
+
* construction, not during application.
|
|
15
|
+
* 3. **Ordered** — operations are applied in the order they appear.
|
|
16
|
+
* 4. **Independent** — each operation stands alone; the adapter does not
|
|
17
|
+
* need engine internals to apply the plan.
|
|
18
|
+
*
|
|
19
|
+
* ## Operation Types
|
|
20
|
+
*
|
|
21
|
+
* - `ScalarWrite` — write a single value to a formula cell's result.
|
|
22
|
+
* - `CSEWrite` — distribute an array across a CSE formula's target range.
|
|
23
|
+
* - `SpillWrite` — write a dynamic array result to adjacent cells (spill).
|
|
24
|
+
* - `SpillErrorWrite` — write #SPILL! to the source cell (conflict detected).
|
|
25
|
+
* - `CleanupWrite` — clear stale ghost cells from a previous spill.
|
|
26
|
+
* - `PreserveWrite` — keep the cell's existing cached result (unsupported fn).
|
|
27
|
+
*/
|
|
28
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|