feat(tapbundle_serverside): add network port discovery utilities and migrate file I/O to smartfs; refactor runtimes to use Node fs and SmartFs, update server APIs and bump dependencies
This commit is contained in:
@@ -132,7 +132,7 @@ export class TsTest {
|
||||
}
|
||||
|
||||
public async runWatch(ignorePatterns: string[] = []) {
|
||||
const smartchokInstance = new plugins.smartchok.Smartchok([this.testDir.cwd]);
|
||||
const smartwatchInstance = new plugins.smartwatch.Smartwatch([this.testDir.cwd]);
|
||||
|
||||
console.clear();
|
||||
this.logger.watchModeStart();
|
||||
@@ -155,12 +155,12 @@ export class TsTest {
|
||||
};
|
||||
|
||||
// Start watching before subscribing to events
|
||||
await smartchokInstance.start();
|
||||
|
||||
await smartwatchInstance.start();
|
||||
|
||||
// Subscribe to file change events
|
||||
const changeObservable = await smartchokInstance.getObservableFor('change');
|
||||
const addObservable = await smartchokInstance.getObservableFor('add');
|
||||
const unlinkObservable = await smartchokInstance.getObservableFor('unlink');
|
||||
const changeObservable = await smartwatchInstance.getObservableFor('change');
|
||||
const addObservable = await smartwatchInstance.getObservableFor('add');
|
||||
const unlinkObservable = await smartwatchInstance.getObservableFor('unlink');
|
||||
|
||||
const handleFileChange = (changedPath: string) => {
|
||||
// Skip if path matches ignore patterns
|
||||
@@ -194,7 +194,7 @@ export class TsTest {
|
||||
// Handle Ctrl+C to exit gracefully
|
||||
process.on('SIGINT', async () => {
|
||||
this.logger.watchModeStop();
|
||||
await smartchokInstance.stop();
|
||||
await smartwatchInstance.stop();
|
||||
process.exit(0);
|
||||
});
|
||||
|
||||
@@ -316,8 +316,8 @@ export class TsTest {
|
||||
const initFile = plugins.path.join(testDir, '00init.ts');
|
||||
let runCommand = `tsrun ${fileNameArg}${tsrunOptions}`;
|
||||
|
||||
const initFileExists = await plugins.smartfile.fs.fileExists(initFile);
|
||||
|
||||
const initFileExists = await plugins.smartfsInstance.file(initFile).exists();
|
||||
|
||||
// If 00init.ts exists, run it first
|
||||
if (initFileExists) {
|
||||
// Create a temporary loader file that imports both 00init.ts and the test file
|
||||
@@ -328,7 +328,7 @@ import '${absoluteInitFile.replace(/\\/g, '/')}';
|
||||
import '${absoluteTestFile.replace(/\\/g, '/')}';
|
||||
`;
|
||||
const loaderPath = plugins.path.join(testDir, `.loader_${plugins.path.basename(fileNameArg)}`);
|
||||
await plugins.smartfile.memory.toFs(loaderContent, loaderPath);
|
||||
await plugins.smartfsInstance.file(loaderPath).write(loaderContent);
|
||||
runCommand = `tsrun ${loaderPath}${tsrunOptions}`;
|
||||
}
|
||||
|
||||
@@ -339,14 +339,14 @@ import '${absoluteTestFile.replace(/\\/g, '/')}';
|
||||
const loaderPath = plugins.path.join(testDir, `.loader_${plugins.path.basename(fileNameArg)}`);
|
||||
const cleanup = () => {
|
||||
try {
|
||||
if (plugins.smartfile.fs.fileExistsSync(loaderPath)) {
|
||||
plugins.smartfile.fs.removeSync(loaderPath);
|
||||
if (plugins.fs.existsSync(loaderPath)) {
|
||||
plugins.fs.rmSync(loaderPath, { force: true });
|
||||
}
|
||||
} catch (e) {
|
||||
// Ignore cleanup errors
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
execResultStreaming.childProcess.on('exit', cleanup);
|
||||
execResultStreaming.childProcess.on('error', cleanup);
|
||||
}
|
||||
@@ -445,7 +445,8 @@ import '${absoluteTestFile.replace(/\\/g, '/')}';
|
||||
const bundleFilePath = plugins.path.join(tsbundleCacheDirPath, bundleFileName);
|
||||
|
||||
// lets bundle the test
|
||||
await plugins.smartfile.fs.ensureEmptyDir(tsbundleCacheDirPath);
|
||||
try { await plugins.smartfsInstance.directory(tsbundleCacheDirPath).recursive().delete(); } catch (e) { /* may not exist */ }
|
||||
await plugins.smartfsInstance.directory(tsbundleCacheDirPath).recursive().create();
|
||||
await this.tsbundleInstance.build(process.cwd(), fileNameArg, bundleFilePath, {
|
||||
bundler: 'esbuild',
|
||||
});
|
||||
@@ -454,15 +455,13 @@ import '${absoluteTestFile.replace(/\\/g, '/')}';
|
||||
const { httpPort, wsPort } = await this.findFreePorts();
|
||||
|
||||
// lets create a server
|
||||
const server = new plugins.typedserver.servertools.Server({
|
||||
const server = new plugins.typedserver.TypedServer({
|
||||
cors: true,
|
||||
port: httpPort,
|
||||
serveDir: tsbundleCacheDirPath,
|
||||
});
|
||||
server.addRoute(
|
||||
'/test',
|
||||
new plugins.typedserver.servertools.Handler('GET', async (_req, res) => {
|
||||
res.type('.html');
|
||||
res.write(`
|
||||
server.addRoute('/test', 'GET', async () => {
|
||||
return new Response(`
|
||||
<html>
|
||||
<head>
|
||||
<script>
|
||||
@@ -472,11 +471,8 @@ import '${absoluteTestFile.replace(/\\/g, '/')}';
|
||||
</head>
|
||||
<body></body>
|
||||
</html>
|
||||
`);
|
||||
res.end();
|
||||
})
|
||||
);
|
||||
server.addRoute('/*splat', new plugins.typedserver.servertools.HandlerStatic(tsbundleCacheDirPath));
|
||||
`, { headers: { 'Content-Type': 'text/html' } });
|
||||
});
|
||||
await server.start();
|
||||
|
||||
// lets handle realtime comms
|
||||
@@ -640,34 +636,33 @@ import '${absoluteTestFile.replace(/\\/g, '/')}';
|
||||
|
||||
try {
|
||||
// Delete 00err and 00diff directories if they exist
|
||||
if (plugins.smartfile.fs.isDirectorySync(errDir)) {
|
||||
plugins.smartfile.fs.removeSync(errDir);
|
||||
if (plugins.fs.existsSync(errDir) && plugins.fs.statSync(errDir).isDirectory()) {
|
||||
plugins.fs.rmSync(errDir, { recursive: true, force: true });
|
||||
}
|
||||
if (plugins.smartfile.fs.isDirectorySync(diffDir)) {
|
||||
plugins.smartfile.fs.removeSync(diffDir);
|
||||
if (plugins.fs.existsSync(diffDir) && plugins.fs.statSync(diffDir).isDirectory()) {
|
||||
plugins.fs.rmSync(diffDir, { recursive: true, force: true });
|
||||
}
|
||||
|
||||
|
||||
// Get all .log files in log directory (not in subdirectories)
|
||||
const files = await plugins.smartfile.fs.listFileTree(logDir, '*.log');
|
||||
const logFiles = files.filter((file: string) => !file.includes('/'));
|
||||
|
||||
const entries = await plugins.smartfsInstance.directory(logDir).filter('*.log').list();
|
||||
const logFiles = entries.filter((entry) => entry.isFile).map((entry) => entry.name);
|
||||
|
||||
if (logFiles.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Ensure previous directory exists
|
||||
await plugins.smartfile.fs.ensureDir(previousDir);
|
||||
|
||||
await plugins.smartfsInstance.directory(previousDir).recursive().create();
|
||||
|
||||
// Move each log file to previous directory
|
||||
for (const file of logFiles) {
|
||||
const filename = plugins.path.basename(file);
|
||||
for (const filename of logFiles) {
|
||||
const sourcePath = plugins.path.join(logDir, filename);
|
||||
const destPath = plugins.path.join(previousDir, filename);
|
||||
|
||||
|
||||
try {
|
||||
// Copy file to new location and remove original
|
||||
await plugins.smartfile.fs.copy(sourcePath, destPath);
|
||||
await plugins.smartfile.fs.remove(sourcePath);
|
||||
await plugins.smartfsInstance.file(sourcePath).copy(destPath);
|
||||
await plugins.smartfsInstance.file(sourcePath).delete();
|
||||
} catch (error) {
|
||||
// Silently continue if a file can't be moved
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user