@stencil/store
Advanced tools
Comparing version 0.1.0 to 0.2.0
@@ -5,1 +5,2 @@ export { createStore } from './store'; | ||
export { stencilSubscription } from './subscriptions/stencil'; | ||
export { ComputedReturn, ObservableMap, StoreSubscriptionObject, StoreSubscription } from './types'; |
@@ -1,4 +0,205 @@ | ||
export { createStore } from './store'; | ||
export { createObservableMap } from './observable-map'; | ||
export { computedSubscription } from './subscriptions/computed'; | ||
export { stencilSubscription } from './subscriptions/stencil'; | ||
'use strict'; | ||
Object.defineProperty(exports, '__esModule', { value: true }); | ||
var core = require('@stencil/core'); | ||
const appendToMap = (map, propName, value) => { | ||
const items = map.get(propName); | ||
if (!items) { | ||
map.set(propName, [value]); | ||
} | ||
else if (!items.includes(value)) { | ||
items.push(value); | ||
} | ||
}; | ||
const toSubscription = (subscription) => { | ||
if (typeof subscription === 'function') { | ||
return subscription; | ||
} | ||
const hasGet = 'get' in subscription; | ||
const hasSet = 'set' in subscription; | ||
const hasReset = 'reset' in subscription; | ||
return (action, propNameOrStore, newValue, oldValue) => { | ||
switch (action) { | ||
case 'get': | ||
return hasGet && subscription.get(propNameOrStore); | ||
case 'set': | ||
return hasSet && subscription.set(propNameOrStore, newValue, oldValue); | ||
case 'reset': | ||
return hasReset && subscription.reset(); | ||
} | ||
}; | ||
}; | ||
const debounce = (fn, ms) => { | ||
let timeoutId; | ||
return (...args) => { | ||
if (timeoutId) { | ||
clearTimeout(timeoutId); | ||
} | ||
timeoutId = setTimeout(() => { | ||
timeoutId = null; | ||
fn.apply(args); | ||
}, ms); | ||
}; | ||
}; | ||
/** | ||
* Check if a possible element isConnected. | ||
* The property might not be there, so we check for it. | ||
* | ||
* We want it to return true if isConnected is not a property, | ||
* otherwise we would remove these elements and would not update. | ||
* | ||
* Better leak in Edge than to be useless. | ||
*/ | ||
const isConnected = (maybeElement) => !('isConnected' in maybeElement) || maybeElement.isConnected; | ||
const cleanupElements = debounce(async (map) => { | ||
const keys = Array.from(map.keys()); | ||
for (let key of keys) { | ||
map.set(key, map.get(key).filter(isConnected)); | ||
} | ||
}, 2000); | ||
const stencilSubscription = ({ subscribe }) => { | ||
const elmsToUpdate = new Map(); | ||
if (typeof core.getRenderingRef !== 'function') { | ||
// If we are not in a stencil project, we do nothing. | ||
// This function is not really exported by @stencil/core. | ||
return; | ||
} | ||
subscribe({ | ||
get(propName) { | ||
const elm = core.getRenderingRef(); | ||
if (elm) { | ||
appendToMap(elmsToUpdate, propName, elm); | ||
} | ||
}, | ||
reset() { | ||
elmsToUpdate.forEach(elms => elms.forEach(core.forceUpdate)); | ||
}, | ||
set(propName) { | ||
const elements = elmsToUpdate.get(propName); | ||
if (elements) { | ||
elmsToUpdate.set(propName, elements.filter(core.forceUpdate)); | ||
} | ||
}, | ||
}); | ||
subscribe(() => cleanupElements(elmsToUpdate)); | ||
}; | ||
const createObservableMap = (defaultState) => { | ||
let states = new Map(Object.entries((defaultState !== null && defaultState !== void 0 ? defaultState : {}))); | ||
const subscriptions = []; | ||
const reset = () => { | ||
states = new Map(Object.entries((defaultState !== null && defaultState !== void 0 ? defaultState : {}))); | ||
subscriptions.forEach(s => s('reset')); | ||
}; | ||
const get = (propName) => { | ||
subscriptions.forEach(s => s('get', propName)); | ||
return states.get(propName); | ||
}; | ||
const set = (propName, value) => { | ||
const oldValue = states.get(propName); | ||
if (oldValue !== value || typeof value === 'object') { | ||
states.set(propName, value); | ||
subscriptions.forEach(s => s('set', propName, value, oldValue)); | ||
} | ||
}; | ||
const state = new Proxy(defaultState, { | ||
get(_, propName) { | ||
return get(propName); | ||
}, | ||
set(_, propName, value) { | ||
set(propName, value); | ||
return true; | ||
}, | ||
}); | ||
const subscribe = (subscription) => { | ||
subscriptions.push(toSubscription(subscription)); | ||
}; | ||
return { | ||
/** | ||
* Proxied object that will detect dependencies and call | ||
* the subscriptions and computed properties. | ||
* | ||
* If available, it will detect from which Stencil Component | ||
* it was called and rerender it when the property changes. | ||
*/ | ||
state, | ||
/** | ||
* Only useful if you need to support IE11. | ||
* | ||
* @example | ||
* const { state, get } = createStore({ hola: 'hello', adios: 'goodbye' }); | ||
* console.log(state.hola); // If you don't need to support IE11, use this way. | ||
* console.log(get('hola')); // If you need to support IE11, use this other way. | ||
*/ | ||
get, | ||
/** | ||
* Only useful if you need to support IE11. | ||
* | ||
* @example | ||
* const { state, get } = createStore({ hola: 'hello', adios: 'goodbye' }); | ||
* state.hola = 'ola'; // If you don't need to support IE11, use this way. | ||
* set('hola', 'ola')); // If you need to support IE11, use this other way. | ||
*/ | ||
set, | ||
/** | ||
* Register a subscription that will be called whenever the user gets, sets, or | ||
* resets a value. | ||
*/ | ||
subscribe, | ||
/** | ||
* Resets the state to its original state. | ||
*/ | ||
reset, | ||
}; | ||
}; | ||
const createStore = (defaultState) => { | ||
const map = createObservableMap(defaultState); | ||
stencilSubscription(map); | ||
return map; | ||
}; | ||
const computedSubscription = ({ get, set, subscribe, }) => { | ||
const computedStates = new Map(); | ||
subscribe({ | ||
reset() { | ||
computedStates.forEach(computeds => computeds.forEach(h => h())); | ||
}, | ||
set(propName) { | ||
const computed = computedStates.get(propName); | ||
if (computed) { | ||
computed.forEach(h => h()); | ||
} | ||
}, | ||
}); | ||
return (gen) => { | ||
const states = new Proxy({}, { | ||
get(_, propName) { | ||
appendToMap(computedStates, propName, handler); | ||
return get(propName); | ||
}, | ||
set(_, propName, value) { | ||
set(propName, value); | ||
return true; | ||
}, | ||
}); | ||
let beingCalled = false; | ||
const handler = () => { | ||
if (beingCalled) { | ||
return; | ||
} | ||
beingCalled = true; | ||
gen(states); | ||
beingCalled = false; | ||
}; | ||
handler(); | ||
}; | ||
}; | ||
exports.computedSubscription = computedSubscription; | ||
exports.createObservableMap = createObservableMap; | ||
exports.createStore = createStore; | ||
exports.stencilSubscription = stencilSubscription; |
import { StoreSubscription, StoreSubscriptionObject } from './types'; | ||
export declare const appendToMap: <K, V>(map: Map<K, V[]>, propName: K, value: V) => void; | ||
export declare const toSubscription: <T>(subscription: StoreSubscription<T> | StoreSubscriptionObject<T>) => StoreSubscription<T>; | ||
export declare const debounce: <T extends (...args: any) => any>(fn: T, ms: number) => (...args: Parameters<T>) => void; | ||
export declare const forMs: (ms: number) => Promise<void>; |
{ | ||
"name": "@stencil/store", | ||
"version": "0.1.0", | ||
"version": "0.2.0", | ||
"description": "", | ||
"module": "dist/index.js", | ||
"main": "dist/index.js", | ||
"module": "dist/index.mjs", | ||
"types": "dist/index.d.ts", | ||
"scripts": { | ||
"build": "tsc -p .", | ||
"build": "rm -rf dist && tsc -p . & npm run rollup", | ||
"lint.prettier": "node_modules/.bin/prettier --write 'src/**/*.ts'", | ||
"release": "np", | ||
"rollup": "rollup -c rollup.config.js", | ||
"test": "jest", | ||
@@ -36,2 +38,3 @@ "test.ci": "npm run test && npm run test.prettier", | ||
"prettier": "^1.19.1", | ||
"rollup": "^1.29.1", | ||
"ts-jest": "^24.2.0", | ||
@@ -38,0 +41,0 @@ "typescript": "^3.7.3" |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
17593
437
9
11