@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,281 @@
1
+ #pragma once
2
+
3
+ #include <string>
4
+ #include <unordered_map>
5
+ #include <unordered_set>
6
+ #include <vector>
7
+
8
+ #include "mikrojs/cutils_wrap.h"
9
+ #include "mikrojs/mikrojs.h"
10
+ #include "quickjs.h"
11
+
12
+ #define MIK_TIMER_MAX_ARGS 4
13
+ #define MIK_MAX_DUE_TIMERS 16
14
+ #define MIK_STDIN_BUF_SIZE 256
15
+
16
+ #ifndef PATH_MAX
17
+ #define PATH_MAX 255
18
+ #endif
19
+
20
+ typedef struct MIKTimerEntry {
21
+ uint32_t id;
22
+ // is it an interval or a one-shot timer?
23
+ bool is_interval;
24
+ // original timeout (delay) value in microseconds
25
+ int64_t timeout;
26
+ // next deadline in microseconds
27
+ int64_t next_deadline;
28
+ JSValue func;
29
+ int argc;
30
+ JSValue argv[MIK_TIMER_MAX_ARGS];
31
+ } MIKTimerEntry;
32
+
33
+ typedef struct MIKTimers {
34
+ std::vector<MIKTimerEntry> entries;
35
+ // note: start at 1 to avoid if (timerId) {...} bugs
36
+ uint32_t next_timer_id = 1;
37
+ } MIKTimerRegistry;
38
+
39
+ /* Registered native module init function */
40
+ struct MIKNativeModuleEntry {
41
+ std::string name;
42
+ MIKNativeModuleInitFn init_fn;
43
+ };
44
+
45
+ /* Registered loop consumer */
46
+ struct MIKLoopConsumerEntry {
47
+ MIKLoopConsumeFn consume_fn;
48
+ MIKLoopDestroyFn destroy_fn;
49
+ };
50
+
51
+ struct MIKRuntime {
52
+ MIKRunOptions options;
53
+ MIKConfig config;
54
+ JSRuntime* rt;
55
+ JSContext* ctx;
56
+ bool is_worker;
57
+ bool freeing;
58
+ bool stop_requested; /* Set by promise rejection tracker to stop the loop */
59
+ const char* fs_base_path;
60
+ const char* fs_root; /* Sandbox root for mikrojs/fs operations (separate from module resolution) */
61
+ size_t fs_limit; /* Max bytes for fs_root (0 = unlimited) */
62
+ /* Cached bytes used under fs_root. Populated lazily on the first quota
63
+ * check; adjusted in-place on write/unlink so the O(tree) walk only
64
+ * happens once per run, not per write. Callers invalidate by setting
65
+ * fs_used_known=false when they can't cheaply compute the delta. */
66
+ size_t fs_used;
67
+ bool fs_used_known;
68
+ /* Max bytes a single readFile() call will return. Files larger than
69
+ * this throw FSError(EFBIG); callers use open() for streaming. */
70
+ size_t fs_read_max;
71
+ MIKTimerRegistry* timers;
72
+ std::vector<MIKNativeModuleEntry> native_modules;
73
+ std::vector<MIKLoopConsumerEntry> loop_consumers;
74
+ struct {
75
+ JSValue promise_event_ctor;
76
+ JSValue dispatch_event_func;
77
+ } builtins;
78
+ /* Shared prototype for Result objects ({ok, value} / {ok, error}) created
79
+ * by mik__result_ok/mik__result_err and the native:result ok()/err()
80
+ * functions. Holds .map/.mapErr/.andThen/.match/.orDefault/.orPanic +
81
+ * Symbol.for('mikrojs.inspect'). Initialized eagerly by mik__result_init
82
+ * and freed in MIK_FreeRuntime. */
83
+ JSValue result_proto;
84
+ /* Frozen {ok: true} singleton returned (via JS_DupValue) from
85
+ * mik__result_ok_void. Safe to share because Result is immutable by
86
+ * convention, and the singleton is frozen + non-extensible. */
87
+ JSValue result_ok_void_singleton;
88
+ JSValue env_obj; /* Frozen object with env vars, set on import.meta.env */
89
+ struct {
90
+ JSValue on_data; /* JS callback for stdin data, JS_UNDEFINED when not listening */
91
+ } stdin_state;
92
+ /* Env vars stored before runtime init (for building env_obj) */
93
+ std::vector<std::pair<std::string, std::string>> env_vars;
94
+ /* Opaque per-module data slots for platform-specific modules.
95
+ * Used by registered native modules to store their state on the runtime.
96
+ * Slots are allocated dynamically via MIK_AllocModuleSlot(). */
97
+ void* module_data[MIK_MODULE_DATA_SLOTS] = {};
98
+ int next_module_slot = 0;
99
+ /* Virtual modules: name → JS source. Checked by the module loader before
100
+ * the builtin bytecode table, allowing host-side JS to override any
101
+ * native:* C module (e.g. mocking device modules for desktop dev). */
102
+ std::unordered_map<std::string, std::string> virtual_modules;
103
+ /* Module dependency graph, populated by mik_module_normalizer on every
104
+ * successful normalization call. module_imports[A] = set of modules A
105
+ * statically imports; module_importers[B] = set of modules that import B.
106
+ * Both are keyed by normalized module names (the same strings that
107
+ * appear as JSAtom values on JSModuleDef). Used by mik__unload_module to
108
+ * locate orphaned transitive dependencies. Edges for non-module bases
109
+ * (REPL input, "<input>", task wrappers) are skipped. */
110
+ std::unordered_map<std::string, std::unordered_set<std::string>> module_imports;
111
+ std::unordered_map<std::string, std::unordered_set<std::string>> module_importers;
112
+ /* Optional preprocessor called on module source before compilation.
113
+ * Returns a malloc'd string (caller frees), or NULL to use original source.
114
+ * Used by the Node.js addon to strip TypeScript types. */
115
+ char* (*preprocess_fn)(const char* filename, const char* source, size_t source_len,
116
+ size_t* out_len, void* opaque) = nullptr;
117
+ void* preprocess_opaque = nullptr;
118
+ /* Optional error handler called with the exception value before mik_dump_error
119
+ * consumes it. The handler receives the exception as a borrowed JSValue
120
+ * (do NOT free it). Used by the Node.js addon to forward errors to the host. */
121
+ void (*error_handler_fn)(JSContext* ctx, JSValue error, void* opaque) = nullptr;
122
+ void* error_handler_opaque = nullptr;
123
+ /* Memory profiling: per-module load deltas. Vector capacity is reserved
124
+ * up-front when profiling is enabled so loads don't trigger reallocations
125
+ * that would themselves be visible to JS_ComputeMemoryUsage. The vector
126
+ * itself lives in the regular C++ heap, not the js_malloc pool, so it's
127
+ * invisible to the numbers we're measuring. */
128
+ bool profile_enabled = false;
129
+ std::vector<MIKProfileEntry> profile_entries;
130
+ size_t profile_baseline = 0; /* malloc_size at profiling start */
131
+ /* OOM signalling: flag set by MIK_ReportOOM() when the detection code
132
+ * thinks the runtime is at or past its QuickJS memory ceiling. Cleared
133
+ * by MIK_ConsumeOOMFlag(). Cold path — not read during bytecode
134
+ * execution or allocation, so it adds zero runtime tax. */
135
+ bool oom_flagged = false;
136
+ MIKOOMHandlerFn oom_handler_fn = nullptr;
137
+ void* oom_handler_opaque = nullptr;
138
+ };
139
+
140
+ void mik__pub_fs_register(JSContext* ctx);
141
+ void mik__stdio_init(JSContext* ctx, JSValue ns);
142
+ void mik__sys_api_init(JSContext* ctx, JSValue ns);
143
+ void mik__text_encoding_init(JSContext* ctx, JSValue global);
144
+ void mik__abort_init(JSContext* ctx, JSValue global_obj);
145
+
146
+ JSValue mik_new_error(JSContext* ctx, int err);
147
+ JSValue mik_throw_errno(JSContext* ctx, int err);
148
+
149
+ void mik__execute_jobs(JSContext* ctx);
150
+ JSModuleDef* mik__load_builtin(JSContext* ctx, const char* name);
151
+ int mik__load_file(JSContext* ctx, DynBuf* dbuf, const char* filename);
152
+ void mik__resolve_fs_path(JSContext* ctx, const char* module_name, char* out, size_t out_size);
153
+ int mik__resolve_fs_root(JSContext* ctx, const char* path, char* out, size_t out_size);
154
+ size_t mik__fs_dir_usage(const char* dir_path);
155
+ JSModuleDef* mik_module_loader(JSContext* ctx, const char* module_name, void* opaque);
156
+ char* mik_module_normalizer(JSContext* ctx, const char* base_name, const char* name, void* opaque);
157
+
158
+ /* Unload a module by its normalized name. Walks the mikrojs-side import
159
+ * dependency graph, recursively unloading any transitive dependency
160
+ * whose importer set becomes empty (builtin prefixes native:, mikrojs/,
161
+ * @mikrojs/ are anchored and skipped). Safe to call only on
162
+ * modules in JS_MODULE_STATUS_EVALUATED state; returns the number of
163
+ * modules actually freed, or -1 with a JS exception on invalid,
164
+ * mid-evaluation, or unknown modules. */
165
+ int mik__unload_module(JSContext* ctx, const char* normalized_name);
166
+
167
+ int js_module_set_import_meta(JSContext* ctx, JSValue func_val, bool use_realpath, bool is_main);
168
+
169
+ JSValue mik__get_args(JSContext* ctx);
170
+
171
+ int mik__eval_bytecode(JSContext* ctx, const uint8_t* buf, size_t buf_len, bool check_promise);
172
+
173
+
174
+ void mik__sab_free(void* opaque, void* ptr);
175
+ void mik__sab_dup(void* opaque, void* ptr);
176
+
177
+ MIKTimerRegistry* MIK_NewTimerRegistry(void);
178
+ MIKRuntime* MIK_NewRuntimeWorker(void);
179
+ MIKRuntime* MIK_NewRuntimeInternal(MIKRunOptions* options);
180
+ JSValue MIK_EvalScript(JSContext* ctx, const char* filename);
181
+ JSValue MIK_EvalModule(JSContext* ctx, const char* filename, bool is_main);
182
+ JSValue MIK_EvalModuleContent(JSContext* ctx, const char* filename, const char* content,
183
+ size_t len);
184
+
185
+
186
+ void mik__timers_init(JSContext* ctx, JSValue ns);
187
+ void mik__timers_consume(JSContext* ctx);
188
+ void mik__timers_destroy(JSContext* ctx);
189
+
190
+ void mik__stdin_consume(JSContext* ctx);
191
+
192
+ /* Console global (mik_console.cpp) */
193
+ void mik__console_init(JSContext* ctx, JSValue global_obj);
194
+ void mik__report_uncaught(JSContext* ctx, JSValue exc, bool in_promise = false);
195
+
196
+ /* Inspect (mik_inspect.cpp) */
197
+ std::string mik_inspect(JSContext* ctx, JSValue value, int depth = 2, bool colors = false,
198
+ bool show_hidden = false);
199
+ void mik__inspect_register(JSContext* ctx);
200
+
201
+ /* CBOR module (mik_cbor.cpp) */
202
+ JSModuleDef* mik__cbor_init(JSContext* ctx);
203
+
204
+ /* Result module (mik_result.cpp) */
205
+ JSModuleDef* mik__result_init(JSContext* ctx);
206
+
207
+ bool mik__repl_is_evaluating(void);
208
+
209
+ /* REPL protocol mode (mik_repl.cpp) — used by mik_console.cpp, mik_stdio.cpp */
210
+ bool mik__repl_is_protocol_mode(void);
211
+ void mik__repl_proto_send_output(uint8_t msg_type, const void* data, size_t len);
212
+
213
+ /* Suspend/resume MIK_Loop pumping (timers + loop consumers). Microtasks
214
+ * still drain so in-flight promises can settle. Used by mik_deploy.cpp to
215
+ * freeze user code while a deploy is streaming in. */
216
+ bool mik__repl_is_paused(void);
217
+ void mik__repl_set_paused(bool paused);
218
+
219
+ /* ── Unified MIK Protocol ───────────────────────────────────────── */
220
+ /* Frame format: [type: u8][length: u32le][payload: bytes] */
221
+
222
+ /* Escape hatch: raw byte that triggers hard restart */
223
+ #define MIK_CTRL_R 0x12
224
+
225
+ /* Header size: 1 (type) + 4 (u32le length) */
226
+ #define MIK_PROTO_HEADER_SIZE 5
227
+
228
+ /* Device → CLI message types */
229
+ #define MIK_MSG_READY 0x01
230
+ #define MIK_MSG_LOG 0x02
231
+ #define MIK_MSG_WARN 0x03
232
+ #define MIK_MSG_ERROR 0x04
233
+ #define MIK_MSG_RESULT 0x05
234
+ #define MIK_MSG_INFO 0x06
235
+ #define MIK_MSG_COMPLETIONS 0x07
236
+ #define MIK_MSG_EVAL_ERROR 0x08
237
+ #define MIK_MSG_PROMPT 0x09
238
+ #define MIK_MSG_TEST 0x0B
239
+ #define MIK_MSG_DEBUG 0x0C
240
+ /* Emitted once after the last test file's run_done when the device drove
241
+ * a supervisor-mode manifest. Signals "no more tests coming" to the CLI. */
242
+ #define MIK_MSG_MANIFEST_DONE 0x0D
243
+
244
+ #define MIK_MSG_OK 0x80
245
+ #define MIK_MSG_ERR 0x81
246
+ #define MIK_MSG_CHECKSUM_RESULT 0x82
247
+ #define MIK_MSG_CONFIG_ENTRIES 0x83
248
+
249
+ /* CLI → Device command types */
250
+ #define MIK_CMD_EVAL 0x10
251
+ #define MIK_CMD_COMPLETE 0x11
252
+ /* 0x12 reserved for CTRL_R hard-restart escape hatch */
253
+ #define MIK_CMD_DIRECTIVE 0x13
254
+ #define MIK_CMD_EXIT 0x14
255
+ #define MIK_CMD_HELLO 0x15
256
+
257
+ /* PUT opens the staged file and records the total size; the body arrives in
258
+ * one or more PUT_CHUNK frames so a single TLV frame never exceeds the USJ
259
+ * RX ring. PUT payload: u16le name_len | name | u32le total_size. */
260
+ #define MIK_CMD_DEPLOY_PUT 0x20
261
+ #define MIK_CMD_DEPLOY_DONE 0x21
262
+ #define MIK_CMD_DEPLOY_ABORT 0x22
263
+ #define MIK_CMD_DEPLOY_ERASE 0x23
264
+ /* PUT_CHUNK payload: file bytes (1..N). Appended to the file opened by the
265
+ * preceding PUT; closed automatically when total_remaining reaches zero. */
266
+ #define MIK_CMD_DEPLOY_PUT_CHUNK 0x24
267
+ /* 0x25 formerly MIK_CMD_DEPLOY_ENV_CLEAR — no longer needed; deploy diffs env via CONFIG_DELETE */
268
+ #define MIK_CMD_DEPLOY_KEEP 0x26
269
+ #define MIK_CMD_DEPLOY_CHECKSUM 0x27
270
+ #define MIK_CMD_RESTART 0x28
271
+ #define MIK_CMD_RUNTIME_PAUSE 0x29
272
+ #define MIK_CMD_RUNTIME_RESUME 0x2A
273
+
274
+ #define MIK_CMD_CONFIG_LIST 0x40
275
+ #define MIK_CMD_CONFIG_SET 0x41
276
+ #define MIK_CMD_CONFIG_DELETE 0x42
277
+
278
+ /* Env entry flags */
279
+ #define MIK_ENV_FLAG_SECRET 0x01
280
+
281
+
@@ -0,0 +1,125 @@
1
+
2
+ #pragma once
3
+
4
+ #include <mikrojs/cutils_wrap.h>
5
+ #include <quickjs.h>
6
+
7
+ #ifndef countof
8
+ #define countof(x) (sizeof(x) / sizeof((x)[0]))
9
+ #endif
10
+
11
+ struct AssertionInfo {
12
+ const char* file_line; // filename:line
13
+ const char* message;
14
+ const char* function;
15
+ };
16
+
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); \
22
+ } while (0)
23
+
24
+ #define MIK__LIKELY(expr) __builtin_expect(!!(expr), 1)
25
+ #define MIK__UNLIKELY(expr) __builtin_expect(!!(expr), 0)
26
+ #define PRETTY_FUNCTION_NAME __PRETTY_FUNCTION__
27
+
28
+ #define STRINGIFY_(x) #x
29
+ #define STRINGIFY(x) STRINGIFY_(x)
30
+
31
+ #define CHECK(expr) \
32
+ do { \
33
+ if (MIK__UNLIKELY(!(expr))) { \
34
+ ERROR_AND_ABORT(expr); \
35
+ } \
36
+ } while (0)
37
+
38
+ #define CHECK_EQ(a, b) CHECK((a) == (b))
39
+ #define CHECK_GE(a, b) CHECK((a) >= (b))
40
+ #define CHECK_GT(a, b) CHECK((a) > (b))
41
+ #define CHECK_LE(a, b) CHECK((a) <= (b))
42
+ #define CHECK_LT(a, b) CHECK((a) < (b))
43
+ #define CHECK_NE(a, b) CHECK((a) != (b))
44
+ #define CHECK_NULL(val) CHECK((val) == NULL)
45
+ #define CHECK_NOT_NULL(val) CHECK((val) != NULL)
46
+
47
+ void mik_assert(const struct AssertionInfo info);
48
+
49
+ #define MIK_CONST(x) JS_PROP_INT32_DEF(#x, x, JS_PROP_ENUMERABLE)
50
+ #define MIK_CONST2(name, val) JS_PROP_INT32_DEF(name, val, JS_PROP_ENUMERABLE)
51
+ #define MIK_CFUNC_DEF(name, length, func1) \
52
+ { \
53
+ name, JS_PROP_C_W_E, JS_DEF_CFUNC, 0, { \
54
+ .func = { length, JS_CFUNC_generic, {.generic = func1} } \
55
+ } \
56
+ }
57
+ #define MIK_CFUNC_MAGIC_DEF(name, length, func1, magic) \
58
+ { \
59
+ name, JS_PROP_C_W_E, JS_DEF_CFUNC, magic, { \
60
+ .func = { length, JS_CFUNC_generic_magic, {.generic_magic = func1} } \
61
+ } \
62
+ }
63
+ #define MIK_CGETSET_DEF(name, fgetter, fsetter) \
64
+ { \
65
+ name, JS_PROP_C_W_E, JS_DEF_CGETSET, 0, { \
66
+ .getset = {.get = {.getter = fgetter}, .set = {.setter = fsetter} } \
67
+ } \
68
+ }
69
+
70
+ void mik_call_handler(JSContext* ctx, JSValue func, int argc, JSValue* argv);
71
+ void mik_dump_error(JSContext* ctx);
72
+ void mik_dump_error1(JSContext* ctx, JSValue exception_val);
73
+
74
+ typedef struct {
75
+ JSValue p;
76
+ JSValue rfuncs[2];
77
+ } MIKPromise;
78
+
79
+ JSValue MIK_InitPromise(JSContext* ctx, MIKPromise* p);
80
+ bool MIK_IsPromisePending(JSContext* ctx, MIKPromise* p);
81
+ void MIK_FreePromise(JSContext* ctx, MIKPromise* p);
82
+ void MIK_FreePromiseRT(JSRuntime* rt, MIKPromise* p);
83
+ void MIK_ClearPromise(JSContext* ctx, MIKPromise* p);
84
+ void MIK_MarkPromise(JSRuntime* rt, MIKPromise* p, JS_MarkFunc* mark_func);
85
+ void MIK_SettlePromise(JSContext* ctx, MIKPromise* p, bool is_reject, int argc, JSValue* argv);
86
+ void MIK_ResolvePromise(JSContext* ctx, MIKPromise* p, int argc, JSValue* argv);
87
+ void MIK_RejectPromise(JSContext* ctx, MIKPromise* p, int argc, JSValue* argv);
88
+ JSValue MIK_NewResolvedPromise(JSContext* ctx, int argc, JSValue* argv);
89
+ JSValue MIK_NewRejectedPromise(JSContext* ctx, int argc, JSValue* argv);
90
+
91
+ JSValue MIK_NewUint8Array(JSContext* ctx, uint8_t* data, size_t size);
92
+
93
+ #define MIK_THROW_ARG_ERR(ctx, argno, expected) \
94
+ JS_ThrowTypeError(ctx, "expected argument %d to be %s", argno + 1, expected)
95
+ #define MIK_CHECK_ARG_RET(ctx, check, argno, expected) \
96
+ if (!(check)) { \
97
+ return MIK_THROW_ARG_ERR(ctx, argno, expected); \
98
+ }
99
+
100
+ void mik_dbuf_init(JSContext* ctx, DynBuf* s);
101
+
102
+ /* ── Native result helpers ───────────────────────────────────────── */
103
+ /* Return {ok: true, value: <val>} or {ok: true} (void)
104
+ * or {ok: false, error: {code: 0x8xxx, message: "...", errno?: 0x...}}
105
+ * or {ok: false, error: {name: "VariantName", message: "..."}} (named variant)
106
+ * or {ok: false, error: {name: "VariantName"}} (tag-only variant)
107
+ *
108
+ * Implemented in mik_result.cpp. The returned objects have the shared
109
+ * Result prototype installed, so user code can chain .map/.match/etc.
110
+ *
111
+ * The `_named` / `_tag` forms produce error objects the JS layer can use
112
+ * directly without a code-to-variant remap — keeps mikrojs/X wrappers as
113
+ * pure re-exports of native:X. */
114
+
115
+ JSValue mik__result_ok(JSContext* ctx, JSValue value);
116
+ JSValue mik__result_ok_void(JSContext* ctx);
117
+ JSValue mik__result_err(JSContext* ctx, int code, int platform_errno, const char* fmt, ...)
118
+ __attribute__((format(printf, 4, 5)));
119
+ JSValue mik__result_err_named(JSContext* ctx, const char* name, const char* fmt, ...)
120
+ __attribute__((format(printf, 3, 4)));
121
+ JSValue mik__result_err_tag(JSContext* ctx, const char* name);
122
+ /* Wrap an already-built error object (any shape) in a Result. Caller passes
123
+ * ownership of `error_obj`. For variants with extra fields beyond
124
+ * {name, message} — path, code, limit, etc. */
125
+ JSValue mik__result_err_obj(JSContext* ctx, JSValue error_obj);
package/package.json ADDED
@@ -0,0 +1,100 @@
1
+ {
2
+ "name": "@mikrojs/native",
3
+ "version": "0.0.7",
4
+ "description": "Mikro.js C++ runtime library and Node.js native addon",
5
+ "keywords": [
6
+ "esp32",
7
+ "mikrojs",
8
+ "native",
9
+ "quickjs",
10
+ "runtime"
11
+ ],
12
+ "homepage": "https://github.com/mikrojs/mikrojs#readme",
13
+ "bugs": {
14
+ "url": "https://github.com/mikrojs/mikrojs/issues"
15
+ },
16
+ "license": "MIT",
17
+ "author": "Bjørge Næss <bjoerge@gmail.com>",
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "git+https://github.com/mikrojs/mikrojs.git"
21
+ },
22
+ "files": [
23
+ "dist",
24
+ "prebuilds",
25
+ "cmake",
26
+ "cmake.js",
27
+ "CMakeLists.txt",
28
+ "include",
29
+ "runtime",
30
+ "scripts",
31
+ "src",
32
+ "!**/__test__",
33
+ "!**/*.test.ts",
34
+ "!**/*.test.tsx",
35
+ "!**/*.test-d.ts"
36
+ ],
37
+ "os": [
38
+ "darwin",
39
+ "linux"
40
+ ],
41
+ "type": "module",
42
+ "sideEffects": false,
43
+ "exports": {
44
+ ".": "./dist/index.js",
45
+ "./cmake": "./cmake.js",
46
+ "./package.json": "./package.json",
47
+ "./runtime/ble/types": "./runtime/ble/types.ts",
48
+ "./runtime/cbor/types": "./runtime/cbor/types.ts",
49
+ "./runtime/console/types": "./runtime/console/types.ts",
50
+ "./runtime/env/types": "./runtime/env/types.ts",
51
+ "./runtime/format/types": "./runtime/format/types.ts",
52
+ "./runtime/http/helpers": "./runtime/http/helpers.ts",
53
+ "./runtime/fs/types": "./runtime/fs/types.ts",
54
+ "./runtime/i2c/types": "./runtime/i2c/types.ts",
55
+ "./runtime/inspect/types": "./runtime/inspect/types.ts",
56
+ "./runtime/kv/shared": "./runtime/kv/shared.ts",
57
+ "./runtime/kv/types": "./runtime/kv/types.ts",
58
+ "./runtime/neopixel/types": "./runtime/neopixel/types.ts",
59
+ "./runtime/pin/types": "./runtime/pin/types.ts",
60
+ "./runtime/pwm/types": "./runtime/pwm/types.ts",
61
+ "./runtime/reader/types": "./runtime/reader/types.ts",
62
+ "./runtime/result/types": "./runtime/result/types.ts",
63
+ "./runtime/schema/types": "./runtime/schema/types.ts",
64
+ "./runtime/sleep/types": "./runtime/sleep/types.ts",
65
+ "./runtime/sntp/types": "./runtime/sntp/types.ts",
66
+ "./runtime/spi/types": "./runtime/spi/types.ts",
67
+ "./runtime/stdio/types": "./runtime/stdio/types.ts",
68
+ "./runtime/stream/types": "./runtime/stream/types.ts",
69
+ "./runtime/sys/types": "./runtime/sys/types.ts",
70
+ "./runtime/test/types": "./runtime/test/types.ts",
71
+ "./runtime/uart/types": "./runtime/uart/types.ts",
72
+ "./runtime/wifi/types": "./runtime/wifi/types.ts"
73
+ },
74
+ "dependencies": {
75
+ "cmake-js": "^8.0.0",
76
+ "node-addon-api": "^8.7.0",
77
+ "node-gyp-build": "^4.8.4",
78
+ "@mikrojs/quickjs": "0.0.7"
79
+ },
80
+ "devDependencies": {
81
+ "@swc/core": "^1.15.30",
82
+ "@types/node": "^25.6.0",
83
+ "esbuild": "^0.28.0",
84
+ "terser": "^5.46.2"
85
+ },
86
+ "engines": {
87
+ "node": ">=24.0.0"
88
+ },
89
+ "scripts": {
90
+ "bench": "cmake -B build -DBUILD_TESTING=ON && cmake --build build --target memory_bench &&./build/memory_bench",
91
+ "build:native": "cmake-js compile --directory addon && node scripts/copy-prebuild.js",
92
+ "build:native:debug": "cmake-js compile --debug --directory addon && node scripts/copy-prebuild.js",
93
+ "build:ts": "tsc -p tsconfig.build.json",
94
+ "clean": "cmake-js clean --directory addon && rm -rf prebuilds",
95
+ "compare-minifiers": "node scripts/compare-minifiers.js --open",
96
+ "publint": "publint",
97
+ "typecheck": "tsc --noEmit -p tsconfig.addon.json && tsc --noEmit -p tsconfig.runtime.json",
98
+ "watch": "node --experimental-strip-types watch.ts"
99
+ }
100
+ }