@anfenn/dync 1.0.7 → 1.0.9
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/{chunk-PCA4XM2N.js → chunk-MOYMEJP5.js} +50 -160
- package/dist/chunk-MOYMEJP5.js.map +1 -0
- package/dist/{dexie-1_xyU5MV.d.cts → dexie-BqktVP7s.d.cts} +5 -9
- package/dist/{dexie-ChZ0o0Sz.d.ts → dexie-DRLMKLl5.d.ts} +5 -9
- package/dist/dexie.cjs +1 -7
- package/dist/dexie.cjs.map +1 -1
- package/dist/dexie.d.cts +1 -1
- package/dist/dexie.d.ts +1 -1
- package/dist/dexie.js +1 -7
- package/dist/dexie.js.map +1 -1
- package/dist/index.cjs +49 -159
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/{index.shared-DsDBNWlz.d.cts → index.shared-C8JTfet7.d.cts} +1 -1
- package/dist/{index.shared-Byhq6TyU.d.ts → index.shared-DajtjVW7.d.ts} +1 -1
- package/dist/react/index.d.cts +2 -2
- package/dist/react/index.d.ts +2 -2
- package/dist/react/index.js +1 -1
- package/package.json +1 -1
- package/src/storage/dexie/DexieTable.ts +2 -9
- package/src/storage/memory/MemoryTable.ts +3 -8
- package/src/storage/memory/MemoryWhereClause.ts +5 -5
- package/src/storage/sqlite/SQLiteTable.ts +3 -8
- package/src/storage/sqlite/SQLiteWhereClause.ts +41 -153
- package/src/storage/sqlite/helpers.ts +0 -6
- package/src/storage/sqlite/types.ts +1 -8
- package/src/storage/types.ts +1 -3
- package/dist/chunk-PCA4XM2N.js.map +0 -1
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { A as AfterRemoteAddCallback, a as ApiFunctions, d as BatchFirstLoadResult, b as BatchPushPayload, c as BatchPushResult, B as BatchSync, C as ConflictResolutionStrategy, D as Dync, F as FirstLoadProgress, e as FirstLoadProgressCallback, f as MissingRemoteRecordDuringUpdateCallback, M as MissingRemoteRecordStrategy, g as MutationEvent, S as SyncAction, h as SyncOptions, i as SyncState, j as SyncedRecord, T as TableMap } from './index.shared-
|
|
2
|
-
export { M as MemoryAdapter, a as MemoryQueryContext, S as SQLiteAdapter, b as SqliteQueryContext, c as StorageAdapter } from './dexie-
|
|
1
|
+
export { A as AfterRemoteAddCallback, a as ApiFunctions, d as BatchFirstLoadResult, b as BatchPushPayload, c as BatchPushResult, B as BatchSync, C as ConflictResolutionStrategy, D as Dync, F as FirstLoadProgress, e as FirstLoadProgressCallback, f as MissingRemoteRecordDuringUpdateCallback, M as MissingRemoteRecordStrategy, g as MutationEvent, S as SyncAction, h as SyncOptions, i as SyncState, j as SyncedRecord, T as TableMap } from './index.shared-C8JTfet7.cjs';
|
|
2
|
+
export { M as MemoryAdapter, a as MemoryQueryContext, S as SQLiteAdapter, b as SqliteQueryContext, c as StorageAdapter } from './dexie-BqktVP7s.cjs';
|
|
3
3
|
export { S as SQLiteDatabaseDriver, b as SQLiteQueryResult, a as SQLiteRunResult } from './types-CSbIAfu2.cjs';
|
|
4
4
|
import 'dexie';
|
|
5
5
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { A as AfterRemoteAddCallback, a as ApiFunctions, d as BatchFirstLoadResult, b as BatchPushPayload, c as BatchPushResult, B as BatchSync, C as ConflictResolutionStrategy, D as Dync, F as FirstLoadProgress, e as FirstLoadProgressCallback, f as MissingRemoteRecordDuringUpdateCallback, M as MissingRemoteRecordStrategy, g as MutationEvent, S as SyncAction, h as SyncOptions, i as SyncState, j as SyncedRecord, T as TableMap } from './index.shared-
|
|
2
|
-
export { M as MemoryAdapter, a as MemoryQueryContext, S as SQLiteAdapter, b as SqliteQueryContext, c as StorageAdapter } from './dexie-
|
|
1
|
+
export { A as AfterRemoteAddCallback, a as ApiFunctions, d as BatchFirstLoadResult, b as BatchPushPayload, c as BatchPushResult, B as BatchSync, C as ConflictResolutionStrategy, D as Dync, F as FirstLoadProgress, e as FirstLoadProgressCallback, f as MissingRemoteRecordDuringUpdateCallback, M as MissingRemoteRecordStrategy, g as MutationEvent, S as SyncAction, h as SyncOptions, i as SyncState, j as SyncedRecord, T as TableMap } from './index.shared-DajtjVW7.js';
|
|
2
|
+
export { M as MemoryAdapter, a as MemoryQueryContext, S as SQLiteAdapter, b as SqliteQueryContext, c as StorageAdapter } from './dexie-DRLMKLl5.js';
|
|
3
3
|
export { S as SQLiteDatabaseDriver, b as SQLiteQueryResult, a as SQLiteRunResult } from './types-CSbIAfu2.js';
|
|
4
4
|
import 'dexie';
|
|
5
5
|
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { d as StorageTable, c as StorageAdapter, T as TableSchemaDefinition, D as DexieQueryContext, b as SqliteQueryContext, a as MemoryQueryContext } from './dexie-
|
|
1
|
+
import { d as StorageTable, c as StorageAdapter, T as TableSchemaDefinition, D as DexieQueryContext, b as SqliteQueryContext, a as MemoryQueryContext } from './dexie-BqktVP7s.cjs';
|
|
2
2
|
import { c as SQLiteVersionConfigurator } from './types-CSbIAfu2.cjs';
|
|
3
3
|
|
|
4
4
|
type LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'none';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { d as StorageTable, c as StorageAdapter, T as TableSchemaDefinition, D as DexieQueryContext, b as SqliteQueryContext, a as MemoryQueryContext } from './dexie-
|
|
1
|
+
import { d as StorageTable, c as StorageAdapter, T as TableSchemaDefinition, D as DexieQueryContext, b as SqliteQueryContext, a as MemoryQueryContext } from './dexie-DRLMKLl5.js';
|
|
2
2
|
import { c as SQLiteVersionConfigurator } from './types-CSbIAfu2.js';
|
|
3
3
|
|
|
4
4
|
type LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'none';
|
package/dist/react/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { a as ApiFunctions, h as SyncOptions, B as BatchSync, D as Dync, i as SyncState } from '../index.shared-
|
|
2
|
-
import { c as StorageAdapter } from '../dexie-
|
|
1
|
+
import { a as ApiFunctions, h as SyncOptions, B as BatchSync, D as Dync, i as SyncState } from '../index.shared-C8JTfet7.cjs';
|
|
2
|
+
import { c as StorageAdapter } from '../dexie-BqktVP7s.cjs';
|
|
3
3
|
import '../types-CSbIAfu2.cjs';
|
|
4
4
|
import 'dexie';
|
|
5
5
|
|
package/dist/react/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { a as ApiFunctions, h as SyncOptions, B as BatchSync, D as Dync, i as SyncState } from '../index.shared-
|
|
2
|
-
import { c as StorageAdapter } from '../dexie-
|
|
1
|
+
import { a as ApiFunctions, h as SyncOptions, B as BatchSync, D as Dync, i as SyncState } from '../index.shared-DajtjVW7.js';
|
|
2
|
+
import { c as StorageAdapter } from '../dexie-DRLMKLl5.js';
|
|
3
3
|
import '../types-CSbIAfu2.js';
|
|
4
4
|
import 'dexie';
|
|
5
5
|
|
package/dist/react/index.js
CHANGED
package/package.json
CHANGED
|
@@ -8,7 +8,6 @@ export class DexieTable<T = any> implements StorageTable<T> {
|
|
|
8
8
|
readonly name: string;
|
|
9
9
|
readonly schema: unknown;
|
|
10
10
|
readonly primaryKey: unknown;
|
|
11
|
-
readonly hook: unknown;
|
|
12
11
|
readonly raw = Object.freeze({
|
|
13
12
|
add: (item: T): Promise<string> => this.table.add(item) as Promise<string>,
|
|
14
13
|
put: (item: T): Promise<string> => this.table.put(item) as Promise<string>,
|
|
@@ -29,7 +28,6 @@ export class DexieTable<T = any> implements StorageTable<T> {
|
|
|
29
28
|
this.name = table.name;
|
|
30
29
|
this.schema = table.schema;
|
|
31
30
|
this.primaryKey = table.schema?.primKey;
|
|
32
|
-
this.hook = table.hook;
|
|
33
31
|
}
|
|
34
32
|
|
|
35
33
|
add(item: AddItem<T>): Promise<string> {
|
|
@@ -84,8 +82,8 @@ export class DexieTable<T = any> implements StorageTable<T> {
|
|
|
84
82
|
return this.table.bulkDelete(keys as any);
|
|
85
83
|
}
|
|
86
84
|
|
|
87
|
-
where(index: string
|
|
88
|
-
return new DexieWhereClause(this.table.where(
|
|
85
|
+
where(index: string): StorageWhereClause<T> {
|
|
86
|
+
return new DexieWhereClause(this.table.where(index));
|
|
89
87
|
}
|
|
90
88
|
|
|
91
89
|
orderBy(index: string | string[]): StorageCollection<T> {
|
|
@@ -104,11 +102,6 @@ export class DexieTable<T = any> implements StorageTable<T> {
|
|
|
104
102
|
return new DexieCollection(this.table.limit(count));
|
|
105
103
|
}
|
|
106
104
|
|
|
107
|
-
mapToClass(ctor: new (...args: any[]) => any): StorageTable<T> {
|
|
108
|
-
this.table.mapToClass(ctor as any);
|
|
109
|
-
return this;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
105
|
async each(callback: (item: T) => void | Promise<void>): Promise<void> {
|
|
113
106
|
const tasks: Array<void | Promise<void>> = [];
|
|
114
107
|
await this.table.each((item) => {
|
|
@@ -10,7 +10,6 @@ export class MemoryTable<T extends MemoryRecord = MemoryRecord> implements Stora
|
|
|
10
10
|
readonly name: string;
|
|
11
11
|
readonly schema: unknown = undefined;
|
|
12
12
|
readonly primaryKey: unknown = LOCAL_PK;
|
|
13
|
-
readonly hook: unknown = Object.freeze({});
|
|
14
13
|
readonly raw: {
|
|
15
14
|
add: (item: T) => Promise<string>;
|
|
16
15
|
put: (item: T) => Promise<string>;
|
|
@@ -133,7 +132,7 @@ export class MemoryTable<T extends MemoryRecord = MemoryRecord> implements Stora
|
|
|
133
132
|
}
|
|
134
133
|
}
|
|
135
134
|
|
|
136
|
-
where(index: string
|
|
135
|
+
where(index: string): StorageWhereClause<T> {
|
|
137
136
|
return this.createWhereClause(index);
|
|
138
137
|
}
|
|
139
138
|
|
|
@@ -155,10 +154,6 @@ export class MemoryTable<T extends MemoryRecord = MemoryRecord> implements Stora
|
|
|
155
154
|
return this.createCollection({ limit: count });
|
|
156
155
|
}
|
|
157
156
|
|
|
158
|
-
mapToClass(_ctor: new (...args: any[]) => any): StorageTable<T> {
|
|
159
|
-
return this;
|
|
160
|
-
}
|
|
161
|
-
|
|
162
157
|
async each(callback: (item: T) => void | Promise<void>): Promise<void> {
|
|
163
158
|
for (const [, record] of this.entries()) {
|
|
164
159
|
await callback(this.cloneRecord(record));
|
|
@@ -187,8 +182,8 @@ export class MemoryTable<T extends MemoryRecord = MemoryRecord> implements Stora
|
|
|
187
182
|
});
|
|
188
183
|
}
|
|
189
184
|
|
|
190
|
-
createWhereClause(
|
|
191
|
-
return new MemoryWhereClause(this,
|
|
185
|
+
createWhereClause(column: string, baseCollection?: MemoryCollection<T>): MemoryWhereClause<T> {
|
|
186
|
+
return new MemoryWhereClause(this, column, baseCollection);
|
|
192
187
|
}
|
|
193
188
|
|
|
194
189
|
entries(): Array<[string, T]> {
|
|
@@ -5,12 +5,12 @@ import type { MemoryCollection } from './MemoryCollection';
|
|
|
5
5
|
|
|
6
6
|
export class MemoryWhereClause<T extends MemoryRecord = MemoryRecord> implements StorageWhereClause<T> {
|
|
7
7
|
private readonly table: MemoryTable<T>;
|
|
8
|
-
private readonly
|
|
8
|
+
private readonly column: string;
|
|
9
9
|
private readonly baseCollection?: MemoryCollection<T>;
|
|
10
10
|
|
|
11
|
-
constructor(table: MemoryTable<T>,
|
|
11
|
+
constructor(table: MemoryTable<T>, column: string, baseCollection?: MemoryCollection<T>) {
|
|
12
12
|
this.table = table;
|
|
13
|
-
this.
|
|
13
|
+
this.column = column;
|
|
14
14
|
this.baseCollection = baseCollection;
|
|
15
15
|
}
|
|
16
16
|
|
|
@@ -116,10 +116,10 @@ export class MemoryWhereClause<T extends MemoryRecord = MemoryRecord> implements
|
|
|
116
116
|
}
|
|
117
117
|
|
|
118
118
|
private createCollection(predicate: (indexValue: unknown) => boolean): StorageCollection<T> {
|
|
119
|
-
const condition = (record: T, _key: string): boolean => predicate(this.table.getIndexValue(record, this.
|
|
119
|
+
const condition = (record: T, _key: string): boolean => predicate(this.table.getIndexValue(record, this.column));
|
|
120
120
|
if (this.baseCollection) {
|
|
121
121
|
const combined = (record: T, key: string): boolean =>
|
|
122
|
-
this.baseCollection!.matches(record, key) || predicate(this.table.getIndexValue(record, this.
|
|
122
|
+
this.baseCollection!.matches(record, key) || predicate(this.table.getIndexValue(record, this.column));
|
|
123
123
|
return this.table.createCollectionFromPredicate(combined, this.baseCollection);
|
|
124
124
|
}
|
|
125
125
|
return this.table.createCollectionFromPredicate(condition);
|
|
@@ -9,7 +9,6 @@ import { cloneValue, createDefaultState, normalizeComparableValue, quoteIdentifi
|
|
|
9
9
|
export class SQLiteTable<T = any> implements StorageTable<T> {
|
|
10
10
|
readonly name: string;
|
|
11
11
|
readonly schema: SQLiteTableSchemaMetadata;
|
|
12
|
-
readonly hook: unknown = Object.freeze({});
|
|
13
12
|
readonly raw: {
|
|
14
13
|
add: (item: T) => Promise<string>;
|
|
15
14
|
put: (item: T) => Promise<string>;
|
|
@@ -224,7 +223,7 @@ export class SQLiteTable<T = any> implements StorageTable<T> {
|
|
|
224
223
|
await this.adapter.run(`DELETE FROM ${quoteIdentifier(this.name)} WHERE ${quoteIdentifier(LOCAL_PK)} IN (${placeholders})`, validKeys);
|
|
225
224
|
}
|
|
226
225
|
|
|
227
|
-
where(index: string
|
|
226
|
+
where(index: string): StorageWhereClause<T> {
|
|
228
227
|
return this.createWhereClause(index);
|
|
229
228
|
}
|
|
230
229
|
|
|
@@ -246,10 +245,6 @@ export class SQLiteTable<T = any> implements StorageTable<T> {
|
|
|
246
245
|
return this.createCollection({ limit: count });
|
|
247
246
|
}
|
|
248
247
|
|
|
249
|
-
mapToClass(_ctor: new (...args: any[]) => any): StorageTable<T> {
|
|
250
|
-
return this;
|
|
251
|
-
}
|
|
252
|
-
|
|
253
248
|
async each(callback: (item: T) => void | Promise<void>): Promise<void> {
|
|
254
249
|
const entries = await this.getEntries();
|
|
255
250
|
for (const entry of entries) {
|
|
@@ -277,8 +272,8 @@ export class SQLiteTable<T = any> implements StorageTable<T> {
|
|
|
277
272
|
});
|
|
278
273
|
}
|
|
279
274
|
|
|
280
|
-
createWhereClause(
|
|
281
|
-
return new SQLiteWhereClause(this,
|
|
275
|
+
createWhereClause(column: string, baseCollection?: SQLiteCollection<T>): SQLiteWhereClause<T> {
|
|
276
|
+
return new SQLiteWhereClause(this, column, baseCollection);
|
|
282
277
|
}
|
|
283
278
|
|
|
284
279
|
async *iterateEntries(options?: SQLiteIterateEntriesOptions): AsyncGenerator<TableEntry<T>> {
|
|
@@ -5,55 +5,20 @@ import { SQLiteCollection } from './SQLiteCollection';
|
|
|
5
5
|
|
|
6
6
|
export class SQLiteWhereClause<T = any> implements StorageWhereClause<T> {
|
|
7
7
|
private readonly table: SQLiteTable<T>;
|
|
8
|
-
private readonly
|
|
8
|
+
private readonly column: string;
|
|
9
9
|
private readonly baseCollection?: SQLiteCollection<T>;
|
|
10
10
|
|
|
11
|
-
constructor(table: SQLiteTable<T>,
|
|
11
|
+
constructor(table: SQLiteTable<T>, column: string, baseCollection?: SQLiteCollection<T>) {
|
|
12
12
|
this.table = table;
|
|
13
|
-
this.
|
|
13
|
+
this.column = column;
|
|
14
14
|
this.baseCollection = baseCollection;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
private getColumn(): string {
|
|
18
|
-
// For compound indexes, we only support the first column in SQL conditions
|
|
19
|
-
// Complex compound index queries fall back to JS
|
|
20
|
-
if (Array.isArray(this.index)) {
|
|
21
|
-
return this.index[0]!;
|
|
22
|
-
}
|
|
23
|
-
return this.index;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
private isCompoundIndex(): boolean {
|
|
27
|
-
return Array.isArray(this.index) && this.index.length > 1;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
private getCompoundColumns(): string[] {
|
|
31
|
-
return Array.isArray(this.index) ? this.index : [this.index];
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
private getCompoundValues(value: unknown): unknown[] {
|
|
35
|
-
// For compound indexes, value should be an array of values matching each column
|
|
36
|
-
if (Array.isArray(value)) {
|
|
37
|
-
return value;
|
|
38
|
-
}
|
|
39
|
-
// Single value for single-column index
|
|
40
|
-
return [value];
|
|
41
|
-
}
|
|
42
|
-
|
|
43
17
|
private createCollectionWithCondition(condition: SQLiteCondition): SQLiteCollection<T> {
|
|
44
18
|
const base = this.baseCollection ?? this.table.createCollection();
|
|
45
19
|
return base.addSqlCondition(condition);
|
|
46
20
|
}
|
|
47
21
|
|
|
48
|
-
private createCollectionWithJsPredicate(predicate: (record: T) => boolean): SQLiteCollection<T> {
|
|
49
|
-
const base = this.baseCollection ?? this.table.createCollection();
|
|
50
|
-
return base.jsFilter(predicate) as SQLiteCollection<T>;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
private getIndexValue(record: T): unknown {
|
|
54
|
-
return this.table.getIndexValue(record, this.index);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
22
|
private flattenArgs<TValue>(args: any[]): TValue[] {
|
|
58
23
|
if (args.length === 1 && Array.isArray(args[0])) {
|
|
59
24
|
return args[0] as TValue[];
|
|
@@ -62,85 +27,53 @@ export class SQLiteWhereClause<T = any> implements StorageWhereClause<T> {
|
|
|
62
27
|
}
|
|
63
28
|
|
|
64
29
|
equals(value: any): StorageCollection<T> {
|
|
65
|
-
if (this.isCompoundIndex()) {
|
|
66
|
-
// Use native SQL: WHERE col1 = ? AND col2 = ? AND ...
|
|
67
|
-
const columns = this.getCompoundColumns();
|
|
68
|
-
const values = this.getCompoundValues(value);
|
|
69
|
-
return this.createCollectionWithCondition({
|
|
70
|
-
type: 'compoundEquals',
|
|
71
|
-
columns,
|
|
72
|
-
values,
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
30
|
return this.createCollectionWithCondition({
|
|
76
31
|
type: 'equals',
|
|
77
|
-
column: this.
|
|
32
|
+
column: this.column,
|
|
78
33
|
value,
|
|
79
34
|
});
|
|
80
35
|
}
|
|
81
36
|
|
|
82
37
|
above(value: any): StorageCollection<T> {
|
|
83
|
-
if (this.isCompoundIndex()) {
|
|
84
|
-
return this.createCollectionWithJsPredicate((record) => this.table.compareValues(this.getIndexValue(record), value) > 0);
|
|
85
|
-
}
|
|
86
38
|
return this.createCollectionWithCondition({
|
|
87
39
|
type: 'comparison',
|
|
88
|
-
column: this.
|
|
40
|
+
column: this.column,
|
|
89
41
|
op: '>',
|
|
90
42
|
value,
|
|
91
43
|
});
|
|
92
44
|
}
|
|
93
45
|
|
|
94
46
|
aboveOrEqual(value: any): StorageCollection<T> {
|
|
95
|
-
if (this.isCompoundIndex()) {
|
|
96
|
-
return this.createCollectionWithJsPredicate((record) => this.table.compareValues(this.getIndexValue(record), value) >= 0);
|
|
97
|
-
}
|
|
98
47
|
return this.createCollectionWithCondition({
|
|
99
48
|
type: 'comparison',
|
|
100
|
-
column: this.
|
|
49
|
+
column: this.column,
|
|
101
50
|
op: '>=',
|
|
102
51
|
value,
|
|
103
52
|
});
|
|
104
53
|
}
|
|
105
54
|
|
|
106
55
|
below(value: any): StorageCollection<T> {
|
|
107
|
-
if (this.isCompoundIndex()) {
|
|
108
|
-
return this.createCollectionWithJsPredicate((record) => this.table.compareValues(this.getIndexValue(record), value) < 0);
|
|
109
|
-
}
|
|
110
56
|
return this.createCollectionWithCondition({
|
|
111
57
|
type: 'comparison',
|
|
112
|
-
column: this.
|
|
58
|
+
column: this.column,
|
|
113
59
|
op: '<',
|
|
114
60
|
value,
|
|
115
61
|
});
|
|
116
62
|
}
|
|
117
63
|
|
|
118
64
|
belowOrEqual(value: any): StorageCollection<T> {
|
|
119
|
-
if (this.isCompoundIndex()) {
|
|
120
|
-
return this.createCollectionWithJsPredicate((record) => this.table.compareValues(this.getIndexValue(record), value) <= 0);
|
|
121
|
-
}
|
|
122
65
|
return this.createCollectionWithCondition({
|
|
123
66
|
type: 'comparison',
|
|
124
|
-
column: this.
|
|
67
|
+
column: this.column,
|
|
125
68
|
op: '<=',
|
|
126
69
|
value,
|
|
127
70
|
});
|
|
128
71
|
}
|
|
129
72
|
|
|
130
73
|
between(lower: any, upper: any, includeLower = true, includeUpper = false): StorageCollection<T> {
|
|
131
|
-
if (this.isCompoundIndex()) {
|
|
132
|
-
return this.createCollectionWithJsPredicate((record) => {
|
|
133
|
-
const value = this.getIndexValue(record);
|
|
134
|
-
const lowerCmp = this.table.compareValues(value, lower);
|
|
135
|
-
const upperCmp = this.table.compareValues(value, upper);
|
|
136
|
-
const lowerPass = includeLower ? lowerCmp >= 0 : lowerCmp > 0;
|
|
137
|
-
const upperPass = includeUpper ? upperCmp <= 0 : upperCmp < 0;
|
|
138
|
-
return lowerPass && upperPass;
|
|
139
|
-
});
|
|
140
|
-
}
|
|
141
74
|
return this.createCollectionWithCondition({
|
|
142
75
|
type: 'between',
|
|
143
|
-
column: this.
|
|
76
|
+
column: this.column,
|
|
144
77
|
lower,
|
|
145
78
|
upper,
|
|
146
79
|
includeLower,
|
|
@@ -149,24 +82,19 @@ export class SQLiteWhereClause<T = any> implements StorageWhereClause<T> {
|
|
|
149
82
|
}
|
|
150
83
|
|
|
151
84
|
inAnyRange(ranges: Array<[any, any]>, options?: { includeLower?: boolean; includeUpper?: boolean }): StorageCollection<T> {
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
return this.
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
const upperPass = options?.includeUpper ? upperCmp <= 0 : upperCmp < 0;
|
|
161
|
-
return lowerPass && upperPass;
|
|
162
|
-
});
|
|
163
|
-
});
|
|
85
|
+
if (ranges.length === 0) {
|
|
86
|
+
// Empty ranges = no matches
|
|
87
|
+
return this.createCollectionWithCondition({
|
|
88
|
+
type: 'comparison',
|
|
89
|
+
column: this.column,
|
|
90
|
+
op: '=',
|
|
91
|
+
value: null,
|
|
92
|
+
}).jsFilter(() => false) as SQLiteCollection<T>;
|
|
164
93
|
}
|
|
165
94
|
|
|
166
|
-
const column = this.getColumn();
|
|
167
95
|
const orConditions: SQLiteCondition[] = ranges.map(([lower, upper]) => ({
|
|
168
96
|
type: 'between' as const,
|
|
169
|
-
column,
|
|
97
|
+
column: this.column,
|
|
170
98
|
lower,
|
|
171
99
|
upper,
|
|
172
100
|
includeLower: options?.includeLower !== false,
|
|
@@ -180,31 +108,21 @@ export class SQLiteWhereClause<T = any> implements StorageWhereClause<T> {
|
|
|
180
108
|
}
|
|
181
109
|
|
|
182
110
|
startsWith(prefix: string): StorageCollection<T> {
|
|
183
|
-
if (this.isCompoundIndex()) {
|
|
184
|
-
return this.createCollectionWithJsPredicate((record) => String(this.getIndexValue(record) ?? '').startsWith(prefix));
|
|
185
|
-
}
|
|
186
111
|
// SQLite LIKE pattern: 'prefix%' matches strings starting with prefix
|
|
187
112
|
// Escape special LIKE characters in the prefix
|
|
188
113
|
const escapedPrefix = prefix.replace(/[%_\\]/g, '\\$&');
|
|
189
114
|
return this.createCollectionWithCondition({
|
|
190
115
|
type: 'like',
|
|
191
|
-
column: this.
|
|
116
|
+
column: this.column,
|
|
192
117
|
pattern: `${escapedPrefix}%`,
|
|
193
118
|
});
|
|
194
119
|
}
|
|
195
120
|
|
|
196
121
|
startsWithIgnoreCase(prefix: string): StorageCollection<T> {
|
|
197
|
-
if (this.isCompoundIndex()) {
|
|
198
|
-
return this.createCollectionWithJsPredicate((record) =>
|
|
199
|
-
String(this.getIndexValue(record) ?? '')
|
|
200
|
-
.toLowerCase()
|
|
201
|
-
.startsWith(prefix.toLowerCase()),
|
|
202
|
-
);
|
|
203
|
-
}
|
|
204
122
|
const escapedPrefix = prefix.replace(/[%_\\]/g, '\\$&');
|
|
205
123
|
return this.createCollectionWithCondition({
|
|
206
124
|
type: 'like',
|
|
207
|
-
column: this.
|
|
125
|
+
column: this.column,
|
|
208
126
|
pattern: `${escapedPrefix}%`,
|
|
209
127
|
caseInsensitive: true,
|
|
210
128
|
});
|
|
@@ -212,19 +130,20 @@ export class SQLiteWhereClause<T = any> implements StorageWhereClause<T> {
|
|
|
212
130
|
|
|
213
131
|
startsWithAnyOf(...args: any[]): StorageCollection<T> {
|
|
214
132
|
const prefixes = this.flattenArgs<string>(args);
|
|
215
|
-
if (
|
|
216
|
-
return this.
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
133
|
+
if (prefixes.length === 0) {
|
|
134
|
+
return this.createCollectionWithCondition({
|
|
135
|
+
type: 'comparison',
|
|
136
|
+
column: this.column,
|
|
137
|
+
op: '=',
|
|
138
|
+
value: null,
|
|
139
|
+
}).jsFilter(() => false) as SQLiteCollection<T>;
|
|
220
140
|
}
|
|
221
141
|
|
|
222
|
-
const column = this.getColumn();
|
|
223
142
|
const orConditions: SQLiteCondition[] = prefixes.map((prefix) => {
|
|
224
143
|
const escapedPrefix = prefix.replace(/[%_\\]/g, '\\$&');
|
|
225
144
|
return {
|
|
226
145
|
type: 'like' as const,
|
|
227
|
-
column,
|
|
146
|
+
column: this.column,
|
|
228
147
|
pattern: `${escapedPrefix}%`,
|
|
229
148
|
};
|
|
230
149
|
});
|
|
@@ -237,20 +156,20 @@ export class SQLiteWhereClause<T = any> implements StorageWhereClause<T> {
|
|
|
237
156
|
|
|
238
157
|
startsWithAnyOfIgnoreCase(...args: any[]): StorageCollection<T> {
|
|
239
158
|
const prefixes = this.flattenArgs<string>(args);
|
|
240
|
-
if (
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
159
|
+
if (prefixes.length === 0) {
|
|
160
|
+
return this.createCollectionWithCondition({
|
|
161
|
+
type: 'comparison',
|
|
162
|
+
column: this.column,
|
|
163
|
+
op: '=',
|
|
164
|
+
value: null,
|
|
165
|
+
}).jsFilter(() => false) as SQLiteCollection<T>;
|
|
246
166
|
}
|
|
247
167
|
|
|
248
|
-
const column = this.getColumn();
|
|
249
168
|
const orConditions: SQLiteCondition[] = prefixes.map((prefix) => {
|
|
250
169
|
const escapedPrefix = prefix.replace(/[%_\\]/g, '\\$&');
|
|
251
170
|
return {
|
|
252
171
|
type: 'like' as const,
|
|
253
|
-
column,
|
|
172
|
+
column: this.column,
|
|
254
173
|
pattern: `${escapedPrefix}%`,
|
|
255
174
|
caseInsensitive: true,
|
|
256
175
|
};
|
|
@@ -263,12 +182,9 @@ export class SQLiteWhereClause<T = any> implements StorageWhereClause<T> {
|
|
|
263
182
|
}
|
|
264
183
|
|
|
265
184
|
equalsIgnoreCase(value: string): StorageCollection<T> {
|
|
266
|
-
if (this.isCompoundIndex()) {
|
|
267
|
-
return this.createCollectionWithJsPredicate((record) => String(this.getIndexValue(record) ?? '').toLowerCase() === value.toLowerCase());
|
|
268
|
-
}
|
|
269
185
|
return this.createCollectionWithCondition({
|
|
270
186
|
type: 'equals',
|
|
271
|
-
column: this.
|
|
187
|
+
column: this.column,
|
|
272
188
|
value,
|
|
273
189
|
caseInsensitive: true,
|
|
274
190
|
});
|
|
@@ -276,38 +192,18 @@ export class SQLiteWhereClause<T = any> implements StorageWhereClause<T> {
|
|
|
276
192
|
|
|
277
193
|
anyOf(...args: any[]): StorageCollection<T> {
|
|
278
194
|
const values = this.flattenArgs<any>(args);
|
|
279
|
-
if (this.isCompoundIndex()) {
|
|
280
|
-
// Use native SQL: (col1 = ? AND col2 = ?) OR (col1 = ? AND col2 = ?) OR ...
|
|
281
|
-
const columns = this.getCompoundColumns();
|
|
282
|
-
const orConditions: SQLiteCondition[] = values.map((value) => ({
|
|
283
|
-
type: 'compoundEquals' as const,
|
|
284
|
-
columns,
|
|
285
|
-
values: this.getCompoundValues(value),
|
|
286
|
-
}));
|
|
287
|
-
return this.createCollectionWithCondition({
|
|
288
|
-
type: 'or',
|
|
289
|
-
conditions: orConditions,
|
|
290
|
-
});
|
|
291
|
-
}
|
|
292
195
|
return this.createCollectionWithCondition({
|
|
293
196
|
type: 'in',
|
|
294
|
-
column: this.
|
|
197
|
+
column: this.column,
|
|
295
198
|
values,
|
|
296
199
|
});
|
|
297
200
|
}
|
|
298
201
|
|
|
299
202
|
anyOfIgnoreCase(...args: any[]): StorageCollection<T> {
|
|
300
203
|
const values = this.flattenArgs<string>(args);
|
|
301
|
-
if (this.isCompoundIndex()) {
|
|
302
|
-
const lowerValues = values.map((v) => v.toLowerCase());
|
|
303
|
-
return this.createCollectionWithJsPredicate((record) => {
|
|
304
|
-
const value = String(this.getIndexValue(record) ?? '').toLowerCase();
|
|
305
|
-
return lowerValues.includes(value);
|
|
306
|
-
});
|
|
307
|
-
}
|
|
308
204
|
return this.createCollectionWithCondition({
|
|
309
205
|
type: 'in',
|
|
310
|
-
column: this.
|
|
206
|
+
column: this.column,
|
|
311
207
|
values,
|
|
312
208
|
caseInsensitive: true,
|
|
313
209
|
});
|
|
@@ -315,25 +211,17 @@ export class SQLiteWhereClause<T = any> implements StorageWhereClause<T> {
|
|
|
315
211
|
|
|
316
212
|
noneOf(...args: any[]): StorageCollection<T> {
|
|
317
213
|
const values = this.flattenArgs<any>(args);
|
|
318
|
-
if (this.isCompoundIndex()) {
|
|
319
|
-
return this.createCollectionWithJsPredicate((record) =>
|
|
320
|
-
values.every((candidate) => this.table.compareValues(this.getIndexValue(record), candidate) !== 0),
|
|
321
|
-
);
|
|
322
|
-
}
|
|
323
214
|
return this.createCollectionWithCondition({
|
|
324
215
|
type: 'notIn',
|
|
325
|
-
column: this.
|
|
216
|
+
column: this.column,
|
|
326
217
|
values,
|
|
327
218
|
});
|
|
328
219
|
}
|
|
329
220
|
|
|
330
221
|
notEqual(value: any): StorageCollection<T> {
|
|
331
|
-
if (this.isCompoundIndex()) {
|
|
332
|
-
return this.createCollectionWithJsPredicate((record) => this.table.compareValues(this.getIndexValue(record), value) !== 0);
|
|
333
|
-
}
|
|
334
222
|
return this.createCollectionWithCondition({
|
|
335
223
|
type: 'comparison',
|
|
336
|
-
column: this.
|
|
224
|
+
column: this.column,
|
|
337
225
|
op: '!=',
|
|
338
226
|
value,
|
|
339
227
|
});
|
|
@@ -59,12 +59,6 @@ const buildCondition = (condition: SQLiteCondition): BuiltCondition => {
|
|
|
59
59
|
return { clause: `(${subClauses.join(' OR ')})`, parameters: subParams };
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
// Handle compound equals (multiple columns ANDed together)
|
|
63
|
-
if (condition.type === 'compoundEquals') {
|
|
64
|
-
const clauses = condition.columns.map((col) => `${quoteIdentifier(col)} = ?`);
|
|
65
|
-
return { clause: `(${clauses.join(' AND ')})`, parameters: condition.values };
|
|
66
|
-
}
|
|
67
|
-
|
|
68
62
|
const col = quoteIdentifier(condition.column);
|
|
69
63
|
|
|
70
64
|
switch (condition.type) {
|
|
@@ -69,12 +69,6 @@ export interface SQLiteConditionOr {
|
|
|
69
69
|
conditions: SQLiteCondition[];
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
export interface SQLiteConditionCompoundEquals {
|
|
73
|
-
type: 'compoundEquals';
|
|
74
|
-
columns: string[];
|
|
75
|
-
values: unknown[];
|
|
76
|
-
}
|
|
77
|
-
|
|
78
72
|
export type SQLiteCondition =
|
|
79
73
|
| SQLiteConditionEquals
|
|
80
74
|
| SQLiteConditionComparison
|
|
@@ -82,8 +76,7 @@ export type SQLiteCondition =
|
|
|
82
76
|
| SQLiteConditionIn
|
|
83
77
|
| SQLiteConditionNotIn
|
|
84
78
|
| SQLiteConditionLike
|
|
85
|
-
| SQLiteConditionOr
|
|
86
|
-
| SQLiteConditionCompoundEquals;
|
|
79
|
+
| SQLiteConditionOr;
|
|
87
80
|
|
|
88
81
|
export interface SQLiteCollectionState<T> {
|
|
89
82
|
/** SQL-expressible WHERE conditions (ANDed together) */
|
package/src/storage/types.ts
CHANGED
|
@@ -77,7 +77,6 @@ export type AddItem<T> = Omit<T, '_localId'> & { _localId?: string };
|
|
|
77
77
|
export interface StorageTable<T = any> {
|
|
78
78
|
readonly name: string;
|
|
79
79
|
readonly schema: unknown;
|
|
80
|
-
readonly hook: unknown;
|
|
81
80
|
add(item: AddItem<T>): Promise<string>;
|
|
82
81
|
put(item: T): Promise<string>;
|
|
83
82
|
update(key: string, changes: Partial<T>): Promise<number>;
|
|
@@ -91,12 +90,11 @@ export interface StorageTable<T = any> {
|
|
|
91
90
|
bulkGet(keys: string[]): Promise<Array<T | undefined>>;
|
|
92
91
|
bulkUpdate(keysAndChanges: Array<{ key: string; changes: Partial<T> }>): Promise<number>;
|
|
93
92
|
bulkDelete(keys: string[]): Promise<void>;
|
|
94
|
-
where(index: string
|
|
93
|
+
where(index: string): StorageWhereClause<T>;
|
|
95
94
|
orderBy(index: string | string[]): StorageCollection<T>;
|
|
96
95
|
reverse(): StorageCollection<T>;
|
|
97
96
|
offset(offset: number): StorageCollection<T>;
|
|
98
97
|
limit(count: number): StorageCollection<T>;
|
|
99
|
-
mapToClass(ctor: new (...args: any[]) => any): StorageTable<T>;
|
|
100
98
|
each(callback: (item: T) => void | Promise<void>): Promise<void>;
|
|
101
99
|
jsFilter(predicate: (item: T) => boolean): StorageCollection<T>;
|
|
102
100
|
// The "raw" property exposes the underlying storage operations without Dync sync logic.
|