diff --git a/README.md b/README.md index eeb1387..a380487 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ An in-progress offline map style and tile server for Mapeo. -`npm install @mapeo/map-server better-sqlite3` +`npm install @mapeo/map-server` _⚠️ This is alpha software. No guarantees can be made about the stability of the API at the moment, so proceed with caution. 😄_ @@ -25,8 +25,6 @@ _⚠️ This is alpha software. No guarantees can be made about the stability of The default export is a factory function for creating a map server instance, which is built on top of [Fastify](https://www.fastify.io/). Basic usage is as follows: ```js -// better-sqlite3 is a peer dependency and must be installed manually. -const Database = require('better-sqlite3') // If you're using TypeScript, you may want to use one of the following import syntaxes to get type definitions: // - `require('@mapeo/map-server').default` // - `import createMapServer from '@mapeo/map-server' @@ -35,7 +33,7 @@ const createMapServer = require('@mapeo/map-server') // Create the server instance const mapServer = createMapServer( { logger: true }, - { database: new Database('./example.db') } + { storagePath: './map-server-example.db' } ) // Run the server! @@ -53,7 +51,7 @@ Creates the map server instance - `fastifyOpts (optional)`: Options object to customize the Fastify instance. Refer to the [official Fastify documentation](https://www.fastify.io/docs/latest/Reference/Server/) for more details. - `mapServerOpts (required)`: Options object to customize the map server instance. Options include: - - `database: BetterSqlite3.Database (required)`: [BetterSqlite3](https://github.com/WiseLibs/better-sqlite3) database instance representing the SQLite database to use. + - `storagePath: string (required)`: Path to use for persistent map server storage. Happens to be a SQLite database under the hood, but consumers should treat this as an opaque path managed exclusively by the map server. ## API Documentation diff --git a/package-lock.json b/package-lock.json index c2f3484..a82e28d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,6 +18,7 @@ "@types/readable-stream": "^2.3.15", "ajv": "^8.11.0", "base32.js": "^0.1.0", + "better-sqlite3": "^8.7.0", "fastify": "^3.29.0", "fastify-plugin": "^3.0.1", "got": "^11.8.5", @@ -46,7 +47,6 @@ "@types/uuid": "^8.3.4", "@typescript-eslint/eslint-plugin": "^5.43.0", "@typescript-eslint/parser": "^5.43.0", - "better-sqlite3": "^8.7.0", "c8": "^7.12.0", "eslint": "^8.2.0", "eslint-config-prettier": "^8.3.0", @@ -71,9 +71,6 @@ }, "engines": { "node": ">=16.17.1" - }, - "peerDependencies": { - "better-sqlite3": ">=8.7.0" } }, "node_modules/@ampproject/remapping": { @@ -4165,7 +4162,6 @@ "version": "8.7.0", "resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-8.7.0.tgz", "integrity": "sha512-99jZU4le+f3G6aIl6PmmV0cxUIWqKieHxsiF7G34CVFiE+/UabpYqkU0NJIkY/96mQKikHeBjtR27vFfs5JpEw==", - "dev": true, "hasInstallScript": true, "dependencies": { "bindings": "^1.5.0", @@ -4185,7 +4181,6 @@ "version": "1.5.0", "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "dev": true, "dependencies": { "file-uri-to-path": "1.0.0" } @@ -4194,7 +4189,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "dev": true, "dependencies": { "buffer": "^5.5.0", "inherits": "^2.0.4", @@ -4205,7 +4199,6 @@ "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -4297,7 +4290,6 @@ "version": "5.7.0", "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.0.tgz", "integrity": "sha512-cd+5r1VLBwUqTrmnzW+D7ABkJUM6mr7uv1dv+6jRw4Rcl7tFIFHDqHPL98LhpGFn3dbAt3gtLxtrWp4m1kFrqg==", - "dev": true, "funding": [ { "type": "github", @@ -4732,8 +4724,7 @@ "node_modules/chownr": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" }, "node_modules/ci-info": { "version": "2.0.0", @@ -7331,7 +7322,6 @@ "version": "0.6.0", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true, "engines": { "node": ">=4.0.0" } @@ -7500,7 +7490,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz", "integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==", - "dev": true, "engines": { "node": ">=8" } @@ -8582,7 +8571,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", - "dev": true, "engines": { "node": ">=6" } @@ -9011,8 +8999,7 @@ "node_modules/file-uri-to-path": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "dev": true + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" }, "node_modules/fill-range": { "version": "7.0.1", @@ -9237,8 +9224,7 @@ "node_modules/fs-constants": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "dev": true + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" }, "node_modules/fs-extra": { "version": "7.0.1", @@ -9592,8 +9578,7 @@ "node_modules/github-from-package": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", - "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==", - "dev": true + "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==" }, "node_modules/glob": { "version": "7.1.6", @@ -10292,7 +10277,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true, "funding": [ { "type": "github", @@ -10385,8 +10369,7 @@ "node_modules/ini": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" }, "node_modules/internal-slot": { "version": "1.0.6", @@ -13810,8 +13793,7 @@ "node_modules/mkdirp-classic": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", - "dev": true + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" }, "node_modules/mock-property": { "version": "1.0.3", @@ -13904,8 +13886,7 @@ "node_modules/napi-build-utils": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", - "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==", - "dev": true + "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==" }, "node_modules/natural-compare": { "version": "1.4.0", @@ -13973,7 +13954,6 @@ "version": "3.31.0", "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.31.0.tgz", "integrity": "sha512-eSKV6s+APenqVh8ubJyiu/YhZgxQpGP66ntzUb3lY1xB9ukSRaGnx0AIxI+IM+1+IVYC1oWobgG5L3Lt9ARykQ==", - "dev": true, "dependencies": { "semver": "^7.3.5" }, @@ -13985,7 +13965,6 @@ "version": "7.3.8", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", - "dev": true, "dependencies": { "lru-cache": "^6.0.0" }, @@ -14850,7 +14829,6 @@ "version": "7.1.1", "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz", "integrity": "sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==", - "dev": true, "dependencies": { "detect-libc": "^2.0.0", "expand-template": "^2.0.3", @@ -15621,7 +15599,6 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dev": true, "dependencies": { "deep-extend": "^0.6.0", "ini": "~1.3.0", @@ -16682,7 +16659,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", - "dev": true, "funding": [ { "type": "github", @@ -16702,7 +16678,6 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", - "dev": true, "funding": [ { "type": "github", @@ -17556,7 +17531,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -17843,7 +17817,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", - "dev": true, "dependencies": { "chownr": "^1.1.1", "mkdirp-classic": "^0.5.2", @@ -17855,7 +17828,6 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", - "dev": true, "dependencies": { "bl": "^4.0.3", "end-of-stream": "^1.4.1", @@ -17871,7 +17843,6 @@ "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -18396,7 +18367,6 @@ "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", - "dev": true, "dependencies": { "safe-buffer": "^5.0.1" }, diff --git a/package.json b/package.json index 4df15cc..00052a6 100644 --- a/package.json +++ b/package.json @@ -45,6 +45,7 @@ "@types/readable-stream": "^2.3.15", "ajv": "^8.11.0", "base32.js": "^0.1.0", + "better-sqlite3": "^8.7.0", "fastify": "^3.29.0", "fastify-plugin": "^3.0.1", "got": "^11.8.5", @@ -56,9 +57,6 @@ "readable-stream": "^3.6.0", "uuid": "^8.3.2" }, - "peerDependencies": { - "better-sqlite3": ">=8.7.0" - }, "devDependencies": { "@fastify/etag": "^3.0.0", "@mapbox/point-geometry": "^0.1.0", @@ -76,7 +74,6 @@ "@types/uuid": "^8.3.4", "@typescript-eslint/eslint-plugin": "^5.43.0", "@typescript-eslint/parser": "^5.43.0", - "better-sqlite3": "^8.7.0", "c8": "^7.12.0", "eslint": "^8.2.0", "eslint-config-prettier": "^8.3.0", diff --git a/server.ts b/server.ts index 1ffe8f2..7ea0b24 100644 --- a/server.ts +++ b/server.ts @@ -1,10 +1,9 @@ import 'make-promises-safe' -import Database from 'better-sqlite3' import createMapServer, { MapServerOptions } from './src/app' const mapServerOpts: MapServerOptions = { - database: new Database('./example.db'), + storagePath: './example.db', } // Require the framework and instantiate it diff --git a/src/api/index.ts b/src/api/index.ts index 225491f..635d424 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -1,4 +1,4 @@ -import type { Database } from 'better-sqlite3' +import Database, { type Database as DatabaseInstance } from 'better-sqlite3' import { FastifyPluginAsync } from 'fastify' import fp from 'fastify-plugin' import path from 'path' @@ -16,12 +16,12 @@ import createTilesApi, { TilesApi } from './tiles' import createTilesetsApi, { TilesetsApi } from './tilesets' export interface MapServerOptions { - database: Database + storagePath: string } export interface Context { activeImports: Map - db: Database + db: DatabaseInstance piscina: Piscina upstreamRequestsManager: UpstreamRequestsManager } @@ -81,7 +81,9 @@ function createApi(context: Context): Api { } } -function init(db: Database): Context { +function init(storagePath: string): Context { + const db = new Database(storagePath) + // Enable auto-vacuum by setting it to incremental mode // This has to be set before the anything on the db instance is called! // https://www.sqlite.org/pragma.html#pragma_auto_vacuum @@ -118,15 +120,10 @@ function init(db: Database): Context { const ApiPlugin: FastifyPluginAsync = async ( fastify, - { database } + { storagePath } ) => { - if (database == null) - throw new Error( - `Instance of BetterSqlite3.Database must be specified for 'database' option (https://github.com/WiseLibs/better-sqlite3/blob/master/docs/api.md#class-database)` - ) - // Create context once for each fastify instance - const context = init(database) + const context = init(storagePath) const api = createApi(context) diff --git a/test/test-helpers/create-server.js b/test/test-helpers/create-server.js index f68b67a..5d25983 100644 --- a/test/test-helpers/create-server.js +++ b/test/test-helpers/create-server.js @@ -1,7 +1,6 @@ const tmp = require('tmp') const path = require('path') const fs = require('fs') -const Db = require('better-sqlite3') const createMapServer = require('../..') @@ -23,11 +22,11 @@ module.exports = createServer function createServer(t) { const { name: dataDir, removeCallback } = tmp.dirSync({ unsafeCleanup: true }) - const dbPath = path.resolve(dataDir, 'test.db') + const storagePath = path.resolve(dataDir, 'test.db') const server = createMapServer( { logger: false, forceCloseConnections: true }, - { database: new Db(dbPath) } + { storagePath }, ) t.teardown(async () => {