feat: Phase 1 — extract the client (web SPA + desktop) to dtoro/oikos-web
Problem: the hexagonal refactor churns the backend tree for nine more phases; the UI delivery stack (web/ SPA, cmd/desktop Wails wrapper, compose/web image) must move to its own repo first so doc/layout rewrites land once on a backend-only tree. Change: - New repo git.hubris.network/dtoro/oikos-web (v0.33.0): web/, desktop/ (updateURL repointed to oikos-web releases), compose/, own CI (web + desktop jobs), own deploy script (CI-green gate, TOCTOU guard, version-tagged images, prune-to-3), own webhook receiver on :9798 + launchd unit, own compose project publishing the same 8091:80. - Cutover executed on mac-mini in order: oikos stack's web service stopped+removed, oikos-web project brought up on 8091; outer Caddy untouched (targets the published port) — serving + Authentik flow + /wails 404 quirk verified post-cutover. - Stripped from oikos: web/, cmd/desktop/, compose/web/, desktop CI workflow, ci.yml web job, Makefile ui/desktop/desktop-package/install targets, the compose web service, oikos-web from deploy.sh's fallback prune list; wails + go-keyring dropped from go.mod, vendor synced. - README / CONTRIBUTING / AGENTS.md / .agents dev+operations docs now point at the new repo; mbse + mascot design docs carry a path note. Risk: production SPA serving depends on the new pipeline now; rollback is versioned-image re-up of the old web service from a pre-split checkout (port 8091). Desktop builds installed before the split still check dtoro/oikos releases — one manual reinstall, noted in the oikos-web release notes. Verification: go vet, make test (race), make generate-check, golangci (no new findings; baseline down 400→365); post-cutover curls — localhost:8091 200, /wails/runtime.js 404, outer Caddy 302 Authentik.
This commit is contained in:
206
web/node_modules/graphology-layout-forceatlas2/worker.js
generated
vendored
Normal file
206
web/node_modules/graphology-layout-forceatlas2/worker.js
generated
vendored
Normal file
@@ -0,0 +1,206 @@
|
||||
/**
|
||||
* Graphology ForceAtlas2 Layout Supervisor
|
||||
* =========================================
|
||||
*
|
||||
* Supervisor class able to spawn a web worker to run the FA2 layout in a
|
||||
* separate thread not to block UI with heavy synchronous computations.
|
||||
*/
|
||||
var workerFunction = require('./webworker.js');
|
||||
var isGraph = require('graphology-utils/is-graph');
|
||||
var createEdgeWeightGetter =
|
||||
require('graphology-utils/getters').createEdgeWeightGetter;
|
||||
var helpers = require('./helpers.js');
|
||||
|
||||
var DEFAULT_SETTINGS = require('./defaults.js');
|
||||
|
||||
/**
|
||||
* Class representing a FA2 layout run by a webworker.
|
||||
*
|
||||
* @constructor
|
||||
* @param {Graph} graph - Target graph.
|
||||
* @param {object|number} params - Parameters:
|
||||
* @param {object} [settings] - Settings.
|
||||
*/
|
||||
function FA2LayoutSupervisor(graph, params) {
|
||||
params = params || {};
|
||||
|
||||
// Validation
|
||||
if (!isGraph(graph))
|
||||
throw new Error(
|
||||
'graphology-layout-forceatlas2/worker: the given graph is not a valid graphology instance.'
|
||||
);
|
||||
|
||||
var getEdgeWeight = createEdgeWeightGetter(
|
||||
'getEdgeWeight' in params ? params.getEdgeWeight : 'weight'
|
||||
).fromEntry;
|
||||
|
||||
// Validating settings
|
||||
var settings = helpers.assign({}, DEFAULT_SETTINGS, params.settings);
|
||||
var validationError = helpers.validateSettings(settings);
|
||||
|
||||
if (validationError)
|
||||
throw new Error(
|
||||
'graphology-layout-forceatlas2/worker: ' + validationError.message
|
||||
);
|
||||
|
||||
// Properties
|
||||
this.worker = null;
|
||||
this.graph = graph;
|
||||
this.settings = settings;
|
||||
this.getEdgeWeight = getEdgeWeight;
|
||||
this.matrices = null;
|
||||
this.running = false;
|
||||
this.killed = false;
|
||||
this.outputReducer =
|
||||
typeof params.outputReducer === 'function' ? params.outputReducer : null;
|
||||
|
||||
// Binding listeners
|
||||
this.handleMessage = this.handleMessage.bind(this);
|
||||
|
||||
var respawnFrame = undefined;
|
||||
var self = this;
|
||||
|
||||
this.handleGraphUpdate = function () {
|
||||
if (self.worker) self.worker.terminate();
|
||||
|
||||
if (respawnFrame) clearTimeout(respawnFrame);
|
||||
|
||||
respawnFrame = setTimeout(function () {
|
||||
respawnFrame = undefined;
|
||||
self.spawnWorker();
|
||||
}, 0);
|
||||
};
|
||||
|
||||
graph.on('nodeAdded', this.handleGraphUpdate);
|
||||
graph.on('edgeAdded', this.handleGraphUpdate);
|
||||
graph.on('nodeDropped', this.handleGraphUpdate);
|
||||
graph.on('edgeDropped', this.handleGraphUpdate);
|
||||
|
||||
// Spawning worker
|
||||
this.spawnWorker();
|
||||
}
|
||||
|
||||
FA2LayoutSupervisor.prototype.isRunning = function () {
|
||||
return this.running;
|
||||
};
|
||||
|
||||
/**
|
||||
* Internal method used to spawn the web worker.
|
||||
*/
|
||||
FA2LayoutSupervisor.prototype.spawnWorker = function () {
|
||||
if (this.worker) this.worker.terminate();
|
||||
|
||||
this.worker = helpers.createWorker(workerFunction);
|
||||
this.worker.addEventListener('message', this.handleMessage);
|
||||
|
||||
if (this.running) {
|
||||
this.running = false;
|
||||
this.start();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Internal method used to handle the worker's messages.
|
||||
*
|
||||
* @param {object} event - Event to handle.
|
||||
*/
|
||||
FA2LayoutSupervisor.prototype.handleMessage = function (event) {
|
||||
if (!this.running) return;
|
||||
|
||||
var matrix = new Float32Array(event.data.nodes);
|
||||
|
||||
helpers.assignLayoutChanges(this.graph, matrix, this.outputReducer);
|
||||
if (this.outputReducer) helpers.readGraphPositions(this.graph, matrix);
|
||||
this.matrices.nodes = matrix;
|
||||
|
||||
// Looping
|
||||
this.askForIterations();
|
||||
};
|
||||
|
||||
/**
|
||||
* Internal method used to ask for iterations from the worker.
|
||||
*
|
||||
* @param {boolean} withEdges - Should we send edges along?
|
||||
* @return {FA2LayoutSupervisor}
|
||||
*/
|
||||
FA2LayoutSupervisor.prototype.askForIterations = function (withEdges) {
|
||||
var matrices = this.matrices;
|
||||
|
||||
var payload = {
|
||||
settings: this.settings,
|
||||
nodes: matrices.nodes.buffer
|
||||
};
|
||||
|
||||
var buffers = [matrices.nodes.buffer];
|
||||
|
||||
if (withEdges) {
|
||||
payload.edges = matrices.edges.buffer;
|
||||
buffers.push(matrices.edges.buffer);
|
||||
}
|
||||
|
||||
this.worker.postMessage(payload, buffers);
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Method used to start the layout.
|
||||
*
|
||||
* @return {FA2LayoutSupervisor}
|
||||
*/
|
||||
FA2LayoutSupervisor.prototype.start = function () {
|
||||
if (this.killed)
|
||||
throw new Error(
|
||||
'graphology-layout-forceatlas2/worker.start: layout was killed.'
|
||||
);
|
||||
|
||||
if (this.running) return this;
|
||||
|
||||
// Building matrices
|
||||
this.matrices = helpers.graphToByteArrays(this.graph, this.getEdgeWeight);
|
||||
|
||||
this.running = true;
|
||||
this.askForIterations(true);
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Method used to stop the layout.
|
||||
*
|
||||
* @return {FA2LayoutSupervisor}
|
||||
*/
|
||||
FA2LayoutSupervisor.prototype.stop = function () {
|
||||
this.running = false;
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Method used to kill the layout.
|
||||
*
|
||||
* @return {FA2LayoutSupervisor}
|
||||
*/
|
||||
FA2LayoutSupervisor.prototype.kill = function () {
|
||||
if (this.killed) return this;
|
||||
|
||||
this.running = false;
|
||||
this.killed = true;
|
||||
|
||||
// Clearing memory
|
||||
this.matrices = null;
|
||||
|
||||
// Terminating worker
|
||||
this.worker.terminate();
|
||||
|
||||
// Unbinding listeners
|
||||
this.graph.removeListener('nodeAdded', this.handleGraphUpdate);
|
||||
this.graph.removeListener('edgeAdded', this.handleGraphUpdate);
|
||||
this.graph.removeListener('nodeDropped', this.handleGraphUpdate);
|
||||
this.graph.removeListener('edgeDropped', this.handleGraphUpdate);
|
||||
};
|
||||
|
||||
/**
|
||||
* Exporting.
|
||||
*/
|
||||
module.exports = FA2LayoutSupervisor;
|
||||
Reference in New Issue
Block a user