jscall 1.2.0 → 1.4.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: dad6ca4017b93ba7f1675b3d1e3727a143d5e413f86d9f000966f7eae9306d06
4
- data.tar.gz: e50ef13d47441f195194e4a36886b506266f87339f9d7bbf7f5b9d79dc500814
3
+ metadata.gz: ccebaf9700a3adef5c0bba832014a8f29ecfecee4d2e6fd1303c77a986bd6e5a
4
+ data.tar.gz: ea718525489e87dd340200008540c269b33e5b3432a8b6eb6ddd6103ca53329e
5
5
  SHA512:
6
- metadata.gz: 16a7885d6e0e5ef993a9f8ea43a6dc2bcfe78624f20cd10517642c00f59525b1edab1a91ab99367f962d3f63ba5a5c6705bf7cad915673613fb9ee805358baeb
7
- data.tar.gz: 1f7d95224652882839fd9bce1d4fd539021980018ecc1cca73aed56e598a2c034b8800cdfb88cc6ffd4b09f6488867e33335e8180f7e5e81aa29663ebdc6a5d4
6
+ metadata.gz: d6852583f9276d903886d9f3ff1dbcf3ca16569844567f43751bee97917715d0014c8bf598e84aae7a2ba4db6145398b397c1b21e59d921755a6c8d3b0f6bee9
7
+ data.tar.gz: 3fe7e88204d5971a3a425ca3a2329f560a547204e06e009f791017036ef75e2054da4716b2ddc948b8d170d3eaa05845c30551a88e700cda03eee814530f4857
data/README.md CHANGED
@@ -110,6 +110,11 @@ created in Ruby.
110
110
  Note that you must `await` every call to Ruby object since it is
111
111
  asynchronous call.
112
112
 
113
+ A shorthand for `obj.to_a()` is `obj.to_a` in Ruby. However,
114
+ this shorthand is not available in JavaScript.
115
+ You must explicitly write `obj.to_a()`
116
+ in JavaScript when `obj` is a Ruby object.
117
+
113
118
  In JavaScript, `Ruby.exec` is available to run a program in Ruby.
114
119
  For example,
115
120
 
@@ -392,6 +397,22 @@ Jscall.config()
392
397
 
393
398
  ### Other configurations
394
399
 
400
+ To obtain more detailed error messages,
401
+ set a debugging level to 10.
402
+ In Ruby,
403
+
404
+ ```
405
+ Jscall.debug = 10
406
+ ```
407
+
408
+ In JavaScript,
409
+
410
+ ```
411
+ Ruby.setDebugLevel(10)
412
+ ```
413
+
414
+ The default debugging level is 0.
415
+
395
416
  To change the name of the node command,
396
417
 
