Break into separate source files per object
authorNick Downing <nick@ndcode.org>
Fri, 7 Jan 2022 05:27:22 +0000 (16:27 +1100)
committerNick Downing <nick@ndcode.org>
Fri, 7 Jan 2022 05:27:22 +0000 (16:27 +1100)
CachedValue.mjs [new file with mode: 0644]
Database.mjs [moved from logjson.mjs with 51% similarity]
Lazy.mjs [new file with mode: 0644]
LazyArray.mjs [new file with mode: 0644]
LazyObject.mjs [new file with mode: 0644]
Transaction.mjs [new file with mode: 0644]
index.mjs [new file with mode: 0644]
tests/a.mjs
tests/b.mjs

diff --git a/CachedValue.mjs b/CachedValue.mjs
new file mode 100644 (file)
index 0000000..3caab66
--- /dev/null
@@ -0,0 +1,9 @@
+class CachedValue {
+  constructor(refs, value, stale_count) {
+    this.refs = refs
+    this.value = value
+    this.stale_count = stale_count
+  }
+}
+
+export default CachedValue
similarity index 51%
rename from logjson.mjs
rename to Database.mjs
index ccbe174..d3f9af3 100644 (file)
@@ -1,14 +1,8 @@
 import assert from 'assert'
 import fsPromises from 'fs/promises'
+import CachedValue from './CachedValue.mjs'
 import Mutex from './Mutex.mjs'
-
-class CachedValue {
-  constructor(refs, value, stale_count) {
-    this.refs = refs
-    this.value = value
-    this.stale_count = stale_count
-  }
-}
+import Transaction from './Transaction.mjs'
 
 let open_angle = Buffer.from('\n<', 'utf-8')
 let close_angle = Buffer.from('>\n', 'utf-8')
@@ -267,299 +261,4 @@ class Database {
   }
 }
 
