FERS vanuit JavaScript gebruiken
De FERS-solver is gepubliceerd als WebAssembly-build van dezelfde Rust-rekenkern die de webapplicatie aandrijft. Hij draait in de browser of in Node, rekent zonder serverronde en vraagt in het gratis abonnement geen API-sleutel.
Installatie
Uit dezelfde rekenkern worden twee pakketten met een identieke API gepubliceerd — alleen de installatie en de bundlerinstelling verschillen. Neem -web voor alles wat door een bundler gaat en het pakket zonder achtervoegsel voor Node aan de serverzijde.
# Browser apps (Vite, Next.js, webpack):
npm install @ferscloud/fers-calculation-web
# Node.js / server-side:
npm install @ferscloud/fers-calculationBeide pakketten dragen de versie van de rekenkern en gaan samen mee. Zet ze vast op dezelfde exacte versie in plaats van op een caret-bereik.
De bundler instellen
@ferscloud/fers-calculation-web is een WASM-ES-module die zich initialiseert via een top-level await. De meeste bundlers hebben daarvoor een eenmalige instelling nodig; het Node-pakket niet.
Vite
Voeg de plug-in toe en stel daarna een build-target in dat top-level await ondersteunt.
npm i -D vite-plugin-wasmVite-configuratie
// vite.config.ts
import wasm from "vite-plugin-wasm";
// The package initialises with a top-level await, so the build target
// has to be one that supports it. esnext needs no second plugin.
export default {
plugins: [wasm()],
build: { target: "esnext" },
};Next.js en webpack
Transpileer het pakket en zet asynchrone WebAssembly aan. asyncFunction is nodig omdat de module zich met een top-level await initialiseert.
// next.config.js
module.exports = {
transpilePackages: ["@ferscloud/fers-calculation-web"],
webpack(config) {
config.experiments = { ...config.experiments, asyncWebAssembly: true };
config.output.environment = {
...config.output.environment,
asyncFunction: true,
};
return config;
},
};De solver is synchroon en rekenintensief. Draai hem bij grote modellen in een Web Worker zodat de UI-thread responsief blijft.
Een model rekenen
Geen init()-aanroep en geen API-sleutel. Het gratis abonnement dekt elk model tot 100 staven.
import { calculate_from_json } from "@ferscloud/fers-calculation";
// No init() call needed — the nodejs and bundler builds initialise the
// WASM module automatically on import.
const res = JSON.parse(calculate_from_json(JSON.stringify(myModel)));
if (res.ok) {
const data = res.result; // displacements, member_results, unity_checks, …
} else {
console.error(res.error.code, res.error.message);
}De resultaat-envelope
Elke solveraanroep geeft een JSON-envelope terug, zodat u één keer parseert en op ok vertakt — u hoeft nooit te raden of de teruggegeven tekenreeks op een fout lijkt. De teruggegeven waarde is altijd geldig JSON.
// success
{ "ok": true, "result": { /* the full result document */ } }
// failure (invalid model, over the member limit, malformed JSON, …)
{ "ok": false, "error": { "code": "LimitExceeded",
"message": "Number of members (250) exceeds allowed maximum of 100" } }| error.code | Betekenis |
|---|---|
InvalidJson | De modeltekenreeks was geen parseerbaar JSON. |
LimitExceeded | Meer staven dan het actieve abonnement toestaat (100 gratis, 10,000 Pro). |
SolveError | Het model is gelezen maar kon niet worden opgelost — meestal een singuliere stijfheidsmatrix door een ontbrekende of te losse oplegging. |
InternalPanic | Een fout in de rekenkern. Graag melden. |
InternalSerialization | De resultaten konden niet worden geserialiseerd. Ook een fout die het melden waard is. |
TypeScript-types
Het browserpakket levert gegenereerde modeltypes naast de functiehandtekeningen mee. Ze worden uit het OpenAPI-schema van de rekenkern gegenereerd en volgen dus de gepubliceerde versie in plaats van met de hand te worden bijgehouden.
import type {
FERS,
ResultsBundle,
} from "@ferscloud/fers-calculation-web/fers-models";
// FERS — the input model
// ResultsBundle — the `result` payload of a successful envelope
// Both are generated from the engine's OpenAPI schema, so they track
// the published version.FERS vermelden in het gratis abonnement
Resultaten uit het gratis abonnement dragen een attribution-object dat binnen de solver wordt aangemaakt. Pro-resultaten, gerekend met een geldig token, dragen het niet — dezelfde code toont dus een vermelding op gratis en levert onder Pro white-label-uitvoer, zonder dat u iets hoeft in te stellen.
Daarnaast worden getFersAttribution, fersAttributionText en createFersBadge geëxporteerd. Ze accepteren allemaal de envelope, het geparseerde model of de resultatenbundel, en geven allemaal niets terug bij een Pro-resultaat of een foutenvelope.
import { fersAttributionHtml } from "@ferscloud/fers-calculation-web/badge.js";
// Free-tier results carry result.attribution; this renders the credit.
// With a Pro solve token the field is absent and this returns "" — the
// same code white-labels, with no flag to set.
const credit = fersAttributionHtml(res);Gebruikt u het gratis abonnement in een applicatie, toon dan de vermelding. Het is het enige dat het gratis abonnement van u vraagt. Beschikbaar vanaf engine 0.2.61.
Pro-grenzen met een rekentoken
De Pro-grenzen worden vrijgegeven met een kortlevend ondertekend token dat de FERS Cloud-server uitgeeft. Het token wordt binnen de WebAssembly-module geverifieerd tegen een in het binaire bestand ingebakken Ed25519-publieke sleutel en is daardoor niet te vervalsen.
Uw server houdt de API-sleutel en wisselt die in voor een token van 30 minuten; de browser ziet alleen het token. Houd FERS_API_KEY serverzijdig — nooit in browsercode.
// pages/api/solve-token.ts
const FERS_API_KEY = process.env.FERS_API_KEY!;
let cached: { token: string; expiresAt: number } | null = null;
export default async function handler(req, res) {
const now = Date.now();
// Re-use if more than 5 minutes remain
if (cached && cached.expiresAt - now > 5 * 60 * 1000) {
return res.json({ token: cached.token });
}
const resp = await fetch("https://ferscloud.com/api/solver/token", {
method: "POST",
headers: { "X-API-Key": FERS_API_KEY },
});
if (!resp.ok) return res.status(502).json({ error: "Token fetch failed" });
const { token, expiresAt } = await resp.json();
cached = { token, expiresAt: new Date(expiresAt).getTime() };
return res.json({ token });
}De solver met een token aanroepen
Ontbreekt het token of is het verlopen of ongeldig, dan valt de solver terug op de gratis staafgrens — hij werpt nooit een uitzondering. Een echte rekenfout komt nog steeds terug als { ok: false, error } en niet als exception.
import { calculate_from_json_with_token } from "@ferscloud/fers-calculation";
const { token } = await fetch("/api/solve-token").then((r) => r.json());
const res = JSON.parse(
calculate_from_json_with_token(JSON.stringify(myModel), token),
);
if (!res.ok) throw new Error(`${res.error.code}: ${res.error.message}`);
const data = res.result;| Gratis | Pro | |
|---|---|---|
| Maximaal aantal staven | 100 | 10,000 |
| Functie | calculate_from_json | calculate_from_json_with_token |
| Token vereist | Nee | Ja |
| Geldigheid van het token | — | 30 minuten |
Doorbuigingslijn
Zet include_member_deflected_shape in de analyse-opties van het model om per staaf een direct tekenbare, belastingexacte doorbuigingslijn te krijgen — de globale vervorming van de staaf bemonsterd over zijn lengte — in plaats van de kromme zelf te reconstrueren.
Hij staat standaard uit om het antwoord licht te houden en ontbreekt in member_results wanneer hij niet is aangevraagd.
const model = {
/* … model + load cases … */
analysis: {
/* … */
options: {
/* … */
include_member_deflected_shape: true,
},
},
};
const res = JSON.parse(calculate_from_json(JSON.stringify(model)));
const mr = res.result.results.loadcases["…"].member_results["1"];
// mr.member_displacements: [{ x_frac, displacement: [dx, dy, dz] }, …]
// x_frac 0–1 along the member; displacement in the global input frame.Andere ingangen
- Waarom constructies in JavaScript rekenen — de argumenten voor een solver aan de clientzijde.
- REST-API — de solver via HTTP aanroepen vanuit elke taal.
- MCP-server — Claude, ChatGPT, Cursor of VS Code FERS rechtstreeks laten aansturen.
- Python-pakket — dezelfde rekenkern vanuit een script.
Gerelateerde pagina’s
REST-API-referentie
Elk SDK-eindpunt met verzoek en antwoord — authenticatie, sleutels, rekenen, valideren, liggertoetsing en modelbeheer.
Snelstart: uw eerste model in de browser
Bouw en bereken een 3D-raamwerk in de browser: materialen, doorsneden, knopen, opleggingen, staven, belastingen, Berekenen.
Zie ook
Veelgestelde vragen
Heb ik een API-sleutel nodig om in de browser te rekenen?
calculate_from_json werkt zonder sleutel en zonder account voor modellen tot 100 staven. Een sleutel is alleen nodig om het Pro-rekentoken uit te geven.Verlaat het model de browser?
Waarom heeft Vite extra configuratie nodig?
await initialiseert. vite-plugin-wasm verzorgt de WebAssembly-import en build.target: "esnext" houdt die await in de uitvoer — dat vereist Chrome, Edge of Firefox 89+, of Safari 15+. webpack heeft asyncWebAssembly en asyncFunction nodig in de experiments- en output-instellingen. Staat vite-plugin-top-level-await nog in je configuratie uit een eerdere versie van deze pagina, dan kun je het verwijderen: met recente @swc/core-versies laat het vite build mislukken.Moet ik de solver in een Web Worker draaien?
Heb ik een init()-aanroep nodig?
await init(); dat is niet meer nodig.Wat gebeurt er als het rekentoken is verlopen?
LimitExceeded.Welk pakket gebruik ik op de server?
@ferscloud/fers-calculation, gebouwd voor het Node-target. Het vraagt geen bundlerinstelling en initialiseert zichzelf bij het importeren.