dalila 1.8.2 → 1.8.4
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/dist/cli/routes-generator.js +1 -2
- package/dist/components/ui/dialog/index.d.ts +0 -8
- package/dist/components/ui/dialog/index.js +2 -41
- package/dist/components/ui/dialog/internal.d.ts +5 -0
- package/dist/{componentes/ui/dialog/index.js → components/ui/dialog/internal.js} +1 -23
- package/dist/components/ui/drawer/index.js +2 -2
- package/dist/components/ui/index.d.ts +1 -1
- package/dist/components/ui/index.js +1 -1
- package/dist/core/index.d.ts +1 -1
- package/dist/core/index.js +1 -1
- package/dist/core/query.js +9 -7
- package/dist/core/resource.d.ts +23 -171
- package/dist/core/resource.js +178 -15
- package/dist/form/index.d.ts +1 -1
- package/dist/form/index.js +1 -1
- package/dist/router/index.d.ts +1 -1
- package/dist/router/index.js +1 -1
- package/dist/runtime/bind.d.ts +10 -0
- package/dist/runtime/bind.js +382 -53
- package/package.json +1 -1
- package/dist/componentes/ui/accordion/index.d.ts +0 -2
- package/dist/componentes/ui/accordion/index.js +0 -114
- package/dist/componentes/ui/calendar/index.d.ts +0 -2
- package/dist/componentes/ui/calendar/index.js +0 -132
- package/dist/componentes/ui/combobox/index.d.ts +0 -2
- package/dist/componentes/ui/combobox/index.js +0 -161
- package/dist/componentes/ui/dialog/index.d.ts +0 -10
- package/dist/componentes/ui/drawer/index.d.ts +0 -2
- package/dist/componentes/ui/drawer/index.js +0 -41
- package/dist/componentes/ui/dropdown/index.d.ts +0 -2
- package/dist/componentes/ui/dropdown/index.js +0 -48
- package/dist/componentes/ui/dropzone/index.d.ts +0 -2
- package/dist/componentes/ui/dropzone/index.js +0 -92
- package/dist/componentes/ui/env.d.ts +0 -1
- package/dist/componentes/ui/env.js +0 -2
- package/dist/componentes/ui/index.d.ts +0 -13
- package/dist/componentes/ui/index.js +0 -12
- package/dist/componentes/ui/popover/index.d.ts +0 -2
- package/dist/componentes/ui/popover/index.js +0 -156
- package/dist/componentes/ui/runtime.d.ts +0 -20
- package/dist/componentes/ui/runtime.js +0 -421
- package/dist/componentes/ui/tabs/index.d.ts +0 -3
- package/dist/componentes/ui/tabs/index.js +0 -101
- package/dist/componentes/ui/toast/index.d.ts +0 -3
- package/dist/componentes/ui/toast/index.js +0 -115
- package/dist/componentes/ui/ui-types.d.ts +0 -175
- package/dist/componentes/ui/ui-types.js +0 -1
- package/dist/componentes/ui/validate.d.ts +0 -7
- package/dist/componentes/ui/validate.js +0 -71
- package/dist/core/store.d.ts +0 -130
- package/dist/core/store.js +0 -234
- package/dist/core/virtual.d.ts +0 -26
- package/dist/core/virtual.js +0 -277
- package/dist/core/watch-testing.d.ts +0 -13
- package/dist/core/watch-testing.js +0 -16
- package/dist/router/route.d.ts +0 -23
- package/dist/router/route.js +0 -48
- package/dist/simple.d.ts +0 -11
- package/dist/simple.js +0 -11
- package/dist/ui/accordion.d.ts +0 -2
- package/dist/ui/accordion.js +0 -114
- package/dist/ui/calendar.d.ts +0 -2
- package/dist/ui/calendar.js +0 -132
- package/dist/ui/combobox.d.ts +0 -2
- package/dist/ui/combobox.js +0 -161
- package/dist/ui/dialog.d.ts +0 -10
- package/dist/ui/dialog.js +0 -54
- package/dist/ui/drawer.d.ts +0 -2
- package/dist/ui/drawer.js +0 -41
- package/dist/ui/dropdown.d.ts +0 -2
- package/dist/ui/dropdown.js +0 -48
- package/dist/ui/dropzone.d.ts +0 -2
- package/dist/ui/dropzone.js +0 -92
- package/dist/ui/env.d.ts +0 -1
- package/dist/ui/env.js +0 -2
- package/dist/ui/index.d.ts +0 -13
- package/dist/ui/index.js +0 -12
- package/dist/ui/popover.d.ts +0 -2
- package/dist/ui/popover.js +0 -156
- package/dist/ui/runtime.d.ts +0 -20
- package/dist/ui/runtime.js +0 -421
- package/dist/ui/tabs.d.ts +0 -3
- package/dist/ui/tabs.js +0 -101
- package/dist/ui/toast.d.ts +0 -3
- package/dist/ui/toast.js +0 -115
- package/dist/ui/ui-types.d.ts +0 -175
- package/dist/ui/ui-types.js +0 -1
- package/dist/ui/validate.d.ts +0 -7
- package/dist/ui/validate.js +0 -71
|
@@ -969,8 +969,7 @@ function generateRouteObject(node, depth = 0) {
|
|
|
969
969
|
export async function generateRoutesFile(routesDir, outputPath) {
|
|
970
970
|
console.log('🔍 Scanning app directory:', routesDir);
|
|
971
971
|
if (!await pathExists(routesDir)) {
|
|
972
|
-
|
|
973
|
-
process.exit(1);
|
|
972
|
+
throw new Error(`Routes directory not found: ${routesDir}`);
|
|
974
973
|
}
|
|
975
974
|
const tree = await buildRouteTree(routesDir, '', '');
|
|
976
975
|
const projectRoot = await findProjectRoot(routesDir) ?? process.cwd();
|
|
@@ -1,10 +1,2 @@
|
|
|
1
|
-
import { type Signal } from "../../../core/signal.js";
|
|
2
1
|
import type { Dialog, DialogOptions } from "../ui-types.js";
|
|
3
|
-
/**
|
|
4
|
-
* Shared dialog behavior — used by both createDialog and createDrawer.
|
|
5
|
-
*/
|
|
6
|
-
export declare function _attachDialogBehavior(el: HTMLDialogElement, open: Signal<boolean>, closeFn: () => void, opts: {
|
|
7
|
-
closeOnBackdrop: boolean;
|
|
8
|
-
closeOnEscape: boolean;
|
|
9
|
-
}): void;
|
|
10
2
|
export declare function createDialog(options?: DialogOptions): Dialog;
|
|
@@ -1,45 +1,6 @@
|
|
|
1
1
|
import { signal } from "../../../core/signal.js";
|
|
2
|
-
import { getCurrentScope } from "../../../core/scope.js";
|
|
3
2
|
import { validateDialogOptions } from "../validate.js";
|
|
4
|
-
|
|
5
|
-
* Shared dialog behavior — used by both createDialog and createDrawer.
|
|
6
|
-
*/
|
|
7
|
-
export function _attachDialogBehavior(el, open, closeFn, opts) {
|
|
8
|
-
const scope = getCurrentScope();
|
|
9
|
-
// Sync signal → native dialog
|
|
10
|
-
const unsub = open.on((isOpen) => {
|
|
11
|
-
if (isOpen && !el.open)
|
|
12
|
-
el.showModal();
|
|
13
|
-
else if (!isOpen && el.open)
|
|
14
|
-
el.close();
|
|
15
|
-
});
|
|
16
|
-
// Native close event → sync signal
|
|
17
|
-
const onClose = () => open.set(false);
|
|
18
|
-
el.addEventListener("close", onClose);
|
|
19
|
-
// Backdrop click
|
|
20
|
-
const onBackdropClick = (e) => {
|
|
21
|
-
if (opts.closeOnBackdrop && e.target === el)
|
|
22
|
-
closeFn();
|
|
23
|
-
};
|
|
24
|
-
el.addEventListener("click", onBackdropClick);
|
|
25
|
-
// Escape key
|
|
26
|
-
if (!opts.closeOnEscape) {
|
|
27
|
-
const onCancel = (e) => e.preventDefault();
|
|
28
|
-
el.addEventListener("cancel", onCancel);
|
|
29
|
-
if (scope) {
|
|
30
|
-
scope.onCleanup(() => el.removeEventListener("cancel", onCancel));
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
// ARIA
|
|
34
|
-
el.setAttribute("aria-modal", "true");
|
|
35
|
-
if (scope) {
|
|
36
|
-
scope.onCleanup(() => {
|
|
37
|
-
unsub();
|
|
38
|
-
el.removeEventListener("close", onClose);
|
|
39
|
-
el.removeEventListener("click", onBackdropClick);
|
|
40
|
-
});
|
|
41
|
-
}
|
|
42
|
-
}
|
|
3
|
+
import { attachDialogBehavior } from "./internal.js";
|
|
43
4
|
export function createDialog(options = {}) {
|
|
44
5
|
validateDialogOptions(options);
|
|
45
6
|
const { closeOnBackdrop = true, closeOnEscape = true } = options;
|
|
@@ -48,7 +9,7 @@ export function createDialog(options = {}) {
|
|
|
48
9
|
const close = () => open.set(false);
|
|
49
10
|
const toggle = () => open.update((v) => !v);
|
|
50
11
|
const _attachTo = (el) => {
|
|
51
|
-
|
|
12
|
+
attachDialogBehavior(el, open, close, { closeOnBackdrop, closeOnEscape });
|
|
52
13
|
};
|
|
53
14
|
return { open, show, close, toggle, _attachTo };
|
|
54
15
|
}
|
|
@@ -1,28 +1,19 @@
|
|
|
1
|
-
import { signal } from "../../../core/signal.js";
|
|
2
1
|
import { getCurrentScope } from "../../../core/scope.js";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Shared dialog behavior — used by both createDialog and createDrawer.
|
|
6
|
-
*/
|
|
7
|
-
export function _attachDialogBehavior(el, open, closeFn, opts) {
|
|
2
|
+
export function attachDialogBehavior(el, open, closeFn, opts) {
|
|
8
3
|
const scope = getCurrentScope();
|
|
9
|
-
// Sync signal → native dialog
|
|
10
4
|
const unsub = open.on((isOpen) => {
|
|
11
5
|
if (isOpen && !el.open)
|
|
12
6
|
el.showModal();
|
|
13
7
|
else if (!isOpen && el.open)
|
|
14
8
|
el.close();
|
|
15
9
|
});
|
|
16
|
-
// Native close event → sync signal
|
|
17
10
|
const onClose = () => open.set(false);
|
|
18
11
|
el.addEventListener("close", onClose);
|
|
19
|
-
// Backdrop click
|
|
20
12
|
const onBackdropClick = (e) => {
|
|
21
13
|
if (opts.closeOnBackdrop && e.target === el)
|
|
22
14
|
closeFn();
|
|
23
15
|
};
|
|
24
16
|
el.addEventListener("click", onBackdropClick);
|
|
25
|
-
// Escape key
|
|
26
17
|
if (!opts.closeOnEscape) {
|
|
27
18
|
const onCancel = (e) => e.preventDefault();
|
|
28
19
|
el.addEventListener("cancel", onCancel);
|
|
@@ -30,7 +21,6 @@ export function _attachDialogBehavior(el, open, closeFn, opts) {
|
|
|
30
21
|
scope.onCleanup(() => el.removeEventListener("cancel", onCancel));
|
|
31
22
|
}
|
|
32
23
|
}
|
|
33
|
-
// ARIA
|
|
34
24
|
el.setAttribute("aria-modal", "true");
|
|
35
25
|
if (scope) {
|
|
36
26
|
scope.onCleanup(() => {
|
|
@@ -40,15 +30,3 @@ export function _attachDialogBehavior(el, open, closeFn, opts) {
|
|
|
40
30
|
});
|
|
41
31
|
}
|
|
42
32
|
}
|
|
43
|
-
export function createDialog(options = {}) {
|
|
44
|
-
validateDialogOptions(options);
|
|
45
|
-
const { closeOnBackdrop = true, closeOnEscape = true } = options;
|
|
46
|
-
const open = signal(false);
|
|
47
|
-
const show = () => open.set(true);
|
|
48
|
-
const close = () => open.set(false);
|
|
49
|
-
const toggle = () => open.update((v) => !v);
|
|
50
|
-
const _attachTo = (el) => {
|
|
51
|
-
_attachDialogBehavior(el, open, close, { closeOnBackdrop, closeOnEscape });
|
|
52
|
-
};
|
|
53
|
-
return { open, show, close, toggle, _attachTo };
|
|
54
|
-
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { signal } from "../../../core/signal.js";
|
|
2
2
|
import { getCurrentScope } from "../../../core/scope.js";
|
|
3
|
-
import {
|
|
3
|
+
import { attachDialogBehavior } from "../dialog/internal.js";
|
|
4
4
|
import { validateDrawerOptions } from "../validate.js";
|
|
5
5
|
const SIDE_CLASSES = {
|
|
6
6
|
right: "",
|
|
@@ -18,7 +18,7 @@ export function createDrawer(options = {}) {
|
|
|
18
18
|
const _attachTo = (el) => {
|
|
19
19
|
const scope = getCurrentScope();
|
|
20
20
|
// Shared dialog behavior (open sync, backdrop, escape, ARIA)
|
|
21
|
-
|
|
21
|
+
attachDialogBehavior(el, open, close, { closeOnBackdrop, closeOnEscape });
|
|
22
22
|
// Apply initial side class
|
|
23
23
|
const initial = SIDE_CLASSES[side()];
|
|
24
24
|
if (initial)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export * from "./ui-types.js";
|
|
2
|
-
export { createDialog
|
|
2
|
+
export { createDialog } from "./dialog/index.js";
|
|
3
3
|
export { createDrawer } from "./drawer/index.js";
|
|
4
4
|
export { createToast, toastIcon } from "./toast/index.js";
|
|
5
5
|
export { createTabs, tabBindings } from "./tabs/index.js";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export * from "./ui-types.js";
|
|
2
|
-
export { createDialog
|
|
2
|
+
export { createDialog } from "./dialog/index.js";
|
|
3
3
|
export { createDrawer } from "./drawer/index.js";
|
|
4
4
|
export { createToast, toastIcon } from "./toast/index.js";
|
|
5
5
|
export { createTabs, tabBindings } from "./tabs/index.js";
|
package/dist/core/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export * from "./scope.js";
|
|
2
2
|
export * from "./signal.js";
|
|
3
|
-
export
|
|
3
|
+
export { watch, onMount, onCleanup, useEvent, useInterval, useTimeout, useFetch } from "./watch.js";
|
|
4
4
|
export * from "./when.js";
|
|
5
5
|
export * from "./match.js";
|
|
6
6
|
export * from "./for.js";
|
package/dist/core/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export * from "./scope.js";
|
|
2
2
|
export * from "./signal.js";
|
|
3
|
-
export
|
|
3
|
+
export { watch, onMount, onCleanup, useEvent, useInterval, useTimeout, useFetch } from "./watch.js";
|
|
4
4
|
export * from "./when.js";
|
|
5
5
|
export * from "./match.js";
|
|
6
6
|
export * from "./for.js";
|
package/dist/core/query.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { computed, effect } from "./signal.js";
|
|
2
2
|
import { getCurrentScope, createScope, withScope } from "./scope.js";
|
|
3
3
|
import { key as keyBuilder, encodeKey } from "./key.js";
|
|
4
|
-
import {
|
|
4
|
+
import { createResource, invalidateResourceCache, invalidateResourceTag, invalidateResourceTags, } from "./resource.js";
|
|
5
5
|
import { createMutation } from "./mutation.js";
|
|
6
6
|
import { isInDevMode } from "./dev.js";
|
|
7
7
|
/**
|
|
@@ -111,17 +111,19 @@ export function createQueryClient() {
|
|
|
111
111
|
cfg.onSuccess?.(data);
|
|
112
112
|
scheduleStaleRevalidate(r, ck);
|
|
113
113
|
},
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
114
|
+
cache: {
|
|
115
|
+
key: ck,
|
|
116
|
+
tags: cfg.tags,
|
|
117
|
+
persist: behavior.persist,
|
|
118
|
+
},
|
|
117
119
|
};
|
|
118
120
|
if (cfg.initialValue !== undefined)
|
|
119
121
|
opts.initialValue = cfg.initialValue;
|
|
120
122
|
// Keyed cache entry (scope-safe unless persist is enabled).
|
|
121
|
-
const make = () =>
|
|
123
|
+
const make = () => createResource(async (sig) => {
|
|
122
124
|
await Promise.resolve(); // break reactive tracking
|
|
123
125
|
return cfg.fetch(sig, k);
|
|
124
|
-
},
|
|
126
|
+
}, opts);
|
|
125
127
|
r = ks ? withScope(ks, make) : make();
|
|
126
128
|
return r;
|
|
127
129
|
});
|
|
@@ -158,7 +160,7 @@ export function createQueryClient() {
|
|
|
158
160
|
return makeQuery(cfg, { persist: false });
|
|
159
161
|
}
|
|
160
162
|
function queryGlobal(cfg) {
|
|
161
|
-
return makeQuery(cfg, { persist: true
|
|
163
|
+
return makeQuery(cfg, { persist: true });
|
|
162
164
|
}
|
|
163
165
|
function mutation(cfg) {
|
|
164
166
|
return createMutation(cfg);
|
package/dist/core/resource.d.ts
CHANGED
|
@@ -14,6 +14,18 @@ export interface ResourceOptions<T> {
|
|
|
14
14
|
onError?: (error: Error) => void;
|
|
15
15
|
onSuccess?: (data: T) => void;
|
|
16
16
|
}
|
|
17
|
+
export interface ResourceCachePolicy {
|
|
18
|
+
key: string | (() => string);
|
|
19
|
+
ttlMs?: number;
|
|
20
|
+
tags?: readonly string[];
|
|
21
|
+
persist?: boolean;
|
|
22
|
+
}
|
|
23
|
+
export interface CreateResourceOptions<T> extends ResourceOptions<T> {
|
|
24
|
+
deps?: () => unknown;
|
|
25
|
+
cache?: string | ResourceCachePolicy;
|
|
26
|
+
refreshInterval?: number;
|
|
27
|
+
fetchOptions?: RequestInit;
|
|
28
|
+
}
|
|
17
29
|
export interface ResourceRefreshOptions {
|
|
18
30
|
/** If true, abort any in-flight request and revalidate now. */
|
|
19
31
|
force?: boolean;
|
|
@@ -32,105 +44,12 @@ export interface ResourceState<T> {
|
|
|
32
44
|
*/
|
|
33
45
|
refresh: (options?: ResourceRefreshOptions) => Promise<void>;
|
|
34
46
|
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
*
|
|
38
|
-
* Design goals:
|
|
39
|
-
* - Scope-first: if created inside a scope, abort + cleanup on scope disposal.
|
|
40
|
-
* - Abort-safe callbacks: do not call onSuccess/onError for aborted runs.
|
|
41
|
-
* - Correct refresh: `await refresh()` must wait for the *new* fetch, not a stale inFlight.
|
|
42
|
-
*
|
|
43
|
-
* Semantics:
|
|
44
|
-
* - A driver `effectAsync` runs `fetchFn(signal)` whenever `refreshTick` changes.
|
|
45
|
-
* - Each run gets a fresh AbortController.
|
|
46
|
-
* - Reruns abort the previous controller.
|
|
47
|
-
*
|
|
48
|
-
* Why a waiter system?
|
|
49
|
-
* - Without it, refresh() can accidentally await an older promise and resolve early.
|
|
50
|
-
* - We map each refresh request to a runId and resolve its waiter when that run finishes.
|
|
51
|
-
*
|
|
52
|
-
* Safety:
|
|
53
|
-
* - If the driver reruns during a fetch, an aborted run must NOT resolve the latest waiter.
|
|
54
|
-
* Guard: only resolve if `lastRunController === controller` for that run.
|
|
55
|
-
*
|
|
56
|
-
* Lifetime:
|
|
57
|
-
* - On parent scope cleanup:
|
|
58
|
-
* - abort current request
|
|
59
|
-
* - dispose the driver
|
|
60
|
-
* - resolve all pending waiters (avoid hanging Promises)
|
|
61
|
-
*/
|
|
62
|
-
export declare function createResource<T>(fetchFn: (signal: AbortSignal) => Promise<T>, options?: ResourceOptions<T>): ResourceState<T>;
|
|
63
|
-
/**
|
|
64
|
-
* Fetch helper built on top of createResource().
|
|
65
|
-
*
|
|
66
|
-
* Semantics:
|
|
67
|
-
* - `url` may be static or dynamic (function).
|
|
68
|
-
* - Uses fetch() with AbortSignal.
|
|
69
|
-
* - Non-2xx responses throw (surfaced via resource.error()).
|
|
70
|
-
*/
|
|
71
|
-
export declare function createFetchResource<T>(url: string | (() => string), options?: ResourceOptions<T> & {
|
|
72
|
-
fetchOptions?: RequestInit;
|
|
73
|
-
}): ResourceState<T>;
|
|
47
|
+
export declare function createResource<T>(fetchFn: (signal: AbortSignal) => Promise<T>, options?: CreateResourceOptions<T>): ResourceState<T>;
|
|
48
|
+
export declare function resourceFromUrl<T>(url: string | (() => string), options?: CreateResourceOptions<T>): ResourceState<T>;
|
|
74
49
|
export type DepSource<D> = (() => D) | ReadonlyArray<Signal<any>> | {
|
|
75
50
|
get: () => D;
|
|
76
51
|
key?: () => any;
|
|
77
52
|
};
|
|
78
|
-
/**
|
|
79
|
-
* Resource that revalidates when dependencies change.
|
|
80
|
-
*
|
|
81
|
-
* Design goals:
|
|
82
|
-
* - Same guarantees as createResource():
|
|
83
|
-
* - abort-safe callbacks
|
|
84
|
-
* - refresh waiter correctness
|
|
85
|
-
* - Flexible deps:
|
|
86
|
-
* - function getter (value mode)
|
|
87
|
-
* - array of signals (array mode)
|
|
88
|
-
* - accessor with optional key() (key mode for stable change detection)
|
|
89
|
-
*
|
|
90
|
-
* Semantics:
|
|
91
|
-
* - The driver reads deps, decides if changed, then fetches.
|
|
92
|
-
* - If deps didn't change, it does nothing (no remount/refetch).
|
|
93
|
-
*
|
|
94
|
-
* Important edge-case:
|
|
95
|
-
* - If the effect reruns while a fetch is still in flight and deps are unchanged,
|
|
96
|
-
* we must not resolve refresh waiters prematurely.
|
|
97
|
-
* Guard: early-return resolves only if `!loading()`.
|
|
98
|
-
*/
|
|
99
|
-
export declare function createDependentResource<T, D>(fetchFn: (signal: AbortSignal, deps: D) => Promise<T>, deps: DepSource<D>, options?: ResourceOptions<T>): ResourceState<T>;
|
|
100
|
-
/**
|
|
101
|
-
* CacheEntry:
|
|
102
|
-
* A cached resource plus book-keeping for memory safety and invalidation.
|
|
103
|
-
*
|
|
104
|
-
* Fields:
|
|
105
|
-
* - createdAt/ttlMs: TTL-based expiry.
|
|
106
|
-
* - tags: tag index for invalidation.
|
|
107
|
-
* - stale: marker used by invalidation flows.
|
|
108
|
-
* - refCount: number of active scopes referencing this entry.
|
|
109
|
-
* - persist: if true, entry may live outside scopes (global cache).
|
|
110
|
-
* - cacheScope: dedicated scope that owns the underlying resource lifetime.
|
|
111
|
-
*
|
|
112
|
-
* Why cacheScope?
|
|
113
|
-
* - If a cached resource were created in the caller scope, it could be disposed
|
|
114
|
-
* prematurely when that scope ends, even though other scopes still reference it.
|
|
115
|
-
* - We isolate each cache entry in its own scope so the cache controls disposal.
|
|
116
|
-
*/
|
|
117
|
-
type CacheEntry = {
|
|
118
|
-
resource: ResourceState<any>;
|
|
119
|
-
createdAt: number;
|
|
120
|
-
ttlMs?: number;
|
|
121
|
-
tags: Set<string>;
|
|
122
|
-
stale: boolean;
|
|
123
|
-
/** Active scoped users. */
|
|
124
|
-
refCount: number;
|
|
125
|
-
/** Explicit "keep global" flag. */
|
|
126
|
-
persist: boolean;
|
|
127
|
-
/**
|
|
128
|
-
* Dedicated scope for this cache entry.
|
|
129
|
-
* The resource is created inside this scope, isolating it from caller scopes.
|
|
130
|
-
* When the entry is removed from cache, this scope is disposed.
|
|
131
|
-
*/
|
|
132
|
-
cacheScope: Scope;
|
|
133
|
-
};
|
|
134
53
|
export interface CachedResourceOptions<T> extends ResourceOptions<T> {
|
|
135
54
|
ttlMs?: number;
|
|
136
55
|
tags?: readonly string[];
|
|
@@ -167,25 +86,6 @@ interface CacheConfig {
|
|
|
167
86
|
* Call this early in your app initialization.
|
|
168
87
|
*/
|
|
169
88
|
export declare function configureResourceCache(config: Partial<CacheConfig>): void;
|
|
170
|
-
/**
|
|
171
|
-
* Create or reuse a cached resource by cache key.
|
|
172
|
-
*
|
|
173
|
-
* Safe-by-default:
|
|
174
|
-
* - If called outside a scope and persist !== true, it returns a non-cached resource.
|
|
175
|
-
* - This prevents accidental global cache growth from unscoped usage.
|
|
176
|
-
*
|
|
177
|
-
* TTL:
|
|
178
|
-
* - On access, if an existing entry is expired, it is removed and recreated.
|
|
179
|
-
*
|
|
180
|
-
* Lifetime:
|
|
181
|
-
* - Each entry has a dedicated cacheScope, disposed when the entry is removed.
|
|
182
|
-
* - Scopes referencing an entry increment refCount; on scope cleanup they release it.
|
|
183
|
-
*/
|
|
184
|
-
export declare function createCachedResource<T>(key: string, fetchFn: (signal: AbortSignal) => Promise<T>, options?: CachedResourceOptions<T>): ResourceState<T>;
|
|
185
|
-
/**
|
|
186
|
-
* Convenience wrapper: builds the cache key from an id.
|
|
187
|
-
*/
|
|
188
|
-
export declare function createCachedResourceById<T, I>(id: I, keyFn: (id: I) => string, fetchFn: (signal: AbortSignal, id: I) => Promise<T>, options?: CachedResourceOptions<T>): ResourceState<T>;
|
|
189
89
|
/**
|
|
190
90
|
* Clears the cache:
|
|
191
91
|
* - with no key: clears everything
|
|
@@ -223,77 +123,29 @@ export declare function invalidateResourceTags(tags: readonly string[], opts?: {
|
|
|
223
123
|
* Introspection helper: returns cache keys registered for a tag.
|
|
224
124
|
*/
|
|
225
125
|
export declare function getResourceCacheKeysByTag(tag: string): string[];
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
* - Requires a scope so the interval can be cleaned up automatically.
|
|
231
|
-
* - Outside a scope, it warns and returns a normal resource (no interval).
|
|
232
|
-
*/
|
|
233
|
-
export declare function createAutoRefreshResource<T>(fetchFn: (signal: AbortSignal) => Promise<T>, refreshInterval: number, options?: ResourceOptions<T>): ResourceState<T>;
|
|
234
|
-
/**
|
|
235
|
-
* Isolated cache instance for SSR and testing.
|
|
236
|
-
*
|
|
237
|
-
* Use this when you need complete cache isolation:
|
|
238
|
-
* - SSR: each request gets its own cache
|
|
239
|
-
* - Testing: each test gets fresh state
|
|
240
|
-
*
|
|
241
|
-
* Example:
|
|
242
|
-
* ```ts
|
|
243
|
-
* const { createCachedResource, clearCache, invalidateKey, getCache } = createIsolatedCache();
|
|
244
|
-
*
|
|
245
|
-
* // Use the isolated createCachedResource instead of the global one
|
|
246
|
-
* const resource = createCachedResource('key', fetchFn);
|
|
247
|
-
*
|
|
248
|
-
* // Clean up when done
|
|
249
|
-
* clearCache();
|
|
250
|
-
* ```
|
|
251
|
-
*/
|
|
252
|
-
export interface IsolatedCache {
|
|
253
|
-
/**
|
|
254
|
-
* Create a cached resource using this isolated cache.
|
|
255
|
-
*/
|
|
256
|
-
createCachedResource: <T>(key: string, fetchFn: (signal: AbortSignal) => Promise<T>, options?: CachedResourceOptions<T>) => ResourceState<T>;
|
|
257
|
-
/**
|
|
258
|
-
* Clear all entries in this isolated cache.
|
|
259
|
-
*/
|
|
260
|
-
clearCache: (key?: string) => void;
|
|
261
|
-
/**
|
|
262
|
-
* Invalidate a specific key in this isolated cache.
|
|
263
|
-
*/
|
|
264
|
-
invalidateKey: (key: string, opts?: {
|
|
126
|
+
export interface ResourceCache {
|
|
127
|
+
create: <T>(key: string, fetchFn: (signal: AbortSignal) => Promise<T>, options?: CachedResourceOptions<T>) => ResourceState<T>;
|
|
128
|
+
clear: (key?: string) => void;
|
|
129
|
+
invalidate: (key: string, opts?: {
|
|
265
130
|
revalidate?: boolean;
|
|
266
131
|
force?: boolean;
|
|
267
132
|
}) => void;
|
|
268
|
-
/**
|
|
269
|
-
* Invalidate all entries with a specific tag.
|
|
270
|
-
*/
|
|
271
133
|
invalidateTag: (tag: string, opts?: {
|
|
272
134
|
revalidate?: boolean;
|
|
273
135
|
force?: boolean;
|
|
274
136
|
}) => void;
|
|
275
|
-
/**
|
|
276
|
-
* Invalidate all entries with any of the specified tags.
|
|
277
|
-
*/
|
|
278
137
|
invalidateTags: (tags: readonly string[], opts?: {
|
|
279
138
|
revalidate?: boolean;
|
|
280
139
|
force?: boolean;
|
|
281
140
|
}) => void;
|
|
282
|
-
|
|
283
|
-
* Get the underlying cache Map (for debugging/inspection).
|
|
284
|
-
*/
|
|
285
|
-
getCache: () => Map<string, CacheEntry>;
|
|
286
|
-
/**
|
|
287
|
-
* Get cache keys by tag.
|
|
288
|
-
*/
|
|
289
|
-
getKeysByTag: (tag: string) => string[];
|
|
290
|
-
/**
|
|
291
|
-
* Configure cache limits for this instance.
|
|
292
|
-
*/
|
|
141
|
+
keys: () => string[];
|
|
293
142
|
configure: (config: Partial<{
|
|
294
143
|
maxEntries: number;
|
|
295
144
|
warnOnEviction: boolean;
|
|
296
145
|
}>) => void;
|
|
297
146
|
}
|
|
298
|
-
export declare function
|
|
147
|
+
export declare function createResourceCache(config?: Partial<{
|
|
148
|
+
maxEntries: number;
|
|
149
|
+
warnOnEviction: boolean;
|
|
150
|
+
}>): ResourceCache;
|
|
299
151
|
export {};
|