@instantdb/core 0.22.86-experimental.split-store.20178922132.1 → 0.22.87-experimental.drewh-explorer-component.20180358679.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/dist/commonjs/Reactor.d.ts +6 -20
- package/dist/commonjs/Reactor.d.ts.map +1 -1
- package/dist/commonjs/Reactor.js +42 -97
- package/dist/commonjs/Reactor.js.map +1 -1
- package/dist/commonjs/SyncTable.d.ts +1 -4
- package/dist/commonjs/SyncTable.d.ts.map +1 -1
- package/dist/commonjs/SyncTable.js +37 -35
- package/dist/commonjs/SyncTable.js.map +1 -1
- package/dist/commonjs/instaml.d.ts +4 -17
- package/dist/commonjs/instaml.d.ts.map +1 -1
- package/dist/commonjs/instaml.js +76 -105
- package/dist/commonjs/instaml.js.map +1 -1
- package/dist/commonjs/instaql.d.ts +1 -2
- package/dist/commonjs/instaql.d.ts.map +1 -1
- package/dist/commonjs/instaql.js +63 -65
- package/dist/commonjs/instaql.js.map +1 -1
- package/dist/commonjs/store.d.ts +21 -44
- package/dist/commonjs/store.d.ts.map +1 -1
- package/dist/commonjs/store.js +69 -164
- package/dist/commonjs/store.js.map +1 -1
- package/dist/esm/Reactor.d.ts +6 -20
- package/dist/esm/Reactor.d.ts.map +1 -1
- package/dist/esm/Reactor.js +43 -98
- package/dist/esm/Reactor.js.map +1 -1
- package/dist/esm/SyncTable.d.ts +1 -4
- package/dist/esm/SyncTable.d.ts.map +1 -1
- package/dist/esm/SyncTable.js +37 -35
- package/dist/esm/SyncTable.js.map +1 -1
- package/dist/esm/instaml.d.ts +4 -17
- package/dist/esm/instaml.d.ts.map +1 -1
- package/dist/esm/instaml.js +71 -102
- package/dist/esm/instaml.js.map +1 -1
- package/dist/esm/instaql.d.ts +1 -2
- package/dist/esm/instaql.d.ts.map +1 -1
- package/dist/esm/instaql.js +63 -65
- package/dist/esm/instaql.js.map +1 -1
- package/dist/esm/store.d.ts +21 -44
- package/dist/esm/store.d.ts.map +1 -1
- package/dist/esm/store.js +69 -161
- package/dist/esm/store.js.map +1 -1
- package/dist/standalone/index.js +1364 -1536
- package/dist/standalone/index.umd.cjs +3 -3
- package/package.json +2 -2
- package/src/Reactor.js +58 -126
- package/src/SyncTable.ts +45 -85
- package/src/{instaml.ts → instaml.js} +95 -195
- package/src/instaql.ts +60 -86
- package/src/store.ts +79 -209
- package/dist/commonjs/reactorTypes.d.ts +0 -29
- package/dist/commonjs/reactorTypes.d.ts.map +0 -1
- package/dist/commonjs/reactorTypes.js +0 -3
- package/dist/commonjs/reactorTypes.js.map +0 -1
- package/dist/esm/reactorTypes.d.ts +0 -29
- package/dist/esm/reactorTypes.d.ts.map +0 -1
- package/dist/esm/reactorTypes.js +0 -2
- package/dist/esm/reactorTypes.js.map +0 -1
- package/src/reactorTypes.ts +0 -32
|
@@ -1,32 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
allMapValues,
|
|
3
|
-
AttrsStore,
|
|
4
|
-
getAttrByFwdIdentName,
|
|
5
|
-
getAttrByReverseIdentName,
|
|
6
|
-
Store,
|
|
7
|
-
} from './store.ts';
|
|
1
|
+
import { allMapValues } from './store.ts';
|
|
8
2
|
import { getOps, isLookup, parseLookup } from './instatx.ts';
|
|
9
3
|
import { immutableRemoveUndefined } from './utils/object.js';
|
|
10
4
|
import { coerceToDate } from './utils/dates.ts';
|
|
11
5
|
import uuid from './utils/uuid.ts';
|
|
12
|
-
import {
|
|
13
|
-
EntitiesWithLinks,
|
|
14
|
-
IContainEntitiesAndLinks,
|
|
15
|
-
LinkDef,
|
|
16
|
-
} from './schemaTypes.ts';
|
|
17
|
-
import { InstantDBAttr, InstantDBIdent } from './attrTypes.ts';
|
|
18
|
-
|
|
19
|
-
export type AttrMapping = {
|
|
20
|
-
attrIdMap: Record<string, string>;
|
|
21
|
-
refSwapAttrIds: Set<string>;
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
type TXStep = any[];
|
|
25
6
|
|
|
26
7
|
// Rewrites optimistic attrs with the attrs we get back from the server.
|
|
27
|
-
export function rewriteStep(attrMapping
|
|
8
|
+
export function rewriteStep(attrMapping, txStep) {
|
|
28
9
|
const { attrIdMap, refSwapAttrIds } = attrMapping;
|
|
29
|
-
const rewritten
|
|
10
|
+
const rewritten = [];
|
|
30
11
|
for (const part of txStep) {
|
|
31
12
|
const newValue = attrIdMap[part];
|
|
32
13
|
|
|
@@ -54,6 +35,22 @@ export function rewriteStep(attrMapping: AttrMapping, txStep: TXStep): TXStep {
|
|
|
54
35
|
return rewritten;
|
|
55
36
|
}
|
|
56
37
|
|
|
38
|
+
export function getAttrByFwdIdentName(attrs, inputEtype, inputIdentName) {
|
|
39
|
+
return Object.values(attrs).find((attr) => {
|
|
40
|
+
const [_id, etype, label] = attr['forward-identity'];
|
|
41
|
+
return etype === inputEtype && label === inputIdentName;
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function getAttrByReverseIdentName(attrs, inputEtype, inputIdentName) {
|
|
46
|
+
return Object.values(attrs).find((attr) => {
|
|
47
|
+
const revIdent = attr['reverse-identity'];
|
|
48
|
+
if (!revIdent) return false;
|
|
49
|
+
const [_id, etype, label] = revIdent;
|
|
50
|
+
return etype === inputEtype && label === inputIdentName;
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
|
|
57
54
|
function explodeLookupRef(eid) {
|
|
58
55
|
if (Array.isArray(eid)) {
|
|
59
56
|
return eid;
|
|
@@ -67,7 +64,7 @@ function explodeLookupRef(eid) {
|
|
|
67
64
|
return entries[0];
|
|
68
65
|
}
|
|
69
66
|
|
|
70
|
-
function isRefLookupIdent(attrs
|
|
67
|
+
function isRefLookupIdent(attrs, etype, identName) {
|
|
71
68
|
return (
|
|
72
69
|
identName.indexOf('.') !== -1 &&
|
|
73
70
|
// attr names can have `.` in them, so use the attr we find with a `.`
|
|
@@ -85,11 +82,7 @@ function extractRefLookupFwdName(identName) {
|
|
|
85
82
|
return fwdName;
|
|
86
83
|
}
|
|
87
84
|
|
|
88
|
-
function lookupIdentToAttr(
|
|
89
|
-
attrs: AttrsStore,
|
|
90
|
-
etype: string,
|
|
91
|
-
identName: string,
|
|
92
|
-
) {
|
|
85
|
+
function lookupIdentToAttr(attrs, etype, identName) {
|
|
93
86
|
if (!isRefLookupIdent(attrs, etype, identName)) {
|
|
94
87
|
return getAttrByFwdIdentName(attrs, etype, identName);
|
|
95
88
|
}
|
|
@@ -116,7 +109,7 @@ function lookupPairOfEid(eid) {
|
|
|
116
109
|
: explodeLookupRef(eid);
|
|
117
110
|
}
|
|
118
111
|
|
|
119
|
-
function extractLookup(attrs
|
|
112
|
+
function extractLookup(attrs, etype, eid) {
|
|
120
113
|
const lookupPair = lookupPairOfEid(eid);
|
|
121
114
|
|
|
122
115
|
if (lookupPair === null) {
|
|
@@ -131,12 +124,7 @@ function extractLookup(attrs: AttrsStore, etype: string, eid: string) {
|
|
|
131
124
|
return [attr.id, value];
|
|
132
125
|
}
|
|
133
126
|
|
|
134
|
-
function withIdAttrForLookup(
|
|
135
|
-
attrs: AttrsStore,
|
|
136
|
-
etype: string,
|
|
137
|
-
eidA: string,
|
|
138
|
-
txSteps: TXStep[],
|
|
139
|
-
) {
|
|
127
|
+
function withIdAttrForLookup(attrs, etype, eidA, txSteps) {
|
|
140
128
|
const lookup = extractLookup(attrs, etype, eidA);
|
|
141
129
|
if (!Array.isArray(lookup)) {
|
|
142
130
|
return txSteps;
|
|
@@ -144,72 +132,63 @@ function withIdAttrForLookup(
|
|
|
144
132
|
const idTuple = [
|
|
145
133
|
'add-triple',
|
|
146
134
|
lookup,
|
|
147
|
-
getAttrByFwdIdentName(attrs, etype, 'id')
|
|
135
|
+
getAttrByFwdIdentName(attrs, etype, 'id').id,
|
|
148
136
|
lookup,
|
|
149
137
|
];
|
|
150
138
|
return [idTuple].concat(txSteps);
|
|
151
139
|
}
|
|
152
140
|
|
|
153
|
-
function expandLink({
|
|
141
|
+
function expandLink({ attrs }, [etype, eidA, obj]) {
|
|
154
142
|
const addTriples = Object.entries(obj).flatMap(([label, eidOrEids]) => {
|
|
155
143
|
const eids = Array.isArray(eidOrEids) ? eidOrEids : [eidOrEids];
|
|
156
|
-
const fwdAttr = getAttrByFwdIdentName(
|
|
157
|
-
const revAttr = getAttrByReverseIdentName(
|
|
144
|
+
const fwdAttr = getAttrByFwdIdentName(attrs, etype, label);
|
|
145
|
+
const revAttr = getAttrByReverseIdentName(attrs, etype, label);
|
|
158
146
|
return eids.map((eidB) => {
|
|
159
147
|
const txStep = fwdAttr
|
|
160
148
|
? [
|
|
161
149
|
'add-triple',
|
|
162
|
-
extractLookup(
|
|
150
|
+
extractLookup(attrs, etype, eidA),
|
|
163
151
|
fwdAttr.id,
|
|
164
|
-
|
|
165
|
-
extractLookup(attrsStore, fwdAttr!['reverse-identity']![1], eidB),
|
|
152
|
+
extractLookup(attrs, fwdAttr['reverse-identity'][1], eidB),
|
|
166
153
|
]
|
|
167
154
|
: [
|
|
168
155
|
'add-triple',
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
extractLookup(attrsStore, etype, eidA),
|
|
156
|
+
extractLookup(attrs, revAttr['forward-identity'][1], eidB),
|
|
157
|
+
revAttr.id,
|
|
158
|
+
extractLookup(attrs, etype, eidA),
|
|
173
159
|
];
|
|
174
160
|
return txStep;
|
|
175
161
|
});
|
|
176
162
|
});
|
|
177
|
-
return withIdAttrForLookup(
|
|
163
|
+
return withIdAttrForLookup(attrs, etype, eidA, addTriples);
|
|
178
164
|
}
|
|
179
165
|
|
|
180
|
-
function expandUnlink({
|
|
166
|
+
function expandUnlink({ attrs }, [etype, eidA, obj]) {
|
|
181
167
|
const retractTriples = Object.entries(obj).flatMap(([label, eidOrEids]) => {
|
|
182
168
|
const eids = Array.isArray(eidOrEids) ? eidOrEids : [eidOrEids];
|
|
183
|
-
const fwdAttr = getAttrByFwdIdentName(
|
|
184
|
-
const revAttr = getAttrByReverseIdentName(
|
|
169
|
+
const fwdAttr = getAttrByFwdIdentName(attrs, etype, label);
|
|
170
|
+
const revAttr = getAttrByReverseIdentName(attrs, etype, label);
|
|
185
171
|
return eids.map((eidB) => {
|
|
186
172
|
const txStep = fwdAttr
|
|
187
173
|
? [
|
|
188
174
|
'retract-triple',
|
|
189
|
-
extractLookup(
|
|
175
|
+
extractLookup(attrs, etype, eidA),
|
|
190
176
|
fwdAttr.id,
|
|
191
|
-
|
|
192
|
-
extractLookup(attrsStore, fwdAttr!['reverse-identity']![1], eidB),
|
|
177
|
+
extractLookup(attrs, fwdAttr['reverse-identity'][1], eidB),
|
|
193
178
|
]
|
|
194
179
|
: [
|
|
195
180
|
'retract-triple',
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
extractLookup(attrsStore, etype, eidA),
|
|
181
|
+
extractLookup(attrs, revAttr['forward-identity'][1], eidB),
|
|
182
|
+
revAttr.id,
|
|
183
|
+
extractLookup(attrs, etype, eidA),
|
|
200
184
|
];
|
|
201
185
|
return txStep;
|
|
202
186
|
});
|
|
203
187
|
});
|
|
204
|
-
return withIdAttrForLookup(
|
|
188
|
+
return withIdAttrForLookup(attrs, etype, eidA, retractTriples);
|
|
205
189
|
}
|
|
206
190
|
|
|
207
|
-
function checkEntityExists(
|
|
208
|
-
stores: (Store | undefined)[],
|
|
209
|
-
attrsStore: AttrsStore,
|
|
210
|
-
etype: string,
|
|
211
|
-
eid: string,
|
|
212
|
-
) {
|
|
191
|
+
function checkEntityExists(stores, etype, eid) {
|
|
213
192
|
if (Array.isArray(eid)) {
|
|
214
193
|
// lookup ref
|
|
215
194
|
const [entity_a, entity_v] = eid;
|
|
@@ -230,7 +209,7 @@ function checkEntityExists(
|
|
|
230
209
|
const av = store?.eav.get(eid);
|
|
231
210
|
if (av) {
|
|
232
211
|
for (const attr_id of av.keys()) {
|
|
233
|
-
if (
|
|
212
|
+
if (store.attrs[attr_id]['forward-identity'][1] == etype) {
|
|
234
213
|
return true;
|
|
235
214
|
}
|
|
236
215
|
}
|
|
@@ -240,34 +219,26 @@ function checkEntityExists(
|
|
|
240
219
|
return false;
|
|
241
220
|
}
|
|
242
221
|
|
|
243
|
-
|
|
244
|
-
stores: (Store | undefined)[];
|
|
245
|
-
attrsStore: AttrsStore;
|
|
246
|
-
schema: Schema;
|
|
247
|
-
useDateObjects: boolean | null;
|
|
248
|
-
};
|
|
249
|
-
|
|
250
|
-
function convertOpts({ stores, attrsStore }: Ctx, [etype, eid, obj_, opts]) {
|
|
222
|
+
function convertOpts({ stores, attrs }, [etype, eid, obj_, opts]) {
|
|
251
223
|
return opts?.upsert === false
|
|
252
224
|
? { mode: 'update' }
|
|
253
225
|
: opts?.upsert === true
|
|
254
226
|
? null
|
|
255
|
-
: checkEntityExists(stores,
|
|
227
|
+
: checkEntityExists(stores, etype, eid)
|
|
256
228
|
? { mode: 'update' }
|
|
257
229
|
: null; // auto mode chooses between update and upsert, not update and create, just in case
|
|
258
230
|
}
|
|
259
231
|
|
|
260
|
-
function expandCreate(ctx
|
|
261
|
-
const {
|
|
232
|
+
function expandCreate(ctx, step) {
|
|
233
|
+
const { stores, attrs } = ctx;
|
|
262
234
|
const [etype, eid, obj_, opts] = step;
|
|
263
235
|
const obj = immutableRemoveUndefined(obj_);
|
|
264
|
-
const lookup = extractLookup(
|
|
236
|
+
const lookup = extractLookup(attrs, etype, eid);
|
|
265
237
|
// id first so that we don't clobber updates on the lookup field
|
|
266
238
|
const attrTuples = [['id', lookup]]
|
|
267
239
|
.concat(Object.entries(obj))
|
|
268
|
-
.map(([identName, value]
|
|
269
|
-
|
|
270
|
-
const attr = getAttrByFwdIdentName(attrsStore, etype, identName)!;
|
|
240
|
+
.map(([identName, value]) => {
|
|
241
|
+
const attr = getAttrByFwdIdentName(attrs, etype, identName);
|
|
271
242
|
|
|
272
243
|
if (attr['checked-data-type'] === 'date' && ctx.useDateObjects) {
|
|
273
244
|
value = coerceToDate(value);
|
|
@@ -278,17 +249,17 @@ function expandCreate(ctx: Ctx, step) {
|
|
|
278
249
|
return attrTuples;
|
|
279
250
|
}
|
|
280
251
|
|
|
281
|
-
function expandUpdate(ctx
|
|
282
|
-
const {
|
|
252
|
+
function expandUpdate(ctx, step) {
|
|
253
|
+
const { stores, attrs } = ctx;
|
|
283
254
|
const [etype, eid, obj_, opts] = step;
|
|
284
255
|
const obj = immutableRemoveUndefined(obj_);
|
|
285
|
-
const lookup = extractLookup(
|
|
256
|
+
const lookup = extractLookup(attrs, etype, eid);
|
|
286
257
|
const serverOpts = convertOpts(ctx, [etype, lookup, obj_, opts]);
|
|
287
258
|
// id first so that we don't clobber updates on the lookup field
|
|
288
259
|
const attrTuples = [['id', lookup]]
|
|
289
260
|
.concat(Object.entries(obj))
|
|
290
|
-
.map(([identName, value]
|
|
291
|
-
const attr = getAttrByFwdIdentName(
|
|
261
|
+
.map(([identName, value]) => {
|
|
262
|
+
const attr = getAttrByFwdIdentName(attrs, etype, identName);
|
|
292
263
|
|
|
293
264
|
if (attr['checked-data-type'] === 'date' && ctx.useDateObjects) {
|
|
294
265
|
value = coerceToDate(value);
|
|
@@ -305,19 +276,19 @@ function expandUpdate(ctx: Ctx, step) {
|
|
|
305
276
|
return attrTuples;
|
|
306
277
|
}
|
|
307
278
|
|
|
308
|
-
function expandDelete({
|
|
309
|
-
const lookup = extractLookup(
|
|
279
|
+
function expandDelete({ attrs }, [etype, eid]) {
|
|
280
|
+
const lookup = extractLookup(attrs, etype, eid);
|
|
310
281
|
return [['delete-entity', lookup, etype]];
|
|
311
282
|
}
|
|
312
283
|
|
|
313
|
-
function expandDeepMerge(ctx
|
|
314
|
-
const {
|
|
284
|
+
function expandDeepMerge(ctx, step) {
|
|
285
|
+
const { stores, attrs } = ctx;
|
|
315
286
|
const [etype, eid, obj_, opts] = step;
|
|
316
287
|
const obj = immutableRemoveUndefined(obj_);
|
|
317
|
-
const lookup = extractLookup(
|
|
288
|
+
const lookup = extractLookup(attrs, etype, eid);
|
|
318
289
|
const serverOpts = convertOpts(ctx, [etype, lookup, obj_, opts]);
|
|
319
290
|
const attrTuples = Object.entries(obj).map(([identName, value]) => {
|
|
320
|
-
const attr = getAttrByFwdIdentName(
|
|
291
|
+
const attr = getAttrByFwdIdentName(attrs, etype, identName);
|
|
321
292
|
return [
|
|
322
293
|
'deep-merge-triple',
|
|
323
294
|
lookup,
|
|
@@ -330,7 +301,7 @@ function expandDeepMerge(ctx: Ctx, step) {
|
|
|
330
301
|
const idTuple = [
|
|
331
302
|
'add-triple',
|
|
332
303
|
lookup,
|
|
333
|
-
getAttrByFwdIdentName(
|
|
304
|
+
getAttrByFwdIdentName(attrs, etype, 'id').id,
|
|
334
305
|
lookup,
|
|
335
306
|
...(serverOpts ? [serverOpts] : []),
|
|
336
307
|
];
|
|
@@ -339,8 +310,8 @@ function expandDeepMerge(ctx: Ctx, step) {
|
|
|
339
310
|
return [idTuple].concat(attrTuples);
|
|
340
311
|
}
|
|
341
312
|
|
|
342
|
-
function expandRuleParams({
|
|
343
|
-
const lookup = extractLookup(
|
|
313
|
+
function expandRuleParams({ attrs }, [etype, eid, ruleParams]) {
|
|
314
|
+
const lookup = extractLookup(attrs, etype, eid);
|
|
344
315
|
return [['rule-params', lookup, etype, ruleParams]];
|
|
345
316
|
}
|
|
346
317
|
|
|
@@ -354,7 +325,7 @@ function removeIdFromArgs(step) {
|
|
|
354
325
|
return [op, etype, eid, newObj, ...(opts ? [opts] : [])];
|
|
355
326
|
}
|
|
356
327
|
|
|
357
|
-
function toTxSteps(ctx
|
|
328
|
+
function toTxSteps(ctx, step) {
|
|
358
329
|
const [action, ...args] = removeIdFromArgs(step);
|
|
359
330
|
switch (action) {
|
|
360
331
|
case 'merge':
|
|
@@ -427,12 +398,8 @@ function createObjectAttr(schema, etype, label, props) {
|
|
|
427
398
|
};
|
|
428
399
|
}
|
|
429
400
|
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
function findSchemaLink(schema: Schema, etype, label): Link | undefined {
|
|
434
|
-
const links: Link[] = Object.values(schema.links);
|
|
435
|
-
const found = links.find((x: Link) => {
|
|
401
|
+
function findSchemaLink(schema, etype, label) {
|
|
402
|
+
const found = Object.values(schema.links).find((x) => {
|
|
436
403
|
return (
|
|
437
404
|
(x.forward.on === etype && x.forward.label === label) ||
|
|
438
405
|
(x.reverse.on === etype && x.reverse.label === label)
|
|
@@ -441,7 +408,7 @@ function findSchemaLink(schema: Schema, etype, label): Link | undefined {
|
|
|
441
408
|
return found;
|
|
442
409
|
}
|
|
443
410
|
|
|
444
|
-
function refPropsFromSchema(schema
|
|
411
|
+
function refPropsFromSchema(schema, etype, label) {
|
|
445
412
|
const found = findSchemaLink(schema, etype, label);
|
|
446
413
|
if (!found) {
|
|
447
414
|
throw new Error(`Couldn't find the link ${etype}.${label} in your schema`);
|
|
@@ -457,26 +424,18 @@ function refPropsFromSchema(schema: Schema, etype, label) {
|
|
|
457
424
|
};
|
|
458
425
|
}
|
|
459
426
|
|
|
460
|
-
function createRefAttr(
|
|
461
|
-
schema: Schema,
|
|
462
|
-
etype: string,
|
|
463
|
-
label: string,
|
|
464
|
-
props?: Partial<InstantDBAttr> | undefined,
|
|
465
|
-
): InstantDBAttr {
|
|
427
|
+
function createRefAttr(schema, etype, label, props) {
|
|
466
428
|
const schemaRefProps = schema
|
|
467
429
|
? refPropsFromSchema(schema, etype, label)
|
|
468
430
|
: null;
|
|
469
431
|
const attrId = uuid();
|
|
470
|
-
const fwdIdent
|
|
471
|
-
const revIdent
|
|
432
|
+
const fwdIdent = [uuid(), etype, label];
|
|
433
|
+
const revIdent = [uuid(), label, etype];
|
|
472
434
|
return {
|
|
473
435
|
id: attrId,
|
|
474
|
-
// @ts-ignore: ts thinks it's any[]
|
|
475
436
|
'forward-identity': fwdIdent,
|
|
476
|
-
// @ts-ignore: ts thinks it's any[]
|
|
477
437
|
'reverse-identity': revIdent,
|
|
478
438
|
'value-type': 'ref',
|
|
479
|
-
// @ts-ignore: ts thinks it's type string
|
|
480
439
|
cardinality: 'many',
|
|
481
440
|
'unique?': false,
|
|
482
441
|
'index?': false,
|
|
@@ -500,14 +459,11 @@ const SUPPORTS_LOOKUP_ACTIONS = new Set([
|
|
|
500
459
|
'ruleParams',
|
|
501
460
|
]);
|
|
502
461
|
|
|
503
|
-
const lookupProps
|
|
504
|
-
const refLookupProps
|
|
505
|
-
...lookupProps,
|
|
506
|
-
cardinality: 'one',
|
|
507
|
-
};
|
|
462
|
+
const lookupProps = { 'unique?': true, 'index?': true };
|
|
463
|
+
const refLookupProps = { ...lookupProps, cardinality: 'one' };
|
|
508
464
|
|
|
509
465
|
function lookupPairsOfOp(op) {
|
|
510
|
-
const res
|
|
466
|
+
const res = [];
|
|
511
467
|
const [action, etype, eid, obj] = op;
|
|
512
468
|
if (!SUPPORTS_LOOKUP_ACTIONS.has(action)) {
|
|
513
469
|
return res;
|
|
@@ -535,72 +491,24 @@ function lookupPairsOfOp(op) {
|
|
|
535
491
|
return res;
|
|
536
492
|
}
|
|
537
493
|
|
|
538
|
-
function createMissingAttrs(
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
const addedIds = new Set();
|
|
543
|
-
const localAttrs: InstantDBAttr[] = [];
|
|
544
|
-
const addOps: TXStep[] = [];
|
|
545
|
-
|
|
546
|
-
function attrByFwdIdent(etype, label): InstantDBAttr | undefined {
|
|
547
|
-
return (
|
|
548
|
-
getAttrByFwdIdentName(attrsStore, etype, label) ||
|
|
549
|
-
localAttrs.find(
|
|
550
|
-
(x) =>
|
|
551
|
-
x['forward-identity'][1] === etype &&
|
|
552
|
-
x['forward-identity'][2] === label,
|
|
553
|
-
)
|
|
554
|
-
);
|
|
555
|
-
}
|
|
556
|
-
|
|
557
|
-
function attrByRevIdent(etype, label): InstantDBAttr | undefined {
|
|
558
|
-
return (
|
|
559
|
-
getAttrByReverseIdentName(attrsStore, etype, label) ||
|
|
560
|
-
localAttrs.find(
|
|
561
|
-
(x) =>
|
|
562
|
-
x['reverse-identity']?.[1] === etype &&
|
|
563
|
-
x['reverse-identity']?.[2] === label,
|
|
564
|
-
)
|
|
565
|
-
);
|
|
566
|
-
}
|
|
567
|
-
|
|
568
|
-
function addAttr(attr: InstantDBAttr) {
|
|
569
|
-
localAttrs.push(attr);
|
|
494
|
+
function createMissingAttrs({ attrs: existingAttrs, schema }, ops) {
|
|
495
|
+
const [addedIds, attrs, addOps] = [new Set(), { ...existingAttrs }, []];
|
|
496
|
+
function addAttr(attr) {
|
|
497
|
+
attrs[attr.id] = attr;
|
|
570
498
|
addOps.push(['add-attr', attr]);
|
|
571
499
|
addedIds.add(attr.id);
|
|
572
500
|
}
|
|
573
|
-
function addUnsynced(
|
|
574
|
-
attr
|
|
575
|
-
| (InstantDBAttr & { isUnsynced?: boolean })
|
|
576
|
-
| InstantDBAttr
|
|
577
|
-
| undefined,
|
|
578
|
-
) {
|
|
579
|
-
if (
|
|
580
|
-
attr &&
|
|
581
|
-
'isUnsynced' in attr &&
|
|
582
|
-
attr.isUnsynced &&
|
|
583
|
-
!addedIds.has(attr.id)
|
|
584
|
-
) {
|
|
585
|
-
localAttrs.push(attr);
|
|
501
|
+
function addUnsynced(attr) {
|
|
502
|
+
if (attr?.isUnsynced && !addedIds.has(attr.id)) {
|
|
586
503
|
addOps.push(['add-attr', attr]);
|
|
587
504
|
addedIds.add(attr.id);
|
|
588
505
|
}
|
|
589
506
|
}
|
|
590
507
|
|
|
591
|
-
function isRefLookupIdentLocal(etype: string, identName: string) {
|
|
592
|
-
return (
|
|
593
|
-
identName.indexOf('.') !== -1 &&
|
|
594
|
-
// attr names can have `.` in them, so use the attr we find with a `.`
|
|
595
|
-
// before assuming it's a ref lookup.
|
|
596
|
-
!attrByRevIdent(etype, identName)
|
|
597
|
-
);
|
|
598
|
-
}
|
|
599
|
-
|
|
600
508
|
// Adds attrs needed for a ref lookup
|
|
601
509
|
function addForRef(etype, label) {
|
|
602
|
-
const fwdAttr =
|
|
603
|
-
const revAttr =
|
|
510
|
+
const fwdAttr = getAttrByFwdIdentName(attrs, etype, label);
|
|
511
|
+
const revAttr = getAttrByReverseIdentName(attrs, etype, label);
|
|
604
512
|
addUnsynced(fwdAttr);
|
|
605
513
|
addUnsynced(revAttr);
|
|
606
514
|
if (!fwdAttr && !revAttr) {
|
|
@@ -622,18 +530,18 @@ function createMissingAttrs(
|
|
|
622
530
|
|
|
623
531
|
// Figure out the link etype so we can make sure we have the attrs
|
|
624
532
|
// for the link lookup
|
|
625
|
-
const fwdAttr =
|
|
626
|
-
const revAttr =
|
|
533
|
+
const fwdAttr = getAttrByFwdIdentName(attrs, etype, linkLabel);
|
|
534
|
+
const revAttr = getAttrByReverseIdentName(attrs, etype, linkLabel);
|
|
627
535
|
addUnsynced(fwdAttr);
|
|
628
536
|
addUnsynced(revAttr);
|
|
629
537
|
const linkEtype =
|
|
630
538
|
fwdAttr?.['reverse-identity']?.[1] ||
|
|
631
539
|
revAttr?.['forward-identity']?.[1] ||
|
|
632
540
|
linkLabel;
|
|
633
|
-
if (
|
|
541
|
+
if (isRefLookupIdent(attrs, linkEtype, identName)) {
|
|
634
542
|
addForRef(linkEtype, extractRefLookupFwdName(identName));
|
|
635
543
|
} else {
|
|
636
|
-
const attr =
|
|
544
|
+
const attr = getAttrByFwdIdentName(attrs, linkEtype, identName);
|
|
637
545
|
if (!attr) {
|
|
638
546
|
addAttr(
|
|
639
547
|
createObjectAttr(schema, linkEtype, identName, lookupProps),
|
|
@@ -641,10 +549,10 @@ function createMissingAttrs(
|
|
|
641
549
|
}
|
|
642
550
|
addUnsynced(attr);
|
|
643
551
|
}
|
|
644
|
-
} else if (
|
|
552
|
+
} else if (isRefLookupIdent(attrs, etype, identName)) {
|
|
645
553
|
addForRef(etype, extractRefLookupFwdName(identName));
|
|
646
554
|
} else {
|
|
647
|
-
const attr =
|
|
555
|
+
const attr = getAttrByFwdIdentName(attrs, etype, identName);
|
|
648
556
|
if (!attr) {
|
|
649
557
|
addAttr(createObjectAttr(schema, etype, identName, lookupProps));
|
|
650
558
|
}
|
|
@@ -657,14 +565,14 @@ function createMissingAttrs(
|
|
|
657
565
|
for (const op of ops) {
|
|
658
566
|
const [action, etype, eid, obj] = op;
|
|
659
567
|
if (OBJ_ACTIONS.has(action)) {
|
|
660
|
-
const idAttr =
|
|
568
|
+
const idAttr = getAttrByFwdIdentName(attrs, etype, 'id');
|
|
661
569
|
addUnsynced(idAttr);
|
|
662
570
|
if (!idAttr) {
|
|
663
571
|
addAttr(createObjectAttr(schema, etype, 'id', { 'unique?': true }));
|
|
664
572
|
}
|
|
665
573
|
|
|
666
574
|
for (const label of Object.keys(obj)) {
|
|
667
|
-
const fwdAttr =
|
|
575
|
+
const fwdAttr = getAttrByFwdIdentName(attrs, etype, label);
|
|
668
576
|
addUnsynced(fwdAttr);
|
|
669
577
|
if (UPDATE_ACTIONS.has(action)) {
|
|
670
578
|
if (!fwdAttr) {
|
|
@@ -679,7 +587,7 @@ function createMissingAttrs(
|
|
|
679
587
|
}
|
|
680
588
|
}
|
|
681
589
|
if (REF_ACTIONS.has(action)) {
|
|
682
|
-
const revAttr =
|
|
590
|
+
const revAttr = getAttrByReverseIdentName(attrs, etype, label);
|
|
683
591
|
if (!fwdAttr && !revAttr) {
|
|
684
592
|
addAttr(createRefAttr(schema, etype, label));
|
|
685
593
|
}
|
|
@@ -688,22 +596,14 @@ function createMissingAttrs(
|
|
|
688
596
|
}
|
|
689
597
|
}
|
|
690
598
|
}
|
|
691
|
-
|
|
692
|
-
if (localAttrs.length) {
|
|
693
|
-
const nextAttrs = { ...attrsStore.attrs };
|
|
694
|
-
for (const attr of localAttrs) {
|
|
695
|
-
nextAttrs[attr.id] = attr;
|
|
696
|
-
}
|
|
697
|
-
return [new AttrsStore(nextAttrs, attrsStore.linkIndex), addOps];
|
|
698
|
-
}
|
|
699
|
-
return [attrsStore, addOps];
|
|
599
|
+
return [attrs, addOps];
|
|
700
600
|
}
|
|
701
601
|
|
|
702
|
-
export function transform(ctx
|
|
602
|
+
export function transform(ctx, inputChunks) {
|
|
703
603
|
const chunks = Array.isArray(inputChunks) ? inputChunks : [inputChunks];
|
|
704
604
|
const ops = chunks.flatMap((tx) => getOps(tx));
|
|
705
605
|
const [newAttrs, addAttrTxSteps] = createMissingAttrs(ctx, ops);
|
|
706
|
-
const newCtx = { ...ctx,
|
|
606
|
+
const newCtx = { ...ctx, attrs: newAttrs };
|
|
707
607
|
const txSteps = ops.flatMap((op) => toTxSteps(newCtx, op));
|
|
708
608
|
return [...addAttrTxSteps, ...txSteps];
|
|
709
609
|
}
|