Skip to content

Instantly share code, notes, and snippets.

Avatar

Jacob Ebey jacob-ebey

View GitHub Profile
@jacob-ebey
jacob-ebey / client-navigation.js
Created Jan 11, 2023
Navigation and View Transition API example
View client-navigation.js
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;
View flat-routes-universal.ts
/**
* 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"
View deferred-overview.md

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 Dec 31, 2022
A very naive implementation of React's use() hook
View react-use.ts
// 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 Oct 9, 2022
Run tests in a browser web-worker using puppeteer
View example.test.ts
import invariant from "tiny-invariant";
export function thisTestShouldFail() {
invariant(false, "update this test 🙂");
}
@jacob-ebey
jacob-ebey / upstash-session-storage.ts
Last active Oct 2, 2022
Remix Upstash Session Storage
View upstash-session-storage.ts
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 Sep 7, 2022
Remix Deferred Infinite Scrolling
View dashboard.pokemon.tsx
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 Jul 2, 2022
Inline CSS for Remix express applications
View inline-css-middleware.js
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 Jun 5, 2022
Node.js dynamic import cache buster
View dynamic-import-cache-bust-loader.js
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
Simple Remix SSE Chat Application on new fetch polyfill
View api.chat.ts
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");
}