@live-change/db 0.3.62 → 0.5.3
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/lib/Database.js +34 -19
- package/lib/Index.js +8 -5
- package/lib/ScriptContext.js +4 -3
- package/package.json +5 -12
package/lib/Database.js
CHANGED
|
@@ -7,6 +7,8 @@ const getRandomValues = require('get-random-values')
|
|
|
7
7
|
|
|
8
8
|
const ReactiveDao = require("@live-change/dao")
|
|
9
9
|
|
|
10
|
+
const debug = require('debug')('db')
|
|
11
|
+
|
|
10
12
|
class Database {
|
|
11
13
|
constructor(config, storeFactory, saveConfig, deleteStore, name, createScriptContext) {
|
|
12
14
|
this.name = name
|
|
@@ -28,7 +30,7 @@ class Database {
|
|
|
28
30
|
this.configObservable = new ReactiveDao.ObservableValue(JSON.parse(JSON.stringify(this.config)))
|
|
29
31
|
this.tablesListObservable = new ReactiveDao.ObservableList(Object.keys(this.config.tables))
|
|
30
32
|
this.indexesListObservable = new ReactiveDao.ObservableList(Object.keys(this.config.indexes))
|
|
31
|
-
this.logsListObservable = new ReactiveDao.ObservableList(Object.keys(this.config.logs))
|
|
33
|
+
this.logsListObservable = new ReactiveDao.ObservableList(Object.keys(this.config.logs))
|
|
32
34
|
}
|
|
33
35
|
|
|
34
36
|
async start(startConfig = {}) {
|
|
@@ -93,7 +95,7 @@ class Database {
|
|
|
93
95
|
this.tablesListObservable.remove(name)
|
|
94
96
|
this.tables.delete(name)
|
|
95
97
|
}
|
|
96
|
-
|
|
98
|
+
|
|
97
99
|
renameTable(name, newName) {
|
|
98
100
|
if(this.config.tables[newName]) throw new Error(`Table ${newName} already exists`)
|
|
99
101
|
const table = this.table(name)
|
|
@@ -227,25 +229,38 @@ class Database {
|
|
|
227
229
|
return summary
|
|
228
230
|
}
|
|
229
231
|
|
|
232
|
+
async openIndex(name) {
|
|
233
|
+
let config = this.config.indexes[name]
|
|
234
|
+
if(!config) {
|
|
235
|
+
debug("INDEX", name, "NOT EXISTS - WAITING!")
|
|
236
|
+
await new Promise(r => setTimeout(r, 500))
|
|
237
|
+
config = this.config.indexes[name]
|
|
238
|
+
}
|
|
239
|
+
let index, code
|
|
240
|
+
if(!config) throw new Error(`Index ${name} not found`)
|
|
241
|
+
code = config.code
|
|
242
|
+
const params = config.parameters
|
|
243
|
+
index = new Index(this, name, code, params, config)
|
|
244
|
+
try {
|
|
245
|
+
debug("STARTING INDEX", name)
|
|
246
|
+
await index.startIndex()
|
|
247
|
+
debug("STARTED INDEX", name)
|
|
248
|
+
} catch(error) {
|
|
249
|
+
console.error("INDEX", name, "ERROR", error, "CODE:\n", code)
|
|
250
|
+
console.error("DELETING INDEX", name)
|
|
251
|
+
delete this.config.indexes[name]
|
|
252
|
+
this.indexesListObservable.remove(name)
|
|
253
|
+
if(this.onAutoRemoveIndex && config) this.onAutoRemoveIndex(name, config.uid)
|
|
254
|
+
await this.saveConfig(this.config)
|
|
255
|
+
throw error
|
|
256
|
+
}
|
|
257
|
+
this.indexes.set(name, index)
|
|
258
|
+
return index
|
|
259
|
+
}
|
|
230
260
|
async index(name) {
|
|
231
261
|
let index = this.indexes.get(name)
|
|
232
262
|
if(!index) {
|
|
233
|
-
|
|
234
|
-
if(!config) throw new Error(`Index ${name} not found`)
|
|
235
|
-
const code = config.code
|
|
236
|
-
const params = config.parameters
|
|
237
|
-
index = new Index(this, name, code, params, config)
|
|
238
|
-
try {
|
|
239
|
-
await index.startIndex()
|
|
240
|
-
} catch(error) {
|
|
241
|
-
console.error("INDEX", name, "ERROR", error, "CODE:\n", index.code)
|
|
242
|
-
console.error("DELETING INDEX", name)
|
|
243
|
-
delete this.config.indexes[name]
|
|
244
|
-
this.indexesListObservable.remove(name)
|
|
245
|
-
if(this.onAutoRemoveIndex) this.onAutoRemoveIndex(name, config.uid)
|
|
246
|
-
await this.saveConfig(this.config)
|
|
247
|
-
throw error
|
|
248
|
-
}
|
|
263
|
+
index = this.openIndex(name)
|
|
249
264
|
this.indexes.set(name, index)
|
|
250
265
|
}
|
|
251
266
|
return index
|
|
@@ -273,7 +288,7 @@ class Database {
|
|
|
273
288
|
|
|
274
289
|
handleUnhandledRejectionInIndex(name, reason, promise) {
|
|
275
290
|
const config = this.config.indexes[name]
|
|
276
|
-
console.error("INDEX", name, "unhandledRejection", reason, "CODE:\n", config
|
|
291
|
+
console.error("INDEX", name, "unhandledRejection", reason, "CODE:\n", config?.code)
|
|
277
292
|
console.error("DELETING INDEX", name)
|
|
278
293
|
process.nextTick(() => {
|
|
279
294
|
if(!config) {
|
package/lib/Index.js
CHANGED
|
@@ -6,6 +6,8 @@ const profileLog = require('./profileLog.js')
|
|
|
6
6
|
const queryObservable = require('./queryObservable.js')
|
|
7
7
|
const { ChangeStream } = require('./ChangeStream.js')
|
|
8
8
|
|
|
9
|
+
const debug = require('debug')('db')
|
|
10
|
+
|
|
9
11
|
const opLogBatchSize = 128 /// TODO: incrase after testing
|
|
10
12
|
|
|
11
13
|
class ObjectReader extends ChangeStream {
|
|
@@ -63,6 +65,7 @@ class TableReader extends ChangeStream {
|
|
|
63
65
|
this.opLogReader = opLogReader
|
|
64
66
|
this.prefix = prefix
|
|
65
67
|
this.table = table
|
|
68
|
+
Promise.resolve(this.table).then(t=> {if(!t) throw new Error("TABLE NOT FOUND!!!")})
|
|
66
69
|
this.isLog = isLog
|
|
67
70
|
this.objectReaders = new Map()
|
|
68
71
|
this.rangeReaders = new Map()
|
|
@@ -436,7 +439,7 @@ class Index extends Table {
|
|
|
436
439
|
this.code = code
|
|
437
440
|
}
|
|
438
441
|
async startIndex() {
|
|
439
|
-
|
|
442
|
+
debug("EXECUTING INDEX CODE", this.name)
|
|
440
443
|
this.scriptContext = this.database.createScriptContext({
|
|
441
444
|
/// TODO: script available routines
|
|
442
445
|
})
|
|
@@ -444,7 +447,7 @@ class Index extends Table {
|
|
|
444
447
|
this.codeFunction = (input, output) => queryFunction(input, output, this.params)
|
|
445
448
|
this.writer = new IndexWriter(this)
|
|
446
449
|
this.reader = null
|
|
447
|
-
|
|
450
|
+
debug("STARTING INDEX", this.name)
|
|
448
451
|
const lastIndexOperations = await this.opLog.rangeGet({ reverse: true, limit: 1 })
|
|
449
452
|
const lastIndexOperation = lastIndexOperations[0]
|
|
450
453
|
let lastUpdateTimestamp = 0
|
|
@@ -474,11 +477,11 @@ class Index extends Table {
|
|
|
474
477
|
codePromise = this.codeFunction(this.reader, this.writer)
|
|
475
478
|
//console.log("READING!")
|
|
476
479
|
await this.reader.readMore()
|
|
477
|
-
|
|
480
|
+
debug("WAITING FOR CODE!", this.name)
|
|
478
481
|
await codePromise
|
|
479
482
|
this.state = INDEX_READY
|
|
480
483
|
const startTime = Date.now()
|
|
481
|
-
|
|
484
|
+
debug("INDEX STARTED!", this.name)
|
|
482
485
|
await this.opLog.put({
|
|
483
486
|
id: ((''+startTime).padStart(16, '0'))+':000000',
|
|
484
487
|
timestamp: startTime,
|
|
@@ -498,7 +501,7 @@ class Index extends Table {
|
|
|
498
501
|
if(existingSourceInfo) return
|
|
499
502
|
const newSourceInfo = { type: sourceType, name: sourceName }
|
|
500
503
|
config.sources.push(newSourceInfo)
|
|
501
|
-
|
|
504
|
+
debug("NEW INDEX", this.name, "SOURCE DETECTED", sourceType, sourceName)
|
|
502
505
|
this.configObservable.set(config)
|
|
503
506
|
this.database.config.indexes[this.name] = config
|
|
504
507
|
this.database.handleConfigUpdated()
|
package/lib/ScriptContext.js
CHANGED
|
@@ -35,6 +35,7 @@ const defaultContext = {
|
|
|
35
35
|
return new ChangeStreamPipe()
|
|
36
36
|
},
|
|
37
37
|
'performance': require('perf_hooks').performance,
|
|
38
|
+
constructor: null
|
|
38
39
|
}
|
|
39
40
|
|
|
40
41
|
const filenameRE = /scriptFile:(\d+):(\d+)\)$/g
|
|
@@ -47,9 +48,9 @@ class ScriptContext {
|
|
|
47
48
|
}
|
|
48
49
|
this.context = vm.createContext({ ...defaultContext, ...context, ...userContext })
|
|
49
50
|
/* vm.runInContext(`
|
|
50
|
-
(function() {
|
|
51
|
-
const allowed = ${JSON.stringify(nativeGlobals.concat(Object.keys(userContext)))}
|
|
52
|
-
const keys = Object.getOwnPropertyNames(this)
|
|
51
|
+
(function() {
|
|
52
|
+
const allowed = ${JSON.stringify(nativeGlobals.concat(Object.keys(userContext)))}
|
|
53
|
+
const keys = Object.getOwnPropertyNames(this)
|
|
53
54
|
keys.forEach((key) => {
|
|
54
55
|
const item = this[key]
|
|
55
56
|
if(!item) return
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@live-change/db",
|
|
3
|
-
"version": "0.3
|
|
3
|
+
"version": "0.5.3",
|
|
4
4
|
"description": "Database with observable data for live queries",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -21,19 +21,11 @@
|
|
|
21
21
|
},
|
|
22
22
|
"homepage": "https://github.com/live-change/db",
|
|
23
23
|
"devDependencies": {
|
|
24
|
-
"@live-change/db-store-level": "^0.
|
|
25
|
-
"@live-change/db-store-lmdb": "^0.
|
|
26
|
-
"encoding-down": "^6.3.0",
|
|
27
|
-
"level-rocksdb": "^4.0.0",
|
|
28
|
-
"leveldown": "^5.6.0",
|
|
29
|
-
"levelup": "^4.4.0",
|
|
30
|
-
"memdown": "^5.1.0",
|
|
24
|
+
"@live-change/db-store-level": "^0.5.3",
|
|
25
|
+
"@live-change/db-store-lmdb": "^0.5.3",
|
|
31
26
|
"minimist": ">=1.2.3",
|
|
32
|
-
"node-lmdb": "^0.8.0",
|
|
33
27
|
"rimraf": "^3.0.2",
|
|
34
|
-
"rocksdb": "^4.1.0",
|
|
35
28
|
"sockjs": "^0.3.21",
|
|
36
|
-
"subleveldown": "^4.1.4",
|
|
37
29
|
"tape": "^4.13.3",
|
|
38
30
|
"websocket-extensions": ">=0.1.4"
|
|
39
31
|
},
|
|
@@ -41,5 +33,6 @@
|
|
|
41
33
|
"@live-change/dao": "^0.3.3",
|
|
42
34
|
"get-random-values": "^1.2.2",
|
|
43
35
|
"node-interval-tree": "^1.3.3"
|
|
44
|
-
}
|
|
36
|
+
},
|
|
37
|
+
"gitHead": "d92fb65e55f55e246e7a4615cff609cafdc32eba"
|
|
45
38
|
}
|