diff --git a/builder/codegen.js b/builder/codegen.js index 11ef2bf..b5fb62c 100644 --- a/builder/codegen.js +++ b/builder/codegen.js @@ -66,17 +66,20 @@ const Falsies = new Map([ ]) module.exports = function generateCode (hyperdb, { directory = '.', esm = false } = {}) { + const messagesPath = p.relative(p.resolve(directory), hyperdb.schema.dir).replaceAll('\\', '/') + let str = '' str += '// This file is autogenerated by the hyperdb compiler\n' str += '/* eslint-disable camelcase */\n' str += '\n' + if (esm) { str += `import { IndexEncoder, c } from '${pkg.name}/runtime'\n` - str += 'import { version, getEncoding, setVersion } from \'./messages.js\'\n' + str += `import { version, getEncoding, setVersion } from ${s(messagesPath)}\n` str += '\n' } else { str += `const { IndexEncoder, c } = require('${pkg.name}/runtime')\n` - str += 'const { version, getEncoding, setVersion } = require(\'./messages.js\')\n' + str += `const { version, getEncoding, setVersion } = require(${s(messagesPath)})\n` str += '\n' } @@ -86,9 +89,9 @@ module.exports = function generateCode (hyperdb, { directory = '.', esm = false addedHelper = true const helpers = p.relative(p.resolve(directory), ns.helpers).replaceAll('\\', '/') if (esm) { - str += `import * as helpers${ns.id} from '${helpers}'\n` + str += `import * as helpers${ns.id} from ${s(helpers)}\n` } else { - str += `const helpers${ns.id} = require('${helpers}')\n` + str += `const helpers${ns.id} = require(${s(helpers)})\n` } } if (addedHelper) str += '\n' diff --git a/builder/example/example.js b/builder/example/example.js index 952d150..6466a38 100644 --- a/builder/example/example.js +++ b/builder/example/example.js @@ -94,11 +94,10 @@ example.register({ ] }) -Hyperschema.toDisk(schema) +const db = HyperDB.from(DB_DIR) +db.registerSchema(schema) -const db = HyperDB.from(SCHEMA_DIR, DB_DIR) const exampleDb = db.namespace('example') - exampleDb.require('./helpers.js') exampleDb.collections.register({ @@ -153,4 +152,5 @@ exampleDb.indexes.register({ key: ['name', 'tags'] }) +Hyperschema.toDisk(schema) HyperDB.toDisk(db) diff --git a/builder/index.js b/builder/index.js index ca0f32a..19b7ce7 100644 --- a/builder/index.js +++ b/builder/index.js @@ -1,6 +1,5 @@ const p = require('path') const fs = require('fs') -const Hyperschema = require('hyperschema') const generateCode = require('./codegen') @@ -9,7 +8,6 @@ const INDEX_TYPE = 2 const DB_JSON_FILE_NAME = 'db.json' const CODE_FILE_NAME = 'index.js' -const MESSAGES_FILE_NAME = 'messages.js' class DBType { constructor (builder, namespace, description) { @@ -269,12 +267,10 @@ class BuilderNamespace { } class Builder { - constructor (schema, dbJson, { offset = 0, dbDir = null, schemaDir = null } = {}) { - this.schema = schema + constructor (dbJson, { offset = 0, dbDir = null } = {}) { this.version = dbJson ? dbJson.version : 0 this.offset = dbJson ? dbJson.offset : offset this.dbDir = dbDir - this.schemaDir = schemaDir this.namespaces = new Map() this.typesByName = new Map() @@ -311,6 +307,8 @@ class Builder { } registerCollection (description, namespace) { + if (!this.schema) throw new Error('registerSchema must be called with a Hyperschema instance before registering collections') + const fqn = getFQN(namespace, description.name) // TODO: also validate this for invalid mutations if it was hydrated from JSON if (this.typesByName.has(fqn)) return @@ -322,6 +320,8 @@ class Builder { } registerIndex (description, namespace) { + if (!this.schema) throw new Error('registerSchema must be called with a Hyperschema instance before registering collections') + const fqn = getFQN(namespace, description.name) // TODO: also validate this for invalid mutations if it was hydrated from JSON if (this.typesByName.has(fqn)) return @@ -339,6 +339,11 @@ class Builder { return ns } + registerSchema (schema) { + if (this.schema) throw new Error('Already registered a hyperschema instance') + this.schema = schema + } + toJSON () { return { version: this.version, @@ -357,17 +362,14 @@ class Builder { const { esm = this.esm } = opts - const messagesPath = p.join(p.resolve(dbDir), MESSAGES_FILE_NAME) const dbJsonPath = p.join(p.resolve(dbDir), DB_JSON_FILE_NAME) const codePath = p.join(p.resolve(dbDir), CODE_FILE_NAME) - fs.writeFileSync(messagesPath, hyperdb.schema.toCode({ esm }), { encoding: 'utf-8' }) fs.writeFileSync(dbJsonPath, JSON.stringify(hyperdb.toJSON(), null, 2), { encoding: 'utf-8' }) fs.writeFileSync(codePath, generateCode(hyperdb, { directory: dbDir, esm }), { encoding: 'utf-8' }) } - static from (schemaJson, dbJson, opts) { - const schema = Hyperschema.from(schemaJson) + static from (dbJson, opts) { if (typeof dbJson === 'string') { const jsonFilePath = p.join(p.resolve(dbJson), DB_JSON_FILE_NAME) let exists = false @@ -377,11 +379,11 @@ class Builder { } catch (err) { if (err.code !== 'ENOENT') throw err } - opts = { ...opts, dbDir: dbJson, schemaDir: schemaJson } - if (exists) return new this(schema, JSON.parse(fs.readFileSync(jsonFilePath)), opts) - return new this(schema, null, opts) + opts = { ...opts, dbDir: dbJson } + if (exists) return new this(JSON.parse(fs.readFileSync(jsonFilePath)), opts) + return new this(null, opts) } - return new this(schema, dbJson, opts) + return new this(dbJson, opts) } } diff --git a/test/indexes.js b/test/indexes.js index 881c7e8..63e0f14 100644 --- a/test/indexes.js +++ b/test/indexes.js @@ -191,9 +191,9 @@ function createExampleDB (HyperDB, Hyperschema, paths) { ] }) - Hyperschema.toDisk(schema) + const db = HyperDB.from(paths.db) + db.registerSchema(schema) - const db = HyperDB.from(paths.schema, paths.db) const exampleDB = db.namespace('example') exampleDB.require(paths.helpers) @@ -239,5 +239,6 @@ function createExampleDB (HyperDB, Hyperschema, paths) { } }) + Hyperschema.toDisk(schema) HyperDB.toDisk(db) } diff --git a/test/trigger.js b/test/trigger.js index 252fe39..ccf8e4e 100644 --- a/test/trigger.js +++ b/test/trigger.js @@ -65,11 +65,10 @@ function createExampleDB (HyperDB, Hyperschema, paths) { ] }) - Hyperschema.toDisk(schema) + const db = HyperDB.from(paths.db) + db.registerSchema(schema) - const db = HyperDB.from(paths.schema, paths.db) const exampleDB = db.namespace('example') - exampleDB.require(paths.helpers) exampleDB.collections.register({ @@ -85,5 +84,6 @@ function createExampleDB (HyperDB, Hyperschema, paths) { trigger: 'triggerCountMembers' }) + Hyperschema.toDisk(schema) HyperDB.toDisk(db) }