@venizia/ardor-react 0.4.8-0 → 0.4.8-2
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/README.md +5 -4
- package/dist/contexts/application.d.ts +4 -0
- package/dist/contexts/application.js +1 -0
- package/dist/hooks/element-target.d.ts +9 -0
- package/dist/hooks/element-target.js +7 -0
- package/dist/hooks/index.d.ts +6 -1
- package/dist/hooks/index.js +5 -1
- package/dist/hooks/redux/use-app-dispatch.d.ts +5 -1
- package/dist/hooks/redux/use-app-dispatch.js +5 -1
- package/dist/hooks/redux/use-app-selector.js +27 -2
- package/dist/hooks/resize-observation.d.ts +19 -0
- package/dist/hooks/resize-observation.js +67 -0
- package/dist/hooks/use-application-context.d.ts +2 -0
- package/dist/hooks/use-application-context.js +2 -0
- package/dist/hooks/use-artifact.d.ts +26 -0
- package/dist/hooks/use-artifact.js +24 -2
- package/dist/hooks/use-autosave.d.ts +7 -0
- package/dist/hooks/use-autosave.js +4 -0
- package/dist/hooks/use-before-unload.d.ts +2 -0
- package/dist/hooks/use-before-unload.js +1 -0
- package/dist/hooks/use-confirm.d.ts +6 -0
- package/dist/hooks/use-confirm.js +1 -0
- package/dist/hooks/use-copy-to-clipboard.d.ts +21 -1
- package/dist/hooks/use-copy-to-clipboard.js +39 -15
- package/dist/hooks/use-debounce.d.ts +4 -0
- package/dist/hooks/use-debounce.js +1 -0
- package/dist/hooks/use-document-visibility.d.ts +3 -0
- package/dist/hooks/use-document-visibility.js +10 -0
- package/dist/hooks/use-element-size.d.ts +13 -1
- package/dist/hooks/use-element-size.js +11 -20
- package/dist/hooks/use-injectable.d.ts +32 -1
- package/dist/hooks/use-injectable.js +17 -3
- package/dist/hooks/use-intersection.d.ts +28 -0
- package/dist/hooks/use-intersection.js +50 -0
- package/dist/hooks/use-media-query.d.ts +5 -0
- package/dist/hooks/use-media-query.js +14 -0
- package/dist/hooks/use-online-status.d.ts +3 -0
- package/dist/hooks/use-online-status.js +14 -0
- package/dist/hooks/use-resize-effect.d.ts +31 -0
- package/dist/hooks/use-resize-effect.js +42 -0
- package/dist/hooks/use-stored-state.d.ts +28 -1
- package/dist/hooks/use-stored-state.js +38 -11
- package/dist/hooks/use-window-dimensions.d.ts +1 -0
- package/dist/hooks/use-window-dimensions.js +1 -0
- package/package.json +16 -16
- package/dist/contexts/application.d.ts.map +0 -1
- package/dist/contexts/application.js.map +0 -1
- package/dist/contexts/index.d.ts.map +0 -1
- package/dist/contexts/index.js.map +0 -1
- package/dist/hooks/index.d.ts.map +0 -1
- package/dist/hooks/index.js.map +0 -1
- package/dist/hooks/redux/index.d.ts.map +0 -1
- package/dist/hooks/redux/index.js.map +0 -1
- package/dist/hooks/redux/use-app-dispatch.d.ts.map +0 -1
- package/dist/hooks/redux/use-app-dispatch.js.map +0 -1
- package/dist/hooks/redux/use-app-selector.d.ts.map +0 -1
- package/dist/hooks/redux/use-app-selector.js.map +0 -1
- package/dist/hooks/use-application-context.d.ts.map +0 -1
- package/dist/hooks/use-application-context.js.map +0 -1
- package/dist/hooks/use-artifact.d.ts.map +0 -1
- package/dist/hooks/use-artifact.js.map +0 -1
- package/dist/hooks/use-autosave.d.ts.map +0 -1
- package/dist/hooks/use-autosave.js.map +0 -1
- package/dist/hooks/use-before-unload.d.ts.map +0 -1
- package/dist/hooks/use-before-unload.js.map +0 -1
- package/dist/hooks/use-confirm.d.ts.map +0 -1
- package/dist/hooks/use-confirm.js.map +0 -1
- package/dist/hooks/use-copy-to-clipboard.d.ts.map +0 -1
- package/dist/hooks/use-copy-to-clipboard.js.map +0 -1
- package/dist/hooks/use-debounce.d.ts.map +0 -1
- package/dist/hooks/use-debounce.js.map +0 -1
- package/dist/hooks/use-element-size.d.ts.map +0 -1
- package/dist/hooks/use-element-size.js.map +0 -1
- package/dist/hooks/use-injectable.d.ts.map +0 -1
- package/dist/hooks/use-injectable.js.map +0 -1
- package/dist/hooks/use-sizer.d.ts +0 -10
- package/dist/hooks/use-sizer.d.ts.map +0 -1
- package/dist/hooks/use-sizer.js +0 -23
- package/dist/hooks/use-sizer.js.map +0 -1
- package/dist/hooks/use-stored-state.d.ts.map +0 -1
- package/dist/hooks/use-stored-state.js.map +0 -1
- package/dist/hooks/use-window-dimensions.d.ts.map +0 -1
- package/dist/hooks/use-window-dimensions.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
import { ResizeObservation } from './resize-observation.js';
|
|
2
3
|
const ZERO_SIZE = { width: 0, height: 0, measured: false };
|
|
3
4
|
const readSize = (opts) => {
|
|
4
5
|
const { entry, box, round } = opts;
|
|
@@ -16,36 +17,26 @@ export function useElementSize(opts = {}) {
|
|
|
16
17
|
React.useEffect(() => {
|
|
17
18
|
setSize((current) => (current.measured ? ZERO_SIZE : current));
|
|
18
19
|
const target = ref ? ref.current : element;
|
|
19
|
-
if (!target
|
|
20
|
+
if (!target) {
|
|
20
21
|
return () => { };
|
|
21
22
|
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
return;
|
|
28
|
-
}
|
|
29
|
-
frame = requestAnimationFrame(() => {
|
|
30
|
-
frame = undefined;
|
|
31
|
-
if (!latest) {
|
|
23
|
+
const observation = ResizeObservation.observe({
|
|
24
|
+
box,
|
|
25
|
+
onFrame: (entries) => {
|
|
26
|
+
const entry = entries.at(-1);
|
|
27
|
+
if (!entry) {
|
|
32
28
|
return;
|
|
33
29
|
}
|
|
34
|
-
const next = readSize({ entry
|
|
30
|
+
const next = readSize({ entry, box, round });
|
|
35
31
|
setSize((current) => {
|
|
36
32
|
return current.measured && current.width === next.width && current.height === next.height
|
|
37
33
|
? current
|
|
38
34
|
: next;
|
|
39
35
|
});
|
|
40
|
-
}
|
|
36
|
+
},
|
|
41
37
|
});
|
|
42
|
-
|
|
43
|
-
return
|
|
44
|
-
observer.disconnect();
|
|
45
|
-
if (frame !== undefined) {
|
|
46
|
-
cancelAnimationFrame(frame);
|
|
47
|
-
}
|
|
48
|
-
};
|
|
38
|
+
observation.sync([target]);
|
|
39
|
+
return observation.stop;
|
|
49
40
|
}, [ref, element, box, round]);
|
|
50
41
|
return ref ? size : { ...size, ref: setElement };
|
|
51
42
|
}
|
|
@@ -1,14 +1,31 @@
|
|
|
1
1
|
import { type Container, type TClass } from '@venizia/ignis-inversion';
|
|
2
2
|
import type { CoreBindings, ValueOf } from '@venizia/ardor-kernel';
|
|
3
|
+
/** Declaration-merge string keys into this interface to make them valid `key` values of the injectable hooks. */
|
|
3
4
|
export interface IUseInjectableKeysOverrides {
|
|
4
5
|
}
|
|
6
|
+
/** The binding keys the kernel defines (the string values of `CoreBindings`). */
|
|
5
7
|
export type TUseInjectableKeysDefault = Extract<ValueOf<typeof CoreBindings>, string>;
|
|
8
|
+
/** A key the injectable hooks accept: a kernel binding key or one added to `IUseInjectableKeysOverrides`. */
|
|
6
9
|
export type TUseInjectableKeys = TUseInjectableKeysDefault | keyof IUseInjectableKeysOverrides;
|
|
10
|
+
/**
|
|
11
|
+
* Resolve by `key` or by `target` class, never both.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```ts
|
|
15
|
+
* import { CoreBindings, type TUseInjectableOptions } from '@venizia/ardor';
|
|
16
|
+
*
|
|
17
|
+
* const byKey: TUseInjectableOptions = { key: CoreBindings.DEFAULT_REST_DATA_PROVIDER };
|
|
18
|
+
* class Greeter {}
|
|
19
|
+
* const byTarget: TUseInjectableOptions = { target: Greeter };
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
7
22
|
export type TUseInjectableOptions = {
|
|
23
|
+
/** The container to resolve from. @default The application's container (`ApplicationContext`) */
|
|
8
24
|
container?: Container;
|
|
9
25
|
key: TUseInjectableKeys;
|
|
10
26
|
target?: never;
|
|
11
27
|
} | {
|
|
28
|
+
/** The container to resolve from. @default The application's container (`ApplicationContext`) */
|
|
12
29
|
container?: Container;
|
|
13
30
|
key?: never;
|
|
14
31
|
target: TClass<unknown>;
|
|
@@ -16,9 +33,23 @@ export type TUseInjectableOptions = {
|
|
|
16
33
|
/**
|
|
17
34
|
* The container an injectable hook resolves from: the one passed in, else the application's. Shared,
|
|
18
35
|
* so a hook never checks one container and resolves from another.
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```tsx
|
|
39
|
+
* import { CoreBindings, useApplicationContainer } from '@venizia/ardor';
|
|
40
|
+
*
|
|
41
|
+
* export function BindingCheck() {
|
|
42
|
+
* const container = useApplicationContainer();
|
|
43
|
+
* return <span>{container.isBound({ key: CoreBindings.DEFAULT_REST_DATA_PROVIDER }) ? 'bound' : 'unbound'}</span>;
|
|
44
|
+
* }
|
|
45
|
+
* ```
|
|
19
46
|
*/
|
|
20
|
-
export declare const
|
|
47
|
+
export declare const useApplicationContainer: (opts?: {
|
|
21
48
|
container?: Container;
|
|
22
49
|
}) => Container;
|
|
50
|
+
/**
|
|
51
|
+
* Resolves an instance from the container by `key` or by `target` class. Throws when the key is not
|
|
52
|
+
* bound, when the class has no recorded binding key, or when neither `key` nor `target` is given.
|
|
53
|
+
*/
|
|
23
54
|
export declare const useInjectable: <TInstance>(opts: TUseInjectableOptions) => TInstance;
|
|
24
55
|
//# sourceMappingURL=use-injectable.d.ts.map
|
|
@@ -4,19 +4,33 @@ import { ApplicationContext } from '../contexts/application.js';
|
|
|
4
4
|
/**
|
|
5
5
|
* The container an injectable hook resolves from: the one passed in, else the application's. Shared,
|
|
6
6
|
* so a hook never checks one container and resolves from another.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```tsx
|
|
10
|
+
* import { CoreBindings, useApplicationContainer } from '@venizia/ardor';
|
|
11
|
+
*
|
|
12
|
+
* export function BindingCheck() {
|
|
13
|
+
* const container = useApplicationContainer();
|
|
14
|
+
* return <span>{container.isBound({ key: CoreBindings.DEFAULT_REST_DATA_PROVIDER }) ? 'bound' : 'unbound'}</span>;
|
|
15
|
+
* }
|
|
16
|
+
* ```
|
|
7
17
|
*/
|
|
8
|
-
export const
|
|
18
|
+
export const useApplicationContainer = (opts) => {
|
|
9
19
|
const applicationContext = React.useContext(ApplicationContext);
|
|
10
20
|
const container = opts?.container ?? applicationContext.container;
|
|
11
21
|
if (!container) {
|
|
12
22
|
throw getError({
|
|
13
|
-
message: '[
|
|
23
|
+
message: '[useApplicationContainer] Failed to determine the application container!',
|
|
14
24
|
});
|
|
15
25
|
}
|
|
16
26
|
return container;
|
|
17
27
|
};
|
|
28
|
+
/**
|
|
29
|
+
* Resolves an instance from the container by `key` or by `target` class. Throws when the key is not
|
|
30
|
+
* bound, when the class has no recorded binding key, or when neither `key` nor `target` is given.
|
|
31
|
+
*/
|
|
18
32
|
export const useInjectable = (opts) => {
|
|
19
|
-
const container =
|
|
33
|
+
const container = useApplicationContainer({ container: opts?.container });
|
|
20
34
|
const { key, target } = opts;
|
|
21
35
|
if (key) {
|
|
22
36
|
if (!container.isBound({ key })) {
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { type TElementTarget } from './element-target.js';
|
|
2
|
+
export interface IUseIntersectionOptions {
|
|
3
|
+
/** Read after every render: an element, a ref to one, or `null`. */
|
|
4
|
+
target: TElementTarget;
|
|
5
|
+
/** @default '0px' */
|
|
6
|
+
rootMargin?: string;
|
|
7
|
+
/** The ratio of the element in view at which an entry is delivered; a single number, not an array. @default 0 */
|
|
8
|
+
threshold?: number;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* The latest `IntersectionObserverEntry` of the target, or `undefined` before the first one and
|
|
12
|
+
* where there is no `IntersectionObserver`. The state changes only when `isIntersecting` or the
|
|
13
|
+
* ratio changed. A new element, `rootMargin` or `threshold` starts again from `undefined`.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```tsx
|
|
17
|
+
* import React from 'react';
|
|
18
|
+
* import { useIntersection } from '@venizia/ardor';
|
|
19
|
+
*
|
|
20
|
+
* export function Lazy() {
|
|
21
|
+
* const ref = React.useRef<HTMLDivElement>(null);
|
|
22
|
+
* const entry = useIntersection({ target: ref, threshold: 0.5 });
|
|
23
|
+
* return <div ref={ref}>{entry?.isIntersecting ? 'visible' : 'hidden'}</div>;
|
|
24
|
+
* }
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export declare const useIntersection: (opts: IUseIntersectionOptions) => IntersectionObserverEntry | undefined;
|
|
28
|
+
//# sourceMappingURL=use-intersection.d.ts.map
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { ElementTargets } from './element-target.js';
|
|
3
|
+
/**
|
|
4
|
+
* The latest `IntersectionObserverEntry` of the target, or `undefined` before the first one and
|
|
5
|
+
* where there is no `IntersectionObserver`. The state changes only when `isIntersecting` or the
|
|
6
|
+
* ratio changed. A new element, `rootMargin` or `threshold` starts again from `undefined`.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```tsx
|
|
10
|
+
* import React from 'react';
|
|
11
|
+
* import { useIntersection } from '@venizia/ardor';
|
|
12
|
+
*
|
|
13
|
+
* export function Lazy() {
|
|
14
|
+
* const ref = React.useRef<HTMLDivElement>(null);
|
|
15
|
+
* const entry = useIntersection({ target: ref, threshold: 0.5 });
|
|
16
|
+
* return <div ref={ref}>{entry?.isIntersecting ? 'visible' : 'hidden'}</div>;
|
|
17
|
+
* }
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
export const useIntersection = (opts) => {
|
|
21
|
+
const { target, rootMargin, threshold } = opts;
|
|
22
|
+
const [element, setElement] = React.useState(null);
|
|
23
|
+
const [entry, setEntry] = React.useState();
|
|
24
|
+
// oxlint-disable-next-line react-hooks/exhaustive-deps -- the target is read after every render, and a state set to the same element renders nothing
|
|
25
|
+
React.useEffect(() => {
|
|
26
|
+
setElement(ElementTargets.resolve({ target }));
|
|
27
|
+
});
|
|
28
|
+
React.useEffect(() => {
|
|
29
|
+
setEntry(undefined);
|
|
30
|
+
if (!element || typeof IntersectionObserver === 'undefined') {
|
|
31
|
+
return () => { };
|
|
32
|
+
}
|
|
33
|
+
const observer = new IntersectionObserver((entries) => {
|
|
34
|
+
const latest = entries.at(-1);
|
|
35
|
+
if (!latest) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
setEntry((current) => {
|
|
39
|
+
return current?.isIntersecting === latest.isIntersecting &&
|
|
40
|
+
current.intersectionRatio === latest.intersectionRatio
|
|
41
|
+
? current
|
|
42
|
+
: latest;
|
|
43
|
+
});
|
|
44
|
+
}, { rootMargin, threshold });
|
|
45
|
+
observer.observe(element);
|
|
46
|
+
return () => observer.disconnect();
|
|
47
|
+
}, [element, rootMargin, threshold]);
|
|
48
|
+
return entry;
|
|
49
|
+
};
|
|
50
|
+
//# sourceMappingURL=use-intersection.js.map
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
/** Whether the media query matches now, and again after each change. `false` in a server render. */
|
|
3
|
+
export const useMediaQuery = (opts) => {
|
|
4
|
+
const { query } = opts;
|
|
5
|
+
const subscribe = React.useMemo(() => {
|
|
6
|
+
return (listener) => {
|
|
7
|
+
const list = window.matchMedia(query);
|
|
8
|
+
list.addEventListener('change', listener);
|
|
9
|
+
return () => list.removeEventListener('change', listener);
|
|
10
|
+
};
|
|
11
|
+
}, [query]);
|
|
12
|
+
return React.useSyncExternalStore(subscribe, () => window.matchMedia(query).matches, () => false);
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=use-media-query.js.map
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
const subscribe = (listener) => {
|
|
3
|
+
window.addEventListener('online', listener);
|
|
4
|
+
window.addEventListener('offline', listener);
|
|
5
|
+
return () => {
|
|
6
|
+
window.removeEventListener('online', listener);
|
|
7
|
+
window.removeEventListener('offline', listener);
|
|
8
|
+
};
|
|
9
|
+
};
|
|
10
|
+
/** Whether the browser is online, kept by the `online` and `offline` events. `true` in a server render. */
|
|
11
|
+
export const useOnlineStatus = () => {
|
|
12
|
+
return React.useSyncExternalStore(subscribe, () => navigator.onLine, () => true);
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=use-online-status.js.map
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type TElementTarget } from './element-target.js';
|
|
2
|
+
import { type TResizeBox } from './resize-observation.js';
|
|
3
|
+
export interface IUseResizeEffectOptions {
|
|
4
|
+
/** Read after every render: an element, a ref to one, or `null`, which is skipped. */
|
|
5
|
+
targets: TElementTarget[];
|
|
6
|
+
/** Receives the latest entry of each element that resized since the last call. */
|
|
7
|
+
onResize: (entries: ResizeObserverEntry[]) => void;
|
|
8
|
+
/** @default 'content-box' */
|
|
9
|
+
box?: TResizeBox;
|
|
10
|
+
/** Also observe the direct children of each target, and again whenever they change. @default false */
|
|
11
|
+
children?: boolean;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Calls `onResize` at most once per animation frame when any of the targets resizes. A new
|
|
15
|
+
* `onResize` is used without observing again, and the targets are read after every render, so an
|
|
16
|
+
* element held in state, a ref whose element changed and a list that grows or shrinks are followed.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```tsx
|
|
20
|
+
* import React from 'react';
|
|
21
|
+
* import { useResizeEffect } from '@venizia/ardor';
|
|
22
|
+
*
|
|
23
|
+
* export function Panel() {
|
|
24
|
+
* const ref = React.useRef<HTMLDivElement>(null);
|
|
25
|
+
* useResizeEffect({ targets: [ref], onResize: (entries) => console.log(entries.length) });
|
|
26
|
+
* return <div ref={ref} />;
|
|
27
|
+
* }
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
export declare const useResizeEffect: (opts: IUseResizeEffectOptions) => void;
|
|
31
|
+
//# sourceMappingURL=use-resize-effect.d.ts.map
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { ElementTargets } from './element-target.js';
|
|
3
|
+
import { ResizeObservation } from './resize-observation.js';
|
|
4
|
+
/**
|
|
5
|
+
* Calls `onResize` at most once per animation frame when any of the targets resizes. A new
|
|
6
|
+
* `onResize` is used without observing again, and the targets are read after every render, so an
|
|
7
|
+
* element held in state, a ref whose element changed and a list that grows or shrinks are followed.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```tsx
|
|
11
|
+
* import React from 'react';
|
|
12
|
+
* import { useResizeEffect } from '@venizia/ardor';
|
|
13
|
+
*
|
|
14
|
+
* export function Panel() {
|
|
15
|
+
* const ref = React.useRef<HTMLDivElement>(null);
|
|
16
|
+
* useResizeEffect({ targets: [ref], onResize: (entries) => console.log(entries.length) });
|
|
17
|
+
* return <div ref={ref} />;
|
|
18
|
+
* }
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export const useResizeEffect = (opts) => {
|
|
22
|
+
const { targets, onResize, box = 'content-box', children = false } = opts;
|
|
23
|
+
const handleResize = React.useRef(onResize);
|
|
24
|
+
const observation = React.useRef(undefined);
|
|
25
|
+
React.useEffect(() => {
|
|
26
|
+
handleResize.current = onResize;
|
|
27
|
+
return () => { };
|
|
28
|
+
}, [onResize]);
|
|
29
|
+
React.useEffect(() => {
|
|
30
|
+
const created = ResizeObservation.observe({
|
|
31
|
+
box,
|
|
32
|
+
children,
|
|
33
|
+
onFrame: (entries) => handleResize.current(entries),
|
|
34
|
+
});
|
|
35
|
+
observation.current = created;
|
|
36
|
+
return created.stop;
|
|
37
|
+
}, [box, children]);
|
|
38
|
+
React.useEffect(() => {
|
|
39
|
+
observation.current?.sync(targets.flatMap((target) => ElementTargets.resolve({ target }) ?? []));
|
|
40
|
+
});
|
|
41
|
+
};
|
|
42
|
+
//# sourceMappingURL=use-resize-effect.js.map
|
|
@@ -1,21 +1,48 @@
|
|
|
1
1
|
import { type IStorageCodec, type TStorageArea } from '@venizia/ardor-kernel';
|
|
2
2
|
export interface IUseStoredStateOptions<TValue> {
|
|
3
|
+
/** The storage key. */
|
|
3
4
|
key: string;
|
|
5
|
+
/** The value while the key holds nothing. */
|
|
4
6
|
defaultValue: TValue;
|
|
5
7
|
/** @default 'local' */
|
|
6
8
|
storage?: TStorageArea;
|
|
7
9
|
/** @default JSON */
|
|
8
10
|
codec?: IStorageCodec<TValue>;
|
|
11
|
+
/** Write storage once, this many milliseconds after the last `setValue`; `value` changes at once. Above 0, also pass a stable `codec`. @default 0 */
|
|
12
|
+
writeDelayMs?: number;
|
|
9
13
|
}
|
|
10
14
|
export interface IUseStoredStateReturn<TValue> {
|
|
15
|
+
/** The stored value, or `defaultValue` when the key holds nothing. */
|
|
11
16
|
value: TValue;
|
|
17
|
+
/** Stores a value, or the result of an updater called with the current one. */
|
|
12
18
|
setValue: (next: TValue | ((current: TValue) => TValue)) => void;
|
|
19
|
+
/** Removes the key, so `value` is `defaultValue` again. */
|
|
13
20
|
remove: () => void;
|
|
14
21
|
}
|
|
22
|
+
export interface IUseStoredState {
|
|
23
|
+
/** With a codec, the value type is the codec's: a literal `defaultValue` is checked against it, not widened past it. */
|
|
24
|
+
<TValue>(opts: Omit<IUseStoredStateOptions<TValue>, 'defaultValue' | 'codec'> & {
|
|
25
|
+
defaultValue: NoInfer<TValue>;
|
|
26
|
+
codec: IStorageCodec<TValue>;
|
|
27
|
+
}): IUseStoredStateReturn<TValue>;
|
|
28
|
+
<TValue>(opts: IUseStoredStateOptions<TValue>): IUseStoredStateReturn<TValue>;
|
|
29
|
+
}
|
|
15
30
|
/**
|
|
16
31
|
* A value kept in `localStorage` or `sessionStorage`, in step with other hooks on the key, with code
|
|
17
32
|
* that writes through `BrowserStorage`, and with other tabs. Pass a stable `codec` and `defaultValue`.
|
|
18
33
|
* A write or a removal that the storage refuses is kept in this hook until the storage next changes.
|
|
34
|
+
* With `writeDelayMs` the value waits in the same place for the delay: a change of the storage from
|
|
35
|
+
* outside drops it, and an unmount or a new key or storage writes it at once.
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```tsx
|
|
39
|
+
* import { useStoredState } from '@venizia/ardor';
|
|
40
|
+
*
|
|
41
|
+
* export function ThemeToggle() {
|
|
42
|
+
* const { value, setValue } = useStoredState({ key: 'theme', defaultValue: 'light' });
|
|
43
|
+
* return <button onClick={() => setValue(value === 'light' ? 'dark' : 'light')}>{value}</button>;
|
|
44
|
+
* }
|
|
45
|
+
* ```
|
|
19
46
|
*/
|
|
20
|
-
export declare const useStoredState:
|
|
47
|
+
export declare const useStoredState: IUseStoredState;
|
|
21
48
|
//# sourceMappingURL=use-stored-state.d.ts.map
|
|
@@ -1,25 +1,48 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { BrowserStorage } from '@venizia/ardor-kernel';
|
|
3
|
-
|
|
4
|
-
const RAW_TEXT = {
|
|
5
|
-
encode: (text) => text ?? '',
|
|
6
|
-
decode: (text) => text,
|
|
7
|
-
};
|
|
2
|
+
import { BrowserStorage, StorageCodecs, } from '@venizia/ardor-kernel';
|
|
3
|
+
const RAW_TEXT = StorageCodecs.text();
|
|
8
4
|
const isUpdater = (next) => typeof next === 'function';
|
|
9
5
|
/**
|
|
10
6
|
* A value kept in `localStorage` or `sessionStorage`, in step with other hooks on the key, with code
|
|
11
7
|
* that writes through `BrowserStorage`, and with other tabs. Pass a stable `codec` and `defaultValue`.
|
|
12
8
|
* A write or a removal that the storage refuses is kept in this hook until the storage next changes.
|
|
9
|
+
* With `writeDelayMs` the value waits in the same place for the delay: a change of the storage from
|
|
10
|
+
* outside drops it, and an unmount or a new key or storage writes it at once.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```tsx
|
|
14
|
+
* import { useStoredState } from '@venizia/ardor';
|
|
15
|
+
*
|
|
16
|
+
* export function ThemeToggle() {
|
|
17
|
+
* const { value, setValue } = useStoredState({ key: 'theme', defaultValue: 'light' });
|
|
18
|
+
* return <button onClick={() => setValue(value === 'light' ? 'dark' : 'light')}>{value}</button>;
|
|
19
|
+
* }
|
|
20
|
+
* ```
|
|
13
21
|
*/
|
|
14
22
|
export const useStoredState = (opts) => {
|
|
15
|
-
const { key, defaultValue, storage, codec } = opts;
|
|
23
|
+
const { key, defaultValue, storage, codec, writeDelayMs = 0 } = opts;
|
|
16
24
|
const decoded = React.useRef(undefined);
|
|
17
25
|
const keptRef = React.useRef(undefined);
|
|
26
|
+
const timerRef = React.useRef(undefined);
|
|
18
27
|
const [kept, setKept] = React.useState();
|
|
28
|
+
// Every change of the kept value ends a pending write; only a delayed setValue starts one.
|
|
19
29
|
const keep = React.useCallback((next) => {
|
|
30
|
+
clearTimeout(timerRef.current);
|
|
31
|
+
timerRef.current = undefined;
|
|
20
32
|
keptRef.current = next;
|
|
21
33
|
setKept(next);
|
|
22
34
|
}, []);
|
|
35
|
+
const write = React.useCallback((entry) => {
|
|
36
|
+
keep(BrowserStorage.set(entry) ? undefined : entry);
|
|
37
|
+
}, [keep]);
|
|
38
|
+
// A new key or storage, and an unmount, write the pending value to the key it was set for.
|
|
39
|
+
React.useEffect(() => {
|
|
40
|
+
return () => {
|
|
41
|
+
if (timerRef.current !== undefined && keptRef.current) {
|
|
42
|
+
write(keptRef.current);
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
}, [key, storage, write]);
|
|
23
46
|
const subscribe = React.useCallback((listener) => {
|
|
24
47
|
return BrowserStorage.subscribe({
|
|
25
48
|
key,
|
|
@@ -48,10 +71,14 @@ export const useStoredState = (opts) => {
|
|
|
48
71
|
const setValue = React.useCallback((next) => {
|
|
49
72
|
const hit = keptRef.current;
|
|
50
73
|
const current = hit?.key === key && hit.storage === storage ? hit.value : getSnapshot();
|
|
51
|
-
const
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
74
|
+
const entry = { key, storage, codec, value: isUpdater(next) ? next(current) : next };
|
|
75
|
+
if (!(writeDelayMs > 0)) {
|
|
76
|
+
write(entry);
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
keep(entry);
|
|
80
|
+
timerRef.current = setTimeout(() => write(entry), writeDelayMs);
|
|
81
|
+
}, [key, storage, codec, writeDelayMs, getSnapshot, keep, write]);
|
|
55
82
|
const remove = React.useCallback(() => {
|
|
56
83
|
const isRemoved = BrowserStorage.remove({ key, storage });
|
|
57
84
|
keep(isRemoved ? undefined : { key, storage, value: defaultValue });
|
|
@@ -6,6 +6,7 @@ const readWindowDimensions = () => {
|
|
|
6
6
|
? { width: window.innerWidth, height: window.innerHeight }
|
|
7
7
|
: { width: 0, height: 0 };
|
|
8
8
|
};
|
|
9
|
+
/** The window's `innerWidth` and `innerHeight`, updated on resize; 0 x 0 where there is no window. */
|
|
9
10
|
export const useWindowDimensions = () => {
|
|
10
11
|
const [windowDimensions, setWindowDimensions] = React.useState(readWindowDimensions);
|
|
11
12
|
React.useEffect(() => {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@venizia/ardor-react",
|
|
3
|
-
"version": "0.4.8-
|
|
4
|
-
"description": "ARDOR React bindings - the application context, the injectable and logger hooks that read it, typed Redux hook factories, and the framework-agnostic UI hooks (debounce, autosave, confirm, clipboard,
|
|
3
|
+
"version": "0.4.8-2",
|
|
4
|
+
"description": "ARDOR React bindings - the application context, the injectable and logger hooks that read it, typed Redux hook factories, and the framework-agnostic UI hooks (debounce, autosave, confirm, clipboard, element size, window dimensions). No react-admin.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ardor",
|
|
7
7
|
"ardor-react",
|
|
@@ -35,6 +35,7 @@
|
|
|
35
35
|
"LICENSE.md",
|
|
36
36
|
"dist",
|
|
37
37
|
"!/**/__tests__",
|
|
38
|
+
"!**/*.map",
|
|
38
39
|
"!**/*.tsbuildinfo"
|
|
39
40
|
],
|
|
40
41
|
"type": "module",
|
|
@@ -58,8 +59,7 @@
|
|
|
58
59
|
"prepublishOnly": "make rebuild"
|
|
59
60
|
},
|
|
60
61
|
"dependencies": {
|
|
61
|
-
"@venizia/ardor-kernel": "0.4.8-
|
|
62
|
-
"lodash": "^4.18.1"
|
|
62
|
+
"@venizia/ardor-kernel": "0.4.8-2"
|
|
63
63
|
},
|
|
64
64
|
"devDependencies": {
|
|
65
65
|
"@happy-dom/global-registrator": "^21.0.4",
|
|
@@ -67,17 +67,18 @@
|
|
|
67
67
|
"@size-limit/preset-small-lib": "^14.2.0",
|
|
68
68
|
"@testing-library/react": "^16.3.3",
|
|
69
69
|
"@types/bun": "^1.4.3",
|
|
70
|
-
"@types/lodash": "^4.17.27",
|
|
71
70
|
"@types/react": "^19",
|
|
72
|
-
"@
|
|
73
|
-
"@venizia/
|
|
74
|
-
"@venizia/ignis-
|
|
75
|
-
"@venizia/ignis-
|
|
76
|
-
"@venizia/ignis-
|
|
71
|
+
"@types/react-dom": "^19",
|
|
72
|
+
"@venizia/dev-configs": "^0.4.8-1",
|
|
73
|
+
"@venizia/ignis-filter": "^0.4.7-1",
|
|
74
|
+
"@venizia/ignis-helpers": "^0.4.8-1",
|
|
75
|
+
"@venizia/ignis-inversion": "^0.4.7-1",
|
|
76
|
+
"@venizia/ignis-kernel": "^0.4.8-1",
|
|
77
77
|
"eslint": "^10.13.0",
|
|
78
78
|
"oxlint": "1.89.0",
|
|
79
79
|
"oxlint-tsgolint": "7.0.2004",
|
|
80
80
|
"react": "^19.3.1",
|
|
81
|
+
"react-dom": "^19.3.1",
|
|
81
82
|
"react-redux": "^9.3.0",
|
|
82
83
|
"reflect-metadata": "^0.2.2",
|
|
83
84
|
"size-limit": "^14.2.0",
|
|
@@ -86,10 +87,10 @@
|
|
|
86
87
|
},
|
|
87
88
|
"peerDependencies": {
|
|
88
89
|
"@reduxjs/toolkit": ">=2.13.0",
|
|
89
|
-
"@venizia/ignis-filter": "^0.4.
|
|
90
|
-
"@venizia/ignis-helpers": "^0.4.
|
|
91
|
-
"@venizia/ignis-inversion": "^0.4.
|
|
92
|
-
"@venizia/ignis-kernel": "^0.4.
|
|
90
|
+
"@venizia/ignis-filter": "^0.4.7-1",
|
|
91
|
+
"@venizia/ignis-helpers": "^0.4.8-1",
|
|
92
|
+
"@venizia/ignis-inversion": "^0.4.7-1",
|
|
93
|
+
"@venizia/ignis-kernel": "^0.4.8-1",
|
|
93
94
|
"react": ">=19.3.1",
|
|
94
95
|
"react-redux": ">=9.3.0",
|
|
95
96
|
"reflect-metadata": ">=0.2.2"
|
|
@@ -107,11 +108,10 @@
|
|
|
107
108
|
"@reduxjs/toolkit",
|
|
108
109
|
"@venizia/ardor-kernel",
|
|
109
110
|
"@venizia/ignis-inversion",
|
|
110
|
-
"lodash",
|
|
111
111
|
"react",
|
|
112
112
|
"react-redux"
|
|
113
113
|
],
|
|
114
|
-
"limit": "
|
|
114
|
+
"limit": "3450 B"
|
|
115
115
|
}
|
|
116
116
|
],
|
|
117
117
|
"engines": {
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"application.d.ts","sourceRoot":"","sources":["../../src/contexts/application.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAE1D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AAE3D,MAAM,WAAW,wBAAwB;IACvC,SAAS,EAAE,SAAS,GAAG,IAAI,CAAC;IAC5B,MAAM,EAAE,OAAO,GAAG,IAAI,CAAC;CACxB;AAED,eAAO,MAAM,kBAAkB,yCAG7B,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"application.js","sourceRoot":"","sources":["../../src/contexts/application.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAW1B,MAAM,CAAC,MAAM,kBAAkB,GAAG,KAAK,CAAC,aAAa,CAA2B;IAC9E,SAAS,EAAE,IAAI;IACf,MAAM,EAAE,IAAI;CACb,CAAC,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/contexts/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/contexts/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,2BAA2B,CAAC;AAC1C,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,qBAAqB,CAAC;AACpC,cAAc,eAAe,CAAC;AAC9B,cAAc,yBAAyB,CAAC;AACxC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,aAAa,CAAC;AAC5B,cAAc,oBAAoB,CAAC;AACnC,cAAc,yBAAyB,CAAC"}
|
package/dist/hooks/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,2BAA2B,CAAC;AAC1C,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,qBAAqB,CAAC;AACpC,cAAc,eAAe,CAAC;AAC9B,cAAc,yBAAyB,CAAC;AACxC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,aAAa,CAAC;AAC5B,cAAc,oBAAoB,CAAC;AACnC,cAAc,yBAAyB,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/hooks/redux/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/hooks/redux/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"use-app-dispatch.d.ts","sourceRoot":"","sources":["../../../src/hooks/redux/use-app-dispatch.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAGhE,qBAAa,aAAa;IACxB,qGAAqG;IACrG,MAAM,CAAC,MAAM,CAAC,SAAS,SAAS,QAAQ,CAAC,aAAa,CAAC,GAAG,QAAQ,CAAC,aAAa,CAAC;;mDAS9D,0BAAoB;;CAkBxC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"use-app-dispatch.js","sourceRoot":"","sources":["../../../src/hooks/redux/use-app-dispatch.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,MAAM,OAAO,aAAa;IACxB,qGAAqG;IACrG,MAAM,CAAC,MAAM;QACX,MAAM,cAAc,GAAG,WAAW,CAAC,SAAS,EAAa,CAAC;QAE1D,MAAM,sBAAsB,GAAG,GAAG,EAAE;YAClC,MAAM,QAAQ,GAAG,cAAc,EAAE,CAAC;YAIlC,MAAM,gBAAgB,GAAG,KAAK,CAAC,WAAW,CACxC,CAAC,GAAG,OAA6B,EAAE,EAAE;gBACnC,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE;oBACzB,IAAI,MAAM,EAAE,CAAC;wBACX,QAAQ,CAAC,MAAM,CAAC,CAAC;oBACnB,CAAC;gBACH,CAAC,CAAC,CAAC;YACL,CAAC,EACD,CAAC,QAAQ,CAAC,CACX,CAAC;YAEF,OAAO,gBAAgB,CAAC;QAC1B,CAAC,CAAC;QAEF,OAAO;YACL,cAAc;YACd,sBAAsB;SACvB,CAAC;IACJ,CAAC;CACF"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"use-app-selector.d.ts","sourceRoot":"","sources":["../../../src/hooks/redux/use-app-selector.ts"],"names":[],"mappings":"AAGA,qBAAa,aAAa;IACxB,yGAAyG;IACzG,MAAM,CAAC,MAAM,CAAC,MAAM;;kCAGe,SAAS,YAAY,CAAC,KAAK,EAAE,MAAM,KAAK,SAAS;+BAIpD,SAAS,YAAY,CAAC,KAAK,EAAE,MAAM,KAAK,SAAS;;CAUlF"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"use-app-selector.js","sourceRoot":"","sources":["../../../src/hooks/redux/use-app-selector.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,mBAAmB,CAAC;AACxC,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAExD,MAAM,OAAO,aAAa;IACxB,yGAAyG;IACzG,MAAM,CAAC,MAAM;QACX,MAAM,cAAc,GAAG,WAAW,CAAC,SAAS,EAAU,CAAC;QAEvD,MAAM,uBAAuB,GAAG,CAAY,QAAsC,EAAE,EAAE;YACpF,OAAO,cAAc,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;QAChD,CAAC,CAAC;QAEF,MAAM,oBAAoB,GAAG,CAAY,QAAsC,EAAE,EAAE;YACjF,OAAO,cAAc,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAC3C,CAAC,CAAC;QAEF,OAAO;YACL,cAAc;YACd,uBAAuB;YACvB,oBAAoB;SACrB,CAAC;IACJ,CAAC;CACF"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"use-application-context.d.ts","sourceRoot":"","sources":["../../src/hooks/use-application-context.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,qBAAqB,oDAUjC,CAAC;AAEF,eAAO,MAAM,oBAAoB,qDAUhC,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"use-application-context.js","sourceRoot":"","sources":["../../src/hooks/use-application-context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAEpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAE7D,MAAM,CAAC,MAAM,qBAAqB,GAAG,GAAG,EAAE;IACxC,MAAM,OAAO,GAAG,KAAK,CAAC,UAAU,CAAC,kBAAkB,CAAC,CAAC;IAErD,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,CAAC;QACxB,MAAM,QAAQ,CAAC;YACb,OAAO,EAAE,0EAA0E;SACpF,CAAC,CAAC;IACL,CAAC;IAED,OAAO,OAAO,CAAC,SAAS,CAAC;AAC3B,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,oBAAoB,GAAG,GAAG,EAAE;IACvC,MAAM,OAAO,GAAG,KAAK,CAAC,UAAU,CAAC,kBAAkB,CAAC,CAAC;IAErD,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC;QACrB,MAAM,QAAQ,CAAC;YACb,OAAO,EAAE,yEAAyE;SACnF,CAAC,CAAC;IACL,CAAC;IAED,OAAO,OAAO,CAAC,MAAM,CAAC;AACxB,CAAC,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"use-artifact.d.ts","sourceRoot":"","sources":["../../src/hooks/use-artifact.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,SAAS,EAAY,KAAK,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAEjF,OAAO,EAGL,KAAK,kBAAkB,EAExB,MAAM,kBAAkB,CAAC;AAE1B,6DAA6D;AAC7D,MAAM,WAAW,oBAAoB,CAAC,SAAS;IAC7C,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;IAC1B,GAAG,CAAC,EAAE,KAAK,CAAC;CACb;AAED,4CAA4C;AAC5C,MAAM,WAAW,iBAAiB;IAChC,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,GAAG,EAAE,kBAAkB,CAAC;IACxB,MAAM,CAAC,EAAE,KAAK,CAAC;CAChB;AAgCD,eAAO,MAAM,UAAU,GAAI,SAAS,GAAG,OAAO,EAC5C,MAAM,oBAAoB,CAAC,SAAS,CAAC,GAAG,iBAAiB,KACxD,SAKC,CAAC;AAEL,eAAO,MAAM,WAAW,GAAI,SAAS,GAAG,OAAO,EAC7C,MAAM,oBAAoB,CAAC,SAAS,CAAC,GAAG,iBAAiB,KACxD,SAKC,CAAC;AAEL,eAAO,MAAM,YAAY,GAAI,SAAS,GAAG,OAAO,EAC9C,MAAM,oBAAoB,CAAC,SAAS,CAAC,GAAG,iBAAiB,KACxD,SAKC,CAAC;AAEL,eAAO,MAAM,gBAAgB,GAAI,SAAS,GAAG,OAAO,EAClD,MAAM,oBAAoB,CAAC,SAAS,CAAC,GAAG,iBAAiB,KACxD,SAKC,CAAC;AAEL,eAAO,MAAM,aAAa,GAAI,SAAS,GAAG,OAAO,EAC/C,MAAM,oBAAoB,CAAC,SAAS,CAAC,GAAG,iBAAiB,KACxD,SAKC,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"use-artifact.js","sourceRoot":"","sources":["../../src/hooks/use-artifact.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAkB,QAAQ,EAAe,MAAM,0BAA0B,CAAC;AAEjF,OAAO,EACL,aAAa,EACb,sBAAsB,GAGvB,MAAM,kBAAkB,CAAC;AAgB1B;;;GAGG;AACH,MAAM,sBAAsB,GAAG,CAAY,IAI1C,EAAa,EAAE;IACd,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC;IAE1C,mFAAmF;IACnF,MAAM,SAAS,GAAG,sBAAsB,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;IAE3E,2EAA2E;IAC3E,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACnB,MAAM,GAAG,GAAG,SAAS,CAAC,mBAAmB,EAAE,CAAC,aAAa,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;QACtF,4EAA4E;QAC5E,MAAM,KAAK,GAAG,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAE1D,IAAI,KAAK,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,SAAS,GAAG,CAAC,EAAE,CAAC;YAChD,MAAM,QAAQ,CAAC;gBACb,OAAO,EAAE,IAAI,IAAI,KAAK,OAAO,CAAC,MAAM,CAAC,IAAI,iBAAiB,KAAK,iBAAiB,SAAS,4EAA4E;aACtK,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,aAAa,CAAY,OAAO,CAAC,CAAC;AAC3C,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,UAAU,GAAG,CACxB,IAAyD,EAC9C,EAAE,CACb,sBAAsB,CAAY;IAChC,OAAO,EAAE,IAAI;IACb,SAAS,EAAE,iBAAiB,CAAC,OAAO;IACpC,IAAI,EAAE,YAAY;CACnB,CAAC,CAAC;AAEL,MAAM,CAAC,MAAM,WAAW,GAAG,CACzB,IAAyD,EAC9C,EAAE,CACb,sBAAsB,CAAY;IAChC,OAAO,EAAE,IAAI;IACb,SAAS,EAAE,iBAAiB,CAAC,QAAQ;IACrC,IAAI,EAAE,aAAa;CACpB,CAAC,CAAC;AAEL,MAAM,CAAC,MAAM,YAAY,GAAG,CAC1B,IAAyD,EAC9C,EAAE,CACb,sBAAsB,CAAY;IAChC,OAAO,EAAE,IAAI;IACb,SAAS,EAAE,iBAAiB,CAAC,SAAS;IACtC,IAAI,EAAE,cAAc;CACrB,CAAC,CAAC;AAEL,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAC9B,IAAyD,EAC9C,EAAE,CACb,sBAAsB,CAAY;IAChC,OAAO,EAAE,IAAI;IACb,SAAS,EAAE,iBAAiB,CAAC,aAAa;IAC1C,IAAI,EAAE,kBAAkB;CACzB,CAAC,CAAC;AAEL,MAAM,CAAC,MAAM,aAAa,GAAG,CAC3B,IAAyD,EAC9C,EAAE,CACb,sBAAsB,CAAY;IAChC,OAAO,EAAE,IAAI;IACb,SAAS,EAAE,iBAAiB,CAAC,UAAU;IACvC,IAAI,EAAE,eAAe;CACtB,CAAC,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"use-autosave.d.ts","sourceRoot":"","sources":["../../src/hooks/use-autosave.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,mBAAmB,CAAC,KAAK,EAAE,OAAO;IACjD,IAAI,EAAE,KAAK,CAAC;IACZ,MAAM,EAAE,CAAC,IAAI,EAAE,KAAK,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,GAAG,IAAI,CAAC;IAC3D,oBAAoB;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,oBAAoB;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAID,eAAO,MAAM,WAAW,GAAI,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC,KAAK,EAAE,OAAO,CAAC,SA4CpF,CAAC"}
|