feat: add config and page

This commit is contained in:
xion 2024-11-30 00:10:51 +08:00
parent f62254af26
commit ebf0b230b1
8 changed files with 231 additions and 8 deletions

3
.npmrc Normal file
View File

@ -0,0 +1,3 @@
//npm.xiongxiao.me/:_authToken=${ME_NPM_TOKEN}
@abearxiong:registry=https://npm.pkg.github.com
//registry.npmjs.org/:_authToken=${NPM_TOKEN}

View File

@ -1,6 +1,6 @@
{ {
"name": "@kevisual/store", "name": "@kevisual/store",
"version": "0.0.1-alpha.2", "version": "0.0.1-alpha.3",
"main": "dist/store.js", "main": "dist/store.js",
"module": "dist/store.js", "module": "dist/store.js",
"types": "dist/store.d.ts", "types": "dist/store.d.ts",
@ -29,13 +29,13 @@
"fast-deep-equal": "^3.1.3", "fast-deep-equal": "^3.1.3",
"immer": "^10.1.1", "immer": "^10.1.1",
"lodash-es": "^4.17.21", "lodash-es": "^4.17.21",
"nanoid": "^5.0.7", "nanoid": "^5.0.9",
"rollup": "^4.24.0", "rollup": "^4.27.4",
"rollup-plugin-dts": "^6.1.1", "rollup-plugin-dts": "^6.1.1",
"ts-node": "^10.9.2", "ts-node": "^10.9.2",
"tslib": "^2.8.0", "tslib": "^2.8.1",
"typescript": "^5.6.3", "typescript": "^5.7.2",
"zustand": "^5.0.0" "zustand": "^5.0.1"
}, },
"publishConfig": { "publishConfig": {
"access": "public" "access": "public"
@ -48,6 +48,21 @@
".": { ".": {
"import": "./dist/store.js", "import": "./dist/store.js",
"require": "./dist/store.js" "require": "./dist/store.js"
},
"./config": {
"import": "./dist/web-config.js",
"require": "./dist/web-config.js"
},
"./context": {
"import": "./dist/web-context.js",
"require": "./dist/web-context.js"
},
"./page": {
"import": "./dist/web-page.js",
"require": "./dist/web-page.js"
} }
},
"dependencies": {
"path-to-regexp": "^8.2.0"
} }
} }

View File

@ -10,7 +10,7 @@ import { dts } from 'rollup-plugin-dts';
*/ */
export default [ export default [
{ {
input: 'src/index.ts', // TypeScript 入口文件 input: 'src/store.ts', // TypeScript 入口文件
output: { output: {
file: 'dist/store.js', // 输出文件 file: 'dist/store.js', // 输出文件
format: 'es', // 输出格式设置为 ES 模块 format: 'es', // 输出格式设置为 ES 模块
@ -22,11 +22,59 @@ export default [
], ],
}, },
{ {
input: 'src/index.ts', input: 'src/store.ts',
output: { output: {
file: 'dist/store.d.ts', file: 'dist/store.d.ts',
format: 'es', format: 'es',
}, },
plugins: [dts()], plugins: [dts()],
}, },
{
input: 'src/web-config.ts',
output: {
file: 'dist/web-config.js',
format: 'cjs',
},
plugins: [resolve(), 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(), commonjs(), typescript()],
},
{
input: 'src/web-context.ts',
output: {
file: 'dist/web-context.d.ts',
format: 'es',
},
plugins: [dts()],
},
{
input: 'src/page.ts',
output: {
file: 'dist/web-page.js',
format: 'es',
},
plugins: [resolve(), commonjs(), typescript()],
},
{
input: 'src/page.ts',
output: {
file: 'dist/web-page.d.ts',
format: 'es',
},
plugins: [dts()],
},
]; ];

68
src/page.ts Normal file
View File

@ -0,0 +1,68 @@
import { getPathKey } from '@/utils/path-key.ts';
import { match } from 'path-to-regexp';
type PageOptions = {
path?: string;
key?: string;
basename?: string;
};
type PageModule = {
// 模块的key如 user定义模块的唯一标识
key: string;
// 模块的path路径如 /user/:idmatch的时候会用到
path: string;
};
export class Page {
pageModule = new Map<string, PageModule>();
path: string;
key: string;
basename: string;
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}`;
}
addPage(path: string, key?: string) {
this.pageModule.set(key, { path, key });
}
check(key: string, pathname?: string): boolean | Record<string, string> {
if (!key) {
console.error('key is required');
return;
}
const has = this.pageModule.has(key);
if (!has) {
console.error(`PageModule ${key} not found`);
return;
}
const pageModule = this.pageModule.get(key);
const location = window.location;
const _pathname = pathname || location.pathname;
const cur = _pathname.replace(this.basename, '');
const routeMatch = match(pageModule.path, { decode: decodeURIComponent });
const result = routeMatch(cur);
let params = {};
if (result) {
result.path;
params = result.params;
return params;
}
return false;
}
/**
*
* @returns
*/
getPath() {
const location = window.location;
const pathname = location.pathname;
return pathname.replace(this.basename, '');
}
decodePath(path: string) {
return decodeURIComponent(path);
}
encodePath(path: string) {
return encodeURIComponent(path);
}
}

7
src/utils/path-key.ts Normal file
View File

@ -0,0 +1,7 @@
export const getPathKey = () => {
// 从localtion.href的路径中/a/b 中 a为pathb为key
const pathname = location.pathname;
const paths = pathname.split('/');
const [path, key] = paths.slice(1);
return { path, key, id: path + '---' + key, prefix: `/${path}/${key}` };
};

41
src/web-config.ts Normal file
View File

@ -0,0 +1,41 @@
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);
};

41
src/web-context.ts Normal file
View File

@ -0,0 +1,41 @@
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);
};