@makano/rew 1.1.0 → 1.1.2

Sign up to get free protection for your applications and to get access to all the features.
package/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
  <h3 align="center">
2
- <img src="https://raw.githubusercontent.com/kevinJ045/rew/main/assets/logo.png" width="100" />
2
+ <img src="https://raw.githubusercontent.com/kevinJ045/rew-docs/main/assets/logo.png" width="100" />
3
3
  <br/>
4
4
  Rew
5
5
  <br/>
package/bin/rew CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  const path = require('path');
3
3
  const fs = require('fs');
4
- const rew_mod = path.resolve(process.cwd(), 'node_modules/@makano/rew');
4
+ const rew_mod = path.resolve(process.cwd(), 'snode_moduless/@makano/rew');
5
5
  if(fs.existsSync(rew_mod)){
6
6
  require(path.join(rew_mod, 'lib/rew/cli/cli.js'));
7
7
  } else {
@@ -3,9 +3,11 @@
3
3
  const yargs = require('yargs/yargs');
4
4
  const path = require('path');
5
5
  const { hideBin } = require('yargs/helpers');
6
- const { fork } = require('child_process');
6
+ const { fork, exec } = require('child_process');
7
7
  const { watch } = require('chokidar');
8
8
  const utils = require('./utils');
9
+ const { existsSync } = require('fs');
10
+ const { log } = require('./log');
9
11
 
10
12
  yargs(hideBin(process.argv))
11
13
  .command(
@@ -25,6 +27,10 @@ yargs(hideBin(process.argv))
25
27
  },
26
28
  (argv) => {
27
29
  const filePath = path.resolve(process.cwd(), argv.file);
30
+ if(!existsSync(filePath)){
31
+ log('File not found:', argv.file, ':end');
32
+ return;
33
+ }
28
34
  const watching = [];
29
35
  const watchIt = (file) => {
30
36
  if(watching.includes(file)) return;
@@ -41,8 +47,6 @@ yargs(hideBin(process.argv))
41
47
  data.forEach(file => {
42
48
  watchIt(file);
43
49
  });
44
- } else {
45
- process.exit();
46
50
  }
47
51
  }).send({ filePath, watch: argv.watch });
48
52
  if(argv.watch) watchIt(filePath);
@@ -104,6 +108,18 @@ yargs(hideBin(process.argv))
104
108
  utils.runApp(argv.path);
105
109
  }
106
110
  )
