@spooky-sync/query-builder 0.0.1-canary.21 → 0.0.1-canary.210

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/types.ts CHANGED
@@ -23,6 +23,79 @@ export interface QueryInfo {
23
23
  query: string;
24
24
  hash: number;
25
25
  vars?: Record<string, unknown>;
26
+ /**
27
+ * Engine-neutral description of the same SELECT, used by non-SurrealQL local
28
+ * cache backends (e.g. SQLite) that cannot parse the `query` string. Only
29
+ * populated for `SELECT` (undefined for LIVE/UPDATE/DELETE). See `QueryPlan`.
30
+ */
31
+ plan?: QueryPlan;
32
+ }
33
+
34
+ /**
35
+ * A single WHERE comparison. `value` is the resolved value (string IDs already
36
+ * converted to `RecordId`); when `paramRef` is set the condition references an
37
+ * existing query param verbatim (`$name`) instead of an inline value. `swap`
38
+ * flips the operands (`value op field`), mirroring `ComparisonOp._swap`.
39
+ */
40
+ export interface WhereComparison {
41
+ field: string;
42
+ op: ComparisonOp['_op'];
43
+ value: unknown;
44
+ paramRef?: string;
45
+ swap?: boolean;
46
+ }
47
+
48
+ /** A parenthesised `(c1 OR c2 …)` group, from a `_or` fragment. */
49
+ export interface WhereOr {
50
+ or: WhereComparison[];
51
+ }
52
+
53
+ /**
54
+ * Engine-neutral WHERE: a top-level conjunction (AND) of comparisons and/or
55
+ * OR-groups. Mirrors `buildQueryFromOptions`'s condition assembly exactly.
56
+ */
57
+ export type WhereNode = WhereComparison | WhereOr;
58
+
59
+ /**
60
+ * Engine-neutral description of a SELECT query. Backends render it to their own
61
+ * dialect (SurrealQL, SQLite, …). Relations are resolved by the caller via
62
+ * level-ordered decomposition rather than nested projection, so `relations`
63
+ * carries the tree rather than a flattened subquery string.
64
+ */
65
+ export interface QueryPlan {
66
+ table: string;
67
+ /** Projection field names; undefined means all (`*`). */
68
+ select?: string[];
69
+ where?: WhereNode[];
70
+ orderBy?: [field: string, direction: 'asc' | 'desc'][];
71
+ limit?: number;
72
+ offset?: number;
73
+ relations?: RelationPlan[];
74
+ /**
75
+ * Window materialization: when set, the base rows are EXACTLY these record
76
+ * ids (the window the SSP already computed), ignoring `where`/`limit`/
77
+ * `offset`. `orderBy`, `select` and `relations` still apply. Set by
78
+ * {@link buildWindowMaterializationPlan}; see `window-query.ts`.
79
+ */
80
+ ids?: unknown[];
81
+ }
82
+
83
+ /**
84
+ * One `.related()` edge in a {@link QueryPlan}. Correlation:
85
+ * - `one` → parent[`foreignKeyField`] = child.id (attach `bucket[0] ?? null`)
86
+ * - `many` → child[`foreignKeyField`] = parent.id (attach `bucket`)
87
+ * `limit`/`orderBy` are applied PER PARENT during decomposition.
88
+ */
89
+ export interface RelationPlan {
90
+ alias: string;
91
+ table: string;
92
+ cardinality: 'one' | 'many';
93
+ foreignKeyField: string;
94
+ select?: string[];
95
+ where?: WhereNode[];
96
+ orderBy?: [field: string, direction: 'asc' | 'desc'][];
97
+ limit?: number;
98
+ relations?: RelationPlan[];
26
99
  }
27
100
 
