nodo 1.5.0 → 1.5.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8f997b2c506f2cec9bfd235c68cb0db93fcb103fa7f9b40f03740ca27b59ffb4
4
- data.tar.gz: 8a1ba6ae691ee2a992b2af5a127c43c70178cc403134db04a08f9597dd8588b3
3
+ metadata.gz: c2a8ef54e67cf745b78353e740a440edf45ee300e97d50d7e0edd93abf33bf62
4
+ data.tar.gz: 4c5196d63edf85242640050487a86b582fb2fe9d373b79408750973b88622a68
5
5
  SHA512:
6
- metadata.gz: 77c7a96627569da1b4093eb0fbfb6ab94c0c7dae4e425b019d52e06183f098daac57b88f68924fbe117afc1a0cf8be3aec143fd8e6935c839ebd573dde5afd70
7
- data.tar.gz: 8057351d0968d8bc357af3926b805f82ce6e05949ee54efb9df40293ba4faf0ce8d337550318de0114c7f9dc2df05958ea481dc35aa2981a0d95501c9cb18c64
6
+ metadata.gz: aad587338156426fd70ba262b01086056e70730aeff6774e70272c01898c9ba81e2937121226304dc00cd38f83917a788da5507160577747829a595a03a37e13
7
+ data.tar.gz: 14abb31d37eb578bba1233afa22c6f1d5c79ea28d9cb48eefa052604a3d148494f58c7af019b6ec85682348d357fdef79d14fea2e4d90cb30de96a6222b5935f
data/README.md CHANGED
@@ -117,8 +117,9 @@ end
117
117
  class BarFoo < Nodo::Core
118
118
 
119
119
  script <<~JS
120
- // some custom JS
121
- // to be executed during initialization
120
+ // custom JS to be executed during initialization
121
+ // things defined here can later be used inside functions
122
+ const bigThing = someLib.init();
122
123
  JS
123
124
  end
