@instantdb/core 0.22.88 → 0.22.89-experimental.drewh-ssr.20277611943.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/serializeSchema.test.ts +123 -0
- package/__tests__/src/{store.test.js → store.test.ts} +215 -212
- package/dist/commonjs/Reactor.d.ts +36 -7
- package/dist/commonjs/Reactor.d.ts.map +1 -1
- package/dist/commonjs/Reactor.js +176 -47
- 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/createRouteHandler.d.ts +8 -0
- package/dist/commonjs/createRouteHandler.d.ts.map +1 -0
- package/dist/commonjs/createRouteHandler.js +57 -0
- package/dist/commonjs/createRouteHandler.js.map +1 -0
- package/dist/commonjs/framework.d.ts +77 -0
- package/dist/commonjs/framework.d.ts.map +1 -0
- package/dist/commonjs/framework.js +209 -0
- package/dist/commonjs/framework.js.map +1 -0
- package/dist/commonjs/index.d.ts +5 -1
- package/dist/commonjs/index.d.ts.map +1 -1
- package/dist/commonjs/index.js +7 -1
- package/dist/commonjs/index.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/parseSchemaFromJSON.d.ts +3 -0
- package/dist/commonjs/parseSchemaFromJSON.d.ts.map +1 -0
- package/dist/commonjs/parseSchemaFromJSON.js +148 -0
- package/dist/commonjs/parseSchemaFromJSON.js.map +1 -0
- package/dist/commonjs/reactorTypes.d.ts +30 -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 +36 -7
- package/dist/esm/Reactor.d.ts.map +1 -1
- package/dist/esm/Reactor.js +177 -48
- 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/createRouteHandler.d.ts +8 -0
- package/dist/esm/createRouteHandler.d.ts.map +1 -0
- package/dist/esm/createRouteHandler.js +53 -0
- package/dist/esm/createRouteHandler.js.map +1 -0
- package/dist/esm/framework.d.ts +77 -0
- package/dist/esm/framework.d.ts.map +1 -0
- package/dist/esm/framework.js +169 -0
- package/dist/esm/framework.js.map +1 -0
- package/dist/esm/index.d.ts +5 -1
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +5 -2
- package/dist/esm/index.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/parseSchemaFromJSON.d.ts +3 -0
- package/dist/esm/parseSchemaFromJSON.d.ts.map +1 -0
- package/dist/esm/parseSchemaFromJSON.js +144 -0
- package/dist/esm/parseSchemaFromJSON.js.map +1 -0
- package/dist/esm/reactorTypes.d.ts +30 -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 +2899 -2389
- package/dist/standalone/index.umd.cjs +3 -3
- package/package.json +2 -2
- package/src/Reactor.js +232 -77
- package/src/SyncTable.ts +85 -45
- package/src/createRouteHandler.ts +44 -0
- package/src/framework.ts +294 -0
- package/src/index.ts +9 -0
- package/src/{instaml.js → instaml.ts} +201 -96
- package/src/instaql.ts +88 -62
- package/src/parseSchemaFromJSON.ts +176 -0
- package/src/reactorTypes.ts +33 -0
- package/src/store.ts +257 -101
- package/__tests__/src/instaql.bench.js +0 -29
package/src/instaql.ts
CHANGED
|
@@ -47,8 +47,8 @@ class AttrNotFoundError extends Error {
|
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
-
function idAttr(
|
|
51
|
-
const attr = s.getPrimaryKeyAttr(
|
|
50
|
+
function idAttr(attrsStore: s.AttrsStore, ns: string): InstantDBAttr {
|
|
51
|
+
const attr = s.getPrimaryKeyAttr(attrsStore, ns);
|
|
52
52
|
|
|
53
53
|
if (!attr) {
|
|
54
54
|
throw new AttrNotFoundError(`Could not find id attr for ${ns}`);
|
|
@@ -58,22 +58,22 @@ function idAttr(store: s.Store, ns: string): InstantDBAttr {
|
|
|
58
58
|
|
|
59
59
|
function defaultWhere(
|
|
60
60
|
makeVar: MakeVar,
|
|
61
|
-
|
|
61
|
+
attrsStore: s.AttrsStore,
|
|
62
62
|
etype: string,
|
|
63
63
|
level: number,
|
|
64
64
|
): Pats {
|
|
65
|
-
return [eidWhere(makeVar,
|
|
65
|
+
return [eidWhere(makeVar, attrsStore, etype, level)];
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
function eidWhere(
|
|
69
69
|
makeVar: MakeVar,
|
|
70
|
-
|
|
70
|
+
attrsStore: s.AttrsStore,
|
|
71
71
|
etype: string,
|
|
72
72
|
level: number,
|
|
73
73
|
): Pat {
|
|
74
74
|
return [
|
|
75
75
|
makeVar(etype, level),
|
|
76
|
-
idAttr(
|
|
76
|
+
idAttr(attrsStore, etype).id,
|
|
77
77
|
makeVar(etype, level),
|
|
78
78
|
makeVar('time', level),
|
|
79
79
|
];
|
|
@@ -85,13 +85,13 @@ function replaceInAttrPat(attrPat: Pat, needle: string, v: any): Pat {
|
|
|
85
85
|
|
|
86
86
|
function refAttrPat(
|
|
87
87
|
makeVar: MakeVar,
|
|
88
|
-
|
|
88
|
+
attrsStore: s.AttrsStore,
|
|
89
89
|
etype: string,
|
|
90
90
|
level: number,
|
|
91
91
|
label: string,
|
|
92
92
|
): [string, number, Pat, InstantDBAttr, boolean] {
|
|
93
|
-
const fwdAttr = s.getAttrByFwdIdentName(
|
|
94
|
-
const revAttr = s.getAttrByReverseIdentName(
|
|
93
|
+
const fwdAttr = s.getAttrByFwdIdentName(attrsStore, etype, label);
|
|
94
|
+
const revAttr = s.getAttrByReverseIdentName(attrsStore, etype, label);
|
|
95
95
|
const attr = fwdAttr || revAttr;
|
|
96
96
|
|
|
97
97
|
if (!attr) {
|
|
@@ -235,14 +235,18 @@ function parseValue(attr: InstantDBAttr, v: any) {
|
|
|
235
235
|
|
|
236
236
|
function valueAttrPat(
|
|
237
237
|
makeVar: MakeVar,
|
|
238
|
-
|
|
238
|
+
attrsStore: s.AttrsStore,
|
|
239
239
|
valueEtype: string,
|
|
240
240
|
valueLevel: number,
|
|
241
241
|
valueLabel: string,
|
|
242
242
|
v: any,
|
|
243
243
|
): Pat {
|
|
244
|
-
const fwdAttr = s.getAttrByFwdIdentName(
|
|
245
|
-
const revAttr = s.getAttrByReverseIdentName(
|
|
244
|
+
const fwdAttr = s.getAttrByFwdIdentName(attrsStore, valueEtype, valueLabel);
|
|
245
|
+
const revAttr = s.getAttrByReverseIdentName(
|
|
246
|
+
attrsStore,
|
|
247
|
+
valueEtype,
|
|
248
|
+
valueLabel,
|
|
249
|
+
);
|
|
246
250
|
const attr = fwdAttr || revAttr;
|
|
247
251
|
|
|
248
252
|
if (!attr) {
|
|
@@ -252,7 +256,7 @@ function valueAttrPat(
|
|
|
252
256
|
}
|
|
253
257
|
|
|
254
258
|
if (v?.hasOwnProperty('$isNull')) {
|
|
255
|
-
const idAttr = s.getAttrByFwdIdentName(
|
|
259
|
+
const idAttr = s.getAttrByFwdIdentName(attrsStore, valueEtype, 'id');
|
|
256
260
|
if (!idAttr) {
|
|
257
261
|
throw new AttrNotFoundError(
|
|
258
262
|
`No attr for etype = ${valueEtype} label = id`,
|
|
@@ -280,7 +284,7 @@ function valueAttrPat(
|
|
|
280
284
|
|
|
281
285
|
function refAttrPats(
|
|
282
286
|
makeVar: MakeVar,
|
|
283
|
-
|
|
287
|
+
attrsStore: s.AttrsStore,
|
|
284
288
|
etype: string,
|
|
285
289
|
level: number,
|
|
286
290
|
refsPath: string[],
|
|
@@ -290,7 +294,7 @@ function refAttrPats(
|
|
|
290
294
|
const [etype, level, attrPats] = acc;
|
|
291
295
|
const [nextEtype, nextLevel, attrPat] = refAttrPat(
|
|
292
296
|
makeVar,
|
|
293
|
-
|
|
297
|
+
attrsStore,
|
|
294
298
|
etype,
|
|
295
299
|
level,
|
|
296
300
|
label,
|
|
@@ -305,7 +309,7 @@ function refAttrPats(
|
|
|
305
309
|
|
|
306
310
|
function whereCondAttrPats(
|
|
307
311
|
makeVar: MakeVar,
|
|
308
|
-
|
|
312
|
+
attrsStore: s.AttrsStore,
|
|
309
313
|
etype: string,
|
|
310
314
|
level: number,
|
|
311
315
|
path: string[],
|
|
@@ -315,14 +319,14 @@ function whereCondAttrPats(
|
|
|
315
319
|
const valueLabel = path[path.length - 1];
|
|
316
320
|
const [lastEtype, lastLevel, refPats] = refAttrPats(
|
|
317
321
|
makeVar,
|
|
318
|
-
|
|
322
|
+
attrsStore,
|
|
319
323
|
etype,
|
|
320
324
|
level,
|
|
321
325
|
refsPath,
|
|
322
326
|
);
|
|
323
327
|
const valuePat = valueAttrPat(
|
|
324
328
|
makeVar,
|
|
325
|
-
|
|
329
|
+
attrsStore,
|
|
326
330
|
lastEtype,
|
|
327
331
|
lastLevel,
|
|
328
332
|
valueLabel,
|
|
@@ -359,7 +363,7 @@ function genMakeVar(baseMakeVar: MakeVar, joinSym: string, orIdx: number) {
|
|
|
359
363
|
function parseWhereClauses(
|
|
360
364
|
makeVar: MakeVar,
|
|
361
365
|
clauseType: 'or' | 'and' /* 'or' | 'and' */,
|
|
362
|
-
|
|
366
|
+
attrsStore: s.AttrsStore,
|
|
363
367
|
etype: string,
|
|
364
368
|
level: number,
|
|
365
369
|
whereValue: any,
|
|
@@ -367,7 +371,7 @@ function parseWhereClauses(
|
|
|
367
371
|
const joinSym = makeVar(etype, level);
|
|
368
372
|
const patterns: FullPats = whereValue.map((w, i) => {
|
|
369
373
|
const makeNamespacedVar = genMakeVar(makeVar, joinSym, i);
|
|
370
|
-
return parseWhere(makeNamespacedVar,
|
|
374
|
+
return parseWhere(makeNamespacedVar, attrsStore, etype, level, w);
|
|
371
375
|
});
|
|
372
376
|
return { [clauseType]: { patterns, joinSym } } as AndPat | OrPat;
|
|
373
377
|
}
|
|
@@ -386,29 +390,31 @@ function growPath<T>(path: T[]) {
|
|
|
386
390
|
// to capture any intermediate nulls
|
|
387
391
|
function whereCondAttrPatsForNullIsTrue(
|
|
388
392
|
makeVar: MakeVar,
|
|
389
|
-
|
|
393
|
+
attrsStore: s.AttrsStore,
|
|
390
394
|
etype: string,
|
|
391
395
|
level: number,
|
|
392
396
|
path: string[],
|
|
393
397
|
): Pats[] {
|
|
394
398
|
return growPath(path).map((path) =>
|
|
395
|
-
whereCondAttrPats(makeVar,
|
|
399
|
+
whereCondAttrPats(makeVar, attrsStore, etype, level, path, {
|
|
400
|
+
$isNull: true,
|
|
401
|
+
}),
|
|
396
402
|
);
|
|
397
403
|
}
|
|
398
404
|
|
|
399
405
|
function parseWhere(
|
|
400
406
|
makeVar: MakeVar,
|
|
401
|
-
|
|
407
|
+
attrsStore: s.AttrsStore,
|
|
402
408
|
etype: string,
|
|
403
409
|
level: number,
|
|
404
410
|
where: Record<string, any>,
|
|
405
411
|
): FullPats {
|
|
406
412
|
return Object.entries(where).flatMap(([k, v]) => {
|
|
407
413
|
if (isOrClauses([k, v])) {
|
|
408
|
-
return parseWhereClauses(makeVar, 'or',
|
|
414
|
+
return parseWhereClauses(makeVar, 'or', attrsStore, etype, level, v);
|
|
409
415
|
}
|
|
410
416
|
if (isAndClauses([k, v])) {
|
|
411
|
-
return parseWhereClauses(makeVar, 'and',
|
|
417
|
+
return parseWhereClauses(makeVar, 'and', attrsStore, etype, level, v);
|
|
412
418
|
}
|
|
413
419
|
|
|
414
420
|
// Temporary hack until we have support for a uuid index on `id`
|
|
@@ -427,10 +433,17 @@ function parseWhere(
|
|
|
427
433
|
if (v?.hasOwnProperty('$not')) {
|
|
428
434
|
// `$not` won't pick up entities that are missing the attr, so we
|
|
429
435
|
// add in a `$isNull` to catch those too.
|
|
430
|
-
const notPats = whereCondAttrPats(
|
|
436
|
+
const notPats = whereCondAttrPats(
|
|
437
|
+
makeVar,
|
|
438
|
+
attrsStore,
|
|
439
|
+
etype,
|
|
440
|
+
level,
|
|
441
|
+
path,
|
|
442
|
+
v,
|
|
443
|
+
);
|
|
431
444
|
const nilPats = whereCondAttrPatsForNullIsTrue(
|
|
432
445
|
makeVar,
|
|
433
|
-
|
|
446
|
+
attrsStore,
|
|
434
447
|
etype,
|
|
435
448
|
level,
|
|
436
449
|
path,
|
|
@@ -453,7 +466,7 @@ function parseWhere(
|
|
|
453
466
|
or: {
|
|
454
467
|
patterns: whereCondAttrPatsForNullIsTrue(
|
|
455
468
|
makeVar,
|
|
456
|
-
|
|
469
|
+
attrsStore,
|
|
457
470
|
etype,
|
|
458
471
|
level,
|
|
459
472
|
path,
|
|
@@ -464,22 +477,22 @@ function parseWhere(
|
|
|
464
477
|
];
|
|
465
478
|
}
|
|
466
479
|
|
|
467
|
-
return whereCondAttrPats(makeVar,
|
|
480
|
+
return whereCondAttrPats(makeVar, attrsStore, etype, level, path, v);
|
|
468
481
|
});
|
|
469
482
|
}
|
|
470
483
|
|
|
471
484
|
function makeWhere(
|
|
472
|
-
|
|
485
|
+
attrsStore: s.AttrsStore,
|
|
473
486
|
etype: string,
|
|
474
487
|
level: number,
|
|
475
488
|
where: Record<string, any> | null,
|
|
476
489
|
): FullPats {
|
|
477
490
|
const makeVar = makeVarImpl;
|
|
478
491
|
if (!where) {
|
|
479
|
-
return defaultWhere(makeVar,
|
|
492
|
+
return defaultWhere(makeVar, attrsStore, etype, level);
|
|
480
493
|
}
|
|
481
|
-
const parsedWhere = parseWhere(makeVar,
|
|
482
|
-
return parsedWhere.concat(defaultWhere(makeVar,
|
|
494
|
+
const parsedWhere = parseWhere(makeVar, attrsStore, etype, level, where);
|
|
495
|
+
return parsedWhere.concat(defaultWhere(makeVar, attrsStore, etype, level));
|
|
483
496
|
}
|
|
484
497
|
|
|
485
498
|
// Find
|
|
@@ -494,7 +507,7 @@ function makeFind(makeVar: MakeVar, etype: string, level: number) {
|
|
|
494
507
|
|
|
495
508
|
function makeJoin(
|
|
496
509
|
makeVar: MakeVar,
|
|
497
|
-
|
|
510
|
+
attrsStore: s.AttrsStore,
|
|
498
511
|
etype: string,
|
|
499
512
|
level: number,
|
|
500
513
|
label: string,
|
|
@@ -502,7 +515,7 @@ function makeJoin(
|
|
|
502
515
|
) {
|
|
503
516
|
const [nextEtype, nextLevel, pat, attr, isForward] = refAttrPat(
|
|
504
517
|
makeVar,
|
|
505
|
-
|
|
518
|
+
attrsStore,
|
|
506
519
|
etype,
|
|
507
520
|
level,
|
|
508
521
|
label,
|
|
@@ -511,7 +524,13 @@ function makeJoin(
|
|
|
511
524
|
return [nextEtype, nextLevel, actualized, attr, isForward];
|
|
512
525
|
}
|
|
513
526
|
|
|
514
|
-
function extendObjects(
|
|
527
|
+
function extendObjects(
|
|
528
|
+
makeVar: MakeVar,
|
|
529
|
+
store: s.Store,
|
|
530
|
+
attrsStore: s.AttrsStore,
|
|
531
|
+
{ etype, level, form },
|
|
532
|
+
objects,
|
|
533
|
+
) {
|
|
515
534
|
const childQueries = Object.keys(form).filter((c) => c !== '$');
|
|
516
535
|
if (!childQueries.length) {
|
|
517
536
|
return Object.values(objects);
|
|
@@ -520,20 +539,20 @@ function extendObjects(makeVar, store, { etype, level, form }, objects) {
|
|
|
520
539
|
const childResults = childQueries.map(function getChildResult(label) {
|
|
521
540
|
const isSingular = Boolean(
|
|
522
541
|
store.cardinalityInference &&
|
|
523
|
-
|
|
542
|
+
attrsStore.linkIndex?.[etype]?.[label]?.isSingular,
|
|
524
543
|
);
|
|
525
544
|
|
|
526
545
|
try {
|
|
527
546
|
const [nextEtype, nextLevel, join] = makeJoin(
|
|
528
547
|
makeVar,
|
|
529
|
-
|
|
548
|
+
attrsStore,
|
|
530
549
|
etype,
|
|
531
550
|
level,
|
|
532
551
|
label,
|
|
533
552
|
eid,
|
|
534
553
|
);
|
|
535
554
|
|
|
536
|
-
const childrenArray = queryOne(store, {
|
|
555
|
+
const childrenArray = queryOne(store, attrsStore, {
|
|
537
556
|
etype: nextEtype,
|
|
538
557
|
level: nextLevel,
|
|
539
558
|
form: form[label],
|
|
@@ -624,38 +643,38 @@ function isBefore(startCursor, orderAttr, direction, idVec) {
|
|
|
624
643
|
);
|
|
625
644
|
}
|
|
626
645
|
|
|
627
|
-
function orderAttrFromCursor(
|
|
646
|
+
function orderAttrFromCursor(attrsStore: s.AttrsStore, cursor) {
|
|
628
647
|
const cursorAttrId = cursor[1];
|
|
629
|
-
return
|
|
648
|
+
return attrsStore.getAttr(cursorAttrId);
|
|
630
649
|
}
|
|
631
650
|
|
|
632
|
-
function orderAttrFromOrder(
|
|
651
|
+
function orderAttrFromOrder(attrsStore: s.AttrsStore, etype, order) {
|
|
633
652
|
const label = Object.keys(order)[0];
|
|
634
|
-
return s.getAttrByFwdIdentName(
|
|
653
|
+
return s.getAttrByFwdIdentName(attrsStore, etype, label);
|
|
635
654
|
}
|
|
636
655
|
|
|
637
|
-
function getOrderAttr(
|
|
656
|
+
function getOrderAttr(attrsStore: s.AttrsStore, etype, cursor, order) {
|
|
638
657
|
if (cursor) {
|
|
639
|
-
return orderAttrFromCursor(
|
|
658
|
+
return orderAttrFromCursor(attrsStore, cursor);
|
|
640
659
|
}
|
|
641
660
|
if (order) {
|
|
642
|
-
return orderAttrFromOrder(
|
|
661
|
+
return orderAttrFromOrder(attrsStore, etype, order);
|
|
643
662
|
}
|
|
644
663
|
}
|
|
645
664
|
|
|
646
665
|
function objectAttrs(
|
|
647
|
-
|
|
666
|
+
attrsStore: s.AttrsStore,
|
|
648
667
|
etype,
|
|
649
668
|
dq,
|
|
650
669
|
): Map<string, InstantDBAttr> | undefined {
|
|
651
670
|
if (!Array.isArray(dq.fields)) {
|
|
652
|
-
return s.getBlobAttrs(
|
|
671
|
+
return s.getBlobAttrs(attrsStore, etype);
|
|
653
672
|
}
|
|
654
673
|
|
|
655
674
|
const attrs = new Map();
|
|
656
675
|
|
|
657
676
|
for (const field of dq.fields) {
|
|
658
|
-
const attr = s.getAttrByFwdIdentName(
|
|
677
|
+
const attr = s.getAttrByFwdIdentName(attrsStore, etype, field);
|
|
659
678
|
const label = attr?.['forward-identity']?.[2];
|
|
660
679
|
if (label && s.isBlob(attr)) {
|
|
661
680
|
attrs.set(label, attr);
|
|
@@ -663,7 +682,7 @@ function objectAttrs(
|
|
|
663
682
|
}
|
|
664
683
|
// Ensure we add the id field to avoid empty objects
|
|
665
684
|
if (!attrs.has('id')) {
|
|
666
|
-
const attr = s.getAttrByFwdIdentName(
|
|
685
|
+
const attr = s.getAttrByFwdIdentName(attrsStore, etype, 'id');
|
|
667
686
|
const label = attr?.['forward-identity']?.[2];
|
|
668
687
|
if (label) {
|
|
669
688
|
attrs.set(label, attr);
|
|
@@ -675,6 +694,7 @@ function objectAttrs(
|
|
|
675
694
|
|
|
676
695
|
function runDataloadAndReturnObjects(
|
|
677
696
|
store: s.Store,
|
|
697
|
+
attrsStore: s.AttrsStore,
|
|
678
698
|
{ etype, pageInfo, dq, form },
|
|
679
699
|
) {
|
|
680
700
|
const order = form?.$?.order;
|
|
@@ -684,7 +704,7 @@ function runDataloadAndReturnObjects(
|
|
|
684
704
|
let idVecs = datalogQuery(store, dq);
|
|
685
705
|
|
|
686
706
|
const startCursor = pageInfo?.['start-cursor'];
|
|
687
|
-
const orderAttr = getOrderAttr(
|
|
707
|
+
const orderAttr = getOrderAttr(attrsStore, etype, startCursor, order);
|
|
688
708
|
|
|
689
709
|
if (orderAttr && orderAttr?.['forward-identity']?.[2] !== 'id') {
|
|
690
710
|
const isDate = orderAttr['checked-data-type'] === 'date';
|
|
@@ -711,7 +731,7 @@ function runDataloadAndReturnObjects(
|
|
|
711
731
|
);
|
|
712
732
|
|
|
713
733
|
let objects = {};
|
|
714
|
-
const attrs = objectAttrs(
|
|
734
|
+
const attrs = objectAttrs(attrsStore, etype, dq);
|
|
715
735
|
|
|
716
736
|
for (const idVec of idVecs) {
|
|
717
737
|
const [id] = idVec;
|
|
@@ -771,6 +791,7 @@ function isLeading(form) {
|
|
|
771
791
|
*/
|
|
772
792
|
function resolveObjects(
|
|
773
793
|
store: s.Store,
|
|
794
|
+
attrsStore: s.AttrsStore,
|
|
774
795
|
{ etype, level, form, join, pageInfo },
|
|
775
796
|
) {
|
|
776
797
|
// Wait for server to tell us where we start if we don't start from the beginning
|
|
@@ -778,11 +799,14 @@ function resolveObjects(
|
|
|
778
799
|
return [];
|
|
779
800
|
}
|
|
780
801
|
|
|
781
|
-
const where = withJoin(
|
|
802
|
+
const where = withJoin(
|
|
803
|
+
makeWhere(attrsStore, etype, level, form.$?.where),
|
|
804
|
+
join,
|
|
805
|
+
);
|
|
782
806
|
const find = makeFind(makeVarImpl, etype, level);
|
|
783
807
|
const fields = form.$?.fields;
|
|
784
808
|
|
|
785
|
-
const objs = runDataloadAndReturnObjects(store, {
|
|
809
|
+
const objs = runDataloadAndReturnObjects(store, attrsStore, {
|
|
786
810
|
etype,
|
|
787
811
|
pageInfo,
|
|
788
812
|
form,
|
|
@@ -816,9 +840,9 @@ function resolveObjects(
|
|
|
816
840
|
* This swallows the missing attr error and returns
|
|
817
841
|
* an empty result instead
|
|
818
842
|
*/
|
|
819
|
-
function guardedResolveObjects(store: s.Store, opts) {
|
|
843
|
+
function guardedResolveObjects(store: s.Store, attrsStore: s.AttrsStore, opts) {
|
|
820
844
|
try {
|
|
821
|
-
return resolveObjects(store, opts);
|
|
845
|
+
return resolveObjects(store, attrsStore, opts);
|
|
822
846
|
} catch (e) {
|
|
823
847
|
if (e instanceof AttrNotFoundError) {
|
|
824
848
|
return {};
|
|
@@ -839,9 +863,9 @@ function guardedResolveObjects(store: s.Store, opts) {
|
|
|
839
863
|
* `guardResolveObjects` will return the relevant `users` objects
|
|
840
864
|
* `extendObjects` will then extend each `user` object with relevant `posts`.
|
|
841
865
|
*/
|
|
842
|
-
function queryOne(store: s.Store, opts) {
|
|
843
|
-
const objects = guardedResolveObjects(store, opts);
|
|
844
|
-
return extendObjects(makeVarImpl, store, opts, objects);
|
|
866
|
+
function queryOne(store: s.Store, attrsStore: s.AttrsStore, opts) {
|
|
867
|
+
const objects = guardedResolveObjects(store, attrsStore, opts);
|
|
868
|
+
return extendObjects(makeVarImpl, store, attrsStore, opts, objects);
|
|
845
869
|
}
|
|
846
870
|
|
|
847
871
|
function formatPageInfo(
|
|
@@ -870,12 +894,14 @@ function formatPageInfo(
|
|
|
870
894
|
export default function query(
|
|
871
895
|
{
|
|
872
896
|
store,
|
|
897
|
+
attrsStore,
|
|
873
898
|
pageInfo,
|
|
874
899
|
aggregate,
|
|
875
900
|
}: {
|
|
876
901
|
store: s.Store;
|
|
877
|
-
|
|
878
|
-
|
|
902
|
+
attrsStore: s.AttrsStore;
|
|
903
|
+
pageInfo?: any;
|
|
904
|
+
aggregate?: any;
|
|
879
905
|
},
|
|
880
906
|
q,
|
|
881
907
|
) {
|
|
@@ -885,7 +911,7 @@ export default function query(
|
|
|
885
911
|
// so don't bother querying further
|
|
886
912
|
return res;
|
|
887
913
|
}
|
|
888
|
-
res[k] = queryOne(store, {
|
|
914
|
+
res[k] = queryOne(store, attrsStore, {
|
|
889
915
|
etype: k,
|
|
890
916
|
form: q[k],
|
|
891
917
|
level: 0,
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { i } from './schema.ts';
|
|
2
|
+
import { DataAttrDef, InstantSchemaDef } from './schemaTypes.ts';
|
|
3
|
+
|
|
4
|
+
export const parseSchemaFromJSON = (
|
|
5
|
+
s: any,
|
|
6
|
+
): InstantSchemaDef<any, any, any> => {
|
|
7
|
+
// Parse entities
|
|
8
|
+
const entities: Record<string, any> = {};
|
|
9
|
+
|
|
10
|
+
for (const [entityName, entityInfo] of Object.entries(s.entities)) {
|
|
11
|
+
const entityDef = entityInfo as any;
|
|
12
|
+
const attrs: Record<string, any> = {};
|
|
13
|
+
|
|
14
|
+
// Parse attributes
|
|
15
|
+
for (const [attrName, attrInfo] of Object.entries(entityDef.attrs)) {
|
|
16
|
+
const attrDef = attrInfo as any;
|
|
17
|
+
let attr: DataAttrDef<any, any, any>;
|
|
18
|
+
|
|
19
|
+
// Create the appropriate attribute type
|
|
20
|
+
switch (attrDef.valueType) {
|
|
21
|
+
case 'string':
|
|
22
|
+
attr = i.string();
|
|
23
|
+
break;
|
|
24
|
+
case 'number':
|
|
25
|
+
attr = i.number();
|
|
26
|
+
break;
|
|
27
|
+
case 'boolean':
|
|
28
|
+
attr = i.boolean();
|
|
29
|
+
break;
|
|
30
|
+
case 'date':
|
|
31
|
+
attr = i.date();
|
|
32
|
+
break;
|
|
33
|
+
case 'json':
|
|
34
|
+
attr = i.json();
|
|
35
|
+
break;
|
|
36
|
+
default:
|
|
37
|
+
attr = i.json();
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Apply modifiers
|
|
41
|
+
if (!attrDef.required) {
|
|
42
|
+
attr = attr.optional();
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (attrDef.config?.indexed) {
|
|
46
|
+
attr = attr.indexed();
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (attrDef.config?.unique) {
|
|
50
|
+
attr = attr.unique();
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
attrs[attrName] = attr;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
entities[entityName] = i.entity(attrs);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Parse links
|
|
60
|
+
const links: Record<string, any> = s.links || {};
|
|
61
|
+
|
|
62
|
+
// Parse rooms
|
|
63
|
+
const rooms: Record<string, any> = {};
|
|
64
|
+
|
|
65
|
+
if (s.rooms) {
|
|
66
|
+
for (const [roomName, roomInfo] of Object.entries(s.rooms)) {
|
|
67
|
+
const roomDef = roomInfo as any;
|
|
68
|
+
|
|
69
|
+
// Parse presence
|
|
70
|
+
const presenceAttrs: Record<string, any> = {};
|
|
71
|
+
for (const [attrName, attrInfo] of Object.entries(
|
|
72
|
+
roomDef.presence.attrs,
|
|
73
|
+
)) {
|
|
74
|
+
const attrDef = attrInfo as any;
|
|
75
|
+
let attr: DataAttrDef<any, any, any>;
|
|
76
|
+
|
|
77
|
+
switch (attrDef.valueType) {
|
|
78
|
+
case 'string':
|
|
79
|
+
attr = i.string();
|
|
80
|
+
break;
|
|
81
|
+
case 'number':
|
|
82
|
+
attr = i.number();
|
|
83
|
+
break;
|
|
84
|
+
case 'boolean':
|
|
85
|
+
attr = i.boolean();
|
|
86
|
+
break;
|
|
87
|
+
case 'date':
|
|
88
|
+
attr = i.date();
|
|
89
|
+
break;
|
|
90
|
+
case 'json':
|
|
91
|
+
attr = i.json();
|
|
92
|
+
break;
|
|
93
|
+
default:
|
|
94
|
+
attr = i.json();
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
if (!attrDef.required) {
|
|
98
|
+
attr = attr.optional();
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (attrDef.config?.indexed) {
|
|
102
|
+
attr = attr.indexed();
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (attrDef.config?.unique) {
|
|
106
|
+
attr = attr.unique();
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
presenceAttrs[attrName] = attr;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Parse topics
|
|
113
|
+
const topics: Record<string, any> = {};
|
|
114
|
+
if (roomDef.topics) {
|
|
115
|
+
for (const [topicName, topicInfo] of Object.entries(roomDef.topics)) {
|
|
116
|
+
const topicDef = topicInfo as any;
|
|
117
|
+
const topicAttrs: Record<string, any> = {};
|
|
118
|
+
|
|
119
|
+
for (const [attrName, attrInfo] of Object.entries(topicDef.attrs)) {
|
|
120
|
+
const attrDef = attrInfo as any;
|
|
121
|
+
let attr: DataAttrDef<any, any, any>;
|
|
122
|
+
|
|
123
|
+
switch (attrDef.valueType) {
|
|
124
|
+
case 'string':
|
|
125
|
+
attr = i.string();
|
|
126
|
+
break;
|
|
127
|
+
case 'number':
|
|
128
|
+
attr = i.number();
|
|
129
|
+
break;
|
|
130
|
+
case 'boolean':
|
|
131
|
+
attr = i.boolean();
|
|
132
|
+
break;
|
|
133
|
+
case 'date':
|
|
134
|
+
attr = i.date();
|
|
135
|
+
break;
|
|
136
|
+
case 'json':
|
|
137
|
+
attr = i.json();
|
|
138
|
+
break;
|
|
139
|
+
default:
|
|
140
|
+
attr = i.json();
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
if (!attrDef.required) {
|
|
144
|
+
attr = attr.optional();
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
if (attrDef.config?.indexed) {
|
|
148
|
+
attr = attr.indexed();
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
if (attrDef.config?.unique) {
|
|
152
|
+
attr = attr.unique();
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
topicAttrs[attrName] = attr;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
topics[topicName] = i.entity(topicAttrs);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
rooms[roomName] = {
|
|
163
|
+
presence: i.entity(presenceAttrs),
|
|
164
|
+
topics,
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
const resultingSchema = i.schema({
|
|
170
|
+
entities,
|
|
171
|
+
links,
|
|
172
|
+
rooms,
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
return resultingSchema;
|
|
176
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { PageInfoResponse } from './queryTypes.ts';
|
|
2
|
+
import { AttrsStore, AttrsStoreJson, Store, StoreJson } from './store.ts';
|
|
3
|
+
|
|
4
|
+
export type QuerySubResult = {
|
|
5
|
+
store: Store;
|
|
6
|
+
attrsStore: AttrsStore;
|
|
7
|
+
pageInfo?: PageInfoResponse<any> | null | undefined;
|
|
8
|
+
aggregate?: any;
|
|
9
|
+
processedTxId?: number;
|
|
10
|
+
isExternal?: boolean;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export type QuerySub = {
|
|
14
|
+
q: Object;
|
|
15
|
+
eventId?: string;
|
|
16
|
+
lastAccessed?: number | null | undefined;
|
|
17
|
+
result?: QuerySubResult;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export type QuerySubResultInStorage = {
|
|
21
|
+
store: StoreJson;
|
|
22
|
+
attrsStore: AttrsStoreJson;
|
|
23
|
+
pageInfo?: PageInfoResponse<any> | null | undefined;
|
|
24
|
+
aggregate?: any;
|
|
25
|
+
processedTxId?: number;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export type QuerySubInStorage = {
|
|
29
|
+
q: Object;
|
|
30
|
+
eventId?: string;
|
|
31
|
+
lastAccessed?: number | null | undefined;
|
|
32
|
+
result?: QuerySubResultInStorage;
|
|
33
|
+
};
|