Compare commits
	
		
			23 Commits
		
	
	
		
			415f008209
			...
			main
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| bbf826b765 | |||
| 9d22faa8ba | |||
| e4768b6360 | |||
| 598e29cf5a | |||
| 4152133951 | |||
| 02446fd60f | |||
| 351b2e3366 | |||
| d70118ad3d | |||
| 69784e8ed4 | |||
| 3d50b64543 | |||
| 077e99cbc8 | |||
| abdc5c7923 | |||
| 3ee69a4f81 | |||
| 86ae2c7f70 | |||
| 3a027efb79 | |||
| d8d5073542 | |||
| b39c950ef7 | |||
| 01db9c9ea2 | |||
| c855c7d3d5 | |||
| 7cb42edc5f | |||
| 9b3de5eba3 | |||
| 3b19cd8581 | |||
| 78d581c98c | 
| @@ -1,9 +1,11 @@ | ||||
| console.log('index.js'); | ||||
| // console.log('index.js'); | ||||
| // //@ts-ignore | ||||
| import { Page } from '@kevisual/store/page'; | ||||
|  | ||||
| const page = new Page({ | ||||
|   isListen: true, | ||||
| }); | ||||
| page.basename = ''; | ||||
| page.addPage('/', 'home'); | ||||
| page.addPage('/:id', 'user'); | ||||
| page.subscribe( | ||||
| @@ -21,3 +23,6 @@ page.subscribe('user', (params, state) => { | ||||
| // page.navigate('/c', { id: 3 }); | ||||
| // page.navigate('/c', { id: 2 }); | ||||
| // page.refresh(); | ||||
|  | ||||
| // @ts-ignore | ||||
| window.page = page; | ||||
|   | ||||
							
								
								
									
										31
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										31
									
								
								package.json
									
									
									
									
									
								
							| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|   "name": "@kevisual/store", | ||||
|   "version": "0.0.3", | ||||
|   "version": "0.0.8", | ||||
|   "main": "dist/store.js", | ||||
|   "module": "dist/store.js", | ||||
|   "types": "dist/store.d.ts", | ||||
| @@ -26,22 +26,27 @@ | ||||
|   "license": "ISC", | ||||
|   "description": "", | ||||
|   "devDependencies": { | ||||
|     "@kevisual/context": "^0.0.3", | ||||
|     "@kevisual/load": "^0.0.6", | ||||
|     "@kevisual/router": "^0.0.21", | ||||
|     "@kevisual/types": "link:../types", | ||||
|     "@rollup/plugin-commonjs": "^28.0.3", | ||||
|     "@rollup/plugin-node-resolve": "^16.0.1", | ||||
|     "@rollup/plugin-terser": "^0.4.4", | ||||
|     "@rollup/plugin-typescript": "^12.1.2", | ||||
|     "@types/lodash-es": "^4.17.12", | ||||
|     "eventemitter3": "^5.0.1", | ||||
|     "fast-deep-equal": "^3.1.3", | ||||
|     "immer": "^10.1.1", | ||||
|     "lodash-es": "^4.17.21", | ||||
|     "nanoid": "^5.1.5", | ||||
|     "rollup": "^4.37.0", | ||||
|     "path-to-regexp": "^8.2.0", | ||||
|     "rollup": "^4.41.1", | ||||
|     "rollup-plugin-dts": "^6.2.1", | ||||
|     "ts-node": "^10.9.2", | ||||
|     "tslib": "^2.8.1", | ||||
|     "tsup": "^8.4.0", | ||||
|     "typescript": "^5.8.2", | ||||
|     "vite-plugin-dts": "^4.5.3", | ||||
|     "zustand": "^5.0.3" | ||||
|     "typescript": "^5.8.3", | ||||
|     "zustand": "^5.0.5" | ||||
|   }, | ||||
|   "publishConfig": { | ||||
|     "access": "public" | ||||
| @@ -60,24 +65,16 @@ | ||||
|       "require": "./dist/web-config.js" | ||||
|     }, | ||||
|     "./context": { | ||||
|       "import": "./dist/web-context.js", | ||||
|       "require": "./dist/web-context.js" | ||||
|       "import": "./dist/web-config.js", | ||||
|       "require": "./dist/web-config.js" | ||||
|     }, | ||||
|     "./page": { | ||||
|     "./web-page.js": { | ||||
|       "import": "./dist/web-page.js", | ||||
|       "require": "./dist/web-page.js" | ||||
|     }, | ||||
|     "./web": { | ||||
|       "import": "./dist/web.js", | ||||
|       "require": "./dist/web.js" | ||||
|     }, | ||||
|     "./react": { | ||||
|       "import": "./dist-react/store-react.js", | ||||
|       "types": "./dist-react/index.d.ts" | ||||
|     } | ||||
|   }, | ||||
|   "dependencies": { | ||||
|     "eventemitter3": "^5.0.1", | ||||
|     "path-to-regexp": "^8.2.0" | ||||
|   } | ||||
| } | ||||
| @@ -40,7 +40,7 @@ export const StoreContextProvider = ({ | ||||
|  | ||||
| type SimpleObject = Record<string, any>; | ||||
|  | ||||
| export const useStore = (selector: any): any => { | ||||
| export const useStore = function (selector: any): any { | ||||
|   const store = useContext(StoreContext); | ||||
|   const allState = store.getState(); | ||||
|   const selectedState = selector ? selector(allState) : allState; | ||||
| @@ -58,5 +58,34 @@ export const useStore = (selector: any): any => { | ||||
|  | ||||
|   return state; | ||||
| }; | ||||
|  | ||||
| export type BoundStore<T> = UseBoundStore<StoreApi<T>>; | ||||
| useStore.getState = function (id: string) { | ||||
|   const store = useContextKey<any>('store'); | ||||
|   if (!store) { | ||||
|     console.error('store not found'); | ||||
|     return null; | ||||
|   } | ||||
|   return store.getStore(id).getState(); | ||||
| }; | ||||
| useStore.setState = function (id: string, state: any) { | ||||
|   const store = useContextKey<any>('store'); | ||||
|   if (!store) { | ||||
|     console.error('store not found'); | ||||
|     return null; | ||||
|   } | ||||
|   store.getStore(id).setState(state); | ||||
| }; | ||||
| useStore.subscribe = function (fn: any) { | ||||
|   const store = useContextKey<any>('store'); | ||||
|   if (!store) { | ||||
|     console.error('store not found'); | ||||
|     return null; | ||||
|   } | ||||
|   return store.subscribe(fn); | ||||
| }; | ||||
| export type BoundStore<T> = UseBoundStore<StoreApi<T>> & { | ||||
|   getState: (id: string) => T; | ||||
|   setState: (id: string, state: T) => void; | ||||
|   subscribe: (fn: (state: T) => void) => () => void; | ||||
|   createStore: (stateCreator: StateCreator<any, [], [], any>) => void; | ||||
|   createIfNotExists: (stateCreator: StateCreator<any, [], [], any>) => void; | ||||
| }; | ||||
|   | ||||
| @@ -4,6 +4,7 @@ import typescript from '@rollup/plugin-typescript'; | ||||
| import resolve from '@rollup/plugin-node-resolve'; | ||||
| import commonjs from '@rollup/plugin-commonjs'; | ||||
| import { dts } from 'rollup-plugin-dts'; | ||||
| import terser from '@rollup/plugin-terser'; | ||||
|  | ||||
| /** | ||||
|  * @type {import('rollup').RollupOptions} | ||||
| @@ -29,38 +30,22 @@ export default [ | ||||
|     }, | ||||
|     plugins: [dts()], | ||||
|   }, | ||||
|   { | ||||
|     input: 'src/web-config.ts', | ||||
|     output: { | ||||
|       file: 'dist/web-config.js', | ||||
|       format: 'es', | ||||
|     }, | ||||
|     plugins: [resolve({ browser: true }), commonjs(), typescript()], | ||||
|   }, | ||||
|   { | ||||
|     input: 'src/web-config.ts', | ||||
|     output: { | ||||
|       file: 'dist/web-config.d.ts', | ||||
|       format: 'es', | ||||
|     }, | ||||
|     plugins: [dts()], | ||||
|   }, | ||||
|   { | ||||
|     input: 'src/web-context.ts', | ||||
|     output: { | ||||
|       file: 'dist/web-context.js', | ||||
|       format: 'es', | ||||
|     }, | ||||
|     plugins: [resolve({ browser: true }), commonjs(), typescript()], | ||||
|   }, | ||||
|   { | ||||
|     input: 'src/web-context.ts', | ||||
|     output: { | ||||
|       file: 'dist/web-context.d.ts', | ||||
|       format: 'es', | ||||
|     }, | ||||
|     plugins: [dts()], | ||||
|   }, | ||||
|   // { | ||||
|   //   input: 'src/web-env.ts', | ||||
|   //   output: { | ||||
|   //     file: 'dist/web-config.js', | ||||
|   //     format: 'es', | ||||
|   //   }, | ||||
|   //   plugins: [resolve({ browser: true }), commonjs(), typescript()], | ||||
|   // }, | ||||
|   // { | ||||
|   //   input: 'src/web-env.ts', | ||||
|   //   output: { | ||||
|   //     file: 'dist/web-config.d.ts', | ||||
|   //     format: 'es', | ||||
|   //   }, | ||||
|   //   plugins: [dts()], | ||||
|   // }, | ||||
|   { | ||||
|     input: 'src/page.ts', | ||||
|     output: { | ||||
| @@ -77,20 +62,4 @@ export default [ | ||||
|     }, | ||||
|     plugins: [dts()], | ||||
|   }, | ||||
|   { | ||||
|     input: 'src/web.ts', | ||||
|     output: { | ||||
|       file: 'dist/web.js', | ||||
|       format: 'es', | ||||
|     }, | ||||
|     plugins: [resolve({ browser: true }), commonjs(), typescript()], | ||||
|   }, | ||||
|   { | ||||
|     input: 'src/web.ts', | ||||
|     output: { | ||||
|       file: 'dist/web.d.ts', | ||||
|       format: 'es', | ||||
|     }, | ||||
|     plugins: [dts()], | ||||
|   }, | ||||
| ]; | ||||
|   | ||||
							
								
								
									
										161
									
								
								src/page.ts
									
									
									
									
									
								
							
							
						
						
									
										161
									
								
								src/page.ts
									
									
									
									
									
								
							| @@ -1,10 +1,23 @@ | ||||
| import { getPathKey } from '@/utils/path-key.ts'; | ||||
| import { match } from 'path-to-regexp'; | ||||
| import * as pathToRegexp from 'path-to-regexp'; | ||||
| import deepEqual from 'fast-deep-equal'; | ||||
|  | ||||
| const generateRandom = () => { | ||||
|   // return Math.random().toString(36).substring(8); | ||||
|   return crypto.randomUUID(); | ||||
| }; | ||||
| type PageOptions = { | ||||
|   /** | ||||
|    * 路径 | ||||
|    */ | ||||
|   path?: string; | ||||
|   /** | ||||
|    * key | ||||
|    */ | ||||
|   key?: string; | ||||
|   /** | ||||
|    * basename | ||||
|    */ | ||||
|   basename?: string; | ||||
|   isListen?: boolean; | ||||
| }; | ||||
| @@ -19,6 +32,9 @@ type CallbackInfo = { | ||||
|   fn: CallFn; | ||||
|   id: string; | ||||
| } & PageModule; | ||||
| /** | ||||
|  * 根据basename,其中的path和key,来判断一个应用的模块。 | ||||
|  */ | ||||
| export class Page { | ||||
|   pageModule = new Map<string, PageModule>(); | ||||
|   // pathname的第一个路径 | ||||
| @@ -28,18 +44,51 @@ export class Page { | ||||
|   basename: string; | ||||
|   isListen: boolean; | ||||
|   callbacks = [] as CallbackInfo[]; | ||||
|   ok = false; | ||||
|   constructor(opts?: PageOptions) { | ||||
|     const pathKey = getPathKey(); | ||||
|     this.path = opts?.path ?? pathKey.path; | ||||
|     this.key = opts?.key ?? pathKey.key; | ||||
|     this.basename = opts?.basename ?? `/${this.path}/${this.key}`; | ||||
|     if (opts?.basename) { | ||||
|       this.basename = opts?.basename; | ||||
|     } else { | ||||
|       if (this.key) { | ||||
|         this.basename = `/${this.path}/${this.key}`; | ||||
|       } else { | ||||
|         const location = window.location; | ||||
|         this.basename = location.pathname; | ||||
|       } | ||||
|     } | ||||
|     this.clearEndSlash(); | ||||
|     const isListen = opts?.isListen ?? true; | ||||
|     if (isListen) { | ||||
|       this.listen(); | ||||
|     } | ||||
|     this.ok = !!this.key; | ||||
|   } | ||||
|   popstate(event?: PopStateEvent, manualOpts?: { id?: string; type: 'singal' | 'all' }) { | ||||
|     const pathname = window.location.pathname; | ||||
|   /** | ||||
|    * 清除路径的结尾斜杠,所有的最后的斜杠都删除 | ||||
|    */ | ||||
|   clearEndSlash() { | ||||
|     this.basename = this.basename.replace(/\/+$/, ''); | ||||
|     return this; | ||||
|   } | ||||
|   /** | ||||
|    * 检查路径 | ||||
|    */ | ||||
|   checkPath() { | ||||
|     const pathKey = getPathKey(); | ||||
|     const { path, key } = pathKey; | ||||
|     this.path = path || ''; | ||||
|     this.key = key || ''; | ||||
|     this.ok = !!this.key; | ||||
|     this.basename = `/${this.path}/${this.key}`; | ||||
|     this.clearEndSlash(); | ||||
|     return this; | ||||
|   } | ||||
|  | ||||
|   popstate(event?: PopStateEvent, manualOpts?: { id?: string; type: 'singal' | 'all'; pathname?: string }) { | ||||
|     const pathname = manualOpts?.pathname ?? window.location.pathname; | ||||
|     if (manualOpts) { | ||||
|       if (manualOpts.type === 'singal') { | ||||
|         const item = this.callbacks.find((item) => item.id === manualOpts.id); | ||||
| @@ -56,7 +105,17 @@ export class Page { | ||||
|       result && item.fn?.(result.params, event.state, { event, manualOpts }); | ||||
|     }); | ||||
|   } | ||||
|   /** | ||||
|    * 调用callback中id或者pathname的函数, 其中id优先级高于pathname,若都没有,则从location.pathname中获取 | ||||
|    * @param opts | ||||
|    */ | ||||
|   call(opts?: { id?: string; pathname?: string }) { | ||||
|     this.popstate({ state: window.history.state } as any, { ...opts, type: 'all' }); | ||||
|   } | ||||
|   listen() { | ||||
|     if (this.isListen) { | ||||
|       return; | ||||
|     } | ||||
|     this.isListen = true; | ||||
|     window.addEventListener('popstate', this.popstate.bind(this), false); | ||||
|   } | ||||
| @@ -83,7 +142,7 @@ export class Page { | ||||
|     }); | ||||
|   } | ||||
|   /** | ||||
|    * 检查当前路径是否匹配 | ||||
|    * 检查当前路径是否匹配, 如何提交pathname,则检查pathname | ||||
|    * @param key | ||||
|    * @param pathname | ||||
|    * @returns | ||||
| @@ -100,8 +159,12 @@ export class Page { | ||||
|     } | ||||
|     const location = window.location; | ||||
|     const _pathname = pathname || location.pathname; | ||||
|     if (!_pathname.includes(this.basename)) { | ||||
|       // console.error(`PageModule ${key} not found`); | ||||
|       return false; | ||||
|     } | ||||
|     const cur = _pathname.replace(this.basename, ''); | ||||
|     const routeMatch = match(pageModule.path, { decode: decodeURIComponent }); | ||||
|     const routeMatch = pathToRegexp.match(pageModule.path, { decode: decodeURIComponent }); | ||||
|     const result = routeMatch(cur); | ||||
|     let params = {}; | ||||
|     if (result) { | ||||
| @@ -118,20 +181,22 @@ export class Page { | ||||
|    * @param opts | ||||
|    * @returns | ||||
|    */ | ||||
|   subscribe(key: string, fn?: CallFn, opts?: { pathname?: string; runImmediately?: boolean; id?: string }) { | ||||
|   async subscribe(key: string, fn?: CallFn, opts?: { pathname?: string; runImmediately?: boolean; id?: string }) { | ||||
|     const runImmediately = opts?.runImmediately ?? true; // 默认立即执行 | ||||
|     const id = opts?.id ?? Math.random().toString(36).slice(2); | ||||
|     const path = this.pageModule.get(key)?.path; | ||||
|     if (!path) { | ||||
|     const id = opts?.id ?? generateRandom(); | ||||
|     const pageModule = this.pageModule.get(key); | ||||
|     if (!pageModule) { | ||||
|       console.error(`PageModule ${key} not found`); | ||||
|       return () => {}; | ||||
|     } | ||||
|     const path = pageModule?.path || ''; | ||||
|     this.callbacks.push({ key, fn, id: id, path }); | ||||
|     if (runImmediately) { | ||||
|       const location = window.location; | ||||
|       const pathname = opts?.pathname ?? location.pathname; | ||||
|       const result = this.check(key, pathname); | ||||
|       if (result) { | ||||
|         // 如果是手动调用,则不需要检查是否相等,直接执行,而且是执行当前的subscribe的函数 | ||||
|         this.popstate({ state: window.history.state } as any, { id, type: 'singal' }); | ||||
|       } | ||||
|     } | ||||
| @@ -139,6 +204,9 @@ export class Page { | ||||
|       this.callbacks = this.callbacks.filter((item) => item.id !== id); | ||||
|     }; | ||||
|   } | ||||
|   getPathKey() { | ||||
|     return getPathKey(); | ||||
|   } | ||||
|   /** | ||||
|    * 返回当前路径,不包含basename | ||||
|    * @returns | ||||
| @@ -151,12 +219,26 @@ export class Page { | ||||
|   getAppPath() { | ||||
|     return this.path; | ||||
|   } | ||||
|   /** | ||||
|    * 返回当前key | ||||
|    * @returns | ||||
|    */ | ||||
|   getAppKey() { | ||||
|     return this.key; | ||||
|   } | ||||
|   /** | ||||
|    * 解码路径 | ||||
|    * @param path | ||||
|    * @returns | ||||
|    */ | ||||
|   decodePath(path: string) { | ||||
|     return decodeURIComponent(path); | ||||
|   } | ||||
|   /** | ||||
|    * 编码路径 | ||||
|    * @param path | ||||
|    * @returns | ||||
|    */ | ||||
|   encodePath(path: string) { | ||||
|     return encodeURIComponent(path); | ||||
|   } | ||||
| @@ -164,7 +246,7 @@ export class Page { | ||||
|    * 如果state 和 pathname都相等,则不执行popstate | ||||
|    * @param path | ||||
|    * @param state | ||||
|    * @param check | ||||
|    * @param check 是否检查, 默认检查 | ||||
|    * @returns | ||||
|    */ | ||||
|   navigate(path: string | number, state?: any, check?: boolean) { | ||||
| @@ -187,15 +269,70 @@ export class Page { | ||||
|       this.popstate({ state } as any, { type: 'all' }); | ||||
|     } | ||||
|   } | ||||
|   /** | ||||
|    * 替换当前路径 | ||||
|    * @param path | ||||
|    * @param state | ||||
|    * @param check | ||||
|    */ | ||||
|   replace(path: string, state?: any, check?: boolean) { | ||||
|     let _check = check ?? true; | ||||
|     window.history.replaceState(state, '', this.basename + path); | ||||
|     let newPath = this.basename + path; | ||||
|     if (path.startsWith('http')) { | ||||
|       const url = new URL(path); | ||||
|       const origin = url.origin; | ||||
|       newPath = url.toString().replace(origin, ''); | ||||
|     } | ||||
|     window.history.replaceState(state, '', newPath); | ||||
|     if (_check) { | ||||
|       this.popstate({ state } as any, { type: 'all' }); | ||||
|     } | ||||
|   } | ||||
|   /** | ||||
|    * 刷新当前页面 | ||||
|    */ | ||||
|   refresh() { | ||||
|     const state = window.history.state; | ||||
|     this.popstate({ state } as any, { type: 'all' }); | ||||
|   } | ||||
|   /** | ||||
|    * 检查路径是否匹配 | ||||
|    * @param path | ||||
|    * @param checkPath | ||||
|    * @returns | ||||
|    */ | ||||
|   pathMatch(regexpPath: string, checkPath: string) { | ||||
|     return pathToRegexp.match(regexpPath, { decode: decodeURIComponent })(checkPath); | ||||
|   } | ||||
|   pathToRegexp = pathToRegexp; | ||||
|   static match(regexpPath: string, checkPath: string) { | ||||
|     return pathToRegexp.match(regexpPath, { decode: decodeURIComponent })(checkPath); | ||||
|   } | ||||
| } | ||||
| /** | ||||
|  * 获取history state | ||||
|  * @returns | ||||
|  */ | ||||
| export const getHistoryState = <T = Record<string, any>>() => { | ||||
|   const history = window.history; | ||||
|   const state = history.state || {}; | ||||
|   return state as T; | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * 设置history state | ||||
|  * @param state | ||||
|  */ | ||||
| export const setHistoryState = (state: any, url?: string) => { | ||||
|   const history = window.history; | ||||
|   const oldState = getHistoryState(); | ||||
|   history.replaceState({ ...oldState, ...state }, '', url || window.location.href); | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * 清除history state | ||||
|  */ | ||||
| export const clearHistoryState = (url?: string) => { | ||||
|   const history = window.history; | ||||
|   history.replaceState({}, '', url || window.location.href); | ||||
| }; | ||||
|   | ||||
| @@ -2,6 +2,8 @@ export const getPathKey = () => { | ||||
|   // 从localtion.href的路径中,/a/b 中 a为path,b为key | ||||
|   const pathname = location.pathname; | ||||
|   const paths = pathname.split('/'); | ||||
|   const [path, key] = paths.slice(1); | ||||
|   let [path, key] = paths.slice(1); | ||||
|   path = path || ''; | ||||
|   key = key || ''; | ||||
|   return { path, key, id: path + '---' + key, prefix: `/${path}/${key}` }; | ||||
| }; | ||||
|   | ||||
| @@ -1,41 +0,0 @@ | ||||
| import { getPathKey } from './utils/path-key.ts'; | ||||
|  | ||||
| type GlobalConfig = { | ||||
|   name?: string; | ||||
|   [key: string]: any; | ||||
| }; | ||||
| export const useConfig = (initConfig?: GlobalConfig) => { | ||||
|   const config: GlobalConfig = (window as any).config; | ||||
|   const _config = config || initConfig; | ||||
|   !config && ((window as any)['config'] = _config); | ||||
|   return _config; | ||||
| }; | ||||
|  | ||||
| export const useConfigKey = <T>(key: string, init?: () => T): T => { | ||||
|   const _config = useConfig({}); | ||||
|   if (key && init) { | ||||
|     _config[key] = init(); | ||||
|     return _config[key] as any; | ||||
|   } | ||||
|   if (key) { | ||||
|     return _config[key]; | ||||
|   } | ||||
|   return _config as any; | ||||
| }; | ||||
|  | ||||
| export const useConfigKeySync = async <T = any>(key: string, init?: () => Promise<T>): Promise<T> => { | ||||
|   const _config = useConfig({}); | ||||
|   if (key && init) { | ||||
|     _config[key] = await init(); | ||||
|     return _config[key] as any; | ||||
|   } | ||||
|   if (key) { | ||||
|     return _config[key]; | ||||
|   } | ||||
|   return _config as any; | ||||
| }; | ||||
|  | ||||
| export const usePageConfig = (init?: () => {}) => { | ||||
|   const { id } = getPathKey(); | ||||
|   return useConfigKey(id, init); | ||||
| }; | ||||
| @@ -1,41 +0,0 @@ | ||||
| import { getPathKey } from './utils/path-key.ts'; | ||||
|  | ||||
| type GlobalContext = { | ||||
|   name?: string; | ||||
|   [key: string]: any; | ||||
| }; | ||||
| export const useContext = (initContext?: GlobalContext) => { | ||||
|   const context: GlobalContext = (window as any).context; | ||||
|   const _context = context || initContext; | ||||
|   !context && ((window as any)['context'] = _context); | ||||
|   return _context; | ||||
| }; | ||||
|  | ||||
| export const useContextKey = <T>(key: string, init?: () => T): T => { | ||||
|   const _context = useContext({}); | ||||
|   if (key && init) { | ||||
|     _context[key] = init(); | ||||
|     return _context[key] as any; | ||||
|   } | ||||
|   if (key) { | ||||
|     return _context[key]; | ||||
|   } | ||||
|   return _context as any; | ||||
| }; | ||||
|  | ||||
| export const useContextKeySync = async <T = any>(key: string, init?: () => Promise<T>): Promise<T> => { | ||||
|   const _context = useContext({}); | ||||
|   if (key && init) { | ||||
|     _context[key] = await init(); | ||||
|     return _context[key] as any; | ||||
|   } | ||||
|   if (key) { | ||||
|     return _context[key]; | ||||
|   } | ||||
|   return _context as any; | ||||
| }; | ||||
|  | ||||
| export const usePageContext = (init?: () => {}) => { | ||||
|   const { id } = getPathKey(); | ||||
|   return useContextKey(id, init); | ||||
| }; | ||||
							
								
								
									
										1
									
								
								src/web-env.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								src/web-env.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| export * from '@kevisual/context'; | ||||
| @@ -1,8 +0,0 @@ | ||||
| export * from './page.ts'; | ||||
| export * from './web-context.ts'; | ||||
| export * from './web-config.ts'; | ||||
|  | ||||
| export * from 'nanoid'; | ||||
| export * from 'path-to-regexp'; | ||||
|  | ||||
| export * from 'eventemitter3'; | ||||
| @@ -10,6 +10,7 @@ | ||||
|     "baseUrl": "./", | ||||
|     "typeRoots": [ | ||||
|       "node_modules/@types", | ||||
|       "node_modules/@kevisual/types", | ||||
|     ], | ||||
|     "declaration": false, | ||||
|     "noEmit": true, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user