Comparing version
import { JITI } from 'jiti'; | ||
import { JITIOptions } from 'jiti/dist/types'; | ||
import { WatchOptions } from 'chokidar'; | ||
import { diff } from 'ohash'; | ||
@@ -94,2 +96,26 @@ interface DotenvOptions { | ||
export { C12InputConfig, ConfigLayer, ConfigLayerMeta, DefineConfig, DotenvOptions, Env, InputConfig, LoadConfigOptions, ResolvedConfig, SourceOptions, UserInputConfig, createDefineConfig, loadConfig, loadDotenv, setupDotenv }; | ||
type ConfigWatcher<T extends UserInputConfig = UserInputConfig, MT extends ConfigLayerMeta = ConfigLayerMeta> = ResolvedConfig<T, MT> & { | ||
watchingFiles: string[]; | ||
unwatch: () => Promise<void>; | ||
}; | ||
interface WatchConfigOptions<T extends UserInputConfig = UserInputConfig, MT extends ConfigLayerMeta = ConfigLayerMeta> extends LoadConfigOptions<T, MT> { | ||
chokidarOptions?: WatchOptions; | ||
debounce?: false | number; | ||
onWatch?: (event: { | ||
type: "created" | "updated" | "removed"; | ||
path: string; | ||
}) => void | Promise<void>; | ||
acceptHMR?: (context: { | ||
getDiff: () => ReturnType<typeof diff>; | ||
newConfig: ResolvedConfig<T, MT>; | ||
oldConfig: ResolvedConfig<T, MT>; | ||
}) => void | boolean | Promise<void | boolean>; | ||
onUpdate?: (context: { | ||
getDiff: () => ReturnType<typeof diff>; | ||
newConfig: ResolvedConfig<T, MT>; | ||
oldConfig: ResolvedConfig<T, MT>; | ||
}) => void | Promise<void>; | ||
} | ||
declare function watchConfig<T extends UserInputConfig = UserInputConfig, MT extends ConfigLayerMeta = ConfigLayerMeta>(options: WatchConfigOptions<T, MT>): Promise<ConfigWatcher<T, MT>>; | ||
export { C12InputConfig, ConfigLayer, ConfigLayerMeta, ConfigWatcher, DefineConfig, DotenvOptions, Env, InputConfig, LoadConfigOptions, ResolvedConfig, SourceOptions, UserInputConfig, WatchConfigOptions, createDefineConfig, loadConfig, loadDotenv, setupDotenv, watchConfig }; |
{ | ||
"name": "c12", | ||
"version": "1.3.0", | ||
"version": "1.4.0", | ||
"description": "Smart Config Loader", | ||
@@ -33,2 +33,3 @@ "repository": "unjs/c12", | ||
"dependencies": { | ||
"chokidar": "^3.5.3", | ||
"defu": "^6.1.2", | ||
@@ -39,3 +40,5 @@ "dotenv": "^16.0.3", | ||
"mlly": "^1.2.0", | ||
"ohash": "^1.1.1", | ||
"pathe": "^1.1.0", | ||
"perfect-debounce": "^0.1.3", | ||
"pkg-types": "^1.0.2", | ||
@@ -55,3 +58,3 @@ "rc9": "^2.1.0" | ||
}, | ||
"packageManager": "pnpm@8.2.0" | ||
"packageManager": "pnpm@8.3.0" | ||
} |
@@ -19,2 +19,3 @@ # ⚙️ c12 | ||
- Overwrite with [environment-specific configuration](#environment-specific-configuration) | ||
- Config watcher with auto-reload and HMR support | ||
@@ -40,6 +41,6 @@ ## Usage | ||
// ESM | ||
import { loadConfig } from "c12"; | ||
import { loadConfig, watchConfig } from "c12"; | ||
// CommonJS | ||
const { loadConfig } = require("c12"); | ||
const { loadConfig, watchConfig } = require("c12"); | ||
``` | ||
@@ -64,3 +65,3 @@ | ||
3. RC file in CWD | ||
4. Global RC file in user's home directory | ||
4. Global RC file in the user's home directory | ||
5. Config from `package.json` | ||
@@ -240,2 +241,42 @@ 6. Default config passed by options | ||
## Watching Configuration | ||
you can use `watchConfig` instead of `loadConfig` to load config and watch for changes, add and removals in all expected configuration paths and auto reload with new config. | ||
### Lifecycle hooks | ||
- `onWatch`: This function is always called when config is updated, added, or removed before attempting to reload the config. | ||
- `acceptHMR`: By implementing this function, you can compare old and new functions and return `true` if a full reload is not needed. | ||
- `onUpdate`: This function is always called after the new config is updated. If `acceptHMR` returns true, it will be skipped. | ||
```ts | ||
import { watchConfig } from "c12"; | ||
const config = watchConfig({ | ||
cwd: ".", | ||
// chokidarOptions: {}, // Default is { ignoreInitial: true } | ||
// debounce: 200 // Default is 100. You can set it to false to disable debounced watcher | ||
onWatch: (event) => { | ||
console.log("[watcher]", event.type, event.path); | ||
}, | ||
acceptHMR({ oldConfig, newConfig, getDiff }) { | ||
const diff = getDiff(); | ||
if (diff.length === 0) { | ||
console.log("No config changed detected!"); | ||
return true; // No changes! | ||
} | ||
}, | ||
onUpdate({ oldConfig, newConfig, getDiff }) { | ||
const diff = getDiff(); | ||
console.log("Config updated:\n" + diff.map((i) => i.toJSON()).join("\n")); | ||
}, | ||
}); | ||
console.log("watching config files:", config.watchingFiles); | ||
console.log("initial config", config.config); | ||
// Stop watcher when not needed anymore | ||
// await config.unwatch(); | ||
``` | ||
## 💻 Development | ||
@@ -242,0 +283,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
39465
22.51%889
26.46%299
15.89%11
37.5%+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added