nodo 1.6.5 → 1.7.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.

Potentially problematic release.


This version of nodo might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 85e8ece889660e457a3473919da402124d9688011c3dbe5f69015e9f5e258465
4
- data.tar.gz: 32ed8d2c1905c22cc68cf2734272f0d743890be066add8ce8de1a72132c6c3f4
3
+ metadata.gz: 403cadfdfd344847d097f662540d78fd2db53099407de9391f7e453575a2dd21
4
+ data.tar.gz: 14cf5ec07e0dcf47556d1c606a632763614e17a6054ac818952eecd5112bbc7f
5
5
  SHA512:
6
- metadata.gz: 1c6a6af11b36730dae8bc00d31a17a96f0fbe0fe3a5ddc3da5df636efcdc648a6890e37aee63c7f0b67fc000ce354247eaa61cde12557eb9a3126b6cd0d9a291
7
- data.tar.gz: b12074e9a1312694fcb46246eb2d66d418054b3f518be6dc5b2469a908b8b7e35d55d4a30b77144005b2b898c193ed062473ee4916239022c9d32361a5e324c4
6
+ metadata.gz: f14df956cfa21a1732b9a80df51826c32519b9cec0da7679f99846d08348b1d9985e774b6dd83f19eec1cebbb4c0ebf0d70f731f80c896d782b84ed4ec53b0a2
7
+ data.tar.gz: 03f7b885f5dca161dde7c9add5a46733b74d23d90c26180df30c4f75c4c3d2ec2fb6ccc000a651f0c1515a5e5d9b46e03fa73ed2aa4bf2f18ddfa257394ddaef
data/lib/nodo/core.rb CHANGED
@@ -9,48 +9,48 @@ module Nodo
9
9
  ARRAY_CLASS_ATTRIBUTES = %i[dependencies constants scripts].freeze
10
10
  HASH_CLASS_ATTRIBUTES = %i[functions].freeze
11
11
  CLASS_ATTRIBUTES = (ARRAY_CLASS_ATTRIBUTES + HASH_CLASS_ATTRIBUTES).freeze
12
-
12
+
13
13
  @@node_pid = nil
14
14
  @@tmpdir = nil
15
15
  @@mutex = Mutex.new
16
16
  @@exiting = nil
17
-
17
+
18
18
  class << self
19
19
  extend Forwardable
20
-
20
+
21
21
  attr_accessor :class_defined
22
-
22
+
23
23
  def inherited(subclass)
24
24
  CLASS_ATTRIBUTES.each do |attr|
25
25
  subclass.send "#{attr}=", send(attr).dup
26
26
  end
27
27
  end
28
-
28
+
29
29
  def instance
30
30
  @instance ||= new
31
31
  end
32
-
32
+
33
33
  def class_defined?
34
34
  !!class_defined
35
35
  end
36
-
36
+
37
37
  def clsid
38
38
  name || "Class:0x#{object_id.to_s(0x10)}"
39
39
  end
40
-
40
+
41
41
  CLASS_ATTRIBUTES.each do |attr|
42
42
  define_method "#{attr}=" do |value|
43
43
  instance_variable_set :"@#{attr}", value
44
44
  end
45
45
  protected "#{attr}="
46
46
  end
47
-
47
+
48
48
  ARRAY_CLASS_ATTRIBUTES.each do |attr|
49
49
  define_method "#{attr}" do
50
50
  instance_variable_get(:"@#{attr}") || instance_variable_set(:"@#{attr}", [])
51
51
  end
52
52
  end
53
-
53
+
54
54
  HASH_CLASS_ATTRIBUTES.each do |attr|
55
55
  define_method "#{attr}" do
56
56
  instance_variable_get(:"@#{attr}") || instance_variable_set(:"@#{attr}", {})
@@ -60,15 +60,15 @@ module Nodo
60
60
  def generate_core_code
61
61
  <<~JS
62
62
  global.nodo = require(#{nodo_js});
63
-
63
+
64
64
  const socket = process.argv[1];
65
65
  if (!socket) {
66
66
  process.stderr.write('Socket path is required\\n');
67
67
  process.exit(1);
68
68
  }
69
-
69
+
70
70
  process.title = `nodo-core ${socket}`;
71
-
71
+
72
72
  const shutdown = () => {
73
73
  nodo.core.close(() => { process.exit(0) });
74
74
  };
@@ -92,9 +92,9 @@ module Nodo
92
92
  })()
