@trap_stevo/ventry
Version:
The universal engine for creating, tracking, and evolving interactive content — from posts, comments, and likes to offers, auctions, events, and beyond. Define, extend, and analyze content objects in real time. Turn anything into user-driven content.
491 lines (490 loc) • 19.8 kB
JavaScript
"use strict";
function _classPrivateFieldInitSpec(e, t, a) { _checkPrivateRedeclaration(e, t), t.set(e, a); }
function _checkPrivateRedeclaration(e, t) { if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object"); }
function _classPrivateFieldGet(s, a) { return s.get(_assertClassBrand(s, a)); }
function _classPrivateFieldSet(s, a, r) { return s.set(_assertClassBrand(s, a), r), r; }
function _assertClassBrand(e, t, n) { if ("function" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n; throw new TypeError("Private element is not present on this object"); }
const StarVault = require("@trap_stevo/star-vault");
var _auth = /*#__PURE__*/new WeakMap();
var _ai = /*#__PURE__*/new WeakMap();
class ContentVaultInstanceManager {
constructor(instance, options = {}, actionInfo = {}, clientAuth = null) {
_classPrivateFieldInitSpec(this, _auth, null);
_classPrivateFieldInitSpec(this, _ai, {});
this.vault = instance || new StarVault(options.dbPath || "./Ventry", options.logPath || "./Ventry_Logs", options.shardCount || 4, options.maxLogSize || "869MB", options.logRetention || "1w", options.options || {});
this.prefix = options.prefix || "ugc";
_classPrivateFieldSet(_auth, this, clientAuth);
_classPrivateFieldSet(_ai, this, actionInfo);
}
setDefaults(actionInfo = {}, clientAuth = null) {
_classPrivateFieldSet(_auth, this, clientAuth);
_classPrivateFieldSet(_ai, this, actionInfo);
}
setPrefix(prefix = "ugc") {
this.prefix = prefix || "ugc";
}
collection(name) {
return `${this.prefix}-${name}`;
}
upsertType(config, actionInfo) {
const TYPES = this.collection("types");
const existing = this.vault.query(TYPES, actionInfo || _classPrivateFieldGet(_ai, this)).whereRecord({
id: config.typeID
}).limit(1).execute(true)[0];
if (existing) {
return this.vault.update(TYPES, existing.id, {
...existing,
...config
}, actionInfo || _classPrivateFieldGet(_ai, this), _classPrivateFieldGet(_auth, this));
}
return this.vault.create(TYPES, {
id: config.typeID,
...config
}, actionInfo || _classPrivateFieldGet(_ai, this), _classPrivateFieldGet(_auth, this));
}
patchType(typeID, patch, actionInfo) {
const TYPES = this.collection("types");
const existing = this.vault.getByID(TYPES, typeID, actionInfo || _classPrivateFieldGet(_ai, this));
if (!existing) {
console.warn("Type not found.");
return null;
}
return this.vault.update(TYPES, typeID, {
...existing,
...patch
}, actionInfo || _classPrivateFieldGet(_ai, this), _classPrivateFieldGet(_auth, this));
}
listTypes(actionInfo) {
const TYPES = this.collection("types");
return this.vault.query(TYPES, actionInfo || _classPrivateFieldGet(_ai, this)).execute(true);
}
createItem(record, actionInfo) {
const ITEMS = this.collection("items");
return this.vault.create(ITEMS, record, actionInfo || _classPrivateFieldGet(_ai, this), _classPrivateFieldGet(_auth, this));
}
updateItem(id, updates, actionInfo) {
const ITEMS = this.collection("items");
return this.vault.update(ITEMS, id, updates, actionInfo || _classPrivateFieldGet(_ai, this), _classPrivateFieldGet(_auth, this));
}
softDelete(id, actionInfo) {
const ITEMS = this.collection("items");
return this.vault.update(ITEMS, id, {
deletedAt: Date.now(),
deleted: true
}, actionInfo || _classPrivateFieldGet(_ai, this), _classPrivateFieldGet(_auth, this));
}
deleteRecord(id, actionInfo) {
const ITEMS = this.collection("items");
return this.vault.deleteRecord(ITEMS, id, actionInfo || _classPrivateFieldGet(_ai, this), _classPrivateFieldGet(_auth, this));
}
getItems(actionInfo) {
const ITEMS = this.collection("items");
return this.vault.query(ITEMS, actionInfo || _classPrivateFieldGet(_ai, this));
}
getItem(id, actionInfo) {
const ITEMS = this.collection("items");
return this.vault.getByID(ITEMS, id, actionInfo || _classPrivateFieldGet(_ai, this));
}
queryItems(typeID, filter, sort, page, projection, actionInfo) {
const ITEMS = this.collection("items");
let qb = this.vault.query(ITEMS, actionInfo || _classPrivateFieldGet(_ai, this));
if (typeID) {
qb = qb.where({
typeID
});
}
if (filter && typeof filter === "object") {
qb = qb.where(filter);
}
if (sort) {
qb = qb.sort(sort.reduce((o, s) => {
o[s.path] = s.dir === "asc" ? 1 : -1;
return o;
}, {}));
}
if (projection) {
qb = qb.select(projection);
}
if (page && page.limit) {
qb = qb.limit(page.limit);
}
if (page && page.offset) {
qb = qb.offset(page.offset);
}
return qb;
}
getContentRecordHistory(collectionID = "items", id, options = {}, actionInfo, clientAuth) {
const collection = this.collection(collectionID);
return this.vault.getRecordHistory(collection, id, options, actionInfo || _classPrivateFieldGet(_ai, this), clientAuth || _classPrivateFieldGet(_auth, this));
}
getContentRecordTimeline(collectionID = "items", id, options = {}, actionInfo, clientAuth) {
const collection = this.collection(collectionID);
return this.vault.getRecordTimeline(collection, id, options, actionInfo || _classPrivateFieldGet(_ai, this), clientAuth || _classPrivateFieldGet(_auth, this));
}
getContentHistory(collectionID = "items", options = {}, actionInfo, clientAuth) {
const collection = this.collection(collectionID);
return this.vault.getCollectionHistory(collection, options, actionInfo || _classPrivateFieldGet(_ai, this), clientAuth || _classPrivateFieldGet(_auth, this));
}
getContentTimeline(collectionID = "items", options = {}, actionInfo, clientAuth) {
const collection = this.collection(collectionID);
return this.vault.getCollectionTimeline(collection, options, actionInfo || _classPrivateFieldGet(_ai, this), clientAuth || _classPrivateFieldGet(_auth, this));
}
getHistory(options = {}, actionInfo, clientAuth) {
return this.vault.getVaultHistory(options, actionInfo || _classPrivateFieldGet(_ai, this), clientAuth || _classPrivateFieldGet(_auth, this));
}
async syncHistory(actionInfo, clientAuth) {
return await this.vault.syncHistory(actionInfo || _classPrivateFieldGet(_ai, this), clientAuth || _classPrivateFieldGet(_auth, this));
}
importContentRecord(collectionID = "items", record, options = {}, actionInfo, clientAuth) {
const collection = this.collection(collectionID);
return this.vault.importRecord(collection, record, options, actionInfo || _classPrivateFieldGet(_ai, this), clientAuth || _classPrivateFieldGet(_auth, this));
}
importManyContentRecords(collectionID = "items", records, options = {}, actionInfo, clientAuth) {
const collection = this.collection(collectionID);
return this.vault.importManyRecords(collection, records, options, actionInfo || _classPrivateFieldGet(_ai, this), clientAuth || _classPrivateFieldGet(_auth, this));
}
importContent(collectionID = "items", records, options = {}, actionInfo, clientAuth) {
const collection = this.collection(collectionID);
return this.vault.importCollection(collection, records, options, actionInfo || _classPrivateFieldGet(_ai, this), clientAuth || _classPrivateFieldGet(_auth, this));
}
importSnapshot(snapshot, options = {}, actionInfo, clientAuth) {
return this.vault.importStateSnapshot(snapshot, options, actionInfo || _classPrivateFieldGet(_ai, this), clientAuth || _classPrivateFieldGet(_auth, this));
}
createComment(rec, actionInfo) {
const COMMENTS = this.collection("comments");
return this.vault.create(COMMENTS, rec, actionInfo || _classPrivateFieldGet(_ai, this), _classPrivateFieldGet(_auth, this));
}
updateComment(id, updates, actionInfo) {
const COMMENTS = this.collection("comments");
return this.vault.update(COMMENTS, id, updates, actionInfo || _classPrivateFieldGet(_ai, this), _classPrivateFieldGet(_auth, this));
}
getComment(id, actionInfo) {
const COMMENTS = this.collection("comments");
return this.vault.getByID(COMMENTS, id, actionInfo || _classPrivateFieldGet(_ai, this));
}
queryComments(filter, sort, page, actionInfo) {
const COMMENTS = this.collection("comments");
let qb = this.vault.query(COMMENTS, actionInfo || _classPrivateFieldGet(_ai, this));
if (filter) {
qb = qb.where(filter);
}
if (sort) {
qb = qb.sort(sort);
}
if (page && page.limit) {
qb = qb.limit(page.limit);
}
if (page && page.offset) {
qb = qb.offset(page.offset);
}
return qb;
}
createOffer(rec, actionInfo) {
const OFFERS = this.collection("offers");
return this.vault.create(OFFERS, rec, actionInfo || _classPrivateFieldGet(_ai, this), _classPrivateFieldGet(_auth, this));
}
updateOffer(id, updates, actionInfo) {
const OFFERS = this.collection("offers");
return this.vault.update(OFFERS, id, updates, actionInfo || _classPrivateFieldGet(_ai, this), _classPrivateFieldGet(_auth, this));
}
getOffer(id, actionInfo) {
const OFFERS = this.collection("offers");
return this.vault.getByID(OFFERS, id, actionInfo || _classPrivateFieldGet(_ai, this));
}
queryOffers(filter, sort, page, actionInfo) {
const OFFERS = this.collection("offers");
let qb = this.vault.query(OFFERS, actionInfo || _classPrivateFieldGet(_ai, this));
if (filter) {
qb = qb.where(filter);
}
if (sort) {
qb = qb.sort(sort);
}
if (page && page.limit) {
qb = qb.limit(page.limit);
}
if (page && page.offset) {
qb = qb.offset(page.offset);
}
return qb;
}
createAuction(rec, actionInfo) {
const AUCTIONS = this.collection("auctions");
return this.vault.create(AUCTIONS, rec, actionInfo || _classPrivateFieldGet(_ai, this), _classPrivateFieldGet(_auth, this));
}
updateAuction(id, updates, actionInfo) {
const AUCTIONS = this.collection("auctions");
return this.vault.update(AUCTIONS, id, updates, actionInfo || _classPrivateFieldGet(_ai, this), _classPrivateFieldGet(_auth, this));
}
getAuction(id, actionInfo) {
const AUCTIONS = this.collection("auctions");
return this.vault.getByID(AUCTIONS, id, actionInfo || _classPrivateFieldGet(_ai, this));
}
queryAuctions(filter, sort, page, actionInfo) {
const AUCTIONS = this.collection("auctions");
let qb = this.vault.query(AUCTIONS, actionInfo || _classPrivateFieldGet(_ai, this));
if (filter) {
qb = qb.where(filter);
}
if (sort) {
qb = qb.sort(sort);
}
if (page && page.limit) {
qb = qb.limit(page.limit);
}
if (page && page.offset) {
qb = qb.offset(page.offset);
}
return qb;
}
createBid(rec, actionInfo) {
const BIDS = this.collection("bids");
return this.vault.create(BIDS, rec, actionInfo || _classPrivateFieldGet(_ai, this), _classPrivateFieldGet(_auth, this));
}
updateBid(id, updates, actionInfo) {
const BIDS = this.collection("bids");
return this.vault.update(BIDS, id, updates, actionInfo || _classPrivateFieldGet(_ai, this), _classPrivateFieldGet(_auth, this));
}
getBid(id, actionInfo) {
const BIDS = this.collection("bids");
return this.vault.getByID(BIDS, id, actionInfo || _classPrivateFieldGet(_ai, this));
}
queryBids(filter, sort, page, actionInfo) {
const BIDS = this.collection("bids");
let qb = this.vault.query(BIDS, actionInfo || _classPrivateFieldGet(_ai, this));
if (filter) {
qb = qb.where(filter);
}
if (sort) {
qb = qb.sort(sort);
}
if (page && page.limit) {
qb = qb.limit(page.limit);
}
if (page && page.offset) {
qb = qb.offset(page.offset);
}
return qb;
}
createSubvault(rec, actionInfo, branch = "subvault") {
const collectionName = this.collection(branch);
return this.vault.create(collectionName, rec, actionInfo || _classPrivateFieldGet(_ai, this), _classPrivateFieldGet(_auth, this));
}
updateSubvault(id, updates, actionInfo, branch = "subvault") {
const collectionName = this.collection(branch);
return this.vault.update(collectionName, id, updates, actionInfo || _classPrivateFieldGet(_ai, this), _classPrivateFieldGet(_auth, this));
}
getSubvault(id, actionInfo, branch = "subvault") {
const collectionName = this.collection(branch);
return this.vault.getByID(collectionName, id, actionInfo || _classPrivateFieldGet(_ai, this));
}
querySubvault(filter, sort, page, projection, actionInfo, branch = "subvault") {
const collectionName = this.collection(branch);
let qb = this.vault.query(collectionName, actionInfo || _classPrivateFieldGet(_ai, this));
if (filter && typeof filter === "object") {
qb = qb.where(filter);
}
if (sort) {
qb = qb.sort(sort);
}
if (projection) {
qb = qb.select(projection);
}
if (page && page.limit) {
qb = qb.limit(page.limit);
}
if (page && page.offset) {
qb = qb.offset(page.offset);
}
return qb;
}
querySubvaultByParent(parentID, opts = {}, actionInfo, branch = "subvault") {
const collectionName = this.collection(branch);
let qb = this.vault.query(collectionName, actionInfo || _classPrivateFieldGet(_ai, this)).where({
parentID
});
if (opts.filter && typeof opts.filter === "object") {
qb = qb.where(opts.filter);
}
if (opts.sort) {
qb = qb.sort(opts.sort);
}
if (opts.projection) {
qb = qb.select(opts.projection);
}
if (opts.page && opts.page.limit) {
qb = qb.limit(opts.page.limit);
}
if (opts.page && opts.page.offset) {
qb = qb.offset(opts.page.offset);
}
return qb;
}
getSubvaultByKey(parentID, key, actionInfo, branch = "subvault") {
const qb = this.querySubvaultByParent(parentID, {
filter: {
key
},
page: {
limit: 1
}
}, actionInfo, branch);
const items = qb.execute(true);
return items[0] || null;
}
upsertSubvaultByKey(parentID, ownerID, key, payload = {}, extras = {}, actionInfo, branch = "subvault") {
const existing = this.getSubvaultByKey(parentID, key, actionInfo, branch);
if (existing) {
const updates = {
payload,
tags: Array.isArray(extras.tags) ? extras.tags : existing.tags,
labels: Array.isArray(extras.labels) ? extras.labels : existing.labels,
status: extras.status || existing.status || "active",
expiresAt: extras.expiresAt !== undefined ? extras.expiresAt : existing.expiresAt,
updatedAt: Date.now()
};
return this.updateSubvault(existing.id, updates, actionInfo, branch);
}
const rec = {
parentID,
ownerID,
key,
payload,
tags: Array.isArray(extras.tags) ? extras.tags : [],
labels: Array.isArray(extras.labels) ? extras.labels : [],
status: extras.status || "active",
createdAt: Date.now(),
updatedAt: Date.now(),
expiresAt: extras.expiresAt || null
};
return this.createSubvault(rec, actionInfo, branch);
}
existsSubvaultKey(parentID, key, actionInfo, branch = "subvault") {
return !!this.getSubvaultByKey(parentID, key, actionInfo, branch);
}
countSubvault(parentID, filter = {}, actionInfo, branch = "subvault") {
const qb = this.querySubvaultByParent(parentID, {
filter
}, actionInfo, branch);
const items = qb.execute(true);
return items.length;
}
listSubvaultKeys(parentID, filter = {}, actionInfo, branch = "subvault") {
const qb = this.querySubvaultByParent(parentID, {
filter,
page: {
limit: 1000
}
}, actionInfo, branch);
const items = qb.execute(true);
return items.map(it => it.data && it.data.key).filter(Boolean);
}
touchSubvault(subvaultID, actionInfo, branch = "subvault") {
return this.updateSubvault(subvaultID, {
updatedAt: Date.now()
}, actionInfo, branch);
}
setSubvaultStatus(subvaultID, status, actionInfo, branch = "subvault") {
return this.updateSubvault(subvaultID, {
status,
updatedAt: Date.now()
}, actionInfo, branch);
}
moveSubvault(subvaultID, toParentID, actionInfo, branch = "subvault") {
return this.updateSubvault(subvaultID, {
parentID: toParentID,
updatedAt: Date.now()
}, actionInfo, branch);
}
cloneSubvaultRecords(fromParentID, toParentID, options = {}, actionInfo, fromBranch = "subvault", toBranch = null) {
const {
includeKeys,
excludeKeys
} = options || {};
const allow = Array.isArray(includeKeys) && includeKeys.length > 0 ? new Set(includeKeys) : null;
const deny = Array.isArray(excludeKeys) && excludeKeys.length > 0 ? new Set(excludeKeys) : null;
const fromItems = this.querySubvaultByParent(fromParentID, {}, actionInfo, fromBranch).execute(true);
const created = [];
const targetBranch = toBranch || fromBranch;
for (const it of fromItems) {
const k = it.data ? it.data.key : undefined;
if (allow && !allow.has(k)) {
continue;
}
if (deny && deny.has(k)) {
continue;
}
const rec = {
parentID: toParentID,
ownerID: it.data?.ownerID,
key: k,
payload: it.data?.payload || {},
tags: it.data?.tags || [],
labels: it.data?.labels || [],
status: it.data?.status || "active",
createdAt: Date.now(),
updatedAt: Date.now(),
expiresAt: it.data?.expiresAt || null
};
const r = this.createSubvault(rec, actionInfo, targetBranch);
created.push(r.id);
}
return {
created
};
}
purgeExpiredSubvault(parentID, actionInfo, branch = "subvault") {
const collectionName = this.collection(branch);
let qb = this.vault.query(collectionName, actionInfo || _classPrivateFieldGet(_ai, this)).where({
expiresAt: {
$ne: null,
$lte: Date.now()
}
});
if (parentID) {
qb = qb.where({
parentID
});
}
const items = qb.execute(true);
for (const it of items) {
this.vault.deleteRecord(collectionName, it.id, actionInfo || _classPrivateFieldGet(_ai, this), _classPrivateFieldGet(_auth, this));
}
return {
deleted: items.length
};
}
softDeleteSubvault(id, actionInfo, branch = "subvault") {
const collectionName = this.collection(branch);
return this.vault.update(collectionName, id, {
deletedAt: Date.now(),
deleted: true
}, actionInfo || _classPrivateFieldGet(_ai, this), _classPrivateFieldGet(_auth, this));
}
deleteSubvault(id, actionInfo, branch = "subvault") {
const collectionName = this.collection(branch);
return this.vault.deleteRecord(collectionName, id, actionInfo || _classPrivateFieldGet(_ai, this), _classPrivateFieldGet(_auth, this));
}
deleteAllSubvaultForParent(parentID, {
hard = false
} = {}, actionInfo, branch = "subvault") {
const collectionName = this.collection(branch);
const items = this.vault.query(collectionName, actionInfo || _classPrivateFieldGet(_ai, this)).where({
parentID
}).execute(true);
for (const it of items) {
if (hard === true) {
this.vault.deleteRecord(collectionName, it.id, actionInfo || _classPrivateFieldGet(_ai, this), _classPrivateFieldGet(_auth, this));
} else {
this.vault.update(collectionName, it.id, {
deletedAt: Date.now(),
deleted: true
}, actionInfo || _classPrivateFieldGet(_ai, this), _classPrivateFieldGet(_auth, this));
}
}
}
}
;
module.exports = {
ContentVaultInstanceManager
};