@real-router/ssr-data-plugin 0.3.2 → 0.3.4
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 +6 -5
- package/dist/cjs/index.d.ts +2 -3
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +1 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/index.d.mts +2 -3
- package/dist/esm/index.d.mts.map +1 -1
- package/dist/esm/index.mjs +1 -1
- package/dist/esm/index.mjs.map +1 -1
- package/package.json +3 -3
- package/src/factory.ts +10 -52
- package/src/validation.ts +2 -23
package/README.md
CHANGED
|
@@ -108,11 +108,12 @@ In SSR, `router.dispose()` handles cleanup automatically.
|
|
|
108
108
|
|
|
109
109
|
## Related Packages
|
|
110
110
|
|
|
111
|
-
| Package
|
|
112
|
-
|
|
|
113
|
-
| [@real-router/core](https://www.npmjs.com/package/@real-router/core)
|
|
114
|
-
| [@real-router/
|
|
115
|
-
| [@real-router/
|
|
111
|
+
| Package | Description |
|
|
112
|
+
| ------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------- |
|
|
113
|
+
| [@real-router/core](https://www.npmjs.com/package/@real-router/core) | Core router (required peer dependency) |
|
|
114
|
+
| [@real-router/rsc-server-plugin](https://www.npmjs.com/package/@real-router/rsc-server-plugin) | Sibling plugin — same `start()` interceptor pattern but for `ReactNode` (RSC payload). Runs side-by-side on the same router with distinct namespaces (`data` vs `rsc`). |
|
|
115
|
+
| [@real-router/browser-plugin](https://www.npmjs.com/package/@real-router/browser-plugin) | Browser History API integration |
|
|
116
|
+
| [@real-router/react](https://www.npmjs.com/package/@real-router/react) | React bindings |
|
|
116
117
|
|
|
117
118
|
## License
|
|
118
119
|
|
package/dist/cjs/index.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { DefaultDependencies, Params, Router } from "@real-router/types";
|
|
2
|
-
import { PluginFactory } from "@real-router/core";
|
|
1
|
+
import { DefaultDependencies, Params, PluginFactory, Router } from "@real-router/types";
|
|
3
2
|
|
|
4
3
|
//#region src/types.d.ts
|
|
5
4
|
type DataLoaderFn = (params: Params) => Promise<unknown>;
|
|
@@ -16,7 +15,7 @@ type DataLoaderFnFactory<Dependencies extends DefaultDependencies = DefaultDepen
|
|
|
16
15
|
type DataLoaderFactoryMap<Dependencies extends DefaultDependencies = DefaultDependencies> = Record<string, DataLoaderFnFactory<Dependencies>>;
|
|
17
16
|
//#endregion
|
|
18
17
|
//#region src/factory.d.ts
|
|
19
|
-
declare function ssrDataPluginFactory(loaders: DataLoaderFactoryMap): PluginFactory
|
|
18
|
+
declare function ssrDataPluginFactory<Dependencies extends DefaultDependencies = DefaultDependencies>(loaders: DataLoaderFactoryMap<Dependencies>): PluginFactory<Dependencies>;
|
|
20
19
|
//#endregion
|
|
21
20
|
//#region src/index.d.ts
|
|
22
21
|
declare module "@real-router/types" {
|
package/dist/cjs/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../../src/types.ts","../../src/factory.ts","../../src/index.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../../src/types.ts","../../src/factory.ts","../../src/index.ts"],"mappings":";;;KAEY,YAAA,IAAgB,MAAA,EAAQ,MAAA,KAAW,OAAA;;AAA/C;;;;;;;;KAWY,mBAAA,sBACW,mBAAA,GAAsB,mBAAA,KAE3C,MAAA,EAAQ,MAAA,CAAO,YAAA,GACf,aAAA,mBAAgC,YAAA,EAAc,GAAA,EAAK,CAAA,KAAM,YAAA,CAAa,CAAA,MACnE,YAAA;AAAA,KAEO,oBAAA,sBACW,mBAAA,GAAsB,mBAAA,IACzC,MAAA,SAAe,mBAAA,CAAoB,YAAA;;;iBCfvB,oBAAA,sBACO,mBAAA,GAAsB,mBAAA,CAAA,CAC3C,OAAA,EAAS,oBAAA,CAAqB,YAAA,IAAgB,aAAA,CAAc,YAAA;;;;YCAlD,YAAA;IACR,IAAA;EAAA;AAAA"}
|
package/dist/cjs/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require(`@real-router/core/api`);const t=`[@real-router/ssr-data-plugin]`;function n(
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require(`@real-router/core/api`);const t=`[@real-router/ssr-data-plugin]`;function n(t,n){return(r,i)=>{let a=(0,e.getPluginApi)(r),o=a.claimContextNamespace(n.namespace),s=new Map;try{for(let[e,a]of Object.entries(t)){let t=a(r,i);if(typeof t!=`function`)throw TypeError(`${n.errorPrefix} factory for route "${e}" must return a function`);s.set(e,t)}}catch(e){throw o.release(),e}let c=a.addInterceptor(`start`,async(e,t)=>{let n=await e(t),r=s.get(n.name);return r&&o.write(n,await r(n.params)),n});return{teardown(){c(),o.release()}}}}function r(e){return function(t){if(typeof t!=`object`||!t||Array.isArray(t))throw TypeError(`${e} loaders must be a non-null object`);for(let[n,r]of Object.entries(t))if(typeof r!=`function`)throw TypeError(`${e} loader for route "${n}" must be a function`)}}const i=r(t);function a(e){return i(e),n(e,{namespace:`data`,errorPrefix:t})}exports.ssrDataPluginFactory=a;
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/dist/cjs/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../src/constants.ts","../../src/validation.ts","../../src/factory.ts"],"sourcesContent":["const LOGGER_CONTEXT = \"ssr-data-plugin\";\n\nexport const ERROR_PREFIX = `[@real-router/${LOGGER_CONTEXT}]`;\n","import {
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/constants.ts","../../../../shared/ssr/createSsrLoaderPlugin.ts","../../../../shared/ssr/createLoadersValidator.ts","../../src/validation.ts","../../src/factory.ts"],"sourcesContent":["const LOGGER_CONTEXT = \"ssr-data-plugin\";\n\nexport const ERROR_PREFIX = `[@real-router/${LOGGER_CONTEXT}]`;\n","import { getPluginApi } from \"@real-router/core/api\";\n\nimport type {\n SsrLoaderFactoryMap,\n SsrLoaderFn,\n SsrLoaderPluginConfig,\n} from \"./types.js\";\nimport type {\n DefaultDependencies,\n Plugin,\n PluginFactory,\n} from \"@real-router/types\";\n\nexport function createSsrLoaderPlugin<\n T,\n Dependencies extends DefaultDependencies = DefaultDependencies,\n>(\n loaders: SsrLoaderFactoryMap<T, Dependencies>,\n config: SsrLoaderPluginConfig,\n): PluginFactory<Dependencies> {\n return (router, getDependency): Plugin => {\n const api = getPluginApi(router);\n const claim = api.claimContextNamespace(config.namespace);\n\n const compiledLoaders = new Map<string, SsrLoaderFn<T>>();\n\n try {\n for (const [name, factory] of Object.entries(loaders)) {\n const loader = factory(router, getDependency);\n\n if (typeof loader !== \"function\") {\n throw new TypeError(\n `${config.errorPrefix} factory for route \"${name}\" must return a function`,\n );\n }\n\n compiledLoaders.set(name, loader);\n }\n } catch (error) {\n claim.release();\n\n throw error;\n }\n\n const removeStartInterceptor = api.addInterceptor(\n \"start\",\n async (next, path) => {\n const state = await next(path);\n const loader = compiledLoaders.get(state.name);\n\n if (loader) {\n claim.write(state, await loader(state.params));\n }\n\n return state;\n },\n );\n\n return {\n teardown() {\n removeStartInterceptor();\n claim.release();\n },\n };\n };\n}\n","export function createLoadersValidator(errorPrefix: string) {\n return function validateLoaders(loaders: unknown): void {\n if (\n loaders === null ||\n typeof loaders !== \"object\" ||\n Array.isArray(loaders)\n ) {\n throw new TypeError(`${errorPrefix} loaders must be a non-null object`);\n }\n\n for (const [key, value] of Object.entries(\n loaders as Record<string, unknown>,\n )) {\n if (typeof value !== \"function\") {\n throw new TypeError(\n `${errorPrefix} loader for route \"${key}\" must be a function`,\n );\n }\n }\n };\n}\n","import { ERROR_PREFIX } from \"./constants\";\nimport { createLoadersValidator } from \"./shared-ssr\";\n\nexport const validateLoaders = createLoadersValidator(ERROR_PREFIX);\n","import { ERROR_PREFIX } from \"./constants\";\nimport { createSsrLoaderPlugin } from \"./shared-ssr\";\nimport { validateLoaders } from \"./validation\";\n\nimport type { DataLoaderFactoryMap } from \"./types\";\nimport type { DefaultDependencies, PluginFactory } from \"@real-router/types\";\n\nexport function ssrDataPluginFactory<\n Dependencies extends DefaultDependencies = DefaultDependencies,\n>(loaders: DataLoaderFactoryMap<Dependencies>): PluginFactory<Dependencies> {\n validateLoaders(loaders);\n\n return createSsrLoaderPlugin<unknown, Dependencies>(loaders, {\n namespace: \"data\",\n errorPrefix: ERROR_PREFIX,\n });\n}\n"],"mappings":"0GAAA,MAEa,EAAe,iCCW5B,SAAgB,EAId,EACA,EAC6B,CAC7B,OAAQ,EAAQ,IAA0B,CACxC,IAAM,GAAA,EAAA,EAAA,cAAmB,EAAO,CAC1B,EAAQ,EAAI,sBAAsB,EAAO,UAAU,CAEnD,EAAkB,IAAI,IAE5B,GAAI,CACF,IAAK,GAAM,CAAC,EAAM,KAAY,OAAO,QAAQ,EAAQ,CAAE,CACrD,IAAM,EAAS,EAAQ,EAAQ,EAAc,CAE7C,GAAI,OAAO,GAAW,WACpB,MAAU,UACR,GAAG,EAAO,YAAY,sBAAsB,EAAK,0BAClD,CAGH,EAAgB,IAAI,EAAM,EAAO,QAE5B,EAAO,CAGd,MAFA,EAAM,SAAS,CAET,EAGR,IAAM,EAAyB,EAAI,eACjC,QACA,MAAO,EAAM,IAAS,CACpB,IAAM,EAAQ,MAAM,EAAK,EAAK,CACxB,EAAS,EAAgB,IAAI,EAAM,KAAK,CAM9C,OAJI,GACF,EAAM,MAAM,EAAO,MAAM,EAAO,EAAM,OAAO,CAAC,CAGzC,GAEV,CAED,MAAO,CACL,UAAW,CACT,GAAwB,CACxB,EAAM,SAAS,EAElB,EC/DL,SAAgB,EAAuB,EAAqB,CAC1D,OAAO,SAAyB,EAAwB,CACtD,GAEE,OAAO,GAAY,WADnB,GAEA,MAAM,QAAQ,EAAQ,CAEtB,MAAU,UAAU,GAAG,EAAY,oCAAoC,CAGzE,IAAK,GAAM,CAAC,EAAK,KAAU,OAAO,QAChC,EACD,CACC,GAAI,OAAO,GAAU,WACnB,MAAU,UACR,GAAG,EAAY,qBAAqB,EAAI,sBACzC,ECbT,MAAa,EAAkB,EAAuB,EAAa,CCInE,SAAgB,EAEd,EAA0E,CAG1E,OAFA,EAAgB,EAAQ,CAEjB,EAA6C,EAAS,CAC3D,UAAW,OACX,YAAa,EACd,CAAC"}
|
package/dist/esm/index.d.mts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { DefaultDependencies, Params, Router } from "@real-router/types";
|
|
2
|
-
import { PluginFactory } from "@real-router/core";
|
|
1
|
+
import { DefaultDependencies, Params, PluginFactory, Router } from "@real-router/types";
|
|
3
2
|
|
|
4
3
|
//#region src/types.d.ts
|
|
5
4
|
type DataLoaderFn = (params: Params) => Promise<unknown>;
|
|
@@ -16,7 +15,7 @@ type DataLoaderFnFactory<Dependencies extends DefaultDependencies = DefaultDepen
|
|
|
16
15
|
type DataLoaderFactoryMap<Dependencies extends DefaultDependencies = DefaultDependencies> = Record<string, DataLoaderFnFactory<Dependencies>>;
|
|
17
16
|
//#endregion
|
|
18
17
|
//#region src/factory.d.ts
|
|
19
|
-
declare function ssrDataPluginFactory(loaders: DataLoaderFactoryMap): PluginFactory
|
|
18
|
+
declare function ssrDataPluginFactory<Dependencies extends DefaultDependencies = DefaultDependencies>(loaders: DataLoaderFactoryMap<Dependencies>): PluginFactory<Dependencies>;
|
|
20
19
|
//#endregion
|
|
21
20
|
//#region src/index.d.ts
|
|
22
21
|
declare module "@real-router/types" {
|
package/dist/esm/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/types.ts","../../src/factory.ts","../../src/index.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/types.ts","../../src/factory.ts","../../src/index.ts"],"mappings":";;;KAEY,YAAA,IAAgB,MAAA,EAAQ,MAAA,KAAW,OAAA;;AAA/C;;;;;;;;KAWY,mBAAA,sBACW,mBAAA,GAAsB,mBAAA,KAE3C,MAAA,EAAQ,MAAA,CAAO,YAAA,GACf,aAAA,mBAAgC,YAAA,EAAc,GAAA,EAAK,CAAA,KAAM,YAAA,CAAa,CAAA,MACnE,YAAA;AAAA,KAEO,oBAAA,sBACW,mBAAA,GAAsB,mBAAA,IACzC,MAAA,SAAe,mBAAA,CAAoB,YAAA;;;iBCfvB,oBAAA,sBACO,mBAAA,GAAsB,mBAAA,CAAA,CAC3C,OAAA,EAAS,oBAAA,CAAqB,YAAA,IAAgB,aAAA,CAAc,YAAA;;;;YCAlD,YAAA;IACR,IAAA;EAAA;AAAA"}
|
package/dist/esm/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{getPluginApi as e}from"@real-router/core/api";const t=`[@real-router/ssr-data-plugin]`;function n(
|
|
1
|
+
import{getPluginApi as e}from"@real-router/core/api";const t=`[@real-router/ssr-data-plugin]`;function n(t,n){return(r,i)=>{let a=e(r),o=a.claimContextNamespace(n.namespace),s=new Map;try{for(let[e,a]of Object.entries(t)){let t=a(r,i);if(typeof t!=`function`)throw TypeError(`${n.errorPrefix} factory for route "${e}" must return a function`);s.set(e,t)}}catch(e){throw o.release(),e}let c=a.addInterceptor(`start`,async(e,t)=>{let n=await e(t),r=s.get(n.name);return r&&o.write(n,await r(n.params)),n});return{teardown(){c(),o.release()}}}}function r(e){return function(t){if(typeof t!=`object`||!t||Array.isArray(t))throw TypeError(`${e} loaders must be a non-null object`);for(let[n,r]of Object.entries(t))if(typeof r!=`function`)throw TypeError(`${e} loader for route "${n}" must be a function`)}}const i=r(t);function a(e){return i(e),n(e,{namespace:`data`,errorPrefix:t})}export{a as ssrDataPluginFactory};
|
|
2
2
|
//# sourceMappingURL=index.mjs.map
|
package/dist/esm/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../../src/constants.ts","../../src/validation.ts","../../src/factory.ts"],"sourcesContent":["const LOGGER_CONTEXT = \"ssr-data-plugin\";\n\nexport const ERROR_PREFIX = `[@real-router/${LOGGER_CONTEXT}]`;\n","import {
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../src/constants.ts","../../../../shared/ssr/createSsrLoaderPlugin.ts","../../../../shared/ssr/createLoadersValidator.ts","../../src/validation.ts","../../src/factory.ts"],"sourcesContent":["const LOGGER_CONTEXT = \"ssr-data-plugin\";\n\nexport const ERROR_PREFIX = `[@real-router/${LOGGER_CONTEXT}]`;\n","import { getPluginApi } from \"@real-router/core/api\";\n\nimport type {\n SsrLoaderFactoryMap,\n SsrLoaderFn,\n SsrLoaderPluginConfig,\n} from \"./types.js\";\nimport type {\n DefaultDependencies,\n Plugin,\n PluginFactory,\n} from \"@real-router/types\";\n\nexport function createSsrLoaderPlugin<\n T,\n Dependencies extends DefaultDependencies = DefaultDependencies,\n>(\n loaders: SsrLoaderFactoryMap<T, Dependencies>,\n config: SsrLoaderPluginConfig,\n): PluginFactory<Dependencies> {\n return (router, getDependency): Plugin => {\n const api = getPluginApi(router);\n const claim = api.claimContextNamespace(config.namespace);\n\n const compiledLoaders = new Map<string, SsrLoaderFn<T>>();\n\n try {\n for (const [name, factory] of Object.entries(loaders)) {\n const loader = factory(router, getDependency);\n\n if (typeof loader !== \"function\") {\n throw new TypeError(\n `${config.errorPrefix} factory for route \"${name}\" must return a function`,\n );\n }\n\n compiledLoaders.set(name, loader);\n }\n } catch (error) {\n claim.release();\n\n throw error;\n }\n\n const removeStartInterceptor = api.addInterceptor(\n \"start\",\n async (next, path) => {\n const state = await next(path);\n const loader = compiledLoaders.get(state.name);\n\n if (loader) {\n claim.write(state, await loader(state.params));\n }\n\n return state;\n },\n );\n\n return {\n teardown() {\n removeStartInterceptor();\n claim.release();\n },\n };\n };\n}\n","export function createLoadersValidator(errorPrefix: string) {\n return function validateLoaders(loaders: unknown): void {\n if (\n loaders === null ||\n typeof loaders !== \"object\" ||\n Array.isArray(loaders)\n ) {\n throw new TypeError(`${errorPrefix} loaders must be a non-null object`);\n }\n\n for (const [key, value] of Object.entries(\n loaders as Record<string, unknown>,\n )) {\n if (typeof value !== \"function\") {\n throw new TypeError(\n `${errorPrefix} loader for route \"${key}\" must be a function`,\n );\n }\n }\n };\n}\n","import { ERROR_PREFIX } from \"./constants\";\nimport { createLoadersValidator } from \"./shared-ssr\";\n\nexport const validateLoaders = createLoadersValidator(ERROR_PREFIX);\n","import { ERROR_PREFIX } from \"./constants\";\nimport { createSsrLoaderPlugin } from \"./shared-ssr\";\nimport { validateLoaders } from \"./validation\";\n\nimport type { DataLoaderFactoryMap } from \"./types\";\nimport type { DefaultDependencies, PluginFactory } from \"@real-router/types\";\n\nexport function ssrDataPluginFactory<\n Dependencies extends DefaultDependencies = DefaultDependencies,\n>(loaders: DataLoaderFactoryMap<Dependencies>): PluginFactory<Dependencies> {\n validateLoaders(loaders);\n\n return createSsrLoaderPlugin<unknown, Dependencies>(loaders, {\n namespace: \"data\",\n errorPrefix: ERROR_PREFIX,\n });\n}\n"],"mappings":"qDAAA,MAEa,EAAe,iCCW5B,SAAgB,EAId,EACA,EAC6B,CAC7B,OAAQ,EAAQ,IAA0B,CACxC,IAAM,EAAM,EAAa,EAAO,CAC1B,EAAQ,EAAI,sBAAsB,EAAO,UAAU,CAEnD,EAAkB,IAAI,IAE5B,GAAI,CACF,IAAK,GAAM,CAAC,EAAM,KAAY,OAAO,QAAQ,EAAQ,CAAE,CACrD,IAAM,EAAS,EAAQ,EAAQ,EAAc,CAE7C,GAAI,OAAO,GAAW,WACpB,MAAU,UACR,GAAG,EAAO,YAAY,sBAAsB,EAAK,0BAClD,CAGH,EAAgB,IAAI,EAAM,EAAO,QAE5B,EAAO,CAGd,MAFA,EAAM,SAAS,CAET,EAGR,IAAM,EAAyB,EAAI,eACjC,QACA,MAAO,EAAM,IAAS,CACpB,IAAM,EAAQ,MAAM,EAAK,EAAK,CACxB,EAAS,EAAgB,IAAI,EAAM,KAAK,CAM9C,OAJI,GACF,EAAM,MAAM,EAAO,MAAM,EAAO,EAAM,OAAO,CAAC,CAGzC,GAEV,CAED,MAAO,CACL,UAAW,CACT,GAAwB,CACxB,EAAM,SAAS,EAElB,EC/DL,SAAgB,EAAuB,EAAqB,CAC1D,OAAO,SAAyB,EAAwB,CACtD,GAEE,OAAO,GAAY,WADnB,GAEA,MAAM,QAAQ,EAAQ,CAEtB,MAAU,UAAU,GAAG,EAAY,oCAAoC,CAGzE,IAAK,GAAM,CAAC,EAAK,KAAU,OAAO,QAChC,EACD,CACC,GAAI,OAAO,GAAU,WACnB,MAAU,UACR,GAAG,EAAY,qBAAqB,EAAI,sBACzC,ECbT,MAAa,EAAkB,EAAuB,EAAa,CCInE,SAAgB,EAEd,EAA0E,CAG1E,OAFA,EAAgB,EAAQ,CAEjB,EAA6C,EAAS,CAC3D,UAAW,OACX,YAAa,EACd,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@real-router/ssr-data-plugin",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.4",
|
|
4
4
|
"type": "commonjs",
|
|
5
5
|
"description": "SSR per-route data loading plugin for Real-Router",
|
|
6
6
|
"main": "./dist/cjs/index.js",
|
|
@@ -37,10 +37,10 @@
|
|
|
37
37
|
"homepage": "https://github.com/greydragon888/real-router",
|
|
38
38
|
"sideEffects": false,
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@real-router/types": "^0.
|
|
40
|
+
"@real-router/types": "^0.35.0"
|
|
41
41
|
},
|
|
42
42
|
"peerDependencies": {
|
|
43
|
-
"@real-router/core": "^0.
|
|
43
|
+
"@real-router/core": "^0.52.0"
|
|
44
44
|
},
|
|
45
45
|
"scripts": {
|
|
46
46
|
"test": "vitest",
|
package/src/factory.ts
CHANGED
|
@@ -1,59 +1,17 @@
|
|
|
1
|
-
import { getPluginApi } from "@real-router/core/api";
|
|
2
|
-
|
|
3
1
|
import { ERROR_PREFIX } from "./constants";
|
|
2
|
+
import { createSsrLoaderPlugin } from "./shared-ssr";
|
|
4
3
|
import { validateLoaders } from "./validation";
|
|
5
4
|
|
|
6
|
-
import type {
|
|
7
|
-
import type {
|
|
5
|
+
import type { DataLoaderFactoryMap } from "./types";
|
|
6
|
+
import type { DefaultDependencies, PluginFactory } from "@real-router/types";
|
|
8
7
|
|
|
9
|
-
export function ssrDataPluginFactory
|
|
10
|
-
|
|
11
|
-
): PluginFactory {
|
|
8
|
+
export function ssrDataPluginFactory<
|
|
9
|
+
Dependencies extends DefaultDependencies = DefaultDependencies,
|
|
10
|
+
>(loaders: DataLoaderFactoryMap<Dependencies>): PluginFactory<Dependencies> {
|
|
12
11
|
validateLoaders(loaders);
|
|
13
12
|
|
|
14
|
-
return (
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
const compiledLoaders = new Map<string, DataLoaderFn>();
|
|
19
|
-
|
|
20
|
-
try {
|
|
21
|
-
for (const [name, factory] of Object.entries(loaders)) {
|
|
22
|
-
const loader = factory(router, getDependency);
|
|
23
|
-
|
|
24
|
-
if (typeof loader !== "function") {
|
|
25
|
-
throw new TypeError(
|
|
26
|
-
`${ERROR_PREFIX} factory for route "${name}" must return a function`,
|
|
27
|
-
);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
compiledLoaders.set(name, loader);
|
|
31
|
-
}
|
|
32
|
-
} catch (error) {
|
|
33
|
-
claim.release();
|
|
34
|
-
|
|
35
|
-
throw error;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
const removeStartInterceptor = api.addInterceptor(
|
|
39
|
-
"start",
|
|
40
|
-
async (next, path) => {
|
|
41
|
-
const state = await next(path);
|
|
42
|
-
const loader = compiledLoaders.get(state.name);
|
|
43
|
-
|
|
44
|
-
if (loader) {
|
|
45
|
-
claim.write(state, await loader(state.params));
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
return state;
|
|
49
|
-
},
|
|
50
|
-
);
|
|
51
|
-
|
|
52
|
-
return {
|
|
53
|
-
teardown() {
|
|
54
|
-
removeStartInterceptor();
|
|
55
|
-
claim.release();
|
|
56
|
-
},
|
|
57
|
-
};
|
|
58
|
-
};
|
|
13
|
+
return createSsrLoaderPlugin<unknown, Dependencies>(loaders, {
|
|
14
|
+
namespace: "data",
|
|
15
|
+
errorPrefix: ERROR_PREFIX,
|
|
16
|
+
});
|
|
59
17
|
}
|
package/src/validation.ts
CHANGED
|
@@ -1,25 +1,4 @@
|
|
|
1
1
|
import { ERROR_PREFIX } from "./constants";
|
|
2
|
+
import { createLoadersValidator } from "./shared-ssr";
|
|
2
3
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
export function validateLoaders(
|
|
6
|
-
loaders: unknown,
|
|
7
|
-
): asserts loaders is DataLoaderFactoryMap {
|
|
8
|
-
if (
|
|
9
|
-
loaders === null ||
|
|
10
|
-
typeof loaders !== "object" ||
|
|
11
|
-
Array.isArray(loaders)
|
|
12
|
-
) {
|
|
13
|
-
throw new TypeError(`${ERROR_PREFIX} loaders must be a non-null object`);
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
for (const [key, value] of Object.entries(
|
|
17
|
-
loaders as Record<string, unknown>,
|
|
18
|
-
)) {
|
|
19
|
-
if (typeof value !== "function") {
|
|
20
|
-
throw new TypeError(
|
|
21
|
-
`${ERROR_PREFIX} loader for route "${key}" must be a function`,
|
|
22
|
-
);
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
}
|
|
4
|
+
export const validateLoaders = createLoadersValidator(ERROR_PREFIX);
|