@mikrojs/native 0.0.7

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.
Files changed (109) hide show
  1. package/CMakeLists.txt +198 -0
  2. package/LICENSE +21 -0
  3. package/README.md +49 -0
  4. package/cmake/mikrojs_bytecode.cmake +146 -0
  5. package/cmake.js +22 -0
  6. package/dist/index.d.ts +52 -0
  7. package/dist/index.d.ts.map +1 -0
  8. package/dist/index.js +132 -0
  9. package/dist/index.js.map +1 -0
  10. package/dist/types.d.ts +43 -0
  11. package/dist/types.d.ts.map +1 -0
  12. package/dist/types.js +2 -0
  13. package/dist/types.js.map +1 -0
  14. package/include/byteorder_apple.h +11 -0
  15. package/include/byteorder_windows.h +12 -0
  16. package/include/mikrojs/cbor_helpers.h +24 -0
  17. package/include/mikrojs/cutils_wrap.h +59 -0
  18. package/include/mikrojs/errors.h +144 -0
  19. package/include/mikrojs/mem.h +11 -0
  20. package/include/mikrojs/mik_color.h +32 -0
  21. package/include/mikrojs/mikrojs.h +331 -0
  22. package/include/mikrojs/platform.h +82 -0
  23. package/include/mikrojs/private.h +281 -0
  24. package/include/mikrojs/utils.h +125 -0
  25. package/package.json +100 -0
  26. package/prebuilds/darwin-arm64/mikrojs.napi.node +0 -0
  27. package/prebuilds/linux-arm64/mikrojs.napi.node +0 -0
  28. package/prebuilds/linux-x64/mikrojs.napi.node +0 -0
  29. package/runtime/ble/ble.ts +231 -0
  30. package/runtime/ble/types.ts +194 -0
  31. package/runtime/ble/uuid.ts +89 -0
  32. package/runtime/ble/validators.ts +61 -0
  33. package/runtime/cbor/cbor.ts +1 -0
  34. package/runtime/cbor/types.ts +8 -0
  35. package/runtime/console/types.ts +50 -0
  36. package/runtime/env/env.ts +17 -0
  37. package/runtime/env/types.ts +12 -0
  38. package/runtime/format/types.ts +4 -0
  39. package/runtime/fs/fs.ts +93 -0
  40. package/runtime/fs/types.ts +92 -0
  41. package/runtime/globals.d.ts +87 -0
  42. package/runtime/http/helpers.ts +222 -0
  43. package/runtime/http/native.ts +151 -0
  44. package/runtime/http/request.ts +25 -0
  45. package/runtime/i2c/i2c.ts +35 -0
  46. package/runtime/i2c/types.ts +55 -0
  47. package/runtime/inspect/types.ts +10 -0
  48. package/runtime/internal.d.ts +456 -0
  49. package/runtime/kv/nvs.ts +17 -0
  50. package/runtime/kv/rtc.ts +17 -0
  51. package/runtime/kv/shared.ts +107 -0
  52. package/runtime/kv/types.ts +150 -0
  53. package/runtime/neopixel/neopixel.ts +38 -0
  54. package/runtime/neopixel/types.ts +27 -0
  55. package/runtime/pin/pin.ts +51 -0
  56. package/runtime/pin/types.ts +49 -0
  57. package/runtime/pwm/pwm.ts +32 -0
  58. package/runtime/pwm/types.ts +29 -0
  59. package/runtime/reader/reader.ts +167 -0
  60. package/runtime/reader/types.ts +34 -0
  61. package/runtime/result/native-result.node-shim.ts +44 -0
  62. package/runtime/result/result.ts +26 -0
  63. package/runtime/result/types.ts +60 -0
  64. package/runtime/schema/schema.ts +321 -0
  65. package/runtime/schema/types.ts +152 -0
  66. package/runtime/sleep/sleep.ts +14 -0
  67. package/runtime/sleep/types.ts +44 -0
  68. package/runtime/sntp/sntp.ts +54 -0
  69. package/runtime/sntp/types.ts +38 -0
  70. package/runtime/spi/spi.ts +31 -0
  71. package/runtime/spi/types.ts +42 -0
  72. package/runtime/stdio/stdio.ts +44 -0
  73. package/runtime/stdio/types.ts +22 -0
  74. package/runtime/stream/stream.ts +150 -0
  75. package/runtime/stream/types.ts +47 -0
  76. package/runtime/sys/sys.ts +90 -0
  77. package/runtime/sys/types.ts +131 -0
  78. package/runtime/test/test.ts +595 -0
  79. package/runtime/test/types.ts +97 -0
  80. package/runtime/uart/types.ts +75 -0
  81. package/runtime/uart/uart.ts +51 -0
  82. package/runtime/wifi/types.ts +156 -0
  83. package/runtime/wifi/wifi.ts +208 -0
  84. package/scripts/bundle-runtime.js +149 -0
  85. package/scripts/compare-minifiers.js +189 -0
  86. package/scripts/compile-bytecode.sh +38 -0
  87. package/scripts/copy-prebuild.js +20 -0
  88. package/scripts/generate-symbol-map.js +146 -0
  89. package/src/builtins.cpp +82 -0
  90. package/src/cutils_compat.c +38 -0
  91. package/src/eval_bytecode.cpp +42 -0
  92. package/src/fs.cpp +878 -0
  93. package/src/mem.cpp +63 -0
  94. package/src/mik_abort.cpp +160 -0
  95. package/src/mik_app_config.cpp +358 -0
  96. package/src/mik_cbor.cpp +334 -0
  97. package/src/mik_color.cpp +46 -0
  98. package/src/mik_console.cpp +422 -0
  99. package/src/mik_inspect.cpp +850 -0
  100. package/src/mik_repl.cpp +1122 -0
  101. package/src/mik_result.cpp +344 -0
  102. package/src/mik_stdio.cpp +147 -0
  103. package/src/mik_sys.cpp +239 -0
  104. package/src/mik_text_encoding.cpp +443 -0
  105. package/src/mikrojs.cpp +942 -0
  106. package/src/modules.cpp +944 -0
  107. package/src/platform_posix.cpp +134 -0
  108. package/src/timers.cpp +208 -0
  109. package/src/utils.cpp +173 -0
