spawnPreviewGenerator function

Future<Isolate> spawnPreviewGenerator(
  1. String normProjectPath,
  2. SendPort refreshPortSender
)

Implementation

Future<Isolate> spawnPreviewGenerator(
  String normProjectPath,
  SendPort refreshPortSender,
) {
  return Isolate.spawn(
    (ports) async {
      Process.runSync(
        'flutter',
        [
          'create',
          '-e',
          '--platforms',
          'web',
          'preview',
        ],
      );

      final parentPubspec = PubSpec.load();
      final parent = parentPubspec.name.value;
      final previewPubspec = PubSpec.load(directory: './preview');
      if (!previewPubspec.dependencies.exists('hypen')) {
        previewPubspec.dependencies.append(
          DependencyPubHostedBuilder(
            name: 'hypen',
          ),
        );
      }
      if (!previewPubspec.dependencies.exists(parent)) {
        previewPubspec.dependencies.append(
          DependencyPathBuilder(
            name: parent,
            path: '../',
          ),
        );
      }
      previewPubspec.save();

      await startPreviewServer();

      try {
        ProcessSignal.sigterm.watch().listen(
          (event) {
            server?.kill();
            exit(0);
          },
        );
        ProcessSignal.sigkill.watch().listen(
          (event) {
            server?.kill();
            exit(0);
          },
        );
        ProcessSignal.sigint.watch().listen(
          (event) {
            server?.kill();
            exit(0);
          },
        );
      } catch (e) {
        //
      }

      final refreshPort = ReceivePort();

      final libPath = p.join(normProjectPath, 'lib');
      final binPath = p.join(normProjectPath, 'bin');
      final testPath = p.join(normProjectPath, 'test');
      final ctxCollection = AnalysisContextCollection(
        includedPaths: [
          libPath,
          binPath,
          testPath,
        ],
      );

      final libCtx = ctxCollection.contextFor(libPath);
      final binCtx = ctxCollection.contextFor(binPath);
      final testCtx = ctxCollection.contextFor(testPath);

      ports.initRefreshPort.send(refreshPort.sendPort);

      await for (final path in refreshPort) {
        if (path is! String) {
          continue;
        }
        if (!path.startsWith('/')) {
          if (path.toLowerCase() == 'r' && server == null) {
            await startPreviewServer();
          }
          server?.stdin.add(path.codeUnits);
          continue;
        }

        if (!(await File(path).exists())) {
          await removePreview(path);
          continue;
        }

        late AnalysisContext ctx;

        if (p.isWithin(libPath, path)) {
          ctx = libCtx;
        } else if (p.isWithin(binPath, path)) {
          ctx = binCtx;
        } else if (p.isWithin(testPath, path)) {
          ctx = testCtx;
        } else {
          continue;
        }

        ctx.changeFile(path);

        await ctx.applyPendingFileChanges();

        final result = await ctx.currentSession.getResolvedLibrary(path);
        if (result is! ResolvedLibraryResult) {
          return;
        }
        await writeHypenRouter(path, result);
      }
    },
    (initRefreshPort: refreshPortSender,),
  );
}