quickjs 0.1.13 → 0.2.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 12a5b713531ad393cb5d16486516f3288eb2b9c88931b8db5fa440a4701393df
4
- data.tar.gz: c780fe075e29223e90a4f0183b02506ed2209ed2f17dd33e9e734e753a9b0b3d
3
+ metadata.gz: 30027c93cb2dd5dbb85d43ab40700f7ee06679a824b503bee42786a42bc5dc26
4
+ data.tar.gz: 51c60a962c82bbbbaa3a3fc4202255809751848d1474f9a4e9f6b7ebe4df0277
5
5
  SHA512:
6
- metadata.gz: 524a227ede71099f8da470ae3178df0c63fab2613cb3e9a37ec0215d462dab2fbbb52f69449273cf58ffc58758dbab8743be624c75ce0818335e86b312e49bda
7
- data.tar.gz: 9602f54b31a71163ce054aaad3b6da4b5e00d1866b63e98617971d3279ba3a5cef9c8aa2ade1e130dd4499c121c62cc94a8a48dc3eba92a8eaf7bd1a2093ef56
6
+ metadata.gz: e1f248cbafcc56ceba481f658aae542660ac8de6036b7fc1e9425e5f214f4f51a918a3051b82e796a075ed83726f59ba6b8dcc85e8b1c38ee1369b089ebd410a
7
+ data.tar.gz: 7c7346da3a318d3ed07bfd490561ced7deda800678bda0cb23c4f2b19b84b9720191a7999a7d9a5225d91d4c2140b7fffae03f16d75b791cd4d3b746bbab50a9
data/README.md CHANGED
@@ -104,6 +104,16 @@ vm = Quickjs::VM.new(
104
104
  )
105
105
  ```
106
106
 
107
+ #### ⚡️ Import ESM from source
108
+
109
+ ```rb
110
+ vm = Quickjs::VM.new
111
+ vm.import({ default: 'aliasedDefault', member: 'member' }, from: File.read('exports.esm.js'))
112
+
113
+ vm.eval_code("aliasedDefault()") #=> Exported `default` of the ESM is called
114
+ vm.eval_code("member()") #=> Exported `member` of the ESM is called
115
+ ```
116
+
107
117
  #### ⚡️ Define a global function for JS by Ruby
108
118
 
109
119
  ```rb
@@ -191,7 +191,7 @@ VALUE to_rb_value(JSContext *ctx, JSValue j_val)
191
191
  if (promiseState != -1)
192
192
  {
193
193
  VALUE r_error_message = rb_str_new2("cannot translate a Promise to Ruby. await within JavaScript's end");
194
- rb_exc_raise(rb_exc_new_str(rb_eRuntimeError, r_error_message));
194
+ rb_exc_raise(rb_funcall(rb_cQuickjsRuntimeError, rb_intern("new"), 2, r_error_message, Qnil));
195
195
  return Qnil;
196
196
  }
197
197
 
@@ -229,43 +229,35 @@ VALUE to_rb_value(JSContext *ctx, JSValue j_val)
229
229
  JS_FreeValue(ctx, j_errorClassMessage);
230
230
  JS_FreeValue(ctx, j_errorClassName);
231
231
 
232
- VALUE r_error_message = rb_sprintf("%s: %s", errorClassName, errorClassMessage);
233
- VALUE r_error_class = rb_eRuntimeError;
232
+ VALUE r_error_class, r_error_message = rb_str_new2(errorClassMessage);
234
233
 
235
234
  if (strcmp(errorClassName, "SyntaxError") == 0)
236
235
  {
237
236
  r_error_class = rb_cQuickjsSyntaxError;
238
- r_error_message = rb_str_new2(errorClassMessage);
239
237
  }
240
238
  else if (strcmp(errorClassName, "TypeError") == 0)
241
239
  {
242
240
  r_error_class = rb_cQuickjsTypeError;
243
- r_error_message = rb_str_new2(errorClassMessage);
244
241
  }
245
242
  else if (strcmp(errorClassName, "ReferenceError") == 0)
246
243
  {
247
244
  r_error_class = rb_cQuickjsReferenceError;
248
- r_error_message = rb_str_new2(errorClassMessage);
249
245
  }
250
246
  else if (strcmp(errorClassName, "RangeError") == 0)
251
247
  {
252
248
  r_error_class = rb_cQuickjsRangeError;
253
- r_error_message = rb_str_new2(errorClassMessage);
254
249
  }
255
250
  else if (strcmp(errorClassName, "EvalError") == 0)
256
251
  {
257
252
  r_error_class = rb_cQuickjsEvalError;
258
- r_error_message = rb_str_new2(errorClassMessage);
259
253
  }
260
254
  else if (strcmp(errorClassName, "URIError") == 0)
