From 85e05f5be6dcdda208cd22fccf9ef23a0adc9b78 Mon Sep 17 00:00:00 2001 From: hasnainroopawalla Date: Sat, 6 Apr 2024 19:36:17 +0200 Subject: [PATCH 1/4] init --- src/config-context.interface.ts | 15 +++++++++++++++ src/config-context.tsx | 7 +++++++ src/config.ts | 19 +++++++++++++++++++ src/index.tsx | 11 ++++++++++- src/project-config.ts | 0 5 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 src/config-context.interface.ts create mode 100644 src/config-context.tsx create mode 100644 src/config.ts create mode 100644 src/project-config.ts diff --git a/src/config-context.interface.ts b/src/config-context.interface.ts new file mode 100644 index 0000000..d9fbaaa --- /dev/null +++ b/src/config-context.interface.ts @@ -0,0 +1,15 @@ +type DefaultConfig = { value: unknown }; + +type FilterConfig = ( + | { browser: string } + | { platform: string } + | { os: string } + | { engine: string } +) & + DefaultConfig; + +type IConfigValues = [DefaultConfig, ...FilterConfig[]]; + +export type IConfig = { + [K in keyof TConfig]: IConfigValues; +}; diff --git a/src/config-context.tsx b/src/config-context.tsx new file mode 100644 index 0000000..cb649e3 --- /dev/null +++ b/src/config-context.tsx @@ -0,0 +1,7 @@ +import type { IConfig } from "./config-context.interface"; + +export function createConfig(config: IConfig) { + const useConfig = () => config; + + return useConfig; +} diff --git a/src/config.ts b/src/config.ts new file mode 100644 index 0000000..f48cdbf --- /dev/null +++ b/src/config.ts @@ -0,0 +1,19 @@ +import { createConfig } from "./config-context"; +import { Browser } from "./enums"; + +export const useConfig = createConfig({ + showButton: [ + { + value: true, + }, + { + browser: Browser.Chrome, + value: false, + }, + ], + enableModernUi: [ + { + value: true, + }, + ], +}); diff --git a/src/index.tsx b/src/index.tsx index e6b9641..eb34084 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,8 +1,17 @@ import React from "react"; import ReactDOM from "react-dom/client"; +import { useConfig } from "./config"; + +const App = () => { + const config = useConfig(); + + console.log("config", config.showButton[0].value); + + return Component; +}; const root = ReactDOM.createRoot( document.getElementById("root") as HTMLElement ); -root.render(
hi
); +root.render(); diff --git a/src/project-config.ts b/src/project-config.ts new file mode 100644 index 0000000..e69de29 From c53453ec0d7a1e83f11861684ccac67ba8fb55b7 Mon Sep 17 00:00:00 2001 From: hasnainroopawalla Date: Sat, 6 Apr 2024 19:55:45 +0200 Subject: [PATCH 2/4] WIP traverse --- src/config-context.tsx | 7 ++++++- src/index.tsx | 3 +-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/config-context.tsx b/src/config-context.tsx index cb649e3..a137bf9 100644 --- a/src/config-context.tsx +++ b/src/config-context.tsx @@ -1,7 +1,12 @@ import type { IConfig } from "./config-context.interface"; export function createConfig(config: IConfig) { - const useConfig = () => config; + const useConfig = () => { + for (const key in config) { + const value = config[key]; + console.log(key, value); + } + }; return useConfig; } diff --git a/src/index.tsx b/src/index.tsx index eb34084..15b0ff1 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -4,8 +4,7 @@ import { useConfig } from "./config"; const App = () => { const config = useConfig(); - - console.log("config", config.showButton[0].value); + console.log("render"); return Component; }; From f59c737c82db2e9c7fcee9f33ddd05d9bfa5b341 Mon Sep 17 00:00:00 2001 From: hasnainroopawalla Date: Sun, 7 Apr 2024 12:12:37 +0200 Subject: [PATCH 3/4] working types --- src/config-context.interface.ts | 29 ++++++++++++++++++++++++----- src/config-context.tsx | 31 ++++++++++++++++++++++++++----- src/config.ts | 2 +- src/index.tsx | 3 +-- 4 files changed, 52 insertions(+), 13 deletions(-) diff --git a/src/config-context.interface.ts b/src/config-context.interface.ts index d9fbaaa..39eae90 100644 --- a/src/config-context.interface.ts +++ b/src/config-context.interface.ts @@ -1,15 +1,34 @@ -type DefaultConfig = { value: unknown }; +export type IBaseConfig = { value: TConfigValueType }; -type FilterConfig = ( +type IConfigWithFilters = ( | { browser: string } | { platform: string } | { os: string } | { engine: string } ) & - DefaultConfig; + IBaseConfig; -type IConfigValues = [DefaultConfig, ...FilterConfig[]]; +type IConfigFilters = [ + IBaseConfig, + ...IConfigWithFilters[] +]; +/** + * A strongly typed `userConfig` object required to create the `IConfig` object. + */ +export type IUserConfig = { + [K in keyof TConfig]: IConfigFilters; +}; + +/** + * A type-safe object of the config parameters and corresponding values returned by the `useConfig` hook. + */ export type IConfig = { - [K in keyof TConfig]: IConfigValues; + [K in keyof TConfig]: IBaseConfig["value"]; }; + +/** + * A dynamic type to infer the filters of a specific config parameter. + */ +export type IDynamicConfigFilters = + IUserConfig[Extract]; diff --git a/src/config-context.tsx b/src/config-context.tsx index a137bf9..4330bcd 100644 --- a/src/config-context.tsx +++ b/src/config-context.tsx @@ -1,11 +1,32 @@ -import type { IConfig } from "./config-context.interface"; +import type { + IConfig, + IDynamicConfigFilters, + IUserConfig, +} from "./config-context.interface"; + +// TODO: move to utils +export const getBaseConfig = ( + configFilters: IDynamicConfigFilters +) => + configFilters.find( + (configValue) => + Object.keys(configValue).length === 1 && "value" in configValue + )!; + +export function createConfig( + userConfig: IUserConfig +) { + const configValues: IConfig = {} as IConfig; -export function createConfig(config: IConfig) { const useConfig = () => { - for (const key in config) { - const value = config[key]; - console.log(key, value); + for (const key in userConfig) { + const configFilters = userConfig[key]; + + const baseConfig = getBaseConfig(configFilters); + + configValues[key] = baseConfig.value; } + return configValues; }; return useConfig; diff --git a/src/config.ts b/src/config.ts index f48cdbf..bc94574 100644 --- a/src/config.ts +++ b/src/config.ts @@ -13,7 +13,7 @@ export const useConfig = createConfig({ ], enableModernUi: [ { - value: true, + value: 33, }, ], }); diff --git a/src/index.tsx b/src/index.tsx index 15b0ff1..05e3682 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -4,8 +4,7 @@ import { useConfig } from "./config"; const App = () => { const config = useConfig(); - console.log("render"); - + console.log(config); return Component; }; From cf934301591636c01b83cea65d4ca1d1cbed2aea Mon Sep 17 00:00:00 2001 From: hasnainroopawalla Date: Sun, 7 Apr 2024 15:42:47 +0200 Subject: [PATCH 4/4] optimize --- src/config-context.tsx | 21 ++++++++------------- src/index.tsx | 34 ++++++++++++++++++++++++++++++---- 2 files changed, 38 insertions(+), 17 deletions(-) diff --git a/src/config-context.tsx b/src/config-context.tsx index 4330bcd..80db043 100644 --- a/src/config-context.tsx +++ b/src/config-context.tsx @@ -5,7 +5,7 @@ import type { } from "./config-context.interface"; // TODO: move to utils -export const getBaseConfig = ( +const getBaseConfig = ( configFilters: IDynamicConfigFilters ) => configFilters.find( @@ -16,18 +16,13 @@ export const getBaseConfig = ( export function createConfig( userConfig: IUserConfig ) { + console.log("createConfig"); const configValues: IConfig = {} as IConfig; + for (const key in userConfig) { + const configFilters = userConfig[key]; + const baseConfig = getBaseConfig(configFilters); + configValues[key] = baseConfig.value; + } - const useConfig = () => { - for (const key in userConfig) { - const configFilters = userConfig[key]; - - const baseConfig = getBaseConfig(configFilters); - - configValues[key] = baseConfig.value; - } - return configValues; - }; - - return useConfig; + return () => configValues; } diff --git a/src/index.tsx b/src/index.tsx index 05e3682..2397f7a 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -2,10 +2,36 @@ import React from "react"; import ReactDOM from "react-dom/client"; import { useConfig } from "./config"; -const App = () => { - const config = useConfig(); - console.log(config); - return Component; +const App = () => ( +
+ +
+ +
+ +
+); + +const Component1 = () => { + const _config = useConfig(); + console.log("", _config); + return Component 1; +}; + +const Component2 = () => { + const _config = useConfig(); + console.log("", _config); + return Component 2; +}; + +const Component3 = () => { + const [counter, setCounter] = React.useState(0); + + const _config = useConfig(); + const onClick = () => setCounter(counter + 1); + + console.log("", _config); + return ; }; const root = ReactDOM.createRoot(