jinaga
Version:
Data management for web and mobile applications.
162 lines • 6.69 kB
JavaScript
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.FactManager = void 0;
const key_pair_1 = require("../cryptography/key-pair");
const hash_1 = require("../fact/hash");
const observer_1 = require("../observer/observer");
const purgeCompliance_1 = require("../purge/purgeCompliance");
const trace_1 = require("../util/trace");
const NetworkManager_1 = require("./NetworkManager");
const PurgeManager_1 = require("./PurgeManager");
class FactManager {
constructor(fork, observableSource, store, network, purgeConditions, feedRefreshIntervalSeconds) {
this.fork = fork;
this.observableSource = observableSource;
this.store = store;
this.purgeConditions = purgeConditions;
this.singleUseKeyPair = null;
this.networkManager = new NetworkManager_1.NetworkManager(network, store, factsAdded => this.factsAdded(factsAdded), feedRefreshIntervalSeconds);
this.purgeManager = new PurgeManager_1.PurgeManager(store, purgeConditions);
}
addSpecificationListener(specification, onResult) {
return this.observableSource.addSpecificationListener(specification, onResult);
}
removeSpecificationListener(listener) {
this.observableSource.removeSpecificationListener(listener);
}
close() {
return __awaiter(this, void 0, void 0, function* () {
yield this.fork.close();
yield this.store.close();
});
}
testSpecificationForCompliance(specification) {
return (0, purgeCompliance_1.testSpecificationForCompliance)(specification, this.purgeConditions);
}
save(envelopes) {
return __awaiter(this, void 0, void 0, function* () {
// If we have a single-use key pair, sign the facts with it
if (this.singleUseKeyPair) {
envelopes = (0, key_pair_1.signFacts)(this.singleUseKeyPair, envelopes.map(e => e.fact));
}
yield this.fork.save(envelopes);
const saved = yield this.store.save(envelopes);
if (saved.length > 0) {
trace_1.Trace.counter("facts_saved", saved.length);
yield this.factsAdded(saved);
}
return saved;
});
}
/**
* Begin a single-use session. Generates a key pair, creates a User fact with the public key,
* signs it, and saves it to the store.
* @returns A structure containing the user fact
*/
beginSingleUse() {
return __awaiter(this, void 0, void 0, function* () {
// Generate a key pair for the single-use principal
const keyPair = (0, key_pair_1.generateKeyPair)();
// Create a User fact with the public key
const fields = {
publicKey: keyPair.publicPem
};
const predecessors = {};
const hash = (0, hash_1.computeHash)(fields, predecessors);
const userFact = {
hash,
type: "Jinaga.User",
fields,
predecessors
};
// Sign the user fact with the key pair
const signedEnvelopes = (0, key_pair_1.signFacts)(keyPair, [userFact]);
// Save the user fact
yield this.store.save(signedEnvelopes);
// Store the key pair temporarily
this.singleUseKeyPair = keyPair;
// Return a structure containing the user fact
return {
graph: { facts: [userFact] },
last: userFact
};
});
}
/**
* End a single-use session. Discards the private key.
*/
endSingleUse() {
// Discard the private key
this.singleUseKeyPair = null;
}
read(start, specification) {
return __awaiter(this, void 0, void 0, function* () {
this.purgeManager.checkCompliance(specification);
return yield this.store.read(start, specification);
});
}
fetch(start, specification) {
return __awaiter(this, void 0, void 0, function* () {
this.purgeManager.checkCompliance(specification);
yield this.networkManager.fetch(start, specification);
});
}
subscribe(start, specification) {
return __awaiter(this, void 0, void 0, function* () {
this.purgeManager.checkCompliance(specification);
return yield this.networkManager.subscribe(start, specification);
});
}
unsubscribe(feeds) {
this.networkManager.unsubscribe(feeds);
}
load(references) {
return __awaiter(this, void 0, void 0, function* () {
const loaded = yield this.fork.load(references);
trace_1.Trace.counter("facts_loaded", loaded.length);
return loaded;
});
}
getMruDate(specificationHash) {
return this.store.getMruDate(specificationHash);
}
setMruDate(specificationHash, mruDate) {
return this.store.setMruDate(specificationHash, mruDate);
}
startObserver(references, specification, resultAdded, keepAlive) {
const observer = new observer_1.ObserverImpl(this, references, specification, resultAdded);
observer.start(keepAlive);
return observer;
}
factsAdded(factsAdded) {
return __awaiter(this, void 0, void 0, function* () {
yield this.observableSource.notify(factsAdded);
yield this.purgeManager.triggerPurge(factsAdded);
});
}
purge() {
return __awaiter(this, void 0, void 0, function* () {
yield this.purgeManager.purge();
});
}
/**
* Processes the queue immediately, bypassing any delay.
* Only works if the fork is a PersistentFork.
*/
push() {
return __awaiter(this, void 0, void 0, function* () {
yield this.fork.processQueueNow();
});
}
}
exports.FactManager = FactManager;
//# sourceMappingURL=factManager.js.map