@lomray/vite-ssr-boost 2.2.1 → 2.3.0-beta.2

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
@@ -202,7 +202,7 @@ SsrBoost({
202
202
  ```
203
203
 
204
204
  ## Useful imports
205
- ```typescript
205
+ ```typescript tsx
206
206
  /**
207
207
  * Components
208
208
  */
@@ -214,6 +214,8 @@ import ResponseStatus from '@lomray/vite-ssr-boost/components/response-status';
214
214
  import ScrollToTop from '@lomray/vite-ssr-boost/components/scroll-to-top';
215
215
  // HOC for wrap component in Suspense
216
216
  import withSuspense from '@lomray/vite-ssr-boost/components/with-suspense';
217
+ // Only client side components
218
+ import OnlyClient from '@lomray/vite-ssr-boost/components/only-client';
217
219
 
218
220
  /**
219
221
  * Helpers
@@ -230,6 +232,15 @@ import type { FCRoute, FCCRoute } from '@lomray/vite-ssr-boost/interfaces/fc-rou
230
232
  import type { TRouteObject } from '@lomray/vite-ssr-boost/interfaces/route-object';
231
233
  ```
232
234
 
235
+ Client side components import example:
236
+ ```typescript jsx
237
+ <OnlyClient load={() => import('external-package')}>
238
+ {(LoadedComnponent) => (
239
+ <LoadedComnponent />
240
+ )}
241
+ </OnlyClient>
242
+ ```
243
+
233
244
  ## CLI
234
245
  Explore all commands and options:
235
246
  ```shell
@@ -0,0 +1,14 @@
1
+ import { ComponentType, ReactNode } from 'react';
2
+ interface IOnlyClient<T> {
3
+ load: () => Promise<{
4
+ default: ComponentType<T>;
5
+ } | ComponentType<T>>;
6
+ children: (Component: ComponentType<T>) => ReactNode;
7
+ fallback?: ReactNode;
8
+ }
9
+ /**
10
+ * Render component only on client side
11
+ * @constructor
12
+ */
13
+ declare function OnlyClient<T>({ load, children, fallback }: IOnlyClient<T>): ReactNode;
14
+ export { OnlyClient as default };
@@ -0,0 +1,2 @@
1
+ import e,{useState as l,useEffect as t,startTransition as n,lazy as a}from"react";function o({load:o,children:c,fallback:d}){const[r,i]=l(null);return t((()=>{n((()=>{const l=a((()=>o().then((e=>({default:()=>c("default"in e?e.default:e)}))).catch((l=>(console.error("Client side component loading failed:",l),{default:()=>e.createElement("p",null,"Failed to load client side component.")})))));i(l)}))}),[]),r?e.createElement(r,null):d}export{o as default};
2
+ //# sourceMappingURL=only-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"only-client.js","sources":["../../src/components/only-client.tsx"],"sourcesContent":["import type { ComponentType, ReactNode } from 'react';\nimport React, { lazy, startTransition, useEffect, useState } from 'react';\n\ninterface IOnlyClient<T> {\n load: () => Promise<{ default: ComponentType<T> } | ComponentType<T>>;\n children: (Component: ComponentType<T>) => ReactNode;\n fallback?: ReactNode;\n}\n\n/**\n * Render component only on client side\n * @constructor\n */\nfunction OnlyClient<T>({ load, children, fallback }: IOnlyClient<T>): ReactNode {\n const [Component, setComponent] = useState<ComponentType<unknown> | null>(null);\n\n useEffect(() => {\n startTransition(() => {\n const LoadedComponent = lazy(() =>\n load()\n .then((Loaded) => ({\n default: () => children('default' in Loaded ? Loaded.default : Loaded),\n }))\n .catch((error: Error) => {\n console.error('Client side component loading failed:', error);\n\n return { default: () => <p>Failed to load client side component.</p> };\n }),\n );\n\n setComponent(LoadedComponent);\n });\n }, []);\n\n return Component ? <Component /> : fallback;\n}\n\nexport default OnlyClient;\n"],"names":["OnlyClient","load","children","fallback","Component","setComponent","useState","useEffect","startTransition","LoadedComponent","lazy","then","Loaded","default","catch","error","console","React","createElement"],"mappings":"kFAaA,SAASA,GAAcC,KAAEA,EAAIC,SAAEA,EAAQC,SAAEA,IACvC,MAAOC,EAAWC,GAAgBC,EAAwC,MAoB1E,OAlBAC,GAAU,KACRC,GAAgB,KACd,MAAMC,EAAkBC,GAAK,IAC3BT,IACGU,MAAMC,IAAY,CACjBC,QAAS,IAAMX,EAAS,YAAaU,EAASA,EAAOC,QAAUD,OAEhEE,OAAOC,IACNC,QAAQD,MAAM,wCAAyCA,GAEhD,CAAEF,QAAS,IAAMI,EAAAC,cAAA,IAAA,KAAA,+CAI9Bb,EAAaI,EAAgB,GAC7B,GACD,IAEIL,EAAYa,EAAAC,cAACd,EAAS,MAAMD,CACrC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lomray/vite-ssr-boost",
3
- "version": "2.2.1",
3
+ "version": "2.3.0-beta.2",
4
4
  "description": "Vite plugin for create awesome SSR or SPA applications on React.",
5
5
  "type": "module",
6
6
  "keywords": [
@@ -34,40 +34,40 @@
34
34
  },
35
35
  "dependencies": {
36
36
  "chalk": "^5.3.0",
37
- "commander": "^11.1.0",
37
+ "commander": "^12.0.0",
38
38
  "compression": "^1.7.4",
39
39
  "express": "^4.18.2",
40
40
  "hjson": "^3.2.2",
41
41
  "hoist-non-react-statics": "^3.3.2"
42
42
  },
43
43
  "devDependencies": {
44
- "@commitlint/cli": "^18.5.0",
45
- "@commitlint/config-conventional": "^18.5.0",
44
+ "@commitlint/cli": "^18.6.0",
45
+ "@commitlint/config-conventional": "^18.6.0",
46
46
  "@lomray/eslint-config": "^4.0.1",
47
47
  "@lomray/prettier-config": "^2.0.1",
48
48
  "@rollup/plugin-terser": "^0.4.4",
49
- "@testing-library/react": "^14.1.2",
49
+ "@testing-library/react": "^14.2.1",
50
50
  "@types/chai": "^4.3.11",
51
51
  "@types/compression": "^1.7.5",
52
52
  "@types/hjson": "^2.4.6",
53
53
  "@types/hoist-non-react-statics": "^3.3.5",
54
- "@types/react-dom": "^18.2.17",
54
+ "@types/react-dom": "^18.2.19",
55
55
  "@types/sinon": "^17.0.3",
56
56
  "@types/sinon-chai": "^3.2.12",
57
- "@typescript-eslint/eslint-plugin": "^6.19.0",
58
- "@vitest/coverage-v8": "^1.2.1",
57
+ "@typescript-eslint/eslint-plugin": "^6.21.0",
58
+ "@vitest/coverage-v8": "^1.2.2",
59
59
  "@zerollup/ts-transform-paths": "^1.7.18",
60
- "chai": "^4.3.10",
61
- "eslint": "^8.55.0",
60
+ "chai": "^4.4.1",
61
+ "eslint": "^8.56.0",
62
62
  "eslint-config-prettier": "^9.1.0",
63
63
  "eslint-plugin-import": "^2.29.1",
64
64
  "eslint-plugin-jsx-a11y": "^6.8.0",
65
- "eslint-plugin-prettier": "^5.0.1",
66
- "husky": "^8.0.3",
65
+ "eslint-plugin-prettier": "^5.1.3",
66
+ "husky": "^9.0.10",
67
67
  "jsdom": "^24.0.0",
68
- "lint-staged": "^15.2.0",
69
- "prettier": "^3.1.1",
70
- "rollup": "^4.9.0",
68
+ "lint-staged": "^15.2.2",
69
+ "prettier": "^3.2.5",
70
+ "rollup": "^4.10.0",
71
71
  "rollup-plugin-copy": "^3.5.0",
72
72
  "rollup-plugin-folder-input": "^1.0.1",
73
73
  "rollup-plugin-peer-deps-external": "^2.2.4",
@@ -77,8 +77,7 @@
77
77
  "sinon": "^17.0.1",
78
78
  "sinon-chai": "^3.7.0",
79
79
  "typescript": "^5.3.3",
80
- "vite-tsconfig-paths": "^4.3.1",
81
- "vitest": "^1.2.1"
80
+ "vitest": "^1.2.2"
82
81
  },
83
82
  "peerDependencies": {
84
83
  "@types/express": ">=4.17.21",
@@ -1 +1 @@
1
- {"version":3,"file":"make-aliases.js","sources":["../../src/plugins/make-aliases.ts"],"sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\nimport process from 'node:process';\nimport Hjson from 'hjson';\nimport type { Plugin } from 'vite';\nimport PLUGIN_NAME from '@constants/plugin-name';\nimport ViteAliases from '@helpers/vite-aliases';\n\nexport interface IPluginOptions {\n root?: string; // default: cwd()\n tsconfig?: string; // default: tsconfig.json\n}\n\nconst pluginName = `${PLUGIN_NAME}-make-aliases`;\nconst cleanupAlias = (str: string): string => str.replace('/*', '');\n\n/**\n * Read tsconfig file and set vite aliases\n * @see SsrManifest.getAliases\n * @constructor\n */\nfunction ViteMakeAliasesPlugin(options: IPluginOptions = {}): Plugin {\n const { root, tsconfig } = options;\n const projectRoot = root ?? process.cwd();\n const tsconfigPath = path.resolve(projectRoot, tsconfig ?? 'tsconfig.json');\n const aliases: [string, string][] = [];\n\n if (!fs.existsSync(tsconfigPath)) {\n console.error(`${pluginName}: tsconfig not exist in \"${tsconfigPath}\"`);\n } else {\n const tsJson = Hjson.parse(fs.readFileSync(tsconfigPath, { encoding: 'utf-8' }));\n const paths: Record<string, string[]> = tsJson?.compilerOptions?.paths ?? {};\n\n Object.entries(paths).forEach(([alias, aliasPaths]) => {\n aliases.push([cleanupAlias(alias), cleanupAlias(aliasPaths[0])]);\n });\n }\n\n return {\n name: pluginName,\n config(config) {\n if (aliases.length) {\n const resolveConfig = config.resolve ?? {};\n const defaultAliases = resolveConfig.alias ?? [];\n const normalizedAliases = Array.isArray(defaultAliases)\n ? defaultAliases\n : Object.entries(defaultAliases).map(([find, val]) => ({ find, replacement: val }));\n\n normalizedAliases.push(...ViteAliases(aliases, `${projectRoot}/${config?.root ?? ''}`));\n\n config.resolve = {\n ...resolveConfig,\n alias: normalizedAliases,\n };\n }\n\n return config;\n },\n };\n}\n\nexport default ViteMakeAliasesPlugin;\n"],"names":["pluginName","PLUGIN_NAME","cleanupAlias","str","replace","ViteMakeAliasesPlugin","options","root","tsconfig","projectRoot","process","cwd","tsconfigPath","path","resolve","aliases","fs","existsSync","tsJson","Hjson","parse","readFileSync","encoding","paths","compilerOptions","Object","entries","forEach","alias","aliasPaths","push","console","error","name","config","length","resolveConfig","defaultAliases","normalizedAliases","Array","isArray","map","find","val","replacement","ViteAliases"],"mappings":"sLAaA,MAAMA,EAAa,GAAGC,iBAChBC,EAAgBC,GAAwBA,EAAIC,QAAQ,KAAM,IAOhE,SAASC,EAAsBC,EAA0B,IACvD,MAAMC,KAAEA,EAAIC,SAAEA,GAAaF,EACrBG,EAAcF,GAAQG,EAAQC,MAC9BC,EAAeC,EAAKC,QAAQL,EAAaD,GAAY,iBACrDO,EAA8B,GAEpC,GAAKC,EAAGC,WAAWL,GAEZ,CACL,MAAMM,EAASC,EAAMC,MAAMJ,EAAGK,aAAaT,EAAc,CAAEU,SAAU,WAC/DC,EAAkCL,GAAQM,iBAAiBD,OAAS,CAAA,EAE1EE,OAAOC,QAAQH,GAAOI,SAAQ,EAAEC,EAAOC,MACrCd,EAAQe,KAAK,CAAC5B,EAAa0B,GAAQ1B,EAAa2B,EAAW,KAAK,GAEnE,MARCE,QAAQC,MAAM,GAAGhC,6BAAsCY,MAUzD,MAAO,CACLqB,KAAMjC,EACNkC,OAAOA,GACL,GAAInB,EAAQoB,OAAQ,CAClB,MAAMC,EAAgBF,EAAOpB,SAAW,GAClCuB,EAAiBD,EAAcR,OAAS,GACxCU,EAAoBC,MAAMC,QAAQH,GACpCA,EACAZ,OAAOC,QAAQW,GAAgBI,KAAI,EAAEC,EAAMC,MAAU,CAAED,OAAME,YAAaD,MAE9EL,EAAkBR,QAAQe,EAAY9B,EAAS,GAAGN,KAAeyB,GAAQ3B,MAAQ,OAEjF2B,EAAOpB,QAAU,IACZsB,EACHR,MAAOU,EAEV,CAED,OAAOJ,CACR,EAEL"}
1
+ {"version":3,"file":"make-aliases.js","sources":["../../src/plugins/make-aliases.ts"],"sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\nimport process from 'node:process';\nimport Hjson from 'hjson';\nimport type { Plugin } from 'vite';\nimport PLUGIN_NAME from '../constants/plugin-name';\nimport ViteAliases from '../helpers/vite-aliases';\n\nexport interface IPluginOptions {\n root?: string; // default: cwd()\n tsconfig?: string; // default: tsconfig.json\n}\n\nconst pluginName = `${PLUGIN_NAME}-make-aliases`;\nconst cleanupAlias = (str: string): string => str.replace('/*', '');\n\n/**\n * Read tsconfig file and set vite aliases\n * @see SsrManifest.getAliases\n * @constructor\n */\nfunction ViteMakeAliasesPlugin(options: IPluginOptions = {}): Plugin {\n const { root, tsconfig } = options;\n const projectRoot = root ?? process.cwd();\n const tsconfigPath = path.resolve(projectRoot, tsconfig ?? 'tsconfig.json');\n const aliases: [string, string][] = [];\n\n if (!fs.existsSync(tsconfigPath)) {\n console.error(`${pluginName}: tsconfig not exist in \"${tsconfigPath}\"`);\n } else {\n const tsJson = Hjson.parse(fs.readFileSync(tsconfigPath, { encoding: 'utf-8' }));\n const paths: Record<string, string[]> = tsJson?.compilerOptions?.paths ?? {};\n\n Object.entries(paths).forEach(([alias, aliasPaths]) => {\n aliases.push([cleanupAlias(alias), cleanupAlias(aliasPaths[0])]);\n });\n }\n\n return {\n name: pluginName,\n config(config) {\n if (aliases.length) {\n const resolveConfig = config.resolve ?? {};\n const defaultAliases = resolveConfig.alias ?? [];\n const normalizedAliases = Array.isArray(defaultAliases)\n ? defaultAliases\n : Object.entries(defaultAliases).map(([find, val]) => ({ find, replacement: val }));\n\n normalizedAliases.push(...ViteAliases(aliases, `${projectRoot}/${config?.root ?? ''}`));\n\n config.resolve = {\n ...resolveConfig,\n alias: normalizedAliases,\n };\n }\n\n return config;\n },\n };\n}\n\nexport default ViteMakeAliasesPlugin;\n"],"names":["pluginName","PLUGIN_NAME","cleanupAlias","str","replace","ViteMakeAliasesPlugin","options","root","tsconfig","projectRoot","process","cwd","tsconfigPath","path","resolve","aliases","fs","existsSync","tsJson","Hjson","parse","readFileSync","encoding","paths","compilerOptions","Object","entries","forEach","alias","aliasPaths","push","console","error","name","config","length","resolveConfig","defaultAliases","normalizedAliases","Array","isArray","map","find","val","replacement","ViteAliases"],"mappings":"sLAaA,MAAMA,EAAa,GAAGC,iBAChBC,EAAgBC,GAAwBA,EAAIC,QAAQ,KAAM,IAOhE,SAASC,EAAsBC,EAA0B,IACvD,MAAMC,KAAEA,EAAIC,SAAEA,GAAaF,EACrBG,EAAcF,GAAQG,EAAQC,MAC9BC,EAAeC,EAAKC,QAAQL,EAAaD,GAAY,iBACrDO,EAA8B,GAEpC,GAAKC,EAAGC,WAAWL,GAEZ,CACL,MAAMM,EAASC,EAAMC,MAAMJ,EAAGK,aAAaT,EAAc,CAAEU,SAAU,WAC/DC,EAAkCL,GAAQM,iBAAiBD,OAAS,CAAA,EAE1EE,OAAOC,QAAQH,GAAOI,SAAQ,EAAEC,EAAOC,MACrCd,EAAQe,KAAK,CAAC5B,EAAa0B,GAAQ1B,EAAa2B,EAAW,KAAK,GAEnE,MARCE,QAAQC,MAAM,GAAGhC,6BAAsCY,MAUzD,MAAO,CACLqB,KAAMjC,EACNkC,OAAOA,GACL,GAAInB,EAAQoB,OAAQ,CAClB,MAAMC,EAAgBF,EAAOpB,SAAW,GAClCuB,EAAiBD,EAAcR,OAAS,GACxCU,EAAoBC,MAAMC,QAAQH,GACpCA,EACAZ,OAAOC,QAAQW,GAAgBI,KAAI,EAAEC,EAAMC,MAAU,CAAED,OAAME,YAAaD,MAE9EL,EAAkBR,QAAQe,EAAY9B,EAAS,GAAGN,KAAeyB,GAAQ3B,MAAQ,OAEjF2B,EAAOpB,QAAU,IACZsB,EACHR,MAAOU,EAEV,CAED,OAAOJ,CACR,EAEL"}