1
0
mirror of https://github.com/robonen/tools.git synced 2026-03-20 02:44:45 +00:00

Merge pull request #91 from robonen/refactor/web/vue

refactor(web/vue): reuse injection context composable in injection store
This commit is contained in:
2025-08-07 05:28:14 +07:00
committed by GitHub
3 changed files with 24 additions and 23 deletions

View File

@@ -1,6 +1,6 @@
{ {
"name": "@robonen/vue", "name": "@robonen/vue",
"version": "0.0.9", "version": "0.0.10",
"license": "Apache-2.0", "license": "Apache-2.0",
"description": "Collection of powerful tools for Vue", "description": "Collection of powerful tools for Vue",
"keywords": [ "keywords": [

View File

@@ -1,4 +1,4 @@
import { inject, provide, type InjectionKey, type App } from 'vue'; import { inject as vueInject, provide as vueProvide, type InjectionKey, type App } from 'vue';
import { VueToolsError } from '../..'; import { VueToolsError } from '../..';
/** /**
@@ -34,8 +34,8 @@ import { VueToolsError } from '../..';
export function useContextFactory<ContextValue>(name: string) { export function useContextFactory<ContextValue>(name: string) {
const injectionKey: InjectionKey<ContextValue> = Symbol(name); const injectionKey: InjectionKey<ContextValue> = Symbol(name);
const injectContext = <Fallback extends ContextValue = ContextValue>(fallback?: Fallback) => { const inject = <Fallback extends ContextValue = ContextValue>(fallback?: Fallback) => {
const context = inject(injectionKey, fallback); const context = vueInject(injectionKey, fallback);
if (context !== undefined) if (context !== undefined)
return context; return context;
@@ -43,8 +43,8 @@ export function useContextFactory<ContextValue>(name: string) {
throw new VueToolsError(`useContextFactory: '${name}' context is not provided`); throw new VueToolsError(`useContextFactory: '${name}' context is not provided`);
}; };
const provideContext = (context: ContextValue) => { const provide = (context: ContextValue) => {
provide(injectionKey, context); vueProvide(injectionKey, context);
return context; return context;
}; };
@@ -54,8 +54,8 @@ export function useContextFactory<ContextValue>(name: string) {
}; };
return { return {
inject: injectContext, inject,
provide: provideContext, provide,
appProvide, appProvide,
key: injectionKey, key: injectionKey,
} }

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