UNPKG

@dnb/eufemia

Version:

DNB Eufemia Design System UI Library

277 lines (276 loc) 8.63 kB
"use strict"; "use client"; Object.defineProperty(exports, "__esModule", { value: true }); exports.createReferenceKey = createReferenceKey; exports.createSharedState = createSharedState; exports.preSeedSharedState = preSeedSharedState; exports.shallowEqual = shallowEqual; exports.useSharedState = useSharedState; exports.useWeakSharedState = useWeakSharedState; var _push = _interopRequireDefault(require("core-js-pure/stable/instance/push.js")); var _hasOwn = _interopRequireDefault(require("core-js-pure/stable/object/has-own.js")); var _react = require("react"); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } function useWeakSharedState(id, initialData = undefined, onChange = null) { return useSharedState(id, initialData, onChange, { weak: true }); } function useSharedState(id, initialData = undefined, onChange = null, { weak = false } = {}) { const instanceRef = (0, _react.useRef)({}); const sharedState = (0, _react.useMemo)(() => { if (id) { return createSharedState(id, initialData); } return undefined; }, [id, initialData]); const sharedAttachment = (0, _react.useMemo)(() => { if (id) { return createSharedState(createReferenceKey(id, 'oc'), { onChange }); } return undefined; }, [id, onChange]); const syncAttachment = (0, _react.useCallback)(newData => { if (id) { var _sharedAttachment$dat, _sharedAttachment$dat2; (_sharedAttachment$dat = sharedAttachment.data) === null || _sharedAttachment$dat === void 0 || (_sharedAttachment$dat2 = _sharedAttachment$dat.onChange) === null || _sharedAttachment$dat2 === void 0 || _sharedAttachment$dat2.call(_sharedAttachment$dat, newData); } }, [id, sharedAttachment]); const subscribe = (0, _react.useCallback)(onStoreChange => { if (!id || !sharedState) { return () => {}; } const subscriber = () => onStoreChange(); subscriber['ref'] = instanceRef.current; sharedState.subscribe(subscriber); return () => { sharedState.unsubscribe(subscriber); if (weak && sharedState.subscribersRef.current.length === 0) { sharedState.update(undefined); } }; }, [id, sharedState, weak]); const getSnapshot = (0, _react.useCallback)(() => { var _sharedState$get, _sharedState$get2; return id ? (_sharedState$get = sharedState === null || sharedState === void 0 || (_sharedState$get2 = sharedState.get) === null || _sharedState$get2 === void 0 ? void 0 : _sharedState$get2.call(sharedState)) !== null && _sharedState$get !== void 0 ? _sharedState$get : undefined : undefined; }, [id, sharedState]); const data = (0, _react.useSyncExternalStore)(subscribe, getSnapshot, getSnapshot); const get = (0, _react.useCallback)(() => { if (id) { var _sharedState$get3; return sharedState === null || sharedState === void 0 || (_sharedState$get3 = sharedState.get) === null || _sharedState$get3 === void 0 ? void 0 : _sharedState$get3.call(sharedState); } return undefined; }, [id, sharedState]); const update = (0, _react.useCallback)((newData, opts) => { if (id) { sharedState.update(newData, { ...opts, callerRef: instanceRef.current }); } }, [id, sharedState]); const set = (0, _react.useCallback)((newData, opts) => { if (!id) { return false; } const changed = sharedState.set(newData, { ...opts, callerRef: instanceRef.current }); if (changed) { syncAttachment(newData); } return changed; }, [id, sharedState, syncAttachment]); const extend = (0, _react.useCallback)((newData, opts) => { if (!id) { return false; } const changed = sharedState.extend(newData, { ...opts, callerRef: instanceRef.current }); if (changed) { syncAttachment(newData); } return changed; }, [id, sharedState, syncAttachment]); (0, _react.useEffect)(() => { var _sharedAttachment$dat3; if (id && onChange && !((_sharedAttachment$dat3 = sharedAttachment.data) !== null && _sharedAttachment$dat3 !== void 0 && _sharedAttachment$dat3.onChange)) { sharedAttachment.set({ onChange }); } }, [id, onChange, sharedAttachment]); return { get, data: data, hadInitialData: sharedState === null || sharedState === void 0 ? void 0 : sharedState.hadInitialData, update, set, extend }; } const sharedStates = new Map(); function createSharedState(id, initialData) { if (!sharedStates.get(id)) { const subscribersRef = { current: [] }; const sync = (opts = {}) => { subscribersRef.current.forEach(subscriber => { if (opts.preventSyncOfSameInstance && opts.callerRef !== undefined && subscriber['ref'] === opts.callerRef) { return; } subscriber(); }); }; const get = () => sharedStates.get(id).data; const set = (newData, opts) => { const store = sharedStates.get(id); const current = store.data; if (newData === undefined) { if (current === undefined) { return false; } store.data = undefined; if (!(opts !== null && opts !== void 0 && opts.silent)) { sync(opts); } return true; } const next = cloneData(newData); if (!(opts !== null && opts !== void 0 && opts.forceSync) && shallowEqual(current, next)) { return false; } store.data = next; if (!(opts !== null && opts !== void 0 && opts.silent)) { sync(opts); } return true; }; const update = (newData, opts) => { set(newData, opts); }; const extend = (newData, opts) => { const store = sharedStates.get(id); const current = store.data; if (!isMergeableObject(newData)) { return set(newData, opts); } const base = isMergeableObject(current) ? current : {}; const next = { ...base, ...newData }; if (!(opts !== null && opts !== void 0 && opts.forceSync) && shallowEqual(base, next)) { return false; } store.data = next; if (!(opts !== null && opts !== void 0 && opts.silent)) { sync(opts); } return true; }; const subscribe = subscriber => { if (!subscribersRef.current.includes(subscriber)) { var _context; (0, _push.default)(_context = subscribersRef.current).call(_context, subscriber); } }; const unsubscribe = subscriber => { subscribersRef.current = subscribersRef.current.filter(sub => sub !== subscriber); }; sharedStates.set(id, { data: undefined, get, set, extend, update, subscribe, unsubscribe, hadInitialData: Boolean(initialData), subscribersRef }); if (initialData) { extend(initialData); } } else if (sharedStates.get(id).data === undefined && initialData !== undefined) { sharedStates.get(id).data = cloneData(initialData); } return sharedStates.get(id); } function preSeedSharedState(id, data) { createSharedState(id); const store = sharedStates.get(id); if (store && store.data === undefined && data !== undefined) { store.data = cloneData(data); } } function createReferenceKey(ref1, ref2) { if (!cache.has(ref1)) { cache.set(ref1, new Map()); } const innerMap = cache.get(ref1); if (!innerMap.has(ref2)) { innerMap.set(ref2, {}); } return innerMap.get(ref2); } const cache = new Map(); function isObjectLike(value) { return typeof value === 'object' && value !== null; } function isMergeableObject(value) { return isObjectLike(value) && !Array.isArray(value); } function cloneData(value) { if (Array.isArray(value)) { return [...value]; } if (isMergeableObject(value)) { return { ...value }; } return value; } function shallowEqual(a, b) { if (Object.is(a, b)) { return true; } if (Array.isArray(a) && Array.isArray(b)) { if (a.length !== b.length) { return false; } for (let i = 0; i < a.length; i++) { if (!Object.is(a[i], b[i])) { return false; } } return true; } if (isMergeableObject(a) && isMergeableObject(b)) { const keysA = Object.keys(a); const keysB = Object.keys(b); if (keysA.length !== keysB.length) { return false; } for (const key of keysA) { if (!(0, _hasOwn.default)(b, key) || !Object.is(a[key], b[key])) { return false; } } return true; } return false; } //# sourceMappingURL=useSharedState.js.map