@mikrojs/native 0.18.0 → 0.18.1

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 (68) hide show
  1. package/CMakeLists.txt +62 -1
  2. package/dist/index.d.ts +17 -0
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +11 -0
  5. package/dist/index.js.map +1 -1
  6. package/dist/runtime/result/native-result.node-shim.d.ts +3 -0
  7. package/dist/runtime/result/native-result.node-shim.d.ts.map +1 -0
  8. package/dist/runtime/result/native-result.node-shim.js +41 -0
  9. package/dist/runtime/result/native-result.node-shim.js.map +1 -0
  10. package/dist/runtime/result/types.d.ts +55 -0
  11. package/dist/runtime/result/types.d.ts.map +1 -0
  12. package/dist/runtime/result/types.js +2 -0
  13. package/dist/runtime/result/types.js.map +1 -0
  14. package/dist/runtime/schema/core.d.ts +115 -0
  15. package/dist/runtime/schema/core.d.ts.map +1 -0
  16. package/dist/runtime/schema/core.js +259 -0
  17. package/dist/runtime/schema/core.js.map +1 -0
  18. package/dist/runtime/schema/shared.d.ts +54 -0
  19. package/dist/runtime/schema/shared.d.ts.map +1 -0
  20. package/dist/runtime/schema/shared.js +489 -0
  21. package/dist/runtime/schema/shared.js.map +1 -0
  22. package/dist/types.d.ts +7 -0
  23. package/dist/types.d.ts.map +1 -1
  24. package/include/mikrojs/cbor_helpers.h +20 -0
  25. package/include/mikrojs/mem.h +11 -0
  26. package/include/mikrojs/mikrojs.h +2 -1
  27. package/include/mikrojs/ota_client.h +342 -0
  28. package/include/mikrojs/ota_config.h +100 -0
  29. package/include/mikrojs/ota_env.h +192 -0
  30. package/include/mikrojs/ota_js_hooks.h +71 -0
  31. package/include/mikrojs/ota_policy.h +131 -0
  32. package/include/mikrojs/ota_slots.h +47 -0
  33. package/include/mikrojs/sys_codec.h +61 -0
  34. package/package.json +7 -5
  35. package/prebuilds/darwin-arm64/mikrojs.napi.node +0 -0
  36. package/prebuilds/linux-arm64/mikrojs.napi.node +0 -0
  37. package/prebuilds/linux-x64/mikrojs.napi.node +0 -0
  38. package/runtime/internal.d.ts +22 -16
  39. package/runtime/kv/shared.ts +11 -5
  40. package/runtime/kv/types.ts +4 -4
  41. package/runtime/ota/client.ts +12 -51
  42. package/runtime/ota/config.ts +18 -0
  43. package/runtime/ota/ota.ts +28 -70
  44. package/runtime/ota/types.ts +220 -2
  45. package/runtime/schema/core.ts +539 -0
  46. package/runtime/schema/schema.ts +36 -314
  47. package/runtime/schema/shared.ts +494 -0
  48. package/runtime/schema/types.ts +84 -12
  49. package/scripts/bundle-runtime.js +33 -0
  50. package/scripts/gen-checkin-fixtures.js +323 -0
  51. package/src/builtins.cpp +7 -8
  52. package/src/fs.cpp +3 -0
  53. package/src/mem.cpp +38 -0
  54. package/src/mik_abort.cpp +8 -1
  55. package/src/mik_cbor.cpp +43 -5
  56. package/src/mik_inspect.cpp +128 -22
  57. package/src/mik_ota_client.cpp +1230 -0
  58. package/src/mik_ota_config.cpp +296 -0
  59. package/src/mik_ota_js_hooks.cpp +190 -0
  60. package/src/mik_ota_policy.cpp +419 -0
  61. package/src/mik_ota_slots.cpp +249 -0
  62. package/src/mik_repl.cpp +9 -3
  63. package/src/mik_result.cpp +3 -1
  64. package/src/mik_sys_codec.cpp +167 -0
  65. package/src/mikrojs.cpp +15 -0
  66. package/src/modules.cpp +32 -13
  67. package/runtime/ota/client-impl.ts +0 -590
  68. package/runtime/ota/policy.ts +0 -299
