@omgbase/oqx 0.15.0 → 0.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/CHANGELOG.md +60 -0
  2. package/README.md +308 -70
  3. package/dist/ast.d.ts +97 -27
  4. package/dist/ast.d.ts.map +1 -1
  5. package/dist/ast.js +21 -6
  6. package/dist/ast.js.map +1 -1
  7. package/dist/build.d.ts +43 -0
  8. package/dist/build.d.ts.map +1 -0
  9. package/dist/build.js +58 -0
  10. package/dist/build.js.map +1 -0
  11. package/dist/context.d.ts +30 -6
  12. package/dist/context.d.ts.map +1 -1
  13. package/dist/context.js +11 -10
  14. package/dist/context.js.map +1 -1
  15. package/dist/engine.d.ts +13 -3
  16. package/dist/engine.d.ts.map +1 -1
  17. package/dist/engine.js +281 -100
  18. package/dist/engine.js.map +1 -1
  19. package/dist/errors.d.ts +1 -1
  20. package/dist/errors.d.ts.map +1 -1
  21. package/dist/errors.js +2 -1
  22. package/dist/errors.js.map +1 -1
  23. package/dist/index.d.ts +19 -6
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.js +36 -13
  26. package/dist/index.js.map +1 -1
  27. package/dist/lexer.d.ts +15 -1
  28. package/dist/lexer.d.ts.map +1 -1
  29. package/dist/lexer.js +104 -51
  30. package/dist/lexer.js.map +1 -1
  31. package/dist/optimize/analysis.d.ts +3 -2
  32. package/dist/optimize/analysis.d.ts.map +1 -1
  33. package/dist/optimize/analysis.js +19 -18
  34. package/dist/optimize/analysis.js.map +1 -1
  35. package/dist/optimize/ir.d.ts +2 -2
  36. package/dist/optimize/ir.d.ts.map +1 -1
  37. package/dist/optimize/ir.js +3 -3
  38. package/dist/optimize/ir.js.map +1 -1
  39. package/dist/parser.d.ts.map +1 -1
  40. package/dist/parser.js +782 -335
  41. package/dist/parser.js.map +1 -1
  42. package/dist/plan.d.ts.map +1 -1
  43. package/dist/plan.js +4 -2
  44. package/dist/plan.js.map +1 -1
  45. package/dist/print.d.ts +17 -0
  46. package/dist/print.d.ts.map +1 -0
  47. package/dist/print.js +266 -0
  48. package/dist/print.js.map +1 -0
  49. package/dist/resolve.d.ts +23 -0
  50. package/dist/resolve.d.ts.map +1 -0
  51. package/dist/resolve.js +333 -0
  52. package/dist/resolve.js.map +1 -0
  53. package/dist/version.d.ts +5 -0
  54. package/dist/version.d.ts.map +1 -0
  55. package/dist/version.js +5 -0
  56. package/dist/version.js.map +1 -0
  57. package/dist/walk.d.ts +56 -0
  58. package/dist/walk.d.ts.map +1 -0
  59. package/dist/walk.js +157 -0
  60. package/dist/walk.js.map +1 -0
  61. package/package.json +1 -1
  62. package/src/ast.ts +126 -40
  63. package/src/build.ts +73 -0
  64. package/src/context.ts +36 -12
  65. package/src/engine.ts +285 -110
  66. package/src/errors.ts +3 -2
  67. package/src/index.ts +40 -14
  68. package/src/lexer.ts +102 -51
  69. package/src/optimize/analysis.ts +17 -15
  70. package/src/optimize/ir.ts +4 -4
  71. package/src/parser.ts +721 -289
  72. package/src/plan.ts +3 -2
  73. package/src/print.ts +276 -0
  74. package/src/resolve.ts +309 -0
  75. package/src/version.ts +4 -0
  76. package/src/walk.ts +201 -0
package/dist/ast.d.ts CHANGED
@@ -1,142 +1,195 @@
1
+ /** A half-open source range `[start, end)` in Unicode code points over the raw
2
+ * source (`rawSource` for a template, where a binding occupies its `${n}`
3
+ * marker). The empty span `[0, 0]` marks a node that did not come from source. */
4
+ export type Span = [start: number, end: number];
1
5
  /** Query consumers — how a (sub)query's row set is shaped. `none` is the
2
6
  * zero-cardinality complement of `exists` (true iff the block yields no rows). */
3
7
  export type Consumer = "collect" | "exists" | "none" | "count" | "first" | "single";
4
8
  /** Comparison operators usable in a `count { … } <op> <int>` test. */
5
9
  export type RelOp = "==" | "!=" | "<" | "<=" | ">" | ">=";
10
+ /** The identity operators (SEMANTICS §5b, since 0.17). */
11
+ export type IdentityOp = "is" | "is not";
12
+ /** The operator of a `binary` expression: a comparison, an identity test, or arithmetic. */
13
+ export type BinaryOp = RelOp | IdentityOp | "+" | "-" | "*" | "/" | "%";
14
+ /** The operator of a `unary` expression. */
15
+ export type UnaryOp = "!" | "-";
16
+ /** The operator of a `logical` expression. */
17
+ export type LogicalOp = "&&" | "||";
6
18
  /** Scalar value/predicate expression, evaluated against a row scope + bindings. */
