@instantdb/core 0.22.85 → 0.22.86

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@instantdb/core",
3
- "version": "0.22.85",
3
+ "version": "0.22.86",
4
4
  "description": "Instant's core local abstraction",
5
5
  "homepage": "https://github.com/instantdb/instant/tree/main/client/packages/core",
6
6
  "repository": {
@@ -53,7 +53,7 @@
53
53
  "dependencies": {
54
54
  "mutative": "^1.0.10",
55
55
  "uuid": "^11.1.0",
56
- "@instantdb/version": "0.22.85"
56
+ "@instantdb/version": "0.22.86"
57
57
  },
58
58
  "scripts": {
59
59
  "test": "vitest",
package/src/Reactor.js CHANGED
@@ -1,6 +1,6 @@
1
1
  // @ts-check
2
2
  import weakHash from './utils/weakHash.ts';
3
- import instaql from './instaql.js';
3
+ import instaql from './instaql.ts';
4
4
  import * as instaml from './instaml.js';
5
5
  import * as s from './store.ts';
6
6
  import uuid from './utils/uuid.ts';
@@ -365,7 +365,7 @@ export default class Reactor {
365
365
  _reactorStats() {
366
366
  return {
367
367
  inFlightMutationCount: this._inFlightMutationEventIds.size,
368
- pendingMutationCount: this._pendingMutations().size,
368
+ storedMutationCount: this._pendingMutations().size,
369
369
  transportType: this._transportType,
370
370
  };
371
371
  }
package/src/SyncTable.ts CHANGED
@@ -3,7 +3,7 @@ import * as s from './store.ts';
3
3
  import weakHash from './utils/weakHash.ts';
4
4
  import uuid from './utils/uuid.ts';
5
5
  import { Logger } from './Reactor.js';
6
- import instaql, { compareOrder } from './instaql.js';
6
+ import instaql, { compareOrder } from './instaql.ts';
7
7
  import { InstaQLResponse, ValidQuery } from './queryTypes.ts';
8
8
  import { EntitiesDef, IContainEntitiesAndLinks } from './schemaTypes.ts';
9
9
  import { StorageInterface } from './index.ts';
@@ -2,17 +2,38 @@ import { query as datalogQuery } from './datalog.js';
2
2
  import { uuidCompare } from './utils/uuid.ts';
3
3
  import { stringCompare } from './utils/strings.ts';
4
4
  import * as s from './store.ts';
5
+ import { InstantDBAttr } from './attrTypes.ts';
6
+ import { Cursor } from './queryTypes.ts';
7
+
8
+ type Pat = [string | any, string, string | any, string | number];
9
+ type Pats = Array<Pat>;
10
+ type OrPat = {
11
+ or: {
12
+ patterns: FullPats;
13
+ joinSym: string;
14
+ };
15
+ };
16
+ type AndPat = {
17
+ and: {
18
+ patterns: FullPats;
19
+ joinSym: string;
20
+ };
21
+ };
22
+ type FullPat = Pat | OrPat | AndPat;
23
+ type FullPats = Array<FullPat>;
5
24
 
6
25
  // Pattern variables
7
26
  // -----------------
8
27
 
28
+ type MakeVar = (x: string, level: number) => string;
29
+
9
30
  let _seed = 0;
10
31
 
11
- function wildcard(friendlyName) {
32
+ function wildcard(friendlyName: string) {
12
33
  return makeVarImpl(`_${friendlyName}`, _seed++);
13
34
  }
14
35
 
15
- function makeVarImpl(x, level) {
36
+ function makeVarImpl(x: string, level: number): string {
16
37
  return `?${x}-${level}`;
17
38
  }
18
39
 
@@ -26,7 +47,7 @@ class AttrNotFoundError extends Error {
26
47
  }
27
48
  }
28
49
 
29
- function idAttr(store, ns) {
50
+ function idAttr(store: s.Store, ns: string): InstantDBAttr {
30
51
  const attr = s.getPrimaryKeyAttr(store, ns);
31
52
 
32
53
  if (!attr) {
@@ -35,11 +56,21 @@ function idAttr(store, ns) {
35
56
  return attr;
36
57
  }
37
58
 
38
- function defaultWhere(makeVar, store, etype, level) {
59
+ function defaultWhere(
60
+ makeVar: MakeVar,
61
+ store: s.Store,
62
+ etype: string,
63
+ level: number,
64
+ ): Pats {
39
65
  return [eidWhere(makeVar, store, etype, level)];
40
66
  }
41
67
 
42
- function eidWhere(makeVar, store, etype, level) {
68
+ function eidWhere(
69
+ makeVar: MakeVar,
70
+ store: s.Store,
71
+ etype: string,
72
+ level: number,
73
+ ): Pat {
43
74
  return [
44
75
  makeVar(etype, level),
45
76
  idAttr(store, etype).id,
@@ -48,11 +79,17 @@ function eidWhere(makeVar, store, etype, level) {
48
79
  ];
49
80
  }
50
81
 
51
- function replaceInAttrPat(attrPat, needle, v) {
52
- return attrPat.map((x) => (x === needle ? v : x));
82
+ function replaceInAttrPat(attrPat: Pat, needle: string, v: any): Pat {
83
+ return attrPat.map((x) => (x === needle ? v : x)) as Pat;
53
84
  }
54
85
 
55
- function refAttrPat(makeVar, store, etype, level, label) {
86
+ function refAttrPat(
87
+ makeVar: MakeVar,
88
+ store: s.Store,
89
+ etype: string,
90
+ level: number,
91
+ label: string,
92
+ ): [string, number, Pat, InstantDBAttr, boolean] {
56
93
  const fwdAttr = s.getAttrByFwdIdentName(store, etype, label);
57
94
  const revAttr = s.getAttrByReverseIdentName(store, etype, label);
58
95
  const attr = fwdAttr || revAttr;
@@ -66,9 +103,9 @@ function refAttrPat(makeVar, store, etype, level, label) {
66
103
  }
67
104
 
68
105
  const [_f, fwdEtype] = attr['forward-identity'];
69
- const [_r, revEtype] = attr['reverse-identity'];
106
+ const [_r, revEtype] = attr['reverse-identity']!;
70
107
  const nextLevel = level + 1;
71
- const attrPat = fwdAttr
108
+ const attrPat: Pat = fwdAttr
72
109
  ? [
73
110
  makeVar(fwdEtype, level),
74
111
  attr.id,
@@ -89,7 +126,7 @@ function refAttrPat(makeVar, store, etype, level, label) {
89
126
  return [nextEtype, nextLevel, attrPat, attr, isForward];
90
127
  }
91
128
 
92
- function makeLikeMatcher(caseSensitive, pattern) {
129
+ function makeLikeMatcher(caseSensitive: boolean, pattern: string) {
93
130
  if (typeof pattern !== 'string') {
94
131
  return function likeMatcher(_value) {
95
132
  return false;
@@ -112,7 +149,7 @@ function makeLikeMatcher(caseSensitive, pattern) {
112
149
  };
113
150
  }
114
151
 
115
- function parseValue(attr, v) {
152
+ function parseValue(attr: InstantDBAttr, v: any) {
116
153
  if (
117
154
  typeof v !== 'object' ||
118
155
  v.hasOwnProperty('$in') ||
@@ -196,7 +233,14 @@ function parseValue(attr, v) {
196
233
  return v;
197
234
  }
198
235
 
199
- function valueAttrPat(makeVar, store, valueEtype, valueLevel, valueLabel, v) {
236
+ function valueAttrPat(
237
+ makeVar: MakeVar,
238
+ store: s.Store,
239
+ valueEtype: string,
240
+ valueLevel: number,
241
+ valueLabel: string,
242
+ v: any,
243
+ ): Pat {
200
244
  const fwdAttr = s.getAttrByFwdIdentName(store, valueEtype, valueLabel);
201
245
  const revAttr = s.getAttrByReverseIdentName(store, valueEtype, valueLabel);
202
246
  const attr = fwdAttr || revAttr;
@@ -234,7 +278,13 @@ function valueAttrPat(makeVar, store, valueEtype, valueLevel, valueLabel, v) {
234
278
  return [v, attr.id, makeVar(valueEtype, valueLevel), wildcard('time')];
235
279
  }
236
280
 
237
- function refAttrPats(makeVar, store, etype, level, refsPath) {
281
+ function refAttrPats(
282
+ makeVar: MakeVar,
283
+ store: s.Store,
284
+ etype: string,
285
+ level: number,
286
+ refsPath: string[],
287
+ ): [string, number, Pats] {
238
288
  const [lastEtype, lastLevel, attrPats] = refsPath.reduce(
239
289
  (acc, label) => {
240
290
  const [etype, level, attrPats] = acc;
@@ -253,7 +303,14 @@ function refAttrPats(makeVar, store, etype, level, refsPath) {
253
303
  return [lastEtype, lastLevel, attrPats];
254
304
  }
255
305
 
256
- function whereCondAttrPats(makeVar, store, etype, level, path, v) {
306
+ function whereCondAttrPats(
307
+ makeVar: MakeVar,
308
+ store: s.Store,
309
+ etype: string,
310
+ level: number,
311
+ path: string[],
312
+ v: any,
313
+ ): Pats {
257
314
  const refsPath = path.slice(0, path.length - 1);
258
315
  const valueLabel = path[path.length - 1];
259
316
  const [lastEtype, lastLevel, refPats] = refAttrPats(
@@ -279,17 +336,17 @@ function withJoin(where, join) {
279
336
  return join ? [join].concat(where) : where;
280
337
  }
281
338
 
282
- function isOrClauses([k, v]) {
339
+ function isOrClauses([k, v]): boolean {
283
340
  return k === 'or' && Array.isArray(v);
284
341
  }
285
342
 
286
- function isAndClauses([k, v]) {
343
+ function isAndClauses([k, v]): boolean {
287
344
  return k === 'and' && Array.isArray(v);
288
345
  }
289
346
 
290
347
  // Creates a makeVar that will namespace symbols for or clauses
291
348
  // to prevent conflicts, except for the base etype
292
- function genMakeVar(baseMakeVar, joinSym, orIdx) {
349
+ function genMakeVar(baseMakeVar: MakeVar, joinSym: string, orIdx: number) {
293
350
  return (x, lvl) => {
294
351
  const base = baseMakeVar(x, lvl);
295
352
  if (joinSym == base) {
@@ -300,25 +357,25 @@ function genMakeVar(baseMakeVar, joinSym, orIdx) {
300
357
  }
301
358
 
302
359
  function parseWhereClauses(
303
- makeVar,
304
- clauseType /* 'or' | 'and' */,
305
- store,
306
- etype,
307
- level,
308
- whereValue,
309
- ) {
360
+ makeVar: MakeVar,
361
+ clauseType: 'or' | 'and' /* 'or' | 'and' */,
362
+ store: s.Store,
363
+ etype: string,
364
+ level: number,
365
+ whereValue: any,
366
+ ): FullPat {
310
367
  const joinSym = makeVar(etype, level);
311
- const patterns = whereValue.map((w, i) => {
368
+ const patterns: FullPats = whereValue.map((w, i) => {
312
369
  const makeNamespacedVar = genMakeVar(makeVar, joinSym, i);
313
370
  return parseWhere(makeNamespacedVar, store, etype, level, w);
314
371
  });
315
- return { [clauseType]: { patterns, joinSym } };
372
+ return { [clauseType]: { patterns, joinSym } } as AndPat | OrPat;
316
373
  }
317
374
 
318
375
  // Given a path, returns a list of paths leading up to this path:
319
376
  // growPath([1, 2, 3]) -> [[1], [1, 2], [1, 2, 3]]
320
- function growPath(path) {
321
- const ret = [];
377
+ function growPath<T>(path: T[]) {
378
+ const ret: Array<T[]> = [];
322
379
  for (let i = 1; i <= path.length; i++) {
323
380
  ret.push(path.slice(0, i));
324
381
  }
@@ -327,13 +384,25 @@ function growPath(path) {
327
384
 
328
385
  // Returns array of pattern arrays that should be grouped in OR
329
386
  // to capture any intermediate nulls
330
- function whereCondAttrPatsForNullIsTrue(makeVar, store, etype, level, path) {
387
+ function whereCondAttrPatsForNullIsTrue(
388
+ makeVar: MakeVar,
389
+ store: s.Store,
390
+ etype: string,
391
+ level: number,
392
+ path: string[],
393
+ ): Pats[] {
331
394
  return growPath(path).map((path) =>
332
395
  whereCondAttrPats(makeVar, store, etype, level, path, { $isNull: true }),
333
396
  );
334
397
  }
335
398
 
336
- function parseWhere(makeVar, store, etype, level, where) {
399
+ function parseWhere(
400
+ makeVar: MakeVar,
401
+ store: s.Store,
402
+ etype: string,
403
+ level: number,
404
+ where: Record<string, any>,
405
+ ): FullPats {
337
406
  return Object.entries(where).flatMap(([k, v]) => {
338
407
  if (isOrClauses([k, v])) {
339
408
  return parseWhereClauses(makeVar, 'or', store, etype, level, v);
@@ -399,7 +468,12 @@ function parseWhere(makeVar, store, etype, level, where) {
399
468
  });
400
469
  }
401
470
 
402
- function makeWhere(store, etype, level, where) {
471
+ function makeWhere(
472
+ store: s.Store,
473
+ etype: string,
474
+ level: number,
475
+ where: Record<string, any> | null,
476
+ ): FullPats {
403
477
  const makeVar = makeVarImpl;
404
478
  if (!where) {
405
479
  return defaultWhere(makeVar, store, etype, level);
@@ -411,14 +485,21 @@ function makeWhere(store, etype, level, where) {
411
485
  // Find
412
486
  // -----------------
413
487
 
414
- function makeFind(makeVar, etype, level) {
488
+ function makeFind(makeVar: MakeVar, etype: string, level: number) {
415
489
  return [makeVar(etype, level), makeVar('time', level)];
416
490
  }
417
491
 
418
492
  // extendObjects
419
493
  // -----------------
420
494
 
421
- function makeJoin(makeVar, store, etype, level, label, eid) {
495
+ function makeJoin(
496
+ makeVar: MakeVar,
497
+ store: s.Store,
498
+ etype: string,
499
+ level: number,
500
+ label: string,
501
+ eid: string,
502
+ ) {
422
503
  const [nextEtype, nextLevel, pat, attr, isForward] = refAttrPat(
423
504
  makeVar,
424
505
  store,
@@ -497,7 +578,7 @@ function compareDisparateValues(a, b, dataType) {
497
578
  return -1;
498
579
  }
499
580
 
500
- export function compareOrder(id_a, v_a, id_b, v_b, dataType) {
581
+ export function compareOrder(id_a: string, v_a, id_b: string, v_b, dataType) {
501
582
  if (v_a === v_b || (v_a == null && v_b == null)) {
502
583
  return uuidCompare(id_a, id_b);
503
584
  }
@@ -512,7 +593,11 @@ export function compareOrder(id_a, v_a, id_b, v_b, dataType) {
512
593
  return compareDisparateValues(v_a, v_b, dataType);
513
594
  }
514
595
 
515
- function compareOrderTriples([id_a, v_a], [id_b, v_b], dataType) {
596
+ function compareOrderTriples(
597
+ [id_a, v_a]: [string, any],
598
+ [id_b, v_b]: [string, any],
599
+ dataType,
600
+ ) {
516
601
  return compareOrder(id_a, v_a, id_b, v_b, dataType);
517
602
  }
518
603
 
@@ -539,17 +624,17 @@ function isBefore(startCursor, orderAttr, direction, idVec) {
539
624
  );
540
625
  }
541
626
 
542
- function orderAttrFromCursor(store, cursor) {
627
+ function orderAttrFromCursor(store: s.Store, cursor) {
543
628
  const cursorAttrId = cursor[1];
544
629
  return store.attrs[cursorAttrId];
545
630
  }
546
631
 
547
- function orderAttrFromOrder(store, etype, order) {
632
+ function orderAttrFromOrder(store: s.Store, etype, order) {
548
633
  const label = Object.keys(order)[0];
549
634
  return s.getAttrByFwdIdentName(store, etype, label);
550
635
  }
551
636
 
552
- function getOrderAttr(store, etype, cursor, order) {
637
+ function getOrderAttr(store: s.Store, etype, cursor, order) {
553
638
  if (cursor) {
554
639
  return orderAttrFromCursor(store, cursor);
555
640
  }
@@ -558,7 +643,11 @@ function getOrderAttr(store, etype, cursor, order) {
558
643
  }
559
644
  }
560
645
 
561
- function objectAttrs(store, etype, dq) {
646
+ function objectAttrs(
647
+ store: s.Store,
648
+ etype,
649
+ dq,
650
+ ): Map<string, InstantDBAttr> | undefined {
562
651
  if (!Array.isArray(dq.fields)) {
563
652
  return s.getBlobAttrs(store, etype);
564
653
  }
@@ -584,7 +673,10 @@ function objectAttrs(store, etype, dq) {
584
673
  return attrs;
585
674
  }
586
675
 
587
- function runDataloadAndReturnObjects(store, { etype, pageInfo, dq, form }) {
676
+ function runDataloadAndReturnObjects(
677
+ store: s.Store,
678
+ { etype, pageInfo, dq, form },
679
+ ) {
588
680
  const order = form?.$?.order;
589
681
  const isLeadingQuery = isLeading(form);
590
682
  const direction = determineDirection(form);
@@ -677,7 +769,10 @@ function isLeading(form) {
677
769
  * into a datalog query. We then run the datalog query,
678
770
  * and reduce all the triples into objects.
679
771
  */
680
- function resolveObjects(store, { etype, level, form, join, pageInfo }) {
772
+ function resolveObjects(
773
+ store: s.Store,
774
+ { etype, level, form, join, pageInfo },
775
+ ) {
681
776
  // Wait for server to tell us where we start if we don't start from the beginning
682
777
  if (!isLeading(form) && (!pageInfo || !pageInfo['start-cursor'])) {
683
778
  return [];
@@ -721,7 +816,7 @@ function resolveObjects(store, { etype, level, form, join, pageInfo }) {
721
816
  * This swallows the missing attr error and returns
722
817
  * an empty result instead
723
818
  */
724
- function guardedResolveObjects(store, opts) {
819
+ function guardedResolveObjects(store: s.Store, opts) {
725
820
  try {
726
821
  return resolveObjects(store, opts);
727
822
  } catch (e) {
@@ -744,12 +839,22 @@ function guardedResolveObjects(store, opts) {
744
839
  * `guardResolveObjects` will return the relevant `users` objects
745
840
  * `extendObjects` will then extend each `user` object with relevant `posts`.
746
841
  */
747
- function queryOne(store, opts) {
842
+ function queryOne(store: s.Store, opts) {
748
843
  const objects = guardedResolveObjects(store, opts);
749
844
  return extendObjects(makeVarImpl, store, opts, objects);
750
845
  }
751
846
 
752
- function formatPageInfo(pageInfo) {
847
+ function formatPageInfo(
848
+ pageInfo: Record<
849
+ string,
850
+ {
851
+ 'start-cursor'?: Cursor | null;
852
+ 'end-cursor'?: Cursor | null;
853
+ 'has-next-page?'?: boolean | null;
854
+ 'has-previous-page?'?: boolean | null;
855
+ }
856
+ >,
857
+ ) {
753
858
  const res = {};
754
859
  for (const [k, v] of Object.entries(pageInfo)) {
755
860
  res[k] = {
@@ -762,7 +867,18 @@ function formatPageInfo(pageInfo) {
762
867
  return res;
763
868
  }
764
869
 
765
- export default function query({ store, pageInfo, aggregate }, q) {
870
+ export default function query(
871
+ {
872
+ store,
873
+ pageInfo,
874
+ aggregate,
875
+ }: {
876
+ store: s.Store;
877
+ pageInfo: any;
878
+ aggregate: any;
879
+ },
880
+ q,
881
+ ) {
766
882
  const data = Object.keys(q).reduce(function reduceResult(res, k) {
767
883
  if (aggregate?.[k] || '$$ruleParams' === k) {
768
884
  // Aggregate doesn't return any join rows and has no children,
@@ -778,7 +894,7 @@ export default function query({ store, pageInfo, aggregate }, q) {
778
894
  return res;
779
895
  }, {});
780
896
 
781
- const result = { data };
897
+ const result: { data: any; pageInfo?: any; aggregate?: any } = { data };
782
898
  if (pageInfo) {
783
899
  result.pageInfo = formatPageInfo(pageInfo);
784
900
  }
package/src/store.ts CHANGED
@@ -679,11 +679,15 @@ export function getTriples(store, [e, a, v]) {
679
679
 
680
680
  export function getAsObject(
681
681
  store: Store,
682
- attrs: Map<string, InstantDBAttr>,
682
+ attrs: Map<string, InstantDBAttr> | undefined,
683
683
  e: string,
684
684
  ) {
685
685
  const obj = {};
686
686
 
687
+ if (!attrs) {
688
+ return obj;
689
+ }
690
+
687
691
  for (const [label, attr] of attrs.entries()) {
688
692
  const aMap = store.eav.get(e)?.get(attr.id);
689
693
  const triples = allMapValues(aMap, 1);