larry babby and threejs for glsl

This commit is contained in:
Sam
2024-06-24 21:24:00 +12:00
parent 87d5dc634d
commit 907ebae4c0
6474 changed files with 1279596 additions and 8 deletions

View File

@@ -0,0 +1,321 @@
// @flow strict-local
import assert from 'assert';
import path from 'path';
import {Worker} from 'worker_threads';
import AdjacencyList, {NodeTypeMap, EdgeTypeMap} from '../src/AdjacencyList';
import {toNodeId} from '../src/types';
describe('AdjacencyList', () => {
it('constructor should initialize an empty graph', () => {
let stats = new AdjacencyList().stats;
assert(stats.nodes === 0);
assert(stats.edges === 0);
});
it('addNode should add a node to the graph', () => {
let graph = new AdjacencyList();
let id = graph.addNode();
assert.equal(id, 0);
assert.equal(graph.stats.nodes, 1);
let id2 = graph.addNode();
assert.equal(id2, 1);
assert.equal(graph.stats.nodes, 2);
});
it('addNode should resize nodes array', () => {
let graph = new AdjacencyList();
let size = graph.serialize().nodes.byteLength;
graph.addNode();
graph.addNode();
graph.addNode();
graph.addNode();
assert(size < graph.serialize().nodes.byteLength);
});
it('removeEdge should remove an edge from the graph', () => {
let graph = new AdjacencyList();
let node0 = graph.addNode();
let node1 = graph.addNode();
let node2 = graph.addNode();
let node3 = graph.addNode();
let node4 = graph.addNode();
let node5 = graph.addNode();
let node6 = graph.addNode();
graph.addEdge(node0, node1);
graph.addEdge(node2, node1);
// this will get removed
graph.addEdge(node3, node1);
graph.addEdge(node4, node1);
graph.addEdge(node5, node1);
graph.addEdge(node6, node1);
assert.deepEqual(graph.getNodeIdsConnectedTo(node1), [0, 2, 3, 4, 5, 6]);
graph.removeEdge(node3, node1);
assert.deepEqual(graph.getNodeIdsConnectedTo(node1), [0, 2, 4, 5, 6]);
});
it('getNodeIdsConnectedTo and getNodeIdsConnectedFrom should remove duplicate values', () => {
let graph = new AdjacencyList();
let a = graph.addNode();
let b = graph.addNode();
let c = graph.addNode();
graph.addEdge(a, b);
graph.addEdge(a, c);
graph.addEdge(a, b, 2);
assert.deepEqual(graph.getNodeIdsConnectedFrom(a, -1), [b, c]);
assert.deepEqual(graph.getNodeIdsConnectedTo(b, -1), [a]);
});
it('removeEdge should remove an edge of a specific type from the graph', () => {
let graph = new AdjacencyList();
let a = graph.addNode();
let b = graph.addNode();
let c = graph.addNode();
let d = graph.addNode();
graph.addEdge(a, b);
graph.addEdge(a, b, 2);
graph.addEdge(a, b, 3);
graph.addEdge(a, c);
graph.addEdge(a, d, 3);
assert.equal(graph.stats.edges, 5);
assert.ok(graph.hasEdge(a, b));
assert.ok(graph.hasEdge(a, b, 2));
assert.ok(graph.hasEdge(a, b, 3));
assert.ok(graph.hasEdge(a, c));
assert.ok(graph.hasEdge(a, d, 3));
assert.deepEqual(Array.from(graph.getAllEdges()), [
{from: a, to: b, type: 1},
{from: a, to: b, type: 2},
{from: a, to: b, type: 3},
{from: a, to: c, type: 1},
{from: a, to: d, type: 3},
]);
graph.removeEdge(a, b, 2);
assert.equal(graph.stats.edges, 4);
assert.ok(graph.hasEdge(a, b));
assert.equal(graph.hasEdge(a, b, 2), false);
assert.ok(graph.hasEdge(a, b, 3));
assert.ok(graph.hasEdge(a, c));
assert.ok(graph.hasEdge(a, d, 3));
assert.deepEqual(Array.from(graph.getAllEdges()), [
{from: a, to: b, type: 1},
{from: a, to: b, type: 3},
{from: a, to: c, type: 1},
{from: a, to: d, type: 3},
]);
});
it('addEdge should add an edge to the graph', () => {
let graph = new AdjacencyList();
let a = graph.addNode();
let b = graph.addNode();
graph.addEdge(a, b);
assert.equal(graph.stats.nodes, 2);
assert.equal(graph.stats.edges, 1);
assert.ok(graph.hasEdge(a, b));
});
it('addEdge should add multiple edges from a node in order', () => {
let graph = new AdjacencyList();
let a = graph.addNode();
let b = graph.addNode();
let c = graph.addNode();
let d = graph.addNode();
graph.addEdge(a, b);
graph.addEdge(a, d);
graph.addEdge(a, c);
assert.deepEqual(graph.getNodeIdsConnectedFrom(a), [b, d, c]);
});
it('addEdge should add multiple edges to a node in order', () => {
let graph = new AdjacencyList();
let a = graph.addNode();
let b = graph.addNode();
let c = graph.addNode();
let d = graph.addNode();
graph.addEdge(a, b);
graph.addEdge(d, b);
graph.addEdge(a, d);
graph.addEdge(c, b);
assert.deepEqual(graph.getNodeIdsConnectedTo(b), [a, d, c]);
});
it('addEdge should add multiple edges of different types in order', () => {
let graph = new AdjacencyList();
let a = graph.addNode();
let b = graph.addNode();
graph.addEdge(a, b);
graph.addEdge(a, b, 1);
graph.addEdge(a, b, 4);
graph.addEdge(a, b, 3);
assert.deepEqual(graph.getNodeIdsConnectedFrom(a), [b]);
assert.deepEqual(Array.from(graph.getAllEdges()), [
{from: a, to: b, type: 1},
{from: a, to: b, type: 4},
{from: a, to: b, type: 3},
]);
});
it('addEdge should return false if an edge is already added', () => {
let graph = new AdjacencyList();
let a = graph.addNode();
let b = graph.addNode();
assert.equal(graph.addEdge(a, b), true);
assert.equal(graph.addEdge(a, b), false);
});
it('addEdge should resize nodes array when necessary', () => {
let graph = new AdjacencyList();
let a = graph.addNode();
let b = graph.addNode();
let size = graph.serialize().nodes.byteLength;
graph.addEdge(a, b, 1);
graph.addEdge(a, b, 2);
graph.addEdge(a, b, 3);
graph.addEdge(a, b, 4);
assert(size < graph.serialize().nodes.byteLength);
});
it('addEdge should resize edges array when necessary', () => {
let graph = new AdjacencyList();
let size = graph.serialize().edges.byteLength;
let a = graph.addNode();
let b = graph.addNode();
graph.addEdge(a, b, 1);
graph.addEdge(a, b, 2);
graph.addEdge(a, b, 3);
assert(size < graph.serialize().edges.byteLength);
});
it('addEdge should error when a node has not been added to the graph', () => {
let graph = new AdjacencyList();
assert.throws(() => graph.addEdge(toNodeId(0), toNodeId(1)));
graph.addNode();
assert.throws(() => graph.addEdge(toNodeId(0), toNodeId(1)));
graph.addNode();
assert.doesNotThrow(() => graph.addEdge(toNodeId(0), toNodeId(1)));
assert.throws(() => graph.addEdge(toNodeId(0), toNodeId(2)));
});
it('addEdge should error when an unsupported edge type is provided', () => {
let graph = new AdjacencyList();
let a = graph.addNode();
let b = graph.addNode();
assert.throws(() => graph.addEdge(a, b, 0));
assert.throws(() => graph.addEdge(a, b, -1));
assert.doesNotThrow(() => graph.addEdge(a, b, 1));
});
it('addEdge should not replace a deleted edge if the edge was already added', () => {
// Mock hash fn to generate collisions
// $FlowFixMe[prop-missing]
let originalHash = AdjacencyList.prototype.hash;
// $FlowFixMe[prop-missing]
AdjacencyList.prototype.hash = () => 1;
let graph = new AdjacencyList();
let n0 = graph.addNode();
let n1 = graph.addNode();
let n2 = graph.addNode();
graph.addEdge(n0, n1, 1);
graph.addEdge(n1, n2, 1);
graph.removeEdge(n1, n2, 1);
assert(graph.addEdge(n0, n1, 1) === false);
assert(graph.stats.edges === 1);
// $FlowFixMe[prop-missing]
AdjacencyList.prototype.hash = originalHash;
});
it('addEdge should replace a deleted edge', () => {
// Mock hash fn to generate collisions
// $FlowFixMe[prop-missing]
let originalHash = AdjacencyList.prototype.hash;
// $FlowFixMe[prop-missing]
AdjacencyList.prototype.hash = () => 1;
try {
let graph = new AdjacencyList({initialCapacity: 3});
let n0 = graph.addNode();
let n1 = graph.addNode();
graph.addEdge(n0, n1, 2);
graph.removeEdge(n0, n1, 2);
assert(graph.addEdge(n0, n1, 2));
assert(graph.stats.edges === 1);
assert(graph.stats.deleted === 1);
// Resize to reclaim deleted edge space.
graph.resizeEdges(2);
assert(graph.stats.edges === 1);
assert(graph.stats.deleted === 0);
} finally {
// $FlowFixMe[prop-missing]
AdjacencyList.prototype.hash = originalHash;
}
});
it('hasEdge should accept an array of edge types', () => {
let graph = new AdjacencyList();
let a = graph.addNode();
let b = graph.addNode();
let c = graph.addNode();
graph.addEdge(a, b, 1);
graph.addEdge(b, c, 2);
assert.ok(!graph.hasEdge(a, b, [2, 3]));
assert.ok(graph.hasEdge(a, b, [1, 2]));
assert.ok(!graph.hasEdge(b, c, [1, 3]));
assert.ok(graph.hasEdge(b, c, [2, 3]));
});
describe('deserialize', function () {
this.timeout(10000);
it('should share the underlying data across worker threads', async () => {
let graph = new AdjacencyList();
let n0 = graph.addNode();
let n1 = graph.addNode();
graph.addEdge(n0, n1, 1);
graph.addEdge(n0, n1, 2);
let worker = new Worker(
path.join(__dirname, 'integration/adjacency-list-shared-array.js'),
);
let originalSerialized = graph.serialize();
let originalNodes = [...originalSerialized.nodes];
let originalEdges = [...originalSerialized.edges];
let work = new Promise(resolve => worker.on('message', resolve));
worker.postMessage(originalSerialized);
let received = AdjacencyList.deserialize(await work);
await worker.terminate();
assert.deepEqual(received.serialize().nodes, graph.serialize().nodes);
assert.deepEqual(received.serialize().edges, graph.serialize().edges);
originalNodes.forEach((v, i) => {
if (i < NodeTypeMap.HEADER_SIZE) {
assert.equal(v, received.serialize().nodes[i]);
assert.equal(v, graph.serialize().nodes[i]);
} else {
assert.equal(v * 2, received.serialize().nodes[i]);
assert.equal(v * 2, graph.serialize().nodes[i]);
}
});
originalEdges.forEach((v, i) => {
if (i < EdgeTypeMap.HEADER_SIZE) {
assert.equal(v, received.serialize().edges[i]);
assert.equal(v, graph.serialize().edges[i]);
} else {
assert.equal(v * 2, received.serialize().edges[i]);
assert.equal(v * 2, graph.serialize().edges[i]);
}
});
});
});
});