397
418
  ```
data/Rakefile CHANGED
@@ -6,7 +6,11 @@ require "rake/testtask"
6
6
  Rake::TestTask.new(:test) do |t|
7
7
  t.libs << "test"
8
8
  t.libs << "lib"
9
- t.test_files = FileList["test/**/test_*.rb"]
9
+ files = FileList["test/**/test_*.rb"]
10
+ unless /linux/ =~ RbConfig::CONFIG['host_os']
11
+ files.exclude "test/test_sync_io.rb"
12
+ end
13
+ t.test_files = files
10
14
  end
11
15
 
12
16
  task default: :test
data/lib/jscall/main.mjs CHANGED
@@ -1,5 +1,12 @@
1
1
  // Copyright (C) 2022- Shigeru Chiba. All rights reserved.
2
2
 
3
+ let debug_level = 0
4
+
5
+ // debug level is 0 (default) or 10.
6
+ export const setDebugLevel = d => {
7
+ debug_level = d
8
+ }
9
+
3
10
  export const cmd_eval = 1
4
11
  export const cmd_call = 2
5
12
  export const cmd_reply = 3
@@ -36,8 +43,8 @@ const exported = new class {
36
43
  }
37
44
  }
38
45
 
39
- export_remoteref(prref) { // proxy for remote reference
40
- return prref.__self__.id
46
+ export_remoteref(rref) { // proxy for remote reference
47
+ return rref.id
41
48
  }
42
49
 
43
50
  next_element() {
@@ -54,6 +61,8 @@ const exported = new class {
54
61
  const obj = this.objects[idx]
55
62
  if (typeof obj === 'number')
56
63
  throw `unknown index is given to find(): ${idx}`
64
+ else if (obj === null)
65
+ throw `null is exported? ${idx}`
57
66
  else
58
67
  return obj
59
68
  }
@@ -88,12 +97,12 @@ const remoteRefHandler = new class {
88
97
  else
89
98
  return (...args) => {
90
99
  // this returns Promise
91
- return funcall_to_ruby(obj.id, name, args)
100
+ return funcall_to_ruby(obj, name, args)
92
101
  }
93
102
  }
94
103
  apply(obj, self, args) {
95
104
  // this returns Promise
96
- return funcall_to_ruby(obj.id, 'call', args)
105
+ return funcall_to_ruby(obj, 'call', args)
97
106
  }
98
107
  }
99
108
 
@@ -147,11 +156,11 @@ const encode_obj = obj => {
147
156
  else if (obj instanceof Map) {
148
157
  const hash = {}
149
158
  for (const [key, value] of obj.entries())
150
- hash[key] = value
159
+ hash[key] = encode_obj(value)
151
160
  return [param_hash, hash]
152
161
  }
153
162
  else if (obj instanceof RemoteRef)
154
- return [param_local_object, exported.export_remoteref(obj)]
163
+ return [param_local_object, exported.export_remoteref(obj.__self__)]
155
164
  else
156
165
  return [param_object, exported.export(obj)]
157
166
  }
@@ -196,6 +205,9 @@ export const decode_obj_or_error = obj => {
196
205
  const js_eval = eval
197
206
 
198
207
  export const funcall_from_ruby = cmd => {
208
+ if (debug_level >= 10)
209
+ console.error(`RubyToJS> ${cmd[3]} ${cmd[1]} ${cmd[2]}`)
210
+
199
211
  const receiver = decode_obj(cmd[2])
200
212
  const name = cmd[3]
201
213
  const args = cmd[4].map(e => decode_obj(e))
@@ -219,8 +231,8 @@ export const funcall_from_ruby = cmd => {
219
231
  }
220
232
  else {
221
233
  const f = Reflect.get(receiver, name)
222
- if (f)
223
- if (typeof f === 'function')
234
+ if (f !== undefined)
235
+ if (typeof f === 'function' && !(f instanceof RemoteRef))
224
236
  return Reflect.apply(f, receiver, args)
225
237
  else if (args.length === 0)
226
238
  return f // obtain a propety
@@ -252,8 +264,10 @@ export const reply = (message_id, value, sync_mode) => {
252
264
  }
253
265
  }
254
266
 
255
- export const reply_error = (message_id, e) => {
256
- const cmd = reply_with_piggyback([cmd_reply, message_id, encode_error(e)])
267
+ export const reply_error = (message_id, error) => {
268
+ const msg = typeof error === 'string' ? error : error.toString() +
269
+ '\n ---\n' + error.stack
270
+ const cmd = reply_with_piggyback([cmd_reply, message_id, encode_error(msg)])
257
271
  stdout_puts(JSON.stringify(cmd))
258
272
  }
259
273
 
@@ -299,18 +313,22 @@ export const make_cmd_eval = src => {
299
313
  return reply_with_piggyback([cmd_eval, message_id, src])
300
314
  }
301
315
 
302
- let funcall_to_ruby = (receiver_id, name, args) => {
316
+ let funcall_to_ruby = (receiver, name, args) => {
303
317
  return new Promise((resolve, reject) => {
304
- const cmd = make_cmd_call(receiver_id, name, args)
318
+ const cmd = make_cmd_call(receiver, name, args)
305
319
  const message_id = cmd[1]
306
320
  callback_stack.push([message_id, resolve, reject])
321
+ if (debug_level >= 10)
322
+ console.error(`JStoRuby< ${name} ${message_id} ${cmd[2][1]}`)
323
+
307
324
  stdout_puts(JSON.stringify(cmd))
308
325
  })
309
326
  }
310
327
 
311
328
  export const set_funcall_to_ruby = f => { funcall_to_ruby = f }
312
329
 
313
- export const make_cmd_call = (receiver_id, name, args) => {
330
+ export const make_cmd_call = (obj, name, args) => {
331
+ const receiver_id = exported.export_remoteref(obj)
314
332
  const message_id = fresh_id()
315
333
  const receiver = [param_local_object, receiver_id]
316
334
  const encoded_args = args.map(e => encode_obj(e))
@@ -475,9 +493,7 @@ export const start = async (stdin, use_stdout) => {
475
493
  else // cmd_retry and other unknown commands
476
494
  reply_error(cmd[1], `invalid command ${cmd[0]}`)
477
495
  } catch (error) {
478
- const msg = typeof error === 'string' ? error : error.toString() +
479
- '\n ---\n' + error.stack
480
- reply_error(cmd[1], msg)
496
+ reply_error(cmd[1], error)
481
497
  }
482
498
  }
483
499
  }
data/lib/jscall/synch.mjs CHANGED
@@ -171,8 +171,8 @@ export const exec = src => {
171
171
  return event_loop()
172
172
  }
173
173
 
174
- main.set_funcall_to_ruby((receiver_id, name, args) => {
175
- const cmd = main.make_cmd_call(receiver_id, name, args)
174
+ main.set_funcall_to_ruby((receiver, name, args) => {
175
+ const cmd = main.make_cmd_call(receiver, name, args)
176
176
  main.stdout_puts(JSON.stringify(cmd))
177
177
  return event_loop()
178
178
  })
@@ -3,5 +3,5 @@
3
3
  # Copyright (C) 2022- Shigeru Chiba. All rights reserved.
4
4
 
5
5
  module Jscall
6
- VERSION = "1.2.0"
6
+ VERSION = "1.4.0"
7
7
  end
data/lib/jscall.rb CHANGED
@@ -393,13 +393,15 @@ module Jscall
393
393
  if reply[1] != message_id
394
394
  send_reply(reply[1], nil, false, CMD_REJECT)
395
395
  else
396
- result = @pending_replies.delete(message_id)
397
- if result.nil?
398
- raise RuntimeError.new("bad CMD_RETRY: #{reply}")
399
- elsif result.is_a?(JavaScriptError)
400
- raise result
396
+ if @pending_replies.key?(message_id)
397
+ result = @pending_replies.delete(message_id)
398
+ if result.is_a?(JavaScriptError)
399
+ raise result
400
+ else
401
+ return result
402
+ end
401
403
  else
402
- return result
404
+ raise RuntimeError.new("bad CMD_RETRY: #{reply}")
403
405
  end
404
406
  end
405
407
  else
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jscall
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shigeru Chiba
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-09-23 00:00:00.000000000 Z
11
+ date: 2022-12-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: webrick