@@ -31,6 +31,19 @@ static std::string stylize(const std::string& value, MikThemeToken token, const
31
31
  return value;
32
32
  }
33
33
 
34
+ /* User getters, proxy traps and inspect hooks can throw while inspect reads
35
+ * values; drain the exception so inspect never leaves one pending. */
36
+ static void drain_exception(JSContext* ctx) {
37
+ JSValue exc = JS_GetException(ctx);
38
+ JS_FreeValue(ctx, exc);
39
+ }
40
+
41
+ /* Placeholder rendered where a property read threw */
42
+ static std::string getter_threw(JSContext* ctx, const InspectOpts& opts) {
43
+ drain_exception(ctx);
44
+ return stylize("[getter threw]", MIK_TOKEN_ERROR, opts);
45
+ }
46
+
34
47
  static std::string truncate_str(const std::string& str, int max_len) {
35
48
  if (max_len <= 0) return TRUNCATOR;
36
49
  int slen = static_cast<int>(str.size());
@@ -101,10 +114,13 @@ static bool try_custom_inspect(JSContext* ctx, JSValue value, InspectOpts& opts,
101
114
 
102
115
  bool used = false;
103
116
 
104
- if (!JS_IsException(inspect_sym)) {
117
+ if (JS_IsException(inspect_sym)) {
118
+ drain_exception(ctx);
119
+ } else {
105
120
  JSAtom sym_atom = JS_ValueToAtom(ctx, inspect_sym);
106
121
  JSValue custom_fn = JS_GetProperty(ctx, value, sym_atom);
107
122
  JS_FreeAtom(ctx, sym_atom);
123
+ if (JS_IsException(custom_fn)) drain_exception(ctx);
108
124
 
109
125
  if (JS_IsFunction(ctx, custom_fn)) {
110
126
  /* Set up callback state and create the inspect helper */
@@ -120,6 +136,8 @@ static bool try_custom_inspect(JSContext* ctx, JSValue value, InspectOpts& opts,
120
136
 
121
137
  s_inspect_opts = prev_opts;
122
138
 
139
+ if (JS_IsException(result)) drain_exception(ctx);
140
+
123
141
  if (JS_IsString(result)) {
124
142
  const char* str = JS_ToCString(ctx, result);
125
143
  if (str) {
@@ -197,7 +215,10 @@ static std::string get_object_type(JSContext* ctx, JSValue value) {
197
215
  JSValue result = JS_Call(ctx, to_string, value, 0, nullptr);
198
216
 
199
217
  std::string type;
200
- if (!JS_IsException(result)) {
218
+ if (JS_IsException(result)) {
219
+ /* A throwing Symbol.toStringTag getter or proxy trap */
220
+ drain_exception(ctx);
221
+ } else {
201
222
  const char* str = JS_ToCString(ctx, result);
202
223
  if (str) {
203
224
  /* Extract "Foo" from "[object Foo]" */
@@ -239,7 +260,11 @@ static std::string inspect_array_items(JSContext* ctx, JSValue arr, uint32_t len
239
260
  for (uint32_t i = 0; i < len; i++) {
240
261
  if (i > 0) out += ", ";
241
262
  JSValue item = JS_GetPropertyUint32(ctx, arr, i);
242
- out += inspect_value(ctx, item, opts, depth);
263
+ if (JS_IsException(item)) {
264
+ out += getter_threw(ctx, opts);
265
+ } else {
266
+ out += inspect_value(ctx, item, opts, depth);
267
+ }
243
268
  JS_FreeValue(ctx, item);
244
269
  }
245
270
  return out;
@@ -259,6 +284,7 @@ static std::string inspect_properties(JSContext* ctx, JSValue obj, InspectOpts&
259
284
  }
260
285
 
261
286
  if (JS_GetOwnPropertyNames(ctx, &ptab, &plen, obj, flags) != 0) {
287
+ drain_exception(ctx);
262
288
  return "";
263
289
  }
264
290
 
@@ -289,7 +315,11 @@ static std::string inspect_properties(JSContext* ctx, JSValue obj, InspectOpts&
289
315
  JSValue val = JS_GetPropertyStr(ctx, obj, key);
290
316
  out += quote_key(key);
291
317
  out += ": ";
292
- out += inspect_value(ctx, val, opts, depth);
318
+ if (JS_IsException(val)) {
319
+ out += getter_threw(ctx, opts);
320
+ } else {
321
+ out += inspect_value(ctx, val, opts, depth);
322
+ }
293
323
  JS_FreeValue(ctx, val);
294
324
  }
295
325
 
@@ -336,7 +366,8 @@ static std::string inspect_string(JSContext* ctx, JSValue value, InspectOpts& op
336
366
 
337
367
  static std::string inspect_function(JSContext* ctx, JSValue value, InspectOpts& opts) {
338
368
  JSValue name_val = JS_GetPropertyStr(ctx, value, "name");
339
- const char* name = JS_ToCString(ctx, name_val);
369
+ if (JS_IsException(name_val)) drain_exception(ctx);
370
+ const char* name = JS_IsException(name_val) ? nullptr : JS_ToCString(ctx, name_val);
340
371
  std::string result;
341
372
 
342
373
  /* Check for Symbol.toStringTag */
@@ -347,6 +378,7 @@ static std::string inspect_function(JSContext* ctx, JSValue value, InspectOpts&
347
378
  if (!JS_IsUndefined(tag_sym)) {
348
379
  JSAtom tag_atom = JS_ValueToAtom(ctx, tag_sym);
349
380
  JSValue tag_val = JS_GetProperty(ctx, value, tag_atom);
381
+ if (JS_IsException(tag_val)) drain_exception(ctx);
350
382
  if (JS_IsString(tag_val)) {
351
383
  const char* tag = JS_ToCString(ctx, tag_val);
352
384
  if (tag) {
@@ -374,14 +406,20 @@ static std::string inspect_function(JSContext* ctx, JSValue value, InspectOpts&
374
406
  }
375
407
 
376
408
  static std::string inspect_symbol(JSContext* ctx, JSValue value, InspectOpts& opts) {
377
- const char* str = JS_ToCString(ctx, value);
378
- std::string result;
379
- if (str) {
380
- result = str;
381
- JS_FreeCString(ctx, str);
382
- } else {
383
- result = "Symbol()";
409
+ /* ToString throws on symbols; read the boxed description getter instead */
410
+ JSValue desc_val = JS_GetPropertyStr(ctx, value, "description");
411
+ std::string result = "Symbol(";
412
+ if (JS_IsString(desc_val)) {
413
+ const char* desc = JS_ToCString(ctx, desc_val);
414
+ if (desc) {
415
+ result += desc;
416
+ JS_FreeCString(ctx, desc);
417
+ }
418
+ } else if (JS_IsException(desc_val)) {
419
+ JS_FreeValue(ctx, JS_GetException(ctx));
384
420
  }
421
+ result += ")";
422
+ JS_FreeValue(ctx, desc_val);
385
423
  return stylize(result, MIK_TOKEN_SYMBOL, opts);
386
424
  }
387
425
 
@@ -399,9 +437,15 @@ static std::string inspect_bigint(JSContext* ctx, JSValue value, InspectOpts& op
399
437
 
400
438
  static std::string inspect_date(JSContext* ctx, JSValue value, InspectOpts& opts) {
401
439
  JSValue to_json = JS_GetPropertyStr(ctx, value, "toJSON");
440
+ if (JS_IsException(to_json)) drain_exception(ctx);
402
441
  if (JS_IsFunction(ctx, to_json)) {
403
442
  JSValue json_val = JS_Call(ctx, to_json, value, 0, nullptr);
404
443
  JS_FreeValue(ctx, to_json);
444
+ if (JS_IsException(json_val)) {
445
+ drain_exception(ctx);
446
+ JS_FreeValue(ctx, json_val);
447
+ return "Invalid Date";
448
+ }
405
449
  if (JS_IsNull(json_val) || JS_IsUndefined(json_val)) {
406
450
  JS_FreeValue(ctx, json_val);
407
451
  return "Invalid Date";
@@ -426,16 +470,19 @@ static std::string inspect_regexp(JSContext* ctx, JSValue value, InspectOpts& op
426
470
  JS_FreeCString(ctx, str);
427
471
  return stylize(result, MIK_TOKEN_REGEXP, opts);
428
472
  }
473
+ drain_exception(ctx);
429
474
  return stylize("/(?:)/", MIK_TOKEN_REGEXP, opts);
430
475
  }
431
476
 
432
477
  static std::string inspect_error(JSContext* ctx, JSValue value, InspectOpts& opts, int depth) {
433
478
  /* Get name and message */
434
479
  JSValue name_val = JS_GetPropertyStr(ctx, value, "name");
480
+ if (JS_IsException(name_val)) drain_exception(ctx);
435
481
  JSValue msg_val = JS_GetPropertyStr(ctx, value, "message");
482
+ if (JS_IsException(msg_val)) drain_exception(ctx);
436
483
 
437
- const char* name = JS_ToCString(ctx, name_val);
438
- const char* msg = JS_ToCString(ctx, msg_val);
484
+ const char* name = JS_IsException(name_val) ? nullptr : JS_ToCString(ctx, name_val);
485
+ const char* msg = JS_IsException(msg_val) ? nullptr : JS_ToCString(ctx, msg_val);
439
486
 
440
487
  std::string result;
441
488
  if (name) result = name;
@@ -467,7 +514,11 @@ static std::string inspect_error(JSContext* ctx, JSValue value, InspectOpts& opt
467
514
  static std::string inspect_array(JSContext* ctx, JSValue value, InspectOpts& opts, int depth) {
468
515
  JSValue len_val = JS_GetPropertyStr(ctx, value, "length");
469
516
  uint32_t len = 0;
470
- JS_ToUint32(ctx, &len, len_val);
517
+ if (JS_IsException(len_val)) {
518
+ drain_exception(ctx);
519
+ } else {
520
+ JS_ToUint32(ctx, &len, len_val);
521
+ }
471
522
  JS_FreeValue(ctx, len_val);
472
523
 
473
524
  if (len == 0) {
@@ -484,6 +535,7 @@ static std::string inspect_array(JSContext* ctx, JSValue value, InspectOpts& opt
484
535
  js_free(ctx, ptab);
485
536
  if (!has_non_index) return "[]";
486
537
  } else {
538
+ drain_exception(ctx);
487
539
  return "[]";
488
540
  }
489
541
  }
@@ -502,7 +554,11 @@ static std::string inspect_array(JSContext* ctx, JSValue value, InspectOpts& opt
502
554
  static std::string inspect_map(JSContext* ctx, JSValue value, InspectOpts& opts, int depth) {
503
555
  JSValue size_val = JS_GetPropertyStr(ctx, value, "size");
504
556
  int32_t size = 0;
505
- JS_ToInt32(ctx, &size, size_val);
557
+ if (JS_IsException(size_val)) {
558
+ drain_exception(ctx);
559
+ } else {
560
+ JS_ToInt32(ctx, &size, size_val);
561
+ }
506
562
  JS_FreeValue(ctx, size_val);
507
563
 
508
564
  if (size <= 0) return "Map{}";
@@ -515,12 +571,24 @@ static std::string inspect_map(JSContext* ctx, JSValue value, InspectOpts& opts,
515
571
  JSValue iterator = JS_Call(ctx, entries_fn, value, 0, nullptr);
516
572
  JS_FreeValue(ctx, entries_fn);
517
573
 
574
+ if (JS_IsException(iterator)) {
575
+ drain_exception(ctx);
576
+ JS_FreeValue(ctx, iterator);
577
+ opts.seen.pop_back();
578
+ return "Map{}";
579
+ }
580
+
518
581
  JSValue next_fn = JS_GetPropertyStr(ctx, iterator, "next");
519
582
 
520
583
  std::string items;
521
584
  bool first = true;
522
585
  for (int i = 0; i < size; i++) {
523
586
  JSValue step = JS_Call(ctx, next_fn, iterator, 0, nullptr);
587
+ if (JS_IsException(step)) {
588
+ drain_exception(ctx);
589
+ JS_FreeValue(ctx, step);
590
+ break;
591
+ }
524
592
  JSValue done = JS_GetPropertyStr(ctx, step, "done");
525
593
  if (JS_ToBool(ctx, done)) {
526
594
  JS_FreeValue(ctx, done);
@@ -556,7 +624,11 @@ static std::string inspect_map(JSContext* ctx, JSValue value, InspectOpts& opts,
556
624
  static std::string inspect_set(JSContext* ctx, JSValue value, InspectOpts& opts, int depth) {
557
625
  JSValue size_val = JS_GetPropertyStr(ctx, value, "size");
558
626
  int32_t size = 0;
559
- JS_ToInt32(ctx, &size, size_val);
627
+ if (JS_IsException(size_val)) {
628
+ drain_exception(ctx);
629
+ } else {
630
+ JS_ToInt32(ctx, &size, size_val);
631
+ }
560
632
  JS_FreeValue(ctx, size_val);
561
633
 
562
634
  if (size == 0) return "Set{}";
@@ -574,10 +646,22 @@ static std::string inspect_set(JSContext* ctx, JSValue value, InspectOpts& opts,
574
646
  JS_FreeValue(ctx, values_fn);
575
647
  JS_FreeValue(ctx, for_each_fn);
576
648
 
649
+ if (JS_IsException(iterator)) {
650
+ drain_exception(ctx);
651
+ JS_FreeValue(ctx, iterator);
652
+ opts.seen.pop_back();
653
+ return "Set{}";
654
+ }
655
+
577
656
  JSValue next_fn = JS_GetPropertyStr(ctx, iterator, "next");
578
657
  bool first = true;
579
658
  for (int i = 0; i < size; i++) {
580
659
  JSValue step = JS_Call(ctx, next_fn, iterator, 0, nullptr);
660
+ if (JS_IsException(step)) {
661
+ drain_exception(ctx);
662
+ JS_FreeValue(ctx, step);
663
+ break;
664
+ }
581
665
  JSValue done = JS_GetPropertyStr(ctx, step, "done");
582
666
  if (JS_ToBool(ctx, done)) {
583
667
  JS_FreeValue(ctx, done);
@@ -608,11 +692,16 @@ static std::string inspect_typed_array(JSContext* ctx, JSValue value, const std:
608
692
  size_t byte_offset;
609
693
  size_t bytes_per_element;
610
694
  JSValue buffer = JS_GetTypedArrayBuffer(ctx, value, &byte_offset, &byte_length, &bytes_per_element);
695
+ if (JS_IsException(buffer)) drain_exception(ctx);
611
696
  JS_FreeValue(ctx, buffer);
612
697
 
613
698
  JSValue len_val = JS_GetPropertyStr(ctx, value, "length");
614
699
  uint32_t len = 0;
615
- JS_ToUint32(ctx, &len, len_val);
700
+ if (JS_IsException(len_val)) {
701
+ drain_exception(ctx);
702
+ } else {
703
+ JS_ToUint32(ctx, &len, len_val);
704
+ }
616
705
  JS_FreeValue(ctx, len_val);
617
706
 
618
707
  if (len == 0) return type_name + "[]";
@@ -621,6 +710,11 @@ static std::string inspect_typed_array(JSContext* ctx, JSValue value, const std:
621
710
  for (uint32_t i = 0; i < len; i++) {
622
711
  if (i > 0) items += ", ";
623
712
  JSValue elem = JS_GetPropertyUint32(ctx, value, i);
713
+ if (JS_IsException(elem)) {
714
+ JS_FreeValue(ctx, elem);
715
+ items += getter_threw(ctx, opts);
716
+ continue;
717
+ }
624
718
  const char* str = JS_ToCString(ctx, elem);
625
719
  JS_FreeValue(ctx, elem);
626
720
  items += stylize(str ? str : "0", MIK_TOKEN_NUMBER, opts);
@@ -642,6 +736,7 @@ static std::string inspect_object(JSContext* ctx, JSValue value, InspectOpts& op
642
736
  }
643
737
 
644
738
  if (JS_GetOwnPropertyNames(ctx, &ptab, &plen, value, flags) != 0) {
739
+ drain_exception(ctx);
645
740
  return "{}";
646
741
  }
647
742
  for (uint32_t i = 0; i < plen; i++) {
@@ -665,9 +760,12 @@ static std::string inspect_class(JSContext* ctx, JSValue value, const std::strin
665
760
 
666
761
  if (name.empty() || name == "Object") {
667
762
  JSValue ctor = JS_GetPropertyStr(ctx, value, "constructor");
763
+ if (JS_IsException(ctor)) drain_exception(ctx);
668
764
  if (JS_IsFunction(ctx, ctor)) {
669
765
  JSValue ctor_name = JS_GetPropertyStr(ctx, ctor, "name");
670
- const char* n = JS_ToCString(ctx, ctor_name);
766
+ if (JS_IsException(ctor_name)) drain_exception(ctx);
767
+ const char* n =
768
+ JS_IsException(ctor_name) ? nullptr : JS_ToCString(ctx, ctor_name);
671
769
  if (n && n[0] && strcmp(n, "Object") != 0) {
672
770
  name = n;
673
771
  }
@@ -720,7 +818,11 @@ static std::string inspect_value(JSContext* ctx, JSValue value, InspectOpts& opt
720
818
  if (JS_IsArray(value)) {
721
819
  JSValue len_val = JS_GetPropertyStr(ctx, value, "length");
722
820
  uint32_t len = 0;
723
- JS_ToUint32(ctx, &len, len_val);
821
+ if (JS_IsException(len_val)) {
822
+ drain_exception(ctx);
823
+ } else {
824
+ JS_ToUint32(ctx, &len, len_val);
825
+ }
724
826
  JS_FreeValue(ctx, len_val);
725
827
  char buf[32];
726
828
  snprintf(buf, sizeof(buf), "[Array(%u)]", len);
@@ -775,6 +877,7 @@ static std::string inspect_value(JSContext* ctx, JSValue value, InspectOpts& opt
775
877
 
776
878
  /* Plain object vs class instance */
777
879
  JSValue proto = JS_GetPrototype(ctx, value);
880
+ if (JS_IsException(proto)) drain_exception(ctx);
778
881
  JSValue global = JS_GetGlobalObject(ctx);
779
882
  JSValue obj_ctor = JS_GetPropertyStr(ctx, global, "Object");
780
883
  JSValue obj_proto = JS_GetPropertyStr(ctx, obj_ctor, "prototype");
@@ -816,6 +919,7 @@ static JSValue mik__inspect_js(JSContext* ctx, JSValue this_val, int argc, JSVal
816
919
 
817
920
  if (argc >= 2 && JS_IsObject(argv[1])) {
818
921
  JSValue d = JS_GetPropertyStr(ctx, argv[1], "depth");
922
+ if (JS_IsException(d)) drain_exception(ctx);
819
923
  if (JS_IsNumber(d)) {
820
924
  int32_t d32;
821
925
  JS_ToInt32(ctx, &d32, d);
@@ -824,11 +928,13 @@ static JSValue mik__inspect_js(JSContext* ctx, JSValue this_val, int argc, JSVal
824
928
  JS_FreeValue(ctx, d);
825
929
 
826
930
  JSValue c = JS_GetPropertyStr(ctx, argv[1], "colors");
827
- if (!JS_IsUndefined(c)) colors = JS_ToBool(ctx, c);
931
+ if (JS_IsException(c)) drain_exception(ctx);
932
+ else if (!JS_IsUndefined(c)) colors = JS_ToBool(ctx, c);
828
933
  JS_FreeValue(ctx, c);
829
934
 
830
935
  JSValue h = JS_GetPropertyStr(ctx, argv[1], "showHidden");
831
- if (!JS_IsUndefined(h)) show_hidden = JS_ToBool(ctx, h);
936
+ if (JS_IsException(h)) drain_exception(ctx);
937
+ else if (!JS_IsUndefined(h)) show_hidden = JS_ToBool(ctx, h);
832
938
  JS_FreeValue(ctx, h);
833
939
  }
834
940