-class Transaction {
-  constructor(database, value) {
-    assert(database instanceof Database)
-    this.database = database
-    this.dirty = false
-    this.value = value
-  }
-
-  async read(ptr_len) {
-    let value = await this.database.read(ptr_len)
-    if (typeof value === 'object' && value !== null)
-      value =
-        value instanceof Array ?
-          new LazyArray(this, ptr_len, value) :
-          new LazyObject(this, ptr_len, value)
-    return value
-  }
-
-  async get(default_value) {
-    if (this.value === undefined) {
-      if (default_value === undefined)
-        return undefined
-      set(default_value)
-    }
-
-    if (this.value instanceof Array)
-      this.value = this.read(this.value)
-    return this.value
-  }
-
-  set(value) {
-    this.dirty = true
-    assert(
-      typeof value !== 'object' ||
-      value === null ||
-      (value instanceof Lazy && value.transaction === this)
-    )
-    this.value = value
-  }
-
-  async commit() {
-    assert(this.value !== undefined)
-
-    if (this.value instanceof Lazy) {
-      if (await this.value.commit())
-        this.dirty = true
-      this.value = this.value.ptr_len
-    }
-
-    if (this.dirty) {
-      this.database.write_root(this.value)
-      this.database.value = this.value
-    }
-
-    if (
-      this.database.eof1 > this.database.eof &&
-      this.database.write_count === 0
-    ) {
-      if (this.database.write_timeout === 0)
-        await this.database.flush()
-      else
-        this.database.write_count = this.database.write_timeout
-    }
-
-    this.database.mutex.release()
-  }
-
-  rollback() {
-    this.database.mutex.release()
-  }
-
-  LazyArray(...args) {
-    return new LazyArray(this, null, ...args)
-  }
-
-  LazyObject(...args) {
-    return new LazyObject(this, null, ...args)
-  }
-
-  json_to_logjson(value) {
-    if (typeof value === 'object' && value !== null) {
-      let new_value
-      if (value instanceof Array) {
-        new_value = new LazyArray(this)
-        for (let i = 0; i < value.length; ++i)
-          new_value.push(this.json_to_logjson(value[i]))
-      }
-      else {
-        new_value = new LazyObject(this)
-        for (let i in value)
-          new_value.set(i, this.json_to_logjson(value[i]))
-      }
-      value = new_value
-    }
-    return value
-  }
-}
-
-// logjson array or object
-class Lazy {
-  constructor(transaction, ptr_len) {
-    assert(transaction instanceof Transaction)
-    this.transaction = transaction
-    this.ptr_len = ptr_len || null
-  }
-
-  has(key) {
-    throw new Error('not implemented')
-  }
-
-  async get(key, default_value) {
-    throw new Error('not implemented')
-  }
-
-  set(key, value) {
-    throw new Error('not implemented')
-  }
-
-  delete(key) {
-    throw new Error('not implemented')
-  }
-
-  async commit() {
-    throw new Error('not implemented')
-  }
-}
-
-class LazyArray extends Lazy {
-  constructor(transaction, ptr_len, array) {
-    super(transaction, ptr_len)
-    this.array = array || []
-    this.length = this.array.length
-  }
-
-  has(key) {
-    assert(typeof key === 'number')
-    return key >= 0 && key < this.length
-  }
-
-  async get(key, default_value) {
-    assert(typeof key === 'number')
-    if (key < 0 || key >= this.length) {
-      if (default_value === undefined)
-        return undefined
-      set(key, default_value)
-    }
-
-    let value = this.array[key]
-    if (value instanceof Array) {
-      value = this.transaction.read(value)
-      this.array[key] = value
-    }
-    return value
-  }
-
-  set(key, value) {
-    assert(typeof key === 'number')
-    assert(
-      typeof value !== 'object' ||
-      value === null ||
-      (value instanceof Lazy && value.transaction === this.transaction)
-    )
-    this.ptr_len = null // mark dirty
-    this.array[key] = value
-    this.length = this.array.length
-  }
-
-  delete(key) {
-    delete this.array[key]
-  }
-
-  push(value) {
-    this.set(this.length, value)
-  }
-
-  async pop() {
-    assert(this.length)
-    this.length -= 1
-    let value = await this.get(this.length)
-    this.delete(this.length)
-    return value
-  }
-
-  async commit() {
-    for (let i = 0; i < this.length; ++i) {
-      let value = this.array[i]
-      if (value instanceof Lazy) {
-        if (await value.commit())
-          this.ptr_len = null // mark dirty
-        this.array[i] = value.ptr_len
-      }
-    }
-
-    if (this.ptr_len === null) {
-      this.ptr_len = this.transaction.database.write(this.array)
-      return true
-    }
-    return false
-  }
-}
-
-class LazyObject extends Lazy {
-  constructor(transaction, ptr_len, object) {
-    super(transaction, ptr_len)
-    this.object = object || {}
-  }
-
-  has(key) {
-    assert(typeof key === 'string')
-    return Object.prototype.hasOwnProperty.call(this.object, key)
-  }
-
-  async get(key, default_value) {
-    assert(typeof key === 'string')
-    if (!Object.prototype.hasOwnProperty.call(this.object, key)) {
-      if (default_value === undefined)
-        return undefined
-      set(key, default_value)
-    }
-
-    let value = this.object[key]
-    if (value instanceof Array) {
-      value = this.transaction.read(value)
-      this.object[key] = value
-    }
-    return value
-  }
-
-  set(key, value) {
-    assert(typeof key === 'string')
-    assert(
-      typeof value !== 'object' ||
-      value === null ||
-      (value instanceof Lazy && value.transaction === this.transaction)
-    )
-    this.ptr_len = null // mark dirty
-    this.object[key] = value
-  }
-
-  delete(key) {
-    delete this.object[key]
-  }
-
-  keys() {
-    let keys = []
-    for (let i in this.object)
-      keys.push(i)
-    return keys
-  }
-
-  async commit() {
-    for (let i in this.object) {
-      let value = this.object[i]
-      if (value instanceof Lazy) {
-        if (await value.commit())
-          this.ptr_len = null // mark dirty
-        this.object[i] = value.ptr_len
-      }
-    }
-
-    if (this.ptr_len === null) {
-      this.ptr_len = this.transaction.database.write(this.object)
-      return true
-    }
-    return false
-  }
-}
-
-let logjson_to_json = async value => {
-  if (value instanceof Lazy) {
-    let new_value
-    if (value instanceof LazyArray) {
-      new_value = []
-      for (let i = 0; i < value.length; ++i)
-        new_value.push(await logjson_to_json(await value.get(i)))
-    }
-    else {
-      new_value = {}
-      let keys = value.keys()
-      for (let i = 0; i < keys.length; ++i) {
-        let key = keys[i]
-        new_value[key] = await logjson_to_json(await value.get(key))
-      }
-    }
-    value = new_value
-  }
-  return value
-}
-
-export default {
-  Database,
-  Lazy,
-  LazyArray,
-  LazyObject,
-  logjson_to_json
-}
+export default Database
diff --git a/Lazy.mjs b/Lazy.mjs
new file mode 100644 (file)
index 0000000..4bc36b9
--- /dev/null
+++ b/Lazy.mjs
@@ -0,0 +1,32 @@
+import assert from 'assert'
+import Transaction from './Transaction.mjs'
+
+class Lazy {
+  constructor(transaction, ptr_len) {
+    assert(transaction instanceof Transaction)
+    this.transaction = transaction
+    this.ptr_len = ptr_len || null
+  }
+
+  has(key) {
+    throw new Error('not implemented')
+  }
+
+  async get(key, default_value) {
+    throw new Error('not implemented')
+  }
+
+  set(key, value) {
+    throw new Error('not implemented')
+  }
+
+  delete(key) {
+    throw new Error('not implemented')
+  }
+
+  async commit() {
+    throw new Error('not implemented')
+  }
+}
+
+export default Lazy
diff --git a/LazyArray.mjs b/LazyArray.mjs
new file mode 100644 (file)
index 0000000..e6bbf50
--- /dev/null
@@ -0,0 +1,78 @@
+import assert from 'assert'
+import Lazy from './Lazy.mjs'
+
+class LazyArray extends Lazy {
+  constructor(transaction, ptr_len, array) {
+    super(transaction, ptr_len)
+    this.array = array || []
+    this.length = this.array.length
+  }
+
+  has(key) {
+    assert(typeof key === 'number')
+    return key >= 0 && key < this.length
+  }
+
+  async get(key, default_value) {
+    assert(typeof key === 'number')
+    if (key < 0 || key >= this.length) {
+      if (default_value === undefined)
+        return undefined
+      set(key, default_value)
+    }
+
+    let value = this.array[key]
+    if (value instanceof Array) {
+      value = this.transaction.read(value)
+      this.array[key] = value
+    }
+    return value
+  }
+
+  set(key, value) {
+    assert(typeof key === 'number')
+    assert(
+      typeof value !== 'object' ||
+      value === null ||
+      (value instanceof Lazy && value.transaction === this.transaction)
+    )
+    this.ptr_len = null // mark dirty
+    this.array[key] = value
+    this.length = this.array.length
+  }
+
+  delete(key) {
+    delete this.array[key]
+  }
+
+  push(value) {
+    this.set(this.length, value)
+  }
+
+  async pop() {
+    assert(this.length)
+    this.length -= 1
+    let value = await this.get(this.length)
+    this.delete(this.length)
+    return value
+  }
+
+  async commit() {
+    for (let i = 0; i < this.length; ++i) {
+      let value = this.array[i]
+      if (value instanceof Lazy) {
+        if (await value.commit())
+          this.ptr_len = null // mark dirty
+        this.array[i] = value.ptr_len
+      }
+    }
+
+    if (this.ptr_len === null) {
+      this.ptr_len = this.transaction.database.write(this.array)
+      return true
+    }
+    return false
+  }
+}
+
+export default LazyArray
diff --git a/LazyObject.mjs b/LazyObject.mjs
new file mode 100644 (file)
index 0000000..fb48c8a
--- /dev/null
@@ -0,0 +1,71 @@
+import assert from 'assert'
+import Lazy from './Lazy.mjs'
+
+class LazyObject extends Lazy {
+  constructor(transaction, ptr_len, object) {
+    super(transaction, ptr_len)
+    this.object = object || {}
+  }
+
+  has(key) {
+    assert(typeof key === 'string')
+    return Object.prototype.hasOwnProperty.call(this.object, key)
+  }
+
+  async get(key, default_value) {
+    assert(typeof key === 'string')
+    if (!Object.prototype.hasOwnProperty.call(this.object, key)) {
+      if (default_value === undefined)
+        return undefined
+      set(key, default_value)
+    }
+
+    let value = this.object[key]
+    if (value instanceof Array) {
+      value = this.transaction.read(value)
+      this.object[key] = value
+    }
+    return value
+  }
+
+  set(key, value) {
+    assert(typeof key === 'string')
+    assert(
+      typeof value !== 'object' ||
+      value === null ||
+      (value instanceof Lazy && value.transaction === this.transaction)
+    )
+    this.ptr_len = null // mark dirty
+    this.object[key] = value
+  }
+
+  delete(key) {
+    delete this.object[key]
+  }
+
+  keys() {
+    let keys = []
+    for (let i in this.object)
+      keys.push(i)
+    return keys
+  }
+
+  async commit() {
+    for (let i in this.object) {
+      let value = this.object[i]
+      if (value instanceof Lazy) {
+        if (await value.commit())
+          this.ptr_len = null // mark dirty
+        this.object[i] = value.ptr_len
+      }
+    }
+
+    if (this.ptr_len === null) {
+      this.ptr_len = this.transaction.database.write(this.object)
+      return true
+    }
+    return false
+  }
+}
+
+export default LazyObject
diff --git a/Transaction.mjs b/Transaction.mjs
new file mode 100644 (file)
index 0000000..1e8160a
--- /dev/null
@@ -0,0 +1,106 @@
+import assert from 'assert'
+import fsPromises from 'fs/promises'
+import Database from './Database.mjs'
+import Lazy from './Lazy.mjs'
+import LazyArray from './LazyArray.mjs'
+import LazyObject from './LazyObject.mjs'
+
+class Transaction {
+  constructor(database, value) {
+    assert(database instanceof Database)
+    this.database = database
+    this.dirty = false
+    this.value = value
+  }
+
+  async read(ptr_len) {
+    let value = await this.database.read(ptr_len)
+    if (typeof value === 'object' && value !== null)
+      value =
+        value instanceof Array ?
+          new LazyArray(this, ptr_len, value) :
+          new LazyObject(this, ptr_len, value)
+    return value
+  }
+
+  async get(default_value) {
+    if (this.value === undefined) {
+      if (default_value === undefined)
+        return undefined
+      set(default_value)
+    }
+
+    if (this.value instanceof Array)
+      this.value = this.read(this.value)
+    return this.value
+  }
+
+  set(value) {
+    this.dirty = true
+    assert(
+      typeof value !== 'object' ||
+      value === null ||
+      (value instanceof Lazy && value.transaction === this)
+    )
+    this.value = value
+  }
+
+  async commit() {
+    assert(this.value !== undefined)
+
+    if (this.value instanceof Lazy) {
+      if (await this.value.commit())
+        this.dirty = true
+      this.value = this.value.ptr_len
+    }
+
+    if (this.dirty) {
+      this.database.write_root(this.value)
+      this.database.value = this.value
+    }
+
+    if (
+      this.database.eof1 > this.database.eof &&
+      this.database.write_count === 0
+    ) {
+      if (this.database.write_timeout === 0)
+        await this.database.flush()
+      else
+        this.database.write_count = this.database.write_timeout
+    }
+
+    this.database.mutex.release()
+  }
+
+  rollback() {
+    this.database.mutex.release()
+  }
+
+  LazyArray(...args) {
+    return new LazyArray(this, null, ...args)
+  }
+
+  LazyObject(...args) {
+    return new LazyObject(this, null, ...args)
+  }
+
+  json_to_logjson(value) {
+    if (typeof value === 'object' && value !== null) {
+      let new_value
+      if (value instanceof Array) {
+        new_value = new LazyArray(this)
+        for (let i = 0; i < value.length; ++i)
+          new_value.push(this.json_to_logjson(value[i]))
+      }
+      else {
+        new_value = new LazyObject(this)
+        for (let i in value)
+          new_value.set(i, this.json_to_logjson(value[i]))
+      }
+      value = new_value
+    }
+    return value
+  }
+}
+
+export default Transaction
diff --git a/index.mjs b/index.mjs
new file mode 100644 (file)
index 0000000..93c46bc
--- /dev/null
+++ b/index.mjs
@@ -0,0 +1,33 @@
+import Database from './Database.mjs'
+import Lazy from './Lazy.mjs'
+import LazyArray from './LazyArray.mjs'
+import LazyObject from './LazyObject.mjs'
+let logjson_to_json = async value => {
+  if (value instanceof Lazy) {
+    let new_value
+    if (value instanceof LazyArray) {
+      new_value = []
+      for (let i = 0; i < value.length; ++i)
+        new_value.push(await logjson_to_json(await value.get(i)))
+    }
+    else {
+      new_value = {}
+      let keys = value.keys()
+      for (let i = 0; i < keys.length; ++i) {
+        let key = keys[i]
+        new_value[key] = await logjson_to_json(await value.get(key))
+      }
+    }
+    value = new_value
+  }
+  return value
+}
+
+export default {
+  Database,
+  Lazy,
+  LazyArray,
+  LazyObject,
+  logjson_to_json
+}
index a591b3e..99be049 100755 (executable)
@@ -1,6 +1,6 @@
 #!/usr/bin/env node
 
-import logjson from '../logjson.mjs'
+import logjson from '../index.mjs'
 import fsPromises from 'fs/promises'
 
 let database = new logjson.Database(5, 1)
index e2afb69..7c0e591 100755 (executable)
@@ -1,6 +1,6 @@
 #!/usr/bin/env node
 
-import logjson from '../logjson.mjs'
+import logjson from '../index.mjs'
 import fsPromises from 'fs/promises'
 
 let database = new logjson.Database()