Skip to content

Instantly share code, notes, and snippets.

@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 / 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

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
import SwiftData
import SwiftUI
@Model final class Parent {
init() {
child = Child()
}
@Transient let uuid = UUID()
@Relationship(deleteRule: .cascade, inverse: \Child.parent) var child: Child?