@ricsam/formula-engine 0.2.8 → 0.2.10

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 (130) hide show
  1. package/README.md +41 -3
  2. package/dist/cjs/core/engine.cjs +551 -166
  3. package/dist/cjs/core/engine.cjs.map +3 -3
  4. package/dist/cjs/core/managers/dependency-manager.cjs +151 -67
  5. package/dist/cjs/core/managers/dependency-manager.cjs.map +3 -3
  6. package/dist/cjs/core/managers/evaluation-manager.cjs.map +1 -1
  7. package/dist/cjs/core/managers/workbook-manager.cjs +197 -1
  8. package/dist/cjs/core/managers/workbook-manager.cjs.map +3 -3
  9. package/dist/cjs/core/mutation-invalidation.cjs +241 -0
  10. package/dist/cjs/core/mutation-invalidation.cjs.map +10 -0
  11. package/dist/cjs/core/types.cjs.map +2 -2
  12. package/dist/cjs/core/workbook-renamer.cjs.map +1 -1
  13. package/dist/cjs/evaluator/formula-evaluator.cjs +22 -48
  14. package/dist/cjs/evaluator/formula-evaluator.cjs.map +3 -3
  15. package/dist/cjs/functions/math/sum/summation-utils.cjs +2 -2
  16. package/dist/cjs/functions/math/sum/summation-utils.cjs.map +2 -2
  17. package/dist/cjs/lib.cjs +2 -13
  18. package/dist/cjs/lib.cjs.map +3 -3
  19. package/dist/cjs/package.json +1 -1
  20. package/dist/cjs/parser/formatter.cjs +3 -4
  21. package/dist/cjs/parser/formatter.cjs.map +3 -3
  22. package/dist/cjs/parser/parser.cjs +24 -216
  23. package/dist/cjs/parser/parser.cjs.map +3 -3
  24. package/dist/mjs/core/engine.mjs +565 -207
  25. package/dist/mjs/core/engine.mjs.map +3 -3
  26. package/dist/mjs/core/managers/dependency-manager.mjs +151 -67
  27. package/dist/mjs/core/managers/dependency-manager.mjs.map +3 -3
  28. package/dist/mjs/core/managers/evaluation-manager.mjs.map +1 -1
  29. package/dist/mjs/core/managers/workbook-manager.mjs +197 -1
  30. package/dist/mjs/core/managers/workbook-manager.mjs.map +3 -3
  31. package/dist/mjs/core/mutation-invalidation.mjs +201 -0
  32. package/dist/mjs/core/mutation-invalidation.mjs.map +10 -0
  33. package/dist/mjs/core/types.mjs.map +2 -2
  34. package/dist/mjs/core/workbook-renamer.mjs.map +1 -1
  35. package/dist/mjs/evaluator/formula-evaluator.mjs +22 -48
  36. package/dist/mjs/evaluator/formula-evaluator.mjs.map +3 -3
  37. package/dist/mjs/functions/math/sum/summation-utils.mjs +2 -2
  38. package/dist/mjs/functions/math/sum/summation-utils.mjs.map +2 -2
  39. package/dist/mjs/lib.mjs +2 -13
  40. package/dist/mjs/lib.mjs.map +3 -3
  41. package/dist/mjs/package.json +1 -1
  42. package/dist/mjs/parser/formatter.mjs +3 -4
  43. package/dist/mjs/parser/formatter.mjs.map +3 -3
  44. package/dist/mjs/parser/parser.mjs +24 -216
  45. package/dist/mjs/parser/parser.mjs.map +3 -3
  46. package/dist/types/core/engine.d.ts +31 -135
  47. package/dist/types/core/managers/dependency-manager.d.ts +5 -1
  48. package/dist/types/core/managers/evaluation-manager.d.ts +1 -1
  49. package/dist/types/core/managers/workbook-manager.d.ts +23 -1
  50. package/dist/types/core/mutation-invalidation.d.ts +46 -0
  51. package/dist/types/core/types.d.ts +35 -0
  52. package/dist/types/lib.d.ts +0 -8
  53. package/dist/types/parser/parser.d.ts +4 -6
  54. package/package.json +1 -1
  55. package/dist/cjs/core/commands/command-executor.cjs +0 -149
  56. package/dist/cjs/core/commands/command-executor.cjs.map +0 -10
  57. package/dist/cjs/core/commands/content-commands.cjs +0 -857
  58. package/dist/cjs/core/commands/content-commands.cjs.map +0 -10
  59. package/dist/cjs/core/commands/metadata-commands.cjs +0 -160
  60. package/dist/cjs/core/commands/metadata-commands.cjs.map +0 -10
  61. package/dist/cjs/core/commands/named-expression-commands.cjs +0 -363
  62. package/dist/cjs/core/commands/named-expression-commands.cjs.map +0 -10
  63. package/dist/cjs/core/commands/structure-commands.cjs +0 -696
  64. package/dist/cjs/core/commands/structure-commands.cjs.map +0 -10
  65. package/dist/cjs/core/commands/style-commands.cjs +0 -229
  66. package/dist/cjs/core/commands/style-commands.cjs.map +0 -10
  67. package/dist/cjs/core/commands/table-commands.cjs +0 -495
  68. package/dist/cjs/core/commands/table-commands.cjs.map +0 -10
  69. package/dist/cjs/core/commands/types.cjs +0 -99
  70. package/dist/cjs/core/commands/types.cjs.map +0 -10
  71. package/dist/cjs/core/managers/schema-manager.cjs +0 -374
  72. package/dist/cjs/core/managers/schema-manager.cjs.map +0 -10
  73. package/dist/cjs/core/schema/cell-orm.cjs +0 -76
  74. package/dist/cjs/core/schema/cell-orm.cjs.map +0 -10
  75. package/dist/cjs/core/schema/grid-orm.cjs +0 -125
  76. package/dist/cjs/core/schema/grid-orm.cjs.map +0 -10
  77. package/dist/cjs/core/schema/schema-builder.cjs +0 -74
  78. package/dist/cjs/core/schema/schema-builder.cjs.map +0 -10
  79. package/dist/cjs/core/schema/schema-helpers.cjs +0 -200
  80. package/dist/cjs/core/schema/schema-helpers.cjs.map +0 -10
  81. package/dist/cjs/core/schema/schema.cjs +0 -91
  82. package/dist/cjs/core/schema/schema.cjs.map +0 -10
  83. package/dist/cjs/core/schema/table-orm.cjs +0 -189
  84. package/dist/cjs/core/schema/table-orm.cjs.map +0 -10
  85. package/dist/mjs/core/commands/command-executor.mjs +0 -109
  86. package/dist/mjs/core/commands/command-executor.mjs.map +0 -10
  87. package/dist/mjs/core/commands/content-commands.mjs +0 -821
  88. package/dist/mjs/core/commands/content-commands.mjs.map +0 -10
  89. package/dist/mjs/core/commands/metadata-commands.mjs +0 -120
  90. package/dist/mjs/core/commands/metadata-commands.mjs.map +0 -10
  91. package/dist/mjs/core/commands/named-expression-commands.mjs +0 -323
  92. package/dist/mjs/core/commands/named-expression-commands.mjs.map +0 -10
  93. package/dist/mjs/core/commands/structure-commands.mjs +0 -661
  94. package/dist/mjs/core/commands/structure-commands.mjs.map +0 -10
  95. package/dist/mjs/core/commands/style-commands.mjs +0 -189
  96. package/dist/mjs/core/commands/style-commands.mjs.map +0 -10
  97. package/dist/mjs/core/commands/table-commands.mjs +0 -459
  98. package/dist/mjs/core/commands/table-commands.mjs.map +0 -10
  99. package/dist/mjs/core/commands/types.mjs +0 -59
  100. package/dist/mjs/core/commands/types.mjs.map +0 -10
  101. package/dist/mjs/core/managers/schema-manager.mjs +0 -334
  102. package/dist/mjs/core/managers/schema-manager.mjs.map +0 -10
  103. package/dist/mjs/core/schema/cell-orm.mjs +0 -35
  104. package/dist/mjs/core/schema/cell-orm.mjs.map +0 -10
  105. package/dist/mjs/core/schema/grid-orm.mjs +0 -84
  106. package/dist/mjs/core/schema/grid-orm.mjs.map +0 -10
  107. package/dist/mjs/core/schema/schema-builder.mjs +0 -34
  108. package/dist/mjs/core/schema/schema-builder.mjs.map +0 -10
  109. package/dist/mjs/core/schema/schema-helpers.mjs +0 -160
  110. package/dist/mjs/core/schema/schema-helpers.mjs.map +0 -10
  111. package/dist/mjs/core/schema/schema.mjs +0 -51
  112. package/dist/mjs/core/schema/schema.mjs.map +0 -10
  113. package/dist/mjs/core/schema/table-orm.mjs +0 -156
  114. package/dist/mjs/core/schema/table-orm.mjs.map +0 -10
  115. package/dist/types/core/commands/command-executor.d.ts +0 -81
  116. package/dist/types/core/commands/content-commands.d.ts +0 -172
  117. package/dist/types/core/commands/metadata-commands.d.ts +0 -55
  118. package/dist/types/core/commands/named-expression-commands.d.ts +0 -130
  119. package/dist/types/core/commands/structure-commands.d.ts +0 -155
  120. package/dist/types/core/commands/style-commands.d.ts +0 -76
  121. package/dist/types/core/commands/table-commands.d.ts +0 -119
  122. package/dist/types/core/commands/types.d.ts +0 -143
  123. package/dist/types/core/managers/schema-manager.d.ts +0 -142
  124. package/dist/types/core/schema/cell-orm.d.ts +0 -33
  125. package/dist/types/core/schema/grid-orm.d.ts +0 -63
  126. package/dist/types/core/schema/schema-builder.d.ts +0 -16
  127. package/dist/types/core/schema/schema-helpers.d.ts +0 -49
  128. package/dist/types/core/schema/schema.d.ts +0 -167
  129. package/dist/types/core/schema/schema.type-test.d.ts +0 -1
  130. package/dist/types/core/schema/table-orm.d.ts +0 -46