124
125
  ```
@@ -126,3 +127,34 @@ end
126
127
  ### Inheritance
127
128
 
128
129
  Subclasses will inherit functions, constants, dependencies and scripts from their superclasses, while only functions can be overwritten.
130
+
131
+ ```ruby
132
+ class Foo < Nodo::Core
133
+ function :foo, "() => 'superclass'"
134
+ end
135
+
136
+ class SubFoo < Foo
137
+ function :bar, "() => { return 'calling' + foo() }"
138
+ end
139
+
140
+ class SubSubFoo < SubFoo
141
+ function :foo, "() => 'subsubclass'"
142
+ end
143
+
144
+ Foo.new.foo => "superclass"
145
+ SubFoo.new.bar => "callingsuperclass"
146
+ SubSubFoo.new.bar => "callingsubsubclass"
147
+ ```
148
+
149
+ ### Async functions
150
+
151
+ `Nodo` supports calling `async` functions from Ruby.
152
+ The Ruby call will happen synchronously, i.e. it will block until the JS function resolves:
153
+
154
+ ```ruby
155
+ class SyncFoo < Nodo::Core
156
+ function :do_something, <<~JS
157
+ async () => { return await asyncFunc(); }
158
+ JS
159
+ end
160
+ ```
data/lib/nodo/nodo.js ADDED
@@ -0,0 +1,120 @@
1
+ module.exports = (function() {
2
+ const DEFINE_METHOD = '__nodo_define_class__';
3
+
4
+ const vm = require('vm');
5
+ const http = require('http');
6
+ const path = require('path');
7
+ const fs = require('fs');
8
+ const performance = require('perf_hooks').performance;
9
+
10
+ let server, closing;
11
+ const classes = {};
12
+
13
+ function render_error(e) {
14
+ let errInfo = {};
15
+ if (e instanceof Error) {
16
+ errInfo.name = e.name;
17
+ Object.getOwnPropertyNames(e).reduce((obj, prop) => { obj[prop] = e[prop]; return obj }, errInfo);
18
+ } else {
19
+ errInfo.name = e.toString();
20
+ }
21
+ return JSON.stringify({ error: errInfo });
22
+ }
23
+
24
+ function respond_with_error(res, code, name) {
25
+ res.statusCode = code;
26
+ const rendered = render_error(name);
27
+ log(`Error ${code} ${rendered}`);
28
+ res.end(rendered, 'utf8');
29
+ }
30
+
31
+ function respond_with_data(res, data, start) {
32
+ let timing;
33
+ res.statusCode = 200;
34
+ res.end(JSON.stringify(data), 'utf8');
35
+ if (start) {
36
+ timing = ` in ${(performance.now() - start).toFixed(2)}ms`;
37
+ }
38
+ log(`Completed 200 OK${timing}`);
39
+ }
40
+
41
+ function log(message) {
42
+ // fs.appendFileSync('log/nodo.log', `${message}\n`);
43
+ // console.log(`[Nodo] ${message}`);
44
+ }
45
+
46
+ const core = {
47
+ run: (socket) => {
48
+ log('Starting up...');
49
+ server = http.createServer((req, res) => {
50
+ const start = performance.now();
51
+
52
+ res.setHeader('Content-Type', 'application/json');
53
+ log(`${req.method} ${req.url}`);
54
+
55
+ if (req.method !== 'POST' || !req.url.startsWith('/')) {
56
+ return respond_with_error(res, 405, 'Method Not Allowed');
57
+ }
58
+
59
+ const url = req.url.substring(1);
60
+ const [class_name, method] = url.split('/');
61
+ let klass;
62
+
63
+ if (classes.hasOwnProperty(class_name)) {
64
+ klass = classes[class_name];
65
+ if (!klass.hasOwnProperty(method)) {
66
+ return respond_with_error(res, 404, `Method ${class_name}#${method} not found`);
67
+ }
68
+ } else if (DEFINE_METHOD != method) {
69
+ return respond_with_error(res, 404, `Class ${class_name} not defined`);
70
+ }
71
+
72
+ let body = '';
73
+
74
+ req.on('data', (data) => { body += data; });
75
+
76
+ req.on('end', () => {
77
+ let input, result;
78
+
79
+ try {
80
+ input = JSON.parse(body);
81
+ } catch (e) {
82
+ return respond_with_error(res, 400, 'Bad Request');
83
+ }
84
+
85
+ try {
86
+ if (DEFINE_METHOD == method) {
87
+ let new_class = vm.runInThisContext(input, class_name);
88
+ classes[class_name] = new_class;
89
+ respond_with_data(res, class_name, start);
90
+ } else {
91
+ Promise.resolve(klass[method].apply(null, input)).then(function (result) {
92
+ respond_with_data(res, result, start);
93
+ }).catch(function(error) {
94
+ respond_with_error(res, 500, error);
95
+ });
96
+ }
97
+ } catch(error) {
98
+ return respond_with_error(res, 500, error);
99
+ }
100
+
101
+ });
102
+ });
103
+
104
+ //server.maxConnections = 64;
105
+ server.listen(socket, () => {
106
+ log(`server ready, listening on ${socket} (max connections: ${server.maxConnections})`);
107
+ });
108
+ },
109
+
110
+ close: (finalizer) => {
111
+ log("Shutting down");
112
+ if (!closing) {
113
+ closing = true;
114
+ server.close(finalizer);
115
+ }
116
+ }
117
+ };
118
+
119
+ return { core: core, log: log };
120
+ })();
data/lib/nodo/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Nodo
2
- VERSION = '1.5.0'
2
+ VERSION = '1.5.1'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nodo
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.0
4
+ version: 1.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matthias Grosser
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-10-02 00:00:00.000000000 Z
11
+ date: 2021-10-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -82,6 +82,7 @@ files:
82
82
  - lib/nodo/dependency.rb
83
83
  - lib/nodo/errors.rb
84
84
  - lib/nodo/function.rb
85
+ - lib/nodo/nodo.js
85
86
  - lib/nodo/railtie.rb
86
87
  - lib/nodo/script.rb
87
88
  - lib/nodo/version.rb
@@ -89,7 +90,7 @@ homepage: https://github.com/mtgrosser/nodo
89
90
  licenses:
90
91
  - MIT
91
92
  metadata: {}
92
- post_install_message:
93
+ post_install_message:
93
94
  rdoc_options: []
94
95
  require_paths:
95
96
  - lib
@@ -105,7 +106,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
105
106
  version: '0'
106
107
  requirements: []
107
108
  rubygems_version: 3.0.3
108
- signing_key:
109
+ signing_key:
109
110
  specification_version: 4
110
111
  summary: Call Node.js from Ruby
111
112
  test_files: []