261
255
  {
262
256
  r_error_class = rb_cQuickjsURIError;
263
- r_error_message = rb_str_new2(errorClassMessage);
264
257
  }
265
258
  else if (strcmp(errorClassName, "AggregateError") == 0)
266
259
  {
267
260
  r_error_class = rb_cQuickjsAggregateError;
268
- r_error_message = rb_str_new2(errorClassMessage);
269
261
  }
270
262
  else if (strcmp(errorClassName, "InternalError") == 0 && strstr(errorClassMessage, "interrupted") != NULL)
271
263
  {
@@ -275,13 +267,16 @@ VALUE to_rb_value(JSContext *ctx, JSValue j_val)
275
267
  else if (strcmp(errorClassName, "Quickjs::InterruptedError") == 0)
276
268
  {
277
269
  r_error_class = rb_cQuickjsInterruptedError;
278
- r_error_message = rb_str_new2(errorClassMessage);
270
+ }
271
+ else
272
+ {
273
+ r_error_class = rb_cQuickjsRuntimeError;
279
274
  }
280
275
  JS_FreeCString(ctx, errorClassName);
281
276
  JS_FreeCString(ctx, errorClassMessage);
282
277
  JS_FreeValue(ctx, j_exceptionVal);
283
278
 
284
- rb_exc_raise(rb_exc_new_str(r_error_class, r_error_message));
279
+ rb_exc_raise(rb_funcall(r_error_class, rb_intern("new"), 2, r_error_message, rb_str_new2(errorClassName)));
285
280
  }
286
281
  else // exception without Error object
287
282
  {
@@ -290,7 +285,7 @@ VALUE to_rb_value(JSContext *ctx, JSValue j_val)
290
285
 
291
286
  JS_FreeCString(ctx, errorMessage);
292
287
  JS_FreeValue(ctx, j_exceptionVal);
293
- rb_exc_raise(rb_exc_new_str(rb_cQuickjsRuntimeError, r_error_message));
288
+ rb_exc_raise(rb_funcall(rb_cQuickjsRuntimeError, rb_intern("new"), 2, r_error_message, Qnil));
294
289
  }
295
290
  return Qnil;
296
291
  }
@@ -490,7 +485,7 @@ static VALUE vm_m_evalCode(VALUE r_self, VALUE r_code)
490
485
  JS_FreeValue(data->context, j_returnedValue);
491
486
  JS_FreeValue(data->context, j_awaitedResult);
492
487
  VALUE r_error_message = rb_str_new2("An unawaited Promise was returned to the top-level");
493
- rb_exc_raise(rb_exc_new_str(rb_cQuickjsNoAwaitError, r_error_message));
488
+ rb_exc_raise(rb_funcall(rb_cQuickjsNoAwaitError, rb_intern("new"), 2, r_error_message, Qnil));
494
489
  return Qnil;
495
490
  }
496
491
  else
@@ -530,11 +525,6 @@ static VALUE vm_m_defineGlobalFunction(VALUE r_self, VALUE r_name)
530
525
  return Qnil;
531
526
  }
532
527
 
533
- // WISH: vm.import('hey', from: '...source...') imports just default
534
- // WISH: vm.import('{ member, member2 }', from: '...source...')
535
- // WISH: vm.import('{ member as aliasedName }', from: '...source...')
536
- // WISH: vm.import('defaultMember, { member }', from: '...source...')
537
- // WISH: vm.import('* as all', from: '...source...')
538
528
  static VALUE vm_m_import(int argc, VALUE *argv, VALUE r_self)
