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 +4 -4
- data/README.md +21 -0
- data/Rakefile +5 -1
- data/lib/jscall/main.mjs +32 -16
- data/lib/jscall/synch.mjs +2 -2
- data/lib/jscall/version.rb +1 -1
- data/lib/jscall.rb +8 -6
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ccebaf9700a3adef5c0bba832014a8f29ecfecee4d2e6fd1303c77a986bd6e5a
|
4
|
+
data.tar.gz: ea718525489e87dd340200008540c269b33e5b3432a8b6eb6ddd6103ca53329e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
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(
|
40
|
-
return
|
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
|
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
|
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,
|
256
|
-
const
|
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 = (
|
316
|
+
let funcall_to_ruby = (receiver, name, args) => {
|
303
317
|
return new Promise((resolve, reject) => {
|
304
|
-
const cmd = make_cmd_call(
|
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 = (
|
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
|
-
|
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((
|
175
|
-
const cmd = main.make_cmd_call(
|
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
|
})
|
data/lib/jscall/version.rb
CHANGED
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
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
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
|
-
|
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.
|
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-
|
11
|
+
date: 2022-12-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: webrick
|