Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: return streams #357

Merged
merged 15 commits into from
Aug 13, 2024
Merged
4 changes: 2 additions & 2 deletions .github/workflows/release-experimental.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
# - Make whatever changes you need and commit them:
# - `git add . && git commit "experimental changes!"`
# - Update version numbers and create a release tag:
# - `yarn run version:experimental`
# - `pnpm run version:experimental`
# - Push to GitHub:
# - `git push origin --follow-tags`
# - Create a new release for the tag on GitHub to trigger the CI workflow that
Expand Down Expand Up @@ -62,7 +62,7 @@ jobs:
run: pnpm install --recursive --frozen-lockfile --strict-peer-dependencies

- name: 🏗 Build
run: yarn build
run: pnpm run build

- name: 🔐 Setup npm auth
run: |
Expand Down
13 changes: 13 additions & 0 deletions .pnpmfile.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,19 @@ function readPackage(pkg) {
pkg.dependencies["@mcansh/remix-fastify"] = "workspace:*";
}

let remixPackages = Object.keys(pkg.dependencies).filter((p) => {
return p.startsWith("@remix-run");
});
if (pkg.dependencies["remix"]) {
pkg.dependencies["remix"] = "latest";
}

for (let p of remixPackages) {
if (pkg.dependencies[p]) {
pkg.dependencies[p] = "latest";
}
}

return pkg;
}

