miqro 6.2.11 → 6.2.13

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.
@@ -1,5 +1,5 @@
1
1
  import { Router, newURL, Response, Request, RouterHandlerOptions, Logger, APIRoute, normalizePath, HandlerWithOptions, Handler } from "@miqro/core";
2
- import { existsSync, mkdirSync, readFile, readFileSync, readdirSync, statSync, writeFileSync } from "node:fs";
2
+ import { existsSync, mkdir, readFile, readFileSync, readdirSync, statSync } from "node:fs";
3
3
  import { dirname, join, relative, resolve as pathResolve } from "node:path";
4
4
 
5
5
  import { CONTENT_TYPE_MAP, DEFAULT_CONTENT_TYPE } from "../common/content-type.js";
@@ -13,7 +13,7 @@ import { getHTTPRouterPath, getStaticFilesPath } from "../common/paths.js";
13
13
  import { setupCORS } from "./setup-cors.js";
14
14
  import { setupAUTH } from "./setup-auth.js";
15
15
  import { getRoutes } from "../services/utils/get-route.js";
16
- import { describeFilePath } from "../common/fs.js";
16
+ import { describeFilePath, mkdirASync, writeFileASync } from "../common/fs.js";
17
17
  import { inflateMD2HTML } from "./md.js";
18
18
  import { MiddlewareConfig, ServerInterface, ServerRequest } from "../types.js";
19
19
  import { setupMiddleware } from "./setup-middleware.js";
@@ -45,7 +45,7 @@ export interface StaticFileMap {
45
45
  }
46
46
  }
47
47
 
