@atomic-ehr/fhirpath 0.0.1-canary.0c6931e.20250727185306

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 (85) hide show
  1. package/README.md +473 -0
  2. package/dist/index.d.ts +462 -0
  3. package/dist/index.js +10307 -0
  4. package/dist/index.js.map +1 -0
  5. package/package.json +58 -0
  6. package/src/analyzer/analyzer.ts +499 -0
  7. package/src/analyzer/model-provider.ts +244 -0
  8. package/src/analyzer/schemas/index.ts +2 -0
  9. package/src/analyzer/schemas/types.ts +40 -0
  10. package/src/analyzer/types.ts +142 -0
  11. package/src/api/builder.ts +157 -0
  12. package/src/api/errors.ts +145 -0
  13. package/src/api/expression.ts +156 -0
  14. package/src/api/index.ts +122 -0
  15. package/src/api/inspect.ts +99 -0
  16. package/src/api/registry.ts +128 -0
  17. package/src/api/types.ts +210 -0
  18. package/src/compiler/compiler.ts +546 -0
  19. package/src/compiler/index.ts +2 -0
  20. package/src/compiler/prototype-context-adapter.ts +99 -0
  21. package/src/compiler/types.ts +24 -0
  22. package/src/index.ts +107 -0
  23. package/src/interpreter/README.md +78 -0
  24. package/src/interpreter/interpreter.ts +475 -0
  25. package/src/interpreter/types.ts +108 -0
  26. package/src/lexer/char-tables.ts +37 -0
  27. package/src/lexer/errors.ts +31 -0
  28. package/src/lexer/index.ts +5 -0
  29. package/src/lexer/lexer.ts +745 -0
  30. package/src/lexer/token.ts +104 -0
  31. package/src/lexer2/index.md +232 -0
  32. package/src/lexer2/index.perf.test.ts +68 -0
  33. package/src/lexer2/index.test.ts +549 -0
  34. package/src/lexer2/index.ts +1251 -0
  35. package/src/lexer2/notes.md +173 -0
  36. package/src/lexer2/optimization-summary.md +718 -0
  37. package/src/parser/ast-factory.ts +220 -0
  38. package/src/parser/ast.ts +144 -0
  39. package/src/parser/collection-parser.ts +89 -0
  40. package/src/parser/diagnostic-messages.ts +216 -0
  41. package/src/parser/diagnostics.ts +85 -0
  42. package/src/parser/error-reporter.ts +230 -0
  43. package/src/parser/index.ts +3 -0
  44. package/src/parser/literal-parser.ts +103 -0
  45. package/src/parser/parse-error.ts +16 -0
  46. package/src/parser/parser-error-factory.ts +141 -0
  47. package/src/parser/parser-state.ts +134 -0
  48. package/src/parser/parser.ts +1272 -0
  49. package/src/parser/pprint.ts +169 -0
  50. package/src/parser/precedence-manager.ts +64 -0
  51. package/src/parser/source-mapper.ts +248 -0
  52. package/src/parser/special-constructs.ts +142 -0
  53. package/src/parser/token-navigator.ts +110 -0
  54. package/src/parser/types.ts +60 -0
  55. package/src/parser2/index.md +177 -0
  56. package/src/parser2/index.perf.test.ts +184 -0
  57. package/src/parser2/index.test.ts +305 -0
  58. package/src/parser2/index.ts +578 -0
  59. package/src/parser2/optimization-summary.md +176 -0
  60. package/src/registry/default-analyzers.ts +257 -0
  61. package/src/registry/default-compilers.ts +31 -0
  62. package/src/registry/index.ts +96 -0
  63. package/src/registry/operations/arithmetic.ts +506 -0
  64. package/src/registry/operations/collection.ts +425 -0
  65. package/src/registry/operations/comparison.ts +432 -0
  66. package/src/registry/operations/existence.ts +703 -0
  67. package/src/registry/operations/filtering.ts +358 -0
  68. package/src/registry/operations/literals.ts +341 -0
  69. package/src/registry/operations/logical.ts +439 -0
  70. package/src/registry/operations/math.ts +128 -0
  71. package/src/registry/operations/membership.ts +132 -0
  72. package/src/registry/operations/navigation.ts +52 -0
  73. package/src/registry/operations/string.ts +507 -0
  74. package/src/registry/operations/subsetting.ts +174 -0
  75. package/src/registry/operations/type-checking.ts +162 -0
  76. package/src/registry/operations/type-conversion.ts +404 -0
  77. package/src/registry/operations/type-operators.ts +308 -0
  78. package/src/registry/operations/utility.ts +644 -0
  79. package/src/registry/registry.ts +146 -0
  80. package/src/registry/types.ts +161 -0
  81. package/src/registry/utils/evaluation-helpers.ts +93 -0
  82. package/src/registry/utils/index.ts +3 -0
  83. package/src/registry/utils/type-system.ts +173 -0
  84. package/src/runtime/context.ts +158 -0
  85. package/src/runtime/debug-context.ts +135 -0
