mirror of
https://github.com/ilyakooo0/urbit.git
synced 2025-01-04 21:33:41 +03:00
graph-js: useBigIntOrderedMap
This commit is contained in:
parent
225718b8cf
commit
c6dc485d24
93
pkg/interface/package-lock.json
generated
93
pkg/interface/package-lock.json
generated
@ -2666,6 +2666,11 @@
|
||||
"integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=",
|
||||
"dev": true
|
||||
},
|
||||
"big-integer": {
|
||||
"version": "1.6.48",
|
||||
"resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.48.tgz",
|
||||
"integrity": "sha512-j51egjPa7/i+RdiRuJbPdJ2FIUYYPhvYLjzoYbcMMm62ooO6F94fETG4MTs46zPAF9Brs04OajboA/qTGuz78w=="
|
||||
},
|
||||
"big.js": {
|
||||
"version": "5.2.2",
|
||||
"resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
|
||||
@ -10112,7 +10117,8 @@
|
||||
"ansi-regex": {
|
||||
"version": "2.1.1",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"aproba": {
|
||||
"version": "1.2.0",
|
||||
@ -10133,12 +10139,14 @@
|
||||
"balanced-match": {
|
||||
"version": "1.0.0",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
@ -10153,17 +10161,20 @@
|
||||
"code-point-at": {
|
||||
"version": "1.1.0",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"concat-map": {
|
||||
"version": "0.0.1",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"console-control-strings": {
|
||||
"version": "1.1.0",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"core-util-is": {
|
||||
"version": "1.0.2",
|
||||
@ -10280,7 +10291,8 @@
|
||||
"inherits": {
|
||||
"version": "2.0.4",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"ini": {
|
||||
"version": "1.3.5",
|
||||
@ -10292,6 +10304,7 @@
|
||||
"version": "1.0.0",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"number-is-nan": "^1.0.0"
|
||||
}
|
||||
@ -10306,6 +10319,7 @@
|
||||
"version": "3.0.4",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
}
|
||||
@ -10313,12 +10327,14 @@
|
||||
"minimist": {
|
||||
"version": "1.2.5",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"minipass": {
|
||||
"version": "2.9.0",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"safe-buffer": "^5.1.2",
|
||||
"yallist": "^3.0.0"
|
||||
@ -10337,6 +10353,7 @@
|
||||
"version": "0.5.3",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"minimist": "^1.2.5"
|
||||
}
|
||||
@ -10398,7 +10415,8 @@
|
||||
"npm-normalize-package-bin": {
|
||||
"version": "1.0.1",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"npm-packlist": {
|
||||
"version": "1.4.8",
|
||||
@ -10426,7 +10444,8 @@
|
||||
"number-is-nan": {
|
||||
"version": "1.0.1",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"object-assign": {
|
||||
"version": "4.1.1",
|
||||
@ -10438,6 +10457,7 @@
|
||||
"version": "1.4.0",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
@ -10515,7 +10535,8 @@
|
||||
"safe-buffer": {
|
||||
"version": "5.1.2",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"safer-buffer": {
|
||||
"version": "2.1.2",
|
||||
@ -10551,6 +10572,7 @@
|
||||
"version": "1.0.2",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"code-point-at": "^1.0.0",
|
||||
"is-fullwidth-code-point": "^1.0.0",
|
||||
@ -10570,6 +10592,7 @@
|
||||
"version": "3.0.1",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"ansi-regex": "^2.0.0"
|
||||
}
|
||||
@ -10613,12 +10636,14 @@
|
||||
"wrappy": {
|
||||
"version": "1.0.2",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"yallist": {
|
||||
"version": "3.1.1",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -11099,7 +11124,8 @@
|
||||
"ansi-regex": {
|
||||
"version": "2.1.1",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"aproba": {
|
||||
"version": "1.2.0",
|
||||
@ -11120,12 +11146,14 @@
|
||||
"balanced-match": {
|
||||
"version": "1.0.0",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
@ -11140,17 +11168,20 @@
|
||||
"code-point-at": {
|
||||
"version": "1.1.0",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"concat-map": {
|
||||
"version": "0.0.1",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"console-control-strings": {
|
||||
"version": "1.1.0",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"core-util-is": {
|
||||
"version": "1.0.2",
|
||||
@ -11267,7 +11298,8 @@
|
||||
"inherits": {
|
||||
"version": "2.0.4",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"ini": {
|
||||
"version": "1.3.5",
|
||||
@ -11279,6 +11311,7 @@
|
||||
"version": "1.0.0",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"number-is-nan": "^1.0.0"
|
||||
}
|
||||
@ -11293,6 +11326,7 @@
|
||||
"version": "3.0.4",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
}
|
||||
@ -11300,12 +11334,14 @@
|
||||
"minimist": {
|
||||
"version": "1.2.5",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"minipass": {
|
||||
"version": "2.9.0",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"safe-buffer": "^5.1.2",
|
||||
"yallist": "^3.0.0"
|
||||
@ -11324,6 +11360,7 @@
|
||||
"version": "0.5.3",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"minimist": "^1.2.5"
|
||||
}
|
||||
@ -11385,7 +11422,8 @@
|
||||
"npm-normalize-package-bin": {
|
||||
"version": "1.0.1",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"npm-packlist": {
|
||||
"version": "1.4.8",
|
||||
@ -11413,7 +11451,8 @@
|
||||
"number-is-nan": {
|
||||
"version": "1.0.1",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"object-assign": {
|
||||
"version": "4.1.1",
|
||||
@ -11425,6 +11464,7 @@
|
||||
"version": "1.4.0",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
@ -11502,7 +11542,8 @@
|
||||
"safe-buffer": {
|
||||
"version": "5.1.2",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"safer-buffer": {
|
||||
"version": "2.1.2",
|
||||
@ -11538,6 +11579,7 @@
|
||||
"version": "1.0.2",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"code-point-at": "^1.0.0",
|
||||
"is-fullwidth-code-point": "^1.0.0",
|
||||
@ -11557,6 +11599,7 @@
|
||||
"version": "3.0.1",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"ansi-regex": "^2.0.0"
|
||||
}
|
||||
@ -11600,12 +11643,14 @@
|
||||
"wrappy": {
|
||||
"version": "1.0.2",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"yallist": {
|
||||
"version": "3.1.1",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -12,6 +12,7 @@
|
||||
"@tlon/indigo-react": "urbit/indigo-react#lf/1.2.9",
|
||||
"@tlon/sigil-js": "^1.4.2",
|
||||
"aws-sdk": "^2.726.0",
|
||||
"big-integer": "^1.6.48",
|
||||
"classnames": "^2.2.6",
|
||||
"codemirror": "^5.55.0",
|
||||
"css-loader": "^3.5.3",
|
||||
|
193
pkg/interface/src/logic/lib/BigIntOrderedMap.ts
Normal file
193
pkg/interface/src/logic/lib/BigIntOrderedMap.ts
Normal file
@ -0,0 +1,193 @@
|
||||
import bigInt, { BigInteger } from "big-integer";
|
||||
|
||||
interface NonemptyNode<V> {
|
||||
n: [BigInteger, V];
|
||||
l: MapNode<V>;
|
||||
r: MapNode<V>;
|
||||
}
|
||||
|
||||
type MapNode<V> = NonemptyNode<V> | null;
|
||||
|
||||
/**
|
||||
* An implementation of ordered maps for JS
|
||||
* Plagiarised wholesale from sys/zuse
|
||||
*/
|
||||
export class BigIntOrderedMap<V> implements Iterable<[BigInteger, V]> {
|
||||
private root: MapNode<V> = null;
|
||||
size: number = 0;
|
||||
|
||||
constructor() {}
|
||||
|
||||
/**
|
||||
* Retrieve an value for a key
|
||||
*/
|
||||
get(key: BigInteger): V | null {
|
||||
const inner = (node: MapNode<V>) => {
|
||||
if (!node) {
|
||||
return node;
|
||||
}
|
||||
const [k, v] = node.n;
|
||||
if (key.eq(k)) {
|
||||
return v;
|
||||
}
|
||||
if (key.gt(k)) {
|
||||
return inner(node.l);
|
||||
} else {
|
||||
return inner(node.r);
|
||||
}
|
||||
};
|
||||
|
||||
return inner(this.root);
|
||||
}
|
||||
|
||||
/**
|
||||
* Put an item by a key
|
||||
*/
|
||||
set(key: BigInteger, value: V): void {
|
||||
|
||||
const inner = (node: MapNode<V>) => {
|
||||
if (!node) {
|
||||
return {
|
||||
n: [key, value],
|
||||
l: null,
|
||||
r: null,
|
||||
};
|
||||
}
|
||||
const [k] = node.n;
|
||||
if (key.eq(k)) {
|
||||
this.size--;
|
||||
return {
|
||||
...node,
|
||||
n: [k, value],
|
||||
};
|
||||
}
|
||||
if (key.gt(k)) {
|
||||
const l = inner(node.l);
|
||||
if (!l) {
|
||||
throw new Error("invariant violation");
|
||||
}
|
||||
return {
|
||||
...node,
|
||||
l,
|
||||
};
|
||||
}
|
||||
const r = inner(node.r);
|
||||
if (!r) {
|
||||
throw new Error("invariant violation");
|
||||
}
|
||||
|
||||
return { ...node, r };
|
||||
};
|
||||
this.size++;
|
||||
this.root = inner(this.root);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all entries
|
||||
*/
|
||||
clear() {
|
||||
this.root = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Predicate testing if map contains key
|
||||
*/
|
||||
has(key: BigInteger): boolean {
|
||||
const inner = (node: MapNode<V>) => {
|
||||
if (!node) {
|
||||
return false;
|
||||
}
|
||||
const [k] = node.n;
|
||||
|
||||
if (k.eq(key)) {
|
||||
return true;
|
||||
}
|
||||
if (key.gt(k)) {
|
||||
return inner(node.l);
|
||||
}
|
||||
return inner(node.r);
|
||||
};
|
||||
return inner(this.root);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove value associated with key, returning whether that key
|
||||
* existed in the first place
|
||||
*/
|
||||
delete(key: BigInteger) {
|
||||
const inner = (node: MapNode<V>): [boolean, MapNode<V>] => {
|
||||
if (!node) {
|
||||
return [false, null];
|
||||
}
|
||||
const [k] = node.n;
|
||||
if (k.eq(key)) {
|
||||
return [true, this.nip(node)];
|
||||
}
|
||||
if (key.gt(k)) {
|
||||
const [bool, l] = inner(node.l);
|
||||
return [
|
||||
bool,
|
||||
{
|
||||
...node,
|
||||
l,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
const [bool, r] = inner(node.r);
|
||||
return [
|
||||
bool,
|
||||
{
|
||||
...node,
|
||||
r,
|
||||
},
|
||||
];
|
||||
};
|
||||
const [ret, newRoot] = inner(this.root);
|
||||
if(ret) {
|
||||
this.size--;
|
||||
}
|
||||
this.root = newRoot;
|
||||
return ret;
|
||||
}
|
||||
|
||||
private nip(nod: NonemptyNode<V>): MapNode<V> {
|
||||
const inner = (node: NonemptyNode<V>) => {
|
||||
if (!node.l) {
|
||||
return node.r;
|
||||
}
|
||||
if (!node.r) {
|
||||
return node.l;
|
||||
}
|
||||
return {
|
||||
...node.l,
|
||||
r: inner(node.r),
|
||||
};
|
||||
};
|
||||
return inner(nod);
|
||||
}
|
||||
|
||||
[Symbol.iterator](): IterableIterator<[BigInteger, V]> {
|
||||
let result: [BigInteger, V][] = [];
|
||||
const inner = (node: MapNode<V>) => {
|
||||
if (!node) {
|
||||
return;
|
||||
}
|
||||
inner(node.l);
|
||||
result.push(node.n);
|
||||
inner(node.r);
|
||||
};
|
||||
inner(this.root);
|
||||
|
||||
let idx = 0;
|
||||
return {
|
||||
[Symbol.iterator]: this[Symbol.iterator],
|
||||
next: (): IteratorResult<[BigInteger, V]> => {
|
||||
if (idx < result.length) {
|
||||
return { value: result[idx++], done: false };
|
||||
}
|
||||
return { done: true, value: null };
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
@ -1,5 +1,7 @@
|
||||
import { Post, GraphNode, TextContent, Graph, NodeMap } from "~/types";
|
||||
import { buntPost } from '~/logic/lib/post';
|
||||
import {BigIntOrderedMap} from "./BigIntOrderedMap";
|
||||
import bigInt from 'big-integer';
|
||||
|
||||
export function newPost(
|
||||
title: string,
|
||||
@ -73,7 +75,7 @@ export function editPost(rev: number, noteId: number, title: string, body: strin
|
||||
}
|
||||
|
||||
export function getLatestRevision(node: GraphNode): [number, string, string, Post] {
|
||||
const revs = node.children.get(1);
|
||||
const revs = node.children.get(bigInt(1));
|
||||
const empty = [1, "", "", buntPost()] as [number, string, string, Post];
|
||||
if(!revs) {
|
||||
return empty;
|
||||
@ -87,9 +89,9 @@ export function getLatestRevision(node: GraphNode): [number, string, string, Pos
|
||||
}
|
||||
|
||||
export function getComments(node: GraphNode): GraphNode {
|
||||
const comments = node.children.get(2);
|
||||
const comments = node.children.get(bigInt(2));
|
||||
if(!comments) {
|
||||
return { post: buntPost(), children: new Map() }
|
||||
return { post: buntPost(), children: new BigIntOrderedMap() }
|
||||
}
|
||||
return comments;
|
||||
}
|
||||
|
@ -1,16 +1,6 @@
|
||||
import _ from 'lodash';
|
||||
import { OrderedMap } from "~/logic/lib/OrderedMap";
|
||||
|
||||
const DA_UNIX_EPOCH = 170141184475152167957503069145530368000;
|
||||
const normalizeKey = (key) => {
|
||||
if(key > DA_UNIX_EPOCH) {
|
||||
// new links uses milliseconds since unix epoch
|
||||
// old (pre-graph-store) use @da
|
||||
// ported from +time:enjs:format in hoon.hoon
|
||||
return Math.round((1000 * (9223372036854775 + (key - DA_UNIX_EPOCH))) / 18446744073709551616);
|
||||
}
|
||||
return key;
|
||||
}
|
||||
import { BigIntOrderedMap } from "~/logic/lib/BigIntOrderedMap";
|
||||
import bigInt, { BigInteger } from "big-integer";
|
||||
|
||||
export const GraphReducer = (json, state) => {
|
||||
const data = _.get(json, 'graph-update', false);
|
||||
@ -38,33 +28,26 @@ const addGraph = (json, state) => {
|
||||
const _processNode = (node) => {
|
||||
// is empty
|
||||
if (!node.children) {
|
||||
node.children = new OrderedMap();
|
||||
node.post.originalIndex = node.post.index;
|
||||
node.post.index = node.post.index.split('/').map(x => x.length === 0 ? '' : normalizeKey(parseInt(x, 10))).join('/');
|
||||
node.children = new BigIntOrderedMap();
|
||||
return node;
|
||||
}
|
||||
|
||||
// is graph
|
||||
let converted = new OrderedMap();
|
||||
let converted = new BigIntOrderedMap();
|
||||
for (let i in node.children) {
|
||||
let item = node.children[i];
|
||||
let index = item[0].split('/').slice(1).map((ind) => {
|
||||
return parseInt(ind, 10);
|
||||
return bigInt(ind);
|
||||
});
|
||||
|
||||
if (index.length === 0) { break; }
|
||||
|
||||
const normalKey = normalizeKey(index[index.length - 1]);
|
||||
item[1].post.originalKey = index[index.length - 1];
|
||||
|
||||
converted.set(
|
||||
normalKey,
|
||||
index[index.length - 1],
|
||||
_processNode(item[1])
|
||||
);
|
||||
}
|
||||
node.children = converted;
|
||||
node.post.originalIndex = node.post.index;
|
||||
node.post.index = node.post.index.split('/').map(x => x.length === 0 ? '' : normalizeKey(parseInt(x, 10))).join('/');
|
||||
return node;
|
||||
};
|
||||
|
||||
@ -75,21 +58,22 @@ const addGraph = (json, state) => {
|
||||
}
|
||||
|
||||
let resource = data.resource.ship + '/' + data.resource.name;
|
||||
state.graphs[resource] = new OrderedMap();
|
||||
state.graphs[resource] = new BigIntOrderedMap();
|
||||
|
||||
for (let i in data.graph) {
|
||||
let item = data.graph[i];
|
||||
let index = item[0].split('/').slice(1).map((ind) => {
|
||||
return parseInt(ind, 10);
|
||||
return bigInt(ind);
|
||||
});
|
||||
|
||||
if (index.length === 0) { break; }
|
||||
|
||||
let node = _processNode(item[1]);
|
||||
|
||||
const normalKey = normalizeKey(index[index.length - 1])
|
||||
node.post.originalKey = index[index.length - 1];
|
||||
state.graphs[resource].set(normalKey, node);
|
||||
state.graphs[resource].set(
|
||||
index[index.length - 1],
|
||||
node
|
||||
);
|
||||
}
|
||||
state.graphKeys.add(resource);
|
||||
}
|
||||
@ -108,7 +92,7 @@ const removeGraph = (json, state) => {
|
||||
};
|
||||
|
||||
const mapifyChildren = (children) => {
|
||||
return new OrderedMap(
|
||||
return new BigIntOrderedMap(
|
||||
children.map(([idx, node]) => {
|
||||
const nd = {...node, children: mapifyChildren(node.children || []) };
|
||||
return [normalizeKey(parseInt(idx.slice(1), 10)), nd];
|
||||
@ -119,23 +103,18 @@ const addNodes = (json, state) => {
|
||||
const _addNode = (graph, index, node) => {
|
||||
// set child of graph
|
||||
if (index.length === 1) {
|
||||
node.post.originalIndex = node.post.index;
|
||||
node.post.index = node.post.index.split('/').map(x => x.length === 0 ? '' : normalizeKey(parseInt(x, 10))).join('/');
|
||||
|
||||
const normalKey = normalizeKey(index[0])
|
||||
node.post.originalKey = index[0];
|
||||
graph.set(normalKey, node);
|
||||
graph.set(index[0], node);
|
||||
return graph;
|
||||
}
|
||||
|
||||
// set parent of graph
|
||||
let parNode = graph.get(normalizeKey(index[0]));
|
||||
let parNode = graph.get(index[0]);
|
||||
if (!parNode) {
|
||||
console.error('parent node does not exist, cannot add child');
|
||||
return;
|
||||
}
|
||||
parNode.children = _addNode(parNode.children, index.slice(1), node);
|
||||
graph.set(normalizeKey(index[0]), parNode);
|
||||
graph.set(index[0], parNode);
|
||||
return graph;
|
||||
};
|
||||
|
||||
@ -151,7 +130,7 @@ const addNodes = (json, state) => {
|
||||
if (item[0].split('/').length === 0) { return; }
|
||||
|
||||
let index = item[0].split('/').slice(1).map((ind) => {
|
||||
return parseInt(ind, 10);
|
||||
return bigInt(ind);
|
||||
});
|
||||
|
||||
if (index.length === 0) { return; }
|
||||
@ -174,9 +153,9 @@ const removeNodes = (json, state) => {
|
||||
if (index.length === 1) {
|
||||
graph.delete(index[0]);
|
||||
} else {
|
||||
const child = graph.get(normalizeKey(index[0]));
|
||||
const child = graph.get(index[0]);
|
||||
_remove(child.children, index.slice(1));
|
||||
graph.set(normalizeKey(index[0]), child);
|
||||
graph.set(index[0], child);
|
||||
}
|
||||
};
|
||||
const data = _.get(json, 'remove-nodes', false);
|
||||
@ -188,7 +167,7 @@ const removeNodes = (json, state) => {
|
||||
data.indices.forEach((index) => {
|
||||
if (index.split('/').length === 0) { return; }
|
||||
let indexArr = index.split('/').slice(1).map((ind) => {
|
||||
return parseInt(ind, 10);
|
||||
return bigInt(ind);
|
||||
});
|
||||
_remove(state.graphs[res], indexArr);
|
||||
});
|
||||
|
@ -1,4 +1,5 @@
|
||||
import {Patp} from "./noun";
|
||||
import { Patp } from "./noun";
|
||||
import { BigIntOrderedMap } from "~/logic/lib/BigIntOrderedMap";
|
||||
|
||||
|
||||
export interface TextContent { text: string; };
|
||||
@ -23,7 +24,7 @@ export interface GraphNode {
|
||||
post: Post;
|
||||
}
|
||||
|
||||
export type Graph = Map<number, GraphNode>;
|
||||
export type Graph = BigIntOrderedMap<GraphNode>;
|
||||
|
||||
export type Graphs = { [rid: string]: Graph };
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
import React, { useEffect } from "react";
|
||||
import { Box, Row, Col, Center, LoadingSpinner } from "@tlon/indigo-react";
|
||||
import { Switch, Route, Link } from "react-router-dom";
|
||||
import bigInt from 'big-integer';
|
||||
|
||||
import GlobalApi from "~/logic/api/global";
|
||||
import { StoreState } from "~/logic/store/type";
|
||||
@ -99,7 +100,7 @@ export function LinkResource(props: LinkResourceProps) {
|
||||
return <div>Malformed URL</div>;
|
||||
}
|
||||
|
||||
const index = parseInt(indexArr[1], 10);
|
||||
const index = bigInt(indexArr[1]);
|
||||
const node = !!graph ? graph.get(index) : null;
|
||||
|
||||
if (!node) {
|
||||
@ -124,7 +125,7 @@ export function LinkResource(props: LinkResourceProps) {
|
||||
name={name}
|
||||
ship={ship}
|
||||
api={api}
|
||||
parentIndex={node.post.originalIndex}
|
||||
parentIndex={node.post.index}
|
||||
/>
|
||||
</Row>
|
||||
<Comments
|
||||
|
@ -1,6 +1,8 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { Box, Text, Col } from "@tlon/indigo-react";
|
||||
import ReactMarkdown from "react-markdown";
|
||||
import bigInt from 'big-integer';
|
||||
|
||||
import { Link, RouteComponentProps } from "react-router-dom";
|
||||
import { Spinner } from "~/views/components/Spinner";
|
||||
import { Comments } from "./Comments";
|
||||
@ -19,7 +21,6 @@ interface NoteProps {
|
||||
api: GlobalApi;
|
||||
hideAvatars: boolean;
|
||||
hideNicknames: boolean;
|
||||
baseUrl?: string;
|
||||
remoteContentPolicy: LocalUpdateRemoteContentPolicy;
|
||||
rootUrl: string;
|
||||
baseUrl: string;
|
||||
@ -40,7 +41,7 @@ export function Note(props: NoteProps & RouteComponentProps) {
|
||||
const comments = getComments(note);
|
||||
const [revNum, title, body, post] = getLatestRevision(note);
|
||||
|
||||
const noteId = parseInt(note.post.index.split('/')[1], 10);
|
||||
const noteId = bigInt(note.post.index.split('/')[1]);
|
||||
|
||||
let adminLinks: JSX.Element | null = null;
|
||||
if (window.ship === note?.post?.author) {
|
||||
|
@ -2,8 +2,9 @@ import React, { Component } from "react";
|
||||
import moment from "moment";
|
||||
import { Box } from "@tlon/indigo-react";
|
||||
import { Link } from "react-router-dom";
|
||||
import {Graph, GraphNode} from "~/types";
|
||||
import {getLatestRevision} from "~/logic/lib/publish";
|
||||
import { Graph, GraphNode } from "~/types";
|
||||
import { getLatestRevision } from "~/logic/lib/publish";
|
||||
import { BigInteger } from "big-integer";
|
||||
|
||||
function NavigationItem(props: {
|
||||
url: string;
|
||||
@ -31,17 +32,20 @@ function NavigationItem(props: {
|
||||
);
|
||||
}
|
||||
|
||||
function getAdjacentId(graph: Graph, child: number, backwards = false): number | null {
|
||||
function getAdjacentId(
|
||||
graph: Graph,
|
||||
child: BigInteger,
|
||||
backwards = false
|
||||
): BigInteger | null {
|
||||
const children = Array.from(graph);
|
||||
const i = children.findIndex(([index]) => index === child);
|
||||
const target = children[backwards ? i+1 : i-1];
|
||||
const i = children.findIndex(([index]) => index.eq(child));
|
||||
const target = children[backwards ? i + 1 : i - 1];
|
||||
return target?.[0] || null;
|
||||
}
|
||||
|
||||
function makeNoteUrl(noteId: number) {
|
||||
return noteId.toString();
|
||||
}
|
||||
|
||||
|
||||
interface NoteNavigationProps {
|
||||
noteId: number;
|
||||
@ -53,7 +57,7 @@ export function NoteNavigation(props: NoteNavigationProps) {
|
||||
let nextComponent = <Box />;
|
||||
let prevComponent = <Box />;
|
||||
const { noteId, notebook } = props;
|
||||
if(!notebook) {
|
||||
if (!notebook) {
|
||||
return null;
|
||||
}
|
||||
const nextId = getAdjacentId(notebook, noteId);
|
||||
@ -67,27 +71,16 @@ export function NoteNavigation(props: NoteNavigationProps) {
|
||||
|
||||
if (next && nextId) {
|
||||
const nextUrl = makeNoteUrl(nextId);
|
||||
const [,title,, post] = getLatestRevision(next);
|
||||
const date = post['time-sent'];
|
||||
nextComponent = (
|
||||
<NavigationItem
|
||||
title={title}
|
||||
date={date}
|
||||
url={nextUrl}
|
||||
/>
|
||||
);
|
||||
const [, title, , post] = getLatestRevision(next);
|
||||
const date = post["time-sent"];
|
||||
nextComponent = <NavigationItem title={title} date={date} url={nextUrl} />;
|
||||
}
|
||||
if (prev && prevId) {
|
||||
const prevUrl = makeNoteUrl(prevId);
|
||||
const [,title,, post] = getLatestRevision(prev);
|
||||
const date = post['time-sent'];
|
||||
const [, title, , post] = getLatestRevision(prev);
|
||||
const date = post["time-sent"];
|
||||
prevComponent = (
|
||||
<NavigationItem
|
||||
title={title}
|
||||
date={date}
|
||||
url={prevUrl}
|
||||
prev
|
||||
/>
|
||||
<NavigationItem title={title} date={date} url={prevUrl} prev />
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -19,7 +19,7 @@ export function NotebookPosts(props: NotebookPostsProps) {
|
||||
([date, node]) =>
|
||||
node && (
|
||||
<NotePreview
|
||||
key={date}
|
||||
key={date.toString()}
|
||||
host={props.host}
|
||||
book={props.book}
|
||||
contact={props.contacts[node.post.author]}
|
||||
|
@ -12,6 +12,7 @@ import {
|
||||
} from "~/types";
|
||||
import { Center, LoadingSpinner } from "@tlon/indigo-react";
|
||||
import { Notebook as INotebook } from "~/types/publish-update";
|
||||
import bigInt, { BigInteger } from 'big-integer';
|
||||
|
||||
import Notebook from "./Notebook";
|
||||
import NewPost from "./new-post";
|
||||
@ -82,7 +83,7 @@ export function NotebookRoutes(
|
||||
path={relativePath("/note/:noteId")}
|
||||
render={(routeProps) => {
|
||||
const { noteId } = routeProps.match.params;
|
||||
const noteIdNum = parseInt(noteId, 10);
|
||||
const noteIdNum = bigInt(noteId)
|
||||
|
||||
if(!graph) {
|
||||
return <Center height="100%"><LoadingSpinner /></Center>;
|
||||
|
@ -24,12 +24,12 @@ function SidebarItemIndicator(props: { status?: SidebarItemStatus }) {
|
||||
}
|
||||
}
|
||||
|
||||
const getAppIcon = (app: string, module: string) => {
|
||||
const getAppIcon = (app: string, mod: string) => {
|
||||
if (app === "graph") {
|
||||
if (module === "link") {
|
||||
if (mod === "link") {
|
||||
return "Links";
|
||||
}
|
||||
return _.capitalize(module);
|
||||
return _.capitalize(mod);
|
||||
}
|
||||
return _.capitalize(app);
|
||||
};
|
||||
@ -58,7 +58,7 @@ export function SidebarItem(props: {
|
||||
const { association, path, selected, apps, groups } = props;
|
||||
const title = getItemTitle(association);
|
||||
const appName = association?.["app-name"];
|
||||
const module = association?.metadata?.module || appName;
|
||||
const mod = association?.metadata?.module || appName;
|
||||
const appPath = association?.["app-path"];
|
||||
const groupPath = association?.["group-path"];
|
||||
const app = apps[appName];
|
||||
@ -74,8 +74,8 @@ export function SidebarItem(props: {
|
||||
const baseUrl = isUnmanaged ? `/~landscape/home` : `/~landscape${groupPath}`;
|
||||
|
||||
const to = isSynced
|
||||
? `${baseUrl}/resource/${module}${appPath}`
|
||||
: `${baseUrl}/join/${module}${appPath}`;
|
||||
? `${baseUrl}/resource/${mod}${appPath}`
|
||||
: `${baseUrl}/join/${mod}${appPath}`;
|
||||
|
||||
const color = selected ? "black" : isSynced ? "gray" : "lightGray";
|
||||
|
||||
@ -101,7 +101,7 @@ export function SidebarItem(props: {
|
||||
<Icon
|
||||
display="block"
|
||||
color={color}
|
||||
icon={getAppIcon(appName, module) as any}
|
||||
icon={getAppIcon(appName, mod) as any}
|
||||
/>
|
||||
<Box width='100%' flexShrink={2} ml={2} display='flex' overflow='hidden'>
|
||||
<Text
|
||||
|
Loading…
Reference in New Issue
Block a user