View File

@@ -0,0 +1,110 @@
// @flow strict-local
import assert from 'assert';
import {BitSet} from '../src/BitSet';
function assertValues(set: BitSet, values: Array<number>) {
let setValues = [];
set.forEach(bit => {
setValues.push(bit);
});
for (let value of values) {
assert(set.has(value), 'Set.has returned false');
assert(
setValues.some(v => v === value),
'Set values is missing value',
);
}
assert(
setValues.length === values.length,
`Expected ${values.length} values but got ${setValues.length}`,
);
}
describe('BitSet', () => {
it('clone should return a set with the same values', () => {
let set1 = new BitSet(5);
set1.add(1);
set1.add(3);
let set2 = set1.clone();
assertValues(set2, [1, 3]);
});
it('clear should remove all values from the set', () => {
let set1 = new BitSet(5);
set1.add(1);
set1.add(3);
set1.clear();
assertValues(set1, []);
});
it('delete should remove values from the set', () => {
let set1 = new BitSet(5);
set1.add(1);
set1.add(3);
set1.add(5);
set1.delete(3);
assertValues(set1, [1, 5]);
});
it('empty should check if there are no values set', () => {
let set1 = new BitSet(5);
assert(set1.empty());
set1.add(3);
assert(!set1.empty());
set1.delete(3);
assert(set1.empty());
});
it('should intersect with another BitSet', () => {
let set1 = new BitSet(5);
set1.add(1);
set1.add(3);
let set2 = new BitSet(5);
set2.add(3);
set2.add(5);
set1.intersect(set2);
assertValues(set1, [3]);
});
it('should union with another BitSet', () => {
let set1 = new BitSet(5);
set1.add(1);
set1.add(3);
let set2 = new BitSet(5);
set2.add(3);
set2.add(5);
set1.union(set2);
assertValues(set1, [1, 3, 5]);
});
it('BitSet.union should create a new BitSet with the union', () => {
let set1 = new BitSet(5);
set1.add(1);
set1.add(3);
let set2 = new BitSet(5);
set2.add(3);
set2.add(5);
let set3 = BitSet.union(set1, set2);
assertValues(set1, [1, 3]);
assertValues(set2, [3, 5]);
assertValues(set3, [1, 3, 5]);
});
});

