@valbuild/server 0.60.22 → 0.60.23

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.
@@ -160,3 +160,4 @@ export type RequestHeaders = {
160
160
  host?: string | null;
161
161
  "x-forwarded-proto"?: string | null;
162
162
  };
163
+ export declare function debugTiming<R>(id: string, fn: () => Promise<R>): Promise<R>;
@@ -1452,7 +1452,7 @@ class ValServer {
1452
1452
  async getTree(treePath,
1453
1453
  // TODO: use the params: patch, schema, source now we return everything, every time
1454
1454
  query, cookies, requestHeaders) {
1455
- const ensureRes = await this.ensureInitialized("getTree", cookies);
1455
+ const ensureRes = await debugTiming("ensureInitialized", () => this.ensureInitialized("getTree", cookies));
1456
1456
  if (fp.result.isErr(ensureRes)) {
1457
1457
  return ensureRes.error;
1458
1458
  }
@@ -1460,7 +1460,7 @@ class ValServer {
1460
1460
  const execValidations = query.validate === "true";
1461
1461
  const includeSource = query.source === "true";
1462
1462
  const includeSchema = query.schema === "true";
1463
- const moduleIds = await this.getAllModules(treePath);
1463
+ const moduleIds = await debugTiming("getAllModules", () => this.getAllModules(treePath));
1464
1464
  let {
1465
1465
  patchIdsByModuleId,
1466
1466
  patchesById,
@@ -1471,7 +1471,7 @@ class ValServer {
1471
1471
  fileUpdates: {}
1472
1472
  };
1473
1473
  if (applyPatches) {
1474
- const res = await this.readPatches(cookies);
1474
+ const res = await debugTiming("readPatches", () => this.readPatches(cookies));
1475
1475
  if (fp.result.isErr(res)) {
1476
1476
  return res.error;
1477
1477
  }
@@ -1479,9 +1479,9 @@ class ValServer {
1479
1479
  patchesById = res.value.patchesById;
1480
1480
  fileUpdates = res.value.fileUpdates;
1481
1481
  }
1482
- const possiblyPatchedContent = await Promise.all(moduleIds.map(async moduleId => {
1482
+ const possiblyPatchedContent = await debugTiming("applyAllPatchesThenValidate", () => Promise.all(moduleIds.map(async moduleId => {
1483
1483
  return this.applyAllPatchesThenValidate(moduleId, patchIdsByModuleId, patchesById, fileUpdates, cookies, requestHeaders, applyPatches, execValidations, includeSource, includeSchema);
1484
- }));
1484
+ })));
1485
1485
  const modules = Object.fromEntries(possiblyPatchedContent.map(serializedModuleContent => {
1486
1486
  const module = {
1487
1487
  schema: serializedModuleContent.schema,
@@ -1551,38 +1551,40 @@ class ValServer {
1551
1551
  return serializedModuleContent;
1552
1552
  }
1553
1553
  let source = maybeSource;
1554
- for (const patchId of patchIdsByModuleId[moduleId] ?? []) {
1555
- const patch$1 = patchesById[patchId];
1556
- if (!patch$1) {
1557
- continue;
1558
- }
1559
- const patchRes = patch.applyPatch(source, ops, patch$1.filter(core.Internal.notFileOp));
1560
- if (fp.result.isOk(patchRes)) {
1561
- source = patchRes.value;
1562
- } else {
1563
- console.error("Val: got an unexpected error while applying patch. Is there a mismatch in Val versions? Perhaps Val is misconfigured?", {
1564
- patchId,
1565
- moduleId,
1566
- patch: JSON.stringify(patch$1, null, 2),
1567
- error: patchRes.error
1568
- });
1569
- return {
1570
- path: moduleId,
1571
- schema,
1572
- source,
1573
- errors: {
1574
- fatal: [{
1575
- message: "Unexpected error applying patch",
1576
- type: "invalid-patch"
1577
- }]
1578
- }
1579
- };
1554
+ await debugTiming("applyPatches:" + moduleId, async () => {
1555
+ for (const patchId of patchIdsByModuleId[moduleId] ?? []) {
1556
+ const patch$1 = patchesById[patchId];
1557
+ if (!patch$1) {
1558
+ continue;
1559
+ }
1560
+ const patchRes = patch.applyPatch(source, ops, patch$1.filter(core.Internal.notFileOp));
1561
+ if (fp.result.isOk(patchRes)) {
1562
+ source = patchRes.value;
1563
+ } else {
1564
+ console.error("Val: got an unexpected error while applying patch. Is there a mismatch in Val versions? Perhaps Val is misconfigured?", {
1565
+ patchId,
1566
+ moduleId,
1567
+ patch: JSON.stringify(patch$1, null, 2),
1568
+ error: patchRes.error
1569
+ });
1570
+ return {
1571
+ path: moduleId,
1572
+ schema,
1573
+ source,
1574
+ errors: {
1575
+ fatal: [{
1576
+ message: "Unexpected error applying patch",
1577
+ type: "invalid-patch"
1578
+ }]
1579
+ }
1580
+ };
1581
+ }
1580
1582
  }
1581
- }
1583
+ });
1582
1584
  if (validate) {
1583
- const validationErrors = core.deserializeSchema(schema).validate(moduleId, source);
1585
+ const validationErrors = await debugTiming("validate:" + moduleId, async () => core.deserializeSchema(schema).validate(moduleId, source));
1584
1586
  if (validationErrors) {
1585
- const revalidated = await this.revalidateImageAndFileValidation(validationErrors, fileUpdates, cookies, requestHeaders);
1587
+ const revalidated = await debugTiming("revalidate image/file:" + moduleId, async () => this.revalidateImageAndFileValidation(validationErrors, fileUpdates, cookies, requestHeaders));
1586
1588
  return {
1587
1589
  path: moduleId,
1588
1590
  schema,
@@ -2034,6 +2036,16 @@ function guessMimeTypeFromPath(filePath) {
2034
2036
  function isCachedPatchFileOp(op) {
2035
2037
  return !!(op.op === "file" && typeof op.filePath === "string" && op.value && typeof op.value === "object" && !Array.isArray(op.value) && "sha256" in op.value && typeof op.value.sha256 === "string");
2036
2038
  }
2039
+ async function debugTiming(id, fn) {
2040
+ if (process.env["VAL_DEBUG_TIMING"] === "true") {
2041
+ const start = Date.now();
2042
+ const r = await fn();
2043
+ console.log(`Timing: ${id} took: ${Date.now() - start}ms (${new Date().toISOString()})`);
2044
+ return r;
2045
+ } else {
2046
+ return fn();
2047
+ }
2048
+ }
2037
2049
 
2038
2050
  const textEncoder = new TextEncoder();
2039
2051
  class LocalValServer extends ValServer {
@@ -2824,76 +2836,51 @@ class ProxyValServer extends ValServer {
2824
2836
  }
2825
2837
  });
2826
2838
  }
2827
- async getFiles(filePath, query, cookies, reqHeaders) {
2828
- return withAuth(this.options.valSecret, cookies, "getFiles", async data => {
2829
- const url = new URL(`/v1/files/${this.options.remote}${filePath}`, this.options.valContentUrl);
2830
- if (typeof query.sha256 === "string") {
2831
- url.searchParams.append("sha256", query.sha256);
2839
+ async getFiles(filePath, query, _cookies, reqHeaders) {
2840
+ const url = new URL(`/v1/files/${this.options.remote}${filePath}`, this.options.valContentUrl);
2841
+ if (typeof query.sha256 === "string") {
2842
+ url.searchParams.append("sha256", query.sha256);
2843
+ }
2844
+ const fetchRes = await fetch(url);
2845
+ if (fetchRes.status === 200) {
2846
+ // TODO: does this stream data?
2847
+ if (fetchRes.body) {
2848
+ return {
2849
+ status: fetchRes.status,
2850
+ headers: {
2851
+ "Content-Type": fetchRes.headers.get("Content-Type") || "",
2852
+ "Content-Length": fetchRes.headers.get("Content-Length") || "0",
2853
+ "Cache-Control": fetchRes.headers.get("Cache-Control") || ""
2854
+ },
2855
+ body: fetchRes.body
2856
+ };
2832
2857
  } else {
2833
- console.warn("Missing sha256 query param");
2858
+ return {
2859
+ status: 500,
2860
+ json: {
2861
+ message: "No body in response"
2862
+ }
2863
+ };
2834
2864
  }
2835
- const fetchRes = await fetch(url, {
2836
- headers: getAuthHeaders(data.token)
2837
- });
2838
- if (fetchRes.status === 200) {
2839
- // TODO: does this stream data?
2840
- if (fetchRes.body) {
2841
- return {
2842
- status: fetchRes.status,
2843
- headers: {
2844
- "Content-Type": fetchRes.headers.get("Content-Type") || "",
2845
- "Content-Length": fetchRes.headers.get("Content-Length") || "0",
2846
- "Cache-Control": "public, max-age=31536000, immutable"
2847
- },
2848
- body: fetchRes.body
2849
- };
2850
- } else {
2851
- return {
2852
- status: 500,
2853
- json: {
2854
- message: "No body in response"
2855
- }
2856
- };
2857
- }
2858
- } else {
2859
- if (!(reqHeaders.host && reqHeaders["x-forwarded-proto"])) {
2860
- return {
2861
- status: 500,
2862
- json: {
2863
- message: "Missing host or x-forwarded-proto header"
2864
- }
2865
- };
2866
- }
2867
- const host = `${reqHeaders["x-forwarded-proto"]}://${reqHeaders["host"]}`;
2868
- const staticPublicUrl = new URL(filePath.slice("/public".length), host).toString();
2869
- const fetchRes = await fetch(staticPublicUrl, {
2870
- headers: getAuthHeaders(data.token)
2871
- });
2872
- if (fetchRes.status === 200) {
2873
- // TODO: does this stream data?
2874
- if (fetchRes.body) {
2875
- return {
2876
- status: fetchRes.status,
2877
- headers: {
2878
- "Content-Type": fetchRes.headers.get("Content-Type") || "",
2879
- "Content-Length": fetchRes.headers.get("Content-Length") || "0",
2880
- "Cache-Control": "public, max-age=31536000, immutable"
2881
- },
2882
- body: fetchRes.body
2883
- };
2884
- } else {
2885
- return {
2886
- status: 500,
2887
- json: {
2888
- message: "No body in response"
2889
- }
2890
- };
2865
+ } else {
2866
+ if (!(reqHeaders.host && reqHeaders["x-forwarded-proto"])) {
2867
+ return {
2868
+ status: 500,
2869
+ json: {
2870
+ message: "Missing host or x-forwarded-proto header"
2891
2871
  }
2892
- } else {
2893
- throw new Error("Failed to fetch file: " + filePath);
2894
- }
2872
+ };
2895
2873
  }
2896
- });
2874
+ const host = `${reqHeaders["x-forwarded-proto"]}://${reqHeaders["host"]}`;
2875
+ const staticPublicUrl = new URL(filePath.slice("/public".length), host).toString();
2876
+ const fetchRes = await fetch(staticPublicUrl);
2877
+ return {
2878
+ status: fetchRes.status,
2879
+ // forward headers from static public url
2880
+ headers: Object.fromEntries(fetchRes.headers.entries()),
2881
+ body: fetchRes.body
2882
+ };
2883
+ }
2897
2884
  }
2898
2885
  }
2899
2886
  function verifyCallbackReq(stateCookie, queryParams) {
@@ -1452,7 +1452,7 @@ class ValServer {
1452
1452
  async getTree(treePath,
1453
1453
  // TODO: use the params: patch, schema, source now we return everything, every time
1454
1454
  query, cookies, requestHeaders) {
1455
- const ensureRes = await this.ensureInitialized("getTree", cookies);
1455
+ const ensureRes = await debugTiming("ensureInitialized", () => this.ensureInitialized("getTree", cookies));
1456
1456
  if (fp.result.isErr(ensureRes)) {
1457
1457
  return ensureRes.error;
1458
1458
  }
@@ -1460,7 +1460,7 @@ class ValServer {
1460
1460
  const execValidations = query.validate === "true";
1461
1461
  const includeSource = query.source === "true";
1462
1462
  const includeSchema = query.schema === "true";
1463
- const moduleIds = await this.getAllModules(treePath);
1463
+ const moduleIds = await debugTiming("getAllModules", () => this.getAllModules(treePath));
1464
1464
  let {
1465
1465
  patchIdsByModuleId,
1466
1466
  patchesById,
@@ -1471,7 +1471,7 @@ class ValServer {
1471
1471
  fileUpdates: {}
1472
1472
  };
1473
1473
  if (applyPatches) {
1474
- const res = await this.readPatches(cookies);
1474
+ const res = await debugTiming("readPatches", () => this.readPatches(cookies));
1475
1475
  if (fp.result.isErr(res)) {
1476
1476
  return res.error;
1477
1477
  }
@@ -1479,9 +1479,9 @@ class ValServer {
1479
1479
  patchesById = res.value.patchesById;
1480
1480
  fileUpdates = res.value.fileUpdates;
1481
1481
  }
1482
- const possiblyPatchedContent = await Promise.all(moduleIds.map(async moduleId => {
1482
+ const possiblyPatchedContent = await debugTiming("applyAllPatchesThenValidate", () => Promise.all(moduleIds.map(async moduleId => {
1483
1483
  return this.applyAllPatchesThenValidate(moduleId, patchIdsByModuleId, patchesById, fileUpdates, cookies, requestHeaders, applyPatches, execValidations, includeSource, includeSchema);
1484
- }));
1484
+ })));
1485
1485
  const modules = Object.fromEntries(possiblyPatchedContent.map(serializedModuleContent => {
1486
1486
  const module = {
1487
1487
  schema: serializedModuleContent.schema,
@@ -1551,38 +1551,40 @@ class ValServer {
1551
1551
  return serializedModuleContent;
1552
1552
  }
1553
1553
  let source = maybeSource;
1554
- for (const patchId of patchIdsByModuleId[moduleId] ?? []) {
1555
- const patch$1 = patchesById[patchId];
1556
- if (!patch$1) {
1557
- continue;
1558
- }
1559
- const patchRes = patch.applyPatch(source, ops, patch$1.filter(core.Internal.notFileOp));
1560
- if (fp.result.isOk(patchRes)) {
1561
- source = patchRes.value;
1562
- } else {
1563
- console.error("Val: got an unexpected error while applying patch. Is there a mismatch in Val versions? Perhaps Val is misconfigured?", {
1564
- patchId,
1565
- moduleId,
1566
- patch: JSON.stringify(patch$1, null, 2),
1567
- error: patchRes.error
1568
- });
1569
- return {
1570
- path: moduleId,
1571
- schema,
1572
- source,
1573
- errors: {
1574
- fatal: [{
1575
- message: "Unexpected error applying patch",
1576
- type: "invalid-patch"
1577
- }]
1578
- }
1579
- };
1554
+ await debugTiming("applyPatches:" + moduleId, async () => {
1555
+ for (const patchId of patchIdsByModuleId[moduleId] ?? []) {
1556
+ const patch$1 = patchesById[patchId];
1557
+ if (!patch$1) {
1558
+ continue;
1559
+ }
1560
+ const patchRes = patch.applyPatch(source, ops, patch$1.filter(core.Internal.notFileOp));
1561
+ if (fp.result.isOk(patchRes)) {
1562
+ source = patchRes.value;
1563
+ } else {
1564
+ console.error("Val: got an unexpected error while applying patch. Is there a mismatch in Val versions? Perhaps Val is misconfigured?", {
1565
+ patchId,
1566
+ moduleId,
1567
+ patch: JSON.stringify(patch$1, null, 2),
1568
+ error: patchRes.error
1569
+ });
1570
+ return {
1571
+ path: moduleId,
1572
+ schema,
1573
+ source,
1574
+ errors: {
1575
+ fatal: [{
1576
+ message: "Unexpected error applying patch",
1577
+ type: "invalid-patch"
1578
+ }]
1579
+ }
1580
+ };
1581
+ }
1580
1582
  }
1581
- }
1583
+ });
1582
1584
  if (validate) {
1583
- const validationErrors = core.deserializeSchema(schema).validate(moduleId, source);
1585
+ const validationErrors = await debugTiming("validate:" + moduleId, async () => core.deserializeSchema(schema).validate(moduleId, source));
1584
1586
  if (validationErrors) {
1585
- const revalidated = await this.revalidateImageAndFileValidation(validationErrors, fileUpdates, cookies, requestHeaders);
1587
+ const revalidated = await debugTiming("revalidate image/file:" + moduleId, async () => this.revalidateImageAndFileValidation(validationErrors, fileUpdates, cookies, requestHeaders));
1586
1588
  return {
1587
1589
  path: moduleId,
1588
1590
  schema,
@@ -2034,6 +2036,16 @@ function guessMimeTypeFromPath(filePath) {
2034
2036
  function isCachedPatchFileOp(op) {
2035
2037
  return !!(op.op === "file" && typeof op.filePath === "string" && op.value && typeof op.value === "object" && !Array.isArray(op.value) && "sha256" in op.value && typeof op.value.sha256 === "string");
2036
2038
  }
2039
+ async function debugTiming(id, fn) {
2040
+ if (process.env["VAL_DEBUG_TIMING"] === "true") {
2041
+ const start = Date.now();
2042
+ const r = await fn();
2043
+ console.log(`Timing: ${id} took: ${Date.now() - start}ms (${new Date().toISOString()})`);
2044
+ return r;
2045
+ } else {
2046
+ return fn();
2047
+ }
2048
+ }
2037
2049
 
2038
2050
  const textEncoder = new TextEncoder();
2039
2051
  class LocalValServer extends ValServer {
@@ -2824,76 +2836,51 @@ class ProxyValServer extends ValServer {
2824
2836
  }
2825
2837
  });
2826
2838
  }
2827
- async getFiles(filePath, query, cookies, reqHeaders) {
2828
- return withAuth(this.options.valSecret, cookies, "getFiles", async data => {
2829
- const url = new URL(`/v1/files/${this.options.remote}${filePath}`, this.options.valContentUrl);
2830
- if (typeof query.sha256 === "string") {
2831
- url.searchParams.append("sha256", query.sha256);
2839
+ async getFiles(filePath, query, _cookies, reqHeaders) {
2840
+ const url = new URL(`/v1/files/${this.options.remote}${filePath}`, this.options.valContentUrl);
2841
+ if (typeof query.sha256 === "string") {
2842
+ url.searchParams.append("sha256", query.sha256);
2843
+ }
2844
+ const fetchRes = await fetch(url);
2845
+ if (fetchRes.status === 200) {
2846
+ // TODO: does this stream data?
2847
+ if (fetchRes.body) {
2848
+ return {
2849
+ status: fetchRes.status,
2850
+ headers: {
2851
+ "Content-Type": fetchRes.headers.get("Content-Type") || "",
2852
+ "Content-Length": fetchRes.headers.get("Content-Length") || "0",
2853
+ "Cache-Control": fetchRes.headers.get("Cache-Control") || ""
2854
+ },
2855
+ body: fetchRes.body
2856
+ };
2832
2857
  } else {
2833
- console.warn("Missing sha256 query param");
2858
+ return {
2859
+ status: 500,
2860
+ json: {
2861
+ message: "No body in response"
2862
+ }
2863
+ };
2834
2864
  }
2835
- const fetchRes = await fetch(url, {
2836
- headers: getAuthHeaders(data.token)
2837
- });
2838
- if (fetchRes.status === 200) {
2839
- // TODO: does this stream data?
2840
- if (fetchRes.body) {
2841
- return {
2842
- status: fetchRes.status,
2843
- headers: {
2844
- "Content-Type": fetchRes.headers.get("Content-Type") || "",
2845
- "Content-Length": fetchRes.headers.get("Content-Length") || "0",
2846
- "Cache-Control": "public, max-age=31536000, immutable"
2847
- },
2848
- body: fetchRes.body
2849
- };
2850
- } else {
2851
- return {
2852
- status: 500,
2853
- json: {
2854
- message: "No body in response"
2855
- }
2856
- };
2857
- }
2858
- } else {
2859
- if (!(reqHeaders.host && reqHeaders["x-forwarded-proto"])) {
2860
- return {
2861
- status: 500,
2862
- json: {
2863
- message: "Missing host or x-forwarded-proto header"
2864
- }
2865
- };
2866
- }
2867
- const host = `${reqHeaders["x-forwarded-proto"]}://${reqHeaders["host"]}`;
2868
- const staticPublicUrl = new URL(filePath.slice("/public".length), host).toString();
2869
- const fetchRes = await fetch(staticPublicUrl, {
2870
- headers: getAuthHeaders(data.token)
2871
- });
2872
- if (fetchRes.status === 200) {
2873
- // TODO: does this stream data?
2874
- if (fetchRes.body) {
2875
- return {
2876
- status: fetchRes.status,
2877
- headers: {
2878
- "Content-Type": fetchRes.headers.get("Content-Type") || "",
2879
- "Content-Length": fetchRes.headers.get("Content-Length") || "0",
2880
- "Cache-Control": "public, max-age=31536000, immutable"
2881
- },
2882
- body: fetchRes.body
2883
- };
2884
- } else {
2885
- return {
2886
- status: 500,
2887
- json: {
2888
- message: "No body in response"
2889
- }
2890
- };
2865
+ } else {
2866
+ if (!(reqHeaders.host && reqHeaders["x-forwarded-proto"])) {
2867
+ return {
2868
+ status: 500,
2869
+ json: {
2870
+ message: "Missing host or x-forwarded-proto header"
2891
2871
  }
2892
- } else {
2893
- throw new Error("Failed to fetch file: " + filePath);
2894
- }
2872
+ };
2895
2873
  }
2896
- });
2874
+ const host = `${reqHeaders["x-forwarded-proto"]}://${reqHeaders["host"]}`;
2875
+ const staticPublicUrl = new URL(filePath.slice("/public".length), host).toString();
2876
+ const fetchRes = await fetch(staticPublicUrl);
2877
+ return {
2878
+ status: fetchRes.status,
2879
+ // forward headers from static public url
2880
+ headers: Object.fromEntries(fetchRes.headers.entries()),
2881
+ body: fetchRes.body
2882
+ };
2883
+ }
2897
2884
  }
2898
2885
  }
2899
2886
  function verifyCallbackReq(stateCookie, queryParams) {
@@ -1422,7 +1422,7 @@ class ValServer {
1422
1422
  async getTree(treePath,
1423
1423
  // TODO: use the params: patch, schema, source now we return everything, every time
1424
1424
  query, cookies, requestHeaders) {
1425
- const ensureRes = await this.ensureInitialized("getTree", cookies);
1425
+ const ensureRes = await debugTiming("ensureInitialized", () => this.ensureInitialized("getTree", cookies));
1426
1426
  if (result.isErr(ensureRes)) {
1427
1427
  return ensureRes.error;
1428
1428
  }
@@ -1430,7 +1430,7 @@ class ValServer {
1430
1430
  const execValidations = query.validate === "true";
1431
1431
  const includeSource = query.source === "true";
1432
1432
  const includeSchema = query.schema === "true";
1433
- const moduleIds = await this.getAllModules(treePath);
1433
+ const moduleIds = await debugTiming("getAllModules", () => this.getAllModules(treePath));
1434
1434
  let {
1435
1435
  patchIdsByModuleId,
1436
1436
  patchesById,
@@ -1441,7 +1441,7 @@ class ValServer {
1441
1441
  fileUpdates: {}
1442
1442
  };
1443
1443
  if (applyPatches) {
1444
- const res = await this.readPatches(cookies);
1444
+ const res = await debugTiming("readPatches", () => this.readPatches(cookies));
1445
1445
  if (result.isErr(res)) {
1446
1446
  return res.error;
1447
1447
  }
@@ -1449,9 +1449,9 @@ class ValServer {
1449
1449
  patchesById = res.value.patchesById;
1450
1450
  fileUpdates = res.value.fileUpdates;
1451
1451
  }
1452
- const possiblyPatchedContent = await Promise.all(moduleIds.map(async moduleId => {
1452
+ const possiblyPatchedContent = await debugTiming("applyAllPatchesThenValidate", () => Promise.all(moduleIds.map(async moduleId => {
1453
1453
  return this.applyAllPatchesThenValidate(moduleId, patchIdsByModuleId, patchesById, fileUpdates, cookies, requestHeaders, applyPatches, execValidations, includeSource, includeSchema);
1454
- }));
1454
+ })));
1455
1455
  const modules = Object.fromEntries(possiblyPatchedContent.map(serializedModuleContent => {
1456
1456
  const module = {
1457
1457
  schema: serializedModuleContent.schema,
@@ -1521,38 +1521,40 @@ class ValServer {
1521
1521
  return serializedModuleContent;
1522
1522
  }
1523
1523
  let source = maybeSource;
1524
- for (const patchId of patchIdsByModuleId[moduleId] ?? []) {
1525
- const patch = patchesById[patchId];
1526
- if (!patch) {
1527
- continue;
1528
- }
1529
- const patchRes = applyPatch(source, ops, patch.filter(Internal.notFileOp));
1530
- if (result.isOk(patchRes)) {
1531
- source = patchRes.value;
1532
- } else {
1533
- console.error("Val: got an unexpected error while applying patch. Is there a mismatch in Val versions? Perhaps Val is misconfigured?", {
1534
- patchId,
1535
- moduleId,
1536
- patch: JSON.stringify(patch, null, 2),
1537
- error: patchRes.error
1538
- });
1539
- return {
1540
- path: moduleId,
1541
- schema,
1542
- source,
1543
- errors: {
1544
- fatal: [{
1545
- message: "Unexpected error applying patch",
1546
- type: "invalid-patch"
1547
- }]
1548
- }
1549
- };
1524
+ await debugTiming("applyPatches:" + moduleId, async () => {
1525
+ for (const patchId of patchIdsByModuleId[moduleId] ?? []) {
1526
+ const patch = patchesById[patchId];
1527
+ if (!patch) {
1528
+ continue;
1529
+ }
1530
+ const patchRes = applyPatch(source, ops, patch.filter(Internal.notFileOp));
1531
+ if (result.isOk(patchRes)) {
1532
+ source = patchRes.value;
1533
+ } else {
1534
+ console.error("Val: got an unexpected error while applying patch. Is there a mismatch in Val versions? Perhaps Val is misconfigured?", {
1535
+ patchId,
1536
+ moduleId,
1537
+ patch: JSON.stringify(patch, null, 2),
1538
+ error: patchRes.error
1539
+ });
1540
+ return {
1541
+ path: moduleId,
1542
+ schema,
1543
+ source,
1544
+ errors: {
1545
+ fatal: [{
1546
+ message: "Unexpected error applying patch",
1547
+ type: "invalid-patch"
1548
+ }]
1549
+ }
1550
+ };
1551
+ }
1550
1552
  }
1551
- }
1553
+ });
1552
1554
  if (validate) {
1553
- const validationErrors = deserializeSchema(schema).validate(moduleId, source);
1555
+ const validationErrors = await debugTiming("validate:" + moduleId, async () => deserializeSchema(schema).validate(moduleId, source));
1554
1556
  if (validationErrors) {
1555
- const revalidated = await this.revalidateImageAndFileValidation(validationErrors, fileUpdates, cookies, requestHeaders);
1557
+ const revalidated = await debugTiming("revalidate image/file:" + moduleId, async () => this.revalidateImageAndFileValidation(validationErrors, fileUpdates, cookies, requestHeaders));
1556
1558
  return {
1557
1559
  path: moduleId,
1558
1560
  schema,
@@ -2004,6 +2006,16 @@ function guessMimeTypeFromPath(filePath) {
2004
2006
  function isCachedPatchFileOp(op) {
2005
2007
  return !!(op.op === "file" && typeof op.filePath === "string" && op.value && typeof op.value === "object" && !Array.isArray(op.value) && "sha256" in op.value && typeof op.value.sha256 === "string");
2006
2008
  }
2009
+ async function debugTiming(id, fn) {
2010
+ if (process.env["VAL_DEBUG_TIMING"] === "true") {
2011
+ const start = Date.now();
2012
+ const r = await fn();
2013
+ console.log(`Timing: ${id} took: ${Date.now() - start}ms (${new Date().toISOString()})`);
2014
+ return r;
2015
+ } else {
2016
+ return fn();
2017
+ }
2018
+ }
2007
2019
 
2008
2020
  const textEncoder = new TextEncoder();
2009
2021
  class LocalValServer extends ValServer {
@@ -2794,76 +2806,51 @@ class ProxyValServer extends ValServer {
2794
2806
  }
2795
2807
  });
2796
2808
  }
2797
- async getFiles(filePath, query, cookies, reqHeaders) {
2798
- return withAuth(this.options.valSecret, cookies, "getFiles", async data => {
2799
- const url = new URL(`/v1/files/${this.options.remote}${filePath}`, this.options.valContentUrl);
2800
- if (typeof query.sha256 === "string") {
2801
- url.searchParams.append("sha256", query.sha256);
2809
+ async getFiles(filePath, query, _cookies, reqHeaders) {
2810
+ const url = new URL(`/v1/files/${this.options.remote}${filePath}`, this.options.valContentUrl);
2811
+ if (typeof query.sha256 === "string") {
2812
+ url.searchParams.append("sha256", query.sha256);
2813
+ }
2814
+ const fetchRes = await fetch(url);
2815
+ if (fetchRes.status === 200) {
2816
+ // TODO: does this stream data?
2817
+ if (fetchRes.body) {
2818
+ return {
2819
+ status: fetchRes.status,
2820
+ headers: {
2821
+ "Content-Type": fetchRes.headers.get("Content-Type") || "",
2822
+ "Content-Length": fetchRes.headers.get("Content-Length") || "0",
2823
+ "Cache-Control": fetchRes.headers.get("Cache-Control") || ""
2824
+ },
2825
+ body: fetchRes.body
2826
+ };
2802
2827
  } else {
2803
- console.warn("Missing sha256 query param");
2828
+ return {
2829
+ status: 500,
2830
+ json: {
2831
+ message: "No body in response"
2832
+ }
2833
+ };
2804
2834
  }
2805
- const fetchRes = await fetch(url, {
2806
- headers: getAuthHeaders(data.token)
2807
- });
2808
- if (fetchRes.status === 200) {
2809
- // TODO: does this stream data?
2810
- if (fetchRes.body) {
2811
- return {
2812
- status: fetchRes.status,
2813
- headers: {
2814
- "Content-Type": fetchRes.headers.get("Content-Type") || "",
2815
- "Content-Length": fetchRes.headers.get("Content-Length") || "0",
2816
- "Cache-Control": "public, max-age=31536000, immutable"
2817
- },
2818
- body: fetchRes.body
2819
- };
2820
- } else {
2821
- return {
2822
- status: 500,
2823
- json: {
2824
- message: "No body in response"
2825
- }
2826
- };
2827
- }
2828
- } else {
2829
- if (!(reqHeaders.host && reqHeaders["x-forwarded-proto"])) {
2830
- return {
2831
- status: 500,
2832
- json: {
2833
- message: "Missing host or x-forwarded-proto header"
2834
- }
2835
- };
2836
- }
2837
- const host = `${reqHeaders["x-forwarded-proto"]}://${reqHeaders["host"]}`;
2838
- const staticPublicUrl = new URL(filePath.slice("/public".length), host).toString();
2839
- const fetchRes = await fetch(staticPublicUrl, {
2840
- headers: getAuthHeaders(data.token)
2841
- });
2842
- if (fetchRes.status === 200) {
2843
- // TODO: does this stream data?
2844
- if (fetchRes.body) {
2845
- return {
2846
- status: fetchRes.status,
2847
- headers: {
2848
- "Content-Type": fetchRes.headers.get("Content-Type") || "",
2849
- "Content-Length": fetchRes.headers.get("Content-Length") || "0",
2850
- "Cache-Control": "public, max-age=31536000, immutable"
2851
- },
2852
- body: fetchRes.body
2853
- };
2854
- } else {
2855
- return {
2856
- status: 500,
2857
- json: {
2858
- message: "No body in response"
2859
- }
2860
- };
2835
+ } else {
2836
+ if (!(reqHeaders.host && reqHeaders["x-forwarded-proto"])) {
2837
+ return {
2838
+ status: 500,
2839
+ json: {
2840
+ message: "Missing host or x-forwarded-proto header"
2861
2841
  }
2862
- } else {
2863
- throw new Error("Failed to fetch file: " + filePath);
2864
- }
2842
+ };
2865
2843
  }
2866
- });
2844
+ const host = `${reqHeaders["x-forwarded-proto"]}://${reqHeaders["host"]}`;
2845
+ const staticPublicUrl = new URL(filePath.slice("/public".length), host).toString();
2846
+ const fetchRes = await fetch(staticPublicUrl);
2847
+ return {
2848
+ status: fetchRes.status,
2849
+ // forward headers from static public url
2850
+ headers: Object.fromEntries(fetchRes.headers.entries()),
2851
+ body: fetchRes.body
2852
+ };
2853
+ }
2867
2854
  }
2868
2855
  }
2869
2856
  function verifyCallbackReq(stateCookie, queryParams) {
package/package.json CHANGED
@@ -12,7 +12,7 @@
12
12
  "./package.json": "./package.json"
13
13
  },
14
14
  "types": "dist/valbuild-server.cjs.d.ts",
15
- "version": "0.60.22",
15
+ "version": "0.60.23",
16
16
  "scripts": {
17
17
  "typecheck": "tsc --noEmit",
18
18
  "test": "jest",
@@ -24,9 +24,9 @@
24
24
  "concurrently": "^7.6.0"
25
25
  },
26
26
  "dependencies": {
27
- "@valbuild/core": "~0.60.22",
28
- "@valbuild/shared": "~0.60.22",
29
- "@valbuild/ui": "~0.60.22",
27
+ "@valbuild/core": "~0.60.23",
28
+ "@valbuild/shared": "~0.60.23",
29
+ "@valbuild/ui": "~0.60.23",
30
30
  "express": "^4.18.2",
31
31
  "image-size": "^1.0.2",
32
32
  "minimatch": "^3.0.4",