Skip to content

Instantly share code, notes, and snippets.

View jacob-ebey's full-sized avatar

Jacob Ebey jacob-ebey

View GitHub Profile
@jacob-ebey
jacob-ebey / client-navigation.js
Created January 11, 2023 00:53
Navigation and View Transition API example
import { html } from "html-tagged";
export default function ClientNavigation() {
return html`
<script type="module">
if (typeof navigation !== "undefined") {
let lastAbortController;
navigation.addEventListener("navigate", (event) => {
if (!event.canIntercept) return;
@jacob-ebey
jacob-ebey / flat-routes-universal.ts
Last active December 21, 2022 22:14
Universal Flat Routes
/**
* Create route configs from a list of routes using the flat routes conventions.
* @param appDirectory The absolute root directory the routes were looked up from.
* @param routePaths The absolute route paths.
* @param prefix The prefix to strip off of the routes.
*/
export function flatRoutesUniversal(
appDirectory: string,
routePaths: string[],
prefix: string = "routes"
@jacob-ebey
jacob-ebey / deferred-overview.md
Last active February 28, 2025 05:42
Deferred Overview

Remix Deferred

Remix Deferred is currently implemented on top of React's Suspense model but is not limited to React. This will be a quick dive into how "promise over the wire" is accomplished.

SSR + Hydration

It isn't rocket science, but a quick recap of how frameworks such as react do SSR:

  1. Load data
  2. Render the app
@jacob-ebey
jacob-ebey / react-use.ts
Last active December 31, 2022 00:46
A very naive implementation of React's use() hook
// A very naive implementation of React's use() hook you can copy and paste into your app today
// to use with solutions such as remix's experimental `defer()` feature.
function use<T>(useable: Promise<T> | T) {
if (typeof useable != "object" || !useable || !("then" in useable)) {
return useable;
}
let promise = useable as Promise<T> & { _data?: T; _error?: unknown };
if ("_data" in promise) {
@jacob-ebey
jacob-ebey / example.test.ts
Created October 9, 2022 05:26
Run tests in a browser web-worker using puppeteer
import invariant from "tiny-invariant";
export function thisTestShouldFail() {
invariant(false, "update this test 🙂");
}
@jacob-ebey
jacob-ebey / upstash-session-storage.ts
Last active July 15, 2023 18:52
Remix Upstash Session Storage
import { type Agent } from "https";
import {
createSessionStorage,
type RequestInit,
type SessionData,
type SessionIdStorageStrategy,
} from "@remix-run/node";
export interface UpstashSessionStorageOptions {
cookie?: SessionIdStorageStrategy["cookie"];
@jacob-ebey
jacob-ebey / dashboard.pokemon.tsx
Created September 7, 2022 02:05
Remix Deferred Infinite Scrolling
import * as React from "react";
import { defer, type LoaderArgs } from "@remix-run/node";
import {
Await,
Link,
Outlet,
useLoaderData,
useLocation,
useNavigate,
useTransition,
@jacob-ebey
jacob-ebey / inline-css-middleware.js
Created July 2, 2022 06:41
Inline CSS for Remix express applications
let fs = require("fs");
// TODO: Make it configurable based on publicPath and assetsBuildDirectory
function inlineCssMiddleware() {
/**
*
* @param {import("express").Request} req
* @param {import("express").Response} res
* @param {import("express").NextFunction} next
*/
@jacob-ebey
jacob-ebey / dynamic-import-cache-bust-loader.js
Created June 5, 2022 21:10
Node.js dynamic import cache buster
import { readFile } from "fs/promises";
import { createRequire } from "module";
import * as URL from "url";
import { readConfig } from "./config.mjs";
let require = createRequire(import.meta.url);
let config = await readConfig(process.cwd(), "development");
let outputFile = URL.pathToFileURL(config.serverBuildPath);
@jacob-ebey
jacob-ebey / api.chat.ts
Created May 8, 2022 22:20
Simple Remix SSE Chat Application on new fetch polyfill
import type { LoaderFunction } from "@remix-run/node";
import type { ChatMessageEvent } from "~/events.server";
import { chatEvents } from "~/events.server";
export let loader: LoaderFunction = ({ request }) => {
if (!request.signal) {
throw new Error("No request signal provided by the platform");
}