UNPKG

@cbpds/web-components

Version:
206 lines (198 loc) 6.25 kB
/*! * CPB Design System web components - built with Stencil */ 'use strict'; const index = require('./index-cd71cbd5.js'); 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 debounce = (fn, ms) => { let timeoutId; return (...args) => { if (timeoutId) { clearTimeout(timeoutId); } timeoutId = setTimeout(() => { timeoutId = 0; fn(...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((map) => { for (let key of map.keys()) { map.set(key, map.get(key).filter(isConnected)); } }, 2_000); const stencilSubscription = () => { if (typeof index.getRenderingRef !== 'function') { // If we are not in a stencil project, we do nothing. // This function is not really exported by @stencil/core. return {}; } const elmsToUpdate = new Map(); return { dispose: () => elmsToUpdate.clear(), get: (propName) => { const elm = index.getRenderingRef(); if (elm) { appendToMap(elmsToUpdate, propName, elm); } }, set: (propName) => { const elements = elmsToUpdate.get(propName); if (elements) { elmsToUpdate.set(propName, elements.filter(index.forceUpdate)); } cleanupElements(elmsToUpdate); }, reset: () => { elmsToUpdate.forEach((elms) => elms.forEach(index.forceUpdate)); cleanupElements(elmsToUpdate); }, }; }; const unwrap = (val) => (typeof val === 'function' ? val() : val); const createObservableMap = (defaultState, shouldUpdate = (a, b) => a !== b) => { const unwrappedState = unwrap(defaultState); let states = new Map(Object.entries(unwrappedState ?? {})); const handlers = { dispose: [], get: [], set: [], reset: [], }; const reset = () => { // When resetting the state, the default state may be a function - unwrap it to invoke it. // otherwise, the state won't be properly reset states = new Map(Object.entries(unwrap(defaultState) ?? {})); handlers.reset.forEach((cb) => cb()); }; const dispose = () => { // Call first dispose as resetting the state would // cause less updates ;) handlers.dispose.forEach((cb) => cb()); reset(); }; const get = (propName) => { handlers.get.forEach((cb) => cb(propName)); return states.get(propName); }; const set = (propName, value) => { const oldValue = states.get(propName); if (shouldUpdate(value, oldValue, propName)) { states.set(propName, value); handlers.set.forEach((cb) => cb(propName, value, oldValue)); } }; const state = (typeof Proxy === 'undefined' ? {} : new Proxy(unwrappedState, { get(_, propName) { return get(propName); }, ownKeys(_) { return Array.from(states.keys()); }, getOwnPropertyDescriptor() { return { enumerable: true, configurable: true, }; }, has(_, propName) { return states.has(propName); }, set(_, propName, value) { set(propName, value); return true; }, })); const on = (eventName, callback) => { handlers[eventName].push(callback); return () => { removeFromArray(handlers[eventName], callback); }; }; const onChange = (propName, cb) => { const unSet = on('set', (key, newValue) => { if (key === propName) { cb(newValue); } }); // We need to unwrap the defaultState because it might be a function. // Otherwise we might not be sending the right reset value. const unReset = on('reset', () => cb(unwrap(defaultState)[propName])); return () => { unSet(); unReset(); }; }; const use = (...subscriptions) => { const unsubs = subscriptions.reduce((unsubs, subscription) => { if (subscription.set) { unsubs.push(on('set', subscription.set)); } if (subscription.get) { unsubs.push(on('get', subscription.get)); } if (subscription.reset) { unsubs.push(on('reset', subscription.reset)); } if (subscription.dispose) { unsubs.push(on('dispose', subscription.dispose)); } return unsubs; }, []); return () => unsubs.forEach((unsub) => unsub()); }; const forceUpdate = (key) => { const oldValue = states.get(key); handlers.set.forEach((cb) => cb(key, oldValue, oldValue)); }; return { state, get, set, on, onChange, use, dispose, reset, forceUpdate, }; }; const removeFromArray = (array, item) => { const index = array.indexOf(item); if (index >= 0) { array[index] = array[array.length - 1]; array.length--; } }; const createStore = (defaultState, shouldUpdate) => { const map = createObservableMap(defaultState, shouldUpdate); map.use(stencilSubscription()); return map; }; const { state } = createStore({ currentPage: undefined, currentParent: undefined, activeItemName: undefined, }); exports.state = state; //# sourceMappingURL=store-f67f3d11.js.map