Skip to content

Instantly share code, notes, and snippets.

Avatar

Wout Mertens wmertens

View GitHub Profile
@wmertens
wmertens / nix-store-in-git.md
Last active Jan 26, 2021
Store Nix store in git
View nix-store-in-git.md

Store Nix store in git

The Nix store is an immutable file tree store, addressed by output hashes ($outhash-$name or $out), but could also be tweaked to be addressed by the content hash of the file tree ($cas).

Git is a content-addressed immutable object store. It is optimized for storing files as blobs and directories as tree objects.

Here we consider using a git repository for deduplicating, compressing and distributing the Nix store. We want to achieve maximum deduplication so we extract small changes from files before storing, so they become more similar.

Method

@wmertens
wmertens / BoundRoute.jsx
Created Jul 28, 2019
BoundRoute treats a URL like a React bound input
View BoundRoute.jsx
// This behaves like an input field with value and onChange, except that onChange can be called on mount
// Pass defaults so it knows which value keys to encode/decode
// Steps:
// Initial mount, or location changes: start at 1
// Value changes: start at 4
// 1. parse match into parsed
// 2. parse search, merge into parsed
// 3. post-process parsed => value; onChange(value)
// 4. pre-process value => toStore
// 5. create new pathname from toStore or keep current. This can mutate toStore
@wmertens
wmertens / use-id.js
Created Jul 22, 2019
Hook for consistent auto-incrementing ids between SSR and browser. To use, wrap your app with <IdProvider> and call useId or useGetId
View use-id.js
import React, {createContext, useContext, useRef} from 'react'
import PropTypes from 'prop-types'
const Id = createContext()
const useIdGetter = (prefix = 'id') => {
const ref = useRef()
if (!ref.current) {
const me = {id: 0, get: () => `${prefix}-${me.id++}`}
ref.current = me
@wmertens
wmertens / makeSchema.js
Created Nov 14, 2018
Wrap graphql schema with enforced admin-only for mutations, timing etc
View makeSchema.js
/* eslint-disable max-depth, no-console */
// TODO create adminSchema, leave adminQueries and mutations out of schema
// In the graphqlhandler, pass the right schema depending on isAdmin
import debug from 'debug'
import {get} from 'lodash'
import {GraphQLSchema, GraphQLObjectType} from 'graphql'
import ssrCache from 'stratokit/prerender/cache'
import {adminOnly} from './utils'
import {maskErrors} from 'graphql-errors'
@wmertens
wmertens / slateToReact.js
Created Jul 6, 2018
Convert Slate JSON object to React element tree
View slateToReact.js
@@ -0,0 +1,62 @@
import React from 'react'
import RULES from './somewhere' // What you normally feed slate-html-serializer
const rules = [
...RULES,
// from slate-html-serializer
{
serialize(obj, children) {
if (obj.object === 'string') {
@wmertens
wmertens / App.jsx
Created Jan 27, 2018
Use svg symbols in React, works without changes with SSR
View App.jsx
import arrow from 'symbol-loader!arrow.svg'
const App = () => (
<SymbolProvider>
<svg><Use symbol={arrow} /></svg>
</SymbolProvider>
)
@wmertens
wmertens / graphqlExpress.js
Created Sep 7, 2017
Add dataloaders to graphql context
View graphqlExpress.js
import DataLoader from 'dataloader'
import {graphqlExpress} from 'graphql-server-express'
import schema from './schema'
import db from './database'
const contextFromReq = req => {
const {session} = req
const loaders = {}
const getLoader = (id, makeGetter) => {
View keybase.md

Keybase proof

I hereby claim:

  • I am wmertens on github.
  • I am wmertens (https://keybase.io/wmertens) on keybase.
  • I have a public key ASA6XQ6RqdgBgVFsOKWY0PV55O0x0hHULlbBfmNNhGbUXwo

To claim this, I am signing this object:

@wmertens
wmertens / router.jsx
Last active Aug 10, 2017
Wrapper for react-router v4 with an API more to my tastes
View router.jsx
import React, {Component, PropTypes} from 'react'
import {Link, Route as OrigRoute, Switch, Redirect, BrowserRouter as Router, withRouter} from 'react-router-dom'
// Subscribes a child to history updates, passing the current location as a prop
// This is needed to work around the React context API not updating all children
// See https://github.com/ReactTraining/react-router/issues/4629#issuecomment-284218493
export class LocationListener extends Component {
static contextTypes = {
history: PropTypes.object,
}
@wmertens
wmertens / New iTerm Window.scpt
Last active Feb 2, 2017
Open a new iTerm window (https://iterm2.com) in the current application folder via Applescript
View New iTerm Window.scpt
on run
-- Figure out if we want to do the cd (doIt)
-- Figure out what the path is and quote it (myPath)
set doIt to false
try
tell application "Finder" to set doIt to frontmost
set myPath to finder_path()
if myPath is equal to "" then
set doIt to false
else