informa-db.js
Advanced tools
Comparing version 4.1.0 to 5.0.0
@@ -21,5 +21,3 @@ module.exports = { | ||
'no-param-reassign': ['error', { 'props': false }], | ||
'import/extensions': 'off', | ||
'no-console': 'off', | ||
}, | ||
}; |
@@ -13,62 +13,2 @@ import DbUtils from './utilsBrowser.js'; // eslint-disable-line import/extensions | ||
if (!path) throw new Error('No path provided'); | ||
if (path.match(/^https?:\/\//)) { | ||
this.path = path; | ||
this.awaitEvents = new Event('DbDoneUpdating'); | ||
this.online = true; | ||
if (!settings.request) settings.request = {}; | ||
this.debug = settings.request.debug; | ||
this.method = settings.request.method || 'POST'; | ||
if (!settings.request.headers) settings.request.headers = {}; | ||
settings.request.headers['Content-Type'] = 'application/json'; | ||
settings.request.headers.Accept = 'application/json'; | ||
this.headers = settings.request.headers; | ||
this.updating = []; | ||
const outerThis = this; | ||
// See server.js:35 | ||
this.update = async () => { | ||
const updateID = outerThis.updating.length; | ||
outerThis.updating[updateID] = true; | ||
await new Promise((r) => document.addEventListener('DbDoneUpdating', r)); | ||
const timeoutGuard = setTimeout(async () => { | ||
if (outerThis.debug) console.warn('Request timed out'); | ||
outerThis.updating[updateID] = false; | ||
if (outerThis.updating.every((v) => !v)) document.dispatchEvent(outerThis.awaitEvents); | ||
return outerThis.value; | ||
}, 5000); | ||
const fetched = await fetch(outerThis.path, { | ||
body: JSON.stringify(outerThis.readOnlyValue, null, outerThis.saveSpace ? null : '\t'), | ||
headers: outerThis.headers, | ||
method: outerThis.method, | ||
mode: 'cors', | ||
}); | ||
if (outerThis.debug) console.log(await fetched.text()); | ||
outerThis.updating[updateID] = false; | ||
if (outerThis.updating.every((v) => !v)) document.dispatchEvent(outerThis.awaitEvents); | ||
clearTimeout(timeoutGuard); | ||
return outerThis.value; | ||
}; | ||
window.onbeforeunload = (callback) => { | ||
(async () => { | ||
console.log(this.updating, this.updating.some((v) => v)); | ||
if (this.updating.some((v) => v)) console.log(await new Promise((r) => document.addEventListener('DbDoneUpdating', r))); | ||
await this.update(); | ||
callback(); | ||
})(); | ||
}; | ||
return (async () => { | ||
const currentValue = await (await fetch(outerThis.path, { | ||
method: 'GET', | ||
headers: outerThis.headers, | ||
mode: 'cors', | ||
})).json(); | ||
outerThis.readOnlyValue = currentValue ?? settings.defaultValue ?? {}; | ||
const updated = currentValue ? this.value : await outerThis.update(); | ||
if (!settings.exportThis) return updated; | ||
return outerThis; | ||
})(); | ||
} | ||
if (typeof path !== 'string') throw new Error('Provided path is not a string'); | ||
@@ -81,10 +21,39 @@ if ((path.includes('/') || path.includes('.')) && !settings.ack?.noFSPath) console.warn('You seem to want to use a file system.\nSadly, to keep this as lightweight as possible, we will not be using any filesystem library based on localstorage but we will however use the localstorage.\nPlease change your path or acknowledge this issue (by setting `settings.ack.noFSPath`) to dismiss this warning.'); // eslint-disable-line no-console | ||
this.readOnlyValue = JSON.parse(localStorage.getItem(path)); | ||
this.update = () => { | ||
localStorage.setItem(this.path, JSON.stringify(this.readOnlyValue, null, this.saveSpace ? null : '\t')); | ||
return this.value; | ||
}; | ||
if (!settings.exportThis || settings.exportThis == null) return this.value; | ||
} | ||
genProxy(data) { | ||
return new Proxy(data, { | ||
set: (obj, prop, val) => { | ||
obj[prop] = val; | ||
if (this.saveOnChange) { | ||
this.update(); | ||
} | ||
return true; | ||
}, | ||
deleteProperty: (obj, prop) => { | ||
delete obj[prop]; | ||
if (this.saveOnChange) { | ||
this.update(); | ||
} | ||
return true; | ||
}, | ||
get: (obj, prop) => ( | ||
typeof obj[prop] === 'object' && obj[prop] | ||
? this.genProxy(obj[prop]) | ||
: obj[prop] | ||
), | ||
}); | ||
} | ||
/** | ||
* async Updates the file/db from this.readOnlyValue | ||
* @returns {any} - The json file | ||
*/ | ||
update() { | ||
localStorage.setItem(this.path, JSON.stringify(this.readOnlyValue, null, this.saveSpace ? null : '\t')); | ||
return this.readOnlyValue; | ||
} | ||
/** | ||
* @type {any} | ||
@@ -106,3 +75,3 @@ * @returns {true} | ||
get value() { | ||
return DbUtils.genProxy(this.readOnlyValue, this.saveOnChange, this.update); | ||
return this.genProxy(this.readOnlyValue); | ||
} | ||
@@ -109,0 +78,0 @@ } |
{ | ||
"name": "informa-db.js", | ||
"version": "4.1.0", | ||
"version": "5.0.0", | ||
"description": "DataBases made easier", | ||
@@ -5,0 +5,0 @@ "main": "server.js", |
# Informa-Db.js | ||
*Now with browser support* | ||
*and with online support* | ||
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section --> | ||
@@ -39,13 +38,2 @@ [![All Contributors](https://img.shields.io/badge/all_contributors-2-orange.svg?style=flat-square)](#contributors-) | ||
console.log(wordDocument.value); | ||
(async () => { | ||
const onlineDb = await (new Db('https://api.jsonbin.io/b/<Insert hex number here>', { | ||
request: { | ||
method: 'PUT', | ||
}, | ||
debug: true, | ||
})); | ||
console.log(onlineDb); | ||
onlineDb.working = 'Probably'; | ||
})(); | ||
``` | ||
@@ -69,22 +57,6 @@ | ||
#### `settings.saveSpace<Any>` | ||
Whether not to indent on file save | ||
Wether not to indent on file save | ||
Defaults to `false` | ||
-- | ||
The following applies if `path` starts with `https` | ||
#### `settings.request.debug` | ||
Whether to output the result of every request | ||
Defaults to false | ||
#### `settings.request.method` | ||
Method to use when updating the database | ||
Defaults to `POST` | ||
#### `settings.request.headers` | ||
Headers to send when updating/fetching the DB | ||
Defaults to `{}` | ||
`Accept` and `Content-Type` headers will always be `application/json` | ||
-- | ||
The following applies only if `settings.enableThis` was set to `true` | ||
@@ -99,6 +71,4 @@ | ||
### `DbUtils` | ||
#### `DbUtils.setAllTo( DBValue<Proxy>, setTo<Object/Array> )` | ||
#### `DbUtils.setAllTo( DB<Db>, setTo<Object/Array> )` | ||
"Resets" or sets the entire DB to a `setTo` | ||
#### `DbUtils.genProxy( JSONToListenTo<Db>, saveOnChange<Boolean>, update<function> )` | ||
Utility function used internally to listen for changes in a specific object | ||
@@ -105,0 +75,0 @@ ## Contributors ✨ |
100
server.js
@@ -5,10 +5,2 @@ const fs = require('fs'); | ||
let fetch; | ||
try { | ||
fetch = require('node-fetch'); // eslint-disable-line import/no-extraneous-dependencies, import/no-unresolved | ||
} catch { | ||
fetch = null; | ||
} | ||
Object.freeze(fetch); | ||
class Db { | ||
@@ -24,67 +16,45 @@ constructor(path, settings = {}) { | ||
this.path = path; | ||
if (path.match(/^https?:\/\//)) { | ||
if (!fetch) throw new Error('Has not found node-fetch installed'); | ||
this.debug = settings.debug; | ||
this.awaitEvents = new (require('events'))(); | ||
this.online = true; | ||
if (!settings.request) settings.request = {}; | ||
this.method = settings.request.method || 'POST'; | ||
if (!settings.request.headers) settings.request.headers = {}; | ||
settings.request.headers['Content-Type'] = 'application/json'; | ||
this.headers = settings.request.headers; | ||
this.updating = []; | ||
const outerThis = this; | ||
// Before posting this into r/badcode or r/programminghorror | ||
// please comment how you would've done it and u/ me | ||
// -Informa <u/informathemusic> | ||
if (!fs.existsSync(path)) fs.writeFileSync(path, JSON.stringify(settings.defaultValue) ?? '{}', (e) => { if (e) throw e; }); | ||
this.update = async () => { | ||
const updateID = outerThis.updating.length; | ||
outerThis.updating[updateID] = true; | ||
const timeoutGuard = setTimeout(async () => { | ||
if (outerThis.debug) console.warn('Request timed out'); | ||
outerThis.updating[updateID] = false; | ||
if (outerThis.updating.every((v) => !v)) outerThis.awaitEvents.emit('doneUpdating'); | ||
return outerThis.value; | ||
}, 5000); | ||
const fetched = await fetch(outerThis.path, { | ||
body: JSON.stringify(outerThis.readOnlyValue, null, outerThis.saveSpace ? null : '\t'), | ||
headers: outerThis.headers, | ||
method: outerThis.method, | ||
}); | ||
if (outerThis.debug) console.log(await fetched.text()); | ||
outerThis.updating[updateID] = false; | ||
if (outerThis.updating.every((v) => !v)) outerThis.awaitEvents.emit('doneUpdating'); | ||
clearTimeout(timeoutGuard); | ||
return outerThis.value; | ||
}; | ||
process.on('beforeExit', async () => { | ||
if (this.updating.some((v) => v)) await new Promise((r) => this.awaitEvents.once('doneUpdating', () => r)); | ||
await this.update(); | ||
return null; | ||
}); | ||
return (async () => { | ||
const currentValue = await (await fetch(outerThis.path, { | ||
method: 'GET', | ||
headers: this.headers, | ||
})).json(); | ||
outerThis.readOnlyValue = currentValue ?? settings.defaultValue ?? {}; | ||
const updated = currentValue ? this.value : await outerThis.update(); | ||
return updated; | ||
})(); | ||
} | ||
if (!fs.existsSync(path)) fs.writeFileSync(path, JSON.stringify(settings.defaultValue) ?? '{}', (e) => { if (e) throw e; }); | ||
if (fs.readFileSync(path, 'utf8') === '') fs.writeFileSync(path, JSON.stringify(settings.defaultValue) ?? '{}', (e) => { if (e) throw e; }); | ||
this.readOnlyValue = JSON.parse(fs.readFileSync(path, 'utf8')); | ||
this.update = () => { | ||
fs.writeFileSync(this.path, JSON.stringify(this.readOnlyValue, null, this.saveSpace ? null : '\t')); | ||
return this.value; | ||
}; | ||
if (!settings.exportThis || settings.exportThis == null) return this.value; | ||
} | ||
genProxy(data, saveOnChange, update) { | ||
return new Proxy(data, { | ||
set: (obj, prop, val) => { | ||
obj[prop] = val; | ||
if (saveOnChange) { | ||
update(); | ||
} | ||
return true; | ||
}, | ||
deleteProperty: (obj, prop) => { | ||
delete obj[prop]; | ||
if (saveOnChange) { | ||
update(); | ||
} | ||
return true; | ||
}, | ||
get: (obj, prop) => ( | ||
typeof obj[prop] === 'object' && obj[prop] | ||
? this.genProxy(obj[prop]) | ||
: obj[prop] | ||
), | ||
}); | ||
} | ||
/** | ||
* async Updates the file/db from this.readOnlyValue | ||
* @returns {any} - The json file | ||
*/ | ||
update() { | ||
fs.writeFileSync(this.path, JSON.stringify(this.readOnlyValue, null, this.saveSpace ? null : '\t')); | ||
return this.readOnlyValue; | ||
} | ||
/** | ||
* @type {any} | ||
@@ -106,3 +76,3 @@ * @returns {true} | ||
get value() { | ||
return DbUtils.genProxy(this.readOnlyValue, this.saveOnChange, this.update); | ||
return this.genProxy(this.readOnlyValue); | ||
} | ||
@@ -109,0 +79,0 @@ } |
31
utils.js
@@ -1,6 +0,5 @@ | ||
const utils = { | ||
module.exports = { | ||
setAllTo(db, setTo) { | ||
try { | ||
db.splice(0, db.length, ...setTo); | ||
} catch { | ||
if (db.splice) db.splice(0, db.length, ...setTo); | ||
else { | ||
Object.keys(db).forEach((k) => delete db[k]); | ||
@@ -10,26 +9,2 @@ Object.keys(setTo).forEach((k) => { db[k] = setTo[k]; }); | ||
}, | ||
genProxy(data, saveOnChange, update) { | ||
return new Proxy(data, { | ||
set: (obj, prop, val) => { | ||
obj[prop] = val; | ||
if (saveOnChange) { | ||
update(); | ||
} | ||
return true; | ||
}, | ||
deleteProperty: (obj, prop) => { | ||
delete obj[prop]; | ||
if (saveOnChange) { | ||
update(); | ||
} | ||
return true; | ||
}, | ||
get: (obj, prop) => ( | ||
typeof obj[prop] === 'object' && obj[prop] | ||
? this.genProxy(obj[prop]) | ||
: obj[prop] | ||
), | ||
}); | ||
}, | ||
}; | ||
module.exports = utils; |
export default { | ||
setAllTo(db, setTo) { | ||
try { | ||
db.splice(0, db.length, ...setTo); | ||
} catch { | ||
if (db.splice) db.splice(0, db.length, ...setTo); | ||
else { | ||
Object.keys(db).forEach((k) => delete db[k]); | ||
@@ -10,25 +9,2 @@ Object.keys(setTo).forEach((k) => { db[k] = setTo[k]; }); | ||
}, | ||
genProxy(data, saveOnChange, update) { | ||
return new Proxy(data, { | ||
set: (obj, prop, val) => { | ||
obj[prop] = val; | ||
if (saveOnChange) { | ||
update(); | ||
} | ||
return true; | ||
}, | ||
deleteProperty: (obj, prop) => { | ||
delete obj[prop]; | ||
if (saveOnChange) { | ||
update(); | ||
} | ||
return true; | ||
}, | ||
get: (obj, prop) => ( | ||
typeof obj[prop] === 'object' && obj[prop] | ||
? this.genProxy(obj[prop]) | ||
: obj[prop] | ||
), | ||
}); | ||
}, | ||
}; |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
1
10403
175
91