Skip to content

Commit

Permalink
Merge pull request #51 from seald/feat/clean-native-node-modules-imports
Browse files Browse the repository at this point in the history
Clean & document native node modules imports / polyfills
  • Loading branch information
tex0l authored Jan 11, 2024
2 parents d4c096b + 60929bb commit bc10dde
Show file tree
Hide file tree
Showing 15 changed files with 64 additions and 28 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
### Fixed
- Explicitly import `buffer` [#34](https://github.com/seald/nedb/pull/34).
- Fix `Cursor`'s typings [#45](https://github.com/seald/nedb/issues/45)
- Removes unnecessary uses of the native `path` module for the browser and React-Native version by replacing the internal `Persistance.ensureDirectoryExistsAsync` static method with `Persistance.ensureParentDirectoryExistsAsync` so that any `path` functions are used only in Node.js where it is necessary, as it is not necessary for the browser and React-Native.

## [4.0.3] - 2023-12-13
### Fixed
Expand Down Expand Up @@ -76,7 +77,7 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
- `Persistence#persistCachedDatabase` replaced with `Persistence#persistCachedDatabaseAsync`;
- `Persistence#persistNewState` replaced with `Persistence#persistNewStateAsync`;
- `Persistence#treatRawStream` replaced with `Persistence#treatRawStreamAsync`;
- `Persistence.ensureDirectoryExists` replaced with `Persistence#ensureDirectoryExistsAsync`;
- `Persistence.ensureDirectoryExists` replaced with `Persistence.ensureDirectoryExistsAsync`;
- Cursor:
- `Cursor#_exec` replaced with `Cursor#_execAsync`;
- `Cursor#project` replaced with `Cursor#_project`;
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -838,6 +838,10 @@ This is done for:
the repo because it is unmaintained). It isn't used in the browser nor
react-native versions, therefore it is shimmed with an empty object.

However, the `browser` and `react-native` versions rely on node native modules and therefore must be polyfilled:
- `util` with https://github.com/browserify/node-util.
- `events` with https://github.com/browserify/events.

## Performance

