@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
package/src/store.ts
CHANGED
|
@@ -7,34 +7,163 @@ import { LinkIndex } from './utils/linkIndex.ts';
|
|
|
7
7
|
type Triple = [string, string, any, number];
|
|
8
8
|
type Attrs = Record<string, InstantDBAttr>;
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
interface AttrIndexes {
|
|
11
11
|
blobAttrs: Map<string, Map<string, InstantDBAttr>>;
|
|
12
12
|
primaryKeys: Map<string, InstantDBAttr>;
|
|
13
13
|
forwardIdents: Map<string, Map<string, InstantDBAttr>>;
|
|
14
14
|
revIdents: Map<string, Map<string, InstantDBAttr>>;
|
|
15
|
-
}
|
|
15
|
+
}
|
|
16
16
|
|
|
17
17
|
export type Store = {
|
|
18
18
|
eav: Map<string, Map<string, Map<any, Triple>>>;
|
|
19
19
|
aev: Map<string, Map<string, Map<any, Triple>>>;
|
|
20
20
|
vae: Map<any, Map<string, Map<string, Triple>>>;
|
|
21
|
-
useDateObjects: boolean | null;
|
|
22
|
-
|
|
23
|
-
attrIndexes: AttrIndexes;
|
|
24
|
-
cardinalityInference: boolean | null;
|
|
25
|
-
linkIndex: LinkIndex | null;
|
|
26
|
-
__type: 'store';
|
|
21
|
+
useDateObjects: boolean | null | undefined;
|
|
22
|
+
cardinalityInference: boolean | null | undefined;
|
|
27
23
|
};
|
|
28
24
|
|
|
29
|
-
|
|
25
|
+
type StoreJsonVersion0 = {
|
|
30
26
|
__type: 'store';
|
|
31
27
|
attrs: Attrs;
|
|
32
28
|
triples: Triple[];
|
|
33
|
-
cardinalityInference: boolean | null;
|
|
29
|
+
cardinalityInference: boolean | null | undefined;
|
|
30
|
+
linkIndex: LinkIndex | null;
|
|
31
|
+
useDateObjects: boolean | null | undefined;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
type StoreJsonVersion1 = {
|
|
35
|
+
triples: Triple[];
|
|
36
|
+
cardinalityInference: boolean | null | undefined;
|
|
37
|
+
useDateObjects: boolean | null | undefined;
|
|
38
|
+
version: 1;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export type StoreJson = StoreJsonVersion0 | StoreJsonVersion1;
|
|
42
|
+
|
|
43
|
+
export type AttrsStoreJson = {
|
|
44
|
+
attrs: Attrs;
|
|
34
45
|
linkIndex: LinkIndex | null;
|
|
35
|
-
useDateObjects: boolean | null;
|
|
36
46
|
};
|
|
37
47
|
|
|
48
|
+
export interface AttrsStore {
|
|
49
|
+
attrs: Attrs;
|
|
50
|
+
linkIndex: LinkIndex | null;
|
|
51
|
+
resetAttrIndexes(): void;
|
|
52
|
+
addAttr(attr: InstantDBAttr): void;
|
|
53
|
+
deleteAttr(attrId: string): void;
|
|
54
|
+
updateAttr(partialAttr: Partial<InstantDBAttr> & { id: string }): void;
|
|
55
|
+
getAttr(id: string): InstantDBAttr | undefined;
|
|
56
|
+
blobAttrs: Map<string, Map<string, InstantDBAttr>>;
|
|
57
|
+
primaryKeys: Map<string, InstantDBAttr>;
|
|
58
|
+
forwardIdents: Map<string, Map<string, InstantDBAttr>>;
|
|
59
|
+
revIdents: Map<string, Map<string, InstantDBAttr>>;
|
|
60
|
+
toJSON(): AttrsStoreJson;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export class AttrsStoreClass implements AttrsStore {
|
|
64
|
+
public attrs: Attrs;
|
|
65
|
+
public linkIndex: LinkIndex | null;
|
|
66
|
+
private _blobAttrs: Map<string, Map<string, InstantDBAttr>> | null = null;
|
|
67
|
+
private _primaryKeys: Map<string, InstantDBAttr> | null = null;
|
|
68
|
+
private _forwardIdents: Map<string, Map<string, InstantDBAttr>> | null = null;
|
|
69
|
+
private _revIdents: Map<string, Map<string, InstantDBAttr>> | null = null;
|
|
70
|
+
constructor(attrs: Attrs, linkIndex: LinkIndex | null) {
|
|
71
|
+
this.attrs = attrs;
|
|
72
|
+
this.linkIndex = linkIndex;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
public resetAttrIndexes() {
|
|
76
|
+
this._blobAttrs = null;
|
|
77
|
+
this._primaryKeys = null;
|
|
78
|
+
this._forwardIdents = null;
|
|
79
|
+
this._revIdents = null;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
public addAttr(attr: InstantDBAttr) {
|
|
83
|
+
this.attrs[attr.id] = attr;
|
|
84
|
+
this.resetAttrIndexes();
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
public deleteAttr(attrId: string) {
|
|
88
|
+
delete this.attrs[attrId];
|
|
89
|
+
this.resetAttrIndexes();
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
public updateAttr(partialAttr: Partial<InstantDBAttr> & { id: string }) {
|
|
93
|
+
const attr = this.attrs[partialAttr.id];
|
|
94
|
+
if (!attr) return;
|
|
95
|
+
this.attrs[partialAttr.id] = { ...attr, ...partialAttr };
|
|
96
|
+
this.resetAttrIndexes();
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
public getAttr(id: string): InstantDBAttr | undefined {
|
|
100
|
+
return this.attrs[id];
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
get blobAttrs(): Map<string, Map<string, InstantDBAttr>> {
|
|
104
|
+
if (this._blobAttrs) {
|
|
105
|
+
return this._blobAttrs;
|
|
106
|
+
}
|
|
107
|
+
this._blobAttrs = new Map();
|
|
108
|
+
for (const attr of Object.values(this.attrs)) {
|
|
109
|
+
if (isBlob(attr)) {
|
|
110
|
+
const [_, fwdEtype, fwdLabel] = attr['forward-identity'];
|
|
111
|
+
setInMap(this.blobAttrs, [fwdEtype, fwdLabel], attr);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return this._blobAttrs;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
get primaryKeys(): Map<string, InstantDBAttr> {
|
|
118
|
+
if (this._primaryKeys) {
|
|
119
|
+
return this._primaryKeys;
|
|
120
|
+
}
|
|
121
|
+
this._primaryKeys = new Map();
|
|
122
|
+
|
|
123
|
+
for (const attr of Object.values(this.attrs)) {
|
|
124
|
+
if (attr['primary?']) {
|
|
125
|
+
const [_, fwdEtype] = attr['forward-identity'];
|
|
126
|
+
setInMap(this._primaryKeys, [fwdEtype], attr);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return this._primaryKeys;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
get forwardIdents(): Map<string, Map<string, InstantDBAttr>> {
|
|
133
|
+
if (this._forwardIdents) {
|
|
134
|
+
return this._forwardIdents;
|
|
135
|
+
}
|
|
136
|
+
this._forwardIdents = new Map();
|
|
137
|
+
|
|
138
|
+
for (const attr of Object.values(this.attrs)) {
|
|
139
|
+
const fwdIdent = attr['forward-identity'];
|
|
140
|
+
const [_, fwdEtype, fwdLabel] = fwdIdent;
|
|
141
|
+
setInMap(this._forwardIdents, [fwdEtype, fwdLabel], attr);
|
|
142
|
+
}
|
|
143
|
+
return this._forwardIdents;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
get revIdents(): Map<string, Map<string, InstantDBAttr>> {
|
|
147
|
+
if (this._revIdents) {
|
|
148
|
+
return this._revIdents;
|
|
149
|
+
}
|
|
150
|
+
this._revIdents = new Map();
|
|
151
|
+
|
|
152
|
+
for (const attr of Object.values(this.attrs)) {
|
|
153
|
+
const revIdent = attr['reverse-identity'];
|
|
154
|
+
if (revIdent) {
|
|
155
|
+
const [_, revEtype, revLabel] = revIdent;
|
|
156
|
+
setInMap(this._revIdents, [revEtype, revLabel], attr);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
return this._revIdents;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
public toJSON(): AttrsStoreJson {
|
|
163
|
+
return { attrs: this.attrs, linkIndex: this.linkIndex };
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
38
167
|
function hasEA(attr: InstantDBAttr) {
|
|
39
168
|
return attr['cardinality'] === 'one';
|
|
40
169
|
}
|
|
@@ -66,19 +195,22 @@ function deleteInMap(m, path) {
|
|
|
66
195
|
deleteInMap(m.get(head), tail);
|
|
67
196
|
}
|
|
68
197
|
|
|
69
|
-
function setInMap(m, path, value) {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
198
|
+
function setInMap(m: Map<any, any>, path: any[], value: any) {
|
|
199
|
+
let current = m;
|
|
200
|
+
const lastI = path.length - 1;
|
|
201
|
+
for (let i = 0; i < lastI; i++) {
|
|
202
|
+
const part = path[i];
|
|
203
|
+
|
|
204
|
+
let nextMap = current.get(part);
|
|
205
|
+
if (nextMap === undefined) {
|
|
206
|
+
nextMap = new Map();
|
|
207
|
+
current.set(part, nextMap);
|
|
208
|
+
}
|
|
209
|
+
current = nextMap;
|
|
74
210
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
if (!nextM) {
|
|
78
|
-
nextM = new Map();
|
|
79
|
-
m.set(head, nextM);
|
|
211
|
+
if (lastI > -1) {
|
|
212
|
+
current.set(path[lastI], value);
|
|
80
213
|
}
|
|
81
|
-
setInMap(nextM, tail, value);
|
|
82
214
|
}
|
|
83
215
|
|
|
84
216
|
function isDateAttr(attr: InstantDBAttr) {
|
|
@@ -86,18 +218,18 @@ function isDateAttr(attr: InstantDBAttr) {
|
|
|
86
218
|
}
|
|
87
219
|
|
|
88
220
|
function createTripleIndexes(
|
|
89
|
-
|
|
221
|
+
attrsStore: AttrsStore,
|
|
90
222
|
triples: Triple[],
|
|
91
|
-
useDateObjects: boolean | null,
|
|
223
|
+
useDateObjects: boolean | null | undefined,
|
|
92
224
|
): Pick<Store, 'eav' | 'aev' | 'vae'> {
|
|
93
225
|
const eav = new Map();
|
|
94
226
|
const aev = new Map();
|
|
95
227
|
const vae = new Map();
|
|
96
228
|
for (const triple of triples) {
|
|
97
|
-
let [eid, aid, v
|
|
98
|
-
const attr = getAttr(
|
|
229
|
+
let [eid, aid, v] = triple;
|
|
230
|
+
const attr = attrsStore.getAttr(aid);
|
|
99
231
|
if (!attr) {
|
|
100
|
-
console.warn('no such attr',
|
|
232
|
+
console.warn('no such attr', aid, eid);
|
|
101
233
|
continue;
|
|
102
234
|
}
|
|
103
235
|
|
|
@@ -142,27 +274,36 @@ function createAttrIndexes(attrs: Record<string, InstantDBAttr>): AttrIndexes {
|
|
|
142
274
|
return { blobAttrs, primaryKeys, forwardIdents, revIdents };
|
|
143
275
|
}
|
|
144
276
|
|
|
145
|
-
export function toJSON(store: Store):
|
|
277
|
+
export function toJSON(store: Store): StoreJsonVersion1 {
|
|
146
278
|
return {
|
|
147
|
-
__type: store.__type,
|
|
148
|
-
attrs: store.attrs,
|
|
149
279
|
triples: allMapValues(store.eav, 3),
|
|
150
280
|
cardinalityInference: store.cardinalityInference,
|
|
151
|
-
linkIndex: store.linkIndex,
|
|
152
281
|
useDateObjects: store.useDateObjects,
|
|
282
|
+
version: 1,
|
|
153
283
|
};
|
|
154
284
|
}
|
|
155
285
|
|
|
156
|
-
export function fromJSON(storeJSON: StoreJson): Store {
|
|
286
|
+
export function fromJSON(attrsStore: AttrsStore, storeJSON: StoreJson): Store {
|
|
157
287
|
return createStore(
|
|
158
|
-
|
|
288
|
+
attrsStore,
|
|
159
289
|
storeJSON.triples,
|
|
160
290
|
storeJSON.cardinalityInference,
|
|
161
|
-
storeJSON.linkIndex,
|
|
162
291
|
storeJSON.useDateObjects,
|
|
163
292
|
);
|
|
164
293
|
}
|
|
165
294
|
|
|
295
|
+
export function attrsStoreFromJSON(
|
|
296
|
+
attrsStoreJSON: AttrsStoreJson | null,
|
|
297
|
+
storeJSON: StoreJson | null,
|
|
298
|
+
): AttrsStore | undefined {
|
|
299
|
+
if (attrsStoreJSON) {
|
|
300
|
+
return new AttrsStoreClass(attrsStoreJSON.attrs, attrsStoreJSON.linkIndex);
|
|
301
|
+
}
|
|
302
|
+
if (storeJSON && '__type' in storeJSON) {
|
|
303
|
+
return new AttrsStoreClass(storeJSON.attrs, storeJSON.linkIndex);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
|
|
166
307
|
export function hasTriple(store: Store, [e, a, v]: [string, string, any]) {
|
|
167
308
|
return getInMap(store.eav, [e, a, v]) !== undefined;
|
|
168
309
|
}
|
|
@@ -171,29 +312,19 @@ export function hasEntity(store: Store, e: string) {
|
|
|
171
312
|
return getInMap(store.eav, [e]) !== undefined;
|
|
172
313
|
}
|
|
173
314
|
|
|
174
|
-
function resetAttrIndexes(store: Store) {
|
|
175
|
-
store.attrIndexes = createAttrIndexes(store.attrs);
|
|
176
|
-
}
|
|
177
|
-
|
|
178
315
|
export function createStore(
|
|
179
|
-
|
|
316
|
+
attrsStore: AttrsStore,
|
|
180
317
|
triples: Triple[],
|
|
181
|
-
enableCardinalityInference
|
|
182
|
-
|
|
183
|
-
useDateObjects: boolean | null,
|
|
318
|
+
enableCardinalityInference?: boolean | null,
|
|
319
|
+
useDateObjects?: boolean | null,
|
|
184
320
|
): Store {
|
|
185
321
|
const store = createTripleIndexes(
|
|
186
|
-
|
|
322
|
+
attrsStore,
|
|
187
323
|
triples,
|
|
188
324
|
useDateObjects,
|
|
189
325
|
) as unknown as Store;
|
|
190
|
-
store.useDateObjects = useDateObjects;
|
|
191
|
-
store.attrs = attrs;
|
|
192
|
-
store.attrIndexes = createAttrIndexes(attrs);
|
|
193
326
|
store.cardinalityInference = enableCardinalityInference;
|
|
194
|
-
store.
|
|
195
|
-
store.__type = 'store';
|
|
196
|
-
|
|
327
|
+
store.useDateObjects = useDateObjects;
|
|
197
328
|
return store;
|
|
198
329
|
}
|
|
199
330
|
|
|
@@ -254,13 +385,17 @@ function resolveLookupRefs(store: Store, triple: Triple): Triple | null {
|
|
|
254
385
|
}
|
|
255
386
|
}
|
|
256
387
|
|
|
257
|
-
export function retractTriple(
|
|
388
|
+
export function retractTriple(
|
|
389
|
+
store: Store,
|
|
390
|
+
attrsStore: AttrsStore,
|
|
391
|
+
rawTriple: Triple,
|
|
392
|
+
): void {
|
|
258
393
|
const triple = resolveLookupRefs(store, rawTriple);
|
|
259
394
|
if (!triple) {
|
|
260
395
|
return;
|
|
261
396
|
}
|
|
262
397
|
const [eid, aid, v] = triple;
|
|
263
|
-
const attr = getAttr(
|
|
398
|
+
const attr = attrsStore.getAttr(aid);
|
|
264
399
|
if (!attr) {
|
|
265
400
|
return;
|
|
266
401
|
}
|
|
@@ -310,13 +445,17 @@ function getCreatedAt(
|
|
|
310
445
|
return createdAt || Date.now() * 10 + _seed++;
|
|
311
446
|
}
|
|
312
447
|
|
|
313
|
-
export function addTriple(
|
|
448
|
+
export function addTriple(
|
|
449
|
+
store: Store,
|
|
450
|
+
attrsStore: AttrsStore,
|
|
451
|
+
rawTriple: Triple,
|
|
452
|
+
) {
|
|
314
453
|
const triple = resolveLookupRefs(store, rawTriple);
|
|
315
454
|
if (!triple) {
|
|
316
455
|
return;
|
|
317
456
|
}
|
|
318
457
|
let [eid, aid, v] = triple;
|
|
319
|
-
const attr = getAttr(
|
|
458
|
+
const attr = attrsStore.getAttr(aid);
|
|
320
459
|
if (!attr) {
|
|
321
460
|
// (XXX): Due to the way we're handling attrs, it's
|
|
322
461
|
// possible to enter a state where we receive a triple without an attr.
|
|
@@ -349,14 +488,14 @@ export function addTriple(store: Store, rawTriple: Triple) {
|
|
|
349
488
|
}
|
|
350
489
|
}
|
|
351
490
|
|
|
352
|
-
function mergeTriple(store: Store, rawTriple: Triple) {
|
|
491
|
+
function mergeTriple(store: Store, attrsStore: AttrsStore, rawTriple: Triple) {
|
|
353
492
|
const triple = resolveLookupRefs(store, rawTriple);
|
|
354
493
|
if (!triple) {
|
|
355
494
|
return;
|
|
356
495
|
}
|
|
357
496
|
|
|
358
497
|
const [eid, aid, update] = triple;
|
|
359
|
-
const attr = getAttr(
|
|
498
|
+
const attr = attrsStore.getAttr(aid);
|
|
360
499
|
|
|
361
500
|
if (!attr) return;
|
|
362
501
|
|
|
@@ -380,9 +519,10 @@ function mergeTriple(store: Store, rawTriple: Triple) {
|
|
|
380
519
|
];
|
|
381
520
|
|
|
382
521
|
setInMap(store.eav, [eid, aid], new Map([[updatedValue, enhancedTriple]]));
|
|
522
|
+
setInMap(store.aev, [aid, eid], new Map([[updatedValue, enhancedTriple]]));
|
|
383
523
|
}
|
|
384
524
|
|
|
385
|
-
function deleteEntity(store: Store, args: any[]) {
|
|
525
|
+
function deleteEntity(store: Store, attrsStore: AttrsStore, args: any[]) {
|
|
386
526
|
const [lookup, etype] = args;
|
|
387
527
|
const triple = resolveLookupRefs(store, [lookup] as unknown as Triple);
|
|
388
528
|
|
|
@@ -395,13 +535,13 @@ function deleteEntity(store: Store, args: any[]) {
|
|
|
395
535
|
const eMap = store.eav.get(id);
|
|
396
536
|
if (eMap) {
|
|
397
537
|
for (const a of eMap.keys()) {
|
|
398
|
-
const attr =
|
|
538
|
+
const attr = attrsStore.getAttr(a);
|
|
399
539
|
|
|
400
540
|
// delete cascade refs
|
|
401
541
|
if (attr && attr['on-delete-reverse'] === 'cascade') {
|
|
402
542
|
allMapValues(eMap.get(a), 1).forEach(
|
|
403
543
|
([e, a, v]: [string, string, any]) =>
|
|
404
|
-
deleteEntity(store, [v, attr['reverse-identity']?.[1]]),
|
|
544
|
+
deleteEntity(store, attrsStore, [v, attr['reverse-identity']?.[1]]),
|
|
405
545
|
);
|
|
406
546
|
}
|
|
407
547
|
|
|
@@ -430,7 +570,7 @@ function deleteEntity(store: Store, args: any[]) {
|
|
|
430
570
|
if (vaeTriples) {
|
|
431
571
|
vaeTriples.forEach((triple: Triple) => {
|
|
432
572
|
const [e, a, v] = triple;
|
|
433
|
-
const attr =
|
|
573
|
+
const attr = attrsStore.getAttr(a);
|
|
434
574
|
if (!etype || !attr || attr['reverse-identity']?.[1] === etype) {
|
|
435
575
|
deleteInMap(store.eav, [e, a, v]);
|
|
436
576
|
deleteInMap(store.aev, [a, e, v]);
|
|
@@ -441,7 +581,7 @@ function deleteEntity(store: Store, args: any[]) {
|
|
|
441
581
|
attr['on-delete'] === 'cascade' &&
|
|
442
582
|
attr['reverse-identity']?.[1] === etype
|
|
443
583
|
) {
|
|
444
|
-
deleteEntity(store, [e, attr['forward-identity']?.[1]]);
|
|
584
|
+
deleteEntity(store, attrsStore, [e, attr['forward-identity']?.[1]]);
|
|
445
585
|
}
|
|
446
586
|
});
|
|
447
587
|
}
|
|
@@ -458,9 +598,9 @@ function deleteEntity(store: Store, args: any[]) {
|
|
|
458
598
|
// * We could batch this reset at the end
|
|
459
599
|
// * We could add an ave index for all triples, so removing the
|
|
460
600
|
// right triples is easy and fast.
|
|
461
|
-
function resetIndexMap(store: Store, newTriples: Triple[]) {
|
|
601
|
+
function resetIndexMap(store: Store, attrsStore, newTriples: Triple[]) {
|
|
462
602
|
const newIndexMap = createTripleIndexes(
|
|
463
|
-
|
|
603
|
+
attrsStore,
|
|
464
604
|
newTriples,
|
|
465
605
|
store.useDateObjects,
|
|
466
606
|
);
|
|
@@ -469,57 +609,55 @@ function resetIndexMap(store: Store, newTriples: Triple[]) {
|
|
|
469
609
|
});
|
|
470
610
|
}
|
|
471
611
|
|
|
472
|
-
function addAttr(
|
|
473
|
-
|
|
474
|
-
resetAttrIndexes(store);
|
|
612
|
+
function addAttr(attrsStore: AttrsStore, [attr]: [InstantDBAttr]) {
|
|
613
|
+
attrsStore.addAttr(attr);
|
|
475
614
|
}
|
|
476
615
|
|
|
477
616
|
function getAllTriples(store: Store): Triple[] {
|
|
478
617
|
return allMapValues(store.eav, 3);
|
|
479
618
|
}
|
|
480
619
|
|
|
481
|
-
function deleteAttr(store: Store, [id]: [string]) {
|
|
482
|
-
if (!
|
|
620
|
+
function deleteAttr(store: Store, attrsStore: AttrsStore, [id]: [string]) {
|
|
621
|
+
if (!attrsStore.getAttr(id)) return;
|
|
483
622
|
const newTriples = getAllTriples(store).filter(([_, aid]) => aid !== id);
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
resetIndexMap(store, newTriples);
|
|
623
|
+
attrsStore.deleteAttr(id);
|
|
624
|
+
resetIndexMap(store, attrsStore, newTriples);
|
|
487
625
|
}
|
|
488
626
|
|
|
489
627
|
function updateAttr(
|
|
490
628
|
store: Store,
|
|
629
|
+
attrsStore: AttrsStore,
|
|
491
630
|
[partialAttr]: [Partial<InstantDBAttr> & { id: string }],
|
|
492
631
|
) {
|
|
493
|
-
const attr =
|
|
632
|
+
const attr = attrsStore.getAttr(partialAttr.id);
|
|
494
633
|
if (!attr) return;
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
resetIndexMap(store, getAllTriples(store));
|
|
634
|
+
attrsStore.updateAttr(partialAttr);
|
|
635
|
+
resetIndexMap(store, attrsStore, getAllTriples(store));
|
|
498
636
|
}
|
|
499
637
|
|
|
500
|
-
function applyTxStep(store: Store, txStep) {
|
|
638
|
+
function applyTxStep(store: Store, attrsStore: AttrsStore, txStep) {
|
|
501
639
|
const [action, ...args] = txStep;
|
|
502
640
|
switch (action) {
|
|
503
641
|
case 'add-triple':
|
|
504
|
-
addTriple(store, args);
|
|
642
|
+
addTriple(store, attrsStore, args);
|
|
505
643
|
break;
|
|
506
644
|
case 'deep-merge-triple':
|
|
507
|
-
mergeTriple(store, args);
|
|
645
|
+
mergeTriple(store, attrsStore, args);
|
|
508
646
|
break;
|
|
509
647
|
case 'retract-triple':
|
|
510
|
-
retractTriple(store, args);
|
|
648
|
+
retractTriple(store, attrsStore, args);
|
|
511
649
|
break;
|
|
512
650
|
case 'delete-entity':
|
|
513
|
-
deleteEntity(store, args);
|
|
651
|
+
deleteEntity(store, attrsStore, args);
|
|
514
652
|
break;
|
|
515
653
|
case 'add-attr':
|
|
516
|
-
addAttr(
|
|
654
|
+
addAttr(attrsStore, args);
|
|
517
655
|
break;
|
|
518
656
|
case 'delete-attr':
|
|
519
|
-
deleteAttr(store, args);
|
|
657
|
+
deleteAttr(store, attrsStore, args);
|
|
520
658
|
break;
|
|
521
659
|
case 'update-attr':
|
|
522
|
-
updateAttr(store, args);
|
|
660
|
+
updateAttr(store, attrsStore, args);
|
|
523
661
|
break;
|
|
524
662
|
case 'restore-attr':
|
|
525
663
|
break;
|
|
@@ -700,35 +838,36 @@ export function getAsObject(
|
|
|
700
838
|
}
|
|
701
839
|
|
|
702
840
|
export function getAttrByFwdIdentName(
|
|
703
|
-
|
|
841
|
+
attrsStore: AttrsStore,
|
|
704
842
|
inputEtype: string,
|
|
705
843
|
inputLabel: string,
|
|
706
844
|
) {
|
|
707
|
-
return
|
|
845
|
+
return attrsStore.forwardIdents.get(inputEtype)?.get(inputLabel);
|
|
708
846
|
}
|
|
709
847
|
|
|
710
848
|
export function getAttrByReverseIdentName(
|
|
711
|
-
|
|
849
|
+
attrsStore: AttrsStore,
|
|
712
850
|
inputEtype: string,
|
|
713
851
|
inputLabel: string,
|
|
714
852
|
) {
|
|
715
|
-
return
|
|
853
|
+
return attrsStore.revIdents.get(inputEtype)?.get(inputLabel);
|
|
716
854
|
}
|
|
717
855
|
|
|
718
|
-
export function getBlobAttrs(
|
|
719
|
-
return
|
|
856
|
+
export function getBlobAttrs(attrsStore: AttrsStore, etype: string) {
|
|
857
|
+
return attrsStore.blobAttrs.get(etype);
|
|
720
858
|
}
|
|
721
859
|
|
|
722
|
-
export function getPrimaryKeyAttr(
|
|
723
|
-
const fromPrimary =
|
|
860
|
+
export function getPrimaryKeyAttr(attrsStore: AttrsStore, etype: string) {
|
|
861
|
+
const fromPrimary = attrsStore.primaryKeys.get(etype);
|
|
724
862
|
if (fromPrimary) {
|
|
725
863
|
return fromPrimary;
|
|
726
864
|
}
|
|
727
|
-
return
|
|
865
|
+
return attrsStore.forwardIdents.get(etype)?.get('id');
|
|
728
866
|
}
|
|
729
867
|
|
|
730
868
|
function findTriple(
|
|
731
869
|
store: Store,
|
|
870
|
+
attrsStore: AttrsStore,
|
|
732
871
|
rawTriple: [string, string, any] | Triple,
|
|
733
872
|
): Triple | undefined {
|
|
734
873
|
const triple = resolveLookupRefs(store, rawTriple as Triple);
|
|
@@ -737,7 +876,7 @@ function findTriple(
|
|
|
737
876
|
}
|
|
738
877
|
|
|
739
878
|
const [eid, aid, v] = triple;
|
|
740
|
-
const attr = getAttr(
|
|
879
|
+
const attr = attrsStore.getAttr(aid);
|
|
741
880
|
if (!attr) {
|
|
742
881
|
// (XXX): Due to the way we're handling attrs, it's
|
|
743
882
|
// possible to enter a state where we receive a triple without an attr.
|
|
@@ -749,7 +888,11 @@ function findTriple(
|
|
|
749
888
|
return getInMap(store.eav, [eid, aid]);
|
|
750
889
|
}
|
|
751
890
|
|
|
752
|
-
export function transact(
|
|
891
|
+
export function transact(
|
|
892
|
+
store: Store,
|
|
893
|
+
attrsStore: AttrsStore,
|
|
894
|
+
txSteps,
|
|
895
|
+
): { store: Store; attrsStore: AttrsStore } {
|
|
753
896
|
const txStepsFiltered = txSteps.filter(
|
|
754
897
|
([action, eid, attrId, value, opts]) => {
|
|
755
898
|
if (action !== 'add-triple' && action !== 'deep-merge-triple') {
|
|
@@ -763,10 +906,13 @@ export function transact(store: Store, txSteps) {
|
|
|
763
906
|
|
|
764
907
|
let exists = false;
|
|
765
908
|
|
|
766
|
-
const attr = getAttr(
|
|
909
|
+
const attr = attrsStore.getAttr(attrId);
|
|
767
910
|
if (attr) {
|
|
768
|
-
const idAttr = getPrimaryKeyAttr(
|
|
769
|
-
|
|
911
|
+
const idAttr = getPrimaryKeyAttr(
|
|
912
|
+
attrsStore,
|
|
913
|
+
attr['forward-identity'][1],
|
|
914
|
+
);
|
|
915
|
+
exists = !!findTriple(store, attrsStore, [
|
|
770
916
|
eid as string,
|
|
771
917
|
idAttr?.id as string,
|
|
772
918
|
eid,
|
|
@@ -785,9 +931,19 @@ export function transact(store: Store, txSteps) {
|
|
|
785
931
|
},
|
|
786
932
|
);
|
|
787
933
|
|
|
788
|
-
return create(
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
934
|
+
return create(
|
|
935
|
+
{ store, attrsStore },
|
|
936
|
+
(draft) => {
|
|
937
|
+
txStepsFiltered.forEach((txStep) => {
|
|
938
|
+
applyTxStep(draft.store, draft.attrsStore, txStep);
|
|
939
|
+
});
|
|
940
|
+
},
|
|
941
|
+
{
|
|
942
|
+
mark: (target) => {
|
|
943
|
+
if (target instanceof AttrsStoreClass) {
|
|
944
|
+
return 'immutable';
|
|
945
|
+
}
|
|
946
|
+
},
|
|
947
|
+
},
|
|
948
|
+
);
|
|
793
949
|
}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { bench } from 'vitest';
|
|
2
|
-
|
|
3
|
-
import zenecaAttrs from './data/zeneca/attrs.json';
|
|
4
|
-
import zenecaTriples from './data/zeneca/triples.json';
|
|
5
|
-
import { createStore } from '../../src/store';
|
|
6
|
-
import query from '../../src/instaql';
|
|
7
|
-
|
|
8
|
-
const zenecaIdToAttr = zenecaAttrs.reduce((res, x) => {
|
|
9
|
-
res[x.id] = x;
|
|
10
|
-
return res;
|
|
11
|
-
}, {});
|
|
12
|
-
|
|
13
|
-
const store = createStore(zenecaIdToAttr, zenecaTriples);
|
|
14
|
-
|
|
15
|
-
bench('big query', () => {
|
|
16
|
-
query(
|
|
17
|
-
{ store },
|
|
18
|
-
{
|
|
19
|
-
users: {
|
|
20
|
-
bookshelves: {
|
|
21
|
-
books: {},
|
|
22
|
-
users: {
|
|
23
|
-
bookshelves: {},
|
|
24
|
-
},
|
|
25
|
-
},
|
|
26
|
-
},
|
|
27
|
-
},
|
|
28
|
-
);
|
|
29
|
-
});
|