Skip to content

Commit

Permalink
Update to latest version of dom expressions
Browse files Browse the repository at this point in the history
  • Loading branch information
ryansolid committed May 25, 2019
1 parent 3c7a832 commit 27cf8cf
Show file tree
Hide file tree
Showing 9 changed files with 243 additions and 123 deletions.
12 changes: 6 additions & 6 deletions dom-expressions.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ module.exports = {
includeTypes: true,
variables: {
imports: [
`import { untracked } from 'mobx'`,
`import { root as mRoot, cleanup as mCleanup, computed as mComputed } from './core'`
`import { untracked as sample } from 'mobx'`,
`import {
root, cleanup, computed as wrap, setContext,
registerSuspense, getContextOwner as currentContext
} from './core'`
],
computed: 'mComputed',
sample: 'untracked',
root: 'mRoot',
cleanup: 'mCleanup'
includeContext: true
}
}
101 changes: 61 additions & 40 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 8 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "mobx-jsx",
"description": "Raw MobX performance without the restraints of a Virtual DOM",
"version": "0.4.2",
"version": "0.5.0",
"author": "Ryan Carniato",
"license": "MIT",
"repository": {
Expand All @@ -16,16 +16,16 @@
"prepublishOnly": "npm run build"
},
"devDependencies": {
"@babel/core": "7.4.3",
"@babel/core": "7.4.5",
"@babel/preset-typescript": "7.3.3",
"dom-expressions": "0.8.4",
"hyper-dom-expressions": "~0.8.0",
"lit-dom-expressions": "~0.8.0",
"dom-expressions": "0.9.0",
"hyper-dom-expressions": "0.9.0",
"lit-dom-expressions": "0.9.0",
"mobx": "^5.9.0",
"rollup": "^1.11.3",
"rollup": "^1.12.3",
"rollup-plugin-babel": "4.3.2",
"rollup-plugin-node-resolve": "4.2.3",
"typescript": "3.4.4"
"rollup-plugin-node-resolve": "5.0.0",
"typescript": "3.4.5"
},
"peerDependencies": {
"mobx": "*"
Expand Down
112 changes: 97 additions & 15 deletions src/core.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,26 @@
import { autorun, untracked } from 'mobx'
import { autorun, untracked, observable, IObservableValue } from 'mobx'

type Context = { disposables: any[] };
let globalContext: Context;
type ContextOwner = { disposables: any[], owner: ContextOwner | null, context?: any };
interface Context { id: symbol, initFn: Function };

let globalContext: ContextOwner | null = null;

export function getContextOwner() { return globalContext; }

export function root<T>(fn: (dispose: () => void) => T) {
let context, d: any[], ret: T;
context = globalContext;
let d: any[], ret: T;
globalContext = {
disposables: d = []
disposables: d = [],
owner: globalContext
};
ret = untracked(() =>
fn(() => {
let disposable, k, len: number;
for (k = 0, len = d.length; k < len; k++) {
disposable = d[k];
disposable();
}
let k, len: number;
for (k = 0, len = d.length; k < len; k++) d[k]();
d = [];
})
);
globalContext = context;
globalContext = globalContext.owner;
return ret;
};

Expand All @@ -29,7 +30,88 @@ export function cleanup(fn: () => void) {
}

export function computed<T>(fn: (prev?: T) => T) {
let current: T,
dispose = autorun(() => current = fn(current));
cleanup(dispose);
let current: T, d: any[];
const context = {
disposables: d = [],
owner: globalContext
},
dispose = autorun(() => {
for (let k = 0, len = d.length; k < len; k++) d[k]();
d = [];
globalContext = context;
current = fn(current)
globalContext = globalContext.owner;
});
cleanup(() => {
for (let k = 0, len = d.length; k < len; k++) d[k]();
dispose();
});
}

function lookup(owner: ContextOwner, key: symbol | string): any {
return (owner && owner.context && owner.context[key]) || (owner.owner && lookup(owner.owner, key));
}

export function setContext(key: symbol | string, value: any) {
if (globalContext === null) return console.warn("Context keys cannot be set without a root or parent");
const context = globalContext.context || (globalContext.context = {});
context[key] = value;
}

export function createContext(initFn: any) {
const id = Symbol('context');
return { id, initFn };
}

export function useContext(context: Context) {
if (globalContext === null) return console.warn("Context keys cannot be looked up without a root or parent");
return lookup(globalContext, context.id);
}

// Suspense Context
export const SuspenseContext = createContext(() => {
let counter = 0;
const obsv = observable.box(0),
store = {
increment: () => ++counter === 1 && !store.initializing && obsv.set(counter),
decrement: () => --counter === 0 && obsv.set(counter),
suspended: () => {
obsv.get();
return !!counter;
},
initializing: true
}
return store;
});

// used in the runtime to seed the Suspend control flow
export function registerSuspense(fn: (o: { suspended: () => any, initializing: boolean }) => void) {
computed(() => {
const c = SuspenseContext.initFn();
setContext(SuspenseContext.id, c);
fn(c);
c.initializing = false;
});
};

// lazy load a function component asyncronously
export function lazy<T extends Function>(fn: () => Promise<{default: T}>) {
return (props: object) => {
const getComp = loadResource(fn().then(mod => mod.default))
let Comp: T | undefined;
return () => (Comp = getComp()) && untracked(() => (Comp as T)(props));
}
}

// load any async resource and return an accessor
export function loadResource<T>(p: Promise<T>) {
const { increment, decrement } = useContext(SuspenseContext) || { increment: undefined, decrement: undefined};
const results = observable.box<T | undefined>(),
error = observable.box<any>();
increment && increment();
p.then(data => results.set(data))
.catch(err => error.set(err))
.finally(() => decrement && decrement());
(results as (any & { error: () => any})).error = error;
return results.get.bind(results);
}
2 changes: 1 addition & 1 deletion src/h.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
import { createHyperScript } from 'hyper-dom-expressions';
import * as r from './index';

export { root, cleanup, selectWhen, selectEach } from './index';
export * from './index';
export const h = createHyperScript(r);
2 changes: 1 addition & 1 deletion src/html.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
import { createHTML } from 'lit-dom-expressions';
import * as r from './index';

export { root, cleanup, selectWhen, selectEach } from './index';
export * from './index';
export const html = createHTML(r);
Loading

0 comments on commit 27cf8cf

Please sign in to comment.