kv-storage
Version:
💾 Create data storage that uses a simple key-value method for Node, Browser, Deno, Bun, Cloudflare Workers
415 lines (414 loc) • 17.3 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.KVStorage = void 0;
function KVStorage({ runtime = 'node', databaseName = 'kvstorage', storageName = 'storage', databaseBinding }) {
return __awaiter(this, void 0, void 0, function* () {
function isAlphanumeric(str) {
return /^[a-zA-Z0-9]+$/.test(str);
}
function showError(msg = 'Error') {
throw new Error(msg);
}
if (!isAlphanumeric(runtime))
showError('Runtime must be Alphanumeric');
if (!isAlphanumeric(databaseName))
showError('storageName must be Alphanumeric');
if (!isAlphanumeric(storageName))
showError('storageName must be Alphanumeric');
switch (runtime.toLowerCase()) {
case 'node':
if (typeof caches === "undefined" && typeof global !== "undefined" && typeof window === "undefined") {
let runnode;
try {
const url = './kv-storage-module';
runnode = yield Promise.resolve(`${url}`).then(s => __importStar(require(s)));
}
catch (_a) {
const url = './kv-storage-module.js';
runnode = yield Promise.resolve(`${url}`).then(s => __importStar(require(s)));
}
const dbnode = yield runnode.KVStorageModule.init({
dataDirName: databaseName,
storageName
});
return dbnode;
}
break;
case 'deno':
if ((typeof caches !== "undefined" && typeof global !== "undefined" && typeof window === "undefined") || (typeof caches !== "undefined" && typeof global === "undefined" && typeof window !== "undefined")) {
let rundeno;
try {
const url = './kv-storage-module.ts';
rundeno = yield Promise.resolve(`${url}`).then(s => __importStar(require(s)));
}
catch (_b) {
const url = './kv-storage-module.js';
rundeno = yield Promise.resolve(`${url}`).then(s => __importStar(require(s)));
}
const dbdeno = yield rundeno.KVStorageModule.init({
dataDirName: databaseName,
storageName
});
return dbdeno;
}
break;
case 'bun':
if (typeof caches === "undefined" && typeof global !== "undefined" && typeof window === "undefined") {
let runbun;
try {
const url = './kv-storage-module';
runbun = yield Promise.resolve(`${url}`).then(s => __importStar(require(s)));
}
catch (_c) {
const url = './kv-storage-module.js';
runbun = yield Promise.resolve(`${url}`).then(s => __importStar(require(s)));
}
const dbbun = yield runbun.KVStorageModule.init({
dataDirName: databaseName,
storageName
});
return dbbun;
}
break;
case 'browser':
if (typeof window !== "undefined" && typeof window.document !== "undefined") {
if (databaseName === 'kvstorage')
databaseName = storageName;
const dbbrowser = KVStorageBrowser.init({
databaseName,
storageName
});
return dbbrowser;
}
break;
case 'cloudflare':
if (typeof caches !== "undefined" && typeof global === "undefined" && typeof window === "undefined") {
const dbcloudflare = yield KVStorageCloudflare.init({
databaseBinding,
storageName
});
return dbcloudflare;
}
break;
default:
showError('Runtime unknown');
}
});
}
exports.KVStorage = KVStorage;
class KVStorageCloudflare {
constructor({ databaseBinding, storageName }) {
this._databaseBinding = databaseBinding;
this._storageName = storageName;
}
isAlphanumeric(str) {
return /^[a-zA-Z0-9]+$/.test(str);
}
showError(msg = 'Error') {
throw new Error(msg);
}
static init({ databaseBinding, storageName, }) {
return __awaiter(this, void 0, void 0, function* () {
function isAlphanumeric(str) {
return /^[a-zA-Z0-9]+$/.test(str);
}
function showError(msg = 'Error') {
throw new Error(msg);
}
if (!isAlphanumeric(storageName))
showError('storageName must be Alphanumeric');
const stmt = databaseBinding.prepare('CREATE TABLE IF NOT EXISTS ' + storageName + ' (key text NOT NULL PRIMARY KEY,value text NOT NULL)');
const values = yield stmt.run();
return new KVStorageCloudflare({ databaseBinding, storageName });
});
}
put(key, value) {
return __awaiter(this, void 0, void 0, function* () {
if (!this.isAlphanumeric(key))
this.showError('Key must be Alphanumeric');
const stmt = this._databaseBinding.prepare('SELECT value FROM ' + this._storageName + ' WHERE key = ?1').bind(key);
const values = yield stmt.first();
if (values == null) {
const stmt = this._databaseBinding.prepare('INSERT INTO ' + this._storageName + ' (key,value) VALUES (?1,?2)').bind(key, value);
const values = yield stmt.run();
return values.success;
}
else {
const stmt = this._databaseBinding.prepare('UPDATE ' + this._storageName + ' SET value = ?2 WHERE key = ?1').bind(key, value);
const values = yield stmt.run();
return values.success;
}
});
}
get(key) {
return __awaiter(this, void 0, void 0, function* () {
if (!this.isAlphanumeric(key))
this.showError('Key must be Alphanumeric');
const stmt = this._databaseBinding.prepare('SELECT value FROM ' + this._storageName + ' WHERE key = ?1').bind(key);
const values = yield stmt.first();
let output;
if (values == null) {
output = false;
}
else {
output = values.value;
}
return output;
});
}
delete(key) {
return __awaiter(this, void 0, void 0, function* () {
if (!this.isAlphanumeric(key))
this.showError('Key must be Alphanumeric');
const stmt = this._databaseBinding.prepare('DELETE FROM ' + this._storageName + ' WHERE key = ?1').bind(key);
const values = yield stmt.run();
return values.success;
});
}
has(key) {
return __awaiter(this, void 0, void 0, function* () {
if (!this.isAlphanumeric(key))
this.showError('Key must be Alphanumeric');
const stmt = this._databaseBinding.prepare('SELECT value FROM ' + this._storageName + ' WHERE key = ?1').bind(key);
const values = yield stmt.run();
let output;
if (values.results == 0) {
output = false;
}
else {
output = true;
}
return output;
});
}
list() {
return __awaiter(this, void 0, void 0, function* () {
const stmt = this._databaseBinding.prepare('SELECT key FROM ' + this._storageName).bind();
const values = yield stmt.all();
let output;
if (values.success) {
let keys = [];
values.results.forEach((obj) => {
keys.push(obj.key);
});
let result = {
keys: keys,
complete: true
};
output = result;
}
else {
output = false;
}
return output;
});
}
clear() {
return __awaiter(this, void 0, void 0, function* () {
const stmt = this._databaseBinding.prepare('DELETE FROM ' + this._storageName);
const values = yield stmt.run();
return values.success;
});
}
}
class KVStorageBrowser {
constructor({ databaseName, storageName, dbVersion, iDB }) {
this._databaseName = databaseName;
this._storageName = storageName;
this._dbVersion = 1;
this._iDB = iDB;
}
isAlphanumeric(str) {
return /^[a-zA-Z0-9]+$/.test(str);
}
showError(msg = 'Error') {
throw new Error(msg);
}
static init({ databaseName = "data", storageName, }) {
return __awaiter(this, void 0, void 0, function* () {
function isAlphanumeric(str) {
return /^[a-zA-Z0-9]+$/.test(str);
}
function showError(msg = 'Error') {
throw new Error(msg);
}
function indexedDBStuff() {
// Check for IndexedDB support
if (!('indexedDB' in window)) {
// Can't use IndexedDB
showError("This browser doesn't support IndexedDB");
return;
}
else {
// Do IndexedDB stuff here
}
}
// Run IndexedDB code
indexedDBStuff();
const dbVersion = 1;
if (!isAlphanumeric(databaseName))
showError('dataDirName must be Alphanumeric');
if (!isAlphanumeric(storageName))
showError('storageName must be Alphanumeric');
const createdb = new Promise((resolve) => {
let request = window.indexedDB.open(databaseName, dbVersion);
request.onerror = function () {
console.error("Error", request.error);
};
request.onsuccess = function () {
let db = request.result;
resolve(db);
};
request.onupgradeneeded = function (event) {
let db = request.result;
if (!db.objectStoreNames.contains(storageName)) {
db.createObjectStore(storageName, { keyPath: 'key' });
}
};
request.onblocked = function () {
console.error("Error, conflict");
};
});
const iDB = yield createdb;
return new KVStorageBrowser({ databaseName, storageName, dbVersion, iDB });
});
}
put(key, value) {
return __awaiter(this, void 0, void 0, function* () {
return new Promise((resolve) => {
if (!this.isAlphanumeric(key))
this.showError('Key must be Alphanumeric');
let transaction = this._iDB.transaction(this._storageName, "readwrite");
let request = transaction.objectStore(this._storageName).put({ key: key, value: value });
request.onsuccess = function () {
resolve(true);
};
request.onerror = function () {
resolve(false);
};
});
});
}
get(key) {
return __awaiter(this, void 0, void 0, function* () {
return new Promise((resolve) => {
if (!this.isAlphanumeric(key))
this.showError('Key must be Alphanumeric');
let transaction = this._iDB.transaction(this._storageName, "readonly");
let request = transaction.objectStore(this._storageName).get(key);
request.onsuccess = function (event) {
if (request.result != undefined) {
resolve(request.result.value);
}
else {
resolve(false);
}
};
request.onerror = function () {
resolve(false);
};
});
});
}
delete(key) {
return __awaiter(this, void 0, void 0, function* () {
return new Promise((resolve) => {
if (!this.isAlphanumeric(key))
this.showError('Key must be Alphanumeric');
let transaction = this._iDB.transaction(this._storageName, "readwrite");
let request = transaction.objectStore(this._storageName).delete(key);
request.onsuccess = function (event) {
resolve(true);
};
request.onerror = function () {
resolve(false);
};
});
});
}
has(key) {
return __awaiter(this, void 0, void 0, function* () {
return new Promise((resolve) => {
if (!this.isAlphanumeric(key))
this.showError('Key must be Alphanumeric');
let transaction = this._iDB.transaction(this._storageName, "readonly");
let request = transaction.objectStore(this._storageName).get(key);
request.onsuccess = function (event) {
if (request.result != undefined) {
resolve(true);
}
else {
resolve(false);
}
};
request.onerror = function () {
resolve(false);
};
});
});
}
list() {
return __awaiter(this, void 0, void 0, function* () {
return new Promise((resolve) => {
let transaction = this._iDB.transaction(this._storageName, "readonly");
let request = transaction.objectStore(this._storageName).getAllKeys();
request.onsuccess = function (event) {
let result = {
keys: request.result,
complete: true
};
resolve(result);
};
request.onerror = function () {
resolve(false);
};
});
});
}
clear() {
return __awaiter(this, void 0, void 0, function* () {
return new Promise((resolve) => {
let transaction = this._iDB.transaction(this._storageName, "readwrite");
let request = transaction.objectStore(this._storageName).clear();
request.onsuccess = function (event) {
resolve(true);
};
request.onerror = function () {
resolve(false);
};
});
});
}
}