@cmtlyt/lingshu-toolkit 0.1.1 → 0.3.0

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.
Files changed (76) hide show
  1. package/README.md +2 -0
  2. package/dist/607.js +288 -108
  3. package/dist/707.js +136 -0
  4. package/dist/react/index.d.ts +7 -0
  5. package/dist/react/index.js +129 -8
  6. package/dist/react/use-boolean/index.d.ts +6 -0
  7. package/dist/react/use-boolean/index.js +16 -0
  8. package/dist/react/use-boolean/index.test.d.ts +1 -0
  9. package/dist/react/use-controllable-value/index.js +1 -2
  10. package/dist/react/use-counter/index.js +2 -2
  11. package/dist/react/use-force-update/index.d.ts +1 -0
  12. package/dist/react/use-force-update/index.js +6 -0
  13. package/dist/react/use-force-update/index.test.d.ts +1 -0
  14. package/dist/react/use-mount/index.d.ts +1 -0
  15. package/dist/react/use-mount/index.js +16 -0
  16. package/dist/react/use-mount/index.test.d.ts +1 -0
  17. package/dist/react/use-ref-state/index.d.ts +8 -0
  18. package/dist/react/use-ref-state/index.js +35 -0
  19. package/dist/react/use-ref-state/index.test.d.ts +1 -0
  20. package/dist/react/use-storage/index.d.ts +2 -0
  21. package/dist/react/use-storage/index.js +15 -0
  22. package/dist/react/use-storage/index.test.d.ts +1 -0
  23. package/dist/react/use-title/index.d.ts +6 -0
  24. package/dist/react/use-title/index.js +24 -0
  25. package/dist/react/use-title/index.test.d.ts +1 -0
  26. package/dist/react/use-toggle/index.d.ts +10 -0
  27. package/dist/react/use-toggle/index.js +26 -0
  28. package/dist/react/use-toggle/index.test.d.ts +1 -0
  29. package/dist/react/use-valid-data/index.d.ts +4 -2
  30. package/dist/react/use-valid-data/index.js +5 -2
  31. package/dist/shared/animation/__test__/animation-pause-resume.test.d.ts +1 -0
  32. package/dist/shared/animation/__test__/animation.test.d.ts +1 -0
  33. package/dist/shared/animation/__test__/step-animation.test.d.ts +1 -0
  34. package/dist/shared/animation/__test__/utils.test.d.ts +1 -0
  35. package/dist/shared/animation/index.d.ts +3 -0
  36. package/dist/shared/animation/index.js +71 -0
  37. package/dist/shared/animation/types.d.ts +22 -0
  38. package/dist/shared/animation/types.js +0 -0
  39. package/dist/shared/animation/utils.d.ts +16 -0
  40. package/dist/shared/animation/utils.js +138 -0
  41. package/dist/shared/condition-merge/index.d.ts +31 -0
  42. package/dist/shared/condition-merge/index.js +30 -0
  43. package/dist/shared/condition-merge/index.test-d.d.ts +1 -0
  44. package/dist/shared/condition-merge/index.test-d.js +108 -0
  45. package/dist/shared/condition-merge/index.test.d.ts +1 -0
  46. package/dist/shared/create-storage-handler/index.browser.test.d.ts +1 -0
  47. package/dist/shared/create-storage-handler/index.d.ts +10 -0
  48. package/dist/shared/create-storage-handler/index.js +68 -0
  49. package/dist/shared/create-storage-handler/index.test.d.ts +1 -0
  50. package/dist/shared/data-handler/index.d.ts +7 -2
  51. package/dist/shared/data-handler/index.js +4 -4
  52. package/dist/shared/data-handler/tools.d.ts +36 -12
  53. package/dist/shared/data-handler/tools.js +8 -2
  54. package/dist/shared/data-handler/types.d.ts +3 -2
  55. package/dist/shared/index.d.ts +5 -0
  56. package/dist/shared/index.js +2 -1
  57. package/dist/shared/logger/index.d.ts +5 -1
  58. package/dist/shared/logger/index.js +2 -2
  59. package/dist/shared/throw-error/index.d.ts +2 -2
  60. package/dist/shared/throw-error/index.js +4 -4
  61. package/dist/shared/types/base.d.ts +8 -0
  62. package/dist/shared/types/base.js +0 -0
  63. package/dist/shared/types/index.d.ts +2 -2
  64. package/dist/shared/types/index.js +2 -0
  65. package/dist/shared/types/pack.d.ts +9 -0
  66. package/dist/shared/types/pack.js +1 -0
  67. package/dist/shared/with-resolvers/index.d.ts +6 -0
  68. package/dist/shared/with-resolvers/index.js +15 -0
  69. package/dist/shared/with-resolvers/index.test.d.ts +1 -0
  70. package/dist/test/utils.d.ts +13 -0
  71. package/dist/vue/index.d.ts +1 -0
  72. package/dist/vue/index.js +29 -0
  73. package/dist/vue/use-title/index.d.ts +6 -0
  74. package/dist/vue/use-title/index.js +29 -0
  75. package/dist/vue/use-title/index.test.d.ts +1 -0
  76. package/package.json +16 -4
