@trap_stevo/star-vault
Version:
Unleash the future of data management with the ultimate platform for secure, scalable, and dynamic data operations. Power the next generation of applications by combining advanced encryption, revolutionary real-time querying, and seamless synchronization
342 lines (341 loc) • 15.2 kB
JavaScript
"use strict";
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
var StorageEngine = require("./HUDControllers/StorageEngine");
var SecurityCore = require("./HUDControllers/SecurityCore");
var QueryEngine = require("./HUDControllers/QueryEngine");
var StarLogger = require("./HUDControllers/StarLogger");
var StarCache = require("./HUDControllers/StarCache");
var StarVault = /*#__PURE__*/function () {
function StarVault(dbPath, logPath) {
var shardCount = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 4;
var maxLogSize = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : "869MB";
var logRetention = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : "1w";
var options = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : {};
_classCallCheck(this, StarVault);
var _options$enableEncryp = options.enableEncryption,
enableEncryption = _options$enableEncryp === void 0 ? false : _options$enableEncryp,
_options$vaultPath = options.vaultPath,
vaultPath = _options$vaultPath === void 0 ? "./star-vault.json" : _options$vaultPath,
_options$masterKey = options.masterKey,
masterKey = _options$masterKey === void 0 ? null : _options$masterKey,
_options$authHandler = options.authHandler,
authHandler = _options$authHandler === void 0 ? null : _options$authHandler,
_options$dirMode = options.dirMode,
dirMode = _options$dirMode === void 0 ? 448 : _options$dirMode,
_options$fileMode = options.fileMode,
fileMode = _options$fileMode === void 0 ? 384 : _options$fileMode;
this.storage = new StorageEngine(dbPath, shardCount, {
dirMode: dirMode,
fileMode: fileMode
});
this.security = enableEncryption ? new SecurityCore({
masterKey: masterKey,
vaultPath: vaultPath,
dirMode: dirMode,
fileMode: fileMode
}) : null;
this.cache = new StarCache(1000);
this.wal = new StarLogger(logPath, maxLogSize, logRetention, dirMode, fileMode);
this.authHandler = authHandler;
this.listeners = new Map();
}
return _createClass(StarVault, [{
key: "authenticate",
value: function authenticate(clientAuth) {
if (!this.authHandler) {
return;
}
if (!this.authHandler(clientAuth)) {
throw new Error("Unauthorized access.");
}
}
}, {
key: "secureData",
value: function secureData(data, collection) {
return this.security ? this.security.lock(data, collection) : data;
}
}, {
key: "unsecureData",
value: function unsecureData(data, collection) {
if (!this.security || !data) {
return data;
}
try {
return this.security.unlock(data, collection);
} catch (error) {
console.error("Error decrypting data for collection ~ \"".concat(collection, "\" ~"), error.message);
throw new Error("Did not decrypt data for collection ~ \"".concat(collection, "\"."));
}
}
}, {
key: "create",
value: function create(collection, data) {
var actionInfo = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
var clientAuth = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
this.authenticate(clientAuth);
var id = data.id || Date.now().toString();
var record = {
id: id,
data: data,
timestamp: Date.now()
};
var securedData = this.secureData(record, collection);
this.wal.logWrite(collection, securedData, actionInfo);
this.storage.write(collection, id, securedData);
this.cache.set("".concat(collection, ":").concat(id), securedData);
console.log("Emitting create event for path ~ ".concat(collection, "/").concat(id));
this.emit("create", "".concat(collection, "/").concat(id), record);
return record;
}
}, {
key: "update",
value: function update(collection, id, updates) {
var actionInfo = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
var clientAuth = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : null;
this.authenticate(clientAuth);
var records = this.storage.read(collection).filter(function (r) {
return r.id === id;
});
if (records.length === 0) {
throw new Error("Record ~ ".concat(id, " not found."));
}
var currentRecord = this.unsecureData(records[0].data, collection);
var updatedData = _objectSpread(_objectSpread({}, currentRecord.data), updates);
var updatedRecord = {
id: currentRecord.id,
data: updatedData,
lastModified: Date.now(),
timestamp: currentRecord.timestamp
};
var securedData = this.secureData(updatedRecord, collection);
this.storage.write(collection, id, securedData);
this.wal.logWrite(collection, securedData, actionInfo, "UPDATE");
console.log("Emitting update event for path ~ ".concat(collection, "/").concat(id));
this.emit("update", "".concat(collection, "/").concat(id), updatedRecord);
return updatedRecord;
}
}, {
key: "deleteCollection",
value: function deleteCollection(collection) {
var actionInfo = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var clientAuth = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
this.authenticate(clientAuth);
var success = this.storage.deleteCollection(collection);
if (!success) {
console.log("Collection ~ ".concat(collection, " not found."));
return {
wholeCollection: true,
deleted: false
};
}
console.log("Emitting delete event for path ~ ".concat(collection));
this.wal.logSystemAction("DELETE", collection, {
wholeCollection: true
}, actionInfo);
this.emit("delete", "".concat(collection), {
wholeCollection: true,
deleted: true
});
return {
wholeCollection: true,
deleted: true
};
}
}, {
key: "deleteRecord",
value: function deleteRecord(collection, id) {
var actionInfo = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
var clientAuth = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
this.authenticate(clientAuth);
var success = this.storage["delete"](collection, id);
if (!success) {
console.log("Record ~ ".concat(id, " not found in collection ~ ").concat(collection, "."));
return {
id: id,
deleted: false
};
}
console.log("Emitting delete event for path ~ ".concat(collection, "/").concat(id));
this.wal.logSystemAction("DELETE", collection, {
id: id
}, actionInfo);
this.emit("delete", "".concat(collection, "/").concat(id), {
id: id,
deleted: true
});
return {
id: id,
deleted: true
};
}
}, {
key: "delete",
value: function _delete(collection, id) {
var actionInfo = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
var clientAuth = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
this.authenticate(clientAuth);
var records = this.storage.read(collection).filter(function (r) {
return r.id !== id;
});
var newRecords = records.map(function (r) {
return JSON.stringify(r);
}).join("\n");
this.storage.overwrite(collection, newRecords);
console.log("Emitting delete event for path ~ ".concat(collection, "/").concat(id));
this.wal.logSystemAction("DELETE", collection, {
id: id
}, actionInfo);
this.emit("delete", "".concat(collection, "/").concat(id), {
id: id,
deleted: true
});
return {
id: id,
deleted: true
};
}
}, {
key: "getByID",
value: function getByID(collection, id) {
var actionInfo = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
return this.query(collection, actionInfo).where("id", id).limit(1).execute()[0] || null;
}
}, {
key: "query",
value: function query(collection) {
var _this = this;
var actionInfo = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var queryEngine = new QueryEngine(this.storage, this.security).from(collection);
var queryObject = {
where: function where(criteria) {
queryEngine.where(criteria);
return queryObject;
},
search: function search(field, text) {
queryEngine.search(field, text);
return queryObject;
},
recent: function recent(field, duration) {
queryEngine.recent(field, duration);
return queryObject;
},
near: function near(field, center, radius) {
queryEngine.near(field, center, radius);
return queryObject;
},
sort: function sort(criteria) {
queryEngine.sort(criteria);
return queryObject;
},
contains: function contains(value) {
queryEngine.contains(value);
return queryObject;
},
select: function select(fields) {
queryEngine.select(fields);
return queryObject;
},
limit: function limit(value) {
queryEngine.limit(value);
return queryObject;
},
offset: function offset(value) {
queryEngine.offset(value);
return queryObject;
},
filterBy: function filterBy(fn) {
queryEngine.filterBy(fn);
return queryObject;
},
callback: function callback(fn) {
queryEngine.callback(fn);
return queryObject;
},
execute: function execute() {
var collections = _this.getMatchingCollections(collection);
queryEngine.from(collections);
var results = queryEngine.execute();
_this.wal.logSystemAction("QUERY", collection, {
collectionsQueried: collections,
results: results
}, actionInfo);
return results;
}
};
return queryObject;
}
}, {
key: "listen",
value: function listen(event, nodePath, callback) {
if (!this.listeners.has(event)) {
this.listeners.set(event, []);
}
this.listeners.get(event).push({
nodePath: nodePath,
callback: callback
});
console.log("Listener added for event ~ \"".concat(event, "\" on path ~ \"").concat(nodePath, "\""));
}
}, {
key: "emit",
value: function emit(event, nodePath, data) {
var _this2 = this;
if (this.listeners.has(event)) {
console.log("Processing emit for event ~ \"".concat(event, "\" on path ~ \"").concat(nodePath, "\""));
this.listeners.get(event).forEach(function (_ref) {
var listenerPath = _ref.nodePath,
callback = _ref.callback;
console.log("Matching listener path ~ \"".concat(listenerPath, "\" with node path ~ \"").concat(nodePath, "\""));
if (_this2.matchesPath(listenerPath, nodePath)) {
console.log("Listener triggered for path ~ \"".concat(listenerPath, "\""));
callback(nodePath, data);
}
});
}
}
}, {
key: "getMatchingCollections",
value: function getMatchingCollections(basePath) {
var allCollections = this.storage.listCollections();
var containsWildcard = basePath.includes("*");
var normalizedBase = basePath.replace(/\\/g, "/");
var regex = containsWildcard ? new RegExp("^" + normalizedBase.replace("*", ".*") + "$") : new RegExp("^" + normalizedBase.replace(/\/$/, "") + "(?:\/.*)?$");
var matchedCollections = allCollections.filter(function (collection) {
var normalized = collection.replace(/\\/g, "/");
return regex.test(normalized) || normalized.startsWith(normalizedBase);
});
console.log("Matched Collections for \"".concat(basePath, "\" ~"), matchedCollections);
return matchedCollections;
}
}, {
key: "matchesPath",
value: function matchesPath(listenerPath, nodePath) {
var listenerSegments = listenerPath.split("/");
var nodeSegments = nodePath.split("/");
if (listenerSegments.length > nodeSegments.length) {
console.log("Path mismatch: Listener path ~ \"".concat(listenerPath, "\" longer than node path ~ \"").concat(nodePath, "\""));
return false;
}
var match = listenerSegments.every(function (seg, idx) {
return seg === "*" || seg === nodeSegments[idx];
});
console.log("Path match result for \"".concat(listenerPath, "\" and \"").concat(nodePath, "\" ~ ").concat(match));
return match;
}
}], [{
key: "range",
value: function range(min, max) {
return QueryEngine.range(min, max);
}
}]);
}();
;
module.exports = StarVault;