@@ -52,6 +52,9 @@ class Parser {
52
52
  }
53
53
  if (token.type === "RBRACKET") {
54
54
  const nextToken = this.tokens.peekAhead(pos + 1);
55
+ if (nextToken?.type === "EXCLAMATION") {
56
+ return { isWorkbookReference: true };
57
+ }
55
58
  if (nextToken && nextToken.type === "IDENTIFIER") {
56
59
  let lookPos = pos + 2;
57
60
  while (lookPos < pos + 10) {
@@ -94,6 +97,10 @@ class Parser {
94
97
  }
95
98
  const workbookName = this.input.substring(workbookStartPos, workbookEndPos);
96
99
  this.tokens.consume();
100
+ if (this.tokens.match("EXCLAMATION")) {
101
+ this.tokens.consume();
102
+ return this.parseWorkbookQualifiedTableReference(workbookName, start);
103
+ }
97
104
  if (!this.tokens.match("IDENTIFIER")) {
98
105
  throw new ParseError("Expected sheet name after workbook reference", this.tokens.peek().position);
99
106
  }
@@ -156,6 +163,16 @@ class Parser {
156
163
  });
157
164
  }
158
165
  }
166
+ parseWorkbookQualifiedTableReference(workbookName, startPos) {
167
+ if (!this.tokens.match("IDENTIFIER")) {
168
+ throw new ParseError(`Expected table name after [${workbookName}]!`, this.tokens.peek().position);
169
+ }
170
+ const tableName = this.tokens.consume().value;
171
+ if (!this.tokens.match("LBRACKET")) {
172
+ throw new ParseError(`Workbook-qualified references without a sheet only support tables. Use [${workbookName}]!${tableName}[...] for tables or [${workbookName}]Sheet!A1 for sheet references`, this.tokens.peek().position);
173
+ }
174
+ return this.parseTableReference(tableName, startPos, { workbookName });
175
+ }
159
176
  parseBareColumnReference() {
160
177
  const startPos = this.tokens.peek().position.start;
161
178
  this.tokens.consume();
@@ -670,7 +687,8 @@ class Parser {
670
687
  sheetName: parsed.sheet
671
688
  });
