1
0
mirror of https://github.com/robonen/tools.git synced 2026-03-20 19:04:46 +00:00

refactor(web/vue): reuse inject context composable in context state

This commit is contained in:
2025-08-07 05:25:04 +07:00
parent acee7e4167
commit d55e3989f3
2 changed files with 23 additions and 22 deletions

View File

@@ -1,7 +1,8 @@
import { inject, provide, type App, type InjectionKey } from 'vue';
import { useContextFactory } from '../useContextFactory';
import type { App, InjectionKey } from 'vue';
export interface useInjectionStoreOptions<Return> {
injectionKey: string | InjectionKey<Return>;
injectionName?: string;
defaultValue?: Return;
}
@@ -9,28 +10,28 @@ export interface useInjectionStoreOptions<Return> {
* @name useInjectionStore
* @category State
* @description Create a global state that can be injected into components
*
*
* @param {Function} stateFactory A factory function that creates the state
* @param {useInjectionStoreOptions} options An object with the following properties
* @param {string | InjectionKey} options.injectionKey The key to use for the injection
* @param {any} options.defaultValue The default value to use when the state is not provided
* @returns {Object} An object with `useProvidingState`, `useAppProvidingState`, and `useInjectedState` functions
*
*
* @example
* const { useProvidingState, useInjectedState } = useInjectionStore(() => ref('Hello World'));
*
*
* // In a parent component
* const state = useProvidingState();
*
*
* // In a child component
* const state = useInjectedState();
*
*
* @example
* const { useProvidingState, useInjectedState } = useInjectionStore(() => ref('Hello World'), {
* injectionKey: 'MyState',
* defaultValue: 'Default Value'
* });
*
*
* // In a plugin
* {
* install(app) {
@@ -38,31 +39,31 @@ export interface useInjectionStoreOptions<Return> {
* state.value = 'Hello World';
* }
* }
*
*
* // In a component
* const state = useInjectedState();
*
*
* @since 0.0.5
*/
export function useInjectionStore<Args extends any[], Return>(
stateFactory: (...args: Args) => Return,
options?: useInjectionStoreOptions<Return>,
options?: useInjectionStoreOptions<Return>
) {
const key = options?.injectionKey ?? Symbol(stateFactory.name ?? 'InjectionStore');
const ctx = useContextFactory<Return>(options?.injectionName ?? stateFactory.name ?? 'InjectionStore');
const useProvidingState = (...args: Args) => {
const state = stateFactory(...args);
provide(key, state);
ctx.provide(state);
return state;
};
const useAppProvidingState = (app: App) => (...args: Args) => {
const state = stateFactory(...args);
app.provide(key, state);
ctx.appProvide(app)(state);
return state;
};
const useInjectedState = () => inject(key, options?.defaultValue);
const useInjectedState = () => ctx.inject(options?.defaultValue);
return {
useProvidingState,