@live-change/db 0.8.20 → 0.8.21

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
@@ -239,22 +239,23 @@ class Database {
239
239
  let code = config.code
240
240
  const params = config.parameters
241
241
  index = new Index(this, name, code, params, config)
242
+ this.indexes.set(name, index)
242
243
  try {
243
- debug("STARTING INDEX", name, "IN DATABASE", this.name)
244
244
  await index.startIndex()
245
- debug("STARTED INDEX", name, "IN DATABASE", this.name)
246
245
  } catch(error) {
247
246
  console.error("INDEX", name, "ERROR", error, "CODE:\n", code)
248
- console.error("DELETING INDEX", name)
247
+ console.error("DELETINGww INDEX", name)
249
248
  delete this.config.indexes[name]
250
249
  this.indexesListObservable.remove(name)
251
250
  if(this.onAutoRemoveIndex && config) this.onAutoRemoveIndex(name, config.uid)
251
+ console.error("DELETED INDEX", name)
252
252
  await this.saveConfig(this.config)
253
253
  throw error
254
254
  }
255
255
  this.indexes.set(name, index)
256
256
  return index
257
257
  }
258
+ await index.startPromise
258
259
  return index
259
260
  }
260
261
 
package/lib/Index.js CHANGED
@@ -25,7 +25,7 @@ class ObjectReader extends ChangeStream {
25
25
  return {
26
26
  dispose() {
27
27
  const callbackIndex = this.callbacks.indexOf(cb)
28
- if(callbackIndex == -1) throw new Error('Observer double dispose')
28
+ if(callbackIndex === -1) throw new Error('Observer double dispose')
29
29
  this.callbacks.splice(callbackIndex, 1)
30
30
  /// TODO: dispose or ignore reader somehow if no callbacks
31
31
  }
@@ -68,6 +68,8 @@ class RangeReader extends ChangeStream {
68
68
  }
69
69
  }
70
70
 
71
+ let commandsReaderCreated = false
72
+
71
73
  class TableReader extends ChangeStream {
72
74
 
73
75
  /* set opLogPromise(promise) {
@@ -93,6 +95,15 @@ class TableReader extends ChangeStream {
93
95
 
94
96
  this.readOpLog(this.opLogReader.currentKey)
95
97
 
98
+ if(table.name === 'commands') {
99
+ console.trace("TABLE READER CREATED", prefix, table.name)
100
+ if(commandsReaderCreated) {
101
+ console.error("TABLE READER CREATED TWICE!!!", prefix, table.name)
102
+ process.exit(1)
103
+ }
104
+ commandsReaderCreated = true
105
+ }
106
+
96
107
  let firstFull = 0
97
108
  /*setInterval(() => {
98
109
  if(this.opLogObservable && this.opLogObservable.list && this.opLogObservable.list.length == opLogBatchSize) {
@@ -160,8 +171,22 @@ class TableReader extends ChangeStream {
160
171
  }
161
172
  dispose() {
162
173
  this.disposed = true
163
- for(let objectReader of this.objectReaders) objectReader.dispose()
164
- for(let rangeReader of this.objectReaders) rangeReader.dispose()
174
+ for(let objectReader of this.objectReaders.values()) {
175
+ try {
176
+ objectReader.dispose()
177
+ } catch(e) {
178
+ console.error("ERROR DISPOSING OBJECT READER", objectReader)
179
+ throw e
180
+ }
181
+ }
182
+ for(let rangeReader of this.rangeReaders.values()) {
183
+ try {
184
+ rangeReader.dispose()
185
+ } catch(e) {
186
+ console.error("ERROR DISPOSING RANGE READER", rangeReader)
187
+ throw e
188
+ }
189
+ }
165
190
  }
166
191
 
167
192
  async readOpLog(key) {
@@ -205,7 +230,7 @@ class TableReader extends ChangeStream {
205
230
  putByField(field, id, object) {
206
231
  //if(this.prefix == 'table_triggers') console.log("TABLE", this.prefix, " READER PUT", object, this.disposed)
207
232
  if(this.disposed) return
208
- if(field != 'id') throw new Error("incompatible range protocol")
233
+ if(field !== 'id') throw new Error("incompatible range protocol")
209
234
  this.opLogBuffer.push(object)
210
235
  this.opLogReader.handleSignal()
211
236
  }
@@ -249,10 +274,10 @@ class TableReader extends ChangeStream {
249
274
  } else {
250
275
  const op = next.operation
251
276
  if(op) {
252
- if(op.type == 'put') {
277
+ if(op.type === 'put') {
253
278
  await this.change(op.object, op.oldObject, op.object.id, next.id)
254
279
  }
255
- if(op.type == 'delete') {
280
+ if(op.type === 'delete') {
256
281
  //console.log("DELETE CHANGE", next)
257
282
  await this.change(null, op.object, op.object.id, next.id)
258
283
  }
@@ -260,7 +285,7 @@ class TableReader extends ChangeStream {
260
285
  console.error("NULL OPERATION", next)
261
286
  }
262
287
  }
263
- if(this.opLogBuffer.length == 0 && this.opLogObservable.list.length >= opLogBatchSize) {
288
+ if(this.opLogBuffer.length === 0 && this.opLogObservable.list.length >= opLogBatchSize) {
264
289
  //console.log("ENTER OPLOG READ!")
265
290
  await this.readOpLog(this.opLogObservable.list[this.opLogObservable.list.length - 1].id)
266
291
  //console.log("READ TO RESULT, OP LOG PROMISE:", this.opLogPromise)
@@ -283,7 +308,7 @@ class OpLogReader {
283
308
  }
284
309
  table(name) {
285
310
  const prefix = 'table_'+name
286
- let reader = this.tableReaders.find(tr => tr.prefix == prefix)
311
+ let reader = this.tableReaders.find(tr => tr.prefix === prefix)
287
312
  if(!reader) {
288
313
  reader = new TableReader(this, prefix, this.database.table(name))
289
314
  this.tableReaders.push(reader)
@@ -293,7 +318,7 @@ class OpLogReader {
293
318
  }
294
319
  index(name) {
295
320
  const prefix = 'index_'+name
296
- let reader = this.tableReaders.find(tr => tr.prefix == prefix)
321
+ let reader = this.tableReaders.find(tr => tr.prefix === prefix)
297
322
  if(!reader) {
298
323
  reader = new TableReader(this, prefix, this.database.index(name))
299
324
  this.tableReaders.push(reader)
@@ -303,7 +328,7 @@ class OpLogReader {
303
328
  }
304
329
  log(name) {
305
330
  const prefix = 'log_'+name
306
- let reader = this.tableReaders.find(tr => tr.prefix == prefix)
331
+ let reader = this.tableReaders.find(tr => tr.prefix === prefix)
307
332
  if(!reader) {
308
333
  reader = new TableReader(this, prefix, this.database.log(name), true)
309
334
  this.tableReaders.push(reader)
@@ -335,7 +360,7 @@ class OpLogReader {
335
360
  //console.log("GOT NEXT KEYS")
336
361
  if(this.disposed) return
337
362
  //console.log("POSSIBLE NEXT KEYS", possibleNextKeys.map(({key, reader}) => [reader.prefix, key]))
338
- if(possibleNextKeys.length == 0) { /// It could happen when oplog is cleared
363
+ if(possibleNextKeys.length === 0) { /// It could happen when oplog is cleared
339
364
  return
340
365
  }
341
366
  let next = null
@@ -348,10 +373,10 @@ class OpLogReader {
348
373
  //console.log("NEXT KEY", next && next.reader && next.reader.prefix, next && next.key)
349
374
  const lastKey = '\xFF\xFF\xFF\xFF'
350
375
  //console.log("NEXT", !!next, "KEY", next && next.key, lastKey)
351
- if(!next || next.key == lastKey) break // nothing to read
376
+ if(!next || next.key === lastKey) break // nothing to read
352
377
  let otherReaderNext = null
353
378
  for(const possibleKey of possibleNextKeys) {
354
- if(possibleKey.reader != next.reader && possibleKey.key
379
+ if(possibleKey.reader !== next.reader && possibleKey.key
355
380
  && (!otherReaderNext || possibleKey.key < otherReaderNext.key))
356
381
  otherReaderNext = possibleKey
357
382
  }
@@ -408,9 +433,9 @@ class IndexWriter {
408
433
  this.index.put(object)
409
434
  }
410
435
  delete(object) {
411
- const id = object.id
436
+ const id = typeof object === 'string' ? object : object.id
412
437
  if(!id) throw new Error(`ID is empty ${JSON.stringify(object)}`)
413
- this.index.delete(object.id)
438
+ this.index.delete(id)
414
439
  }
415
440
  update(id, ops) {
416
441
  if(typeof id != 'string') {
@@ -463,8 +488,14 @@ class Index extends Table {
463
488
  this.codeObservable = new ReactiveDao.ObservableValue(code)
464
489
  this.params = params
465
490
  this.code = code
491
+ this.startPromise = null
466
492
  }
467
493
  async startIndex() {
494
+ if(!this.startPromise)this.startPromise = this.startIndexInternal()
495
+ return this.startPromise
496
+ }
497
+ async startIndexInternal() {
498
+ console.error("STARTING INDEX", this.name, "IN DATABASE", this.database.name)
468
499
  debug("EXECUTING INDEX CODE", this.name)
469
500
  this.scriptContext = this.database.createScriptContext({
470
501
  /// TODO: script available routines
@@ -520,6 +551,7 @@ class Index extends Table {
520
551
  type: 'indexed'
521
552
  }
522
553
  })
554
+ debug("STARTED INDEX", this.name, "IN DATABASE", this.database.name)
523
555
  }
524
556
  async deleteIndex() {
525
557
  this.reader.dispose()
package/lib/queryGet.js CHANGED
@@ -63,7 +63,7 @@ class TableReader extends ChangeStream {
63
63
  while(true) {
64
64
  objects = await (await this.#table).rangeGet(range)
65
65
  results = results.concat(await Promise.all(objects.map(object => cb(object, null, object.id, this.#time()))))
66
- if(objects.length == maxGetLimit) {
66
+ if(objects.length === maxGetLimit) {
67
67
  range.gt = objects[objects.length - 1].id
68
68
  console.log("GET LIMIT REACHED! GETTING MORE", range)
69
69
  } else {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@live-change/db",
3
- "version": "0.8.20",
3
+ "version": "0.8.21",
4
4
  "description": "Database with observable data for live queries",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -22,8 +22,8 @@
22
22
  "type": "module",
23
23
  "homepage": "https://github.com/live-change/live-change-stack",
24
24
  "devDependencies": {
25
- "@live-change/db-store-level": "^0.8.20",
26
- "@live-change/db-store-lmdb": "^0.8.20",
25
+ "@live-change/db-store-level": "0.8.21",
26
+ "@live-change/db-store-lmdb": "0.8.21",
27
27
  "minimist": ">=1.2.3",
28
28
  "next-tick": "^1.1.0",
29
29
  "rimraf": "^5.0.5",
@@ -32,9 +32,9 @@
32
32
  "websocket-extensions": ">=0.1.4"
33
33
  },
34
34
  "dependencies": {
35
- "@live-change/dao": "^0.8.20",
35
+ "@live-change/dao": "0.8.21",
36
36
  "get-random-values": "^1.2.2",
37
37
  "node-interval-tree": "^1.3.3"
38
38
  },
39
- "gitHead": "e238d89b80f45ddaf9e92bc3d07459870a14e07b"
39
+ "gitHead": "4453aa639a9fe1a857d93d73ebd28a82c97fdd87"
40
40
  }
package/LICENSE.md DELETED
@@ -1,11 +0,0 @@
1
- Copyright 2019-2024 Michał Łaszczewski
2
-
3
- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
4
-
5
- 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
6
-
7
- 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8
-
9
- 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
10
-
11
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.