@mikrojs/native 0.21.1-next.20260928214050 → 0.22.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/CMakeLists.txt CHANGED
@@ -46,6 +46,7 @@ set(MIKROJS_CORE_SOURCES
46
46
  src/mik_wifi_client.cpp
47
47
  src/mik_cbor.cpp
48
48
  src/mik_schema.cpp
49
+ src/mik_test.cpp
49
50
  src/mik_result.cpp
50
51
  src/mik_console.cpp
51
52
  src/mik_sys.cpp
@@ -244,6 +245,7 @@ if(BUILD_TESTING)
244
245
  test/sys_codec_test.cpp
245
246
  test/watchdog_test.cpp
246
247
  test/gpio_claim_test.cpp
248
+ test/test_runner_test.cpp
247
249
  )
248
250
 
249
251
  # ── Check-in wire fixtures ───────────────────────────────────────
@@ -100,6 +100,12 @@ typedef struct MIKPlatform {
100
100
  * "unknown". The returned pointer must remain valid for the lifetime
101
101
  * of the platform. */
102
102
  const char* (*get_reset_reason)(void);
103
+ /** Bring up the TCP/IP stack if the platform has one that starts on
104
+ * demand. Called before a networking module creates its first socket;
105
+ * idempotent. NULL where sockets need no setup (hosts). On ESP32 the
106
+ * stack otherwise starts only as a side effect of the wifi or http
107
+ * module loading, and lwip aborts on a socket call before that. */
108
+ void (*net_init)(void);
103
109
  } MIKPlatform;
104
110
 
105
111
  /* Log levels (matching ESP-IDF ESP_LOG_xxx values) */