93
93
  JS
94
94
  end
95
-
95
+
96
96
  protected
97
-
97
+
98
98
  def finalize_context(context_id)
99
99
  proc do
100
100
  if not @@exiting and core = Nodo::Core.instance
@@ -102,9 +102,9 @@ module Nodo
102
102
  end
103
103
  end
104
104
  end
105
-
105
+
106
106
  private
107
-
107
+
108
108
  def require(*mods)
109
109
  deps = mods.last.is_a?(Hash) ? mods.pop : {}
110
110
  mods = mods.map { |m| [m, m] }.to_h
@@ -118,7 +118,7 @@ module Nodo
118
118
  self.functions = functions.merge(name => Function.new(name, _code || code, source_location, timeout, &block))
119
119
  define_method(name) { |*args| call_js_method(name, args) }
120
120
  end
121
-
121
+
122
122
  def class_function(*methods)
123
123
  singleton_class.def_delegators(:instance, *methods)
124
124
  end
@@ -126,20 +126,20 @@ module Nodo
126
126
  def const(name, value)
127
127
  self.constants = constants + [Constant.new(name, value)]
128
128
  end
129
-
129
+
130
130
  def script(code = nil, &block)
131
131
  self.scripts = scripts + [Script.new(code, &block)]
132
132
  end
133
-
133
+
134
134
  def nodo_js
135
- Pathname.new(__FILE__).dirname.join('nodo.js').to_s.to_json
135
+ Pathname.new(__FILE__).dirname.join('nodo.cjs').to_s.to_json
136
136
  end
137
-
137
+
138
138
  def reserved_method_name?(name)
139
139
  Nodo::Core.method_defined?(name, false) || Nodo::Core.private_method_defined?(name, false) || name.to_s == DEFINE_METHOD
140
140
  end
141
141
  end
142
-
142
+
143
143
  def initialize
144
144
  raise ClassError, :new if self.class == Nodo::Core
145
145
  @@mutex.synchronize do
@@ -148,18 +148,18 @@ module Nodo
148
148
  ensure_class_is_defined
149
149
  end
150
150
  end
151
-
151
+
152
152
  def evaluate(code)
153
153
  ensure_context_is_defined
154
154
  call_js_method(EVALUATE_METHOD, code)
155
155
  end
156
-
156
+
157
157
  private
158
-
158
+
159
159
  def node_pid
160
160
  @@node_pid
161
161
  end
162
-
162
+
163
163
  def tmpdir
164
164
  @@tmpdir
165
165
  end
@@ -167,33 +167,33 @@ module Nodo
167
167
  def socket_path
168
168
  tmpdir && tmpdir.join(SOCKET_NAME)
169
169
  end
170
-
170
+
171
171
  def clsid
172
172
  self.class.clsid
173
173
  end
174
-
174
+
175
175
  def context_defined?
176
176
  @context_defined
177
177
  end
178
-
178
+
179
179
  def log_exception(e)
180
180
  return unless logger = Nodo.logger
181
181
  message = "\n#{e.class} (#{e.message})"
182
182
  message << ":\n\n#{e.backtrace.join("\n")}" if e.backtrace
183
183
  logger.error message
184
184
  end
185
-
185
+
186
186
  def ensure_process_is_spawned
187
187
  return if node_pid
188
188
  spawn_process
189
189
  end
190
-
190
+
191
191
  def ensure_class_is_defined
192
192
  return if self.class.class_defined?
193
193
  call_js_method(DEFINE_METHOD, self.class.generate_class_code)
194
194
  self.class.class_defined = true
195
195
  end
196
-
196
+
197
197
  def ensure_context_is_defined
198
198
  return if context_defined?
199
199
  @@mutex.synchronize do
@@ -202,7 +202,7 @@ module Nodo
202
202
  @context_defined = true
203
203
  end
204
204
  end
205
-
205
+
206
206
  def spawn_process
207
207
  @@tmpdir = Pathname.new(Dir.mktmpdir('nodo'))
208
208
  env = Nodo.env.merge('NODE_PATH' => Nodo.modules_root.to_s)
