tova 0.3.3 → 0.3.4
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/bin/tova.js +21 -6
- package/package.json +1 -1
- package/src/codegen/codegen.js +2 -2
- package/src/codegen/server-codegen.js +43 -18
- package/src/version.js +1 -1
package/bin/tova.js
CHANGED
|
@@ -345,10 +345,8 @@ async function runTests(args) {
|
|
|
345
345
|
const outDir = dirname(outPath);
|
|
346
346
|
if (!existsSync(outDir)) mkdirSync(outDir, { recursive: true });
|
|
347
347
|
|
|
348
|
-
//
|
|
349
|
-
|
|
350
|
-
const fullTest = result.test;
|
|
351
|
-
writeFileSync(outPath, fullTest);
|
|
348
|
+
// Shared code (top-level definitions) is now included by generateTests()
|
|
349
|
+
writeFileSync(outPath, result.test);
|
|
352
350
|
compiledFiles.push(outPath);
|
|
353
351
|
console.log(` Compiled: ${relative('.', file)}`);
|
|
354
352
|
}
|
|
@@ -883,9 +881,16 @@ async function checkProject(args) {
|
|
|
883
881
|
}
|
|
884
882
|
|
|
885
883
|
const explicitSrc = args.filter(a => !a.startsWith('--'))[0];
|
|
886
|
-
const
|
|
884
|
+
const srcPath = resolve(explicitSrc || '.');
|
|
887
885
|
|
|
888
|
-
|
|
886
|
+
// Support both single file and directory arguments
|
|
887
|
+
let tovaFiles;
|
|
888
|
+
if (existsSync(srcPath) && statSync(srcPath).isFile()) {
|
|
889
|
+
tovaFiles = srcPath.endsWith('.tova') ? [srcPath] : [];
|
|
890
|
+
} else {
|
|
891
|
+
tovaFiles = findFiles(srcPath, '.tova');
|
|
892
|
+
}
|
|
893
|
+
const srcDir = existsSync(srcPath) && statSync(srcPath).isFile() ? dirname(srcPath) : srcPath;
|
|
889
894
|
if (tovaFiles.length === 0) {
|
|
890
895
|
console.error('No .tova files found');
|
|
891
896
|
process.exit(1);
|
|
@@ -2780,6 +2785,16 @@ async function productionBuild(srcDir, outDir) {
|
|
|
2780
2785
|
console.log(` server.${hash}.js`);
|
|
2781
2786
|
}
|
|
2782
2787
|
|
|
2788
|
+
// Write script bundle for plain scripts (no server/client blocks)
|
|
2789
|
+
if (!allServerCode.trim() && !allClientCode.trim() && allSharedCode.trim()) {
|
|
2790
|
+
const stdlib = getRunStdlib();
|
|
2791
|
+
const scriptBundle = stdlib + '\n' + allSharedCode;
|
|
2792
|
+
const hash = hashCode(scriptBundle);
|
|
2793
|
+
const scriptPath = join(outDir, `script.${hash}.js`);
|
|
2794
|
+
writeFileSync(scriptPath, scriptBundle);
|
|
2795
|
+
console.log(` script.${hash}.js`);
|
|
2796
|
+
}
|
|
2797
|
+
|
|
2783
2798
|
// Write client bundle
|
|
2784
2799
|
if (allClientCode.trim()) {
|
|
2785
2800
|
const fullClientModule = allSharedCode + '\n' + allClientCode;
|
package/package.json
CHANGED
package/src/codegen/codegen.js
CHANGED
|
@@ -160,7 +160,7 @@ export class CodeGenerator {
|
|
|
160
160
|
let testCode = '';
|
|
161
161
|
if (testBlocks.length > 0) {
|
|
162
162
|
const testGen = new (getServerCodegen())();
|
|
163
|
-
testCode = testGen.generateTests(testBlocks);
|
|
163
|
+
testCode = testGen.generateTests(testBlocks, combinedShared);
|
|
164
164
|
|
|
165
165
|
// Add __handleRequest export to server code
|
|
166
166
|
const defaultServer = servers['default'] || '';
|
|
@@ -173,7 +173,7 @@ export class CodeGenerator {
|
|
|
173
173
|
let benchCode = '';
|
|
174
174
|
if (benchBlocks.length > 0) {
|
|
175
175
|
const benchGen = new (getServerCodegen())();
|
|
176
|
-
benchCode = benchGen.generateBench(benchBlocks);
|
|
176
|
+
benchCode = benchGen.generateBench(benchBlocks, combinedShared);
|
|
177
177
|
}
|
|
178
178
|
|
|
179
179
|
// Backward-compatible: if only unnamed blocks, return flat structure
|
|
@@ -2677,7 +2677,7 @@ export class ServerCodegen extends BaseCodegen {
|
|
|
2677
2677
|
this._emitHandlerCall(lines, `__grpChain(req)`, timeoutMs);
|
|
2678
2678
|
}
|
|
2679
2679
|
|
|
2680
|
-
generateTests(testBlocks) {
|
|
2680
|
+
generateTests(testBlocks, sharedCode) {
|
|
2681
2681
|
const lines = [];
|
|
2682
2682
|
lines.push('import { describe, test, expect } from "bun:test";');
|
|
2683
2683
|
lines.push('');
|
|
@@ -2701,6 +2701,12 @@ export class ServerCodegen extends BaseCodegen {
|
|
|
2701
2701
|
lines.push(' if (!condition) throw new Error(message || "Assertion failed");');
|
|
2702
2702
|
lines.push('}');
|
|
2703
2703
|
lines.push('');
|
|
2704
|
+
// Include top-level definitions (functions, variables) so tests can reference them
|
|
2705
|
+
if (sharedCode && sharedCode.trim()) {
|
|
2706
|
+
lines.push('// ── Module Code ──');
|
|
2707
|
+
lines.push(sharedCode);
|
|
2708
|
+
lines.push('');
|
|
2709
|
+
}
|
|
2704
2710
|
|
|
2705
2711
|
for (const block of testBlocks) {
|
|
2706
2712
|
const name = block.name || 'Tests';
|
|
@@ -2729,24 +2735,37 @@ export class ServerCodegen extends BaseCodegen {
|
|
|
2729
2735
|
lines.push(' });');
|
|
2730
2736
|
}
|
|
2731
2737
|
|
|
2732
|
-
|
|
2733
|
-
|
|
2734
|
-
|
|
2735
|
-
|
|
2736
|
-
|
|
2737
|
-
|
|
2738
|
-
const
|
|
2739
|
-
|
|
2738
|
+
const hasFnTests = block.body.some(s => s.type === 'FunctionDeclaration');
|
|
2739
|
+
|
|
2740
|
+
if (hasFnTests) {
|
|
2741
|
+
// Function declarations become individual test cases
|
|
2742
|
+
for (const stmt of block.body) {
|
|
2743
|
+
if (stmt.type === 'FunctionDeclaration') {
|
|
2744
|
+
const fnName = stmt.name;
|
|
2745
|
+
const displayName = fnName.replace(/_/g, ' ');
|
|
2746
|
+
this.pushScope();
|
|
2747
|
+
for (const p of (stmt.params || [])) {
|
|
2748
|
+
const pName = typeof p === 'string' ? p : (p.name || p.identifier);
|
|
2749
|
+
if (pName) this.declareVar(pName);
|
|
2750
|
+
}
|
|
2751
|
+
const body = this.genBlockBody(stmt.body);
|
|
2752
|
+
this.popScope();
|
|
2753
|
+
const timeoutArg = blockTimeout ? `, ${blockTimeout}` : '';
|
|
2754
|
+
lines.push(` test(${JSON.stringify(displayName)}, async () => {`);
|
|
2755
|
+
lines.push(body);
|
|
2756
|
+
lines.push(` }${timeoutArg});`);
|
|
2757
|
+
} else {
|
|
2758
|
+
lines.push(' ' + this.generateStatement(stmt));
|
|
2740
2759
|
}
|
|
2741
|
-
const body = this.genBlockBody(stmt.body);
|
|
2742
|
-
this.popScope();
|
|
2743
|
-
const timeoutArg = blockTimeout ? `, ${blockTimeout}` : '';
|
|
2744
|
-
lines.push(` test(${JSON.stringify(displayName)}, async () => {`);
|
|
2745
|
-
lines.push(body);
|
|
2746
|
-
lines.push(` }${timeoutArg});`);
|
|
2747
|
-
} else {
|
|
2748
|
-
lines.push(' ' + this.generateStatement(stmt));
|
|
2749
2760
|
}
|
|
2761
|
+
} else {
|
|
2762
|
+
// No function declarations — wrap all statements in a single test case
|
|
2763
|
+
const timeoutArg = blockTimeout ? `, ${blockTimeout}` : '';
|
|
2764
|
+
lines.push(` test(${JSON.stringify(name)}, async () => {`);
|
|
2765
|
+
for (const stmt of block.body) {
|
|
2766
|
+
lines.push(' ' + this.generateStatement(stmt));
|
|
2767
|
+
}
|
|
2768
|
+
lines.push(` }${timeoutArg});`);
|
|
2750
2769
|
}
|
|
2751
2770
|
lines.push('});');
|
|
2752
2771
|
lines.push('');
|
|
@@ -2755,10 +2774,16 @@ export class ServerCodegen extends BaseCodegen {
|
|
|
2755
2774
|
return lines.join('\n');
|
|
2756
2775
|
}
|
|
2757
2776
|
|
|
2758
|
-
generateBench(benchBlocks) {
|
|
2777
|
+
generateBench(benchBlocks, sharedCode) {
|
|
2759
2778
|
const lines = [];
|
|
2760
2779
|
lines.push('// ── Tova Benchmark Runner ──');
|
|
2761
2780
|
lines.push('');
|
|
2781
|
+
// Include top-level definitions (functions, variables) so benchmarks can reference them
|
|
2782
|
+
if (sharedCode && sharedCode.trim()) {
|
|
2783
|
+
lines.push('// ── Module Code ──');
|
|
2784
|
+
lines.push(sharedCode);
|
|
2785
|
+
lines.push('');
|
|
2786
|
+
}
|
|
2762
2787
|
lines.push('async function __runBench(name, fn, runs) {');
|
|
2763
2788
|
lines.push(' runs = runs || 100;');
|
|
2764
2789
|
lines.push(' // Warmup');
|
package/src/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// Auto-generated by scripts/embed-runtime.js — do not edit
|
|
2
|
-
export const VERSION = "0.3.
|
|
2
|
+
export const VERSION = "0.3.4";
|