rtjscomp 0.8.3 → 0.8.4
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.
- package/package.json +1 -1
- package/rtjscomp.js +86 -49
package/package.json
CHANGED
package/rtjscomp.js
CHANGED
|
@@ -22,6 +22,7 @@ const PATH_PUBLIC = 'public/';
|
|
|
22
22
|
const PATH_CONFIG = 'config/';
|
|
23
23
|
const PATH_DATA = 'data/';
|
|
24
24
|
const GZIP_OPTIONS = {level: 9};
|
|
25
|
+
const WATCH_OPTIONS = {persistent: true, interval: 1000};
|
|
25
26
|
const AGENT_CHECK_BOT = /bot|googlebot|crawler|spider|robot|crawling|favicon/i;
|
|
26
27
|
const AGENT_CHECK_MOBIL = /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino|android|ipad|playbook|silk/i;
|
|
27
28
|
const HTTP_LIST_REG = /,\s*/;
|
|
@@ -59,6 +60,29 @@ if (!Object.fromEntries) {
|
|
|
59
60
|
};
|
|
60
61
|
}
|
|
61
62
|
|
|
63
|
+
// workaround for bun: https://github.com/oven-sh/bun/issues/18919
|
|
64
|
+
let fs_watch = fs.watch;
|
|
65
|
+
if (typeof Bun !== 'undefined') {
|
|
66
|
+
const fs_watch_original = fs_watch;
|
|
67
|
+
const watch_callbacks = new Map;
|
|
68
|
+
fs_watch = (path, options, callback) => {
|
|
69
|
+
if (!watch_callbacks.has(path)) {
|
|
70
|
+
fs_watch_original(path, options, () => {
|
|
71
|
+
const callback = watch_callbacks.get(path);
|
|
72
|
+
if (callback) {
|
|
73
|
+
callback();
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
watch_callbacks.set(path, callback);
|
|
78
|
+
return {
|
|
79
|
+
close: () => (
|
|
80
|
+
watch_callbacks.set(path, null)
|
|
81
|
+
),
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
62
86
|
// legacy, will be removed soon!
|
|
63
87
|
global.globals = rtjscomp;
|
|
64
88
|
global.actions = rtjscomp.actions;
|
|
@@ -141,6 +165,7 @@ actions.module_cache_clear = () => {
|
|
|
141
165
|
custom_require_cache.clear();
|
|
142
166
|
custom_import_cache.clear();
|
|
143
167
|
}
|
|
168
|
+
const AsyncFunction = custom_import.constructor;
|
|
144
169
|
|
|
145
170
|
const services_active = new Map;
|
|
146
171
|
const services_loading = new Set;
|
|
@@ -161,21 +186,25 @@ const service_start = async path => {
|
|
|
161
186
|
handler_stop: null,
|
|
162
187
|
path,
|
|
163
188
|
stopped: false,
|
|
189
|
+
watcher: null,
|
|
164
190
|
};
|
|
165
191
|
|
|
166
|
-
await file_keep_new(
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
192
|
+
service_object.watcher = await file_keep_new(
|
|
193
|
+
PATH_PUBLIC + path + '.service.js',
|
|
194
|
+
async file_content => {
|
|
195
|
+
if (file_content === null) {
|
|
196
|
+
log('[error] service file not found: ' + path);
|
|
197
|
+
return service_stop(service_object, true);
|
|
198
|
+
}
|
|
199
|
+
if (services_loading.size > 0) {
|
|
200
|
+
await Promise.all(Array.from(services_loading));
|
|
201
|
+
}
|
|
202
|
+
const start_promise = service_start_inner(path, service_object, file_content);
|
|
203
|
+
services_loading.add(start_promise);
|
|
204
|
+
await start_promise;
|
|
205
|
+
services_loading.delete(start_promise);
|
|
173
206
|
}
|
|
174
|
-
|
|
175
|
-
services_loading.add(start_promise);
|
|
176
|
-
await start_promise;
|
|
177
|
-
services_loading.delete(start_promise);
|
|
178
|
-
});
|
|
207
|
+
);
|
|
179
208
|
}
|
|
180
209
|
const service_start_inner = async (path, service_object, file_content) => {
|
|
181
210
|
if (services_active.has(path)) {
|
|
@@ -193,14 +222,15 @@ const service_start_inner = async (path, service_object, file_content) => {
|
|
|
193
222
|
}
|
|
194
223
|
|
|
195
224
|
try {
|
|
196
|
-
const
|
|
197
|
-
|
|
225
|
+
const result = await (new AsyncFunction(
|
|
226
|
+
'require',
|
|
227
|
+
'custom_import',
|
|
228
|
+
`const log=a=>rtjscomp.log(${
|
|
198
229
|
JSON.stringify(path + ': ')
|
|
199
230
|
}+a);${
|
|
200
231
|
file_content.replace(IMPORT_REG, 'custom_import(') + '\n'
|
|
201
|
-
}
|
|
202
|
-
);
|
|
203
|
-
const result = await fun.call(content_object, custom_require, custom_import);
|
|
232
|
+
}`
|
|
233
|
+
)).call(content_object, custom_require, custom_import);
|
|
204
234
|
if (service_object.stopped) {
|
|
205
235
|
clearInterval(start_interval);
|
|
206
236
|
return;
|
|
@@ -247,11 +277,12 @@ const services_shutdown = () => (
|
|
|
247
277
|
.map(service_object => service_stop(service_object, true))
|
|
248
278
|
)
|
|
249
279
|
)
|
|
250
|
-
const service_stop =
|
|
251
|
-
service_object.stopped = true
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
280
|
+
const service_stop = (service_object, forget) => (
|
|
281
|
+
service_object.stopped = true,
|
|
282
|
+
forget && service_object.watcher &&
|
|
283
|
+
service_object.watcher.close(),
|
|
284
|
+
service_stop_handler(service_object)
|
|
285
|
+
)
|
|
255
286
|
const service_stop_handler = async service_object => {
|
|
256
287
|
services_active.delete(service_object.path);
|
|
257
288
|
log('stop service: ' + service_object.path);
|
|
@@ -307,36 +338,34 @@ const map_generate_equ = (map, data) => {
|
|
|
307
338
|
}
|
|
308
339
|
}
|
|
309
340
|
|
|
310
|
-
const
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
)
|
|
316
|
-
|
|
317
|
-
fs.watchFile(path, (curr, prev) => {
|
|
318
|
-
if (file_compare(curr, prev, path)) {
|
|
319
|
-
fs.unwatchFile(path);
|
|
320
|
-
callback();
|
|
321
|
-
}
|
|
322
|
-
})
|
|
323
|
-
)
|
|
341
|
+
const file_watch_once = (path, callback) => {
|
|
342
|
+
const watcher = fs_watch(path, WATCH_OPTIONS, () => (
|
|
343
|
+
watcher.close(),
|
|
344
|
+
log_verbose && log('file updated: ' + path),
|
|
345
|
+
callback()
|
|
346
|
+
));
|
|
347
|
+
};
|
|
324
348
|
const file_keep_new = async (path, callback) => {
|
|
325
349
|
try {
|
|
326
350
|
const data = await fsp.readFile(path, 'utf8');
|
|
327
351
|
if (log_verbose) log('load file: ' + path);
|
|
328
352
|
await callback(data);
|
|
329
|
-
fs.watchFile(path, async (curr, prev) => {
|
|
330
|
-
if (file_compare(curr, prev, path)) {
|
|
331
|
-
await callback(
|
|
332
|
-
await fsp.readFile(path, 'utf8').catch(() => null)
|
|
333
|
-
);
|
|
334
|
-
}
|
|
335
|
-
});
|
|
336
353
|
}
|
|
337
354
|
catch (err) {
|
|
338
355
|
await callback(null);
|
|
356
|
+
return null;
|
|
339
357
|
}
|
|
358
|
+
|
|
359
|
+
let timeout = 0;
|
|
360
|
+
return fs_watch(path, WATCH_OPTIONS, () => (
|
|
361
|
+
clearTimeout(timeout),
|
|
362
|
+
timeout = setTimeout(() => (
|
|
363
|
+
log_verbose && log('file updated: ' + path),
|
|
364
|
+
fsp.readFile(path, 'utf8')
|
|
365
|
+
.catch(() => null)
|
|
366
|
+
.then(callback)
|
|
367
|
+
), 50)
|
|
368
|
+
));
|
|
340
369
|
}
|
|
341
370
|
|
|
342
371
|
let log_history = rtjscomp.log_history = [];
|
|
@@ -510,7 +539,7 @@ const request_handle = async (request, response, https) => {
|
|
|
510
539
|
if (file_stat.isDirectory()) throw 403;
|
|
511
540
|
|
|
512
541
|
if (file_dyn_enabled) { // compile file
|
|
513
|
-
const file_content =
|
|
542
|
+
const file_content = await fsp.readFile(path_real, 'utf8');
|
|
514
543
|
try {
|
|
515
544
|
if (file_content.includes('\r')) {
|
|
516
545
|
throw 'illegal line break, must be unix';
|
|
@@ -520,7 +549,7 @@ const request_handle = async (request, response, https) => {
|
|
|
520
549
|
}
|
|
521
550
|
const file_content_length = file_content.length;
|
|
522
551
|
|
|
523
|
-
let code = `
|
|
552
|
+
let code = `const log=a=>rtjscomp.log(${
|
|
524
553
|
JSON.stringify(path + ': ')
|
|
525
554
|
}+a);`;
|
|
526
555
|
|
|
@@ -596,7 +625,15 @@ const request_handle = async (request, response, https) => {
|
|
|
596
625
|
}
|
|
597
626
|
|
|
598
627
|
try {
|
|
599
|
-
file_function =
|
|
628
|
+
file_function = new AsyncFunction(
|
|
629
|
+
'input',
|
|
630
|
+
'output',
|
|
631
|
+
'request',
|
|
632
|
+
'response',
|
|
633
|
+
'require',
|
|
634
|
+
'custom_import',
|
|
635
|
+
code
|
|
636
|
+
);
|
|
600
637
|
}
|
|
601
638
|
catch (err) {
|
|
602
639
|
throw err.message;
|
|
@@ -608,9 +645,9 @@ const request_handle = async (request, response, https) => {
|
|
|
608
645
|
}
|
|
609
646
|
|
|
610
647
|
file_cache_functions.set(path, file_function);
|
|
611
|
-
|
|
612
|
-
file_cache_functions.delete(path)
|
|
613
|
-
|
|
648
|
+
file_watch_once(path_real, () => (
|
|
649
|
+
file_cache_functions.delete(path)
|
|
650
|
+
));
|
|
614
651
|
}
|
|
615
652
|
}
|
|
616
653
|
|