@x5e/gink
Version:
an eventually consistent database
127 lines • 5.25 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Box = void 0;
const Container_1 = require("./Container");
const Bundler_1 = require("./Bundler");
const utils_1 = require("./utils");
const factories_1 = require("./factories");
const builders_1 = require("./builders");
class Box extends Container_1.Container {
constructor(database, address, containerBuilder) {
super(database, address, builders_1.Behavior.BOX);
if (this.address.timestamp < 0) {
//TODO(https://github.com/google/gink/issues/64): document default magic containers
(0, utils_1.ensure)(address.offset === builders_1.Behavior.BOX);
}
else {
(0, utils_1.ensure)(containerBuilder.getBehavior() === builders_1.Behavior.BOX);
}
}
/**
* Puts a value or a reference to another container in this box.
* If a bundler is supplied, the function will add the entry to that bundler
* and return immediately (presumably you know what to do with a CS if you passed it in).
* If the caller does not supply a bundler, then one is created on the fly, and
* then this method will await on the CS being added to the database instance.
* This is to allow simple console usage like:
* await myBox.put("some value");
* @param value
* @param change an optional bundler to put this in.
* @returns a promise that resolves to the address of the newly created entry
*/
async set(value, change) {
return this.addEntry(undefined, value, change);
}
/**
* Returns a promise that resolves to the most recent value put in the box, or undefined.
* @returns undefined, a basic value, or a container
*/
async get(asOf) {
const entry = await this.database.store.getEntryByKey(this.address, undefined, asOf);
return (0, factories_1.interpret)(entry, this.database);
}
/**
* checks to see how many things are in the box (will be either 0 or 1)
* @param asOf Historical time to look
* @returns 0 or 1 depending on whether there's something in the box.
*/
async size(asOf) {
const entry = await this.database.store.getEntryByKey(this.address, undefined, asOf);
return +!(entry === undefined || entry.deletion);
}
async reset(args) {
var _a;
const toTime = args === null || args === void 0 ? void 0 : args.toTime;
const bundlerOrComment = args === null || args === void 0 ? void 0 : args.bundlerOrComment;
const skipProperties = args === null || args === void 0 ? void 0 : args.skipProperties;
const recurse = args === null || args === void 0 ? void 0 : args.recurse;
const seen = recurse ? ((_a = args === null || args === void 0 ? void 0 : args.seen) !== null && _a !== void 0 ? _a : new Set()) : undefined;
if (seen) {
seen.add((0, utils_1.muidToString)(this.address));
}
let immediate = false;
let bundler;
if (bundlerOrComment instanceof Bundler_1.Bundler) {
bundler = bundlerOrComment;
}
else {
immediate = true;
bundler = new Bundler_1.Bundler(bundlerOrComment);
}
if (!toTime) {
// If no time is specified, we are resetting to epoch, which is just a clear
this.clear(false, bundler);
}
else {
const thereNow = await this.get();
const thereThen = await this.get(toTime);
if (thereThen !== thereNow) {
await this.set(thereThen, bundler);
}
if (seen &&
thereThen instanceof Container_1.Container &&
!seen.has((0, utils_1.muidToString)(thereThen.address))) {
await thereThen.reset({
toTime,
bundlerOrComment: bundler,
skipProperties,
recurse,
seen,
});
}
}
if (!skipProperties) {
await this.resetProperties(toTime, bundler);
}
if (immediate) {
await this.database.addBundler(bundler);
}
}
/**
* checks to see if something is in the box
* @param asOf
* @returns true if no value or container is in the box
*/
async isEmpty(asOf) {
const entry = await this.database.store.getEntryByKey(this.address, undefined, asOf);
return entry === undefined || entry.deletion;
}
/**
* Generates a JSON representation of the data in the box (the box itself is transparent).
* Mostly intended for demo/debug purposes.
* @param indent true to pretty print
* @param asOf effective time
* @param seen (internal use only! Prevent cycles from breaking things)
* @returns a JSON string
*/
async toJson(indent = false, asOf, seen) {
if (seen === undefined)
seen = new Set();
const contents = await this.get(asOf);
if (contents === undefined)
return "null";
return await (0, factories_1.toJson)(contents, indent, asOf, seen);
}
}
exports.Box = Box;
//# sourceMappingURL=Box.js.map