UNPKG

@dark-engine/core

Version:

The lightweight and powerful UI rendering engine without dependencies and written in TypeScript (Browser, Node.js, Android, iOS, Windows, Linux, macOS)

64 lines (63 loc) 2.28 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); exports.useContext = exports.createContext = void 0; const component_1 = require('../component'); const use_layout_effect_1 = require('../use-layout-effect'); const internal_1 = require('../internal'); const emitter_1 = require('../emitter'); const use_update_1 = require('../use-update'); const utils_1 = require('../utils'); const use_memo_1 = require('../use-memo'); function createContext(defaultValue, options) { const { displayName = 'Component' } = options || {}; const context = (0, component_1.component)( ({ value = defaultValue, slot }) => { const cursor = (0, internal_1.__useCursor)(); const { hook } = cursor; let providers = hook.getProviders(); if (!providers) { providers = new Map(); providers.set(context, { value, emitter: new emitter_1.EventEmitter() }); hook.setProviders(providers); } const provider = providers.get(context); (0, use_layout_effect_1.useLayoutEffect)(() => { provider.emitter.emit('publish', value); }, [value]); provider.value = value; return slot; }, { displayName: `Context(${displayName})` }, ); context.defaultValue = defaultValue; Object.freeze(context); return context; } exports.createContext = createContext; function useContext(context) { const { defaultValue } = context; const cursor = (0, internal_1.__useCursor)(); const scope = (0, use_memo_1.useMemo)(() => ({ value: null, provider: getProvider(context, cursor) }), []); const update = (0, use_update_1.useUpdate)(); const { provider } = scope; const value = provider ? provider.value : defaultValue; (0, use_layout_effect_1.useLayoutEffect)(() => { if (!provider) return; return provider.emitter.on('publish', value => { !(0, utils_1.detectIsEqual)(scope.value, value) && update(); }); }, []); scope.value = value; return value; } exports.useContext = useContext; function getProvider(context, fiber) { let $fiber = fiber; while ($fiber) { const providers = $fiber.hook?.getProviders(); if (providers?.has(context)) return providers.get(context); $fiber = $fiber.parent; } return null; } //# sourceMappingURL=context.js.map