@spooky-sync/query-builder 0.0.1-canary.37 → 0.0.1-canary.371

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,17 +109,58 @@ 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'>>;
45
149
  /** Related tables to include via subqueries */
46
150
  related?: RelatedQuery[];
47
151
  isOne?: IsOne;
152
+ /**
153
+ * Set by `.ignoreUnusedArgs()`: the caller knows some parts of this query
154
+ * are ignored where it is used (a channel only reads the `where`), so no
155
+ * warning is wanted. Not part of the query: never changes surql or hash.
156
+ */
157
+ ignoreUnusedArgs?: boolean;
48
158
  }
49
159
 
160
+ /** A user a channel connects to: a record id, its string form, or nothing. */
161
+ export type ChannelPeer = string | { toString(): string } | null | undefined;
162
+
163
+
50
164
  export type LiveQueryOptions<TModel extends GenericModel> = Omit<
51
165
  QueryOptions<TModel, boolean>,
52
166
  'orderBy'
@@ -78,7 +192,7 @@ export type SchemaAwareQueryModifier<
78
192
 
79
193
  // Simplified query builder interface for modifying subqueries
80
194
  export interface QueryModifierBuilder<TModel extends GenericModel> {
81
- where(conditions: Partial<TModel>): this;
195
+ where(conditions: WhereInput<TModel>): this;
82
196
  select(...fields: ((keyof TModel & string) | '*')[]): this;
83
197
  limit(count: number): this;
84
198
  offset(count: number): this;
@@ -93,7 +207,7 @@ export interface SchemaAwareQueryModifierBuilder<
93
207
  TableName extends TableNames<S>,
94
208
  RelatedFields extends Record<string, any> = {},
95
209
  > {
96
- where(conditions: Partial<TableModel<GetTable<S, TableName>>>): this;
210
+ where(conditions: WhereInput<TableModel<GetTable<S, TableName>>>): this;
97
211
  select(...fields: ((keyof TableModel<GetTable<S, TableName>> & string) | '*')[]): this;
98
212
  limit(count: number): this;
99
213
  offset(count: number): this;