### Speed
Expand Down
3 changes: 1 addition & 2 deletions benchmarks/commonUtilities.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
* Functions that are used in several benchmark tests
*/
const fs = require('fs')
const path = require('path')
const Datastore = require('../lib/datastore')
const Persistence = require('../lib/persistence')
const { callbackify } = require('util')
Expand Down Expand Up @@ -46,7 +45,7 @@ module.exports.getConfiguration = function (benchDb) {
* Ensure the workspace stat and the db datafile is empty
*/
module.exports.prepareDb = function (filename, cb) {
callbackify((dirname) => Persistence.ensureDirectoryExistsAsync(dirname))(path.dirname(filename), function () {
callbackify((filename) => Persistence.ensureParentDirectoryExistsAsync(filename))(filename, function () {
fs.access(filename, fs.constants.FS_OK, function (err) {
if (!err) {
fs.unlink(filename, cb)
Expand Down
13 changes: 13 additions & 0 deletions browser-version/lib/storage.browser.js
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,17 @@ const unlinkAsync = async filename => {
*/
const mkdirAsync = (path, options) => Promise.resolve()

/**
* Shim for {@link module:storage.ensureParentDirectoryExistsAsync}, nothing to do, no directories will be used on the browser.
* @function
* @param {string} file
* @param {number} [mode]
* @return {Promise<void|string>}
* @alias module:storageBrowser.ensureParentDirectoryExistsAsync
* @async
*/
const ensureParentDirectoryExistsAsync = async (file, mode) => Promise.resolve()

/**
* Shim for {@link module:storage.ensureDatafileIntegrityAsync}, nothing to do, no data corruption possible in the browser.
* @param {string} filename
Expand Down Expand Up @@ -176,3 +187,5 @@ module.exports.unlinkAsync = unlinkAsync
module.exports.mkdirAsync = mkdirAsync

module.exports.ensureDatafileIntegrityAsync = ensureDatafileIntegrityAsync

module.exports.ensureParentDirectoryExistsAsync = ensureParentDirectoryExistsAsync
13 changes: 13 additions & 0 deletions browser-version/lib/storage.react-native.js
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,17 @@ const crashSafeWriteFileLinesAsync = async (filename, lines) => {
*/
const crashSafeWriteFileLines = callbackify(crashSafeWriteFileLinesAsync)

/**
* Shim for {@link module:storage.ensureParentDirectoryExistsAsync}, nothing to do, no directories will be used on the browser.
* @function
* @param {string} file
* @param {number} [mode]
* @return {Promise<void|string>}
* @alias module:storageBrowser.ensureParentDirectoryExistsAsync
* @async
*/
const ensureParentDirectoryExistsAsync = async (file, mode) => Promise.resolve()

// Interface
module.exports.exists = exists
module.exports.existsAsync = existsAsync
Expand Down Expand Up @@ -280,3 +291,5 @@ module.exports.mkdirAsync = mkdirAsync

module.exports.ensureDatafileIntegrity = ensureDatafileIntegrity
module.exports.ensureDatafileIntegrityAsync = ensureDatafileIntegrityAsync

module.exports.ensureParentDirectoryExistsAsync = ensureParentDirectoryExistsAsync
11 changes: 3 additions & 8 deletions lib/persistence.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
const path = require('path')
const { deprecate } = require('util')
const byline = require('./byline')
const customUtils = require('./customUtils.js')
Expand Down Expand Up @@ -308,7 +307,7 @@ class Persistence {

// In-memory only datastore
if (this.inMemoryOnly) return
await Persistence.ensureDirectoryExistsAsync(path.dirname(this.filename), this.modes.dirMode)
await Persistence.ensureParentDirectoryExistsAsync(this.filename, this.modes.dirMode)
await storage.ensureDatafileIntegrityAsync(this.filename, this.modes.fileMode)

let treatedData
Expand Down Expand Up @@ -372,12 +371,8 @@ class Persistence {
* @return {Promise<void>}
* @private
*/
static async ensureDirectoryExistsAsync (dir, mode = DEFAULT_DIR_MODE) {
const parsedDir = path.parse(path.resolve(dir))
// this is because on Windows mkdir throws a permission error when called on the root directory of a volume
if (process.platform !== 'win32' || parsedDir.dir !== parsedDir.root || parsedDir.base !== '') {
await storage.mkdirAsync(dir, { recursive: true, mode })
}
static async ensureParentDirectoryExistsAsync (dir, mode = DEFAULT_DIR_MODE) {
return storage.ensureParentDirectoryExistsAsync(dir, mode)
}
}

Expand Down
20 changes: 19 additions & 1 deletion lib/storage.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/**
* Way data is stored for this database.
* This version is the Node.js/Node Webkit version.
* This version is the Node.js version.
* It's essentially fs, mkdirp and crash safe write and read functions.
*
* @see module:storageBrowser
Expand Down Expand Up @@ -271,6 +271,22 @@ const ensureDatafileIntegrityAsync = async (filename, mode = DEFAULT_FILE_MODE)
else await renameAsync(tempFilename, filename)
}

/**
* Check if a file's parent directory exists and create it on the fly if it is not the case.
* @param {string} filename
* @param {number} mode
* @return {Promise<void>}
* @private
*/
const ensureParentDirectoryExistsAsync = async (filename, mode) => {
const dir = path.dirname(filename)
const parsedDir = path.parse(path.resolve(dir))
// this is because on Windows mkdir throws a permission error when called on the root directory of a volume
if (process.platform !== 'win32' || parsedDir.dir !== parsedDir.root || parsedDir.base !== '') {
await mkdirAsync(dir, { recursive: true, mode })
}
}

// Interface
module.exports.existsAsync = existsAsync

Expand All @@ -297,3 +313,5 @@ module.exports.flushToStorageAsync = flushToStorageAsync
module.exports.ensureDatafileIntegrityAsync = ensureDatafileIntegrityAsync

module.exports.ensureFileDoesntExistAsync = ensureFileDoesntExistAsync

module.exports.ensureParentDirectoryExistsAsync = ensureParentDirectoryExistsAsync
3 changes: 1 addition & 2 deletions test/cursor.async.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
const testDb = 'workspace/test.db'
const { promises: fs } = require('fs')
const assert = require('assert').strict
const path = require('path')
const Datastore = require('../lib/datastore')
const Persistence = require('../lib/persistence')
const Cursor = require('../lib/cursor')
Expand All @@ -15,7 +14,7 @@ describe('Cursor Async', function () {
d = new Datastore({ filename: testDb })
assert.equal(d.filename, testDb)
assert.equal(d.inMemoryOnly, false)
await Persistence.ensureDirectoryExistsAsync(path.dirname(testDb))
await Persistence.ensureParentDirectoryExistsAsync(testDb)
if (await exists(testDb)) await fs.unlink(testDb)
await d.loadDatabaseAsync()
assert.equal(d.getAllData().length, 0)
Expand Down
3 changes: 1 addition & 2 deletions test/cursor.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
const chai = require('chai')
const testDb = 'workspace/test.db'
const fs = require('fs')
const path = require('path')
const { each, waterfall } = require('./utils.test.js')
const Datastore = require('../lib/datastore')
const Persistence = require('../lib/persistence')
Expand All @@ -22,7 +21,7 @@ describe('Cursor', function () {

waterfall([
function (cb) {
callbackify((dirname) => Persistence.ensureDirectoryExistsAsync(dirname))(path.dirname(testDb), function () {
callbackify((filename) => Persistence.ensureParentDirectoryExistsAsync(filename))(testDb, function () {
fs.access(testDb, fs.constants.F_OK, function (err) {
if (!err) {
fs.unlink(testDb, cb)
Expand Down
3 changes: 1 addition & 2 deletions test/db.async.test.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
/* eslint-env mocha */
const testDb = 'workspace/test.db'
const { promises: fs } = require('fs')
const path = require('path')
const assert = require('assert').strict
const model = require('../lib/model')
const Datastore = require('../lib/datastore')
Expand All @@ -17,7 +16,7 @@ describe('Database async', function () {
d = new Datastore({ filename: testDb })
assert.equal(d.filename, testDb)
assert.equal(d.inMemoryOnly, false)
await Persistence.ensureDirectoryExistsAsync(path.dirname(testDb))
await Persistence.ensureParentDirectoryExistsAsync(testDb)
if (await exists(testDb)) await fs.unlink(testDb)
await d.loadDatabaseAsync()
assert.equal(d.getAllData().length, 0)
Expand Down
3 changes: 1 addition & 2 deletions test/db.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
const chai = require('chai')
const testDb = 'workspace/test.db'
const fs = require('fs')
const path = require('path')
const { apply, each, waterfall } = require('./utils.test.js')
const model = require('../lib/model')
const Datastore = require('../lib/datastore')
Expand All @@ -23,7 +22,7 @@ describe('Database', function () {

waterfall([
function (cb) {
callbackify((dirname) => Persistence.ensureDirectoryExistsAsync(dirname))(path.dirname(testDb), function () {
callbackify((filename) => Persistence.ensureParentDirectoryExistsAsync(filename))(testDb, function () {
fs.access(testDb, fs.constants.FS_OK, function (err) {
if (!err) {
fs.unlink(testDb, cb)
Expand Down
3 changes: 1 addition & 2 deletions test/executor.async.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
const testDb = 'workspace/test.db'
const { promises: fs } = require('fs')
const assert = require('assert').strict
const path = require('path')
const Datastore = require('../lib/datastore')
const Persistence = require('../lib/persistence')
const { exists } = require('./utils.test.js')
Expand Down Expand Up @@ -53,7 +52,7 @@ describe('Executor async', function () {
d = new Datastore({ filename: testDb })
assert.equal(d.filename, testDb)
assert.equal(d.inMemoryOnly, false)
await Persistence.ensureDirectoryExistsAsync(path.dirname(testDb))
await Persistence.ensureParentDirectoryExistsAsync(testDb)
if (await exists(testDb)) await fs.unlink(testDb)
await d.loadDatabaseAsync()
assert.equal(d.getAllData().length, 0)
Expand Down
3 changes: 1 addition & 2 deletions test/executor.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
const chai = require('chai')
const testDb = 'workspace/test.db'
const fs = require('fs')
const path = require('path')
const { waterfall } = require('./utils.test.js')
const Datastore = require('../lib/datastore')
const Persistence = require('../lib/persistence')
Expand Down Expand Up @@ -154,7 +153,7 @@ describe('Executor', function () {

waterfall([
function (cb) {
callbackify((dirname) => Persistence.ensureDirectoryExistsAsync(dirname))(path.dirname(testDb), function () {
callbackify((filename) => Persistence.ensureParentDirectoryExistsAsync(filename))(testDb, function () {
fs.access(testDb, fs.constants.F_OK, function (err) {
if (!err) {
fs.unlink(testDb, cb)
Expand Down
4 changes: 2 additions & 2 deletions test/persistence.async.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ describe('Persistence async', function () {
d = new Datastore({ filename: testDb })
assert.equal(d.filename, testDb)
assert.equal(d.inMemoryOnly, false)
await Persistence.ensureDirectoryExistsAsync(path.dirname(testDb))
await Persistence.ensureParentDirectoryExistsAsync(testDb)
if (await exists(testDb)) await fs.unlink(testDb)
await d.loadDatabaseAsync()
assert.equal(d.getAllData().length, 0)
Expand Down Expand Up @@ -1062,7 +1062,7 @@ describe('permissions', function () {
})

it('ensureDirectoryExists forwards mode argument', async () => {
await Persistence.ensureDirectoryExistsAsync(path.dirname(testDb), 0o700)
await Persistence.ensureParentDirectoryExistsAsync(testDb, 0o700)
assert.equal(await getMode(path.dirname(testDb)), 0o700)
})

Expand Down
3 changes: 1 addition & 2 deletions test/persistence.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
const chai = require('chai')
const testDb = 'workspace/test.db'
const fs = require('fs')
const path = require('path')
const { apply, waterfall } = require('./utils.test.js')
const model = require('../lib/model')
const Datastore = require('../lib/datastore')
Expand All @@ -27,7 +26,7 @@ describe('Persistence', function () {

waterfall([
function (cb) {
callbackify((dirname) => Persistence.ensureDirectoryExistsAsync(dirname))(path.dirname(testDb), function () {
callbackify((filename) => Persistence.ensureParentDirectoryExistsAsync(filename))(testDb, function () {
fs.access(testDb, fs.constants.FS_OK, function (err) {
if (!err) {
fs.unlink(testDb, cb)
Expand Down

0 comments on commit bc10dde

Please sign in to comment.