48
- export async function setupHTTPRouter(server: ServerInterface, logger: Logger, hotreload: boolean, servicePath: string, service: string, routeFileMap: RouteFileMap, staticFileMap: StaticFileMap | null, inflateDir: string | undefined | false, inflateSea: boolean, errors: InflateError[]) {
48
+ export async function setupHTTPRouter(server: ServerInterface, logger: Logger, hotreload: boolean, servicePath: string, service: string, routeFileMap: RouteFileMap, staticFileMap: StaticFileMap | null, inflateDir: string | undefined | false, inflateSea: boolean, errors: InflateError[], inflateParallel?: number) {
49
49
  const mainRouter = new Router();
50
50
  const apiRouterPath = getHTTPRouterPath(servicePath); //resolve(process.cwd(), service, "http");
51
51
  let middlewareConfig: MiddlewareConfig | null = null;
@@ -58,14 +58,14 @@ export async function setupHTTPRouter(server: ServerInterface, logger: Logger, h
58
58
 
59
59
  if (apiRouterPath) {
60
60
  logger.trace("setting up http routes from [%s]", service);
61
- const { router: httpRouter } = await createRouterFromDirectory(server, hotreload, service, logger, apiRouterPath, errors, routeFileMap, staticFileMap, inflateDir, inflateSea);
61
+ const { router: httpRouter } = await createRouterFromDirectory(server, hotreload, service, logger, apiRouterPath, errors, routeFileMap, staticFileMap, inflateDir, inflateSea, inflateParallel);
62
62
  mainRouter.use(httpRouter);
63
63
  }
64
64
 
65
65
  const staticFilesPath = getStaticFilesPath(servicePath); //resolve(process.cwd(), service, "static");
66
66
  if (staticFilesPath) {
67
67
  logger.trace("setting up static file routes from [%s]", service);
68
- const staticRouter = createStaticRouterFromDirectory(service, logger, staticFilesPath, inflateDir, routeFileMap, staticFileMap);
68
+ const staticRouter = await createStaticRouterFromDirectory(service, logger, staticFilesPath, inflateDir, routeFileMap, staticFileMap, inflateParallel);
69
69
  mainRouter.use(staticRouter);
70
70
  }
71
71
 
@@ -78,95 +78,123 @@ export async function setupHTTPRouter(server: ServerInterface, logger: Logger, h
78
78
  return mainRouter;
79
79
  }
80
80
 
81
- function createStaticRoute(service: string, logger: Logger, router: Router, dir: string, file: ScannedFile, inflateDir?: string | undefined | false, routeFileMap?: RouteFileMap, staticFileMap?: StaticFileMap) {
82
- logger.trace("creating static route for [%s]", file.filePath);
83
- logger.trace("[%o]", {
84
- file,
85
- dir
86
- });
87
- const contentType = CONTENT_TYPE_MAP[String(file.ext).toLocaleLowerCase()];
88
- const path = join("/", relative(dir, file.filePath));
89
-
90
-
91
- routeFileMap[file.filePath] = {
92
- routes: [{
93
- method: "GET",
94
- path: normalizePath(path)
95
- }],
96
- service,
97
- filePath: file.filePath,
98
- previewMethod: "html"
99
- };
100
-
101
- if (inflateDir) {
102
- const inflatePath = join(inflateDir, service, "static", path);
103
- mkdirSync(dirname(inflatePath), {
104
- recursive: true
105
- });
106
- logger.log("writing [%s]", relative(cwd(), inflatePath));
107
- const body = readFileSync(file.filePath);
108
- writeFileSync(inflatePath, body);
109
- if (staticFileMap) {
110
- staticFileMap[file.filePath] = {
111
- contentType,
81
+ async function createStaticRoute(service: string, logger: Logger, router: Router, dir: string, file: ScannedFile, inflateDir?: string | undefined | false, routeFileMap?: RouteFileMap, staticFileMap?: StaticFileMap) {
82
+ return new Promise<void>(async (resolve, reject) => {
83
+ try {
84
+ logger.trace("creating static route for [%s]", file.filePath);
85
+ logger.trace("[%o]", {
86
+ file,
87
+ dir
88
+ });
89
+ const contentType = CONTENT_TYPE_MAP[String(file.ext).toLocaleLowerCase()];
90
+ const path = join("/", relative(dir, file.filePath));
91
+
92
+
93
+ routeFileMap[file.filePath] = {
94
+ routes: [{
95
+ method: "GET",
96
+ path: normalizePath(path)
97
+ }],
98
+ service,
112
99
  filePath: file.filePath,
113
- previewMethod: "html",
114
- method: "GET",
115
- path: normalizePath(path),
116
- body: Buffer.from(body),
117
- inflatePath: inflateDir ? join(inflateDir, service, "static", path) : undefined
100
+ previewMethod: "html"
101
+ };
102
+
103
+ if (inflateDir) {
104
+ const inflatePath = join(inflateDir, service, "static", path);
105
+ mkdir(dirname(inflatePath), {
106
+ recursive: true
107
+ }, (err) => {
108
+
109
+ })
110
+ await mkdirASync(dirname(inflatePath), {
111
+ recursive: true
112
+ });
113
+ logger.log("writing [%s]", relative(cwd(), inflatePath));
114
+ const body = readFileSync(file.filePath);
115
+ await writeFileASync(inflatePath, body);
116
+ if (staticFileMap) {
117
+ staticFileMap[file.filePath] = {
118
+ contentType,
119
+ filePath: file.filePath,
120
+ previewMethod: "html",
121
+ method: "GET",
122
+ path: normalizePath(path),
123
+ body: Buffer.from(body),
124
+ inflatePath: inflateDir ? join(inflateDir, service, "static", path) : undefined
125
+ }
126
+ }
118
127
  }
119
- }
120
- }
121
128
 
122
129
 
123
130
 
124
- router.use(assertGlobalTampered);
125
- router.get(path, async function (_req, res) {
126
- await new Promise<void>((resolve, reject) => {
127
- try {
128
- readFile(file.filePath, async (err, body) => {
129
- if (err) {
130
- reject(err);
131
- } else {
132
- try {
133
- await res.asyncEnd({
134
- status: 200,
135
- headers: {
136
- ["Content-Type"]: contentType ? contentType : DEFAULT_CONTENT_TYPE
137
- },
138
- body
139
- });
140
- resolve();
141
- } catch (e) {
142
- reject(e);
143
- }
131
+ router.use(assertGlobalTampered);
132
+ router.get(path, async function (_req, res) {
133
+ await new Promise<void>((resolve, reject) => {
134
+ try {
135
+ readFile(file.filePath, async (err, body) => {
136
+ if (err) {
137
+ reject(err);
138
+ } else {
139
+ try {
140
+ await res.asyncEnd({
141
+ status: 200,
142
+ headers: {
143
+ ["Content-Type"]: contentType ? contentType : DEFAULT_CONTENT_TYPE
144
+ },
145
+ body
146
+ });
147
+ resolve();
148
+ } catch (e) {
149
+ reject(e);
150
+ }
151
+ }
152
+ })
153
+ } catch (e) {
154
+ reject(e);
144
155
  }
145
- })
146
- } catch (e) {
147
- reject(e);
148
- }
149
- });
156
+ });
157
+ });
158
+ resolve();
159
+ } catch (e) {
160
+ reject(e);
161
+ }
150
162
  });
151
163
  }
152
164
 
153
- function createStaticRouterFromDirectory(service: string, logger: Logger, dir: string, inflateDir: string | false | undefined, routeFileMap: RouteFileMap | undefined, staticFileMap: StaticFileMap | null): Router {
165
+ async function createStaticRouterFromDirectory(service: string, logger: Logger, dir: string, inflateDir: string | false | undefined, routeFileMap: RouteFileMap | undefined, staticFileMap: StaticFileMap | null, inflateParallel?: number): Promise<Router> {
154
166
  const router = new Router();
155
- scanFiles(dir).forEach(file => {
156
- createStaticRoute(service, logger, router, dir, file, inflateDir, routeFileMap, staticFileMap);
157
- });
167
+ const maxParallel = inflateParallel ? inflateParallel : 1;
168
+ logger.debug("loading static directory with parallel [%s]", maxParallel);
169
+ let tR = [];
170
+ const files = scanFiles(dir);
171
+ for (const file of files) {
172
+ tR.push(await createStaticRoute(service, logger, router, dir, file, inflateDir, routeFileMap, staticFileMap));
173
+ if (tR.length >= maxParallel) {
174
+ await Promise.all(tR);
175
+ tR = [];
176
+ }
177
+ }
178
+ if (tR.length > 0) {
179
+ await Promise.all(tR);
180
+ tR = [];
181
+ }
158
182
  return router;
159
183
  }
160
184
 
161
- async function createRouterFromDirectory(server: ServerInterface, hotreload: boolean, service: string, logger: Logger, dir: string, errors: InflateError[] = [], routeFileMap: RouteFileMap = {}, staticFileMap: StaticFileMap | null = null, inflateDir: string | undefined | false, inflateSea: boolean): Promise<{
185
+ async function createRouterFromDirectory(server: ServerInterface, hotreload: boolean, service: string, logger: Logger, dir: string, errors: InflateError[] = [], routeFileMap: RouteFileMap = {}, staticFileMap: StaticFileMap | null = null, inflateDir: string | undefined | false, inflateSea: boolean, inflateParallel?: number): Promise<{
162
186
  router: Router;
163
187
  errors: InflateError[];
164
188
  routeFileMap: RouteFileMap;
165
189
  }> {
166
190
  const router = new Router();
191
+ const maxParallel = inflateParallel ? inflateParallel : 1;
192
+ server.logger.debug("loading http directory with parallel [%s]", maxParallel);
193
+ let tR = [];
167
194
  router.use(assertGlobalTampered);
168
- for (const file of scanFiles(dir)) {
169
- await new Promise<void>(async (resolve) => {
195
+ const files = scanFiles(dir);
196
+ for (const file of files) {
197
+ tR.push(new Promise<void>(async (resolve) => {
170
198
  try {
171
199
  switch (file.ext) {
172
200
  case ".jsx":
@@ -216,11 +244,11 @@ async function createRouterFromDirectory(server: ServerInterface, hotreload: boo
216
244
  if (inflateDir && r.defaultInflatePath && inflateSea) {
217
245
  const rPath = r.defaultInflatePath;
218
246
  const inflatePath = join(inflateDir, service, "http", rPath + ".api.cjs");
219
- mkdirSync(dirname(inflatePath), {
247
+ await mkdirASync(dirname(inflatePath), {
220
248
  recursive: true
221
249
  });
222
250
  logger.log("writing [%s]", relative(cwd(), inflatePath));
223
- writeFileSync(inflatePath, inflatedCode);
251
+ await writeFileASync(inflatePath, inflatedCode);
224
252
  }
225
253
 
226
254
 
@@ -252,7 +280,7 @@ async function createRouterFromDirectory(server: ServerInterface, hotreload: boo
252
280
  //if (r.method === "GET" || r.method === "get") {
253
281
  const rPath = r.inflatePath;
254
282
  const inflatePath = join(inflateDir, service, "static", rPath);
255
- mkdirSync(dirname(inflatePath), {
283
+ await mkdirASync(dirname(inflatePath), {
256
284
  recursive: true
257
285
  });
258
286
  if (existsSync(inflatePath) && statSync(inflatePath).isDirectory()) {
@@ -262,7 +290,7 @@ async function createRouterFromDirectory(server: ServerInterface, hotreload: boo
262
290
  const JSON_STATIC = await getJSON({ server } as ServerRequest, null, newURL(r.path), module.apiOptions?.basePath, module.default);
263
291
  //const JSON = await getJSON({ server } as ServerRequest, null, newURL(r.path), module.apiOptions?.basePath, module.default);
264
292
  logger.log("writing [%s]", relative(cwd(), inflatePath));
265
- writeFileSync(inflatePath, JSON_STATIC);
293
+ await writeFileASync(inflatePath, JSON_STATIC);
266
294
  //}
267
295
 
268
296
  if (staticFileMap && inflateSea) {
@@ -319,7 +347,7 @@ async function createRouterFromDirectory(server: ServerInterface, hotreload: boo
319
347
  //if (r.method === "GET" || r.method === "get") {
320
348
  const rPath = r.inflatePath;
321
349
  const inflatePath = join(inflateDir, service, "static", rPath);
322
- mkdirSync(dirname(inflatePath), {
350
+ await mkdirASync(dirname(inflatePath), {
323
351
  recursive: true
324
352
  });
325
353
  if (existsSync(inflatePath) && statSync(inflatePath).isDirectory()) {
@@ -330,7 +358,7 @@ async function createRouterFromDirectory(server: ServerInterface, hotreload: boo
330
358
  const HTML_STATIC = await getHTML(hotreload, { server } as ServerRequest, null, newURL(r.path), module.apiOptions?.basePath, await toRender);
331
359
 
332
360
  logger.log("writing [%s]", relative(cwd(), inflatePath));
333
- writeFileSync(inflatePath, HTML_STATIC);
361
+ await writeFileASync(inflatePath, HTML_STATIC);
334
362
  //}
335
363
 
336
364
 
@@ -390,11 +418,11 @@ async function createRouterFromDirectory(server: ServerInterface, hotreload: boo
390
418
 
391
419
  if (inflateDir) {
392
420
  const inflatePath = join(inflateDir, service, "static", path);
393
- mkdirSync(dirname(inflatePath), {
421
+ await mkdirASync(dirname(inflatePath), {
394
422
  recursive: true
395
423
  });
396
424
  logger.log("writing [%s]", relative(cwd(), inflatePath));
397
- writeFileSync(inflatePath, code);
425
+ await writeFileASync(inflatePath, code);
398
426
 
399
427
 
400
428
  if (staticFileMap && inflateSea) {
@@ -443,11 +471,11 @@ async function createRouterFromDirectory(server: ServerInterface, hotreload: boo
443
471
 
444
472
  if (inflateDir) {
445
473
  const inflatePath = join(inflateDir, service, "static", path);
446
- mkdirSync(dirname(inflatePath), {
474
+ await mkdirASync(dirname(inflatePath), {
447
475
  recursive: true
448
476
  });
449
477
  logger.log("writing [%s]", relative(cwd(), inflatePath));
450
- writeFileSync(inflatePath, code);
478
+ await writeFileASync(inflatePath, code);
451
479
  if (staticFileMap && inflateSea) {
452
480
  staticFileMap[file.filePath] = {
453
481
  contentType,
@@ -504,11 +532,11 @@ async function createRouterFromDirectory(server: ServerInterface, hotreload: boo
504
532
 
505
533
  if (inflateDir) {
506
534
  const inflatePath = join(inflateDir, service, "static", path);
507
- mkdirSync(dirname(inflatePath), {
535
+ await mkdirASync(dirname(inflatePath), {
508
536
  recursive: true
509
537
  });
510
538
  logger.log("writing [%s]", relative(cwd(), inflatePath));
511
- writeFileSync(inflatePath, code);
539
+ await writeFileASync(inflatePath, code);
512
540
  if (staticFileMap && inflateSea) {
513
541
  staticFileMap[file.filePath] = {
514
542
  contentType,
@@ -562,11 +590,11 @@ async function createRouterFromDirectory(server: ServerInterface, hotreload: boo
562
590
 
563
591
  if (inflateDir) {
564
592
  const inflatePath = join(inflateDir, service, "static", path);
565
- mkdirSync(dirname(inflatePath), {
593
+ await mkdirASync(dirname(inflatePath), {
566
594
  recursive: true
567
595
  });
568
596
  logger.log("writing [%s]", relative(cwd(), inflatePath));
569
- writeFileSync(inflatePath, code);
597
+ await writeFileASync(inflatePath, code);
570
598
  if (staticFileMap && inflateSea) {
571
599
  staticFileMap[file.filePath] = {
572
600
  contentType,
@@ -594,7 +622,7 @@ async function createRouterFromDirectory(server: ServerInterface, hotreload: boo
594
622
  }
595
623
  }
596
624
  }
597
- createStaticRoute(service, logger, router, dir, file, inflateDir, routeFileMap, staticFileMap);
625
+ await createStaticRoute(service, logger, router, dir, file, inflateDir, routeFileMap, staticFileMap);
598
626
  return resolve();
599
627
 
600
628
  }
@@ -608,7 +636,15 @@ async function createRouterFromDirectory(server: ServerInterface, hotreload: boo
608
636
  } finally {
609
637
  return resolve();
610
638
  }
611
- });
639
+ }));
640
+ if (tR.length >= maxParallel) {
641
+ await Promise.all(tR);
642
+ tR = [];
643
+ }
644
+ }
645
+ if (tR.length > 0) {
646
+ await Promise.all(tR);
647
+ tR = [];
612
648
  }
613
649
  router.use(assertGlobalTampered);
614
650
  return {
package/src/main.ts CHANGED
@@ -30,7 +30,9 @@ async function main(args: Arguments) {
30
30
  // check arguments
31
31
  if (args.generateDoc) {
32
32
  // --generate-doc
33
- const inflated = await app.inflate();
33
+ const inflated = await app.inflate({
34
+ inflateParallel: args.inflateParallel
35
+ });
34
36
  await generateDocs(args, app.logger, inflated);
35
37
  process.exit(EXIT_CODES.NORMAL_EXIT);
36
38
  } else if (args.migrateUp || args.migrateDown) {
@@ -44,7 +46,9 @@ async function main(args: Arguments) {
44
46
  process.exit(EXIT_CODES.NORMAL_EXIT);
45
47
  } else if (args.test) {
46
48
  // --test
47
- await app.inflate();
49
+ await app.inflate({
50
+ inflateParallel: args.inflateParallel
51
+ });
48
52
  await app.start();
49
53
  await testMain(app);
50
54
  await app.stop();
@@ -55,7 +59,8 @@ async function main(args: Arguments) {
55
59
  // --compile
56
60
  await app.inflate({
57
61
  inflateDir: args.inflateDir,
58
- inflateSea: true
62
+ inflateSea: true,
63
+ inflateParallel: args.inflateParallel
59
64
  });
60
65
  await app.dbManager.closeAll();
61
66
  await app.webSocketManager.disconnectAll();
@@ -66,14 +71,17 @@ async function main(args: Arguments) {
66
71
  // loadApp with inflateDir arg to inflate inflatable files
67
72
  await app.inflate({
68
73
  inflateDir: args.inflateDir,
69
- inflateSea: args.inflateSEA
74
+ inflateSea: args.inflateSEA,
75
+ inflateParallel: args.inflateParallel
70
76
  });
71
77
  await app.dbManager.closeAll();
72
78
  await app.webSocketManager.disconnectAll();
73
79
  process.exit(EXIT_CODES.NORMAL_EXIT);
74
80
  } else {
75
81
  // server
76
- await app.inflate();
82
+ await app.inflate({
83
+ inflateParallel: args.inflateParallel
84
+ });
77
85
  await app.start();
78
86
  }
79
87
  }
@@ -51,6 +51,7 @@ export interface MiqroOptions {
51
51
  export interface InflateOptions {
52
52
  inflateDir?: string;
53
53
  inflateSea?: boolean;
54
+ inflateParallel?: number;
54
55
  }
55
56
 
56
57
  export interface InflatedResult {
@@ -185,6 +186,7 @@ export class Miqro {
185
186
  });
186
187
  await app.inflate({
187
188
  inflateDir: miqroJSON.inflateDir ? String(miqroJSON.inflateDir) : undefined,
189
+ inflateParallel: miqroJSON.inflateParallel ? miqroJSON.inflateParallel : undefined,
188
190
  ...(inflate ? inflate : {}),
189
191
  });
190
192
  return app;
@@ -370,7 +372,8 @@ export class Miqro {
370
372
  inflateDir: options?.inflateDir,
371
373
  inflateSea: options?.inflateSea ? true : false,
372
374
  //inflateTests: options?.inflateTests ? true : false,
373
- hotreload: this.options?.hotreload ? true : false
375
+ hotreload: this.options?.hotreload ? true : false,
376
+ inflateParallel: options?.inflateParallel
374
377
  });
375
378
 
376
379
  wsConfigList.push(...serviceWSConfigList);