Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
smalluban committed May 29, 2019
1 parent cf8e409 commit 14e4e20
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 5 deletions.
4 changes: 2 additions & 2 deletions src/cache.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,8 @@ export function get(target, key, getter) {
return entry.value;
}

export function set(target, key, setter, value) {
if (context) {
export function set(target, key, setter, value, force) {
if (context && !force) {
context = null;
throw Error(`Try to set '${key}' of '${stringifyElement(target)}' in get call`);
}
Expand Down
52 changes: 52 additions & 0 deletions src/store.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import * as cache from './cache';

const metaMap = new WeakMap();
const _ = (h, v) => v;

function getMeta(Model) {
let meta = metaMap.get(Model);
if (!meta) {
meta = {
get: new Set(),
set: new Set(),
};
metaMap.set(Model, meta);
}
return meta;
}

export function observe(Model, callbacks = {}) {
const meta = getMeta(Model);

if (callbacks.get) {
meta.get.add((id) => {
const result = callbacks.get(id);
if (result !== undefined) {
cache.set(Model, id, _, result, true);
}
});
}

if (callbacks.set) meta.set.add(callbacks.set);

return () => {
meta.get.delete(callbacks.get);
meta.set.delete(callbacks.set);
};
}

export function isReady() {
return true;
}

export function get(Model, id) {
const model = cache.get(Model, id, _);

if (model === undefined) {
const meta = getMeta(Model);
meta.get.forEach(cb => cb(id));
return cache.get(Model, id, _);
}

return model;
}
5 changes: 2 additions & 3 deletions src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,8 @@ export function shadyCSS(fn, fallback) {
return fallback;
}

export function stringifyElement(element) {
const tagName = String(element.tagName).toLowerCase();
return `<${tagName}>`;
export function stringifyElement(target) {
return target.tagName ? `<${String(target.tagName).toLowerCase()}>` : target;
}

export const IS_IE = 'ActiveXObject' in window;
Expand Down
34 changes: 34 additions & 0 deletions test/spec/store.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { test, resolveRaf } from '../helpers';
import { define, html } from '../../src';

import * as store from '../../src/store';

fdescribe('store:', () => {
describe('one type with synchronous storage', () => {
const Profile = {
firstName: '',
lastName: '',
};

store.observe(Profile, {
get: () => ({ firstName: 'John', lastName: 'Smith' }),
});

define('test-store', {
id: '1',
profile: ({ id }) => store.get(Profile, id),
render: ({ profile }) => {
console.log('render');
return html`
${profile && html`<h1>${profile.firstName} ${profile.lastName}</h1>`}
`;
},
});

const tree = test('<test-store></test-store>');

it('renders profile data', tree(el => resolveRaf(() => {
expect(el.shadowRoot.innerHTML.trim()).toBe('<h1>John Smith</h1>');
})));
});
});

0 comments on commit 14e4e20

Please sign in to comment.