diff --git a/browser-version/lib/storage.browser.js b/browser-version/lib/storage.browser.js index e2c3f35..b713a7d 100755 --- a/browser-version/lib/storage.browser.js +++ b/browser-version/lib/storage.browser.js @@ -1,10 +1,10 @@ /** * Way data is stored for this database - * For a Node.js/Node Webkit database it's the file system - * For a browser-side database it's localforage which chooses the best option depending on user browser (IndexedDB then WebSQL then localStorage) * - * This version is the browser version + * This version is the browser version and uses [localforage]{@link https://github.com/localForage/localForage} which chooses the best option depending on user browser (IndexedDB then WebSQL then localStorage). * @module storageBrowser + * @see module:storage + * @see module:storageReactNative */ const localforage = require('localforage') @@ -17,11 +17,14 @@ const store = localforage.createInstance({ }) /** - * Returns Promise if file exists + * Returns Promise if file exists. + * + * Async version of {@link module:storageBrowser.exists}. * @param {string} file * @return {Promise} * @async * @alias module:storageBrowser.existsAsync + * @see module:storageBrowser.exists */ const existsAsync = async file => { try { @@ -39,7 +42,7 @@ const existsAsync = async file => { */ /** - * Callback returns true if file exists + * Callback returns true if file exists. * @function * @param {string} file * @param {module:storageBrowser~existsCallback} cb @@ -48,12 +51,13 @@ const existsAsync = async file => { const exists = callbackify(existsAsync) /** - * Moves the item from one path to another + * Async version of {@link module:storageBrowser.rename}. * @param {string} oldPath * @param {string} newPath * @return {Promise} * @alias module:storageBrowser.renameAsync * @async + * @see module:storageBrowser.rename */ const renameAsync = async (oldPath, newPath) => { try { @@ -80,13 +84,14 @@ const renameAsync = async (oldPath, newPath) => { const rename = callbackify(renameAsync) /** - * Saves the item at given path + * Async version of {@link module:storageBrowser.writeFile}. * @param {string} file * @param {string} data * @param {object} [options] * @return {Promise} * @alias module:storageBrowser.writeFileAsync * @async + * @see module:storageBrowser.writeFile */ const writeFileAsync = async (file, data, options) => { // Options do not matter in browser setup @@ -109,7 +114,7 @@ const writeFileAsync = async (file, data, options) => { const writeFile = callbackify(writeFileAsync) /** - * Append to the item at given path + * Async version of {@link module:storageBrowser.appendFile}. * @function * @param {string} filename * @param {string} toAppend @@ -117,6 +122,7 @@ const writeFile = callbackify(writeFileAsync) * @return {Promise} * @alias module:storageBrowser.appendFileAsync * @async + * @see module:storageBrowser.appendFile */ const appendFileAsync = async (filename, toAppend, options) => { // Options do not matter in browser setup @@ -140,13 +146,14 @@ const appendFileAsync = async (filename, toAppend, options) => { const appendFile = callbackify(appendFileAsync) /** - * Read data at given path + * Async version of {@link module:storageBrowser.readFile}. * @function * @param {string} filename * @param {object} [options] * @return {Promise} * @alias module:storageBrowser.readFileAsync * @async + * @see module:storageBrowser.readFile */ const readFileAsync = async (filename, options) => { try { @@ -167,12 +174,13 @@ const readFileAsync = async (filename, options) => { const readFile = callbackify(readFileAsync) /** - * Remove the data at given path + * Async version of {@link module:storageBrowser.unlink}. * @function * @param {string} filename * @return {Promise} * @async * @alias module:storageBrowser.unlinkAsync + * @see module:storageBrowser.unlink */ const unlinkAsync = async filename => { try { @@ -192,7 +200,7 @@ const unlinkAsync = async filename => { const unlink = callbackify(unlinkAsync) /** - * Shim for storage.mkdirAsync, nothing to do, no directories will be used on the browser + * Shim for {@link module:storage.mkdirAsync}, nothing to do, no directories will be used on the browser. * @function * @param {string} path * @param {object} [options] @@ -202,7 +210,7 @@ const unlink = callbackify(unlinkAsync) */ const mkdirAsync = (path, options) => Promise.resolve() /** - * Shim for storage.mkdir, nothing to do, no directories will be used on the browser + * Shim for {@link module:storage.mkdir}, nothing to do, no directories will be used on the browser. * @function * @param {string} path * @param {object} options @@ -212,8 +220,7 @@ const mkdirAsync = (path, options) => Promise.resolve() const mkdir = callbackify(mkdirAsync) /** - * Ensure the datafile contains all the data, even if there was a crash during a full file write - * Nothing to do, no data corruption possible in the browser + * Shim for {@link module:storage.ensureDatafileIntegrityAsync}, nothing to do, no data corruption possible in the browser. * @param {string} filename * @return {Promise} * @alias module:storageBrowser.ensureDatafileIntegrityAsync @@ -221,8 +228,7 @@ const mkdir = callbackify(mkdirAsync) const ensureDatafileIntegrityAsync = (filename) => Promise.resolve() /** - * Ensure the datafile contains all the data, even if there was a crash during a full file write - * Nothing to do, no data corruption possible in the browser + * Shim for {@link module:storage.ensureDatafileIntegrity}, nothing to do, no data corruption possible in the browser. * @function * @param {string} filename * @param {NoParamCallback} callback signature: err @@ -231,11 +237,12 @@ const ensureDatafileIntegrityAsync = (filename) => Promise.resolve() const ensureDatafileIntegrity = callbackify(ensureDatafileIntegrityAsync) /** - * Fully write or rewrite the datafile, immune to crashes during the write operation (data will not be lost) + * Async version of {@link module:storageBrowser.crashSafeWriteFileLines}. * @param {string} filename * @param {string[]} lines * @return {Promise} * @alias module:storageBrowser.crashSafeWriteFileLinesAsync + * @see module:storageBrowser.crashSafeWriteFileLines */ const crashSafeWriteFileLinesAsync = async (filename, lines) => { lines.push('') // Add final new line diff --git a/browser-version/lib/storage.react-native.js b/browser-version/lib/storage.react-native.js index 6c5dbba..ca2c8d2 100755 --- a/browser-version/lib/storage.react-native.js +++ b/browser-version/lib/storage.react-native.js @@ -1,21 +1,22 @@ /** * Way data is stored for this database - * For a Node.js/Node Webkit database it's the file system - * For a browser-side database it's localforage, which uses the best backend available (IndexedDB then WebSQL then localStorage) - * For a react-native database, we use @react-native-async-storage/async-storage * - * This version is the react-native version + * This version is the React-Native version and uses [@react-native-async-storage/async-storage]{@link https://github.com/react-native-async-storage/async-storage}. * @module storageReactNative + * @see module:storageBrowser + * @see module:storageReactNative */ + const AsyncStorage = require('@react-native-async-storage/async-storage').default const { callbackify } = require('util') // TODO: util is not a dependency, this would fail if util is not polyfilled /** - * Returns Promise if file exists + * Async version of {@link module:storageReactNative.exists}. * @param {string} file * @return {Promise} * @async * @alias module:storageReactNative.existsAsync + * @see module:storageReactNative.exists */ const existsAsync = async file => { try { @@ -41,12 +42,13 @@ const existsAsync = async file => { const exists = callbackify(existsAsync) /** - * Moves the item from one path to another + * Async version of {@link module:storageReactNative.rename}. * @param {string} oldPath * @param {string} newPath * @return {Promise} * @alias module:storageReactNative.renameAsync * @async + * @see module:storageReactNative.rename */ const renameAsync = async (oldPath, newPath) => { try { @@ -73,13 +75,14 @@ const renameAsync = async (oldPath, newPath) => { const rename = callbackify(renameAsync) /** - * Saves the item at given path + * Async version of {@link module:storageReactNative.writeFile}. * @param {string} file * @param {string} data * @param {object} [options] * @return {Promise} * @alias module:storageReactNative.writeFileAsync * @async + * @see module:storageReactNative.writeFile */ const writeFileAsync = async (file, data, options) => { // Options do not matter in browser setup @@ -102,7 +105,7 @@ const writeFileAsync = async (file, data, options) => { const writeFile = callbackify(writeFileAsync) /** - * Append to the item at given path + * Async version of {@link module:storageReactNative.appendFile}. * @function * @param {string} filename * @param {string} toAppend @@ -110,6 +113,7 @@ const writeFile = callbackify(writeFileAsync) * @return {Promise} * @alias module:storageReactNative.appendFileAsync * @async + * @see module:storageReactNative.appendFile */ const appendFileAsync = async (filename, toAppend, options) => { // Options do not matter in browser setup @@ -133,13 +137,14 @@ const appendFileAsync = async (filename, toAppend, options) => { const appendFile = callbackify(appendFileAsync) /** - * Read data at given path + * Async version of {@link module:storageReactNative.readFile}. * @function * @param {string} filename * @param {object} [options] * @return {Promise} * @alias module:storageReactNative.readFileAsync * @async + * @see module:storageReactNative.readFile */ const readFileAsync = async (filename, options) => { try { @@ -161,12 +166,13 @@ const readFileAsync = async (filename, options) => { const readFile = callbackify(readFileAsync) /** - * Remove the data at given path + * Async version of {@link module:storageReactNative.unlink}. * @function * @param {string} filename * @return {Promise} * @async * @alias module:storageReactNative.unlinkAsync + * @see module:storageReactNative.unlink */ const unlinkAsync = async filename => { try { @@ -186,7 +192,7 @@ const unlinkAsync = async filename => { const unlink = callbackify(unlinkAsync) /** - * Shim for storage.mkdirAsync, nothing to do, no directories will be used on the browser + * Shim for {@link module:storage.mkdirAsync}, nothing to do, no directories will be used on the browser. * @function * @param {string} dir * @param {object} [options] @@ -197,7 +203,7 @@ const unlink = callbackify(unlinkAsync) const mkdirAsync = (dir, options) => Promise.resolve() /** - * Shim for storage.mkdir, nothing to do, no directories will be used on the browser + * Shim for {@link module:storage.mkdir}, nothing to do, no directories will be used on the browser. * @function * @param {string} path * @param {object} options @@ -207,8 +213,7 @@ const mkdirAsync = (dir, options) => Promise.resolve() const mkdir = callbackify(mkdirAsync) /** - * Ensure the datafile contains all the data, even if there was a crash during a full file write - * Nothing to do, no data corruption possible in the browser + * Shim for {@link module:storage.ensureDatafileIntegrityAsync}, nothing to do, no data corruption possible in the browser. * @param {string} filename * @return {Promise} * @alias module:storageReactNative.ensureDatafileIntegrityAsync @@ -216,8 +221,7 @@ const mkdir = callbackify(mkdirAsync) const ensureDatafileIntegrityAsync = (filename) => Promise.resolve() /** - * Ensure the datafile contains all the data, even if there was a crash during a full file write - * Nothing to do, no data corruption possible in the browser + * Shim for {@link module:storage.ensureDatafileIntegrity}, nothing to do, no data corruption possible in the browser. * @function * @param {string} filename * @param {NoParamCallback} callback signature: err @@ -226,11 +230,12 @@ const ensureDatafileIntegrityAsync = (filename) => Promise.resolve() const ensureDatafileIntegrity = callbackify(ensureDatafileIntegrityAsync) /** - * Fully write or rewrite the datafile, immune to crashes during the write operation (data will not be lost) + * Async version of {@link module:storageReactNative.crashSafeWriteFileLines}. * @param {string} filename * @param {string[]} lines * @return {Promise} * @alias module:storageReactNative.crashSafeWriteFileLinesAsync + * @see module:storageReactNative.crashSafeWriteFileLines */ const crashSafeWriteFileLinesAsync = async (filename, lines) => { lines.push('') // Add final new line diff --git a/lib/executor.js b/lib/executor.js index 61f593f..531ced7 100755 --- a/lib/executor.js +++ b/lib/executor.js @@ -12,19 +12,19 @@ class Executor { /** * If this.ready is `false`, then every task pushed will be buffered until this.processBuffer is called. * @type {boolean} - * @protected + * @private */ this.ready = false /** * The main queue * @type {Waterfall} - * @protected + * @private */ this.queue = new Waterfall() /** * The buffer queue * @type {Waterfall} - * @protected + * @private */ this.buffer = new Waterfall() this.buffer.chain(new Promise(resolve => { @@ -33,7 +33,7 @@ class Executor { * * Do not be use directly, use `this.processBuffer` instead. * @function - * @protected + * @private */ this._triggerBuffer = resolve })) @@ -78,12 +78,15 @@ class Executor { } /** - * If executor is ready, queue task (and process it immediately if executor was idle) - * If not, buffer task for later processing - * @param {function(...*):Promise<*>} task + * Async version of {@link Executor#push}. + * This version is way simpler than its callbackEquivalent: you give it an async function `task`, it is executed when + * all the previous tasks are done, and then resolves or rejects and when it is finished with its original result or + * error. + * @param {AsyncFunction} task * @param {boolean} [forceQueuing = false] * @return {Promise<*>} * @async + * @see Executor#push */ pushAsync (task, forceQueuing = false) { if (this.ready || forceQueuing) return this.queue.waterfall(task)() diff --git a/lib/persistence.js b/lib/persistence.js index f3b4853..414a14e 100755 --- a/lib/persistence.js +++ b/lib/persistence.js @@ -15,8 +15,8 @@ class Persistence { * @param {Datastore} options.db * @param {Number} [options.corruptAlertThreshold] Optional, threshold after which an alert is thrown if too much data is corrupt * @param {string} [options.nodeWebkitAppName] Optional, specify the name of your NW app if you want options.filename to be relative to the directory where Node Webkit stores application data such as cookies and local storage (the best place to store data in my opinion) - * @param {function} [options.beforeDeserialization] Hook you can use to transform data after it was serialized and before it is written to disk. - * @param {function} [options.afterSerialization] Inverse of `afterSerialization`. + * @param {serializationHook} [options.beforeDeserialization] Hook you can use to transform data after it was serialized and before it is written to disk. + * @param {serializationHook} [options.afterSerialization] Inverse of `afterSerialization`. */ constructor (options) { this.db = options.db @@ -64,19 +64,22 @@ class Persistence { * Persist cached database * This serves as a compaction function since the cache always contains only the number of documents in the collection * while the data file is append-only so it may grow larger - * This is an internal function, use compactDataFile which uses the executor - * @param {NoParamCallback} callback Optional callback, signature: err + * + * This is an internal function, use {@link Persistence#compactDatafile} which uses the [executor]{@link Datastore#executor}. + * @param {NoParamCallback} [callback = () => {}] + * @protected */ persistCachedDatabase (callback = () => {}) { return callbackify(this.persistCachedDatabaseAsync.bind(this))(callback) } /** - * Persist cached database - * This serves as a compaction function since the cache always contains only the number of documents in the collection - * while the data file is append-only so it may grow larger - * This is an internal function, use compactDataFileAsync which uses the executor + * Async version of {@link Persistence#persistCachedDatabase}. + * + * This is an internal function, use {@link Persistence#compactDatafileAsync} which uses the [executor]{@link Datastore#executor}. * @return {Promise} + * @protected + * @see Persistence#persistCachedDatabase */ async persistCachedDatabaseAsync () { const lines = [] @@ -104,23 +107,25 @@ class Persistence { /** * Queue a rewrite of the datafile - * @param {NoParamCallback} [callback = () => {}] Optional callback, signature: err + * @param {NoParamCallback} [callback = () => {}] + * @see Persistence#persistCachedDatabase */ compactDatafile (callback = () => {}) { this.db.executor.push({ this: this, fn: this.persistCachedDatabase, arguments: [callback] }) } /** - * Queue a rewrite of the datafile + * Async version of {@link Persistence#compactDatafile}. * @async + * @see Persistence#compactDatafile */ compactDatafileAsync () { return this.db.executor.pushAsync(() => this.persistCachedDatabaseAsync()) } /** - * Set automatic compaction every interval ms - * @param {Number} interval in milliseconds, with an enforced minimum of 5 seconds + * Set automatic compaction every `interval` ms + * @param {Number} interval in milliseconds, with an enforced minimum of 5000 milliseconds */ setAutocompactionInterval (interval) { const minInterval = 5000 @@ -134,7 +139,7 @@ class Persistence { } /** - * Stop autocompaction (do nothing if autocompaction was not running) + * Stop autocompaction (do nothing if automatic compaction was not running) */ stopAutocompaction () { if (this.autocompactionIntervalId) clearInterval(this.autocompactionIntervalId) @@ -143,18 +148,24 @@ class Persistence { /** * Persist new state for the given newDocs (can be insertion, update or removal) * Use an append-only format + * + * Do not use directly, it should only used by a {@link Datastore} instance. * @param {string[]} newDocs Can be empty if no doc was updated/removed - * @param {NoParamCallback} [callback = () => {}] Optional, signature: err + * @param {NoParamCallback} [callback = () => {}] + * @protected */ persistNewState (newDocs, callback = () => {}) { callbackify(this.persistNewStateAsync.bind(this))(newDocs, err => callback(err)) } /** - * Persist new state for the given newDocs (can be insertion, update or removal) - * Use an append-only format + * Async version of {@link Persistence#persistNewState} + * + * Do not use directly, it should only used by a {@link Datastore} instance. * @param {document[]} newDocs Can be empty if no doc was updated/removed * @return {Promise} + * @protected + * @see Persistence#persistNewState */ async persistNewStateAsync (newDocs) { let toPersist = '' @@ -179,9 +190,12 @@ class Persistence { */ /** - * From a database's raw data, return the corresponding machine understandable collection + * From a database's raw data, return the corresponding machine understandable collection. + * + * Do not use directly, it should only used by a {@link Datastore} instance. * @param {string} rawData database file * @return {{data: document[], indexes: Object.}} + * @protected */ treatRawData (rawData) { const data = rawData.split('\n') @@ -218,13 +232,23 @@ class Persistence { /** * @callback Persistence~treatRawStreamCallback * @param {?Error} err - * @param {{data: document[], indexes: Object.}?} data + * @param {?object} data + * @param {document[]} data.data + * @param {Object.} data.indexes */ /** * From a database's raw data stream, return the corresponding machine understandable collection + * Is only used by a {@link Datastore} instance. + * + * Is only used in the Node.js version, since [React-Native]{@link module:storageReactNative} & + * [browser]{@link module:storageBrowser} storage modules don't provide an equivalent of + * {@link module:storage.readFileStream}. + * + * Do not use directly, it should only used by a {@link Datastore} instance. * @param {Readable} rawStream * @param {Persistence~treatRawStreamCallback} cb + * @protected */ treatRawStream (rawStream, cb) { const dataById = {} @@ -270,10 +294,14 @@ class Persistence { } /** - * From a database's raw data stream, return the corresponding machine understandable collection + * Async version of {@link Persistence#treatRawStream}. + * + * Do not use directly, it should only used by a {@link Datastore} instance. * @param {Readable} rawStream * @return {Promise<{data: document[], indexes: Object.}>} * @async + * @protected + * @see Persistence#treatRawStream */ treatRawStreamAsync (rawStream) { return promisify(this.treatRawStream.bind(this))(rawStream) @@ -284,24 +312,23 @@ class Persistence { * 1) Create all indexes * 2) Insert all data * 3) Compact the database + * * This means pulling data out of the data file or creating it if it doesn't exist * Also, all data is persisted right away, which has the effect of compacting the database file * This operation is very quick at startup for a big collection (60ms for ~10k docs) - * @param {NoParamCallback} callback Optional callback, signature: err + * + * Do not use directly as it does not use the [Executor]{@link Datastore.executor}, use {@link Datastore#loadDatabase} instead. + * @param {NoParamCallback} callback + * @protected */ loadDatabase (callback = () => {}) { callbackify(this.loadDatabaseAsync.bind(this))(err => callback(err)) } /** - * Load the database - * 1) Create all indexes - * 2) Insert all data - * 3) Compact the database - * This means pulling data out of the data file or creating it if it doesn't exist - * Also, all data is persisted right away, which has the effect of compacting the database file - * This operation is very quick at startup for a big collection (60ms for ~10k docs) + * Async version of {@link Persistence#loadDatabase} * @return {Promise} + * @see Persistence#loadDatabase */ async loadDatabaseAsync () { this.db.resetIndexes() @@ -339,18 +366,19 @@ class Persistence { } /** - * Check if a directory stat and create it on the fly if it is not the case + * Check if a directory stat and create it on the fly if it is not the case. * @param {string} dir - * @param {NoParamCallback} [callback = () => {}] optional callback, signature: err + * @param {NoParamCallback} [callback = () => {}] */ static ensureDirectoryExists (dir, callback = () => {}) { storage.mkdir(dir, { recursive: true }, err => { callback(err) }) } /** - * Check if a directory stat and create it on the fly if it is not the case + * Async version of {@link Persistence.ensureDirectoryExists}. * @param {string} dir * @return {Promise} + * @see Persistence.ensureDirectoryExists */ static async ensureDirectoryExistsAsync (dir) { await storage.mkdirAsync(dir, { recursive: true }) diff --git a/lib/storage.js b/lib/storage.js index 5022279..4cbcd26 100755 --- a/lib/storage.js +++ b/lib/storage.js @@ -1,11 +1,10 @@ /** - * Way data is stored for this database - * For a Node.js/Node Webkit database it's the file system - * For a browser-side database it's localforage, which uses the best backend available (IndexedDB then WebSQL then localStorage) - * For a react-native database, we use @react-native-async-storage/async-storage + * Way data is stored for this database. + * This version is the Node.js/Node Webkit version. + * It's essentially fs, mkdirp and crash safe write and read functions. * - * This version is the Node.js/Node Webkit version - * It's essentially fs, mkdirp and crash safe write and read functions + * @see module:storageBrowser + * @see module:storageReactNative * @module storage */ const fs = require('fs') @@ -20,7 +19,7 @@ const { Readable } = require('stream') */ /** - * Callback returns true if file exists + * Callback returns true if file exists. * @param {string} file * @param {module:storage~existsCallback} cb * @alias module:storage.exists @@ -29,16 +28,17 @@ const { Readable } = require('stream') const exists = (file, cb) => fs.access(file, fs.constants.F_OK, (err) => { cb(!err) }) /** - * Returns Promise if file exists + * Async version of {@link module:storage.exists}. * @param {string} file * @return {Promise} * @async * @alias module:storage.existsAsync + * @see module:storage.exists */ const existsAsync = file => fsPromises.access(file, fs.constants.F_OK).then(() => true, () => false) /** - * Node.js' fs.rename + * Node.js' [fs.rename]{@link https://nodejs.org/api/fs.html#fsrenameoldpath-newpath-callback}. * @function * @param {string} oldPath * @param {string} newPath @@ -49,18 +49,19 @@ const existsAsync = file => fsPromises.access(file, fs.constants.F_OK).then(() = const rename = fs.rename /** - * Node.js' fs.promises.rename + * Async version of {@link module:storage.rename}. * @function * @param {string} oldPath * @param {string} newPath * @return {Promise} * @alias module:storage.renameAsync * @async + * @see module:storage.rename */ const renameAsync = fsPromises.rename /** - * Node.js' fs.writeFile + * Node.js' [fs.writeFile]{@link https://nodejs.org/api/fs.html#fswritefilefile-data-options-callback}. * @function * @param {string} path * @param {string} data @@ -71,7 +72,7 @@ const renameAsync = fsPromises.rename const writeFile = fs.writeFile /** - * Node.js' fs.promises.writeFile + * Async version of {@link module:storage.writeFile}. * @function * @param {string} path * @param {string} data @@ -79,11 +80,12 @@ const writeFile = fs.writeFile * @return {Promise} * @alias module:storage.writeFileAsync * @async + * @see module:storage.writeFile */ const writeFileAsync = fsPromises.writeFile /** - * Node.js' fs.createWriteStream + * Node.js' [fs.createWriteStream]{@link https://nodejs.org/api/fs.html#fscreatewritestreampath-options}. * @function * @param {string} path * @param {Object} [options] @@ -93,7 +95,7 @@ const writeFileAsync = fsPromises.writeFile const writeFileStream = fs.createWriteStream /** - * Node.js' fs.unlink + * Node.js' [fs.unlink]{@link https://nodejs.org/api/fs.html#fsunlinkpath-callback}. * @function * @param {string} path * @param {function} callback @@ -102,17 +104,18 @@ const writeFileStream = fs.createWriteStream const unlink = fs.unlink /** - * Node.js' fs.promises.unlink + * Async version of {@link module:storage.unlink}. * @function * @param {string} path * @return {Promise} * @async * @alias module:storage.unlinkAsync + * @see module:storage.unlink */ const unlinkAsync = fsPromises.unlink /** - * Node.js' fs.appendFile + * Node.js' [fs.appendFile]{@link https://nodejs.org/api/fs.html#fsappendfilepath-data-options-callback}. * @function * @param {string} path * @param {string} data @@ -123,7 +126,7 @@ const unlinkAsync = fsPromises.unlink const appendFile = fs.appendFile /** - * Node.js' fs.promises.appendFile + * Async version of {@link module:storage.appendFile}. * @function * @param {string} path * @param {string} data @@ -131,10 +134,12 @@ const appendFile = fs.appendFile * @return {Promise} * @alias module:storage.appendFileAsync * @async + * @see module:storage.appendFile */ const appendFileAsync = fsPromises.appendFile + /** - * Node.js' fs.readFile + * Node.js' [fs.readFile]{@link https://nodejs.org/api/fs.html#fsreadfilepath-options-callback} * @function * @param {string} path * @param {object} options @@ -142,18 +147,21 @@ const appendFileAsync = fsPromises.appendFile * @alias module:storage.readFile */ const readFile = fs.readFile + /** - * Node.js' fs.promises.readFile + * Async version of {@link module:storage.readFile}. * @function * @param {string} path * @param {object} [options] * @return {Promise} * @alias module:storage.readFileAsync * @async + * @see module:storage.readFile */ const readFileAsync = fsPromises.readFile + /** - * Node.js' fs.createReadStream + * Node.js' [fs.createReadStream]{@link https://nodejs.org/api/fs.html#fscreatereadstreampath-options}. * @function * @param {string} path * @param {Object} [options] @@ -161,8 +169,9 @@ const readFileAsync = fsPromises.readFile * @alias module:storage.readFileStream */ const readFileStream = fs.createReadStream + /** - * Node.js' fs.mkdir + * Node.js' [fs.mkdir]{@link https://nodejs.org/api/fs.html#fsmkdirpath-options-callback}. * @function * @param {string} path * @param {object} options @@ -170,28 +179,33 @@ const readFileStream = fs.createReadStream * @alias module:storage.mkdir */ const mkdir = fs.mkdir + /** - * Node.js' fs.promises.mkdir + * Async version of {@link module:storage.mkdir}. * @function * @param {string} path * @param {object} options * @return {Promise} * @alias module:storage.mkdirAsync * @async + * @see module:storage.mkdir */ const mkdirAsync = fsPromises.mkdir /** + * Async version of {@link module:storage.ensureFileDoesntExist} * @param {string} file * @return {Promise} * @alias module:storage.ensureFileDoesntExistAsync * @async + * @see module:storage.ensureFileDoesntExist */ const ensureFileDoesntExistAsync = async file => { if (await existsAsync(file)) await unlinkAsync(file) } /** + * Removes file if it exists. * @param {string} file * @param {NoParamCallback} callback * @alias module:storage.ensureFileDoesntExist @@ -199,7 +213,7 @@ const ensureFileDoesntExistAsync = async file => { const ensureFileDoesntExist = (file, callback) => callbackify(ensureFileDoesntExistAsync)(file, err => callback(err)) /** - * Flush data in OS buffer to storage if corresponding option is set + * Flush data in OS buffer to storage if corresponding option is set. * @param {object|string} options If options is a string, it is assumed that the flush of the file (not dir) called options was requested * @param {string} [options.filename] * @param {boolean} [options.isDir = false] Optional, defaults to false @@ -209,13 +223,14 @@ const ensureFileDoesntExist = (file, callback) => callbackify(ensureFileDoesntEx const flushToStorage = (options, callback) => callbackify(flushToStorageAsync)(options, callback) /** - * Flush data in OS buffer to storage if corresponding option is set - * @param {object|string} options If options is a string, it is assumed that the flush of the file (not dir) called options was requested + * Async version of {@link module:storage.flushToStorage}. + * @param {object|string} options * @param {string} [options.filename] - * @param {boolean} [options.isDir = false] Optional, defaults to false + * @param {boolean} [options.isDir = false] * @return {Promise} * @alias module:storage.flushToStorageAsync * @async + * @see module:storage.flushToStorage */ const flushToStorageAsync = async (options) => { let filename @@ -266,10 +281,10 @@ const flushToStorageAsync = async (options) => { } /** - * Fully write or rewrite the datafile + * Fully write or rewrite the datafile. * @param {string} filename * @param {string[]} lines - * @param {NoParamCallback} callback + * @param {NoParamCallback} [callback = () => {}] * @alias module:storage.writeFileLines */ const writeFileLines = (filename, lines, callback = () => {}) => { @@ -293,17 +308,18 @@ const writeFileLines = (filename, lines, callback = () => {}) => { } } /** - * Fully write or rewrite the datafile + * Async version of {@link module:storage.writeFileLines}. * @param {string} filename * @param {string[]} lines * @return {Promise} * @alias module:storage.writeFileLinesAsync * @async + * @see module:storage.writeFileLines */ const writeFileLinesAsync = (filename, lines) => promisify(writeFileLines)(filename, lines) /** - * Fully write or rewrite the datafile, immune to crashes during the write operation (data will not be lost) + * Fully write or rewrite the datafile, immune to crashes during the write operation (data will not be lost). * @param {string} filename * @param {string[]} lines * @param {NoParamCallback} [callback] Optional callback, signature: err @@ -313,11 +329,12 @@ const crashSafeWriteFileLines = (filename, lines, callback = () => {}) => { callbackify(crashSafeWriteFileLinesAsync)(filename, lines, callback) } /** - * Fully write or rewrite the datafile, immune to crashes during the write operation (data will not be lost) + * Async version of {@link module:storage.crashSafeWriteFileLines}. * @param {string} filename * @param {string[]} lines * @return {Promise} * @alias module:storage.crashSafeWriteFileLinesAsync + * @see module:storage.crashSafeWriteFileLines */ const crashSafeWriteFileLinesAsync = async (filename, lines) => { const tempFilename = filename + '~' @@ -337,7 +354,7 @@ const crashSafeWriteFileLinesAsync = async (filename, lines) => { } /** - * Ensure the datafile contains all the data, even if there was a crash during a full file write + * Ensure the datafile contains all the data, even if there was a crash during a full file write. * @param {string} filename * @param {NoParamCallback} callback signature: err * @alias module:storage.ensureDatafileIntegrity @@ -345,10 +362,11 @@ const crashSafeWriteFileLinesAsync = async (filename, lines) => { const ensureDatafileIntegrity = (filename, callback) => callbackify(ensureDatafileIntegrityAsync)(filename, callback) /** - * Ensure the datafile contains all the data, even if there was a crash during a full file write + * Async version of {@link module:storage.ensureDatafileIntegrity}. * @param {string} filename * @return {Promise} * @alias module:storage.ensureDatafileIntegrityAsync + * @see module:storage.ensureDatafileIntegrity */ const ensureDatafileIntegrityAsync = async filename => { const tempFilename = filename + '~' diff --git a/lib/utils.js b/lib/utils.js index 1700790..ac64bf6 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -9,7 +9,8 @@ * Produces a duplicate-free version of the array, using === to test object equality. In particular only the first * occurrence of each value is kept. If you want to compute unique items based on a transformation, pass an iteratee * function. - * Heavily inspired by https://underscorejs.org/#uniq + * + * Heavily inspired by {@link https://underscorejs.org/#uniq}. * @param {Array} array * @param {function} [iteratee] transformation applied to every element before checking for duplicates. This will not * transform the items in the result. @@ -23,7 +24,8 @@ const uniq = (array, iteratee) => { /** * Returns true if arg is an Object. Note that JavaScript arrays and functions are objects, while (normal) strings * and numbers are not. - * Heavily inspired by https://underscorejs.org/#isObject + * + * Heavily inspired by {@link https://underscorejs.org/#isObject}. * @param {*} arg * @return {boolean} */ @@ -31,7 +33,8 @@ const isObject = arg => typeof arg === 'object' && arg !== null /** * Returns true if d is a Date. - * Heavily inspired by https://underscorejs.org/#isDate + * + * Heavily inspired by {@link https://underscorejs.org/#isDate}. * @param {*} d * @return {boolean} * @alias module:utils.isDate @@ -40,7 +43,8 @@ const isDate = d => isObject(d) && Object.prototype.toString.call(d) === '[objec /** * Returns true if re is a RegExp. - * Heavily inspired by https://underscorejs.org/#isRegExp + * + * Heavily inspired by {@link https://underscorejs.org/#isRegExp}. * @param {*} re * @return {boolean} * @alias module:utils.isRegExp diff --git a/lib/waterfall.js b/lib/waterfall.js index b35e3cd..fab25b4 100644 --- a/lib/waterfall.js +++ b/lib/waterfall.js @@ -13,7 +13,7 @@ class Waterfall { * * Use {@link Waterfall#guardian} instead which retrievethe latest version of the guardian. * @type {Promise} - * @protected + * @private */ this._guardian = Promise.resolve() } diff --git a/package.json b/package.json index c5590d2..4b38f34 100755 --- a/package.json +++ b/package.json @@ -88,7 +88,7 @@ "test:typings": "ts-node ./typings-tests.ts", "prepublishOnly": "npm run build:browser", "generateDocs:markdown": "node jsdoc2md.js", - "generateDocs:html": "jsdoc -c jsdoc.conf.js -d docs-html --readme README.md lib/*.js browser-version/lib/*.js" + "generateDocs:html": "jsdoc -c jsdoc.conf.js -d docs-html --readme README.md" }, "main": "index.js", "browser": {