@1771technologies/lytenyte-pro 2.0.4-dev.3 → 2.0.4-dev.4

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 (175) hide show
  1. package/css/components/expression-editor.css +105 -0
  2. package/dist/components/column-manager/column-manager.d.ts +6 -1
  3. package/dist/components/column-manager/column-manager.js +23 -2
  4. package/dist/components/expressions-editor/(expressions)/expression.play.d.ts +4 -0
  5. package/dist/components/expressions-editor/(expressions)/expression.play.js +69 -0
  6. package/dist/components/expressions-editor/create-completion-provider.d.ts +3 -0
  7. package/dist/components/expressions-editor/create-completion-provider.js +161 -0
  8. package/dist/components/expressions-editor/create-key-down-handler.d.ts +18 -0
  9. package/dist/components/expressions-editor/create-key-down-handler.js +49 -0
  10. package/dist/components/expressions-editor/cursor-position/measure-cursor-at-pointer.d.ts +2 -0
  11. package/dist/components/expressions-editor/cursor-position/measure-cursor-at-pointer.js +56 -0
  12. package/dist/components/expressions-editor/cursor-position/use-cursor-position.d.ts +5 -0
  13. package/dist/components/expressions-editor/cursor-position/use-cursor-position.js +17 -0
  14. package/dist/components/expressions-editor/expression-editor.d.ts +3 -0
  15. package/dist/components/expressions-editor/expression-editor.js +138 -0
  16. package/dist/components/expressions-editor/get-indentation.d.ts +1 -0
  17. package/dist/components/expressions-editor/get-indentation.js +7 -0
  18. package/dist/components/expressions-editor/handle-completion-key-down.d.ts +2 -0
  19. package/dist/components/expressions-editor/handle-completion-key-down.js +22 -0
  20. package/dist/components/expressions-editor/handle-enter-key.d.ts +4 -0
  21. package/dist/components/expressions-editor/handle-enter-key.js +11 -0
  22. package/dist/components/expressions-editor/handle-manual-trigger.d.ts +2 -0
  23. package/dist/components/expressions-editor/handle-manual-trigger.js +3 -0
  24. package/dist/components/expressions-editor/index.d.ts +17 -0
  25. package/dist/components/expressions-editor/index.js +11 -0
  26. package/dist/components/expressions-editor/intellisence/completion-context.d.ts +16 -0
  27. package/dist/components/expressions-editor/intellisence/completion-context.js +7 -0
  28. package/dist/components/expressions-editor/intellisence/completion-item.d.ts +5 -0
  29. package/dist/components/expressions-editor/intellisence/completion-item.js +11 -0
  30. package/dist/components/expressions-editor/intellisence/completion-list.d.ts +8 -0
  31. package/dist/components/expressions-editor/intellisence/completion-list.js +18 -0
  32. package/dist/components/expressions-editor/intellisence/completion-popover.d.ts +1 -0
  33. package/dist/components/expressions-editor/intellisence/completion-popover.js +30 -0
  34. package/dist/components/expressions-editor/intellisence/filter-completions-by-prefix.d.ts +2 -0
  35. package/dist/components/expressions-editor/intellisence/filter-completions-by-prefix.js +6 -0
  36. package/dist/components/expressions-editor/intellisence/get-word-at-cursor.d.ts +2 -0
  37. package/dist/components/expressions-editor/intellisence/get-word-at-cursor.js +12 -0
  38. package/dist/components/expressions-editor/intellisence/use-complete-trigger.d.ts +13 -0
  39. package/dist/components/expressions-editor/intellisence/use-complete-trigger.js +41 -0
  40. package/dist/components/expressions-editor/intellisence/use-completions.d.ts +14 -0
  41. package/dist/components/expressions-editor/intellisence/use-completions.js +78 -0
  42. package/dist/components/expressions-editor/replace-word-at-cursor.d.ts +5 -0
  43. package/dist/components/expressions-editor/replace-word-at-cursor.js +7 -0
  44. package/dist/components/expressions-editor/token-highlighter-default.d.ts +4 -0
  45. package/dist/components/expressions-editor/token-highlighter-default.js +18 -0
  46. package/dist/components/expressions-editor/types.d.ts +47 -0
  47. package/dist/components/expressions-editor/types.js +1 -0
  48. package/dist/components/expressions-editor/use-keyboard-navigation.d.ts +10 -0
  49. package/dist/components/expressions-editor/use-keyboard-navigation.js +16 -0
  50. package/dist/components/pill-manager/container.js +55 -9
  51. package/dist/components/pill-manager/item.js +15 -1
  52. package/dist/components/select-all.js +1 -1
  53. package/dist/components/tree-view/root.d.ts +9 -0
  54. package/dist/components/tree-view/root.js +4 -2
  55. package/dist/data-source-client/hooks/use-flattened-groups.js +2 -2
  56. package/dist/expressions/compiler/compile.d.ts +3 -0
  57. package/dist/expressions/compiler/compile.js +4 -0
  58. package/dist/expressions/compiler/eval-constant.d.ts +2 -0
  59. package/dist/expressions/compiler/eval-constant.js +19 -0
  60. package/dist/expressions/compiler/is-constant.d.ts +2 -0
  61. package/dist/expressions/compiler/is-constant.js +6 -0
  62. package/dist/expressions/compiler/make-constant.d.ts +2 -0
  63. package/dist/expressions/compiler/make-constant.js +11 -0
  64. package/dist/expressions/compiler/optimize.d.ts +3 -0
  65. package/dist/expressions/compiler/optimize.js +47 -0
  66. package/dist/expressions/compiler/value-of.d.ts +2 -0
  67. package/dist/expressions/compiler/value-of.js +11 -0
  68. package/dist/expressions/errors/clamp-offset.d.ts +1 -0
  69. package/dist/expressions/errors/clamp-offset.js +3 -0
  70. package/dist/expressions/errors/expression-error.d.ts +10 -0
  71. package/dist/expressions/errors/expression-error.js +19 -0
  72. package/dist/expressions/errors/format-error.d.ts +3 -0
  73. package/dist/expressions/errors/format-error.js +27 -0
  74. package/dist/expressions/errors/get-line-end.d.ts +1 -0
  75. package/dist/expressions/errors/get-line-end.js +8 -0
  76. package/dist/expressions/errors/get-line-start.d.ts +1 -0
  77. package/dist/expressions/errors/get-line-start.js +8 -0
  78. package/dist/expressions/errors/index.d.ts +7 -0
  79. package/dist/expressions/errors/index.js +6 -0
  80. package/dist/expressions/errors/offset-to-position.d.ts +2 -0
  81. package/dist/expressions/errors/offset-to-position.js +17 -0
  82. package/dist/expressions/errors/types.d.ts +10 -0
  83. package/dist/expressions/errors/types.js +1 -0
  84. package/dist/expressions/evaluator/evaluate-binary.d.ts +4 -0
  85. package/dist/expressions/evaluator/evaluate-binary.js +21 -0
  86. package/dist/expressions/evaluator/evaluate-unary.d.ts +2 -0
  87. package/dist/expressions/evaluator/evaluate-unary.js +10 -0
  88. package/dist/expressions/evaluator/evaluate.d.ts +15 -0
  89. package/dist/expressions/evaluator/evaluate.js +62 -0
  90. package/dist/expressions/index.d.ts +5 -0
  91. package/dist/expressions/index.js +3 -0
  92. package/dist/expressions/lexer/predicates/is-alpha-numeric.d.ts +1 -0
  93. package/dist/expressions/lexer/predicates/is-alpha-numeric.js +5 -0
  94. package/dist/expressions/lexer/predicates/is-alpha.d.ts +1 -0
  95. package/dist/expressions/lexer/predicates/is-alpha.js +3 -0
  96. package/dist/expressions/lexer/predicates/is-binary-digit.d.ts +1 -0
  97. package/dist/expressions/lexer/predicates/is-binary-digit.js +3 -0
  98. package/dist/expressions/lexer/predicates/is-digit.d.ts +1 -0
  99. package/dist/expressions/lexer/predicates/is-digit.js +3 -0
  100. package/dist/expressions/lexer/predicates/is-hex-digit.d.ts +1 -0
  101. package/dist/expressions/lexer/predicates/is-hex-digit.js +4 -0
  102. package/dist/expressions/lexer/predicates/is-octal-digit.d.ts +1 -0
  103. package/dist/expressions/lexer/predicates/is-octal-digit.js +3 -0
  104. package/dist/expressions/lexer/tokenize/consume-digits.d.ts +1 -0
  105. package/dist/expressions/lexer/tokenize/consume-digits.js +5 -0
  106. package/dist/expressions/lexer/tokenize/scan-identifier.d.ts +6 -0
  107. package/dist/expressions/lexer/tokenize/scan-identifier.js +20 -0
  108. package/dist/expressions/lexer/tokenize/scan-number.d.ts +4 -0
  109. package/dist/expressions/lexer/tokenize/scan-number.js +32 -0
  110. package/dist/expressions/lexer/tokenize/scan-operator.d.ts +6 -0
  111. package/dist/expressions/lexer/tokenize/scan-operator.js +71 -0
  112. package/dist/expressions/lexer/tokenize/scan-string-literal.d.ts +4 -0
  113. package/dist/expressions/lexer/tokenize/scan-string-literal.js +22 -0
  114. package/dist/expressions/lexer/tokenize/scan-string.d.ts +4 -0
  115. package/dist/expressions/lexer/tokenize/scan-string.js +98 -0
  116. package/dist/expressions/lexer/tokenize/scan-template-literal.d.ts +4 -0
  117. package/dist/expressions/lexer/tokenize/scan-template-literal.js +51 -0
  118. package/dist/expressions/lexer/tokenize/tokenize.d.ts +4 -0
  119. package/dist/expressions/lexer/tokenize/tokenize.js +99 -0
  120. package/dist/expressions/lexer/types.d.ts +12 -0
  121. package/dist/expressions/lexer/types.js +1 -0
  122. package/dist/expressions/parser/parse-array-literal.d.ts +3 -0
  123. package/dist/expressions/parser/parse-array-literal.js +15 -0
  124. package/dist/expressions/parser/parse-expression.d.ts +3 -0
  125. package/dist/expressions/parser/parse-expression.js +74 -0
  126. package/dist/expressions/parser/parse-object-literal.d.ts +3 -0
  127. package/dist/expressions/parser/parse-object-literal.js +69 -0
  128. package/dist/expressions/parser/parse-pipe-transform.d.ts +3 -0
  129. package/dist/expressions/parser/parse-pipe-transform.js +26 -0
  130. package/dist/expressions/parser/parse-postfix.d.ts +3 -0
  131. package/dist/expressions/parser/parse-postfix.js +23 -0
  132. package/dist/expressions/parser/parse-primary.d.ts +3 -0
  133. package/dist/expressions/parser/parse-primary.js +35 -0
  134. package/dist/expressions/parser/parse-template-literal.d.ts +3 -0
  135. package/dist/expressions/parser/parse-template-literal.js +41 -0
  136. package/dist/expressions/parser/parse-unary.d.ts +3 -0
  137. package/dist/expressions/parser/parse-unary.js +28 -0
  138. package/dist/expressions/parser/parse.d.ts +3 -0
  139. package/dist/expressions/parser/parse.js +26 -0
  140. package/dist/expressions/parser/parser-context.d.ts +12 -0
  141. package/dist/expressions/parser/parser-context.js +14 -0
  142. package/dist/expressions/parser/precedence.d.ts +1 -0
  143. package/dist/expressions/parser/precedence.js +8 -0
  144. package/dist/expressions/parser/types.d.ts +97 -0
  145. package/dist/expressions/parser/types.js +1 -0
  146. package/dist/expressions/plugin.d.ts +20 -0
  147. package/dist/expressions/plugin.js +1 -0
  148. package/dist/expressions/plugins/access.d.ts +2 -0
  149. package/dist/expressions/plugins/access.js +138 -0
  150. package/dist/expressions/plugins/arrows.d.ts +2 -0
  151. package/dist/expressions/plugins/arrows.js +83 -0
  152. package/dist/expressions/plugins/booleans.d.ts +2 -0
  153. package/dist/expressions/plugins/booleans.js +34 -0
  154. package/dist/expressions/plugins/collections.d.ts +2 -0
  155. package/dist/expressions/plugins/collections.js +70 -0
  156. package/dist/expressions/plugins/comparison.d.ts +2 -0
  157. package/dist/expressions/plugins/comparison.js +51 -0
  158. package/dist/expressions/plugins/logical.d.ts +2 -0
  159. package/dist/expressions/plugins/logical.js +103 -0
  160. package/dist/expressions/plugins/membership.d.ts +2 -0
  161. package/dist/expressions/plugins/membership.js +71 -0
  162. package/dist/expressions/plugins/pipe.d.ts +2 -0
  163. package/dist/expressions/plugins/pipe.js +57 -0
  164. package/dist/expressions/plugins/resolved-identifier.d.ts +5 -0
  165. package/dist/expressions/plugins/resolved-identifier.js +19 -0
  166. package/dist/expressions/plugins/standard.d.ts +13 -0
  167. package/dist/expressions/plugins/standard.js +23 -0
  168. package/dist/expressions/plugins/strings.d.ts +2 -0
  169. package/dist/expressions/plugins/strings.js +44 -0
  170. package/dist/expressions/plugins/ternary.d.ts +2 -0
  171. package/dist/expressions/plugins/ternary.js +58 -0
  172. package/dist/expressions.d.ts +2 -0
  173. package/dist/expressions.js +2 -0
  174. package/dist/index.d.ts +1 -0
  175. package/package.json +11 -5