@@ -215,7 +215,7 @@ module Nodo
215
215
  FileUtils.remove_entry(tmpdir) if File.directory?(tmpdir)
216
216
  end
217
217
  end
218
-
218
+
219
219
  def wait_for_socket
220
220
  start = Time.now
221
221
  socket = nil
@@ -257,7 +257,7 @@ module Nodo
257
257
  # TODO: restart or something? If this happens the process is completely broken
258
258
  raise Error, 'Node process failed'
259
259
  end
260
-
260
+
261
261
  def handle_error(response, function)
262
262
  if response.body
263
263
  result = parse_response(response)
@@ -270,12 +270,12 @@ module Nodo
270
270
  log_exception(error)
271
271
  raise error
272
272
  end
273
-
273
+
274
274
  def parse_response(response)
275
275
  data = response.body.force_encoding('UTF-8')
276
276
  JSON.parse(data) unless data == ''
277
277
  end
278
-
278
+
279
279
  def with_tempfile(name)
280
280
  ext = File.extname(name)
281
281
  result = nil
@@ -284,6 +284,6 @@ module Nodo
284
284
  end
285
285
  result
286
286
  end
287
-
287
+
288
288
  end
289
289
  end
data/lib/nodo/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Nodo
2
- VERSION = '1.6.5'
2
+ VERSION = '1.7.0'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nodo
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.5
4
+ version: 1.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matthias Grosser
@@ -11,56 +11,56 @@ cert_chain: []
11
11
  date: 2021-10-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
+ name: bundler
14
15
  requirement: !ruby/object:Gem::Requirement
15
16
  requirements:
16
17
  - - ">="
17
18
  - !ruby/object:Gem::Version
18
19
  version: '0'
19
- name: bundler
20
- prerelease: false
21
20
  type: :development
21
+ prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
+ name: rake
28
29
  requirement: !ruby/object:Gem::Requirement
29
30
  requirements:
30
31
  - - ">="
31
32
  - !ruby/object:Gem::Version
32
33
  version: '0'
33
- name: rake
34
- prerelease: false
35
34
  type: :development
35
+ prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
+ name: byebug
42
43
  requirement: !ruby/object:Gem::Requirement
43
44
  requirements:
44
45
  - - ">="
45
46
  - !ruby/object:Gem::Version
46
47
  version: '0'
47
- name: byebug
48
- prerelease: false
49
48
  type: :development
49
+ prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
+ name: minitest
56
57
  requirement: !ruby/object:Gem::Requirement
57
58
  requirements:
58
59
  - - ">="
59
60
  - !ruby/object:Gem::Version
60
61
  version: '0'
61
- name: minitest
62
- prerelease: false
63
62
  type: :development
63
+ prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - ">="
@@ -82,7 +82,6 @@ files:
82
82
  - lib/nodo/dependency.rb
83
83
  - lib/nodo/errors.rb
84
84
  - lib/nodo/function.rb
85
- - lib/nodo/nodo.js
86
85
  - lib/nodo/railtie.rb
87
86
  - lib/nodo/script.rb
88
87
  - lib/nodo/version.rb
@@ -105,7 +104,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
105
104
  - !ruby/object:Gem::Version
106
105
  version: '0'
107
106
  requirements: []
108
- rubygems_version: 3.3.25
107
+ rubygems_version: 3.5.11
109
108
  signing_key:
110
109
  specification_version: 4
111
110
  summary: Call Node.js from Ruby
