Skip to content

Instantly share code, notes, and snippets.

@gordonbrander
gordonbrander / viewstore.swift
Last active May 17, 2021 20:48
SwiftUI immutable ViewStore
/// ViewStore acts as a state container, typically for some view over the application's central store.
/// You construct a ViewStore and pass it to a subview. Because it is Equatable, you can
/// make the subview Equatable as well, with `.equatable()`. The subview will then only render
/// when the actual value of the state changes.
struct ViewStore<LocalState, LocalAction>: Equatable
where LocalState: Equatable {
static func == (
lhs: ViewStore<LocalState, LocalAction>,
rhs: ViewStore<LocalState, LocalAction>
) -> Bool {
@gordonbrander
gordonbrander / UnwrapOptional.swift
Created June 15, 2021 13:51
UnwrapOptional.swift
import Foundation
extension Optional {
struct NilError: Error {
let file: String
let line: Int
let column: Int
let function: String
}
import Foundation
import Combine
/// Holds cancellables returned by Publisher until the publisher completes.
///
/// Combine Publishers return a Cancellable that will automatically cancel the Publisher if the
/// Cancellable falls out of scope. Since Publishers can take some time to complete, you often
/// want to hold on to the Cancellable reference until the publisher has completed.
///
/// PublisherManager takes care of the boilerplate of holding on to Cancellables, and helps
@gordonbrander
gordonbrander / Store.swift
Last active February 17, 2022 01:55
Store.swift - a simple Elm-like ObservableObject store for SwiftUI
//
// Store.swift
//
// Created by Gordon Brander on 9/15/21.
//
// MIT LICENSE
// Copyright 2021 Gordon Brander
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
@gordonbrander
gordonbrander / route.js
Last active April 30, 2022 01:26
route.js: a history.pushState microrouter without the routing fluff.
// Microrouter based on history.pushState.
// All thrills, no frills.
// Usage:
//
// var h = urlstate(callback);
// h.push('#foo')
function urlstate(callback) {
// Since `history.pushState` doesn't fire `popstate`, we can use this function
// instead. Will update history state and call `callback` with currently
// showing `url`.
@gordonbrander
gordonbrander / yayquery.js
Created September 2, 2015 21:09
yayquery.js - All you really need
export const $$ = (selector) => document.querySelector(selector);
export const $ = (selector) => document.querySelectorAll(selector);
// Apply a side effect to `n` items.
export const sets = (f, n, ...rest) => {
for (var i = 0; i < n.length; i++) f(n[i], ...rest);
}
export const toggleClass = (el, classname, isAdding) =>
isAdding ? el.classList.add(classname) : el.classList.remove(classname);
@gordonbrander
gordonbrander / framescheduler.js
Created October 20, 2020 17:34
FrameScheduler - a frame scheduler that will call callback at most once per frame.
// Creates a frame scheduler that will call callback at most once per frame.
export const FrameScheduler = callback => {
let isScheduled = false
const draw = t => {
isScheduled = false
callback(t)
}
const schedule = () => {
@gordonbrander
gordonbrander / decorateCtor.js
Created January 29, 2012 21:41
jQuery-style Instantiation: Decorate a Constructor Function to Enforce `new` and `return this`
// Takes a function and wraps it, making sure:
//
// * It enforces `new`
// * It returns `this`
//
// Doing this enables a jQuery coding style for object creation,
// where constructor functions become chain-able immediately after
// construction, and don't have to be called with `new`. For example:
//
// var F = decorateCtor(function (a, b, c) { ... });
@gordonbrander
gordonbrander / foldable.js
Last active November 6, 2022 07:34
Foldable -- fold elements based on search strings in hash
// Foldable.js
// =============================================================================
//
// Fold DOM elements based on whether they match a query string.
//
// How:
//
// var foldableParagraphs = document.querySelectorAll('p.foldable');
// foldable(foldableParagraphs)
//
@gordonbrander
gordonbrander / dispatcher.js
Created March 23, 2013 00:06
JavaScript multiple dispatch using predicate functions
var nil = 'indicating a nil value';
function reducePredicatePair(reduction, pair) {
// If no reduction has yet been found and the predicate
// matches, run the assocated function.
if(reduction[0] === nil && pair[0].apply(null, reduction[1])) {
reduction[0] = pair[1].apply(null, reduction[1]);
}
return reduction;
}