Skip to content

Instantly share code, notes, and snippets.

View fostyfost's full-sized avatar
🤪
All you need is Half-Life 3

Fosty Fost fostyfost

🤪
All you need is Half-Life 3
View GitHub Profile
@fostyfost
fostyfost / action-creator.ts
Last active July 8, 2021 20:08
Redux Action Helper
import type { ActionsUnion } from '@/store/action-helper'
import { createAction } from '@/store/action-helper'
export enum StoreActionType {
HYDRATE = '@@store/HYDRATE',
}
export const StoreAction = {
hydrate(payload: Record<string, unknown>) {
return createAction(StoreActionType.HYDRATE, payload)
type KnownKeys<T> = {
[K in keyof T]: string extends K ? never : number extends K ? never : K
} extends { [_ in keyof T]: infer U } ? U : never;
import type { CountedItem} from './counter';
import { getCounter } from './counter'
describe('Counter tests', () => {
it('should work with functions', () => {
const noop1 = () => null
const noop2 = () => null
const counter = getCounter()
@fostyfost
fostyfost / use-isomorphic-layout-effect.ts
Created August 16, 2021 08:12
React isomorphic `useLayoutEffect` hook with `react-hooks` linter support
import { useEffect, useLayoutEffect } from 'react'
// React currently throws a warning when using useLayoutEffect on the server.
// To get around it, we can conditionally useEffect on the server (no-op) and
// useLayoutEffect in the browser. We need useLayoutEffect to ensure the store
// subscription callback always has the selector from the latest render commit
// available, otherwise a store update may happen between render and the effect,
// which may cause missed updates; we also must ensure the store subscription
// is created synchronously, otherwise a store update may occur before the
// subscription is created and an inconsistent state may be observed
@fostyfost
fostyfost / helper.d.ts
Last active September 1, 2021 21:56
Next.js: `InferGetStaticParams` and `InferGetServerSideParams`
export type InferGetStaticPropsQueryType<Fn> = Fn extends GetStaticProps<any, infer Query>
? Query
: Fn extends (
context?: GetStaticPropsContext<infer Query>,
) => Promise<GetStaticPropsResult<any>> | GetStaticPropsResult<any>
? Query
: never
export type InferGetServerSidePropsQueryType<Fn> = Fn extends GetServerSideProps<any, infer Query>
? Query
@fostyfost
fostyfost / censor.ts
Created September 20, 2021 11:11
Converting circular structure to JSON
function censor(censor: any) {
let i = 0
return function(_: any, value: unknown) {
if (i !== 0 && typeof censor === 'object' && typeof value === 'object' && censor === value) {
return '[Circular]'
}
// seems to be a harded maximum of 11 serialized objects?
if (i >= 10) {
@fostyfost
fostyfost / dependabot.yml
Created September 24, 2021 07:45
Dependabot
version: 2
updates:
- package-ecosystem: npm
directory: '/'
schedule:
interval: weekly
time: '12:00'
open-pull-requests-limit: 100
@fostyfost
fostyfost / index.ts
Created October 4, 2021 16:07
Isomorphic Base64
export const toBase64 = (str: string): string => {
return typeof window === 'undefined' ? Buffer.from(str).toString('base64') : btoa(str)
}
export const fromBase64 = (str: string): string => {
return typeof window === 'undefined' ? Buffer.from(str, 'base64').toString() : atob(str)
}
@fostyfost
fostyfost / get-chunks.ts
Created October 8, 2021 09:04
Split Array Into Chunks
export const getChunks = <T = unknown>(arr: T[], length: number = 1): T[][] => {
const chunks = []
for (let index = 0; index < arr.length; index += length) {
chunks.push(arr.slice(index, index + length))
}
return chunks
}
@fostyfost
fostyfost / is-absolute-url.ts
Created November 4, 2021 10:37
Absolute URL check
// Universal, non case-sensitive, protocol-agnostic approach:
const reg = new RegExp('^(?:[a-z]+:)?//', 'i')
export const isAbsoluteUrl = (value: string): boolean => reg.test(value)