672
689
  }
673
- parseTableReference(tableName, startPos) {
690
+ parseTableReference(tableName, startPos, qualifiers) {
691
+ const { sheetName, workbookName } = qualifiers ?? {};
674
692
  this.tokens.consume();
675
693
  let selector;
676
694
  let cols;
@@ -868,6 +886,8 @@ class Parser {
868
886
  }
869
887
  return createStructuredReferenceNode({
870
888
  tableName,
889
+ sheetName,
890
+ workbookName,
871
891
  cols,
872
892
  selector,
873
893
  isCurrentRow,
@@ -878,212 +898,7 @@ class Parser {
878
898
  });
879
899
  }
880
900
  parseTableReferenceWithSheet(tableName, sheetName, startPos) {
881
- this.tokens.consume();
882
- let selector;
883
- let cols;
884
- let isCurrentRow = false;
885
- if (this.tokens.match("LBRACKET")) {
886
- this.tokens.consume();
887
- if (this.tokens.match("HASH")) {
888
- this.tokens.consume();
889
- if (!this.tokens.match("IDENTIFIER")) {
890
- throw new ParseError("Expected selector name after #", this.tokens.peek().position);
891
- }
892
- const selectorName = this.tokens.consume().value;
893
- selector = `#${selectorName}`;
894
- if (!this.tokens.match("RBRACKET")) {
895
- throw new ParseError("Expected ] after selector", this.tokens.peek().position);
896
- }
897
- this.tokens.consume();
898
- if (this.tokens.match("COMMA")) {
899
- this.tokens.consume();
900
- if (!this.tokens.match("LBRACKET")) {
901
- throw new ParseError("Expected [ after comma", this.tokens.peek().position);
902
- }
903
- this.tokens.consume();
904
- if (!this.tokens.match("IDENTIFIER") && !this.tokens.match("FUNCTION") && !this.tokens.match("NUMBER") && !this.tokens.match("OPERATOR")) {
905
- throw new ParseError("Expected column name", this.tokens.peek().position);
906
- }
907
- const colStart = this.parseColumnName();
908
- if (this.tokens.match("COLON") && !this.tokens.peekAhead(1)?.type.match(/RBRACKET/)) {
909
- this.tokens.consume();
910
- if (!this.tokens.match("IDENTIFIER") && !this.tokens.match("FUNCTION") && !this.tokens.match("NUMBER") && !this.tokens.match("OPERATOR")) {
911
- throw new ParseError("Expected end column name after :", this.tokens.peek().position);
912
- }
913
- const colEnd = this.parseColumnName();
914
- cols = {
915
- startCol: colStart,
916
- endCol: colEnd
917
- };
918
- } else {
919
- cols = {
920
- startCol: colStart,
921
- endCol: colStart
922
- };
923
- }
924
- if (!this.tokens.match("RBRACKET")) {
925
- throw new ParseError("Expected ] after column specification", this.tokens.peek().position);
926
- }
927
- this.tokens.consume();
928
- if (this.tokens.match("COLON")) {
929
- this.tokens.consume();
930
- if (!this.tokens.match("LBRACKET")) {
931
- throw new ParseError("Expected [ after : in column range", this.tokens.peek().position);
932
- }
933
- this.tokens.consume();
934
- if (!this.tokens.match("IDENTIFIER") && !this.tokens.match("FUNCTION") && !this.tokens.match("NUMBER") && !this.tokens.match("OPERATOR")) {
935
- throw new ParseError("Expected end column name", this.tokens.peek().position);
936
- }
937
- const colEnd = this.parseColumnName();
938
- if (!this.tokens.match("RBRACKET")) {
939
- throw new ParseError("Expected ] after end column name", this.tokens.peek().position);
940
- }
941
- this.tokens.consume();
942
- cols = {
943
- startCol: colStart,
944
- endCol: colEnd
945
- };
946
- }
947
- }
948
- if (!this.tokens.match("RBRACKET")) {
949
- throw new ParseError("Expected ] to close table reference", this.tokens.peek().position);
950
- }
951
- this.tokens.consume();
952
- } else if (this.tokens.match("IDENTIFIER") || this.tokens.match("FUNCTION") || this.tokens.match("NUMBER") || this.tokens.match("OPERATOR")) {
953
- const colStart = this.parseColumnName();
954
- if (!this.tokens.match("RBRACKET")) {
955
- throw new ParseError("Expected ] after column name", this.tokens.peek().position);
956
- }
957
- this.tokens.consume();
958
- if (this.tokens.match("COLON")) {
959
- this.tokens.consume();
960
- if (!this.tokens.match("LBRACKET")) {
961
- throw new ParseError("Expected [ before second column name", this.tokens.peek().position);
962
- }
963
- this.tokens.consume();
964
- const colEnd = this.parseColumnName();
965
- if (!this.tokens.match("RBRACKET")) {
966
- throw new ParseError("Expected ] after second column name", this.tokens.peek().position);
967
- }
968
- this.tokens.consume();
969
- if (!this.tokens.match("RBRACKET")) {
970
- throw new ParseError("Expected ] to close table reference", this.tokens.peek().position);
971
- }
972
- this.tokens.consume();
973
- cols = {
974
- startCol: colStart,
975
- endCol: colEnd
976
- };
977
- } else {
978
- if (!this.tokens.match("RBRACKET")) {
979
- throw new ParseError("Expected ] to close table reference", this.tokens.peek().position);
980
- }
981
- this.tokens.consume();
982
- cols = {
983
- startCol: colStart,
984
- endCol: colStart
985
- };
986
- }
987
- }
988
- } else if (this.tokens.match("AT")) {
989
- this.tokens.consume();
990
- isCurrentRow = true;
991
- if (this.tokens.match("LBRACKET")) {
992
- this.tokens.consume();
993
- const colStart = this.parseColumnName();
994
- if (!this.tokens.match("RBRACKET")) {
995
- throw new ParseError("Expected ] after column name", this.tokens.peek().position);
996
- }
997
- this.tokens.consume();
998
- if (this.tokens.match("COLON")) {
999
- this.tokens.consume();
1000
- if (!this.tokens.match("LBRACKET")) {
1001
- throw new ParseError("Expected [ before second column name", this.tokens.peek().position);
1002
- }
1003
- this.tokens.consume();
1004
- const colEnd = this.parseColumnName();
1005
- if (!this.tokens.match("RBRACKET")) {
1006
- throw new ParseError("Expected ] after second column name", this.tokens.peek().position);
1007
- }
1008
- this.tokens.consume();
1009
- cols = {
1010
- startCol: colStart,
1011
- endCol: colEnd
1012
- };
1013
- } else {
1014
- cols = {
1015
- startCol: colStart,
1016
- endCol: colStart
1017
- };
1018
- }
1019
- if (!this.tokens.match("RBRACKET")) {
1020
- throw new ParseError("Expected ] to close table reference", this.tokens.peek().position);
1021
- }
1022
- this.tokens.consume();
1023
- } else {
1024
- const colStart = this.parseColumnName();
1025
- if (this.tokens.match("COLON")) {
1026
- this.tokens.consume();
1027
- const colEnd = this.parseColumnName();
1028
- cols = {
1029
- startCol: colStart,
1030
- endCol: colEnd
1031
- };
1032
- } else {
1033
- cols = {
1034
- startCol: colStart,
1035
- endCol: colStart
1036
- };
1037
- }
1038
- if (!this.tokens.match("RBRACKET")) {
1039
- throw new ParseError("Expected ] after column reference", this.tokens.peek().position);
1040
- }
1041
- this.tokens.consume();
1042
- }
1043
- } else if (this.tokens.match("IDENTIFIER") || this.tokens.match("FUNCTION") || this.tokens.match("NUMBER") || this.tokens.match("OPERATOR")) {
1044
- const colStart = this.parseColumnName();
1045
- if (this.tokens.match("COLON")) {
1046
- this.tokens.consume();
1047
- const colEnd = this.parseColumnName();
1048
- cols = {
1049
- startCol: colStart,
1050
- endCol: colEnd
1051
- };
1052
- } else {
1053
- cols = {
1054
- startCol: colStart,
1055
- endCol: colStart
1056
- };
1057
- }
1058
- if (!this.tokens.match("RBRACKET")) {
1059
- throw new ParseError("Expected ] after column name", this.tokens.peek().position);
1060
- }
1061
- this.tokens.consume();
1062
- } else if (this.tokens.match("HASH")) {
1063
- this.tokens.consume();
1064
- if (!this.tokens.match("IDENTIFIER")) {
1065
- throw new ParseError("Expected selector name after #", this.tokens.peek().position);
1066
- }
1067
- const selectorName = this.tokens.consume().value;
1068
- selector = `#${selectorName}`;
1069
- if (!this.tokens.match("RBRACKET")) {
1070
- throw new ParseError("Expected ] after selector", this.tokens.peek().position);
1071
- }
1072
- this.tokens.consume();
1073
- } else {
1074
- throw new ParseError("Expected column name or selector in table reference", this.tokens.peek().position);
1075
- }
1076
- return createStructuredReferenceNode({
1077
- tableName,
1078
- sheetName,
1079
- cols,
1080
- selector,
1081
- isCurrentRow,
1082
- position: {
1083
- start: startPos,
1084
- end: this.tokens.peek().position?.end ?? 0
1085
- }
1086
- });
901
+ return this.parseTableReference(tableName, startPos, { sheetName });
1087
902
  }
1088
903
  parseCellOrRangeAfterSheets() {
1089
904
  const start = this.tokens.peek().position?.start ?? 0;
@@ -1257,13 +1072,6 @@ class Parser {
1257
1072
  rangeNode.workbookName = workbookName;
1258
1073
  return rangeNode;
1259
1074
  }
1260
- parseTableReferenceWithWorkbookAndSheet(tableName, workbookName, sheetName, startPos) {
1261
- const tableRef = this.parseTableReferenceWithSheet(tableName, sheetName, startPos);
1262
- if (tableRef.type === "structured-reference") {
1263
- tableRef.workbookName = workbookName;
1264
- }
1265
- return tableRef;
1266
- }
1267
1075
  parseRange(startRef, endRef, startPos, endPos) {
1268
1076
  let fullRange = `${startRef}:${endRef}`;
1269
1077
  let sheetName;
@@ -1575,7 +1383,7 @@ class Parser {
1575
1383
  const identifier2 = this.tokens.consume();
1576
1384
  ref += identifier2.value;
1577
1385
  if (this.tokens.match("LBRACKET")) {
1578
- return this.parseTableReferenceWithWorkbookAndSheet(identifier2.value, workbookName, sheetName, startPos);
1386
+ throw new ParseError(`Cross-workbook table references use [${workbookName}]!${identifier2.value}[...] instead of [${workbookName}]${sheetName}!${identifier2.value}[...]`, this.tokens.peek().position);
1579
1387
  }
1580
1388
  if (this.tokens.match("COLON")) {
1581
1389
  this.tokens.consume();
@@ -1689,4 +1497,4 @@ export {
1689
1497
  ParseError
1690
1498
  };
1691
1499
 
1692
- //# debugId=A96B29CE76343DE364756E2164756E21
1500
+ //# debugId=E7749E5263A4F26E64756E2164756E21