Skip to content

Commit

Permalink
Merge branch 'main' into v7
Browse files Browse the repository at this point in the history
  • Loading branch information
juliusmarminge committed Jun 25, 2024
2 parents 56b6f85 + f4f876c commit 99bce48
Show file tree
Hide file tree
Showing 28 changed files with 492 additions and 410 deletions.
6 changes: 6 additions & 0 deletions .changeset/proud-elephants-kick.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@uploadthing/shared": patch
"uploadthing": patch
---

refactor: use `effect/Micro` for client bundle, reducing bundle size shipped to browser by 84kB (-67%)
1 change: 1 addition & 0 deletions .envrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
use flake;
125 changes: 73 additions & 52 deletions .github/analyze-bundle.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,72 +49,93 @@ async function getTotalBundleSize(filepath) {
return totalGzipLength;
}

function formatBytes(bytes) {
if (bytes === 0) return "0B";
const abs = Math.abs(bytes);
const units = ["B", "KB", "MB"];
const i = Math.floor(Math.log(abs) / Math.log(1000));
const size = (abs / Math.pow(1000, i)).toFixed(2);
return `${size}${units[i]}`;
}

/** @param {number} diff */
function formatDiff(diff) {
if (diff === 0) return "0B 📦";
if (diff === 0) return "No change";
const sign = diff > 0 ? "↑" : "↓";

const units = ["B", "KB", "MB"];
const i = Math.floor(Math.log(diff) / Math.log(1000));
const size = (diff / Math.pow(1000, i)).toFixed(2);
return `${sign}${size}${units[i]} 📦`;
return `${sign}${formatBytes(diff)}`;
}

