arri 0.84.0 → 0.85.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.
package/dist/index.cjs CHANGED
@@ -439,34 +439,53 @@ const require = topLevelCreateRequire(import.meta.url);`
439
439
  const appModule = path__default.resolve(config.rootDir, config.srcDir, config.entry);
440
440
  const appImportParts = path__default.relative(path__default.resolve(config.rootDir, config.srcDir), appModule).split(".");
441
441
  appImportParts.pop();
442
+ const virtualEntry = createServerEntryTemplate(config);
443
+ await fs__namespace.writeFile(
444
+ path__default.resolve(config.rootDir, ".output", OUT_SERVER_ENTRY),
445
+ virtualEntry
446
+ );
447
+ }
448
+ function createServerEntryTemplate(config) {
442
449
  let httpsString = ``;
443
450
  if (config.https === true) {
444
451
  httpsString = `https: true,`;
445
452
  } else if (typeof config.https === "object") {
446
453
  httpsString = `https: { cert: '${config.https.cert}', key: '${config.https.key}', passphrase: ${config.https.passphrase ? `'${config.https.passphrase}'` : "undefined"}},`;
447
454
  }
448
- const virtualEntry = `import { toNodeListener } from '@arrirpc/server';
455
+ return `import { toNodeListener } from '@arrirpc/server';
449
456
  import { listen } from '@joshmossas/listhen';
450
457
  import app from './${OUT_APP_FILE}';
451
458
 
452
- void listen(toNodeListener(app.h3App), {
453
- port: process.env.PORT ?? ${config.port},
454
- public: true,
455
- ws: {
456
- resolve(info) {
457
- if (app.h3App.websocket?.resolve) {
458
- return app.h3App.websocket.resolve(info);
459
+ async function startServer() {
460
+ const listener = await listen(toNodeListener(app.h3App), {
461
+ port: process.env.PORT ?? ${config.port},
462
+ public: true,
463
+ ws: {
464
+ resolve(info) {
465
+ if (app.h3App.websocket?.resolve) {
466
+ return app.h3App.websocket.resolve(info);
467
+ }
468
+ return app.h3App.websocket?.hooks ?? app.h3App.handler?.__websocket__ ?? {};
459
469
  }
460
- return app.h3App.websocket?.hooks ?? app.h3App.handler?.__websocket__ ?? {};
461
- }
462
- },
463
- http2: ${config.http2 ?? false},
464
- ${httpsString}
465
- });`;
466
- await fs__namespace.writeFile(
467
- path__default.resolve(config.rootDir, ".output", OUT_SERVER_ENTRY),
468
- virtualEntry
469
- );
470
+ },
471
+ http2: ${config.http2 ?? false},
472
+ ${httpsString}
473
+ });
474
+ await app.start?.();
475
+
476
+ let isShuttingDown = false;
477
+ const handleShutdown = async () => {
478
+ if (isShuttingDown) return;
479
+ isShuttingDown = true;
480
+ await app.stop?.();
481
+ await listener.close();
482
+ process.exit(0);
483
+ };
484
+ process.on('SIGTERM', handleShutdown);
485
+ process.on('SIGINT', handleShutdown);
486
+ }
487
+
488
+ void startServer();`;
470
489
  }
471
490
  async function bundleFilesContext(config) {
472
491
  return await esbuild__default.context({
@@ -527,6 +546,7 @@ async function createDevServer(config) {
527
546
  `Serving unencrypted traffic from port ${secondaryListener.address.port}`
528
547
  );
529
548
  }
549
+ let currentApp;
530
550
  async function reload() {
531
551
  let importPath = path__default.resolve(
532
552
  config.rootDir,
@@ -536,18 +556,29 @@ async function createDevServer(config) {
536
556
  if (isOnWindows()) {
537
557
  importPath = createWindowsCompatibleImportPath(importPath);
538
558
  }
559
+ if (currentApp) {
560
+ await currentApp.stop?.();
561
+ }
539
562
  const appEntry = (await import(importPath)).default;
563
+ currentApp = appEntry;
540
564
  dynamicHandler.set(h3.fromNodeMiddleware(appEntry.h3App.handler));
541
565
  ws = appEntry.h3App.websocket;
566
+ await appEntry.start?.();
542
567
  return appEntry.getAppDefinition();
543
568
  }
544
- await reload();
569
+ const initialAppDef = await reload();
545
570
  return {
546
571
  h3App: app,
547
572
  listener,
548
573
  secondaryListener,
549
574
  reload,
550
- ws
575
+ ws,
576
+ close: async () => {
577
+ if (currentApp) {
578
+ await currentApp.stop?.();
579
+ }
580
+ },
581
+ currentAppDef: initialAppDef
551
582
  };
552
583
  }
553
584
  async function startDevServer(config, generators) {
@@ -558,7 +589,7 @@ async function startDevServer(config, generators) {
558
589
  const context = await bundleFilesContext(config);
559
590
  await context.rebuild();
560
591
  const devServer = await createDevServer(config);
561
- let appDef = await devServer.reload();
592
+ let appDef = devServer.currentAppDef;
562
593
  let appDefStr = JSON.stringify(appDef);
563
594
  if (generators.length) {
564
595
  common.logger.info(`Running generators...`);
@@ -567,10 +598,15 @@ async function startDevServer(config, generators) {
567
598
  common.logger.warn(`No generators specified in config. Skipping codegen.`);
568
599
  }
569
600
  const cleanExit = async () => {
601
+ await devServer.close();
570
602
  process.exit();
571
603
  };
572
604
  process.on("exit", async () => {
573
- await Promise.allSettled([fileWatcher?.close(), context.dispose()]);
605
+ await Promise.allSettled([
606
+ fileWatcher?.close(),
607
+ context.dispose(),
608
+ devServer.close()
609
+ ]);
574
610
  });
575
611
  process.on("SIGINT", cleanExit);
576
612
  process.on("SIGTERM", cleanExit);
package/dist/index.mjs CHANGED
@@ -412,34 +412,53 @@ const require = topLevelCreateRequire(import.meta.url);`
412
412
  const appModule = path.resolve(config.rootDir, config.srcDir, config.entry);
