UNPKG

@x5e/gink

Version:

an eventually consistent database

192 lines 8.48 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Container = void 0; const Bundler_1 = require("./Bundler"); const utils_1 = require("./utils"); const Deletion_1 = require("./Deletion"); const Inclusion_1 = require("./Inclusion"); const builders_1 = require("./builders"); const builders_2 = require("./builders"); const Addressable_1 = require("./Addressable"); const store_utils_1 = require("./store_utils"); class Container extends Addressable_1.Addressable { constructor(database, address, behavior) { super(address); this.database = database; this.behavior = behavior; } toString() { const address = this.address; return `Container(${address.timestamp},${address.medallion},${address.offset})`; } async toJson(indent = false, asOf, seen) { return Promise.resolve(`"${this.toString()}"`); } async setName(name, bundlerOrComment) { return await this.database .getGlobalProperty() .set(this, name, bundlerOrComment); } async getName(asOf) { return await this.database.getGlobalProperty().get(this, asOf); } async clear(purge, bundlerOrComment) { if (!(purge === undefined || purge === true || purge === false)) { throw new Error("first parameter to clear must be boolean (true => purge)"); } let immediate = false; let bundler; if (bundlerOrComment instanceof Bundler_1.Bundler) { bundler = bundlerOrComment; } else { immediate = true; bundler = new Bundler_1.Bundler(bundlerOrComment); } const clearanceBuilder = new builders_1.ClearanceBuilder(); clearanceBuilder.setPurge(purge || false); clearanceBuilder.setContainer((0, utils_1.muidToBuilder)(this.address, bundler.medallion)); const changeBuilder = new builders_1.ChangeBuilder(); changeBuilder.setClearance(clearanceBuilder); const address = bundler.addChange(changeBuilder); if (immediate) { await this.database.addBundler(bundler); } return address; } /** * Reset this Container to a previous time. If no time is specified, the container will * be cleared. * @param args Optional arguments, including: * @argument toTime Optional time to reset to. If absent, the container will be cleared. * @argument bundlerOrComment Bundler to add this change to, string to add a comment to a * new bundle, or empty to apply immediately. * @argument skipProperties If true, do not reset properties of this container. By default, * all properties associated with this container will be reset to the time specified in toTime. * @argument recurse Recursively reset all child containers held by this container at reset time? * @argument seen A Set of seen container muids (in string form) to prevent infinite recursion. * Primarily for internal use, but could be used to prevent specific containers from being reset. */ async reset(args) { throw new Error("Child class should have implemented this method."); } async size() { throw new Error("Child class should have implemented this method."); } /** * * @param key If absent, create a boxed entry, if KeyType, set a key in entry, if true, create a list entry * @param value What the container ought to contain (an immediate Value, a reference, or a deletion) * @param bundlerOrComment Bundler to add this change to, or empty to apply immediately. * @returns a promise the resolves to the muid of the change */ addEntry(key, value, bundlerOrComment) { let immediate = false; let bundler; if (bundlerOrComment instanceof Bundler_1.Bundler) { bundler = bundlerOrComment; } else { immediate = true; bundler = new Bundler_1.Bundler(bundlerOrComment); } const entryBuilder = new builders_1.EntryBuilder(); if (this.address) { entryBuilder.setContainer((0, utils_1.muidToBuilder)(this.address, bundler.medallion)); } entryBuilder.setBehavior(this.behavior); if (typeof key === "number" || typeof key === "string" || key instanceof Uint8Array) { entryBuilder.setKey((0, utils_1.wrapKey)(key)); } else if (Array.isArray(key)) { const pair = new builders_2.PairBuilder(); let key1 = key[0]; let key2 = key[1]; if ("address" in key[0] && "address" in key[1]) { key1 = key[0].address; key2 = key[1].address; } pair.setLeft((0, utils_1.muidToBuilder)(key1)); pair.setRite((0, utils_1.muidToBuilder)(key2)); entryBuilder.setPair(pair); } else if (key instanceof Addressable_1.Addressable) { entryBuilder.setDescribing((0, utils_1.muidToBuilder)(key.address)); } else if (key && "timestamp" in key) { entryBuilder.setDescribing((0, utils_1.muidToBuilder)(key)); } // TODO: check that the destination/value is compatible with Container if (value !== undefined) { if (value instanceof Addressable_1.Addressable) { entryBuilder.setPointee((0, utils_1.muidToBuilder)(value.address, bundler.medallion)); } else if (value instanceof Deletion_1.Deletion) { entryBuilder.setDeletion(true); } else if (value instanceof Inclusion_1.Inclusion) { } else { entryBuilder.setValue((0, utils_1.wrapValue)(value)); } } const changeBuilder = new builders_1.ChangeBuilder(); changeBuilder.setEntry(entryBuilder); const address = bundler.addChange(changeBuilder); if (immediate) { return this.database.addBundler(bundler).then((_) => address); } return Promise.resolve(address); } /** * Reset the properties associated with this container to a previous time. * @param toTime optional timestamp to reset to. If not provided, the properties will be deleted. * @param bundlerOrComment optional bundler to add this change to, or a string to add a comment to a new bundle. */ async resetProperties(toTime, bundlerOrComment) { let immediate = false; let bundler; if (bundlerOrComment instanceof Bundler_1.Bundler) { bundler = bundlerOrComment; } else { immediate = true; bundler = new Bundler_1.Bundler(bundlerOrComment); } const propertiesNow = await this.database.store.getContainerProperties(this); if (!toTime) { for (const [key, _] of propertiesNow.entries()) { const propertyMuid = (0, utils_1.strToMuid)(key); // Omitting value parameter creates a deleting entry (0, store_utils_1.bundlePropertyEntry)(bundler, propertyMuid, this.address); } } else { const propertiesThen = await this.database.store.getContainerProperties(this, toTime); for (const [key, value] of propertiesThen.entries()) { if (value !== propertiesNow.get(key)) { const propertyMuid = (0, utils_1.strToMuid)(key); (0, store_utils_1.bundlePropertyEntry)(bundler, propertyMuid, this.address, value); } // Remove from propertiesNow so we can delete the rest // after this iteration propertiesNow.delete(key); } // Now loop through the remaining propertiesNow and delete them for (const [key, _] of propertiesNow.entries()) { const propertyMuid = (0, utils_1.strToMuid)(key); // Omitting value parameter creates a deleting entry (0, store_utils_1.bundlePropertyEntry)(bundler, propertyMuid, this.address); } } if (immediate) { await this.database.addBundler(bundler); } } } exports.Container = Container; Container.DELETION = new Deletion_1.Deletion(); Container.INCLUSION = new Inclusion_1.Inclusion(); //# sourceMappingURL=Container.js.map