Skip to content

Instantly share code, notes, and snippets.

import SwiftData
import SwiftUI
@Model final class Parent {
init() {
child = Child()
}
@Transient let uuid = UUID()
@Relationship(deleteRule: .cascade, inverse: \Child.parent) var child: Child?

Synthetic IDs and cache normalization in Apollo 3

We are using Apollo 2 in production and are very happy with it. Thanks for developing it! :) Now that Apollo 3 is out, we tried to upgrade and ran into some issues with caching.

Apollo 3 seems to believe that it is practical to manually specify merge strategies for every type and/or field (hundreds or thousands of lines of configuration) and also that this manual configuration cannot be checked at build time or start time, but instead fail eventually at runtime. To me, this sounds like an unacceptable combination. Given this, I set about writing code to inspect our schema and generate type policies. However, I ran into issues with Apollo not exposing sufficient information to build these policies.

I believe that a simple and general normalization strategy is sufficient for our use and for the vast majority of non-pathologic schemas that make the following assumptions:

  1. Most objects have ids that allow normalization
  2. Objects that do not have ids a
@domkm
domkm / machine.js
Last active April 14, 2020 16:55
Generated by XState Viz: https://xstate.js.org/viz
// Available variables:
// - Machine
// - interpret
// - assign
// - send
// - sendParent
// - spawn
// - raise
// - actions
@domkm
domkm / react_relay.clj
Created April 4, 2017 23:07
This is an incredibly hacky ClojureScript wrapper for Relay 0. While we used this in production at one point, I would recommend against doing so. I'm only uploading it for posterity. Relay 1, which decouples the React wrapper from the GraphQL client, will enable us to write a good CLJS wrapper, as opposed to this abomination.
(ns broadbrim.react-relay
(:require
[cljs.core :refer [specify! this-as js-arguments js-obj]]
[clojure.java.io :as io]
[clojure.string :as str]
[clojure.tools.macro :as macro]
[me.raynes.conch :as conch]
[potemkin]
[sablono.core :as sablono]
[taoensso.timbre :as log]))
@domkm
domkm / broadbrim.datomic.api.cljc
Created December 16, 2015 07:57
Datomic EntityMap wrapper for DataScript consistency
;;;; Entity wrapper
#?(:clj (declare ->EntityMap))
#?(:clj (deftype EntityMap [^datomic.query.EntityMap entity ^boolean ident?]
Object
(hashCode [this]
(.hashCode entity))
(equals [this o]
(and (instance? (class this) o)
(.equals entity (.entity o))))
@domkm
domkm / namespace.clj
Last active August 29, 2015 14:13
ClojureScript reads records as maps. Bug?
(ns namespace)
(defrecord Language [name])
(defmacro lang [name]
(->Language name))
(def clj
(lang "Clojure"))
### Keybase proof
I hereby claim:
* I am DomKM on github.
* I am domkm (https://keybase.io/domkm) on keybase.
* I have a public key whose fingerprint is E8A7 7F7C FC53 EE8E 59FA 5468 0A66 DE7B 9E89 228D
To claim this, I am signing this object:
@domkm
domkm / fsm.clj
Last active August 29, 2015 14:05
(require '[automat.core :as a])
(-> [1 2 (a/$ :conj) 3 4 (a/$ :conj)]
(a/compile {:reducers {:conj conj}})
(a/find nil [1 2 3 4])
:value)
;=> (4 2)
(-> [1 a/any (a/$ :conj) 3 4 (a/$ :conj)]
(a/compile {:reducers {:conj conj}})
@domkm
domkm / silk.clj
Last active August 29, 2015 14:05
(defrecord User [id])
; --------------------
; unmatch on Routes
(def routes
(silk/routes [[User ["users" (silk/integer :id)]]]))
(silk/unmatch routes User (User. 42)) ; you can use a record as a params map
@domkm
domkm / view.cljs
Created May 21, 2014 01:44
TypeError: Cannot read property 'firstChild' of undefined
(defn render-str [el]
(dom/render-to-str
(om/build
(fn [data owner]
(reify
om/IRender
(render [_] el)))
{})))
(render-str (dom/div nil))