@mikrojs/native 0.12.0-next.7.g0a0155c → 0.12.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mikrojs/native",
3
- "version": "0.12.0-next.7.g0a0155c",
3
+ "version": "0.12.0",
4
4
  "description": "Mikro.js C++ runtime library and Node.js native addon",
5
5
  "keywords": [
6
6
  "esp32",
@@ -80,7 +80,7 @@
80
80
  "cmake-js": "^8.0.0",
81
81
  "node-addon-api": "^8.7.0",
82
82
  "node-gyp-build": "^4.8.4",
83
- "@mikrojs/quickjs": "0.12.0-next.7.g0a0155c"
83
+ "@mikrojs/quickjs": "0.12.0"
84
84
  },
85
85
  "devDependencies": {
86
86
  "@swc/core": "^1.15.30",
@@ -30,6 +30,17 @@ interface Suite {
30
30
  const suites: Suite[] = []
31
31
  let currentSuite: Suite | null = null
32
32
  let heapBaseline = 0
33
+ /** Free system heap (bytes) at the baseline point, or 0 on the host (no
34
+ * system heap). Reference point for the "peak" figure: baseline free minus
35
+ * the run's low-water is the most the suite needed at once. Recaptured after
36
+ * each suite's beforeAll, in step with heapBaseline, so warmup is excluded
37
+ * from the figure. */
38
+ let sysFreeStart = 0
39
+ /** Lowest free system heap (bytes) sampled (post-gc) this run, or 0 on the
40
+ * host. The suite's closest sampled approach to OOM. The module re-inits
41
+ * for each test file (fresh runtime per file), so this is a true per-file
42
+ * figure, not a process-lifetime watermark shared across files. */
43
+ let sysFreeFloor = 0
33
44
 
34
45
  /**
35
46
  * Recapture the heap baseline. Called by the harness after each suite's
@@ -43,7 +54,15 @@ let heapBaseline = 0
43
54
  async function captureHeapBaseline(): Promise<void> {
44
55
  await Promise.resolve()
45
56
  gc()
46
- heapBaseline = memoryUsage().heapUsed
57
+ const {heapUsed, systemFree} = memoryUsage()
58
+ heapBaseline = heapUsed
59
+ // Recapture the system-heap baseline and reset the per-file low-water in
60
+ // step with heapBaseline, so warmup (module loads, TLS, wifi) is excluded
61
+ // from sysUsed the same way it is from heapDelta.
62
+ if (systemFree > 0) {
63
+ sysFreeStart = systemFree
64
+ sysFreeFloor = systemFree
65
+ }
47
66
  }
48
67
 
49
68
  function newSuite(name: string, flags: {skip?: boolean; only?: boolean; todo?: boolean}): Suite {
@@ -363,6 +382,8 @@ type TestEvent =
363
382
  d: number
364
383
  hb?: number
365
384
  ha?: number
385
+ su?: number
386
+ sf?: number
366
387
  tb?: number
367
388
  ta?: number
368
389
  pb?: number
@@ -401,7 +422,10 @@ function emitHeap(): void {
401
422
  gc()
402
423
  const mem = memoryUsage()
403
424
  const evt: TestEvent = {e: 8, u: mem.heapUsed, t: mem.heapTotal}
404
- if (mem.systemFree > 0) evt.f = mem.systemFree
425
+ if (mem.systemFree > 0) {
426
+ evt.f = mem.systemFree
427
+ if (sysFreeFloor === 0 || mem.systemFree < sysFreeFloor) sysFreeFloor = mem.systemFree
428
+ }
405
429
  if (mem.systemMinFree > 0) evt.mf = mem.systemMinFree
406
430
  emit(evt)
407
431
  }
@@ -420,7 +444,14 @@ async function run(): Promise<void> {
420
444
  // warmup costs (module loads, TLS lazy-init, wifi connection) get
421
445
  // folded into the baseline automatically.
422
446
  gc()
423
- heapBaseline = memoryUsage().heapUsed
447
+ // Destructure to primitives so the live memoryUsage() object isn't held
448
+ // while heapBaseline is captured (it would otherwise be counted in it).
449
+ const {heapUsed: startHeap, systemFree: startFree} = memoryUsage()
450
+ heapBaseline = startHeap
451
+ if (startFree > 0) {
452
+ sysFreeStart = startFree
453
+ sysFreeFloor = startFree
454
+ }
424
455
  const timersBefore = activeTimers()
425
456
  const pendingBefore = pendingHttpCount()
426
457
 
@@ -569,11 +600,23 @@ async function run(): Promise<void> {
569
600
  }
570
601
 
571
602
  gc()
572
- const heapAfter = memoryUsage().heapUsed
603
+ // Destructure to primitives (see baseline capture above) so the live
604
+ // memoryUsage() object isn't held while we build the run_done event.
605
+ const {heapUsed: heapAfter, systemFree: endFree} = memoryUsage()
606
+ if (endFree > 0 && (sysFreeFloor === 0 || endFree < sysFreeFloor)) {
607
+ sysFreeFloor = endFree
608
+ }
573
609
  const timersAfter = activeTimers()
574
610
  const pendingAfter = pendingHttpCount()
575
611
 
576
- emit({
612
+ // Per-file system-heap figures. sysFreeFloor is the lowest free heap we
613
+ // sampled (post-gc) this run; sysUsed is how far free heap fell from the
614
+ // baseline to that low. They sum back to the baseline free, so "peak" and
615
+ // "min free" read as one story. Samples are taken between tests, so a
616
+ // transient peak inside a single test can dip below what sysFreeFloor saw.
617
+ const sysUsed = sysFreeStart > sysFreeFloor ? sysFreeStart - sysFreeFloor : 0
618
+
619
+ const doneEvt: TestEvent = {
577
620
  e: 6,
578
621
  p: passed,
579
622
  f: failed,
@@ -586,7 +629,12 @@ async function run(): Promise<void> {
586
629
  ta: timersAfter,
587
630
  pb: pendingBefore,
588
631
  pa: pendingAfter,
589
- })
632
+ }
633
+ if (sysFreeStart > 0) {
634
+ doneEvt.su = sysUsed
635
+ doneEvt.sf = sysFreeFloor
636
+ }
637
+ emit(doneEvt)
590
638
 
591
639
  // Signal the supervisor (if any) that this file is complete so it can
592
640
  // swap in the next runtime. No-op in non-test-harness contexts.