@@ -220,8 +220,12 @@ struct MIKRuntime {
220
220
  void mik__pub_fs_register(JSContext* ctx);
221
221
  void mik__stdio_init(JSContext* ctx, JSValue ns);
222
222
  void mik__sys_api_init(JSContext* ctx, JSValue ns);
223
- /* Board name of this build: MIK_BOARD_NAME if defined, else "<chip>-generic"
224
- * on device, "generic" on host. Static storage, never NULL. */
223
+ /* Name of this build: MIK_BOARD_NAME if defined, else "<chip>-generic" on
224
+ * device, "generic" on host. Static storage, never NULL. */
225
+ const char* mik__firmware_name(void);
226
+ /* The board: the name `mikro flash` wrote into the image when it flashed the
227
+ * generic firmware for a board, else mik__firmware_name(). Static storage,
228
+ * never NULL. */
225
229
  const char* mik__board_name(void);
226
230
  void mik__text_encoding_init(JSContext* ctx, JSValue global);
227
231
  /* UTF-8 pass shared by TextDecoder and the http body drain: each invalid byte
@@ -344,6 +348,9 @@ JSModuleDef* mik__observable_operators_load(JSContext* ctx);
344
348
  int mik__observable_multicast_new(JSContext* ctx, JSValue* observable, JSValue* next,
345
349
  JSValue* complete);
346
350
 
351
+ /* Test runner module (mik_test.cpp): mikro/test, C-module table in modules.cpp. */
352
+ JSModuleDef* mik__test_load(JSContext* ctx);
353
+
347
354
  /* Watchdog (mik_watchdog.cpp). */
348
355
  /* Start a fresh blocking budget: top of each MIK_Loop pass, eval entry
349
356
  * points, REPL eval, and on return from a deliberately blocking native
@@ -11,19 +11,24 @@
11
11
  struct AssertionInfo {
12
12
  const char* file_line; // filename:line
13
13
  const char* message;
14
- const char* function;
15
14
  };
16
15
 
17
- #define ERROR_AND_ABORT(expr) \
18
- do { \
19
- static const struct AssertionInfo args = {__FILE__ ":" STRINGIFY(__LINE__), #expr, \
20
- PRETTY_FUNCTION_NAME}; \
21
- mik_assert(args); \
16
+ /* Base name only: __FILE__ would put the build machine's absolute path in flash at every
17
+ * call site. */
18
+ #ifdef __FILE_NAME__
19
+ #define MIK__FILE_NAME __FILE_NAME__
20
+ #else
21
+ #define MIK__FILE_NAME __FILE__
22
+ #endif
23
+
24
+ #define ERROR_AND_ABORT(expr) \
25
+ do { \
26
+ static const struct AssertionInfo args = {MIK__FILE_NAME ":" STRINGIFY(__LINE__), #expr}; \
27
+ mik_assert(args); \
22
28
  } while (0)
23
29
 
24
30
  #define MIK__LIKELY(expr) __builtin_expect(!!(expr), 1)
25
31
  #define MIK__UNLIKELY(expr) __builtin_expect(!!(expr), 0)
26
- #define PRETTY_FUNCTION_NAME __PRETTY_FUNCTION__
27
32
 
28
33
  #define STRINGIFY_(x) #x
29
34
  #define STRINGIFY(x) STRINGIFY_(x)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mikrojs/native",
3
- "version": "0.21.1-next.20260928214050",
3
+ "version": "0.22.0",
4
4
  "description": "Mikro.js C++ runtime library and Node.js native addon",
5
5
  "keywords": [
6
6
  "esp32",
@@ -86,14 +86,14 @@
86
86
  "./runtime/wifi/types": "./runtime/wifi/types.ts"
87
87
  },
88
88
  "dependencies": {
89
- "@mikrojs/quickjs": "0.21.1-next.20260928214050+4d8353a",
89
+ "@mikrojs/quickjs": "0.22.0",
90
90
  "cmake-js": "^8.0.0",
91
91
  "node-addon-api": "^8.9.2",
92
92
  "node-gyp-build": "^4.8.4"
93
93
  },
94
94
  "devDependencies": {
95
- "@mikrojs/registry": "0.21.1-next.20260928214050+4d8353a",
96
- "@mikrojs/schema": "0.21.1-next.20260928214050+4d8353a",
95
+ "@mikrojs/registry": "0.22.0",
96
+ "@mikrojs/schema": "0.22.0",
97
97
  "@swc/core": "^1.16.2",
98
98
  "@types/node": "^24.12.2",
99
99
  "esbuild": "^0.28.2",
@@ -23,7 +23,6 @@
23
23
  {"name": "stdio"},
24
24
  {"name": "stream"},
25
25
  {"name": "sys"},
26
- {"name": "test"},
27
26
  {"name": "udp"},
28
27
  {"name": "watchdog"},
29
28
  {"name": "ble", "native": "ble", "feature": "ble", "when": "ble"},
@@ -38,6 +37,7 @@
38
37
  {"name": "http/helpers", "bytecode": false},
39
38
  {"name": "observable/operators", "bytecode": false},
40
39
  {"name": "inspect", "bytecode": false},
40
+ {"name": "test", "bytecode": false},
41
41
  {"name": "wifi", "bytecode": false, "native": "wifi", "feature": "wifi", "when": "wifi"}
42
42
  ]
43
43
  }
@@ -98,8 +98,9 @@ export declare const version: string
98
98
  export type BoardFeature = 'wifi' | 'ble' | 'bt' | 'ieee802154'
99
99
 
100
100
  export interface BoardInfo {
101
- /** Board name from the firmware build (e.g. "xiao-esp32c6"). A build for no
102
- * particular board is "<chip>-generic" (e.g. "esp32c6-generic"). */
101
+ /** The board (e.g. "@acme/devboard"). The generic firmware reports
102
+ * "<chip>-generic" (e.g. "esp32c6-generic"), or the name of the board it was
103
+ * flashed for. */
103
104
  name: string
104
105
  /** Chip target (e.g. "esp32c6") or "host" */
105
106
  chip: string
@@ -148,6 +149,8 @@ export declare function setDeviceName(value: DeviceName): void
148
149
 
149
150
  /** Firmware build identifiers */
150
151
  export declare const firmware: {
152
+ /** The build (e.g. "esp32c6-generic", "@acme/devboard") */
153
+ readonly name: string
151
154
  /** ELF SHA256 hash on ESP32, "dev" on host */
152
155
  readonly hash: string
153
156
  /** Build date and time */
package/src/mik_repl.cpp CHANGED
@@ -927,8 +927,9 @@ static std::vector<uint8_t> proto_complete(JSContext* ctx, const char* partial,
927
927
  * lists the registered C modules outside the core namespace (package native
928
928
  * modules compiled in, e.g. "@mikrojs/drivers/sh8601"; empty on a generic
929
929
  * build), so the host can refuse an app importing one this firmware lacks.
930
- * `fw` is the firmware identity: the board name the build set (MIK_BOARD_NAME),
931
- * which `board` also reports. The host only auto-flashes its bundled image over
930
+ * `fw` is the firmware identity: the name the build set (MIK_BOARD_NAME). `board`
931
+ * reports the same unless `mikro flash` wrote a board's name into a generic
932
+ * image (mik__board_name). The host only auto-flashes its bundled image over
932
933
  * a device whose identity matches that image's name; omitting it reads as
933
934
  * firmware predating identity reporting, which the host treats as its own
934
935
  * bundled firmware.
package/src/mik_sys.cpp CHANGED
@@ -171,7 +171,7 @@ static JSValue mik__sys_restart(JSContext* ctx, JSValue this_val, int argc, JSVa
171
171
  return JS_UNDEFINED;
172
172
  }
173
173
 
174
- const char* mik__board_name(void) {
174
+ const char* mik__firmware_name(void) {
175
175
  #ifdef MIK_BOARD_NAME
176
176
  return MIK_BOARD_NAME;
177
177
  #elif defined(CONFIG_IDF_TARGET)
@@ -181,6 +181,36 @@ const char* mik__board_name(void) {
181
181
  #endif
182
182
  }
183
183
 
184
+ #ifdef CONFIG_IDF_TARGET
185
+ /* The board name `mikro flash` writes into a copy of the image when it flashes
186
+ * the generic firmware for a board (packages/mikro/src/cli/lib/boardName.ts).
187
+ * ESP-IDF places .rodata_custom_desc right after esp_app_desc_t, at image
188
+ * offset 0x120. Empty in the built image. */
189
+ struct MIKBoardDesc {
190
+ uint32_t magic;
191
+ char board[64];
192
+ };
193
+ static const MIKBoardDesc s_board_desc
194
+ __attribute__((section(".rodata_custom_desc"), used)) = {0x424b494d /* "MIKB" */, {}};
195
+
196
+ /* Copied through volatile reads: the compiler knows the empty initializer and
197
+ * would otherwise fold every read of it. */
198
+ static const char* mik__patched_board_name(void) {
199
+ static char name[sizeof(s_board_desc.board)];
200
+ const volatile char* src = s_board_desc.board;
201
+ for (size_t i = 0; i + 1 < sizeof(name) && src[i] != '\0'; i++) name[i] = src[i];
202
+ return name;
203
+ }
204
+ #endif
205
+
206
+ const char* mik__board_name(void) {
207
+ #ifdef CONFIG_IDF_TARGET
208
+ static const char* patched = mik__patched_board_name();
209
+ if (patched[0] != '\0') return patched;
210
+ #endif
211
+ return mik__firmware_name();
212
+ }
213
+
184
214
  static JSValue mik__sys_board(JSContext* ctx) {
185
215
  JSValue obj = JS_NewObject(ctx);
186
216
  JS_SetPropertyStr(ctx, obj, "name", JS_NewString(ctx, mik__board_name()));
@@ -248,6 +278,7 @@ static JSValue mik__sys_board(JSContext* ctx) {
248
278
 
249
279
  static JSValue mik__sys_firmware(JSContext* ctx) {
250
280
  JSValue obj = JS_NewObject(ctx);
281
+ JS_SetPropertyStr(ctx, obj, "name", JS_NewString(ctx, mik__firmware_name()));
251
282
  #ifdef CONFIG_IDF_TARGET
252
283
  const esp_app_desc_t* desc = esp_app_get_description();
253
284
  char elf_hash[65];