@arc-js/config-manager 0.0.94 → 0.0.95

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/index.min.js ADDED
@@ -0,0 +1,2 @@
1
+ var hasRequiredTimez,hasRequiredCooks,cooks={},timez={};function requireTimez(){if(!hasRequiredTimez){hasRequiredTimez=1,Object.defineProperty(timez,"__esModule",{value:!0});class f{constructor(e,t=!1){!1===this.dateChecker(e)?this._date=void 0:e instanceof f&&e&&null!=e&&e._date?this._date=new Date(null==e?void 0:e._date):e instanceof Date?this._date=new Date(e):"string"==typeof e?this._date=f.parseString(e,t):"number"==typeof e?this._date=new Date(e):null==e||"number"==typeof e&&isNaN(e)?this._date=new Date:this._date=void 0}static now(){return new f}static parse(e,t){return"string"==typeof t&&0<t.length&&(e instanceof f&&e&&null!=e&&e._date||e instanceof Date||"string"==typeof e||"number"==typeof e||null==e||"number"==typeof e&&isNaN(e))&&f.parseWithFormat(e,t)||new f(e)}static unix(e){return new f(1e3*e)}static utc(){var e=new Date;return new f(Date.UTC(e.getUTCFullYear(),e.getUTCMonth(),e.getUTCDate(),e.getUTCHours(),e.getUTCMinutes(),e.getUTCSeconds(),e.getUTCMilliseconds()))}year(){var e;return null==(e=this._date)?void 0:e.getFullYear()}month(){return this._date?this._date.getMonth()+1:void 0}date(){var e;return null==(e=this._date)?void 0:e.getDate()}hour(){var e;return null==(e=this._date)?void 0:e.getHours()}minute(){var e;return null==(e=this._date)?void 0:e.getMinutes()}second(){var e;return null==(e=this._date)?void 0:e.getSeconds()}millisecond(){var e;return null==(e=this._date)?void 0:e.getMilliseconds()}day(){var e;return null==(e=this._date)?void 0:e.getDay()}add(e,t){if(!this._date)return new f(void 0);var a=new Date(this._date);switch(t){case"years":a.setFullYear(a.getFullYear()+e);break;case"months":a.setMonth(a.getMonth()+e);break;case"days":a.setDate(a.getDate()+e);break;case"hours":a.setHours(a.getHours()+e);break;case"minutes":a.setMinutes(a.getMinutes()+e);break;case"seconds":a.setSeconds(a.getSeconds()+e);break;case"milliseconds":a.setMilliseconds(a.getMilliseconds()+e)}return new f(a)}subtract(e,t){return this.add(-e,t)}startOf(e){if(!this._date)return new f(void 0);var t=new Date(this._date);switch(e){case"year":t.setMonth(0,1),t.setHours(0,0,0,0);break;case"month":t.setDate(1),t.setHours(0,0,0,0);break;case"day":t.setHours(0,0,0,0);break;case"hour":t.setMinutes(0,0,0);break;case"minute":t.setSeconds(0,0);break;case"second":t.setMilliseconds(0)}return new f(t)}endOf(e){var t=this.startOf(e);switch(e){case"year":return t.add(1,"years").subtract(1,"milliseconds");case"month":return t.add(1,"months").subtract(1,"milliseconds");case"day":return t.add(1,"days").subtract(1,"milliseconds");case"hour":return t.add(1,"hours").subtract(1,"milliseconds");case"minute":return t.add(1,"minutes").subtract(1,"milliseconds");case"second":return t.add(1,"seconds").subtract(1,"milliseconds");default:return t}}isBefore(e,t="()"){t="]"===t[1],e=e instanceof f?e:new f(e);return!(!this._date||!e._date)&&(!t&&this._date<e._date||!!t&&this._date<=e._date)}isAfter(e,t="()"){t="["===t[0],e=e instanceof f?e:new f(e);return!(!this._date||!e._date)&&(!t&&this._date>e._date||!!t&&this._date>=e._date)}isSame(e,t){var a,e=e instanceof f?e:new f(e);return!t&&this._date&&e._date?this._date.getTime()===e._date.getTime():(a=t?this.startOf(t):void 0,e=t?e.startOf(t):void 0,!!(a&&null!=a&&a._date&&e&&null!=e&&e._date)&&a._date.getTime()===e._date.getTime())}isBetween(e,t,a="()"){var e=e instanceof f?e:new f(e),t=t instanceof f?t:new f(t),i="["===a[0],a="]"===a[1],i=i&&this.isSame(e)||this.isAfter(e),e=a&&this.isSame(t)||this.isBefore(t);return i&&e}format(e){if(!e)return this.toISOString();var t,a,i=f.PREDEFINED_FORMATS[e];if(i)return this.format(i);let r="",s=0;for(;s<e.length;)"["===e[s]?-1===(a=e.indexOf("]",s))?(r+=e[s],s++):(t=e.substring(s+1,a),r+=t,s=a+1):"%"===e[s]&&s+1<e.length?(t="%"+e[s+1],a=f.FORMAT_TOKENS[t],r+=a?a(this):t,s+=2):(r+=e[s],s++);return r}setTimezone(e){var t;return this._date?(t=this._date.getTimezoneOffset(),e=this.parseTimezoneOffset(e),e=new Date(this._date.getTime()+6e4*(e-t)),new f(e)):new f(void 0)}utc(){return this._date?new f(new Date(Date.UTC(this._date.getUTCFullYear(),this._date.getUTCMonth(),this._date.getUTCDate(),this._date.getUTCHours(),this._date.getUTCMinutes(),this._date.getUTCSeconds(),this._date.getUTCMilliseconds()))):new f(void 0)}local(){return this._date?new f(new Date(this._date.getFullYear(),this._date.getMonth(),this._date.getDate(),this._date.getHours(),this._date.getMinutes(),this._date.getSeconds(),this._date.getMilliseconds())):new f(void 0)}toString(){var e;return null==(e=this._date)?void 0:e.toString()}toISOString(){var e;return null==(e=this._date)?void 0:e.toISOString()}toDate(){return this._date?new Date(this._date):void 0}valueOf(){var e;return null==(e=this._date)?void 0:e.getTime()}unix(){return this._date?Math.floor(this._date.getTime()/1e3):void 0}utcOffset(){return this._date?-this._date.getTimezoneOffset():void 0}isCorrect(){return!!this._date&&!isNaN(this._date.getTime())}timezone(){if(this._date)try{return(new Intl.DateTimeFormat).resolvedOptions().timeZone||void 0}catch(e){return this.timezoneFromOffset()}}timezoneAbbr(){if(this._date)try{var e=new Intl.DateTimeFormat("en",{timeZoneName:"short"}).formatToParts(this._date).find(e=>"timeZoneName"===e.type);return(null==e?void 0:e.value)||void 0}catch(e){return this.timezoneAbbrFromOffset()}}timezoneName(){if(this._date)try{var e=new Intl.DateTimeFormat("en",{timeZoneName:"long"}).formatToParts(this._date).find(e=>"timeZoneName"===e.type);return(null==e?void 0:e.value)||void 0}catch(e){return this.timezoneNameFromOffset()}}timezoneOffsetString(){var e=this.utcOffset();if(void 0!==e)return(0<=e?"+":"-")+Math.floor(Math.abs(e)/60).toString().padStart(2,"0")+":"+(Math.abs(e)%60).toString().padStart(2,"0")}dateChecker(e){return e instanceof f&&!!e&&!(null==e||!e._date)||e instanceof Date||"string"==typeof e||"number"==typeof e||null==e||"number"==typeof e&&isNaN(e)}timezoneFromOffset(){var e=this.utcOffset();if(void 0!==e)return{0:"Etc/UTC",60:"Europe/Paris",120:"Europe/Athens",180:"Europe/Moscow",240:"Asia/Dubai",270:"Asia/Tehran",300:"Asia/Karachi",330:"Asia/Kolkata",345:"Asia/Rangoon",360:"Asia/Dhaka",390:"Asia/Yangon",420:"Asia/Bangkok",480:"Asia/Shanghai",525:"Asia/Kathmandu",540:"Asia/Tokyo",570:"Australia/Adelaide",600:"Australia/Sydney",630:"Australia/Lord_Howe",660:"Pacific/Noumea",675:"Australia/Eucla",720:"Pacific/Auckland",780:"Pacific/Chatham","-60":"Atlantic/Azores","-120":"America/Noronha","-180":"America/Argentina/Buenos_Aires","-210":"America/St_Johns","-240":"America/Halifax","-270":"America/Caracas","-300":"America/New_York","-360":"America/Chicago","-420":"America/Denver","-480":"America/Los_Angeles","-540":"America/Anchorage","-600":"Pacific/Honolulu","-660":"Pacific/Pago_Pago","-720":"Pacific/Kiritimati"}[e]||"Etc/GMT"+(0<=e?"-":"+")+Math.abs(e)/60}timezoneAbbrFromOffset(){var e=this.utcOffset();if(void 0!==e)return{0:"GMT",60:"CET","-300":"EST","-360":"CST","-420":"MST","-480":"PST"}[e]||"GMT"+(0<=e?"+":"")+e/60}timezoneNameFromOffset(){var e=this.utcOffset();if(void 0!==e)return{0:"Greenwich Mean Time",60:"Central European Time","-300":"Eastern Standard Time","-360":"Central Standard Time","-420":"Mountain Standard Time","-480":"Pacific Standard Time"}[e]||"GMT"+(0<=e?"+":"")+e/60}isDST(){if(this._date)try{var e=new Date(this._date.getFullYear(),0,1),t=new Date(this._date.getFullYear(),6,1),a=Math.max(e.getTimezoneOffset(),t.getTimezoneOffset());return this._date.getTimezoneOffset()<a}catch(e){}}static parseString(e,t=!1){var a=new Date(e);if(!isNaN(a.getTime()))return a;var i,r=[/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})\.(\d{3})Z$/,/^(\d{4})-(\d{2})-(\d{2})$/,/^(\d{4})\/(\d{2})\/(\d{2}) (\d{2}):(\d{2}):(\d{2})$/,/^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})$/];for(i of r){var s=e.match(i);if(s){s=s.slice(1).map(Number);if(i===r[0])return new Date(Date.UTC(s[0],s[1]-1,s[2],s[3],s[4],s[5],s[6]));if(i===r[1])return new Date(s[0],s[1]-1,s[2]);if(i===r[2])return new Date(s[0],s[1]-1,s[2],s[3],s[4],s[5]);if(i===r[3])return new Date(s[0],s[1]-1,s[2],s[3],s[4],s[5])}}a=new Date(e);if(!isNaN(a.getTime()))return a;if(t)throw new Error("Unable to parse date string: "+e)}static parseWithFormat(e,r){if(e&&r){var s=String(e).trim();if(s){var n={Y:{regex:/\d{4}/,extract:e=>parseInt(e,10)},y:{regex:/\d{2}/,extract:e=>{e=parseInt(e,10);return 70<=e?1900+e:2e3+e}},m:{regex:/\d{1,2}/,extract:e=>parseInt(e,10)},d:{regex:/\d{1,2}/,extract:e=>parseInt(e,10)},H:{regex:/\d{1,2}/,extract:e=>parseInt(e,10)},M:{regex:/\d{1,2}/,extract:e=>parseInt(e,10)},S:{regex:/\d{1,2}/,extract:e=>parseInt(e,10)},f:{regex:/\d{1,3}/,extract:e=>parseInt(e,10)}},o={year:(new Date).getFullYear(),month:1,day:1,hour:0,minute:0,second:0,millisecond:0};let e=0,t=0,a=!1,i="";for(;t<r.length&&e<s.length;){var d=r[t];if("["===d)a=!0,i="",t++;else if("]"===d&&a){if(s.substring(e,e+i.length)!==i)return;e+=i.length,a=!1,i="",t++}else if(a)i+=d,t++;else if("%"===d&&t+1<r.length){var u=r[t+1],c=n[u];if(c){var l=s.substring(e).match(c.regex);if(!l||0!==l.index)return;var l=l[0],h=c.extract(l);switch(u){case"Y":case"y":o.year=h;break;case"m":o.month=h;break;case"d":o.day=h;break;case"H":o.hour=h;break;case"M":o.minute=h;break;case"S":o.second=h;break;case"f":o.millisecond=h}e+=l.length}else e++;t+=2}else{if(d!==s[e])return;e++,t++}}if(!(o.month<1||12<o.month||o.day<1||31<o.day||o.hour<0||23<o.hour||o.minute<0||59<o.minute||o.second<0||59<o.second||o.millisecond<0||999<o.millisecond))try{var m=new Date(o.year,o.month-1,o.day,o.hour,o.minute,o.second,o.millisecond);if(!isNaN(m.getTime()))return new f(m)}catch(e){}}}}static getTokenLength(e){return{Y:4,y:2,m:2,d:2,H:2,M:2,S:2,f:3,z:5}[e]||1}parseTimezoneOffset(e){var t={UTC:0,EST:-300,EDT:-240,CST:-360,CDT:-300,PST:-480,PDT:-420};return void 0!==t[e.toUpperCase()]?t[e.toUpperCase()]:(t=e.match(/^([+-])(\d{1,2}):?(\d{2})?$/))?("+"===t[1]?1:-1)*(60*parseInt(t[2],10)+(t[3]?parseInt(t[3],10):0)):this._date?-this._date.getTimezoneOffset():0}static get FORMATS(){return Object.assign({},f.PREDEFINED_FORMATS)}static exposeToGlobal(){"undefined"!=typeof window&&(window.Timez=f)}}f.FORMAT_TOKENS={"%Y":e=>null==(e=e.year())?void 0:e.toString().padStart(4,"0"),"%y":e=>null==(e=e.year())?void 0:e.toString().slice(-2).padStart(2,"0"),"%m":e=>null==(e=e.month())?void 0:e.toString().padStart(2,"0"),"%d":e=>null==(e=e.date())?void 0:e.toString().padStart(2,"0"),"%H":e=>null==(e=e.hour())?void 0:e.toString().padStart(2,"0"),"%M":e=>null==(e=e.minute())?void 0:e.toString().padStart(2,"0"),"%S":e=>null==(e=e.second())?void 0:e.toString().padStart(2,"0"),"%f":e=>null==(e=e.millisecond())?void 0:e.toString().padStart(3,"0"),"%z":e=>{e=e.utcOffset();if(e)return(0<=e?"+":"-")+Math.floor(Math.abs(e)/60).toString().padStart(2,"0")+(Math.abs(e)%60).toString().padStart(2,"0")},"%s":e=>{e=e.valueOf();return e?Math.floor(e/1e3).toString():void 0}},f.PREDEFINED_FORMATS={ISO:"%Y-%m-%dT%H:%M:%S.%fZ",ISO_DATE:"%Y-%m-%d",ISO_TIME:"%H:%M:%S.%fZ",COMPACT:"%Y%m%d%H%M%S",SLASH_DATETIME:"%Y/%m/%d %H:%M:%S.%fZ",SLASH_DATETIME_SEC:"%Y/%m/%d %H:%M:%S",SLASH_DATETIME_MIN:"%Y/%m/%d %H:%M",EUROPEAN:"%d/%m/%Y %H:%M:%S GMT%z",SLASH_DATE:"%Y/%m/%d",TIME_MICRO:"%H:%M:%S.%fZ",TIME_SEC:"%H:%M:%S",CUSTOM_GREETING:"[Bonjour celestin, ][la date actuelle est:: le] %d/%m/%Y [à] %H:%M:%S.%f[Z]"},"undefined"!=typeof window&&(window.Timez=f),timez.Timez=f,timez.default=f}return timez}function requireCooks(){if(!hasRequiredCooks){hasRequiredCooks=1,Object.defineProperty(cooks,"__esModule",{value:!0});var r=requireTimez(),e=["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"];[...e,...e.map(e=>e.toUpperCase())];class t{static set(e,t,a={}){if(this.isBrowser())try{var i=this.serialize(t),r=encodeURIComponent(i),s=this.buildCookieString(e,r,a);document.cookie=s}catch(e){}}static get(e){if(!this.isBrowser())return null;try{var t,a=this.getAllCookies()[e];return a?(t=decodeURIComponent(a),this.deserialize(t)):null}catch(e){return null}}static remove(e,t="/",a){this.isBrowser()&&(t={expires:new Date(0),path:t,domain:a},this.set(e,"",t))}static has(e){return null!==this.get(e)}static keys(){var e;return this.isBrowser()?(e=this.getAllCookies(),Object.keys(e)):[]}static clear(){var e;this.isBrowser()&&(e=this.getAllCookies(),Object.keys(e).forEach(e=>{this.remove(e)}))}static serialize(e){return e instanceof Date?JSON.stringify({__type:"Date",__value:e.toISOString()}):JSON.stringify(e)}static deserialize(e){e=JSON.parse(e);return e&&"object"==typeof e&&"Date"===e.__type?new Date(e.__value):e}static buildCookieString(e,t,a){a=Object.assign(Object.assign({},this.DEFAULT_OPTIONS),a);let i=e+"="+t;if(void 0!==a.expires){let e;e="number"==typeof a.expires?(new r.Timez).add(a.expires,"seconds").toDate()||new Date:a.expires,i+="; expires="+e.toUTCString()}return a.path&&(i+="; path="+a.path),a.domain&&(i+="; domain="+a.domain),a.secure&&(i+="; secure"),a.sameSite&&(i+="; samesite="+a.sameSite),i}static getAllCookies(){return document.cookie.split(";").reduce((e,t)=>{var[t,a]=t.split("=").map(e=>e.trim());return t&&(e[t]=a||""),e},{})}static isBrowser(){return"undefined"!=typeof window&&"undefined"!=typeof document}static exposeToGlobal(){"undefined"!=typeof window&&(window.Cooks=t)}}t.DEFAULT_OPTIONS={path:"/",secure:!0,sameSite:"lax"},"undefined"!=typeof window&&(window.Cooks=t),cooks.Cooks=t,cooks.default=t}return cooks}requireCooks();let DEFAULT_SCOPE="app";export{DEFAULT_SCOPE};
2
+ //# sourceMappingURL=index.min.js.map
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "0.0.94",
6
+ "version": "0.0.95",
7
7
  "description": "CONFIG-MANAGER est un système de gestion de configuration modulaire pour les applications React avec TypeScript/JavaScript. Il fournit une gestion centralisée des configurations, un chargement dynamique des modules, et une intégration transparente avec les variables d'environnement.",
