{"_id":"@astermind/astermind-elm","_rev":"8-c185ddf5d36a9c208dc7f01cc89dd14f","name":"@astermind/astermind-elm","dist-tags":{"latest":"2.1.1"},"versions":{"2.1.1":{"name":"@astermind/astermind-elm","version":"2.1.1","keywords":["elm","extreme-learning-machine","ml","javascript","browser","node"],"author":{"name":"Julian Wilkison-Duran","email":"clockworksyler@gmail.com"},"license":"MIT","_id":"@astermind/astermind-elm@2.1.1","maintainers":[{"name":"clockworksyler","email":"clockworksyler@gmail.com"}],"homepage":"https://github.com/infiniteCrank/AsterMind-ELM#readme","bugs":{"url":"https://github.com/infiniteCrank/AsterMind-ELM/issues"},"dist":{"shasum":"2f6e1440d97ebea2a2bde1463347b2454c466f48","tarball":"https://registry.npmjs.org/@astermind/astermind-elm/-/astermind-elm-2.1.1.tgz","fileCount":42,"integrity":"sha512-kMNoc4QhAthaz5RKNLMfC+ibHnxBLsnNyQ5x62gGUphkdR1jvKJVlFjt4gri49zzjS7dRjNUmIFS6ztBPVcdSw==","signatures":[{"sig":"MEYCIQCBafW+gESpjwvZl770XD010rv5R8XCXcYDLRNFFGn2UgIhAIovzjyhjJjhdruns1CrYd7L5c6zf/d3SIwhn9kv50iw","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1774452},"main":"dist/astermind.umd.js","type":"module","types":"dist/index.d.ts","module":"dist/astermind.esm.js","company":"AsterMind LLC","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/astermind.esm.js","default":"./dist/astermind.esm.js","require":"./dist/astermind.umd.js"},"./workers/elm-worker.js":"./dist/workers/elm-worker.js"},"founder":"Julian Wilkison-Duran","gitHead":"b920586fce06ae5f2f5bb57c4f8c03aeb1c55f33","scripts":{"dev":"vite","test":"vitest","build":"rollup -c && npm run build:types","clean":"rm -rf dist","watch":"rollup -c -w","dev:elm":"DEMO=elm-explination vite","dev:lang":"DEMO=language-awareness-demo vite","dev:news":"DEMO=ag-news-demo vite","dev:chain":"DEMO=chain-with-save vite","dev:music":"DEMO=elm-drum-demo-mainthread vite","postbuild":"cp dist/astermind.umd.js public/astermind.umd.js || true","build:types":"tsc -p tsconfig.types.json","dev:autocomplete":"DEMO=autocomplete-chain vite"},"_npmUser":{"name":"clockworksyler","email":"clockworksyler@gmail.com"},"repository":{"url":"git+https://github.com/infiniteCrank/AsterMind-ELM.git","type":"git"},"_npmVersion":"11.6.2","description":"JavaScript Extreme Learning Machine (ELM) library for browser and Node.js.","directories":{},"sideEffects":false,"_nodeVersion":"25.2.0","patentPending":"US 63/897,713","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^6.3.5","jsdom":"^26.1.0","tslib":"^2.8.1","yargs":"^18.0.0","eslint":"^9.29.0","ml-pca":"^4.1.1","rollup":"^4.43.0","vitest":"^3.2.4","ts-node":"^10.9.2","tsne-js":"^1.0.3","umap-js":"^1.4.0","prettier":"^3.5.3","csv-parse":"^5.6.0","ml-matrix":"^6.12.1","typescript":"^5.8.3","@types/node":"^24.0.3","@types/yargs":"^17.0.33","plotly.js-dist":"^3.0.1","@types/csv-parse":"^1.1.12","@xenova/transformers":"^2.17.2","@rollup/plugin-commonjs":"^25.0.8","rollup-plugin-typescript2":"^0.36.0","@rollup/plugin-node-resolve":"^15.3.0"},"incorporationDate":"2025-10-10","_npmOperationalInternal":{"tmp":"tmp/astermind-elm_2.1.1_1763271921024_0.2556298838992772","host":"s3://npm-registry-packages-npm-production"}}},"time":{"created":"2025-11-16T05:45:20.907Z","modified":"2025-12-31T18:06:59.216Z","1.0.1":"2025-09-17T18:16:16.428Z","1.0.2":"2025-09-17T18:33:28.951Z","2.1.0":"2025-09-22T23:29:51.941Z","2.1.1":"2025-11-16T05:45:21.249Z"},"bugs":{"url":"https://github.com/infiniteCrank/AsterMind-ELM/issues"},"author":{"name":"Julian Wilkison-Duran","email":"clockworksyler@gmail.com"},"license":"MIT","homepage":"https://github.com/infiniteCrank/AsterMind-ELM#readme","keywords":["elm","extreme-learning-machine","ml","javascript","browser","node"],"repository":{"url":"git+https://github.com/infiniteCrank/AsterMind-ELM.git","type":"git"},"description":"JavaScript Extreme Learning Machine (ELM) library for browser and Node.js.","maintainers":[{"email":"tim@astermind.ai","name":"spockinnator"},{"email":"clockworksyler@gmail.com","name":"clockworksyler"}],"readme":"# AsterMind-ELM\n\n[![npm version](https://img.shields.io/npm/v/%40astermind/astermind-elm.svg)](https://www.npmjs.com/package/@astermind/astermind-elm)\n[![npm downloads](https://img.shields.io/npm/dm/%40astermind/astermind-elm.svg)](https://www.npmjs.com/package/@astermind/astermind-elm)\n[![license: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](#license)\n\nA modular Extreme Learning Machine (ELM) library for JS/TS (browser + Node).\n\n---\n\n# 🚀 What you can build — and why this is groundbreaking\n\nAsterMind brings **instant, tiny, on-device ML** to the web. It lets you ship models that **train in milliseconds**, **predict with microsecond latency**, and **run entirely in the browser** — no GPU, no server, no tracking. With **Kernel ELMs**, **Online ELM**, **DeepELM**, and **Web Worker offloading**, you can create:\n\n- **Private, on-device classifiers** (language, intent, toxicity, spam) that retrain on user feedback  \n- **Real-time retrieval & reranking** with compact embeddings (ELM, KernelELM, Nyström whitening) for search and RAG  \n- **Interactive creative tools** (music/drum generators, autocompletes) that respond instantly  \n- **Edge analytics**: regressors/classifiers from data that never leaves the page  \n- **Deep ELM chains**: stack encoders → embedders → classifiers for powerful pipelines, still tiny and transparent  \n\n**Why it matters:** ELMs give you **closed-form training** (no heavy SGD), **interpretable structure**, and **tiny memory footprints**.  \nAsterMind modernizes ELM with kernels, online learning, workerized training, robust preprocessing, and deep chaining — making **seriously fast ML** practical for every web app.\n\n---\n\n## 🆕 New in this release\n\n- **Kernel ELMs (KELMs)** — exact and Nyström kernels (RBF/Linear/Poly/Laplacian/Custom) with ridge solve  \n- **Whitened Nyström** — optional \\(K_{mm}^{-1/2}\\) whitening via symmetric eigendecomposition  \n- **Online ELM (OS-ELM)** — streaming RLS updates with forgetting factor (no full retrain)  \n- **DeepELM** — multi-layer stacked ELM with non-linear projections  \n- **Web Worker adapter** — off-main-thread training/prediction for ELM and KELM  \n- **Matrix upgrades** — Jacobi eigendecomp, invSqrtSym, improved Cholesky  \n- **EmbeddingStore 2.0** — unit-norm vectors, ring buffer capacity, metadata filters  \n- **ELMChain+Embeddings** — safer chaining with dimension checks, JSON I/O  \n- **Activations** — added **linear** and **gelu**; centralized registry  \n- **Configs** — split into **Numeric** and **Text** configs; stronger typing  \n- **UMD exports** — `window.astermind` exposes `ELM`, `OnlineELM`, `KernelELM`, `DeepELM`, `KernelRegistry`, `EmbeddingStore`, `ELMChain`, etc.  \n- **Robust preprocessing** — safer encoder path, improved error handling\n\nSee [Releases](#releases) for full changelog.\n\n---\n\n## 📑 Table of Contents\n\n1. [Introduction](#introduction)  \n2. [Features](#features)  \n3. [Kernel ELMs (KELM)](#kernel-elms-kelm)  \n4. [Online ELM (OS-ELM)](#online-elm-os-elm)  \n5. [DeepELM](#deepelm)  \n6. [Web Worker Adapter](#web-worker-adapter)  \n7. [Installation](#installation)  \n8. [Usage Examples](#usage-examples)  \n9. [Suggested Experiments](#suggested-experiments)  \n10. [Why Use AsterMind](#why-use-astermind)  \n11. [Core API Documentation](#core-api-documentation)  \n12. [Method Options Reference](#method-options-reference)  \n13. [ELMConfig Options](#elmconfig-options-reference)  \n14. [Prebuilt Modules](#prebuilt-modules-and-custom-modules)  \n15. [Text Encoding Modules](#text-encoding-modules)  \n16. [UI Binding Utility](#ui-binding-utility)  \n17. [Data Augmentation Utilities](#data-augmentation-utilities)  \n18. [IO Utilities (Experimental)](#io-utilities-experimental)  \n19. [Embedding Store](#embedding-store)  \n20. [Utilities: Matrix & Activations](#utilities-matrix--activations)  \n21. [Adapters & Chains](#adapters--chains)  \n22. [Workers: ELMWorker & ELMWorkerClient](#workers-elmworker--elmworkerclient)  \n23. [Example Demos and Scripts](#example-demos-and-scripts)  \n24. [Experiments and Results](#experiments-and-results)  \n25. [Releases](#releases)  \n26. [License](#license)\n\n---\n\n<a id=\"introduction\"></a>\n# 🌟 AsterMind: Decentralized ELM Framework Inspired by Nature\n\nWelcome to **AsterMind**, a modular, decentralized ML framework built around cooperating Extreme Learning Machines (ELMs) that self-train, self-evaluate, and self-repair — like the nervous system of a starfish.\n\n**How This ELM Library Differs from a Traditional ELM**\n\nThis library preserves the core Extreme Learning Machine idea — random hidden layer, nonlinear activation, closed-form output solve — but extends it with:\n\n- Multiple activations (ReLU, LeakyReLU, Sigmoid, **Linear, GELU**)  \n- Xavier/Uniform/**He** initialization  \n- Dropout on hidden activations  \n- Sample weighting  \n- Metrics gate (RMSE, MAE, Accuracy, F1, Cross-Entropy, R²)  \n- JSON export/import  \n- Model lifecycle management  \n- UniversalEncoder for text (char/token)  \n- Data augmentation utilities  \n- Chaining (ELMChain) for stacked embeddings  \n- Weight reuse (simulated fine-tuning)  \n- Logging utilities\n\nAsterMind is designed for:\n\n* Lightweight, in-browser ML pipelines  \n* Transparent, interpretable predictions  \n* Continuous, incremental learning  \n* Resilient systems with no single point of failure  \n\n---\n\n<a id=\"features\"></a>\n## ✨ Features\n\n- ✅ Modular Architecture  \n- ✅ Closed-form training (ridge / pseudoinverse)  \n- ✅ Activations: relu, leakyrelu, sigmoid, tanh, linear, gelu  \n- ✅ Initializers: uniform, xavier, he  \n- ✅ Numeric + Text configs  \n- ✅ Kernel ELM with Nyström + whitening  \n- ✅ Online ELM (RLS) with forgetting factor  \n- ✅ DeepELM (stacked layers)  \n- ✅ Web Worker adapter  \n- ✅ Embeddings & Chains for retrieval and deep pipelines  \n- ✅ JSON import/export  \n- ✅ Self-governing training  \n- ✅ Flexible preprocessing  \n- ✅ Lightweight deployment (ESM + UMD)  \n- ✅ Retrieval and classification utilities  \n- ✅ Zero server/GPU — private, on-device ML  \n\n---\n\n<a id=\"kernel-elms-kelm\"></a>\n## 🧠 Kernel ELMs (KELM)\n\nSupports **Exact** and **Nyström** modes with RBF/Linear/Poly/Laplacian/Custom kernels.  \nIncludes **whitened Nyström** (persisted whitener for inference parity).\n\n```ts\nimport { KernelELM, KernelRegistry } from '@astermind/astermind-elm';\n\nconst kelm = new KernelELM({\n  outputDim: Y[0].length,\n  kernel: { type: 'rbf', gamma: 1 / X[0].length },\n  mode: 'nystrom',\n  nystrom: { m: 256, strategy: 'kmeans++', whiten: true },\n  ridgeLambda: 1e-2,\n});\nkelm.fit(X, Y);\n```\n\n---\n\n<a id=\"online-elm-os-elm\"></a>\n## 🔁 Online ELM (OS-ELM)\n\nStream updates via **Recursive Least Squares (RLS)** with optional forgetting factor. Supports He/Xavier/Uniform initializers.\n\n```ts\nimport { OnlineELM } from '@astermind/astermind-elm';\nconst ol = new OnlineELM({ inputDim: D, outputDim: K, hiddenUnits: 256 });\nol.init(X0, Y0);\nol.update(Xt, Yt);\nol.predictProbaFromVectors(Xq);\n```\n\n**Notes**  \n- `forgettingFactor` controls how fast older observations decay (default 1.0).  \n- Two natural embedding modes: **hidden** (activations) or **logits** (pre-softmax). Use with `ELMAdapter` (see below).\n\n---\n\n<a id=\"deepelm\"></a>\n## 🌊 DeepELM\n\nStack multiple ELM layers for deep nonlinear embeddings and an optional top ELM classifier.\n\n```ts\nimport { DeepELM } from '@astermind/astermind-elm';\nconst deep = new DeepELM({\n  inputDim: D,\n  layers: [{ hiddenUnits: 128 }, { hiddenUnits: 64 }],\n  numClasses: K\n});\n// 1) Unsupervised layer-wise training (autoencoders Y=X)\nconst X_L = deep.fitAutoencoders(X);\n// 2) Supervised head (ELM) on last layer features\ndeep.fitClassifier(X_L, Y);\n// 3) Predict\nconst probs = deep.predictProbaFromVectors(Xq);\n```\n\n**JSON I/O**  \n`toJSON()` and `fromJSON()` persist the full stack (AEs + classifier).\n\n---\n\n<a id=\"web-worker-adapter\"></a>\n## 🧵 Web Worker Adapter\n\nMove heavy ops off the main thread. Provides `ELMWorker` + `ELMWorkerClient` for RPC-style training/prediction with progress events.\n\n- Initialize with `initELM(config)` or `initOnlineELM(config)`  \n- Train via `train` / `trainFromData` / `fit` / `update`  \n- Predict via `predict`, `predictFromVector`, or `predictLogits`  \n- Subscribe to progress callbacks per call\n\nSee [Workers](#workers-elmworker--elmworkerclient) for full API.\n\n---\n\n<a id=\"installation\"></a>\n## 🚀 Installation\n\n**NPM (scoped package):**\n```bash\nnpm install @astermind/astermind-elm\n# or\npnpm add @astermind/astermind-elm\n# or\nyarn add @astermind/astermind-elm\n```\n\n**CDN / `<script>` (UMD global `astermind`):**\n```html\n<!-- jsDelivr -->\n<script src=\"https://cdn.jsdelivr.net/npm/@astermind/astermind-elm/dist/astermind.umd.js\"></script>\n\n<!-- or unpkg -->\n<script src=\"https://unpkg.com/@astermind/astermind-elm/dist/astermind.umd.js\"></script>\n\n<script>\n  const { ELM, KernelELM } = window.astermind;\n</script>\n```\n\n**Repository:**\n- GitHub: https://github.com/infiniteCrank/AsterMind-ELM  \n- NPM: https://www.npmjs.com/package/@astermind/astermind-elm  \n\n---\n\n<a id=\"usage-examples\"></a>\n## 🛠️ Usage Examples\n\n**Basic ELM Classifier**\n\n```ts\nimport { ELM } from \"@astermind/astermind-elm\";\n\nconst config = { categories: ['English', 'French'], hiddenUnits: 128 };\nconst elm = new ELM(config);\n\n// Load or train logic here\nconst results = elm.predict(\"bonjour\");\nconsole.log(results);\n```\n\n**CommonJS / Node:**\n```js\nconst { ELM } = require(\"@astermind/astermind-elm\");\n```\n\n**Kernel ELM / DeepELM:** see above examples.\n\n---\n\n<a id=\"suggested-experiments\"></a>\n## 🧪 Suggested Experiments\n\n* Compare retrieval performance with Sentence-BERT and TFIDF.  \n* Experiment with activations and token vs char encoding.  \n* Deploy in-browser retraining workflows.  \n\n---\n\n<a id=\"why-use-astermind\"></a>\n## 🌿 Why Use AsterMind?\n\nBecause you can build AI systems that:\n\n* Are decentralized.  \n* Self-heal and retrain independently.  \n* Run in the browser.  \n* Are transparent and interpretable.  \n\n---\n\n<a id=\"core-api-documentation\"></a>\n## 📚 Core API Documentation\n\n### ELM  \n- `train`, `trainFromData`, `predict`, `predictFromVector`, `getEmbedding`, **`predictLogitsFromVectors`**, JSON I/O, metrics  \n- `loadModelFromJSON`, `saveModelAsJSONFile`  \n- Evaluation: RMSE, MAE, Accuracy, F1, Cross-Entropy, R²  \n- Config highlights: `ridgeLambda`, `weightInit` (`uniform` | `xavier` | `he`), `seed`\n\n### OnlineELM  \n- `init`, `update`, `fit`, `predictLogitsFromVectors`, `predictProbaFromVectors`, embeddings (hidden/logits), JSON I/O  \n- Config highlights: `inputDim`, `outputDim`, `hiddenUnits`, `activation`, `ridgeLambda`, `forgettingFactor`\n\n### KernelELM  \n- `fit`, `predictProbaFromVectors`, `getEmbedding`, JSON I/O  \n- `mode: 'exact' | 'nystrom'`, kernels: `rbf | linear | poly | laplacian | custom`\n\n### DeepELM  \n- `fitAutoencoders(X)`, `transform(X)`, `fitClassifier(X_L, Y)`, `predictProbaFromVectors(X)`  \n- `toJSON()`, `fromJSON()` for full-pipeline persistence\n\n### ELMChain  \n- sequential embeddings through multiple encoders\n\n### TFIDFVectorizer  \n- `vectorize`, `vectorizeAll`\n\n### KNN  \n- `find(queryVec, dataset, k, topX, metric)`\n\n---\n\n<a id=\"method-options-reference\"></a>\n## 📘 Method Options Reference\n\n### `train(augmentationOptions?, weights?)`\n- `augmentationOptions`: `{ suffixes, prefixes, includeNoise }`  \n- `weights`: sample weights\n\n### `trainFromData(X, Y, options?)`\n- `X`: Input matrix  \n- `Y`: Label matrix or one-hot  \n- `options`: `{ reuseWeights, weights }`  \n\n### `predict(text, topK)`  \n- `text`: string  \n- `topK`: number of predictions  \n\n### `predictFromVector(vector, topK)`  \n- `vector`: numeric  \n- `topK`: number of predictions  \n\n### `saveModelAsJSONFile(filename?)`  \n- `filename`: optional file name  \n\n---\n\n<a id=\"elmconfig-options-reference\"></a>\n## ⚙️ ELMConfig Options Reference\n\n| Option               | Type       | Description                                                   |\n| -------------------- | ---------- | ------------------------------------------------------------- |\n| `categories`         | `string[]` | List of labels the model should classify. *(Required)*        |\n| `hiddenUnits`        | `number`   | Number of hidden layer units (default: 50).                   |\n| `maxLen`             | `number`   | Max length of input sequences (default: 30).                  |\n| `activation`         | `string`   | Activation function (`relu`, `tanh`, etc.).                   |\n| `encoder`            | `any`      | Custom UniversalEncoder instance (optional).                  |\n| `charSet`            | `string`   | Character set used for encoding.                              |\n| `useTokenizer`       | `boolean`  | Use token-level encoding.                                     |\n| `tokenizerDelimiter` | `RegExp`   | Tokenizer regex.                                              |\n| `exportFileName`     | `string`   | Filename to export JSON.                                      |\n| `metrics`            | `object`   | Thresholds (`rmse`, `mae`, `accuracy`, etc.).                 |\n| `log`                | `object`   | Logging config.                                               |\n| `dropout`            | `number`   | Dropout rate.                                                 |\n| `weightInit`         | `string`   | Initializer. (`uniform` | `xavier` | `he`)                    |\n| `ridgeLambda`        | `number`   | Ridge penalty for closed-form solve.                          |\n| `seed`               | `number`   | PRNG seed for reproducibility.                                |\n\n---\n\n<a id=\"prebuilt-modules-and-custom-modules\"></a>\n## 🧩 Prebuilt Modules and Custom Modules\n\nIncludes: AutoComplete, EncoderELM, CharacterLangEncoderELM, FeatureCombinerELM, ConfidenceClassifierELM, IntentClassifier, LanguageClassifier, VotingClassifierELM, RefinerELM.  \n\nEach exposes `.train()`, `.predict()`, `.loadModelFromJSON()`, `.saveModelAsJSONFile()`, `.encode()`.\n\nCustom modules can be built on top.\n\n---\n\n<a id=\"text-encoding-modules\"></a>\n## ✨ Text Encoding Modules\n\nIncludes `TextEncoder`, `Tokenizer`, `UniversalEncoder`.  \nSupports char-level & token-level, normalization, n-grams.\n\n---\n\n<a id=\"ui-binding-utility\"></a>\n## 🖥️ UI Binding Utility\n\n`bindAutocompleteUI(model, inputElement, outputElement, topK)` helper.  \nBinds model predictions to live HTML input.\n\n---\n\n<a id=\"data-augmentation-utilities\"></a>\n## ✨ Data Augmentation Utilities\n\nAugment with prefixes, suffixes, noise.  \nExample: `Augment.generateVariants(\"hello\", \"abc\", { suffixes:[\"world\"], includeNoise:true })`.\n\n---\n\n<a id=\"io-utilities-experimental\"></a>\n## ⚠️ IO Utilities (Experimental)\n\nJSON/CSV/TSV import/export, schema inference.  \nExperimental and may be unstable.\n\n---\n\n<a id=\"embedding-store\"></a>\n## 🧰 Embedding Store\n\nLightweight vector store with cosine/dot/euclidean KNN, unit-norm storage, ring buffer capacity.\n\n**Usage**\n```ts\nimport { EmbeddingStore } from '@astermind/astermind-elm';\n\nconst store = new EmbeddingStore({ capacity: 5000, normalize: true });\nstore.add({ id: 'doc1', vector: [/* ... */], meta: { title: 'Hello' } });\nconst hits = store.query({ vector: q, k: 10, metric: 'cosine' });\n```\n\n---\n\n<a id=\"utilities-matrix--activations\"></a>\n## 🔧 Utilities: Matrix & Activations\n\n**Matrix** – internal linear algebra utilities (multiply, transpose, addRegularization, solveCholesky, etc.).  \n**Activations** – `relu`, `leakyrelu`, `sigmoid`, `tanh`, `linear`, `gelu`, plus `softmax`, derivatives, and helpers (`get`, `getDerivative`, `getPair`).\n\n---\n\n<a id=\"adapters--chains\"></a>\n## 🔗 Adapters & Chains\n\n**ELMAdapter** wraps an `ELM` or `OnlineELM` to behave like an encoder for `ELMChain`:\n\n```ts\nimport { ELMAdapter, wrapELM, wrapOnlineELM } from '@astermind/astermind-elm';\n\nconst enc1 = wrapELM(elm);                          // uses elm.getEmbedding(X)\nconst enc2 = wrapOnlineELM(online, { mode: 'logits' }); // 'hidden' or 'logits'\nconst chain = new ELMChain([enc1, enc2], { normalizeFinal: true });\n\nconst Z = chain.getEmbedding(X); // stacked embeddings\n```\n\n---\n\n<a id=\"workers-elmworker--elmworkerclient\"></a>\n## 🧱 Workers: ELMWorker & ELMWorkerClient\n\n**ELMWorker** (inside a Web Worker) exposes a tolerant RPC surface:  \n- lifecycle: `initELM`, `initOnlineELM`, `dispose`, `getKind`, `setVerbose`  \n- training: `train`, `fit`, `update`, `trainFromData` (all routed appropriately)  \n- prediction: `predict`, `predictFromVector`, `predictLogits`  \n- progress events: `{ type:'progress', phase, pct }` during training\n\n**ELMWorkerClient** (on the main thread) is a thin promise-based RPC client:\n\n```ts\nimport { ELMWorkerClient } from '@astermind/astermind-elm/worker';\n\nconst client = new ELMWorkerClient(new Worker(new URL('./ELMWorker.js', import.meta.url)));\nawait client.initELM({ categories:['A','B'], hiddenUnits:128 });\n\nawait client.elmTrain({}, (p) => console.log(p.phase, p.pct));\nconst preds = await client.elmPredict('bonjour', 5);\n```\n\n---\n\n<a id=\"example-demos-and-scripts\"></a>\n## 🧪 Example Demos and Scripts\n\nRun with `npm run dev:*` (autocomplete, lang, chain, news).  \nFully in-browser.\n\n---\n\n<a id=\"experiments-and-results\"></a>\n## 🧪 Experiments and Results\n\nIncludes dropout tuning, hybrid retrieval, ensemble distillation, multi-level pipelines.  \nResults reported (Recall@1, Recall@5, MRR).\n\n---\n\n<a id=\"releases\"></a>\n## 📦 Releases\n\n### v2.1.0 — 2025-09-19\n**New features:** Kernel ELM, Nyström whitening, OnlineELM, DeepELM, Worker adapter, EmbeddingStore 2.0, activations linear/gelu, config split.  \n**Fixes:** Xavier init, encoder guards, dropout scaling.  \n**Breaking:** Config now `NumericConfig|TextConfig`.\n\n---\n\n<a id=\"license\"></a>\n## 📄 License\n\nMIT License\n\n---\n\n> **“AsterMind doesn’t just mimic a brain—it functions more like a starfish: fully decentralized, self-evaluating, and self-repairing.”**\n","readmeFilename":"README.md"}