@glandais/vcyclist-engine 1.0.0 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -112,16 +112,42 @@ suspend fun virtualize(xml: String): String {
112
112
  `generateTypeScriptDefinitions()` is enabled on both `js(IR)` and `wasmJs`, so you get a
113
113
  `.d.ts` next to the bundle in `build/dist/{js,wasmJs}/productionExecutable/vcyclist-engine.d.{ts,mts}`.
114
114
 
115
+ The Kotlin/JS variant (`@glandais/vcyclist-engine`, `@glandais/vcyclist-elevation`) runs
116
+ **in both browser and Node.js / Bun**. The Wasm variants (`*-wasm`) are browser-only.
117
+
118
+ #### Browser
119
+
115
120
  ```js
116
- import { parseGpx, enhance, writeGpx, pathSize, pathTotalDistance } from './vcyclist-engine.mjs';
121
+ import { parseGpx, enhance, writeGpx, pathSize, pathTotalDistance } from '@glandais/vcyclist-engine';
117
122
 
118
123
  const handle = parseGpx(gpxXml);
119
124
  console.log('input points:', pathSize(handle));
120
- const out = await enhance(handle, null);
125
+ const out = await enhance(handle, null); // physics only, no HTTP
121
126
  console.log('output:', pathSize(out), pathTotalDistance(out), 'm');
122
127
  const xml = writeGpx(out);
123
128
  ```
124
129
 
130
+ #### Node.js / Bun (with elevation correction)
131
+
132
+ ```js
133
+ import { parseGpx, enhance, writeGpx } from '@glandais/vcyclist-engine';
134
+
135
+ const handle = parseGpx(gpxXml);
136
+ const out = await enhance(handle, { fixElevation: true }); // fetches DEM tiles, decodes WebP
137
+ const xml = writeGpx(out);
138
+ ```
139
+
140
+ `enhance(..., { fixElevation: true })` auto-instantiates a default `ElevationProvider`
141
+ (mapterhorn Terrarium tiles) and runs the full pipeline (densify → fix elevation → smooth →
142
+ max speeds → virtualize → resample → simplify).
143
+
144
+ On Node.js / Bun, tile decoding uses [`@jsquash/webp`](https://www.npmjs.com/package/@jsquash/webp)
145
+ (a pure-WASM WebP decoder, ~50 KB, listed as a runtime `dependency` of
146
+ `@glandais/vcyclist-engine` and `@glandais/vcyclist-elevation`). It is loaded lazily via
147
+ `eval('require')`, so browser bundlers do not pull it into the browser build. Requires
148
+ Node ≥ 18 (`globalThis.fetch` is built-in since Node 18 / Bun) ; Node 22+ recommended for
149
+ ESM `require()` support.
150
+
125
151
  ## Build & test
126
152
 
127
153
  ```bash
@@ -158,6 +184,12 @@ vcyclist/
158
184
  GPX I/O, full physics, simulation, post-processing, `Enhancer`, CLI, `@JsExport` façades.
159
185
  - ✅ **Phase 2bis** — pipeline fidelity fixes (tasks 29-31) : `VirtualizeService` last-point
160
186
  timestamp, `PointPerDistance` port, integration into `Enhancer`.
187
+ - ✅ **Phase 3** — Node.js / Bun support (tasks 32-33) : runtime-detection in
188
+ `TileFetcher.js.kt` (browser path unchanged, Node path uses `globalThis.fetch` +
189
+ `@jsquash/webp` WASM decoder loaded via lazy `eval('require')`), webpack externals to keep
190
+ the browser bundle free of `@jsquash/webp`, `ElevationProvider` auto-instantiation in
191
+ `EngineJsApi.enhance` when `opts.fixElevation` is true (JS + Wasm façades), 6 jsTest classes
192
+ gated by `INTEGRATION=1`.
161
193
 
162
194
  Total `:engine` test coverage : 32 test classes / ~326 commonTest cases / 4 targets =
163
195
  ~1300 green executions, plus JVM-only smoke tests for the CLI and the full pipeline.
@@ -173,8 +205,20 @@ output points covering ~128.6 km / ~5.3 h of simulated ride.
173
205
  - [`docs/parity.md`](docs/parity.md) — TS↔Kotlin parity approach and tolerances.
174
206
  - [`docs/kotlin-wasm-jvm-webp.md`](docs/kotlin-wasm-jvm-webp.md) — Kotlin/Wasm ↔ JS interop
175
207
  guide that underpins the `@JsExport` façades and the WebP tile decoding.
208
+ - [`docs/publishing.md`](docs/publishing.md) — release flow (Maven Central + npm via
209
+ semantic-release on push to `develop`).
176
210
  - [`elevation/README.md`](elevation/README.md) — `:elevation` module details + browser demos.
177
211
 
212
+ ## Contributing
213
+
214
+ `develop` is the **default and only long-lived branch** — there is no `main`. Open PRs
215
+ against `develop` using [Conventional Commits](https://www.conventionalcommits.org/) :
216
+ `feat:` triggers a minor release, `fix:` a patch, anything else is a no-op release-wise.
217
+ Every push to `develop` runs the full multi-target test suite via
218
+ `.github/workflows/release.yml` and, if green, lets semantic-release tag a new version,
219
+ publish to Maven Central + npm, and commit the version bump back to `develop` with
220
+ `[skip ci]`. See [`docs/publishing.md`](docs/publishing.md) for the full flow.
221
+
178
222
  ## License
179
223
 
180
224
  Apache License 2.0, aligned with the upstream `gpx2web` project. See the Maven Central POM
@@ -46,6 +46,17 @@ if (typeof Array.prototype.fill === 'undefined') {
46
46
  Object.defineProperty(TypedArray.prototype, 'fill', {value: Array.prototype.fill});
47
47
  }
48
48
  });
49
+ if (typeof Math.clz32 === 'undefined') {
50
+ Math.clz32 = function (log, LN2) {
51
+ return function (x) {
52
+ var asUint = x >>> 0;
53
+ if (asUint === 0) {
54
+ return 32;
55
+ }
56
+ return 31 - (log(asUint) / LN2 | 0) | 0; // the "| 0" acts like math.floor
57
+ };
58
+ }(Math.log, Math.LN2);
59
+ }
49
60
  if (typeof Math.hypot === 'undefined') {
50
61
  Math.hypot = function () {
51
62
  var y = 0;
@@ -59,17 +70,6 @@ if (typeof Math.hypot === 'undefined') {
59
70
  return Math.sqrt(y);
60
71
  };
61
72
  }
62
- if (typeof Math.clz32 === 'undefined') {
63
- Math.clz32 = function (log, LN2) {
64
- return function (x) {
65
- var asUint = x >>> 0;
66
- if (asUint === 0) {
67
- return 32;
68
- }
69
- return 31 - (log(asUint) / LN2 | 0) | 0; // the "| 0" acts like math.floor
70
- };
71
- }(Math.log, Math.LN2);
72
- }
73
73
  //endregion
74
74
  (function (factory) {
75
75
  if (typeof define === 'function' && define.amd)
@@ -112,12 +112,12 @@ if (typeof Math.clz32 === 'undefined') {
112
112
  initMetadataForClass(AbstractCollection, 'AbstractCollection', VOID, VOID, [Collection]);
113
113
  initMetadataForClass(AbstractMutableCollection, 'AbstractMutableCollection', VOID, AbstractCollection, [Collection]);
114
114
  initMetadataForClass(IteratorImpl, 'IteratorImpl');
115
- initMetadataForClass(AbstractMutableList, 'AbstractMutableList', VOID, AbstractMutableCollection, [KtList, Collection]);
115
+ initMetadataForClass(AbstractMutableList, 'AbstractMutableList', VOID, AbstractMutableCollection, [Collection, KtList]);
116
116
  initMetadataForClass(AbstractMap, 'AbstractMap', VOID, VOID, [KtMap]);
117
117
  initMetadataForClass(AbstractMutableMap, 'AbstractMutableMap', VOID, AbstractMap, [KtMap]);
118
118
  initMetadataForClass(AbstractMutableSet, 'AbstractMutableSet', VOID, AbstractMutableCollection, [KtSet, Collection]);
119
119
  initMetadataForCompanion(Companion_2);
120
- initMetadataForClass(ArrayList, 'ArrayList', ArrayList_init_$Create$, AbstractMutableList, [KtList, Collection]);
120
+ initMetadataForClass(ArrayList, 'ArrayList', ArrayList_init_$Create$, AbstractMutableList, [Collection, KtList]);
121
121
  initMetadataForClass(HashMap, 'HashMap', HashMap_init_$Create$, AbstractMutableMap, [KtMap]);
122
122
  initMetadataForClass(HashMapKeys, 'HashMapKeys', VOID, AbstractMutableSet, [KtSet, Collection]);
123
123
  initMetadataForClass(HashMapEntrySetBase, 'HashMapEntrySetBase', VOID, AbstractMutableSet, [KtSet, Collection]);
@@ -192,6 +192,7 @@ if (typeof Math.clz32 === 'undefined') {
192
192
  initMetadataForClass(PrimitiveKClassImpl, 'PrimitiveKClassImpl', VOID, KClassImpl);
193
193
  initMetadataForObject(NothingKClassImpl, 'NothingKClassImpl', VOID, KClassImpl);
194
194
  initMetadataForClass(SimpleKClassImpl, 'SimpleKClassImpl', VOID, KClassImpl);
195
+ initMetadataForInterface(KProperty0, 'KProperty0');
195
196
  initMetadataForInterface(KProperty1, 'KProperty1');
196
197
  initMetadataForObject(PrimitiveClasses, 'PrimitiveClasses');
197
198
  initMetadataForClass(StringBuilder, 'StringBuilder', StringBuilder_init_$Create$_0, VOID, [CharSequence]);
@@ -522,12 +523,12 @@ if (typeof Math.clz32 === 'undefined') {
522
523
  }
523
524
  return optimizeReadOnlyList(toMutableList_0(_this__u8e3s4));
524
525
  }
525
- function toMutableList(_this__u8e3s4) {
526
- return ArrayList_init_$Create$_1(_this__u8e3s4);
527
- }
528
526
  function firstOrNull(_this__u8e3s4) {
529
527
  return _this__u8e3s4.n() ? null : _this__u8e3s4.m(0);
530
528
  }
529
+ function toMutableList(_this__u8e3s4) {
530
+ return ArrayList_init_$Create$_1(_this__u8e3s4);
531
+ }
531
532
  function sorted(_this__u8e3s4) {
532
533
  if (isInterface(_this__u8e3s4, Collection)) {
533
534
  if (_this__u8e3s4.l() <= 1)
@@ -3982,6 +3983,8 @@ if (typeof Math.clz32 === 'undefined') {
3982
3983
  protoOf(SimpleKClassImpl).e7 = function () {
3983
3984
  return this.l7_1;
3984
3985
  };
3986
+ function KProperty0() {
3987
+ }
3985
3988
  function KProperty1() {
3986
3989
  }
3987
3990
  function get_functionClasses() {
@@ -7877,58 +7880,60 @@ if (typeof Math.clz32 === 'undefined') {
7877
7880
  _.$_$.y4 = initMetadataForObject;
7878
7881
  _.$_$.z4 = isCharSequence;
7879
7882
  _.$_$.a5 = isInterface;
7880
- _.$_$.b5 = numberToChar;
7881
- _.$_$.c5 = numberToInt;
7882
- _.$_$.d5 = objectCreate;
7883
- _.$_$.e5 = protoOf;
7884
- _.$_$.f5 = toShort;
7885
- _.$_$.g5 = toString_1;
7886
- _.$_$.h5 = roundToInt;
7887
- _.$_$.i5 = round;
7888
- _.$_$.j5 = UIntRange;
7889
- _.$_$.k5 = coerceAtLeast;
7890
- _.$_$.l5 = coerceIn_0;
7891
- _.$_$.m5 = coerceIn;
7892
- _.$_$.n5 = downTo;
7893
- _.$_$.o5 = until;
7894
- _.$_$.p5 = getKClassFromExpression;
7895
- _.$_$.q5 = KProperty1;
7896
- _.$_$.r5 = StringBuilder;
7897
- _.$_$.s5 = concatToString;
7898
- _.$_$.t5 = indexOf_0;
7899
- _.$_$.u5 = isBlank;
7900
- _.$_$.v5 = isHighSurrogate;
7901
- _.$_$.w5 = replace;
7902
- _.$_$.x5 = substring;
7903
- _.$_$.y5 = toDoubleOrNull;
7904
- _.$_$.z5 = toInt;
7905
- _.$_$.a6 = toInt_0;
7906
- _.$_$.b6 = toLongOrNull;
7907
- _.$_$.c6 = toString_6;
7908
- _.$_$.d6 = toString_3;
7909
- _.$_$.e6 = trim;
7910
- _.$_$.f6 = Char;
7911
- _.$_$.g6 = Enum;
7912
- _.$_$.h6 = Error_0;
7913
- _.$_$.i6 = Exception;
7914
- _.$_$.j6 = IllegalArgumentException;
7915
- _.$_$.k6 = Long;
7916
- _.$_$.l6 = Pair;
7917
- _.$_$.m6 = Result;
7918
- _.$_$.n6 = RuntimeException;
7919
- _.$_$.o6 = THROW_CCE;
7920
- _.$_$.p6 = Unit;
7921
- _.$_$.q6 = UnsupportedOperationException;
7922
- _.$_$.r6 = addSuppressed;
7923
- _.$_$.s6 = createFailure;
7924
- _.$_$.t6 = ensureNotNull;
7925
- _.$_$.u6 = isNaN_0;
7926
- _.$_$.v6 = lazy;
7927
- _.$_$.w6 = noWhenBranchMatchedException;
7928
- _.$_$.x6 = stackTraceToString;
7929
- _.$_$.y6 = throwOnFailure;
7930
- _.$_$.z6 = toString_0;
7931
- _.$_$.a7 = uintCompare;
7883
+ _.$_$.b5 = isNumber;
7884
+ _.$_$.c5 = numberToChar;
7885
+ _.$_$.d5 = numberToInt;
7886
+ _.$_$.e5 = objectCreate;
7887
+ _.$_$.f5 = protoOf;
7888
+ _.$_$.g5 = toShort;
7889
+ _.$_$.h5 = toString_1;
7890
+ _.$_$.i5 = roundToInt;
7891
+ _.$_$.j5 = round;
7892
+ _.$_$.k5 = UIntRange;
7893
+ _.$_$.l5 = coerceAtLeast;
7894
+ _.$_$.m5 = coerceIn_0;
7895
+ _.$_$.n5 = coerceIn;
7896
+ _.$_$.o5 = downTo;
7897
+ _.$_$.p5 = until;
7898
+ _.$_$.q5 = getKClassFromExpression;
7899
+ _.$_$.r5 = KProperty0;
7900
+ _.$_$.s5 = KProperty1;
7901
+ _.$_$.t5 = StringBuilder;
7902
+ _.$_$.u5 = concatToString;
7903
+ _.$_$.v5 = indexOf_0;
7904
+ _.$_$.w5 = isBlank;
7905
+ _.$_$.x5 = isHighSurrogate;
7906
+ _.$_$.y5 = replace;
7907
+ _.$_$.z5 = substring;
7908
+ _.$_$.a6 = toDoubleOrNull;
7909
+ _.$_$.b6 = toInt;
7910
+ _.$_$.c6 = toInt_0;
7911
+ _.$_$.d6 = toLongOrNull;
7912
+ _.$_$.e6 = toString_6;
7913
+ _.$_$.f6 = toString_3;
7914
+ _.$_$.g6 = trim;
7915
+ _.$_$.h6 = Char;
7916
+ _.$_$.i6 = Enum;
7917
+ _.$_$.j6 = Error_0;
7918
+ _.$_$.k6 = Exception;
7919
+ _.$_$.l6 = IllegalArgumentException;
7920
+ _.$_$.m6 = Long;
7921
+ _.$_$.n6 = Pair;
7922
+ _.$_$.o6 = Result;
7923
+ _.$_$.p6 = RuntimeException;
7924
+ _.$_$.q6 = THROW_CCE;
7925
+ _.$_$.r6 = Unit;
7926
+ _.$_$.s6 = UnsupportedOperationException;
7927
+ _.$_$.t6 = addSuppressed;
7928
+ _.$_$.u6 = createFailure;
7929
+ _.$_$.v6 = ensureNotNull;
7930
+ _.$_$.w6 = isNaN_0;
7931
+ _.$_$.x6 = lazy;
7932
+ _.$_$.y6 = noWhenBranchMatchedException;
7933
+ _.$_$.z6 = stackTraceToString;
7934
+ _.$_$.a7 = throwOnFailure;
7935
+ _.$_$.b7 = toString_0;
7936
+ _.$_$.c7 = uintCompare;
7932
7937
  //endregion
7933
7938
  return _;
7934
7939
  }));