@x5e/gink
Version:
an eventually consistent database
187 lines • 7.91 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Container = void 0;
const utils_1 = require("./utils");
const store_utils_1 = require("./store_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 factories_1 = require("./factories");
const utils_2 = require("./utils");
class Container extends Addressable_1.Addressable {
constructor(database, address, behavior) {
super(address);
this.database = database;
this.behavior = behavior;
}
[utils_2.inspectSymbol](depth, opts) {
/*
const timestamp = this.address.timestamp;
const medallion = this.address.medallion;
const offset = this.address.offset;
{timestamp: ${timestamp}, medallion: ${medallion}, offset: ${offset}}
*/
/*
{
stylize: [Function: stylizeWithColor],
showHidden: false,
depth: 2,
colors: true,
customInspect: true,
showProxy: true,
maxArrayLength: 100,
maxStringLength: 10000,
breakLength: 80,
compact: 3,
sorted: false,
getters: false,
numericSeparator: false
}
*/
return `[${this.whatAmI()}]`;
}
whatAmI() {
const name = this.constructor?.name;
if (name && name.length > 2)
return name;
return "(Minified)";
}
static async addContainer({ database, behavior, meta, }) {
const bundler = await database.startBundle(meta);
const containerBuilder = new builders_1.ContainerBuilder();
containerBuilder.setBehavior(behavior);
const muid = bundler.addChange(new builders_1.ChangeBuilder().setContainer(containerBuilder));
if (!meta?.bundler) {
await bundler.commit();
}
return muid;
}
async setName(name, meta) {
return await this.addEntry(this, name, meta, Container.globalPropertyMuid);
}
async getName(asOf) {
const entry = await this.database.store.getEntryByKey(Container.globalPropertyMuid, this.address, asOf);
const result = await (0, factories_1.interpret)(entry, this.database);
return result;
}
async clear(purge, meta) {
const bundler = await this.database.startBundle(meta);
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 (!meta?.bundler) {
await bundler.commit();
}
return address;
}
addEntry(key, value, meta, onContainer) {
return this.database.startBundle(meta).then((bundler) => {
const entryBuilder = new builders_1.EntryBuilder();
if (!this.address)
throw new Error("unexpected");
entryBuilder.setContainer((0, utils_1.muidToBuilder)(onContainer ?? this.address, bundler.medallion));
let behavior = this.behavior;
if (onContainer) {
if (onContainer.timestamp !== -1)
throw new Error("unexpected");
behavior = onContainer.offset;
}
entryBuilder.setBehavior(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 (!meta?.bundler) {
return bundler.commit().then(() => address);
}
return 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, meta) {
const bundler = await this.database.startBundle(meta);
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 (!meta?.bundler) {
await bundler.commit();
}
}
}
exports.Container = Container;
Container.DELETION = new Deletion_1.Deletion();
Container.INCLUSION = new Inclusion_1.Inclusion();
Container.globalPropertyMuid = {
medallion: -1,
timestamp: -1,
offset: builders_1.Behavior.PROPERTY,
};
//# sourceMappingURL=Container.js.map