View File

@@ -0,0 +1,42 @@
// @flow strict-local
import assert from 'assert';
import ContentGraph from '../src/ContentGraph';
describe('ContentGraph', () => {
it('should addNodeByContentKey if no node exists with the content key', () => {
let graph = new ContentGraph();
const node = {};
const nodeId1 = graph.addNodeByContentKey('contentKey', node);
assert.deepEqual(graph.getNode(nodeId1), node);
assert(graph.hasContentKey('contentKey'));
assert.deepEqual(graph.getNodeByContentKey('contentKey'), node);
});
it('should throw if a node with the content key already exists', () => {
let graph = new ContentGraph();
graph.addNodeByContentKey('contentKey', {});
assert.throws(() => {
graph.addNodeByContentKey('contentKey', {});
}, /already has content key/);
});
it('should remove the content key from graph when node is removed', () => {
let graph = new ContentGraph();
const node1 = {};
const nodeId1 = graph.addNodeByContentKey('contentKey', node1);
assert.equal(graph.getNode(nodeId1), node1);
assert(graph.hasContentKey('contentKey'));
graph.removeNode(nodeId1);
assert(!graph.hasContentKey('contentKey'));
});
});

View File

@@ -0,0 +1,343 @@
// @flow strict-local
import assert from 'assert';
import sinon from 'sinon';
import Graph from '../src/Graph';
import {toNodeId} from '../src/types';
describe('Graph', () => {
it('constructor should initialize an empty graph', () => {
let graph = new Graph();
assert.deepEqual(graph.nodes, []);
assert.deepEqual([...graph.getAllEdges()], []);
});
it('addNode should add a node to the graph', () => {
let graph = new Graph();
let node = {};
let id = graph.addNode(node);
assert.equal(graph.getNode(id), node);
});
it('errors when traversing a graph with no root', () => {
let graph = new Graph();
assert.throws(() => {
graph.traverse(() => {});
}, /A start node is required to traverse/);
});
it("errors when traversing a graph with a startNode that doesn't belong", () => {
let graph = new Graph();
assert.throws(() => {
graph.traverse(() => {}, toNodeId(-1));
}, /Does not have node/);
});
it("errors if replaceNodeIdsConnectedTo is called with a node that doesn't belong", () => {
let graph = new Graph();
assert.throws(() => {
graph.replaceNodeIdsConnectedTo(toNodeId(-1), []);
}, /Does not have node/);
});
it("errors when adding an edge to a node that doesn't exist", () => {
let graph = new Graph();
let node = graph.addNode({});
assert.throws(() => {
graph.addEdge(node, toNodeId(-1));
}, /"to" node '-1' not found/);
});
it("errors when adding an edge from a node that doesn't exist", () => {
let graph = new Graph();
let node = graph.addNode({});
assert.throws(() => {
graph.addEdge(toNodeId(-1), node);
}, /"from" node '-1' not found/);
});
it('hasNode should return a boolean based on whether the node exists in the graph', () => {
let graph = new Graph();
let node = graph.addNode({});
assert(graph.hasNode(node));
assert(!graph.hasNode(toNodeId(-1)));
});
it('addEdge should add an edge to the graph', () => {
let graph = new Graph();
let nodeA = graph.addNode('a');
let nodeB = graph.addNode('b');
graph.addEdge(nodeA, nodeB);
assert(graph.hasEdge(nodeA, nodeB));
});
it('isOrphanedNode should return true or false if the node is orphaned or not', () => {
let graph = new Graph();
let rootNode = graph.addNode('root');
graph.setRootNodeId(rootNode);
let nodeA = graph.addNode('a');
let nodeB = graph.addNode('b');
let nodeC = graph.addNode('c');
graph.addEdge(rootNode, nodeB);
graph.addEdge(nodeB, nodeC, 1);
assert(graph.isOrphanedNode(nodeA));
assert(!graph.isOrphanedNode(nodeB));
assert(!graph.isOrphanedNode(nodeC));
});
it("removeEdge should throw if the edge doesn't exist", () => {
let graph = new Graph();
let nodeA = graph.addNode('a');
let nodeB = graph.addNode('b');
assert.throws(() => {
graph.removeEdge(nodeA, nodeB);
}, /Edge from 0 to 1 not found!/);
});
it('removeEdge should prune the graph at that edge', () => {
// a
// / \
// b - d
// /
// c
let graph = new Graph();
let nodeA = graph.addNode('a');
graph.setRootNodeId(nodeA);
let nodeB = graph.addNode('b');
let nodeC = graph.addNode('c');
let nodeD = graph.addNode('d');
graph.addEdge(nodeA, nodeB);
graph.addEdge(nodeA, nodeD);
graph.addEdge(nodeB, nodeC);
graph.addEdge(nodeB, nodeD);
graph.removeEdge(nodeA, nodeB);
assert(graph.hasNode(nodeA));
assert(graph.hasNode(nodeD));
assert(!graph.hasNode(nodeB));
assert(!graph.hasNode(nodeC));
assert.deepEqual(
[...graph.getAllEdges()],
[{from: nodeA, to: nodeD, type: 1}],
);
});
it('removing a node recursively deletes orphaned nodes', () => {
// before:
// a
// / \
// b c
// / \ \
// d e f
// /
// g
//
// after:
// a
// \
// c
// \
// f
let graph = new Graph();
let nodeA = graph.addNode('a');
graph.setRootNodeId(nodeA);
let nodeB = graph.addNode('b');
let nodeC = graph.addNode('c');
let nodeD = graph.addNode('d');
let nodeE = graph.addNode('e');
let nodeF = graph.addNode('f');
let nodeG = graph.addNode('g');
graph.addEdge(nodeA, nodeB);
graph.addEdge(nodeA, nodeC);
graph.addEdge(nodeB, nodeD);
graph.addEdge(nodeB, nodeE);
graph.addEdge(nodeC, nodeF);
graph.addEdge(nodeD, nodeG);
graph.removeNode(nodeB);
assert.deepEqual(graph.nodes.filter(Boolean), ['a', 'c', 'f']);
assert.deepEqual(Array.from(graph.getAllEdges()), [
{from: nodeA, to: nodeC, type: 1},
{from: nodeC, to: nodeF, type: 1},
]);
});
it('removing a node recursively deletes orphaned nodes if there is no path to the root', () => {
// before:
// a
// / \
// b c
// / \ \
// |-d e f
// |/
// g
//
// after:
// a
// \
// c
// \
// f
let graph = new Graph();
let nodeA = graph.addNode('a');
let nodeB = graph.addNode('b');
let nodeC = graph.addNode('c');
let nodeD = graph.addNode('d');
let nodeE = graph.addNode('e');
let nodeF = graph.addNode('f');
let nodeG = graph.addNode('g');
graph.setRootNodeId(nodeA);
graph.addEdge(nodeA, nodeB);
graph.addEdge(nodeA, nodeC);
graph.addEdge(nodeB, nodeD);
graph.addEdge(nodeG, nodeD);
graph.addEdge(nodeB, nodeE);
graph.addEdge(nodeC, nodeF);
graph.addEdge(nodeD, nodeG);
graph.removeNode(nodeB);
assert.deepEqual(graph.nodes.filter(Boolean), ['a', 'c', 'f']);
assert.deepEqual(Array.from(graph.getAllEdges()), [
{from: nodeA, to: nodeC, type: 1},
{from: nodeC, to: nodeF, type: 1},
]);
});
it('removing an edge to a node that cycles does not remove it if there is a path to the root', () => {
// a
// |
// b <----
// / \ |
// c d |
// \ / |
// e -----
let graph = new Graph();
let nodeA = graph.addNode('a');
let nodeB = graph.addNode('b');
let nodeC = graph.addNode('c');
let nodeD = graph.addNode('d');
let nodeE = graph.addNode('e');
graph.setRootNodeId(nodeA);
graph.addEdge(nodeA, nodeB);
graph.addEdge(nodeB, nodeC);
graph.addEdge(nodeB, nodeD);
graph.addEdge(nodeC, nodeE);
graph.addEdge(nodeD, nodeE);
graph.addEdge(nodeE, nodeB);
const getNodeIds = () => [...graph.nodes.keys()];
let nodesBefore = getNodeIds();
graph.removeEdge(nodeC, nodeE);
assert.deepEqual(nodesBefore, getNodeIds());
assert.deepEqual(Array.from(graph.getAllEdges()), [
{from: nodeA, to: nodeB, type: 1},
{from: nodeB, to: nodeC, type: 1},
{from: nodeB, to: nodeD, type: 1},
{from: nodeD, to: nodeE, type: 1},
{from: nodeE, to: nodeB, type: 1},
]);
});
it('removing a node with only one inbound edge does not cause it to be removed as an orphan', () => {
let graph = new Graph();
let nodeA = graph.addNode('a');
let nodeB = graph.addNode('b');
graph.setRootNodeId(nodeA);
graph.addEdge(nodeA, nodeB);
let spy = sinon.spy(graph, 'removeNode');
try {
graph.removeNode(nodeB);
assert(spy.calledOnceWithExactly(nodeB));
} finally {
spy.restore();
}
});
it("replaceNodeIdsConnectedTo should update a node's downstream nodes", () => {
let graph = new Graph();
let nodeA = graph.addNode('a');
graph.setRootNodeId(nodeA);
let nodeB = graph.addNode('b');
let nodeC = graph.addNode('c');
graph.addEdge(nodeA, nodeB);
graph.addEdge(nodeA, nodeC);
let nodeD = graph.addNode('d');
graph.replaceNodeIdsConnectedTo(nodeA, [nodeB, nodeD]);
assert(graph.hasNode(nodeA));
assert(graph.hasNode(nodeB));
assert(!graph.hasNode(nodeC));
assert(graph.hasNode(nodeD));
assert.deepEqual(Array.from(graph.getAllEdges()), [
{from: nodeA, to: nodeB, type: 1},
{from: nodeA, to: nodeD, type: 1},
]);
});
it('traverses along edge types if a filter is given', () => {
let graph = new Graph();
let nodeA = graph.addNode('a');
let nodeB = graph.addNode('b');
let nodeC = graph.addNode('c');
let nodeD = graph.addNode('d');
graph.addEdge(nodeA, nodeB, 2);
graph.addEdge(nodeA, nodeD);
graph.addEdge(nodeB, nodeC);
graph.addEdge(nodeB, nodeD, 2);
graph.setRootNodeId(nodeA);
let visited = [];
graph.traverse(
nodeId => {
visited.push(nodeId);
},
null, // use root as startNode
2,
);
assert.deepEqual(visited, [nodeA, nodeB, nodeD]);
});
it('correctly removes non-tree subgraphs', () => {
let graph = new Graph();
let nodeRoot = graph.addNode('root');
let node1 = graph.addNode('1');
let node2 = graph.addNode('2');
let node3 = graph.addNode('3');
graph.addEdge(nodeRoot, node1);
graph.addEdge(node1, node2);
graph.addEdge(node1, node3);
graph.addEdge(node2, node3);
graph.setRootNodeId(nodeRoot);
graph.removeNode(node1);
assert.deepEqual(graph.nodes.filter(Boolean), ['root']);
assert.deepStrictEqual(Array.from(graph.getAllEdges()), []);
});
});

View File

@@ -0,0 +1,20 @@
require('@parcel/babel-register');
const {parentPort} = require('worker_threads');
const {
default: AdjacencyList,
NodeTypeMap,
EdgeTypeMap,
} = require('../../src/AdjacencyList');
parentPort.once('message', (serialized) => {
let graph = AdjacencyList.deserialize(serialized);
serialized.nodes.forEach((v, i) => {
if (i < NodeTypeMap.HEADER_SIZE) return;
serialized.nodes[i] = v * 2;
});
serialized.edges.forEach((v, i) => {
if (i < EdgeTypeMap.HEADER_SIZE) return;
serialized.edges[i] = v * 2;
});
parentPort.postMessage(graph.serialize());
});