@@ -0,0 +1,31 @@
1
+ import * as native from 'native:spi'
2
+
3
+ import type {Result} from '../result/types.js'
4
+ import type {Spi as PlatformSpi, SpiError, SpiOptions} from './types.js'
5
+
6
+ /**
7
+ * @public
8
+ */
9
+ export class Spi implements PlatformSpi {
10
+ #native: native.Spi
11
+
12
+ constructor(hostNo: 1 | 2, options: SpiOptions) {
13
+ this.#native = new native.Spi(hostNo, options)
14
+ }
15
+
16
+ begin(): Result<void, SpiError> {
17
+ return this.#native.begin()
18
+ }
19
+
20
+ end(): Result<void, SpiError> {
21
+ return this.#native.end()
22
+ }
23
+
24
+ transfer(data: Uint8Array): Result<Uint8Array, SpiError> {
25
+ return this.#native.transfer(data)
26
+ }
27
+
28
+ write(data: Uint8Array): Result<void, SpiError> {
29
+ return this.#native.write(data)
30
+ }
31
+ }
@@ -0,0 +1,42 @@
1
+ import type {Result} from '../result/types.js'
2
+
3
+ /**
4
+ * @public
5
+ */
6
+ export interface SpiOptions {
7
+ clk: number
8
+ mosi: number
9
+ miso?: number
10
+ cs?: number
11
+ freq?: number
12
+ mode?: 0 | 1 | 2 | 3
13
+ }
14
+
15
+ export type SpiError =
16
+ | {name: 'BusInitFailed'; message: string}
17
+ | {name: 'AddDeviceFailed'; message: string}
18
+ | {name: 'NotStarted'}
19
+ | {name: 'MissingPins'}
20
+ | {name: 'TransferFailed'; message: string}
21
+ | {name: 'WriteFailed'; message: string}
22
+
23
+ /**
24
+ * @public
25
+ */
26
+ export declare const Spi: {
27
+ prototype: Spi
28
+ new (hostNo: 1 | 2, options: SpiOptions): Spi
29
+ }
30
+
31
+ /**
32
+ * @public
33
+ */
34
+ export interface Spi {
35
+ begin(): Result<void, SpiError>
36
+
37
+ end(): Result<void, SpiError>
38
+
39
+ transfer(data: Uint8Array): Result<Uint8Array, SpiError>
40
+
41
+ write(data: Uint8Array): Result<void, SpiError>
42
+ }
@@ -0,0 +1,44 @@
1
+ import * as native from 'native:stdio'
2
+
3
+ import type {StdIn, StdOut} from './types.js'
4
+
5
+ function createStdIn(nativeStdin: typeof native.stdin): StdIn {
6
+ const listeners: ((buffer: Uint8Array) => void)[] = []
7
+
8
+ function onData(chunk: Uint8Array) {
9
+ listeners.forEach((listener) => listener(chunk))
10
+ }
11
+
12
+ return {
13
+ addListener(_event: 'data', callback: (buffer: Uint8Array) => void) {
14
+ if (!listeners.includes(callback)) {
15
+ listeners.push(callback)
16
+ if (listeners.length === 1) {
17
+ nativeStdin.setHandler(onData)
18
+ }
19
+ }
20
+ },
21
+ removeListener(_event: 'data', callback: (buffer: Uint8Array) => void) {
22
+ const idx = listeners.indexOf(callback)
23
+ if (idx > -1) {
24
+ listeners.splice(idx, 1)
25
+ if (listeners.length === 0) {
26
+ nativeStdin.clearHandler()
27
+ }
28
+ }
29
+ },
30
+ read: nativeStdin.read,
31
+ }
32
+ }
33
+
34
+ function createStdOut(nativeStdout: typeof native.stdout): StdOut {
35
+ return {
36
+ write: nativeStdout.write,
37
+ flush: nativeStdout.flush,
38
+ isTTY: false,
39
+ getWindowSize: undefined,
40
+ }
41
+ }
42
+
43
+ export const stdin = createStdIn(native.stdin)
44
+ export const stdout = createStdOut(native.stdout)
@@ -0,0 +1,22 @@
1
+ export interface StdIn {
2
+ addListener(event: 'data', callback: (chunk: Uint8Array) => any): void
3
+
4
+ removeListener(event: 'data', callback: (chunk: Uint8Array) => any): void
5
+
6
+ read(): Uint8Array | undefined
7
+
8
+ setRawMode?: (rawMode: boolean) => void
9
+ }
10
+
11
+ export interface StdOut {
12
+ isTTY: boolean
13
+
14
+ write(output: string | Uint8Array): boolean
15
+
16
+ getWindowSize?: () => [width: number, height: number]
17
+
18
+ flush(): void
19
+ }
20
+
21
+ export declare const stdin: StdIn
22
+ export declare const stdout: StdOut
@@ -0,0 +1,150 @@
1
+ /**
2
+ * Minimal composable stream primitives for mikrojs.
3
+ *
4
+ * Streams are plain `AsyncIterable<T>` — no class hierarchy, no
5
+ * lockable readers, no BYOB, no queueing strategies. Transforms are
6
+ * async generator functions. Composition is function call.
7
+ *
8
+ * This is deliberately a subset of what Snell's "new-streams" proposal
9
+ * covers, adapted for the realities of QuickJS on a microcontroller:
10
+ * no fast-path promise optimizations, no sendfile-style native
11
+ * shortcuts, tight heap budget.
12
+ *
13
+ * V1 scope: enough to rewrite a modem AT channel as a one-file shim.
14
+ * Expand only when a second call site asks for it.
15
+ */
16
+
17
+ /** Decode a stream of UTF-8 byte chunks into a stream of strings. */
18
+ export async function* decodeUtf8(source: AsyncIterable<Uint8Array>): AsyncIterable<string> {
19
+ const decoder = new TextDecoder()
20
+ for await (const chunk of source) yield decoder.decode(chunk, {stream: true})
21
+ yield decoder.decode()
22
+ }
23
+
24
+ /**
25
+ * Split a stream of text into a stream of lines.
26
+ *
27
+ * The delimiter is a string (default `\n`). Partial lines that don't
28
+ * end with the delimiter in a given input chunk are held in an
29
+ * internal buffer and prepended to the next chunk's content — so
30
+ * splitting happens correctly regardless of how the underlying source
31
+ * chunks its data. If the source closes before emitting a final
32
+ * delimiter, any trailing buffered content is emitted as a final line
33
+ * (matching how Node's readline handles EOF).
34
+ *
35
+ * Empty lines (consecutive delimiters) are preserved. This matters
36
+ * for protocols that use a blank line as a separator, e.g. HTTP
37
+ * headers vs. body.
38
+ */
39
+ export async function* splitLines(
40
+ source: AsyncIterable<string>,
41
+ delimiter: string = '\n',
42
+ ): AsyncIterable<string> {
43
+ // indexOf('') returns 0 unconditionally, which would make the inner
44
+ // loop spin forever yielding empty strings. Reject at entry instead
45
+ // of hanging the event loop on a user mistake.
46
+ if (delimiter.length === 0) {
47
+ throw new RangeError('splitLines: delimiter must be non-empty')
48
+ }
49
+ let buffer = ''
50
+ for await (const chunk of source) {
51
+ buffer += chunk
52
+ let idx = buffer.indexOf(delimiter)
53
+ while (idx !== -1) {
54
+ yield buffer.slice(0, idx)
55
+ buffer = buffer.slice(idx + delimiter.length)
56
+ idx = buffer.indexOf(delimiter)
57
+ }
58
+ }
59
+ if (buffer.length > 0) yield buffer
60
+ }
61
+
62
+ /**
63
+ * Consume a stream until an item matches `predicate`, then stop.
64
+ *
65
+ * Returns both the matching item and every item that came before it.
66
+ * The matching item is NOT included in `collected` — callers who need
67
+ * it have `matched` for that. This distinction matters for protocols
68
+ * like modem AT commands where the terminator (`OK`/`ERROR`) is
69
+ * semantically different from the response body lines in between.
70
+ *
71
+ * If the stream closes before any item matches, throws `StreamClosed`
72
+ * (a plain Error with a `.name`). Callers should wrap this in their
73
+ * own Result type if they want structured error handling.
74
+ */
75
+ export async function collectUntil<T>(
76
+ source: AsyncIterable<T>,
77
+ predicate: (item: T) => boolean,
78
+ ): Promise<{matched: T; collected: T[]}> {
79
+ const collected: T[] = []
80
+ for await (const item of source) {
81
+ if (predicate(item)) {
82
+ return {matched: item, collected}
83
+ }
84
+ collected.push(item)
85
+ }
86
+ const err = new Error('Stream closed before predicate matched')
87
+ err.name = 'StreamClosed'
88
+ throw err
89
+ }
90
+
91
+ /**
92
+ * Wrap an async iterable with a total-duration timeout.
93
+ *
94
+ * The deadline starts when this function is called (not per-item).
95
+ * If the next item doesn't arrive before the deadline, the returned
96
+ * iterable throws a `TimeoutError`, and cleans up the upstream source
97
+ * by calling its `return()` method. Callers using `for await` will see
98
+ * the error propagate out of the loop.
99
+ *
100
+ * Implementation notes:
101
+ * - Promise.race with setTimeout would leak orphaned timers on the
102
+ * fast path (source wins, setTimeout's callback still fires
103
+ * eventually). We track the timer id and clearTimeout() in a finally
104
+ * around the race so fast-path calls don't accumulate pending jobs.
105
+ * - The upstream iterator is explicitly .return()'d on exit (normal,
106
+ * timeout, or consumer break) so underlying resources (UART claims,
107
+ * socket handles, ring buffers) get released.
108
+ */
109
+ export async function* withTimeout<T>(source: AsyncIterable<T>, ms: number): AsyncIterable<T> {
110
+ const deadline = Date.now() + ms
111
+ const iter = source[Symbol.asyncIterator]()
112
+ try {
113
+ while (true) {
114
+ const remaining = deadline - Date.now()
115
+ if (remaining <= 0) {
116
+ const err = new Error(`Stream did not complete within ${ms}ms`)
117
+ err.name = 'TimeoutError'
118
+ throw err
119
+ }
120
+
121
+ let timerId: ReturnType<typeof setTimeout> | undefined
122
+ let result: IteratorResult<T, unknown>
123
+ try {
124
+ result = await Promise.race([
125
+ iter.next(),
126
+ new Promise<IteratorResult<T, unknown>>((_, reject) => {
127
+ timerId = setTimeout(() => {
128
+ const err = new Error(`Stream did not complete within ${ms}ms`)
129
+ err.name = 'TimeoutError'
130
+ reject(err)
131
+ }, remaining)
132
+ }),
133
+ ])
134
+ } finally {
135
+ if (timerId !== undefined) clearTimeout(timerId)
136
+ }
137
+
138
+ if (result.done) return
139
+ yield result.value as T
140
+ }
141
+ } finally {
142
+ if (typeof iter.return === 'function') {
143
+ try {
144
+ await iter.return(undefined)
145
+ } catch {
146
+ /* swallow — upstream cleanup errors shouldn't mask ours */
147
+ }
148
+ }
149
+ }
150
+ }
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Public types for `mikrojs/stream`.
3
+ *
4
+ * The runtime implementation lives in `./stream.ts` and is compiled to
5
+ * bytecode at firmware build time. This file is the declaration-only
6
+ * surface consumed by the `mikrojs/stream` re-export in
7
+ * `packages/mikrojs` and by user apps via their tsconfig.
8
+ */
9
+
10
+ /** Decode a stream of UTF-8 byte chunks into a stream of strings. */
11
+ export declare function decodeUtf8(source: AsyncIterable<Uint8Array>): AsyncIterable<string>
12
+
13
+ /**
14
+ * Split a stream of text into a stream of lines on the given delimiter
15
+ * (default `\n`). Partial lines spanning chunk boundaries are buffered
16
+ * and reassembled. Empty lines between consecutive delimiters are
17
+ * preserved. Throws `RangeError` if called with an empty delimiter.
18
+ */
19
+ export declare function splitLines(
20
+ source: AsyncIterable<string>,
21
+ delimiter?: string,
22
+ ): AsyncIterable<string>
23
+
24
+ /**
25
+ * Consume a stream until an item matches `predicate`, then stop.
26
+ *
27
+ * Returns `{matched, collected}` where `collected` is every item that
28
+ * came BEFORE the match (not including the matching item). Throws an
29
+ * Error with `name === 'StreamClosed'` if the stream ends before any
30
+ * item matches.
31
+ */
32
+ export declare function collectUntil<T>(
33
+ source: AsyncIterable<T>,
34
+ predicate: (item: T) => boolean,
35
+ ): Promise<{matched: T; collected: T[]}>
36
+
37
+ /**
38
+ * Wrap an async iterable with a total-duration deadline. Throws an
39
+ * Error with `name === 'TimeoutError'` if the next item doesn't
40
+ * arrive in time. Releases the upstream iterator via `return()` on
41
+ * timeout, error, or consumer break.
42
+ */
43
+ export declare function withTimeout<T>(source: AsyncIterable<T>, ms: number): AsyncIterable<T>
44
+
45
+ /* BufferedReader lives in the sibling `mikrojs/reader` module — see
46
+ * `runtime/reader/` — so apps that only need byte-level framing can
47
+ * avoid loading the async-generator transforms above. */
@@ -0,0 +1,90 @@
1
+ import {err, ok, PanicError, type Result} from 'mikrojs/result'
2
+ import * as native from 'native:sys'
3
+
4
+ export function uptime(): {boot: number; rtc: number} {
5
+ return native.uptime()
6
+ }
7
+
8
+ export function setSystemTime(millisSinceEpoch: number): void
9
+ export function setSystemTime(date: Date): void
10
+ export function setSystemTime(dateOrMillisSinceEpoch: Date | number): void
11
+ export function setSystemTime(dateOrMillisSinceEpoch: Date | number): void {
12
+ return native.setTime(
13
+ dateOrMillisSinceEpoch instanceof Date
14
+ ? dateOrMillisSinceEpoch.getTime()
15
+ : dateOrMillisSinceEpoch,
16
+ )
17
+ }
18
+
19
+ export function memoryUsage() {
20
+ return native.memoryUsage()
21
+ }
22
+
23
+ export function jsMemoryUsage() {
24
+ return native.jsMemoryUsage()
25
+ }
26
+
27
+ export function gc() {
28
+ return native.gc()
29
+ }
30
+
31
+ export const version: string = native.version
32
+
33
+ export const board = native.board
34
+
35
+ export const firmware = native.firmware
36
+
37
+ export const deviceId: string = native.deviceId
38
+
39
+ export function restart(): never {
40
+ return native.restart() as never
41
+ }
42
+
43
+ export function exit(_exitCode?: number): never {
44
+ return native.restart() as never
45
+ }
46
+
47
+ export function panic(message: string): never {
48
+ throw new PanicError(message)
49
+ }
50
+
51
+ const buildDate = new Date(native.firmware.date)
52
+
53
+ export class MonotonicTimestamp {
54
+ readonly uptimeMs: number
55
+
56
+ private constructor(uptimeMs: number) {
57
+ this.uptimeMs = uptimeMs
58
+ }
59
+
60
+ static now(): MonotonicTimestamp {
61
+ return new MonotonicTimestamp(uptime().rtc)
62
+ }
63
+
64
+ /** Rehydrate a previously-serialized timestamp. `uptimeMs` must be a
65
+ * value that originated from `.uptimeMs` on a MonotonicTimestamp taken
66
+ * within the current RTC reset cycle; values from prior reset cycles
67
+ * will resolve to meaningless wall-clock times because the RTC counter
68
+ * reset between then and now. Callers must guard cross-reset-cycle
69
+ * misuse themselves (e.g. via a cold-boot session id). */
70
+ static fromRtcMs(uptimeMs: number): MonotonicTimestamp {
71
+ return new MonotonicTimestamp(uptimeMs)
72
+ }
73
+
74
+ /** Elapsed ms since another MonotonicTimestamp (NTP-independent) */
75
+ since(other: MonotonicTimestamp): number {
76
+ return this.uptimeMs - other.uptimeMs
77
+ }
78
+
79
+ /** Resolve to wall-clock epoch ms */
80
+ private resolveMs(): number {
81
+ const elapsed = uptime().rtc - this.uptimeMs
82
+ return Date.now() - elapsed
83
+ }
84
+
85
+ wallDate(): Result<Date, 'ClockNotSynced'> {
86
+ const date = new Date(this.resolveMs())
87
+ if (date < buildDate) return err('ClockNotSynced' as const)
88
+ return ok(date)
89
+ }
90
+ }
@@ -0,0 +1,131 @@
1
+ import type {Result} from '../result/types.js'
2
+
3
+ export interface MemoryUsage {
4
+ heapUsed: number
5
+ heapTotal: number
6
+ /** Free system heap in bytes (0 on host) */
7
+ systemFree: number
8
+ /** All-time minimum free system heap in bytes (0 on host) */
9
+ systemMinFree: number
10
+ /** Total system heap in bytes (0 on host) */
11
+ systemTotal: number
12
+ /** Largest contiguous free block in bytes (0 on host). Allocations
13
+ * larger than this fail even when `systemFree` is bigger — the gap
14
+ * between `systemLargestFree` and `systemFree` measures heap
15
+ * fragmentation. */
16
+ systemLargestFree: number
17
+ }
18
+
19
+ export interface Uptime {
20
+ /** Milliseconds since last boot (resets on deep sleep) */
21
+ readonly boot: number
22
+ /** Milliseconds from RTC clock (survives deep sleep) */
23
+ readonly rtc: number
24
+ }
25
+
26
+ export declare function uptime(): Uptime
27
+
28
+ export declare function setSystemTime(timestamp: number): void
29
+ export declare function setSystemTime(date: Date): void
30
+
31
+ export declare function memoryUsage(): MemoryUsage
32
+
33
+ /** Curated breakdown of the QuickJS engine heap — "where is memory
34
+ * going?" Use this when `memoryUsage()` tells you the heap is full
35
+ * and you want to know *what kind* of allocation dominates. Values
36
+ * are in bytes unless the field name ends in `Count`. */
37
+ export interface JsMemoryUsage {
38
+ /** Number of live JS strings */
39
+ strCount: number
40
+ /** Bytes held by live JS strings */
41
+ strSize: number
42
+ /** Number of live JS objects */
43
+ objCount: number
44
+ /** Bytes held by live JS object headers */
45
+ objSize: number
46
+ /** Number of object properties across all live objects */
47
+ propCount: number
48
+ /** Bytes held by property slots */
49
+ propSize: number
50
+ /** Number of distinct object shapes (hidden classes) */
51
+ shapeCount: number
52
+ /** Bytes held by shape descriptors */
53
+ shapeSize: number
54
+ /** Number of compiled JS functions in memory */
55
+ jsFuncCount: number
56
+ /** Bytes of compiled JS bytecode in memory (usually the biggest
57
+ * contributor to QuickJS heap on an mikrojs app) */
58
+ jsFuncCodeSize: number
59
+ /** Number of live arrays (fast + slow) */
60
+ arrayCount: number
61
+ /** Total element slots across all fast arrays */
62
+ fastArrayElements: number
63
+ /** Bytes of backing storage for ArrayBuffer / TypedArray data */
64
+ binaryObjectSize: number
65
+ }
66
+
67
+ export declare function jsMemoryUsage(): JsMemoryUsage
68
+
69
+ export declare function gc(): void
70
+
71
+ /** Firmware version string (e.g. "0.1.0") */
72
+ export declare const version: string
73
+
74
+ export interface BoardInfo {
75
+ /** Board name from the firmware build (e.g. "xiao-esp32c6") or "generic" */
76
+ name: string
77
+ /** Chip target (e.g. "esp32c6") or "host" */
78
+ chip: string
79
+ /** Number of CPU cores */
80
+ cores: number
81
+ /** Silicon revision (major * 100 + minor on ESP32, 0 on host) */
82
+ revision: number
83
+ /** Supported features (e.g. ["wifi", "ble"]) */
84
+ features: string[]
85
+ /** Flash size in bytes (0 on host) */
86
+ flash: number
87
+ /** PSRAM size in bytes (0 if unavailable) */
88
+ psram: number
89
+ }
90
+
91
+ /** Board and hardware info */
92
+ export declare const board: BoardInfo
93
+
94
+ /** Unique device identifier encoded as Crockford's Base32 (10 lowercase
95
+ * characters, no special symbols). On ESP32, derived from the chip's
96
+ * base MAC address; the encoding is lossless so decoding the 10 chars
97
+ * yields the original 6 MAC bytes. On host/Node builds, derived from
98
+ * the hostname via FNV-1a hash (stable across restarts on the same
99
+ * machine). */
100
+ export declare const deviceId: string
101
+
102
+ /** Firmware build identifiers */
103
+ export declare const firmware: {
104
+ /** ELF SHA256 hash on ESP32, "dev" on host */
105
+ readonly hash: string
106
+ /** Build date and time */
107
+ readonly date: string
108
+ /** ESP-IDF version, undefined on host */
109
+ readonly idfVersion: string | undefined
110
+ }
111
+
112
+ export declare function restart(): never
113
+
114
+ export declare function exit(exitCode?: number): never
115
+
116
+ /** Immediately crash with an error message. Use for unrecoverable situations. */
117
+ export declare function panic(message: string): never
118
+
119
+ export declare class MonotonicTimestamp {
120
+ readonly uptimeMs: number
121
+ private constructor(uptimeMs: number)
122
+ static now(): MonotonicTimestamp
123
+ /** Rehydrate a previously-serialized timestamp. The `uptimeMs` value
124
+ * must come from the current RTC reset cycle; values from prior reset
125
+ * cycles will resolve to meaningless wall-clock times. */
126
+ static fromRtcMs(uptimeMs: number): MonotonicTimestamp
127
+ /** Elapsed ms since another MonotonicTimestamp (NTP-independent) */
128
+ since(other: MonotonicTimestamp): number
129
+ /** Resolve to a Date. Returns err if the system clock is clearly not synced. */
130
+ wallDate(): Result<Date, 'ClockNotSynced'>
131
+ }