@dstanesc/o-o-o-o-o-o-o
Version:
O-O-O-O-O-O-O is a collection of content addressed persistent data structures
369 lines • 13.3 kB
JavaScript
var __asyncValues = (this && this.__asyncValues) || function (o) {
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
var m = o[Symbol.asyncIterator], i;
return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
};
var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }
var __asyncDelegator = (this && this.__asyncDelegator) || function (o) {
var i, p;
return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; } : f; }
};
var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) {
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
var g = generator.apply(thisArg, _arguments || []), i, q = [];
return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i;
function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }
function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
function fulfill(value) { resume("next", value); }
function reject(value) { resume("throw", value); }
function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }
};
import { Graph } from '../graph';
import { graphStore } from '../graph-store';
import { PathElemType, navigateVertices, navigateEdges, NavigationThreshold, } from '../navigate';
const protoGremlinFactory = ({ chunk, linkCodec, valueCodec, blockStore, versionStore, indexStore, }) => {
const g = () => {
const store = graphStore({ chunk, linkCodec, valueCodec, blockStore });
const graph = new Graph(versionStore, store, indexStore);
return new ProtoGremlin(graph);
};
return { g };
};
class NavigateWrapper {
constructor(graph, navigation) {
this.graph = graph;
this.navigation = navigation;
navigation.navigator = this;
}
mergePush(pathElem) {
const path = this.navigation.path;
if (path.length > 0) {
let previous = path[path.length - 1];
if (previous.elemType === pathElem.elemType) {
previous = this.navigation.path.pop();
pathElem = this.merge(previous, pathElem);
}
}
this.navigation.path.push(pathElem);
}
values(...keys) {
const pathElem = {
elemType: PathElemType.EXTRACT,
props: keys,
};
this.navigation.path.push(pathElem);
return this;
}
template(template) {
const pathElem = {
elemType: PathElemType.TEMPLATE,
template,
};
this.navigation.path.push(pathElem);
return this;
}
maxResults(value) {
this.navigation.request = new NavigationThreshold(value);
return this;
}
exec() {
return __asyncGenerator(this, arguments, function* exec_1() {
const navigator = this.navigation.navigator;
const refs = this.navigation.refs;
yield __await(yield* __asyncDelegator(__asyncValues(navigator.navigate(refs))));
});
}
}
class NavigateVertexWrapper extends NavigateWrapper {
constructor(graph, navigation) {
super(graph, navigation);
}
merge(previous, current) {
const p = previous;
const c = current;
const r = {
elemType: PathElemType.VERTEX,
types: undefined,
propPredicate: undefined,
};
if (p.types === undefined && c.types === undefined) {
// ok
}
else if (p.types !== undefined && c.types === undefined)
r.types = p.types;
else if (p.types === undefined && c.types !== undefined)
r.types = c.types;
else
r.types = p.types.filter((type) => c.types.includes(type));
if (p.propPredicate === undefined && c.propPredicate === undefined) {
// ok
}
else if (p.propPredicate !== undefined &&
c.propPredicate === undefined)
r.propPredicate = p.propPredicate;
else if (p.propPredicate === undefined && c.propPredicate !== undefined)
r.propPredicate = c.propPredicate;
else
throw new Error(`Cannot merge prop predicates`);
//r.propPredicate = p.propPredicate && c.propPredicate
return r;
}
hasType(...vertexTypes) {
const pathElem = {
elemType: PathElemType.VERTEX,
types: vertexTypes.length === 0 ? undefined : vertexTypes,
};
this.mergePush(pathElem);
return this;
}
has(vertexType, propPredicate) {
const pathElem = {
elemType: PathElemType.VERTEX,
types: [vertexType],
propPredicate,
};
this.mergePush(pathElem);
return this;
}
outE(...edgeTypes) {
const pathElem = {
elemType: PathElemType.EDGE,
types: edgeTypes.length === 0 ? undefined : edgeTypes,
};
this.navigation.path.push(pathElem);
return new NavigateEdgeWrapper(this.graph, this.navigation);
}
out(...edgeTypes) {
return this.outE(...edgeTypes).inV();
}
navigate(refs) {
return __asyncGenerator(this, arguments, function* navigate_1() {
if (this.navigation.request === undefined)
this.navigation.request = new NavigationThreshold(Number.MAX_SAFE_INTEGER);
yield __await(yield* __asyncDelegator(__asyncValues(navigateVertices(this.graph, refs, {
path: this.navigation.path,
request: this.navigation.request,
}))));
});
}
}
class NavigateEdgeWrapper extends NavigateWrapper {
constructor(graph, navigation) {
super(graph, navigation);
}
merge(previous, current) {
const p = previous;
const c = current;
const r = {
elemType: PathElemType.EDGE,
types: undefined,
propPredicate: undefined,
};
if (p.types === undefined && c.types === undefined) {
// ok
}
else if (p.types !== undefined && c.types === undefined)
r.types = p.types;
else if (p.types === undefined && c.types !== undefined)
r.types = c.types;
else
r.types = p.types.filter((type) => c.types.includes(type));
if (p.propPredicate === undefined && c.propPredicate === undefined) {
// ok
}
else if (p.propPredicate !== undefined &&
c.propPredicate === undefined)
r.propPredicate = p.propPredicate;
else if (p.propPredicate === undefined && c.propPredicate !== undefined)
r.propPredicate = c.propPredicate;
else
throw new Error(`Cannot merge prop predicates`);
// r.propPredicate = p.propPredicate && c.propPredicate
return r;
}
hasType(...edgeTypes) {
const pathElem = {
elemType: PathElemType.EDGE,
types: edgeTypes,
};
this.mergePush(pathElem);
return this;
}
has(edgeType, propPredicate) {
const pathElem = {
elemType: PathElemType.EDGE,
types: [edgeType],
propPredicate,
};
this.mergePush(pathElem);
return this;
}
inV(...vertexTypes) {
const pathElem = {
elemType: PathElemType.VERTEX,
types: vertexTypes.length === 0 ? undefined : vertexTypes,
};
this.navigation.path.push(pathElem);
return new NavigateVertexWrapper(this.graph, this.navigation);
}
navigate(refs) {
return __asyncGenerator(this, arguments, function* navigate_2() {
if (this.navigation.request === undefined)
this.navigation.request = new NavigationThreshold(Number.MAX_SAFE_INTEGER);
yield __await(yield* __asyncDelegator(__asyncValues(navigateEdges(this.graph, refs, {
path: this.navigation.path,
request: this.navigation.request,
}))));
});
}
}
class CreateWrapper {
constructor(tx) {
this.tx = tx;
this.props = [];
}
}
class VertexCreateWrapper extends CreateWrapper {
constructor(tx, vertexType) {
super(tx);
this.vertexType = vertexType;
}
async next() {
this.vertex = this.tx.addVertex(this.vertexType);
for (const prop of this.props) {
await this.tx.addVertexProp(this.vertex, prop.keyType, prop.value, prop.type);
}
return this;
}
property(keyType, value, type) {
this.props.push({ keyType, value, type });
return this;
}
async uniqueIndex(keyType, indexType) {
await this.tx.uniqueIndex(this.vertex, keyType, indexType);
return this;
}
get offset() {
return this.vertex.offset;
}
get type() {
return this.vertexType;
}
}
class EdgeCreateWrapper extends CreateWrapper {
constructor(tx, edgeType) {
super(tx);
this.edgeType = edgeType;
}
from(fromVertex) {
this.fromVertex = fromVertex;
return this;
}
to(toVertex) {
this.toVertex = toVertex;
return this;
}
property(keyType, value, type) {
this.props.push({ keyType, value, type });
return this;
}
async next() {
if (this.fromVertex === undefined)
throw new Error('from vertex needs defined before');
if (this.toVertex === undefined)
throw new Error('to vertex needs defined before');
this.edge = await this.tx.addEdge(this.fromVertex.vertex, this.toVertex.vertex, this.edgeType);
for (const prop of this.props) {
await this.tx.addEdgeProp(this.edge, prop.keyType, prop.value, prop.type);
}
return this;
}
get offset() {
return this.edge.offset;
}
get type() {
return this.edgeType;
}
}
class ProtoGremlinTransaction {
constructor(tx) {
this.tx = tx;
}
addV(vertexType) {
return new VertexCreateWrapper(this.tx, vertexType);
}
addE(edgeType) {
return new EdgeCreateWrapper(this.tx, edgeType);
}
async commit({ comment, tags, }) {
const result = await this.tx.commit({ comment, tags });
return result;
}
}
class ProtoGremlin {
constructor(graph) {
this.graph = graph;
}
V(refs) {
const pathElem = {
elemType: PathElemType.VERTEX,
};
return new NavigateVertexWrapper(this.graph, {
path: [pathElem],
request: undefined,
refs,
});
}
E(refs) {
const pathElem = {
elemType: PathElemType.EDGE,
};
return new NavigateEdgeWrapper(this.graph, {
path: [pathElem],
request: undefined,
refs,
});
}
async tx() {
const tx = await this.graph.tx().start();
return new ProtoGremlinTransaction(tx);
}
// For debug only
async allVertices() {
return await this.graph.allVertices();
}
// For debug only
async allEdges() {
return await this.graph.allEdges();
}
// For debug only
async allProps() {
return await this.graph.allProps();
}
/**
* Pack a complete graph
* @param versionRoot - the version root
* @returns - a block containing the packed graph
*/
async pack(versionRoot) {
return await this.graph.packGraph(versionRoot);
}
/**
* Pack a graph fragment
*
* @param vertexOffsetStart - the offset of the first vertex
* @param vertexCount - the number of vertices, counting from the first vertex
* @param graphDepth - the depth of the fragment
* @param versionRoot - the version root
* @returns - a block containing the packed graph fragment
*/
async packFragment(vertexOffsetStart, vertexCount, graphDepth, versionRoot) {
return await this.graph.packGraphFragment(vertexOffsetStart, vertexCount, graphDepth, versionRoot);
}
}
export { ProtoGremlin, ProtoGremlinTransaction, NavigateVertexWrapper, NavigateEdgeWrapper, protoGremlinFactory, };
//# sourceMappingURL=proto-gremlin.js.map