@live-change/db 0.3.61 → 0.5.2

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 CHANGED
@@ -7,8 +7,10 @@ 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
- constructor(config, storeFactory, saveConfig, deleteStore, name) {
13
+ constructor(config, storeFactory, saveConfig, deleteStore, name, createScriptContext) {
12
14
  this.name = name
13
15
  this.config = {
14
16
  tables: {},
@@ -23,6 +25,7 @@ class Database {
23
25
  this.tables = new Map()
24
26
  this.logs = new Map()
25
27
  this.indexes = new Map()
28
+ this.createScriptContext = createScriptContext
26
29
 
27
30
  this.configObservable = new ReactiveDao.ObservableValue(JSON.parse(JSON.stringify(this.config)))
28
31
  this.tablesListObservable = new ReactiveDao.ObservableList(Object.keys(this.config.tables))
@@ -92,7 +95,7 @@ class Database {
92
95
  this.tablesListObservable.remove(name)
93
96
  this.tables.delete(name)
94
97
  }
95
-
98
+
96
99
  renameTable(name, newName) {
97
100
  if(this.config.tables[newName]) throw new Error(`Table ${newName} already exists`)
98
101
  const table = this.table(name)
@@ -226,25 +229,38 @@ class Database {
226
229
  return summary
227
230
  }
228
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
+ }
229
260
  async index(name) {
230
261
  let index = this.indexes.get(name)
231
262
  if(!index) {
232
- const config = this.config.indexes[name]
233
- if(!config) throw new Error(`Index ${name} not found`)
234
- const code = config.code
235
- const params = config.parameters
236
- index = new Index(this, name, code, params, config)
237
- try {
238
- await index.startIndex()
239
- } catch(error) {
240
- console.error("INDEX", name, "ERROR", error, "CODE:\n", index.code)
241
- console.error("DELETING INDEX", name)
242
- delete this.config.indexes[name]
243
- this.indexesListObservable.remove(name)
244
- if(this.onAutoRemoveIndex) this.onAutoRemoveIndex(name, config.uid)
245
- await this.saveConfig(this.config)
246
- throw error
247
- }
263
+ index = this.openIndex(name)
248
264
  this.indexes.set(name, index)
249
265
  }
250
266
  return index
@@ -272,7 +288,7 @@ class Database {
272
288
 
273
289
  handleUnhandledRejectionInIndex(name, reason, promise) {
274
290
  const config = this.config.indexes[name]
275
- console.error("INDEX", name, "unhandledRejection", reason, "CODE:\n", config.code)
291
+ console.error("INDEX", name, "unhandledRejection", reason, "CODE:\n", config?.code)
276
292
  console.error("DELETING INDEX", name)
277
293
  process.nextTick(() => {
278
294
  if(!config) {
package/lib/Index.js CHANGED
@@ -1,12 +1,13 @@
1
1
  const IntervalTree = require('node-interval-tree').default
2
2
  const ReactiveDao = require("@live-change/dao")
3
3
  const Table = require('./Table.js')
4
- const ScriptContext = require('./ScriptContext.js')
5
4
  const queryGet = require('./queryGet.js')
6
5
  const profileLog = require('./profileLog.js')
7
6
  const queryObservable = require('./queryObservable.js')
8
7
  const { ChangeStream } = require('./ChangeStream.js')
9
8
 
9
+ const debug = require('debug')('db')
10
+
10
11
  const opLogBatchSize = 128 /// TODO: incrase after testing
11
12
 
12
13
  class ObjectReader extends ChangeStream {
@@ -64,6 +65,7 @@ class TableReader extends ChangeStream {
64
65
  this.opLogReader = opLogReader
65
66
  this.prefix = prefix
66
67
  this.table = table
68
+ Promise.resolve(this.table).then(t=> {if(!t) throw new Error("TABLE NOT FOUND!!!")})
67
69
  this.isLog = isLog
68
70
  this.objectReaders = new Map()
69
71
  this.rangeReaders = new Map()
@@ -437,15 +439,15 @@ class Index extends Table {
437
439
  this.code = code
438
440
  }
439
441
  async startIndex() {
440
- console.log("EXECUTING INDEX CODE", this.name)
441
- this.scriptContext = new ScriptContext({
442
+ debug("EXECUTING INDEX CODE", this.name)
443
+ this.scriptContext = this.database.createScriptContext({
442
444
  /// TODO: script available routines
443
445
  })
444
446
  const queryFunction = this.scriptContext.run(this.code,`userCode:${this.database.name}/indexes/${this.name}`)
445
447
  this.codeFunction = (input, output) => queryFunction(input, output, this.params)
446
448
  this.writer = new IndexWriter(this)
447
449
  this.reader = null
448
- console.log("STARTING INDEX", this.name)
450
+ debug("STARTING INDEX", this.name)
449
451
  const lastIndexOperations = await this.opLog.rangeGet({ reverse: true, limit: 1 })
450
452
  const lastIndexOperation = lastIndexOperations[0]
451
453
  let lastUpdateTimestamp = 0
@@ -475,11 +477,11 @@ class Index extends Table {
475
477
  codePromise = this.codeFunction(this.reader, this.writer)
476
478
  //console.log("READING!")
477
479
  await this.reader.readMore()
478
- console.log("WAITING FOR CODE!", this.name)
480
+ debug("WAITING FOR CODE!", this.name)
479
481
  await codePromise
480
482
  this.state = INDEX_READY
481
483
  const startTime = Date.now()
482
- console.log("INDEX STARTED!", this.name)
484
+ debug("INDEX STARTED!", this.name)
483
485
  await this.opLog.put({
484
486
  id: ((''+startTime).padStart(16, '0'))+':000000',
485
487
  timestamp: startTime,
@@ -499,7 +501,7 @@ class Index extends Table {
499
501
  if(existingSourceInfo) return
500
502
  const newSourceInfo = { type: sourceType, name: sourceName }
501
503
  config.sources.push(newSourceInfo)
502
- console.log("NEW INDEX", this.name, "SOURCE DETECTED", sourceType, sourceName)
504
+ debug("NEW INDEX", this.name, "SOURCE DETECTED", sourceType, sourceName)
503
505
  this.configObservable.set(config)
504
506
  this.database.config.indexes[this.name] = config
505
507
  this.database.handleConfigUpdated()
@@ -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.61",
3
+ "version": "0.5.2",
4
4
  "description": "Database with observable data for live queries",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -21,25 +21,18 @@
21
21
  },
22
22
  "homepage": "https://github.com/live-change/db",
23
23
  "devDependencies": {
24
- "@live-change/db-store-level": "^0.1.14",
25
- "@live-change/db-store-lmdb": "^0.1.13",
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.2",
25
+ "@live-change/db-store-lmdb": "^0.5.2",
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
  },
40
32
  "dependencies": {
41
- "@live-change/dao": "^0.2.43",
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": "af756efb8db9ba90d79774786201cffe9c2162cf"
45
38
  }