Skip to content

Commit

Permalink
feat(store): adds store feature for complex data management
Browse files Browse the repository at this point in the history
  • Loading branch information
smalluban committed Apr 10, 2020
1 parent 8b81bc5 commit 7ac55f6
Show file tree
Hide file tree
Showing 13 changed files with 1,930 additions and 22 deletions.
64 changes: 48 additions & 16 deletions src/cache.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { stringifyElement } from "./utils.js";
import * as emitter from "./emitter.js";

const entries = new WeakMap();
Expand Down Expand Up @@ -28,6 +27,17 @@ export function getEntry(target, key) {
return entry;
}

export function getEntries(target) {
const result = [];
const targetMap = entries.get(target);
if (targetMap) {
targetMap.forEach(entry => {
result.push(entry);
});
}
return result;
}

function calculateChecksum(entry) {
let checksum = entry.state;
if (entry.deps) {
Expand All @@ -48,6 +58,7 @@ function restoreObservedDeps(entry, deps) {
if (deps) {
deps.forEach(depEntry => {
entry.deps.add(depEntry);
/* istanbul ignore if */
if (!depEntry.contexts) depEntry.contexts = new Set();
depEntry.contexts.add(entry);
restoreObservedDeps(entry, depEntry.deps);
Expand All @@ -56,15 +67,11 @@ function restoreObservedDeps(entry, deps) {
}

const contextStack = new Set();
export function get(target, key, getter) {
export function get(target, key, getter, validate) {
const entry = getEntry(target, key);

if (contextStack.size && contextStack.has(entry)) {
throw Error(
`Circular get invocation of the '${key}' property in '${stringifyElement(
target,
)}'`,
);
throw Error(`Circular get invocation is forbidden: '${key}'`);
}

contextStack.forEach(context => {
Expand All @@ -77,7 +84,11 @@ export function get(target, key, getter) {
}
});

if (entry.checksum && entry.checksum === calculateChecksum(entry)) {
if (
((validate && validate(entry.value)) || !validate) &&
entry.checksum &&
entry.checksum === calculateChecksum(entry)
) {
return entry.value;
}

Expand All @@ -86,6 +97,7 @@ export function get(target, key, getter) {

if (entry.observed && entry.deps && entry.deps.size) {
entry.deps.forEach(depEntry => {
/* istanbul ignore else */
if (depEntry.contexts) depEntry.contexts.delete(entry);
});
}
Expand Down Expand Up @@ -126,7 +138,7 @@ export function get(target, key, getter) {
export function set(target, key, setter, value, force) {
if (contextStack.size && !force) {
throw Error(
`Try to set '${key}' of '${stringifyElement(target)}' in get call`,
`Setting property in chain of get calls is forbidden: '${key}'`,
);
}

Expand All @@ -142,22 +154,40 @@ export function set(target, key, setter, value, force) {
}
}

function invalidateEntry(entry, clearValue) {
entry.checksum = 0;
entry.state += 1;

dispatchDeep(entry);

if (clearValue) {
entry.value = undefined;
}
}

export function invalidate(target, key, clearValue) {
if (contextStack.size) {
throw Error(
`Try to invalidate '${key}' in '${stringifyElement(target)}' get call`,
`Invalidating property in chain of get calls is forbidden: '${key}'`,
);
}

const entry = getEntry(target, key);
invalidateEntry(entry, clearValue);
}

entry.checksum = 0;
entry.state += 1;

dispatchDeep(entry);
export function invalidateAll(target, clearValue) {
if (contextStack.size) {
throw Error(
"Invalidating all properties in chain of get calls is forbidden",
);
}

if (clearValue) {
entry.value = undefined;
const targetMap = entries.get(target);
if (targetMap) {
targetMap.forEach(entry => {
invalidateEntry(entry, clearValue);
});
}
}

Expand All @@ -176,6 +206,7 @@ export function observe(target, key, getter, fn) {

if (entry.deps) {
entry.deps.forEach(depEntry => {
/* istanbul ignore else */
if (!depEntry.contexts) depEntry.contexts = new Set();
depEntry.contexts.add(entry);
});
Expand All @@ -186,6 +217,7 @@ export function observe(target, key, getter, fn) {
entry.observed = false;
if (entry.deps && entry.deps.size) {
entry.deps.forEach(depEntry => {
/* istanbul ignore else */
if (depEntry.contexts) depEntry.contexts.delete(entry);
});
}
Expand Down
7 changes: 5 additions & 2 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import * as store from "./store/index.js";

export { default as define } from "./define.js";
export { default as property } from "./property.js";
export { default as parent } from "./parent.js";
export { default as children } from "./children.js";
export { default as render } from "./render.js";

export { dispatch } from "./utils.js";

export { html, svg } from "./template/index.js";
export { store };

export { dispatch } from "./utils.js";

0 comments on commit 7ac55f6

Please sign in to comment.