Skip to content

Instantly share code, notes, and snippets.

@gordonbrander
gordonbrander / modest-example.js
Last active March 25, 2023 19:39
Modest - a modest framework for unambitious web apps. One file. No dependencies. No build steps.
import {StoreElement, change} from './modest.js'
class ModestApp extends StoreElement {
static template() {
return `
<style>
:host {
display: block;
}
.time {
@gordonbrander
gordonbrander / freeze.js
Created March 21, 2023 19:17
freeze.js - immutable JS object helpers
// Shorthand for Object.freeze
export const freeze = Object.freeze
// Define an immutable model intializer.
// Objects are frozen on the way out.
export const Model = init => flags => freeze(init(flags))
// Put a value to a key, returning a new frozen object
export const put = (state, key, val) => freeze({...state, [key]: val})
@gordonbrander
gordonbrander / read-only-proxy.js
Created March 8, 2023 13:55
Ready-only Proxy - a read-only view over JS objects
export const isObject = thing => thing != null && typeof thing === "object"
export class ReadOnlyProxyWriteError extends Error {}
const ReadOnlyProxyDescriptor = {
get: (target, key) => {
let value = target[key]
if (!isObject(value)) {
return value
}
@gordonbrander
gordonbrander / mut.js
Last active March 6, 2023 16:13
Mut.js - efficient DOM writing via mutation and version flag
const $version = Symbol('version')
export const version = state => {
if state[$version] == null {
return 0
}
return state[$version]
}
export const markSynced = (following, leading) => {
@gordonbrander
gordonbrander / versioned-proxy.js
Created March 6, 2023 14:30
Versioned Proxy - using proxy to increment a version on object mutation
export const $version = Symbol('version')
const VersionedProxy = {
set(target, prop, value) {
target[$version] = target[$version] + 1
target[prop] = value
},
deleteProperty(target, prop) {
target[$version] = target[$version] + 1
@gordonbrander
gordonbrander / rendering-element.js
Created March 6, 2023 13:39
RenderingElement - A custom element that batches updates on animation frame
// RenderingElement
// A custom element that batches state updates on animation frame.
export class RenderingElement extends HTMLElement {
// Element state to render
#state = this.defaults();
// Has an animation frame been scheduled?
#isAnimationFrameScheduled = false
// Perform a render and flag that animationFrame has completed.
@gordonbrander
gordonbrander / DispatchQueue+future.swift
Created February 16, 2023 19:22
DispatchQueue.future
import Foundation
import Combine
extension DispatchQueue {
/// Run a closure on a dispatch queue asyncronously.
/// - Returns a future.
func future<Output>(
perform: @escaping () -> Output
) -> Future<Output, Never> {
Future<Output, Never> { promise in
@gordonbrander
gordonbrander / webvr-daydream.md
Last active January 31, 2023 22:21
How to get WebVR working with Daydream

How to get WebVR working with your brand-new Daydream View & Pixel.

  1. Update Daydream app to latest (Play Store)
  2. Update Chrome app to latest (Play Store)
    • Tip: if you're feeling brave, download Chrome Canary instead. Better perf and new features.
  3. Update Google VR Services (Play Store)
  4. Open chrome://flags/#enable-webvr
    • Click "Enable"
  5. Open chrome://flags/#enable-vr-shell
    • Set dropdown to "Enabled"
@gordonbrander
gordonbrander / tiny-state-machine.js
Created May 25, 2012 17:01
World's Tiniest JavaScript State Machine
var StateMachine = {
// Register valid states for this object.
__states__: {
'success': ['failure'],
'failure': ['success']
},
// Set initial state.
__state__: 'success',
@gordonbrander
gordonbrander / multimethod-example.js
Last active November 18, 2022 05:05
Javascript multimethods
import multimethod from './multimethod.js'
const foo = multimethod(x => typeof x)
foo.string = x => 'called string method'
foo.number = x => 'called number method'
foo('x')
// 'called string method'
foo(1)