28
101
  export interface RelatedQuery {
@@ -36,9 +109,40 @@ export interface RelatedQuery {
36
109
  cardinality: 'one' | 'many';
37
110
  }
38
111
 
112
+ /**
113
+ * Comparison-operator descriptor for a single WHERE field, e.g.
114
+ * `{ _op: '<=', _val: 5 }` → `field <= $field`. A `$`-prefixed string `_val`
115
+ * references an existing query param verbatim; `_swap: true` flips the operands
116
+ * (`$val _op field`). Plain values still mean equality (`field = $field`).
117
+ */
118
+ export interface ComparisonOp {
119
+ _op: '=' | '!=' | '>' | '>=' | '<' | '<=' | (string & {});
120
+ _val: unknown;
121
+ _swap?: boolean;
122
+ }
123
+
124
+ /** A single WHERE field value: an equality value or a comparison descriptor. */
125
+ export type WhereFieldValue<V> = V | ComparisonOp;
126
+
127
+ /** A flat conjunction of field conditions (equality or comparison). */
128
+ export type WhereConditions<TModel extends GenericModel> = {
129
+ [K in keyof TModel]?: WhereFieldValue<TModel[K]>;
130
+ };
131
+
132
+ /**
133
+ * WHERE input for `.where()`. Supports equality (`{ field: value }`), comparison
134
+ * operators (`{ field: { _op, _val } }`), and a single top-level `_or` group of
135
+ * condition fragments that compile to a parenthesised `(... OR ...)` conjunct —
136
+ * e.g. `{ _or: [{ white: x }, { black: x }] }` → `(white = $white__or0 OR black = $black__or1)`.
137
+ * Backward-compatible with plain `Partial<TModel>` equality objects.
138
+ */
139
+ export type WhereInput<TModel extends GenericModel> = WhereConditions<TModel> & {
140
+ _or?: WhereConditions<TModel>[];
141
+ };
142
+
39
143
  export interface QueryOptions<TModel extends GenericModel, IsOne extends boolean> {
40
144
  select?: ((keyof TModel & string) | '*')[];
41
- where?: Partial<TModel>;
145
+ where?: WhereInput<TModel>;
42
146
  limit?: number;
43
147
  offset?: number;
44
148
  orderBy?: Partial<Record<keyof TModel, 'asc' | 'desc'>>;
@@ -47,10 +151,10 @@ export interface QueryOptions<TModel extends GenericModel, IsOne extends boolean
47
151
  isOne?: IsOne;
48
152
  }
49
153
 
50
- export interface LiveQueryOptions<TModel extends GenericModel> extends Omit<
154
+ export type LiveQueryOptions<TModel extends GenericModel> = Omit<
51
155
  QueryOptions<TModel, boolean>,
52
156
  'orderBy'
53
- > {}
157
+ >;
54
158
 
55
159
  // Import schema types for schema-aware modifiers
56
160
  import type {
@@ -78,7 +182,7 @@ export type SchemaAwareQueryModifier<
78
182
 
79
183
  // Simplified query builder interface for modifying subqueries
80
184
  export interface QueryModifierBuilder<TModel extends GenericModel> {
81
- where(conditions: Partial<TModel>): this;
185
+ where(conditions: WhereInput<TModel>): this;
82
186
  select(...fields: ((keyof TModel & string) | '*')[]): this;
83
187
  limit(count: number): this;
84
188
  offset(count: number): this;
@@ -93,7 +197,7 @@ export interface SchemaAwareQueryModifierBuilder<
93
197
  TableName extends TableNames<S>,
94
198
  RelatedFields extends Record<string, any> = {},
95
199
  > {
96
- where(conditions: Partial<TableModel<GetTable<S, TableName>>>): this;
200
+ where(conditions: WhereInput<TableModel<GetTable<S, TableName>>>): this;
97
201
  select(...fields: ((keyof TableModel<GetTable<S, TableName>> & string) | '*')[]): this;
98
202
  limit(count: number): this;
99
203
  offset(count: number): this;
@@ -139,6 +243,7 @@ export type RelationshipFields<TModel extends GenericModel> = {
139
243
  * Simplified to directly access the nested structure
140
244
  */
141
245
  export type InferRelatedModelFromMetadata<
246
+ // oxlint-disable-next-line no-unused-vars -- Schema is used as a generic constraint
142
247
  Schema extends GenericSchema,
143
248
  TableName extends string,
144
249
  FieldName extends string,