Skip to content

Instantly share code, notes, and snippets.

Doing things

Matthew Phillips matthewp

Doing things
Block or report user

Report or block matthewp

Hide content and notifications from this user.

Learn more about blocking users

Contact Support about this user’s behavior.

Learn more about reporting abuse

Report abuse
View GitHub Profile
matthewp / lit-haunted-element.js
Last active Aug 19, 2019
Haunted State Integration
View lit-haunted-element.js
import { LitElement } from 'lit-element';
import { State } from 'haunted';
export default class LitHauntedElement extends LitElement {
constructor() {
this.hauntedState = new State(() => this.requestUpdate(), this);
View constants.js
export const HOLE = 'hole';
export const ASSIGN = 'assign';
matthewp / .gitignore
Created Jul 12, 2019
haunted example
View .gitignore
matthewp /
Last active Jul 12, 2019
Haunted 4.5.0

👻 Haunted 4.5.0 is out 🎉. This is a pretty big release as it introduces some nice new features:


the new haunted/core entry point is ideal for those who are using a templating library other than lit-html, for example lighterhtml. This has been one of the most requested features for Haunted for a long time. Although Haunted has always worked with hyperHTML, lighterhtml, and others, it always included lit-html even if it was unused.

I didn't like the idea of not including support for a templating library out-of-the-box and forcing configuration on everything, so Haunted still works the easy way with lit-html. The new haunted/core is for people who want a little more control. The haunted export is a function that wires together a render function and produces the component function, createContext, and a few other things. Here's a simple example:

import haunted, { useState } from 'haunted/core';

In the past CanJS typed objects such as CanMap, DefineMap, and DefineList would always eagerly convert objects into observables. For example when you do:

let map = new DefineMap({a: {b: 'c'}});

Then map.a is also a DefineMap, and is therefore observable.

This changes with DefineObject, DefineArray and anything else that uses their mixins, like StacheDefineElement. These objects do not convert inner values. So:

View example-minified.html
<!doctype html>
<html lang="en">
<title>Web component SSR</title>
customElements.define("shadow-root",class extends HTMLElement{connectedCallback(){let a=this.parentNode,b=a.firstElementChild;this.remove(),a.attachShadow({mode:"open"}).append(b.content.cloneNode(!0))}});
matthewp / example.html
Created Jun 12, 2019
Observed attributes dynamic
View example.html
<!doctype html>
<html lang="en">
<title>Some title</title>
<my-element id="myel"><my-element>
<script type="module">
class MyElement extends HTMLElement {
static get observedAttributes() {
let defines = this.define;
View .gitignore
matthewp /
Last active May 1, 2019
Client/server abstractions

One of the most difficult problems in web development today is the need to use the same views to render HTML on a web server and to update DOM nodes to reflect changes that occur on the client.

This desire comes down the need to server render for SEO, performance, and fallback reasons, while additionally needing complex, interactive applications.

Most frameworks today have consolidated on the idea of Isomorphic JavaScript, sometimes also called Universal JavaScript, as a solution to this problem.


I find isomorphism to be an inadequate solution to the use-case stated above. Isomorphism has the following problems:

View .gitignore
You can’t perform that action at this time.