@linyjs/plugin-docs 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +97 -0
- package/docs/api-reference/index.md +341 -0
- package/docs/best-practices/error-handling.md +462 -0
- package/docs/best-practices/naming-conventions.md +495 -0
- package/docs/best-practices/performance.md +532 -0
- package/docs/best-practices/security.md +620 -0
- package/docs/faq.md +323 -0
- package/docs/getting-started/first-plugin.md +358 -0
- package/docs/getting-started/installation.md +244 -0
- package/docs/getting-started/quick-start.md +174 -0
- package/docs/guides/client-module.md +598 -0
- package/docs/guides/data-persistence.md +536 -0
- package/docs/guides/permissions.md +440 -0
- package/docs/guides/server-module.md +371 -0
- package/docs/guides/ui-slots.md +475 -0
- package/docs/migration/v0-to-v1.md +354 -0
- package/examples/analytics-plugin/README.md +416 -0
- package/examples/analytics-plugin/dist/client/index.d.ts +36 -0
- package/examples/analytics-plugin/dist/client/index.js +173 -0
- package/examples/analytics-plugin/dist/index.d.ts +64 -0
- package/examples/analytics-plugin/dist/index.js +72 -0
- package/examples/analytics-plugin/dist/server/index.d.ts +119 -0
- package/examples/analytics-plugin/dist/server/index.js +313 -0
- package/examples/analytics-plugin/package.json +28 -0
- package/examples/analytics-plugin/src/client/index.tsx +410 -0
- package/examples/analytics-plugin/src/index.ts +71 -0
- package/examples/analytics-plugin/src/server/index.ts +348 -0
- package/examples/analytics-plugin/tsconfig.json +21 -0
- package/examples/blog-plugin/README.md +316 -0
- package/examples/blog-plugin/dist/client/index.d.ts +22 -0
- package/examples/blog-plugin/dist/client/index.js +197 -0
- package/examples/blog-plugin/dist/server/index.d.ts +5 -0
- package/examples/blog-plugin/dist/server/index.js +220 -0
- package/examples/blog-plugin/package.json +24 -0
- package/examples/blog-plugin/src/client/index.tsx +405 -0
- package/examples/blog-plugin/src/server/index.ts +240 -0
- package/examples/blog-plugin/tsconfig.json +16 -0
- package/examples/hello-world/README.md +101 -0
- package/examples/hello-world/dist/client/index.d.ts +5 -0
- package/examples/hello-world/dist/client/index.js +80 -0
- package/examples/hello-world/dist/server/index.d.ts +5 -0
- package/examples/hello-world/dist/server/index.js +38 -0
- package/examples/hello-world/node_modules/.package-lock.json +61 -0
- package/examples/hello-world/node_modules/@linyjs/client-module-interface/HOOKS_USAGE.md +281 -0
- package/examples/hello-world/node_modules/@linyjs/client-module-interface/IMPLEMENTATION_SUMMARY.md +166 -0
- package/examples/hello-world/node_modules/@linyjs/client-module-interface/QUICK_REFERENCE.md +130 -0
- package/examples/hello-world/node_modules/@linyjs/client-module-interface/README.md +214 -0
- package/examples/hello-world/node_modules/@linyjs/client-module-interface/package.json +26 -0
- package/examples/hello-world/node_modules/@linyjs/client-module-interface/src/application.ts +50 -0
- package/examples/hello-world/node_modules/@linyjs/client-module-interface/src/comparison-example.tsx +229 -0
- package/examples/hello-world/node_modules/@linyjs/client-module-interface/src/di.ts +127 -0
- package/examples/hello-world/node_modules/@linyjs/client-module-interface/src/domain.ts +52 -0
- package/examples/hello-world/node_modules/@linyjs/client-module-interface/src/hooks-example.tsx +275 -0
- package/examples/hello-world/node_modules/@linyjs/client-module-interface/src/hooks.ts +175 -0
- package/examples/hello-world/node_modules/@linyjs/client-module-interface/src/index.ts +87 -0
- package/examples/hello-world/node_modules/@linyjs/client-module-interface/src/interfaces.ts +117 -0
- package/examples/hello-world/node_modules/@linyjs/client-module-interface/src/router.ts +49 -0
- package/examples/hello-world/node_modules/@linyjs/client-module-interface/tsconfig.json +10 -0
- package/examples/hello-world/node_modules/@linyjs/server-module-interface/package.json +21 -0
- package/examples/hello-world/node_modules/@linyjs/server-module-interface/src/application.ts +21 -0
- package/examples/hello-world/node_modules/@linyjs/server-module-interface/src/di.ts +127 -0
- package/examples/hello-world/node_modules/@linyjs/server-module-interface/src/domain.ts +75 -0
- package/examples/hello-world/node_modules/@linyjs/server-module-interface/src/index.ts +55 -0
- package/examples/hello-world/node_modules/@linyjs/server-module-interface/src/interfaces.ts +58 -0
- package/examples/hello-world/node_modules/@linyjs/server-module-interface/tsconfig.json +8 -0
- package/examples/hello-world/node_modules/@types/react/LICENSE +21 -0
- package/examples/hello-world/node_modules/@types/react/README.md +15 -0
- package/examples/hello-world/node_modules/@types/react/canary.d.ts +129 -0
- package/examples/hello-world/node_modules/@types/react/compiler-runtime.d.ts +4 -0
- package/examples/hello-world/node_modules/@types/react/experimental.d.ts +184 -0
- package/examples/hello-world/node_modules/@types/react/global.d.ts +166 -0
- package/examples/hello-world/node_modules/@types/react/index.d.ts +4369 -0
- package/examples/hello-world/node_modules/@types/react/jsx-dev-runtime.d.ts +33 -0
- package/examples/hello-world/node_modules/@types/react/jsx-runtime.d.ts +24 -0
- package/examples/hello-world/node_modules/@types/react/package.json +210 -0
- package/examples/hello-world/node_modules/@types/react/ts5.0/canary.d.ts +129 -0
- package/examples/hello-world/node_modules/@types/react/ts5.0/experimental.d.ts +184 -0
- package/examples/hello-world/node_modules/@types/react/ts5.0/global.d.ts +166 -0
- package/examples/hello-world/node_modules/@types/react/ts5.0/index.d.ts +4356 -0
- package/examples/hello-world/node_modules/@types/react/ts5.0/jsx-dev-runtime.d.ts +33 -0
- package/examples/hello-world/node_modules/@types/react/ts5.0/jsx-runtime.d.ts +24 -0
- package/examples/hello-world/node_modules/csstype/LICENSE +19 -0
- package/examples/hello-world/node_modules/csstype/README.md +291 -0
- package/examples/hello-world/node_modules/csstype/index.d.ts +22569 -0
- package/examples/hello-world/node_modules/csstype/index.js.flow +6863 -0
- package/examples/hello-world/node_modules/csstype/package.json +70 -0
- package/examples/hello-world/node_modules/react/LICENSE +21 -0
- package/examples/hello-world/node_modules/react/README.md +37 -0
- package/examples/hello-world/node_modules/react/cjs/react-compiler-runtime.development.js +24 -0
- package/examples/hello-world/node_modules/react/cjs/react-compiler-runtime.production.js +16 -0
- package/examples/hello-world/node_modules/react/cjs/react-compiler-runtime.profiling.js +16 -0
- package/examples/hello-world/node_modules/react/cjs/react-jsx-dev-runtime.development.js +338 -0
- package/examples/hello-world/node_modules/react/cjs/react-jsx-dev-runtime.production.js +14 -0
- package/examples/hello-world/node_modules/react/cjs/react-jsx-dev-runtime.profiling.js +14 -0
- package/examples/hello-world/node_modules/react/cjs/react-jsx-dev-runtime.react-server.development.js +370 -0
- package/examples/hello-world/node_modules/react/cjs/react-jsx-dev-runtime.react-server.production.js +40 -0
- package/examples/hello-world/node_modules/react/cjs/react-jsx-runtime.development.js +352 -0
- package/examples/hello-world/node_modules/react/cjs/react-jsx-runtime.production.js +34 -0
- package/examples/hello-world/node_modules/react/cjs/react-jsx-runtime.profiling.js +34 -0
- package/examples/hello-world/node_modules/react/cjs/react-jsx-runtime.react-server.development.js +370 -0
- package/examples/hello-world/node_modules/react/cjs/react-jsx-runtime.react-server.production.js +40 -0
- package/examples/hello-world/node_modules/react/cjs/react.development.js +1284 -0
- package/examples/hello-world/node_modules/react/cjs/react.production.js +542 -0
- package/examples/hello-world/node_modules/react/cjs/react.react-server.development.js +848 -0
- package/examples/hello-world/node_modules/react/cjs/react.react-server.production.js +423 -0
- package/examples/hello-world/node_modules/react/compiler-runtime.js +14 -0
- package/examples/hello-world/node_modules/react/index.js +7 -0
- package/examples/hello-world/node_modules/react/jsx-dev-runtime.js +7 -0
- package/examples/hello-world/node_modules/react/jsx-dev-runtime.react-server.js +7 -0
- package/examples/hello-world/node_modules/react/jsx-runtime.js +7 -0
- package/examples/hello-world/node_modules/react/jsx-runtime.react-server.js +7 -0
- package/examples/hello-world/node_modules/react/package.json +51 -0
- package/examples/hello-world/node_modules/react/react.react-server.js +7 -0
- package/examples/hello-world/node_modules/typescript/LICENSE.txt +55 -0
- package/examples/hello-world/node_modules/typescript/README.md +50 -0
- package/examples/hello-world/node_modules/typescript/SECURITY.md +41 -0
- package/examples/hello-world/node_modules/typescript/ThirdPartyNoticeText.txt +193 -0
- package/examples/hello-world/node_modules/typescript/bin/tsc +2 -0
- package/examples/hello-world/node_modules/typescript/bin/tsserver +2 -0
- package/examples/hello-world/node_modules/typescript/lib/_tsc.js +133818 -0
- package/examples/hello-world/node_modules/typescript/lib/_tsserver.js +659 -0
- package/examples/hello-world/node_modules/typescript/lib/_typingsInstaller.js +222 -0
- package/examples/hello-world/node_modules/typescript/lib/cs/diagnosticMessages.generated.json +2122 -0
- package/examples/hello-world/node_modules/typescript/lib/de/diagnosticMessages.generated.json +2122 -0
- package/examples/hello-world/node_modules/typescript/lib/es/diagnosticMessages.generated.json +2122 -0
- package/examples/hello-world/node_modules/typescript/lib/fr/diagnosticMessages.generated.json +2122 -0
- package/examples/hello-world/node_modules/typescript/lib/it/diagnosticMessages.generated.json +2122 -0
- package/examples/hello-world/node_modules/typescript/lib/ja/diagnosticMessages.generated.json +2122 -0
- package/examples/hello-world/node_modules/typescript/lib/ko/diagnosticMessages.generated.json +2122 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.d.ts +22 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.decorators.d.ts +384 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.decorators.legacy.d.ts +22 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.dom.asynciterable.d.ts +41 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.dom.d.ts +39429 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.dom.iterable.d.ts +571 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es2015.collection.d.ts +147 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es2015.core.d.ts +597 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es2015.d.ts +28 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es2015.generator.d.ts +77 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es2015.iterable.d.ts +605 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es2015.promise.d.ts +81 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es2015.proxy.d.ts +128 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es2015.reflect.d.ts +144 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es2015.symbol.d.ts +46 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts +326 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es2016.array.include.d.ts +116 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es2016.d.ts +21 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es2016.full.d.ts +23 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es2016.intl.d.ts +31 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es2017.arraybuffer.d.ts +21 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es2017.d.ts +26 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es2017.date.d.ts +31 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es2017.full.d.ts +23 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es2017.intl.d.ts +44 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es2017.object.d.ts +49 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts +135 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es2017.string.d.ts +45 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es2017.typedarrays.d.ts +53 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts +77 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es2018.asynciterable.d.ts +53 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es2018.d.ts +24 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es2018.full.d.ts +24 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es2018.intl.d.ts +83 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es2018.promise.d.ts +30 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es2018.regexp.d.ts +37 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es2019.array.d.ts +79 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es2019.d.ts +24 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es2019.full.d.ts +24 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es2019.intl.d.ts +23 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es2019.object.d.ts +33 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es2019.string.d.ts +37 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es2019.symbol.d.ts +24 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es2020.bigint.d.ts +765 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es2020.d.ts +27 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es2020.date.d.ts +42 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es2020.full.d.ts +24 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es2020.intl.d.ts +474 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es2020.number.d.ts +28 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es2020.promise.d.ts +47 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts +99 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es2020.string.d.ts +44 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts +41 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es2021.d.ts +23 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es2021.full.d.ts +24 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es2021.intl.d.ts +166 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es2021.promise.d.ts +48 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es2021.string.d.ts +33 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es2021.weakref.d.ts +78 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es2022.array.d.ts +121 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es2022.d.ts +25 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es2022.error.d.ts +75 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es2022.full.d.ts +24 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es2022.intl.d.ts +145 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es2022.object.d.ts +26 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es2022.regexp.d.ts +39 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es2022.string.d.ts +25 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es2023.array.d.ts +924 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es2023.collection.d.ts +21 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es2023.d.ts +22 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es2023.full.d.ts +24 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es2023.intl.d.ts +56 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es2024.arraybuffer.d.ts +65 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es2024.collection.d.ts +29 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es2024.d.ts +26 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es2024.full.d.ts +24 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es2024.object.d.ts +29 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es2024.promise.d.ts +35 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es2024.regexp.d.ts +25 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es2024.sharedmemory.d.ts +68 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es2024.string.d.ts +29 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es5.d.ts +4601 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.es6.d.ts +23 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.esnext.array.d.ts +35 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.esnext.collection.d.ts +96 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.esnext.d.ts +29 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.esnext.decorators.d.ts +28 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.esnext.disposable.d.ts +193 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.esnext.error.d.ts +24 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.esnext.float16.d.ts +445 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.esnext.full.d.ts +24 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.esnext.intl.d.ts +21 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.esnext.iterator.d.ts +148 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.esnext.promise.d.ts +34 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.esnext.sharedmemory.d.ts +25 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.scripthost.d.ts +322 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.webworker.asynciterable.d.ts +41 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.webworker.d.ts +13150 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.webworker.importscripts.d.ts +23 -0
- package/examples/hello-world/node_modules/typescript/lib/lib.webworker.iterable.d.ts +340 -0
- package/examples/hello-world/node_modules/typescript/lib/pl/diagnosticMessages.generated.json +2122 -0
- package/examples/hello-world/node_modules/typescript/lib/pt-br/diagnosticMessages.generated.json +2122 -0
- package/examples/hello-world/node_modules/typescript/lib/ru/diagnosticMessages.generated.json +2122 -0
- package/examples/hello-world/node_modules/typescript/lib/tr/diagnosticMessages.generated.json +2122 -0
- package/examples/hello-world/node_modules/typescript/lib/tsc.js +8 -0
- package/examples/hello-world/node_modules/typescript/lib/tsserver.js +8 -0
- package/examples/hello-world/node_modules/typescript/lib/tsserverlibrary.d.ts +17 -0
- package/examples/hello-world/node_modules/typescript/lib/tsserverlibrary.js +21 -0
- package/examples/hello-world/node_modules/typescript/lib/typesMap.json +497 -0
- package/examples/hello-world/node_modules/typescript/lib/typescript.d.ts +11437 -0
- package/examples/hello-world/node_modules/typescript/lib/typescript.js +200276 -0
- package/examples/hello-world/node_modules/typescript/lib/typingsInstaller.js +8 -0
- package/examples/hello-world/node_modules/typescript/lib/watchGuard.js +53 -0
- package/examples/hello-world/node_modules/typescript/lib/zh-cn/diagnosticMessages.generated.json +2122 -0
- package/examples/hello-world/node_modules/typescript/lib/zh-tw/diagnosticMessages.generated.json +2122 -0
- package/examples/hello-world/node_modules/typescript/package.json +120 -0
- package/examples/hello-world/package-lock.json +74 -0
- package/examples/hello-world/package.json +23 -0
- package/examples/hello-world/src/client/index.tsx +110 -0
- package/examples/hello-world/src/server/index.ts +42 -0
- package/examples/hello-world/tsconfig.json +16 -0
- package/package.json +42 -0
- package/src/cli.ts +321 -0
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 客户端资源消费 Hooks
|
|
3
|
+
* 详见 [前端模块接口设计](../../spec/前端模块接口设计.md) - 资源消费章节
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { useContext } from 'react'
|
|
7
|
+
import type { IComponent } from './domain.js'
|
|
8
|
+
import {
|
|
9
|
+
ClientComponentsContext,
|
|
10
|
+
ClientServicesContext,
|
|
11
|
+
ClientHooksContext,
|
|
12
|
+
ClientRouterContext,
|
|
13
|
+
} from './interfaces.js'
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* 解析资源引用路径
|
|
17
|
+
*
|
|
18
|
+
* 支持两种格式:
|
|
19
|
+
* 1. 模块内引用:'serviceTag.name' → 需要当前模块名补全
|
|
20
|
+
* 2. 跨模块引用:'moduleName.serviceTag.name' → 直接使用
|
|
21
|
+
*
|
|
22
|
+
* @param refPath 引用路径
|
|
23
|
+
* @param currentModuleName 当前模块名称(可选)
|
|
24
|
+
* @returns 完整的 RegistryKey
|
|
25
|
+
*/
|
|
26
|
+
function resolveRegistryKey(refPath: string, currentModuleName?: string): string {
|
|
27
|
+
// 如果已经是完整路径(包含两个点),直接返回
|
|
28
|
+
const dotCount = (refPath.match(/\./g) || []).length
|
|
29
|
+
if (dotCount >= 2) {
|
|
30
|
+
return refPath
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// 模块内引用,需要补全模块名
|
|
34
|
+
if (currentModuleName) {
|
|
35
|
+
return `${currentModuleName}.${refPath}`
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// 如果没有提供模块名,假设用户传入的是完整路径
|
|
39
|
+
return refPath
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* 获取当前模块名称的 Hook
|
|
44
|
+
*
|
|
45
|
+
* 通过 React Context 或其他方式获取当前组件所属的模块名
|
|
46
|
+
* TODO: 未来可以通过 ModuleContext 提供
|
|
47
|
+
* 目前暂时返回 undefined,依赖用户显式传递完整路径
|
|
48
|
+
*/
|
|
49
|
+
function useCurrentModuleName(): string | undefined {
|
|
50
|
+
// TODO: 从 ModuleContext 获取当前模块名
|
|
51
|
+
// const moduleContext = useContext(ModuleContext)
|
|
52
|
+
// return moduleContext?.moduleName
|
|
53
|
+
return undefined
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* 使用客户端组件
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* // 模块内引用
|
|
61
|
+
* const Avatar = useClientComponent('userComponents.Avatar')
|
|
62
|
+
*
|
|
63
|
+
* // 跨模块引用
|
|
64
|
+
* const Avatar = useClientComponent('userModule.userComponents.Avatar')
|
|
65
|
+
*
|
|
66
|
+
* @param refPath 组件引用路径
|
|
67
|
+
* @returns React 组件
|
|
68
|
+
*/
|
|
69
|
+
export function useClientComponent<P = any>(refPath: string): IComponent<P> | undefined {
|
|
70
|
+
const components = useContext(ClientComponentsContext)
|
|
71
|
+
const currentModuleName = useCurrentModuleName()
|
|
72
|
+
|
|
73
|
+
const registryKey = resolveRegistryKey(refPath, currentModuleName)
|
|
74
|
+
const component = components[registryKey]
|
|
75
|
+
|
|
76
|
+
if (!component) {
|
|
77
|
+
console.warn(`[useClientComponent] Component not found: "${registryKey}"`)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return component as IComponent<P> | undefined
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* 使用客户端 Hook
|
|
85
|
+
*
|
|
86
|
+
* @example
|
|
87
|
+
* // 模块内引用
|
|
88
|
+
* const useAuth = useClientHook('authHooks.useAuth')
|
|
89
|
+
*
|
|
90
|
+
* // 跨模块引用
|
|
91
|
+
* const useAuth = useClientHook('authModule.authHooks.useAuth')
|
|
92
|
+
*
|
|
93
|
+
* @param refPath Hook 引用路径
|
|
94
|
+
* @returns Hook 函数
|
|
95
|
+
*/
|
|
96
|
+
export function useClientHook<T extends Function>(refPath: string): T | undefined {
|
|
97
|
+
const hooks = useContext(ClientHooksContext)
|
|
98
|
+
const currentModuleName = useCurrentModuleName()
|
|
99
|
+
|
|
100
|
+
const registryKey = resolveRegistryKey(refPath, currentModuleName)
|
|
101
|
+
const hook = hooks[registryKey]
|
|
102
|
+
|
|
103
|
+
if (!hook) {
|
|
104
|
+
console.warn(`[useClientHook] Hook not found: "${registryKey}"`)
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return hook as T | undefined
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* 使用客户端服务
|
|
112
|
+
*
|
|
113
|
+
* @example
|
|
114
|
+
* // 模块内引用
|
|
115
|
+
* const userService = useClientService<IUserService>('userService')
|
|
116
|
+
*
|
|
117
|
+
* // 跨模块引用
|
|
118
|
+
* const userService = useClientService<IUserService>('userModule.userService')
|
|
119
|
+
*
|
|
120
|
+
* @param refPath 服务引用路径
|
|
121
|
+
* @returns 服务实例
|
|
122
|
+
*/
|
|
123
|
+
export function useClientService<T = any>(refPath: string): T | undefined {
|
|
124
|
+
const services = useContext(ClientServicesContext)
|
|
125
|
+
const currentModuleName = useCurrentModuleName()
|
|
126
|
+
|
|
127
|
+
const registryKey = resolveRegistryKey(refPath, currentModuleName)
|
|
128
|
+
const service = services[registryKey]
|
|
129
|
+
|
|
130
|
+
if (!service) {
|
|
131
|
+
console.warn(`[useClientService] Service not found: "${registryKey}"`)
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return service as T | undefined
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* 使用客户端路由功能
|
|
139
|
+
*
|
|
140
|
+
* 根据传入的 key 返回对应的路由组件或 Hook:
|
|
141
|
+
* - 'NavLink' → NavLink 组件
|
|
142
|
+
* - 'Link' → Link 组件
|
|
143
|
+
* - 'useNavigate' → useNavigate Hook
|
|
144
|
+
* - 'useParams' → useParams Hook
|
|
145
|
+
* - 'useLocation' → useLocation Hook
|
|
146
|
+
* - 'useSearchParams' → useSearchParams Hook
|
|
147
|
+
*
|
|
148
|
+
* @example
|
|
149
|
+
* // 获取 NavLink 组件
|
|
150
|
+
* const NavLink = useClientRoute('NavLink')
|
|
151
|
+
*
|
|
152
|
+
* // 获取 useNavigate Hook
|
|
153
|
+
* const useNavigate = useClientRoute('useNavigate')
|
|
154
|
+
* const navigate = useNavigate()
|
|
155
|
+
*
|
|
156
|
+
* @param key 路由功能 key
|
|
157
|
+
* @returns 路由组件或 Hook
|
|
158
|
+
*/
|
|
159
|
+
export function useClientRoute(key: string): any {
|
|
160
|
+
const router = useContext(ClientRouterContext)
|
|
161
|
+
|
|
162
|
+
if (!router) {
|
|
163
|
+
console.warn('[useClientRoute] Router context is not available. Make sure RouterProvider is set up.')
|
|
164
|
+
return undefined
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// 从 router 中获取对应的组件或 Hook
|
|
168
|
+
const value = router[key]
|
|
169
|
+
|
|
170
|
+
if (!value) {
|
|
171
|
+
console.warn(`[useClientRoute] Route feature not found: "${key}". Available keys: ${Object.keys(router).join(', ')}`)
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
return value
|
|
175
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @linyjs/client-module-interface
|
|
3
|
+
*
|
|
4
|
+
* 前端模块接口定义
|
|
5
|
+
* 详见 [前端模块接口设计](../../spec/前端模块接口设计.md)
|
|
6
|
+
* 详见 [前端插件式架构设计](../../spec/前端插件式架构设计.md)
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
// 基础依赖注入类型
|
|
10
|
+
export type {
|
|
11
|
+
IService,
|
|
12
|
+
IServiceConstructor,
|
|
13
|
+
IServiceFactory,
|
|
14
|
+
IServiceMaker,
|
|
15
|
+
IServiceMetadata,
|
|
16
|
+
IServiceDef,
|
|
17
|
+
IModule,
|
|
18
|
+
ILoadedModule,
|
|
19
|
+
IModuleHandler,
|
|
20
|
+
IModuleContainer,
|
|
21
|
+
ModuleEventType,
|
|
22
|
+
IModuleEvent,
|
|
23
|
+
} from './di.js'
|
|
24
|
+
|
|
25
|
+
// 模块状态枚举(运行时值)
|
|
26
|
+
export { ModuleState } from './di.js'
|
|
27
|
+
|
|
28
|
+
// 前端领域类型
|
|
29
|
+
export type {
|
|
30
|
+
IComponent,
|
|
31
|
+
IRouteGuard,
|
|
32
|
+
IRouteLoader,
|
|
33
|
+
IRoute,
|
|
34
|
+
RegistryKey,
|
|
35
|
+
} from './domain.js'
|
|
36
|
+
|
|
37
|
+
// 路由适配器
|
|
38
|
+
export type {
|
|
39
|
+
IRouterOptions,
|
|
40
|
+
INavigateOptions,
|
|
41
|
+
IRouterAdapter,
|
|
42
|
+
} from './router.js'
|
|
43
|
+
export { RouterType } from './router.js'
|
|
44
|
+
|
|
45
|
+
// 服务接口、元数据、ServiceDef 组合类型
|
|
46
|
+
export type {
|
|
47
|
+
IAtom,
|
|
48
|
+
IRouteService,
|
|
49
|
+
IGlobalStateService,
|
|
50
|
+
IComponentListService,
|
|
51
|
+
IHooksService,
|
|
52
|
+
IClientServiceUsageType,
|
|
53
|
+
IRouteMetadata,
|
|
54
|
+
IGlobalStateMetadata,
|
|
55
|
+
IComponentListMetadata,
|
|
56
|
+
IHooksMetadata,
|
|
57
|
+
INormalServiceMetadata,
|
|
58
|
+
IRouteDef,
|
|
59
|
+
IGlobalStateDef,
|
|
60
|
+
IComponentListDef,
|
|
61
|
+
IHooksDef,
|
|
62
|
+
INormalServiceDef,
|
|
63
|
+
IClientServiceDef,
|
|
64
|
+
} from './interfaces.js'
|
|
65
|
+
|
|
66
|
+
// React Context(运行时值)
|
|
67
|
+
export {
|
|
68
|
+
ClientComponentsContext,
|
|
69
|
+
ClientGlobalStateContext,
|
|
70
|
+
ClientServicesContext,
|
|
71
|
+
ClientHooksContext,
|
|
72
|
+
ClientRouterContext,
|
|
73
|
+
} from './interfaces.js'
|
|
74
|
+
|
|
75
|
+
// 客户端应用接口
|
|
76
|
+
export type {
|
|
77
|
+
IClientRegistries,
|
|
78
|
+
IClientApplication,
|
|
79
|
+
} from './application.js'
|
|
80
|
+
|
|
81
|
+
// 资源消费 Hooks
|
|
82
|
+
export {
|
|
83
|
+
useClientComponent,
|
|
84
|
+
useClientHook,
|
|
85
|
+
useClientService,
|
|
86
|
+
useClientRoute,
|
|
87
|
+
} from './hooks.js'
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 前端服务接口、元数据类型、React Context、ServiceDef 组合类型
|
|
3
|
+
* 详见 [前端模块接口设计](../../spec/前端模块接口设计.md)
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { IServiceDef, IServiceMetadata } from './di.js'
|
|
7
|
+
import type { IRoute, IComponent } from './domain.js'
|
|
8
|
+
|
|
9
|
+
// ==================== jotai Atom 兼容类型 ====================
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* jotai Atom 兼容类型
|
|
13
|
+
* 避免直接依赖 jotai,使用者应使用 jotai 的 atom() 创建
|
|
14
|
+
* 此处仅做类型兼容,实际 Atom 结构由 jotai 保证
|
|
15
|
+
*/
|
|
16
|
+
export interface IAtom<T = any> {
|
|
17
|
+
readonly key: symbol
|
|
18
|
+
init?: T
|
|
19
|
+
[key: string]: unknown
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// ==================== 服务接口 ====================
|
|
23
|
+
|
|
24
|
+
/** 路由服务 — 声明页面路由 */
|
|
25
|
+
export interface IRouteService {
|
|
26
|
+
getRoutes(): IRoute[]
|
|
27
|
+
basePath?: string
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/** 全局状态服务 — 声明 jotai atoms */
|
|
31
|
+
export interface IGlobalStateService {
|
|
32
|
+
atoms: Record<string, IAtom>
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** 组件列表服务 — 声明可跨模块共享的组件 */
|
|
36
|
+
export interface IComponentListService {
|
|
37
|
+
components: Record<string, IComponent>
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** Hooks 服务 — 声明可跨模块共享的 hooks */
|
|
41
|
+
export interface IHooksService {
|
|
42
|
+
hooks: Record<string, Function>
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// ==================== 元数据类型 ====================
|
|
46
|
+
|
|
47
|
+
/** 前端服务用途类型 */
|
|
48
|
+
export type IClientServiceUsageType = 'route' | 'global_state' | 'component' | 'hook' | 'normal_service'
|
|
49
|
+
|
|
50
|
+
/** 路由元数据 */
|
|
51
|
+
export interface IRouteMetadata extends IServiceMetadata {
|
|
52
|
+
usageType: 'route'
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** 全局状态元数据 */
|
|
56
|
+
export interface IGlobalStateMetadata extends IServiceMetadata {
|
|
57
|
+
usageType: 'global_state'
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** 组件列表元数据 */
|
|
61
|
+
export interface IComponentListMetadata extends IServiceMetadata {
|
|
62
|
+
usageType: 'component'
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/** Hooks 元数据 */
|
|
66
|
+
export interface IHooksMetadata extends IServiceMetadata {
|
|
67
|
+
usageType: 'hook'
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/** 普通服务元数据 */
|
|
71
|
+
export interface INormalServiceMetadata extends IServiceMetadata {
|
|
72
|
+
usageType: 'normal_service'
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// ==================== ServiceDef 组合类型 ====================
|
|
76
|
+
|
|
77
|
+
/** 路由服务定义 */
|
|
78
|
+
export type IRouteDef = IServiceDef<IRouteService, IRouteMetadata>
|
|
79
|
+
|
|
80
|
+
/** 全局状态服务定义 */
|
|
81
|
+
export type IGlobalStateDef = IServiceDef<IGlobalStateService, IGlobalStateMetadata>
|
|
82
|
+
|
|
83
|
+
/** 组件列表服务定义 */
|
|
84
|
+
export type IComponentListDef = IServiceDef<IComponentListService, IComponentListMetadata>
|
|
85
|
+
|
|
86
|
+
/** Hooks 服务定义 */
|
|
87
|
+
export type IHooksDef = IServiceDef<IHooksService, IHooksMetadata>
|
|
88
|
+
|
|
89
|
+
/** 普通服务定义 */
|
|
90
|
+
export type INormalServiceDef = IServiceDef<any, INormalServiceMetadata>
|
|
91
|
+
|
|
92
|
+
/** 前端 ServiceDef 联合类型 */
|
|
93
|
+
export type IClientServiceDef =
|
|
94
|
+
| IRouteDef
|
|
95
|
+
| IGlobalStateDef
|
|
96
|
+
| IComponentListDef
|
|
97
|
+
| IHooksDef
|
|
98
|
+
| INormalServiceDef
|
|
99
|
+
|
|
100
|
+
// ==================== React Context ====================
|
|
101
|
+
|
|
102
|
+
import { createContext } from 'react'
|
|
103
|
+
|
|
104
|
+
/** 组件注册表 Context */
|
|
105
|
+
export const ClientComponentsContext = createContext<Record<string, IComponent>>({})
|
|
106
|
+
|
|
107
|
+
/** 全局状态 Context(jotai atoms) */
|
|
108
|
+
export const ClientGlobalStateContext = createContext<Record<string, IAtom>>({})
|
|
109
|
+
|
|
110
|
+
/** 服务注册表 Context */
|
|
111
|
+
export const ClientServicesContext = createContext<Record<string, any>>({})
|
|
112
|
+
|
|
113
|
+
/** Hooks 注册表 Context */
|
|
114
|
+
export const ClientHooksContext = createContext<Record<string, Function>>({})
|
|
115
|
+
|
|
116
|
+
/** 路由适配器 Context */
|
|
117
|
+
export const ClientRouterContext = createContext<any>(null)
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 路由适配器
|
|
3
|
+
* 详见 [前端模块接口设计](../../spec/前端模块接口设计.md)
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { IRoute } from './domain.js'
|
|
7
|
+
|
|
8
|
+
/** 路由器类型枚举 */
|
|
9
|
+
export enum RouterType {
|
|
10
|
+
REACT_ROUTER = 'react-router',
|
|
11
|
+
WECHAT_MINI_PROGRAM = 'wechat-mini-program',
|
|
12
|
+
CUSTOM = 'custom',
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/** 路由器配置选项 */
|
|
16
|
+
export interface IRouterOptions {
|
|
17
|
+
/** 路由基础路径 */
|
|
18
|
+
basename?: string
|
|
19
|
+
/** 其他配置 */
|
|
20
|
+
[key: string]: unknown
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** 导航选项 */
|
|
24
|
+
export interface INavigateOptions {
|
|
25
|
+
replace?: boolean
|
|
26
|
+
state?: unknown
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** 路由适配器接口 */
|
|
30
|
+
export interface IRouterAdapter {
|
|
31
|
+
/** 初始化路由 */
|
|
32
|
+
init(routes: IRoute[], options?: IRouterOptions): void
|
|
33
|
+
/** 获取路由组件(用于渲染到 React 树中) */
|
|
34
|
+
getRouterComponent(): import('react').ComponentType
|
|
35
|
+
/** 编程式导航 */
|
|
36
|
+
navigate(to: string, options?: INavigateOptions): void
|
|
37
|
+
/** 返回上一页 */
|
|
38
|
+
goBack(): void
|
|
39
|
+
/** 前进到下一页 */
|
|
40
|
+
goForward(): void
|
|
41
|
+
/** 获取当前位置 */
|
|
42
|
+
getCurrentLocation(): Location
|
|
43
|
+
/** 监听位置变化 */
|
|
44
|
+
listen(listener: (location: Location) => void): () => void
|
|
45
|
+
/** 获取路由参数 */
|
|
46
|
+
getParams(): Record<string, string>
|
|
47
|
+
/** 获取查询参数 */
|
|
48
|
+
getSearchParams(): URLSearchParams
|
|
49
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@linyjs/server-module-interface",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"types": "./dist/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"import": "./dist/index.js",
|
|
11
|
+
"default": "./dist/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"scripts": {
|
|
15
|
+
"build": "tsc -b",
|
|
16
|
+
"clean": "rm -rf dist *.tsbuildinfo"
|
|
17
|
+
},
|
|
18
|
+
"devDependencies": {
|
|
19
|
+
"typescript": "^5.7.0"
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 服务端应用接口
|
|
3
|
+
* 详见 [服务端插件式架构设计](../../spec/服务端插件式架构设计.md)
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { IModule, IModuleHandler, IModuleContainer } from './di.js'
|
|
7
|
+
|
|
8
|
+
/** 服务端应用接口 */
|
|
9
|
+
export interface IServerApplication {
|
|
10
|
+
/** 设置模块生命周期处理器 */
|
|
11
|
+
setHandler(handler: IModuleHandler): void
|
|
12
|
+
|
|
13
|
+
/** 加载一组模块,按依赖拓扑排序后由容器实例化服务 */
|
|
14
|
+
loadModules(modules: IModule[]): Promise<void>
|
|
15
|
+
|
|
16
|
+
/** 获取服务实例 */
|
|
17
|
+
getService<T>(moduleName: string, serviceTag: string): T
|
|
18
|
+
|
|
19
|
+
/** 销毁所有已加载模块(逆序调用 handler.onModuleUnloaded) */
|
|
20
|
+
destroyAll(): Promise<void>
|
|
21
|
+
}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 基础依赖注入类型定义
|
|
3
|
+
* 详见 [依赖注入机制设计](../../spec/依赖注入机制设计.md)
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/** 所有服务的基础类型 */
|
|
7
|
+
export type IService = object
|
|
8
|
+
|
|
9
|
+
/** 服务类构造器类型 */
|
|
10
|
+
export interface IServiceConstructor<S extends IService> {
|
|
11
|
+
new (...args: any[]): S
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/** 服务工厂函数类型 */
|
|
15
|
+
export type IServiceFactory<S extends IService> = (...args: any[]) => S
|
|
16
|
+
|
|
17
|
+
/** 服务实现类型(类或工厂函数) */
|
|
18
|
+
export type IServiceMaker<S extends IService> =
|
|
19
|
+
| IServiceConstructor<S>
|
|
20
|
+
| IServiceFactory<S>
|
|
21
|
+
|
|
22
|
+
/** 服务元数据基础类型 */
|
|
23
|
+
export type IServiceMetadata = Record<string, any>
|
|
24
|
+
|
|
25
|
+
/** 服务定义 */
|
|
26
|
+
export interface IServiceDef<
|
|
27
|
+
S extends IService = IService,
|
|
28
|
+
M extends IServiceMetadata = IServiceMetadata
|
|
29
|
+
> {
|
|
30
|
+
/** 服务唯一标识(模块内唯一) */
|
|
31
|
+
serviceTag: string
|
|
32
|
+
/** 服务实现,可以是类或工厂函数 */
|
|
33
|
+
serviceImpl: IServiceMaker<S>
|
|
34
|
+
/** 依赖的其他服务列表,支持 'serviceTag' 或 'moduleName.serviceTag' 格式 */
|
|
35
|
+
dependencies?: string[]
|
|
36
|
+
/** 元数据 */
|
|
37
|
+
meta?: M
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** 模块定义 */
|
|
41
|
+
export interface IModule {
|
|
42
|
+
/** 模块名称 */
|
|
43
|
+
name: string
|
|
44
|
+
/** 依赖的其他模块名称 */
|
|
45
|
+
moduleDependencies?: string[]
|
|
46
|
+
/** 服务定义列表 */
|
|
47
|
+
serviceDefs: IServiceDef[]
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// ==================== 模块状态与事件 ====================
|
|
51
|
+
|
|
52
|
+
/** 模块状态枚举 */
|
|
53
|
+
export enum ModuleState {
|
|
54
|
+
Unloaded = 'unloaded',
|
|
55
|
+
Loading = 'loading',
|
|
56
|
+
Loaded = 'loaded',
|
|
57
|
+
Error = 'error',
|
|
58
|
+
Unloading = 'unloading',
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/** 模块事件类型 */
|
|
62
|
+
export type ModuleEventType =
|
|
63
|
+
| 'module_loaded'
|
|
64
|
+
| 'module_unloaded'
|
|
65
|
+
| 'module_error'
|
|
66
|
+
| 'module_state_changed'
|
|
67
|
+
|
|
68
|
+
/** 模块事件 */
|
|
69
|
+
export interface IModuleEvent {
|
|
70
|
+
type: ModuleEventType
|
|
71
|
+
moduleName: string
|
|
72
|
+
module?: ILoadedModule
|
|
73
|
+
error?: Error
|
|
74
|
+
timestamp: number
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** 已加载模块的运行时表示 */
|
|
78
|
+
export interface ILoadedModule {
|
|
79
|
+
/** 模块名称 */
|
|
80
|
+
name: string
|
|
81
|
+
/** 模块状态 */
|
|
82
|
+
state: ModuleState
|
|
83
|
+
/** 服务实例映射表 */
|
|
84
|
+
services: Map<string, IService>
|
|
85
|
+
/** 源模块定义 */
|
|
86
|
+
sourceModule?: IModule
|
|
87
|
+
/** 加载时间戳 */
|
|
88
|
+
loadedAt?: number
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/** 模块生命周期处理器 */
|
|
92
|
+
export interface IModuleHandler {
|
|
93
|
+
/** 模块加载完成后执行 */
|
|
94
|
+
onModuleLoaded?(module: ILoadedModule): void | Promise<void>
|
|
95
|
+
/** 模块卸载后执行 */
|
|
96
|
+
onModuleUnloaded?(module: ILoadedModule): void | Promise<void>
|
|
97
|
+
/** 模块加载错误时执行 */
|
|
98
|
+
onModuleError?(moduleName: string, error: Error): void | Promise<void>
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/** 模块容器接口 */
|
|
102
|
+
export interface IModuleContainer {
|
|
103
|
+
/** 设置模块生命周期处理器 */
|
|
104
|
+
setModuleHandler(handler: IModuleHandler): void
|
|
105
|
+
|
|
106
|
+
/** 加载模块 */
|
|
107
|
+
loadModules(modules: IModule[]): Promise<void>
|
|
108
|
+
|
|
109
|
+
/** 卸载模块 */
|
|
110
|
+
unloadModule(moduleName: string): Promise<void>
|
|
111
|
+
/** 重新加载模块 */
|
|
112
|
+
reloadModule(moduleName: string, newModule?: IModule): Promise<void>
|
|
113
|
+
|
|
114
|
+
/** 检查模块是否已加载 */
|
|
115
|
+
isModuleLoaded(moduleName: string): boolean
|
|
116
|
+
/** 获取已加载模块 */
|
|
117
|
+
getLoadedModule(moduleName: string): ILoadedModule | undefined
|
|
118
|
+
/** 获取模块状态 */
|
|
119
|
+
getModuleState(moduleName: string): ModuleState
|
|
120
|
+
/** 获取服务实例 */
|
|
121
|
+
getService<T>(moduleName: string, serviceTag: string): T
|
|
122
|
+
|
|
123
|
+
/** 监听模块事件 */
|
|
124
|
+
on(event: ModuleEventType, listener: (event: IModuleEvent) => void): void
|
|
125
|
+
/** 取消监听模块事件 */
|
|
126
|
+
off(event: ModuleEventType, listener: (event: IModuleEvent) => void): void
|
|
127
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 服务端领域类型
|
|
3
|
+
* 详见 [服务端模块接口设计](../../spec/服务端模块接口设计.md)
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/** 路由上下文 — 由中间件逐步填充的可变上下文 */
|
|
7
|
+
export interface IRouteContext {
|
|
8
|
+
[key: string]: unknown
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/** 中间件 next 函数 */
|
|
12
|
+
export type INextFunction = () => void | Promise<void>
|
|
13
|
+
|
|
14
|
+
/** 路由处理函数返回值 - 根据 responseType 自动推断 */
|
|
15
|
+
export type IRouteHandlerResult =
|
|
16
|
+
| any // responseType='json': 直接返回任意数据
|
|
17
|
+
| string // responseType='file': 返回文件路径(简单场景)
|
|
18
|
+
| { filePath: string; filename?: string; contentType?: string } // responseType='file': 完整配置
|
|
19
|
+
| NodeJS.ReadableStream // responseType='video_stream': 返回流对象
|
|
20
|
+
| { data: any; status?: number } // responseType='json': 带状态码的响应
|
|
21
|
+
| void // 无返回值
|
|
22
|
+
|
|
23
|
+
/** 路由处理函数 */
|
|
24
|
+
export type IRouteHandler = (
|
|
25
|
+
params: Record<string, any>,
|
|
26
|
+
ctx: IRouteContext
|
|
27
|
+
) => IRouteHandlerResult | Promise<IRouteHandlerResult>
|
|
28
|
+
|
|
29
|
+
/** 中间件处理函数 */
|
|
30
|
+
export type IMiddlewareHandler = (
|
|
31
|
+
params: Record<string, any>,
|
|
32
|
+
ctx: IRouteContext,
|
|
33
|
+
next: INextFunction
|
|
34
|
+
) => void | Promise<void>
|
|
35
|
+
|
|
36
|
+
/** 路由 */
|
|
37
|
+
export interface IRoute {
|
|
38
|
+
method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH'
|
|
39
|
+
path: string
|
|
40
|
+
/**
|
|
41
|
+
* 中间件引用列表,元素为 IMiddleware.middlewareId。
|
|
42
|
+
* 解析规则:
|
|
43
|
+
* - 裸 ID(如 'auth'):优先在当前模块内查找,找不到则按模块依赖顺序向外查找
|
|
44
|
+
* - 跨模块引用(如 'security.auth'):显式指定 moduleName,格式为 "moduleName.middlewareId"
|
|
45
|
+
* - 引用的 middlewareId 不存在时,Handler 应在加载阶段抛出错误,拒绝注册该路由
|
|
46
|
+
* - 数组顺序即执行顺序,按从前到后依次调用
|
|
47
|
+
*/
|
|
48
|
+
middlewares: string[]
|
|
49
|
+
handler: IRouteHandler
|
|
50
|
+
/**
|
|
51
|
+
* 响应类型声明(可选),用于框架层自动处理响应格式化
|
|
52
|
+
* - 'json': 自动序列化为 JSON,设置 Content-Type: application/json
|
|
53
|
+
* - 'file': 自动发送文件,支持断点续传
|
|
54
|
+
* - 'video_stream': 流式传输视频,支持 range 请求
|
|
55
|
+
*
|
|
56
|
+
* 如果未指定,框架会根据 handler 返回值的 type 字段自动推断
|
|
57
|
+
*/
|
|
58
|
+
responseType?: 'json' | 'file' | 'video_stream'
|
|
59
|
+
meta?: Record<string, any>
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** 中间件 */
|
|
63
|
+
export interface IMiddleware {
|
|
64
|
+
/** 中间件唯一标识,模块内唯一。跨模块引用时通过 "moduleName.middlewareId" 定位 */
|
|
65
|
+
middlewareId: string
|
|
66
|
+
handler: IMiddlewareHandler
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/** 定时任务 */
|
|
70
|
+
export interface ICronJob {
|
|
71
|
+
name: string
|
|
72
|
+
/** cron 表达式 */
|
|
73
|
+
schedule: string
|
|
74
|
+
run(): Promise<void>
|
|
75
|
+
}
|