@tanstack/db 0.0.14 → 0.0.15
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/dist/cjs/collection.cjs +117 -104
- package/dist/cjs/collection.cjs.map +1 -1
- package/dist/cjs/collection.d.cts +18 -21
- package/dist/cjs/index.cjs +35 -13
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.cts +0 -1
- package/dist/cjs/query/builder/functions.cjs +107 -0
- package/dist/cjs/query/builder/functions.cjs.map +1 -0
- package/dist/cjs/query/builder/functions.d.cts +38 -0
- package/dist/cjs/query/builder/index.cjs +499 -0
- package/dist/cjs/query/builder/index.cjs.map +1 -0
- package/dist/cjs/query/builder/index.d.cts +324 -0
- package/dist/cjs/query/builder/ref-proxy.cjs +96 -0
- package/dist/cjs/query/builder/ref-proxy.cjs.map +1 -0
- package/dist/cjs/query/builder/ref-proxy.d.cts +28 -0
- package/dist/cjs/query/builder/types.d.cts +80 -0
- package/dist/cjs/query/compiler/evaluators.cjs +261 -0
- package/dist/cjs/query/compiler/evaluators.cjs.map +1 -0
- package/dist/cjs/query/compiler/evaluators.d.cts +11 -0
- package/dist/cjs/query/compiler/group-by.cjs +271 -0
- package/dist/cjs/query/compiler/group-by.cjs.map +1 -0
- package/dist/cjs/query/compiler/group-by.d.cts +7 -0
- package/dist/cjs/query/compiler/index.cjs +181 -0
- package/dist/cjs/query/compiler/index.cjs.map +1 -0
- package/dist/cjs/query/compiler/index.d.cts +15 -0
- package/dist/cjs/query/compiler/joins.cjs +116 -0
- package/dist/cjs/query/compiler/joins.cjs.map +1 -0
- package/dist/cjs/query/compiler/joins.d.cts +11 -0
- package/dist/cjs/query/compiler/order-by.cjs +89 -0
- package/dist/cjs/query/compiler/order-by.cjs.map +1 -0
- package/dist/cjs/query/compiler/order-by.d.cts +9 -0
- package/dist/cjs/query/compiler/select.cjs +57 -0
- package/dist/cjs/query/compiler/select.cjs.map +1 -0
- package/dist/cjs/query/compiler/select.d.cts +15 -0
- package/dist/cjs/query/index.d.cts +6 -5
- package/dist/cjs/query/ir.cjs +57 -0
- package/dist/cjs/query/ir.cjs.map +1 -0
- package/dist/cjs/query/ir.d.cts +81 -0
- package/dist/cjs/query/live-query-collection.cjs +224 -0
- package/dist/cjs/query/live-query-collection.cjs.map +1 -0
- package/dist/cjs/query/live-query-collection.d.cts +124 -0
- package/dist/cjs/transactions.cjs +20 -13
- package/dist/cjs/transactions.cjs.map +1 -1
- package/dist/cjs/transactions.d.cts +10 -1
- package/dist/cjs/types.d.cts +13 -0
- package/dist/esm/collection.d.ts +18 -21
- package/dist/esm/collection.js +118 -105
- package/dist/esm/collection.js.map +1 -1
- package/dist/esm/index.d.ts +0 -1
- package/dist/esm/index.js +34 -12
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/query/builder/functions.d.ts +38 -0
- package/dist/esm/query/builder/functions.js +107 -0
- package/dist/esm/query/builder/functions.js.map +1 -0
- package/dist/esm/query/builder/index.d.ts +324 -0
- package/dist/esm/query/builder/index.js +499 -0
- package/dist/esm/query/builder/index.js.map +1 -0
- package/dist/esm/query/builder/ref-proxy.d.ts +28 -0
- package/dist/esm/query/builder/ref-proxy.js +96 -0
- package/dist/esm/query/builder/ref-proxy.js.map +1 -0
- package/dist/esm/query/builder/types.d.ts +80 -0
- package/dist/esm/query/compiler/evaluators.d.ts +11 -0
- package/dist/esm/query/compiler/evaluators.js +261 -0
- package/dist/esm/query/compiler/evaluators.js.map +1 -0
- package/dist/esm/query/compiler/group-by.d.ts +7 -0
- package/dist/esm/query/compiler/group-by.js +271 -0
- package/dist/esm/query/compiler/group-by.js.map +1 -0
- package/dist/esm/query/compiler/index.d.ts +15 -0
- package/dist/esm/query/compiler/index.js +181 -0
- package/dist/esm/query/compiler/index.js.map +1 -0
- package/dist/esm/query/compiler/joins.d.ts +11 -0
- package/dist/esm/query/compiler/joins.js +116 -0
- package/dist/esm/query/compiler/joins.js.map +1 -0
- package/dist/esm/query/compiler/order-by.d.ts +9 -0
- package/dist/esm/query/compiler/order-by.js +89 -0
- package/dist/esm/query/compiler/order-by.js.map +1 -0
- package/dist/esm/query/compiler/select.d.ts +15 -0
- package/dist/esm/query/compiler/select.js +57 -0
- package/dist/esm/query/compiler/select.js.map +1 -0
- package/dist/esm/query/index.d.ts +6 -5
- package/dist/esm/query/ir.d.ts +81 -0
- package/dist/esm/query/ir.js +57 -0
- package/dist/esm/query/ir.js.map +1 -0
- package/dist/esm/query/live-query-collection.d.ts +124 -0
- package/dist/esm/query/live-query-collection.js +224 -0
- package/dist/esm/query/live-query-collection.js.map +1 -0
- package/dist/esm/transactions.d.ts +10 -1
- package/dist/esm/transactions.js +20 -13
- package/dist/esm/transactions.js.map +1 -1
- package/dist/esm/types.d.ts +13 -0
- package/package.json +3 -4
- package/src/collection.ts +152 -129
- package/src/index.ts +0 -1
- package/src/query/builder/functions.ts +267 -0
- package/src/query/builder/index.ts +648 -0
- package/src/query/builder/ref-proxy.ts +156 -0
- package/src/query/builder/types.ts +278 -0
- package/src/query/compiler/evaluators.ts +315 -0
- package/src/query/compiler/group-by.ts +428 -0
- package/src/query/compiler/index.ts +276 -0
- package/src/query/compiler/joins.ts +228 -0
- package/src/query/compiler/order-by.ts +139 -0
- package/src/query/compiler/select.ts +173 -0
- package/src/query/index.ts +64 -5
- package/src/query/ir.ts +128 -0
- package/src/query/live-query-collection.ts +509 -0
- package/src/transactions.ts +27 -16
- package/src/types.ts +15 -0
- package/dist/cjs/query/compiled-query.cjs +0 -160
- package/dist/cjs/query/compiled-query.cjs.map +0 -1
- package/dist/cjs/query/compiled-query.d.cts +0 -20
- package/dist/cjs/query/evaluators.cjs +0 -161
- package/dist/cjs/query/evaluators.cjs.map +0 -1
- package/dist/cjs/query/evaluators.d.cts +0 -14
- package/dist/cjs/query/extractors.cjs +0 -122
- package/dist/cjs/query/extractors.cjs.map +0 -1
- package/dist/cjs/query/extractors.d.cts +0 -22
- package/dist/cjs/query/functions.cjs +0 -152
- package/dist/cjs/query/functions.cjs.map +0 -1
- package/dist/cjs/query/functions.d.cts +0 -21
- package/dist/cjs/query/group-by.cjs +0 -88
- package/dist/cjs/query/group-by.cjs.map +0 -1
- package/dist/cjs/query/group-by.d.cts +0 -40
- package/dist/cjs/query/joins.cjs +0 -141
- package/dist/cjs/query/joins.cjs.map +0 -1
- package/dist/cjs/query/joins.d.cts +0 -14
- package/dist/cjs/query/order-by.cjs +0 -185
- package/dist/cjs/query/order-by.cjs.map +0 -1
- package/dist/cjs/query/order-by.d.cts +0 -3
- package/dist/cjs/query/pipeline-compiler.cjs +0 -89
- package/dist/cjs/query/pipeline-compiler.cjs.map +0 -1
- package/dist/cjs/query/pipeline-compiler.d.cts +0 -10
- package/dist/cjs/query/query-builder.cjs +0 -307
- package/dist/cjs/query/query-builder.cjs.map +0 -1
- package/dist/cjs/query/query-builder.d.cts +0 -225
- package/dist/cjs/query/schema.d.cts +0 -100
- package/dist/cjs/query/select.cjs +0 -130
- package/dist/cjs/query/select.cjs.map +0 -1
- package/dist/cjs/query/select.d.cts +0 -3
- package/dist/cjs/query/types.d.cts +0 -189
- package/dist/cjs/query/utils.cjs +0 -154
- package/dist/cjs/query/utils.cjs.map +0 -1
- package/dist/cjs/query/utils.d.cts +0 -37
- package/dist/cjs/utils.cjs +0 -17
- package/dist/cjs/utils.cjs.map +0 -1
- package/dist/cjs/utils.d.cts +0 -3
- package/dist/esm/query/compiled-query.d.ts +0 -20
- package/dist/esm/query/compiled-query.js +0 -160
- package/dist/esm/query/compiled-query.js.map +0 -1
- package/dist/esm/query/evaluators.d.ts +0 -14
- package/dist/esm/query/evaluators.js +0 -161
- package/dist/esm/query/evaluators.js.map +0 -1
- package/dist/esm/query/extractors.d.ts +0 -22
- package/dist/esm/query/extractors.js +0 -122
- package/dist/esm/query/extractors.js.map +0 -1
- package/dist/esm/query/functions.d.ts +0 -21
- package/dist/esm/query/functions.js +0 -152
- package/dist/esm/query/functions.js.map +0 -1
- package/dist/esm/query/group-by.d.ts +0 -40
- package/dist/esm/query/group-by.js +0 -88
- package/dist/esm/query/group-by.js.map +0 -1
- package/dist/esm/query/joins.d.ts +0 -14
- package/dist/esm/query/joins.js +0 -141
- package/dist/esm/query/joins.js.map +0 -1
- package/dist/esm/query/order-by.d.ts +0 -3
- package/dist/esm/query/order-by.js +0 -185
- package/dist/esm/query/order-by.js.map +0 -1
- package/dist/esm/query/pipeline-compiler.d.ts +0 -10
- package/dist/esm/query/pipeline-compiler.js +0 -89
- package/dist/esm/query/pipeline-compiler.js.map +0 -1
- package/dist/esm/query/query-builder.d.ts +0 -225
- package/dist/esm/query/query-builder.js +0 -307
- package/dist/esm/query/query-builder.js.map +0 -1
- package/dist/esm/query/schema.d.ts +0 -100
- package/dist/esm/query/select.d.ts +0 -3
- package/dist/esm/query/select.js +0 -130
- package/dist/esm/query/select.js.map +0 -1
- package/dist/esm/query/types.d.ts +0 -189
- package/dist/esm/query/utils.d.ts +0 -37
- package/dist/esm/query/utils.js +0 -154
- package/dist/esm/query/utils.js.map +0 -1
- package/dist/esm/utils.d.ts +0 -3
- package/dist/esm/utils.js +0 -17
- package/dist/esm/utils.js.map +0 -1
- package/src/query/compiled-query.ts +0 -234
- package/src/query/evaluators.ts +0 -250
- package/src/query/extractors.ts +0 -214
- package/src/query/functions.ts +0 -297
- package/src/query/group-by.ts +0 -139
- package/src/query/joins.ts +0 -260
- package/src/query/order-by.ts +0 -264
- package/src/query/pipeline-compiler.ts +0 -149
- package/src/query/query-builder.ts +0 -902
- package/src/query/schema.ts +0 -268
- package/src/query/select.ts +0 -208
- package/src/query/types.ts +0 -418
- package/src/query/utils.ts +0 -245
- package/src/utils.ts +0 -15
package/dist/esm/utils.d.ts
DELETED
package/dist/esm/utils.js
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
function getLockedObjects() {
|
|
2
|
-
return /* @__PURE__ */ new Set();
|
|
3
|
-
}
|
|
4
|
-
let globalVersion = 0;
|
|
5
|
-
function getGlobalVersion() {
|
|
6
|
-
return globalVersion;
|
|
7
|
-
}
|
|
8
|
-
function advanceGlobalVersion() {
|
|
9
|
-
console.log(`==== advancing global version`, globalVersion + 1);
|
|
10
|
-
return globalVersion++;
|
|
11
|
-
}
|
|
12
|
-
export {
|
|
13
|
-
advanceGlobalVersion,
|
|
14
|
-
getGlobalVersion,
|
|
15
|
-
getLockedObjects
|
|
16
|
-
};
|
|
17
|
-
//# sourceMappingURL=utils.js.map
|
package/dist/esm/utils.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sources":["../../src/utils.ts"],"sourcesContent":["export function getLockedObjects(): Set<string> {\n // Stub implementation that returns an empty Set\n return new Set()\n}\n\nlet globalVersion = 0\n\nexport function getGlobalVersion(): number {\n return globalVersion\n}\n\nexport function advanceGlobalVersion(): number {\n console.log(`==== advancing global version`, globalVersion + 1)\n return globalVersion++\n}\n"],"names":[],"mappings":"AAAO,SAAS,mBAAgC;AAE9C,6BAAW,IAAI;AACjB;AAEA,IAAI,gBAAgB;AAEb,SAAS,mBAA2B;AAClC,SAAA;AACT;AAEO,SAAS,uBAA+B;AACrC,UAAA,IAAI,iCAAiC,gBAAgB,CAAC;AACvD,SAAA;AACT;"}
|
|
@@ -1,234 +0,0 @@
|
|
|
1
|
-
import { D2, MultiSet, output } from "@electric-sql/d2mini"
|
|
2
|
-
import { createCollection } from "../collection.js"
|
|
3
|
-
import { compileQueryPipeline } from "./pipeline-compiler.js"
|
|
4
|
-
import type { StandardSchemaV1 } from "@standard-schema/spec"
|
|
5
|
-
import type { Collection } from "../collection.js"
|
|
6
|
-
import type { ChangeMessage, ResolveType, SyncConfig } from "../types.js"
|
|
7
|
-
import type {
|
|
8
|
-
IStreamBuilder,
|
|
9
|
-
MultiSetArray,
|
|
10
|
-
RootStreamBuilder,
|
|
11
|
-
} from "@electric-sql/d2mini"
|
|
12
|
-
import type { QueryBuilder, ResultsFromContext } from "./query-builder.js"
|
|
13
|
-
import type { Context, Schema } from "./types.js"
|
|
14
|
-
|
|
15
|
-
export function compileQuery<TContext extends Context<Schema>>(
|
|
16
|
-
queryBuilder: QueryBuilder<TContext>
|
|
17
|
-
) {
|
|
18
|
-
return new CompiledQuery<
|
|
19
|
-
ResultsFromContext<TContext> & { _key?: string | number }
|
|
20
|
-
>(queryBuilder)
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export class CompiledQuery<TResults extends object = Record<string, unknown>> {
|
|
24
|
-
private graph: D2
|
|
25
|
-
private inputs: Record<string, RootStreamBuilder<any>>
|
|
26
|
-
private inputCollections: Record<string, Collection<any>>
|
|
27
|
-
private resultCollection: Collection<TResults>
|
|
28
|
-
public state: `compiled` | `running` | `stopped` = `compiled`
|
|
29
|
-
private unsubscribeCallbacks: Array<() => void> = []
|
|
30
|
-
|
|
31
|
-
constructor(queryBuilder: QueryBuilder<Context<Schema>>) {
|
|
32
|
-
const query = queryBuilder._query
|
|
33
|
-
const collections = query.collections
|
|
34
|
-
|
|
35
|
-
if (!collections) {
|
|
36
|
-
throw new Error(`No collections provided`)
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
this.inputCollections = collections
|
|
40
|
-
|
|
41
|
-
const graph = new D2()
|
|
42
|
-
const inputs = Object.fromEntries(
|
|
43
|
-
Object.entries(collections).map(([key]) => [key, graph.newInput<any>()])
|
|
44
|
-
)
|
|
45
|
-
|
|
46
|
-
// Use TResults directly to ensure type compatibility
|
|
47
|
-
const sync: SyncConfig<TResults>[`sync`] = ({
|
|
48
|
-
begin,
|
|
49
|
-
write,
|
|
50
|
-
commit,
|
|
51
|
-
collection,
|
|
52
|
-
}) => {
|
|
53
|
-
compileQueryPipeline<IStreamBuilder<[unknown, TResults]>>(
|
|
54
|
-
query,
|
|
55
|
-
inputs
|
|
56
|
-
).pipe(
|
|
57
|
-
output((data) => {
|
|
58
|
-
begin()
|
|
59
|
-
data
|
|
60
|
-
.getInner()
|
|
61
|
-
.reduce((acc, [[key, value], multiplicity]) => {
|
|
62
|
-
const changes = acc.get(key) || {
|
|
63
|
-
deletes: 0,
|
|
64
|
-
inserts: 0,
|
|
65
|
-
value,
|
|
66
|
-
}
|
|
67
|
-
if (multiplicity < 0) {
|
|
68
|
-
changes.deletes += Math.abs(multiplicity)
|
|
69
|
-
} else if (multiplicity > 0) {
|
|
70
|
-
changes.inserts += multiplicity
|
|
71
|
-
changes.value = value
|
|
72
|
-
}
|
|
73
|
-
acc.set(key, changes)
|
|
74
|
-
return acc
|
|
75
|
-
}, new Map<unknown, { deletes: number; inserts: number; value: TResults }>())
|
|
76
|
-
.forEach((changes, rawKey) => {
|
|
77
|
-
const { deletes, inserts, value } = changes
|
|
78
|
-
const valueWithKey = { ...value, _key: rawKey }
|
|
79
|
-
|
|
80
|
-
// Simple singular insert.
|
|
81
|
-
if (inserts && deletes === 0) {
|
|
82
|
-
write({
|
|
83
|
-
value: valueWithKey,
|
|
84
|
-
type: `insert`,
|
|
85
|
-
})
|
|
86
|
-
} else if (
|
|
87
|
-
// Insert & update(s) (updates are a delete & insert)
|
|
88
|
-
inserts > deletes ||
|
|
89
|
-
// Just update(s) but the item is already in the collection (so
|
|
90
|
-
// was inserted previously).
|
|
91
|
-
(inserts === deletes &&
|
|
92
|
-
collection.has(valueWithKey._key as string | number))
|
|
93
|
-
) {
|
|
94
|
-
write({
|
|
95
|
-
value: valueWithKey,
|
|
96
|
-
type: `update`,
|
|
97
|
-
})
|
|
98
|
-
// Only delete is left as an option
|
|
99
|
-
} else if (deletes > 0) {
|
|
100
|
-
write({
|
|
101
|
-
value: valueWithKey,
|
|
102
|
-
type: `delete`,
|
|
103
|
-
})
|
|
104
|
-
} else {
|
|
105
|
-
throw new Error(
|
|
106
|
-
`This should never happen ${JSON.stringify(changes)}`
|
|
107
|
-
)
|
|
108
|
-
}
|
|
109
|
-
})
|
|
110
|
-
commit()
|
|
111
|
-
})
|
|
112
|
-
)
|
|
113
|
-
graph.finalize()
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
this.graph = graph
|
|
117
|
-
this.inputs = inputs
|
|
118
|
-
|
|
119
|
-
const compare = query.orderBy
|
|
120
|
-
? (
|
|
121
|
-
val1: ResolveType<
|
|
122
|
-
TResults,
|
|
123
|
-
StandardSchemaV1,
|
|
124
|
-
Record<string, unknown>
|
|
125
|
-
>,
|
|
126
|
-
val2: ResolveType<TResults, StandardSchemaV1, Record<string, unknown>>
|
|
127
|
-
): number => {
|
|
128
|
-
// The query builder always adds an _orderByIndex property if the results are ordered
|
|
129
|
-
const x = val1 as TResults & { _orderByIndex: number }
|
|
130
|
-
const y = val2 as TResults & { _orderByIndex: number }
|
|
131
|
-
if (x._orderByIndex < y._orderByIndex) {
|
|
132
|
-
return -1
|
|
133
|
-
} else if (x._orderByIndex > y._orderByIndex) {
|
|
134
|
-
return 1
|
|
135
|
-
} else {
|
|
136
|
-
return 0
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
: undefined
|
|
140
|
-
|
|
141
|
-
this.resultCollection = createCollection<TResults>({
|
|
142
|
-
getKey: (val: unknown) => {
|
|
143
|
-
return (val as any)._key
|
|
144
|
-
},
|
|
145
|
-
gcTime: 0,
|
|
146
|
-
startSync: true,
|
|
147
|
-
compare,
|
|
148
|
-
sync: {
|
|
149
|
-
sync: sync as unknown as (params: {
|
|
150
|
-
collection: Collection<
|
|
151
|
-
ResolveType<TResults, never, Record<string, unknown>>,
|
|
152
|
-
string | number,
|
|
153
|
-
{}
|
|
154
|
-
>
|
|
155
|
-
begin: () => void
|
|
156
|
-
write: (
|
|
157
|
-
message: Omit<
|
|
158
|
-
ChangeMessage<
|
|
159
|
-
ResolveType<TResults, never, Record<string, unknown>>,
|
|
160
|
-
string | number
|
|
161
|
-
>,
|
|
162
|
-
`key`
|
|
163
|
-
>
|
|
164
|
-
) => void
|
|
165
|
-
commit: () => void
|
|
166
|
-
}) => void,
|
|
167
|
-
},
|
|
168
|
-
}) as unknown as Collection<TResults, string | number, {}>
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
get results() {
|
|
172
|
-
return this.resultCollection
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
private sendChangesToInput(
|
|
176
|
-
inputKey: string,
|
|
177
|
-
changes: Array<ChangeMessage>,
|
|
178
|
-
getKey: (item: ChangeMessage[`value`]) => any
|
|
179
|
-
) {
|
|
180
|
-
const input = this.inputs[inputKey]!
|
|
181
|
-
const multiSetArray: MultiSetArray<unknown> = []
|
|
182
|
-
for (const change of changes) {
|
|
183
|
-
const key = getKey(change.value)
|
|
184
|
-
if (change.type === `insert`) {
|
|
185
|
-
multiSetArray.push([[key, change.value], 1])
|
|
186
|
-
} else if (change.type === `update`) {
|
|
187
|
-
multiSetArray.push([[key, change.previousValue], -1])
|
|
188
|
-
multiSetArray.push([[key, change.value], 1])
|
|
189
|
-
} else {
|
|
190
|
-
// change.type === `delete`
|
|
191
|
-
multiSetArray.push([[key, change.value], -1])
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
input.sendData(new MultiSet(multiSetArray))
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
private runGraph() {
|
|
198
|
-
this.graph.run()
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
start() {
|
|
202
|
-
if (this.state === `running`) {
|
|
203
|
-
throw new Error(`Query is already running`)
|
|
204
|
-
} else if (this.state === `stopped`) {
|
|
205
|
-
throw new Error(`Query is stopped`)
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
// Subscribe to changes
|
|
209
|
-
Object.entries(this.inputCollections).forEach(([key, collection]) => {
|
|
210
|
-
const unsubscribe = collection.subscribeChanges(
|
|
211
|
-
(changes) => {
|
|
212
|
-
this.sendChangesToInput(key, changes, collection.config.getKey)
|
|
213
|
-
this.runGraph()
|
|
214
|
-
},
|
|
215
|
-
{ includeInitialState: true }
|
|
216
|
-
)
|
|
217
|
-
|
|
218
|
-
this.unsubscribeCallbacks.push(unsubscribe)
|
|
219
|
-
})
|
|
220
|
-
|
|
221
|
-
this.runGraph()
|
|
222
|
-
|
|
223
|
-
this.state = `running`
|
|
224
|
-
return () => {
|
|
225
|
-
this.stop()
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
stop() {
|
|
230
|
-
this.unsubscribeCallbacks.forEach((unsubscribe) => unsubscribe())
|
|
231
|
-
this.unsubscribeCallbacks = []
|
|
232
|
-
this.state = `stopped`
|
|
233
|
-
}
|
|
234
|
-
}
|
package/src/query/evaluators.ts
DELETED
|
@@ -1,250 +0,0 @@
|
|
|
1
|
-
import { evaluateOperandOnNamespacedRow } from "./extractors.js"
|
|
2
|
-
import { compareValues, convertLikeToRegex, isValueInArray } from "./utils.js"
|
|
3
|
-
import type {
|
|
4
|
-
Comparator,
|
|
5
|
-
Condition,
|
|
6
|
-
ConditionOperand,
|
|
7
|
-
LogicalOperator,
|
|
8
|
-
SimpleCondition,
|
|
9
|
-
Where,
|
|
10
|
-
WhereCallback,
|
|
11
|
-
} from "./schema.js"
|
|
12
|
-
import type { NamespacedRow } from "../types.js"
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Evaluates a Where clause (which is always an array of conditions and/or callbacks) against a nested row structure
|
|
16
|
-
*/
|
|
17
|
-
export function evaluateWhereOnNamespacedRow(
|
|
18
|
-
namespacedRow: NamespacedRow,
|
|
19
|
-
where: Where,
|
|
20
|
-
mainTableAlias?: string,
|
|
21
|
-
joinedTableAlias?: string
|
|
22
|
-
): boolean {
|
|
23
|
-
// Where is always an array of conditions and/or callbacks
|
|
24
|
-
// Evaluate all items and combine with AND logic
|
|
25
|
-
return where.every((item) => {
|
|
26
|
-
if (typeof item === `function`) {
|
|
27
|
-
return (item as WhereCallback)(namespacedRow)
|
|
28
|
-
} else {
|
|
29
|
-
return evaluateConditionOnNamespacedRow(
|
|
30
|
-
namespacedRow,
|
|
31
|
-
item as Condition,
|
|
32
|
-
mainTableAlias,
|
|
33
|
-
joinedTableAlias
|
|
34
|
-
)
|
|
35
|
-
}
|
|
36
|
-
})
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Evaluates a condition against a nested row structure
|
|
41
|
-
*/
|
|
42
|
-
export function evaluateConditionOnNamespacedRow(
|
|
43
|
-
namespacedRow: NamespacedRow,
|
|
44
|
-
condition: Condition,
|
|
45
|
-
mainTableAlias?: string,
|
|
46
|
-
joinedTableAlias?: string
|
|
47
|
-
): boolean {
|
|
48
|
-
// Handle simple conditions with exactly 3 elements
|
|
49
|
-
if (condition.length === 3 && !Array.isArray(condition[0])) {
|
|
50
|
-
const [left, comparator, right] = condition as SimpleCondition
|
|
51
|
-
return evaluateSimpleConditionOnNamespacedRow(
|
|
52
|
-
namespacedRow,
|
|
53
|
-
left,
|
|
54
|
-
comparator,
|
|
55
|
-
right,
|
|
56
|
-
mainTableAlias,
|
|
57
|
-
joinedTableAlias
|
|
58
|
-
)
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
// Handle flat composite conditions (multiple conditions in a single array)
|
|
62
|
-
if (
|
|
63
|
-
condition.length > 3 &&
|
|
64
|
-
!Array.isArray(condition[0]) &&
|
|
65
|
-
typeof condition[1] === `string` &&
|
|
66
|
-
![`and`, `or`].includes(condition[1] as string)
|
|
67
|
-
) {
|
|
68
|
-
// Start with the first condition (first 3 elements)
|
|
69
|
-
let result = evaluateSimpleConditionOnNamespacedRow(
|
|
70
|
-
namespacedRow,
|
|
71
|
-
condition[0],
|
|
72
|
-
condition[1] as Comparator,
|
|
73
|
-
condition[2],
|
|
74
|
-
mainTableAlias,
|
|
75
|
-
joinedTableAlias
|
|
76
|
-
)
|
|
77
|
-
|
|
78
|
-
// Process the rest in groups: logical operator, then 3 elements for each condition
|
|
79
|
-
for (let i = 3; i < condition.length; i += 4) {
|
|
80
|
-
const logicalOp = condition[i] as LogicalOperator
|
|
81
|
-
|
|
82
|
-
// Make sure we have a complete condition to evaluate
|
|
83
|
-
if (i + 3 <= condition.length) {
|
|
84
|
-
const nextResult = evaluateSimpleConditionOnNamespacedRow(
|
|
85
|
-
namespacedRow,
|
|
86
|
-
condition[i + 1],
|
|
87
|
-
condition[i + 2] as Comparator,
|
|
88
|
-
condition[i + 3],
|
|
89
|
-
mainTableAlias,
|
|
90
|
-
joinedTableAlias
|
|
91
|
-
)
|
|
92
|
-
|
|
93
|
-
// Apply the logical operator
|
|
94
|
-
if (logicalOp === `and`) {
|
|
95
|
-
result = result && nextResult
|
|
96
|
-
} else {
|
|
97
|
-
// logicalOp === `or`
|
|
98
|
-
result = result || nextResult
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
return result
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
// Handle nested composite conditions where the first element is an array
|
|
107
|
-
if (condition.length > 0 && Array.isArray(condition[0])) {
|
|
108
|
-
// Start with the first condition
|
|
109
|
-
let result = evaluateConditionOnNamespacedRow(
|
|
110
|
-
namespacedRow,
|
|
111
|
-
condition[0] as Condition,
|
|
112
|
-
mainTableAlias,
|
|
113
|
-
joinedTableAlias
|
|
114
|
-
)
|
|
115
|
-
|
|
116
|
-
// Process the rest of the conditions and logical operators in pairs
|
|
117
|
-
for (let i = 1; i < condition.length; i += 2) {
|
|
118
|
-
if (i + 1 >= condition.length) break // Make sure we have a pair
|
|
119
|
-
|
|
120
|
-
const operator = condition[i] as LogicalOperator
|
|
121
|
-
const nextCondition = condition[i + 1] as Condition
|
|
122
|
-
|
|
123
|
-
// Apply the logical operator
|
|
124
|
-
if (operator === `and`) {
|
|
125
|
-
result =
|
|
126
|
-
result &&
|
|
127
|
-
evaluateConditionOnNamespacedRow(
|
|
128
|
-
namespacedRow,
|
|
129
|
-
nextCondition,
|
|
130
|
-
mainTableAlias,
|
|
131
|
-
joinedTableAlias
|
|
132
|
-
)
|
|
133
|
-
} else {
|
|
134
|
-
// logicalOp === `or`
|
|
135
|
-
result =
|
|
136
|
-
result ||
|
|
137
|
-
evaluateConditionOnNamespacedRow(
|
|
138
|
-
namespacedRow,
|
|
139
|
-
nextCondition,
|
|
140
|
-
mainTableAlias,
|
|
141
|
-
joinedTableAlias
|
|
142
|
-
)
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
return result
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
// Fallback - this should not happen with valid conditions
|
|
150
|
-
return true
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
/**
|
|
154
|
-
* Evaluates a simple condition against a nested row structure
|
|
155
|
-
*/
|
|
156
|
-
export function evaluateSimpleConditionOnNamespacedRow(
|
|
157
|
-
namespacedRow: Record<string, unknown>,
|
|
158
|
-
left: ConditionOperand,
|
|
159
|
-
comparator: Comparator,
|
|
160
|
-
right: ConditionOperand,
|
|
161
|
-
mainTableAlias?: string,
|
|
162
|
-
joinedTableAlias?: string
|
|
163
|
-
): boolean {
|
|
164
|
-
const leftValue = evaluateOperandOnNamespacedRow(
|
|
165
|
-
namespacedRow,
|
|
166
|
-
left,
|
|
167
|
-
mainTableAlias,
|
|
168
|
-
joinedTableAlias
|
|
169
|
-
)
|
|
170
|
-
|
|
171
|
-
const rightValue = evaluateOperandOnNamespacedRow(
|
|
172
|
-
namespacedRow,
|
|
173
|
-
right,
|
|
174
|
-
mainTableAlias,
|
|
175
|
-
joinedTableAlias
|
|
176
|
-
)
|
|
177
|
-
|
|
178
|
-
// The rest of the function remains the same as evaluateSimpleCondition
|
|
179
|
-
switch (comparator) {
|
|
180
|
-
case `=`:
|
|
181
|
-
return leftValue === rightValue
|
|
182
|
-
case `!=`:
|
|
183
|
-
return leftValue !== rightValue
|
|
184
|
-
case `<`:
|
|
185
|
-
return compareValues(leftValue, rightValue, `<`)
|
|
186
|
-
case `<=`:
|
|
187
|
-
return compareValues(leftValue, rightValue, `<=`)
|
|
188
|
-
case `>`:
|
|
189
|
-
return compareValues(leftValue, rightValue, `>`)
|
|
190
|
-
case `>=`:
|
|
191
|
-
return compareValues(leftValue, rightValue, `>=`)
|
|
192
|
-
case `like`:
|
|
193
|
-
case `not like`:
|
|
194
|
-
if (typeof leftValue === `string` && typeof rightValue === `string`) {
|
|
195
|
-
// Convert SQL LIKE pattern to proper regex pattern
|
|
196
|
-
const pattern = convertLikeToRegex(rightValue)
|
|
197
|
-
const matches = new RegExp(`^${pattern}$`, `i`).test(leftValue)
|
|
198
|
-
return comparator === `like` ? matches : !matches
|
|
199
|
-
}
|
|
200
|
-
return comparator === `like` ? false : true
|
|
201
|
-
case `in`:
|
|
202
|
-
// If right value is not an array, we can't do an IN operation
|
|
203
|
-
if (!Array.isArray(rightValue)) {
|
|
204
|
-
return false
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
// For empty arrays, nothing is contained in them
|
|
208
|
-
if (rightValue.length === 0) {
|
|
209
|
-
return false
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
// Handle array-to-array comparison (check if any element in leftValue exists in rightValue)
|
|
213
|
-
if (Array.isArray(leftValue)) {
|
|
214
|
-
return leftValue.some((item) => isValueInArray(item, rightValue))
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
// Handle single value comparison
|
|
218
|
-
return isValueInArray(leftValue, rightValue)
|
|
219
|
-
|
|
220
|
-
case `not in`:
|
|
221
|
-
// If right value is not an array, everything is "not in" it
|
|
222
|
-
if (!Array.isArray(rightValue)) {
|
|
223
|
-
return true
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
// For empty arrays, everything is "not in" them
|
|
227
|
-
if (rightValue.length === 0) {
|
|
228
|
-
return true
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
// Handle array-to-array comparison (check if no element in leftValue exists in rightValue)
|
|
232
|
-
if (Array.isArray(leftValue)) {
|
|
233
|
-
return !leftValue.some((item) => isValueInArray(item, rightValue))
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
// Handle single value comparison
|
|
237
|
-
return !isValueInArray(leftValue, rightValue)
|
|
238
|
-
|
|
239
|
-
case `is`:
|
|
240
|
-
return leftValue === rightValue
|
|
241
|
-
case `is not`:
|
|
242
|
-
// Properly handle null/undefined checks
|
|
243
|
-
if (rightValue === null) {
|
|
244
|
-
return leftValue !== null && leftValue !== undefined
|
|
245
|
-
}
|
|
246
|
-
return leftValue !== rightValue
|
|
247
|
-
default:
|
|
248
|
-
return false
|
|
249
|
-
}
|
|
250
|
-
}
|