@instantdb/core 0.22.88 → 0.22.89-experimental.drewh-fix-export.20277749804.1
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/__tests__/src/Reactor.test.js +18 -11
- package/__tests__/src/{datalog.test.js → datalog.test.ts} +17 -5
- package/__tests__/src/{instaml.test.js → instaml.test.ts} +183 -119
- package/__tests__/src/instaql.bench.ts +34 -0
- package/__tests__/src/{instaql.test.js → instaql.test.ts} +342 -455
- package/__tests__/src/instaqlInference.test.js +13 -9
- package/__tests__/src/{store.test.js → store.test.ts} +215 -212
- package/dist/commonjs/Reactor.d.ts +23 -6
- package/dist/commonjs/Reactor.d.ts.map +1 -1
- package/dist/commonjs/Reactor.js +110 -45
- package/dist/commonjs/Reactor.js.map +1 -1
- package/dist/commonjs/SyncTable.d.ts +4 -1
- package/dist/commonjs/SyncTable.d.ts.map +1 -1
- package/dist/commonjs/SyncTable.js +35 -37
- package/dist/commonjs/SyncTable.js.map +1 -1
- package/dist/commonjs/instaml.d.ts +17 -4
- package/dist/commonjs/instaml.d.ts.map +1 -1
- package/dist/commonjs/instaml.js +115 -82
- package/dist/commonjs/instaml.js.map +1 -1
- package/dist/commonjs/instaql.d.ts +4 -3
- package/dist/commonjs/instaql.d.ts.map +1 -1
- package/dist/commonjs/instaql.js +65 -63
- package/dist/commonjs/instaql.js.map +1 -1
- package/dist/commonjs/reactorTypes.d.ts +29 -0
- package/dist/commonjs/reactorTypes.d.ts.map +1 -0
- package/dist/commonjs/reactorTypes.js +3 -0
- package/dist/commonjs/reactorTypes.js.map +1 -0
- package/dist/commonjs/store.d.ts +67 -25
- package/dist/commonjs/store.d.ts.map +1 -1
- package/dist/commonjs/store.js +177 -81
- package/dist/commonjs/store.js.map +1 -1
- package/dist/esm/Reactor.d.ts +23 -6
- package/dist/esm/Reactor.d.ts.map +1 -1
- package/dist/esm/Reactor.js +111 -46
- package/dist/esm/Reactor.js.map +1 -1
- package/dist/esm/SyncTable.d.ts +4 -1
- package/dist/esm/SyncTable.d.ts.map +1 -1
- package/dist/esm/SyncTable.js +35 -37
- package/dist/esm/SyncTable.js.map +1 -1
- package/dist/esm/instaml.d.ts +17 -4
- package/dist/esm/instaml.d.ts.map +1 -1
- package/dist/esm/instaml.js +112 -77
- package/dist/esm/instaml.js.map +1 -1
- package/dist/esm/instaql.d.ts +4 -3
- package/dist/esm/instaql.d.ts.map +1 -1
- package/dist/esm/instaql.js +65 -63
- package/dist/esm/instaql.js.map +1 -1
- package/dist/esm/reactorTypes.d.ts +29 -0
- package/dist/esm/reactorTypes.d.ts.map +1 -0
- package/dist/esm/reactorTypes.js +2 -0
- package/dist/esm/reactorTypes.js.map +1 -0
- package/dist/esm/store.d.ts +67 -25
- package/dist/esm/store.d.ts.map +1 -1
- package/dist/esm/store.js +174 -81
- package/dist/esm/store.js.map +1 -1
- package/dist/standalone/index.js +1605 -1415
- package/dist/standalone/index.umd.cjs +3 -3
- package/package.json +2 -2
- package/src/Reactor.js +152 -75
- package/src/SyncTable.ts +85 -45
- package/src/{instaml.js → instaml.ts} +201 -96
- package/src/instaql.ts +88 -62
- package/src/reactorTypes.ts +32 -0
- package/src/store.ts +257 -101
- package/__tests__/src/instaql.bench.js +0 -29
|
@@ -2,23 +2,37 @@ import { test, expect, vi } from 'vitest';
|
|
|
2
2
|
|
|
3
3
|
import zenecaAttrs from './data/zeneca/attrs.json';
|
|
4
4
|
import zenecaTriples from './data/zeneca/triples.json';
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
createStore,
|
|
7
|
+
transact,
|
|
8
|
+
AttrsStoreClass,
|
|
9
|
+
Store,
|
|
10
|
+
AttrsStore,
|
|
11
|
+
} from '../../src/store';
|
|
6
12
|
import query from '../../src/instaql';
|
|
7
13
|
import { tx, lookup } from '../../src/instatx';
|
|
8
14
|
import { i } from '../../src/index';
|
|
9
15
|
import * as instaml from '../../src/instaml';
|
|
10
16
|
import { randomUUID } from 'crypto';
|
|
11
17
|
|
|
12
|
-
const
|
|
13
|
-
res
|
|
14
|
-
|
|
15
|
-
|
|
18
|
+
const zenecaAttrsStore = new AttrsStoreClass(
|
|
19
|
+
zenecaAttrs.reduce((res, x) => {
|
|
20
|
+
res[x.id] = x;
|
|
21
|
+
return res;
|
|
22
|
+
}, {}),
|
|
23
|
+
null,
|
|
24
|
+
);
|
|
16
25
|
|
|
17
|
-
const store = createStore(
|
|
26
|
+
const store = createStore(
|
|
27
|
+
zenecaAttrsStore,
|
|
28
|
+
zenecaTriples as [string, string, any, number][],
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
const ctx = { store, attrsStore: zenecaAttrsStore };
|
|
18
32
|
|
|
19
33
|
test('Simple Query Without Where', () => {
|
|
20
34
|
expect(
|
|
21
|
-
query(
|
|
35
|
+
query(ctx, { users: {} })
|
|
22
36
|
.data.users.map((x) => x.handle)
|
|
23
37
|
.sort(),
|
|
24
38
|
).toEqual(['alex', 'joe', 'nicolegf', 'stopa']);
|
|
@@ -26,7 +40,7 @@ test('Simple Query Without Where', () => {
|
|
|
26
40
|
|
|
27
41
|
test('Simple Where', () => {
|
|
28
42
|
expect(
|
|
29
|
-
query(
|
|
43
|
+
query(ctx, { users: { $: { where: { handle: 'joe' } } } })
|
|
30
44
|
.data.users.map((x) => x.handle)
|
|
31
45
|
.sort(),
|
|
32
46
|
).toEqual(['joe']);
|
|
@@ -35,45 +49,38 @@ test('Simple Where', () => {
|
|
|
35
49
|
test('Simple Where has expected keys', () => {
|
|
36
50
|
expect(
|
|
37
51
|
Object.keys(
|
|
38
|
-
query(
|
|
39
|
-
.users[0],
|
|
52
|
+
query(ctx, { users: { $: { where: { handle: 'joe' } } } }).data.users[0],
|
|
40
53
|
).sort(),
|
|
41
54
|
).toEqual(['createdAt', 'email', 'fullName', 'handle', 'id']);
|
|
42
55
|
});
|
|
43
56
|
|
|
44
57
|
test('Simple Where with multiple clauses', () => {
|
|
45
58
|
expect(
|
|
46
|
-
query(
|
|
47
|
-
{
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
'bookshelves.books.title': 'The Count of Monte Cristo',
|
|
53
|
-
handle: 'stopa',
|
|
54
|
-
},
|
|
59
|
+
query(ctx, {
|
|
60
|
+
users: {
|
|
61
|
+
$: {
|
|
62
|
+
where: {
|
|
63
|
+
'bookshelves.books.title': 'The Count of Monte Cristo',
|
|
64
|
+
handle: 'stopa',
|
|
55
65
|
},
|
|
56
66
|
},
|
|
57
67
|
},
|
|
58
|
-
)
|
|
68
|
+
})
|
|
59
69
|
.data.users.map((x) => x.handle)
|
|
60
70
|
.sort(),
|
|
61
71
|
).toEqual(['stopa']);
|
|
62
72
|
|
|
63
73
|
expect(
|
|
64
|
-
query(
|
|
65
|
-
{
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
'bookshelves.books.title': 'Title nobody has',
|
|
71
|
-
handle: 'stopa',
|
|
72
|
-
},
|
|
74
|
+
query(ctx, {
|
|
75
|
+
users: {
|
|
76
|
+
$: {
|
|
77
|
+
where: {
|
|
78
|
+
'bookshelves.books.title': 'Title nobody has',
|
|
79
|
+
handle: 'stopa',
|
|
73
80
|
},
|
|
74
81
|
},
|
|
75
82
|
},
|
|
76
|
-
)
|
|
83
|
+
})
|
|
77
84
|
.data.users.map((x) => x.handle)
|
|
78
85
|
.sort(),
|
|
79
86
|
).toEqual([]);
|
|
@@ -81,35 +88,29 @@ test('Simple Where with multiple clauses', () => {
|
|
|
81
88
|
|
|
82
89
|
test('Where in', () => {
|
|
83
90
|
expect(
|
|
84
|
-
query(
|
|
85
|
-
{
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
where: {
|
|
90
|
-
handle: { in: ['stopa', 'joe'] },
|
|
91
|
-
},
|
|
91
|
+
query(ctx, {
|
|
92
|
+
users: {
|
|
93
|
+
$: {
|
|
94
|
+
where: {
|
|
95
|
+
handle: { in: ['stopa', 'joe'] },
|
|
92
96
|
},
|
|
93
97
|
},
|
|
94
98
|
},
|
|
95
|
-
)
|
|
99
|
+
})
|
|
96
100
|
.data.users.map((x) => x.handle)
|
|
97
101
|
.sort(),
|
|
98
102
|
).toEqual(['joe', 'stopa']);
|
|
99
103
|
|
|
100
104
|
expect(
|
|
101
|
-
query(
|
|
102
|
-
{
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
where: {
|
|
107
|
-
handle: { $in: ['stopa', 'joe'] },
|
|
108
|
-
},
|
|
105
|
+
query(ctx, {
|
|
106
|
+
users: {
|
|
107
|
+
$: {
|
|
108
|
+
where: {
|
|
109
|
+
handle: { $in: ['stopa', 'joe'] },
|
|
109
110
|
},
|
|
110
111
|
},
|
|
111
112
|
},
|
|
112
|
-
)
|
|
113
|
+
})
|
|
113
114
|
.data.users.map((x) => x.handle)
|
|
114
115
|
.sort(),
|
|
115
116
|
).toEqual(['joe', 'stopa']);
|
|
@@ -117,18 +118,15 @@ test('Where in', () => {
|
|
|
117
118
|
|
|
118
119
|
test('Where %like%', () => {
|
|
119
120
|
expect(
|
|
120
|
-
query(
|
|
121
|
-
{
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
where: {
|
|
126
|
-
handle: { $like: '%o%' },
|
|
127
|
-
},
|
|
121
|
+
query(ctx, {
|
|
122
|
+
users: {
|
|
123
|
+
$: {
|
|
124
|
+
where: {
|
|
125
|
+
handle: { $like: '%o%' },
|
|
128
126
|
},
|
|
129
127
|
},
|
|
130
128
|
},
|
|
131
|
-
)
|
|
129
|
+
})
|
|
132
130
|
.data.users.map((x) => x.handle)
|
|
133
131
|
.sort(),
|
|
134
132
|
).toEqual(['joe', 'nicolegf', 'stopa']);
|
|
@@ -136,18 +134,15 @@ test('Where %like%', () => {
|
|
|
136
134
|
|
|
137
135
|
test('Where like equality', () => {
|
|
138
136
|
expect(
|
|
139
|
-
query(
|
|
140
|
-
{
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
where: {
|
|
145
|
-
handle: { $like: 'joe' },
|
|
146
|
-
},
|
|
137
|
+
query(ctx, {
|
|
138
|
+
users: {
|
|
139
|
+
$: {
|
|
140
|
+
where: {
|
|
141
|
+
handle: { $like: 'joe' },
|
|
147
142
|
},
|
|
148
143
|
},
|
|
149
144
|
},
|
|
150
|
-
)
|
|
145
|
+
})
|
|
151
146
|
.data.users.map((x) => x.handle)
|
|
152
147
|
.sort(),
|
|
153
148
|
).toEqual(['joe']);
|
|
@@ -155,18 +150,15 @@ test('Where like equality', () => {
|
|
|
155
150
|
|
|
156
151
|
test('Where startsWith deep', () => {
|
|
157
152
|
expect(
|
|
158
|
-
query(
|
|
159
|
-
{
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
where: {
|
|
164
|
-
'bookshelves.books.title': { $like: '%Monte Cristo' },
|
|
165
|
-
},
|
|
153
|
+
query(ctx, {
|
|
154
|
+
users: {
|
|
155
|
+
$: {
|
|
156
|
+
where: {
|
|
157
|
+
'bookshelves.books.title': { $like: '%Monte Cristo' },
|
|
166
158
|
},
|
|
167
159
|
},
|
|
168
160
|
},
|
|
169
|
-
)
|
|
161
|
+
})
|
|
170
162
|
.data.users.map((x) => x.handle)
|
|
171
163
|
.sort(),
|
|
172
164
|
).toEqual(['nicolegf', 'stopa']);
|
|
@@ -174,18 +166,15 @@ test('Where startsWith deep', () => {
|
|
|
174
166
|
|
|
175
167
|
test('Where endsWith deep', () => {
|
|
176
168
|
expect(
|
|
177
|
-
query(
|
|
178
|
-
{
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
where: {
|
|
183
|
-
'bookshelves.books.title': { $like: 'Anti%' },
|
|
184
|
-
},
|
|
169
|
+
query(ctx, {
|
|
170
|
+
users: {
|
|
171
|
+
$: {
|
|
172
|
+
where: {
|
|
173
|
+
'bookshelves.books.title': { $like: 'Anti%' },
|
|
185
174
|
},
|
|
186
175
|
},
|
|
187
176
|
},
|
|
188
|
-
)
|
|
177
|
+
})
|
|
189
178
|
.data.users.map((x) => x.handle)
|
|
190
179
|
.sort(),
|
|
191
180
|
).toEqual(['alex', 'nicolegf', 'stopa']);
|
|
@@ -193,18 +182,15 @@ test('Where endsWith deep', () => {
|
|
|
193
182
|
|
|
194
183
|
test('like case sensitivity', () => {
|
|
195
184
|
function runQuery(where) {
|
|
196
|
-
return query(
|
|
197
|
-
{
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
where: {
|
|
202
|
-
fullName: where,
|
|
203
|
-
},
|
|
185
|
+
return query(ctx, {
|
|
186
|
+
users: {
|
|
187
|
+
$: {
|
|
188
|
+
where: {
|
|
189
|
+
fullName: where,
|
|
204
190
|
},
|
|
205
191
|
},
|
|
206
192
|
},
|
|
207
|
-
)
|
|
193
|
+
})
|
|
208
194
|
.data.users.map((x) => x.fullName)
|
|
209
195
|
.sort();
|
|
210
196
|
}
|
|
@@ -237,41 +223,35 @@ test('like special regex characters', () => {
|
|
|
237
223
|
const chunk = tx.users[lookup('handle', 'stopa')].update({
|
|
238
224
|
fullName: newName,
|
|
239
225
|
});
|
|
240
|
-
const txSteps = instaml.transform({
|
|
241
|
-
return transact(store, txSteps);
|
|
226
|
+
const txSteps = instaml.transform({ attrsStore: zenecaAttrsStore }, chunk);
|
|
227
|
+
return transact(store, zenecaAttrsStore, txSteps);
|
|
242
228
|
}
|
|
243
229
|
|
|
244
230
|
for (const [char, newName] of specialChars) {
|
|
245
|
-
const
|
|
246
|
-
const res = query(
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
users: {
|
|
250
|
-
$: { where: { fullName: { $like: `%${char}%` } } },
|
|
251
|
-
},
|
|
231
|
+
const newCtx = renameStopa(store, newName);
|
|
232
|
+
const res = query(newCtx, {
|
|
233
|
+
users: {
|
|
234
|
+
$: { where: { fullName: { $like: `%${char}%` } } },
|
|
252
235
|
},
|
|
253
|
-
).data.users;
|
|
236
|
+
}).data.users;
|
|
254
237
|
expect(res[0]?.fullName).toBe(newName);
|
|
255
238
|
}
|
|
256
239
|
});
|
|
257
240
|
|
|
258
241
|
test('Where and', () => {
|
|
259
242
|
expect(
|
|
260
|
-
query(
|
|
261
|
-
{
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
{ 'bookshelves.books.title': 'Antifragile' },
|
|
269
|
-
],
|
|
270
|
-
},
|
|
243
|
+
query(ctx, {
|
|
244
|
+
users: {
|
|
245
|
+
$: {
|
|
246
|
+
where: {
|
|
247
|
+
and: [
|
|
248
|
+
{ 'bookshelves.books.title': 'The Count of Monte Cristo' },
|
|
249
|
+
{ 'bookshelves.books.title': 'Antifragile' },
|
|
250
|
+
],
|
|
271
251
|
},
|
|
272
252
|
},
|
|
273
253
|
},
|
|
274
|
-
)
|
|
254
|
+
})
|
|
275
255
|
.data.users.map((x) => x.handle)
|
|
276
256
|
.sort(),
|
|
277
257
|
).toEqual(['nicolegf', 'stopa']);
|
|
@@ -388,16 +368,13 @@ test.each([
|
|
|
388
368
|
],
|
|
389
369
|
])('Where OR %s', (_, whereQuery, expected) => {
|
|
390
370
|
expect(
|
|
391
|
-
query(
|
|
392
|
-
{
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
$: {
|
|
396
|
-
where: whereQuery,
|
|
397
|
-
},
|
|
371
|
+
query(ctx, {
|
|
372
|
+
users: {
|
|
373
|
+
$: {
|
|
374
|
+
where: whereQuery,
|
|
398
375
|
},
|
|
399
376
|
},
|
|
400
|
-
)
|
|
377
|
+
})
|
|
401
378
|
.data.users.map((x) => x.handle)
|
|
402
379
|
.sort(),
|
|
403
380
|
).toEqual(expected);
|
|
@@ -405,15 +382,12 @@ test.each([
|
|
|
405
382
|
|
|
406
383
|
test('Get association', () => {
|
|
407
384
|
expect(
|
|
408
|
-
query(
|
|
409
|
-
{
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
bookshelves: {},
|
|
413
|
-
$: { where: { handle: 'alex' } },
|
|
414
|
-
},
|
|
385
|
+
query(ctx, {
|
|
386
|
+
users: {
|
|
387
|
+
bookshelves: {},
|
|
388
|
+
$: { where: { handle: 'alex' } },
|
|
415
389
|
},
|
|
416
|
-
).data.users.map((x) => [
|
|
390
|
+
}).data.users.map((x) => [
|
|
417
391
|
x.handle,
|
|
418
392
|
x.bookshelves.map((x) => x.name).sort(),
|
|
419
393
|
]),
|
|
@@ -422,15 +396,12 @@ test('Get association', () => {
|
|
|
422
396
|
|
|
423
397
|
test('Get reverse association', () => {
|
|
424
398
|
expect(
|
|
425
|
-
query(
|
|
426
|
-
{
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
users: {},
|
|
430
|
-
$: { where: { name: 'Short Stories' } },
|
|
431
|
-
},
|
|
399
|
+
query(ctx, {
|
|
400
|
+
bookshelves: {
|
|
401
|
+
users: {},
|
|
402
|
+
$: { where: { name: 'Short Stories' } },
|
|
432
403
|
},
|
|
433
|
-
).data.bookshelves.map((x) => [
|
|
404
|
+
}).data.bookshelves.map((x) => [
|
|
434
405
|
x.name,
|
|
435
406
|
x.users.map((x) => x.handle).sort(),
|
|
436
407
|
]),
|
|
@@ -439,15 +410,12 @@ test('Get reverse association', () => {
|
|
|
439
410
|
|
|
440
411
|
test('Get deep association', () => {
|
|
441
412
|
expect(
|
|
442
|
-
query(
|
|
443
|
-
{
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
bookshelves: { books: {} },
|
|
447
|
-
$: { where: { handle: 'alex' } },
|
|
448
|
-
},
|
|
413
|
+
query(ctx, {
|
|
414
|
+
users: {
|
|
415
|
+
bookshelves: { books: {} },
|
|
416
|
+
$: { where: { handle: 'alex' } },
|
|
449
417
|
},
|
|
450
|
-
)
|
|
418
|
+
})
|
|
451
419
|
.data.users.flatMap((x) => x.bookshelves)
|
|
452
420
|
.flatMap((x) => x.books)
|
|
453
421
|
.map((x) => x.title),
|
|
@@ -466,18 +434,15 @@ test('Get deep association', () => {
|
|
|
466
434
|
|
|
467
435
|
test('Nested wheres', () => {
|
|
468
436
|
expect(
|
|
469
|
-
query(
|
|
470
|
-
{
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
books: {},
|
|
475
|
-
$: { where: { name: 'Short Stories' } },
|
|
476
|
-
},
|
|
477
|
-
$: { where: { handle: 'alex' } },
|
|
437
|
+
query(ctx, {
|
|
438
|
+
users: {
|
|
439
|
+
bookshelves: {
|
|
440
|
+
books: {},
|
|
441
|
+
$: { where: { name: 'Short Stories' } },
|
|
478
442
|
},
|
|
443
|
+
$: { where: { handle: 'alex' } },
|
|
479
444
|
},
|
|
480
|
-
)
|
|
445
|
+
})
|
|
481
446
|
.data.users.flatMap((x) => x.bookshelves)
|
|
482
447
|
.flatMap((x) => x.books)
|
|
483
448
|
.map((x) => x.title),
|
|
@@ -490,20 +455,17 @@ test('Nested wheres', () => {
|
|
|
490
455
|
|
|
491
456
|
test('Nested wheres with OR queries', () => {
|
|
492
457
|
expect(
|
|
493
|
-
query(
|
|
494
|
-
{
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
$: {
|
|
500
|
-
where: { or: [{ name: 'Short Stories' }] },
|
|
501
|
-
},
|
|
458
|
+
query(ctx, {
|
|
459
|
+
users: {
|
|
460
|
+
bookshelves: {
|
|
461
|
+
books: {},
|
|
462
|
+
$: {
|
|
463
|
+
where: { or: [{ name: 'Short Stories' }] },
|
|
502
464
|
},
|
|
503
|
-
$: { where: { handle: 'alex' } },
|
|
504
465
|
},
|
|
466
|
+
$: { where: { handle: 'alex' } },
|
|
505
467
|
},
|
|
506
|
-
)
|
|
468
|
+
})
|
|
507
469
|
.data.users.flatMap((x) => x.bookshelves)
|
|
508
470
|
.flatMap((x) => x.books)
|
|
509
471
|
.map((x) => x.title),
|
|
@@ -516,20 +478,17 @@ test('Nested wheres with OR queries', () => {
|
|
|
516
478
|
|
|
517
479
|
test('Nested wheres with AND queries', () => {
|
|
518
480
|
expect(
|
|
519
|
-
query(
|
|
520
|
-
{
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
$: {
|
|
526
|
-
where: { and: [{ name: 'Short Stories' }, { order: 0 }] },
|
|
527
|
-
},
|
|
481
|
+
query(ctx, {
|
|
482
|
+
users: {
|
|
483
|
+
bookshelves: {
|
|
484
|
+
books: {},
|
|
485
|
+
$: {
|
|
486
|
+
where: { and: [{ name: 'Short Stories' }, { order: 0 }] },
|
|
528
487
|
},
|
|
529
|
-
$: { where: { handle: 'alex' } },
|
|
530
488
|
},
|
|
489
|
+
$: { where: { handle: 'alex' } },
|
|
531
490
|
},
|
|
532
|
-
)
|
|
491
|
+
})
|
|
533
492
|
.data.users.flatMap((x) => x.bookshelves)
|
|
534
493
|
.flatMap((x) => x.books)
|
|
535
494
|
.map((x) => x.title),
|
|
@@ -542,32 +501,26 @@ test('Nested wheres with AND queries', () => {
|
|
|
542
501
|
|
|
543
502
|
test('Deep where', () => {
|
|
544
503
|
expect(
|
|
545
|
-
query(
|
|
546
|
-
{
|
|
547
|
-
|
|
548
|
-
users: {
|
|
549
|
-
$: { where: { 'bookshelves.books.title': "Aesop's Fables" } },
|
|
550
|
-
},
|
|
504
|
+
query(ctx, {
|
|
505
|
+
users: {
|
|
506
|
+
$: { where: { 'bookshelves.books.title': "Aesop's Fables" } },
|
|
551
507
|
},
|
|
552
|
-
).data.users.map((x) => x.handle),
|
|
508
|
+
}).data.users.map((x) => x.handle),
|
|
553
509
|
).toEqual(['alex']);
|
|
554
510
|
});
|
|
555
511
|
|
|
556
512
|
test('Missing etype', () => {
|
|
557
|
-
expect(query(
|
|
513
|
+
expect(query(ctx, { moopy: {} }).data).toEqual({ moopy: [] });
|
|
558
514
|
});
|
|
559
515
|
|
|
560
516
|
test('Missing inner etype', () => {
|
|
561
517
|
expect(
|
|
562
|
-
query(
|
|
563
|
-
{
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
moopy: {},
|
|
567
|
-
$: { where: { handle: 'joe' } },
|
|
568
|
-
},
|
|
518
|
+
query(ctx, {
|
|
519
|
+
users: {
|
|
520
|
+
moopy: {},
|
|
521
|
+
$: { where: { handle: 'joe' } },
|
|
569
522
|
},
|
|
570
|
-
)
|
|
523
|
+
})
|
|
571
524
|
.data.users.map((x) => [x.handle, x.moopy])
|
|
572
525
|
.sort(),
|
|
573
526
|
).toEqual([['joe', []]]);
|
|
@@ -575,29 +528,23 @@ test('Missing inner etype', () => {
|
|
|
575
528
|
|
|
576
529
|
test('Missing filter attr', () => {
|
|
577
530
|
expect(
|
|
578
|
-
query(
|
|
579
|
-
{
|
|
580
|
-
|
|
581
|
-
users: {
|
|
582
|
-
$: { where: { 'bookshelves.moopy': 'joe' } },
|
|
583
|
-
},
|
|
531
|
+
query(ctx, {
|
|
532
|
+
users: {
|
|
533
|
+
$: { where: { 'bookshelves.moopy': 'joe' } },
|
|
584
534
|
},
|
|
585
|
-
).data,
|
|
535
|
+
}).data,
|
|
586
536
|
).toEqual({ users: [] });
|
|
587
537
|
});
|
|
588
538
|
|
|
589
539
|
test('multiple connections', () => {
|
|
590
540
|
expect(
|
|
591
|
-
query(
|
|
592
|
-
{
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
users: {},
|
|
597
|
-
$: { where: { name: 'Short Stories' } },
|
|
598
|
-
},
|
|
541
|
+
query(ctx, {
|
|
542
|
+
bookshelves: {
|
|
543
|
+
books: {},
|
|
544
|
+
users: {},
|
|
545
|
+
$: { where: { name: 'Short Stories' } },
|
|
599
546
|
},
|
|
600
|
-
).data.bookshelves.map((x) => [
|
|
547
|
+
}).data.bookshelves.map((x) => [
|
|
601
548
|
x.name,
|
|
602
549
|
x.users.map((x) => x.handle).sort(),
|
|
603
550
|
x.books.map((x) => x.title).sort(),
|
|
@@ -616,73 +563,52 @@ test('multiple connections', () => {
|
|
|
616
563
|
});
|
|
617
564
|
|
|
618
565
|
test('query forward references work with and without id', () => {
|
|
619
|
-
const bookshelf = query(
|
|
620
|
-
{
|
|
621
|
-
|
|
622
|
-
bookshelves: {
|
|
623
|
-
$: { where: { 'users.handle': 'stopa' } },
|
|
624
|
-
},
|
|
566
|
+
const bookshelf = query(ctx, {
|
|
567
|
+
bookshelves: {
|
|
568
|
+
$: { where: { 'users.handle': 'stopa' } },
|
|
625
569
|
},
|
|
626
|
-
).data.bookshelves[0];
|
|
570
|
+
}).data.bookshelves[0];
|
|
627
571
|
|
|
628
|
-
const usersByBookshelfId = query(
|
|
629
|
-
{
|
|
630
|
-
|
|
631
|
-
users: {
|
|
632
|
-
$: { where: { 'bookshelves.id': bookshelf.id } },
|
|
633
|
-
},
|
|
572
|
+
const usersByBookshelfId = query(ctx, {
|
|
573
|
+
users: {
|
|
574
|
+
$: { where: { 'bookshelves.id': bookshelf.id } },
|
|
634
575
|
},
|
|
635
|
-
).data.users.map((x) => x.handle);
|
|
576
|
+
}).data.users.map((x) => x.handle);
|
|
636
577
|
|
|
637
|
-
const usersByBookshelfLinkFIeld = query(
|
|
638
|
-
{
|
|
639
|
-
|
|
640
|
-
users: {
|
|
641
|
-
$: { where: { bookshelves: bookshelf.id } },
|
|
642
|
-
},
|
|
578
|
+
const usersByBookshelfLinkFIeld = query(ctx, {
|
|
579
|
+
users: {
|
|
580
|
+
$: { where: { bookshelves: bookshelf.id } },
|
|
643
581
|
},
|
|
644
|
-
).data.users.map((x) => x.handle);
|
|
582
|
+
}).data.users.map((x) => x.handle);
|
|
645
583
|
|
|
646
584
|
expect(usersByBookshelfId).toEqual(['stopa']);
|
|
647
585
|
expect(usersByBookshelfLinkFIeld).toEqual(['stopa']);
|
|
648
586
|
});
|
|
649
587
|
|
|
650
588
|
test('query reverse references work with and without id', () => {
|
|
651
|
-
const stopa = query(
|
|
652
|
-
{
|
|
653
|
-
|
|
654
|
-
users: {
|
|
655
|
-
$: { where: { handle: 'stopa' } },
|
|
656
|
-
},
|
|
589
|
+
const stopa = query(ctx, {
|
|
590
|
+
users: {
|
|
591
|
+
$: { where: { handle: 'stopa' } },
|
|
657
592
|
},
|
|
658
|
-
).data.users[0];
|
|
593
|
+
}).data.users[0];
|
|
659
594
|
|
|
660
|
-
const stopaBookshelvesByHandle = query(
|
|
661
|
-
{
|
|
662
|
-
|
|
663
|
-
bookshelves: {
|
|
664
|
-
$: { where: { 'users.handle': 'stopa' } },
|
|
665
|
-
},
|
|
595
|
+
const stopaBookshelvesByHandle = query(ctx, {
|
|
596
|
+
bookshelves: {
|
|
597
|
+
$: { where: { 'users.handle': 'stopa' } },
|
|
666
598
|
},
|
|
667
|
-
).data.bookshelves;
|
|
599
|
+
}).data.bookshelves;
|
|
668
600
|
|
|
669
|
-
const stopaBookshelvesById = query(
|
|
670
|
-
{
|
|
671
|
-
|
|
672
|
-
bookshelves: {
|
|
673
|
-
$: { where: { 'users.id': stopa.id } },
|
|
674
|
-
},
|
|
601
|
+
const stopaBookshelvesById = query(ctx, {
|
|
602
|
+
bookshelves: {
|
|
603
|
+
$: { where: { 'users.id': stopa.id } },
|
|
675
604
|
},
|
|
676
|
-
).data.bookshelves;
|
|
605
|
+
}).data.bookshelves;
|
|
677
606
|
|
|
678
|
-
const stopaBookshelvesByLinkField = query(
|
|
679
|
-
{
|
|
680
|
-
|
|
681
|
-
bookshelves: {
|
|
682
|
-
$: { where: { users: stopa.id } },
|
|
683
|
-
},
|
|
607
|
+
const stopaBookshelvesByLinkField = query(ctx, {
|
|
608
|
+
bookshelves: {
|
|
609
|
+
$: { where: { users: stopa.id } },
|
|
684
610
|
},
|
|
685
|
-
).data.bookshelves;
|
|
611
|
+
}).data.bookshelves;
|
|
686
612
|
|
|
687
613
|
expect(stopaBookshelvesByHandle.length).toBe(16);
|
|
688
614
|
|
|
@@ -691,46 +617,41 @@ test('query reverse references work with and without id', () => {
|
|
|
691
617
|
});
|
|
692
618
|
|
|
693
619
|
test('objects are created by etype', () => {
|
|
694
|
-
const stopa = query(
|
|
695
|
-
{
|
|
696
|
-
|
|
697
|
-
users: {
|
|
698
|
-
$: { where: { handle: 'stopa' } },
|
|
699
|
-
},
|
|
620
|
+
const stopa = query(ctx, {
|
|
621
|
+
users: {
|
|
622
|
+
$: { where: { handle: 'stopa' } },
|
|
700
623
|
},
|
|
701
|
-
).data.users[0];
|
|
624
|
+
}).data.users[0];
|
|
702
625
|
expect(stopa.email).toEqual('stopa@instantdb.com');
|
|
703
626
|
const chunk = tx.not_users[stopa.id].update({
|
|
704
627
|
email: 'this-should-not-change-users-stopa@gmail.com',
|
|
705
628
|
});
|
|
706
|
-
const txSteps = instaml.transform({
|
|
707
|
-
const
|
|
708
|
-
const newStopa = query(
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
users: {
|
|
712
|
-
$: { where: { handle: 'stopa' } },
|
|
713
|
-
},
|
|
629
|
+
const txSteps = instaml.transform({ attrsStore: zenecaAttrsStore }, chunk);
|
|
630
|
+
const newCtx = transact(store, zenecaAttrsStore, txSteps);
|
|
631
|
+
const newStopa = query(newCtx, {
|
|
632
|
+
users: {
|
|
633
|
+
$: { where: { handle: 'stopa' } },
|
|
714
634
|
},
|
|
715
|
-
).data.users[0];
|
|
635
|
+
}).data.users[0];
|
|
716
636
|
expect(newStopa.email).toEqual('stopa@instantdb.com');
|
|
717
637
|
});
|
|
718
638
|
|
|
719
639
|
test('create and update triples in one tx', () => {
|
|
720
640
|
const userId = randomUUID();
|
|
721
641
|
|
|
722
|
-
const getUser = (store) =>
|
|
723
|
-
query(
|
|
642
|
+
const getUser = (ctx: { store: Store; attrsStore: AttrsStore }) =>
|
|
643
|
+
query(ctx, { users: { $: { where: { id: userId } } } }).data.users[0];
|
|
724
644
|
|
|
725
645
|
const chunk1 = tx.users[userId].create({
|
|
726
646
|
email: 'e@mail',
|
|
727
647
|
handle: 'handle',
|
|
728
648
|
});
|
|
729
|
-
const
|
|
649
|
+
const ctx1 = transact(
|
|
730
650
|
store,
|
|
731
|
-
|
|
651
|
+
zenecaAttrsStore,
|
|
652
|
+
instaml.transform({ attrsStore: zenecaAttrsStore }, chunk1),
|
|
732
653
|
);
|
|
733
|
-
const user1 = getUser(
|
|
654
|
+
const user1 = getUser(ctx1);
|
|
734
655
|
expect(user1.email).toEqual('e@mail');
|
|
735
656
|
expect(user1.fullName).toEqual(undefined);
|
|
736
657
|
|
|
@@ -741,54 +662,46 @@ test('create and update triples in one tx', () => {
|
|
|
741
662
|
},
|
|
742
663
|
{ upsert: false },
|
|
743
664
|
);
|
|
744
|
-
const
|
|
745
|
-
|
|
746
|
-
|
|
665
|
+
const ctx2 = transact(
|
|
666
|
+
ctx1.store,
|
|
667
|
+
ctx1.attrsStore,
|
|
668
|
+
instaml.transform({ attrsStore: zenecaAttrsStore }, chunk2),
|
|
747
669
|
);
|
|
748
|
-
const user2 = getUser(
|
|
670
|
+
const user2 = getUser(ctx2);
|
|
749
671
|
expect(user2.email).toEqual('e@mail 2');
|
|
750
672
|
expect(user2.fullName).toEqual('Full Name');
|
|
751
673
|
});
|
|
752
674
|
|
|
753
675
|
test('object values', () => {
|
|
754
|
-
const stopa = query(
|
|
755
|
-
{
|
|
756
|
-
|
|
757
|
-
users: {
|
|
758
|
-
$: { where: { handle: 'stopa' } },
|
|
759
|
-
},
|
|
676
|
+
const stopa = query(ctx, {
|
|
677
|
+
users: {
|
|
678
|
+
$: { where: { handle: 'stopa' } },
|
|
760
679
|
},
|
|
761
|
-
).data.users[0];
|
|
680
|
+
}).data.users[0];
|
|
762
681
|
expect(stopa.email).toEqual('stopa@instantdb.com');
|
|
763
682
|
const chunk = tx.users[stopa.id].update({
|
|
764
683
|
jsonField: { hello: 'world' },
|
|
765
684
|
otherJsonField: { world: 'hello' },
|
|
766
685
|
});
|
|
767
|
-
const txSteps = instaml.transform({
|
|
768
|
-
const
|
|
769
|
-
const newStopa = query(
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
users: {
|
|
773
|
-
$: { where: { handle: 'stopa' } },
|
|
774
|
-
},
|
|
686
|
+
const txSteps = instaml.transform({ attrsStore: zenecaAttrsStore }, chunk);
|
|
687
|
+
const newCtx = transact(store, zenecaAttrsStore, txSteps);
|
|
688
|
+
const newStopa = query(newCtx, {
|
|
689
|
+
users: {
|
|
690
|
+
$: { where: { handle: 'stopa' } },
|
|
775
691
|
},
|
|
776
|
-
).data.users[0];
|
|
692
|
+
}).data.users[0];
|
|
777
693
|
|
|
778
694
|
expect(newStopa.jsonField).toEqual({ hello: 'world' });
|
|
779
695
|
});
|
|
780
696
|
|
|
781
697
|
test('pagination limit', () => {
|
|
782
|
-
const books = query(
|
|
783
|
-
{
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
$: {
|
|
787
|
-
limit: 10,
|
|
788
|
-
},
|
|
698
|
+
const books = query(ctx, {
|
|
699
|
+
books: {
|
|
700
|
+
$: {
|
|
701
|
+
limit: 10,
|
|
789
702
|
},
|
|
790
703
|
},
|
|
791
|
-
).data.books;
|
|
704
|
+
}).data.books;
|
|
792
705
|
|
|
793
706
|
expect(books.length).toEqual(10);
|
|
794
707
|
});
|
|
@@ -798,18 +711,15 @@ test('nested limit works but warns', () => {
|
|
|
798
711
|
.spyOn(console, 'warn')
|
|
799
712
|
.mockImplementation(() => undefined);
|
|
800
713
|
|
|
801
|
-
const result = query(
|
|
802
|
-
{
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
$: {
|
|
807
|
-
limit: 4,
|
|
808
|
-
},
|
|
714
|
+
const result = query(ctx, {
|
|
715
|
+
bookshelves: {
|
|
716
|
+
books: {
|
|
717
|
+
$: {
|
|
718
|
+
limit: 4,
|
|
809
719
|
},
|
|
810
720
|
},
|
|
811
721
|
},
|
|
812
|
-
);
|
|
722
|
+
});
|
|
813
723
|
|
|
814
724
|
expect(result.data.bookshelves.length).toEqual(45);
|
|
815
725
|
// Should be "6" but is limited to 4
|
|
@@ -825,23 +735,21 @@ test('pagination offset waits for pageInfo', () => {
|
|
|
825
735
|
// wait to know which items in the store we should return.
|
|
826
736
|
// Otherwise, we might render optimistic changes for items
|
|
827
737
|
// that aren't in our range.
|
|
828
|
-
const booksWithOffset = query(
|
|
829
|
-
{
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
offset: 10,
|
|
834
|
-
limit: 5,
|
|
835
|
-
},
|
|
738
|
+
const booksWithOffset = query(ctx, {
|
|
739
|
+
books: {
|
|
740
|
+
$: {
|
|
741
|
+
offset: 10,
|
|
742
|
+
limit: 5,
|
|
836
743
|
},
|
|
837
744
|
},
|
|
838
|
-
).data.books;
|
|
745
|
+
}).data.books;
|
|
839
746
|
|
|
840
747
|
expect(booksWithOffset.length).toEqual(0);
|
|
841
748
|
|
|
842
749
|
const booksWithPageInfo = query(
|
|
843
750
|
{
|
|
844
751
|
store,
|
|
752
|
+
attrsStore: zenecaAttrsStore,
|
|
845
753
|
pageInfo: {
|
|
846
754
|
books: {
|
|
847
755
|
'start-cursor': [
|
|
@@ -881,6 +789,7 @@ test('pagination offset waits for pageInfo', () => {
|
|
|
881
789
|
const booksWithPageInfoAsc = query(
|
|
882
790
|
{
|
|
883
791
|
store,
|
|
792
|
+
attrsStore: zenecaAttrsStore,
|
|
884
793
|
pageInfo: {
|
|
885
794
|
books: {
|
|
886
795
|
'start-cursor': [
|
|
@@ -919,31 +828,25 @@ test('pagination offset waits for pageInfo', () => {
|
|
|
919
828
|
});
|
|
920
829
|
|
|
921
830
|
test('pagination last', () => {
|
|
922
|
-
const books = query(
|
|
923
|
-
{
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
$: {
|
|
927
|
-
last: 10,
|
|
928
|
-
},
|
|
831
|
+
const books = query(ctx, {
|
|
832
|
+
books: {
|
|
833
|
+
$: {
|
|
834
|
+
last: 10,
|
|
929
835
|
},
|
|
930
836
|
},
|
|
931
|
-
).data.books;
|
|
837
|
+
}).data.books;
|
|
932
838
|
|
|
933
839
|
expect(books.length).toEqual(10);
|
|
934
840
|
});
|
|
935
841
|
|
|
936
842
|
test('pagination first', () => {
|
|
937
|
-
const books = query(
|
|
938
|
-
{
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
$: {
|
|
942
|
-
first: 10,
|
|
943
|
-
},
|
|
843
|
+
const books = query(ctx, {
|
|
844
|
+
books: {
|
|
845
|
+
$: {
|
|
846
|
+
first: 10,
|
|
944
847
|
},
|
|
945
848
|
},
|
|
946
|
-
).data.books;
|
|
849
|
+
}).data.books;
|
|
947
850
|
|
|
948
851
|
expect(books.length).toEqual(10);
|
|
949
852
|
});
|
|
@@ -954,8 +857,8 @@ test('Leading queries should ignore the start cursor', () => {
|
|
|
954
857
|
createdAt: '2025-09-05 18:53:07.993689',
|
|
955
858
|
});
|
|
956
859
|
|
|
957
|
-
const txSteps = instaml.transform({
|
|
958
|
-
return transact(store, txSteps);
|
|
860
|
+
const txSteps = instaml.transform({ attrsStore: zenecaAttrsStore }, chunk);
|
|
861
|
+
return transact(store, zenecaAttrsStore, txSteps);
|
|
959
862
|
}
|
|
960
863
|
|
|
961
864
|
function storeWithBob() {
|
|
@@ -966,8 +869,8 @@ test('Leading queries should ignore the start cursor', () => {
|
|
|
966
869
|
createdAt: '2025-09-05 18:53:07.993689',
|
|
967
870
|
});
|
|
968
871
|
|
|
969
|
-
const txSteps = instaml.transform({
|
|
970
|
-
return transact(store, txSteps);
|
|
872
|
+
const txSteps = instaml.transform({ attrsStore: zenecaAttrsStore }, chunk);
|
|
873
|
+
return transact(store, zenecaAttrsStore, txSteps);
|
|
971
874
|
}
|
|
972
875
|
|
|
973
876
|
// Existing pageInfo from server: starts at Nicole (2021-02-05), ends at Alex (2021-01-09)
|
|
@@ -988,7 +891,7 @@ test('Leading queries should ignore the start cursor', () => {
|
|
|
988
891
|
},
|
|
989
892
|
};
|
|
990
893
|
const existingUsers = query(
|
|
991
|
-
{ store, pageInfo },
|
|
894
|
+
{ store, attrsStore: zenecaAttrsStore, pageInfo },
|
|
992
895
|
{
|
|
993
896
|
users: {
|
|
994
897
|
$: {
|
|
@@ -1006,7 +909,7 @@ test('Leading queries should ignore the start cursor', () => {
|
|
|
1006
909
|
// She should _still_ show up,
|
|
1007
910
|
// even though the cursor says otherwise
|
|
1008
911
|
const usersWithUpdatedNicole = query(
|
|
1009
|
-
{
|
|
912
|
+
{ ...storeWithUpdatedNicole(), pageInfo },
|
|
1010
913
|
{
|
|
1011
914
|
users: {
|
|
1012
915
|
$: {
|
|
@@ -1024,7 +927,7 @@ test('Leading queries should ignore the start cursor', () => {
|
|
|
1024
927
|
// Bob _should_ show up,
|
|
1025
928
|
// even though the cursor says otherwise
|
|
1026
929
|
const usersWithBob = query(
|
|
1027
|
-
{
|
|
930
|
+
{ ...storeWithBob(), pageInfo },
|
|
1028
931
|
{
|
|
1029
932
|
users: {
|
|
1030
933
|
$: {
|
|
@@ -1040,10 +943,9 @@ test('Leading queries should ignore the start cursor', () => {
|
|
|
1040
943
|
});
|
|
1041
944
|
|
|
1042
945
|
test('arbitrary ordering', () => {
|
|
1043
|
-
const books = query(
|
|
1044
|
-
{
|
|
1045
|
-
|
|
1046
|
-
);
|
|
946
|
+
const books = query(ctx, {
|
|
947
|
+
books: { $: { first: 10, order: { title: 'asc' } } },
|
|
948
|
+
});
|
|
1047
949
|
|
|
1048
950
|
const titles = books.data.books.map((x) => x.title);
|
|
1049
951
|
expect(titles).toEqual([
|
|
@@ -1071,7 +973,7 @@ test('arbitrary ordering with dates', () => {
|
|
|
1071
973
|
},
|
|
1072
974
|
});
|
|
1073
975
|
|
|
1074
|
-
const txSteps = [];
|
|
976
|
+
const txSteps: any[] = [];
|
|
1075
977
|
let id = 0;
|
|
1076
978
|
for (let i = -5; i < 5; i++) {
|
|
1077
979
|
txSteps.push(
|
|
@@ -1112,20 +1014,22 @@ test('arbitrary ordering with dates', () => {
|
|
|
1112
1014
|
}),
|
|
1113
1015
|
);
|
|
1114
1016
|
|
|
1115
|
-
const
|
|
1017
|
+
const newCtx = transact(
|
|
1116
1018
|
store,
|
|
1117
|
-
|
|
1019
|
+
zenecaAttrsStore,
|
|
1020
|
+
instaml.transform(
|
|
1021
|
+
{ attrsStore: zenecaAttrsStore, schema: schema },
|
|
1022
|
+
txSteps,
|
|
1023
|
+
),
|
|
1118
1024
|
);
|
|
1119
1025
|
|
|
1120
|
-
const descRes = query(
|
|
1121
|
-
{
|
|
1122
|
-
|
|
1123
|
-
).data.tests.map((x) => x.date);
|
|
1026
|
+
const descRes = query(newCtx, {
|
|
1027
|
+
tests: { $: { order: { date: 'desc' } } },
|
|
1028
|
+
}).data.tests.map((x) => x.date);
|
|
1124
1029
|
|
|
1125
|
-
const numDescRes = query(
|
|
1126
|
-
{
|
|
1127
|
-
|
|
1128
|
-
).data.tests.map((x) => x.num);
|
|
1030
|
+
const numDescRes = query(newCtx, {
|
|
1031
|
+
tests: { $: { order: { num: 'desc' } } },
|
|
1032
|
+
}).data.tests.map((x) => x.num);
|
|
1129
1033
|
|
|
1130
1034
|
const descExpected = [
|
|
1131
1035
|
4,
|
|
@@ -1148,15 +1052,13 @@ test('arbitrary ordering with dates', () => {
|
|
|
1148
1052
|
|
|
1149
1053
|
expect(numDescRes).toEqual(descExpected);
|
|
1150
1054
|
|
|
1151
|
-
const ascRes = query(
|
|
1152
|
-
{
|
|
1153
|
-
|
|
1154
|
-
).data.tests.map((x) => x.date);
|
|
1055
|
+
const ascRes = query(newCtx, {
|
|
1056
|
+
tests: { $: { order: { date: 'asc' } } },
|
|
1057
|
+
}).data.tests.map((x) => x.date);
|
|
1155
1058
|
|
|
1156
|
-
const numAscRes = query(
|
|
1157
|
-
{
|
|
1158
|
-
|
|
1159
|
-
).data.tests.map((x) => x.num);
|
|
1059
|
+
const numAscRes = query(newCtx, {
|
|
1060
|
+
tests: { $: { order: { num: 'asc' } } },
|
|
1061
|
+
}).data.tests.map((x) => x.num);
|
|
1160
1062
|
|
|
1161
1063
|
const ascExpected = [
|
|
1162
1064
|
null,
|
|
@@ -1188,7 +1090,7 @@ test('arbitrary ordering with strings', () => {
|
|
|
1188
1090
|
},
|
|
1189
1091
|
});
|
|
1190
1092
|
|
|
1191
|
-
const txSteps = [];
|
|
1093
|
+
const txSteps: any[] = [];
|
|
1192
1094
|
const vs = ['10', '2', 'a0', 'Zz'];
|
|
1193
1095
|
for (const v of vs) {
|
|
1194
1096
|
txSteps.push(
|
|
@@ -1198,36 +1100,39 @@ test('arbitrary ordering with strings', () => {
|
|
|
1198
1100
|
);
|
|
1199
1101
|
}
|
|
1200
1102
|
|
|
1201
|
-
const
|
|
1103
|
+
const newCtx = transact(
|
|
1202
1104
|
store,
|
|
1203
|
-
|
|
1105
|
+
zenecaAttrsStore,
|
|
1106
|
+
instaml.transform(
|
|
1107
|
+
{ attrsStore: zenecaAttrsStore, schema: schema },
|
|
1108
|
+
txSteps,
|
|
1109
|
+
),
|
|
1204
1110
|
);
|
|
1205
1111
|
|
|
1206
|
-
const ascRes = query(
|
|
1207
|
-
{
|
|
1208
|
-
|
|
1209
|
-
).data.tests.map((x) => x.string);
|
|
1112
|
+
const ascRes = query(newCtx, {
|
|
1113
|
+
tests: { $: { order: { string: 'asc' } } },
|
|
1114
|
+
}).data.tests.map((x) => x.string);
|
|
1210
1115
|
|
|
1211
1116
|
expect(ascRes).toEqual(vs);
|
|
1212
1117
|
|
|
1213
|
-
const descRes = query(
|
|
1214
|
-
{
|
|
1215
|
-
|
|
1216
|
-
).data.tests.map((x) => x.string);
|
|
1118
|
+
const descRes = query(newCtx, {
|
|
1119
|
+
tests: { $: { order: { string: 'desc' } } },
|
|
1120
|
+
}).data.tests.map((x) => x.string);
|
|
1217
1121
|
|
|
1122
|
+
// @ts-expect-error: doesn't like toReversed()
|
|
1218
1123
|
expect(descRes).toEqual(vs.toReversed());
|
|
1219
1124
|
});
|
|
1220
1125
|
|
|
1221
1126
|
test('$isNull', () => {
|
|
1222
1127
|
const q = { books: { $: { where: { title: { $isNull: true } } } } };
|
|
1223
|
-
expect(query(
|
|
1128
|
+
expect(query(ctx, q).data.books.length).toEqual(0);
|
|
1224
1129
|
const chunks = [
|
|
1225
1130
|
tx.books[randomUUID()].update({ title: null }),
|
|
1226
1131
|
tx.books[randomUUID()].update({ pageCount: 20 }),
|
|
1227
1132
|
];
|
|
1228
|
-
const txSteps = instaml.transform({
|
|
1229
|
-
const
|
|
1230
|
-
expect(query(
|
|
1133
|
+
const txSteps = instaml.transform({ attrsStore: zenecaAttrsStore }, chunks);
|
|
1134
|
+
const newCtx = transact(store, zenecaAttrsStore, txSteps);
|
|
1135
|
+
expect(query(newCtx, q).data.books.map((x) => x.title)).toEqual([
|
|
1231
1136
|
null,
|
|
1232
1137
|
undefined,
|
|
1233
1138
|
]);
|
|
@@ -1235,47 +1140,37 @@ test('$isNull', () => {
|
|
|
1235
1140
|
|
|
1236
1141
|
test('$isNull with relations', () => {
|
|
1237
1142
|
const q = { users: { $: { where: { bookshelves: { $isNull: true } } } } };
|
|
1238
|
-
expect(query(
|
|
1143
|
+
expect(query(ctx, q).data.users.length).toEqual(0);
|
|
1239
1144
|
const chunks = [tx.users[randomUUID()].update({ handle: 'dww' })];
|
|
1240
|
-
const txSteps = instaml.transform({
|
|
1241
|
-
const
|
|
1242
|
-
expect(query(
|
|
1243
|
-
['dww'],
|
|
1244
|
-
);
|
|
1145
|
+
const txSteps = instaml.transform({ attrsStore: zenecaAttrsStore }, chunks);
|
|
1146
|
+
const newCtx = transact(store, zenecaAttrsStore, txSteps);
|
|
1147
|
+
expect(query(newCtx, q).data.users.map((x) => x.handle)).toEqual(['dww']);
|
|
1245
1148
|
|
|
1246
|
-
const bookId = query(
|
|
1247
|
-
{
|
|
1248
|
-
|
|
1249
|
-
).data.books[0].id;
|
|
1149
|
+
const bookId = query(ctx, {
|
|
1150
|
+
books: { $: { where: { title: 'The Count of Monte Cristo' } } },
|
|
1151
|
+
}).data.books[0].id;
|
|
1250
1152
|
|
|
1251
|
-
const usersWithBook = query(
|
|
1252
|
-
{
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
$: {
|
|
1256
|
-
where: { 'bookshelves.books.title': 'The Count of Monte Cristo' },
|
|
1257
|
-
},
|
|
1153
|
+
const usersWithBook = query(ctx, {
|
|
1154
|
+
users: {
|
|
1155
|
+
$: {
|
|
1156
|
+
where: { 'bookshelves.books.title': 'The Count of Monte Cristo' },
|
|
1258
1157
|
},
|
|
1259
1158
|
},
|
|
1260
|
-
).data.users.map((x) => x.handle);
|
|
1159
|
+
}).data.users.map((x) => x.handle);
|
|
1261
1160
|
|
|
1262
|
-
const
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
]),
|
|
1161
|
+
const ctxWithNullTitle = transact(
|
|
1162
|
+
newCtx.store,
|
|
1163
|
+
newCtx.attrsStore,
|
|
1164
|
+
instaml.transform(newCtx, [tx.books[bookId].update({ title: null })]),
|
|
1267
1165
|
);
|
|
1268
1166
|
|
|
1269
|
-
const usersWithNullTitle = query(
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
$: {
|
|
1274
|
-
where: { 'bookshelves.books.title': { $isNull: true } },
|
|
1275
|
-
},
|
|
1167
|
+
const usersWithNullTitle = query(ctxWithNullTitle, {
|
|
1168
|
+
users: {
|
|
1169
|
+
$: {
|
|
1170
|
+
where: { 'bookshelves.books.title': { $isNull: true } },
|
|
1276
1171
|
},
|
|
1277
1172
|
},
|
|
1278
|
-
).data.users.map((x) => x.handle);
|
|
1173
|
+
}).data.users.map((x) => x.handle);
|
|
1279
1174
|
|
|
1280
1175
|
expect(usersWithNullTitle).toEqual([...usersWithBook, 'dww']);
|
|
1281
1176
|
});
|
|
@@ -1284,16 +1179,16 @@ test('$isNull with reverse relations', () => {
|
|
|
1284
1179
|
const q = {
|
|
1285
1180
|
bookshelves: { $: { where: { 'users.id': { $isNull: true } } }, users: {} },
|
|
1286
1181
|
};
|
|
1287
|
-
expect(query(
|
|
1182
|
+
expect(query(ctx, q).data.bookshelves.length).toBe(0);
|
|
1288
1183
|
|
|
1289
1184
|
const chunks = [
|
|
1290
1185
|
tx.bookshelves[randomUUID()].update({ name: 'Lonely shelf' }),
|
|
1291
1186
|
];
|
|
1292
|
-
const txSteps = instaml.transform({
|
|
1293
|
-
const
|
|
1294
|
-
expect(
|
|
1295
|
-
|
|
1296
|
-
|
|
1187
|
+
const txSteps = instaml.transform({ attrsStore: zenecaAttrsStore }, chunks);
|
|
1188
|
+
const newCtx = transact(store, zenecaAttrsStore, txSteps);
|
|
1189
|
+
expect(query(newCtx, q).data.bookshelves.map((x) => x.name)).toEqual([
|
|
1190
|
+
'Lonely shelf',
|
|
1191
|
+
]);
|
|
1297
1192
|
});
|
|
1298
1193
|
|
|
1299
1194
|
test('$not and $ne', () => {
|
|
@@ -1306,15 +1201,11 @@ test('$not and $ne', () => {
|
|
|
1306
1201
|
tx.tests[randomUUID()].update({ val: null }),
|
|
1307
1202
|
tx.tests[randomUUID()].update({ undefinedVal: 'd' }),
|
|
1308
1203
|
];
|
|
1309
|
-
const txSteps = instaml.transform({
|
|
1310
|
-
const
|
|
1204
|
+
const txSteps = instaml.transform({ attrsStore: zenecaAttrsStore }, chunks);
|
|
1205
|
+
const newCtx = transact(store, zenecaAttrsStore, txSteps);
|
|
1311
1206
|
const expected = ['b', 'c', null, undefined];
|
|
1312
|
-
expect(query(
|
|
1313
|
-
|
|
1314
|
-
);
|
|
1315
|
-
expect(query({ store: newStore }, qNe).data.tests.map((x) => x.val)).toEqual(
|
|
1316
|
-
expected,
|
|
1317
|
-
);
|
|
1207
|
+
expect(query(newCtx, qNot).data.tests.map((x) => x.val)).toEqual(expected);
|
|
1208
|
+
expect(query(newCtx, qNe).data.tests.map((x) => x.val)).toEqual(expected);
|
|
1318
1209
|
});
|
|
1319
1210
|
|
|
1320
1211
|
test('comparators', () => {
|
|
@@ -1329,7 +1220,7 @@ test('comparators', () => {
|
|
|
1329
1220
|
},
|
|
1330
1221
|
});
|
|
1331
1222
|
|
|
1332
|
-
const txSteps = [];
|
|
1223
|
+
const txSteps: any[] = [];
|
|
1333
1224
|
for (let i = 0; i < 5; i++) {
|
|
1334
1225
|
txSteps.push(
|
|
1335
1226
|
tx.tests[randomUUID()].update({
|
|
@@ -1341,20 +1232,21 @@ test('comparators', () => {
|
|
|
1341
1232
|
);
|
|
1342
1233
|
}
|
|
1343
1234
|
|
|
1344
|
-
const
|
|
1235
|
+
const newCtx = transact(
|
|
1345
1236
|
store,
|
|
1346
|
-
|
|
1237
|
+
zenecaAttrsStore,
|
|
1238
|
+
instaml.transform(
|
|
1239
|
+
{ attrsStore: zenecaAttrsStore, schema: schema },
|
|
1240
|
+
txSteps,
|
|
1241
|
+
),
|
|
1347
1242
|
);
|
|
1348
1243
|
|
|
1349
1244
|
function runQuery(dataType, op, value) {
|
|
1350
|
-
const res = query(
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
tests: {
|
|
1354
|
-
$: { where: { [dataType]: { [op]: value } } },
|
|
1355
|
-
},
|
|
1245
|
+
const res = query(newCtx, {
|
|
1246
|
+
tests: {
|
|
1247
|
+
$: { where: { [dataType]: { [op]: value } } },
|
|
1356
1248
|
},
|
|
1357
|
-
);
|
|
1249
|
+
});
|
|
1358
1250
|
return res.data.tests.map((x) => x[dataType]);
|
|
1359
1251
|
}
|
|
1360
1252
|
|
|
@@ -1394,9 +1286,7 @@ test('comparators', () => {
|
|
|
1394
1286
|
});
|
|
1395
1287
|
|
|
1396
1288
|
test('fields', () => {
|
|
1397
|
-
expect(
|
|
1398
|
-
query({ store }, { users: { $: { fields: ['handle'] } } }).data,
|
|
1399
|
-
).toEqual({
|
|
1289
|
+
expect(query(ctx, { users: { $: { fields: ['handle'] } } }).data).toEqual({
|
|
1400
1290
|
users: [
|
|
1401
1291
|
{ handle: 'joe', id: 'ce942051-2d74-404a-9c7d-4aa3f2d54ae4' },
|
|
1402
1292
|
{ handle: 'alex', id: 'ad45e100-777a-4de8-8978-aa13200a4824' },
|
|
@@ -1406,15 +1296,12 @@ test('fields', () => {
|
|
|
1406
1296
|
});
|
|
1407
1297
|
|
|
1408
1298
|
expect(
|
|
1409
|
-
query(
|
|
1410
|
-
{
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
$: { where: { handle: 'alex' }, fields: ['handle'] },
|
|
1414
|
-
bookshelves: { $: { fields: ['name'] } },
|
|
1415
|
-
},
|
|
1299
|
+
query(ctx, {
|
|
1300
|
+
users: {
|
|
1301
|
+
$: { where: { handle: 'alex' }, fields: ['handle'] },
|
|
1302
|
+
bookshelves: { $: { fields: ['name'] } },
|
|
1416
1303
|
},
|
|
1417
|
-
).data,
|
|
1304
|
+
}).data,
|
|
1418
1305
|
).toEqual({
|
|
1419
1306
|
users: [
|
|
1420
1307
|
{
|
|
@@ -1435,7 +1322,7 @@ test('fields', () => {
|
|
|
1435
1322
|
});
|
|
1436
1323
|
|
|
1437
1324
|
// id is always included
|
|
1438
|
-
expect(query(
|
|
1325
|
+
expect(query(ctx, { users: { $: { fields: [] } } }).data).toEqual({
|
|
1439
1326
|
users: [
|
|
1440
1327
|
{ id: 'ce942051-2d74-404a-9c7d-4aa3f2d54ae4' },
|
|
1441
1328
|
{ id: 'ad45e100-777a-4de8-8978-aa13200a4824' },
|