Skip to content

Instantly share code, notes, and snippets.

View AndrewIngram's full-sized avatar
🦊
Being foxy

Andy Ingram AndrewIngram

🦊
Being foxy
View GitHub Profile
View gist:2e5d530eb91b96c6a1b009b21c59db52
import { useRef, useCallback, useInsertionEffect } from "react";
// Approximation of React's upcoming useEffectEvent hook
// This gives us a non-reactive effect event callback, it will always use the latest version of
// the callback, rather than the one that was closed over.
export default function useEffectEventShim<T extends (...args: any[]) => any>(
fn: T
): (...funcArgs: Parameters<T>) => ReturnType<T> {
const ref = useRef(fn);
@AndrewIngram
AndrewIngram / 01_Readme.md
Last active March 6, 2023 02:06
Sketch of migrating eager to lazy popovers with RSC + Server Actions
View 01_Readme.md

A simple sketch of how we migrate a "card" component to lazy-load its popover content by server actions. The after (lazy) version is visibly more complex, but the steps involved are fairly straightforward -- and if it were a common pattern, there are steps that could be taken to abstract it into something simpler.

Important to note that if it's determined that server actions can only be defined in server components, the solution would be a little different.

@AndrewIngram
AndrewIngram / R2_storage.ts
Last active August 20, 2023 22:39
Read/write from Cloudflare R2 in a Vercel edge function w/default
View R2_storage.ts
import { AwsClient } from "aws4fetch";
import { deflate } from "pako";
const R2_ACCOUNT_ID = "SOMETHING"
const R2_ACCESS_KEY_ID = "SOMETHING"
const R2_SECRET_ACCESS_KEY ="SOMETHING"
const R2_BUCKET = "SOMETHING"
const R2_URL = `https://${R2_BUCKET}.${R2_ACCOUNT_ID}.r2.cloudflarestorage.com`;
@AndrewIngram
AndrewIngram / route.ts
Last active February 17, 2023 02:14
Next.js SItemap route with streaming (requires Node 18+)
View route.ts
import { SitemapStream, EnumChangefreq } from "sitemap";
import { getAllPosts } from "~/data";
import { Readable } from "node:stream";
async function* getSitemapUrls(request: Request) {
const url = new URL(request.url);
const origin = `${url.protocol}//${url.host}`;
@AndrewIngram
AndrewIngram / route.ts
Last active February 16, 2023 22:45
Next.js Sitemap route handler
View route.ts
import { SitemapStream, EnumChangefreq, streamToPromise } from "sitemap";
import { getAllPosts } from "~/data";
import { Readable } from "stream";
async function* getSitemapUrls(request: Request) {
const url = new URL(request.url);
const origin = `${url.protocol}//${url.host}`;
@AndrewIngram
AndrewIngram / Await.tsx
Created February 7, 2023 18:08
Remix-inspired "Await" component for RSC / Next 13
View Await.tsx
import { use } from "react";
type Props<T> = {
resolve: Promise<T>;
children: (value: T) => React.ReactElement;
};
export default function Await<T>({ resolve, children }: Props<T>) {
const value = use(resolve);
@AndrewIngram
AndrewIngram / 01_readme.md
Last active January 20, 2023 21:49
MASSIVE HACK ALERT: Using headers() and cache() in Next 13.1 API routes
View 01_readme.md

Warning, this is a bad idea. It'll eventually break and use undocumented framework internals

Using headers() and cache() in Next 13.1 API routes

Note: API routes are still only supported in the pages folder, not app.

I was playing around with using API routes with the experimental app dir stuff in Next 13, and I was frustrated at having to use completely different code paths for accessing the request headers and cookies compared to in server components. So I hacked together a workaround which you definitely shouldn't use.

Usage requires two steps, one is easy, the other is invasive:

@AndrewIngram
AndrewIngram / letting_agent.py
Last active January 24, 2023 14:41
Django Queryset capabilites example
View letting_agent.py
"""
This snippet will return all the letting agents, bucketed into discrete bands based on distance from
an origin point (for example, the user's current location), then sorted alphabetically within each
band. The goal being to prioritise agents in close proximity, but not excessively so -- all agents
within the same band should be given equal distance-related priority.
If there's a search term, we then boost the distance score based on the name's similiarity to the
search query.
"""
qs = LettingAgentLocation.objects.select_related("agent").filter(postcode__isnull=False)
@AndrewIngram
AndrewIngram / utils.ts
Created October 27, 2022 18:25
Fix object returned from GraphQL-js to work without intermediate serialization
View utils.ts
import { mergeWith } from "lodash";
export function nullPrototypeFix(object: Object): Object {
return mergeWith({}, object, (a: any, b: any) => {
if (b === null || typeof b === "undefined") {
return b;
} else if (typeof b.toJSON == "function") {
return b.toJSON();
}
});
@AndrewIngram
AndrewIngram / toggle.jsx
Last active November 16, 2022 15:24
Naive sketch of mutation API
View toggle.jsx
function getIsLiked(viewerId, entityId) {
// hit a database or something
}
function toggleLikeStatus(viewerId, entityId) {
// hit a database or something
return !currentStatus;
}