8
8
  "main": "index.js",
9
9
  "keywords": [],
@@ -16,6 +16,7 @@
16
16
  "devDependencies": {
17
17
  },
18
18
  "dependencies": {
19
- "react": "^19.2.3"
19
+ "react": "^19.2.3",
20
+ "@arc-js/cooks": "^0.0.3"
20
21
  }
21
22
  }
@@ -1,74 +1,103 @@
1
1
  import React from "react";
2
2
  import { createContext, useContext, useState, useEffect, useCallback } from 'react';
3
3
  import { ConfigService } from '../core/ConfigService';
4
- import { setConfigManagerConfig } from '../config';
5
- const ConfigManagerContext = createContext(null);
6
- const useConfigManagerValue = configManagerConfig => {
7
- const [service] = useState(() => new ConfigService());
8
- const [isLoading, setIsLoading] = useState(true)
9
-
10
- useEffect(() => {
11
- setConfigManagerConfig(configManagerConfig);
12
- }, [configManagerConfig])
4
+ import { getSavedScope, saveScope, DEFAULT_SCOPE } from '../config';
5
+ const ArcConfigContext = createContext(null);
6
+ const useArcConfigValue = (configManagerConfig, supportedScopes = [DEFAULT_SCOPE]) => {
7
+ const [service] = useState(() => new ConfigService(supportedScopes, configManagerConfig));
8
+ const [currentScope, setCurrentScope] = useState(getSavedScope());
9
+ const [isLoading, setIsLoading] = useState(true);
10
+ const [initialized, setInitialized] = useState(false)
13
11
 
14
12
  useEffect(() => {
15
13
  const initialize = async () => {
16
14
  setIsLoading(true);
17
15
  try {
18
- await service.initialize();
16
+ if (!initialized) {
17
+ await service.initialize(currentScope);
18
+ setInitialized(true);
19
+ } else {
20
+ await service.initialize(currentScope);
21
+ }
19
22
  } catch (error) {
20
- console.error('Failed to initialize config manager:', error);
23
+ console.error('Failed to initialize config:', error);
21
24
  } finally {
22
25
  setIsLoading(false);
23
26
  }
24
27
  };
25
- initialize();
26
- }, [service]);
27
- const reloadConfig = useCallback(async () => {
28
+ const timer = setTimeout(() => {
29
+ initialize();
30
+ }, 0);
31
+ return () => clearTimeout(timer);
32
+ }, [currentScope, service, initialized])
33
+
34
+ useEffect(() => {
35
+ if (!initialized || isLoading || !configManagerConfig.modules) return;
36
+ const loadAllModules = async () => {
37
+ const moduleNames = Object.keys(configManagerConfig.modules || {});
38
+ for (const moduleName of moduleNames) {
39
+ try {
40
+ await service.loadModule(moduleName);
41
+ } catch (error) {
42
+ console.error(`❌ Failed to load module ${moduleName}:`, error);
43
+ }
44
+ }
45
+ };
46
+ loadAllModules();
47
+ }, [initialized, configManagerConfig.modules, service, isLoading]);
48
+ const changeScope = useCallback(async scope => {
49
+ if (!supportedScopes.includes(scope)) {
50
+ console.warn(`⚠️ Scope ${scope} is not supported`);
51
+ return;
52
+ }
53
+ if (scope === currentScope) return;
28
54
  setIsLoading(true);
29
55
  try {
30
- await service.reload();
56
+ await service.initialize(scope);
57
+ setCurrentScope(scope);
58
+ saveScope(scope);
31
59
  } catch (error) {
32
- console.error('Failed to reload config:', error);
60
+ console.error('Failed to change scope:', error);
33
61
  } finally {
34
62
  setIsLoading(false);
35
63
  }
36
- }, [service]);
64
+ }, [currentScope, supportedScopes, service]);
37
65
  const loadModuleConfig = useCallback(async moduleName => {
38
66
  setIsLoading(true);
39
67
  try {
40
68
  await service.loadModule(moduleName);
41
69
  } catch (error) {
42
- console.error(`Failed to load module config ${moduleName}:`, error);
70
+ console.error(`❌ Failed to load module ${moduleName}:`, error);
71
+ throw error;
43
72
  } finally {
44
73
  setIsLoading(false);
45
74
  }
46
75
  }, [service]);
