@glandais/vcyclist-elevation 1.0.0 → 1.1.0

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.
@@ -110,16 +110,16 @@ if (typeof Math.hypot === 'undefined') {
110
110
  initMetadataForClass(AbstractCollection, 'AbstractCollection', VOID, VOID, [Collection]);
111
111
  initMetadataForClass(AbstractMutableCollection, 'AbstractMutableCollection', VOID, AbstractCollection, [Collection]);
112
112
  initMetadataForClass(IteratorImpl, 'IteratorImpl');
113
- initMetadataForClass(AbstractMutableList, 'AbstractMutableList', VOID, AbstractMutableCollection, [KtList, Collection]);
113
+ initMetadataForClass(AbstractMutableList, 'AbstractMutableList', VOID, AbstractMutableCollection, [Collection, KtList]);
114
114
  initMetadataForClass(AbstractMap, 'AbstractMap', VOID, VOID, [KtMap]);
115
115
  initMetadataForClass(AbstractMutableMap, 'AbstractMutableMap', VOID, AbstractMap, [KtMap]);
116
- initMetadataForClass(AbstractMutableSet, 'AbstractMutableSet', VOID, AbstractMutableCollection, [KtSet, Collection]);
116
+ initMetadataForClass(AbstractMutableSet, 'AbstractMutableSet', VOID, AbstractMutableCollection, [Collection, KtSet]);
117
117
  initMetadataForCompanion(Companion_1);
118
- initMetadataForClass(ArrayList, 'ArrayList', ArrayList_init_$Create$, AbstractMutableList, [KtList, Collection]);
118
+ initMetadataForClass(ArrayList, 'ArrayList', ArrayList_init_$Create$, AbstractMutableList, [Collection, KtList]);
119
119
  initMetadataForClass(HashMap, 'HashMap', HashMap_init_$Create$, AbstractMutableMap, [KtMap]);
120
- initMetadataForClass(HashMapEntrySetBase, 'HashMapEntrySetBase', VOID, AbstractMutableSet, [KtSet, Collection]);
120
+ initMetadataForClass(HashMapEntrySetBase, 'HashMapEntrySetBase', VOID, AbstractMutableSet, [Collection, KtSet]);
121
121
  initMetadataForClass(HashMapEntrySet, 'HashMapEntrySet', VOID, HashMapEntrySetBase);
122
- initMetadataForClass(HashSet, 'HashSet', HashSet_init_$Create$, AbstractMutableSet, [KtSet, Collection]);
122
+ initMetadataForClass(HashSet, 'HashSet', HashSet_init_$Create$, AbstractMutableSet, [Collection, KtSet]);
123
123
  initMetadataForCompanion(Companion_2);
124
124
  initMetadataForClass(Itr, 'Itr');
125
125
  initMetadataForClass(KeysItr, 'KeysItr', VOID, Itr);
@@ -163,7 +163,7 @@ if (typeof Math.hypot === 'undefined') {
163
163
  initMetadataForInterface(InternalMap, 'InternalMap');
164
164
  initMetadataForClass(InternalHashMap, 'InternalHashMap', InternalHashMap_init_$Create$, VOID, [InternalMap]);
165
165
  initMetadataForClass(LinkedHashMap, 'LinkedHashMap', LinkedHashMap_init_$Create$, HashMap, [KtMap]);
166
- initMetadataForClass(LinkedHashSet, 'LinkedHashSet', LinkedHashSet_init_$Create$, HashSet, [KtSet, Collection]);
166
+ initMetadataForClass(LinkedHashSet, 'LinkedHashSet', LinkedHashSet_init_$Create$, HashSet, [Collection, KtSet]);
167
167
  initMetadataForInterface(Continuation, 'Continuation');
168
168
  initMetadataForClass(InterceptedCoroutine, 'InterceptedCoroutine', VOID, VOID, [Continuation]);
169
169
  initMetadataForClass(CoroutineImpl, 'CoroutineImpl', VOID, InterceptedCoroutine, [Continuation]);
@@ -186,6 +186,7 @@ if (typeof Math.hypot === 'undefined') {
186
186
  initMetadataForClass(PrimitiveKClassImpl, 'PrimitiveKClassImpl', VOID, KClassImpl);
187
187
  initMetadataForObject(NothingKClassImpl, 'NothingKClassImpl', VOID, KClassImpl);
188
188
  initMetadataForClass(SimpleKClassImpl, 'SimpleKClassImpl', VOID, KClassImpl);
189
+ initMetadataForInterface(KProperty0, 'KProperty0');
189
190
  initMetadataForObject(PrimitiveClasses, 'PrimitiveClasses');
190
191
  initMetadataForClass(StringBuilder, 'StringBuilder', StringBuilder_init_$Create$_0, VOID, [CharSequence]);
191
192
  initMetadataForCompanion(Companion_3);
@@ -267,6 +268,8 @@ if (typeof Math.hypot === 'undefined') {
267
268
  initMetadataForObject(State, 'State');
268
269
  initMetadataForClass(LinesIterator, 'LinesIterator');
269
270
  initMetadataForClass(lineSequence$$inlined$Sequence$1);
271
+ initMetadataForClass(UnsafeLazyImpl, 'UnsafeLazyImpl');
272
+ initMetadataForObject(UNINITIALIZED_VALUE, 'UNINITIALIZED_VALUE');
270
273
  initMetadataForCompanion(Companion_10);
271
274
  initMetadataForClass(Failure, 'Failure');
272
275
  initMetadataForClass(NotImplementedError, 'NotImplementedError', NotImplementedError, Error_0);
@@ -1559,6 +1562,60 @@ if (typeof Math.hypot === 'undefined') {
1559
1562
  function numberRangeToNumber(start, endInclusive) {
1560
1563
  return new IntRange(start, endInclusive);
1561
1564
  }
1565
+ function get_propertyRefClassMetadataCache() {
1566
+ _init_properties_reflectRuntime_kt__5r4uu3();
1567
+ return propertyRefClassMetadataCache;
1568
+ }
1569
+ var propertyRefClassMetadataCache;
1570
+ function metadataObject() {
1571
+ _init_properties_reflectRuntime_kt__5r4uu3();
1572
+ return createMetadata('class', VOID, VOID, VOID, VOID, VOID);
1573
+ }
1574
+ function getPropertyCallableRef(name, paramCount, superType, getter, setter, linkageError) {
1575
+ _init_properties_reflectRuntime_kt__5r4uu3();
1576
+ getter.get = getter;
1577
+ getter.set = setter;
1578
+ getter.callableName = name;
1579
+ // Inline function 'kotlin.js.unsafeCast' call
1580
+ return getPropertyRefClass(getter, getKPropMetadata(paramCount, setter), superType);
1581
+ }
1582
+ function getPropertyRefClass(obj, metadata, superType) {
1583
+ _init_properties_reflectRuntime_kt__5r4uu3();
1584
+ obj.$metadata$ = metadata;
1585
+ obj.constructor = obj;
1586
+ var symbol = superType.Symbol;
1587
+ if (symbol != null) {
1588
+ // Inline function 'kotlin.js.asDynamic' call
1589
+ obj[symbol] = true;
1590
+ }
1591
+ Object.assign(obj, superType.prototype);
1592
+ return obj;
1593
+ }
1594
+ function getKPropMetadata(paramCount, setter) {
1595
+ _init_properties_reflectRuntime_kt__5r4uu3();
1596
+ return get_propertyRefClassMetadataCache()[paramCount][setter == null ? 0 : 1];
1597
+ }
1598
+ var properties_initialized_reflectRuntime_kt_inkhwd;
1599
+ function _init_properties_reflectRuntime_kt__5r4uu3() {
1600
+ if (!properties_initialized_reflectRuntime_kt_inkhwd) {
1601
+ properties_initialized_reflectRuntime_kt_inkhwd = true;
1602
+ // Inline function 'kotlin.arrayOf' call
1603
+ // Inline function 'kotlin.js.unsafeCast' call
1604
+ // Inline function 'kotlin.js.asDynamic' call
1605
+ var tmp = [metadataObject(), metadataObject()];
1606
+ // Inline function 'kotlin.arrayOf' call
1607
+ // Inline function 'kotlin.js.unsafeCast' call
1608
+ // Inline function 'kotlin.js.asDynamic' call
1609
+ var tmp_0 = [metadataObject(), metadataObject()];
1610
+ // Inline function 'kotlin.arrayOf' call
1611
+ // Inline function 'kotlin.js.unsafeCast' call
1612
+ // Inline function 'kotlin.js.asDynamic' call
1613
+ // Inline function 'kotlin.arrayOf' call
1614
+ // Inline function 'kotlin.js.unsafeCast' call
1615
+ // Inline function 'kotlin.js.asDynamic' call
1616
+ propertyRefClassMetadataCache = [tmp, tmp_0, [metadataObject(), metadataObject()]];
1617
+ }
1618
+ }
1562
1619
  function isArrayish(o) {
1563
1620
  return isJsArray(o) || isView(o);
1564
1621
  }
@@ -3173,6 +3230,9 @@ if (typeof Math.hypot === 'undefined') {
3173
3230
  function ClassCastException() {
3174
3231
  captureStack(this, ClassCastException);
3175
3232
  }
3233
+ function lazy(initializer) {
3234
+ return new UnsafeLazyImpl(initializer);
3235
+ }
3176
3236
  function fillFrom(src, dst) {
3177
3237
  var srcLen = src.length;
3178
3238
  var dstLen = dst.length;
@@ -3301,6 +3361,8 @@ if (typeof Math.hypot === 'undefined') {
3301
3361
  protoOf(SimpleKClassImpl).k6 = function () {
3302
3362
  return this.r6_1;
3303
3363
  };
3364
+ function KProperty0() {
3365
+ }
3304
3366
  function get_functionClasses() {
3305
3367
  _init_properties_primitives_kt__3fums4();
3306
3368
  return functionClasses;
@@ -5348,6 +5410,29 @@ if (typeof Math.hypot === 'undefined') {
5348
5410
  protoOf(lineSequence$$inlined$Sequence$1).g = function () {
5349
5411
  return new LinesIterator(this.r9_1);
5350
5412
  };
5413
+ function UnsafeLazyImpl(initializer) {
5414
+ this.s9_1 = initializer;
5415
+ this.t9_1 = UNINITIALIZED_VALUE_instance;
5416
+ }
5417
+ protoOf(UnsafeLazyImpl).r = function () {
5418
+ if (this.t9_1 === UNINITIALIZED_VALUE_instance) {
5419
+ this.t9_1 = ensureNotNull(this.s9_1)();
5420
+ this.s9_1 = null;
5421
+ }
5422
+ return this.t9_1;
5423
+ };
5424
+ protoOf(UnsafeLazyImpl).u9 = function () {
5425
+ return !(this.t9_1 === UNINITIALIZED_VALUE_instance);
5426
+ };
5427
+ protoOf(UnsafeLazyImpl).toString = function () {
5428
+ return this.u9() ? toString_0(this.r()) : 'Lazy value not initialized yet.';
5429
+ };
5430
+ function UNINITIALIZED_VALUE() {
5431
+ }
5432
+ var UNINITIALIZED_VALUE_instance;
5433
+ function UNINITIALIZED_VALUE_getInstance() {
5434
+ return UNINITIALIZED_VALUE_instance;
5435
+ }
5351
5436
  function _Result___init__impl__xyqfz8(value) {
5352
5437
  return value;
5353
5438
  }
@@ -5361,7 +5446,7 @@ if (typeof Math.hypot === 'undefined') {
5361
5446
  function Result__exceptionOrNull_impl_p6xea9($this) {
5362
5447
  var tmp;
5363
5448
  if (_Result___get_value__impl__bjfvqg($this) instanceof Failure) {
5364
- tmp = _Result___get_value__impl__bjfvqg($this).s9_1;
5449
+ tmp = _Result___get_value__impl__bjfvqg($this).v9_1;
5365
5450
  } else {
5366
5451
  tmp = null;
5367
5452
  }
@@ -5374,22 +5459,22 @@ if (typeof Math.hypot === 'undefined') {
5374
5459
  return Companion_instance_10;
5375
5460
  }
5376
5461
  function Failure(exception) {
5377
- this.s9_1 = exception;
5462
+ this.v9_1 = exception;
5378
5463
  }
5379
5464
  protoOf(Failure).equals = function (other) {
5380
5465
  var tmp;
5381
5466
  if (other instanceof Failure) {
5382
- tmp = equals(this.s9_1, other.s9_1);
5467
+ tmp = equals(this.v9_1, other.v9_1);
5383
5468
  } else {
5384
5469
  tmp = false;
5385
5470
  }
5386
5471
  return tmp;
5387
5472
  };
5388
5473
  protoOf(Failure).hashCode = function () {
5389
- return hashCode_0(this.s9_1);
5474
+ return hashCode_0(this.v9_1);
5390
5475
  };
5391
5476
  protoOf(Failure).toString = function () {
5392
- return 'Failure(' + this.s9_1.toString() + ')';
5477
+ return 'Failure(' + this.v9_1.toString() + ')';
5393
5478
  };
5394
5479
  function createFailure(exception) {
5395
5480
  return new Failure(exception);
@@ -5419,6 +5504,7 @@ if (typeof Math.hypot === 'undefined') {
5419
5504
  Key_instance = new Key();
5420
5505
  Companion_instance_9 = new Companion_9();
5421
5506
  State_instance = new State();
5507
+ UNINITIALIZED_VALUE_instance = new UNINITIALIZED_VALUE();
5422
5508
  Companion_instance_10 = new Companion_10();
5423
5509
  //endregion
5424
5510
  //region block: exports
@@ -5502,41 +5588,45 @@ if (typeof Math.hypot === 'undefined') {
5502
5588
  _.$_$.y2 = equals;
5503
5589
  _.$_$.z2 = getBooleanHashCode;
5504
5590
  _.$_$.a3 = getNumberHashCode;
5505
- _.$_$.b3 = getStringHashCode;
5506
- _.$_$.c3 = hashCode_0;
5507
- _.$_$.d3 = initMetadataForClass;
5508
- _.$_$.e3 = initMetadataForCompanion;
5509
- _.$_$.f3 = initMetadataForCoroutine;
5510
- _.$_$.g3 = initMetadataForFunctionReference;
5511
- _.$_$.h3 = initMetadataForInterface;
5512
- _.$_$.i3 = initMetadataForLambda;
5513
- _.$_$.j3 = initMetadataForObject;
5514
- _.$_$.k3 = isInterface;
5515
- _.$_$.l3 = numberToInt;
5516
- _.$_$.m3 = objectCreate;
5517
- _.$_$.n3 = protoOf;
5518
- _.$_$.o3 = toString_1;
5519
- _.$_$.p3 = round;
5520
- _.$_$.q3 = coerceIn;
5521
- _.$_$.r3 = coerceIn_0;
5522
- _.$_$.s3 = getKClassFromExpression;
5523
- _.$_$.t3 = replace;
5524
- _.$_$.u3 = toLongOrNull;
5525
- _.$_$.v3 = Enum;
5526
- _.$_$.w3 = Error_0;
5527
- _.$_$.x3 = Exception;
5528
- _.$_$.y3 = Long;
5529
- _.$_$.z3 = RuntimeException;
5530
- _.$_$.a4 = THROW_CCE;
5531
- _.$_$.b4 = Unit;
5532
- _.$_$.c4 = UnsupportedOperationException;
5533
- _.$_$.d4 = addSuppressed;
5534
- _.$_$.e4 = createFailure;
5535
- _.$_$.f4 = ensureNotNull;
5536
- _.$_$.g4 = isNaN_0;
5537
- _.$_$.h4 = noWhenBranchMatchedException;
5538
- _.$_$.i4 = stackTraceToString;
5539
- _.$_$.j4 = toString_0;
5591
+ _.$_$.b3 = getPropertyCallableRef;
5592
+ _.$_$.c3 = getStringHashCode;
5593
+ _.$_$.d3 = hashCode_0;
5594
+ _.$_$.e3 = initMetadataForClass;
5595
+ _.$_$.f3 = initMetadataForCompanion;
5596
+ _.$_$.g3 = initMetadataForCoroutine;
5597
+ _.$_$.h3 = initMetadataForFunctionReference;
5598
+ _.$_$.i3 = initMetadataForInterface;
5599
+ _.$_$.j3 = initMetadataForLambda;
5600
+ _.$_$.k3 = initMetadataForObject;
5601
+ _.$_$.l3 = isInterface;
5602
+ _.$_$.m3 = isNumber;
5603
+ _.$_$.n3 = numberToInt;
5604
+ _.$_$.o3 = objectCreate;
5605
+ _.$_$.p3 = protoOf;
5606
+ _.$_$.q3 = toString_1;
5607
+ _.$_$.r3 = round;
5608
+ _.$_$.s3 = coerceIn;
5609
+ _.$_$.t3 = coerceIn_0;
5610
+ _.$_$.u3 = getKClassFromExpression;
5611
+ _.$_$.v3 = KProperty0;
5612
+ _.$_$.w3 = replace;
5613
+ _.$_$.x3 = toLongOrNull;
5614
+ _.$_$.y3 = Enum;
5615
+ _.$_$.z3 = Error_0;
5616
+ _.$_$.a4 = Exception;
5617
+ _.$_$.b4 = Long;
5618
+ _.$_$.c4 = RuntimeException;
5619
+ _.$_$.d4 = THROW_CCE;
5620
+ _.$_$.e4 = Unit;
5621
+ _.$_$.f4 = UnsupportedOperationException;
5622
+ _.$_$.g4 = addSuppressed;
5623
+ _.$_$.h4 = createFailure;
5624
+ _.$_$.i4 = ensureNotNull;
5625
+ _.$_$.j4 = isNaN_0;
5626
+ _.$_$.k4 = lazy;
5627
+ _.$_$.l4 = noWhenBranchMatchedException;
5628
+ _.$_$.m4 = stackTraceToString;
5629
+ _.$_$.n4 = toString_0;
5540
5630
  //endregion
5541
5631
  return _;
5542
5632
  }));