(async () => {
const mainGzip = await getTotalBundleSize(`bundle-main/out.json`);
const prGzip = await getTotalBundleSize(`bundle-current-pr/out.json`);

// Upload HTML files for easy inspection
const utapi = new UTApi();
const files = await utapi.uploadFiles([
new File(
[await fs.readFile("bundle-main/out.html", "utf-8")],
`${context.sha}-bundle-main.html`,
),
new File(
[await fs.readFile("bundle-current-pr/out.html", "utf-8")],
`${context.sha}-bundle-pr-${pr.number}.html`,
),
]);

if (!files[0].data || !files[1].data) {
throw new Error("Failed to upload files");
console.log(`mainGzip: ${formatBytes(mainGzip)}`);
console.log(`prGzip: ${formatBytes(prGzip)}`);
console.log(`diff: ${formatDiff(prGzip - mainGzip)}`);

// Upload HTML files for easy inspection (not on forks)
let treemapMain = "_No treemap on forks_";
let treemapPr = "_No treemap on forks_";
if (
typeof process.env.UPLOADTHING_SECRET === "string" &&
process.env.UPLOADTHING_SECRET.length > 0
) {
const utapi = new UTApi();
const files = await utapi.uploadFiles([
new File(
[await fs.readFile("bundle-main/out.html", "utf-8")],
`${context.sha}-bundle-main.html`,
),
new File(
[await fs.readFile("bundle-current-pr/out.html", "utf-8")],
`${context.sha}-bundle-pr-${pr.number}.html`,
),
]);

if (files[0].data && files[1].data) {
treemapMain = `[See Treemap 📊](${files[0].data.url})`;
treemapPr = `[See Treemap 📊](${files[1].data.url})`;
}
}

const commentBody = `
## ${STICKY_COMMENT_TITLE}
| Bundle | Size (gzip) | Visualization |
| ------------------- | ------------------------------------ | -------------------------------------- |
| Main | ${mainGzip} | [See Treemap 📊](${files[0].data.url}) |
| PR (${context.sha}) | ${prGzip} | [See Treemap 📊](${files[1].data.url}) |
| **Diff** | **${formatDiff(mainGzip - prGzip)}** | |
`;
## ${STICKY_COMMENT_TITLE}
| Bundle | Size (gzip) | Visualization |
| ------------------- | ------------------------------------ | -------------- |
| Main | ${mainGzip} | ${treemapMain} |
| PR (${context.sha}) | ${prGzip} | ${treemapPr} |
| **Diff** | **${formatDiff(prGzip - mainGzip)}** | |
`;

// Write a comment with the diff
const comment = await github.rest.issues
.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: pr.number,
})
.then((cmts) =>
cmts.data.find((cmt) => cmt.body?.includes(STICKY_COMMENT_TITLE)),
);
if (comment) {
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: comment.id,
body: commentBody,
});
} else {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: pr.number,
body: commentBody,
});
try {
const comment = await github.rest.issues
.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: pr.number,
})
.then((cmts) =>
cmts.data.find((cmt) => cmt.body?.includes(STICKY_COMMENT_TITLE)),
);
if (comment) {
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: comment.id,
body: commentBody,
});
} else {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: pr.number,
body: commentBody,
});
}
} catch (error) {
console.error(error);
}
})().catch((error) => {
console.error(error);
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ jobs:
uses: actions/checkout@v4
with:
fetch-depth: 1
ref: ${{ matrix.branch == 'current-pr' && github.head_ref || matrix.branch }}
ref: ${{ matrix.branch == 'current-pr' && github.ref || matrix.branch }}

- name: Setup
uses: ./tooling/gh-actions/setup
Expand Down Expand Up @@ -139,5 +139,5 @@ jobs:
- name: Compare client bundle
run: node .github/analyze-bundle.js
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
UPLOADTHING_SECRET: ${{ secrets.UPLOADTHING_E2E_TEST_SECRET }}
GITHUB_TOKEN: ${{ github.token }}
UPLOADTHING_SECRET: ${{ secrets.UPLOADTHING_E2E_TEST_SECRET }}
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,6 @@ dist
.vercel
.output
.nuxt

# direnv
.direnv/
6 changes: 3 additions & 3 deletions examples/backend-adapters/server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@
"dev:effect": "NODE_ENV=development tsx watch src/effect-platform.ts"
},
"dependencies": {
"@effect/platform": "^0.57.2",
"@effect/platform-node": "^0.51.11",
"@effect/platform": "^0.58.9",
"@effect/platform-node": "^0.53.8",
"@elysiajs/cors": "^0.8.0",
"@fastify/cors": "^9.0.1",
"@hono/node-server": "^1.8.2",
"cors": "^2.8.5",
"dotenv": "^16.4.5",
"effect": "^3.3.2",
"effect": "3.4.2",
"elysia": "^0.8.17",
"express": "^4.18.2",
"fastify": "^4.26.1",
Expand Down
31 changes: 19 additions & 12 deletions examples/backend-adapters/server/src/effect-platform.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
import "dotenv/config";

import { createServer } from "node:http";
import {
Headers,
HttpMiddleware,
HttpRouter,
HttpServer,
HttpServerRequest,
HttpServerResponse,
} from "@effect/platform";
import { NodeHttpServer, NodeRuntime } from "@effect/platform-node";
import * as Http from "@effect/platform/HttpServer";
import { Config, Effect, Layer } from "effect";

import { createRouteHandler } from "uploadthing/effect-platform";
Expand All @@ -17,9 +24,9 @@ const uploadthingRouter = createRouteHandler({
* Simple CORS middleware that allows everything
* Adjust to your needs.
*/
const cors = Http.middleware.make((app) =>
const cors = HttpMiddleware.make((app) =>
Effect.gen(function* () {
const req = yield* Http.request.ServerRequest;
const req = yield* HttpServerRequest.HttpServerRequest;

const corsHeaders = {
"Access-Control-Allow-Origin": "*",
Expand All @@ -28,33 +35,33 @@ const cors = Http.middleware.make((app) =>
};

if (req.method === "OPTIONS") {
return Http.response.empty({
return HttpServerResponse.empty({
status: 204,
headers: Http.headers.fromInput(corsHeaders),
headers: Headers.fromInput(corsHeaders),
});
}

const response = yield* app;

return response.pipe(Http.response.setHeaders(corsHeaders));
return response.pipe(HttpServerResponse.setHeaders(corsHeaders));
}),
);

const router = Http.router.empty.pipe(
Http.router.get("/api", Http.response.text("Hello from Effect")),
Http.router.mount("/api/uploadthing", uploadthingRouter),
const router = HttpRouter.empty.pipe(
HttpRouter.get("/api", HttpServerResponse.text("Hello from Effect")),
HttpRouter.mount("/api/uploadthing", uploadthingRouter),
);

const app = router.pipe(
cors,
Http.server.serve(Http.middleware.logger),
Http.server.withLogAddress,
HttpServer.serve(HttpMiddleware.logger),
HttpServer.withLogAddress,
);

const Port = Config.integer("PORT").pipe(Config.withDefault(3000));
const ServerLive = Layer.unwrapEffect(
Effect.map(Port, (port) =>
NodeHttpServer.server.layer(() => createServer(), { port }),
NodeHttpServer.layer(() => createServer(), { port }),
),
);

Expand Down
27 changes: 27 additions & 0 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

37 changes: 37 additions & 0 deletions flake.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
inputs = {
nixpkgs = {
url = "github:nixos/nixpkgs/nixpkgs-unstable";
};
};
outputs = {nixpkgs, ...}: let
systems = ["x86_64-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin"];
forAllSystems = nixpkgs.lib.genAttrs systems;
in {
formatter = forAllSystems (
system: let
pkgs = nixpkgs.legacyPackages.${system};
in
pkgs.alejandra
);
devShells = forAllSystems (
system: let
pkgs = nixpkgs.legacyPackages.${system};
node = pkgs.nodejs_20;
corepackEnable = pkgs.runCommand "corepack-enable" {} ''
mkdir -p $out/bin
${node}/bin/corepack enable --install-directory $out/bin
'';
in {
default = with pkgs;
mkShell {
buildInputs = [
bun
corepackEnable
node
];
};
}
);
};
}
2 changes: 1 addition & 1 deletion packages/shared/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
},
"dependencies": {
"@uploadthing/mime-types": "workspace:*",
"effect": "^3.3.2",
"effect": "3.4.2",
"std-env": "^3.7.0"
},
"devDependencies": {
Expand Down
Loading

0 comments on commit 99bce48

Please sign in to comment.