diff --git a/package-lock.json b/package-lock.json index 6f3bd2ad2..c8a7906ad 100644 --- a/package-lock.json +++ b/package-lock.json @@ -37,7 +37,7 @@ "fs-native-extensions": "^1.2.7", "hypercore-crypto": "^3.4.1", "hypercore-id-encoding": "^1.3.0", - "hyperdb": "^4.5.1", + "hyperdb": "^4.7.2", "hyperdrive": "^11.8.1", "hyperswarm": "^4.7.14", "iambus": "^1.0.3", @@ -2662,10 +2662,9 @@ } }, "node_modules/hyperdb": { - "version": "4.7.1", - "resolved": "https://registry.npmjs.org/hyperdb/-/hyperdb-4.7.1.tgz", - "integrity": "sha512-HV7MdS/bzF7gkiQIom+/LsFXAkj+K0SX9cLMi1ENQsL6AcBn2pi3Dfi78c7VD+kDZU58wioaPtXt65Fol8T40A==", - "license": "Apache-2.0", + "version": "4.7.2", + "resolved": "https://registry.npmjs.org/hyperdb/-/hyperdb-4.7.2.tgz", + "integrity": "sha512-bpJzObesRzZZh44+EueZwZSILQ6jobXYUmfL5/U6zVaZRkYXfEAtPaCzX4UG8QH5yRqLpq/37exHXGzmWx71ZA==", "dependencies": { "b4a": "^1.6.6", "compact-encoding": "^2.15.0", diff --git a/package.json b/package.json index 71ac5158f..d59314dda 100644 --- a/package.json +++ b/package.json @@ -93,7 +93,7 @@ "fs-native-extensions": "^1.2.7", "hypercore-crypto": "^3.4.1", "hypercore-id-encoding": "^1.3.0", - "hyperdb": "^4.5.1", + "hyperdb": "^4.7.2", "hyperdrive": "^11.8.1", "hyperswarm": "^4.7.14", "iambus": "^1.0.3", diff --git a/spec/db/index.js b/spec/db/index.js index e9865134d..6dab0d5dd 100644 --- a/spec/db/index.js +++ b/spec/db/index.js @@ -3,7 +3,7 @@ const { IndexEncoder, c } = require('hyperdb/runtime') -const { version, resolveStruct } = require('./messages.js') +const { version, getEncoding, setVersion } = require('./messages.js') const helpers0 = require('../helpers.js') @@ -15,10 +15,14 @@ function collection0_indexify (record) { return [] } +// '@pear/dht' value encoding +const collection0_enc = getEncoding('@pear/dht') + // '@pear/dht' reconstruction function function collection0_reconstruct (version, keyBuf, valueBuf) { - const value = c.decode(resolveStruct('@pear/dht/value', version), valueBuf) - return value + setVersion(version) + const record = c.decode(collection0_enc, valueBuf) + return record } // '@pear/dht' key reconstruction function function collection0_reconstruct_key (keyBuf) { @@ -42,7 +46,8 @@ const collection0 = { }) }, encodeValue (version, record) { - return c.encode(resolveStruct('@pear/dht/value', version), record) + setVersion(version) + return c.encode(collection0_enc, record) }, trigger: null, reconstruct: collection0_reconstruct, @@ -60,15 +65,16 @@ function collection1_indexify (record) { return a === undefined ? [] : [a] } +// '@pear/bundle' value encoding +const collection1_enc = getEncoding('@pear/bundle/hyperdb#1') + // '@pear/bundle' reconstruction function function collection1_reconstruct (version, keyBuf, valueBuf) { const key = collection1_key.decode(keyBuf) - const value = c.decode(resolveStruct('@pear/bundle/value', version), valueBuf) - // TODO: This should be fully code generated - return { - link: key[0], - ...value - } + setVersion(version) + const record = c.decode(collection1_enc, valueBuf) + record.link = key[0] + return record } // '@pear/bundle' key reconstruction function function collection1_reconstruct_key (keyBuf) { @@ -95,7 +101,8 @@ const collection1 = { }) }, encodeValue (version, record) { - return c.encode(resolveStruct('@pear/bundle/value', version), record) + setVersion(version) + return c.encode(collection1_enc, record) }, trigger: null, reconstruct: collection1_reconstruct, diff --git a/spec/db/messages.js b/spec/db/messages.js index 74fa3ecd6..5c15697bc 100644 --- a/spec/db/messages.js +++ b/spec/db/messages.js @@ -20,14 +20,13 @@ const encoding0 = { c.uint.encode(state, m.port) }, decode (state) { - const res = {} - res.host = null - res.port = 0 + const r0 = c.string.decode(state) + const r1 = c.uint.decode(state) - res.host = c.string.decode(state) - res.port = c.uint.decode(state) - - return res + return { + host: r0, + port: r1 + } } } @@ -37,29 +36,23 @@ const encoding1_0 = c.frame(c.array(encoding0)) // @pear/dht const encoding1 = { preencode (state, m) { - let flags = 0 - if (m.nodes) flags |= 1 - - c.uint.preencode(state, flags) + state.end++ // max flag is 1 so always one byte if (m.nodes) encoding1_0.preencode(state, m.nodes) }, encode (state, m) { - let flags = 0 - if (m.nodes) flags |= 1 + const flags = m.nodes ? 1 : 0 c.uint.encode(state, flags) if (m.nodes) encoding1_0.encode(state, m.nodes) }, decode (state) { - const res = {} - res.nodes = null + const flags = c.uint.decode(state) - const flags = state.start < state.end ? c.uint.decode(state) : 0 - if ((flags & 1) !== 0) res.nodes = encoding1_0.decode(state) - - return res + return { + nodes: (flags & 1) !== 0 ? encoding1_0.decode(state) : null + } } } @@ -69,21 +62,17 @@ const encoding2_3 = c.array(c.string) // @pear/bundle const encoding2 = { preencode (state, m) { - let flags = 0 - if (m.encryptionKey) flags |= 1 - if (m.tags) flags |= 2 - c.string.preencode(state, m.link) c.string.preencode(state, m.appStorage) - c.uint.preencode(state, flags) + state.end++ // max flag is 2 so always one byte if (m.encryptionKey) c.fixed32.preencode(state, m.encryptionKey) if (m.tags) encoding2_3.preencode(state, m.tags) }, encode (state, m) { - let flags = 0 - if (m.encryptionKey) flags |= 1 - if (m.tags) flags |= 2 + const flags = + (m.encryptionKey ? 1 : 0) | + (m.tags ? 2 : 0) c.string.encode(state, m.link) c.string.encode(state, m.appStorage) @@ -93,111 +82,87 @@ const encoding2 = { if (m.tags) encoding2_3.encode(state, m.tags) }, decode (state) { - const res = {} - res.link = null - res.appStorage = null - res.encryptionKey = null - res.tags = null - - res.link = c.string.decode(state) - res.appStorage = c.string.decode(state) - - const flags = state.start < state.end ? c.uint.decode(state) : 0 - if ((flags & 1) !== 0) res.encryptionKey = c.fixed32.decode(state) - if ((flags & 2) !== 0) res.tags = encoding2_3.decode(state) - - return res + const r0 = c.string.decode(state) + const r1 = c.string.decode(state) + const flags = c.uint.decode(state) + + return { + link: r0, + appStorage: r1, + encryptionKey: (flags & 1) !== 0 ? c.fixed32.decode(state) : null, + tags: (flags & 2) !== 0 ? encoding2_3.decode(state) : null + } } } -// @pear/dht/value.nodes -const encoding3_0 = c.frame(c.array(encoding0)) +// @pear/bundle/hyperdb#1.tags +const encoding3_3 = c.array(c.string) -// @pear/dht/value +// @pear/bundle/hyperdb#1 const encoding3 = { preencode (state, m) { - let flags = 0 - if (m.nodes) flags |= 1 - - c.uint.preencode(state, flags) - - if (m.nodes) encoding3_0.preencode(state, m.nodes) - }, - encode (state, m) { - let flags = 0 - if (m.nodes) flags |= 1 - - c.uint.encode(state, flags) - - if (m.nodes) encoding3_0.encode(state, m.nodes) - }, - decode (state) { - const res = {} - res.nodes = null - - const flags = state.start < state.end ? c.uint.decode(state) : 0 - if ((flags & 1) !== 0) res.nodes = encoding3_0.decode(state) - - return res - } -} - -// @pear/bundle/value.tags -const encoding4_2 = c.array(c.string) - -// @pear/bundle/value -const encoding4 = { - preencode (state, m) { - let flags = 0 - if (m.encryptionKey) flags |= 1 - if (m.tags) flags |= 2 - c.string.preencode(state, m.appStorage) - c.uint.preencode(state, flags) + state.end++ // max flag is 2 so always one byte if (m.encryptionKey) c.fixed32.preencode(state, m.encryptionKey) - if (m.tags) encoding4_2.preencode(state, m.tags) + if (m.tags) encoding3_3.preencode(state, m.tags) }, encode (state, m) { - let flags = 0 - if (m.encryptionKey) flags |= 1 - if (m.tags) flags |= 2 + const flags = + (m.encryptionKey ? 1 : 0) | + (m.tags ? 2 : 0) c.string.encode(state, m.appStorage) c.uint.encode(state, flags) if (m.encryptionKey) c.fixed32.encode(state, m.encryptionKey) - if (m.tags) encoding4_2.encode(state, m.tags) + if (m.tags) encoding3_3.encode(state, m.tags) }, decode (state) { - const res = {} - res.appStorage = null - res.encryptionKey = null - res.tags = null + const r1 = c.string.decode(state) + const flags = c.uint.decode(state) + + return { + link: null, + appStorage: r1, + encryptionKey: (flags & 1) !== 0 ? c.fixed32.decode(state) : null, + tags: (flags & 2) !== 0 ? encoding3_3.decode(state) : null + } + } +} + +function setVersion (v) { + version = v +} - res.appStorage = c.string.decode(state) +function encode (name, value, v = VERSION) { + version = v + return c.encode(getEncoding(name), value) +} - const flags = state.start < state.end ? c.uint.decode(state) : 0 - if ((flags & 1) !== 0) res.encryptionKey = c.fixed32.decode(state) - if ((flags & 2) !== 0) res.tags = encoding4_2.decode(state) +function decode (name, buffer, v = VERSION) { + version = v + return c.decode(getEncoding(name), buffer) +} - return res +function getEnum (name) { + switch (name) { + default: throw new Error('Enum not found ' + name) } } -function getStructByName (name) { +function getEncoding (name) { switch (name) { case '@pear/node': return encoding0 case '@pear/dht': return encoding1 case '@pear/bundle': return encoding2 - case '@pear/dht/value': return encoding3 - case '@pear/bundle/value': return encoding4 + case '@pear/bundle/hyperdb#1': return encoding3 default: throw new Error('Encoder not found ' + name) } } -function resolveStruct (name, v = VERSION) { - const enc = getStructByName(name) +function getStruct (name, v = VERSION) { + const enc = getEncoding(name) return { preencode (state, m) { version = v @@ -214,4 +179,4 @@ function resolveStruct (name, v = VERSION) { } } -module.exports = { resolveStruct, version } +module.exports = { resolveStruct: getStruct, getStruct, getEnum, getEncoding, encode, decode, setVersion, version } diff --git a/spec/schema/index.js b/spec/schema/index.js index ea3547eb9..a1248e211 100644 --- a/spec/schema/index.js +++ b/spec/schema/index.js @@ -20,14 +20,13 @@ const encoding0 = { c.uint.encode(state, m.port) }, decode (state) { - const res = {} - res.host = null - res.port = 0 + const r0 = c.string.decode(state) + const r1 = c.uint.decode(state) - res.host = c.string.decode(state) - res.port = c.uint.decode(state) - - return res + return { + host: r0, + port: r1 + } } } @@ -37,29 +36,23 @@ const encoding1_0 = c.frame(c.array(encoding0)) // @pear/dht const encoding1 = { preencode (state, m) { - let flags = 0 - if (m.nodes) flags |= 1 - - c.uint.preencode(state, flags) + state.end++ // max flag is 1 so always one byte if (m.nodes) encoding1_0.preencode(state, m.nodes) }, encode (state, m) { - let flags = 0 - if (m.nodes) flags |= 1 + const flags = m.nodes ? 1 : 0 c.uint.encode(state, flags) if (m.nodes) encoding1_0.encode(state, m.nodes) }, decode (state) { - const res = {} - res.nodes = null - - const flags = state.start < state.end ? c.uint.decode(state) : 0 - if ((flags & 1) !== 0) res.nodes = encoding1_0.decode(state) + const flags = c.uint.decode(state) - return res + return { + nodes: (flags & 1) !== 0 ? encoding1_0.decode(state) : null + } } } @@ -69,21 +62,17 @@ const encoding2_3 = c.array(c.string) // @pear/bundle const encoding2 = { preencode (state, m) { - let flags = 0 - if (m.encryptionKey) flags |= 1 - if (m.tags) flags |= 2 - c.string.preencode(state, m.link) c.string.preencode(state, m.appStorage) - c.uint.preencode(state, flags) + state.end++ // max flag is 2 so always one byte if (m.encryptionKey) c.fixed32.preencode(state, m.encryptionKey) if (m.tags) encoding2_3.preencode(state, m.tags) }, encode (state, m) { - let flags = 0 - if (m.encryptionKey) flags |= 1 - if (m.tags) flags |= 2 + const flags = + (m.encryptionKey ? 1 : 0) | + (m.tags ? 2 : 0) c.string.encode(state, m.link) c.string.encode(state, m.appStorage) @@ -93,24 +82,40 @@ const encoding2 = { if (m.tags) encoding2_3.encode(state, m.tags) }, decode (state) { - const res = {} - res.link = null - res.appStorage = null - res.encryptionKey = null - res.tags = null + const r0 = c.string.decode(state) + const r1 = c.string.decode(state) + const flags = c.uint.decode(state) + + return { + link: r0, + appStorage: r1, + encryptionKey: (flags & 1) !== 0 ? c.fixed32.decode(state) : null, + tags: (flags & 2) !== 0 ? encoding2_3.decode(state) : null + } + } +} - res.link = c.string.decode(state) - res.appStorage = c.string.decode(state) +function setVersion (v) { + version = v +} - const flags = state.start < state.end ? c.uint.decode(state) : 0 - if ((flags & 1) !== 0) res.encryptionKey = c.fixed32.decode(state) - if ((flags & 2) !== 0) res.tags = encoding2_3.decode(state) +function encode (name, value, v = VERSION) { + version = v + return c.encode(getEncoding(name), value) +} - return res +function decode (name, buffer, v = VERSION) { + version = v + return c.decode(getEncoding(name), buffer) +} + +function getEnum (name) { + switch (name) { + default: throw new Error('Enum not found ' + name) } } -function getStructByName (name) { +function getEncoding (name) { switch (name) { case '@pear/node': return encoding0 case '@pear/dht': return encoding1 @@ -119,8 +124,8 @@ function getStructByName (name) { } } -function resolveStruct (name, v = VERSION) { - const enc = getStructByName(name) +function getStruct (name, v = VERSION) { + const enc = getEncoding(name) return { preencode (state, m) { version = v @@ -137,4 +142,4 @@ function resolveStruct (name, v = VERSION) { } } -module.exports = { resolveStruct, version } +module.exports = { resolveStruct: getStruct, getStruct, getEnum, getEncoding, encode, decode, setVersion, version }