413
413
  const appImportParts = path.relative(path.resolve(config.rootDir, config.srcDir), appModule).split(".");
414
414
  appImportParts.pop();
415
+ const virtualEntry = createServerEntryTemplate(config);
416
+ await fs.writeFile(
417
+ path.resolve(config.rootDir, ".output", OUT_SERVER_ENTRY),
418
+ virtualEntry
419
+ );
420
+ }
421
+ function createServerEntryTemplate(config) {
415
422
  let httpsString = ``;
416
423
  if (config.https === true) {
417
424
  httpsString = `https: true,`;
418
425
  } else if (typeof config.https === "object") {
419
426
  httpsString = `https: { cert: '${config.https.cert}', key: '${config.https.key}', passphrase: ${config.https.passphrase ? `'${config.https.passphrase}'` : "undefined"}},`;
420
427
  }
421
- const virtualEntry = `import { toNodeListener } from '@arrirpc/server';
428
+ return `import { toNodeListener } from '@arrirpc/server';
422
429
  import { listen } from '@joshmossas/listhen';
423
430
  import app from './${OUT_APP_FILE}';
424
431
 
425
- void listen(toNodeListener(app.h3App), {
426
- port: process.env.PORT ?? ${config.port},
427
- public: true,
428
- ws: {
429
- resolve(info) {
430
- if (app.h3App.websocket?.resolve) {
431
- return app.h3App.websocket.resolve(info);
432
+ async function startServer() {
433
+ const listener = await listen(toNodeListener(app.h3App), {
434
+ port: process.env.PORT ?? ${config.port},
435
+ public: true,
436
+ ws: {
437
+ resolve(info) {
438
+ if (app.h3App.websocket?.resolve) {
439
+ return app.h3App.websocket.resolve(info);
440
+ }
441
+ return app.h3App.websocket?.hooks ?? app.h3App.handler?.__websocket__ ?? {};
432
442
  }
433
- return app.h3App.websocket?.hooks ?? app.h3App.handler?.__websocket__ ?? {};
434
- }
435
- },
436
- http2: ${config.http2 ?? false},
437
- ${httpsString}
438
- });`;
439
- await fs.writeFile(
440
- path.resolve(config.rootDir, ".output", OUT_SERVER_ENTRY),
441
- virtualEntry
442
- );
443
+ },
444
+ http2: ${config.http2 ?? false},
445
+ ${httpsString}
446
+ });
447
+ await app.start?.();
448
+
449
+ let isShuttingDown = false;
450
+ const handleShutdown = async () => {
451
+ if (isShuttingDown) return;
452
+ isShuttingDown = true;
453
+ await app.stop?.();
454
+ await listener.close();
455
+ process.exit(0);
456
+ };
457
+ process.on('SIGTERM', handleShutdown);
458
+ process.on('SIGINT', handleShutdown);
459
+ }
460
+
461
+ void startServer();`;
443
462
  }
444
463
  async function bundleFilesContext(config) {
445
464
  return await esbuild.context({
@@ -500,6 +519,7 @@ async function createDevServer(config) {
500
519
  `Serving unencrypted traffic from port ${secondaryListener.address.port}`
501
520
  );
502
521
  }
522
+ let currentApp;
503
523
  async function reload() {
504
524
  let importPath = path.resolve(
505
525
  config.rootDir,
@@ -509,18 +529,29 @@ async function createDevServer(config) {
509
529
  if (isOnWindows()) {
510
530
  importPath = createWindowsCompatibleImportPath(importPath);
511
531
  }
532
+ if (currentApp) {
533
+ await currentApp.stop?.();
534
+ }
512
535
  const appEntry = (await import(importPath)).default;
536
+ currentApp = appEntry;
513
537
  dynamicHandler.set(fromNodeMiddleware(appEntry.h3App.handler));
514
538
  ws = appEntry.h3App.websocket;
539
+ await appEntry.start?.();
515
540
  return appEntry.getAppDefinition();
516
541
  }
517
- await reload();
542
+ const initialAppDef = await reload();
518
543
  return {
519
544
  h3App: app,
520
545
  listener,
521
546
  secondaryListener,
522
547
  reload,
523
- ws
548
+ ws,
549
+ close: async () => {
550
+ if (currentApp) {
551
+ await currentApp.stop?.();
552
+ }
553
+ },
554
+ currentAppDef: initialAppDef
524
555
  };
525
556
  }
526
557
  async function startDevServer(config, generators) {
@@ -531,7 +562,7 @@ async function startDevServer(config, generators) {
531
562
  const context = await bundleFilesContext(config);
532
563
  await context.rebuild();
533
564
  const devServer = await createDevServer(config);
534
- let appDef = await devServer.reload();
565
+ let appDef = devServer.currentAppDef;
535
566
  let appDefStr = JSON.stringify(appDef);
536
567
  if (generators.length) {
537
568
  logger.info(`Running generators...`);
@@ -540,10 +571,15 @@ async function startDevServer(config, generators) {
540
571
  logger.warn(`No generators specified in config. Skipping codegen.`);
541
572
  }
542
573
  const cleanExit = async () => {
574
+ await devServer.close();
543
575
  process.exit();
544
576
  };
545
577
  process.on("exit", async () => {
546
- await Promise.allSettled([fileWatcher?.close(), context.dispose()]);
578
+ await Promise.allSettled([
579
+ fileWatcher?.close(),
580
+ context.dispose(),
581
+ devServer.close()
582
+ ]);
547
583
  });
548
584
  process.on("SIGINT", cleanExit);
549
585
  process.on("SIGTERM", cleanExit);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "arri",
3
- "version": "0.84.0",
3
+ "version": "0.85.0",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "author": {
@@ -39,13 +39,13 @@
39
39
  "ofetch": "^1.5.1",
40
40
  "pathe": "^2.0.3",
41
41
  "prettier": "^3.8.1",
42
- "@arrirpc/codegen-kotlin": "0.84.0",
43
- "@arrirpc/codegen-dart": "0.84.0",
44
- "@arrirpc/codegen-rust": "0.84.0",
45
- "@arrirpc/codegen-utils": "0.84.0",
46
- "@arrirpc/codegen-ts": "0.84.0",
47
- "@arrirpc/codegen-swift": "0.84.0",
48
- "@arrirpc/schema": "0.84.0"
42
+ "@arrirpc/codegen-dart": "0.85.0",
43
+ "@arrirpc/codegen-rust": "0.85.0",
44
+ "@arrirpc/codegen-swift": "0.85.0",
45
+ "@arrirpc/codegen-kotlin": "0.85.0",
46
+ "@arrirpc/codegen-ts": "0.85.0",
47
+ "@arrirpc/codegen-utils": "0.85.0",
48
+ "@arrirpc/schema": "0.85.0"
49
49
  },
50
50
  "devDependencies": {
51
51
  "@types/degit": "^2.8.6"