@@ -0,0 +1,3 @@
1
+ export { Evaluator } from "./evaluator/evaluate.js";
2
+ export { accessPlugin, arrowsPlugin, booleansPlugin, collectionsPlugin, comparisonPlugin, logicalPlugin, membershipPlugin, pipePlugin, standardPlugins, stringsPlugin, ternaryPlugin, } from "./plugins/standard.js";
3
+ export { createResolvedIdentifierPlugin } from "./plugins/resolved-identifier.js";
@@ -0,0 +1 @@
1
+ export declare function isAlphaNumeric(ch: string): boolean;
@@ -0,0 +1,5 @@
1
+ import { isAlpha } from "./is-alpha.js";
2
+ import { isDigit } from "./is-digit.js";
3
+ export function isAlphaNumeric(ch) {
4
+ return isAlpha(ch) || isDigit(ch);
5
+ }
@@ -0,0 +1 @@
1
+ export declare function isAlpha(ch: string): boolean;
@@ -0,0 +1,3 @@
1
+ export function isAlpha(ch) {
2
+ return (ch >= "a" && ch <= "z") || (ch >= "A" && ch <= "Z") || ch === "_" || ch === "$";
3
+ }
@@ -0,0 +1 @@
1
+ export declare function isBinaryDigit(ch: string): ch is "0" | "1";
@@ -0,0 +1,3 @@
1
+ export function isBinaryDigit(ch) {
2
+ return ch === "0" || ch === "1";
3
+ }
@@ -0,0 +1 @@
1
+ export declare function isDigit(ch: string): boolean;
@@ -0,0 +1,3 @@
1
+ export function isDigit(ch) {
2
+ return ch >= "0" && ch <= "9";
3
+ }
@@ -0,0 +1 @@
1
+ export declare function isHexDigit(ch: string): boolean;
@@ -0,0 +1,4 @@
1
+ import { isDigit } from "./is-digit.js";
2
+ export function isHexDigit(ch) {
3
+ return isDigit(ch) || (ch >= "a" && ch <= "f") || (ch >= "A" && ch <= "F");
4
+ }
@@ -0,0 +1 @@
1
+ export declare function isOctalDigit(ch: string): boolean;
@@ -0,0 +1,3 @@
1
+ export function isOctalDigit(ch) {
2
+ return ch >= "0" && ch <= "7";
3
+ }
@@ -0,0 +1 @@
1
+ export declare function consumeDigits(source: string, pos: number, predicate: (ch: string) => boolean): number;
@@ -0,0 +1,5 @@
1
+ export function consumeDigits(source, pos, predicate) {
2
+ while (pos < source.length && (predicate(source[pos]) || source[pos] === "_"))
3
+ pos++;
4
+ return pos;
5
+ }
@@ -0,0 +1,6 @@
1
+ import type { Token } from "../types.js";
2
+ export declare function scanIdentifier(source: string, start: number): {
3
+ type: Token["type"];
4
+ value: string;
5
+ end: number;
6
+ };
@@ -0,0 +1,20 @@
1
+ import { isAlphaNumeric } from "../predicates/is-alpha-numeric.js";
2
+ const KEYWORDS = new Map([
3
+ ["true", { type: "Boolean", value: "true" }],
4
+ ["false", { type: "Boolean", value: "false" }],
5
+ ["null", { type: "Null", value: "null" }],
6
+ ["undefined", { type: "Undefined", value: "undefined" }],
7
+ ["in", { type: "Operator", value: "in" }],
8
+ ["not", { type: "Operator", value: "not" }],
9
+ ]);
10
+ export function scanIdentifier(source, start) {
11
+ let i = start;
12
+ while (i < source.length && isAlphaNumeric(source[i]))
13
+ i++;
14
+ const value = source.slice(start, i);
15
+ const kw = KEYWORDS.get(value);
16
+ if (kw) {
17
+ return { type: kw.type, value: kw.value, end: i };
18
+ }
19
+ return { type: "Identifier", value, end: i };
20
+ }
@@ -0,0 +1,4 @@
1
+ export declare function scanNumber(source: string, start: number): {
2
+ value: string;
3
+ end: number;
4
+ };
@@ -0,0 +1,32 @@
1
+ import { isDigit } from "../predicates/is-digit.js";
2
+ import { isHexDigit } from "../predicates/is-hex-digit.js";
3
+ import { isOctalDigit } from "../predicates/is-octal-digit.js";
4
+ import { isBinaryDigit } from "../predicates/is-binary-digit.js";
5
+ import { consumeDigits } from "./consume-digits.js";
6
+ export function scanNumber(source, start) {
7
+ const ch = source[start];
8
+ const next = source[start + 1];
9
+ let i = start;
10
+ if (ch === "0" && (next === "x" || next === "X")) {
11
+ i = consumeDigits(source, i + 2, isHexDigit);
12
+ }
13
+ else if (ch === "0" && (next === "o" || next === "O")) {
14
+ i = consumeDigits(source, i + 2, isOctalDigit);
15
+ }
16
+ else if (ch === "0" && (next === "b" || next === "B")) {
17
+ i = consumeDigits(source, i + 2, isBinaryDigit);
18
+ }
19
+ else {
20
+ i = consumeDigits(source, i, isDigit);
21
+ if (i < source.length && source[i] === "." && i + 1 < source.length && isDigit(source[i + 1])) {
22
+ i = consumeDigits(source, i + 1, isDigit);
23
+ }
24
+ if (i < source.length && (source[i] === "e" || source[i] === "E")) {
25
+ i++;
26
+ if (i < source.length && (source[i] === "+" || source[i] === "-"))
27
+ i++;
28
+ i = consumeDigits(source, i, isDigit);
29
+ }
30
+ }
31
+ return { value: source.slice(start, i), end: i };
32
+ }
@@ -0,0 +1,6 @@
1
+ import type { Token } from "../types.js";
2
+ export declare function scanOperator(source: string, start: number): {
3
+ type: Token["type"];
4
+ value: string;
5
+ end: number;
6
+ };
@@ -0,0 +1,71 @@
1
+ import { ExpressionError } from "../../errors/index.js";
2
+ export function scanOperator(source, start) {
3
+ const ch = source[start];
4
+ const next = start + 1 < source.length ? source[start + 1] : "";
5
+ // Spread operator ...
6
+ if (ch === "." && next === "." && start + 2 < source.length && source[start + 2] === ".") {
7
+ return { type: "Spread", value: "...", end: start + 3 };
8
+ }
9
+ // Dot (punctuation)
10
+ if (ch === ".") {
11
+ return { type: "Punctuation", value: ".", end: start + 1 };
12
+ }
13
+ // Pipe |> or logical ||
14
+ if (ch === "|" && next === ">") {
15
+ return { type: "Pipe", value: "|>", end: start + 2 };
16
+ }
17
+ if (ch === "|" && next === "|") {
18
+ return { type: "Operator", value: "||", end: start + 2 };
19
+ }
20
+ // &&
21
+ if (ch === "&" && next === "&") {
22
+ return { type: "Operator", value: "&&", end: start + 2 };
23
+ }
24
+ // => (arrow)
25
+ if (ch === "=" && next === ">") {
26
+ return { type: "Arrow", value: "=>", end: start + 2 };
27
+ }
28
+ // == !=
29
+ if (ch === "=" && next === "=") {
30
+ return { type: "Operator", value: "==", end: start + 2 };
31
+ }
32
+ if (ch === "!" && next === "=") {
33
+ return { type: "Operator", value: "!=", end: start + 2 };
34
+ }
35
+ // ! (logical not) - must come after != check
36
+ if (ch === "!") {
37
+ return { type: "Operator", value: "!", end: start + 1 };
38
+ }
39
+ // <= >= < >
40
+ if (ch === "<") {
41
+ if (next === "=")
42
+ return { type: "Operator", value: "<=", end: start + 2 };
43
+ return { type: "Operator", value: "<", end: start + 1 };
44
+ }
45
+ if (ch === ">") {
46
+ if (next === "=")
47
+ return { type: "Operator", value: ">=", end: start + 2 };
48
+ return { type: "Operator", value: ">", end: start + 1 };
49
+ }
50
+ // ** (exponentiation) — must come before single *
51
+ if (ch === "*" && next === "*") {
52
+ return { type: "Operator", value: "**", end: start + 2 };
53
+ }
54
+ // ?. (optional chaining) or ?? (nullish coalescing) or ? (ternary)
55
+ if (ch === "?") {
56
+ if (next === ".")
57
+ return { type: "OptionalChain", value: "?.", end: start + 2 };
58
+ if (next === "?")
59
+ return { type: "NullishCoalescing", value: "??", end: start + 2 };
60
+ return { type: "Punctuation", value: "?", end: start + 1 };
61
+ }
62
+ // Single-character operators
63
+ if (ch === "+" || ch === "-" || ch === "*" || ch === "/" || ch === "%") {
64
+ return { type: "Operator", value: ch, end: start + 1 };
65
+ }
66
+ // Punctuation
67
+ if ("()[]{},:".includes(ch)) {
68
+ return { type: "Punctuation", value: ch, end: start + 1 };
69
+ }
70
+ throw new ExpressionError(`Unexpected character "${ch}"`, { source, start, end: start + 1 });
71
+ }
@@ -0,0 +1,4 @@
1
+ export declare function scanStringLiteral(source: string, start: number): {
2
+ raw: string;
3
+ end: number;
4
+ };
@@ -0,0 +1,22 @@
1
+ import { ExpressionError } from "../../errors/index.js";
2
+ export function scanStringLiteral(source, start) {
3
+ const quote = source[start];
4
+ let raw = quote;
5
+ let i = start + 1;
6
+ while (i < source.length && source[i] !== quote) {
7
+ if (source[i] === "\\" && i + 1 < source.length) {
8
+ raw += source[i] + source[i + 1];
9
+ i += 2;
10
+ }
11
+ else {
12
+ raw += source[i];
13
+ i++;
14
+ }
15
+ }
16
+ if (i >= source.length) {
17
+ throw new ExpressionError("Unterminated string", { source, start, end: i });
18
+ }
19
+ raw += source[i];
20
+ i++;
21
+ return { raw, end: i };
22
+ }
@@ -0,0 +1,4 @@
1
+ export declare function scanString(source: string, start: number): {
2
+ value: string;
3
+ end: number;
4
+ };
@@ -0,0 +1,98 @@
1
+ import { ExpressionError } from "../../errors/index.js";
2
+ import { isHexDigit } from "../predicates/is-hex-digit.js";
3
+ const MAX_CODE_POINT = 0x10ffff;
4
+ const HEX_CODE_POINT_SIZE = 5;
5
+ export function scanString(source, start) {
6
+ const quote = source[start];
7
+ let value = "";
8
+ let i = start + 1;
9
+ while (i < source.length && source[i] !== quote) {
10
+ if (source[i] === "\\") {
11
+ i++;
12
+ const escaped = source[i];
13
+ if (escaped === "n")
14
+ value += "\n";
15
+ else if (escaped === "t")
16
+ value += "\t";
17
+ else if (escaped === "r")
18
+ value += "\r";
19
+ else if (escaped === "\\")
20
+ value += "\\";
21
+ else if (escaped === "0")
22
+ value += "\0";
23
+ else if (escaped === "x") {
24
+ const hex = source.slice(i + 1, i + 3);
25
+ if (hex.length < 2 || !isHexDigit(hex[0]) || !isHexDigit(hex[1])) {
26
+ throw new ExpressionError("Invalid \\x escape", { source, start, end: i });
27
+ }
28
+ value += String.fromCharCode(parseInt(hex, 16));
29
+ i += 3;
30
+ continue;
31
+ }
32
+ else if (escaped === "u") {
33
+ if (source[i + 1] === "{") {
34
+ i += 2;
35
+ let hex = "";
36
+ while (i < source.length && source[i] !== "}" && source[i] !== quote) {
37
+ if (!isHexDigit(source[i])) {
38
+ throw new ExpressionError("Invalid \\u escape: non-hex digit", {
39
+ source,
40
+ start,
41
+ end: i,
42
+ });
43
+ }
44
+ hex += source[i];
45
+ i++;
46
+ }
47
+ if (i >= source.length || source[i] !== "}") {
48
+ throw new ExpressionError("Invalid \\u escape: missing closing brace", {
49
+ source,
50
+ start,
51
+ end: i,
52
+ });
53
+ }
54
+ if (hex.length === 0) {
55
+ throw new ExpressionError("Invalid \\u escape: empty code point", {
56
+ source,
57
+ start,
58
+ end: i,
59
+ });
60
+ }
61
+ const codePoint = parseInt(hex, 16);
62
+ if (codePoint > MAX_CODE_POINT) {
63
+ throw new ExpressionError("Invalid \\u escape: code point out of range", {
64
+ source,
65
+ start,
66
+ end: i,
67
+ });
68
+ }
69
+ value += String.fromCodePoint(codePoint);
70
+ i++;
71
+ continue;
72
+ }
73
+ else {
74
+ const hex = source.slice(i + 1, i + HEX_CODE_POINT_SIZE);
75
+ if (hex.length < 4 || ![...hex].every(isHexDigit)) {
76
+ throw new ExpressionError("Invalid \\u escape", { source, start, end: i });
77
+ }
78
+ value += String.fromCharCode(parseInt(hex, 16));
79
+ i += HEX_CODE_POINT_SIZE;
80
+ continue;
81
+ }
82
+ }
83
+ else {
84
+ value += escaped;
85
+ }
86
+ }
87
+ else {
88
+ value += source[i];
89
+ }
90
+ i++;
91
+ }
92
+ if (i >= source.length) {
93
+ throw new ExpressionError("Unterminated string", { source, start, end: i });
94
+ }
95
+ i++;
96
+ // We keep the string literals in the token.
97
+ return { value: quote + value + quote, end: i };
98
+ }
@@ -0,0 +1,4 @@
1
+ export declare function scanTemplateLiteral(source: string, start: number): {
2
+ raw: string;
3
+ end: number;
4
+ };
@@ -0,0 +1,51 @@
1
+ import { ExpressionError } from "../../errors/index.js";
2
+ import { scanStringLiteral } from "./scan-string-literal.js";
3
+ export function scanTemplateLiteral(source, start) {
4
+ let raw = "`";
5
+ let i = start + 1;
6
+ while (i < source.length && source[i] !== "`") {
7
+ if (source[i] === "\\" && i + 1 < source.length) {
8
+ raw += source[i] + source[i + 1];
9
+ i += 2;
10
+ continue;
11
+ }
12
+ if (source[i] === "$" && i + 1 < source.length && source[i + 1] === "{") {
13
+ raw += "${";
14
+ i += 2;
15
+ let depth = 1;
16
+ while (i < source.length && depth > 0) {
17
+ const c = source[i];
18
+ if (c === '"' || c === "'") {
19
+ const result = scanStringLiteral(source, i);
20
+ raw += result.raw;
21
+ i = result.end;
22
+ continue;
23
+ }
24
+ if (c === "`") {
25
+ const result = scanTemplateLiteral(source, i);
26
+ raw += result.raw;
27
+ i = result.end;
28
+ continue;
29
+ }
30
+ if (c === "{")
31
+ depth++;
32
+ else if (c === "}")
33
+ depth--;
34
+ if (depth > 0)
35
+ raw += c;
36
+ i++;
37
+ }
38
+ raw += "}";
39
+ }
40
+ else {
41
+ raw += source[i];
42
+ i++;
43
+ }
44
+ }
45
+ if (i >= source.length) {
46
+ throw new ExpressionError("Unterminated template literal", { source, start, end: i });
47
+ }
48
+ raw += "`";
49
+ i++;
50
+ return { raw, end: i };
51
+ }
@@ -0,0 +1,4 @@
1
+ import type { Token } from "../types.js";
2
+ import type { Plugin } from "../../plugin.js";
3
+ export declare function tokenizeSafe(source: string, plugins?: Plugin[], tokensizeWhitespace?: boolean): Token[];
4
+ export declare function tokenize(source: string, plugins?: Plugin[], tokensizeWhitespace?: boolean): Token[];
@@ -0,0 +1,99 @@
1
+ import { isDigit } from "../predicates/is-digit.js";
2
+ import { isAlpha } from "../predicates/is-alpha.js";
3
+ import { scanTemplateLiteral } from "./scan-template-literal.js";
4
+ import { scanNumber } from "./scan-number.js";
5
+ import { scanString } from "./scan-string.js";
6
+ import { scanIdentifier } from "./scan-identifier.js";
7
+ import { scanOperator } from "./scan-operator.js";
8
+ import { ExpressionError } from "../../errors/expression-error.js";
9
+ export function tokenizeSafe(source, plugins, tokensizeWhitespace = false) {
10
+ const tokens = [];
11
+ try {
12
+ let i = 0;
13
+ while (i < source.length) {
14
+ const ch = source[i];
15
+ if (/\s/.test(ch)) {
16
+ if (tokensizeWhitespace) {
17
+ tokens.push({
18
+ value: ch,
19
+ start: i,
20
+ end: i + 1,
21
+ type: "Whitespace",
22
+ });
23
+ }
24
+ i++;
25
+ continue;
26
+ }
27
+ const start = i;
28
+ let result = null;
29
+ if (plugins) {
30
+ for (const plugin of plugins) {
31
+ if (plugin.scan) {
32
+ result = plugin.scan(source, i);
33
+ if (result)
34
+ break;
35
+ }
36
+ }
37
+ }
38
+ if (!result) {
39
+ if (isDigit(ch)) {
40
+ const r = scanNumber(source, i);
41
+ result = { type: "Number", value: r.value, end: r.end };
42
+ }
43
+ else if (ch === '"' || ch === "'") {
44
+ const r = scanString(source, i);
45
+ result = { type: "String", value: r.value, end: r.end };
46
+ }
47
+ else if (ch === "`") {
48
+ const r = scanTemplateLiteral(source, i);
49
+ result = { type: "TemplateLiteral", value: r.raw, end: r.end };
50
+ }
51
+ else if (isAlpha(ch)) {
52
+ result = scanIdentifier(source, i);
53
+ }
54
+ else {
55
+ result = scanOperator(source, i);
56
+ }
57
+ }
58
+ i = result.end;
59
+ tokens.push({ type: result.type, value: result.value, start, end: i });
60
+ }
61
+ tokens.push({ type: "EOF", value: "", start: i, end: i });
62
+ }
63
+ catch (e) {
64
+ if (e instanceof ExpressionError) {
65
+ const error = {
66
+ type: "ExpressionError",
67
+ start: e.start,
68
+ end: e.end,
69
+ value: source.slice(e.start, e.end),
70
+ error: e,
71
+ };
72
+ tokens.push(error);
73
+ const left = source.slice(e.end);
74
+ if (left) {
75
+ const remaining = {
76
+ type: "Unparsed",
77
+ start: e.end,
78
+ end: source.length,
79
+ value: left,
80
+ };
81
+ tokens.push(remaining);
82
+ }
83
+ tokens.push({ type: "EOF", value: "", start: source.length, end: source.length });
84
+ return tokens;
85
+ }
86
+ else {
87
+ throw e;
88
+ }
89
+ }
90
+ return tokens;
91
+ }
92
+ export function tokenize(source, plugins, tokensizeWhitespace) {
93
+ const result = tokenizeSafe(source, plugins, tokensizeWhitespace);
94
+ if (result.at(-2)?.type === "ExpressionError")
95
+ throw result.at(-2).error;
96
+ if (result.at(-3)?.type === "ExpressionError")
97
+ throw result.at(-3).error;
98
+ return result;
99
+ }
@@ -0,0 +1,12 @@
1
+ export type BinaryOperator = "||" | "&&" | "==" | "!=" | "<" | ">" | "<=" | ">=" | "+" | "-" | "*" | "/" | "%" | "**" | "in" | "not";
2
+ export type UnaryOperator = "!" | "-" | "+";
3
+ export type BinaryExpressionOperator = Exclude<BinaryOperator, "not"> | "not in" | "??";
4
+ export type OperatorValue = BinaryOperator | UnaryOperator;
5
+ export type PunctuationValue = "(" | ")" | "[" | "]" | "{" | "}" | "," | "." | ":" | "?";
6
+ export interface Token {
7
+ readonly type: string;
8
+ readonly start: number;
9
+ readonly end: number;
10
+ readonly value: string;
11
+ readonly error?: unknown;
12
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,3 @@
1
+ import type { ASTNode } from "./types.js";
2
+ import type { ParserContext } from "./parser-context.js";
3
+ export declare function parseArrayLiteral(ctx: ParserContext): ASTNode;
@@ -0,0 +1,15 @@
1
+ import { current, expect } from "./parser-context.js";
2
+ import { parseExpression } from "./parse-expression.js";
3
+ export function parseArrayLiteral(ctx) {
4
+ const start = expect(ctx, "Punctuation", "[").start;
5
+ const elements = [];
6
+ while (!(current(ctx).type === "Punctuation" && current(ctx).value === "]")) {
7
+ if (elements.length > 0)
8
+ expect(ctx, "Punctuation", ",");
9
+ if (current(ctx).type === "Punctuation" && current(ctx).value === "]")
10
+ break;
11
+ elements.push(parseExpression(ctx, 0));
12
+ }
13
+ const end = expect(ctx, "Punctuation", "]").end;
14
+ return { type: "ArrayLiteral", elements, start, end };
15
+ }
@@ -0,0 +1,3 @@
1
+ import type { ASTNode } from "./types.js";
2
+ import type { ParserContext } from "./parser-context.js";
3
+ export declare function parseExpression(ctx: ParserContext, minPrec?: number): ASTNode;
@@ -0,0 +1,74 @@
1
+ import { current, advance } from "./parser-context.js";
2
+ import { PRECEDENCE } from "./precedence.js";
3
+ import { parseUnary } from "./parse-unary.js";
4
+ export function parseExpression(ctx, minPrec = 0) {
5
+ let left = parseUnary(ctx);
6
+ while (true) {
7
+ const tok = current(ctx);
8
+ let prec;
9
+ // Core precedence (arithmetic only)
10
+ if (tok.type === "Operator") {
11
+ prec = PRECEDENCE[tok.value];
12
+ }
13
+ // Plugin precedence
14
+ if (prec === undefined && ctx.plugins) {
15
+ for (const plugin of ctx.plugins) {
16
+ if (plugin.infixPrecedence) {
17
+ prec = plugin.infixPrecedence(ctx);
18
+ if (prec !== undefined)
19
+ break;
20
+ }
21
+ }
22
+ }
23
+ if (prec !== undefined && prec >= minPrec) {
24
+ // Try plugin parseInfix first (for ternary, pipe, membership, etc.)
25
+ if (ctx.plugins) {
26
+ let handled = false;
27
+ for (const plugin of ctx.plugins) {
28
+ if (plugin.parseInfix) {
29
+ const node = plugin.parseInfix(ctx, left, minPrec);
30
+ if (node) {
31
+ left = node;
32
+ handled = true;
33
+ break;
34
+ }
35
+ }
36
+ }
37
+ if (handled)
38
+ continue;
39
+ }
40
+ // Default: standard binary expression
41
+ const op = advance(ctx);
42
+ const isRightAssoc = op.value === "**";
43
+ const nextMinPrec = isRightAssoc ? prec : prec + 1;
44
+ const right = parseExpression(ctx, nextMinPrec);
45
+ left = {
46
+ type: "BinaryExpression",
47
+ operator: op.value,
48
+ left,
49
+ right,
50
+ start: left.start,
51
+ end: right.end,
52
+ };
53
+ continue;
54
+ }
55
+ // No precedence — try plugin parseInfix (for things without precedence entry)
56
+ if (prec === undefined && ctx.plugins) {
57
+ let handled = false;
58
+ for (const plugin of ctx.plugins) {
59
+ if (plugin.parseInfix) {
60
+ const node = plugin.parseInfix(ctx, left, minPrec);
61
+ if (node) {
62
+ left = node;
63
+ handled = true;
64
+ break;
65
+ }
66
+ }
67
+ }
68
+ if (handled)
69
+ continue;
70
+ }
71
+ break;
72
+ }
73
+ return left;
74
+ }
@@ -0,0 +1,3 @@
1
+ import type { ASTNode } from "./types.js";
2
+ import type { ParserContext } from "./parser-context.js";
3
+ export declare function parseObjectLiteral(ctx: ParserContext): ASTNode;