47
76
  const get = useCallback((key, options) => {
48
- return service.get(key, options);
49
- }, [service]);
50
- const getConfig = useCallback(moduleName => {
51
- return service.getConfig(moduleName);
77
+ const result = service.get(key, options || {});
78
+ return result;
52
79
  }, [service]);
53
80
  return {
54
81
  get,
55
- getConfig,
56
- reloadConfig,
82
+ changeScope,
83
+ currentScope,
57
84
  isLoading,
58
- loadModuleConfig
85
+ loadModuleConfig,
86
+ isInitialized: initialized
59
87
  };
60
88
  };
61
- export const ConfigManagerProvider = ({
62
- configs,
89
+ export const ArcConfigProvider = ({
90
+ config,
91
+ supportedScopes,
63
92
  children
64
93
  }) => {
65
- const value = useConfigManagerValue(configs);
66
- return React.createElement(ConfigManagerContext.Provider, {
94
+ const value = useArcConfigValue(config, typeof supportedScopes === 'object' && !!Array.isArray(supportedScopes) && supportedScopes.length > 0 ? supportedScopes : [DEFAULT_SCOPE]);
95
+ return React.createElement(ArcConfigContext.Provider, {
67
96
  value: value
68
97
  }, children);
69
98
  };
70
- export const useConfigManager = () => {
71
- const context = useContext(ConfigManagerContext);
72
- if (!context) throw new Error('useConfigManager must be used within a ConfigManagerProvider');
99
+ export const useArcConfig = () => {
100
+ const context = useContext(ArcConfigContext);
101
+ if (!context) throw new Error('useArcConfig must be used within an ArcConfigProvider');
73
102
  return context;
74
103
  };
@@ -1,90 +1,134 @@
1
- // @arc-js/config-manager/providers/ConfigProvider.tsx
2
- import { createContext, useContext, useState, useEffect, useCallback } from 'react';
1
+ import { createContext, useContext, useState, useEffect, useMemo, useCallback } from 'react';
3
2
  import { ConfigService } from '../core/ConfigService';
4
- import { setConfigManagerConfig } from '../config';
5
- import type { ConfigManagerConfig } from '../config';
3
+ import { getSavedScope, saveScope, DEFAULT_SCOPE, type ConfigManagerConfig } from '../config';
4
+ import type { ConfigScope } from '../config';
6
5
 
7
- const ConfigManagerContext = createContext<ReturnType<typeof useConfigManagerValue> | null>(null);
6
+ const ArcConfigContext = createContext<ReturnType<typeof useArcConfigValue> | null>(null);
8
7
 
9
- const useConfigManagerValue = (
10
- configManagerConfig: ConfigManagerConfig
8
+ const useArcConfigValue = (
9
+ configManagerConfig: ConfigManagerConfig,
10
+ supportedScopes: string[] = [DEFAULT_SCOPE]
11
11
  ) => {
12
- const [service] = useState(() => new ConfigService());
13
- const [isLoading, setIsLoading] = useState(true);
14
-
15
-
16
- useEffect(() => {
17
- setConfigManagerConfig(configManagerConfig);
18
- }, [configManagerConfig]);
19
-
20
-
21
- useEffect(() => {
22
- const initialize = async () => {
23
- setIsLoading(true);
24
- try {
25
- await service.initialize();
26
- } catch (error) {
27
- console.error('Failed to initialize config manager:', error);
28
- } finally {
29
- setIsLoading(false);
30
- }
12
+ const [service] = useState(() => new ConfigService(supportedScopes, configManagerConfig));
13
+ const [currentScope, setCurrentScope] = useState<ConfigScope>(getSavedScope());
14
+ const [isLoading, setIsLoading] = useState(true);
15
+ const [initialized, setInitialized] = useState(false);
16
+
17
+
18
+ useEffect(() => {
19
+ const initialize = async () => {
20
+ setIsLoading(true);
21
+ try {
22
+ if (!initialized) {
23
+ await service.initialize(currentScope);
24
+ setInitialized(true);
25
+ } else {
26
+ await service.initialize(currentScope);
27
+ }
28
+ } catch (error) {
29
+ console.error('❌ Failed to initialize config:', error);
30
+ } finally {
31
+ setIsLoading(false);
32
+ }
33
+ };
34
+
35
+ const timer = setTimeout(() => {
36
+ initialize();
37
+ }, 0);
38
+
39
+ return () => clearTimeout(timer);
40
+ }, [currentScope, service, initialized]);
41
+
42
+
43
+ useEffect(() => {
44
+ if (!initialized || isLoading || !configManagerConfig.modules) return;
45
+
46
+ const loadAllModules = async () => {
47
+ const moduleNames = Object.keys(configManagerConfig.modules || {});
48
+
49
+ for (const moduleName of moduleNames) {
50
+ try {
51
+ await service.loadModule(moduleName);
52
+ } catch (error) {
53
+ console.error(`❌ Failed to load module ${moduleName}:`, error);
54
+ }
55
+ }
56
+ };
57
+
58
+ loadAllModules();
59
+ }, [initialized, configManagerConfig.modules, service, isLoading]);
60
+
61
+ const changeScope = useCallback(async (scope: ConfigScope) => {
62
+ if (!supportedScopes.includes(scope)) {
63
+ console.warn(`⚠️ Scope ${scope} is not supported`);
64
+ return;
65
+ }
66
+
67
+ if (scope === currentScope) return;
68
+
69
+ setIsLoading(true);
70
+ try {
71
+ await service.initialize(scope);
72
+ setCurrentScope(scope);
73
+ saveScope(scope);
74
+ } catch (error) {
75
+ console.error('❌ Failed to change scope:', error);
76
+ } finally {
77
+ setIsLoading(false);
78
+ }
79
+ }, [currentScope, supportedScopes, service]);
80
+
81
+ const loadModuleConfig = useCallback(async (moduleName: string) => {
82
+ setIsLoading(true);
83
+ try {
84
+ await service.loadModule(moduleName);
85
+ } catch (error) {
86
+ console.error(`❌ Failed to load module ${moduleName}:`, error);
87
+ throw error;
88
+ } finally {
89
+ setIsLoading(false);
90
+ }
91
+ }, [service]);
92
+
93
+ const get = useCallback((key: string, options?: any) => {
94
+ const result = service.get(key, options || {});
95
+ return result;
96
+ }, [service]);
97
+
98
+ return {
99
+ get,
100
+ changeScope,
101
+ currentScope,
102
+ isLoading,
103
+ loadModuleConfig,
104
+ isInitialized: initialized,
31
105
  };
32
- initialize();
33
- }, [service]);
34
-
35
- const reloadConfig = useCallback(async () => {
36
- setIsLoading(true);
37
- try {
38
- await service.reload();
39
- } catch (error) {
40
- console.error('Failed to reload config:', error);
41
- } finally {
42
- setIsLoading(false);
43
- }
44
- }, [service]);
45
-
46
- const loadModuleConfig = useCallback(async (moduleName: string) => {
47
- setIsLoading(true);
48
- try {
49
- await service.loadModule(moduleName);
50
- } catch (error) {
51
- console.error(`Failed to load module config ${moduleName}:`, error);
52
- } finally {
53
- setIsLoading(false);
54
- }
55
- }, [service]);
56
-
57
- const get = useCallback((key: string, options?: any) => {
58
- return service.get(key, options);
59
- }, [service]);
60
-
61
- const getConfig = useCallback((moduleName?: string) => {
62
- return service.getConfig(moduleName);
63
- }, [service]);
64
-
65
- return {
66
- get,
67
- getConfig,
68
- reloadConfig,
69
- isLoading,
70
- loadModuleConfig,
71
- };
72
106
  };
73
107
 
74
- export const ConfigManagerProvider: React.FC<{
75
- children: React.ReactNode
76
- configs: ConfigManagerConfig
108
+ export const ArcConfigProvider: React.FC<{
109
+ children: React.ReactNode
110
+ config: ConfigManagerConfig
111
+ supportedScopes?: string[];
77
112
  }> = ({
78
- configs,
79
- children,
113
+ config,
114
+ supportedScopes,
115
+ children,
80
116
  }) => {
81
- const value = useConfigManagerValue(configs);
82
-
83
- return <ConfigManagerContext.Provider value={value}>{children}</ConfigManagerContext.Provider>;
84
- };
85
117
 
86
- export const useConfigManager = () => {
87
- const context = useContext(ConfigManagerContext);
88
- if (!context) throw new Error('useConfigManager must be used within a ConfigManagerProvider');
89
- return context;
118
+ const value = useArcConfigValue(
119
+ config,
120
+ (typeof supportedScopes === 'object' &&
121
+ !!Array.isArray(supportedScopes) &&
122
+ supportedScopes.length > 0)
123
+ ? supportedScopes
124
+ : [DEFAULT_SCOPE]
125
+ );
126
+
127
+ return <ArcConfigContext.Provider value={value}>{children}</ArcConfigContext.Provider>;
128
+ };
129
+
130
+ export const useArcConfig = () => {
131
+ const context = useContext(ArcConfigContext);
132
+ if (!context) throw new Error('useArcConfig must be used within an ArcConfigProvider');
133
+ return context;
90
134
  };
@@ -1,24 +1,21 @@
1
- interface ConfigMap {
2
- [key: string]: () => Promise<Record<string, any>>;
3
- }
4
1
  interface ModuleConfigs {
5
2
  [moduleName: string]: () => Promise<Record<string, any>>;
6
3
  }
7
- interface ConfigData {
8
- base: ConfigMap;
4
+ interface ConfigManagerConfig {
5
+ base: {
6
+ [scope: string]: () => Promise<Record<string, any>>;
7
+ };
9
8
  modules?: ModuleConfigs;
10
9
  }
11
- type ConfigManagerConfig = ConfigData;
12
- declare const setConfigManagerConfig: (config: ConfigManagerConfig) => void;
13
10
 
14
- declare const loadBaseConfig: () => Promise<Record<string, any>>;
15
- declare const loadModulesConfigs: () => Promise<Array<{
11
+ declare const loadBaseConfig: (scope: string, configManagerConfig: ConfigManagerConfig) => Promise<Record<string, any>>;
12
+ declare const loadModulesConfig: (configManagerConfig: ConfigManagerConfig) => Promise<Array<{
16
13
  moduleName: string;
17
14
  config: Record<string, any>;
18
15
  }>>;
19
- declare const loadModuleConfig: (moduleName: string) => Promise<{
16
+ declare const loadModuleConfig: (moduleName: string, configManagerConfig: ConfigManagerConfig) => Promise<{
20
17
  moduleName: string;
21
18
  config: Record<string, any>;
22
19
  } | undefined>;
23
20
 
24
- export { loadBaseConfig, loadModuleConfig, loadModulesConfigs, setConfigManagerConfig };
21
+ export { loadBaseConfig, loadModuleConfig, loadModulesConfig };
package/utils/loaders.js CHANGED
@@ -8,7 +8,7 @@ function __awaiter(thisArg, _arguments, P, generator) {
8
8
  function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
9
9
  function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
10
10
  function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
11
- step((generator = generator.apply(thisArg, _arguments || [])).next());
11
+ step((generator = generator.apply(thisArg, [])).next());
12
12
  });
13
13
  }
14
14
 
@@ -17,58 +17,47 @@ typeof SuppressedError === "function" ? SuppressedError : function (error, suppr
17
17
  return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
18
18
  };
19
19
 
20
- let configManagerConfig = null;
21
- const setConfigManagerConfig = (config) => {
22
- configManagerConfig = config;
23
- };
24
-
25
- const loadBaseConfig = () => __awaiter(void 0, void 0, void 0, function* () {
20
+ const loadBaseConfig = (scope, configManagerConfig) => __awaiter(void 0, void 0, void 0, function* () {
21
+ if (!(configManagerConfig === null || configManagerConfig === void 0 ? void 0 : configManagerConfig.base[scope])) {
22
+ console.warn(`❌ No base config found for scope: ${scope}`);
23
+ console.warn('Available scopes:', (configManagerConfig === null || configManagerConfig === void 0 ? void 0 : configManagerConfig.base) ? Object.keys(configManagerConfig.base) : 'none');
24
+ return {};
25
+ }
26
26
  try {
27
- if (!(configManagerConfig === null || configManagerConfig === void 0 ? void 0 : configManagerConfig.base)) {
28
- console.warn('No base config found');
29
- return {};
30
- }
31
- const baseConfigs = yield Promise.all(Object.entries(configManagerConfig.base).map((_a) => __awaiter(void 0, [_a], void 0, function* ([key, loader]) {
32
- try {
33
- const config = yield loader();
34
- return { key, config };
35
- }
36
- catch (error) {
37
- console.error(`Failed to load base config ${key}:`, error);
38
- return { key, config: {} };
39
- }
40
- })));
41
- return baseConfigs.reduce((acc, { key, config }) => {
42
- return Object.assign(Object.assign({}, acc), config);
43
- }, {});
27
+ const loader = configManagerConfig.base[scope];
28
+ const result = yield loader();
29
+ return result;
44
30
  }
45
31
  catch (error) {
46
- console.error('Failed to load base config:', error);
32
+ console.error(`❌ Failed to load base ${scope} config`, error);
47
33
  return {};
48
34
  }
49
35
  });
50
- const loadModulesConfigs = () => __awaiter(void 0, void 0, void 0, function* () {
36
+ const loadModulesConfig = (configManagerConfig) => __awaiter(void 0, void 0, void 0, function* () {
51
37
  const results = [];
52
38
  if (!(configManagerConfig === null || configManagerConfig === void 0 ? void 0 : configManagerConfig.modules)) {
39
+ console.warn(`⚠️ No modules configuration found`);
53
40
  return results;
54
41
  }
55
- for (const [moduleName, loader] of Object.entries(configManagerConfig.modules)) {
42
+ for (const [moduleName, moduleLoader] of Object.entries(configManagerConfig.modules)) {
56
43
  try {
57
- const config = yield loader();
44
+ const config = yield moduleLoader();
58
45
  results.push({
59
46
  moduleName,
60
47
  config
61
48
  });
62
49
  }
63
50
  catch (error) {
64
- console.error(`Failed to load config for module "${moduleName}"`, error);
51
+ console.error(`❌ Failed to load config for module "${moduleName}"`, error);
65
52
  }
66
53
  }
67
54
  return results;
68
55
  });
69
- const loadModuleConfig = (moduleName) => __awaiter(void 0, void 0, void 0, function* () {
56
+ const loadModuleConfig = (moduleName, configManagerConfig) => __awaiter(void 0, void 0, void 0, function* () {
70
57
  var _a;
71
58
  if (!((_a = configManagerConfig === null || configManagerConfig === void 0 ? void 0 : configManagerConfig.modules) === null || _a === void 0 ? void 0 : _a[moduleName])) {
59
+ console.warn(`❌ No config found for module "${moduleName}"`);
60
+ console.warn('Available modules:', (configManagerConfig === null || configManagerConfig === void 0 ? void 0 : configManagerConfig.modules) ? Object.keys(configManagerConfig.modules) : 'none');
72
61
  return undefined;
73
62
  }
74
63
  try {
@@ -80,9 +69,9 @@ const loadModuleConfig = (moduleName) => __awaiter(void 0, void 0, void 0, funct
80
69
  };
81
70
  }
82
71
  catch (error) {
83
- console.error(`Failed to load config for module "${moduleName}"`, error);
72
+ console.error(`❌ Failed to load config for module "${moduleName}"`, error);
84
73
  return undefined;
85
74
  }
86
75
  });
87
76
 
88
- export { loadBaseConfig, loadModuleConfig, loadModulesConfigs, setConfigManagerConfig };
77
+ export { loadBaseConfig, loadModuleConfig, loadModulesConfig };
@@ -1,2 +1,2 @@
1
- function __awaiter(n,g,r,t){return new(r=r||Promise)(function(i,o){function e(n){try{f(t.next(n))}catch(n){o(n)}}function a(n){try{f(t.throw(n))}catch(n){o(n)}}function f(n){var o;n.done?i(n.value):((o=n.value)instanceof r?o:new r(function(n){n(o)})).then(e,a)}f((t=t.apply(n,g||[])).next())})}let configManagerConfig=null,setConfigManagerConfig=n=>{configManagerConfig=n},loadBaseConfig=()=>__awaiter(void 0,void 0,void 0,function*(){try{return null!=configManagerConfig&&configManagerConfig.base?(yield Promise.all(Object.entries(configManagerConfig.base).map(n=>__awaiter(void 0,[n],void 0,function*([o,n]){try{return{key:o,config:yield n()}}catch(n){return{key:o,config:{}}}})))).reduce((n,{config:o})=>Object.assign(Object.assign({},n),o),{}):{}}catch(n){return{}}}),loadModulesConfigs=()=>__awaiter(void 0,void 0,void 0,function*(){var n=[];if(null!=configManagerConfig&&configManagerConfig.modules)for(var[o,i]of Object.entries(configManagerConfig.modules))try{var e=yield i();n.push({moduleName:o,config:e})}catch(n){}return n}),loadModuleConfig=i=>__awaiter(void 0,void 0,void 0,function*(){var n;if(null!=(n=null==configManagerConfig?void 0:configManagerConfig.modules)&&n[i])try{var o=yield(0,configManagerConfig.modules[i])();return{moduleName:i,config:o}}catch(n){}});export{loadBaseConfig,loadModuleConfig,loadModulesConfigs,setConfigManagerConfig};
1
+ function __awaiter(o,n,r,u){return new(r=r||Promise)(function(e,n){function i(o){try{a(u.next(o))}catch(o){n(o)}}function t(o){try{a(u.throw(o))}catch(o){n(o)}}function a(o){var n;o.done?e(o.value):((n=o.value)instanceof r?n:new r(function(o){o(n)})).then(i,t)}a((u=u.apply(o,[])).next())})}let loadBaseConfig=(o,n)=>__awaiter(void 0,void 0,void 0,function*(){if(null==n||!n.base[o])return{};try{return yield(0,n.base[o])()}catch(o){return{}}}),loadModulesConfig=t=>__awaiter(void 0,void 0,void 0,function*(){var o=[];if(null!=t&&t.modules)for(var[n,e]of Object.entries(t.modules))try{var i=yield e();o.push({moduleName:n,config:i})}catch(o){}return o}),loadModuleConfig=(e,i)=>__awaiter(void 0,void 0,void 0,function*(){var o;if(null!=(o=null==i?void 0:i.modules)&&o[e])try{var n=yield(0,i.modules[e])();return{moduleName:e,config:n}}catch(o){}});export{loadBaseConfig,loadModuleConfig,loadModulesConfig};
2
2
  //# sourceMappingURL=loaders.min.js.map
package/utils.d.ts ADDED
@@ -0,0 +1,23 @@
1
+ declare const mergeDeep: (target: any, source: any) => any;
2
+
3
+ interface ModuleConfigs {
4
+ [moduleName: string]: () => Promise<Record<string, any>>;
5
+ }
6
+ interface ConfigManagerConfig {
7
+ base: {
8
+ [scope: string]: () => Promise<Record<string, any>>;
9
+ };
10
+ modules?: ModuleConfigs;
11
+ }
12
+
13
+ declare const loadBaseConfig: (scope: string, configManagerConfig: ConfigManagerConfig) => Promise<Record<string, any>>;
14
+ declare const loadModulesConfig: (configManagerConfig: ConfigManagerConfig) => Promise<Array<{
15
+ moduleName: string;
16
+ config: Record<string, any>;
17
+ }>>;
18
+ declare const loadModuleConfig: (moduleName: string, configManagerConfig: ConfigManagerConfig) => Promise<{
19
+ moduleName: string;
20
+ config: Record<string, any>;
21
+ } | undefined>;
22
+
23
+ export { loadBaseConfig, loadModuleConfig, loadModulesConfig, mergeDeep };