@based/db 0.0.48 → 0.0.50
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/lib/darwin_aarch64/libnode-v20.node +0 -0
- package/dist/lib/darwin_aarch64/libnode-v21.node +0 -0
- package/dist/lib/darwin_aarch64/libnode-v22.node +0 -0
- package/dist/lib/darwin_aarch64/libnode-v23.node +0 -0
- package/dist/lib/darwin_aarch64/libnode-v24.node +0 -0
- package/dist/lib/darwin_aarch64/libselva.dylib +0 -0
- package/dist/lib/linux_aarch64/libnode-v20.node +0 -0
- package/dist/lib/linux_aarch64/libnode-v21.node +0 -0
- package/dist/lib/linux_aarch64/libnode-v22.node +0 -0
- package/dist/lib/linux_aarch64/libnode-v23.node +0 -0
- package/dist/lib/linux_aarch64/libnode-v24.node +0 -0
- package/dist/lib/linux_aarch64/libselva.so +0 -0
- package/dist/lib/linux_x86_64/libnode-v20.node +0 -0
- package/dist/lib/linux_x86_64/libnode-v21.node +0 -0
- package/dist/lib/linux_x86_64/libnode-v22.node +0 -0
- package/dist/lib/linux_x86_64/libnode-v23.node +0 -0
- package/dist/lib/linux_x86_64/libnode-v24.node +0 -0
- package/dist/lib/linux_x86_64/libselva.so +0 -0
- package/dist/src/client/index.js +4 -2
- package/dist/src/client/modify/references/references.js +3 -3
- package/dist/src/client/modify/types.d.ts +2 -0
- package/dist/src/client/modify/types.js +2 -0
- package/dist/src/client/query/BasedDbQuery.js +19 -1
- package/dist/src/schema.d.ts +3 -0
- package/dist/src/schema.js +94 -0
- package/dist/src/server/index.js +11 -48
- package/dist/src/server/start.js +23 -7
- package/dist/src/utils.d.ts +0 -1
- package/dist/src/utils.js +0 -47
- package/package.json +1 -1
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/dist/src/client/index.js
CHANGED
|
@@ -10,7 +10,8 @@ import { deleteFn } from './modify/delete.js';
|
|
|
10
10
|
import { wait } from '@saulx/utils';
|
|
11
11
|
import { hash } from '@saulx/hash';
|
|
12
12
|
import { expire } from './modify/expire.js';
|
|
13
|
-
import { debugMode
|
|
13
|
+
import { debugMode } from '../utils.js';
|
|
14
|
+
import { parseSchema, schemaLooseEqual } from '../schema.js';
|
|
14
15
|
const makeFlushIsReady = (dbClient) => {
|
|
15
16
|
dbClient.flushIsReady = new Promise((resolve) => {
|
|
16
17
|
dbClient.flushReady = () => {
|
|
@@ -48,8 +49,9 @@ export class DbClient {
|
|
|
48
49
|
schemaPromise;
|
|
49
50
|
async setSchema(schema, fromStart, transformFns) {
|
|
50
51
|
const strictSchema = fromStart ? schema : parse(schema).schema;
|
|
52
|
+
const parsedSchema = parseSchema(strictSchema);
|
|
51
53
|
// this one excludes all the ids
|
|
52
|
-
if (schemaLooseEqual(
|
|
54
|
+
if (schemaLooseEqual(parsedSchema, this.schema)) {
|
|
53
55
|
return this.schema;
|
|
54
56
|
}
|
|
55
57
|
// drain current things
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { REFERENCES } from '@based/schema/def';
|
|
2
2
|
import { ModifyError, ModifyState } from '../ModifyRes.js';
|
|
3
3
|
import { setCursor } from '../setCursor.js';
|
|
4
|
-
import { DELETE, EDGE_INDEX_REALID, EDGE_INDEX_TMPID, EDGE_NOINDEX_REALID, EDGE_NOINDEX_TMPID, NOEDGE_INDEX_REALID, NOEDGE_INDEX_TMPID, NOEDGE_NOINDEX_REALID, NOEDGE_NOINDEX_TMPID, RANGE_ERR, REF_OP_UPDATE, } from '../types.js';
|
|
4
|
+
import { DELETE, EDGE_INDEX_REALID, EDGE_INDEX_TMPID, EDGE_NOINDEX_REALID, EDGE_NOINDEX_TMPID, NOEDGE_INDEX_REALID, NOEDGE_INDEX_TMPID, NOEDGE_NOINDEX_REALID, NOEDGE_NOINDEX_TMPID, RANGE_ERR, REF_OP_OVERWRITE, REF_OP_PUT_ADD, REF_OP_PUT_OVERWRITE, REF_OP_UPDATE, } from '../types.js';
|
|
5
5
|
import { writeEdges } from './edge.js';
|
|
6
6
|
export function writeReferences(value, ctx, schema, def, res, mod) {
|
|
7
7
|
if (typeof value !== 'object') {
|
|
@@ -266,8 +266,8 @@ function putRefs(def, ctx, modifyOp, refs, op) {
|
|
|
266
266
|
ctx.buf[ctx.len++] = size >>>= 8;
|
|
267
267
|
ctx.buf[ctx.len++] = size >>>= 8;
|
|
268
268
|
ctx.buf[ctx.len++] = size >>>= 8;
|
|
269
|
-
ctx.buf[ctx.len++] =
|
|
270
|
-
|
|
269
|
+
ctx.buf[ctx.len++] =
|
|
270
|
+
op === REF_OP_OVERWRITE ? REF_OP_PUT_OVERWRITE : REF_OP_PUT_ADD;
|
|
271
271
|
let i = 0;
|
|
272
272
|
for (; i < refs.length; i++) {
|
|
273
273
|
let ref = refs[i];
|
|
@@ -37,4 +37,6 @@ export declare const EDGE_INDEX_TMPID = 6;
|
|
|
37
37
|
export declare const NOEDGE_INDEX_TMPID = 7;
|
|
38
38
|
export declare const REF_OP_UPDATE = 1;
|
|
39
39
|
export declare const REF_OP_OVERWRITE = 0;
|
|
40
|
+
export declare const REF_OP_PUT_OVERWRITE = 3;
|
|
41
|
+
export declare const REF_OP_PUT_ADD = 4;
|
|
40
42
|
export type REF_OP = typeof REF_OP_OVERWRITE | typeof REF_OP_UPDATE;
|
|
@@ -12,6 +12,8 @@ import { convertFilter } from './filter/convertFilter.js';
|
|
|
12
12
|
import { validateLocale, validateRange } from './validation.js';
|
|
13
13
|
import { DEF_RANGE_PROP_LIMIT } from './thresholds.js';
|
|
14
14
|
import { concatUint8Arr } from '@saulx/utils';
|
|
15
|
+
import { displayTarget } from './display.js';
|
|
16
|
+
import picocolors from 'picocolors';
|
|
15
17
|
export class QueryBranch {
|
|
16
18
|
db;
|
|
17
19
|
def;
|
|
@@ -325,6 +327,10 @@ export class BasedDbQuery extends QueryBranch {
|
|
|
325
327
|
const res = await this.db.hooks.getQueryBuf(buf);
|
|
326
328
|
if (res.byteLength === 1) {
|
|
327
329
|
if (res[0] === 0) {
|
|
330
|
+
if (this.db.schema?.hash !== this.def.schemaChecksum) {
|
|
331
|
+
this.reBuildQuery();
|
|
332
|
+
return this.#getInternal(resolve, reject);
|
|
333
|
+
}
|
|
328
334
|
reject(new Error('schema mismatch'));
|
|
329
335
|
}
|
|
330
336
|
else {
|
|
@@ -353,7 +359,19 @@ export class BasedDbQuery extends QueryBranch {
|
|
|
353
359
|
return this;
|
|
354
360
|
}
|
|
355
361
|
subscribe(onData, onError) {
|
|
356
|
-
return subscribe(this,
|
|
362
|
+
return subscribe(this, (res) => {
|
|
363
|
+
try {
|
|
364
|
+
onData(res);
|
|
365
|
+
}
|
|
366
|
+
catch (err) {
|
|
367
|
+
// const t = displayTarget(this.def)
|
|
368
|
+
const def = this.def;
|
|
369
|
+
let name = picocolors.red(`QueryError[${displayTarget(def)}]\n`);
|
|
370
|
+
name += ` Error executing onData handler in subscription\n`;
|
|
371
|
+
name += ` ${err.message}\n`;
|
|
372
|
+
console.error(name);
|
|
373
|
+
}
|
|
374
|
+
}, onError ??
|
|
357
375
|
((err) => {
|
|
358
376
|
console.error(err);
|
|
359
377
|
}));
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { getPropType } from '@based/schema';
|
|
2
|
+
const exclude = new Set(['id', 'lastId', 'hash']);
|
|
3
|
+
export const schemaLooseEqual = (a, b, key) => {
|
|
4
|
+
if (a === b) {
|
|
5
|
+
return true;
|
|
6
|
+
}
|
|
7
|
+
const typeofA = typeof a;
|
|
8
|
+
if (typeofA !== 'object') {
|
|
9
|
+
return exclude.has(key);
|
|
10
|
+
}
|
|
11
|
+
const typeofB = typeof b;
|
|
12
|
+
if (typeofA !== typeofB) {
|
|
13
|
+
return exclude.has(key);
|
|
14
|
+
}
|
|
15
|
+
if (a === null || b === null) {
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
if (a.constructor !== b.constructor) {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
if (Array.isArray(a)) {
|
|
22
|
+
let i = a.length;
|
|
23
|
+
if (i !== b.length) {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
while (i--) {
|
|
27
|
+
if (!schemaLooseEqual(a[i], b[i])) {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
for (const k in a) {
|
|
34
|
+
if (!schemaLooseEqual(a[k], b[k], k)) {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
for (const k in b) {
|
|
39
|
+
if (k in a) {
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
if (!schemaLooseEqual(a[k], b[k], k)) {
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return true;
|
|
48
|
+
};
|
|
49
|
+
export const parseSchema = (strictSchema) => {
|
|
50
|
+
let parsedSchema = strictSchema;
|
|
51
|
+
if (strictSchema.props) {
|
|
52
|
+
parsedSchema = {
|
|
53
|
+
...strictSchema,
|
|
54
|
+
types: { ...parsedSchema.types },
|
|
55
|
+
};
|
|
56
|
+
const props = { ...strictSchema.props };
|
|
57
|
+
for (const key in props) {
|
|
58
|
+
const prop = props[key];
|
|
59
|
+
const propType = getPropType(prop);
|
|
60
|
+
let refProp;
|
|
61
|
+
if (propType === 'reference') {
|
|
62
|
+
refProp = prop;
|
|
63
|
+
}
|
|
64
|
+
else if (propType === 'references') {
|
|
65
|
+
refProp = prop.items;
|
|
66
|
+
}
|
|
67
|
+
if (refProp) {
|
|
68
|
+
const type = parsedSchema.types[refProp.ref];
|
|
69
|
+
const inverseKey = '_' + key;
|
|
70
|
+
parsedSchema.types[refProp.ref] = {
|
|
71
|
+
...type,
|
|
72
|
+
props: {
|
|
73
|
+
...type.props,
|
|
74
|
+
[inverseKey]: {
|
|
75
|
+
items: {
|
|
76
|
+
ref: '_root',
|
|
77
|
+
prop: key,
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
refProp.prop = inverseKey;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
// @ts-ignore This creates an internal type to use for root props
|
|
86
|
+
parsedSchema.types._root = {
|
|
87
|
+
id: 1,
|
|
88
|
+
props,
|
|
89
|
+
};
|
|
90
|
+
delete parsedSchema.props;
|
|
91
|
+
}
|
|
92
|
+
return parsedSchema;
|
|
93
|
+
};
|
|
94
|
+
//# sourceMappingURL=schema.js.map
|
package/dist/src/server/index.js
CHANGED
|
@@ -2,7 +2,7 @@ import native from '../native.js';
|
|
|
2
2
|
import createDbHash from './dbHash.js';
|
|
3
3
|
import { rm, writeFile } from 'node:fs/promises';
|
|
4
4
|
import { dirname, join } from 'node:path';
|
|
5
|
-
import {
|
|
5
|
+
import { langCodesMap } from '@based/schema';
|
|
6
6
|
import { updateTypeDefs, schemaToSelvaBuffer, } from '@based/schema/def';
|
|
7
7
|
import { start } from './start.js';
|
|
8
8
|
import { initCsmt, makeCsmtKey, makeCsmtKeyFromNodeId, } from './tree.js';
|
|
@@ -11,10 +11,11 @@ import { Worker, MessageChannel } from 'node:worker_threads';
|
|
|
11
11
|
import { fileURLToPath } from 'node:url';
|
|
12
12
|
import { setTimeout } from 'node:timers/promises';
|
|
13
13
|
import { migrate } from './migrate/index.js';
|
|
14
|
-
import { debugServer
|
|
14
|
+
import { debugServer } from '../utils.js';
|
|
15
15
|
import { readUint16, readUint32, readUint64, writeUint64 } from '@saulx/utils';
|
|
16
|
-
import { hash } from '@saulx/hash';
|
|
17
16
|
import { QueryType } from '../client/query/types.js';
|
|
17
|
+
import { parseSchema, schemaLooseEqual } from '../schema.js';
|
|
18
|
+
import { hash } from '@saulx/hash';
|
|
18
19
|
export const SCHEMA_FILE = 'schema.json';
|
|
19
20
|
export const WRITELOG_FILE = 'writelog.json';
|
|
20
21
|
const __filename = fileURLToPath(import.meta.url);
|
|
@@ -281,64 +282,26 @@ export class DbServer {
|
|
|
281
282
|
return sortIndex;
|
|
282
283
|
}
|
|
283
284
|
setSchema(strictSchema, fromStart = false, transformFns) {
|
|
285
|
+
const parsedSchema = parseSchema(strictSchema);
|
|
284
286
|
if (!fromStart && Object.keys(this.schema.types).length > 0) {
|
|
285
|
-
if (schemaLooseEqual(
|
|
287
|
+
if (schemaLooseEqual(parsedSchema, this.schema)) {
|
|
286
288
|
return this.schema;
|
|
287
289
|
}
|
|
288
290
|
return this.migrateSchema(strictSchema, transformFns);
|
|
289
291
|
}
|
|
290
|
-
const { lastId } = this.schema;
|
|
291
292
|
this.schema = {
|
|
292
|
-
lastId,
|
|
293
|
-
...
|
|
293
|
+
lastId: this.schema.lastId,
|
|
294
|
+
...parsedSchema,
|
|
294
295
|
};
|
|
295
|
-
if (strictSchema.props) {
|
|
296
|
-
this.schema.types ??= {};
|
|
297
|
-
const props = { ...strictSchema.props };
|
|
298
|
-
for (const key in props) {
|
|
299
|
-
const prop = props[key];
|
|
300
|
-
const propType = getPropType(prop);
|
|
301
|
-
let refProp;
|
|
302
|
-
if (propType === 'reference') {
|
|
303
|
-
refProp = prop;
|
|
304
|
-
}
|
|
305
|
-
else if (propType === 'references') {
|
|
306
|
-
refProp = prop.items;
|
|
307
|
-
}
|
|
308
|
-
if (refProp) {
|
|
309
|
-
const type = this.schema.types[refProp.ref];
|
|
310
|
-
const inverseKey = '_' + key;
|
|
311
|
-
this.schema.types[refProp.ref] = {
|
|
312
|
-
...type,
|
|
313
|
-
props: {
|
|
314
|
-
...type.props,
|
|
315
|
-
[inverseKey]: {
|
|
316
|
-
items: {
|
|
317
|
-
ref: '_root',
|
|
318
|
-
prop: key,
|
|
319
|
-
},
|
|
320
|
-
},
|
|
321
|
-
},
|
|
322
|
-
};
|
|
323
|
-
refProp.prop = inverseKey;
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
// @ts-ignore This creates an internal type to use for root props
|
|
327
|
-
this.schema.types._root = {
|
|
328
|
-
id: 1,
|
|
329
|
-
props,
|
|
330
|
-
};
|
|
331
|
-
delete this.schema.props;
|
|
332
|
-
}
|
|
333
296
|
for (const field in this.schema.types) {
|
|
334
297
|
if (!('id' in this.schema.types[field])) {
|
|
335
298
|
this.schema.lastId++;
|
|
336
299
|
this.schema.types[field].id = this.schema.lastId;
|
|
337
300
|
}
|
|
338
301
|
}
|
|
302
|
+
const { hash: _, ...rest } = this.schema;
|
|
303
|
+
this.schema.hash = hash(rest);
|
|
339
304
|
updateTypeDefs(this.schema, this.schemaTypesParsed, this.schemaTypesParsedById);
|
|
340
|
-
const { hash: _, ...schemaWithoutHash } = this.schema;
|
|
341
|
-
this.schema.hash = hash(schemaWithoutHash);
|
|
342
305
|
if (!fromStart) {
|
|
343
306
|
writeFile(join(this.fileSystemPath, SCHEMA_FILE), JSON.stringify(this.schema)).catch((err) => console.error('!!!', SCHEMA_FILE, err));
|
|
344
307
|
let types = Object.keys(this.schemaTypesParsed);
|
|
@@ -354,7 +317,7 @@ export class DbServer {
|
|
|
354
317
|
console.error('Cannot update schema on selva', type.type, err, s[i]);
|
|
355
318
|
}
|
|
356
319
|
}
|
|
357
|
-
if (strictSchema.props) {
|
|
320
|
+
if (strictSchema.props || strictSchema.types?._root) {
|
|
358
321
|
// insert a root node
|
|
359
322
|
// TODO fix this add it in schema at least
|
|
360
323
|
const data = [2, 1, 0, 0, 0, 1, 9, 1, 0, 0, 0, 7, 1, 0, 1];
|
package/dist/src/server/start.js
CHANGED
|
@@ -2,13 +2,12 @@ import { DbWorker, SCHEMA_FILE, WRITELOG_FILE } from './index.js';
|
|
|
2
2
|
import native from '../native.js';
|
|
3
3
|
import { rm, mkdir, readFile } from 'node:fs/promises';
|
|
4
4
|
import { join } from 'node:path';
|
|
5
|
-
import {
|
|
6
|
-
import { foreachBlock, initCsmt, makeCsmtKey } from './tree.js';
|
|
5
|
+
import { destructureCsmtKey, foreachBlock, initCsmt, makeCsmtKey, specialBlock } from './tree.js';
|
|
7
6
|
import { availableParallelism } from 'node:os';
|
|
8
7
|
import exitHook from 'exit-hook';
|
|
9
8
|
import { save } from './save.js';
|
|
10
9
|
import { DEFAULT_BLOCK_CAPACITY } from '@based/schema/def';
|
|
11
|
-
import { bufToHex
|
|
10
|
+
import { bufToHex } from '@saulx/utils';
|
|
12
11
|
export async function start(db, opts) {
|
|
13
12
|
const path = db.fileSystemPath;
|
|
14
13
|
const noop = () => { };
|
|
@@ -74,10 +73,27 @@ export async function start(db, opts) {
|
|
|
74
73
|
}, true);
|
|
75
74
|
}
|
|
76
75
|
if (writelog?.hash) {
|
|
77
|
-
|
|
78
|
-
const
|
|
79
|
-
|
|
80
|
-
|
|
76
|
+
// FIXME FDN-1301
|
|
77
|
+
//const oldHash = hexToBuf(writelog.hash)
|
|
78
|
+
//const newHash = db.merkleTree.getRoot()?.hash
|
|
79
|
+
//if (!hashEq(oldHash, newHash)) {
|
|
80
|
+
// console.error(
|
|
81
|
+
// `WARN: CSMT hash mismatch. expected: ${writelog.hash} actual: ${bufToHex(newHash)}`,
|
|
82
|
+
// )
|
|
83
|
+
//}
|
|
84
|
+
const oldHashSet = new Set();
|
|
85
|
+
const newHashSet = new Set();
|
|
86
|
+
for (let k in writelog.rangeDumps)
|
|
87
|
+
writelog.rangeDumps[k].forEach(({ hash }) => oldHashSet.add(hash));
|
|
88
|
+
db.merkleTree.visitLeafNodes(({ key, hash }) => {
|
|
89
|
+
const [_typeId, start] = destructureCsmtKey(key);
|
|
90
|
+
if (start == specialBlock)
|
|
91
|
+
return; // skip the type specialBlock
|
|
92
|
+
newHashSet.add(bufToHex(hash));
|
|
93
|
+
});
|
|
94
|
+
const setEq = (a, b) => a.size === b.size && [...a].every(value => b.has(value));
|
|
95
|
+
if (!setEq(oldHashSet, newHashSet)) {
|
|
96
|
+
console.error(`WARN: CSMT hash mismatch.`);
|
|
81
97
|
}
|
|
82
98
|
}
|
|
83
99
|
// start workers
|
package/dist/src/utils.d.ts
CHANGED
|
@@ -3,4 +3,3 @@ export declare const DECODER: TextDecoder;
|
|
|
3
3
|
export declare const ENCODER: TextEncoder;
|
|
4
4
|
export declare const debugMode: (target: any, getInfo?: any) => void;
|
|
5
5
|
export declare const debugServer: (server: DbServer) => void;
|
|
6
|
-
export declare const schemaLooseEqual: (a: any, b: any, key?: string) => boolean;
|
package/dist/src/utils.js
CHANGED
|
@@ -43,51 +43,4 @@ export const debugMode = (target, getInfo = null) => {
|
|
|
43
43
|
}
|
|
44
44
|
};
|
|
45
45
|
export const debugServer = (server) => debugMode(server, () => `p: ${server.processingQueries} m: ${server.modifyQueue.length} q: ${server.queryQueue.size}`);
|
|
46
|
-
const exclude = new Set(['id', 'lastId', 'hash']);
|
|
47
|
-
export const schemaLooseEqual = (a, b, key) => {
|
|
48
|
-
if (a === b) {
|
|
49
|
-
return true;
|
|
50
|
-
}
|
|
51
|
-
const typeofA = typeof a;
|
|
52
|
-
if (typeofA !== 'object') {
|
|
53
|
-
return exclude.has(key);
|
|
54
|
-
}
|
|
55
|
-
const typeofB = typeof b;
|
|
56
|
-
if (typeofA !== typeofB) {
|
|
57
|
-
return exclude.has(key);
|
|
58
|
-
}
|
|
59
|
-
if (a === null || b === null) {
|
|
60
|
-
return false;
|
|
61
|
-
}
|
|
62
|
-
if (a.constructor !== b.constructor) {
|
|
63
|
-
return false;
|
|
64
|
-
}
|
|
65
|
-
if (Array.isArray(a)) {
|
|
66
|
-
let i = a.length;
|
|
67
|
-
if (i !== b.length) {
|
|
68
|
-
return false;
|
|
69
|
-
}
|
|
70
|
-
while (i--) {
|
|
71
|
-
if (!schemaLooseEqual(a[i], b[i])) {
|
|
72
|
-
return false;
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
else {
|
|
77
|
-
for (const k in a) {
|
|
78
|
-
if (!schemaLooseEqual(a[k], b[k], k)) {
|
|
79
|
-
return false;
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
for (const k in b) {
|
|
83
|
-
if (k in a) {
|
|
84
|
-
continue;
|
|
85
|
-
}
|
|
86
|
-
if (!schemaLooseEqual(a[k], b[k], k)) {
|
|
87
|
-
return false;
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
return true;
|
|
92
|
-
};
|
|
93
46
|
//# sourceMappingURL=utils.js.map
|