Expand Down
9 changes: 5 additions & 4 deletions examples/basic/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
"type": "module",
"scripts": {
"build": "remix build",
"dev": "remix dev --manual -c \"node --watch-path ./server.js --enable-source-maps ./server.js\"",
"dev": "remix dev --manual -c \"node --watch-path ./server.js ./server.js\"",
"lint": "eslint --ignore-path .gitignore --no-error-on-unmatched-pattern --cache --cache-location node_modules/.cache/eslint --fix .",
"format": "prettier --ignore-path .gitignore --ignore-unknown --cache --cache-location node_modules/.cache/prettiercache --write .",
"start": "cross-env NODE_ENV=production node --enable-source-maps ./server.js",
"start": "cross-env NODE_ENV=production node ./server.js",
"typecheck": "tsc"
},
"dependencies": {
Expand All @@ -21,7 +21,8 @@
"fastify": "^4.28.1",
"isbot": "^5.1.11",
"react": "^18.3.1",
"react-dom": "^18.3.1"
"react-dom": "^18.3.1",
"source-map-support": "^0.5.21"
},
"devDependencies": {
"@remix-run/dev": "*",
Expand All @@ -31,7 +32,7 @@
"chokidar": "^3.6.0",
"eslint": "^8.57.0",
"prettier": "^3.2.5",
"typescript": "^5.4.5"
"typescript": "^5.5.4"
},
"engines": {
"node": ">=18.0.0"
Expand Down
2 changes: 2 additions & 0 deletions examples/basic/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@ import fastify from "fastify";
import { createRequestHandler } from "@mcansh/remix-fastify";
import { broadcastDevReady, installGlobals } from "@remix-run/node";
import { fastifyStatic } from "@fastify/static";
import sourceMapSupport from "source-map-support";

installGlobals();
sourceMapSupport.install();

let __dirname = url.fileURLToPath(new URL(".", import.meta.url));
let BUILD_PATH = "./build/index.js";
Expand Down
4 changes: 3 additions & 1 deletion examples/playground/app/root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@ export default function App() {
<Links />
</head>
<body>
<div className="root-message">{data.message}</div>
<div className="bg-red-700 border-2 border-black text-white p-4 max-w-max mx-auto">
{data.message}
</div>
<Outlet />
<Scripts />
<ScrollRestoration />
Expand Down
56 changes: 33 additions & 23 deletions examples/playground/app/routes/_layout._index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,19 +59,16 @@ export default function Index() {
const [echo, setEcho] = React.useState<string | null>(null);

return (
<div>
<React.Suspense fallback={<h2>loading...</h2>}>
<>
<React.Suspense fallback={<h2 className="text-gray-400">loading...</h2>}>
<Await resolve={data.name} errorElement={<h2>failed...</h2>}>
{(resolvedName) => <h2>Hello {resolvedName}</h2>}
</Await>
</React.Suspense>

<h2>Context: {data.loadContextName}</h2>

<Form
method="post"
style={{ display: "flex", justifyContent: "center", gap: 4 }}
>
<Form method="post" className="flex justify-center gap-2">
<label>
<span>Name: </span>
<React.Suspense fallback={<FallbackNameInput />}>
Expand All @@ -80,47 +77,57 @@ export default function Index() {
</Await>
</React.Suspense>
</label>
<button name="intent" value="submit" type="submit">
<button
name="intent"
value="submit"
className="rounded-md bg-green-600 px-2 text-white"
type="submit"
>
Submit
</button>
<button name="intent" value="reset" type="submit">
<button
name="intent"
value="reset"
className="rounded-md bg-red-600 px-2 text-white"
type="submit"
>
Reset
</button>
</Form>

<form
method="post"
style={{
display: "flex",
justifyContent: "center",
gap: 4,
marginTop: 16,
flexDirection: "column",
}}
className="flex justify-center gap-4 mt-4 flex-col mx-auto max-w-max"
action="/api/echo"
onSubmit={async (event) => {
event.preventDefault();
let formData = new FormData(event.currentTarget);
let response = await fetch(event.currentTarget.action, {
method: event.currentTarget.method,
body: JSON.stringify(Object.fromEntries(formData.entries())),
headers: {
"Content-Type": "application/json",
},
headers: { "Content-Type": "application/json" },
});
let json = await response.json();
setEcho(json);
}}
>
<div>
<input type="text" name="text" />
<button name="intent" type="submit" value="echo">
<div className="flex gap-2">
<label>
<span>Text: </span>
<input type="text" name="text" />
</label>
<button
name="intent"
type="submit"
value="echo"
className="rounded-md bg-green-600 px-2 text-white"
>
Echo
</button>
</div>
{echo ? <pre>{JSON.stringify(echo)}</pre> : null}
</form>
</div>
</>
);
}

Expand All @@ -139,10 +146,13 @@ function NameInput() {
name="name"
placeholder="Enter your name"
defaultValue={defaultValue}
className="px-1"
/>
);
}

function FallbackNameInput() {
return <input type="text" name="name" title="Enter your name" />;
return (
<input type="text" name="name" title="Enter your name" className="px-1" />
);
}
9 changes: 9 additions & 0 deletions examples/playground/app/routes/_layout.loader-error.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { unstable_defineLoader as defineLoader } from "@remix-run/node";

export const loader = defineLoader(() => {
throw new Error("This is an error");
});

export default function Component() {
return <p>You'll never see this</p>;
}
4 changes: 2 additions & 2 deletions examples/playground/app/routes/_layout.page-2.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ import * as React from "react";
import { defer } from "@remix-run/node";
import { Await, useLoaderData } from "@remix-run/react";

import { sleep } from "~/sleep";
import { withDelay } from "~/sleep";

export function loader() {
return defer({
message: "loader data from page 2",
deferred: sleep(2_000, "some text\n".repeat(2_000)),
deferred: withDelay(2_000, "some text\n".repeat(2_000)),
});
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { unstable_defineLoader as defineLoader } from "@remix-run/node";

export const loader = defineLoader(() => {
throw new Error("This is an error");
});
3 changes: 3 additions & 0 deletions examples/playground/app/routes/_layout.route-error.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default function foo() {
throw new Error("This is an error");
}
94 changes: 33 additions & 61 deletions examples/playground/app/routes/_layout.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,25 @@
import { NavLink, Outlet } from "@remix-run/react";

let LINKS = [
{ to: "/", label: "Home" },
{ to: "/page-2", label: "Page 2" },
{ to: "/fetcher", label: "Fetcher" },
{ to: "loader-error", label: "Loader Error" },
{ to: "route-error", label: "Route Error" },
{ to: "resource-route-error", label: "Resource Route Loader Error", reloadDocument: true },
] as const;

export default function Layout() {
return (
<div>
<header>
<h1
style={{
background: `linear-gradient(to right, #ee33aa, rgb(79 70 229 / 1))`,
fontSize: 36,
backgroundClip: "text",
WebkitBackgroundClip: "text",
WebkitTextFillColor: "transparent",
}}
>
<h1 className="bg-clip-text text-4xl transparent bg-gradient-to-r from-pink-500 to-purple-500 text-fill-transparent font-semibold text-center py-2">
Welcome to{" "}
<a
target="_blank"
rel="noreferrer nofollow noopener"
href="https://remix.run"
style={{ borderBottom: "2px solid currentColor" }}
className="border-b-2"
>
Remix
</a>{" "}
Expand All @@ -27,65 +28,36 @@ export default function Layout() {
target="_blank"
rel="noreferrer nofollow noopener"
href="https://fastify.io"
style={{ borderBottom: "2px solid currentColor" }}
className="border-b-2"
>
Fastify
</a>
</h1>
<nav>
<ul
style={{
display: "flex",
listStyle: "none",
gap: "1rem",
padding: 0,
justifyContent: "center",
alignItems: "center",
}}
>
<li>
<NavLink
style={({ isActive }) => {
return {
color: isActive ? "red" : "blue",
textDecoration: isActive ? "underline" : "none",
};
}}
to="/"
>
Home
</NavLink>
</li>
<li>
<NavLink
style={({ isActive }) => {
return {
color: isActive ? "red" : "blue",
textDecoration: isActive ? "underline" : "none",
};
}}
to="/page-2"
>
Page 2
</NavLink>
</li>
<li>
<NavLink
style={({ isActive }) => {
return {
color: isActive ? "red" : "blue",
textDecoration: isActive ? "underline" : "none",
};
}}
to="/fetcher"
>
Fetcher
</NavLink>
</li>
<ul className="flex gap-4 justify-center items-center py-2">
{LINKS.map((link) => (
<li key={link.to}>
<NavLink
to={link.to}
reloadDocument={'reloadDocument' in link ? link.reloadDocument : false}
className={({ isActive }) => {
return isActive
? "text-red-500 underline underline-offset-2"
: "text-blue-500";
}}
>
{link.label}
</NavLink>
</li>
))}
</ul>
</nav>
</header>
<Outlet />


<div className="mx-auto max-w-max text-center space-y-4 mt-4">
<Outlet />
</div>
</div>
);
}
9 changes: 9 additions & 0 deletions examples/playground/app/sleep.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
export function sleep<T>(ms: number, value: T) {
return new Promise<T>((resolve) => setTimeout(() => resolve(value), ms));
}

export async function withDelay<T>(
delay: number,
promise: T| Promise<T>,
): Promise<T> {
// Ensure we throw if this throws
const ret = await promise;
return sleep(delay, ret);
}
Loading