@valbuild/server 0.21.1 → 0.22.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.
@@ -3,7 +3,7 @@ import { getCompilerOptions } from "./getCompilerOptions";
3
3
  import type { IValFSHost } from "./ValFSHost";
4
4
  import { ValSourceFileHandler } from "./ValSourceFileHandler";
5
5
  import fs from "fs";
6
-
6
+ import { transform } from "sucrase";
7
7
  const JsFileLookupMapping: [resolvedFileExt: string, replacements: string[]][] =
8
8
  [
9
9
  // NOTE: first one matching will be used
@@ -35,16 +35,26 @@ export const createModuleLoader = (
35
35
  return loader;
36
36
  };
37
37
 
38
+ const MAX_CACHE_SIZE = 100 * 1024 * 1024; // 100 mb
39
+ const MAX_OBJECT_KEY_SIZE = 2 ** 27; // https://stackoverflow.com/questions/13367391/is-there-a-limit-on-length-of-the-key-string-in-js-object
40
+
38
41
  export class ValModuleLoader {
42
+ private cache: Record<string, string>;
43
+ private cacheSize: number;
39
44
  constructor(
40
45
  public readonly projectRoot: string,
46
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
41
47
  private readonly compilerOptions: ts.CompilerOptions,
42
48
  private readonly sourceFileHandler: ValSourceFileHandler,
43
49
  private readonly host: IValFSHost = {
44
50
  ...ts.sys,
45
51
  writeFile: fs.writeFileSync,
46
- }
47
- ) {}
52
+ },
53
+ private readonly disableCache: boolean = false
54
+ ) {
55
+ this.cache = {};
56
+ this.cacheSize = 0;
57
+ }
48
58
 
49
59
  getModule(modulePath: string): string {
50
60
  if (!modulePath) {
@@ -54,16 +64,29 @@ export class ValModuleLoader {
54
64
  if (!code) {
55
65
  throw Error(`Could not read file "${modulePath}"`);
56
66
  }
57
- return ts.transpile(code, {
58
- ...this.compilerOptions,
59
- jsx: ts.JsxEmit.React,
60
- // allowJs: true,
61
- // rootDir: this.compilerOptions.rootDir,
62
- module: ts.ModuleKind.ESNext,
63
- target: ts.ScriptTarget.ES2015, // QuickJS supports a lot of ES2020: https://test262.report/, however not all cases are in that report (e.g. export const {} = {})
64
- // moduleResolution: ts.ModuleResolutionKind.NodeNext,
65
- // target: ts.ScriptTarget.ES2020, // QuickJs runs in ES2020 so we must use that
66
- });
67
+ let compiledCode;
68
+ if (this.cache[code] && !this.disableCache) {
69
+ // TODO: use hash instead of code as key
70
+ compiledCode = this.cache[code];
71
+ } else {
72
+ compiledCode = transform(code, {
73
+ filePath: modulePath,
74
+ disableESTransforms: true,
75
+ transforms: ["typescript"],
76
+ }).code;
77
+ if (!this.disableCache) {
78
+ if (this.cacheSize > MAX_CACHE_SIZE) {
79
+ console.warn("Cache size exceeded, clearing cache");
80
+ this.cache = {};
81
+ this.cacheSize = 0;
82
+ }
83
+ if (code.length < MAX_OBJECT_KEY_SIZE) {
84
+ this.cache[code] = compiledCode;
85
+ this.cacheSize += code.length + compiledCode.length; // code is mostly ASCII so 1 byte per char
86
+ }
87
+ }
88
+ }
89
+ return compiledCode;
67
90
  }
68
91
 
69
92
  resolveModulePath(
package/src/ValServer.ts CHANGED
@@ -20,4 +20,5 @@ export interface ValServer {
20
20
  disable(req: express.Request, res: express.Response): Promise<void>;
21
21
 
22
22
  getTree(req: express.Request, res: express.Response): Promise<void>;
23
+ getFiles(req: express.Request, res: express.Response): Promise<void>;
23
24
  }
@@ -22,5 +22,6 @@ export function createRequestHandler(valServer: ValServer): RequestHandler {
22
22
  router.get("/enable", valServer.enable.bind(valServer));
23
23
  router.get("/disable", valServer.disable.bind(valServer));
24
24
  router.get("/tree/*", valServer.getTree.bind(valServer));
25
+ router.get("/files/*", valServer.getFiles.bind(valServer));
25
26
  return router;
26
27
  }
@@ -71,6 +71,7 @@ const OperationJSONT: z.ZodType<OperationJSONT> = z.discriminatedUnion("op", [
71
71
  .object({
72
72
  op: z.literal("file"),
73
73
  path: z.string(),
74
+ filePath: z.string(),
74
75
  value: z.string(),
75
76
  })
76
77
  .strict(),
@@ -85,14 +85,6 @@ export const patchValFile = async (
85
85
  }
86
86
  }
87
87
 
88
- for (const [ref, patch] of Object.entries(derefRes.value.remotePatches)) {
89
- throw Error(
90
- `Cannot update remote ${ref} with ${JSON.stringify(
91
- patch
92
- )}: not implemented`
93
- );
94
- }
95
-
96
88
  sourceFileHandler.writeSourceFile(newSourceFile.value);
97
89
 
98
90
  return readValFile(id, valConfigPath, runtime);
@@ -1,4 +1,4 @@
1
- import { ModuleId } from "@valbuild/core";
1
+ import { ModuleId, SourcePath } from "@valbuild/core";
2
2
  import path from "path";
3
3
  import { QuickJSRuntime } from "quickjs-emscripten";
4
4
  import { SerializedModuleContent } from "./SerializedModuleContent";
@@ -36,6 +36,7 @@ globalThis.valModule = {
36
36
  error.stack
37
37
  );
38
38
  return {
39
+ path: id as SourcePath,
39
40
  errors: {
40
41
  invalidModuleId: id as ModuleId,
41
42
  fatal: [
@@ -59,13 +60,13 @@ globalThis.valModule = {
59
60
  } else {
60
61
  if (valModule.id !== id) {
61
62
  fatalErrors.push(
62
- `Expected val id: '${id}' but got: '${valModule.id}'`
63
+ `Wrong val.content id! In the file of with: '${id}', found: '${valModule.id}'`
63
64
  );
64
65
  }
65
66
  if (!valModule?.schema) {
66
67
  fatalErrors.push(`Expected val id: '${id}' to have a schema`);
67
68
  }
68
- if (!valModule?.source) {
69
+ if (valModule?.source === undefined) {
69
70
  fatalErrors.push(`Expected val id: '${id}' to have a source`);
70
71
  }
71
72
  }
@@ -83,7 +84,7 @@ globalThis.valModule = {
83
84
  };
84
85
  }
85
86
  return {
86
- path: valModule.id, // NOTE: we use path here, since SerializedModuleContent (maybe bad name?) can be used for whole modules as well as subparts of modules
87
+ path: valModule.id || id, // NOTE: we use path here, since SerializedModuleContent (maybe bad name?) can be used for whole modules as well as subparts of modules
87
88
  source: valModule.source,
88
89
  schema: valModule.schema,
89
90
  errors,