7
19
  export type Expr = {
8
20
  kind: "lit";
21
+ span: Span;
9
22
  value: string | number | boolean | null;
10
23
  } | {
11
24
  kind: "ident";
25
+ span: Span;
12
26
  name: string;
13
27
  } | {
14
28
  kind: "outer";
29
+ span: Span;
15
30
  levels: number;
16
31
  name: string;
17
32
  } | {
18
33
  kind: "binding";
34
+ span: Span;
19
35
  index: number;
20
36
  } | {
21
37
  kind: "member";
38
+ span: Span;
22
39
  recv: Expr;
23
40
  name: string;
24
- } | {
25
- kind: "index";
26
- recv: Expr;
27
- index: Expr;
28
41
  } | {
29
42
  kind: "call";
43
+ span: Span;
30
44
  recv: Expr | null;
31
45
  name: string;
32
46
  args: Expr[];
33
47
  } | {
34
48
  kind: "unary";
35
- op: "!" | "-";
49
+ span: Span;
50
+ op: UnaryOp;
51
+ expr: Expr;
52
+ } | {
53
+ kind: "required";
54
+ span: Span;
36
55
  expr: Expr;
37
56
  } | {
38
57
  kind: "binary";
39
- op: string;
58
+ span: Span;
59
+ op: BinaryOp;
40
60
  left: Expr;
41
61
  right: Expr;
42
62
  } | {
43
63
  kind: "logical";
44
- op: "&&" | "||";
64
+ span: Span;
65
+ op: LogicalOp;
45
66
  left: Expr;
46
67
  right: Expr;
47
68
  } | {
48
69
  kind: "in";
70
+ span: Span;
49
71
  left: Expr;
50
72
  right: Expr;
51
73
  } | {
52
74
  kind: "range";
75
+ span: Span;
53
76
  lo: Expr | null;
54
77
  hi: Expr | null;
55
78
  exclusiveEnd: boolean;
56
- };
79
+ } | {
80
+ kind: "tuple";
81
+ span: Span;
82
+ items: Expr[];
83
+ } | OpNode;
84
+ /** One `order by` term. */
57
85
  export interface OrderSpec {
86
+ kind: "order";
87
+ span: Span;
58
88
  expr: Expr;
59
89
  desc: boolean;
60
90
  }
61
91
  /** One projection item: a named scalar/navigation value, or a named nested
62
- * collection consumer. `lift` marks a `^name` one-scope lift. */
92
+ * collection consumer. `lift` marks a `^name` lift. */
63
93
  export type SelectItem = {
64
94
  kind: "field";
95
+ span: Span;
65
96
  name: string;
66
97
  expr: Expr;
67
98
  lift: number;
68
99
  } | {
69
100
  kind: "collect";
101
+ span: Span;
70
102
  name: string;
71
103
  op: OpNode;
72
104
  };
105
+ /** The `count { … } <op> <int>` test attached to an `OpNode` — an attribute of
106
+ * the directive, not a node of its own. */
107
+ export interface CountCmp {
108
+ op: RelOp;
109
+ value: number;
110
+ }
73
111
  /** A postfix consumer directive over a receiver collection:
74
112
  * `<receiver> <op> { <sub> }`, optionally `count { … } <relop> <int>`. */
75
113
  export interface OpNode {
76
114
  kind: "op";
115
+ span: Span;
77
116
  receiver: Expr;
78
117
  op: Consumer;
79
118
  sub: Subquery;
80
- countCmp?: {
81
- op: RelOp;
82
- value: number;
83
- };
119
+ countCmp: CountCmp | null;
84
120
  /** `distinct` — dedup the rows this directive consumes by their projected
85
121
  * value (the `select`), so `count distinct { … }` counts distinct projections
86
122
  * and `collect distinct { … }` yields distinct rows. Empty select ⇒ dedup by
87
123
  * row identity. Spellable as `<op> distinct { … }` or `{ select distinct … }`. */
88
- distinct?: boolean;
124
+ distinct: boolean;
89
125
  }
90
126
  /** One `follow` destination: a relation of the current row (an `Expr` receiver), or a
91
127
  * destination block — a select-position directive (`collect`/`first`/`single`) re-evaluated
92
128
  * per frontier row, inside which `^` is that row. Discriminate on `kind === "op"`. */
93
129
  export type FollowDestination = Expr | OpNode;
94
- /** The recursive `follow` clause. */
130
+ /** The recursive `follow` clause (since 0.20 just the destinations: a
131
+ * destination's `where`, `frontier` and `depth` live in its own block). */
95
132
  export interface Follow {
133
+ kind: "follow";
134
+ span: Span;
96
135
  destinations: FollowDestination[];
97
136
  distinct: boolean;
98
- where: Expr | null;
99
- frontier: Expr | null;
100
- depth: number | null;
101
- by: Expr | null;
102
137
  }
103
- /** A nested (sub)query body. */
138
+ /** A nested (sub)query body — the `{ … }` of a directive. */
104
139
  export interface Subquery {
140
+ kind: "subquery";
141
+ span: Span;
105
142
  from: Expr[];
106
143
  where: Where | null;
107
144
  select: SelectItem[];
108
145
  orderBy: OrderSpec[] | null;
109
146
  follow: Follow | null;
147
+ /** `frontier P` / `depth n` (since 0.20). In a `follow` destination block
148
+ * `frontier` marks the occurrences reached through this destination for
149
+ * which `P` holds (not expanded; `P` read one level out, under the walk's
150
+ * enclosing scope), and `depth n` makes the destination expand a frontier
151
+ * row only while that row's `$depth < n` (1..8; `null` = the hard cap 8).
152
+ * In any other block `frontier` is legal only with a `follow` and marks the
153
+ * walk's SEEDS, read in the seed's scope like `where` (as on `Query`);
154
+ * `depth` is destination-only. Both `null` when absent. */
155
+ frontier: Expr | null;
156
+ depth: number | null;
110
157
  /** `values` — scalar projection mode: the (single) projected expression is the
111
158
  * row's result itself rather than being wrapped in a `{ name: value }` record,
112
159
  * so `name values` yields `["Bob", …]` and `$it values` yields the rows. */
113
- values?: boolean;
160
+ values: boolean;
114
161
  /** `limit N` / `offset N` — bound the row set AFTER where/order/distinct and
115
162
  * BEFORE the consumer reduces it, so `count { … limit 5 }` is at most 5 and
116
163
  * `first { … offset 1 }` is the second row. Each is a value expression
117
164
  * (a literal, a `${…}` binding, or an outer reference) read as part of the
118
165
  * block — `^n` is the enclosing row's field, as everywhere inside `{ … }` —
119
166
  * and must yield a non-negative integer. */
120
- limit?: Expr;
121
- offset?: Expr;
167
+ limit: Expr | null;
168
+ offset: Expr | null;
122
169
  }
