@essrt/physics

中文文档
26.15.0发布于 2026/11/14AGPL-3.0-or-laterTypeScriptESM + CJS零依赖近 30 天下载 4410

ESSRT (Expanding Solar System Resonance Theory) physics core — pure, injectable-constants, no I/O, no globals, no DOM. The complete model incl. fitted coefficients; every published version immutably ships one recorded model identity.

原始使用文档
文档目录7 节
  1. Versioning — two axes, deliberately
  2. Usage
  3. The assembled model — createModel()
  4. The series artifact
  5. Underneath: a parts library
  6. Provenance
  7. Licence

@essrt/physics

The physics core of ESSRT — the Expanding Solar System Resonance Theory — as implemented by the ESSRT simulator (source, AGPL-3.0). Pure computation: no I/O, no globals, no DOM, constants injected. The package ships the complete model, including the fitted coefficients, so an installed copy reproduces the simulator's engine on the shared golden masters (bit-exact in Node; the browser build is held to a measured cross-runtime tolerance).

Versioning — two axes, deliberately

  • Package semver (this package's version) tracks the API axis — what import gives you.
  • Model identity rides inside every published version: the essrt.modelVersion field in package.json plus CONSTANTS_HASH and COEFFICIENTS_HASH in src/constants/. A refit or structural model change always lands as a new package version — npm's immutability then guarantees a pinned version's results never change. The hashes cover VALUES: the artifacts' provenance stamps (their inputs blocks) are excluded, so a re-stamp that moves no number moves no hash.

Cite results as model vX.Y (package A.B.C).

Usage

import { DEFAULT_CONSTANTS, FITTED_COEFFICIENTS, createEpochPrimitives } from '@essrt/physics';

Domain modules are CJS subpath exports, each a create* factory taking its dependencies explicitly (the injectable-constants design — counterfactual runs are first-class):

const { createEclipseFinders } = require('@essrt/physics/eclipse/finders');
const { createMoonSeries } = require('@essrt/physics/moon/series');

TypeScript: the package ships declaration files (types/, one per subpath export) generated from the sources' JSDoc — import from @essrt/physics or any subpath is fully typed; no ambient shim needed.

See the exports map in package.json for the full surface: moon (arguments, series, series-extension, apparent, ecc-channel, deep-ecc-channel, month-chain), earth (year-lengths, precession-composed, frame-of-date, sidereal-year-channel, deep-orbital-history), planets (keplerian-chain, orbit-chain, secular-shape, secular-series, inv-plane-frame, spin-channel, ecc-channel, geometry, model), deltat (cycles, deep-time, moon-distance-history + moon-distance-artifact — the cited AstroGeo22 Earth–Moon distance history, historical), the cardinal structure, the deep calendar, chain-cycles, sun, climate and eclipse finders.

For rendered display values (day/year lengths, precession rates, orbital elements as preformatted strings), see @essrt/model-values — generated from this engine at the same model version.

The assembled model — createModel()

The canonical assembly, wired once inside the package:

import { createModel, DEFAULT_CONSTANTS } from '@essrt/physics';

const model = createModel();
model.identity.modelVersion;          // the shipped model identity (e.g. 'v21.0') + both content hashes
model.lunisolar.meanPeriodYearsAtYear(2000 - 380e6); // 21699 — the Devonian precession period
model.epoch.lodSecondsAtYear(2000 - 380e6);          // 78895 — the Devonian day (Wells 1963's coral count)
model.earth.obliquityDeg(2000);       // 23.4393
model.cardinal.jd(2000, 'SS');        // 2451716.5751 — June solstice 2000, the apparent Sun's crossing (USNO 2451716.575)
model.lengths.tropicalYearDays(2000); // 365.24219

// Counterfactual (§2d): inject different constants, get a different solar
// system — self-identifying, with its own constants hash.
const cf = createModel({
  ...DEFAULT_CONSTANTS,
  earthOrbital: { ...DEFAULT_CONSTANTS.earthOrbital, obliquityJ2000_deg: 23.5 },
});
cf.earth.obliquityDeg(2000);          // 23.5 — the injected anchor read through the assembly
cf.identity.counterfactual;           // true

The surface groups: time (exact JD ↔ model-year conversion on the SI axis the fits were anchored on — callers holding a JD convert here, never with their own formula), identity (version + hashes + citation DOI), epoch (the internal unit, LOD, α, ΔT, the precession period and the deep-time quantities at any year ±500 Myr), lunisolar (the mean lunisolar precession period and rate at any year, its solar/lunar torque split, the nodal mode and the obliquity beat, the apsidal and perihelion-of-date periods and their ratios over the published window), earth (obliquity, eccentricity, inclination, perihelion), lengths (year and day lengths), cardinal (solstice/equinox JD, RA, year length), moon (distance and months at epoch, plus the apparent-position chain on the JD(UT) axis — ecliptic longitude, latitude and distance from the shared Meeus series over framework-native arguments), eclipse (geocentric solar/lunar eclipse search over a JD window, greatest-eclipse convention), climate (the L1 orbital-forcing formula) and planets (the N-body chain's elements of date — perihelion longitude, node and inclination on the invariable plane, eccentricity — and spin). Validation targets are refused as inputs — a counterfactual cannot move the goalposts it is judged by.

The series artifact

Earth's published orbit history (eccentricity, perihelion, obliquity) is the engine's banked N-body series — a 9-MB governed artifact kept in the public repository (data/nbody-secular-series.json), not inside this package. Pass it in to get the published values:

const series = JSON.parse(readFileSync('nbody-secular-series.json', 'utf8'));
const model = createModel(undefined, { secularSeriesArtifact: series });
model.earth.eccentricity(2000 - 100000);   // 0.04008 — the series (La2004: 0.04006)
createModel().earth.eccentricity(2000 - 100000);   // 0.03374 — the mode table

model.identity.earthElements names which one a result came from ('secular-series' or 'mode-table'), so a stored value is never ambiguous. Without the artifact createModel() evaluates the embedded 18-term mode table at every epoch: exact at J2000, a compact approximation away from it (RMS 3.6·10⁻³ in e against La2010a over the last 500 kyr, where the series reads 2.5·10⁻⁵). The API handler, the MCP server and the simulator always pass the artifact.

Underneath: a parts library

createModel() is assembly over unassembled factories. Each factory receives everything through one deps object — plain numbers plus functions — and no module imports another; that is what makes counterfactuals first-class and lets the same core run in Node and the browser. The assembly itself is src/model.js, a composer of the named slices in src/model/ (one file per family of quantities — one-source-movement, lunar-theory, sun-and-eclipses, surface, …), so a quantity is found by its slice's filename. For custom wiring (different α channel, subset assembly), use the factories directly: the reference adapter is tools/lib/ in the public repository — the hosted simulator and the project's verification gates run on it. A service surface over createModel() lives in the same repository (packages/api, an OpenAPI 3.1 handler with zero runtime dependencies) — build-only until the hosting decision.

Provenance

Every value derives from the model parameters and fitted coefficients in this package; the fitting pipeline, verification gates, dataset manifest and documentation live in the public repository. Preprint: https://doi.org/10.21203/rs.3.rs-8758810/v4.

Licence

AGPL-3.0-or-later. Commercial licensing: [email protected].

版本与发布记录

@essrt/physics 共发布 94 个版本,首次发布于 2026/08/12;过去 12 个月发布了 94 个版本。

版本发布日期距今
26.15.0latest2026/11/14今天
26.12.02026/11/112 天前
26.11.02026/11/113 天前
26.10.02026/11/085 天前
26.8.02026/11/068 天前
26.7.02026/11/059 天前

关于 @essrt/physics 的常见问题

@essrt/physics 是什么?

ESSRT (Expanding Solar System Resonance Theory) physics core — pure, injectable-constants, no I/O, no globals, no DOM. The complete model incl. fitted coefficients; every published version immutably ships one recorded model identity.

如何安装 @essrt/physics?

在项目目录运行 npm install @essrt/physics,或使用 pnpm add / yarn add / bun add。

@essrt/physics 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@essrt/physics 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@essrt/physics 可以商用吗?

@essrt/physics 使用 AGPL-3.0-or-later 许可。最严格的 Copyleft:除分发外,通过网络向用户提供基于它的服务也需要开源对应源码。闭源 SaaS 使用前务必评估。以上为概括,不构成法律意见,请以许可原文为准。

@essrt/physics 的下载量有多少?

根据 npm 官方下载统计,@essrt/physics 在 2026/10/14 – 2026/11/12 这 30 天内被下载 4,410 次,日均约 147 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@essrt/physics 还在维护吗?

最新版本 26.15.0 发布于 2026/11/14(今天);至今共发布 94 个版本,其中过去 12 个月发布了 94 个;首次发布于 2026/08/12。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。