Skip to content

Commit

Permalink
feat(👻): extract cache behavior with haunted-polymer hook (#120)
Browse files Browse the repository at this point in the history
* feat(👻): wip: extract behavior hooks with haunted-polymer

Start with a small hook to extract as much of the caching as
possible.
Also fixes a test suite setup.

WIP to move to haunted-polymer from cosmoz-utils if merged.

Signed-off-by: Patrik Kullman <[email protected]>

* fix: use haunted-polymer from cosmoz-utils

Signed-off-by: Patrik Kullman <[email protected]>

* fix: cache -> use-cache name (PR review)

Signed-off-by: Patrik Kullman <[email protected]>
  • Loading branch information
Patrik Kullman authored Jun 18, 2020
1 parent 68ec600 commit 126aeac
Show file tree
Hide file tree
Showing 5 changed files with 2,257 additions and 6,851 deletions.
46 changes: 13 additions & 33 deletions cosmoz-data-nav.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ import '@neovici/cosmoz-bottom-bar/cosmoz-bottom-bar-view';
import { translatable } from '@neovici/cosmoz-i18next';
import '@neovici/cosmoz-page-router/cosmoz-page-location';

import { hauntedPolymer } from '@neovici/cosmoz-utils';

import { useCache } from './lib/use-cache.js';

const _async = window.requestIdleCallback || window.requestAnimationFrame || window.setTimeout,
_hasDeadline = 'IdleDeadline' in window,
_asyncPeriod = (cb, timeout = 1500) => {
Expand Down Expand Up @@ -75,7 +79,7 @@ Example:
@demo demo/index.html
@appliesMixin translatable
*/
class CosmozDataNav extends translatable(mixinBehaviors([IronResizableBehavior], PolymerElement)) {
class CosmozDataNav extends hauntedPolymer('__cache', useCache)(translatable(mixinBehaviors([IronResizableBehavior], PolymerElement))) {
static get template() { // eslint-disable-line max-lines-per-function
return html`
<style include="iron-flex iron-positioning">
Expand Down Expand Up @@ -345,10 +349,8 @@ class CosmozDataNav extends translatable(mixinBehaviors([IronResizableBehavior],
constructor() {
super();
this._previouslySelectedItem = null;
this._cache = {};
this._preloadIdx = 0;
this._boundOnTemplatesChange = this._onTemplatesChange.bind(this);
this._onCachePurgeHandler = this._onCachePurge.bind(this);
}

connectedCallback() {
Expand All @@ -357,7 +359,6 @@ class CosmozDataNav extends translatable(mixinBehaviors([IronResizableBehavior],
this.$.templatesSlot,
this._boundOnTemplatesChange
);
window.addEventListener('cosmoz-cache-purge', this._onCachePurgeHandler);
this.addEventListener('tap', this._onTap);
this.addEventListener('transitionend', this._onTransitionEnd);
}
Expand All @@ -374,9 +375,7 @@ class CosmozDataNav extends translatable(mixinBehaviors([IronResizableBehavior],
}

this._previouslySelectedItem = null;
this._cache = {};
this._indexRenderQueue = [];
window.removeEventListener('cosmoz-cache-purge', this._onCachePurgeHandler);
this.removeEventListener('tap', this._onTap);
this.removeEventListener('transitionend', this._onTransitionEnd);

Expand Down Expand Up @@ -462,7 +461,7 @@ class CosmozDataNav extends translatable(mixinBehaviors([IronResizableBehavior],
if (prop !== this.as || value === item || this._allElementInstances.indexOf(inst) < 0) {
return;
}
this.removeFromCache(item);
this.__cache.dropItem(item);
this.set(['items', index], value);
}

Expand Down Expand Up @@ -517,8 +516,8 @@ class CosmozDataNav extends translatable(mixinBehaviors([IronResizableBehavior],
console.warn('Multiple replaceable items matches idPath', this.idPath, 'with id', id, 'in the item list', items, 'to replace with item', item);
}

this._cache[id] = Object.assign({}, item);
matches.forEach(match => this.set(['items', items.indexOf(match)], Object.assign({}, item)));
this.__cache.set(id, item);
matches.forEach(match => this.set(['items', items.indexOf(match)], { ...item }));

this._preload();

Expand All @@ -529,21 +528,6 @@ class CosmozDataNav extends translatable(mixinBehaviors([IronResizableBehavior],
this._updateSelected();
}

clearCache() {
this._cache = {};
}

removeFromCache(item) {
if (item == null) {
return;
}
const cache = this._cache,
key = Object.keys(cache).find(k => cache[k] === item);
if (key != null) {
delete cache[key];
}
}

/**
* Observes full changes to `items` properties
* and replaces cached items with full data if available.
Expand All @@ -561,8 +545,11 @@ class CosmozDataNav extends translatable(mixinBehaviors([IronResizableBehavior],
// replace incomplete items with cached item data
if (length) {
items.forEach((item, index) => {
if (this.isIncompleteFn(item) && this._cache[item]) {
this.set(['items', index], this._cache[item]);
if (this.isIncompleteFn(item)) {
const cachedItem = this.__cache?.get(item);
if (cachedItem) {
this.set(['items', index], cachedItem);
}
}
});
}
Expand Down Expand Up @@ -1099,13 +1086,6 @@ class CosmozDataNav extends translatable(mixinBehaviors([IronResizableBehavior],
}
}

_onCachePurge(e) {
if (e == null || e.detail == null || !Array.isArray(e.detail.ids) || e.detail.ids.length === 0) {
return this.clearCache();
}
e.detail.ids.forEach(id => delete this._cache[id]);
}

_getItemId(item) {
return this.isIncompleteFn(item) ? item : this.get(this.idPath, item);
}
Expand Down
43 changes: 43 additions & 0 deletions lib/use-cache.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { useEffect } from 'haunted';

let storage = {};

const clear = () => {
storage = {};
},
cachePurgeHandler = event => {
if (Array.isArray(event?.detail?.ids) && event.detail.ids.length > 0) {
event.detail.ids.forEach(id => delete storage[id]);
return;
}
clear();
};

export const useCache = () => {

useEffect(() => {
window.addEventListener('cosmoz-cache-purge', cachePurgeHandler);
return () => {
clear();
window.removeEventListener('cosmoz-cache-purge', cachePurgeHandler);
};
}, []);

return {
clear,
drop(key) {
delete storage[key];
},
dropItem(item) {
Object.entries(storage)
.filter(([, value]) => value === item)
.forEach(([key]) => delete storage[key]);
},
get(key) {
return storage[key];
},
set(key, item) {
storage[key] = item;
}
};
};
Loading

0 comments on commit 126aeac

Please sign in to comment.