@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
package/CMakeLists.txt ADDED
@@ -0,0 +1,198 @@
1
+ cmake_minimum_required(VERSION 3.20)
2
+ project(mikrojs LANGUAGES C CXX)
3
+
4
+ set(CMAKE_C_STANDARD 11)
5
+ set(CMAKE_CXX_STANDARD 23)
6
+ set(CMAKE_C_STANDARD_REQUIRED ON)
7
+ set(CMAKE_CXX_STANDARD_REQUIRED ON)
8
+
9
+ # ── Resolve @mikrojs/quickjs via Node.js ─────────────────────────────
10
+ execute_process(
11
+ COMMAND node -e "import('@mikrojs/quickjs').then(m=>process.stdout.write(m.cmakePath))"
12
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
13
+ OUTPUT_VARIABLE QUICKJS_CMAKE_PATH
14
+ OUTPUT_STRIP_TRAILING_WHITESPACE
15
+ RESULT_VARIABLE _QUICKJS_RESOLVE_RESULT
16
+ )
17
+ if(NOT _QUICKJS_RESOLVE_RESULT EQUAL 0)
18
+ message(FATAL_ERROR "Failed to resolve @mikrojs/quickjs. Run pnpm install first.")
19
+ endif()
20
+
21
+ include("${QUICKJS_CMAKE_PATH}")
22
+
23
+ # qjsc is built by @mikrojs/quickjs postinstall during pnpm install
24
+ if(NOT EXISTS "${QJSC_EXECUTABLE}")
25
+ message(FATAL_ERROR "qjsc not found at ${QJSC_EXECUTABLE}. Run 'pnpm install' first.")
26
+ endif()
27
+
28
+ # ── mikrojs static library ──────────────────────────────────────────
29
+ # Core source files shared between standalone lib and ESP-IDF builds.
30
+ # platform_posix.cpp is only used in the standalone build (ESP-IDF uses platform_esp32.cpp).
31
+ set(MIKROJS_CORE_SOURCES
32
+ src/cutils_compat.c
33
+ src/mikrojs.cpp
34
+ src/modules.cpp
35
+ src/builtins.cpp
36
+ src/timers.cpp
37
+ src/fs.cpp
38
+ src/mem.cpp
39
+ src/utils.cpp
40
+ src/eval_bytecode.cpp
41
+ src/mik_inspect.cpp
42
+ src/mik_stdio.cpp
43
+ src/mik_text_encoding.cpp
44
+ src/mik_color.cpp
45
+ src/mik_abort.cpp
46
+ src/mik_cbor.cpp
47
+ src/mik_result.cpp
48
+ src/mik_console.cpp
49
+ src/mik_sys.cpp
50
+ src/mik_repl.cpp
51
+ src/mik_app_config.cpp
52
+ )
53
+
54
+ add_library(mikrojs STATIC
55
+ ${MIKROJS_CORE_SOURCES}
56
+ src/platform_posix.cpp
57
+ deps/nanocbor/src/encoder.c
58
+ deps/nanocbor/src/decoder.c
59
+ )
60
+ set_target_properties(mikrojs PROPERTIES POSITION_INDEPENDENT_CODE ON)
61
+
62
+ target_include_directories(mikrojs PUBLIC
63
+ "${CMAKE_CURRENT_SOURCE_DIR}/include"
64
+ )
65
+ target_include_directories(mikrojs PRIVATE
66
+ "${CMAKE_CURRENT_SOURCE_DIR}/deps/nanocbor/include"
67
+ )
68
+
69
+ # nanocbor defaults to <endian.h> (glibc). Apple SDKs and MSVC don't ship
70
+ # it, so route them to per-platform shims that map htobe*/be*toh onto
71
+ # whatever native intrinsics the toolchain provides.
72
+ if(APPLE)
73
+ target_compile_definitions(mikrojs PRIVATE "NANOCBOR_BYTEORDER_HEADER=\"byteorder_apple.h\"")
74
+ elseif(WIN32)
75
+ target_compile_definitions(mikrojs PRIVATE "NANOCBOR_BYTEORDER_HEADER=\"byteorder_windows.h\"")
76
+ endif()
77
+
78
+ # ── Generated bytecode headers ────────────────────────────────────
79
+ include(cmake/mikrojs_bytecode.cmake)
80
+ mikrojs_generate_bytecode(
81
+ RUNTIME_DIR "${CMAKE_CURRENT_SOURCE_DIR}/runtime"
82
+ MODULES cbor env result schema fs http/helpers http/request i2c kv/nvs kv/rtc kv/shared neopixel pin pwm reader sleep spi sntp stdio stream sys test uart wifi
83
+ MODULE_PREFIX "mikrojs"
84
+ SYMBOL_PREFIX "mikrojs"
85
+ TARGET gen_bytecode
86
+ )
87
+ add_dependencies(mikrojs gen_bytecode)
88
+ target_include_directories(mikrojs PRIVATE "${gen_bytecode_INCLUDE_DIR}")
89
+
90
+ target_link_libraries(mikrojs PUBLIC quickjs)
91
+
92
+ # Note: self-registering native modules need force-include linker flags (-u symbol)
93
+ # to prevent stripping from static libraries. These are added by consumers:
94
+ # - ESP-IDF firmware: mikrojs_force_include_modules() in firmware CMakeLists
95
+ # - Host tests: target_link_options on mikrojs_tests below
96
+
97
+ # Suppress warnings from QuickJS headers in our code. MSVC uses /W3 by default
98
+ # and doesn't understand the -W flags. The dead-stripping flags below are
99
+ # similarly GCC/Clang-only; MSVC's linker dead-strips by default with /OPT:REF.
100
+ if(NOT MSVC)
101
+ target_compile_options(mikrojs PRIVATE -Wall -Wextra -Wno-unused-parameter)
102
+ # Emit per-function/data sections so the linker can dead-strip unreferenced
103
+ # symbols at executable link time. This matches ESP-IDF's default toolchain
104
+ # flags and lets us measure flash-size effects of source-level changes
105
+ # (e.g. intrinsic stripping) on the host build.
106
+ target_compile_options(mikrojs PRIVATE -ffunction-sections -fdata-sections)
107
+ endif()
108
+
109
+ # Version metadata for sys.version()
110
+ execute_process(
111
+ COMMAND node -e "import('../../../package.json',{with:{type:'json'}}).then(m=>process.stdout.write(m.default.version))"
112
+ WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
113
+ OUTPUT_VARIABLE _MIK_VERSION
114
+ OUTPUT_STRIP_TRAILING_WHITESPACE
115
+ RESULT_VARIABLE _MIK_VERSION_RESULT
116
+ )
117
+ if(NOT _MIK_VERSION_RESULT EQUAL 0 OR _MIK_VERSION STREQUAL "")
118
+ message(FATAL_ERROR "Failed to resolve package version for MIK_FW_VERSION. Check that package.json exists at the workspace root.")
119
+ endif()
120
+ target_compile_definitions(mikrojs PRIVATE "MIK_FW_VERSION=\"${_MIK_VERSION}\"")
121
+
122
+ # UTC build timestamp. `string(TIMESTAMP ... UTC)` honors SOURCE_DATE_EPOCH
123
+ # when set (for reproducible builds). Refreshes on re-configure only, not
124
+ # every build — coarse enough for sys.firmware.date, which is a sanity
125
+ # fence for clock-synced checks, not a precise build identifier.
126
+ string(TIMESTAMP _MIK_BUILD_DATE_UTC "%Y-%m-%dT%H:%M:%SZ" UTC)
127
+ target_compile_definitions(mikrojs PRIVATE "MIK_BUILD_DATE_UTC=\"${_MIK_BUILD_DATE_UTC}\"")
128
+
129
+ # ── Exported variables for ESP-IDF consumers ─────────────────────────
130
+ # ESP-IDF components can't use CMake targets, so export source/include paths.
131
+ # Only set PARENT_SCOPE when included as a subdirectory (avoids warnings in standalone builds).
132
+ if(NOT CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
133
+ # Prefix each core source with the full path for PARENT_SCOPE export
134
+ set(MIKROJS_SOURCES "")
135
+ foreach(_src ${MIKROJS_CORE_SOURCES})
136
+ list(APPEND MIKROJS_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/${_src}")
137
+ endforeach()
138
+ set(MIKROJS_SOURCES ${MIKROJS_SOURCES} PARENT_SCOPE)
139
+ set(MIKROJS_NANOCBOR_DIR "${CMAKE_CURRENT_SOURCE_DIR}/deps/nanocbor" PARENT_SCOPE)
140
+ set(MIKROJS_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/include" PARENT_SCOPE)
141
+ set(MIKROJS_SCRIPTS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/scripts" PARENT_SCOPE)
142
+ set(MIKROJS_RUNTIME_DIR "${CMAKE_CURRENT_SOURCE_DIR}/runtime" PARENT_SCOPE)
143
+ endif()
144
+
145
+ # ── Tests ────────────────────────────────────────────────────────────
146
+ if(BUILD_TESTING)
147
+ enable_testing()
148
+
149
+ add_executable(mikrojs_tests
150
+ test/main.cpp
151
+ test/runtime_test.cpp
152
+ test/modules_test.cpp
153
+ test/text_encoding_test.cpp
154
+ test/cbor_test.cpp
155
+ test/abort_test.cpp
156
+ test/repl_protocol_test.cpp
157
+ test/app_config_test.cpp
158
+ test/oom_test.cpp
159
+ test/reader_test.cpp
160
+ test/stream_test.cpp
161
+ test/runtime_recycle_test.cpp
162
+ )
163
+
164
+ target_link_libraries(mikrojs_tests PRIVATE mikrojs)
165
+ target_include_directories(mikrojs_tests PRIVATE
166
+ "${CMAKE_CURRENT_SOURCE_DIR}/test"
167
+ "${CMAKE_CURRENT_SOURCE_DIR}/deps/nanocbor/include"
168
+ )
169
+
170
+ include(CTest)
171
+ add_test(NAME mikrojs_tests COMMAND mikrojs_tests)
172
+
173
+ # native_stubs registers no-op `native:*` modules so the bench can load
174
+ # ESP-only builtins (wifi, fetch, kv, …) on the host. Compiled into the
175
+ # executable directly so its self-registering constructors aren't
176
+ # dead-stripped (no -u flags needed).
177
+ add_executable(memory_bench test/memory_bench.cpp test/native_stubs.cpp)
178
+ target_link_libraries(memory_bench PRIVATE mikrojs)
179
+ # Run the bench as a smoke test so module-load regressions (e.g. a
180
+ # builtin that imports an unregistered native module on host) surface
181
+ # in `pnpm test:lib` / `pnpm check` rather than only in the CI
182
+ # memory-bench workflow. Output is discarded; we only assert it exits 0.
183
+ add_test(NAME memory_bench COMMAND memory_bench)
184
+ set_tests_properties(memory_bench PROPERTIES
185
+ WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
186
+
187
+ add_executable(bundle_compare test/bundle_compare.cpp)
188
+ target_link_libraries(bundle_compare PRIVATE mikrojs)
189
+ # Dead-strip unreferenced code at link time. Used for measuring the
190
+ # binary-size impact of source-level changes (intrinsic drops, etc.).
191
+ # Applied only to memory_bench to avoid interfering with doctest's
192
+ # static-initializer registration in mikrojs_tests.
193
+ if(APPLE)
194
+ target_link_options(memory_bench PRIVATE -Wl,-dead_strip)
195
+ else()
196
+ target_link_options(memory_bench PRIVATE -Wl,--gc-sections)
197
+ endif()
198
+ endif()
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) Bjørge Næss
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,49 @@
1
+ # @mikrojs/native
2
+
3
+ Standalone, platform-independent C++ runtime library for mikrojs, powered by QuickJS-NG. Zero ESP-IDF dependencies — runs on any POSIX host for development and testing, and on ESP32 via a thin platform adapter.
4
+
5
+ ## Directory structure
6
+
7
+ ```
8
+ include/ Public C/C++ headers (mikrojs.h, platform.h, private.h, …)
9
+ src/ C/C++ source files (runtime, modules, timers, REPL, …)
10
+ runtime/ TypeScript runtime modules bundled to bytecode at build time
11
+ addon/ Node-API addon exposing the runtime to Node.js
12
+ scripts/ Build scripts (esbuild bundling, qjsc bytecode compilation)
13
+ test/ Host-side C++ tests (Unity, run via ctest)
14
+ ```
15
+
16
+ ## Build
17
+
18
+ ```sh
19
+ # Standalone library (host)
20
+ cmake -B build && cmake --build build
21
+
22
+ # Run C++ tests
23
+ ctest --test-dir build --output-on-failure
24
+
25
+ # Node addon
26
+ pnpm run build:native
27
+ ```
28
+
29
+ ## Architecture
30
+
31
+ The runtime abstracts platform-specific operations via `MIKPlatform` (defined in `include/mikrojs/platform.h`). A default POSIX implementation is provided in `src/platform_posix.cpp`. The ESP32 adapter in `packages/@mikrojs/firmware/components/mikrojs/` supplies an ESP-IDF implementation.
32
+
33
+ ### Runtime modules
34
+
35
+ TypeScript modules in `runtime/` are the JS-facing APIs (fetch, pin, wifi, etc.). During each CMake build they are:
36
+
37
+ 1. Bundled with esbuild (`scripts/bundle-runtime.js`)
38
+ 2. Compiled to bytecode with qjsc (`scripts/compile-bytecode.sh`)
39
+ 3. Included as C headers in `src/builtins.cpp`
40
+
41
+ Type-checked separately via `tsconfig.runtime.json`:
42
+
43
+ ```sh
44
+ tsc --noEmit -p tsconfig.runtime.json
45
+ ```
46
+
47
+ ### Node addon
48
+
49
+ The `addon/` directory contains a Node-API binding that wraps the C++ runtime for use from Node.js/TypeScript. See [`addon/README.md`](addon/README.md).
@@ -0,0 +1,146 @@
1
+ # mikrojs_generate_bytecode() — Reusable CMake function for compiling TypeScript
2
+ # runtime modules to QuickJS bytecode headers.
3
+ #
4
+ # Used by the core runtime, ESP-IDF component, and board/driver packages.
5
+ #
6
+ # Usage:
7
+ # mikrojs_generate_bytecode(
8
+ # RUNTIME_DIR <path> # Directory containing <mod>/<mod>.ts files
9
+ # MODULES <mod1> <mod2> # Module names to compile
10
+ # MODULE_PREFIX <prefix> # Module name prefix (e.g. "mikrojs" -> "mikrojs/pin")
11
+ # SYMBOL_PREFIX <prefix> # C symbol prefix (e.g. "mikrojs" -> "mikrojs_pin_bytecode")
12
+ # TARGET <name> # Custom target name (default: gen_bytecode)
13
+ # WORKING_DIRECTORY <dir> # Working dir for esbuild (default: CMAKE_CURRENT_SOURCE_DIR)
14
+ # )
15
+ #
16
+ # After calling, the following are set in the caller's scope:
17
+ # ${TARGET}_HEADERS — list of generated .h file paths
18
+ # ${TARGET}_GEN_DIR — directory containing the generated headers (include this)
19
+
20
+ include_guard(GLOBAL)
21
+
22
+ # Resolve paths relative to this file (inside @mikrojs/native).
23
+ # Use CACHE so the path is available across all components that include this file.
24
+ get_filename_component(_MIK_BC_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" DIRECTORY)
25
+ set(_MIK_BC_SCRIPTS_DIR "${_MIK_BC_CMAKE_DIR}/../scripts" CACHE INTERNAL "")
26
+
27
+ function(mikrojs_generate_bytecode)
28
+ cmake_parse_arguments(ARG "" "RUNTIME_DIR;MODULE_PREFIX;SYMBOL_PREFIX;TARGET;WORKING_DIRECTORY" "MODULES" ${ARGN})
29
+
30
+ # Defaults
31
+ if(NOT ARG_TARGET)
32
+ set(ARG_TARGET "gen_bytecode")
33
+ endif()
34
+ if(NOT ARG_WORKING_DIRECTORY)
35
+ set(ARG_WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}")
36
+ endif()
37
+
38
+ # Validate required args
39
+ if(NOT ARG_RUNTIME_DIR)
40
+ message(FATAL_ERROR "mikrojs_generate_bytecode: RUNTIME_DIR is required")
41
+ endif()
42
+ if(NOT ARG_MODULES)
43
+ message(FATAL_ERROR "mikrojs_generate_bytecode: MODULES is required")
44
+ endif()
45
+ if(NOT ARG_MODULE_PREFIX)
46
+ message(FATAL_ERROR "mikrojs_generate_bytecode: MODULE_PREFIX is required")
47
+ endif()
48
+ if(NOT ARG_SYMBOL_PREFIX)
49
+ message(FATAL_ERROR "mikrojs_generate_bytecode: SYMBOL_PREFIX is required")
50
+ endif()
51
+
52
+ # Verify qjsc exists (set by quickjs.cmake)
53
+ if(NOT EXISTS "${QJSC_EXECUTABLE}")
54
+ message(FATAL_ERROR "qjsc not found at ${QJSC_EXECUTABLE}. Run 'pnpm install' first.")
55
+ endif()
56
+
57
+ set(_GEN_DIR "${CMAKE_CURRENT_BINARY_DIR}/gen")
58
+ set(_BUNDLE_DIR "${CMAKE_CURRENT_BINARY_DIR}/bundled")
59
+
60
+ # Collect source files so the bundle step re-runs when they change.
61
+ # Also track the shell scripts that drive the pipeline so changes to
62
+ # the scripts (e.g. qjsc flag fixes) invalidate the generated outputs
63
+ # and trigger a rebuild — otherwise ninja sees `bundle.stamp` unchanged
64
+ # and silently reuses stale bytecode headers.
65
+ file(GLOB_RECURSE _RUNTIME_SOURCES "${ARG_RUNTIME_DIR}/*.ts")
66
+ set(_BUNDLE_SCRIPT "${_MIK_BC_SCRIPTS_DIR}/bundle-runtime.js")
67
+ set(_COMPILE_SCRIPT "${_MIK_BC_SCRIPTS_DIR}/compile-bytecode.sh")
68
+
69
+ # Optional minifier override (e.g. -DMIK_MINIFIER=terser -DMIK_MINIFY_LEVEL=max)
70
+ set(_MINIFIER_ARGS "")
71
+ if(DEFINED MIK_MINIFIER)
72
+ list(APPEND _MINIFIER_ARGS "--minifier=${MIK_MINIFIER}")
73
+ endif()
74
+ if(DEFINED MIK_MINIFY_LEVEL)
75
+ list(APPEND _MINIFIER_ARGS "--minify-level=${MIK_MINIFY_LEVEL}")
76
+ endif()
77
+
78
+ # Step 1: Bundle TypeScript runtime modules to JS with esbuild
79
+ add_custom_command(
80
+ OUTPUT ${_BUNDLE_DIR}/bundle.stamp
81
+ COMMAND node ${_BUNDLE_SCRIPT}
82
+ ${_BUNDLE_DIR} ${ARG_RUNTIME_DIR} ${ARG_MODULES} ${_MINIFIER_ARGS}
83
+ COMMAND ${CMAKE_COMMAND} -E touch ${_BUNDLE_DIR}/bundle.stamp
84
+ DEPENDS ${_RUNTIME_SOURCES} ${_BUNDLE_SCRIPT}
85
+ COMMENT "Bundling runtime modules"
86
+ WORKING_DIRECTORY ${ARG_WORKING_DIRECTORY}
87
+ )
88
+
89
+ # Step 2: Compile each bundled JS file to a bytecode header with qjsc
90
+ set(_HEADERS "")
91
+ foreach(mod ${ARG_MODULES})
92
+ # Sanitize module name for C identifiers (replace non-alphanumeric with _)
93
+ string(REGEX REPLACE "[^a-zA-Z0-9]" "_" _mod_safe "${mod}")
94
+ set(_header "${_GEN_DIR}/${ARG_SYMBOL_PREFIX}_${_mod_safe}.h")
95
+ add_custom_command(
96
+ OUTPUT ${_header}
97
+ COMMAND ${CMAKE_COMMAND} -E make_directory ${_GEN_DIR}
98
+ COMMAND sh ${_COMPILE_SCRIPT}
99
+ ${QJSC_EXECUTABLE}
100
+ ${_BUNDLE_DIR}/${mod}.js
101
+ ${_header}
102
+ "${ARG_MODULE_PREFIX}/${mod}"
103
+ "${ARG_SYMBOL_PREFIX}_${_mod_safe}_bytecode"
104
+ DEPENDS ${_BUNDLE_DIR}/bundle.stamp ${_COMPILE_SCRIPT} ${QJSC_EXECUTABLE}
105
+ COMMENT "Compiling bytecode: ${ARG_MODULE_PREFIX}/${mod}"
106
+ )
107
+ list(APPEND _HEADERS ${_header})
108
+ endforeach()
109
+
110
+ # Step 3: Generate builtins table header (includes + lookup table)
111
+ set(_TABLE_HEADER "${_GEN_DIR}/${ARG_SYMBOL_PREFIX}_builtins_table.h")
112
+ set(_TABLE_CONTENT "/* Auto-generated by mikrojs_generate_bytecode() — do not edit */\n")
113
+ foreach(mod ${ARG_MODULES})
114
+ string(REGEX REPLACE "[^a-zA-Z0-9]" "_" _mod_safe "${mod}")
115
+ string(APPEND _TABLE_CONTENT "#include \"${ARG_SYMBOL_PREFIX}_${_mod_safe}.h\"\n")
116
+ endforeach()
117
+ string(APPEND _TABLE_CONTENT "\nstatic const mik_builtin_t ${ARG_SYMBOL_PREFIX}_builtins[] = {\n")
118
+ foreach(mod ${ARG_MODULES})
119
+ string(REGEX REPLACE "[^a-zA-Z0-9]" "_" _mod_safe "${mod}")
120
+ string(APPEND _TABLE_CONTENT " {\"${ARG_MODULE_PREFIX}/${mod}\", ${ARG_SYMBOL_PREFIX}_${_mod_safe}_bytecode, ${ARG_SYMBOL_PREFIX}_${_mod_safe}_bytecode_size},\n")
121
+ endforeach()
122
+ string(APPEND _TABLE_CONTENT " {NULL, NULL, 0},\n};\n")
123
+ file(GENERATE OUTPUT ${_TABLE_HEADER} CONTENT "${_TABLE_CONTENT}")
124
+ list(APPEND _HEADERS ${_TABLE_HEADER})
125
+
126
+ # Step 4: Create custom target
127
+ add_custom_target(${ARG_TARGET} DEPENDS ${_HEADERS})
128
+
129
+ # Export to caller's scope
130
+ set(${ARG_TARGET}_HEADERS ${_HEADERS} PARENT_SCOPE)
131
+ set(${ARG_TARGET}_GEN_DIR ${_GEN_DIR} PARENT_SCOPE)
132
+ # Include the parent of gen/ so #include "gen/foo.h" works
133
+ set(${ARG_TARGET}_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR} PARENT_SCOPE)
134
+ endfunction()
135
+
136
+ function(mikrojs_force_include_modules)
137
+ foreach(id ${ARGN})
138
+ target_link_libraries(${COMPONENT_LIB} INTERFACE "-u mik__mod_desc_${id}")
139
+ endforeach()
140
+ endfunction()
141
+
142
+ function(mikrojs_force_include_builtins)
143
+ foreach(id ${ARGN})
144
+ target_link_libraries(${COMPONENT_LIB} INTERFACE "-u mik__builtin_${id}")
145
+ endforeach()
146
+ endfunction()
package/cmake.js ADDED
@@ -0,0 +1,22 @@
1
+ import {dirname, join} from 'node:path'
2
+ import {fileURLToPath} from 'node:url'
3
+
4
+ const __dirname = dirname(fileURLToPath(import.meta.url))
5
+
6
+ /** Path to the main CMakeLists.txt */
7
+ export const cmakePath = join(__dirname, 'CMakeLists.txt')
8
+
9
+ /** Path to the public include directory */
10
+ export const includePath = join(__dirname, 'include')
11
+
12
+ /** Path to the C++ source directory */
13
+ export const srcPath = join(__dirname, 'src')
14
+
15
+ /** Path to the build scripts directory */
16
+ export const scriptsPath = join(__dirname, 'scripts')
17
+
18
+ /** Path to the runtime TypeScript modules directory */
19
+ export const runtimePath = join(__dirname, 'runtime')
20
+
21
+ /** Path to the reusable bytecode generation CMake module */
22
+ export const bytecodeCmakePath = join(__dirname, 'cmake', 'mikrojs_bytecode.cmake')
@@ -0,0 +1,52 @@
1
+ import type { HostMessage, MikroRuntimeOptions, ProfileEntry } from './types.js';
2
+ export declare class MikroRuntime {
3
+ private native;
4
+ constructor(options?: MikroRuntimeOptions);
5
+ evalModule(filename: string, isMain?: boolean): void;
6
+ /** Evaluate module source code directly, bypassing filesystem path resolution. */
7
+ evalModuleContent(filename: string, content: string): void;
8
+ /** Evaluate a script (not module) and return the stringified result. Returns undefined if the result is undefined/null. */
9
+ evalScript(code: string): string | undefined;
10
+ loop(): Promise<void>;
11
+ /** Run one iteration of the event loop synchronously. Returns 0 on success. */
12
+ loopOnce(): number;
13
+ stop(): void;
14
+ dispose(): void;
15
+ /** Register a JS source string as a named virtual module.
16
+ * Virtual modules are checked by the loader before builtin bytecode,
17
+ * allowing JS-based mocks to override any native:* C module. */
18
+ registerModuleSource(name: string, source: string): void;
19
+ /** Drain all outbound messages sent from QuickJS via native:host.send().
20
+ * Returns and clears the queue. Call after each loopOnce(). */
21
+ drainMessages(): HostMessage[];
22
+ /** Post a message from Node.js into the QuickJS runtime.
23
+ * Delivered to the native:host.onMessage() callback on the next loop tick. */
24
+ postMessage(type: string, data: string): void;
25
+ /** Set a preprocessor function called on module source before compilation.
26
+ * Return a string to replace the source, or undefined to use the original.
27
+ * Useful for stripping TypeScript types from .ts files. */
28
+ setPreprocessor(fn: (filename: string, source: string) => string | undefined): void;
29
+ /** Set a synchronous RPC handler called from QuickJS via native:host.call().
30
+ * The handler receives a method name (e.g. 'pin.pinMode') and JSON-encoded args,
31
+ * and must return a JSON-encoded result string (or a Promise of one for async). */
32
+ setRpcHandler(handler: (method: string, argsJson: string) => string | Promise<string>): void;
33
+ /** Enable per-module memory profiling. Must be called before any module loads
34
+ * to capture the full import graph. Profile storage lives outside QuickJS's
35
+ * tracked heap so instrumentation does not pollute the numbers being measured. */
36
+ enableProfiling(): void;
37
+ /** Return the collected profile entries. Each entry records the QuickJS heap
38
+ * delta observed while loading a specific module. */
39
+ getProfile(): ProfileEntry[];
40
+ /** Return the QuickJS heap baseline (bytes) at the time profiling was enabled.
41
+ * This is the cost of the runtime + context + built-in prototypes, before
42
+ * any user modules are loaded. */
43
+ getProfileBaseline(): number;
44
+ }
45
+ /** Serialize a JSON string to QuickJS binary JSON (bjson) format. */
46
+ export declare function jsonToBjson(json: string): Buffer;
47
+ /** Compile a JS module to QuickJS bytecode. External imports must be declared to avoid resolution errors. */
48
+ export declare function compileBytecode(source: string, moduleName: string, externals?: string[]): Buffer;
49
+ /** Compile a JS module to bytecode and return as a C header string (equivalent to qjsc -o header.h). */
50
+ export declare function compileBytecodeToHeader(source: string, moduleName: string, symbolName: string, externals?: string[]): string;
51
+ export type { HostMessage, MikroRuntimeOptions, NativeMikroRuntime, ProfileEntry } from './types.ts';
52
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../addon/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,WAAW,EACX,mBAAmB,EAGnB,YAAY,EACb,MAAM,YAAY,CAAA;AAuBnB,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAoB;gBAEtB,OAAO,CAAC,EAAE,mBAAmB;IAIzC,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,UAAO,GAAG,IAAI;IAIjD,kFAAkF;IAClF,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAI1D,2HAA2H;IAC3H,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAI5C,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAIrB,+EAA+E;IAC/E,QAAQ,IAAI,MAAM;IAIlB,IAAI,IAAI,IAAI;IAIZ,OAAO,IAAI,IAAI;IAIf;;oEAEgE;IAChE,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAIxD;mEAC+D;IAC/D,aAAa,IAAI,WAAW,EAAE;IAI9B;kFAC8E;IAC9E,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAI7C;;+DAE2D;IAC3D,eAAe,CAAC,EAAE,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,GAAG,IAAI;IAInF;;uFAEmF;IACnF,aAAa,CAAC,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,IAAI;IAI5F;;sFAEkF;IAClF,eAAe,IAAI,IAAI;IAIvB;yDACqD;IACrD,UAAU,IAAI,YAAY,EAAE;IAI5B;;sCAEkC;IAClC,kBAAkB,IAAI,MAAM;CAG7B;AAED,qEAAqE;AACrE,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED,6GAA6G;AAC7G,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAEhG;AAED,wGAAwG;AACxG,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,SAAS,CAAC,EAAE,MAAM,EAAE,GACnB,MAAM,CA4BR;AAED,YAAY,EAAC,WAAW,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,YAAY,EAAC,MAAM,YAAY,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,132 @@
1
+ import { createRequire } from 'node:module';
2
+ import { join } from 'node:path';
3
+ const require = createRequire(import.meta.url);
4
+ const nodeGypBuild = require('node-gyp-build');
5
+ function loadBindings() {
6
+ const pkgRoot = join(import.meta.dirname, '..');
7
+ try {
8
+ return nodeGypBuild(pkgRoot);
9
+ }
10
+ catch (prebuildErr) {
11
+ // Dev fallback: cmake-js builds to addon/build/Release/, which is outside
12
+ // the paths node-gyp-build probes by default.
13
+ const devPath = join(pkgRoot, 'addon', 'build', 'Release', 'mikrojs_node.node');
14
+ try {
15
+ return require(devPath);
16
+ }
17
+ catch {
18
+ throw prebuildErr;
19
+ }
20
+ }
21
+ }
22
+ const bindings = loadBindings();
23
+ export class MikroRuntime {
24
+ native;
25
+ constructor(options) {
26
+ this.native = new bindings.MikroRuntime(options);
27
+ }
28
+ evalModule(filename, isMain = true) {
29
+ this.native.evalModule(filename, isMain);
30
+ }
31
+ /** Evaluate module source code directly, bypassing filesystem path resolution. */
32
+ evalModuleContent(filename, content) {
33
+ this.native.evalModuleContent(filename, content);
34
+ }
35
+ /** Evaluate a script (not module) and return the stringified result. Returns undefined if the result is undefined/null. */
36
+ evalScript(code) {
37
+ return this.native.evalScript(code);
38
+ }
39
+ loop() {
40
+ return this.native.loop();
41
+ }
42
+ /** Run one iteration of the event loop synchronously. Returns 0 on success. */
43
+ loopOnce() {
44
+ return this.native.loopOnce();
45
+ }
46
+ stop() {
47
+ this.native.stop();
48
+ }
49
+ dispose() {
50
+ this.native.dispose();
51
+ }
52
+ /** Register a JS source string as a named virtual module.
53
+ * Virtual modules are checked by the loader before builtin bytecode,
54
+ * allowing JS-based mocks to override any native:* C module. */
55
+ registerModuleSource(name, source) {
56
+ this.native.registerModuleSource(name, source);
57
+ }
58
+ /** Drain all outbound messages sent from QuickJS via native:host.send().
59
+ * Returns and clears the queue. Call after each loopOnce(). */
60
+ drainMessages() {
61
+ return this.native.drainMessages();
62
+ }
63
+ /** Post a message from Node.js into the QuickJS runtime.
64
+ * Delivered to the native:host.onMessage() callback on the next loop tick. */
65
+ postMessage(type, data) {
66
+ this.native.postMessage(type, data);
67
+ }
68
+ /** Set a preprocessor function called on module source before compilation.
69
+ * Return a string to replace the source, or undefined to use the original.
70
+ * Useful for stripping TypeScript types from .ts files. */
71
+ setPreprocessor(fn) {
72
+ this.native.setPreprocessor(fn);
73
+ }
74
+ /** Set a synchronous RPC handler called from QuickJS via native:host.call().
75
+ * The handler receives a method name (e.g. 'pin.pinMode') and JSON-encoded args,
76
+ * and must return a JSON-encoded result string (or a Promise of one for async). */
77
+ setRpcHandler(handler) {
78
+ this.native.setRpcHandler(handler);
79
+ }
80
+ /** Enable per-module memory profiling. Must be called before any module loads
81
+ * to capture the full import graph. Profile storage lives outside QuickJS's
82
+ * tracked heap so instrumentation does not pollute the numbers being measured. */
83
+ enableProfiling() {
84
+ this.native.enableProfiling();
85
+ }
86
+ /** Return the collected profile entries. Each entry records the QuickJS heap
87
+ * delta observed while loading a specific module. */
88
+ getProfile() {
89
+ return this.native.getProfile();
90
+ }
91
+ /** Return the QuickJS heap baseline (bytes) at the time profiling was enabled.
92
+ * This is the cost of the runtime + context + built-in prototypes, before
93
+ * any user modules are loaded. */
94
+ getProfileBaseline() {
95
+ return this.native.getProfileBaseline();
96
+ }
97
+ }
98
+ /** Serialize a JSON string to QuickJS binary JSON (bjson) format. */
99
+ export function jsonToBjson(json) {
100
+ return bindings.jsonToBjson(json);
101
+ }
102
+ /** Compile a JS module to QuickJS bytecode. External imports must be declared to avoid resolution errors. */
103
+ export function compileBytecode(source, moduleName, externals) {
104
+ return bindings.compileBytecode(source, moduleName, externals);
105
+ }
106
+ /** Compile a JS module to bytecode and return as a C header string (equivalent to qjsc -o header.h). */
107
+ export function compileBytecodeToHeader(source, moduleName, symbolName, externals) {
108
+ const buf = bindings.compileBytecode(source, moduleName, externals);
109
+ // Match qjsc dump_hex format: " 0xNN," with newline every 8 bytes
110
+ let hex = '';
111
+ let col = 0;
112
+ for (let i = 0; i < buf.length; i++) {
113
+ hex += ` 0x${buf[i].toString(16).padStart(2, '0')},`;
114
+ if (++col === 8) {
115
+ hex += '\n';
116
+ col = 0;
117
+ }
118
+ }
119
+ if (col !== 0) {
120
+ hex += '\n';
121
+ }
122
+ return (`/* File generated automatically by the QuickJS-ng compiler. */\n` +
123
+ `\n` +
124
+ `#include <inttypes.h>\n` +
125
+ `\n` +
126
+ `const uint32_t ${symbolName}_size = ${buf.length};\n` +
127
+ `\n` +
128
+ `const uint8_t ${symbolName}[${buf.length}] = {\n` +
129
+ hex +
130
+ `};\n`);
131
+ }
132
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../addon/index.ts"],"names":[],"mappings":"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"}