@based/db 0.0.51 → 0.0.53
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/libdeflate.dylib +0 -0
- package/dist/lib/darwin_aarch64/libjemalloc_selva.2.dylib +0 -0
- 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/flushModify.d.ts +1 -0
- package/dist/src/client/flushModify.js +8 -0
- package/dist/src/client/index.d.ts +8 -32
- package/dist/src/client/index.js +22 -84
- package/dist/src/client/modify/ModifyRes.js +4 -1
- package/dist/src/client/modify/references/reference.js +3 -0
- package/dist/src/client/query/BasedDbQuery.d.ts +2 -3
- package/dist/src/client/query/BasedDbQuery.js +150 -139
- package/dist/src/client/query/aggregates/aggregation.js +3 -0
- package/dist/src/client/query/registerQuery.js +16 -0
- package/dist/src/client/query/subscription/index.d.ts +1 -1
- package/dist/src/client/query/subscription/index.js +32 -9
- package/dist/src/client/setLocalClientSchema.d.ts +3 -0
- package/dist/src/client/setLocalClientSchema.js +30 -0
- package/dist/src/hooks.d.ts +9 -8
- package/dist/src/hooks.js +10 -2
- package/dist/src/index.d.ts +6 -7
- package/dist/src/index.js +24 -41
- package/dist/src/schema.d.ts +5 -2
- package/dist/src/schema.js +1 -95
- package/dist/src/server/DbWorker.d.ts +12 -0
- package/dist/src/server/DbWorker.js +42 -0
- package/dist/src/server/index.d.ts +6 -38
- package/dist/src/server/index.js +39 -146
- package/dist/src/server/migrate/index.d.ts +2 -2
- package/dist/src/server/migrate/index.js +63 -60
- package/dist/src/server/migrate/types.d.ts +4 -0
- package/dist/src/server/migrate/types.js +6 -0
- package/dist/src/server/migrate/utils.d.ts +3 -0
- package/dist/src/server/migrate/utils.js +16 -0
- package/dist/src/server/migrate/worker.js +16 -17
- package/dist/src/server/resizeModifyDirtyRanges.d.ts +2 -0
- package/dist/src/server/resizeModifyDirtyRanges.js +17 -0
- package/dist/src/server/save.js +1 -2
- package/dist/src/server/schema.d.ts +7 -0
- package/dist/src/server/schema.js +111 -0
- package/dist/src/server/start.js +10 -4
- package/dist/src/shared/DbBase.d.ts +13 -0
- package/dist/src/shared/DbBase.js +7 -0
- package/dist/src/shared/Emitter.d.ts +17 -0
- package/dist/src/shared/Emitter.js +66 -0
- package/dist/src/types.d.ts +3 -0
- package/dist/src/types.js +4 -0
- package/package.json +2 -2
package/dist/src/index.js
CHANGED
|
@@ -5,9 +5,10 @@ import { DbClient } from './client/index.js';
|
|
|
5
5
|
import { wait } from '@saulx/utils';
|
|
6
6
|
import { debugMode, debugServer } from './utils.js';
|
|
7
7
|
import { getDefaultHooks } from './hooks.js';
|
|
8
|
+
import { Emitter } from './shared/Emitter.js';
|
|
8
9
|
export * from './client/modify/modify.js';
|
|
9
10
|
export { compress, decompress };
|
|
10
|
-
export { ModifyCtx };
|
|
11
|
+
export { ModifyCtx };
|
|
11
12
|
export { DbClient, DbServer };
|
|
12
13
|
export { xxHash64 } from './client/xxHash64.js';
|
|
13
14
|
export { crc32 } from './client/crc32.js';
|
|
@@ -18,14 +19,27 @@ export * from './client/query/query.js';
|
|
|
18
19
|
export * from './client/query/BasedDbQuery.js';
|
|
19
20
|
export * from './client/query/BasedIterable.js';
|
|
20
21
|
export * from './server/save.js';
|
|
22
|
+
export * from './hooks.js';
|
|
21
23
|
export { getDefaultHooks };
|
|
22
|
-
export class BasedDb {
|
|
24
|
+
export class BasedDb extends Emitter {
|
|
23
25
|
client;
|
|
24
26
|
server;
|
|
25
27
|
fileSystemPath;
|
|
26
28
|
maxModifySize;
|
|
27
29
|
constructor(opts) {
|
|
28
|
-
|
|
30
|
+
super();
|
|
31
|
+
this.fileSystemPath = opts.path;
|
|
32
|
+
this.maxModifySize = opts.maxModifySize;
|
|
33
|
+
const server = new DbServer({
|
|
34
|
+
path: opts.path,
|
|
35
|
+
saveIntervalInSeconds: opts.saveIntervalInSeconds,
|
|
36
|
+
});
|
|
37
|
+
const client = new DbClient({
|
|
38
|
+
maxModifySize: opts.maxModifySize,
|
|
39
|
+
hooks: getDefaultHooks(server),
|
|
40
|
+
});
|
|
41
|
+
this.server = server;
|
|
42
|
+
this.client = client;
|
|
29
43
|
if (opts.debug) {
|
|
30
44
|
if (opts.debug === 'client') {
|
|
31
45
|
debugServer(this.server);
|
|
@@ -38,25 +52,6 @@ export class BasedDb {
|
|
|
38
52
|
}
|
|
39
53
|
}
|
|
40
54
|
}
|
|
41
|
-
#init({ path, maxModifySize, saveIntervalInSeconds, }) {
|
|
42
|
-
this.fileSystemPath = path;
|
|
43
|
-
this.maxModifySize = maxModifySize;
|
|
44
|
-
const server = new DbServer({
|
|
45
|
-
path,
|
|
46
|
-
maxModifySize,
|
|
47
|
-
saveIntervalInSeconds,
|
|
48
|
-
onSchemaChange(schema) {
|
|
49
|
-
client.putLocalSchema(schema);
|
|
50
|
-
},
|
|
51
|
-
});
|
|
52
|
-
const client = new DbClient({
|
|
53
|
-
maxModifySize,
|
|
54
|
-
hooks: getDefaultHooks(server),
|
|
55
|
-
});
|
|
56
|
-
this.server = server;
|
|
57
|
-
this.client = client;
|
|
58
|
-
}
|
|
59
|
-
// client
|
|
60
55
|
create = function () {
|
|
61
56
|
return this.client.create.apply(this.client, arguments);
|
|
62
57
|
};
|
|
@@ -78,6 +73,9 @@ export class BasedDb {
|
|
|
78
73
|
query = function () {
|
|
79
74
|
return this.client.query.apply(this.client, arguments);
|
|
80
75
|
};
|
|
76
|
+
schemaIsSet = function () {
|
|
77
|
+
return this.client.schemaIsSet.apply(this.client, arguments);
|
|
78
|
+
};
|
|
81
79
|
setSchema = function () {
|
|
82
80
|
return this.client.setSchema.apply(this.client, arguments);
|
|
83
81
|
};
|
|
@@ -101,15 +99,9 @@ export class BasedDb {
|
|
|
101
99
|
await this.isModified();
|
|
102
100
|
return this.server.save.apply(this.server, arguments);
|
|
103
101
|
};
|
|
104
|
-
migrateSchema = function () {
|
|
105
|
-
return this.server.migrateSchema.apply(this.server, arguments);
|
|
106
|
-
};
|
|
107
102
|
isModified = function () {
|
|
108
103
|
return this.client.isModified.apply(this.client, arguments);
|
|
109
104
|
};
|
|
110
|
-
schemaIsSet = function () {
|
|
111
|
-
return this.client.schemaIsSet.apply(this.client, arguments);
|
|
112
|
-
};
|
|
113
105
|
async destroy() {
|
|
114
106
|
await this.isModified();
|
|
115
107
|
// Tmp fix: Gives node time to GC existing buffers else it can incorrectly re-asign to mem
|
|
@@ -118,20 +110,11 @@ export class BasedDb {
|
|
|
118
110
|
this.client.destroy();
|
|
119
111
|
await this.server.destroy();
|
|
120
112
|
}
|
|
121
|
-
|
|
122
|
-
const opts = {
|
|
123
|
-
maxModifySize: this.maxModifySize,
|
|
124
|
-
path: this.fileSystemPath,
|
|
125
|
-
};
|
|
126
|
-
await this.destroy();
|
|
127
|
-
this.#init(opts);
|
|
128
|
-
await this.start({ clean: true });
|
|
129
|
-
}
|
|
130
|
-
on = function () {
|
|
113
|
+
on() {
|
|
131
114
|
return this.client.on.apply(this.client, arguments);
|
|
132
|
-
}
|
|
133
|
-
off
|
|
115
|
+
}
|
|
116
|
+
off() {
|
|
134
117
|
return this.client.on.apply(this.client, arguments);
|
|
135
|
-
}
|
|
118
|
+
}
|
|
136
119
|
}
|
|
137
120
|
//# sourceMappingURL=index.js.map
|
package/dist/src/schema.d.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
1
|
import { StrictSchema } from '@based/schema';
|
|
2
|
-
export
|
|
3
|
-
|
|
2
|
+
export type DbSchema = StrictSchema & {
|
|
3
|
+
lastId: number;
|
|
4
|
+
hash: number;
|
|
5
|
+
};
|
|
6
|
+
export type SchemaChecksum = number;
|
package/dist/src/schema.js
CHANGED
|
@@ -1,96 +1,2 @@
|
|
|
1
|
-
|
|
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
|
-
prop.items = refProp;
|
|
67
|
-
}
|
|
68
|
-
if (refProp) {
|
|
69
|
-
const type = parsedSchema.types[refProp.ref];
|
|
70
|
-
const inverseKey = '_' + key;
|
|
71
|
-
parsedSchema.types[refProp.ref] = {
|
|
72
|
-
...type,
|
|
73
|
-
props: {
|
|
74
|
-
...type.props,
|
|
75
|
-
[inverseKey]: {
|
|
76
|
-
items: {
|
|
77
|
-
ref: '_root',
|
|
78
|
-
prop: key,
|
|
79
|
-
},
|
|
80
|
-
},
|
|
81
|
-
},
|
|
82
|
-
};
|
|
83
|
-
refProp.prop = inverseKey;
|
|
84
|
-
}
|
|
85
|
-
props[key] = prop;
|
|
86
|
-
}
|
|
87
|
-
// @ts-ignore This creates an internal type to use for root props
|
|
88
|
-
parsedSchema.types._root = {
|
|
89
|
-
id: 1,
|
|
90
|
-
props,
|
|
91
|
-
};
|
|
92
|
-
delete parsedSchema.props;
|
|
93
|
-
}
|
|
94
|
-
return parsedSchema;
|
|
95
|
-
};
|
|
1
|
+
export {};
|
|
96
2
|
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Worker, MessagePort } from 'node:worker_threads';
|
|
2
|
+
import { DbServer } from './index.js';
|
|
3
|
+
export declare class DbWorker {
|
|
4
|
+
constructor(address: BigInt, db: DbServer);
|
|
5
|
+
db: DbServer;
|
|
6
|
+
channel: MessagePort;
|
|
7
|
+
worker: Worker;
|
|
8
|
+
resolvers: any[];
|
|
9
|
+
callback: (resolve: any) => void;
|
|
10
|
+
updateCtx(address: BigInt): Promise<void>;
|
|
11
|
+
getQueryBuf(buf: Uint8Array): Promise<Uint8Array>;
|
|
12
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { MessageChannel, Worker } from 'node:worker_threads';
|
|
2
|
+
import { fileURLToPath } from 'node:url';
|
|
3
|
+
import { dirname, join } from 'node:path';
|
|
4
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
5
|
+
const __dirname = dirname(__filename);
|
|
6
|
+
const workerPath = join(__dirname, 'worker.js');
|
|
7
|
+
export class DbWorker {
|
|
8
|
+
constructor(address, db) {
|
|
9
|
+
const { port1, port2 } = new MessageChannel();
|
|
10
|
+
this.db = db;
|
|
11
|
+
this.channel = port1;
|
|
12
|
+
this.worker = new Worker(workerPath, {
|
|
13
|
+
workerData: {
|
|
14
|
+
isDbWorker: true,
|
|
15
|
+
channel: port2,
|
|
16
|
+
address,
|
|
17
|
+
},
|
|
18
|
+
transferList: [port2],
|
|
19
|
+
});
|
|
20
|
+
port1.on('message', (buf) => {
|
|
21
|
+
this.resolvers.shift()(new Uint8Array(buf));
|
|
22
|
+
this.db.onQueryEnd();
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
db;
|
|
26
|
+
channel;
|
|
27
|
+
worker;
|
|
28
|
+
resolvers = [];
|
|
29
|
+
callback = (resolve) => {
|
|
30
|
+
this.db.processingQueries++;
|
|
31
|
+
this.resolvers.push(resolve);
|
|
32
|
+
};
|
|
33
|
+
updateCtx(address) {
|
|
34
|
+
this.channel.postMessage(address);
|
|
35
|
+
return new Promise(this.callback);
|
|
36
|
+
}
|
|
37
|
+
getQueryBuf(buf) {
|
|
38
|
+
this.channel.postMessage(buf);
|
|
39
|
+
return new Promise(this.callback);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=DbWorker.js.map
|
|
@@ -1,42 +1,23 @@
|
|
|
1
1
|
import { LangName, StrictSchema } from '@based/schema';
|
|
2
|
-
import { SchemaTypesParsed, SchemaTypesParsedById } from '@based/schema/def';
|
|
3
2
|
import { createTree } from './csmt/index.js';
|
|
4
3
|
import { CsmtNodeRange } from './tree.js';
|
|
5
|
-
import { Worker, MessagePort } from 'node:worker_threads';
|
|
6
4
|
import { TransformFns } from './migrate/index.js';
|
|
7
5
|
import exitHook from 'exit-hook';
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
import { SchemaChecksum } from '../schema.js';
|
|
7
|
+
import { DbWorker } from './DbWorker.js';
|
|
8
|
+
import { DbShared } from '../shared/DbBase.js';
|
|
10
9
|
declare class SortIndex {
|
|
11
10
|
constructor(buf: Uint8Array, dbCtxExternal: any);
|
|
12
11
|
buf: Uint8Array;
|
|
13
12
|
idx: any;
|
|
14
13
|
cnt: number;
|
|
15
14
|
}
|
|
16
|
-
export declare class
|
|
17
|
-
constructor(address: BigInt, db: DbServer);
|
|
18
|
-
db: DbServer;
|
|
19
|
-
channel: MessagePort;
|
|
20
|
-
worker: Worker;
|
|
21
|
-
resolvers: any[];
|
|
22
|
-
callback: (resolve: any) => void;
|
|
23
|
-
updateCtx(address: BigInt): Promise<void>;
|
|
24
|
-
getQueryBuf(buf: Uint8Array): Promise<Uint8Array>;
|
|
25
|
-
}
|
|
26
|
-
type OnSchemaChange = (schema: DbServer['schema']) => void;
|
|
27
|
-
export declare class DbServer {
|
|
15
|
+
export declare class DbServer extends DbShared {
|
|
28
16
|
#private;
|
|
29
17
|
modifyDirtyRanges: Float64Array;
|
|
30
18
|
dbCtxExternal: any;
|
|
31
|
-
schema: StrictSchema & {
|
|
32
|
-
lastId: number;
|
|
33
|
-
hash?: number;
|
|
34
|
-
};
|
|
35
19
|
migrating: number;
|
|
36
|
-
schemaTypesParsed: SchemaTypesParsed;
|
|
37
|
-
schemaTypesParsedById: SchemaTypesParsedById;
|
|
38
20
|
fileSystemPath: string;
|
|
39
|
-
maxModifySize: number;
|
|
40
21
|
merkleTree: ReturnType<typeof createTree<CsmtNodeRange>>;
|
|
41
22
|
dirtyRanges: Set<number>;
|
|
42
23
|
csmtHashFun: {
|
|
@@ -50,14 +31,11 @@ export declare class DbServer {
|
|
|
50
31
|
modifyQueue: Uint8Array[];
|
|
51
32
|
queryQueue: Map<Function, Uint8Array>;
|
|
52
33
|
stopped: boolean;
|
|
53
|
-
onSchemaChange: OnSchemaChange;
|
|
54
34
|
unlistenExit: ReturnType<typeof exitHook>;
|
|
55
35
|
saveIntervalInSeconds?: number;
|
|
56
36
|
saveInterval?: NodeJS.Timeout;
|
|
57
|
-
constructor({ path,
|
|
37
|
+
constructor({ path, debug, saveIntervalInSeconds, }: {
|
|
58
38
|
path: string;
|
|
59
|
-
maxModifySize?: number;
|
|
60
|
-
onSchemaChange?: OnSchemaChange;
|
|
61
39
|
debug?: boolean;
|
|
62
40
|
saveIntervalInSeconds?: number;
|
|
63
41
|
});
|
|
@@ -87,18 +65,8 @@ export declare class DbServer {
|
|
|
87
65
|
createSortIndex(type: string, field: string, lang?: LangName): SortIndex;
|
|
88
66
|
destroySortIndex(type: string, field: string, lang?: LangName): any;
|
|
89
67
|
getSortIndex(typeId: number, field: number, start: number, lang: number): SortIndex;
|
|
90
|
-
migrateSchema(schema: StrictSchema, transform?: Record<string, (node: Record<string, any>) => Record<string, any> | [string, Record<string, any>]>): Promise<StrictSchema & {
|
|
91
|
-
lastId: number;
|
|
92
|
-
hash?: number;
|
|
93
|
-
}>;
|
|
94
68
|
createSortIndexBuffer(typeId: number, field: number, start: number, lang: number): SortIndex;
|
|
95
|
-
setSchema(strictSchema: StrictSchema,
|
|
96
|
-
lastId: number;
|
|
97
|
-
hash?: number;
|
|
98
|
-
}) | Promise<StrictSchema & {
|
|
99
|
-
lastId: number;
|
|
100
|
-
hash?: number;
|
|
101
|
-
}>;
|
|
69
|
+
setSchema(strictSchema: StrictSchema, transformFns?: TransformFns): Promise<SchemaChecksum>;
|
|
102
70
|
modify(buf: Uint8Array): Record<number, number> | null;
|
|
103
71
|
addToQueryQueue(resolve: any, buf: any): void;
|
|
104
72
|
getQueryBuf(buf: Uint8Array, fromQueue?: boolean): Promise<Uint8Array>;
|
package/dist/src/server/index.js
CHANGED
|
@@ -1,26 +1,19 @@
|
|
|
1
1
|
import native from '../native.js';
|
|
2
2
|
import createDbHash from './dbHash.js';
|
|
3
|
-
import { rm
|
|
4
|
-
import { dirname, join } from 'node:path';
|
|
3
|
+
import { rm } from 'node:fs/promises';
|
|
5
4
|
import { langCodesMap } from '@based/schema';
|
|
6
|
-
import { updateTypeDefs, schemaToSelvaBuffer, } from '@based/schema/def';
|
|
7
5
|
import { start } from './start.js';
|
|
8
|
-
import {
|
|
6
|
+
import { makeCsmtKeyFromNodeId } from './tree.js';
|
|
9
7
|
import { save } from './save.js';
|
|
10
|
-
import { Worker, MessageChannel } from 'node:worker_threads';
|
|
11
|
-
import { fileURLToPath } from 'node:url';
|
|
12
8
|
import { setTimeout } from 'node:timers/promises';
|
|
13
9
|
import { migrate } from './migrate/index.js';
|
|
14
10
|
import { debugServer } from '../utils.js';
|
|
15
|
-
import { readUint16, readUint32, readUint64
|
|
11
|
+
import { readUint16, readUint32, readUint64 } from '@saulx/utils';
|
|
16
12
|
import { QueryType } from '../client/query/types.js';
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
22
|
-
const __dirname = dirname(__filename);
|
|
23
|
-
const workerPath = join(__dirname, 'worker.js');
|
|
13
|
+
import { strictSchemaToDbSchema } from './schema.js';
|
|
14
|
+
import { DbShared } from '../shared/DbBase.js';
|
|
15
|
+
import { setNativeSchema, setSchemaOnServer, writeSchemaFile, } from './schema.js';
|
|
16
|
+
import { resizeModifyDirtyRanges } from './resizeModifyDirtyRanges.js';
|
|
24
17
|
const emptyUint8Array = new Uint8Array(0);
|
|
25
18
|
class SortIndex {
|
|
26
19
|
constructor(buf, dbCtxExternal) {
|
|
@@ -31,53 +24,11 @@ class SortIndex {
|
|
|
31
24
|
idx;
|
|
32
25
|
cnt = 0;
|
|
33
26
|
}
|
|
34
|
-
export class
|
|
35
|
-
constructor(address, db) {
|
|
36
|
-
const { port1, port2 } = new MessageChannel();
|
|
37
|
-
this.db = db;
|
|
38
|
-
this.channel = port1;
|
|
39
|
-
this.worker = new Worker(workerPath, {
|
|
40
|
-
workerData: {
|
|
41
|
-
isDbWorker: true,
|
|
42
|
-
channel: port2,
|
|
43
|
-
address,
|
|
44
|
-
},
|
|
45
|
-
transferList: [port2],
|
|
46
|
-
});
|
|
47
|
-
port1.on('message', (buf) => {
|
|
48
|
-
this.resolvers.shift()(new Uint8Array(buf));
|
|
49
|
-
this.db.onQueryEnd();
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
db;
|
|
53
|
-
channel;
|
|
54
|
-
worker;
|
|
55
|
-
resolvers = [];
|
|
56
|
-
callback = (resolve) => {
|
|
57
|
-
this.db.processingQueries++;
|
|
58
|
-
this.resolvers.push(resolve);
|
|
59
|
-
};
|
|
60
|
-
updateCtx(address) {
|
|
61
|
-
this.channel.postMessage(address);
|
|
62
|
-
return new Promise(this.callback);
|
|
63
|
-
}
|
|
64
|
-
getQueryBuf(buf) {
|
|
65
|
-
this.channel.postMessage(buf);
|
|
66
|
-
return new Promise(this.callback);
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
export class DbServer {
|
|
27
|
+
export class DbServer extends DbShared {
|
|
70
28
|
modifyDirtyRanges;
|
|
71
29
|
dbCtxExternal; // pointer to zig dbCtx
|
|
72
|
-
schema = {
|
|
73
|
-
lastId: 1, // we reserve one for root props
|
|
74
|
-
types: {},
|
|
75
|
-
};
|
|
76
30
|
migrating = null;
|
|
77
|
-
schemaTypesParsed = {};
|
|
78
|
-
schemaTypesParsedById = {};
|
|
79
31
|
fileSystemPath;
|
|
80
|
-
maxModifySize;
|
|
81
32
|
merkleTree;
|
|
82
33
|
dirtyRanges = new Set();
|
|
83
34
|
csmtHashFun = createDbHash();
|
|
@@ -87,36 +38,18 @@ export class DbServer {
|
|
|
87
38
|
modifyQueue = [];
|
|
88
39
|
queryQueue = new Map();
|
|
89
40
|
stopped; // = true does not work
|
|
90
|
-
onSchemaChange;
|
|
91
41
|
unlistenExit;
|
|
92
42
|
saveIntervalInSeconds;
|
|
93
43
|
saveInterval;
|
|
94
|
-
constructor({ path,
|
|
95
|
-
|
|
44
|
+
constructor({ path, debug, saveIntervalInSeconds, }) {
|
|
45
|
+
super();
|
|
96
46
|
this.fileSystemPath = path;
|
|
97
47
|
this.sortIndexes = {};
|
|
98
|
-
this.onSchemaChange = onSchemaChange;
|
|
99
48
|
this.saveIntervalInSeconds = saveIntervalInSeconds;
|
|
100
49
|
if (debug) {
|
|
101
50
|
debugServer(this);
|
|
102
51
|
}
|
|
103
52
|
}
|
|
104
|
-
#resizeModifyDirtyRanges() {
|
|
105
|
-
let maxNrChanges = 0;
|
|
106
|
-
for (const typeId in this.schemaTypesParsedById) {
|
|
107
|
-
const def = this.schemaTypesParsedById[typeId];
|
|
108
|
-
const lastId = def.lastId;
|
|
109
|
-
const blockCapacity = def.blockCapacity;
|
|
110
|
-
const tmp = lastId - +!(lastId % def.blockCapacity);
|
|
111
|
-
const lastBlock = Math.ceil((((tmp / blockCapacity) | 0) * blockCapacity + 1) / blockCapacity);
|
|
112
|
-
maxNrChanges += lastBlock;
|
|
113
|
-
}
|
|
114
|
-
if (!this.modifyDirtyRanges ||
|
|
115
|
-
this.modifyDirtyRanges.length < maxNrChanges) {
|
|
116
|
-
const min = Math.max(maxNrChanges * 1.2, 1024) | 0;
|
|
117
|
-
this.modifyDirtyRanges = new Float64Array(min);
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
53
|
start(opts) {
|
|
121
54
|
this.stopped = false;
|
|
122
55
|
return start(this, opts);
|
|
@@ -238,9 +171,6 @@ export class DbServer {
|
|
|
238
171
|
}
|
|
239
172
|
return fields[lang];
|
|
240
173
|
}
|
|
241
|
-
migrateSchema(schema, transform) {
|
|
242
|
-
return migrate(this, schema, transform);
|
|
243
|
-
}
|
|
244
174
|
createSortIndexBuffer(typeId, field, start, lang) {
|
|
245
175
|
const buf = new Uint8Array(9);
|
|
246
176
|
buf[0] = typeId;
|
|
@@ -281,71 +211,34 @@ export class DbServer {
|
|
|
281
211
|
fields[start][lang] = sortIndex;
|
|
282
212
|
return sortIndex;
|
|
283
213
|
}
|
|
284
|
-
setSchema(strictSchema,
|
|
285
|
-
const
|
|
286
|
-
if (
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
return this.schema;
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
this.schema = {
|
|
299
|
-
lastId: this.schema.lastId,
|
|
300
|
-
...parsedSchema,
|
|
301
|
-
};
|
|
302
|
-
for (const field in this.schema.types) {
|
|
303
|
-
if (!('id' in this.schema.types[field])) {
|
|
304
|
-
this.schema.lastId++;
|
|
305
|
-
this.schema.types[field].id = this.schema.lastId;
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
const { hash: _, ...rest } = this.schema;
|
|
309
|
-
this.schema.hash = hash(rest);
|
|
310
|
-
updateTypeDefs(this.schema, this.schemaTypesParsed, this.schemaTypesParsedById);
|
|
311
|
-
if (!fromStart) {
|
|
312
|
-
writeFile(join(this.fileSystemPath, SCHEMA_FILE), JSON.stringify(this.schema)).catch((err) => console.error('!!!', SCHEMA_FILE, err));
|
|
313
|
-
let types = Object.keys(this.schemaTypesParsed);
|
|
314
|
-
const s = schemaToSelvaBuffer(this.schemaTypesParsed);
|
|
315
|
-
for (let i = 0; i < s.length; i++) {
|
|
316
|
-
// TYPE SELVA user Uint8Array(6) [ 1, 17, 23, 0, 11, 0 ]
|
|
317
|
-
const type = this.schemaTypesParsed[types[i]];
|
|
318
|
-
// TODO should not crash!
|
|
319
|
-
try {
|
|
320
|
-
native.updateSchemaType(type.id, new Uint8Array(s[i]), this.dbCtxExternal);
|
|
321
|
-
}
|
|
322
|
-
catch (err) {
|
|
323
|
-
console.error('Cannot update schema on selva', type.type, err, s[i]);
|
|
324
|
-
}
|
|
214
|
+
async setSchema(strictSchema, transformFns) {
|
|
215
|
+
const schema = strictSchemaToDbSchema(strictSchema);
|
|
216
|
+
if (schema.hash === this.schema?.hash) {
|
|
217
|
+
// Todo something for sending back to actual client
|
|
218
|
+
return schema.hash;
|
|
219
|
+
}
|
|
220
|
+
if (this.schema) {
|
|
221
|
+
// skip if allrdy doing the same
|
|
222
|
+
if (schema.hash === this.migrating) {
|
|
223
|
+
await this.once('schema');
|
|
224
|
+
return this.schema.hash;
|
|
325
225
|
}
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
view.setUint32(buf.length - 4, data.length, true);
|
|
343
|
-
this.modify(buf);
|
|
344
|
-
}
|
|
345
|
-
initCsmt(this);
|
|
346
|
-
}
|
|
347
|
-
this.onSchemaChange?.(this.schema);
|
|
348
|
-
return this.schema;
|
|
226
|
+
await migrate(this, this.schema, schema, transformFns);
|
|
227
|
+
// if (this.schema.hash !== schema.hash) {
|
|
228
|
+
// // process.nextTick(() => this.emit('schema', this.schema))
|
|
229
|
+
// await this.once('schema')
|
|
230
|
+
// }
|
|
231
|
+
// Handle this later if it gets changed back to the same schema do false
|
|
232
|
+
// console.log(this.schema.hash == schema.hash)
|
|
233
|
+
return this.schema.hash;
|
|
234
|
+
}
|
|
235
|
+
setSchemaOnServer(this, schema);
|
|
236
|
+
await writeSchemaFile(this, schema);
|
|
237
|
+
await setNativeSchema(this, schema);
|
|
238
|
+
process.nextTick(() => {
|
|
239
|
+
this.emit('schema', this.schema);
|
|
240
|
+
});
|
|
241
|
+
return schema.hash;
|
|
349
242
|
}
|
|
350
243
|
modify(buf) {
|
|
351
244
|
const schemaHash = readUint64(buf, 0);
|
|
@@ -409,7 +302,7 @@ export class DbServer {
|
|
|
409
302
|
//this.dirtyRanges.add(key)
|
|
410
303
|
i += 8;
|
|
411
304
|
}
|
|
412
|
-
|
|
305
|
+
resizeModifyDirtyRanges(this);
|
|
413
306
|
native.modify(data, types, this.dbCtxExternal, this.modifyDirtyRanges);
|
|
414
307
|
for (let key of this.modifyDirtyRanges) {
|
|
415
308
|
if (key === 0) {
|
|
@@ -419,7 +312,7 @@ export class DbServer {
|
|
|
419
312
|
}
|
|
420
313
|
}
|
|
421
314
|
#expire() {
|
|
422
|
-
|
|
315
|
+
resizeModifyDirtyRanges(this);
|
|
423
316
|
native.modify(emptyUint8Array, emptyUint8Array, this.dbCtxExternal, this.modifyDirtyRanges);
|
|
424
317
|
for (let key of this.modifyDirtyRanges) {
|
|
425
318
|
if (key === 0) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { StrictSchema } from '@based/schema';
|
|
2
1
|
import { DbServer } from '../index.js';
|
|
2
|
+
import { DbSchema } from '../../schema.js';
|
|
3
3
|
type TransformFn = (node: Record<string, any>) => Record<string, any> | [string, Record<string, any>];
|
|
4
4
|
export type TransformFns = Record<string, TransformFn>;
|
|
5
|
-
export declare const migrate: (
|
|
5
|
+
export declare const migrate: (server: DbServer, fromSchema: DbSchema, toSchema: DbSchema, transform?: TransformFns) => Promise<void>;
|
|
6
6
|
export {};
|