@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
JavaScript
;
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