539
529
  {
540
530
  VALUE r_import_string, r_opts;
@@ -545,7 +535,7 @@ static VALUE vm_m_import(int argc, VALUE *argv, VALUE r_self)
545
535
  if (NIL_P(r_from))
546
536
  {
547
537
  VALUE r_error_message = rb_str_new2("missing import source");
548
- rb_exc_raise(rb_exc_new_str(rb_eRuntimeError, r_error_message));
538
+ rb_exc_raise(rb_funcall(rb_cQuickjsRuntimeError, rb_intern("new"), 2, r_error_message, Qnil));
549
539
  return Qnil;
550
540
  }
551
541
 
@@ -553,16 +543,25 @@ static VALUE vm_m_import(int argc, VALUE *argv, VALUE r_self)
553
543
  TypedData_Get_Struct(r_self, VMData, &vm_type, data);
554
544
 
555
545
  char *source = StringValueCStr(r_from);
556
- char *import_name = StringValueCStr(r_import_string);
557
546
  JSValue func = JS_Eval(data->context, source, strlen(source), "mmmodule", JS_EVAL_TYPE_MODULE | JS_EVAL_FLAG_COMPILE_ONLY);
558
547
  js_module_set_import_meta(data->context, func, TRUE, FALSE);
559
548
  JS_FreeValue(data->context, func);
560
549
 
561
- const char *importAndGlobalizeModule = "import * as %s from 'mmmodule';\n"
562
- "globalThis['%s'] = %s;\n";
563
- int length = snprintf(NULL, 0, importAndGlobalizeModule, import_name, import_name, import_name);
550
+ VALUE r_import_settings = rb_funcall(
551
+ rb_const_get(rb_cClass, rb_intern("Quickjs")),
552
+ rb_intern("_build_import"),
553
+ 1,
554
+ r_import_string);
555
+ VALUE r_import_name = rb_ary_entry(r_import_settings, 0);
556
+ char *import_name = StringValueCStr(r_import_name);
557
+ VALUE r_globalize = rb_ary_entry(r_import_settings, 1);
558
+ char *globalize = StringValueCStr(r_globalize);
559
+
560
+ const char *importAndGlobalizeModule = "import %s from 'mmmodule';\n"
561
+ "%s\n";
562
+ int length = snprintf(NULL, 0, importAndGlobalizeModule, import_name, globalize);
564
563
  char *result = (char *)malloc(length + 1);
565
- snprintf(result, length + 1, importAndGlobalizeModule, import_name, import_name, import_name);
564
+ snprintf(result, length + 1, importAndGlobalizeModule, import_name, globalize);
566
565
 
567
566
  JSValue j_codeResult = JS_Eval(data->context, result, strlen(result), "<vm>", JS_EVAL_TYPE_MODULE);
568
567
  free(result);
@@ -605,8 +604,15 @@ static VALUE vm_m_to_s(VALUE r_self)
605
604
  return rb_funcall(r_ary, rb_intern("join"), 1, rb_str_new2(" "));
606
605
  }
607
606
 
608
- RUBY_FUNC_EXPORTED void
609
- Init_quickjsrb(void)
607
+ VALUE vm_m_initialize_quickjs_error(VALUE self, VALUE r_message, VALUE r_js_name)
608
+ {
609
+ rb_call_super(1, &r_message);
610
+ rb_iv_set(self, "@js_name", r_js_name);
611
+
612
+ return self;
613
+ }
614
+
615
+ RUBY_FUNC_EXPORTED void Init_quickjsrb(void)
610
616
  {
611
617
  VALUE rb_mQuickjs = rb_define_module("Quickjs");
612
618
  rb_define_const(rb_mQuickjs, "MODULE_STD", ID2SYM(rb_intern(featureStdId)));
@@ -632,6 +638,8 @@ Init_quickjsrb(void)
632
638
  rb_define_method(rb_cQuickjsVMLog, "inspect", vm_m_to_s, 0);
633
639
 
634
640
  rb_cQuickjsRuntimeError = rb_define_class_under(rb_mQuickjs, "RuntimeError", rb_eRuntimeError);
641
+ rb_define_method(rb_cQuickjsRuntimeError, "initialize", vm_m_initialize_quickjs_error, 2);
642
+ rb_define_attr(rb_cQuickjsRuntimeError, "js_name", 1, 0);
635
643
 
636
644
  rb_cQuickjsSyntaxError = rb_define_class_under(rb_mQuickjs, "SyntaxError", rb_cQuickjsRuntimeError);
637
645
  rb_cQuickjsTypeError = rb_define_class_under(rb_mQuickjs, "TypeError", rb_cQuickjsRuntimeError);
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Quickjs
4
- VERSION = "0.1.13"
4
+ VERSION = "0.2.0"
5
5
  end
data/lib/quickjs.rb CHANGED
@@ -17,9 +17,21 @@ module Quickjs
17
17
  def _with_timeout(msec, proc, args)
18
18
  Timeout.timeout(msec / 1_000.0) { proc.call(*args) }
19
19
  rescue Timeout::Error
20
- Quickjs::InterruptedError.new('Ruby runtime got timeout')
20
+ Quickjs::InterruptedError.new('Ruby runtime got timeout', nil)
21
21
  rescue => e
22
22
  e
23
23
  end
24
24
  module_function :_with_timeout
25
+
26
+ def _build_import(mappings)
27
+ imports, aliases = mappings.to_a.map do |imp|
28
+ ["#{imp[0]} as #{imp[1]}", imp[1].to_s]
29
+ end.transpose
30
+
31
+ [
32
+ imports.join(", ").yield_self{|s| '{ %s }' % s },
33
+ aliases.map {|name| "globalThis['#{name}'] = #{name};"}.join("\n")
34
+ ]
35
+ end
36
+ module_function :_build_import
25
37
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: quickjs
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.13
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - hmsk
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-10-02 00:00:00.000000000 Z
11
+ date: 2024-10-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: json