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:
2026-03-03 20:15:59 +00:00
parent 4d1896bdf9
commit f23c902658
24 changed files with 2562 additions and 2094 deletions

View File

@@ -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
}