diff --git a/apps/builder/app/routes/$.tsx b/apps/builder/app/routes/$.tsx
index eaf9d50f59..4b47509620 100644
--- a/apps/builder/app/routes/$.tsx
+++ b/apps/builder/app/routes/$.tsx
@@ -89,3 +89,8 @@ const Content = () => {
};
export default Content;
+
+// Reduces Vercel function size from 29MB to 9MB for unknown reasons; effective when used in limited files.
+export const config = {
+ maxDuration: 30,
+};
diff --git a/apps/builder/app/routes/_index.tsx b/apps/builder/app/routes/_index.tsx
index 58ff518303..d1b8627a49 100644
--- a/apps/builder/app/routes/_index.tsx
+++ b/apps/builder/app/routes/_index.tsx
@@ -16,3 +16,8 @@ export const loader = (args: LoaderFunctionArgs) => catchAllloader(args);
export const ErrorBoundary = () => ;
const Content = () => ;
export default Content;
+
+// Reduces Vercel function size from 29MB to 9MB for unknown reasons; effective when used in limited files.
+export const config = {
+ maxDuration: 30,
+};
diff --git a/apps/builder/app/routes/builder.$projectId.tsx b/apps/builder/app/routes/builder.$projectId.tsx
index b1080572b5..a43e2171db 100644
--- a/apps/builder/app/routes/builder.$projectId.tsx
+++ b/apps/builder/app/routes/builder.$projectId.tsx
@@ -197,3 +197,8 @@ export const shouldRevalidate: ShouldRevalidateFunction = ({
};
export default BuilderRoute;
+
+// Reduces Vercel function size from 29MB to 9MB for unknown reasons; effective when used in limited files.
+export const config = {
+ maxDuration: 30,
+};
diff --git a/apps/builder/app/routes/builder.tsx b/apps/builder/app/routes/builder.tsx
index cf6dc07961..9b878b01cc 100644
--- a/apps/builder/app/routes/builder.tsx
+++ b/apps/builder/app/routes/builder.tsx
@@ -19,3 +19,8 @@ export const shouldRevalidate: ShouldRevalidateFunction = ({
};
export default Root;
+
+// Reduces Vercel function size from 29MB to 9MB for unknown reasons; effective when used in limited files.
+export const config = {
+ maxDuration: 30,
+};
diff --git a/apps/builder/app/routes/dashboard.tsx b/apps/builder/app/routes/dashboard.tsx
index 047a37eef7..685120bb45 100644
--- a/apps/builder/app/routes/dashboard.tsx
+++ b/apps/builder/app/routes/dashboard.tsx
@@ -6,3 +6,8 @@ export const meta: MetaFunction = () => {
};
export default Root;
+
+// Reduces Vercel function size from 29MB to 9MB for unknown reasons; effective when used in limited files.
+export const config = {
+ maxDuration: 30,
+};
diff --git a/apps/builder/app/routes/login._index.tsx b/apps/builder/app/routes/login._index.tsx
index 407a37652b..618211af1b 100644
--- a/apps/builder/app/routes/login._index.tsx
+++ b/apps/builder/app/routes/login._index.tsx
@@ -60,3 +60,8 @@ const LoginRoute = () => {
};
export default LoginRoute;
+
+// Reduces Vercel function size from 29MB to 9MB for unknown reasons; effective when used in limited files.
+export const config = {
+ maxDuration: 30,
+};
diff --git a/apps/builder/app/routes/login.tsx b/apps/builder/app/routes/login.tsx
index c30c0559f4..4e3d9c2cfc 100644
--- a/apps/builder/app/routes/login.tsx
+++ b/apps/builder/app/routes/login.tsx
@@ -6,3 +6,8 @@ export const meta: MetaFunction = () => {
};
export default Root;
+
+// Reduces Vercel function size from 29MB to 9MB for unknown reasons; effective when used in limited files.
+export const config = {
+ maxDuration: 30,
+};
diff --git a/apps/builder/app/routes/rest.patch.ts b/apps/builder/app/routes/rest.patch.ts
index 64095a9aed..9a75a62b8b 100644
--- a/apps/builder/app/routes/rest.patch.ts
+++ b/apps/builder/app/routes/rest.patch.ts
@@ -335,3 +335,8 @@ export const action = async ({ request }: ActionFunctionArgs) => {
return { errors: e instanceof Error ? e.message : JSON.stringify(e) };
}
};
+
+// Reduces Vercel function size from 29MB to 9MB for unknown reasons; effective when used in limited files.
+export const config = {
+ maxDuration: 30, // seconds
+};
diff --git a/apps/builder/package.json b/apps/builder/package.json
index 7e9df323f5..2e6ea2c02f 100644
--- a/apps/builder/package.json
+++ b/apps/builder/package.json
@@ -54,6 +54,7 @@
"@upstash/ratelimit": "^0.4.4",
"@vercel/edge": "^1.1.0",
"@vercel/kv": "^0.2.3",
+ "@vercel/remix": "2.8.1-patch.2",
"@webstudio-is/ai": "workspace:*",
"@webstudio-is/asset-uploader": "workspace:*",
"@webstudio-is/authorization-token": "workspace:*",
diff --git a/apps/builder/vite.config.ts b/apps/builder/vite.config.ts
index acbc9bba6f..0906c828dc 100644
--- a/apps/builder/vite.config.ts
+++ b/apps/builder/vite.config.ts
@@ -1,11 +1,18 @@
import { resolve } from "node:path";
import { defineConfig } from "vite";
import { vitePlugin as remix } from "@remix-run/dev";
+// eslint-disable-next-line import/no-internal-modules
+import { vercelPreset } from "@vercel/remix/vite";
const isStorybook = process.argv[1]?.includes("storybook") ?? false;
export default defineConfig(({ mode }) => ({
- plugins: [isStorybook === false && remix()],
+ plugins: [
+ isStorybook === false &&
+ remix({
+ presets: [vercelPreset()],
+ }),
+ ],
resolve: {
conditions: ["webstudio", "import", "module", "browser", "default"],
alias: [
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 4154e11ebe..bb087d52c6 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -171,6 +171,9 @@ importers:
'@vercel/kv':
specifier: ^0.2.3
version: 0.2.3
+ '@vercel/remix':
+ specifier: 2.8.1-patch.2
+ version: 2.8.1-patch.2(@remix-run/dev@2.8.1(@remix-run/serve@2.8.1(typescript@5.4.5))(@types/node@20.12.7)(typescript@5.4.5)(vite@5.2.8(@types/node@20.12.7))(wrangler@3.50.0(@cloudflare/workers-types@4.20240405.0)))(@remix-run/node@2.8.1(typescript@5.4.5))(@remix-run/server-runtime@2.8.1(typescript@5.4.5))(react-dom@18.3.0-canary-14898b6a9-20240318(react@18.3.0-canary-14898b6a9-20240318))(react@18.3.0-canary-14898b6a9-20240318)
'@webstudio-is/ai':
specifier: workspace:*
version: link:../../packages/ai
@@ -4778,6 +4781,9 @@ packages:
resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==}
engines: {node: '>=10.13.0'}
+ '@ts-morph/common@0.11.1':
+ resolution: {integrity: sha512-7hWZS0NRpEsNV8vWJzg7FEz6V8MaLNeJOmwmghqUXTpzk16V1LLZhdo+4QvE/+zv4cVci0OviuJFnqhEfoV3+g==}
+
'@types/acorn@4.0.6':
resolution: {integrity: sha512-veQTnWP+1D/xbxVrPC3zHnCZRjSrKfhbMUlEA43iMZLu7EsnTtkJklIuwrCPbOi8YkvDQAiW05VQQFvvz9oieQ==}
@@ -5097,6 +5103,19 @@ packages:
resolution: {integrity: sha512-Wq1+EsRBQmvLlcqCZeYVg1MAARWrnETgLe3Sy3UCqG+zg7LThpkt0YHZe1NN3Aj4IRmCKQamotWrLDdEx+ZB3w==}
engines: {node: '>=14.6'}
+ '@vercel/remix@2.8.1-patch.2':
+ resolution: {integrity: sha512-Ao4quvRKJshgB9ABSIdx+oNCxWPvNwvBzhEq97grnF+SP9zas+mENCYOvE4rsk7txFDwob+2Qs+bK0h+r3NScg==}
+ engines: {node: '>=18.0.0'}
+ peerDependencies:
+ '@remix-run/dev': 2.8.1
+ '@remix-run/node': 2.8.1
+ '@remix-run/server-runtime': 2.8.1
+ react: 18.3.0-canary-14898b6a9-20240318
+ react-dom: 18.3.0-canary-14898b6a9-20240318
+
+ '@vercel/static-config@3.0.0':
+ resolution: {integrity: sha512-2qtvcBJ1bGY0dYGYh3iM7yGKkk971FujLEDXzuW5wcZsPr1GSEjO/w2iSr3qve6nDDtBImsGoDEnus5FI4+fIw==}
+
'@vitejs/plugin-react@3.1.0':
resolution: {integrity: sha512-AfgcRL8ZBhAlc3BFdigClmTUMISmmzHn7sB2h9U1odvc5U/MjWXsAaz18b/WoppUTDBzxOJwo2VdClfUcItu9g==}
engines: {node: ^14.18.0 || >=16.0.0}
@@ -5237,6 +5256,9 @@ packages:
ajv@6.12.6:
resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==}
+ ajv@8.6.3:
+ resolution: {integrity: sha512-SMJOdDP6LqTkD0Uq8qLi+gMwSt0imXLSV080qFVwJCpH9U6Mb+SUGHAXM0KNbcBPguytWyvFxcHgMLe2D2XSpw==}
+
ansi-escapes@4.3.2:
resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==}
engines: {node: '>=8'}
@@ -5681,6 +5703,9 @@ packages:
resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==}
engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'}
+ code-block-writer@10.1.1:
+ resolution: {integrity: sha512-67ueh2IRGst/51p0n6FvPrnRjAGHY5F8xdjkgrYE7DDzpJe6qA07RYQ9VcoUeo5ATOjSOiWpSL3SWBRRbempMw==}
+
code-red@1.0.4:
resolution: {integrity: sha512-7qJWqItLA8/VPVlKJlFXU+NBlo/qyfs39aJcuMT/2ere32ZqvF5OSxgdM5xOfJJ7O429gg2HM47y8v9P+9wrNw==}
@@ -7314,9 +7339,15 @@ packages:
resolution: {integrity: sha512-aatBvbL26wVUCLmbWdCpeu9iF5wOyWpagiKkInA+kfws3sWdBrTnsvN2CKcyCYyUrc7rebNBlK6+kteg7ksecg==}
engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
+ json-schema-to-ts@1.6.4:
+ resolution: {integrity: sha512-pR4yQ9DHz6itqswtHCm26mw45FSNfQ9rEQjosaZErhn5J3J2sIViQiz8rDaezjKAhFGpmsoczYVBgGHzFw/stA==}
+
json-schema-traverse@0.4.1:
resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==}
+ json-schema-traverse@1.0.0:
+ resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==}
+
json-stable-stringify-without-jsonify@1.0.1:
resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==}
@@ -8176,6 +8207,9 @@ packages:
resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==}
engines: {node: '>= 0.8'}
+ path-browserify@1.0.1:
+ resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==}
+
path-exists@3.0.0:
resolution: {integrity: sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==}
engines: {node: '>=4'}
@@ -8801,6 +8835,10 @@ packages:
resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
engines: {node: '>=0.10.0'}
+ require-from-string@2.0.2:
+ resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==}
+ engines: {node: '>=0.10.0'}
+
require-like@0.1.2:
resolution: {integrity: sha512-oyrU88skkMtDdauHDuKVrgR+zuItqr6/c//FXzvmxRGMexSDc6hNvJInGW3LL46n+8b50RykrvwSUIIQH2LQ5A==}
@@ -9392,6 +9430,12 @@ packages:
engines: {node: '>=10.0.0'}
hasBin: true
+ ts-morph@12.0.0:
+ resolution: {integrity: sha512-VHC8XgU2fFW7yO1f/b3mxKDje1vmyzFXHWzOYmKEkCEwcLjDtbdLgBQviqj4ZwP4MJkQtRo6Ha2I29lq/B+VxA==}
+
+ ts-toolbelt@6.15.5:
+ resolution: {integrity: sha512-FZIXf1ksVyLcfr7M317jbB67XFJhOO1YqdTcuGaq9q5jLUoTikukZ+98TPjKiP2jC5CgmYdWWYs0s2nLSU0/1A==}
+
tsconfck@3.0.3:
resolution: {integrity: sha512-4t0noZX9t6GcPTfBAbIbbIU4pfpCwh0ueq3S4O/5qXI1VwK1outmxhe9dOiEWqMz3MW2LKgDTpqWV+37IWuVbA==}
engines: {node: ^18 || >=20}
@@ -14218,6 +14262,13 @@ snapshots:
'@trysound/sax@0.2.0': {}
+ '@ts-morph/common@0.11.1':
+ dependencies:
+ fast-glob: 3.2.12
+ minimatch: 3.1.2
+ mkdirp: 1.0.4
+ path-browserify: 1.0.1
+
'@types/acorn@4.0.6':
dependencies:
'@types/estree': 1.0.1
@@ -14632,6 +14683,23 @@ snapshots:
transitivePeerDependencies:
- encoding
+ '@vercel/remix@2.8.1-patch.2(@remix-run/dev@2.8.1(@remix-run/serve@2.8.1(typescript@5.4.5))(@types/node@20.12.7)(typescript@5.4.5)(vite@5.2.8(@types/node@20.12.7))(wrangler@3.50.0(@cloudflare/workers-types@4.20240405.0)))(@remix-run/node@2.8.1(typescript@5.4.5))(@remix-run/server-runtime@2.8.1(typescript@5.4.5))(react-dom@18.3.0-canary-14898b6a9-20240318(react@18.3.0-canary-14898b6a9-20240318))(react@18.3.0-canary-14898b6a9-20240318)':
+ dependencies:
+ '@remix-run/dev': 2.8.1(@remix-run/serve@2.8.1(typescript@5.4.5))(@types/node@20.12.7)(typescript@5.4.5)(vite@5.2.8(@types/node@20.12.7))(wrangler@3.50.0(@cloudflare/workers-types@4.20240405.0))
+ '@remix-run/node': 2.8.1(typescript@5.4.5)
+ '@remix-run/server-runtime': 2.8.1(typescript@5.4.5)
+ '@vercel/static-config': 3.0.0
+ isbot: 3.6.13
+ react: 18.3.0-canary-14898b6a9-20240318
+ react-dom: 18.3.0-canary-14898b6a9-20240318(react@18.3.0-canary-14898b6a9-20240318)
+ ts-morph: 12.0.0
+
+ '@vercel/static-config@3.0.0':
+ dependencies:
+ ajv: 8.6.3
+ json-schema-to-ts: 1.6.4
+ ts-morph: 12.0.0
+
'@vitejs/plugin-react@3.1.0(vite@4.4.9(@types/node@20.12.7))':
dependencies:
'@babel/core': 7.22.9
@@ -14802,6 +14870,13 @@ snapshots:
json-schema-traverse: 0.4.1
uri-js: 4.4.1
+ ajv@8.6.3:
+ dependencies:
+ fast-deep-equal: 3.1.3
+ json-schema-traverse: 1.0.0
+ require-from-string: 2.0.2
+ uri-js: 4.4.1
+
ansi-escapes@4.3.2:
dependencies:
type-fest: 0.21.3
@@ -15325,6 +15400,8 @@ snapshots:
co@4.6.0: {}
+ code-block-writer@10.1.1: {}
+
code-red@1.0.4:
dependencies:
'@jridgewell/sourcemap-codec': 1.4.15
@@ -17384,8 +17461,15 @@ snapshots:
json-parse-even-better-errors@3.0.1: {}
+ json-schema-to-ts@1.6.4:
+ dependencies:
+ '@types/json-schema': 7.0.15
+ ts-toolbelt: 6.15.5
+
json-schema-traverse@0.4.1: {}
+ json-schema-traverse@1.0.0: {}
+
json-stable-stringify-without-jsonify@1.0.1: {}
json5@1.0.2:
@@ -18623,6 +18707,8 @@ snapshots:
parseurl@1.3.3: {}
+ path-browserify@1.0.1: {}
+
path-exists@3.0.0: {}
path-exists@4.0.0: {}
@@ -19347,6 +19433,8 @@ snapshots:
require-directory@2.1.1: {}
+ require-from-string@2.0.2: {}
+
require-like@0.1.2: {}
requires-port@1.0.0: {}
@@ -20020,6 +20108,13 @@ snapshots:
safe-stable-stringify: 2.4.3
typescript: 5.4.5
+ ts-morph@12.0.0:
+ dependencies:
+ '@ts-morph/common': 0.11.1
+ code-block-writer: 10.1.1
+
+ ts-toolbelt@6.15.5: {}
+
tsconfck@3.0.3(typescript@5.4.5):
optionalDependencies:
typescript: 5.4.5