123
170
  /** The where-clause boolean tree: OQX owns &&/||/!/grouping so consumer ops
124
171
  * (invisible to the scalar evaluator) compose with scalar predicates. */
125
172
  export type Where = {
126
173
  kind: "and";
174
+ span: Span;
127
175
  parts: Where[];
128
176
  } | {
129
177
  kind: "or";
178
+ span: Span;
130
179
  parts: Where[];
131
180
  } | {
132
181
  kind: "not";
182
+ span: Span;
133
183
  expr: Where;
134
184
  } | {
135
185
  kind: "scalar";
186
+ span: Span;
136
187
  expr: Expr;
137
188
  } | OpNode;
138
189
  /** A top-level OQX query. */
139
190
  export interface Query {
191
+ kind: "query";
192
+ span: Span;
140
193
  source: Expr;
141
194
  from: Expr[];
142
195
  where: Where | null;
@@ -144,12 +197,29 @@ export interface Query {
144
197
  orderBy: OrderSpec[] | null;
145
198
  consumer: Consumer;
146
199
  follow: Follow | null;
200
+ /** `frontier P` (since 0.20) — legal only when the body has a `follow`: a
201
+ * seed for which `P` holds (read in the seed's own scope, `^` the enclosing
202
+ * scope, like `where`) is a frontier (`$stop == "frontier"`, not expanded).
203
+ * `null` without one. */
204
+ frontier: Expr | null;
147
205
  /** `distinct` — dedup the result rows by their projected value (see OpNode). */
148
- distinct?: boolean;
206
+ distinct: boolean;
149
207
  /** `values` — scalar projection mode (see Subquery). */
150
- values?: boolean;
208
+ values: boolean;
151
209
  /** `limit N` / `offset N` (see Subquery); evaluated at the root scope. */
152
- limit?: Expr;
153
- offset?: Expr;
210
+ limit: Expr | null;
211
+ offset: Expr | null;
154
212
  }
213
+ /** Every node of the tree. `AstNode["kind"]` is the closed set of node kinds. */
214
+ export type AstNode = Query | Subquery | OpNode | Follow | OrderSpec | SelectItem | Where | Expr;
215
+ /** The closed set of node kinds. */
216
+ export type AstKind = AstNode["kind"];
217
+ /** Whether a node is a scalar `Expr` (an `op` in expression position is not: it
218
+ * is an expression only by position, see AST.md §1). */
219
+ export declare function isExpr(node: AstNode): node is Expr;
220
+ /** The parsed query's JSON form (`toJSON`): the tree with the language version
221
+ * it was produced under. */
222
+ export type QueryJson = Query & {
223
+ oqx: string;
224
+ };
155
225
  //# sourceMappingURL=ast.d.ts.map
package/dist/ast.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"ast.d.ts","sourceRoot":"","sources":["../src/ast.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ast.d.ts","sourceRoot":"","sources":["../src/ast.ts"],"names":[],"mappings":"AAaA;;kFAEkF;AAClF,MAAM,MAAM,IAAI,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;AAEhD;kFACkF;AAClF,MAAM,MAAM,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,GAAG,QAAQ,CAAC;AAEpF,sEAAsE;AACtE,MAAM,MAAM,KAAK,GAAG,IAAI,GAAG,IAAI,GAAG,GAAG,GAAG,IAAI,GAAG,GAAG,GAAG,IAAI,CAAC;AAE1D,0DAA0D;AAC1D,MAAM,MAAM,UAAU,GAAG,IAAI,GAAG,QAAQ,CAAC;AAEzC,4FAA4F;AAC5F,MAAM,MAAM,QAAQ,GAAG,KAAK,GAAG,UAAU,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAExE,4CAA4C;AAC5C,MAAM,MAAM,OAAO,GAAG,GAAG,GAAG,GAAG,CAAC;AAEhC,8CAA8C;AAC9C,MAAM,MAAM,SAAS,GAAG,IAAI,GAAG,IAAI,CAAC;AAEpC,mFAAmF;AACnF,MAAM,MAAM,IAAI,GACZ;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAA;CAAE,GACpE;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC3C;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC3D;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,IAAI,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC9C;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACxD;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,IAAI,EAAE,CAAA;CAAE,GAC3E;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,IAAI,CAAC;IAAC,EAAE,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,IAAI,CAAA;CAAE,GAEtD;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,IAAI,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,IAAI,CAAA;CAAE,GAC5C;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,IAAI,CAAC;IAAC,EAAE,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,IAAI,CAAA;CAAE,GACrE;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,IAAI,EAAE,IAAI,CAAC;IAAC,EAAE,EAAE,SAAS,CAAC;IAAC,IAAI,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,IAAI,CAAA;CAAE,GACvE;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,IAAI,CAAA;CAAE,GAInD;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,IAAI,CAAC;IAAC,EAAE,EAAE,IAAI,GAAG,IAAI,CAAC;IAAC,EAAE,EAAE,IAAI,GAAG,IAAI,CAAC;IAAC,YAAY,EAAE,OAAO,CAAA;CAAE,GAKtF;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,IAAI,EAAE,CAAA;CAAE,GAI5C,MAAM,CAAC;AAEX,2BAA2B;AAC3B,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,IAAI,CAAC;IACX,IAAI,EAAE,IAAI,CAAC;IACX,IAAI,EAAE,OAAO,CAAC;CACf;AAED;uDACuD;AACvD,MAAM,MAAM,UAAU,GAKlB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACrE;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,IAAI,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC;AAE9D;2CAC2C;AAC3C,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,KAAK,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;CACf;AAED;0EAC0E;AAC1E,MAAM,WAAW,MAAM;IACrB,IAAI,EAAE,IAAI,CAAC;IACX,IAAI,EAAE,IAAI,CAAC;IACX,QAAQ,EAAE,IAAI,CAAC;IACf,EAAE,EAAE,QAAQ,CAAC;IACb,GAAG,EAAE,QAAQ,CAAC;IACd,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAC;IAC1B;;;sFAGkF;IAClF,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED;;sFAEsF;AACtF,MAAM,MAAM,iBAAiB,GAAG,IAAI,GAAG,MAAM,CAAC;AAE9C;2EAC2E;AAC3E,MAAM,WAAW,MAAM;IACrB,IAAI,EAAE,QAAQ,CAAC;IACf,IAAI,EAAE,IAAI,CAAC;IACX,YAAY,EAAE,iBAAiB,EAAE,CAAC;IAClC,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,6DAA6D;AAC7D,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,UAAU,CAAC;IACjB,IAAI,EAAE,IAAI,CAAC;IACX,IAAI,EAAE,IAAI,EAAE,CAAC;IACb,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,OAAO,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC;IAC5B,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB;;;;;;;+DAO2D;IAC3D,QAAQ,EAAE,IAAI,GAAG,IAAI,CAAC;IACtB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB;;gFAE4E;IAC5E,MAAM,EAAE,OAAO,CAAC;IAChB;;;;;gDAK4C;IAC5C,KAAK,EAAE,IAAI,GAAG,IAAI,CAAC;IACnB,MAAM,EAAE,IAAI,GAAG,IAAI,CAAC;CACrB;AAED;yEACyE;AACzE,MAAM,MAAM,KAAK,GACb;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,KAAK,EAAE,CAAA;CAAE,GAC3C;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,KAAK,EAAE,CAAA;CAAE,GAC1C;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,KAAK,CAAA;CAAE,GACxC;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,IAAI,CAAA;CAAE,GAC1C,MAAM,CAAC;AAEX,6BAA6B;AAC7B,MAAM,WAAW,KAAK;IACpB,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,IAAI,CAAC;IACX,MAAM,EAAE,IAAI,CAAC;IACb,IAAI,EAAE,IAAI,EAAE,CAAC;IACb,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,OAAO,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC;IAC5B,QAAQ,EAAE,QAAQ,CAAC;IACnB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB;;;6BAGyB;IACzB,QAAQ,EAAE,IAAI,GAAG,IAAI,CAAC;IACtB,gFAAgF;IAChF,QAAQ,EAAE,OAAO,CAAC;IAClB,wDAAwD;IACxD,MAAM,EAAE,OAAO,CAAC;IAChB,0EAA0E;IAC1E,KAAK,EAAE,IAAI,GAAG,IAAI,CAAC;IACnB,MAAM,EAAE,IAAI,GAAG,IAAI,CAAC;CACrB;AAED,iFAAiF;AACjF,MAAM,MAAM,OAAO,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,GAAG,UAAU,GAAG,KAAK,GAAG,IAAI,CAAC;AAEjG,oCAAoC;AACpC,MAAM,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;AAOtC;wDACwD;AACxD,wBAAgB,MAAM,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,IAAI,IAAI,CAElD;AAED;4BAC4B;AAC5B,MAAM,MAAM,SAAS,GAAG,KAAK,GAAG;IAAE,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC"}
package/dist/ast.js CHANGED
@@ -1,7 +1,22 @@
1
- // OQX query AST for the generic kernel. The parser produces this directly and
2
- // the interpreter walks it — there is no separate lowering/IR pass, because a
3
- // "relation" in the generic kernel is just an expression evaluated against the
4
- // current row (property navigation on the host object model), resolved at run
5
- // time rather than against a fixed schema.
6
- export {};
1
+ // The OQX AST — a first-class, language-level contract (spec/oqx/AST.md, since
2
+ // language 0.16). The parser produces it, the interpreter walks it, and tools
3
+ // reflect on it without re-parsing: every node carries `kind` and `span`, every
4
+ // optional field is materialized (`null` / `false`), and the in-memory objects
5
+ // ARE the JSON shape both implementations serialize (plain data, no parent
6
+ // pointers, no methods). There is no separate lowering/IR pass: a "relation" is
7
+ // just an expression evaluated against the current row.
8
+ //
9
+ // `where` keeps its surface form: a `select` alias referenced in `where` stays a
10
+ // bare identifier here; `resolveAliases` (resolve.ts) performs the substitution
11
+ // before evaluation. Nodes built by a tool rather than the parser carry the
12
+ // empty span `[0, 0]` (see `build.ts`).
13
+ /** The expression kinds (`Expr["kind"]`), for `isExpr`. */
14
+ const EXPR_KINDS = new Set([
15
+ "lit", "ident", "outer", "binding", "member", "call", "unary", "required", "binary", "logical", "in", "range", "tuple",
16
+ ]);
17
+ /** Whether a node is a scalar `Expr` (an `op` in expression position is not: it
18
+ * is an expression only by position, see AST.md §1). */
19
+ export function isExpr(node) {
20
+ return EXPR_KINDS.has(node.kind);
21
+ }
7
22
  //# sourceMappingURL=ast.js.map
package/dist/ast.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"ast.js","sourceRoot":"","sources":["../src/ast.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,8EAA8E;AAC9E,+EAA+E;AAC/E,8EAA8E;AAC9E,2CAA2C"}
1
+ {"version":3,"file":"ast.js","sourceRoot":"","sources":["../src/ast.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,8EAA8E;AAC9E,gFAAgF;AAChF,+EAA+E;AAC/E,2EAA2E;AAC3E,gFAAgF;AAChF,wDAAwD;AACxD,EAAE;AACF,iFAAiF;AACjF,gFAAgF;AAChF,4EAA4E;AAC5E,wCAAwC;AAsLxC,2DAA2D;AAC3D,MAAM,UAAU,GAAwB,IAAI,GAAG,CAAC;IAC9C,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO;CACvH,CAAC,CAAC;AAEH;wDACwD;AACxD,MAAM,UAAU,MAAM,CAAC,IAAa;IAClC,OAAO,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACnC,CAAC"}
@@ -0,0 +1,43 @@
1
+ import type { BinaryOp, Consumer, CountCmp, Expr, Follow, FollowDestination, LogicalOp, OpNode, OrderSpec, Query, SelectItem, Span, Subquery, UnaryOp, Where } from "./ast.js";
2
+ /** A fresh empty span (never shared: spans are mutable tuples). */
3
+ export declare const span: () => Span;
4
+ export declare const lit: (value: string | number | boolean | null) => Expr;
5
+ export declare const ident: (name: string) => Expr;
6
+ export declare const outer: (levels: number, name: string) => Expr;
7
+ export declare const binding: (index: number) => Expr;
8
+ export declare const member: (recv: Expr, name: string) => Expr;
9
+ /** `a.b.c` from a dotted path. */
10
+ export declare const path: (first: string, ...rest: string[]) => Expr;
11
+ export declare const call: (recv: Expr | null, name: string, args?: Expr[]) => Expr;
12
+ export declare const unary: (op: UnaryOp, expr: Expr) => Expr;
13
+ /** `expr!` — the required value (SEMANTICS §5b). */
14
+ export declare const required: (expr: Expr) => Expr;
15
+ export declare const binary: (op: BinaryOp, left: Expr, right: Expr) => Expr;
16
+ export declare const logical: (op: LogicalOp, left: Expr, right: Expr) => Expr;
17
+ export declare const inOp: (left: Expr, right: Expr) => Expr;
18
+ export declare const range: (lo: Expr | null, hi: Expr | null, exclusiveEnd?: boolean) => Expr;
19
+ /** `(e1, e2, …)` — a tuple of two or more expressions (SEMANTICS §3b). */
20
+ export declare const tuple: (items: Expr[]) => Expr;
21
+ export declare const scalar: (expr: Expr) => Where;
22
+ export declare const and: (parts: Where[]) => Where;
23
+ export declare const or: (parts: Where[]) => Where;
24
+ export declare const not: (expr: Where) => Where;
25
+ export declare const field: (name: string, expr: Expr, lift?: number) => SelectItem;
26
+ export declare const collect: (name: string, op: OpNode) => SelectItem;
27
+ export declare const order: (expr: Expr, desc?: boolean) => OrderSpec;
28
+ /** A block body; every clause defaults to empty/absent. */
29
+ export declare function subquery(parts?: Partial<Omit<Subquery, "kind" | "span">>): Subquery;
30
+ /** `<receiver> <op> [distinct] { sub } [<relop> N]`. */
31
+ export declare function op(receiver: Expr, consumer: Consumer, sub?: Subquery, opts?: {
32
+ distinct?: boolean;
33
+ countCmp?: CountCmp | null;
34
+ }): OpNode;
35
+ /** `follow [distinct] <destinations>`; a destination's `where`/`frontier`/`depth`
36
+ * belong to its block (`op(recv, "collect", subquery({ depth: 2 }))`). */
37
+ export declare function follow(destinations: FollowDestination[], opts?: {
38
+ distinct?: boolean;
39
+ }): Follow;
40
+ /** A top-level query over `source`; every other clause defaults to empty/absent
41
+ * and the consumer to `collect`. */
42
+ export declare function query(source: Expr, parts?: Partial<Omit<Query, "kind" | "span" | "source">>): Query;
43
+ //# sourceMappingURL=build.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../src/build.ts"],"names":[],"mappings":"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"}
package/dist/build.js ADDED
@@ -0,0 +1,58 @@
1
+ // Builders for AST nodes a tool constructs itself (spec/oqx/AST.md §7). Every
2
+ // node they make carries the empty span `[0, 0]` — "not from source" — and the
3
+ // materialized defaults (`distinct: false`, `limit: null`, …), so a hand-built
4
+ // tree has the same shape as a parsed one and prints with `print`.
5
+ /** A fresh empty span (never shared: spans are mutable tuples). */
6
+ export const span = () => [0, 0];
7
+ export const lit = (value) => ({ kind: "lit", span: span(), value });
8
+ export const ident = (name) => ({ kind: "ident", span: span(), name });
9
+ export const outer = (levels, name) => ({ kind: "outer", span: span(), levels, name });
10
+ export const binding = (index) => ({ kind: "binding", span: span(), index });
11
+ export const member = (recv, name) => ({ kind: "member", span: span(), recv, name });
12
+ /** `a.b.c` from a dotted path. */
13
+ export const path = (first, ...rest) => rest.reduce((e, n) => member(e, n), ident(first));
14
+ export const call = (recv, name, args = []) => ({ kind: "call", span: span(), recv, name, args });
15
+ export const unary = (op, expr) => ({ kind: "unary", span: span(), op, expr });
16
+ /** `expr!` — the required value (SEMANTICS §5b). */
17
+ export const required = (expr) => ({ kind: "required", span: span(), expr });
18
+ export const binary = (op, left, right) => ({ kind: "binary", span: span(), op, left, right });
19
+ export const logical = (op, left, right) => ({ kind: "logical", span: span(), op, left, right });
20
+ export const inOp = (left, right) => ({ kind: "in", span: span(), left, right });
21
+ export const range = (lo, hi, exclusiveEnd = false) => ({ kind: "range", span: span(), lo, hi, exclusiveEnd });
22
+ /** `(e1, e2, …)` — a tuple of two or more expressions (SEMANTICS §3b). */
23
+ export const tuple = (items) => ({ kind: "tuple", span: span(), items });
24
+ export const scalar = (expr) => ({ kind: "scalar", span: span(), expr });
25
+ export const and = (parts) => ({ kind: "and", span: span(), parts });
26
+ export const or = (parts) => ({ kind: "or", span: span(), parts });
27
+ export const not = (expr) => ({ kind: "not", span: span(), expr });
28
+ export const field = (name, expr, lift = 0) => ({ kind: "field", span: span(), name, expr, lift });
29
+ export const collect = (name, op) => ({ kind: "collect", span: span(), name, op });
30
+ export const order = (expr, desc = false) => ({ kind: "order", span: span(), expr, desc });
31
+ /** A block body; every clause defaults to empty/absent. */
32
+ export function subquery(parts = {}) {
33
+ return {
34
+ kind: "subquery", span: span(),
35
+ from: [], where: null, select: [], orderBy: null, follow: null, frontier: null, depth: null, values: false, limit: null, offset: null,
36
+ ...parts,
37
+ };
38
+ }
39
+ /** `<receiver> <op> [distinct] { sub } [<relop> N]`. */
40
+ export function op(receiver, consumer, sub = subquery(), opts = {}) {
41
+ return { kind: "op", span: span(), receiver, op: consumer, sub, countCmp: opts.countCmp ?? null, distinct: opts.distinct ?? false };
42
+ }
43
+ /** `follow [distinct] <destinations>`; a destination's `where`/`frontier`/`depth`
44
+ * belong to its block (`op(recv, "collect", subquery({ depth: 2 }))`). */
45
+ export function follow(destinations, opts = {}) {
46
+ return { kind: "follow", span: span(), destinations, distinct: opts.distinct ?? false };
47
+ }
48
+ /** A top-level query over `source`; every other clause defaults to empty/absent
49
+ * and the consumer to `collect`. */
50
+ export function query(source, parts = {}) {
51
+ return {
52
+ kind: "query", span: span(), source,
53
+ from: [], where: null, select: [], orderBy: null, consumer: "collect", follow: null, frontier: null,
54
+ distinct: false, values: false, limit: null, offset: null,
55
+ ...parts,
56
+ };
57
+ }
58
+ //# sourceMappingURL=build.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build.js","sourceRoot":"","sources":["../src/build.ts"],"names":[],"mappings":"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"}
package/dist/context.d.ts CHANGED
@@ -9,6 +9,14 @@ export interface CallResult {
9
9
  export interface DataContext {
10
10
  /** Resolve a named root collection (the `from <name>` / directive receiver). */
11
11
  root(name: string): unknown;
12
+ /** The root scope's row — the host's root object: what `$it` is at the root
13
+ * scope and `^$it` from a top-level row (SEMANTICS §2, since 0.18), so
14
+ * `^$it.people` navigates it through `get` and `entries(^$it)` enumerates it.
15
+ * Bare names at the root still resolve through `root(name)`, so a host with
16
+ * lazy roots is unaffected. Optional: a context without it (or returning
17
+ * `undefined`) has no root row — `$it` at the root is absent, the pre-0.18
18
+ * behavior. `DefaultContext` returns its roots record. */
19
+ rootObject?(): unknown;
12
20
  /** Read a property/relation off a row: a bare identifier (`field`), a
13
21
  * `.field` segment, or a `^field` outer reference all come through here, each
14
22
  * against exactly the row of the scope it names. An absent property is
@@ -18,6 +26,13 @@ export interface DataContext {
18
26
  get(row: unknown, key: string): unknown;
19
27
  /** Coerce a relation/source value into rows (may be lazy). */
20
28
  toRows(value: unknown): Iterable<unknown>;
29
+ /** Optional: whether an object this context handed out in row position is
30
+ * ONE row — a record, not a collection (SEMANTICS §3, since 0.20) — so a block
31
+ * over it yields one result rather than a one-element list (`doc { title }`
32
+ * is a record; `docs { title }` a list). Asked only for non-array objects;
33
+ * absent, any non-iterable object is one row and any iterable (a `Set`, a
34
+ * lazy handle with `Symbol.iterator`) is a collection. */
35
+ isSingle?(value: unknown): boolean;
21
36
  /** Optional: a value this context handed out as a stand-in for a collection
22
37
  * it has not read yet (a lazy table handle), resolved to what it stands for.
23
38
  * The engine calls it on every value it is about to observe AS A VALUE — an
@@ -30,8 +45,15 @@ export interface DataContext {
30
45
  * seen by the language. Absent = identity; a context whose handle already
31
46
  * behaves as the collection (a `Proxy` over an array) needs none. */
32
47
  materialize?(value: unknown): unknown;
33
- /** Identity of a row for `follow` cycle detection / dedup. */
34
- identity(row: unknown): unknown;
48
+ /** Optional: the identity a row is known by — `$key` (SEMANTICS §16, since
49
+ * 0.20): what `follow` cycle detection, the per-step union, `follow distinct`,
50
+ * `distinct` over unprojected rows and `is` compare, and what reading `$key`
51
+ * on the row returns. Absent, a row's identity is its structural value (an
52
+ * entry's is its key either way). A store-backed context answers its row id. */
53
+ identityOf?(row: unknown): unknown;
54
+ /** @deprecated The pre-0.20 spelling of `identityOf`; read when `identityOf`
55
+ * is absent. Removed in the next minor. */
56
+ identity?(row: unknown): unknown;
35
57
  /** Optional custom free function; return `{ handled: false }` to defer. */
36
58
  callFunction?(name: string, args: unknown[]): CallResult;
37
59
  /** Optional custom method; return `{ handled: false }` to defer. */
@@ -61,17 +83,19 @@ export interface DefaultContextOptions {
61
83
  regexDialect?: RegexDialect;
62
84
  }
63
85
  /** The default context: ordinary JavaScript objects. Named roots come from a
64
- * plain `{ name: collection }` map; properties are OWN keys only (an array
65
- * exposes only its integer indices, a primitive has none); identity is `.id`
66
- * when present, else the row itself (the engine keys it structurally). */
86
+ * plain `{ name: collection }` map, which is also the root object (`^$it` from
87
+ * a top-level row); properties are OWN keys only (an array exposes only its
88
+ * integer indices, a primitive has none); it names no identity of its own, so a
89
+ * row's `$key` is its structural value (SEMANTICS §16) unless a query projects
90
+ * one (`$key: id`). */
67
91
  export declare class DefaultContext implements DataContext {
68
92
  private roots;
69
93
  readonly regexDialect: RegexDialect;
70
94
  constructor(roots?: Record<string, unknown>, options?: DefaultContextOptions);
71
95
  root(name: string): unknown;
96
+ rootObject(): unknown;
72
97
  get(row: unknown, key: string): unknown;
73
98
  toRows(value: unknown): Iterable<unknown>;
74
- identity(row: unknown): unknown;
75
99
  callFunction(name: string, args: unknown[]): CallResult;
76
100
  callMethod(name: string, recv: unknown, args: unknown[]): CallResult;
77
101
  }
@@ -1 +1 @@
1
- {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAQzD;kEACkE;AAClE,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,gFAAgF;IAChF,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IAC5B;;;;;kFAK8E;IAC9E,GAAG,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IACxC,8DAA8D;IAC9D,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC1C;;;;;;;;;;yEAUqE;IACrE,WAAW,CAAC,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC;IACtC,8DAA8D;IAC9D,QAAQ,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC;IAChC,2EAA2E;IAC3E,YAAY,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,UAAU,CAAC;IACzD,oEAAoE;IACpE,UAAU,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,UAAU,CAAC;IACtE;;;;;;iCAM6B;IAC7B,QAAQ,CAAC,YAAY,CAAC,EAAE,YAAY,CAAC;IACrC;;;;;;;;;yCASqC;IACrC,QAAQ,CAAC,CAAC,UAAU,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,QAAQ,GAAG,SAAS,CAAC;CAC/E;AAED,MAAM,WAAW,qBAAqB;IACpC,uDAAuD;IACvD,YAAY,CAAC,EAAE,YAAY,CAAC;CAC7B;AAED;;;0EAG0E;AAC1E,qBAAa,cAAe,YAAW,WAAW;IAChD,OAAO,CAAC,KAAK,CAA0B;IACvC,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAC;gBAExB,KAAK,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EAAE,OAAO,GAAE,qBAA0B;IAKpF,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI3B,GAAG,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO;IAMvC,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC;IAIzC,QAAQ,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO;IAK/B,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,UAAU;IAKvD,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,UAAU;CAKrE"}
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAQzD;kEACkE;AAClE,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,gFAAgF;IAChF,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IAC5B;;;;;;8DAM0D;IAC1D,UAAU,CAAC,IAAI,OAAO,CAAC;IACvB;;;;;kFAK8E;IAC9E,GAAG,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IACxC,8DAA8D;IAC9D,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC1C;;;;;8DAK0D;IAC1D,QAAQ,CAAC,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC;IACnC;;;;;;;;;;yEAUqE;IACrE,WAAW,CAAC,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC;IACtC;;;;oFAIgF;IAChF,UAAU,CAAC,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC;IACnC;+CAC2C;IAC3C,QAAQ,CAAC,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC;IACjC,2EAA2E;IAC3E,YAAY,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,UAAU,CAAC;IACzD,oEAAoE;IACpE,UAAU,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,UAAU,CAAC;IACtE;;;;;;iCAM6B;IAC7B,QAAQ,CAAC,YAAY,CAAC,EAAE,YAAY,CAAC;IACrC;;;;;;;;;yCASqC;IACrC,QAAQ,CAAC,CAAC,UAAU,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,QAAQ,GAAG,SAAS,CAAC;CAC/E;AAED,MAAM,WAAW,qBAAqB;IACpC,uDAAuD;IACvD,YAAY,CAAC,EAAE,YAAY,CAAC;CAC7B;AAED;;;;;uBAKuB;AACvB,qBAAa,cAAe,YAAW,WAAW;IAChD,OAAO,CAAC,KAAK,CAA0B;IACvC,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAC;gBAExB,KAAK,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EAAE,OAAO,GAAE,qBAA0B;IAKpF,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI3B,UAAU,IAAI,OAAO;IAIrB,GAAG,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO;IAMvC,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC;IAIzC,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,UAAU;IAKvD,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,UAAU;CAKrE"}
package/dist/context.js CHANGED
@@ -1,8 +1,9 @@
1
1
  // The tier-2 seam: a DataContext binds OQX's query semantics to a concrete data
2
2
  // model. The engine never touches host objects directly — it asks the context to
3
3
  // resolve named roots, read properties/relations, coerce a relation result into
4
- // rows, compute identity (for `follow` dedup), and optionally supply custom
5
- // scalar functions/methods. This is what lets the same query semantics run over
4
+ // rows (and say which objects are one row rather than a collection), name a
5
+ // row's identity (`$key`: `follow` dedup, `distinct`, `is`), and optionally
6
+ // supply custom scalar functions/methods. This is what lets the same query semantics run over
6
7
  // plain objects, a lazy ORM graph, or a remote API without changing the engine.
7
8
  //
8
9
  // (Performant execution over a real store is the tier-3 seam — see planner.ts —
@@ -14,9 +15,11 @@ function isIndexKey(key) {
14
15
  return /^(0|[1-9]\d*)$/.test(key);
15
16
  }
16
17
  /** The default context: ordinary JavaScript objects. Named roots come from a
17
- * plain `{ name: collection }` map; properties are OWN keys only (an array
18
- * exposes only its integer indices, a primitive has none); identity is `.id`
19
- * when present, else the row itself (the engine keys it structurally). */
18
+ * plain `{ name: collection }` map, which is also the root object (`^$it` from
19
+ * a top-level row); properties are OWN keys only (an array exposes only its
20
+ * integer indices, a primitive has none); it names no identity of its own, so a
21
+ * row's `$key` is its structural value (SEMANTICS §16) unless a query projects
22
+ * one (`$key: id`). */
20
23
  export class DefaultContext {
21
24
  roots;
22
25
  regexDialect;
@@ -27,6 +30,9 @@ export class DefaultContext {
27
30
  root(name) {
28
31
  return Object.hasOwn(this.roots, name) ? this.roots[name] : undefined;
29
32
  }
33
+ rootObject() {
34
+ return this.roots;
35
+ }
30
36
  get(row, key) {
31
37
  if (row == null || typeof row !== "object")
32
38
  return undefined;
@@ -37,11 +43,6 @@ export class DefaultContext {
37
43
  toRows(value) {
38
44
  return coerceCollection(value);
39
45
  }
40
- identity(row) {
41
- if (row != null && typeof row === "object" && "id" in row)
42
- return row.id;
43
- return row;
44
- }
45
46
  callFunction(name, args) {
46
47
  const fn = Object.hasOwn(BUILTIN_FUNCTIONS, name) ? BUILTIN_FUNCTIONS[name] : undefined;
47
48
  return fn ? { handled: true, value: fn(args) } : { handled: false };
@@ -1 +1 @@
1
- {"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,iFAAiF;AACjF,gFAAgF;AAChF,4EAA4E;AAC5E,4EAA4E;AAC5E,8FAA8F;AAC9F,gFAAgF;AAChF,EAAE;AACF,gFAAgF;AAChF,2EAA2E;AAE3E,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAIpG,0EAA0E;AAC1E,+DAA+D;AAC/D,SAAS,UAAU,CAAC,GAAW;IAC7B,OAAO,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACpC,CAAC;AAuFD;;;;;uBAKuB;AACvB,MAAM,OAAO,cAAc;IACjB,KAAK,CAA0B;IAC9B,YAAY,CAAe;IAEpC,YAAY,QAAiC,EAAE,EAAE,UAAiC,EAAE;QAClF,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI,KAAK,CAAC;IACpD,CAAC;IAED,IAAI,CAAC,IAAY;QACf,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACxE,CAAC;IAED,UAAU;QACR,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;IAED,GAAG,CAAC,GAAY,EAAE,GAAW;QAC3B,IAAI,GAAG,IAAI,IAAI,IAAI,OAAO,GAAG,KAAK,QAAQ;YAAE,OAAO,SAAS,CAAC;QAC7D,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC;YAAE,OAAO,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAC9E,OAAO,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAE,GAA+B,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACrF,CAAC;IAED,MAAM,CAAC,KAAc;QACnB,OAAO,gBAAgB,CAAC,KAAK,CAAC,CAAC;IACjC,CAAC;IAED,YAAY,CAAC,IAAY,EAAE,IAAe;QACxC,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,CAAC,iBAAiB,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QACxF,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IACtE,CAAC;IAED,UAAU,CAAC,IAAY,EAAE,IAAa,EAAE,IAAe;QACrD,IAAI,IAAI,KAAK,SAAS;YAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC;QACrG,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,CAAC,eAAe,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QACpF,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IAC5E,CAAC;CACF"}
package/dist/engine.d.ts CHANGED
@@ -1,10 +1,14 @@
1
1
  import type { Query, OpNode } from "./ast.js";
2
2
  import type { DataContext } from "./context.js";
3
3
  import type { Rule } from "./optimize/index.js";
4
- /** The shaped result of a top-level query, discriminated by consumer. */
4
+ /** The shaped result of a top-level query, discriminated by consumer. A
5
+ * `collect` over a **single** receiver (one object, SEMANTICS §3) is one record
6
+ * or absent rather than a list: `single` is true and `rows` holds at most that
7
+ * one row (`unwrap` yields `rows[0] ?? null`). */
5
8
  export type OqxResult = {
6
9
  consumer: "collect";
7
10
  rows: unknown[];
11
+ single: boolean;
8
12
  } | {
9
13
  consumer: "exists";
10
14
  exists: boolean;
@@ -69,12 +73,18 @@ export declare class InMemoryEngine implements Engine {
69
73
  run(query: Query, bindings?: readonly unknown[]): OqxResult;
70
74
  private boundOf;
71
75
  private matches;
76
+ private coerceRows;
72
77
  private rowsOf;
78
+ private hostIdentity;
79
+ private scopeIdentity;
80
+ private applyKey;
73
81
  private child;
74
82
  private enter;
75
83
  private runFollow;
84
+ private keyed;
76
85
  private dedupByProjection;
77
86
  private followWalk;
87
+ private destinationRows;
78
88
  private shape;
79
89
  private projectRow;
80
90
  private itemValue;
@@ -98,12 +108,12 @@ export declare class InMemoryEngine implements Engine {
98
108
  private indexFor;
99
109
  private evalCollectValue;
100
110
  private evalCollectValuePlanned;
111
+ private evalCollectScopes;
101
112
  private sortScopes;
102
113
  private evalExpr;
103
114
  private evalRaw;
104
115
  private resolveIn;
116
+ private rowIdentity;
105
117
  private evalCall;
106
118
  }
107
- /** Convenience: run a query with plain-object roots (the default context). */
108
- export declare function runQuery(query: Query, bindings: readonly unknown[], roots: unknown): OqxResult;
109
119
  //# sourceMappingURL=engine.d.ts.map