npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@qe-libs/libqe-wasm

v0.1.1

Published

WebAssembly bindings for libqe — shared C++ core for Quantitative Ethnography

Readme

@qe-libs/libqe-wasm

WebAssembly bindings for libqe — the shared C++ core for Quantitative Ethnography packages.

Exposes the full libqe API as a zero-dependency ES module usable in browsers and Node.js.

Install

# one-time: tell npm where to find the @qe-libs scope
echo "@qe-libs:registry=https://gitlab.com/api/v4/projects/epistemic-analytics%2Fqe-packages%2Flibqe/packages/npm/" >> ~/.npmrc

npm install @qe-libs/libqe-wasm

Usage

import loadLibQE from '@qe-libs/libqe-wasm';

const qe = await loadLibQE();

// Code-pair labels
qe.connection_names(['Concept A', 'Concept B', 'Concept C']);
// → ['Concept A & Concept B', 'Concept A & Concept C', 'Concept B & Concept C']

// Stanza-window accumulation
const codes = new Float64Array([1,1,0,  1,0,1,  0,1,1]);  // 3×3 row-major
const out   = qe.accumulate_stanza(codes, 3, 3, /*back=*/2, /*forward=*/0, /*binary=*/true, /*ordered=*/false);
// out → { data: Float64Array, rows: 3, cols: 3 }

// Group confidence interval
const points = new Float64Array([0.1,0.2, 0.3,0.4, 0.5,0.6]);  // 3 units × 2 dims
const ci = qe.mean_ci(points, 3, 2, 0.95);
// ci → { data: Float64Array, rows: 2, cols: 3 }  — [mean, lower, upper] per dim

// Outlier interval (IQR × 1.5)
const oi = qe.outlier_ci(points, 3, 2, 1.5);
// oi → { data: Float64Array, rows: 2, cols: 2 }  — [lower, upper] per dim

Matrix convention

All matrix inputs are flat Float64Array in row-major order with explicit rows and cols arguments. Return values are plain objects:

{ data: Float64Array, rows: number, cols: number }

Access a cell: data[row * cols + col]

API reference

Adjacency

| Function | Description | |----------|-------------| | connection_names(names) | string[] → pair labels ["A & B", ...] | | connection_indices(len) | Upper-triangle index pairs { rows, cols } | | code_connections(data, n_codes) | Code vector → connection vector | | fold_directed_network(data) | n² directed vector → upper-tri | | network_to_vector(data, rows, cols, full) | Matrix → flat vector |

Normalization

| Function | Description | |----------|-------------| | normalize_networks(data, rows, cols) | Row-wise L2 normalization | | scale_networks(data, rows, cols) | Max-norm scaling |

Modeling

| Function | Description | |----------|-------------| | center_points(data, rows, cols) | Subtract column means | | mean_ci(data, rows, cols, conf_level) | t-based CI → n_dims × 3 [mean, lower, upper] | | outlier_ci(data, rows, cols, iqr_factor) | IQR-based interval → n_dims × 2 [lower, upper] | | ena_correlation(pts, pr, pc, cen, cr, cc, conf_level) | Pearson r + CI → n_units × 3 [r, lower, upper] | | node_positions(adj, ar, ac, t, tr, tc, dims) | Undirected ENA node positions. dims may be omitted or 0 to use all columns of t | | directed_node_positions(lw, lr, lc, pt, pr, pc, dims) | Directed ENA node positions. dims may be omitted or 0 to use all columns of pt | | directed_node_positions_combine_pairs(lw, lr, lc, pt, pr, pc, dims) | Directed ENA — ground+response rows averaged before solve. dims may be omitted or 0 |

Accumulation

| Function | Description | |----------|-------------| | connection_matrix(ground, gn, response, rn, weight, ordered) | Core adjacency math for one ground+response pair → n_codes × n_codes matrix | | accumulate_stanza(data, rows, cols, back, forward, binary, ordered) | Stanza-window. ordered=false: upper-tri choose(n,2) cols. ordered=true: directed cols | | row_connections(data, rows, cols, binary) | Per-row co-occurrence | | rolling_window_sum(data, rows, cols, window_size) | Rolling backward sum | | flat_index(indices, dims) | Column-major linear index | | accumulate_unit(codes, rows, cols, unit_rows, decay_fn, ordered) | Ground/response accumulation for one unit (tma). decay_fn(Float64Array) → Float64Array | | accumulate_unit_with_rows(codes, rows, cols, unit_rows, decay_fn, ordered) | Like accumulate_unit but also returns per-response-row networks → { networks, row_networks } | | accumulate_tensor_unit(tensor, dims, dims_sender, dims_receiver, dims_mode, context_lookup, cl_rows, cl_cols, unit_rows, codes, rows, cols, times, ordered) | tma tensor accumulation for one unit → { connection_counts: Float64Array, row_connection_counts: matObj }. All index arrays are 0-based Int32Array; tensor is flat column-major Float64Array; context_lookup is row-major Int32Array (n_context_rows × n_factors) |

Rotation

| Function | Description | |----------|-------------| | ena_svd(data, rows, cols) | SVD rotation → { rotation, eigenvalues, column_names } | | deflate(data, rows, cols, axis) | Project out a given axis → { data, rows, cols } | | orthogonal_svd(data, rows, cols, weights, wr, wc, labels) | Weighted SVD with orthogonalization | | complete_rotation(data, rows, cols, axes, ax_rows, ax_cols, labels) | Fix named axes then fill remaining with SVD | | means_rotation(data, rows, cols, group_pairs) | Group-means rotation. group_pairs: Array<{a: Int32Array, b: Int32Array}> (0-based row indices) | | generalized_means_rotation(V, vr, vc, xm, xr, xc, x_target, x1_cols, x_categorical, x_n_groups, x_subset, has_y, ym, yr, yc, y_target, y1_cols, y_categorical, y_n_groups, n_lambda, k_folds, lasso_eps) | Lasso-based GMR. Index arrays are Int32Array (0-based); pass zero-length Int32Array for x_subset to use all rows. Returns { rotation, eigenvalues, column_names } with labels GMR1, GMR2|SVD2, … |

Building from source

Prerequisites

Steps

# From the libqe repo root:
sh wasm/scripts/build.sh

# Output: wasm/dist/libqe.js  wasm/dist/libqe.wasm

The build uses ../include/libqe/ headers directly — no Conan registry fetch needed. Conan is only used to install Armadillo for the Emscripten cross-compilation.

Notes on Armadillo and BLAS

libqe uses Armadillo for linear algebra. The WASM build compiles with ARMA_DONT_USE_BLAS and ARMA_DONT_USE_LAPACK so Armadillo uses its own built-in LU/QR routines instead of calling external symbols that Emscripten cannot resolve. For ENA's typical data sizes this has no meaningful performance impact.

Running tests

cd wasm
npm ci
npm test   # requires dist/ — run build first