@live-change/db-server 0.9.83 → 0.9.84

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/Dockerfile CHANGED
@@ -9,6 +9,7 @@ RUN npm install -g levelup
9
9
  RUN npm install -g memdown
10
10
  RUN npm install -g node-lmdb
11
11
  RUN npm install -g subleveldown
12
+ RUN npm install -g typescript
12
13
 
13
14
  COPY package.json .
14
15
  RUN npm install -g @live-change/db-server@`echo "console.log(require('./package.json').version)" | node`
@@ -16,6 +17,7 @@ RUN npm install -g @live-change/db-client@`echo "console.log(require('./package.
16
17
  RUN rm package.json
17
18
 
18
19
  RUN cd /usr/local/lib/node_modules/@live-change/db-server/node_modules/@live-change/db-admin/; npm run build
20
+ RUN cd /usr/local/lib/node_modules/@live-change/db-server/; npm run build
19
21
 
20
22
  EXPOSE 9417
21
23
 
@@ -1,7 +1,7 @@
1
1
  #!/bin/bash
2
2
  VERSION=`echo "console.log(require('./package.json').version)" | node`
3
- PLATFORMS="linux/amd64,linux/arm64,linux/arm/v7"
4
- #PLATFORMS="linux/amd64"
3
+ #PLATFORMS="linux/amd64,linux/arm64,linux/arm/v7"
4
+ PLATFORMS="linux/amd64"
5
5
  echo building docker image for version $VERSION
6
6
  docker buildx build --debug \
7
7
  --platform $PLATFORMS \
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
@@ -0,0 +1,181 @@
1
+ #!/usr/bin/env node
2
+ import path from 'path';
3
+ import fs from 'fs';
4
+ import service from "os-service";
5
+ import Server from '../lib/Server.js';
6
+ import { client as WSClient } from "@live-change/dao-websocket";
7
+ import ReactiveDao from '@live-change/dao';
8
+ import * as db from "@live-change/db";
9
+ import profileOutput from "../lib/profileOutput.js";
10
+ import { performance } from 'perf_hooks';
11
+ import yargs from 'yargs';
12
+ import { fileURLToPath } from 'url';
13
+ import { SsrServer, createLoopbackDao } from "@live-change/server";
14
+ process.on('unhandledRejection', (reason, promise) => {
15
+ console.error('Unhandled Promise Rejection', "reason", reason, "stack", reason.stack, "promise", promise);
16
+ //process.exit(1) // TODO: database should not fail because of it, but it should be logged somewhere
17
+ });
18
+ process.on('uncaughtException', function (err) {
19
+ console.error('uncaughtException', err);
20
+ });
21
+ function serverOptions(yargs) {
22
+ yargs.option('port', {
23
+ describe: 'port to bind on',
24
+ type: 'number',
25
+ default: 9417
26
+ });
27
+ yargs.option('host', {
28
+ describe: 'bind host',
29
+ type: 'string',
30
+ default: '::'
31
+ });
32
+ yargs.option('master', {
33
+ describe: 'replicate from master',
34
+ type: 'string',
35
+ default: null
36
+ });
37
+ yargs.option('slowStart', {
38
+ type: 'boolean',
39
+ description: 'start indexes one after another(better for debugging)'
40
+ });
41
+ yargs.option('profileLog', {
42
+ type: 'string',
43
+ description: 'profiling log file path'
44
+ });
45
+ }
46
+ function storeOptions(yargs, defaults = {}) {
47
+ yargs.option('dbRoot', {
48
+ describe: 'server root directory',
49
+ type: 'string',
50
+ default: defaults.dbRoot || '.'
51
+ });
52
+ yargs.option('backend', {
53
+ describe: 'database backend engine ( lmdb | leveldb | rocksdb | memdown | mem )',
54
+ type: "string",
55
+ default: defaults.backend || 'lmdb'
56
+ });
57
+ yargs.option('backendUrl', {
58
+ describe: 'remote database backend address',
59
+ type: "string"
60
+ });
61
+ }
62
+ function serviceOptions(yargs) {
63
+ yargs.option('serviceName', {
64
+ describe: 'name of service',
65
+ type: 'string',
66
+ default: 'liveChangeDb'
67
+ });
68
+ }
69
+ const argv = yargs(process.argv.slice(2)) // eslint-disable-line
70
+ .command('create', 'create database root', (yargs) => {
71
+ storeOptions(yargs);
72
+ }, (argv) => create(argv))
73
+ .command('serve', 'start server', (yargs) => {
74
+ serverOptions(yargs);
75
+ storeOptions(yargs);
76
+ yargs.option('service', {
77
+ describe: 'run as service',
78
+ type: 'boolean'
79
+ });
80
+ }, (argv) => {
81
+ if (argv.service) {
82
+ if (argv.verbose) {
83
+ console.info('running as service!');
84
+ }
85
+ service.run(function () {
86
+ service.stop(0);
87
+ });
88
+ }
89
+ serve(argv);
90
+ })
91
+ .command('install', 'install system service', (yargs) => {
92
+ serviceOptions(yargs);
93
+ serverOptions(yargs);
94
+ storeOptions(yargs, { dbRoot: '/var/db/liveChangeDb' });
95
+ }, async (argv) => {
96
+ const programArgs = ["serve", '--service',
97
+ '--port', argv.port, '--host', argv.host,
98
+ '--dbRoot', argv.dbRoot, '--backend', argv.backend];
99
+ if (argv.verbose)
100
+ console.info(`creating system service ${argv.serviceName}`);
101
+ await fs.promises.mkdir(argv.dbRoot, { recursive: true });
102
+ service.add(argv.serviceName, { programArgs }, function (error) {
103
+ if (error)
104
+ console.trace(error);
105
+ });
106
+ })
107
+ .command('uninstall', 'remove system service', (yargs) => {
108
+ serviceOptions(yargs);
109
+ }, (argv) => {
110
+ if (argv.verbose)
111
+ console.info(`removing system service ${argv.serviceName}`);
112
+ service.remove(argv.serviceName, function (error) {
113
+ if (error)
114
+ console.trace(error);
115
+ });
116
+ })
117
+ .option('verbose', {
118
+ alias: 'v',
119
+ type: 'boolean',
120
+ description: 'Run with verbose logging'
121
+ }).argv;
122
+ async function create({ dbRoot, backend, verbose }) {
123
+ await fs.promises.mkdir(dbRoot, { recursive: true });
124
+ if (verbose)
125
+ console.info(`creating database in ${path.resolve(dbRoot)}`);
126
+ let server = new Server({ dbRoot, backend });
127
+ await server.initialize({ forceNew: true });
128
+ if (verbose)
129
+ console.info(`database server root directory created.`);
130
+ }
131
+ async function serve(argv) {
132
+ const { dbRoot, backend, backendUrl, verbose, host, port, master, slowStart, profileLog } = argv;
133
+ if (profileLog) {
134
+ const out = profileOutput(profileLog);
135
+ await db.profileLog.startLog(out, performance);
136
+ }
137
+ const profileOp = await db.profileLog.begin({ operation: "startingDbServer", ...argv });
138
+ if (verbose)
139
+ console.info(`starting server in ${path.resolve(dbRoot)}`);
140
+ let server = new Server({
141
+ dbRoot, backend, backendUrl, master,
142
+ slowStart
143
+ });
144
+ process.on('unhandledRejection', (reason, promise) => {
145
+ if (reason.stack && reason.stack.match(/\s(userCode:([a-z0-9_.\/-]+):([0-9]+):([0-9]+))\n/i)) {
146
+ server.handleUnhandledRejectionInQuery(reason, promise);
147
+ }
148
+ else {
149
+ console.error('Unhandled Promise Rejection', (reason && reason.stack) || reason, "Promise:", promise);
150
+ //process.exit(1) // TODO: database should not fail because of it, but it should be logged somewhere
151
+ }
152
+ });
153
+ await server.initialize();
154
+ if (verbose)
155
+ console.info(`database initialized!`);
156
+ if (verbose)
157
+ console.info(`listening on: ${argv.host}:${argv.port}`);
158
+ const ssrRoot = path.dirname(fileURLToPath(import.meta.resolve("@live-change/db-admin/front/vite.config.js")));
159
+ const http = await server.getHttp();
160
+ const { app } = http;
161
+ const dev = await fs.promises.access(path.resolve(ssrRoot, './dist'), fs.constants.R_OK)
162
+ .then(r => false).catch(r => true);
163
+ if (dev)
164
+ console.log("STARTING ADMIN IN DEV MODE!");
165
+ const manifest = (dev || argv.spa)
166
+ ? null
167
+ : JSON.parse(fs.readFileSync((path.resolve(ssrRoot, 'dist/client/.vite/ssr-manifest.json'))));
168
+ const admin = new SsrServer(app, manifest, {
169
+ dev,
170
+ fastAuth: true,
171
+ root: ssrRoot,
172
+ daoFactory: async (credentials, ip) => {
173
+ return await createLoopbackDao(credentials, () => server.apiServer.daoFactory(credentials, ip));
174
+ }
175
+ });
176
+ admin.start();
177
+ http.server.listen(port, host);
178
+ if (verbose)
179
+ console.info(`server started!`);
180
+ await db.profileLog.end(profileOp);
181
+ }
@@ -0,0 +1,2 @@
1
+ export default Server;
2
+ import Server from './lib/Server.js';
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ import Server from './lib/Server.js';
2
+ export default Server;
@@ -0,0 +1,13 @@
1
+ export default Replicator;
2
+ declare class Replicator {
3
+ constructor(server: any);
4
+ server: any;
5
+ dao: any;
6
+ listObservable: any;
7
+ databases: Map<any, any>;
8
+ start(): void;
9
+ close(): void;
10
+ set(dbList: any): void;
11
+ push(name: any): void;
12
+ remove(dbName: any): Promise<void>;
13
+ }
@@ -0,0 +1,370 @@
1
+ const bucketSize = 100;
2
+ const LOG_NOTSTARTED = 0;
3
+ const LOG_UPDATING = 2;
4
+ const LOG_READY = 3;
5
+ const LOG_CLOSED = 4;
6
+ class LogReplicator {
7
+ constructor(databaseName, server, logName, destination) {
8
+ this.server = server;
9
+ this.databaseName = databaseName;
10
+ this.logName = logName;
11
+ this.destination = destination;
12
+ this.dao = server.masterDao;
13
+ this.state = LOG_NOTSTARTED;
14
+ this.lastUpdateId = null;
15
+ this.observable = null;
16
+ }
17
+ observeMore() {
18
+ if (this.observable)
19
+ this.observable.unobserve(this);
20
+ this.observable = this.dao.observable(['database', 'logRange', this.databaseName, this.logName, {
21
+ gt: this.lastUpdateId,
22
+ limit: bucketSize
23
+ }]);
24
+ this.observable.observe(this);
25
+ }
26
+ async set(entries) {
27
+ for (let entry of entries) {
28
+ await this.destination.data.put(entry);
29
+ this.lastUpdateId = entry.id;
30
+ }
31
+ if (this.observable.list.length == bucketSize) {
32
+ this.observeMore();
33
+ }
34
+ }
35
+ putByField(_fd, id, entry, _reverse, oldObject) {
36
+ this.destination.data.put(entry);
37
+ this.lastUpdateId = entry.id;
38
+ if (this.observable.list.length == bucketSize) {
39
+ this.observeMore();
40
+ }
41
+ }
42
+ async updateAll() {
43
+ let entries;
44
+ do {
45
+ entries = await this.dao.get(['database', 'logRange', this.databaseName, this.logName, {
46
+ gt: this.lastUpdateId,
47
+ limit: bucketSize
48
+ }]);
49
+ for (let entry of entries) {
50
+ await this.destination.data.put(entry);
51
+ this.lastUpdateId = entry.id;
52
+ }
53
+ } while (entries.length >= bucketSize && this.state != LOG_CLOSED);
54
+ this.state = LOG_READY;
55
+ this.observeMore();
56
+ }
57
+ async start() {
58
+ const lastLogOperations = await this.destination.rangeGet({ reverse: true, limit: 1 });
59
+ const lastLogOperation = lastLogOperations[0];
60
+ if (!lastLogOperation) {
61
+ this.lastUpdateId = '';
62
+ }
63
+ else {
64
+ this.lastUpdateId = lastLogOperation.id; // one second overlap
65
+ }
66
+ this.state = LOG_UPDATING;
67
+ this.updateAll();
68
+ }
69
+ close() {
70
+ this.state = LOG_CLOSED;
71
+ if (this.observable)
72
+ this.observable.unobserve(this);
73
+ }
74
+ }
75
+ const TABLE_NOTSTARTED = 0;
76
+ const TABLE_COPYING = 1;
77
+ const TABLE_UPDATING = 2;
78
+ const TABLE_READY = 3;
79
+ const TABLE_CLOSED = 4;
80
+ class TableReplicator {
81
+ constructor(databaseName, server, tableName, destination) {
82
+ this.server = server;
83
+ this.databaseName = databaseName;
84
+ this.tableName = tableName;
85
+ this.destination = destination;
86
+ this.dao = server.masterDao;
87
+ this.state = TABLE_NOTSTARTED;
88
+ this.lastUpdateId = null;
89
+ this.observable = null;
90
+ }
91
+ observeMore() {
92
+ if (this.observable)
93
+ this.observable.unobserve(this);
94
+ this.observable = this.dao.observable(['database', 'tableOpLogRange', this.databaseName, this.tableName, {
95
+ gt: this.lastUpdateId,
96
+ limit: bucketSize
97
+ }]);
98
+ this.observable.observe(this);
99
+ }
100
+ async set(ops) {
101
+ for (let op of ops) {
102
+ if (op.type == 'put')
103
+ await this.destination.put(op.object);
104
+ if (op.type == 'delete')
105
+ await this.destination.delete(op.object);
106
+ if (op.type == 'clearOpLog')
107
+ await this.destination.clearOpLog(op.to);
108
+ this.lastUpdateId = op.id;
109
+ }
110
+ if (this.observable.list.length == bucketSize) {
111
+ this.observeMore();
112
+ }
113
+ }
114
+ async putByField(_fd, id, op, _reverse, oldObject) {
115
+ if (op.type == 'put')
116
+ this.destination.put(op.object);
117
+ if (op.type == 'delete')
118
+ this.destination.delete(op.object);
119
+ if (op.type == 'clearOpLog')
120
+ await this.destination.clearOpLog(op.to);
121
+ this.lastUpdateId = op.id;
122
+ if (this.observable.list.length == bucketSize) {
123
+ this.observeMore();
124
+ }
125
+ }
126
+ async applyOp(op) {
127
+ if (op.operation.type == 'put')
128
+ await this.destination.data.put(op.operation.object);
129
+ if (op.operation.type == 'delete')
130
+ await this.destination.data.delete(op.operation.object);
131
+ await this.destination.opLog.put(op);
132
+ this.lastUpdateId = op.id;
133
+ }
134
+ async updateAll() {
135
+ // console.log("UPDATE TABLE", this.databaseName, this.tableName, "FROM", this.lastUpdateId)
136
+ let ops;
137
+ do {
138
+ ops = await this.dao.get(['database', 'tableOpLogRange', this.databaseName, this.tableName, {
139
+ gt: this.lastUpdateId,
140
+ limit: bucketSize
141
+ }]);
142
+ //console.log("GOT TABLE OPS", this.databaseName, this.tableName, ":", JSON.stringify(ops, null, " "))
143
+ for (let op of ops) {
144
+ await this.applyOp(op);
145
+ }
146
+ } while (ops.length >= bucketSize && this.state != TABLE_CLOSED);
147
+ this.state = TABLE_READY;
148
+ this.observeMore();
149
+ }
150
+ async copyAll() {
151
+ await Promise.all([
152
+ this.destination.opLog.rangeDelete({}),
153
+ this.destination.data.rangeDelete({}),
154
+ ]);
155
+ //console.log("COPY TABLE", this.databaseName, this.tableName)
156
+ let copyPosition = '';
157
+ let data;
158
+ do {
159
+ data = await this.dao.get(['database', 'tableRange', this.databaseName, this.tableName, {
160
+ gt: copyPosition,
161
+ limit: bucketSize
162
+ }]);
163
+ for (let obj of data) {
164
+ await this.destination.put(obj);
165
+ }
166
+ } while (data.length >= bucketSize && this.state != TABLE_CLOSED);
167
+ this.state = TABLE_READY;
168
+ this.observeMore();
169
+ }
170
+ async start() {
171
+ const lastTableOperation = await this.destination.opLog.rangeGet({ reverse: true, limit: 1 })[0];
172
+ const firstSourceOperation = await this.dao.get(['database', 'tableOpLogRange', this.databaseName, this.tableName, {
173
+ limit: 1
174
+ }]);
175
+ if (!lastTableOperation // If empty table, or opLog desynchronized(cleared)
176
+ || (firstSourceOperation && firstSourceOperation.id > lastTableOperation.id)) { // Copy data first
177
+ let tableCreateTimestamp = Date.now();
178
+ this.state = TABLE_COPYING;
179
+ this.lastUpdateId = ('' + (tableCreateTimestamp - 1000)).padStart(16, '0'); // one second overlay
180
+ this.copyAll();
181
+ }
182
+ else {
183
+ this.state = TABLE_UPDATING;
184
+ this.lastUpdateId = lastTableOperation.id; // one second overlap
185
+ this.updateAll();
186
+ }
187
+ }
188
+ close() {
189
+ this.state = TABLE_CLOSED;
190
+ if (this.observable)
191
+ this.observable.unobserve(this);
192
+ }
193
+ }
194
+ class ListReplicator {
195
+ constructor(databaseName, server, list, type, copy, factory) {
196
+ this.name = databaseName;
197
+ this.database = null;
198
+ this.server = server;
199
+ this.dao = server.masterDao;
200
+ this.list = list;
201
+ this.type = type;
202
+ this.copy = copy;
203
+ this.factory = factory;
204
+ this.observable = null;
205
+ this.objects = new Map();
206
+ }
207
+ start() {
208
+ this.database = this.server.databases.get(this.name);
209
+ /// Observe system table because it is organized by table uids which is better for rename operations
210
+ this.observable = this.dao.observable(['database', 'tableRange', 'system', this.name + '_' + this.list, {}]);
211
+ this.observable.observe(this);
212
+ }
213
+ async createObject(obj) {
214
+ let foundName = null;
215
+ const configList = this.database.config[this.list];
216
+ for (let k in configList)
217
+ if (configList[k].uid == obj.id)
218
+ foundName = k;
219
+ if (foundName) {
220
+ if (foundName != obj.name) {
221
+ await this.database['rename' + this.type](foundName, obj.name);
222
+ await this.server.databases.get('system').table(this.name + '_' + this.list).update(obj.id, [
223
+ { op: 'merge', property: 'name', value: obj.name }
224
+ ]);
225
+ }
226
+ /// TODO: compare configurations?
227
+ }
228
+ else {
229
+ if (configList[obj.name]) { // Object with this name already exists, overwrite?!
230
+ console.error("NAME", obj.name, "EXISTS WITH ANOTHER UID", configList[obj.name].uid, "!=", obj.id, "IN DB", this.name);
231
+ }
232
+ try {
233
+ const object = await this.factory(obj);
234
+ await this.server.databases.get('system').table(this.name + '_' + this.list).put(obj);
235
+ }
236
+ catch (e) {
237
+ console.log("CREATE OBJ", obj, "IN DB", this.name, "FAILED");
238
+ console.error(e);
239
+ }
240
+ }
241
+ if (this.copy) {
242
+ const objRep = this.objects.get(obj.id);
243
+ if (objRep) {
244
+ objRep.close();
245
+ this.objects.delete(obj.id);
246
+ }
247
+ const objectReplicator = this.copy(obj);
248
+ this.objects.set(obj.id, objectReplicator);
249
+ objectReplicator.start();
250
+ }
251
+ }
252
+ set(objects) {
253
+ for (const obj of objects) {
254
+ this.createObject(obj);
255
+ }
256
+ for (const key in this.database.config[this.list]) {
257
+ const value = this.database.config[this.list][key];
258
+ const obj = objects.find(o => o.id == value.uid);
259
+ if (!obj) {
260
+ this.database['delete' + this.type](key);
261
+ this.server.databases.get('system').table(this.name + '_' + this.list).delete(value.uid);
262
+ }
263
+ }
264
+ }
265
+ putByField(_fd, uid, object, _reverse, oldObject) {
266
+ this.createObject(obj);
267
+ }
268
+ removeByField(_fd, uid, oldObject) {
269
+ this.database['delete' + this.type](oldObject.name);
270
+ this.server.databases.get('system').table(this.name + '_' + this.list).delete(uid);
271
+ if (this.copy) {
272
+ this.objects.get(uid).close();
273
+ this.objects.delete(uid);
274
+ }
275
+ }
276
+ }
277
+ class DatabaseReplicator {
278
+ constructor(databaseName, server) {
279
+ this.name = databaseName;
280
+ this.server = server;
281
+ this.dao = server.masterDao;
282
+ this.tables = null;
283
+ this.indexes = null;
284
+ this.logs = null;
285
+ }
286
+ async start() {
287
+ this.databaseConfig = this.dao.get(['database', 'databaseConfig', this.name]);
288
+ if (!this.server.metadata.databases[this.name]) {
289
+ this.server.metadata.databases[this.name] = this.databaseConfig;
290
+ const database = await this.server.initDatabase(this.name, this.databaseConfig);
291
+ this.server.databases.set(this.name, database);
292
+ this.server.databasesListObservable.push(this.name);
293
+ await Promise.all([
294
+ this.server.databases.get('system').createTable(this.name + "_tables"),
295
+ this.server.databases.get('system').createTable(this.name + "_logs"),
296
+ this.server.databases.get('system').createTable(this.name + "_indexes")
297
+ ]);
298
+ await this.server.saveMetadata();
299
+ }
300
+ const database = this.server.databases.get(this.name);
301
+ this.tables = new ListReplicator(this.name, this.server, 'tables', 'Table', (obj) => new TableReplicator(this.name, this.server, obj.name, database.table(obj.name)), (obj) => database.createTable(obj.name, obj.config));
302
+ this.indexes = new ListReplicator(this.name, this.server, 'indexes', 'Index', false, (obj) => {
303
+ //console.log("CREATE INDEX", obj.id, obj.name, "WITH UID", obj.config.uid)
304
+ return database.createIndex(obj.name, obj.config.code, obj.config.parameters, obj.config);
305
+ });
306
+ this.logs = new ListReplicator(this.name, this.server, 'logs', 'Log', (obj) => new LogReplicator(this.name, this.server, obj.name, database.log(obj.name)), (obj) => database.createLog(obj.name, obj.config));
307
+ this.tables.start();
308
+ this.indexes.start();
309
+ this.logs.start();
310
+ }
311
+ close() {
312
+ this.tables.close();
313
+ this.indexes.close();
314
+ this.logs.close();
315
+ }
316
+ }
317
+ class Replicator {
318
+ constructor(server) {
319
+ this.server = server;
320
+ this.dao = server.masterDao;
321
+ this.listObservable = null;
322
+ this.databases = new Map();
323
+ }
324
+ start() {
325
+ this.listObservable = this.dao.observable(['database', 'databasesList']);
326
+ this.listObservable.observe(this);
327
+ }
328
+ close() {
329
+ if (this.listObservable)
330
+ this.listObservable.unobserve(this);
331
+ for (let replicator of this.databases.values())
332
+ replicator.close();
333
+ }
334
+ set(dbList) {
335
+ if (!Array.isArray(dbList))
336
+ return;
337
+ for (let [name, db] of this.server.databases.entries()) {
338
+ if (name != 'system' && dbList.indexOf(name) == -1) { // Database removed
339
+ this.remove(name);
340
+ }
341
+ }
342
+ for (let name of dbList) {
343
+ this.push(name);
344
+ }
345
+ }
346
+ push(name) {
347
+ if (!this.databases.get(name)) {
348
+ const replicator = new DatabaseReplicator(name, this.server);
349
+ this.databases.set(name, replicator);
350
+ replicator.start();
351
+ }
352
+ }
353
+ async remove(dbName) {
354
+ const replicator = this.databases.get(dbName);
355
+ if (replicator) {
356
+ replicator.close();
357
+ }
358
+ delete this.server.metadata.databases[dbName];
359
+ this.server.databases.get(dbName).delete();
360
+ this.server.databaseStores.get(dbName).delete();
361
+ this.server.databasesListObservable.remove(dbName);
362
+ await Promise.all([
363
+ this.server.databases.get('system').deleteTable(dbName + "_tables"),
364
+ this.server.databases.get('system').deleteTable(dbName + "_logs"),
365
+ this.server.databases.get('system').deleteTable(dbName + "_indexes")
366
+ ]);
367
+ await this.server.saveMetadata();
368
+ }
369
+ }
370
+ export default Replicator;
@@ -0,0 +1,68 @@
1
+ /// <reference types="node" resolution-mode="require"/>
2
+ export default Server;
3
+ declare class Server {
4
+ constructor(config: any);
5
+ config: any;
6
+ databases: Map<any, any>;
7
+ metadata: any;
8
+ databaseStores: Map<any, any>;
9
+ metadataSavePromise: Promise<void>;
10
+ databasesListObservable: any;
11
+ apiServer: any;
12
+ backends: {};
13
+ masterDao: import("@live-change/dao/lib/Dao.js").default;
14
+ replicator: Replicator;
15
+ createDaoConfig(session: any): {
16
+ database: {
17
+ type: string;
18
+ source: any;
19
+ };
20
+ serverDatabase: {
21
+ type: string;
22
+ source: any;
23
+ };
24
+ store: {
25
+ type: string;
26
+ source: any;
27
+ };
28
+ version: {
29
+ type: string;
30
+ source: any;
31
+ };
32
+ metadata: {
33
+ type: string;
34
+ source: any;
35
+ };
36
+ };
37
+ createDao(session: any): import("@live-change/dao/lib/Dao.js").default;
38
+ initialize(initOptions?: {}): Promise<void>;
39
+ checkInfoIntegrity(): Promise<void>;
40
+ initDatabase(dbName: any, dbConfig: any): Promise<Database>;
41
+ initializingDatabase: Database;
42
+ doSaveMetadata(): Promise<void>;
43
+ saveMetadata(): Promise<void>;
44
+ getHttp(): Promise<{
45
+ app: any;
46
+ sockJsServer: import("@live-change/sockjs/lib/server.js");
47
+ wsServer: any;
48
+ server: http.Server<typeof http.IncomingMessage, typeof http.ServerResponse>;
49
+ }>;
50
+ httpPromise: Promise<{
51
+ app: any;
52
+ sockJsServer: import("@live-change/sockjs/lib/server.js");
53
+ wsServer: any;
54
+ server: http.Server<typeof http.IncomingMessage, typeof http.ServerResponse>;
55
+ }>;
56
+ http: {
57
+ app: any;
58
+ sockJsServer: import("@live-change/sockjs/lib/server.js");
59
+ wsServer: any;
60
+ server: http.Server<typeof http.IncomingMessage, typeof http.ServerResponse>;
61
+ };
62
+ listen(...args: any[]): Promise<void>;
63
+ close(): Promise<void>;
64
+ handleUnhandledRejectionInQuery(reason: any, promise: any): void;
65
+ }
66
+ import Replicator from './Replicator.js';
67
+ import { Database } from '@live-change/db';
68
+ import http from 'http';