111
+ .command('install <path>', 'Install an app', (yargs) => {
112
+ yargs
113
+ .positional('path', {
114
+ describe: 'Path of the app to install',
115
+ type: 'string',
116
+ });
117
+ },
118
+ async (argv) => {
119
+ if(argv.path.startsWith('github:')) utils.installApp(await utils.cloneGit(argv.path), true, true);
120
+ else utils.installApp(argv.path);
121
+ }
122
+ )
107
123
  .command('build <file>', 'Build the specified file', (yargs) => {
108
124
  yargs
109
125
  .positional('file', {
@@ -1,6 +1,4 @@
1
- const path = require('path');
2
1
  const { run } = require('../main');
3
- const { watch } = require('fs');
4
2
 
5
3
 
6
4
  function exec(filePath){
@@ -8,13 +6,12 @@ function exec(filePath){
8
6
  .context.module.imports;
9
7
  }
10
8
 
11
-
12
- process.on('message', ({ filePath, watch }) => {
9
+ const onmsg = ({ filePath, watch }) => {
13
10
  const imports = exec(filePath);
14
11
  if(watch){
15
12
  process.send(imports);
16
- process.exit();
17
- } else {
18
- process.exit();
19
13
  }
20
- });
14
+ process.off('message', onmsg);
15
+ }
16
+
17
+ process.on('message', onmsg);
@@ -4,8 +4,9 @@ const conf = require('../pkgs/conf');
4
4
  const jsYaml = require('js-yaml');
5
5
  const readline = require('readline');
6
6
  const { log, logget } = require('./log');
7
- const { execSync } = require('child_process');
7
+ const { execSync, exec } = require('child_process');
8
8
  const { run } = require('../main');
9
+ const { generateRandomID } = require('../functions/id');
9
10
 
10
11
  const npm_package_name = '@makano/rew';
11
12
 
@@ -68,6 +69,7 @@ module.exports = {
68
69
  fs.writeFileSync(confPath, jsYaml.dump({ package: project.package, entry: 'main.coffee' }));
69
70
  fs.writeFileSync(entryFile, `print("Hello World!")`);
70
71
  if(project.git) {
72
+ fs.writeFileSync(path.join(projectPath, '.gitignore'), `node_modules/\npackage-lock.json`);
71
73
  execSync('cd '+projectPath+' && git init .');
72
74
  }
73
75
  log('Installing '+npm_package_name);
@@ -104,7 +106,14 @@ module.exports = {
104
106
  const runAppRoot = (root, confPath) => {
105
107
  const c = jsYaml.load(fs.readFileSync(confPath, { encoding: 'utf-8' }));
106
108
  if(c.entry){
107
- run(path.resolve(root, c.entry));
109
+ const r = path.resolve(root, c.entry);
110
+ const mod_path = path.resolve(root, 'snode_moduless/@makano/rew');
111
+ const mod_path_lib = path.join(mod_path, 'lib/rew/cli');
112
+ if(fs.existsSync(mod_path) && __dirname !== mod_path_lib){
113
+ const mod_path_utilsjs = path.join(mod_path_lib, '../main.js');
114
+ require(mod_path_utilsjs)
115
+ .run(r);
116
+ } else run(r);
108
117
  }
109
118
  }
110
119
 
@@ -112,11 +121,70 @@ module.exports = {
112
121
  runAppRoot(apppath, appConfpath);
113
122
  } else {
114
123
  const con = conf({});
115
- const apppath = path.resolve(con.CONFIG_PATH, pathOrPackage, '$app');
124
+ const apppath = path.resolve(con.CONFIG_PATH, pathOrPackage, 'app');
116
125
  const appConfpath = path.join(apppath, 'app.yaml');
117
126
  if(fs.existsSync(apppath) && fs.existsSync(appConfpath)){
118
127
  runAppRoot(apppath, appConfpath);
119
128
  }
120
129
  }
130
+ },
131
+ installApp(pathname, rmidir, rmidiri){
132
+ if(!pathname){
133
+ return;
134
+ }
135
+ const apppath = path.resolve(process.cwd(), pathname);
136
+ const appConfpath = path.join(apppath, 'app.yaml');
137
+ const appPackagepath = path.join(apppath, 'package.json');
138
+ if(fs.existsSync(apppath) && fs.existsSync(appConfpath)){
139
+ const c = jsYaml.load(fs.readFileSync(appConfpath, { encoding: 'utf-8' }));
140
+ const p = JSON.parse(fs.readFileSync(appPackagepath, { encoding: 'utf-8' }));
141
+ const pname = c.package;
142
+ const installPath = path.join(conf({}).create(pname).root, 'app');
143
+ const rl = readline.createInterface({
144
+ input: process.stdin,
145
+ output: process.stdout
146
+ });
147
+ log('Installing '+pname);
148
+ log("Package: "+p.name+'@'+p.version);
149
+ if(p.description){
150
+ log("Description: "+p.description);
151
+ }
152
+ rl.question(logget('Install '+pname+'? (y/N)'), (f) => {
153
+ if(f.toLowerCase() == 'y'){
154
+ if(fs.existsSync(installPath)){
155
+ execSync(`rm -r ${installPath}`);
156
+ }
157
+ execSync(`cp -r ${apppath} ${installPath}`);
158
+ if(rmidir){
159
+ execSync(`rm -r ${apppath}`);
160
+ }
161
+ log('Installed '+pname, ':end');
162
+ rl.close();
163
+ } else {
164
+ if(rmidiri){
165
+ execSync(`rm -r ${apppath}`);
166
+ }
167
+ log('Canceled install', ':end');
168
+ rl.close();
169
+ }
170
+ });
171
+ } else {
172
+ log('Path is not a rew app', ':end');
173
+ }
174
+ },
175
+ async cloneGit(gitpath){
176
+ const p = gitpath.split('github:')[1];
177
+ const url = `https://github.com/${p}`;
178
+ const apiurl = `https://api.github.com/repos/${p}`;
179
+ return await fetch(apiurl)
180
+ .then((r) => {
181
+ if(r.status !== 200) return log('Repo not found', ':end');
182
+ const tempPath = '/tmp/rew-git-clone-'+p.replace(/\//g, '_')+'-'+generateRandomID();
183
+ execSync(`git clone ${url} ${tempPath}`);
184
+ console.log('Installing deps...');
185
+ execSync(`cd ${tempPath} && npm i`);
186
+ return tempPath;
187
+ })
188
+ .catch(r => null);
121
189
  }
122
190
  }
@@ -5,8 +5,9 @@ const future = require("../functions/future");
5
5
  const sleep = require("../functions/sleep");
6
6
  const { match } = require("../functions/match");
7
7
  const { map } = require("../functions/map");
8
- const { typex, typeis, typedef, typei } = require("../functions/types");
8
+ const { typex, typeis, typedef, typei, int, float, num, str, bool } = require("../functions/types");
9
9
  const { isEmpty, clone, deepClone, merge, uniqueId, compose, curry } = require("../functions/core");
10
+ const { print, input } = require("../functions/stdout");
10
11
 
11
12
  module.exports = {
12
13
  cenum,
@@ -16,11 +17,18 @@ module.exports = {
16
17
  sleep,
17
18
  match,
18
19
  map,
20
+
19
21
  typex,
20
22
  typei,
21
23
  typeis,
22
24
  typedef,
23
25
 
26
+ int,
27
+ float,
28
+ num,
29
+ str,
30
+ bool,
31
+
24
32
  isEmpty,
25
33
  clone,
26
34
  deepClone,
@@ -29,7 +37,6 @@ module.exports = {
29
37
  compose,
30
38
  curry,
31
39
 
32
- print: function (...arguments) {
33
- return console.log(...arguments);
34
- },
40
+ print,
41
+ input
35
42
  };
@@ -0,0 +1,8 @@
1
+ const execOptions = {
2
+ sharedContext: true,
3
+ resolveExtensions: [{ext: '.js', options: { type: 'js' }}, '.coffee'],
4
+ nativeRequire: false,
5
+ cwdAlias: '$'
6
+ }
7
+
8
+ module.exports.execOptions = execOptions;
@@ -1,4 +1,5 @@
1
1
 
2
+
2
3
  function isEmpty(value) {
3
4
  if (Array.isArray(value) || typeof value === 'string') {
4
5
  return value.length === 0;
@@ -0,0 +1,54 @@
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+ const { execOptions } = require('../const/opt');
4
+
5
+
6
+ module.exports = (currentFile) => {
7
+
8
+ function gp(filepath){
9
+ return path.resolve(filepath.startsWith(execOptions.cwdAlias) ? process.cwd() : path.dirname(currentFile), filepath.replaceAll(execOptions.cwdAlias+'/', ''));
10
+ }
11
+
12
+ function read(filepath, options = { encoding: 'utf-8' }){
13
+ return fs.readFileSync(gp(filepath), options);
14
+ }
15
+
16
+ function write(filepath, content, options){
17
+ return fs.writeFileSync(gp(filepath), content, options);
18
+ }
19
+
20
+ function exists(filepath, options){
21
+ return fs.existsSync(filepath);
22
+ }
23
+
24
+ function fstat(filepath, options){
25
+ return fs.statSync(gp(filepath), options);
26
+ }
27
+
28
+ function rm(filepath, options){
29
+ return fs.unlinkSync(filepath);
30
+ }
31
+
32
+ function chmod(filepath, mode, options){
33
+ return fs.chmodSync(gp(filepath), mode);
34
+ }
35
+
36
+ function mkdir(filepath, options){
37
+ return fs.mkdirSync(gp(filepath), options);
38
+ }
39
+
40
+ function ls(filepath, options){
41
+ return fs.readdirSync(gp(filepath), options);
42
+ }
43
+
44
+ return {
45
+ ls,
46
+ mkdir,
47
+ chmod,
48
+ rm,
49
+ fstat,
50
+ exists,
51
+ write,
52
+ read
53
+ };
54
+ }
@@ -14,9 +14,10 @@ module.exports = function future(callback, timeout = 0, defData = null) {
14
14
  });
15
15
  return {
16
16
  pipe: (callback) => promise.then(callback),
17
- pipex: (callback) => promise.finally(callback),
17
+ last: (callback) => promise.finally(callback),
18
18
  catch: (callback) => promise.catch(callback),
19
19
  resolve: (data) => listener.emit("resolve", data),
20
20
  reject: (data) => listener.emit("reject", data),
21
+ wait: async () => await promise
21
22
  };
22
23
  };
@@ -2,6 +2,26 @@ const path = require("path");
2
2
  const { getFile, file } = require("../modules/fs");
3
3
  const { importYaml } = require("../modules/yaml");
4
4
  const { findPackage, getPackage } = require("../pkgs/pkgs");
5
+ const { existsSync, readFileSync } = require("fs");
6
+ const conf = require("../pkgs/conf");
7
+ const jsYaml = require("js-yaml");
8
+ const { execOptions } = require("../const/opt");
9
+
10
+ const cachedFiles = [];
11
+
12
+ const lookUpInOtherApps = (fullPath) => {
13
+ const con = conf({});
14
+ const name = fullPath.indexOf('/') ? fullPath.split('/')[0] : fullPath;
15
+ let dpath = fullPath.indexOf('/') ? fullPath.split('/')[1] : '';
16
+ let ppath = path.join(con.CONFIG_PATH, name, 'app');
17
+ if(!existsSync(ppath)) return null;
18
+ if(!dpath){
19
+ dpath = jsYaml.load(readFileSync(path.join(ppath, 'app.yaml'), 'utf-8')).entry;
20
+ }
21
+ ppath = path.join(ppath, dpath);
22
+ if(existsSync(ppath)) return ppath;
23
+ else return null;
24
+ }
5
25
 
6
26
  module.exports.imp = function (runPath, context) {
7
27
  return function (filename, options = {}) {
@@ -9,24 +29,49 @@ module.exports.imp = function (runPath, context) {
9
29
  let exports,
10
30
  ispkg = findPackage(filename);
11
31
 
12
- const filepath = path.resolve(path.dirname(context.module.filepath), filename);
32
+ let filepath = path.resolve(path.dirname(context.module.filepath), filename);
13
33
 
14
34
  // console.log(typeof runPath);
15
35
 
36
+ const lookUp = () => {
37
+ const otherPath = lookUpInOtherApps(filename);
38
+ if(!otherPath) throw new Error('Module "'+filename+'" not found');
39
+ else filepath = otherPath;
40
+ }
41
+
42
+ const foundCache = cachedFiles.find(f => f.filepath == filepath);
43
+
44
+ if(!ispkg && foundCache){
45
+ exports = foundCache.exports;
46
+ }
47
+
48
+ if(!ispkg && !existsSync(filepath)){
49
+ if(Array.isArray(execOptions.resolveExtensions) && execOptions.resolveExtensions.length){
50
+ const resolve = execOptions.resolveExtensions.find(ext => typeof ext == "string" ? existsSync(filepath+ext) : existsSync(filepath+(ext.ext || '')));
51
+ if(resolve) {
52
+ filepath += typeof resolve == "string" ? resolve : resolve.ext;
53
+ if(typeof resolve == "object" && resolve.options){
54
+ if(resolve.options.type) type = resolve.options.type;
55
+ for(let i in resolve.options) options[i] = resolve.options[i];
56
+ }
57
+ } else lookUp();
58
+ } else lookUp();
59
+ }
60
+
61
+ const exec = (coptions = {}) => runPath(
62
+ filepath,
63
+ { ...options, useContext: execOptions.sharedContext == false ? false : true, ...coptions },
64
+ execOptions.sharedContext == false ? {} : context,
65
+ ).context.module.exports;
66
+
16
67
  if (ispkg) {
17
68
  exports = getPackage(filename)(context);
69
+ } else if(foundCache) {
70
+
18
71
  } else if (type == "coffee") {
19
- exports = runPath(
20
- filepath,
21
- { ...options, useContext: true },
22
- context,
23
- ).context.module.exports;
72
+ exports = exec({ });
24
73
  } else if (type == "js") {
25
- exports = runPath(
26
- filepath,
27
- { ...options, useContext: true, compile: false },
28
- context,
29
- ).context.module.exports;
74
+ exports = exec({ compile: false });
30
75
  } else if (type == "yaml" || type == "json" || type == "text") {
31
76
  const f = getFile(filepath);
32
77
  if (type == "yaml") {
@@ -51,6 +96,7 @@ module.exports.imp = function (runPath, context) {
51
96
  }
52
97
 
53
98
  if(!ispkg) context.module.imports.push(filepath);
99
+ if(!ispkg) cachedFiles.push({ filepath, exports });
54
100
 
55
101
  return exports;
56
102
  };
@@ -0,0 +1,13 @@
1
+ const path = require('path');
2
+
3
+ module.exports = (currentFile) => {
4
+ const e = {};
5
+ e.basename = (pathname, suffix) => path.basename(pathname, suffix);
6
+ e.dirname = (pathname) => path.dirname(pathname);
7
+ e.extname = (pathname) => path.extname(pathname);
8
+
9
+ e.pjoin = (...paths) => path.join(...paths);
10
+ e.presolve = (...paths) => path.resolve(...paths);
11
+
12
+ return e;
13
+ }
@@ -0,0 +1,41 @@
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+
4
+
5
+ module.exports.customRequire = function customRequire(modulePath, filePath) {
6
+ const resolvedPath = resolveModulePath(modulePath, filePath);
7
+ return require(resolvedPath);
8
+ }
9
+
10
+ function resolveModulePath(modulePath, filePath) {
11
+ if (modulePath.startsWith('./') || modulePath.startsWith('../') || path.isAbsolute(modulePath)) {
12
+ return path.resolve(modulePath);
13
+ }
14
+
15
+ const paths = module.constructor._nodeModulePaths(path.dirname(filePath));
16
+ for (const basePath of paths) {
17
+ const fullPath = path.join(basePath, modulePath);
18
+ if (fs.existsSync(fullPath + '.js')) {
19
+ return fullPath + '.js';
20
+ }
21
+ if (fs.existsSync(fullPath + '.json')) {
22
+ return fullPath + '.json';
23
+ }
24
+ if (fs.existsSync(fullPath) && fs.statSync(fullPath).isDirectory()) {
25
+ const packageJsonPath = path.join(fullPath, 'package.json');
26
+ if (fs.existsSync(packageJsonPath)) {
27
+ const main = require(packageJsonPath).main || 'index.js';
28
+ const mainPath = path.join(fullPath, main);
29
+ if (fs.existsSync(mainPath)) {
30
+ return mainPath;
31
+ }
32
+ }
33
+ const indexPath = path.join(fullPath, 'index.js');
34
+ if (fs.existsSync(indexPath)) {
35
+ return indexPath;
36
+ }
37
+ }
38
+ }
39
+
40
+ throw new Error(`Cannot find module '${modulePath}'`);
41
+ }
@@ -0,0 +1,30 @@
1
+ const { execSync, spawnSync } = require('child_process');
2
+ const fs = require('fs');
3
+
4
+ const print = module.exports.print = function print(...arguments) {
5
+ return console.log(...arguments);
6
+ };
7
+
8
+ print.stdout = process.stdout;
9
+ print.stdin = process.stdin;
10
+
11
+ module.exports.input = function input(prompt) {
12
+ process.stdout.write(prompt);
13
+
14
+ let cmd;
15
+ let args;
16
+ if ("null" == "win32") {
17
+ cmd = 'cmd';
18
+ args = ['/V:ON', '/C', 'set /p response= && echo !response!'];
19
+ } else {
20
+ cmd = 'bash';
21
+ args = ['-c', 'read response; echo "$response"'];
22
+ }
23
+
24
+ let opts = {
25
+ stdio: ['inherit', 'pipe'],
26
+ shell: false,
27
+ };
28
+
29
+ return spawnSync(cmd, args, opts).stdout.toString().trim();
30
+ }
@@ -67,11 +67,39 @@ function typei(child, parent) {
67
67
  return child instanceof parent || child.constructor === parent;
68
68
  }
69
69
 
70
+ function int(str){
71
+ return parseInt(str);
72
+ }
73
+
74
+ function float(str){
75
+ return parseFloat(str);
76
+ }
77
+
78
+ function num(str){
79
+ return Number(str);
80
+ }
81
+
82
+ function str(str){
83
+ return str ? str.toString() : "";
84
+ }
85
+
86
+ function bool(value){
87
+ return typeof value == 'string' ? (
88
+ value == 'true' ? true : false
89
+ ) : value !== null && value !== undefined;
90
+ }
91
+
70
92
  module.exports = {
71
93
  typex,
72
94
  typei,
73
95
  typeis,
74
- typedef
96
+ typedef,
97
+
98
+ int,
99
+ float,
100
+ num,
101
+ str,
102
+ bool
75
103
  }
76
104
 
77
105
 
@@ -1,7 +1,11 @@
1
1
  const defaultContext = require("../const/default");
2
+ const { execOptions } = require("../const/opt");
2
3
  const emitter = require("../functions/emitter");
3
4
  const { exportsFunction } = require("../functions/export");
4
5
  const { imp } = require("../functions/import");
6
+ const { customRequire } = require("../functions/require");
7
+ const fsLib = require('../functions/fs');
8
+ const pathLib = require('../functions/path');
5
9
 
6
10
  module.exports.prepareContext = function (
7
11
  custom_context,
@@ -16,6 +20,7 @@ module.exports.prepareContext = function (
16
20
  filepath,
17
21
  imports: []
18
22
  },
23
+ ...fsLib(filepath)
19
24
  };
20
25
  if (options.useContext) {
21
26
  context = {
@@ -26,13 +31,20 @@ module.exports.prepareContext = function (
26
31
  context = {
27
32
  ...context,
28
33
  ...defaultContext,
34
+ ...pathLib(filepath),
29
35
  require: (package) => {
30
36
  try {
31
- return require(package);
37
+ return execOptions.nativeRequire || package.startsWith('node:') ? require(package.startsWith('node:') ? package.split('node:')[1] : package) : customRequire(package, filepath);
32
38
  } catch (e) {
33
- throw new Error("Module not found");
39
+ throw new Error("Module "+package+" not found");
34
40
  }
35
41
  },
42
+ opt: {
43
+ set: (key, value) => execOptions[key] = value,
44
+ get: (key) => execOptions[key],
45
+ push: (key, value) => execOptions[key]?.push(value),
46
+ pop: (key) => execOptions[key]?.pop()
47
+ },
36
48
  ...custom_context,
37
49
  };
38
50
  context.imp = imp(runPath, context);
@@ -44,6 +56,8 @@ module.exports.prepareContext = function (
44
56
  argv: process.argv,
45
57
  target: emitter(),
46
58
  env: process.env,
59
+ cwd: () => process.cwd(),
60
+ arch: process.arch
47
61
  };
48
62
  // console.log(custom_context);
49
63
  return context;
@@ -0,0 +1,9 @@
1
+
2
+
3
+ module.exports = (context) => ({
4
+ has: (key) => key in process.env,
5
+ get: (key) => process.env[key],
6
+ set: (key, value) => process.env[key] = value,
7
+ rm: (key) => delete process.env[key],
8
+ is: (key, value) => process.env[key] == value
9
+ })
@@ -0,0 +1,37 @@
1
+ const { parentPort, workerData } = require('worker_threads');
2
+ const { exec } = require('../../../modules/runtime');
3
+
4
+ const target = {};
5
+ target.events = [];
6
+ target.on = (e, cb) => {
7
+ target.events.push({ e, cb });
8
+ }
9
+ target.off = (e) => {
10
+ target.events = target.events.filter(i => i.e !== e);
11
+ }
12
+ target.emit = (e, data) => {
13
+ target.events.filter(i => i.e == e).forEach(i => i.cb(data));
14
+ }
15
+
16
+ parentPort.on('message', (data) => {
17
+ if (data.type === 'event') {
18
+ target.emit(data.event, data.data);
19
+ } else if (data.type === 'start') {
20
+ (async () => {
21
+ try {
22
+ exec(`(${workerData.cb}).call({ process }, context)`, { print: (...a) => console.log(...a), process: {
23
+ on: (e, cb) => { target.on(e, cb) },
24
+ off: (e) => { target.off(e) },
25
+ emit: (e) => { parentPort.postMessage({ type: 'event', event: e, data }) },
26
+ exit: (code) => process.exit(code),
27
+ finish: (data) => {
28
+ parentPort.postMessage({ type: 'result', result: data });
29
+ process.exit(0)
30
+ }
31
+ }, context: workerData.context })
32
+ } catch (e) {
33
+ parentPort.postMessage({ type: 'error', error: e.message });
34
+ }
35
+ })();
36
+ }
37
+ });
@@ -0,0 +1,67 @@
1
+ const { Worker } = require('worker_threads');
2
+ const emitter = require('../functions/emitter');
3
+ const future = require('../functions/future');
4
+ const { struct } = require('../models/struct');
5
+ const path = require('path');
6
+
7
+ module.exports = (context) => ({
8
+ thread: (cb) => {
9
+ const workers = [];
10
+
11
+ const stopWorker = (worker) => {
12
+ workers.splice(workers.indexOf(worker), 1);
13
+ worker.terminate()
14
+ };
15
+
16
+ const athread = {
17
+ stopAll: () => {
18
+ if (!run) return;
19
+ workers.forEach(stopWorker);
20
+ },
21
+ start: (context) => {
22
+ let dataResult = future(() => {}), listener = emitter();
23
+ const worker = new Worker(path.resolve(__dirname, './modules/threads/worker.js'), {
24
+ workerData: { context, cb: cb.toString() }
25
+ });
26
+ workers.push(worker);
27
+
28
+ const stop = () => stopWorker(worker);
29
+
30
+ worker.on('message', (data) => {
31
+ if (data.type === 'result') {
32
+ dataResult.resolve(data.result);
33
+ stop();
34
+ } else if (data.type === 'error') {
35
+ reject(new Error(data.error));
36
+ stop();
37
+ } else if (data.type === 'event') {
38
+ listener.emit(data.event, data.data);
39
+ }
40
+ });
41
+
42
+ worker.on('error', (error) => {
43
+ console.log(error);
44
+ stop();
45
+ });
46
+
47
+ worker.on('exit', (code) => {
48
+ stop();
49
+ if (code !== 0) {
50
+ throw new Error(`Worker stopped with exit code ${code}`);
51
+ }
52
+ });
53
+
54
+ worker.postMessage({ type: 'start' });
55
+
56
+ return {
57
+ on: (e, cb) => listener.on(e, cb),
58
+ off: (e, cb) => listener.off(e, cb),
59
+ emit: (e, data) => worker?.postMessage({ type: 'event', event: e, data }),
60
+ get: () => dataResult.wait()
61
+ };
62
+ }
63
+ };
64
+
65
+ return athread;
66
+ }
67
+ });
package/package.json CHANGED
@@ -1,16 +1,13 @@
1
1
  {
2
2
  "name": "@makano/rew",
3
- "version": "1.1.0",
3
+ "version": "1.1.2",
4
4
  "description": "A simple coffescript runtime",
5
5
  "main": "lib/rew/main.js",
6
6
  "directories": {
7
7
  "lib": "lib"
8
8
  },
9
9
  "scripts": {
10
- "test": "node test/test.js",
11
- "docs:dev": "vitepress dev docs",
12
- "docs:build": "vitepress build docs",
13
- "docs:preview": "vitepress preview docs"
10
+ "test": "node test/test.js"
14
11
  },
15
12
  "files": [
16
13
  "lib/",
@@ -32,7 +29,6 @@
32
29
  "chokidar": "^3.6.0",
33
30
  "js-yaml": "^4.1.0",
34
31
  "vm": "^0.1.0",
35
- "ws": "^8.17.0",
36
32
  "yargs": "^17.7.2"
37
33
  },
38
34
  "devDependencies": {