diff --git a/examples/extra-large-graphs/edge.fast.frag.glsl b/examples/extra-large-graphs/edge.fast.frag.glsl new file mode 100644 index 000000000..21bece896 --- /dev/null +++ b/examples/extra-large-graphs/edge.fast.frag.glsl @@ -0,0 +1,7 @@ +precision mediump float; + +varying vec4 v_color; + +void main(void) { + gl_FragColor = v_color; +} diff --git a/examples/extra-large-graphs/edge.fast.vert.glsl b/examples/extra-large-graphs/edge.fast.vert.glsl new file mode 100644 index 000000000..ac4db39cb --- /dev/null +++ b/examples/extra-large-graphs/edge.fast.vert.glsl @@ -0,0 +1,18 @@ +attribute vec2 a_position; +attribute vec4 a_color; + +uniform mat3 u_matrix; + +varying vec4 v_color; + +void main() { + // Scale from [[-1 1] [-1 1]] to the container: + gl_Position = vec4( + (u_matrix * vec3(a_position, 1)).xy, + 0, + 1 + ); + + // Extract the color: + v_color = a_color; +} diff --git a/examples/extra-large-graphs/edge.gpu.ts b/examples/extra-large-graphs/edge.gpu.ts new file mode 100644 index 000000000..47e759699 --- /dev/null +++ b/examples/extra-large-graphs/edge.gpu.ts @@ -0,0 +1,99 @@ +/** + * Sigma.js WebGL Renderer Fast Edge Program + * ========================================== + * + * Program rendering edges using GL_LINES which is presumably very fast but + * won't render thickness correctly on some GPUs and has some quirks. + * @module + */ +import { AbstractEdgeProgram } from "sigma/rendering/webgl/programs/common/edge"; +import { RenderParams } from "sigma/rendering/webgl/programs/common/program"; + +import fragmentShaderSource from "./edge.fast.frag.glsl"; +import vertexShaderSource from "./edge.fast.vert.glsl"; + +let POINTS = 2; +const ATTRIBUTES = 3; + +export default class EdgeGpuProgram extends AbstractEdgeProgram { + positionLocation: GLint; + colorLocation: GLint; + matrixLocation: WebGLUniformLocation; + + constructor(gl: WebGLRenderingContext) { + super(gl, vertexShaderSource, fragmentShaderSource, POINTS, ATTRIBUTES); + + // Locations: + this.positionLocation = gl.getAttribLocation(this.program, "a_position"); + this.colorLocation = gl.getAttribLocation(this.program, "a_color"); + + // Uniform locations: + const matrixLocation = gl.getUniformLocation(this.program, "u_matrix"); + if (matrixLocation === null) throw new Error("EdgeGpuProgram: error while getting matrixLocation"); + this.matrixLocation = matrixLocation; + + this.bind(); + } + + bind(): void { + const gl = this.gl; + + // Bindings + gl.enableVertexAttribArray(this.positionLocation); + gl.enableVertexAttribArray(this.colorLocation); + + gl.vertexAttribPointer( + this.positionLocation, + 2, + gl.FLOAT, + false, + this.attributes * Float32Array.BYTES_PER_ELEMENT, + 0, + ); + gl.vertexAttribPointer( + this.colorLocation, + 4, + gl.UNSIGNED_BYTE, + true, + this.attributes * Float32Array.BYTES_PER_ELEMENT, + 8, + ); + } + + computeIndices(): void { + //nothing to do + } + + /* The node program for my example + process(data, hidden: boolean, offset: number): void { + this.array = data.buffer.getColumn('nodes').toArray(); + POINTS = this.array.length / ATTRIBUTES; + this.points = POINTS; + } + */ + + process( + sourceData, + targetData, + data, + hidden: boolean, + offset: number, + ): void { + this.array = data.buffer.getColumn('edges').toArray(); + POINTS = this.array.length / ATTRIBUTES; + this.points = POINTS; + } + + render(params: RenderParams): void { + if (this.hasNothingToRender()) return; + + const gl = this.gl; + const program = this.program; + + gl.useProgram(program); + + gl.uniformMatrix3fv(this.matrixLocation, false, params.matrix); + + gl.drawArrays(gl.LINES, 0, this.array.length / ATTRIBUTES); + } +} diff --git a/examples/extra-large-graphs/generate-graph.js b/examples/extra-large-graphs/generate-graph.js new file mode 100644 index 000000000..938f32c5c --- /dev/null +++ b/examples/extra-large-graphs/generate-graph.js @@ -0,0 +1,47 @@ +/** + * This example aims at showcasing sigma's performances. + */ + +const fs = require('fs'); +const seedrandom = require('seedrandom'); + +const {Graph} = require('graphology'); + +const circlepack = require( "graphology-layout/circlepack"); +const clusters = require( "graphology-generators/random/clusters"); + +const rng = seedrandom("sigma"); +const state = { + order: 1000000, + size: 2000000, + clusters: 3, + edgesRenderer: 'edges-fast' +}; + +// 1. Generate a graph: +const graph = clusters(Graph, { ...state, rng }); +circlepack.assign(graph, { + hierarchyAttributes: ["cluster"], +}); +const colors = {}; +for (let i = 0; i < +state.clusters; i++) { + colors[i] = "#" + Math.floor(rng() * 16777215).toString(16); +} +let i = 0; +graph.forEachNode((node, { cluster }) => { + graph.mergeNodeAttributes(node, { + size: graph.degree(node) / 3, + label: `Node n°${++i}, in cluster n°${cluster}`, + color: colors[cluster + ""], + }); +}); + +// 2. Save the graph: +fs.writeFile('./large-graph.json', JSON.stringify(graph.toJSON(), {}, 2), (err) => { + if(err) { + console.log('unable to savfe file'); + } else { + console.log('file saved?'); + } +}); +console.log('Finished step 2'); diff --git a/examples/extra-large-graphs/generate-graph.ts b/examples/extra-large-graphs/generate-graph.ts new file mode 100644 index 000000000..67cda889c --- /dev/null +++ b/examples/extra-large-graphs/generate-graph.ts @@ -0,0 +1,49 @@ +/** + * This example aims at showcasing sigma's performances. + */ + +const fs = require('fs'); +const seedrandom = require('seedrandom'); + +const {Graph} = require('graphology'); + +const circlepack = require('graphology-layout/circlepack'); +const clusters = require('graphology-generators/random/clusters'); +const FA2Layout = require('graphology-layout-forceatlas2/worker'); +const forceAtlas2 = require('graphology-layout-forceatlas2'); + +const rng = seedrandom('sigma'); +const state = { + order: parseInt(process.argv[2]), + size: parseInt(process.argv[3]), + clusters: parseInt(process.argv[4]), + edgesRenderer: 'edges-fast' +}; + +// 1. Generate a graph: +const graph = clusters(Graph, {...state, rng}); +circlepack.assign(graph, { + hierarchyAttributes: ['cluster'], +}); +const colors = {}; +for (let i = 0; i < +state.clusters; i++) { + colors[i] = '#' + Math.floor(rng() * 16777215).toString(16); +} +let i = 0; +graph.forEachNode((node, {cluster}) => { + graph.mergeNodeAttributes(node, { + size: graph.degree(node), + label: `Node n°${++i}, in cluster n°${cluster}`, + color: colors[cluster + ''], + }); +}); + +// 2. Save the graph: +fs.writeFile(process.argv[5], JSON.stringify(graph.toJSON(), null, 2), (err) => { + if (err) { + console.log('unable to save file'); + } else { + console.log('file saved?'); + } +}); +console.log('Finished step 2'); diff --git a/examples/extra-large-graphs/gpu-loader.ts b/examples/extra-large-graphs/gpu-loader.ts new file mode 100644 index 000000000..1a2ac2995 --- /dev/null +++ b/examples/extra-large-graphs/gpu-loader.ts @@ -0,0 +1,61 @@ +/** + * This example aims at showcasing sigma's performances. + */ + +<<<<<<< HEAD +import arrow from 'apache-arrow'; +======= +import {Table} from 'apache-arrow'; +>>>>>>> main + +async function request(obj) { + return new Promise((resolve, reject) => { + let xhr = new XMLHttpRequest(); + xhr.open(obj.method || 'GET', obj.url || obj); + if (obj.headers) { + Object.keys(obj.headers).forEach(key => { xhr.setRequestHeader(key, obj.headers[key]); }); + } + xhr.onload = () => { + try { + if (xhr.status >= 200 && xhr.status < 300) { + resolve(xhr.response); + } else { + reject(xhr.statusText); + } + } catch (e) { reject(e); } + }; + xhr.onerror = () => reject(xhr.statusText); + xhr.send(obj.body); + }); +} + +const SERVER = 'http://localhost:3000'; +const DATASET_ROUTE = '/graphology/read_large_demo?filename=../../public/fewer-edges.json'; +const NODES_ROUTE = '/graphology/get_column/nodes'; +const NODES_BOUNDS_ROUTE = '/graphology/nodes/bounds'; +const NODES_BUFFER_ROUTE = '/graphology/nodes/'; +const EDGES_BUFFER_ROUTE = '/graphology/edges/'; +const TABLE_ROUTE = '/graphology/get_table'; + +const GpuLoader = { + init: async () => request(SERVER + DATASET_ROUTE), + getTable: async (table) => { + return arrow.tableFromIPC(fetch(SERVER + TABLE_ROUTE + '/' + table, {method: 'GET'})); + }, + getColumn: async (table, column) => { + const table_route = {'nodes': '/graphology/get_column/nodes/'}[table]; + const column_route = SERVER + table_route + column; + return arrow.tableFromIPC(fetch(column_route, {method: 'GET'})); + }, + getNodesBounds: async () => request(SERVER + NODES_BOUNDS_ROUTE), + getNodesBuffer: async () => { + const route = SERVER + NODES_BUFFER_ROUTE; + return arrow.tableFromIPC(fetch(route, {method: 'GET'})); + }, + getEdgesBuffer: async () => { + const route = SERVER + EDGES_BUFFER_ROUTE; + return arrow.tableFromIPC(fetch(route, {method: 'GET'})); + } +}; + +export default GpuLoader; diff --git a/examples/extra-large-graphs/index.html b/examples/extra-large-graphs/index.html new file mode 100644 index 000000000..3f5bcf723 --- /dev/null +++ b/examples/extra-large-graphs/index.html @@ -0,0 +1,89 @@ + + + + + + + Sigma example: Performances showcase + + + +
+
+
+
+

Graph

+
+ + +
+
+ + +
+
+ + +
+
+
+

Edges renderer

+
+ + +
+
+ + +
+
+
+ + +
+
+
+ + + diff --git a/examples/extra-large-graphs/index.ts b/examples/extra-large-graphs/index.ts new file mode 100644 index 000000000..420d7ab8b --- /dev/null +++ b/examples/extra-large-graphs/index.ts @@ -0,0 +1,122 @@ +/** + * This example aims at showcasing sigma's performances. + */ + +import {Table} from 'apache-arrow'; +import Graph from 'graphology'; +import clusters from 'graphology-generators/random/clusters'; +import forceAtlas2 from 'graphology-layout-forceatlas2'; +import FA2Layout from 'graphology-layout-forceatlas2/worker'; +import circlepack from 'graphology-layout/circlepack'; +import seedrandom from 'seedrandom'; +import Sigma from 'sigma'; +import Settings from 'sigma'; +import NodeDisplayData from 'sigma'; +import EdgesDefaultProgram from 'sigma/rendering/webgl/programs/edge'; +import EdgesFastProgram from 'sigma/rendering/webgl/programs/edge.fast'; +import {ConsoleLogger} from 'typedoc/dist/lib/utils'; + +import EdgesGpuProgram from './edge.gpu'; +import gpuLoader from './gpu-loader'; +import NodesGpuProgram from './node.gpu'; +import RapidsGraphologyGraph from './rapids-graph' + +const rng = seedrandom('sigma'); +(async function() { + // 1. Read query string, and set form values accordingly: + const query = new URLSearchParams(location.search).entries(); + for (const [key, value] of query) { + const domList = document.getElementsByName(key); + if (domList.length === 1) { + (domList[0] as HTMLInputElement).value = value; + } else if (domList.length > 1) { + domList.forEach((dom: HTMLElement) => { + const input = dom as HTMLInputElement; + input.checked = input.value === value; + }); + } + } + + // 2. Read form values to build a full state: + const state = { + order: +document.querySelector('#order')?.value, + size: +document.querySelector('#size')?.value, + clusters: +document.querySelector('#clusters')?.value, + edgesRenderer: + document.querySelector('[name="edges-renderer"]:checked')?.value, + }; + + // 3. Load the graph from node-rapids + await gpuLoader.init(); + const bounds = await gpuLoader.getNodesBounds(); + const nodes = await gpuLoader.getNodesBuffer(); + const edges = await gpuLoader.getEdgesBuffer(); + const options = await gpuLoader.getTable('options'); + const graph = new RapidsGraphologyGraph(nodes, edges, options); + graph.setExtent(JSON.parse(bounds.toString()).bounds); + + // 3. Generate a graph: + /* + const small_graph = clusters(Graph, {...state, rng}); + circlepack.assign(small_graph, { + hierarchyAttributes: ['cluster'], + }); + const colors: Record = {}; + for (let i = 0; i < +state.clusters; i++) { + colors[i] = '#' + Math.floor(rng() * 16777215).toString(16); + } + let i = 0; + small_graph.forEachNode((node, {cluster}) => {small_graph.mergeNodeAttributes(node, { + size: small_graph.degree(node) * 4, + label: `Node n°${++i}, in cluster n°${cluster}`, + color: colors[cluster + ''], + })}); + */ + + // create random clusters from random source + // set the graph to have cluster attributes + // create n random colors + // for each node in the cluster + // set the size based on its connectedness + // give it an increasing label index + // set the color based on the cluster + + // 4. Render the graph: + const container = document.getElementById('sigma-container') as HTMLElement; + const renderer = new Sigma(graph, container, { + defaultEdgeColor: '#e6e6e6', + defaultEdgeType: state.edgesRenderer, + edgeProgramClasses: { + 'edges-default': EdgesGpuProgram, + 'edges-fast': EdgesGpuProgram, + }, + nodeProgramClasses: { + 'circle': NodesGpuProgram, + }, + }); + // Object.defineProperty(renderer, 'nodeDataCache', {value: graph._gpu_nodes}) + // Object.defineProperty(renderer, 'process', {value: () => { console.log('no more processing.') + // }}) + + // 5. Enable FA2 button: + const fa2Button = document.getElementById('fa2') as HTMLButtonElement; + const sensibleSettings = forceAtlas2.inferSettings(graph); + const fa2Layout = new FA2Layout(graph, { + settings: sensibleSettings, + }); + function toggleFA2Layout() { + if (fa2Layout.isRunning()) { + fa2Layout.stop(); + fa2Button.innerHTML = `Start layout ▶`; + } else { + fa2Layout.start(); + fa2Button.innerHTML = `Stop layout ⏸`; + } + } + fa2Button.addEventListener('click', toggleFA2Layout); + + // Cheap trick: tilt the camera a bit to make labels more readable: + renderer.getCamera().setState({ + angle: 0.2, + }); +})(); diff --git a/examples/extra-large-graphs/node.fast.frag.glsl b/examples/extra-large-graphs/node.fast.frag.glsl new file mode 100644 index 000000000..1f1631a43 --- /dev/null +++ b/examples/extra-large-graphs/node.fast.frag.glsl @@ -0,0 +1,20 @@ +precision mediump float; + +varying vec4 v_color; +varying float v_border; + +const float radius = 0.5; +const vec4 transparent = vec4(0.0, 0.0, 0.0, 0.0); + +void main(void) { + vec2 m = gl_PointCoord - vec2(0.5, 0.5); + float dist = radius - length(m); + + float t = 0.0; + if (dist > v_border) + t = 1.0; + else if (dist > 0.0) + t = dist / v_border; + + gl_FragColor = mix(transparent, v_color, t); +} diff --git a/examples/extra-large-graphs/node.fast.vert.glsl b/examples/extra-large-graphs/node.fast.vert.glsl new file mode 100644 index 000000000..b8574125c --- /dev/null +++ b/examples/extra-large-graphs/node.fast.vert.glsl @@ -0,0 +1,31 @@ +attribute vec2 a_position; +attribute float a_size; +attribute vec4 a_color; + +uniform float u_ratio; +uniform float u_scale; +uniform mat3 u_matrix; + +varying vec4 v_color; +varying float v_border; + +const float bias = 255.0 / 254.0; + +void main() { + gl_Position = vec4( + (u_matrix * vec3(a_position, 1)).xy, + 0, + 1 + ); + + // Multiply the point size twice: + // - x SCALING_RATIO to correct the canvas scaling + // - x 2 to correct the formulae + gl_PointSize = a_size * u_ratio * u_scale * 2.0; + + v_border = (1.0 / u_ratio) * (0.5 / a_size); + + // Extract the color: + v_color = a_color; + v_color.a *= bias; +} diff --git a/examples/extra-large-graphs/node.gpu.ts b/examples/extra-large-graphs/node.gpu.ts new file mode 100644 index 000000000..870f42fa5 --- /dev/null +++ b/examples/extra-large-graphs/node.gpu.ts @@ -0,0 +1,45 @@ +/** + * Sigma.js WebGL Renderer Node Program + * ===================================== + * + * Simple program rendering nodes using GL_POINTS. This is faster than the + * three triangle option but has some quirks and is not supported equally by + * every GPU. + * @module + */ +import {AbstractNodeProgram} from 'sigma/rendering/webgl/programs/common/node'; +import {RenderParams} from 'sigma/rendering/webgl/programs/common/program'; + +import fragmentShaderSource from './node.fast.frag.glsl'; +import vertexShaderSource from './node.fast.vert.glsl'; + +let POINTS = 1; +const ATTRIBUTES = 4; + +export default class NodeGpuProgram extends AbstractNodeProgram { + constructor(gl: WebGLRenderingContext) { + super(gl, vertexShaderSource, fragmentShaderSource, POINTS, ATTRIBUTES); + this.bind(); + } + + process(data, hidden: boolean, offset: number): void { + this.array = data.buffer.getColumn('nodes').toArray(); + POINTS = this.array.length / ATTRIBUTES; + this.points = POINTS; + } + + render(params: RenderParams): void { + if (this.hasNothingToRender()) return; + + const gl = this.gl; + + const program = this.program; + gl.useProgram(program); + + gl.uniform1f(this.ratioLocation, 1 / Math.sqrt(params.ratio)); + gl.uniform1f(this.scaleLocation, params.scalingRatio); + gl.uniformMatrix3fv(this.matrixLocation, false, params.matrix); + + gl.drawArrays(gl.POINTS, 0, this.array.length / ATTRIBUTES); + } +} diff --git a/examples/extra-large-graphs/package.json b/examples/extra-large-graphs/package.json new file mode 100644 index 000000000..06764be7c --- /dev/null +++ b/examples/extra-large-graphs/package.json @@ -0,0 +1,25 @@ +{ + "name": "sigma-example-extra-large-graphs", + "version": "1.0.0", + "description": "A sigma example to showcase node/rapids performances.", + "main": "index.js", + "scripts": { + "start": "kotatsu --port 3001 serve --typescript index.ts --public / ./public" + }, + "license": "MIT", + "dependencies": { + "@types/seedrandom": "^3.0.1", + "apache-arrow": "^4.0.0", + "graphology": "^0.23.0", + "graphology-generators": "^0.11.2", + "graphology-layout": "^0.5.0", + "graphology-layout-forceatlas2": "^0.8.1", + "graphology-types": "^0.23.0", + "seedrandom": "^3.0.5", + "sigma": "latest" + }, + "devDependencies": { + "kotatsu": "^0.22.3", + "typescript": "4.4.4" + } +} diff --git a/examples/extra-large-graphs/rapids-graph.ts b/examples/extra-large-graphs/rapids-graph.ts new file mode 100644 index 000000000..781126048 --- /dev/null +++ b/examples/extra-large-graphs/rapids-graph.ts @@ -0,0 +1,64 @@ +/** + * This example aims at showcasing sigma's performances. + */ + +import {Table} from 'apache-arrow'; +import Graph, {InvalidArgumentsGraphError} from 'graphology'; +import assignPolyfill from 'graphology'; + +let _nodes = null; +let _edges = null; +let _options = null; + +export default class RapidsGraphologyGraph extends Graph { + _gpu_nodes: Table; + _gpu_edges: Table; + _gpu_options: Table; + _the_node: Map; + _nodeExtent: Map; + + constructor(nodes: Table, edges: Table, options: Table) { + super(new Graph({type: 'undirected'})); + this._nodeExtent = new Map(); + this._gpu_nodes = nodes; + this._gpu_edges = edges; + this._gpu_options = options; + this._the_node = new Map(); + this._the_node['node'] = null; + this._the_node['hidden'] = false; + Object.defineProperty(this, 'order', {value: this._gpu_nodes.length}); + Object.defineProperty(this, 'nodeExtent', {value: {x: [0, 5], y: [5, 10]}}); + Object.defineProperty(this, 'nodes', {value: () => { + this._the_node['node'] = this._gpu_nodes; + return [this._the_node]; + }}); + Object.defineProperty(this, 'edges', {value: () => { return [{'edge': this._gpu_edges}] }}); + Object.defineProperty(this, 'getNodeAttributes', { + value: () => { + return { 'buffer': this._gpu_nodes, 'x': -1, 'y': -1 } + } + }); + Object.defineProperty(this, 'getEdgeAttributes', { + value: () => { + return { 'buffer': this._gpu_edges, 'source': -1, 'target': -1, color: '#999', hidden: false } + } + }); + Object.defineProperty(this, 'extremities', { + value: () => { + return [this._the_node, this._the_node] + } + }); + Object.defineProperty(this, 'forEachNode', { + value: (callback) => { + if (typeof callback != 'function') + throw new InvalidArgumentsGraphError( + 'RapidsGraphologyGraph.forEachNode: expecting a callback'); + const p1 = {x: this._nodeExtent['xmin'], y: this._nodeExtent['ymin']}; + const p2 = {x: this._nodeExtent['xmax'], y: this._nodeExtent['ymax']}; + callback('gpu_nodes_p1', p1); + callback('gpu_nodes_p2', p2); + } + }); + } + setExtent(bounds) { this._nodeExtent = bounds; } +} diff --git a/examples/extra-large-graphs/sandbox.config.json b/examples/extra-large-graphs/sandbox.config.json new file mode 100644 index 000000000..33673fa1c --- /dev/null +++ b/examples/extra-large-graphs/sandbox.config.json @@ -0,0 +1,6 @@ +{ + "infiniteLoopProtection": true, + "hardReloadOnChange": false, + "view": "browser", + "template": "create-react-app" +} diff --git a/examples/package.json b/examples/package.json index ed4c88150..0939aba09 100644 --- a/examples/package.json +++ b/examples/package.json @@ -7,7 +7,7 @@ "scripts": { "build": "npm run clean && ./build.js build", "clean": "rimraf build", - "start": "kotatsu serve $npm_config_example/index.ts --index $npm_config_example/index.html --public / $npm_config_example/public" + "start": "kotatsu serve $npm_config_example/index.ts --index $npm_config_example/index.html --public / $npm_config_example/public --port 3002" }, "kotatsu": { "config": "webpack.config.js" @@ -16,6 +16,7 @@ "@types/file-saver": "^2.0.4", "@types/papaparse": "^5.3.1", "@types/seedrandom": "^3.0.1", + "apache-arrow": "^4.0.0", "chroma-js": "^2.1.2", "file-saver": "^2.0.5", "graphology": "^0.23.2", @@ -25,10 +26,13 @@ "graphology-layout": "^0.5.0", "graphology-layout-force": "^0.2.3", "graphology-layout-forceatlas2": "^0.8.1", + "graphology-types": "^0.23.0", "iwanthue": "^1.5.1", "papaparse": "^5.3.1", "seedrandom": "^3.0.5", - "uuid": "^8.3.2" + "uuid": "^8.3.2", + "request": "latest" + }, "devDependencies": { "async": "^3.2.2", diff --git a/examples/webpack.config.js b/examples/webpack.config.js index b34b7f80f..3c4fa02f7 100644 --- a/examples/webpack.config.js +++ b/examples/webpack.config.js @@ -20,8 +20,27 @@ module.exports = { __dirname, "../src/rendering/webgl/programs/common/node.ts", ), + "sigma/rendering/webgl/programs/common/edge": path.resolve( + __dirname, + "../src/rendering/webgl/programs/common/edge.ts", + ), sigma: path.resolve(__dirname, "../src/index.ts"), + "apache-arrow": require.resolve("apache-arrow/Arrow.es2015.min") }, + fallback: { + url: require.resolve('url'), + assert: require.resolve('assert'), + crypto: require.resolve('crypto-browserify'), + http: require.resolve('stream-http'), + https: require.resolve('https-browserify'), + os: require.resolve('os-browserify/browser'), + buffer: require.resolve('buffer'), + stream: require.resolve('stream-browserify'), + net: require.resolve('net'), + tls: require.resolve('tls'), + zlib: require.resolve('zlib'), + fs: require.resolve('fs'), + } }, module: { rules: [ diff --git a/tsconfig.examples.json b/tsconfig.examples.json index 62245bb62..d413a9a88 100644 --- a/tsconfig.examples.json +++ b/tsconfig.examples.json @@ -1,6 +1,7 @@ { "extends": "./tsconfig.json", "compilerOptions": { + "lib": ["dom", "es2015"], "noImplicitAny": false, "strict": false, "paths": { @@ -12,9 +13,11 @@ "sigma/rendering/webgl/programs/edge.fast": ["./src/rendering/webgl/programs/edge.fast.ts"], "sigma/rendering/webgl/programs/node.image": ["./src/rendering/webgl/programs/node.image.ts"], "sigma/rendering/webgl/programs/common/node": ["./src/rendering/webgl/programs/common/node.ts"], + "sigma/rendering/webgl/programs/common/edge": ["./src/rendering/webgl/programs/common/edge.ts"], "sigma/rendering/webgl/programs/common/program": ["./src/rendering/webgl/programs/common/program.ts"] } }, + "declarations": true, "include": ["./external-types/**/*", "./examples/**/*", "./src/**/*"], "exclude": [] } diff --git a/tsconfig.json b/tsconfig.json index 4f9a31695..99c6c83fb 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -9,7 +9,7 @@ "downlevelIteration": true, "resolveJsonModule": true, "typeRoots": ["./node_modules/@types/", "./external-types/"], - "lib": ["dom", "dom.iterable"] + "lib": ["dom", "dom.iterable", "es2015"] }, "include": ["./external-types/**/*", "./src/**/*"], "ts-node": { diff --git a/webpack.config.js b/webpack.config.js index 6a3dc631d..c1b077005 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -27,7 +27,7 @@ module.exports = [ filename: production ? "sigma.min.js" : "sigma.js", path: path.join(__dirname, "build"), library: "Sigma", - libraryTarget: "var", + libraryTarget: "commonjs2", }, resolve: { extensions: [".ts", ".js", ".glsl"],