@@ -0,0 +1,108 @@
1
+ // Core types for FHIRPath interpreter following the stream-processing mental model
2
+
3
+ /**
4
+ * The result of evaluating any FHIRPath expression.
5
+ * Every expression returns a collection and potentially modified context.
6
+ */
7
+ import type { RuntimeContext } from '../runtime/context';
8
+
9
+ export interface EvaluationResult {
10
+ value: any[]; // Always a collection (even single values are collections of one)
11
+ context: RuntimeContext;
12
+ }
13
+
14
+
15
+ /**
16
+ * Error thrown during evaluation with position information
17
+ */
18
+ export class EvaluationError extends Error {
19
+ constructor(
20
+ message: string,
21
+ public position?: { line: number; column: number; offset: number }
22
+ ) {
23
+ super(message);
24
+ this.name = 'EvaluationError';
25
+ }
26
+ }
27
+
28
+ /**
29
+ * Type information for runtime type checking
30
+ */
31
+ export interface TypeInfo {
32
+ namespace: string; // 'System' or 'FHIR'
33
+ name: string; // Type name like 'String', 'Patient'
34
+ isCollection?: boolean;
35
+ }
36
+
37
+ /**
38
+ * Helper type for ensuring we always work with collections
39
+ */
40
+ export type Collection<T = any> = T[];
41
+
42
+ /**
43
+ * Singleton conversion result
44
+ */
45
+ export type SingletonResult<T = any> = T | undefined;
46
+
47
+ /**
48
+ * Helper functions for working with collections
49
+ */
50
+ export const CollectionUtils = {
51
+ /**
52
+ * Convert any value to a collection
53
+ */
54
+ toCollection(value: any): any[] {
55
+ if (value === null || value === undefined) {
56
+ return [];
57
+ }
58
+ return Array.isArray(value) ? value : [value];
59
+ },
60
+
61
+ /**
62
+ * Apply singleton evaluation rules
63
+ * @returns The single value or undefined if rules don't apply
64
+ * @throws Error if multiple items when single expected
65
+ */
66
+ toSingleton(collection: any[], expectedType?: string): SingletonResult {
67
+ if (collection.length === 0) {
68
+ return undefined; // Empty propagates
69
+ }
70
+
71
+ if (collection.length === 1) {
72
+ const value = collection[0];
73
+
74
+ // Rule 2: Collection with one item, expecting Boolean → true
75
+ if (expectedType === 'boolean' && typeof value !== 'boolean') {
76
+ return true;
77
+ }
78
+
79
+ // Rule 1: Collection with one item convertible to expected type → use it
80
+ return value;
81
+ }
82
+
83
+ // Rule 4: Multiple items → ERROR
84
+ throw new EvaluationError(`Expected single value but got ${collection.length} items`);
85
+ },
86
+
87
+ /**
88
+ * Check if a collection is empty
89
+ */
90
+ isEmpty(collection: any[]): boolean {
91
+ return collection.length === 0;
92
+ },
93
+
94
+ /**
95
+ * Flatten nested collections
96
+ */
97
+ flatten(collection: any[]): any[] {
98
+ const result: any[] = [];
99
+ for (const item of collection) {
100
+ if (Array.isArray(item)) {
101
+ result.push(...item);
102
+ } else {
103
+ result.push(item);
104
+ }
105
+ }
106
+ return result;
107
+ }
108
+ };
@@ -0,0 +1,37 @@
1
+ // Character classification lookup table for O(1) checks
2
+ export const CHAR_FLAGS = new Uint8Array(128);
3
+
4
+ // Bit flags for character properties
5
+ export const FLAG_DIGIT = 1 << 0;
6
+ export const FLAG_ALPHA = 1 << 1;
7
+ export const FLAG_WHITESPACE = 1 << 2;
8
+ export const FLAG_IDENTIFIER_START = 1 << 3;
9
+ export const FLAG_IDENTIFIER_CONT = 1 << 4;
10
+
11
+ // Initialize lookup table (called once at startup)
12
+ export function initCharTables(): void {
13
+ // Digits
14
+ for (let i = 48; i <= 57; i++) {
15
+ CHAR_FLAGS[i]! |= FLAG_DIGIT | FLAG_IDENTIFIER_CONT;
16
+ }
17
+
18
+ // Letters
19
+ for (let i = 65; i <= 90; i++) {
20
+ CHAR_FLAGS[i]! |= FLAG_ALPHA | FLAG_IDENTIFIER_START | FLAG_IDENTIFIER_CONT;
21
+ }
22
+ for (let i = 97; i <= 122; i++) {
23
+ CHAR_FLAGS[i]! |= FLAG_ALPHA | FLAG_IDENTIFIER_START | FLAG_IDENTIFIER_CONT;
24
+ }
25
+
26
+ // Underscore
27
+ CHAR_FLAGS[95]! |= FLAG_IDENTIFIER_START | FLAG_IDENTIFIER_CONT;
28
+
29
+ // Whitespace
30
+ CHAR_FLAGS[32]! |= FLAG_WHITESPACE; // space
31
+ CHAR_FLAGS[9]! |= FLAG_WHITESPACE; // tab
32
+ CHAR_FLAGS[10]! |= FLAG_WHITESPACE; // newline
33
+ CHAR_FLAGS[13]! |= FLAG_WHITESPACE; // carriage return
34
+ }
35
+
36
+ // Initialize the table immediately
37
+ initCharTables();
@@ -0,0 +1,31 @@
1
+ import type { Position } from './token';
2
+
3
+ export class LexerError extends Error {
4
+ constructor(
5
+ message: string,
6
+ public position: Position,
7
+ public char?: string
8
+ ) {
9
+ super(message);
10
+ this.name = 'LexerError';
11
+ }
12
+
13
+ override toString(): string {
14
+ const location = `${this.position.line}:${this.position.column}`;
15
+ const charInfo = this.char ? ` (found '${this.char}')` : '';
16
+ return `${this.name}: ${this.message} at ${location}${charInfo}`;
17
+ }
18
+ }
19
+
20
+ export function formatError(error: LexerError, input: string): string {
21
+ const lines = input.split('\n');
22
+ const line = lines[error.position.line - 1] || '';
23
+ const pointer = ' '.repeat(error.position.column - 1) + '^';
24
+
25
+ return [
26
+ error.toString(),
27
+ '',
28
+ line,
29
+ pointer
30
+ ].join('\n');
31
+ }
@@ -0,0 +1,5 @@
1
+ export { FHIRPathLexer, lex } from './lexer';
2
+ export type { Token, Position } from './token';
3
+ export { TokenType, Channel } from './token';
4
+ export { LexerError, formatError } from './errors';
5
+ export { CHAR_FLAGS, FLAG_DIGIT, FLAG_ALPHA, FLAG_WHITESPACE, FLAG_IDENTIFIER_START, FLAG_IDENTIFIER_CONT } from './char-tables';