@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 CHANGED
@@ -108,11 +108,12 @@ In SSR, `router.dispose()` handles cleanup automatically.
108
108
 
109
109
  ## Related Packages
110
110
 
111
- | Package | Description |
112
- | ---------------------------------------------------------------------------------------- | -------------------------------------- |
113
- | [@real-router/core](https://www.npmjs.com/package/@real-router/core) | Core router (required peer dependency) |
114
- | [@real-router/browser-plugin](https://www.npmjs.com/package/@real-router/browser-plugin) | Browser History API integration |
115
- | [@real-router/react](https://www.npmjs.com/package/@real-router/react) | React bindings |
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
 
@@ -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" {
@@ -1 +1 @@
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;;;iBCdvB,oBAAA,CACd,OAAA,EAAS,oBAAA,GACR,aAAA;;;;YCDS,YAAA;IACR,IAAA;EAAA;AAAA"}
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(e){if(typeof e!=`object`||!e||Array.isArray(e))throw TypeError(`${t} loaders must be a non-null object`);for(let[n,r]of Object.entries(e))if(typeof r!=`function`)throw TypeError(`${t} loader for route "${n}" must be a function`)}function r(r){return n(r),(n,i)=>{let a=(0,e.getPluginApi)(n),o=a.claimContextNamespace(`data`),s=new Map;try{for(let[e,a]of Object.entries(r)){let r=a(n,i);if(typeof r!=`function`)throw TypeError(`${t} factory for route "${e}" must return a function`);s.set(e,r)}}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()}}}}exports.ssrDataPluginFactory=r;
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
@@ -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 { ERROR_PREFIX } from \"./constants\";\n\nimport type { DataLoaderFactoryMap } from \"./types\";\n\nexport function validateLoaders(\n loaders: unknown,\n): asserts loaders is DataLoaderFactoryMap {\n if (\n loaders === null ||\n typeof loaders !== \"object\" ||\n Array.isArray(loaders)\n ) {\n throw new TypeError(`${ERROR_PREFIX} 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 `${ERROR_PREFIX} loader for route \"${key}\" must be a function`,\n );\n }\n }\n}\n","import { getPluginApi } from \"@real-router/core/api\";\n\nimport { ERROR_PREFIX } from \"./constants\";\nimport { validateLoaders } from \"./validation\";\n\nimport type { DataLoaderFn, DataLoaderFactoryMap } from \"./types\";\nimport type { PluginFactory, Plugin } from \"@real-router/core\";\n\nexport function ssrDataPluginFactory(\n loaders: DataLoaderFactoryMap,\n): PluginFactory {\n validateLoaders(loaders);\n\n return (router, getDependency): Plugin => {\n const api = getPluginApi(router);\n const claim = api.claimContextNamespace(\"data\");\n\n const compiledLoaders = new Map<string, DataLoaderFn>();\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 `${ERROR_PREFIX} 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"],"mappings":"0GAAA,MAEa,EAAe,iCCE5B,SAAgB,EACd,EACyC,CACzC,GAEE,OAAO,GAAY,WADnB,GAEA,MAAM,QAAQ,EAAQ,CAEtB,MAAU,UAAU,GAAG,EAAa,oCAAoC,CAG1E,IAAK,GAAM,CAAC,EAAK,KAAU,OAAO,QAChC,EACD,CACC,GAAI,OAAO,GAAU,WACnB,MAAU,UACR,GAAG,EAAa,qBAAqB,EAAI,sBAC1C,CCbP,SAAgB,EACd,EACe,CAGf,OAFA,EAAgB,EAAQ,EAEhB,EAAQ,IAA0B,CACxC,IAAM,GAAA,EAAA,EAAA,cAAmB,EAAO,CAC1B,EAAQ,EAAI,sBAAsB,OAAO,CAEzC,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,EAAa,sBAAsB,EAAK,0BAC5C,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"}
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"}
@@ -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" {
@@ -1 +1 @@
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;;;iBCdvB,oBAAA,CACd,OAAA,EAAS,oBAAA,GACR,aAAA;;;;YCDS,YAAA;IACR,IAAA;EAAA;AAAA"}
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"}
@@ -1,2 +1,2 @@
1
- import{getPluginApi as e}from"@real-router/core/api";const t=`[@real-router/ssr-data-plugin]`;function n(e){if(typeof e!=`object`||!e||Array.isArray(e))throw TypeError(`${t} loaders must be a non-null object`);for(let[n,r]of Object.entries(e))if(typeof r!=`function`)throw TypeError(`${t} loader for route "${n}" must be a function`)}function r(r){return n(r),(n,i)=>{let a=e(n),o=a.claimContextNamespace(`data`),s=new Map;try{for(let[e,a]of Object.entries(r)){let r=a(n,i);if(typeof r!=`function`)throw TypeError(`${t} factory for route "${e}" must return a function`);s.set(e,r)}}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()}}}}export{r as ssrDataPluginFactory};
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
@@ -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 { ERROR_PREFIX } from \"./constants\";\n\nimport type { DataLoaderFactoryMap } from \"./types\";\n\nexport function validateLoaders(\n loaders: unknown,\n): asserts loaders is DataLoaderFactoryMap {\n if (\n loaders === null ||\n typeof loaders !== \"object\" ||\n Array.isArray(loaders)\n ) {\n throw new TypeError(`${ERROR_PREFIX} 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 `${ERROR_PREFIX} loader for route \"${key}\" must be a function`,\n );\n }\n }\n}\n","import { getPluginApi } from \"@real-router/core/api\";\n\nimport { ERROR_PREFIX } from \"./constants\";\nimport { validateLoaders } from \"./validation\";\n\nimport type { DataLoaderFn, DataLoaderFactoryMap } from \"./types\";\nimport type { PluginFactory, Plugin } from \"@real-router/core\";\n\nexport function ssrDataPluginFactory(\n loaders: DataLoaderFactoryMap,\n): PluginFactory {\n validateLoaders(loaders);\n\n return (router, getDependency): Plugin => {\n const api = getPluginApi(router);\n const claim = api.claimContextNamespace(\"data\");\n\n const compiledLoaders = new Map<string, DataLoaderFn>();\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 `${ERROR_PREFIX} 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"],"mappings":"qDAAA,MAEa,EAAe,iCCE5B,SAAgB,EACd,EACyC,CACzC,GAEE,OAAO,GAAY,WADnB,GAEA,MAAM,QAAQ,EAAQ,CAEtB,MAAU,UAAU,GAAG,EAAa,oCAAoC,CAG1E,IAAK,GAAM,CAAC,EAAK,KAAU,OAAO,QAChC,EACD,CACC,GAAI,OAAO,GAAU,WACnB,MAAU,UACR,GAAG,EAAa,qBAAqB,EAAI,sBAC1C,CCbP,SAAgB,EACd,EACe,CAGf,OAFA,EAAgB,EAAQ,EAEhB,EAAQ,IAA0B,CACxC,IAAM,EAAM,EAAa,EAAO,CAC1B,EAAQ,EAAI,sBAAsB,OAAO,CAEzC,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,EAAa,sBAAsB,EAAK,0BAC5C,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"}
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.2",
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.34.0"
40
+ "@real-router/types": "^0.35.0"
41
41
  },
42
42
  "peerDependencies": {
43
- "@real-router/core": "^0.50.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 { DataLoaderFn, DataLoaderFactoryMap } from "./types";
7
- import type { PluginFactory, Plugin } from "@real-router/core";
5
+ import type { DataLoaderFactoryMap } from "./types";
6
+ import type { DefaultDependencies, PluginFactory } from "@real-router/types";
8
7
 
9
- export function ssrDataPluginFactory(
10
- loaders: DataLoaderFactoryMap,
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 (router, getDependency): Plugin => {
15
- const api = getPluginApi(router);
16
- const claim = api.claimContextNamespace("data");
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
- import type { DataLoaderFactoryMap } from "./types";
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);