mirror of
https://github.com/hanzo-docs/docs.git
synced 2026-10-24 20:09:02 +00:00
feat(core): support invalidate & revalidate on dynamic loader
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
---
|
||||
'@fumadocs/local-md': patch
|
||||
'fumadocs-core': patch
|
||||
---
|
||||
|
||||
Support `invalidate` & `revalidate` on dynamic loader
|
||||
@@ -15,12 +15,7 @@ import { Loader2, MessageCircleIcon, RefreshCw, SearchIcon, Send, X } from 'luci
|
||||
import { cn } from '@/lib/cn';
|
||||
import { buttonVariants } from 'fumadocs-ui/components/ui/button';
|
||||
import { useChat, type UseChatHelpers } from '@ai-sdk/react';
|
||||
import {
|
||||
DefaultChatTransport,
|
||||
type Tool,
|
||||
type UIMessage,
|
||||
type UIToolInvocation,
|
||||
} from 'ai';
|
||||
import { DefaultChatTransport, type Tool, type UIMessage, type UIToolInvocation } from 'ai';
|
||||
import { Markdown } from '../markdown';
|
||||
import { Presence } from '@radix-ui/react-presence';
|
||||
|
||||
|
||||
@@ -91,7 +91,7 @@ const source = dynamicLoader(
|
||||
export async function getSource() {
|
||||
const { isEnabled } = await draftMode();
|
||||
|
||||
if (isEnabled) source.revalidate();
|
||||
if (isEnabled) source.invalidate();
|
||||
return source.get();
|
||||
}
|
||||
```
|
||||
|
||||
@@ -242,14 +242,18 @@ const page = docs.getPage(['...']);
|
||||
|
||||
Dynamic sources are cached by the loader.
|
||||
|
||||
If your source changes over time, call `revalidate()` to clear the cache:
|
||||
If your source changes over time, call `invalidate()` to clear the cache, or `revalidate()` to update the cache:
|
||||
|
||||
```ts
|
||||
source.revalidate();
|
||||
source.invalidate();
|
||||
|
||||
await source.revalidate();
|
||||
```
|
||||
|
||||
For [multi-source](/docs/headless/source-api/source#multiple-sources) setups, you can revalidate a specific source:
|
||||
For [multi-source](/docs/headless/source-api/source#multiple-sources) setups, you can invalidate/revalidate a specific source:
|
||||
|
||||
```ts
|
||||
source.revalidate('docs');
|
||||
source.invalidate('docs');
|
||||
|
||||
await source.revalidate('docs');
|
||||
```
|
||||
|
||||
@@ -110,7 +110,7 @@ export function createMySource(): DynamicSource<{
|
||||
configure(loader) {
|
||||
// you can revalidate the loader from source, e.g.
|
||||
onMyEvent(() => {
|
||||
loader.revalidate();
|
||||
void loader.revalidate();
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
@@ -17,8 +17,8 @@
|
||||
"@ai-sdk/react": "^3.0.193",
|
||||
"@floating-ui/react-dom": "^2.1.8",
|
||||
"@fumadocs/story": "workspace:*",
|
||||
"@mixedbread/sdk": "^0.71.0",
|
||||
"@llmgateway/ai-sdk-provider": "^3.8.0",
|
||||
"@mixedbread/sdk": "^0.71.0",
|
||||
"@openrouter/ai-sdk-provider": "^2.9.0",
|
||||
"@orama/core": "^1.2.19",
|
||||
"@orama/orama": "^3.1.18",
|
||||
|
||||
@@ -13,7 +13,10 @@ export interface DynamicLoaderConfig extends LoaderConfig {
|
||||
|
||||
export interface DynamicLoader<Config extends DynamicLoaderConfig = DynamicLoaderConfig> {
|
||||
get: () => Promise<LoaderOutput<Config>>;
|
||||
revalidate: (source?: Config['source']) => void;
|
||||
/** update & re-compute dynamic sources */
|
||||
revalidate: (source?: Config['source']) => Promise<void>;
|
||||
/** remove computed cache of dynamic sources */
|
||||
invalidate: (source?: Config['source']) => void;
|
||||
|
||||
get $inferPage(): Config['page'];
|
||||
get $inferMeta(): Config['meta'];
|
||||
@@ -46,22 +49,25 @@ export function dynamicLoader<I extends Input, I18n extends I18nConfig | undefin
|
||||
}
|
||||
}
|
||||
|
||||
async function resolveSources(): Promise<ResolvedSource> {
|
||||
if (isStaticSource(input)) return input;
|
||||
if (isDynamicSource(input)) return resolveDynamicSource(input);
|
||||
async function resolveSources(skipCache = false): Promise<ResolvedSource> {
|
||||
if (isStaticSource(input) || isDynamicSource(input)) {
|
||||
return resolveSource(input, skipCache);
|
||||
}
|
||||
|
||||
const entries = await Promise.all(
|
||||
Object.entries(input).map(async ([k, v]): Promise<[string, StaticSource]> => {
|
||||
if (isStaticSource(v)) return [k, v];
|
||||
return [k, await resolveDynamicSource(v)];
|
||||
}),
|
||||
Object.entries(input).map(async ([k, v]) => [k, await resolveSource(v, skipCache)]),
|
||||
);
|
||||
|
||||
return Object.fromEntries(entries);
|
||||
}
|
||||
|
||||
function resolveDynamicSource(v: DynamicSource): Awaitable<StaticSource> {
|
||||
let resolved = sourceCache.get(v);
|
||||
function resolveSource(
|
||||
v: StaticSource | DynamicSource,
|
||||
skipCache = false,
|
||||
): Awaitable<StaticSource> {
|
||||
if (isStaticSource(v)) return v;
|
||||
|
||||
let resolved = skipCache ? undefined : sourceCache.get(v);
|
||||
if (resolved) return resolved;
|
||||
|
||||
const files = v.files();
|
||||
@@ -89,7 +95,15 @@ export function dynamicLoader<I extends Input, I18n extends I18nConfig | undefin
|
||||
}),
|
||||
$inferPage: undefined as never,
|
||||
$inferMeta: undefined as never,
|
||||
revalidate(name) {
|
||||
async revalidate(name) {
|
||||
// rewrite cache, wait until next `get()` to compute `loader()`
|
||||
if (name === undefined) {
|
||||
await resolveSources(true);
|
||||
} else if (!isStaticSource(input) && !isDynamicSource(input)) {
|
||||
await resolveSource(input[name], true);
|
||||
}
|
||||
},
|
||||
invalidate(name) {
|
||||
if (name === undefined) {
|
||||
sourceCache.clear();
|
||||
} else if (!isStaticSource(input) && !isDynamicSource(input)) {
|
||||
|
||||
@@ -169,7 +169,7 @@ export function localMd<
|
||||
const absolutePath = path.resolve(file);
|
||||
cachedStaticSource = null;
|
||||
storage.invalidateCache(absolutePath);
|
||||
for (const v of registeredLoaders) v.revalidate();
|
||||
for (const v of registeredLoaders) v.invalidate();
|
||||
},
|
||||
async devServer(url = getDevServerUrlFromEnv()) {
|
||||
if (!url) {
|
||||
|
||||
@@ -84,7 +84,7 @@
|
||||
"xml-js": "^1.6.11"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@scalar/api-client-react": "2.0.1",
|
||||
"@scalar/api-client-react": "^2.0.20",
|
||||
"@types/react": "*",
|
||||
"fumadocs-core": "^16.9.0",
|
||||
"fumadocs-ui": "^16.9.0",
|
||||
|
||||
Reference in New Issue
Block a user