data/lib/nodo/nodo.js DELETED
@@ -1,143 +0,0 @@
1
- module.exports = (function() {
2
- const DEFINE_METHOD = '__nodo_define_class__';
3
- const EVALUATE_METHOD = '__nodo_evaluate__';
4
- const GC_METHOD = '__nodo_gc__';
5
- const DEBUG = process.env.NODO_DEBUG;
6
-
7
- const vm = require('vm');
8
- const http = require('http');
9
- const path = require('path');
10
- const fs = require('fs');
11
- const performance = require('perf_hooks').performance;
12
-
13
- let server, closing;
14
- const classes = {};
15
- const contexts = {};
16
-
17
- function render_error(e) {
18
- let errInfo = {};
19
- if (e instanceof Error) {
20
- errInfo.name = e.name;
21
- Object.getOwnPropertyNames(e).reduce((obj, prop) => { obj[prop] = e[prop]; return obj }, errInfo);
22
- } else {
23
- errInfo.name = e.toString();
24
- }
25
- return JSON.stringify({ error: errInfo });
26
- }
27
-
28
- function respond_with_error(res, code, name) {
29
- res.statusCode = code;
30
- const rendered = render_error(name);
31
- debug(`Error ${code} ${rendered}`);
32
- res.end(rendered, 'utf8');
33
- }
34
-
35
- function respond_with_data(res, data, start) {
36
- let timing;
37
- res.statusCode = 200;
38
- res.end(JSON.stringify(data), 'utf8');
39
- if (start) {
40
- timing = ` in ${(performance.now() - start).toFixed(2)}ms`;
41
- }
42
- debug(`Completed 200 OK${timing}\n`);
43
- }
44
-
45
- function debug(message) {
46
- if (DEBUG) {
47
- // fs.appendFileSync('log/nodo.log', `${message}\n`);
48
- console.log(`[Nodo] ${message}`);
49
- }
50
- }
51
-
52
- async function import_module(specifier) {
53
- return await import(specifier);
54
- }
55
-
56
- const core = {
57
- run: (socket) => {
58
- debug('Starting up...');
59
- server = http.createServer((req, res) => {
60
- const start = performance.now();
61
-
62
- res.setHeader('Content-Type', 'application/json');
63
- debug(`${req.method} ${req.url}`);
64
-
65
- if (req.method !== 'POST' || !req.url.startsWith('/')) {
66
- return respond_with_error(res, 405, 'Method Not Allowed');
67
- }
68
-
69
- const url = req.url.substring(1);
70
- const [class_name, object_id, method] = url.split('/');
71
- let klass, context;
72
-
73
- if (classes.hasOwnProperty(class_name)) {
74
- klass = classes[class_name];
75
- if (EVALUATE_METHOD == method) {
76
- if (!contexts.hasOwnProperty(object_id)) {
77
- contexts[object_id] = vm.createContext({ require: require, ...klass });
78
- }
79
- context = contexts[object_id];
80
- } else if (!klass.hasOwnProperty(method) && !GC_METHOD == method) {
81
- return respond_with_error(res, 404, `Method ${class_name}#${method} not found`);
82
- }
83
- } else if (DEFINE_METHOD != method) {
84
- return respond_with_error(res, 404, `Class ${class_name} not defined`);
85
- }
86
-
87
- let body = '';
88
-
89
- req.on('data', (data) => { body += data; });
90
-
91
- req.on('end', () => {
92
- let input, result;
93
-
94
- try {
95
- input = JSON.parse(body);
96
- } catch (e) {
97
- return respond_with_error(res, 400, 'Bad Request');
98
- }
99
-
100
- try {
101
- if (DEFINE_METHOD == method) {
102
- classes[class_name] = vm.runInThisContext(input, class_name);
103
- respond_with_data(res, class_name, start);
104
- } else if (EVALUATE_METHOD == method) {
105
- Promise.resolve(vm.runInNewContext(input, context)).then((result) => {
106
- respond_with_data(res, result, start);
107
- }).catch((error) => {
108
- respond_with_error(res, 500, error);
109
- });
110
- } else if (GC_METHOD == method) {
111
- delete contexts[object_id];
112
- respond_with_data(res, true, start);
113
- } else {
114
- Promise.resolve(klass[method].apply(null, input)).then((result) => {
115
- respond_with_data(res, result, start);
116
- }).catch((error) => {
117
- respond_with_error(res, 500, error);
118
- });
119
- }
120
- } catch(error) {
121
- return respond_with_error(res, 500, error);
122
- }
123
-
124
- });
125
- });
126
-
127
- //server.maxConnections = 64;
128
- server.listen(socket, () => {
129
- debug(`server ready, listening on ${socket} (max connections: ${server.maxConnections})`);
130
- });
131
- },
132
-
133
- close: (finalizer) => {
134
- debug("Shutting down");
135
- if (!closing) {
136
- closing = true;
137
- server.close(finalizer);
138
- }
139
- }
140
- };
141
-
142
- return { core: core, debug: debug, import: import_module };
143
- })();