@@ -1,9 +1,49 @@
1
- import { useEffect, useEffectEvent, useMemo, useRef, useState } from "react";
2
- import { dataHandler, logger, $dt, $t } from "../607.js";
1
+ import { useEffect, useEffectEvent, useMemo, useReducer, useRef, useState } from "react";
2
+ import { dataHandler, logger, $dt, $t, throwType } from "../707.js";
3
+ import { createStorageHandler } from "../607.js";
4
+ function useToggle(defualtValue = false, reverseValue) {
5
+ const [state, setState] = useState(defualtValue);
6
+ const toggleRef = useRef([
7
+ defualtValue,
8
+ void 0 === reverseValue ? !defualtValue : reverseValue
9
+ ]);
10
+ const actions = useMemo(()=>{
11
+ const [left, right] = toggleRef.current;
12
+ return {
13
+ set: (value)=>{
14
+ if (value !== left && value !== right) throwType('useToggle', 'value is not left or right');
15
+ setState(value);
16
+ },
17
+ setLeft: ()=>setState(left),
18
+ setRight: ()=>setState(right),
19
+ toggle: ()=>setState((prev)=>prev === left ? right : left)
20
+ };
21
+ }, []);
22
+ return [
23
+ state,
24
+ actions
25
+ ];
26
+ }
27
+ function useBoolean(defaultValue = false) {
28
+ const [state, { toggle, set }] = useToggle(!!defaultValue);
29
+ const actions = useMemo(()=>({
30
+ toggle,
31
+ setTrue: ()=>set(true),
32
+ setFalse: ()=>set(false),
33
+ set: (value)=>set(!!value)
34
+ }), []);
35
+ return [
36
+ state,
37
+ actions
38
+ ];
39
+ }
3
40
  function useValidData(data, verifyInfo, options) {
4
41
  const verifyInfoRef = useRef(verifyInfo);
5
42
  const optionsRef = useRef(options);
6
- return useMemo(()=>dataHandler(data, verifyInfoRef.current, optionsRef.current), [
43
+ return useMemo(()=>dataHandler(data, verifyInfoRef.current, {
44
+ unwrap: true,
45
+ ...optionsRef.current
46
+ }), [
7
47
  data
8
48
  ]);
9
49
  }
@@ -13,8 +53,7 @@ const validInfo = $dt({
13
53
  trigger: $t.validString('onChange')
14
54
  });
15
55
  function useControllableValue(props = {}, options = {}) {
16
- const { result: validOptions } = useValidData(options, validInfo);
17
- const { defaultValue: _defaultValue, trigger, valuePropName, defaultValuePropName } = validOptions;
56
+ const { defaultValue: _defaultValue, trigger, valuePropName, defaultValuePropName } = useValidData(options, validInfo);
18
57
  const { [valuePropName]: propValue, [defaultValuePropName]: defaultValue = _defaultValue, [trigger]: emitChange } = props;
19
58
  const hasValueRef = useRef(Boolean(Reflect.getOwnPropertyDescriptor(props, valuePropName)));
20
59
  const isFirstRenderRef = useRef(true);
@@ -56,7 +95,7 @@ const use_counter_validInfo = $dt({
56
95
  step: $t.validNumber(nanTransform(1))
57
96
  });
58
97
  function useCounter(initialValue = 0, options = {}) {
59
- const { result: validOptions } = useValidData(options, use_counter_validInfo);
98
+ const validOptions = useValidData(options, use_counter_validInfo);
60
99
  const { step } = validOptions;
61
100
  const initialValueRef = useRef(getRealValue(Number(initialValue), validOptions));
62
101
  const [current, setCurrent] = useState(getRealValue(Number(initialValue), validOptions));
@@ -82,5 +121,87 @@ function useCounter(initialValue = 0, options = {}) {
82
121
  actions
83
122
  ];
84
123
  }
85
- export { $dt, $t, defineTransform } from "../607.js";
86
- export { useControllableValue, useCounter, useValidData };
124
+ function useForceUpdate() {
125
+ const [, forceUpdate] = useReducer((prev)=>(prev + 1) % 10, 0);
126
+ return forceUpdate;
127
+ }
128
+ function useMount(callback) {
129
+ const callbackRef = useRef(callback);
130
+ useEffect(()=>{
131
+ dataHandler({
132
+ fn: callbackRef.current
133
+ }, {
134
+ fn: $t["function"]()
135
+ }, {
136
+ strict: true
137
+ });
138
+ callbackRef.current();
139
+ }, []);
140
+ }
141
+ function clone(_v) {
142
+ return structuredClone(_v);
143
+ }
144
+ function useRefState(initialState) {
145
+ const stateRef = useRef(initialState);
146
+ const forceUpdate = useForceUpdate();
147
+ const ctrl = useMemo(()=>{
148
+ const origin = clone(stateRef.current);
149
+ const updateHandler = (update = true)=>void (update && forceUpdate());
150
+ const patchState = (updater, update = true)=>{
151
+ updater(stateRef.current);
152
+ updateHandler(update);
153
+ };
154
+ const setState = (state, update = true)=>{
155
+ stateRef.current = state;
156
+ updateHandler(update);
157
+ };
158
+ return {
159
+ patchState,
160
+ forceUpdate,
161
+ getState: ()=>stateRef.current,
162
+ setState,
163
+ reset: (update = true)=>setState(clone(origin), update)
164
+ };
165
+ }, [
166
+ forceUpdate
167
+ ]);
168
+ return [
169
+ stateRef.current,
170
+ ctrl
171
+ ];
172
+ }
173
+ function useStorage(storageKey, options, initialData) {
174
+ const optionsRef = useRef({
175
+ initialData,
176
+ options
177
+ });
178
+ return useMemo(()=>{
179
+ const { initialData: _initialData, options: _options } = optionsRef.current;
180
+ return createStorageHandler(storageKey, _initialData || {}, _options);
181
+ }, [
182
+ storageKey
183
+ ]);
184
+ }
185
+ function setTitle(title) {
186
+ if (!title) return;
187
+ document.title = title;
188
+ }
189
+ const use_title_validInfo = $dt({
190
+ restoreOnUnmount: $t.boolean(true)
191
+ });
192
+ function useTitle(title, options = {}) {
193
+ const { restoreOnUnmount } = useValidData(options, use_title_validInfo);
194
+ useEffect(()=>{
195
+ const originalTitle = document.title;
196
+ setTitle(title);
197
+ return ()=>{
198
+ if (restoreOnUnmount) setTitle(originalTitle);
199
+ };
200
+ }, [
201
+ title,
202
+ restoreOnUnmount
203
+ ]);
204
+ return setTitle;
205
+ }
206
+ export { $dt, $t, defineTransform } from "../707.js";
207
+ export { useBoolean, useControllableValue, useCounter, useForceUpdate, useMount, useRefState, useStorage, useTitle, useToggle, useValidData };
@@ -0,0 +1,6 @@
1
+ export declare function useBoolean(defaultValue?: boolean): readonly [boolean, {
2
+ toggle: () => void;
3
+ setTrue: () => void;
4
+ setFalse: () => void;
5
+ set: (value: boolean) => void;
6
+ }];
@@ -0,0 +1,16 @@
1
+ import { useMemo } from "react";
2
+ import { useToggle } from "../use-toggle/index.js";
3
+ function useBoolean(defaultValue = false) {
4
+ const [state, { toggle, set }] = useToggle(!!defaultValue);
5
+ const actions = useMemo(()=>({
6
+ toggle,
7
+ setTrue: ()=>set(true),
8
+ setFalse: ()=>set(false),
9
+ set: (value)=>set(!!value)
10
+ }), []);
11
+ return [
12
+ state,
13
+ actions
14
+ ];
15
+ }
16
+ export { useBoolean };
@@ -0,0 +1 @@
1
+ export {};
@@ -6,8 +6,7 @@ const validInfo = $dt({
6
6
  trigger: $t.validString('onChange')
7
7
  });
8
8
  function useControllableValue(props = {}, options = {}) {
9
- const { result: validOptions } = useValidData(options, validInfo);
10
- const { defaultValue: _defaultValue, trigger, valuePropName, defaultValuePropName } = validOptions;
9
+ const { defaultValue: _defaultValue, trigger, valuePropName, defaultValuePropName } = useValidData(options, validInfo);
11
10
  const { [valuePropName]: propValue, [defaultValuePropName]: defaultValue = _defaultValue, [trigger]: emitChange } = props;
12
11
  const hasValueRef = useRef(Boolean(Reflect.getOwnPropertyDescriptor(props, valuePropName)));
13
12
  const isFirstRenderRef = useRef(true);
@@ -1,6 +1,6 @@
1
- import { logger } from "../../shared/logger/index.js";
2
1
  import { useEffectEvent, useMemo, useRef, useState } from "react";
3
2
  import { $dt, $t, useValidData } from "../use-valid-data/index.js";
3
+ import { logger } from "../../shared/logger/index.js";
4
4
  function getRealValue(value, options) {
5
5
  const { min, max } = options;
6
6
  return Math.min(Math.max(value, min), max);
@@ -20,7 +20,7 @@ const validInfo = $dt({
20
20
  step: $t.validNumber(nanTransform(1))
21
21
  });
22
22
  function useCounter(initialValue = 0, options = {}) {
23
- const { result: validOptions } = useValidData(options, validInfo);
23
+ const validOptions = useValidData(options, validInfo);
24
24
  const { step } = validOptions;
25
25
  const initialValueRef = useRef(getRealValue(Number(initialValue), validOptions));
26
26
  const [current, setCurrent] = useState(getRealValue(Number(initialValue), validOptions));
@@ -0,0 +1 @@
1
+ export declare function useForceUpdate(): import("react").ActionDispatch<[]>;
@@ -0,0 +1,6 @@
1
+ import { useReducer } from "react";
2
+ function useForceUpdate() {
3
+ const [, forceUpdate] = useReducer((prev)=>(prev + 1) % 10, 0);
4
+ return forceUpdate;
5
+ }
6
+ export { useForceUpdate };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export declare function useMount(callback: () => any): void;
@@ -0,0 +1,16 @@
1
+ import { useEffect, useRef } from "react";
2
+ import { $t, dataHandler } from "../../shared/index.js";
3
+ function useMount(callback) {
4
+ const callbackRef = useRef(callback);
5
+ useEffect(()=>{
6
+ dataHandler({
7
+ fn: callbackRef.current
8
+ }, {
9
+ fn: $t["function"]()
10
+ }, {
11
+ strict: true
12
+ });
13
+ callbackRef.current();
14
+ }, []);
15
+ }
16
+ export { useMount };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,8 @@
1
+ export interface UseRefStateCtrl<T> {
2
+ patchState: (updater: (draft: T) => void, update?: boolean) => void;
3
+ forceUpdate: () => void;
4
+ getState: () => T;
5
+ setState: (state: T, update?: boolean) => void;
6
+ reset: (update?: boolean) => void;
7
+ }
8
+ export declare function useRefState<T>(initialState: T): readonly [T, UseRefStateCtrl<T>];
@@ -0,0 +1,35 @@
1
+ import { useMemo, useRef } from "react";
2
+ import { useForceUpdate } from "../use-force-update/index.js";
3
+ function clone(_v) {
4
+ return structuredClone(_v);
5
+ }
6
+ function useRefState(initialState) {
7
+ const stateRef = useRef(initialState);
8
+ const forceUpdate = useForceUpdate();
9
+ const ctrl = useMemo(()=>{
10
+ const origin = clone(stateRef.current);
11
+ const updateHandler = (update = true)=>void (update && forceUpdate());
12
+ const patchState = (updater, update = true)=>{
13
+ updater(stateRef.current);
14
+ updateHandler(update);
15
+ };
16
+ const setState = (state, update = true)=>{
17
+ stateRef.current = state;
18
+ updateHandler(update);
19
+ };
20
+ return {
21
+ patchState,
22
+ forceUpdate,
23
+ getState: ()=>stateRef.current,
24
+ setState,
25
+ reset: (update = true)=>setState(clone(origin), update)
26
+ };
27
+ }, [
28
+ forceUpdate
29
+ ]);
30
+ return [
31
+ stateRef.current,
32
+ ctrl
33
+ ];
34
+ }
35
+ export { useRefState };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,2 @@
1
+ import { type CreateStorageOptions } from '../../shared/create-storage-handler';
2
+ export declare function useStorage<T extends Record<string, any>>(storageKey: string, options?: Partial<CreateStorageOptions>, initialData?: T): import("../../shared/create-storage-handler").StorageHandler<T>;
@@ -0,0 +1,15 @@
1
+ import { useMemo, useRef } from "react";
2
+ import { createStorageHandler } from "../../shared/create-storage-handler/index.js";
3
+ function useStorage(storageKey, options, initialData) {
4
+ const optionsRef = useRef({
5
+ initialData,
6
+ options
7
+ });
8
+ return useMemo(()=>{
9
+ const { initialData: _initialData, options: _options } = optionsRef.current;
10
+ return createStorageHandler(storageKey, _initialData || {}, _options);
11
+ }, [
12
+ storageKey
13
+ ]);
14
+ }
15
+ export { useStorage };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,6 @@
1
+ interface UseTitleOptions {
2
+ restoreOnUnmount: boolean;
3
+ }
4
+ declare function setTitle(title?: string): void;
5
+ export declare function useTitle(title?: string, options?: Partial<UseTitleOptions>): typeof setTitle;
6
+ export {};
@@ -0,0 +1,24 @@
1
+ import { useEffect } from "react";
2
+ import { $dt, $t, useValidData } from "../use-valid-data/index.js";
3
+ function setTitle(title) {
4
+ if (!title) return;
5
+ document.title = title;
6
+ }
7
+ const validInfo = $dt({
8
+ restoreOnUnmount: $t.boolean(true)
9
+ });
10
+ function useTitle(title, options = {}) {
11
+ const { restoreOnUnmount } = useValidData(options, validInfo);
12
+ useEffect(()=>{
13
+ const originalTitle = document.title;
14
+ setTitle(title);
15
+ return ()=>{
16
+ if (restoreOnUnmount) setTitle(originalTitle);
17
+ };
18
+ }, [
19
+ title,
20
+ restoreOnUnmount
21
+ ]);
22
+ return setTitle;
23
+ }
24
+ export { useTitle };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,10 @@
1
+ interface Actions<T> {
2
+ set: (value: T) => void;
3
+ setLeft: () => void;
4
+ setRight: () => void;
5
+ toggle: () => void;
6
+ }
7
+ export declare function useToggle(): [boolean, Actions<boolean>];
8
+ export declare function useToggle<L>(defaultValue: L): [L, Actions<L>];
9
+ export declare function useToggle<L, R>(defaultValue: L, reverseValue: R): [L | R, Actions<L | R>];
10
+ export {};
@@ -0,0 +1,26 @@
1
+ import { useMemo, useRef, useState } from "react";
2
+ import { throwType } from "../../shared/throw-error/index.js";
3
+ function useToggle(defualtValue = false, reverseValue) {
4
+ const [state, setState] = useState(defualtValue);
5
+ const toggleRef = useRef([
6
+ defualtValue,
7
+ void 0 === reverseValue ? !defualtValue : reverseValue
8
+ ]);
9
+ const actions = useMemo(()=>{
10
+ const [left, right] = toggleRef.current;
11
+ return {
12
+ set: (value)=>{
13
+ if (value !== left && value !== right) throwType('useToggle', 'value is not left or right');
14
+ setState(value);
15
+ },
16
+ setLeft: ()=>setState(left),
17
+ setRight: ()=>setState(right),
18
+ toggle: ()=>setState((prev)=>prev === left ? right : left)
19
+ };
20
+ }, []);
21
+ return [
22
+ state,
23
+ actions
24
+ ];
25
+ }
26
+ export { useToggle };
@@ -0,0 +1 @@
1
+ export {};
@@ -1,6 +1,8 @@
1
1
  import type { DataHandlerOptions, Handler } from '../../shared/data-handler/types';
2
2
  export * from '../../shared/data-handler/tools';
3
- export declare function useValidData<T extends Record<PropertyKey, any>>(data: T, verifyInfo: Handler<T>, options?: DataHandlerOptions<T>): {
4
- result: T | (T & undefined);
3
+ export declare function useValidData<T extends Record<PropertyKey, any>, H extends Handler<T> = Handler<T>, O extends DataHandlerOptions<T> = DataHandlerOptions<T> & {
4
+ unwrap: true;
5
+ }>(data: T, verifyInfo: H, options?: O): O["unwrap"] extends true ? import("../../shared").Printify<import("../../shared/data-handler").Transform2Type<H> extends infer T_1 ? T_1 extends import("../../shared/data-handler").Transform2Type<H> ? T_1 extends (...args: any[]) => any ? T & O["defaultValue"] : T & O["defaultValue"] & { [K in keyof T_1]: import("../../shared").Equal<T_1[K], any> extends true ? Required<T & O["defaultValue"]>[K] : T_1[K]; } : never : never> : {
6
+ result: import("../../shared").Printify<import("../../shared/data-handler").Transform2Type<H> extends infer T_2 ? T_2 extends import("../../shared/data-handler").Transform2Type<H> ? T_2 extends (...args: any[]) => any ? T & O["defaultValue"] : T & O["defaultValue"] & { [K_1 in keyof T_2]: import("../../shared").Equal<T_2[K_1], any> extends true ? Required<T & O["defaultValue"]>[K_1] : T_2[K_1]; } : never : never>;
5
7
  errors: string[];
6
8
  };
@@ -1,10 +1,13 @@
1
- import { dataHandler } from "../../shared/index.js";
2
1
  import { useMemo, useRef } from "react";
2
+ import { dataHandler } from "../../shared/data-handler/index.js";
3
3
  export * from "../../shared/data-handler/tools.js";
4
4
  function useValidData(data, verifyInfo, options) {
5
5
  const verifyInfoRef = useRef(verifyInfo);
6
6
  const optionsRef = useRef(options);
7
- return useMemo(()=>dataHandler(data, verifyInfoRef.current, optionsRef.current), [
7
+ return useMemo(()=>dataHandler(data, verifyInfoRef.current, {
8
+ unwrap: true,
9
+ ...optionsRef.current
10
+ }), [
8
11
  data
9
12
  ]);
10
13
  }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,3 @@
1
+ import type { AnimationBaseOptions, AnimationOptions, AnimationResult } from './types';
2
+ export declare function stepAnimation<T>(from: T, to: T, step: number, options?: AnimationBaseOptions): Generator<T, void, unknown>;
3
+ export declare function animation<T>(from: T, to: T, duration: number, options?: AnimationOptions): AnimationResult;
@@ -0,0 +1,71 @@
1
+ import { $dt, $t, dataHandler } from "../data-handler/index.js";
2
+ import { throwError } from "../throw-error/index.js";
3
+ import { createNextTick, createRunningControllerSignal, getNextValueHandler, identity, matchValid, noop } from "./utils.js";
4
+ function* stepAnimation(from, to, step, options = {}) {
5
+ if (!Number.isInteger(step) || step <= 0) throwError('stepAnimation', 'step must be a positive integer', RangeError);
6
+ const { parser: valueParser = identity, formatter: valueFormatter = identity } = options;
7
+ const [validFrom, validTo] = matchValid(from, to, valueParser);
8
+ const getNextValue = getNextValueHandler(validFrom, validTo, valueFormatter);
9
+ for(let i = 0; i <= step; i++){
10
+ const value = getNextValue(i / step);
11
+ yield value;
12
+ }
13
+ }
14
+ const validInfo = $dt({
15
+ autoStart: $t.boolean(true),
16
+ easing: $t["function"](()=>identity),
17
+ onStart: $t["function"](()=>noop),
18
+ onStop: $t["function"](()=>noop),
19
+ onClear: $t["function"](()=>noop),
20
+ onUpdate: $t["function"](()=>noop),
21
+ onComplete: $t["function"](()=>noop),
22
+ formatter: $t["function"](()=>identity),
23
+ parser: $t["function"](()=>identity)
24
+ });
25
+ function animation(from, to, duration, options = {}) {
26
+ if (duration <= 0 || !Number.isInteger(duration)) throwError('animation', 'duration must be a positive integer', RangeError);
27
+ const validOptions = dataHandler(options, validInfo, {
28
+ unwrap: true
29
+ });
30
+ const [validFrom, validTo] = matchValid(from, to, validOptions.parser);
31
+ const { autoStart, easing, onComplete, onUpdate, formatter: valueFormatter } = validOptions;
32
+ const getNextValue = getNextValueHandler(validFrom, validTo, valueFormatter);
33
+ let startTime = 0;
34
+ let hasStarted = false;
35
+ const rcSignal = createRunningControllerSignal(()=>{
36
+ const now = performance.now();
37
+ startTime += now;
38
+ const stopFlag = nextTick(tick);
39
+ if (stopFlag) {
40
+ startTime -= performance.now();
41
+ return;
42
+ }
43
+ if (!hasStarted) {
44
+ onUpdate(getNextValue(0));
45
+ hasStarted = true;
46
+ }
47
+ }, validOptions);
48
+ const { resolvers } = rcSignal;
49
+ const nextTick = createNextTick(resolvers, rcSignal);
50
+ const tick = ()=>{
51
+ const elapsed = performance.now() - startTime;
52
+ const progress = easing(Math.min(elapsed / duration, 1));
53
+ const value = getNextValue(progress);
54
+ onUpdate(value);
55
+ if (elapsed < duration) {
56
+ const stopFlag = nextTick(tick);
57
+ if (stopFlag) startTime = -elapsed;
58
+ } else {
59
+ onComplete();
60
+ resolvers.resolve(false);
61
+ }
62
+ };
63
+ if (false !== autoStart) rcSignal.start();
64
+ return {
65
+ promise: resolvers.promise,
66
+ stop: rcSignal.stop,
67
+ start: rcSignal.start,
68
+ clear: rcSignal.clear
69
+ };
70
+ }
71
+ export { animation, stepAnimation };
@@ -0,0 +1,22 @@
1
+ export type Formatter = (value: number) => any;
2
+ export interface AnimationBaseOptions {
3
+ parser?: (value: any) => number;
4
+ formatter?: Formatter;
5
+ }
6
+ export interface AnimationOptions extends AnimationBaseOptions {
7
+ autoStart?: boolean;
8
+ easing?: (time: number) => number;
9
+ onStart?: () => void;
10
+ onStop?: () => void;
11
+ onClear?: () => void;
12
+ onUpdate?: (value: any) => void;
13
+ onComplete?: () => void;
14
+ }
15
+ export interface AnimationCtrl {
16
+ stop: () => void;
17
+ start: () => void;
18
+ clear: () => void;
19
+ }
20
+ export type AnimationResult = AnimationCtrl & {
21
+ promise: Promise<boolean>;
22
+ };
File without changes
@@ -0,0 +1,16 @@
1
+ import { type Resolver } from '../with-resolvers';
2
+ import type { AnimationOptions, Formatter } from './types';
3
+ export declare const noop: () => undefined;
4
+ export declare const identity: <T>(_v: T) => T;
5
+ export declare function getNextValueHandler(from: any, to: any, valueFormatter: Formatter): (progress: number) => any;
6
+ export declare function matchValid(from: any, to: any, valueParser: (value: any) => number): number[] | unknown[][] | [Record<PropertyKey, any>, Record<PropertyKey, any>];
7
+ export declare function createNextTick(resolvers: Resolver<any>, rcSignal: RCSignal): (callback: (...args: any[]) => void) => boolean;
8
+ export declare function tryRun(callback: () => any, resolvers: Resolver<any>, customErrorHandler?: (err: any) => void): Promise<void>;
9
+ export declare function createRunningControllerSignal(startFn: () => void, options: Required<AnimationOptions>): {
10
+ stopSignal: boolean;
11
+ resolvers: Resolver<boolean>;
12
+ stop: () => void;
13
+ start: () => void;
14
+ clear: () => void;
15
+ };
16
+ export type RCSignal = Omit<ReturnType<typeof createRunningControllerSignal>, 'resolvers'>;